Improve networkConfig and added more relayer data

This commit is contained in:
Tornado Contrib 2024-04-26 22:22:46 +00:00
parent 3312f44a4d
commit 183dc5ca60
Signed by: tornadocontrib
GPG Key ID: 60B4DF1A076C64B1
8 changed files with 87 additions and 79 deletions

@ -24,7 +24,7 @@
"depositInvoice": "ts-node src/cli.ts depositInvoice", "depositInvoice": "ts-node src/cli.ts depositInvoice",
"withdraw": "ts-node src/cli.ts withdraw", "withdraw": "ts-node src/cli.ts withdraw",
"compliance": "ts-node src/cli.ts compliance", "compliance": "ts-node src/cli.ts compliance",
"syncEvents": "ts-node src/cli.ts syncEvents", "updateEvents": "ts-node src/cli.ts updateEvents",
"relayers": "ts-node src/cli.ts relayers", "relayers": "ts-node src/cli.ts relayers",
"createAccount": "ts-node src/cli.ts createAccount", "createAccount": "ts-node src/cli.ts createAccount",
"decryptNotes": "ts-node src/cli.ts decryptNotes", "decryptNotes": "ts-node src/cli.ts decryptNotes",

@ -29,6 +29,7 @@ import {
MaxUint256, MaxUint256,
Transaction, Transaction,
BigNumberish, BigNumberish,
getAddress,
} from 'ethers'; } from 'ethers';
import type MerkleTree from '@tornado/fixed-merkle-tree'; import type MerkleTree from '@tornado/fixed-merkle-tree';
import * as packageJson from '../package.json'; import * as packageJson from '../package.json';
@ -80,6 +81,7 @@ import {
substring, substring,
NoteAccount, NoteAccount,
parseRecoveryKey, parseRecoveryKey,
getSupportedInstances,
} from './services'; } from './services';
const DEFAULT_GAS_LIMIT = 600_000; const DEFAULT_GAS_LIMIT = 600_000;
@ -327,7 +329,11 @@ export async function getProgramRelayer({
relayerClient.selectedRelayer = { relayerClient.selectedRelayer = {
netId: relayerStatus.netId, netId: relayerStatus.netId,
url: relayerStatus.url, url: relayerStatus.url,
rewardAccount: relayerStatus.rewardAccount, hostname: new URL(relayerStatus.url).hostname,
rewardAccount: getAddress(relayerStatus.rewardAccount),
instances: getSupportedInstances(relayerStatus.instances),
gasPrice: relayerStatus.gasPrices?.fast,
ethPrices: relayerStatus.ethPrices,
currentQueue: relayerStatus.currentQueue, currentQueue: relayerStatus.currentQueue,
tornadoServiceFee: relayerStatus.tornadoServiceFee, tornadoServiceFee: relayerStatus.tornadoServiceFee,
}; };
@ -343,13 +349,7 @@ export async function getProgramRelayer({
const relayerStatus = validRelayers[0]; const relayerStatus = validRelayers[0];
if (relayerStatus) { if (relayerStatus) {
relayerClient.selectedRelayer = { relayerClient.selectedRelayer = relayerStatus;
netId: relayerStatus.netId,
url: relayerStatus.url,
rewardAccount: relayerStatus.rewardAccount,
currentQueue: relayerStatus.currentQueue,
tornadoServiceFee: relayerStatus.tornadoServiceFee,
};
} }
return { return {
@ -370,13 +370,7 @@ export async function getProgramRelayer({
const relayerStatus = relayerClient.pickWeightedRandomRelayer(validRelayers); const relayerStatus = relayerClient.pickWeightedRandomRelayer(validRelayers);
if (relayerStatus) { if (relayerStatus) {
relayerClient.selectedRelayer = { relayerClient.selectedRelayer = relayerStatus;
netId: relayerStatus.netId,
url: relayerStatus.url,
rewardAccount: relayerStatus.rewardAccount,
currentQueue: relayerStatus.currentQueue,
tornadoServiceFee: relayerStatus.tornadoServiceFee,
};
} }
return { return {
@ -529,7 +523,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`]; const config = networkConfig[`netId${netId}`];
const { const {
multicall: multicallAddress, multicallContract,
routerContract, routerContract,
echoContract, echoContract,
nativeCurrency, nativeCurrency,
@ -569,7 +563,7 @@ export function tornadoProgram() {
} }
const TornadoProxy = TornadoRouter__factory.connect(routerContract, signer); const TornadoProxy = TornadoRouter__factory.connect(routerContract, signer);
const Multicall = Multicall__factory.connect(multicallAddress, provider); const Multicall = Multicall__factory.connect(multicallContract, provider);
const Token = tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined; const Token = tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined;
const [ethBalance, tokenBalance, tokenApprovals] = await multicall(Multicall, [ const [ethBalance, tokenBalance, tokenApprovals] = await multicall(Multicall, [
@ -674,7 +668,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`]; const config = networkConfig[`netId${netId}`];
const { const {
multicall: multicallAddress, multicallContract,
routerContract, routerContract,
nativeCurrency, nativeCurrency,
tokens: { [currency]: currencyConfig }, tokens: { [currency]: currencyConfig },
@ -705,7 +699,7 @@ export function tornadoProgram() {
} }
const TornadoProxy = TornadoRouter__factory.connect(routerContract, signer); const TornadoProxy = TornadoRouter__factory.connect(routerContract, signer);
const Multicall = Multicall__factory.connect(multicallAddress, provider); const Multicall = Multicall__factory.connect(multicallContract, provider);
const Token = tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined; const Token = tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined;
const [ethBalance, tokenBalance, tokenApprovals] = await multicall(Multicall, [ const [ethBalance, tokenBalance, tokenApprovals] = await multicall(Multicall, [
@ -792,8 +786,8 @@ export function tornadoProgram() {
tornadoSubgraph, tornadoSubgraph,
deployedBlock, deployedBlock,
nativeCurrency, nativeCurrency,
multicallContract,
routerContract, routerContract,
multicall: multicallAddress,
ovmGasPriceOracleContract, ovmGasPriceOracleContract,
tokens: { [currency]: currencyConfig }, tokens: { [currency]: currencyConfig },
} = config; } = config;
@ -829,7 +823,7 @@ export function tornadoProgram() {
const Tornado = Tornado__factory.connect(instanceAddress, provider); const Tornado = Tornado__factory.connect(instanceAddress, provider);
const TornadoProxy = TornadoRouter__factory.connect(routerContract, !walletWithdrawal ? provider : signer); const TornadoProxy = TornadoRouter__factory.connect(routerContract, !walletWithdrawal ? provider : signer);
const Multicall = Multicall__factory.connect(multicallAddress, provider); const Multicall = Multicall__factory.connect(multicallContract, provider);
const tornadoFeeOracle = new TornadoFeeOracle( const tornadoFeeOracle = new TornadoFeeOracle(
ovmGasPriceOracleContract ovmGasPriceOracleContract
@ -1263,7 +1257,7 @@ export function tornadoProgram() {
}); });
program program
.command('syncEvents') .command('updateEvents')
.description('Sync the local cache file of tornado cash events.\n\n') .description('Sync the local cache file of tornado cash events.\n\n')
.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('[currency]', 'Currency to sync events') .argument('[currency]', 'Currency to sync events')
@ -1287,7 +1281,7 @@ export function tornadoProgram() {
routerContract, routerContract,
echoContract, echoContract,
registryContract, registryContract,
['governance.contract.tornadocash.eth']: governanceContract, governanceContract,
deployedBlock, deployedBlock,
constants: { GOVERNANCE_BLOCK, REGISTRY_BLOCK, NOTE_ACCOUNT_BLOCK, ENCRYPTED_NOTES_BLOCK }, constants: { GOVERNANCE_BLOCK, REGISTRY_BLOCK, NOTE_ACCOUNT_BLOCK, ENCRYPTED_NOTES_BLOCK },
} = config; } = config;
@ -1440,6 +1434,8 @@ export function tornadoProgram() {
const validRelayers = allRelayers.validRelayers as RelayerInfo[]; const validRelayers = allRelayers.validRelayers as RelayerInfo[];
const invalidRelayers = allRelayers.invalidRelayers as RelayerError[]; const invalidRelayers = allRelayers.invalidRelayers as RelayerError[];
console.log(validRelayers);
const relayersTable = new Table(); const relayersTable = new Table();
relayersTable.push( relayersTable.push(
@ -1699,7 +1695,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`]; const config = networkConfig[`netId${netId}`];
const { currencyName, multicall: multicallAddress } = config; const { currencyName, multicallContract } = config;
const provider = getProgramProvider(netId, rpc, config, { const provider = getProgramProvider(netId, rpc, config, {
...fetchDataOptions, ...fetchDataOptions,
@ -1715,7 +1711,7 @@ export function tornadoProgram() {
const tokenAddress = tokenArgs ? parseAddress(tokenArgs) : tokenOpts; const tokenAddress = tokenArgs ? parseAddress(tokenArgs) : tokenOpts;
const Multicall = Multicall__factory.connect(multicallAddress, provider); const Multicall = Multicall__factory.connect(multicallContract, provider);
const Token = (tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined) as ERC20; const Token = (tokenAddress ? ERC20__factory.connect(tokenAddress, signer) : undefined) as ERC20;
// Fetching feeData or nonce is unnecessary however we do this to estimate transfer amounts // Fetching feeData or nonce is unnecessary however we do this to estimate transfer amounts
@ -1775,6 +1771,11 @@ export function tornadoProgram() {
const initCost = txGasPrice * BigInt('400000'); const initCost = txGasPrice * BigInt('400000');
toSend = ethBalance - initCost; toSend = ethBalance - initCost;
if (ethBalance === BigInt(0) || ethBalance < initCost) {
const errMsg = `Invalid ${currencyName} balance, wants ${formatEther(initCost)} have ${formatEther(ethBalance)}`;
throw new Error(errMsg);
}
const estimatedGas = await provider.estimateGas({ const estimatedGas = await provider.estimateGas({
type: txType, type: txType,
from: signer.address, from: signer.address,
@ -1830,12 +1831,7 @@ export function tornadoProgram() {
const config = networkConfig[`netId${netId}`]; const config = networkConfig[`netId${netId}`];
const { const { currencyName, multicallContract, tornContract, tokens } = config;
currencyName,
multicall: multicallAddress,
['torn.contract.tornadocash.eth']: tornTokenAddress,
tokens,
} = config;
const provider = getProgramProvider(netId, rpc, config, { const provider = getProgramProvider(netId, rpc, config, {
...fetchDataOptions, ...fetchDataOptions,
@ -1848,14 +1844,14 @@ export function tornadoProgram() {
throw new Error('Address is required however no user address is supplied'); throw new Error('Address is required however no user address is supplied');
} }
const Multicall = Multicall__factory.connect(multicallAddress, provider); const Multicall = Multicall__factory.connect(multicallContract, provider);
const tokenAddresses = Object.values(tokens) const tokenAddresses = Object.values(tokens)
.map(({ tokenAddress }) => tokenAddress) .map(({ tokenAddress }) => tokenAddress)
.filter((t) => t) as string[]; .filter((t) => t) as string[];
if (tornTokenAddress) { if (tornContract) {
tokenAddresses.push(tornTokenAddress); tokenAddresses.push(tornContract);
} }
const tokenBalances = await getTokenBalances({ const tokenBalances = await getTokenBalances({

@ -1,6 +1,6 @@
import { getEncryptionPublicKey, encrypt, decrypt, EthEncryptedData } from '@metamask/eth-sig-util'; import { getEncryptionPublicKey, encrypt, decrypt, EthEncryptedData } from '@metamask/eth-sig-util';
import { Echoer } from '@tornado/contracts'; import { Echoer } from '@tornado/contracts';
import { Wallet, computeAddress } from 'ethers'; import { Wallet, computeAddress, getAddress } 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';
@ -164,7 +164,7 @@ export class NoteAccount {
decryptedEvents.push({ decryptedEvents.push({
blockNumber: event.blockNumber, blockNumber: event.blockNumber,
address, address: getAddress(address),
noteHex, noteHex,
}); });
} catch { } catch {

@ -645,7 +645,7 @@ export async function getNoteAccounts({
subgraphName, subgraphName,
query: GET_NOTE_ACCOUNTS, query: GET_NOTE_ACCOUNTS,
variables: { variables: {
address, address: address.toLowerCase(),
}, },
fetchDataOptions, fetchDataOptions,
}); });

@ -119,7 +119,7 @@ export class MerkleTreeService {
); );
console.time('Created tree in'); console.time('Created tree in');
const tree = await this.createTree(events.map(({ commitment }) => BigInt(commitment).toString())); const tree = await this.createTree(events.map(({ commitment }) => commitment));
console.timeEnd('Created tree in'); console.timeEnd('Created tree in');
console.log(''); console.log('');

@ -56,8 +56,11 @@ export type Config = {
networkName: string; networkName: string;
deployedBlock: number; deployedBlock: number;
rpcUrls: RpcUrls; rpcUrls: RpcUrls;
multicall: string; multicallContract: string;
routerContract: string; routerContract: string;
tornContract?: string;
governanceContract?: string;
stakingRewardsContract?: string;
registryContract?: string; registryContract?: string;
echoContract: string; echoContract: string;
aggregatorContract?: string; aggregatorContract?: string;
@ -81,11 +84,6 @@ export type Config = {
// Should be in seconds // Should be in seconds
MINING_BLOCK_TIME?: number; MINING_BLOCK_TIME?: number;
}; };
'torn.contract.tornadocash.eth'?: string;
'governance.contract.tornadocash.eth'?: string;
'staking-rewards.contract.tornadocash.eth'?: string;
'tornado-router.contract.tornadocash.eth'?: string;
'tornado-proxy-light.contract.tornadocash.eth'?: string;
}; };
export type networkConfig = { export type networkConfig = {
@ -145,7 +143,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com', url: 'https://tornadocash-rpc.com',
}, },
chainnodes: { chainnodes: {
name: 'Tornado RPC', name: 'Chainnodes RPC',
url: 'https://mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607', url: 'https://mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
}, },
mevblockerRPC: { mevblockerRPC: {
@ -173,8 +171,11 @@ export const networkConfig: networkConfig = {
url: 'https://1rpc.io/eth', url: 'https://1rpc.io/eth',
}, },
}, },
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b', routerContract: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
tornContract: '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
governanceContract: '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
stakingRewardsContract: '0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29',
registryContract: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2', registryContract: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2',
echoContract: '0x9B27DD5Bb15d42DC224FCD0B7caEbBe16161Df42', echoContract: '0x9B27DD5Bb15d42DC224FCD0B7caEbBe16161Df42',
aggregatorContract: '0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49', aggregatorContract: '0xE8F47A78A6D52D317D0D2FFFac56739fE14D1b49',
@ -262,14 +263,10 @@ export const networkConfig: networkConfig = {
constants: { constants: {
GOVERNANCE_BLOCK: 11474695, GOVERNANCE_BLOCK: 11474695,
NOTE_ACCOUNT_BLOCK: 11842486, NOTE_ACCOUNT_BLOCK: 11842486,
ENCRYPTED_NOTES_BLOCK: 14248730, ENCRYPTED_NOTES_BLOCK: 12143762,
REGISTRY_BLOCK: 14173129, REGISTRY_BLOCK: 14173129,
MINING_BLOCK_TIME: 15, MINING_BLOCK_TIME: 15,
}, },
'torn.contract.tornadocash.eth': '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
'governance.contract.tornadocash.eth': '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
'tornado-router.contract.tornadocash.eth': '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
'staking-rewards.contract.tornadocash.eth': '0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29',
}, },
netId56: { netId56: {
rpcCallRetryAttempt: 15, rpcCallRetryAttempt: 15,
@ -290,7 +287,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Binance Smart Chain', networkName: 'Binance Smart Chain',
deployedBlock: 8158799, deployedBlock: 8158799,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17', routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/bsc-tornado-subgraph', tornadoSubgraph: 'tornadocash/bsc-tornado-subgraph',
@ -304,7 +301,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/bsc', url: 'https://tornadocash-rpc.com/bsc',
}, },
chainnodes: { chainnodes: {
name: 'Tornado RPC', name: 'Chainnodes RPC',
url: 'https://bsc-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607', url: 'https://bsc-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
}, },
stackup: { stackup: {
@ -338,7 +335,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 8159269, NOTE_ACCOUNT_BLOCK: 8159269,
ENCRYPTED_NOTES_BLOCK: 8159269, ENCRYPTED_NOTES_BLOCK: 8159269,
}, },
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
}, },
netId137: { netId137: {
rpcCallRetryAttempt: 15, rpcCallRetryAttempt: 15,
@ -359,7 +355,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Polygon (Matic) Network', networkName: 'Polygon (Matic) Network',
deployedBlock: 16257962, deployedBlock: 16257962,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17', routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
gasPriceOracleContract: '0xF81A8D8D3581985D3969fe53bFA67074aDFa8F3C', gasPriceOracleContract: '0xF81A8D8D3581985D3969fe53bFA67074aDFa8F3C',
@ -400,7 +396,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 16257996, NOTE_ACCOUNT_BLOCK: 16257996,
ENCRYPTED_NOTES_BLOCK: 16257996, ENCRYPTED_NOTES_BLOCK: 16257996,
}, },
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
}, },
netId10: { netId10: {
rpcCallRetryAttempt: 15, rpcCallRetryAttempt: 15,
@ -421,7 +416,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Optimism', networkName: 'Optimism',
deployedBlock: 2243689, deployedBlock: 2243689,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17', routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F', ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
@ -436,7 +431,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/op', url: 'https://tornadocash-rpc.com/op',
}, },
chainnodes: { chainnodes: {
name: 'Tornado RPC', name: 'Chainnodes RPC',
url: 'https://optimism-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607', url: 'https://optimism-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
}, },
optimism: { optimism: {
@ -470,7 +465,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 2243694, NOTE_ACCOUNT_BLOCK: 2243694,
ENCRYPTED_NOTES_BLOCK: 2243694, ENCRYPTED_NOTES_BLOCK: 2243694,
}, },
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
}, },
netId42161: { netId42161: {
rpcCallRetryAttempt: 15, rpcCallRetryAttempt: 15,
@ -491,7 +485,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Arbitrum One', networkName: 'Arbitrum One',
deployedBlock: 3430648, deployedBlock: 3430648,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17', routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/arbitrum-tornado-subgraph', tornadoSubgraph: 'tornadocash/arbitrum-tornado-subgraph',
@ -505,7 +499,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/arbitrum', url: 'https://tornadocash-rpc.com/arbitrum',
}, },
chainnodes: { chainnodes: {
name: 'Tornado RPC', name: 'Chainnodes RPC',
url: 'https://arbitrum-one.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607', url: 'https://arbitrum-one.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
}, },
arbitrum: { arbitrum: {
@ -539,7 +533,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 3430605, NOTE_ACCOUNT_BLOCK: 3430605,
ENCRYPTED_NOTES_BLOCK: 3430605, ENCRYPTED_NOTES_BLOCK: 3430605,
}, },
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
}, },
netId100: { netId100: {
rpcCallRetryAttempt: 15, rpcCallRetryAttempt: 15,
@ -560,7 +553,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Gnosis Chain', networkName: 'Gnosis Chain',
deployedBlock: 17754561, deployedBlock: 17754561,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17', routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/xdai-tornado-subgraph', tornadoSubgraph: 'tornadocash/xdai-tornado-subgraph',
@ -574,7 +567,7 @@ export const networkConfig: networkConfig = {
url: 'https://tornadocash-rpc.com/gnosis', url: 'https://tornadocash-rpc.com/gnosis',
}, },
chainnodes: { chainnodes: {
name: 'Tornado RPC', name: 'Chainnodes RPC',
url: 'https://gnosis-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607', url: 'https://gnosis-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607',
}, },
gnosis: { gnosis: {
@ -608,7 +601,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 17754564, NOTE_ACCOUNT_BLOCK: 17754564,
ENCRYPTED_NOTES_BLOCK: 17754564, ENCRYPTED_NOTES_BLOCK: 17754564,
}, },
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
}, },
netId43114: { netId43114: {
rpcCallRetryAttempt: 15, rpcCallRetryAttempt: 15,
@ -629,7 +621,7 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Avalanche Mainnet', networkName: 'Avalanche Mainnet',
deployedBlock: 4429818, deployedBlock: 4429818,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17', routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
tornadoSubgraph: 'tornadocash/avalanche-tornado-subgraph', tornadoSubgraph: 'tornadocash/avalanche-tornado-subgraph',
@ -667,7 +659,6 @@ export const networkConfig: networkConfig = {
NOTE_ACCOUNT_BLOCK: 4429813, NOTE_ACCOUNT_BLOCK: 4429813,
ENCRYPTED_NOTES_BLOCK: 4429813, ENCRYPTED_NOTES_BLOCK: 4429813,
}, },
'tornado-proxy-light.contract.tornadocash.eth': '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
}, },
netId11155111: { netId11155111: {
rpcCallRetryAttempt: 15, rpcCallRetryAttempt: 15,
@ -688,8 +679,11 @@ export const networkConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292', emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Ethereum Sepolia', networkName: 'Ethereum Sepolia',
deployedBlock: 5594395, deployedBlock: 5594395,
multicall: '0xcA11bde05977b3631167028862bE2a173976CA11', multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee', routerContract: '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee',
tornContract: '0x3AE6667167C0f44394106E197904519D808323cA',
governanceContract: '0xe5324cD7602eeb387418e594B87aCADee08aeCAD',
stakingRewardsContract: '0x6d0018890751Efd31feb8166711B16732E2b496b',
registryContract: '0x1428e5d2356b13778A13108b10c440C83011dfB8', registryContract: '0x1428e5d2356b13778A13108b10c440C83011dfB8',
echoContract: '0xcDD1fc3F5ac2782D83449d3AbE80D6b7B273B0e5', echoContract: '0xcDD1fc3F5ac2782D83449d3AbE80D6b7B273B0e5',
aggregatorContract: '0x4088712AC9fad39ea133cdb9130E465d235e9642', aggregatorContract: '0x4088712AC9fad39ea133cdb9130E465d235e9642',
@ -745,9 +739,6 @@ export const networkConfig: networkConfig = {
ENCRYPTED_NOTES_BLOCK: 5594395, ENCRYPTED_NOTES_BLOCK: 5594395,
MINING_BLOCK_TIME: 15, MINING_BLOCK_TIME: 15,
}, },
'torn.contract.tornadocash.eth': '0x3AE6667167C0f44394106E197904519D808323cA',
'governance.contract.tornadocash.eth': '0xe5324cD7602eeb387418e594B87aCADee08aeCAD',
'tornado-router.contract.tornadocash.eth': '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee',
}, },
}; };

@ -1,4 +1,4 @@
import { namehash, parseEther } from 'ethers'; import { getAddress, namehash, parseEther } from 'ethers';
import type { Aggregator } from '@tornado/contracts'; import type { Aggregator } from '@tornado/contracts';
import type { RelayerStructOutput } from '@tornado/contracts/dist/contracts/Governance/Aggregator/Aggregator'; import type { RelayerStructOutput } from '@tornado/contracts/dist/contracts/Governance/Aggregator/Aggregator';
import { sleep } from './utils'; import { sleep } from './utils';
@ -17,19 +17,21 @@ export interface RelayerParams {
export interface Relayer { export interface Relayer {
netId: number; netId: number;
url: string; url: string;
hostname: string;
rewardAccount: string; rewardAccount: string;
instances: string[];
gasPrice?: number;
ethPrices?: {
[key in string]: string;
};
currentQueue: number; currentQueue: number;
tornadoServiceFee: number; tornadoServiceFee: number;
} }
export type RelayerInfo = Relayer & { export type RelayerInfo = Relayer & {
hostname: string;
ensName: string; ensName: string;
stakeBalance: bigint; stakeBalance: bigint;
relayerAddress: string; relayerAddress: string;
ethPrices?: {
[key in string]: string;
};
}; };
export type RelayerError = { export type RelayerError = {
@ -139,6 +141,24 @@ export function getWeightRandom(weightsScores: bigint[], random: bigint) {
return Math.floor(Math.random() * weightsScores.length); return Math.floor(Math.random() * weightsScores.length);
} }
export type RelayerInstanceList = {
[key in string]: {
instanceAddress: {
[key in string]: string;
};
};
};
export function getSupportedInstances(instanceList: RelayerInstanceList) {
const rawList = Object.values(instanceList)
.map(({ instanceAddress }) => {
return Object.values(instanceAddress);
})
.flat();
return rawList.map((l) => getAddress(l));
}
export function pickWeightedRandomRelayer(relayers: RelayerInfo[], netId: string | number) { export function pickWeightedRandomRelayer(relayers: RelayerInfo[], netId: string | number) {
let minFee: number, maxFee: number; let minFee: number, maxFee: number;
@ -263,7 +283,9 @@ export class RelayerClient {
ensName, ensName,
stakeBalance, stakeBalance,
relayerAddress, relayerAddress,
rewardAccount: status.rewardAccount, rewardAccount: getAddress(status.rewardAccount),
instances: getSupportedInstances(status.instances),
gasPrice: status.gasPrices?.fast,
ethPrices: status.ethPrices, ethPrices: status.ethPrices,
currentQueue: status.currentQueue, currentQueue: status.currentQueue,
tornadoServiceFee: status.tornadoServiceFee, tornadoServiceFee: status.tornadoServiceFee,

@ -1,4 +1,3 @@
import { URL } from 'url';
import { webcrypto } from 'crypto'; import { webcrypto } from 'crypto';
import BN from 'bn.js'; import BN from 'bn.js';
import type { BigNumberish } from 'ethers'; import type { BigNumberish } from 'ethers';