forked from tornadocash/tornado-cli
Save encrypted notes on router
This commit is contained in:
parent
195da66ce2
commit
3312f44a4d
@ -42,10 +42,12 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"import/order": ["error"],
|
"import/order": ["error"],
|
||||||
|
/**
|
||||||
"indent": [
|
"indent": [
|
||||||
"error",
|
"error",
|
||||||
2
|
2
|
||||||
],
|
],
|
||||||
|
**/
|
||||||
"linebreak-style": [
|
"linebreak-style": [
|
||||||
"error",
|
"error",
|
||||||
"unix"
|
"unix"
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
"compliance": "ts-node src/cli.ts compliance",
|
"compliance": "ts-node src/cli.ts compliance",
|
||||||
"syncEvents": "ts-node src/cli.ts syncEvents",
|
"syncEvents": "ts-node src/cli.ts syncEvents",
|
||||||
"relayers": "ts-node src/cli.ts relayers",
|
"relayers": "ts-node src/cli.ts relayers",
|
||||||
"createNoteAccount": "ts-node src/cli.ts createNoteAccount",
|
"createAccount": "ts-node src/cli.ts createAccount",
|
||||||
"decryptNotes": "ts-node src/cli.ts decryptNotes",
|
"decryptNotes": "ts-node src/cli.ts decryptNotes",
|
||||||
"send": "ts-node src/cli.ts send",
|
"send": "ts-node src/cli.ts send",
|
||||||
"balance": "ts-node src/cli.ts balance",
|
"balance": "ts-node src/cli.ts balance",
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any, prettier/prettier */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import workerThreads from 'worker_threads';
|
import workerThreads from 'worker_threads';
|
||||||
import { MerkleTree, Element, TreeEdge, PartialMerkleTree } from '@tornado/fixed-merkle-tree';
|
import { MerkleTree, Element, TreeEdge, PartialMerkleTree } from '@tornado/fixed-merkle-tree';
|
||||||
import { mimc, isNode } from './services';
|
import { mimc, isNode } from './services';
|
||||||
@ -65,5 +65,5 @@ if (isNode && workerThreads) {
|
|||||||
postMessage(merkleTree.toString());
|
postMessage(merkleTree.toString());
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error('This browser / environment doesn\'t support workers!');
|
throw new Error('This browser / environment does not support workers!');
|
||||||
}
|
}
|
||||||
|
165
src/program.ts
165
src/program.ts
@ -524,13 +524,14 @@ export function tornadoProgram() {
|
|||||||
.action(async (netId: string | number, currency: string, amount: string, cmdOptions: commonProgramOptions) => {
|
.action(async (netId: string | number, currency: string, amount: string, cmdOptions: commonProgramOptions) => {
|
||||||
const { options, fetchDataOptions } = await getProgramOptions(cmdOptions);
|
const { options, fetchDataOptions } = await getProgramOptions(cmdOptions);
|
||||||
currency = currency.toLowerCase();
|
currency = currency.toLowerCase();
|
||||||
const { rpc } = options;
|
const { rpc, accountKey } = options;
|
||||||
|
|
||||||
const config = networkConfig[`netId${netId}`];
|
const config = networkConfig[`netId${netId}`];
|
||||||
|
|
||||||
const {
|
const {
|
||||||
multicall: multicallAddress,
|
multicall: multicallAddress,
|
||||||
routerContract,
|
routerContract,
|
||||||
|
echoContract,
|
||||||
nativeCurrency,
|
nativeCurrency,
|
||||||
tokens: { [currency]: currencyConfig },
|
tokens: { [currency]: currencyConfig },
|
||||||
} = config;
|
} = config;
|
||||||
@ -553,6 +554,14 @@ export function tornadoProgram() {
|
|||||||
provider,
|
provider,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const noteAccount = accountKey
|
||||||
|
? new NoteAccount({
|
||||||
|
netId,
|
||||||
|
recoveryKey: accountKey,
|
||||||
|
Echoer: Echoer__factory.connect(echoContract, provider),
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
if (!signer) {
|
if (!signer) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'Signer not defined, make sure you have either viewOnly address, mnemonic, or private key configured',
|
'Signer not defined, make sure you have either viewOnly address, mnemonic, or private key configured',
|
||||||
@ -569,22 +578,20 @@ export function tornadoProgram() {
|
|||||||
name: 'getEthBalance',
|
name: 'getEthBalance',
|
||||||
params: [signer.address],
|
params: [signer.address],
|
||||||
},
|
},
|
||||||
/* eslint-disable prettier/prettier */
|
|
||||||
...(!isEth
|
...(!isEth
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
contract: Token as ERC20,
|
contract: Token as ERC20,
|
||||||
name: 'balanceOf',
|
name: 'balanceOf',
|
||||||
params: [signer.address],
|
params: [signer.address],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
contract: Token as ERC20,
|
contract: Token as ERC20,
|
||||||
name: 'allowance',
|
name: 'allowance',
|
||||||
params: [signer.address, routerContract],
|
params: [signer.address, routerContract],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
/* eslint-enable prettier/prettier */
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isEth && denomination > ethBalance) {
|
if (isEth && denomination > ethBalance) {
|
||||||
@ -616,18 +623,36 @@ export function tornadoProgram() {
|
|||||||
|
|
||||||
const { note, noteHex, commitmentHex } = deposit;
|
const { note, noteHex, commitmentHex } = deposit;
|
||||||
|
|
||||||
|
const encryptedNote = noteAccount
|
||||||
|
? noteAccount.encryptNote({
|
||||||
|
address: instanceAddress,
|
||||||
|
noteHex,
|
||||||
|
})
|
||||||
|
: '0x';
|
||||||
|
|
||||||
|
const backupFile = `./backup-tornado-${currency}-${amount}-${netId}-${noteHex.slice(0, 10)}.txt`;
|
||||||
|
|
||||||
console.log(`New deposit: ${deposit.toString()}\n`);
|
console.log(`New deposit: ${deposit.toString()}\n`);
|
||||||
|
|
||||||
await writeFile(`./backup-tornado-${currency}-${amount}-${netId}-${noteHex.slice(0, 10)}.txt`, note, {
|
console.log(`Writing note backup at ${backupFile}\n`);
|
||||||
encoding: 'utf8',
|
|
||||||
});
|
await writeFile(backupFile, note, { encoding: 'utf8' });
|
||||||
|
|
||||||
|
if (encryptedNote !== '0x') {
|
||||||
|
console.log(`Storing encrypted note on-chain for backup (Account key: ${accountKey})\n`);
|
||||||
|
}
|
||||||
|
|
||||||
await programSendTransaction({
|
await programSendTransaction({
|
||||||
signer,
|
signer,
|
||||||
options,
|
options,
|
||||||
populatedTransaction: await TornadoProxy.deposit.populateTransaction(instanceAddress, commitmentHex, '0x', {
|
populatedTransaction: await TornadoProxy.deposit.populateTransaction(
|
||||||
value: isEth ? denomination : BigInt(0),
|
instanceAddress,
|
||||||
}),
|
commitmentHex,
|
||||||
|
encryptedNote,
|
||||||
|
{
|
||||||
|
value: isEth ? denomination : BigInt(0),
|
||||||
|
},
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
@ -689,22 +714,20 @@ export function tornadoProgram() {
|
|||||||
name: 'getEthBalance',
|
name: 'getEthBalance',
|
||||||
params: [signer.address],
|
params: [signer.address],
|
||||||
},
|
},
|
||||||
/* eslint-disable prettier/prettier */
|
|
||||||
...(!isEth
|
...(!isEth
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
contract: Token as ERC20,
|
contract: Token as ERC20,
|
||||||
name: 'balanceOf',
|
name: 'balanceOf',
|
||||||
params: [signer.address],
|
params: [signer.address],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
contract: Token as ERC20,
|
contract: Token as ERC20,
|
||||||
name: 'allowance',
|
name: 'allowance',
|
||||||
params: [signer.address, routerContract],
|
params: [signer.address, routerContract],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
/* eslint-enable prettier/prettier */
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (isEth && denomination > ethBalance) {
|
if (isEth && denomination > ethBalance) {
|
||||||
@ -923,15 +946,13 @@ export function tornadoProgram() {
|
|||||||
readFile(CIRCUIT_PATH, { encoding: 'utf8' }).then((s) => JSON.parse(s)),
|
readFile(CIRCUIT_PATH, { encoding: 'utf8' }).then((s) => JSON.parse(s)),
|
||||||
readFile(KEY_PATH).then((b) => new Uint8Array(b).buffer),
|
readFile(KEY_PATH).then((b) => new Uint8Array(b).buffer),
|
||||||
depositTreePromise,
|
depositTreePromise,
|
||||||
/* eslint-disable prettier/prettier */
|
|
||||||
!walletWithdrawal
|
!walletWithdrawal
|
||||||
? getProgramRelayer({
|
? getProgramRelayer({
|
||||||
options,
|
options,
|
||||||
fetchDataOptions,
|
fetchDataOptions,
|
||||||
netId,
|
netId,
|
||||||
}).then(({ relayerClient }) => relayerClient)
|
}).then(({ relayerClient }) => relayerClient)
|
||||||
: undefined,
|
: undefined,
|
||||||
/* eslint-enable prettier/prettier */
|
|
||||||
tornadoFeeOracle.fetchL1OptimismFee(),
|
tornadoFeeOracle.fetchL1OptimismFee(),
|
||||||
!isEth ? tokenPriceOracle.fetchPrices([tokenAddress as string]).then((p) => p[0]) : BigInt(0),
|
!isEth ? tokenPriceOracle.fetchPrices([tokenAddress as string]).then((p) => p[0]) : BigInt(0),
|
||||||
provider.getFeeData(),
|
provider.getFeeData(),
|
||||||
@ -1466,7 +1487,7 @@ export function tornadoProgram() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
program
|
program
|
||||||
.command('createNoteAccount')
|
.command('createAccount')
|
||||||
.description(
|
.description(
|
||||||
'Creates and save on-chain account that would store encrypted notes. \n\n' +
|
'Creates and save on-chain account that would store encrypted notes. \n\n' +
|
||||||
'Would first lookup on on-chain records to see if the notes are stored. \n\n' +
|
'Would first lookup on on-chain records to see if the notes are stored. \n\n' +
|
||||||
@ -1532,7 +1553,7 @@ export function tornadoProgram() {
|
|||||||
|
|
||||||
const userEvents = echoEvents.filter(({ address }) => address === signer.address);
|
const userEvents = echoEvents.filter(({ address }) => address === signer.address);
|
||||||
|
|
||||||
const existingAccounts = userEvents.map((e) => newAccount.decryptAccountWithWallet(signer, e));
|
const existingAccounts = newAccount.decryptAccountsWithWallet(signer, userEvents);
|
||||||
|
|
||||||
const accountsTable = new Table();
|
const accountsTable = new Table();
|
||||||
|
|
||||||
@ -1587,7 +1608,7 @@ export function tornadoProgram() {
|
|||||||
.argument('<netId>', 'Network Chain ID to connect with (see https://chainlist.org for examples)', parseNumber)
|
.argument('<netId>', 'Network Chain ID to connect with (see https://chainlist.org for examples)', parseNumber)
|
||||||
.argument(
|
.argument(
|
||||||
'[accountKey]',
|
'[accountKey]',
|
||||||
'Account key generated from UI or the createNoteAccount to store encrypted notes on-chain',
|
'Account key generated from UI or the createAccount to store encrypted notes on-chain',
|
||||||
parseRecoveryKey,
|
parseRecoveryKey,
|
||||||
)
|
)
|
||||||
.action(async (netId: string | number, accountKey: string | undefined, cmdOptions: commonProgramOptions) => {
|
.action(async (netId: string | number, accountKey: string | undefined, cmdOptions: commonProgramOptions) => {
|
||||||
@ -1614,7 +1635,7 @@ export function tornadoProgram() {
|
|||||||
|
|
||||||
if (!accountKey) {
|
if (!accountKey) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'No account key find! Please supply correct account key from either UI or find one with createNoteAccount command',
|
'No account key find! Please supply correct account key from either UI or find one with createAccount command',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1720,15 +1741,14 @@ export function tornadoProgram() {
|
|||||||
const txGasPrice = feeData.maxFeePerGas
|
const txGasPrice = feeData.maxFeePerGas
|
||||||
? feeData.maxFeePerGas + (feeData.maxPriorityFeePerGas || BigInt(0))
|
? feeData.maxFeePerGas + (feeData.maxPriorityFeePerGas || BigInt(0))
|
||||||
: feeData.gasPrice || BigInt(0);
|
: feeData.gasPrice || BigInt(0);
|
||||||
/* eslint-disable prettier/prettier */
|
|
||||||
const txFees = feeData.maxFeePerGas
|
const txFees = feeData.maxFeePerGas
|
||||||
? {
|
? {
|
||||||
maxFeePerGas: feeData.maxFeePerGas,
|
maxFeePerGas: feeData.maxFeePerGas,
|
||||||
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
maxPriorityFeePerGas: feeData.maxPriorityFeePerGas,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
gasPrice: feeData.gasPrice,
|
gasPrice: feeData.gasPrice,
|
||||||
};
|
};
|
||||||
|
|
||||||
let toSend: bigint;
|
let toSend: bigint;
|
||||||
|
|
||||||
@ -1764,10 +1784,10 @@ export function tornadoProgram() {
|
|||||||
...txFees,
|
...txFees,
|
||||||
});
|
});
|
||||||
|
|
||||||
const bumpedGas = (estimatedGas !== BigInt(21000) && signer.gasLimitBump
|
const bumpedGas =
|
||||||
? (estimatedGas * (BigInt(10000) + BigInt(signer.gasLimitBump))) / BigInt(10000)
|
estimatedGas !== BigInt(21000) && signer.gasLimitBump
|
||||||
: estimatedGas
|
? (estimatedGas * (BigInt(10000) + BigInt(signer.gasLimitBump))) / BigInt(10000)
|
||||||
);
|
: estimatedGas;
|
||||||
|
|
||||||
toSend = ethBalance - txGasPrice * bumpedGas;
|
toSend = ethBalance - txGasPrice * bumpedGas;
|
||||||
}
|
}
|
||||||
@ -1779,15 +1799,14 @@ export function tornadoProgram() {
|
|||||||
populatedTransaction: tokenAddress
|
populatedTransaction: tokenAddress
|
||||||
? await Token.transfer.populateTransaction(to, toSend)
|
? await Token.transfer.populateTransaction(to, toSend)
|
||||||
: await signer.populateTransaction({
|
: await signer.populateTransaction({
|
||||||
type: txType,
|
type: txType,
|
||||||
from: signer.address,
|
from: signer.address,
|
||||||
to,
|
to,
|
||||||
value: toSend,
|
value: toSend,
|
||||||
nonce,
|
nonce,
|
||||||
...txFees,
|
...txFees,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
/* eslint-enable prettier/prettier */
|
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
},
|
},
|
||||||
@ -1891,7 +1910,6 @@ export function tornadoProgram() {
|
|||||||
options,
|
options,
|
||||||
populatedTransaction: deserializedTx,
|
populatedTransaction: deserializedTx,
|
||||||
});
|
});
|
||||||
/* eslint-enable prettier/prettier */
|
|
||||||
|
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
});
|
});
|
||||||
@ -1924,14 +1942,24 @@ export function tornadoProgram() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// common options
|
// common options
|
||||||
/* eslint-disable prettier/prettier */
|
|
||||||
program.commands.forEach((cmd) => {
|
program.commands.forEach((cmd) => {
|
||||||
cmd.option('-r, --rpc <RPC_URL>', 'The RPC that CLI should interact with', parseUrl);
|
cmd.option('-r, --rpc <RPC_URL>', 'The RPC that CLI should interact with', parseUrl);
|
||||||
cmd.option('-e, --eth-rpc <ETHRPC_URL>', 'The Ethereum Mainnet RPC that CLI should interact with', parseUrl);
|
cmd.option('-e, --eth-rpc <ETHRPC_URL>', 'The Ethereum Mainnet RPC that CLI should interact with', parseUrl);
|
||||||
cmd.option('-g, --graph <GRAPH_URL>', 'The Subgraph API that CLI should interact with', parseUrl);
|
cmd.option('-g, --graph <GRAPH_URL>', 'The Subgraph API that CLI should interact with', parseUrl);
|
||||||
cmd.option('-G, --eth-graph <ETHGRAPH_URL>', 'The Ethereum Mainnet Subgraph API that CLI should interact with', parseUrl);
|
cmd.option(
|
||||||
cmd.option('-d, --disable-graph', 'Disable Graph API - Does not enable Subgraph API and use only local RPC as an event source');
|
'-G, --eth-graph <ETHGRAPH_URL>',
|
||||||
cmd.option('-a, --account-key <ACCOUNT_KEY>', 'Account key generated from UI or the createNoteAccount to store encrypted notes on-chain', parseRecoveryKey);
|
'The Ethereum Mainnet Subgraph API that CLI should interact with',
|
||||||
|
parseUrl,
|
||||||
|
);
|
||||||
|
cmd.option(
|
||||||
|
'-d, --disable-graph',
|
||||||
|
'Disable Graph API - Does not enable Subgraph API and use only local RPC as an event source',
|
||||||
|
);
|
||||||
|
cmd.option(
|
||||||
|
'-a, --account-key <ACCOUNT_KEY>',
|
||||||
|
'Account key generated from UI or the createAccount to store encrypted notes on-chain',
|
||||||
|
parseRecoveryKey,
|
||||||
|
);
|
||||||
cmd.option('-R, --relayer <RELAYER>', 'Withdraw via relayer (Should be either .eth name or URL)', parseRelayer);
|
cmd.option('-R, --relayer <RELAYER>', 'Withdraw via relayer (Should be either .eth name or URL)', parseRelayer);
|
||||||
cmd.option('-w, --wallet-withdrawal', 'Withdrawal via wallet (Should not be linked with deposits)');
|
cmd.option('-w, --wallet-withdrawal', 'Withdrawal via wallet (Should not be linked with deposits)');
|
||||||
cmd.option('-T, --tor-port <TOR_PORT>', 'Optional tor port', parseNumber);
|
cmd.option('-T, --tor-port <TOR_PORT>', 'Optional tor port', parseNumber);
|
||||||
@ -1943,13 +1971,13 @@ export function tornadoProgram() {
|
|||||||
);
|
);
|
||||||
cmd.option(
|
cmd.option(
|
||||||
'-m, --mnemonic <MNEMONIC>',
|
'-m, --mnemonic <MNEMONIC>',
|
||||||
'Wallet BIP39 Mnemonic Phrase - If you didn\'t add it to .env file and it is needed for operation',
|
'Wallet BIP39 Mnemonic Phrase - If you did not add it to .env file and it is needed for operation',
|
||||||
parseMnemonic,
|
parseMnemonic,
|
||||||
);
|
);
|
||||||
cmd.option('-i, --mnemonic-index <MNEMONIC_INDEX>', 'Optional wallet mnemonic index', parseNumber);
|
cmd.option('-i, --mnemonic-index <MNEMONIC_INDEX>', 'Optional wallet mnemonic index', parseNumber);
|
||||||
cmd.option(
|
cmd.option(
|
||||||
'-p, --private-key <PRIVATE_KEY>',
|
'-p, --private-key <PRIVATE_KEY>',
|
||||||
'Wallet private key - If you didn\'t add it to .env file and it is needed for operation',
|
'Wallet private key - If you did not add it to .env file and it is needed for operation',
|
||||||
parseKey,
|
parseKey,
|
||||||
);
|
);
|
||||||
cmd.option(
|
cmd.option(
|
||||||
@ -1958,7 +1986,6 @@ export function tornadoProgram() {
|
|||||||
);
|
);
|
||||||
cmd.option('-l, --local-rpc', 'Local node mode - Does not submit signed transaction to the node');
|
cmd.option('-l, --local-rpc', 'Local node mode - Does not submit signed transaction to the node');
|
||||||
});
|
});
|
||||||
/* eslint-enable prettier/prettier */
|
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,11 @@ import { Wallet, computeAddress } from 'ethers';
|
|||||||
import { crypto, base64ToBytes, bytesToBase64, bytesToHex, hexToBytes, toFixedHex, concatBytes } from './utils';
|
import { crypto, base64ToBytes, bytesToBase64, bytesToHex, hexToBytes, toFixedHex, concatBytes } from './utils';
|
||||||
import { EchoEvents, EncryptedNotesEvents } from './events';
|
import { EchoEvents, EncryptedNotesEvents } from './events';
|
||||||
|
|
||||||
|
export interface NoteToEncrypt {
|
||||||
|
address: string;
|
||||||
|
noteHex: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DecryptedNotes {
|
export interface DecryptedNotes {
|
||||||
blockNumber: number;
|
blockNumber: number;
|
||||||
address: string;
|
address: string;
|
||||||
@ -110,26 +115,39 @@ export class NoteAccount {
|
|||||||
/**
|
/**
|
||||||
* Decrypt Echoer backuped note encryption account with private keys
|
* Decrypt Echoer backuped note encryption account with private keys
|
||||||
*/
|
*/
|
||||||
decryptAccountWithWallet(wallet: Wallet, event: EchoEvents): NoteAccount {
|
decryptAccountsWithWallet(wallet: Wallet, events: EchoEvents[]): NoteAccount[] {
|
||||||
let { privateKey } = wallet;
|
let { privateKey } = wallet;
|
||||||
|
|
||||||
if (privateKey.startsWith('0x')) {
|
if (privateKey.startsWith('0x')) {
|
||||||
privateKey = privateKey.replace('0x', '');
|
privateKey = privateKey.replace('0x', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
const unpackedMessage = unpackEncryptedMessage(event.encryptedAccount);
|
const decryptedEvents = [];
|
||||||
|
|
||||||
const recoveryKey = decrypt({
|
for (const event of events) {
|
||||||
encryptedData: unpackedMessage,
|
try {
|
||||||
privateKey,
|
const unpackedMessage = unpackEncryptedMessage(event.encryptedAccount);
|
||||||
});
|
|
||||||
|
|
||||||
return new NoteAccount({
|
const recoveryKey = decrypt({
|
||||||
netId: this.netId,
|
encryptedData: unpackedMessage,
|
||||||
blockNumber: event.blockNumber,
|
privateKey,
|
||||||
recoveryKey,
|
});
|
||||||
Echoer: this.Echoer,
|
|
||||||
});
|
decryptedEvents.push(
|
||||||
|
new NoteAccount({
|
||||||
|
netId: this.netId,
|
||||||
|
blockNumber: event.blockNumber,
|
||||||
|
recoveryKey,
|
||||||
|
Echoer: this.Echoer,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
// decryption may fail for invalid accounts
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return decryptedEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
decryptNotes(events: EncryptedNotesEvents[]): DecryptedNotes[] {
|
decryptNotes(events: EncryptedNotesEvents[]): DecryptedNotes[] {
|
||||||
@ -157,4 +175,14 @@ export class NoteAccount {
|
|||||||
|
|
||||||
return decryptedEvents;
|
return decryptedEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
encryptNote({ address, noteHex }: NoteToEncrypt) {
|
||||||
|
const encryptedData = encrypt({
|
||||||
|
publicKey: this.recoveryPublicKey,
|
||||||
|
data: `${address}-${noteHex}`,
|
||||||
|
version: 'x25519-xsalsa20-poly1305',
|
||||||
|
});
|
||||||
|
|
||||||
|
return packEncryptedMessage(encryptedData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import type { DepositsEvents } from './events';
|
|||||||
|
|
||||||
export type MerkleTreeConstructor = DepositType & {
|
export type MerkleTreeConstructor = DepositType & {
|
||||||
Tornado: Tornado;
|
Tornado: Tornado;
|
||||||
commitment?: string;
|
commitmentHex?: string;
|
||||||
merkleTreeHeight?: number;
|
merkleTreeHeight?: number;
|
||||||
emptyElement?: string;
|
emptyElement?: string;
|
||||||
merkleWorkerPath?: string;
|
merkleWorkerPath?: string;
|
||||||
@ -19,7 +19,7 @@ export class MerkleTreeService {
|
|||||||
amount: string;
|
amount: string;
|
||||||
netId: number;
|
netId: number;
|
||||||
Tornado: Tornado;
|
Tornado: Tornado;
|
||||||
commitment?: string;
|
commitmentHex?: string;
|
||||||
instanceName: string;
|
instanceName: string;
|
||||||
|
|
||||||
merkleTreeHeight: number;
|
merkleTreeHeight: number;
|
||||||
@ -32,7 +32,7 @@ export class MerkleTreeService {
|
|||||||
amount,
|
amount,
|
||||||
currency,
|
currency,
|
||||||
Tornado,
|
Tornado,
|
||||||
commitment,
|
commitmentHex,
|
||||||
merkleTreeHeight = 20,
|
merkleTreeHeight = 20,
|
||||||
emptyElement = '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
emptyElement = '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||||
merkleWorkerPath,
|
merkleWorkerPath,
|
||||||
@ -45,7 +45,7 @@ export class MerkleTreeService {
|
|||||||
|
|
||||||
this.Tornado = Tornado;
|
this.Tornado = Tornado;
|
||||||
this.instanceName = instanceName;
|
this.instanceName = instanceName;
|
||||||
this.commitment = commitment;
|
this.commitmentHex = commitmentHex;
|
||||||
|
|
||||||
this.merkleTreeHeight = merkleTreeHeight;
|
this.merkleTreeHeight = merkleTreeHeight;
|
||||||
this.emptyElement = emptyElement;
|
this.emptyElement = emptyElement;
|
||||||
|
@ -213,47 +213,47 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
|
|||||||
throw errorObject;
|
throw errorObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* eslint-disable prettier/prettier, @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
export const fetchGetUrlFunc =
|
export const fetchGetUrlFunc =
|
||||||
(options: fetchDataOptions = {}): FetchGetUrlFunc =>
|
(options: fetchDataOptions = {}): FetchGetUrlFunc =>
|
||||||
async (req, _signal) => {
|
async (req, _signal) => {
|
||||||
let signal;
|
let signal;
|
||||||
|
|
||||||
if (_signal) {
|
if (_signal) {
|
||||||
const controller = new AbortController();
|
const controller = new AbortController();
|
||||||
signal = controller.signal;
|
signal = controller.signal;
|
||||||
_signal.addListener(() => {
|
_signal.addListener(() => {
|
||||||
controller.abort();
|
controller.abort();
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const init = {
|
|
||||||
...options,
|
|
||||||
method: req.method || 'POST',
|
|
||||||
headers: req.headers,
|
|
||||||
body: req.body || undefined,
|
|
||||||
signal,
|
|
||||||
returnResponse: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const resp = await fetchData(req.url, init);
|
|
||||||
|
|
||||||
const headers = {} as { [key in string]: any };
|
|
||||||
resp.headers.forEach((value: any, key: string) => {
|
|
||||||
headers[key.toLowerCase()] = value;
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const respBody = await resp.arrayBuffer();
|
const init = {
|
||||||
const body = respBody == null ? null : new Uint8Array(respBody);
|
...options,
|
||||||
|
method: req.method || 'POST',
|
||||||
return {
|
headers: req.headers,
|
||||||
statusCode: resp.status,
|
body: req.body || undefined,
|
||||||
statusMessage: resp.statusText,
|
signal,
|
||||||
headers,
|
returnResponse: true,
|
||||||
body,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
/* eslint-enable prettier/prettier, @typescript-eslint/no-explicit-any */
|
|
||||||
|
const resp = await fetchData(req.url, init);
|
||||||
|
|
||||||
|
const headers = {} as { [key in string]: any };
|
||||||
|
resp.headers.forEach((value: any, key: string) => {
|
||||||
|
headers[key.toLowerCase()] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const respBody = await resp.arrayBuffer();
|
||||||
|
const body = respBody == null ? null : new Uint8Array(respBody);
|
||||||
|
|
||||||
|
return {
|
||||||
|
statusCode: resp.status,
|
||||||
|
statusMessage: resp.statusText,
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* eslint-enable @typescript-eslint/no-explicit-any */
|
||||||
|
|
||||||
// caching to improve performance
|
// caching to improve performance
|
||||||
const oracleMapper = new Map();
|
const oracleMapper = new Map();
|
||||||
|
Loading…
Reference in New Issue
Block a user