Compare commits

...

2 Commits

Author SHA1 Message Date
d688f8a2b5
Update Dockerfile 2025-01-21 17:34:31 +00:00
0aa9f00383
Remove cross-fetch deps 2025-01-21 17:34:04 +00:00
29 changed files with 1239 additions and 2222 deletions

@ -7,7 +7,7 @@ RUN apt update && apt install --yes --no-install-recommends wget git apt-transpo
ENV GIT_REPOSITORY=https://github.com/tornadocontrib/tornado-scripts.git ENV GIT_REPOSITORY=https://github.com/tornadocontrib/tornado-scripts.git
# From main branch, double check with git.tornado.ws and codeberg.org # From main branch, double check with git.tornado.ws and codeberg.org
ENV GIT_COMMIT_HASH=5bfef2a2ae887b4cc065af34b6ea106fc3cacde1 ENV GIT_COMMIT_HASH=0aa9f0038354412e01b171df7dcff96b1c55976c
# clone the repository # clone the repository
RUN mkdir /app/ RUN mkdir /app/

12
dist/hashes.json vendored

@ -1,11 +1,11 @@
{ {
"dist/index.js": "sha384-DMBnRJIMRwGIEYdgWy5NptEFmOmmB4DrUWvVNf60ZUMHDWnuHdogrjx1dkCSOWtN", "dist/index.js": "sha384-iQ5shLTi2Nyi35ciUUQRXg2JSgjBguTRXafhYVZuuAyJug9BAXZIWYEwupPOUcCo",
"dist/index.mjs": "sha384-3zq911CcPyyFDXeBw8eByPFafkAn/CA5zHaBTQnpU7wIXczHIYYMBvb9GN3ugnd/", "dist/index.mjs": "sha384-Lx8Qc+R6ak1AaPmSKJ06+EYyFuVF8gI7E+IvBFItO+3Yoc+JmsunEmytkd7mhSQt",
"dist/merkleTreeWorker.js": "sha384-gib4Z6KDvYxUpNTSc4YA2dX5FxaQe2FiorGkBJJDfm86tXdT+57T2Gt+ti6YXTeX", "dist/merkleTreeWorker.js": "sha384-gib4Z6KDvYxUpNTSc4YA2dX5FxaQe2FiorGkBJJDfm86tXdT+57T2Gt+ti6YXTeX",
"dist/merkleTreeWorker.umd.js": "sha384-R1mZHDfLUv9Y/WqKUvzOZY+2plbO/Bp51yBEjC/gR1i6s6/Bs2bvL8fUgayQj9tv", "dist/merkleTreeWorker.umd.js": "sha384-yHNYOc2TzXlkKS8/5dzjggHQmOJw2mRIB8DqagRTQxUP/p6uPXyp07LqXeOHNfv7",
"dist/merkleTreeWorker.umd.min.js": "sha384-Q+7eHKKDxI6F+EIEM2X0y3WYI8Y/UzQsB7iGjwEVTaqhN1B8cAk7faigdcMA9eZ5", "dist/merkleTreeWorker.umd.min.js": "sha384-Hpupvso1ruJIgbYwq+dySfLb75sgwxUexPYSCJu+/i7U3XqR6JiBhWOEnAdxR/An",
"dist/tornado.umd.js": "sha384-DlHTTaIvJDp54vY8Hsd7ACW3GYNpblowCkFERkIC75aWQp2g16pMwSWoJvkxG5nm", "dist/tornado.umd.js": "sha384-ovBwiI34m1uBSV4UlKomzexgVturp0Uq7O207DMS96GwpOeOjdS1RMkh7rqmtMed",
"dist/tornado.umd.min.js": "sha384-SLYHCT9/tmX2h3G6DqPnEqaOrzH1ES+vQ1ge0WYaW6V3Zwd9Bcn6ihkqntxJRuqO", "dist/tornado.umd.min.js": "sha384-z9UM5/+q0Z70nAb+8JebUO/78o9C/W1AZgOWOYsDAyL9sH8ANR9U9tfB467+QHCF",
"dist/tornadoContracts.umd.js": "sha384-Gmawcz/XTH7WFUFnMJKPUCy2zrjDOhf/DtSv9xfHBulPyCEJwI70Hw+n7E1Y60EU", "dist/tornadoContracts.umd.js": "sha384-Gmawcz/XTH7WFUFnMJKPUCy2zrjDOhf/DtSv9xfHBulPyCEJwI70Hw+n7E1Y60EU",
"dist/tornadoContracts.umd.min.js": "sha384-Sclkp3xkhjmDekfQaQFkgUctmauYUF7ieeyyFhFBnwAzyp2eFBS5qzxvOIBhlJza" "dist/tornadoContracts.umd.min.js": "sha384-Sclkp3xkhjmDekfQaQFkgUctmauYUF7ieeyyFhFBnwAzyp2eFBS5qzxvOIBhlJza"
} }

8
dist/idb.d.ts vendored

@ -1,5 +1,11 @@
import { OpenDBCallbacks, IDBPDatabase } from 'idb'; import type * as idb from 'idb';
import type { OpenDBCallbacks, IDBPDatabase } from 'idb';
import { NetIdType } from './networkConfig'; import { NetIdType } from './networkConfig';
declare global {
interface Window {
idb: typeof idb;
}
}
export declare const INDEX_DB_ERROR = "A mutation operation was attempted on a database that did not allow mutations."; export declare const INDEX_DB_ERROR = "A mutation operation was attempted on a database that did not allow mutations.";
export interface IDBIndex { export interface IDBIndex {
name: string; name: string;

294
dist/index.js vendored

@ -5,12 +5,10 @@ var tornadoContracts = require('tornado-contracts');
var crypto$1 = require('crypto'); var crypto$1 = require('crypto');
var BN = require('bn.js'); var BN = require('bn.js');
var contentHashUtils = require('@ensdomains/content-hash'); var contentHashUtils = require('@ensdomains/content-hash');
var crossFetch = require('cross-fetch');
var Ajv = require('ajv'); var Ajv = require('ajv');
var fflate = require('fflate'); var fflate = require('fflate');
var circomlibjs = require('circomlibjs'); var circomlibjs = require('circomlibjs');
var ethSigUtil = require('@metamask/eth-sig-util'); var ethSigUtil = require('@metamask/eth-sig-util');
var idb = require('idb');
var worker_threads = require('worker_threads'); var worker_threads = require('worker_threads');
var fixedMerkleTree = require('fixed-merkle-tree'); var fixedMerkleTree = require('fixed-merkle-tree');
var websnarkUtils = require('websnark/src/utils'); var websnarkUtils = require('websnark/src/utils');
@ -519,37 +517,10 @@ class BatchEventsService {
} }
const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"; const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0";
function getHttpAgent({
fetchUrl,
proxyUrl,
torPort,
retry
}) {
const { HttpProxyAgent } = require("http-proxy-agent");
const { HttpsProxyAgent } = require("https-proxy-agent");
const { SocksProxyAgent } = require("socks-proxy-agent");
if (torPort) {
return new SocksProxyAgent(`socks5h://tor${retry}@127.0.0.1:${torPort}`);
}
if (!proxyUrl) {
return;
}
const isHttps = fetchUrl.includes("https://");
if (proxyUrl.includes("socks://") || proxyUrl.includes("socks4://") || proxyUrl.includes("socks5://")) {
return new SocksProxyAgent(proxyUrl);
}
if (proxyUrl.includes("http://") || proxyUrl.includes("https://")) {
if (isHttps) {
return new HttpsProxyAgent(proxyUrl);
}
return new HttpProxyAgent(proxyUrl);
}
}
async function fetchData(url, options = {}) { async function fetchData(url, options = {}) {
const MAX_RETRY = options.maxRetry ?? 3; const MAX_RETRY = options.maxRetry ?? 3;
const RETRY_ON = options.retryOn ?? 500; const RETRY_ON = options.retryOn ?? 500;
const userAgent = options.userAgent ?? defaultUserAgent; const userAgent = options.userAgent ?? defaultUserAgent;
const fetch = globalThis.useGlobalFetch ? globalThis.fetch : crossFetch;
let retry = 0; let retry = 0;
let errorObject; let errorObject;
if (!options.method) { if (!options.method) {
@ -565,6 +536,9 @@ async function fetchData(url, options = {}) {
if (isNode && !options.headers["User-Agent"]) { if (isNode && !options.headers["User-Agent"]) {
options.headers["User-Agent"] = userAgent; options.headers["User-Agent"] = userAgent;
} }
if (typeof globalThis.fetch !== "function") {
throw new Error("Fetch API is not available, use latest browser or nodejs installation!");
}
while (retry < MAX_RETRY + 1) { while (retry < MAX_RETRY + 1) {
let timeout; let timeout;
if (!options.signal && options.timeout) { if (!options.signal && options.timeout) {
@ -582,15 +556,7 @@ async function fetchData(url, options = {}) {
}); });
} }
} }
if (!options.agent && isNode && (options.proxy || options.torPort)) { if (typeof options.debug === "function") {
options.agent = getHttpAgent({
fetchUrl: url,
proxyUrl: options.proxy,
torPort: options.torPort,
retry
});
}
if (options.debug && typeof options.debug === "function") {
options.debug("request", { options.debug("request", {
url, url,
retry, retry,
@ -599,13 +565,10 @@ async function fetchData(url, options = {}) {
}); });
} }
try { try {
const resp = await fetch(url, { const dispatcher = options.dispatcherFunc ? options.dispatcherFunc(retry) : options.dispatcher;
method: options.method, const resp = await globalThis.fetch(url, {
headers: options.headers, ...options,
body: options.body, dispatcher
redirect: options.redirect,
signal: options.signal,
agent: options.agent
}); });
if (options.debug && typeof options.debug === "function") { if (options.debug && typeof options.debug === "function") {
options.debug("response", resp); options.debug("response", resp);
@ -668,15 +631,25 @@ const fetchGetUrlFunc = (options = {}) => async (req, _signal) => {
body body
}; };
}; };
const FeeDataNetworkPluginName = new ethers.FetchUrlFeeDataNetworkPlugin(
"",
() => new Promise((resolve) => resolve(new ethers.FeeData()))
).name;
async function getProvider(rpcUrl, fetchOptions) { async function getProvider(rpcUrl, fetchOptions) {
const fetchReq = new ethers.FetchRequest(rpcUrl); const fetchReq = new ethers.FetchRequest(rpcUrl);
fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions); fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions);
const staticNetwork = await new ethers.JsonRpcProvider(fetchReq).getNetwork(); const fetchedNetwork = await new ethers.JsonRpcProvider(fetchReq).getNetwork();
const chainId = Number(staticNetwork.chainId); const chainId = Number(fetchedNetwork.chainId);
if (fetchOptions?.netId && fetchOptions.netId !== chainId) { if (fetchOptions?.netId && fetchOptions.netId !== chainId) {
const errMsg = `Wrong network for ${rpcUrl}, wants ${fetchOptions.netId} got ${chainId}`; const errMsg = `Wrong network for ${rpcUrl}, wants ${fetchOptions.netId} got ${chainId}`;
throw new Error(errMsg); throw new Error(errMsg);
} }
const staticNetwork = new ethers.Network(fetchedNetwork.name, fetchedNetwork.chainId);
fetchedNetwork.plugins.forEach((plugin) => {
if (plugin.name !== FeeDataNetworkPluginName) {
staticNetwork.attachPlugin(plugin.clone());
}
});
return new ethers.JsonRpcProvider(fetchReq, staticNetwork, { return new ethers.JsonRpcProvider(fetchReq, staticNetwork, {
staticNetwork, staticNetwork,
pollingInterval: fetchOptions?.pollingInterval || 1e3 pollingInterval: fetchOptions?.pollingInterval || 1e3
@ -708,7 +681,7 @@ const populateTransaction = async (signer, tx) => {
} }
const [feeData, nonce] = await Promise.all([ const [feeData, nonce] = await Promise.all([
tx.maxFeePerGas || tx.gasPrice ? void 0 : provider.getFeeData(), tx.maxFeePerGas || tx.gasPrice ? void 0 : provider.getFeeData(),
tx.nonce ? void 0 : provider.getTransactionCount(signer.address, "pending") tx.nonce || tx.nonce === 0 ? void 0 : provider.getTransactionCount(signer.address, "pending")
]); ]);
if (feeData) { if (feeData) {
if (feeData.maxFeePerGas) { if (feeData.maxFeePerGas) {
@ -727,7 +700,7 @@ const populateTransaction = async (signer, tx) => {
delete tx.maxPriorityFeePerGas; delete tx.maxPriorityFeePerGas;
} }
} }
if (nonce) { if (nonce || nonce === 0) {
tx.nonce = nonce; tx.nonce = nonce;
} }
if (!tx.gasLimit) { if (!tx.gasLimit) {
@ -743,7 +716,7 @@ const populateTransaction = async (signer, tx) => {
} }
} }
} }
return tx; return ethers.resolveProperties(tx);
}; };
class TornadoWallet extends ethers.Wallet { class TornadoWallet extends ethers.Wallet {
nonce; nonce;
@ -766,7 +739,7 @@ class TornadoWallet extends ethers.Wallet {
async populateTransaction(tx) { async populateTransaction(tx) {
const txObject = await populateTransaction(this, tx); const txObject = await populateTransaction(this, tx);
this.nonce = Number(txObject.nonce); this.nonce = Number(txObject.nonce);
return super.populateTransaction(txObject); return txObject;
} }
} }
class TornadoVoidSigner extends ethers.VoidSigner { class TornadoVoidSigner extends ethers.VoidSigner {
@ -785,7 +758,7 @@ class TornadoVoidSigner extends ethers.VoidSigner {
async populateTransaction(tx) { async populateTransaction(tx) {
const txObject = await populateTransaction(this, tx); const txObject = await populateTransaction(this, tx);
this.nonce = Number(txObject.nonce); this.nonce = Number(txObject.nonce);
return super.populateTransaction(txObject); return txObject;
} }
} }
class TornadoRpcSigner extends ethers.JsonRpcSigner { class TornadoRpcSigner extends ethers.JsonRpcSigner {
@ -846,13 +819,6 @@ var NetId = /* @__PURE__ */ ((NetId2) => {
})(NetId || {}); })(NetId || {});
const defaultConfig = { const defaultConfig = {
[1 /* MAINNET */]: { [1 /* MAINNET */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 80,
fast: 50,
standard: 25,
low: 8
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://etherscan.io", explorerUrl: "https://etherscan.io",
@ -865,9 +831,9 @@ const defaultConfig = {
name: "MEV Blocker", name: "MEV Blocker",
url: "https://rpc.mevblocker.io" url: "https://rpc.mevblocker.io"
}, },
tornadoWithdraw: { tornadoRpc: {
name: "Tornado Withdraw", name: "Tornado RPC",
url: "https://tornadowithdraw.com/mainnet" url: "https://tornadocash-rpc.com/mainnet"
}, },
keydonix: { keydonix: {
name: "Horswap ( Keydonix )", name: "Horswap ( Keydonix )",
@ -986,13 +952,6 @@ const defaultConfig = {
} }
}, },
[56 /* BSC */]: { [56 /* BSC */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 3,
fast: 1,
standard: 1,
low: 1
},
nativeCurrency: "bnb", nativeCurrency: "bnb",
currencyName: "BNB", currencyName: "BNB",
explorerUrl: "https://bscscan.com", explorerUrl: "https://bscscan.com",
@ -1016,9 +975,9 @@ const defaultConfig = {
name: "BNB Chain 2", name: "BNB Chain 2",
url: "https://bsc-dataseed1.ninicoin.io" url: "https://bsc-dataseed1.ninicoin.io"
}, },
tornadoWithdraw: { tornadoRpc: {
name: "Tornado Withdraw", name: "Tornado RPC",
url: "https://tornadowithdraw.com/bsc" url: "https://tornadocash-rpc.com/bsc"
}, },
nodereal: { nodereal: {
name: "NodeReal", name: "NodeReal",
@ -1082,13 +1041,6 @@ const defaultConfig = {
} }
}, },
[137 /* POLYGON */]: { [137 /* POLYGON */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 60,
fast: 30,
standard: 30,
low: 30
},
nativeCurrency: "matic", nativeCurrency: "matic",
currencyName: "MATIC", currencyName: "MATIC",
explorerUrl: "https://polygonscan.com", explorerUrl: "https://polygonscan.com",
@ -1104,9 +1056,9 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/matic-tornado-subgraph", tornadoSubgraph: "tornadocash/matic-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { lavaBuild: {
name: "Tornado Withdraw", name: "polygon.lava.build",
url: "https://tornadowithdraw.com/polygon" url: "https://polygon.lava.build"
}, },
polygon: { polygon: {
name: "Polygon", name: "Polygon",
@ -1141,13 +1093,6 @@ const defaultConfig = {
} }
}, },
[10 /* OPTIMISM */]: { [10 /* OPTIMISM */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 1e-3,
fast: 1e-3,
standard: 1e-3,
low: 1e-3
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://optimistic.etherscan.io", explorerUrl: "https://optimistic.etherscan.io",
@ -1164,9 +1109,9 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/optimism-tornado-subgraph", tornadoSubgraph: "tornadocash/optimism-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { lavaBuild: {
name: "Tornado Withdraw", name: "optimism.lava.build",
url: "https://tornadowithdraw.com/op" url: "https://optimism.lava.build"
}, },
optimism: { optimism: {
name: "Optimism", name: "Optimism",
@ -1204,13 +1149,6 @@ const defaultConfig = {
} }
}, },
[42161 /* ARBITRUM */]: { [42161 /* ARBITRUM */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.02,
fast: 0.02,
standard: 0.02,
low: 0.02
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://arbiscan.io", explorerUrl: "https://arbiscan.io",
@ -1230,10 +1168,6 @@ const defaultConfig = {
name: "Arbitrum", name: "Arbitrum",
url: "https://arb1.arbitrum.io/rpc" url: "https://arb1.arbitrum.io/rpc"
}, },
tornadoWithdraw: {
name: "Tornado Withdraw",
url: "https://tornadowithdraw.com/arbitrum"
},
stackup: { stackup: {
name: "Stackup", name: "Stackup",
url: "https://public.stackup.sh/api/v1/node/arbitrum-one" url: "https://public.stackup.sh/api/v1/node/arbitrum-one"
@ -1266,13 +1200,6 @@ const defaultConfig = {
} }
}, },
[8453 /* BASE */]: { [8453 /* BASE */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.1,
fast: 0.06,
standard: 0.05,
low: 0.02
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://basescan.org", explorerUrl: "https://basescan.org",
@ -1293,10 +1220,6 @@ const defaultConfig = {
name: "Base", name: "Base",
url: "https://mainnet.base.org" url: "https://mainnet.base.org"
}, },
tornadoWithdraw: {
name: "Tornado Withdraw",
url: "https://tornadowithdraw.com/base"
},
stackup: { stackup: {
name: "Stackup", name: "Stackup",
url: "https://public.stackup.sh/api/v1/node/base-mainnet" url: "https://public.stackup.sh/api/v1/node/base-mainnet"
@ -1358,13 +1281,6 @@ const defaultConfig = {
} }
}, },
[81457 /* BLAST */]: { [81457 /* BLAST */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 1e-3,
fast: 1e-3,
standard: 1e-3,
low: 1e-3
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://blastscan.io", explorerUrl: "https://blastscan.io",
@ -1384,10 +1300,6 @@ const defaultConfig = {
name: "Blast", name: "Blast",
url: "https://rpc.blast.io" url: "https://rpc.blast.io"
}, },
tornadoWithdraw: {
name: "Tornado Withdraw",
url: "https://tornadowithdraw.com/blast"
},
blastApi: { blastApi: {
name: "BlastApi", name: "BlastApi",
url: "https://blastl2-mainnet.public.blastapi.io" url: "https://blastl2-mainnet.public.blastapi.io"
@ -1415,13 +1327,6 @@ const defaultConfig = {
} }
}, },
[100 /* GNOSIS */]: { [100 /* GNOSIS */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 6,
fast: 5,
standard: 4,
low: 1
},
nativeCurrency: "xdai", nativeCurrency: "xdai",
currencyName: "xDAI", currencyName: "xDAI",
explorerUrl: "https://gnosisscan.io", explorerUrl: "https://gnosisscan.io",
@ -1441,9 +1346,13 @@ const defaultConfig = {
name: "Gnosis", name: "Gnosis",
url: "https://rpc.gnosischain.com" url: "https://rpc.gnosischain.com"
}, },
tornadoWithdraw: { tornadoRpc: {
name: "Tornado Withdraw", name: "Tornado RPC",
url: "https://tornadowithdraw.com/gnosis" url: "https://tornadocash-rpc.com/gnosis"
},
blastApi: {
name: "BlastApi",
url: "https://gnosis-mainnet.public.blastapi.io"
}, },
oneRpc: { oneRpc: {
name: "1RPC", name: "1RPC",
@ -1470,13 +1379,6 @@ const defaultConfig = {
} }
}, },
[43114 /* AVALANCHE */]: { [43114 /* AVALANCHE */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 225,
fast: 35,
standard: 25,
low: 25
},
nativeCurrency: "avax", nativeCurrency: "avax",
currencyName: "AVAX", currencyName: "AVAX",
explorerUrl: "https://snowtrace.io", explorerUrl: "https://snowtrace.io",
@ -1492,9 +1394,9 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/avalanche-tornado-subgraph", tornadoSubgraph: "tornadocash/avalanche-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { blastApi: {
name: "Tornado Withdraw", name: "BlastApi",
url: "https://tornadowithdraw.com/ext/bc/C/rpc" url: "https://ava-mainnet.public.blastapi.io/ext/bc/C/rpc"
}, },
oneRpc: { oneRpc: {
name: "1RPC", name: "1RPC",
@ -1528,13 +1430,6 @@ const defaultConfig = {
} }
}, },
[11155111 /* SEPOLIA */]: { [11155111 /* SEPOLIA */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 2,
fast: 2,
standard: 2,
low: 2
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "SepoliaETH", currencyName: "SepoliaETH",
explorerUrl: "https://sepolia.etherscan.io", explorerUrl: "https://sepolia.etherscan.io",
@ -1556,9 +1451,13 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/sepolia-tornado-subgraph", tornadoSubgraph: "tornadocash/sepolia-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { blastApi: {
name: "Tornado Withdraw", name: "BlastApi",
url: "https://tornadowithdraw.com/sepolia" url: "https://eth-sepolia.public.blastapi.io"
},
tornadoRpc: {
name: "Tornado RPC",
url: "https://tornadocash-rpc.com/sepolia"
}, },
oneRpc: { oneRpc: {
name: "1RPC", name: "1RPC",
@ -1647,15 +1546,6 @@ function getActiveTokens(config) {
const { tokens, disabledTokens } = config; const { tokens, disabledTokens } = config;
return Object.keys(tokens).filter((t) => !disabledTokens?.includes(t)); return Object.keys(tokens).filter((t) => !disabledTokens?.includes(t));
} }
function getActiveTokenInstances(config) {
const { tokens, disabledTokens } = config;
return Object.entries(tokens).reduce((acc, [token, instances]) => {
if (!disabledTokens?.includes(token)) {
acc[token] = instances;
}
return acc;
}, {});
}
function getInstanceByAddress(config, address) { function getInstanceByAddress(config, address) {
const { tokens, disabledTokens } = config; const { tokens, disabledTokens } = config;
for (const [currency, { instanceAddress, tokenAddress, symbol, decimals }] of Object.entries(tokens)) { for (const [currency, { instanceAddress, tokenAddress, symbol, decimals }] of Object.entries(tokens)) {
@ -2225,8 +2115,7 @@ class RelayerClient {
} }
async askRelayerStatus({ async askRelayerStatus({
hostname, hostname,
url, url
relayerAddress
}) { }) {
if (!url && hostname) { if (!url && hostname) {
url = `https://${!hostname.endsWith("/") ? hostname + "/" : hostname}`; url = `https://${!hostname.endsWith("/") ? hostname + "/" : hostname}`;
@ -2241,7 +2130,7 @@ class RelayerClient {
"Content-Type": "application/json, application/x-www-form-urlencoded" "Content-Type": "application/json, application/x-www-form-urlencoded"
}, },
timeout: 3e4, timeout: 3e4,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0 maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0
}); });
const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish)); const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish));
if (!statusValidator(rawStatus)) { if (!statusValidator(rawStatus)) {
@ -2257,9 +2146,6 @@ class RelayerClient {
if (status.netId !== this.netId) { if (status.netId !== this.netId) {
throw new Error("This relayer serves a different network"); throw new Error("This relayer serves a different network");
} }
if (relayerAddress && this.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) {
throw new Error("The Relayer reward address must match registered address");
}
return status; return status;
} }
async filterRelayer(relayer) { async filterRelayer(relayer) {
@ -2270,8 +2156,7 @@ class RelayerClient {
} }
try { try {
const status = await this.askRelayerStatus({ const status = await this.askRelayerStatus({
hostname, hostname
relayerAddress
}); });
return { return {
netId: status.netId, netId: status.netId,
@ -3175,7 +3060,7 @@ async function getTovarishNetworks(registryService, relayers) {
"Content-Type": "application/json" "Content-Type": "application/json"
}, },
timeout: 3e4, timeout: 3e4,
maxRetry: registryService.fetchDataOptions?.torPort ? 2 : 0 maxRetry: registryService.fetchDataOptions?.dispatcher ? 2 : 0
}); });
} catch { } catch {
relayer.tovarishNetworks = []; relayer.tovarishNetworks = [];
@ -3504,14 +3389,38 @@ function unzipAsync(data) {
}); });
}); });
} }
function zlibAsync(data, options) {
return new Promise((res, rej) => {
fflate.zlib(data, { ...options || {} }, (err, data2) => {
if (err) {
rej(err);
return;
}
res(data2);
});
});
}
function unzlibAsync(data, options) {
return new Promise((res, rej) => {
fflate.unzlib(data, { ...options || {} }, (err, data2) => {
if (err) {
rej(err);
return;
}
res(data2);
});
});
}
async function downloadZip({ async function downloadZip({
staticUrl = "", staticUrl = "",
zipName, zipName,
zipDigest, zipDigest,
parseJson = true parseJson = true,
fetchOptions
}) { }) {
const url = `${staticUrl}/${zipName}.zip`; const url = `${staticUrl}/${zipName}.zip`;
const resp = await fetchData(url, { const resp = await fetchData(url, {
...fetchOptions || {},
method: "GET", method: "GET",
returnResponse: true returnResponse: true
}); });
@ -9590,7 +9499,7 @@ class ENSUtils {
} }
async getContracts() { async getContracts() {
const { chainId } = await this.provider.getNetwork(); const { chainId } = await this.provider.getNetwork();
const { ensRegistry, ensPublicResolver, ensNameWrapper } = EnsContracts[Number(chainId)]; const { ensRegistry, ensPublicResolver, ensNameWrapper } = EnsContracts[Number(chainId)] || EnsContracts[NetId.MAINNET];
this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider); this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider);
this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider); this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider);
this.ENSNameWrapper = ENSNameWrapper__factory.connect(ensNameWrapper, this.provider); this.ENSNameWrapper = ENSNameWrapper__factory.connect(ensNameWrapper, this.provider);
@ -9834,7 +9743,7 @@ class IndexedDB {
if (this.dbExists || this.isBlocked) { if (this.dbExists || this.isBlocked) {
return; return;
} }
this.db = await idb.openDB(this.dbName, this.dbVersion, this.options); this.db = await window?.idb?.openDB(this.dbName, this.dbVersion, this.options);
this.db.addEventListener("onupgradeneeded", async () => { this.db.addEventListener("onupgradeneeded", async () => {
await this._removeExist(); await this._removeExist();
}); });
@ -9854,7 +9763,7 @@ class IndexedDB {
} }
} }
async _removeExist() { async _removeExist() {
await idb.deleteDB(this.dbName); await window?.idb?.deleteDB(this.dbName);
this.dbExists = false; this.dbExists = false;
await this.initDB(); await this.initDB();
} }
@ -10160,8 +10069,9 @@ async function getIndexedDB(netId) {
return idb; return idb;
} }
async function fetchIp(ipEcho) { function fetchIp(ipEcho, fetchOptions) {
return await fetchData(ipEcho, { return fetchData(ipEcho, {
...fetchOptions || {},
method: "GET", method: "GET",
timeout: 3e4 timeout: 3e4
}); });
@ -10546,13 +10456,11 @@ class TovarishClient extends RelayerClient {
} }
async askRelayerStatus({ async askRelayerStatus({
hostname, hostname,
url, url
relayerAddress
}) { }) {
const status = await super.askRelayerStatus({ const status = await super.askRelayerStatus({
hostname, hostname,
url, url
relayerAddress
}); });
if (!status.version.includes("tovarish")) { if (!status.version.includes("tovarish")) {
throw new Error("Not a tovarish relayer!"); throw new Error("Not a tovarish relayer!");
@ -10580,24 +10488,17 @@ class TovarishClient extends RelayerClient {
"Content-Type": "application/json, application/x-www-form-urlencoded" "Content-Type": "application/json, application/x-www-form-urlencoded"
}, },
timeout: 3e4, timeout: 3e4,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0 maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0
}); });
if (!Array.isArray(statusArray)) { if (!Array.isArray(statusArray)) {
return []; return [];
} }
const tovarishStatus = []; const tovarishStatus = [];
for (const rawStatus of statusArray) { for (const rawStatus of statusArray) {
const netId = rawStatus.netId; const netId = rawStatus?.netId;
const config = getConfig(netId); const config = getConfig(netId);
const statusValidator = ajv.compile( const statusValidator = ajv.compile(getStatusSchema(rawStatus?.netId, config, this.tovarish));
getStatusSchema( if (!statusValidator(rawStatus)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rawStatus.netId,
config,
this.tovarish
)
);
if (!statusValidator) {
continue; continue;
} }
const status = { const status = {
@ -10863,6 +10764,7 @@ exports.ENSUtils = ENSUtils;
exports.ENS__factory = ENS__factory; exports.ENS__factory = ENS__factory;
exports.ERC20__factory = ERC20__factory; exports.ERC20__factory = ERC20__factory;
exports.EnsContracts = EnsContracts; exports.EnsContracts = EnsContracts;
exports.FeeDataNetworkPluginName = FeeDataNetworkPluginName;
exports.INDEX_DB_ERROR = INDEX_DB_ERROR; exports.INDEX_DB_ERROR = INDEX_DB_ERROR;
exports.IndexedDB = IndexedDB; exports.IndexedDB = IndexedDB;
exports.Invoice = Invoice; exports.Invoice = Invoice;
@ -10927,11 +10829,9 @@ exports.gasZipID = gasZipID;
exports.gasZipInbounds = gasZipInbounds; exports.gasZipInbounds = gasZipInbounds;
exports.gasZipInput = gasZipInput; exports.gasZipInput = gasZipInput;
exports.gasZipMinMax = gasZipMinMax; exports.gasZipMinMax = gasZipMinMax;
exports.getActiveTokenInstances = getActiveTokenInstances;
exports.getActiveTokens = getActiveTokens; exports.getActiveTokens = getActiveTokens;
exports.getConfig = getConfig; exports.getConfig = getConfig;
exports.getEventsSchemaValidator = getEventsSchemaValidator; exports.getEventsSchemaValidator = getEventsSchemaValidator;
exports.getHttpAgent = getHttpAgent;
exports.getIndexedDB = getIndexedDB; exports.getIndexedDB = getIndexedDB;
exports.getInstanceByAddress = getInstanceByAddress; exports.getInstanceByAddress = getInstanceByAddress;
exports.getMultiInstances = getMultiInstances; exports.getMultiInstances = getMultiInstances;
@ -10986,6 +10886,8 @@ exports.toFixedLength = toFixedLength;
exports.tornadoEventsSchema = tornadoEventsSchema; exports.tornadoEventsSchema = tornadoEventsSchema;
exports.unpackEncryptedMessage = unpackEncryptedMessage; exports.unpackEncryptedMessage = unpackEncryptedMessage;
exports.unzipAsync = unzipAsync; exports.unzipAsync = unzipAsync;
exports.unzlibAsync = unzlibAsync;
exports.validateUrl = validateUrl; exports.validateUrl = validateUrl;
exports.withdrawalsEventsSchema = withdrawalsEventsSchema; exports.withdrawalsEventsSchema = withdrawalsEventsSchema;
exports.zipAsync = zipAsync; exports.zipAsync = zipAsync;
exports.zlibAsync = zlibAsync;

295
dist/index.mjs vendored

@ -1,14 +1,12 @@
import { isHexString, assertArgument, assert, EventLog, UndecodedEventLog, Log, FetchRequest, JsonRpcProvider, Network, EnsPlugin, GasCostPlugin, Wallet, HDNodeWallet, VoidSigner, JsonRpcSigner, BrowserProvider, isAddress, parseEther, getAddress, AbiCoder, formatEther, namehash, dataSlice, dataLength, Interface, Contract, computeAddress, keccak256, EnsResolver, parseUnits, Transaction, Signature, MaxUint256, ZeroAddress } from 'ethers'; import { isHexString, assertArgument, assert, EventLog, UndecodedEventLog, Log, FetchUrlFeeDataNetworkPlugin, FeeData, FetchRequest, JsonRpcProvider, Network, EnsPlugin, GasCostPlugin, resolveProperties, Wallet, HDNodeWallet, VoidSigner, JsonRpcSigner, BrowserProvider, isAddress, parseEther, getAddress, AbiCoder, formatEther, namehash, dataSlice, dataLength, Interface, Contract, computeAddress, keccak256, EnsResolver, parseUnits, Transaction, Signature, MaxUint256, ZeroAddress } from 'ethers';
import { Tornado__factory } from 'tornado-contracts'; import { Tornado__factory } from 'tornado-contracts';
import { webcrypto } from 'crypto'; import { webcrypto } from 'crypto';
import BN from 'bn.js'; import BN from 'bn.js';
import * as contentHashUtils from '@ensdomains/content-hash'; import * as contentHashUtils from '@ensdomains/content-hash';
import crossFetch from 'cross-fetch';
import Ajv from 'ajv'; import Ajv from 'ajv';
import { zip, unzip } from 'fflate'; import { zip, unzip, zlib, unzlib } from 'fflate';
import { buildPedersenHash, buildMimcSponge } from 'circomlibjs'; import { buildPedersenHash, buildMimcSponge } from 'circomlibjs';
import { getEncryptionPublicKey, encrypt, decrypt } from '@metamask/eth-sig-util'; import { getEncryptionPublicKey, encrypt, decrypt } from '@metamask/eth-sig-util';
import { openDB, deleteDB } from 'idb';
import { Worker as Worker$1 } from 'worker_threads'; import { Worker as Worker$1 } from 'worker_threads';
import { MerkleTree, PartialMerkleTree } from 'fixed-merkle-tree'; import { MerkleTree, PartialMerkleTree } from 'fixed-merkle-tree';
import * as websnarkUtils from 'websnark/src/utils'; import * as websnarkUtils from 'websnark/src/utils';
@ -497,37 +495,10 @@ class BatchEventsService {
} }
const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"; const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0";
function getHttpAgent({
fetchUrl,
proxyUrl,
torPort,
retry
}) {
const { HttpProxyAgent } = require("http-proxy-agent");
const { HttpsProxyAgent } = require("https-proxy-agent");
const { SocksProxyAgent } = require("socks-proxy-agent");
if (torPort) {
return new SocksProxyAgent(`socks5h://tor${retry}@127.0.0.1:${torPort}`);
}
if (!proxyUrl) {
return;
}
const isHttps = fetchUrl.includes("https://");
if (proxyUrl.includes("socks://") || proxyUrl.includes("socks4://") || proxyUrl.includes("socks5://")) {
return new SocksProxyAgent(proxyUrl);
}
if (proxyUrl.includes("http://") || proxyUrl.includes("https://")) {
if (isHttps) {
return new HttpsProxyAgent(proxyUrl);
}
return new HttpProxyAgent(proxyUrl);
}
}
async function fetchData(url, options = {}) { async function fetchData(url, options = {}) {
const MAX_RETRY = options.maxRetry ?? 3; const MAX_RETRY = options.maxRetry ?? 3;
const RETRY_ON = options.retryOn ?? 500; const RETRY_ON = options.retryOn ?? 500;
const userAgent = options.userAgent ?? defaultUserAgent; const userAgent = options.userAgent ?? defaultUserAgent;
const fetch = globalThis.useGlobalFetch ? globalThis.fetch : crossFetch;
let retry = 0; let retry = 0;
let errorObject; let errorObject;
if (!options.method) { if (!options.method) {
@ -543,6 +514,9 @@ async function fetchData(url, options = {}) {
if (isNode && !options.headers["User-Agent"]) { if (isNode && !options.headers["User-Agent"]) {
options.headers["User-Agent"] = userAgent; options.headers["User-Agent"] = userAgent;
} }
if (typeof globalThis.fetch !== "function") {
throw new Error("Fetch API is not available, use latest browser or nodejs installation!");
}
while (retry < MAX_RETRY + 1) { while (retry < MAX_RETRY + 1) {
let timeout; let timeout;
if (!options.signal && options.timeout) { if (!options.signal && options.timeout) {
@ -560,15 +534,7 @@ async function fetchData(url, options = {}) {
}); });
} }
} }
if (!options.agent && isNode && (options.proxy || options.torPort)) { if (typeof options.debug === "function") {
options.agent = getHttpAgent({
fetchUrl: url,
proxyUrl: options.proxy,
torPort: options.torPort,
retry
});
}
if (options.debug && typeof options.debug === "function") {
options.debug("request", { options.debug("request", {
url, url,
retry, retry,
@ -577,13 +543,10 @@ async function fetchData(url, options = {}) {
}); });
} }
try { try {
const resp = await fetch(url, { const dispatcher = options.dispatcherFunc ? options.dispatcherFunc(retry) : options.dispatcher;
method: options.method, const resp = await globalThis.fetch(url, {
headers: options.headers, ...options,
body: options.body, dispatcher
redirect: options.redirect,
signal: options.signal,
agent: options.agent
}); });
if (options.debug && typeof options.debug === "function") { if (options.debug && typeof options.debug === "function") {
options.debug("response", resp); options.debug("response", resp);
@ -646,15 +609,25 @@ const fetchGetUrlFunc = (options = {}) => async (req, _signal) => {
body body
}; };
}; };
const FeeDataNetworkPluginName = new FetchUrlFeeDataNetworkPlugin(
"",
() => new Promise((resolve) => resolve(new FeeData()))
).name;
async function getProvider(rpcUrl, fetchOptions) { async function getProvider(rpcUrl, fetchOptions) {
const fetchReq = new FetchRequest(rpcUrl); const fetchReq = new FetchRequest(rpcUrl);
fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions); fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions);
const staticNetwork = await new JsonRpcProvider(fetchReq).getNetwork(); const fetchedNetwork = await new JsonRpcProvider(fetchReq).getNetwork();
const chainId = Number(staticNetwork.chainId); const chainId = Number(fetchedNetwork.chainId);
if (fetchOptions?.netId && fetchOptions.netId !== chainId) { if (fetchOptions?.netId && fetchOptions.netId !== chainId) {
const errMsg = `Wrong network for ${rpcUrl}, wants ${fetchOptions.netId} got ${chainId}`; const errMsg = `Wrong network for ${rpcUrl}, wants ${fetchOptions.netId} got ${chainId}`;
throw new Error(errMsg); throw new Error(errMsg);
} }
const staticNetwork = new Network(fetchedNetwork.name, fetchedNetwork.chainId);
fetchedNetwork.plugins.forEach((plugin) => {
if (plugin.name !== FeeDataNetworkPluginName) {
staticNetwork.attachPlugin(plugin.clone());
}
});
return new JsonRpcProvider(fetchReq, staticNetwork, { return new JsonRpcProvider(fetchReq, staticNetwork, {
staticNetwork, staticNetwork,
pollingInterval: fetchOptions?.pollingInterval || 1e3 pollingInterval: fetchOptions?.pollingInterval || 1e3
@ -686,7 +659,7 @@ const populateTransaction = async (signer, tx) => {
} }
const [feeData, nonce] = await Promise.all([ const [feeData, nonce] = await Promise.all([
tx.maxFeePerGas || tx.gasPrice ? void 0 : provider.getFeeData(), tx.maxFeePerGas || tx.gasPrice ? void 0 : provider.getFeeData(),
tx.nonce ? void 0 : provider.getTransactionCount(signer.address, "pending") tx.nonce || tx.nonce === 0 ? void 0 : provider.getTransactionCount(signer.address, "pending")
]); ]);
if (feeData) { if (feeData) {
if (feeData.maxFeePerGas) { if (feeData.maxFeePerGas) {
@ -705,7 +678,7 @@ const populateTransaction = async (signer, tx) => {
delete tx.maxPriorityFeePerGas; delete tx.maxPriorityFeePerGas;
} }
} }
if (nonce) { if (nonce || nonce === 0) {
tx.nonce = nonce; tx.nonce = nonce;
} }
if (!tx.gasLimit) { if (!tx.gasLimit) {
@ -721,7 +694,7 @@ const populateTransaction = async (signer, tx) => {
} }
} }
} }
return tx; return resolveProperties(tx);
}; };
class TornadoWallet extends Wallet { class TornadoWallet extends Wallet {
nonce; nonce;
@ -744,7 +717,7 @@ class TornadoWallet extends Wallet {
async populateTransaction(tx) { async populateTransaction(tx) {
const txObject = await populateTransaction(this, tx); const txObject = await populateTransaction(this, tx);
this.nonce = Number(txObject.nonce); this.nonce = Number(txObject.nonce);
return super.populateTransaction(txObject); return txObject;
} }
} }
class TornadoVoidSigner extends VoidSigner { class TornadoVoidSigner extends VoidSigner {
@ -763,7 +736,7 @@ class TornadoVoidSigner extends VoidSigner {
async populateTransaction(tx) { async populateTransaction(tx) {
const txObject = await populateTransaction(this, tx); const txObject = await populateTransaction(this, tx);
this.nonce = Number(txObject.nonce); this.nonce = Number(txObject.nonce);
return super.populateTransaction(txObject); return txObject;
} }
} }
class TornadoRpcSigner extends JsonRpcSigner { class TornadoRpcSigner extends JsonRpcSigner {
@ -824,13 +797,6 @@ var NetId = /* @__PURE__ */ ((NetId2) => {
})(NetId || {}); })(NetId || {});
const defaultConfig = { const defaultConfig = {
[1 /* MAINNET */]: { [1 /* MAINNET */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 80,
fast: 50,
standard: 25,
low: 8
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://etherscan.io", explorerUrl: "https://etherscan.io",
@ -843,9 +809,9 @@ const defaultConfig = {
name: "MEV Blocker", name: "MEV Blocker",
url: "https://rpc.mevblocker.io" url: "https://rpc.mevblocker.io"
}, },
tornadoWithdraw: { tornadoRpc: {
name: "Tornado Withdraw", name: "Tornado RPC",
url: "https://tornadowithdraw.com/mainnet" url: "https://tornadocash-rpc.com/mainnet"
}, },
keydonix: { keydonix: {
name: "Horswap ( Keydonix )", name: "Horswap ( Keydonix )",
@ -964,13 +930,6 @@ const defaultConfig = {
} }
}, },
[56 /* BSC */]: { [56 /* BSC */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 3,
fast: 1,
standard: 1,
low: 1
},
nativeCurrency: "bnb", nativeCurrency: "bnb",
currencyName: "BNB", currencyName: "BNB",
explorerUrl: "https://bscscan.com", explorerUrl: "https://bscscan.com",
@ -994,9 +953,9 @@ const defaultConfig = {
name: "BNB Chain 2", name: "BNB Chain 2",
url: "https://bsc-dataseed1.ninicoin.io" url: "https://bsc-dataseed1.ninicoin.io"
}, },
tornadoWithdraw: { tornadoRpc: {
name: "Tornado Withdraw", name: "Tornado RPC",
url: "https://tornadowithdraw.com/bsc" url: "https://tornadocash-rpc.com/bsc"
}, },
nodereal: { nodereal: {
name: "NodeReal", name: "NodeReal",
@ -1060,13 +1019,6 @@ const defaultConfig = {
} }
}, },
[137 /* POLYGON */]: { [137 /* POLYGON */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 60,
fast: 30,
standard: 30,
low: 30
},
nativeCurrency: "matic", nativeCurrency: "matic",
currencyName: "MATIC", currencyName: "MATIC",
explorerUrl: "https://polygonscan.com", explorerUrl: "https://polygonscan.com",
@ -1082,9 +1034,9 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/matic-tornado-subgraph", tornadoSubgraph: "tornadocash/matic-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { lavaBuild: {
name: "Tornado Withdraw", name: "polygon.lava.build",
url: "https://tornadowithdraw.com/polygon" url: "https://polygon.lava.build"
}, },
polygon: { polygon: {
name: "Polygon", name: "Polygon",
@ -1119,13 +1071,6 @@ const defaultConfig = {
} }
}, },
[10 /* OPTIMISM */]: { [10 /* OPTIMISM */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 1e-3,
fast: 1e-3,
standard: 1e-3,
low: 1e-3
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://optimistic.etherscan.io", explorerUrl: "https://optimistic.etherscan.io",
@ -1142,9 +1087,9 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/optimism-tornado-subgraph", tornadoSubgraph: "tornadocash/optimism-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { lavaBuild: {
name: "Tornado Withdraw", name: "optimism.lava.build",
url: "https://tornadowithdraw.com/op" url: "https://optimism.lava.build"
}, },
optimism: { optimism: {
name: "Optimism", name: "Optimism",
@ -1182,13 +1127,6 @@ const defaultConfig = {
} }
}, },
[42161 /* ARBITRUM */]: { [42161 /* ARBITRUM */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.02,
fast: 0.02,
standard: 0.02,
low: 0.02
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://arbiscan.io", explorerUrl: "https://arbiscan.io",
@ -1208,10 +1146,6 @@ const defaultConfig = {
name: "Arbitrum", name: "Arbitrum",
url: "https://arb1.arbitrum.io/rpc" url: "https://arb1.arbitrum.io/rpc"
}, },
tornadoWithdraw: {
name: "Tornado Withdraw",
url: "https://tornadowithdraw.com/arbitrum"
},
stackup: { stackup: {
name: "Stackup", name: "Stackup",
url: "https://public.stackup.sh/api/v1/node/arbitrum-one" url: "https://public.stackup.sh/api/v1/node/arbitrum-one"
@ -1244,13 +1178,6 @@ const defaultConfig = {
} }
}, },
[8453 /* BASE */]: { [8453 /* BASE */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.1,
fast: 0.06,
standard: 0.05,
low: 0.02
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://basescan.org", explorerUrl: "https://basescan.org",
@ -1271,10 +1198,6 @@ const defaultConfig = {
name: "Base", name: "Base",
url: "https://mainnet.base.org" url: "https://mainnet.base.org"
}, },
tornadoWithdraw: {
name: "Tornado Withdraw",
url: "https://tornadowithdraw.com/base"
},
stackup: { stackup: {
name: "Stackup", name: "Stackup",
url: "https://public.stackup.sh/api/v1/node/base-mainnet" url: "https://public.stackup.sh/api/v1/node/base-mainnet"
@ -1336,13 +1259,6 @@ const defaultConfig = {
} }
}, },
[81457 /* BLAST */]: { [81457 /* BLAST */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 1e-3,
fast: 1e-3,
standard: 1e-3,
low: 1e-3
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "ETH", currencyName: "ETH",
explorerUrl: "https://blastscan.io", explorerUrl: "https://blastscan.io",
@ -1362,10 +1278,6 @@ const defaultConfig = {
name: "Blast", name: "Blast",
url: "https://rpc.blast.io" url: "https://rpc.blast.io"
}, },
tornadoWithdraw: {
name: "Tornado Withdraw",
url: "https://tornadowithdraw.com/blast"
},
blastApi: { blastApi: {
name: "BlastApi", name: "BlastApi",
url: "https://blastl2-mainnet.public.blastapi.io" url: "https://blastl2-mainnet.public.blastapi.io"
@ -1393,13 +1305,6 @@ const defaultConfig = {
} }
}, },
[100 /* GNOSIS */]: { [100 /* GNOSIS */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 6,
fast: 5,
standard: 4,
low: 1
},
nativeCurrency: "xdai", nativeCurrency: "xdai",
currencyName: "xDAI", currencyName: "xDAI",
explorerUrl: "https://gnosisscan.io", explorerUrl: "https://gnosisscan.io",
@ -1419,9 +1324,13 @@ const defaultConfig = {
name: "Gnosis", name: "Gnosis",
url: "https://rpc.gnosischain.com" url: "https://rpc.gnosischain.com"
}, },
tornadoWithdraw: { tornadoRpc: {
name: "Tornado Withdraw", name: "Tornado RPC",
url: "https://tornadowithdraw.com/gnosis" url: "https://tornadocash-rpc.com/gnosis"
},
blastApi: {
name: "BlastApi",
url: "https://gnosis-mainnet.public.blastapi.io"
}, },
oneRpc: { oneRpc: {
name: "1RPC", name: "1RPC",
@ -1448,13 +1357,6 @@ const defaultConfig = {
} }
}, },
[43114 /* AVALANCHE */]: { [43114 /* AVALANCHE */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 225,
fast: 35,
standard: 25,
low: 25
},
nativeCurrency: "avax", nativeCurrency: "avax",
currencyName: "AVAX", currencyName: "AVAX",
explorerUrl: "https://snowtrace.io", explorerUrl: "https://snowtrace.io",
@ -1470,9 +1372,9 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/avalanche-tornado-subgraph", tornadoSubgraph: "tornadocash/avalanche-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { blastApi: {
name: "Tornado Withdraw", name: "BlastApi",
url: "https://tornadowithdraw.com/ext/bc/C/rpc" url: "https://ava-mainnet.public.blastapi.io/ext/bc/C/rpc"
}, },
oneRpc: { oneRpc: {
name: "1RPC", name: "1RPC",
@ -1506,13 +1408,6 @@ const defaultConfig = {
} }
}, },
[11155111 /* SEPOLIA */]: { [11155111 /* SEPOLIA */]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 2,
fast: 2,
standard: 2,
low: 2
},
nativeCurrency: "eth", nativeCurrency: "eth",
currencyName: "SepoliaETH", currencyName: "SepoliaETH",
explorerUrl: "https://sepolia.etherscan.io", explorerUrl: "https://sepolia.etherscan.io",
@ -1534,9 +1429,13 @@ const defaultConfig = {
tornadoSubgraph: "tornadocash/sepolia-tornado-subgraph", tornadoSubgraph: "tornadocash/sepolia-tornado-subgraph",
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { blastApi: {
name: "Tornado Withdraw", name: "BlastApi",
url: "https://tornadowithdraw.com/sepolia" url: "https://eth-sepolia.public.blastapi.io"
},
tornadoRpc: {
name: "Tornado RPC",
url: "https://tornadocash-rpc.com/sepolia"
}, },
oneRpc: { oneRpc: {
name: "1RPC", name: "1RPC",
@ -1625,15 +1524,6 @@ function getActiveTokens(config) {
const { tokens, disabledTokens } = config; const { tokens, disabledTokens } = config;
return Object.keys(tokens).filter((t) => !disabledTokens?.includes(t)); return Object.keys(tokens).filter((t) => !disabledTokens?.includes(t));
} }
function getActiveTokenInstances(config) {
const { tokens, disabledTokens } = config;
return Object.entries(tokens).reduce((acc, [token, instances]) => {
if (!disabledTokens?.includes(token)) {
acc[token] = instances;
}
return acc;
}, {});
}
function getInstanceByAddress(config, address) { function getInstanceByAddress(config, address) {
const { tokens, disabledTokens } = config; const { tokens, disabledTokens } = config;
for (const [currency, { instanceAddress, tokenAddress, symbol, decimals }] of Object.entries(tokens)) { for (const [currency, { instanceAddress, tokenAddress, symbol, decimals }] of Object.entries(tokens)) {
@ -2203,8 +2093,7 @@ class RelayerClient {
} }
async askRelayerStatus({ async askRelayerStatus({
hostname, hostname,
url, url
relayerAddress
}) { }) {
if (!url && hostname) { if (!url && hostname) {
url = `https://${!hostname.endsWith("/") ? hostname + "/" : hostname}`; url = `https://${!hostname.endsWith("/") ? hostname + "/" : hostname}`;
@ -2219,7 +2108,7 @@ class RelayerClient {
"Content-Type": "application/json, application/x-www-form-urlencoded" "Content-Type": "application/json, application/x-www-form-urlencoded"
}, },
timeout: 3e4, timeout: 3e4,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0 maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0
}); });
const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish)); const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish));
if (!statusValidator(rawStatus)) { if (!statusValidator(rawStatus)) {
@ -2235,9 +2124,6 @@ class RelayerClient {
if (status.netId !== this.netId) { if (status.netId !== this.netId) {
throw new Error("This relayer serves a different network"); throw new Error("This relayer serves a different network");
} }
if (relayerAddress && this.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) {
throw new Error("The Relayer reward address must match registered address");
}
return status; return status;
} }
async filterRelayer(relayer) { async filterRelayer(relayer) {
@ -2248,8 +2134,7 @@ class RelayerClient {
} }
try { try {
const status = await this.askRelayerStatus({ const status = await this.askRelayerStatus({
hostname, hostname
relayerAddress
}); });
return { return {
netId: status.netId, netId: status.netId,
@ -3153,7 +3038,7 @@ async function getTovarishNetworks(registryService, relayers) {
"Content-Type": "application/json" "Content-Type": "application/json"
}, },
timeout: 3e4, timeout: 3e4,
maxRetry: registryService.fetchDataOptions?.torPort ? 2 : 0 maxRetry: registryService.fetchDataOptions?.dispatcher ? 2 : 0
}); });
} catch { } catch {
relayer.tovarishNetworks = []; relayer.tovarishNetworks = [];
@ -3482,14 +3367,38 @@ function unzipAsync(data) {
}); });
}); });
} }
function zlibAsync(data, options) {
return new Promise((res, rej) => {
zlib(data, { ...options || {} }, (err, data2) => {
if (err) {
rej(err);
return;
}
res(data2);
});
});
}
function unzlibAsync(data, options) {
return new Promise((res, rej) => {
unzlib(data, { ...options || {} }, (err, data2) => {
if (err) {
rej(err);
return;
}
res(data2);
});
});
}
async function downloadZip({ async function downloadZip({
staticUrl = "", staticUrl = "",
zipName, zipName,
zipDigest, zipDigest,
parseJson = true parseJson = true,
fetchOptions
}) { }) {
const url = `${staticUrl}/${zipName}.zip`; const url = `${staticUrl}/${zipName}.zip`;
const resp = await fetchData(url, { const resp = await fetchData(url, {
...fetchOptions || {},
method: "GET", method: "GET",
returnResponse: true returnResponse: true
}); });
@ -9568,7 +9477,7 @@ class ENSUtils {
} }
async getContracts() { async getContracts() {
const { chainId } = await this.provider.getNetwork(); const { chainId } = await this.provider.getNetwork();
const { ensRegistry, ensPublicResolver, ensNameWrapper } = EnsContracts[Number(chainId)]; const { ensRegistry, ensPublicResolver, ensNameWrapper } = EnsContracts[Number(chainId)] || EnsContracts[NetId.MAINNET];
this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider); this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider);
this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider); this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider);
this.ENSNameWrapper = ENSNameWrapper__factory.connect(ensNameWrapper, this.provider); this.ENSNameWrapper = ENSNameWrapper__factory.connect(ensNameWrapper, this.provider);
@ -9812,7 +9721,7 @@ class IndexedDB {
if (this.dbExists || this.isBlocked) { if (this.dbExists || this.isBlocked) {
return; return;
} }
this.db = await openDB(this.dbName, this.dbVersion, this.options); this.db = await window?.idb?.openDB(this.dbName, this.dbVersion, this.options);
this.db.addEventListener("onupgradeneeded", async () => { this.db.addEventListener("onupgradeneeded", async () => {
await this._removeExist(); await this._removeExist();
}); });
@ -9832,7 +9741,7 @@ class IndexedDB {
} }
} }
async _removeExist() { async _removeExist() {
await deleteDB(this.dbName); await window?.idb?.deleteDB(this.dbName);
this.dbExists = false; this.dbExists = false;
await this.initDB(); await this.initDB();
} }
@ -10138,8 +10047,9 @@ async function getIndexedDB(netId) {
return idb; return idb;
} }
async function fetchIp(ipEcho) { function fetchIp(ipEcho, fetchOptions) {
return await fetchData(ipEcho, { return fetchData(ipEcho, {
...fetchOptions || {},
method: "GET", method: "GET",
timeout: 3e4 timeout: 3e4
}); });
@ -10524,13 +10434,11 @@ class TovarishClient extends RelayerClient {
} }
async askRelayerStatus({ async askRelayerStatus({
hostname, hostname,
url, url
relayerAddress
}) { }) {
const status = await super.askRelayerStatus({ const status = await super.askRelayerStatus({
hostname, hostname,
url, url
relayerAddress
}); });
if (!status.version.includes("tovarish")) { if (!status.version.includes("tovarish")) {
throw new Error("Not a tovarish relayer!"); throw new Error("Not a tovarish relayer!");
@ -10558,24 +10466,17 @@ class TovarishClient extends RelayerClient {
"Content-Type": "application/json, application/x-www-form-urlencoded" "Content-Type": "application/json, application/x-www-form-urlencoded"
}, },
timeout: 3e4, timeout: 3e4,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0 maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0
}); });
if (!Array.isArray(statusArray)) { if (!Array.isArray(statusArray)) {
return []; return [];
} }
const tovarishStatus = []; const tovarishStatus = [];
for (const rawStatus of statusArray) { for (const rawStatus of statusArray) {
const netId = rawStatus.netId; const netId = rawStatus?.netId;
const config = getConfig(netId); const config = getConfig(netId);
const statusValidator = ajv.compile( const statusValidator = ajv.compile(getStatusSchema(rawStatus?.netId, config, this.tovarish));
getStatusSchema( if (!statusValidator(rawStatus)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rawStatus.netId,
config,
this.tovarish
)
);
if (!statusValidator) {
continue; continue;
} }
const status = { const status = {
@ -10814,4 +10715,4 @@ async function calculateSnarkProof(input, circuit, provingKey) {
return { proof, args }; return { proof, args };
} }
export { BaseEchoService, BaseEncryptedNotesService, BaseEventsService, BaseGovernanceService, BaseMultiTornadoService, BaseRegistryService, BaseRevenueService, BaseTornadoService, BaseTransferService, BatchBlockService, BatchEventsService, BatchTransactionService, DBEchoService, DBEncryptedNotesService, DBGovernanceService, DBMultiTornadoService, DBRegistryService, DBRevenueService, DBTornadoService, Deposit, ENSNameWrapper__factory, ENSRegistry__factory, ENSResolver__factory, ENSUtils, ENS__factory, ERC20__factory, EnsContracts, INDEX_DB_ERROR, IndexedDB, Invoice, MAX_FEE, MAX_TOVARISH_EVENTS, MIN_FEE, MIN_STAKE_BALANCE, MerkleTreeService, Mimc, Multicall__factory, NetId, NoteAccount, OffchainOracle__factory, OvmGasPriceOracle__factory, Pedersen, RelayerClient, ReverseRecords__factory, TokenPriceOracle, TornadoBrowserProvider, TornadoFeeOracle, TornadoRpcSigner, TornadoVoidSigner, TornadoWallet, TovarishClient, addNetwork, addressSchemaType, ajv, base64ToBytes, bigIntReplacer, bnSchemaType, bnToBytes, buffPedersenHash, bufferToBytes, bytes32BNSchemaType, bytes32SchemaType, bytesToBN, bytesToBase64, bytesToHex, calculateScore, calculateSnarkProof, chunk, concatBytes, convertETHToTokenAmount, createDeposit, crypto, customConfig, defaultConfig, defaultUserAgent, deployHasher, depositsEventsSchema, digest, downloadZip, echoEventsSchema, enabledChains, encodedLabelToLabelhash, encryptedNotesSchema, index as factories, fetchData, fetchGetUrlFunc, fetchIp, fromContentHash, gasZipID, gasZipInbounds, gasZipInput, gasZipMinMax, getActiveTokenInstances, getActiveTokens, getConfig, getEventsSchemaValidator, getHttpAgent, getIndexedDB, getInstanceByAddress, getMultiInstances, getNetworkConfig, getPermitSignature, getProvider, getProviderWithNetId, getRelayerEnsSubdomains, getStatusSchema, getSubInfo, getSupportedInstances, getTokenBalances, getTovarishNetworks, getWeightRandom, governanceEventsSchema, hasherBytecode, hexToBytes, initGroth16, isHex, isNode, jobRequestSchema, jobsSchema, labelhash, leBuff2Int, leInt2Buff, loadDBEvents, loadRemoteEvents, makeLabelNodeAndParent, mimc, multiQueryFilter, multicall, numberFormatter, packEncryptedMessage, parseInvoice, parseNote, pedersen, permit2Address, pickWeightedRandomRelayer, populateTransaction, proofSchemaType, proposalState, rBigInt, rHex, relayerRegistryEventsSchema, saveDBEvents, sleep, stakeBurnedEventsSchema, substring, toContentHash, toFixedHex, toFixedLength, tornadoEventsSchema, unpackEncryptedMessage, unzipAsync, validateUrl, withdrawalsEventsSchema, zipAsync }; export { BaseEchoService, BaseEncryptedNotesService, BaseEventsService, BaseGovernanceService, BaseMultiTornadoService, BaseRegistryService, BaseRevenueService, BaseTornadoService, BaseTransferService, BatchBlockService, BatchEventsService, BatchTransactionService, DBEchoService, DBEncryptedNotesService, DBGovernanceService, DBMultiTornadoService, DBRegistryService, DBRevenueService, DBTornadoService, Deposit, ENSNameWrapper__factory, ENSRegistry__factory, ENSResolver__factory, ENSUtils, ENS__factory, ERC20__factory, EnsContracts, FeeDataNetworkPluginName, INDEX_DB_ERROR, IndexedDB, Invoice, MAX_FEE, MAX_TOVARISH_EVENTS, MIN_FEE, MIN_STAKE_BALANCE, MerkleTreeService, Mimc, Multicall__factory, NetId, NoteAccount, OffchainOracle__factory, OvmGasPriceOracle__factory, Pedersen, RelayerClient, ReverseRecords__factory, TokenPriceOracle, TornadoBrowserProvider, TornadoFeeOracle, TornadoRpcSigner, TornadoVoidSigner, TornadoWallet, TovarishClient, addNetwork, addressSchemaType, ajv, base64ToBytes, bigIntReplacer, bnSchemaType, bnToBytes, buffPedersenHash, bufferToBytes, bytes32BNSchemaType, bytes32SchemaType, bytesToBN, bytesToBase64, bytesToHex, calculateScore, calculateSnarkProof, chunk, concatBytes, convertETHToTokenAmount, createDeposit, crypto, customConfig, defaultConfig, defaultUserAgent, deployHasher, depositsEventsSchema, digest, downloadZip, echoEventsSchema, enabledChains, encodedLabelToLabelhash, encryptedNotesSchema, index as factories, fetchData, fetchGetUrlFunc, fetchIp, fromContentHash, gasZipID, gasZipInbounds, gasZipInput, gasZipMinMax, getActiveTokens, getConfig, getEventsSchemaValidator, getIndexedDB, getInstanceByAddress, getMultiInstances, getNetworkConfig, getPermitSignature, getProvider, getProviderWithNetId, getRelayerEnsSubdomains, getStatusSchema, getSubInfo, getSupportedInstances, getTokenBalances, getTovarishNetworks, getWeightRandom, governanceEventsSchema, hasherBytecode, hexToBytes, initGroth16, isHex, isNode, jobRequestSchema, jobsSchema, labelhash, leBuff2Int, leInt2Buff, loadDBEvents, loadRemoteEvents, makeLabelNodeAndParent, mimc, multiQueryFilter, multicall, numberFormatter, packEncryptedMessage, parseInvoice, parseNote, pedersen, permit2Address, pickWeightedRandomRelayer, populateTransaction, proofSchemaType, proposalState, rBigInt, rHex, relayerRegistryEventsSchema, saveDBEvents, sleep, stakeBurnedEventsSchema, substring, toContentHash, toFixedHex, toFixedLength, tornadoEventsSchema, unpackEncryptedMessage, unzipAsync, unzlibAsync, validateUrl, withdrawalsEventsSchema, zipAsync, zlibAsync };

5
dist/ip.d.ts vendored

@ -1,6 +1,9 @@
import { fetchDataOptions } from './providers';
export interface IPResult { export interface IPResult {
ip: string; ip: string;
iso?: string; iso?: string;
country?: string;
country_iso?: string;
tor?: boolean; tor?: boolean;
} }
export declare function fetchIp(ipEcho: string): Promise<IPResult>; export declare function fetchIp(ipEcho: string, fetchOptions?: fetchDataOptions): Promise<IPResult>;

@ -5793,6 +5793,7 @@ PEMEncoder.prototype.encode = function encode(data, options) {
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// Currently in sync with Node.js lib/assert.js // Currently in sync with Node.js lib/assert.js
// https://github.com/nodejs/node/commit/2a51ae424a513ec9a6aa3466baa0cc1d55dd4f3b // https://github.com/nodejs/node/commit/2a51ae424a513ec9a6aa3466baa0cc1d55dd4f3b
@ -6390,6 +6391,7 @@ assert.strict.strict = assert.strict;
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// Currently in sync with Node.js lib/internal/assert/assertion_error.js // Currently in sync with Node.js lib/internal/assert/assertion_error.js
// https://github.com/nodejs/node/commit/0817840f775032169ddd70c85ac059f18ffcc81c // https://github.com/nodejs/node/commit/0817840f775032169ddd70c85ac059f18ffcc81c
@ -14408,6 +14410,7 @@ PassThrough.prototype._transform = function (chunk, encoding, cb) {
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// Copyright Joyent, Inc. and other Node contributors. // Copyright Joyent, Inc. and other Node contributors.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
@ -15655,6 +15658,7 @@ function done(stream, er, data) {
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// Copyright Joyent, Inc. and other Node contributors. // Copyright Joyent, Inc. and other Node contributors.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
@ -47564,6 +47568,7 @@ module.exports = function (password, salt, iterations, keylen, digest, callback)
/***/ 2455: /***/ 2455:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
/* provided dependency */ var process = __webpack_require__(5606);
var defaultEncoding var defaultEncoding
/* istanbul ignore next */ /* istanbul ignore next */
if (__webpack_require__.g.process && __webpack_require__.g.process.browser) { if (__webpack_require__.g.process && __webpack_require__.g.process.browser) {
@ -47763,9 +47768,10 @@ module.exports = [
/***/ }), /***/ }),
/***/ 3225: /***/ 3225:
/***/ ((module) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
if (typeof process === 'undefined' || if (typeof process === 'undefined' ||
@ -47813,6 +47819,197 @@ function nextTick(fn, arg1, arg2, arg3) {
/***/ }),
/***/ 5606:
/***/ ((module) => {
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ }), /***/ }),
/***/ 7168: /***/ 7168:
@ -51557,6 +51754,7 @@ module.exports = function xor (a, b) {
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// limit of Crypto.getRandomValues() // limit of Crypto.getRandomValues()
@ -51615,6 +51813,7 @@ function randomBytes (size, cb) {
/***/ ((__unused_webpack_module, exports, __webpack_require__) => { /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
function oldBrowser () { function oldBrowser () {
@ -51866,6 +52065,7 @@ module.exports.F = codes;
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// Copyright Joyent, Inc. and other Node contributors. // Copyright Joyent, Inc. and other Node contributors.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
@ -52043,6 +52243,7 @@ PassThrough.prototype._transform = function (chunk, encoding, cb) {
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// Copyright Joyent, Inc. and other Node contributors. // Copyright Joyent, Inc. and other Node contributors.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
@ -53274,6 +53475,7 @@ function done(stream, er, data) {
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// Copyright Joyent, Inc. and other Node contributors. // Copyright Joyent, Inc. and other Node contributors.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
@ -53922,6 +54124,7 @@ Writable.prototype._destroy = function (err, cb) {
/***/ ((module, __unused_webpack_exports, __webpack_require__) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
var _Object$setPrototypeO; var _Object$setPrototypeO;
@ -54296,9 +54499,10 @@ module.exports = /*#__PURE__*/function () {
/***/ }), /***/ }),
/***/ 5896: /***/ 5896:
/***/ ((module) => { /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict"; "use strict";
/* provided dependency */ var process = __webpack_require__(5606);
// undocumented cb() API, needed for core, not for public API // undocumented cb() API, needed for core, not for public API
@ -56763,6 +56967,7 @@ exports.isAnyArrayBuffer = isAnyArrayBuffer;
/***/ 537: /***/ 537:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => { /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
/* provided dependency */ var process = __webpack_require__(5606);
// Copyright Joyent, Inc. and other Node contributors. // Copyright Joyent, Inc. and other Node contributors.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
@ -72273,6 +72478,7 @@ class ChaCha {
// EXTERNAL MODULE: ./node_modules/crypto-browserify/index.js // EXTERNAL MODULE: ./node_modules/crypto-browserify/index.js
var crypto_browserify = __webpack_require__(1565); var crypto_browserify = __webpack_require__(1565);
;// ./node_modules/ffjavascript/src/random.js ;// ./node_modules/ffjavascript/src/random.js
/* provided dependency */ var process = __webpack_require__(5606);
@ -75277,6 +75483,7 @@ var browser = __webpack_require__(1072);
// EXTERNAL MODULE: ./node_modules/web-worker/cjs/browser.js // EXTERNAL MODULE: ./node_modules/web-worker/cjs/browser.js
var cjs_browser = __webpack_require__(1723); var cjs_browser = __webpack_require__(1723);
;// ./node_modules/ffjavascript/src/threadman.js ;// ./node_modules/ffjavascript/src/threadman.js
/* provided dependency */ var threadman_process = __webpack_require__(5606);
/* provided dependency */ var Buffer = __webpack_require__(8287)["Buffer"]; /* provided dependency */ var Buffer = __webpack_require__(8287)["Buffer"];
/* /*
Copyright 2019 0KIMS association. Copyright 2019 0KIMS association.
@ -75321,7 +75528,7 @@ function sleep(ms) {
let workerSource; let workerSource;
const threadStr = `(${thread.toString()})(self)`; const threadStr = `(${thread.toString()})(self)`;
if(process.browser) { if(threadman_process.browser) {
if(globalThis?.Blob) { if(globalThis?.Blob) {
const threadBytes= new TextEncoder().encode(threadStr); const threadBytes= new TextEncoder().encode(threadStr);
const workerBlob = new Blob([threadBytes], { type: "application/javascript" }) ; const workerBlob = new Blob([threadBytes], { type: "application/javascript" }) ;
@ -75350,7 +75557,7 @@ async function buildThreadManager(wasm, singleThread) {
} }
}); });
if(process.browser && !globalThis?.Worker) { if(threadman_process.browser && !globalThis?.Worker) {
singleThread = true; singleThread = true;
} }
@ -75382,7 +75589,7 @@ async function buildThreadManager(wasm, singleThread) {
tm.working = []; tm.working = [];
let concurrency = 2; let concurrency = 2;
if (process.browser) { if (threadman_process.browser) {
if (typeof navigator === "object" && navigator.hardwareConcurrency) { if (typeof navigator === "object" && navigator.hardwareConcurrency) {
concurrency = navigator.hardwareConcurrency; concurrency = navigator.hardwareConcurrency;
} }
@ -106399,6 +106606,7 @@ var bn = __webpack_require__(9404);
// EXTERNAL MODULE: ./node_modules/@ensdomains/content-hash/src/index.js // EXTERNAL MODULE: ./node_modules/@ensdomains/content-hash/src/index.js
var src = __webpack_require__(1810); var src = __webpack_require__(1810);
;// ./src/utils.ts ;// ./src/utils.ts
/* provided dependency */ var utils_process = __webpack_require__(5606);
@ -106406,7 +106614,7 @@ var src = __webpack_require__(1810);
BigInt.prototype.toJSON = function() { BigInt.prototype.toJSON = function() {
return this.toString(); return this.toString();
}; };
const isNode = !process.browser && typeof globalThis.window === "undefined"; const isNode = !utils_process.browser && typeof globalThis.window === "undefined";
const utils_crypto = isNode ? crypto_browserify.webcrypto : globalThis.crypto; const utils_crypto = isNode ? crypto_browserify.webcrypto : globalThis.crypto;
const chunk = (arr, size) => [...Array(Math.ceil(arr.length / size))].map((_, i) => arr.slice(size * i, size + size * i)); const chunk = (arr, size) => [...Array(Math.ceil(arr.length / size))].map((_, i) => arr.slice(size * i, size + size * i));
function utils_sleep(ms) { function utils_sleep(ms) {

File diff suppressed because one or more lines are too long

@ -37,14 +37,6 @@ export interface TornadoInstance {
} }
export type TokenInstances = Record<string, TornadoInstance>; export type TokenInstances = Record<string, TornadoInstance>;
export interface Config { export interface Config {
rpcCallRetryAttempt?: number;
gasPrices: {
instant: number;
fast?: number;
standard?: number;
low?: number;
maxPriorityFeePerGas?: number;
};
nativeCurrency: string; nativeCurrency: string;
currencyName: string; currencyName: string;
explorerUrl: string; explorerUrl: string;
@ -65,16 +57,16 @@ export interface Config {
aggregatorContract?: string; aggregatorContract?: string;
reverseRecordsContract?: string; reverseRecordsContract?: string;
ovmGasPriceOracleContract?: string; ovmGasPriceOracleContract?: string;
tornadoSubgraph: string; tornadoSubgraph?: string;
registrySubgraph?: string; registrySubgraph?: string;
governanceSubgraph?: string; governanceSubgraph?: string;
subgraphs: SubgraphUrls; subgraphs?: SubgraphUrls;
tokens: TokenInstances; tokens: TokenInstances;
optionalTokens?: string[]; optionalTokens?: string[];
disabledTokens?: string[]; disabledTokens?: string[];
relayerEnsSubdomain: string; relayerEnsSubdomain: string;
pollInterval: number; pollInterval: number;
constants: { constants?: {
GOVERNANCE_BLOCK?: number; GOVERNANCE_BLOCK?: number;
NOTE_ACCOUNT_BLOCK?: number; NOTE_ACCOUNT_BLOCK?: number;
ENCRYPTED_NOTES_BLOCK?: number; ENCRYPTED_NOTES_BLOCK?: number;
@ -102,7 +94,6 @@ export declare function addNetwork(newConfig: networkConfig): void;
export declare function getNetworkConfig(): networkConfig; export declare function getNetworkConfig(): networkConfig;
export declare function getConfig(netId: NetIdType): Config; export declare function getConfig(netId: NetIdType): Config;
export declare function getActiveTokens(config: Config): string[]; export declare function getActiveTokens(config: Config): string[];
export declare function getActiveTokenInstances(config: Config): TokenInstances;
export declare function getInstanceByAddress(config: Config, address: string): { export declare function getInstanceByAddress(config: Config, address: string): {
amount: string; amount: string;
currency: string; currency: string;

56
dist/providers.d.ts vendored

@ -1,7 +1,6 @@
import type { EventEmitter } from 'stream'; import type { EventEmitter } from 'stream';
import type { RequestOptions } from 'http'; import { JsonRpcApiProvider, JsonRpcProvider, Wallet, FetchGetUrlFunc, Provider, SigningKey, TransactionRequest, JsonRpcSigner, BrowserProvider, Networkish, Eip1193Provider, VoidSigner, FetchCancelSignal, TransactionLike } from 'ethers';
import { JsonRpcApiProvider, JsonRpcProvider, Wallet, FetchGetUrlFunc, Provider, SigningKey, TransactionRequest, JsonRpcSigner, BrowserProvider, Networkish, Eip1193Provider, VoidSigner, FetchCancelSignal } from 'ethers'; import type { Dispatcher, RequestInit } from 'undici-types';
import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch';
import type { Config, NetIdType } from './networkConfig'; import type { Config, NetIdType } from './networkConfig';
declare global { declare global {
interface Window { interface Window {
@ -9,35 +8,54 @@ declare global {
} }
} }
export declare const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0"; export declare const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0";
export type nodeFetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>; export type DispatcherFunc = (retry?: number) => Dispatcher;
export type fetchDataOptions = RequestInit & { export interface fetchDataOptions extends Omit<RequestInit, 'headers'> {
/**
* Overriding RequestInit params
*/
headers?: HeadersInit | any; headers?: HeadersInit | any;
/**
* Expanding RequestInit params
*/
maxRetry?: number; maxRetry?: number;
retryOn?: number; retryOn?: number;
userAgent?: string; userAgent?: string;
timeout?: number; timeout?: number;
proxy?: string;
torPort?: number;
debug?: Function; debug?: Function;
returnResponse?: boolean; returnResponse?: boolean;
cancelSignal?: FetchCancelSignal; cancelSignal?: FetchCancelSignal;
}; dispatcherFunc?: DispatcherFunc;
export type NodeAgent = RequestOptions['agent'] | ((parsedUrl: URL) => RequestOptions['agent']); }
export declare function getHttpAgent({ fetchUrl, proxyUrl, torPort, retry, }: { export declare function fetchData<T>(url: string, options?: fetchDataOptions): Promise<T>;
fetchUrl: string;
proxyUrl?: string;
torPort?: number;
retry: number;
}): NodeAgent | undefined;
export declare function fetchData(url: string, options?: fetchDataOptions): Promise<any>;
export declare const fetchGetUrlFunc: (options?: fetchDataOptions) => FetchGetUrlFunc; export declare const fetchGetUrlFunc: (options?: fetchDataOptions) => FetchGetUrlFunc;
export type getProviderOptions = fetchDataOptions & { export type getProviderOptions = fetchDataOptions & {
netId?: NetIdType; netId?: NetIdType;
pollingInterval?: number; pollingInterval?: number;
}; };
export declare const FeeDataNetworkPluginName: string;
export declare function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider>; export declare function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider>;
export declare function getProviderWithNetId(netId: NetIdType, rpcUrl: string, config: Config, fetchOptions?: getProviderOptions): JsonRpcProvider; export declare function getProviderWithNetId(netId: NetIdType, rpcUrl: string, config: Config, fetchOptions?: getProviderOptions): JsonRpcProvider;
export declare const populateTransaction: (signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner, tx: TransactionRequest) => Promise<TransactionRequest>; export declare const populateTransaction: (signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner, tx: TransactionRequest) => Promise<{
type?: null | number | undefined;
to?: string | import("ethers").Addressable | null | undefined;
from?: string | import("ethers").Addressable | null | undefined;
nonce?: null | number | undefined;
gasLimit?: string | number | bigint | null | undefined;
gasPrice?: string | number | bigint | null | undefined;
maxPriorityFeePerGas?: string | number | bigint | null | undefined;
maxFeePerGas?: string | number | bigint | null | undefined;
data?: null | string | undefined;
value?: string | number | bigint | null | undefined;
chainId?: string | number | bigint | null | undefined;
accessList?: import("ethers").AccessList | [string, string[]][] | Record<string, string[]> | null | undefined;
customData?: any;
blockTag?: string | number | bigint | undefined;
enableCcipRead?: boolean | undefined;
blobVersionedHashes?: (null | Array<string>) | undefined;
maxFeePerBlobGas?: string | number | bigint | null | undefined;
blobs?: (null | Array<import("ethers").BlobLike>) | undefined;
kzg?: (null | import("ethers").KzgLibrary) | undefined;
}>;
export interface TornadoWalletOptions { export interface TornadoWalletOptions {
gasPriceBump?: number; gasPriceBump?: number;
gasLimitBump?: number; gasLimitBump?: number;
@ -53,7 +71,7 @@ export declare class TornadoWallet extends Wallet {
bumpNonce: boolean; bumpNonce: boolean;
constructor(key: string | SigningKey, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions); constructor(key: string | SigningKey, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
static fromMnemonic(mneomnic: string, provider: Provider, index?: number, options?: TornadoWalletOptions): TornadoWallet; static fromMnemonic(mneomnic: string, provider: Provider, index?: number, options?: TornadoWalletOptions): TornadoWallet;
populateTransaction(tx: TransactionRequest): Promise<import("ethers").TransactionLike<string>>; populateTransaction(tx: TransactionRequest): Promise<TransactionLike<string>>;
} }
export declare class TornadoVoidSigner extends VoidSigner { export declare class TornadoVoidSigner extends VoidSigner {
nonce?: number; nonce?: number;
@ -62,7 +80,7 @@ export declare class TornadoVoidSigner extends VoidSigner {
gasFailover: boolean; gasFailover: boolean;
bumpNonce: boolean; bumpNonce: boolean;
constructor(address: string, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions); constructor(address: string, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
populateTransaction(tx: TransactionRequest): Promise<import("ethers").TransactionLike<string>>; populateTransaction(tx: TransactionRequest): Promise<TransactionLike<string>>;
} }
export declare class TornadoRpcSigner extends JsonRpcSigner { export declare class TornadoRpcSigner extends JsonRpcSigner {
nonce?: number; nonce?: number;

@ -120,10 +120,9 @@ export declare class RelayerClient {
fetchDataOptions?: fetchDataOptions; fetchDataOptions?: fetchDataOptions;
tovarish: boolean; tovarish: boolean;
constructor({ netId, config, fetchDataOptions }: RelayerClientConstructor); constructor({ netId, config, fetchDataOptions }: RelayerClientConstructor);
askRelayerStatus({ hostname, url, relayerAddress, }: { askRelayerStatus({ hostname, url, }: {
hostname?: string; hostname?: string;
url?: string; url?: string;
relayerAddress?: string;
}): Promise<RelayerStatus>; }): Promise<RelayerStatus>;
filterRelayer(relayer: CachedRelayerInfo): Promise<RelayerInfo | RelayerError | undefined>; filterRelayer(relayer: CachedRelayerInfo): Promise<RelayerInfo | RelayerError | undefined>;
getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{ getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{

2034
dist/tornado.umd.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -45,7 +45,7 @@ export interface BaseTovarishEvents<T> {
export declare class TovarishClient extends RelayerClient { export declare class TovarishClient extends RelayerClient {
selectedRelayer?: TovarishInfo; selectedRelayer?: TovarishInfo;
constructor(clientConstructor: RelayerClientConstructor); constructor(clientConstructor: RelayerClientConstructor);
askRelayerStatus({ hostname, url, relayerAddress, }: { askRelayerStatus({ hostname, url, }: {
hostname?: string; hostname?: string;
url?: string; url?: string;
relayerAddress?: string; relayerAddress?: string;

8
dist/zip.d.ts vendored

@ -1,9 +1,13 @@
import { AsyncZippable, Unzipped, ZipAttributes } from 'fflate'; import { AsyncZippable, Unzipped, ZipAttributes, AsyncZlibOptions, AsyncUnzlibOptions } from 'fflate';
import { fetchDataOptions } from './providers';
export declare function zipAsync(file: AsyncZippable, options?: ZipAttributes): Promise<Uint8Array>; export declare function zipAsync(file: AsyncZippable, options?: ZipAttributes): Promise<Uint8Array>;
export declare function unzipAsync(data: Uint8Array): Promise<Unzipped>; export declare function unzipAsync(data: Uint8Array): Promise<Unzipped>;
export declare function downloadZip<T>({ staticUrl, zipName, zipDigest, parseJson, }: { export declare function zlibAsync(data: Uint8Array, options?: AsyncZlibOptions): Promise<Uint8Array>;
export declare function unzlibAsync(data: Uint8Array, options?: AsyncUnzlibOptions): Promise<Uint8Array>;
export declare function downloadZip<T>({ staticUrl, zipName, zipDigest, parseJson, fetchOptions, }: {
staticUrl?: string; staticUrl?: string;
zipName: string; zipName: string;
zipDigest?: string; zipDigest?: string;
parseJson?: boolean; parseJson?: boolean;
fetchOptions?: fetchDataOptions;
}): Promise<T>; }): Promise<T>;

@ -46,12 +46,10 @@
"ajv": "^8.17.1", "ajv": "^8.17.1",
"bn.js": "^5.2.1", "bn.js": "^5.2.1",
"circomlibjs": "git+https://github.com/tornadocontrib/circomlibjs.git#2aef7aade8e2b8d103250e4b24c7f1526cf1dd8d", "circomlibjs": "git+https://github.com/tornadocontrib/circomlibjs.git#2aef7aade8e2b8d103250e4b24c7f1526cf1dd8d",
"cross-fetch": "^4.1.0",
"ethers": "^6.13.4", "ethers": "^6.13.4",
"ffjavascript": "git+https://github.com/tornadocontrib/ffjavascript.git#fc766f09818d46967d1329c0fc8e361d8b349109", "ffjavascript": "git+https://github.com/tornadocontrib/ffjavascript.git#fc766f09818d46967d1329c0fc8e361d8b349109",
"fflate": "^0.8.2", "fflate": "^0.8.2",
"fixed-merkle-tree": "0.7.3", "fixed-merkle-tree": "0.7.3",
"idb": "^8.0.1",
"snarkjs": "git+https://github.com/tornadocontrib/snarkjs.git#2c964b3fe6019e057acab04cc17705d1f7fdaf9a", "snarkjs": "git+https://github.com/tornadocontrib/snarkjs.git#2c964b3fe6019e057acab04cc17705d1f7fdaf9a",
"tornado-contracts": "git+https://github.com/tornadocontrib/tornado-contracts.git#9be1e1c308ae891e939944b2220d9e2810e579f5", "tornado-contracts": "git+https://github.com/tornadocontrib/tornado-contracts.git#9be1e1c308ae891e939944b2220d9e2810e579f5",
"websnark": "git+https://github.com/tornadocontrib/websnark.git#e5a79cca905d1ffb61a69739492be58d438c9f17" "websnark": "git+https://github.com/tornadocontrib/websnark.git#e5a79cca905d1ffb61a69739492be58d438c9f17"
@ -74,7 +72,6 @@
"@types/circomlibjs": "^0.1.6", "@types/circomlibjs": "^0.1.6",
"@types/mocha": "^10.0.10", "@types/mocha": "^10.0.10",
"@types/node": "^22.10.2", "@types/node": "^22.10.2",
"@types/node-fetch": "^2.6.12",
"chai": "^4.5.0", "chai": "^4.5.0",
"esbuild-loader": "^4.2.2", "esbuild-loader": "^4.2.2",
"eslint": "^9.17.0", "eslint": "^9.17.0",
@ -85,6 +82,7 @@
"fetch-mock": "^12.2.0", "fetch-mock": "^12.2.0",
"hardhat": "^2.22.17", "hardhat": "^2.22.17",
"hardhat-gas-reporter": "^2.2.2", "hardhat-gas-reporter": "^2.2.2",
"idb": "^8.0.1",
"mocha": "^11.0.1", "mocha": "^11.0.1",
"node-polyfill-webpack-plugin": "^4.1.0", "node-polyfill-webpack-plugin": "^4.1.0",
"nyc": "^17.1.0", "nyc": "^17.1.0",

@ -76,7 +76,8 @@ export class ENSUtils {
async getContracts() { async getContracts() {
const { chainId } = await this.provider.getNetwork(); const { chainId } = await this.provider.getNetwork();
const { ensRegistry, ensPublicResolver, ensNameWrapper } = EnsContracts[Number(chainId)]; const { ensRegistry, ensPublicResolver, ensNameWrapper } =
EnsContracts[Number(chainId)] || EnsContracts[NetId.MAINNET];
this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider); this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider);
this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider); this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider);

@ -1098,7 +1098,7 @@ export async function getTovarishNetworks(registryService: BaseRegistryService,
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
timeout: 30000, timeout: 30000,
maxRetry: registryService.fetchDataOptions?.torPort ? 2 : 0, maxRetry: registryService.fetchDataOptions?.dispatcher ? 2 : 0,
}); });
} catch { } catch {
// Ignore error and disable relayer // Ignore error and disable relayer

@ -471,7 +471,7 @@ export class DBRegistryService extends BaseRegistryService {
const url = `${this.staticUrl}/relayers.json`; const url = `${this.staticUrl}/relayers.json`;
try { try {
const resp = await fetchData(url, { const resp = await fetchData<Response>(url, {
method: 'GET', method: 'GET',
returnResponse: true, returnResponse: true,
}); });

@ -62,7 +62,8 @@ export async function queryGraph<T>({
}: queryGraphParams): Promise<T> { }: queryGraphParams): Promise<T> {
const graphUrl = `${graphApi}/subgraphs/name/${subgraphName}`; const graphUrl = `${graphApi}/subgraphs/name/${subgraphName}`;
const { data, errors } = await fetchData(graphUrl, { // eslint-disable-next-line @typescript-eslint/no-explicit-any
const { data, errors } = await fetchData<{ data: T & { _meta: any }; errors: any }>(graphUrl, {
...fetchDataOptions, ...fetchDataOptions,
method: 'POST', method: 'POST',
headers: { headers: {

@ -1,7 +1,14 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any, import/no-duplicates */
import { openDB, deleteDB, OpenDBCallbacks, IDBPDatabase } from 'idb'; import type * as idb from 'idb';
import type { OpenDBCallbacks, IDBPDatabase } from 'idb';
import { getConfig, NetIdType } from './networkConfig'; import { getConfig, NetIdType } from './networkConfig';
declare global {
interface Window {
idb: typeof idb;
}
}
export const INDEX_DB_ERROR = 'A mutation operation was attempted on a database that did not allow mutations.'; export const INDEX_DB_ERROR = 'A mutation operation was attempted on a database that did not allow mutations.';
export interface IDBIndex { export interface IDBIndex {
@ -64,7 +71,7 @@ export class IndexedDB {
return; return;
} }
this.db = await openDB(this.dbName, this.dbVersion, this.options); this.db = await window?.idb?.openDB(this.dbName, this.dbVersion, this.options);
this.db.addEventListener('onupgradeneeded', async () => { this.db.addEventListener('onupgradeneeded', async () => {
await this._removeExist(); await this._removeExist();
}); });
@ -89,7 +96,7 @@ export class IndexedDB {
} }
async _removeExist() { async _removeExist() {
await deleteDB(this.dbName); await window?.idb?.deleteDB(this.dbName);
this.dbExists = false; this.dbExists = false;
await this.initDB(); await this.initDB();

@ -1,14 +1,17 @@
import { fetchData } from './providers'; import { fetchData, fetchDataOptions } from './providers';
export interface IPResult { export interface IPResult {
ip: string; ip: string;
iso?: string; iso?: string;
country?: string;
country_iso?: string;
tor?: boolean; tor?: boolean;
} }
export async function fetchIp(ipEcho: string) { export function fetchIp(ipEcho: string, fetchOptions?: fetchDataOptions) {
return (await fetchData(ipEcho, { return fetchData<IPResult>(ipEcho, {
...(fetchOptions || {}),
method: 'GET', method: 'GET',
timeout: 30000, timeout: 30000,
})) as IPResult; });
} }

@ -46,17 +46,6 @@ export interface TornadoInstance {
export type TokenInstances = Record<string, TornadoInstance>; export type TokenInstances = Record<string, TornadoInstance>;
export interface Config { export interface Config {
rpcCallRetryAttempt?: number;
// Should be in gwei
gasPrices: {
// fallback gasPrice / maxFeePerGas value
instant: number;
fast?: number;
standard?: number;
low?: number;
// fallback EIP-1559 params
maxPriorityFeePerGas?: number;
};
nativeCurrency: string; nativeCurrency: string;
currencyName: string; currencyName: string;
explorerUrl: string; explorerUrl: string;
@ -78,17 +67,17 @@ export interface Config {
aggregatorContract?: string; aggregatorContract?: string;
reverseRecordsContract?: string; reverseRecordsContract?: string;
ovmGasPriceOracleContract?: string; ovmGasPriceOracleContract?: string;
tornadoSubgraph: string; tornadoSubgraph?: string;
registrySubgraph?: string; registrySubgraph?: string;
governanceSubgraph?: string; governanceSubgraph?: string;
subgraphs: SubgraphUrls; subgraphs?: SubgraphUrls;
tokens: TokenInstances; tokens: TokenInstances;
optionalTokens?: string[]; optionalTokens?: string[];
disabledTokens?: string[]; disabledTokens?: string[];
relayerEnsSubdomain: string; relayerEnsSubdomain: string;
// Should be in seconds // Should be in seconds
pollInterval: number; pollInterval: number;
constants: { constants?: {
GOVERNANCE_BLOCK?: number; GOVERNANCE_BLOCK?: number;
NOTE_ACCOUNT_BLOCK?: number; NOTE_ACCOUNT_BLOCK?: number;
ENCRYPTED_NOTES_BLOCK?: number; ENCRYPTED_NOTES_BLOCK?: number;
@ -104,13 +93,6 @@ export type SubdomainMap = Record<NetIdType, string>;
export const defaultConfig: networkConfig = { export const defaultConfig: networkConfig = {
[NetId.MAINNET]: { [NetId.MAINNET]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 80,
fast: 50,
standard: 25,
low: 8,
},
nativeCurrency: 'eth', nativeCurrency: 'eth',
currencyName: 'ETH', currencyName: 'ETH',
explorerUrl: 'https://etherscan.io', explorerUrl: 'https://etherscan.io',
@ -123,9 +105,9 @@ export const defaultConfig: networkConfig = {
name: 'MEV Blocker', name: 'MEV Blocker',
url: 'https://rpc.mevblocker.io', url: 'https://rpc.mevblocker.io',
}, },
tornadoWithdraw: { tornadoRpc: {
name: 'Tornado Withdraw', name: 'Tornado RPC',
url: 'https://tornadowithdraw.com/mainnet', url: 'https://tornadocash-rpc.com/mainnet',
}, },
keydonix: { keydonix: {
name: 'Horswap ( Keydonix )', name: 'Horswap ( Keydonix )',
@ -244,13 +226,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.BSC]: { [NetId.BSC]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 3,
fast: 1,
standard: 1,
low: 1,
},
nativeCurrency: 'bnb', nativeCurrency: 'bnb',
currencyName: 'BNB', currencyName: 'BNB',
explorerUrl: 'https://bscscan.com', explorerUrl: 'https://bscscan.com',
@ -274,9 +249,9 @@ export const defaultConfig: networkConfig = {
name: 'BNB Chain 2', name: 'BNB Chain 2',
url: 'https://bsc-dataseed1.ninicoin.io', url: 'https://bsc-dataseed1.ninicoin.io',
}, },
tornadoWithdraw: { tornadoRpc: {
name: 'Tornado Withdraw', name: 'Tornado RPC',
url: 'https://tornadowithdraw.com/bsc', url: 'https://tornadocash-rpc.com/bsc',
}, },
nodereal: { nodereal: {
name: 'NodeReal', name: 'NodeReal',
@ -340,13 +315,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.POLYGON]: { [NetId.POLYGON]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 60,
fast: 30,
standard: 30,
low: 30,
},
nativeCurrency: 'matic', nativeCurrency: 'matic',
currencyName: 'MATIC', currencyName: 'MATIC',
explorerUrl: 'https://polygonscan.com', explorerUrl: 'https://polygonscan.com',
@ -362,9 +330,9 @@ export const defaultConfig: networkConfig = {
tornadoSubgraph: 'tornadocash/matic-tornado-subgraph', tornadoSubgraph: 'tornadocash/matic-tornado-subgraph',
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { lavaBuild: {
name: 'Tornado Withdraw', name: 'polygon.lava.build',
url: 'https://tornadowithdraw.com/polygon', url: 'https://polygon.lava.build',
}, },
polygon: { polygon: {
name: 'Polygon', name: 'Polygon',
@ -399,13 +367,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.OPTIMISM]: { [NetId.OPTIMISM]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.001,
fast: 0.001,
standard: 0.001,
low: 0.001,
},
nativeCurrency: 'eth', nativeCurrency: 'eth',
currencyName: 'ETH', currencyName: 'ETH',
explorerUrl: 'https://optimistic.etherscan.io', explorerUrl: 'https://optimistic.etherscan.io',
@ -422,9 +383,9 @@ export const defaultConfig: networkConfig = {
tornadoSubgraph: 'tornadocash/optimism-tornado-subgraph', tornadoSubgraph: 'tornadocash/optimism-tornado-subgraph',
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { lavaBuild: {
name: 'Tornado Withdraw', name: 'optimism.lava.build',
url: 'https://tornadowithdraw.com/op', url: 'https://optimism.lava.build',
}, },
optimism: { optimism: {
name: 'Optimism', name: 'Optimism',
@ -462,13 +423,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.ARBITRUM]: { [NetId.ARBITRUM]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.02,
fast: 0.02,
standard: 0.02,
low: 0.02,
},
nativeCurrency: 'eth', nativeCurrency: 'eth',
currencyName: 'ETH', currencyName: 'ETH',
explorerUrl: 'https://arbiscan.io', explorerUrl: 'https://arbiscan.io',
@ -488,10 +442,6 @@ export const defaultConfig: networkConfig = {
name: 'Arbitrum', name: 'Arbitrum',
url: 'https://arb1.arbitrum.io/rpc', url: 'https://arb1.arbitrum.io/rpc',
}, },
tornadoWithdraw: {
name: 'Tornado Withdraw',
url: 'https://tornadowithdraw.com/arbitrum',
},
stackup: { stackup: {
name: 'Stackup', name: 'Stackup',
url: 'https://public.stackup.sh/api/v1/node/arbitrum-one', url: 'https://public.stackup.sh/api/v1/node/arbitrum-one',
@ -524,13 +474,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.BASE]: { [NetId.BASE]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.1,
fast: 0.06,
standard: 0.05,
low: 0.02,
},
nativeCurrency: 'eth', nativeCurrency: 'eth',
currencyName: 'ETH', currencyName: 'ETH',
explorerUrl: 'https://basescan.org', explorerUrl: 'https://basescan.org',
@ -551,10 +494,6 @@ export const defaultConfig: networkConfig = {
name: 'Base', name: 'Base',
url: 'https://mainnet.base.org', url: 'https://mainnet.base.org',
}, },
tornadoWithdraw: {
name: 'Tornado Withdraw',
url: 'https://tornadowithdraw.com/base',
},
stackup: { stackup: {
name: 'Stackup', name: 'Stackup',
url: 'https://public.stackup.sh/api/v1/node/base-mainnet', url: 'https://public.stackup.sh/api/v1/node/base-mainnet',
@ -616,13 +555,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.BLAST]: { [NetId.BLAST]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 0.001,
fast: 0.001,
standard: 0.001,
low: 0.001,
},
nativeCurrency: 'eth', nativeCurrency: 'eth',
currencyName: 'ETH', currencyName: 'ETH',
explorerUrl: 'https://blastscan.io', explorerUrl: 'https://blastscan.io',
@ -642,10 +574,6 @@ export const defaultConfig: networkConfig = {
name: 'Blast', name: 'Blast',
url: 'https://rpc.blast.io', url: 'https://rpc.blast.io',
}, },
tornadoWithdraw: {
name: 'Tornado Withdraw',
url: 'https://tornadowithdraw.com/blast',
},
blastApi: { blastApi: {
name: 'BlastApi', name: 'BlastApi',
url: 'https://blastl2-mainnet.public.blastapi.io', url: 'https://blastl2-mainnet.public.blastapi.io',
@ -673,13 +601,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.GNOSIS]: { [NetId.GNOSIS]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 6,
fast: 5,
standard: 4,
low: 1,
},
nativeCurrency: 'xdai', nativeCurrency: 'xdai',
currencyName: 'xDAI', currencyName: 'xDAI',
explorerUrl: 'https://gnosisscan.io', explorerUrl: 'https://gnosisscan.io',
@ -699,9 +620,13 @@ export const defaultConfig: networkConfig = {
name: 'Gnosis', name: 'Gnosis',
url: 'https://rpc.gnosischain.com', url: 'https://rpc.gnosischain.com',
}, },
tornadoWithdraw: { tornadoRpc: {
name: 'Tornado Withdraw', name: 'Tornado RPC',
url: 'https://tornadowithdraw.com/gnosis', url: 'https://tornadocash-rpc.com/gnosis',
},
blastApi: {
name: 'BlastApi',
url: 'https://gnosis-mainnet.public.blastapi.io',
}, },
oneRpc: { oneRpc: {
name: '1RPC', name: '1RPC',
@ -728,13 +653,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.AVALANCHE]: { [NetId.AVALANCHE]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 225,
fast: 35,
standard: 25,
low: 25,
},
nativeCurrency: 'avax', nativeCurrency: 'avax',
currencyName: 'AVAX', currencyName: 'AVAX',
explorerUrl: 'https://snowtrace.io', explorerUrl: 'https://snowtrace.io',
@ -750,9 +668,9 @@ export const defaultConfig: networkConfig = {
tornadoSubgraph: 'tornadocash/avalanche-tornado-subgraph', tornadoSubgraph: 'tornadocash/avalanche-tornado-subgraph',
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { blastApi: {
name: 'Tornado Withdraw', name: 'BlastApi',
url: 'https://tornadowithdraw.com/ext/bc/C/rpc', url: 'https://ava-mainnet.public.blastapi.io/ext/bc/C/rpc',
}, },
oneRpc: { oneRpc: {
name: '1RPC', name: '1RPC',
@ -786,13 +704,6 @@ export const defaultConfig: networkConfig = {
}, },
}, },
[NetId.SEPOLIA]: { [NetId.SEPOLIA]: {
rpcCallRetryAttempt: 15,
gasPrices: {
instant: 2,
fast: 2,
standard: 2,
low: 2,
},
nativeCurrency: 'eth', nativeCurrency: 'eth',
currencyName: 'SepoliaETH', currencyName: 'SepoliaETH',
explorerUrl: 'https://sepolia.etherscan.io', explorerUrl: 'https://sepolia.etherscan.io',
@ -814,9 +725,13 @@ export const defaultConfig: networkConfig = {
tornadoSubgraph: 'tornadocash/sepolia-tornado-subgraph', tornadoSubgraph: 'tornadocash/sepolia-tornado-subgraph',
subgraphs: {}, subgraphs: {},
rpcUrls: { rpcUrls: {
tornadoWithdraw: { blastApi: {
name: 'Tornado Withdraw', name: 'BlastApi',
url: 'https://tornadowithdraw.com/sepolia', url: 'https://eth-sepolia.public.blastapi.io',
},
tornadoRpc: {
name: 'Tornado RPC',
url: 'https://tornadocash-rpc.com/sepolia',
}, },
oneRpc: { oneRpc: {
name: '1RPC', name: '1RPC',
@ -932,17 +847,6 @@ export function getActiveTokens(config: Config): string[] {
return Object.keys(tokens).filter((t) => !disabledTokens?.includes(t)); return Object.keys(tokens).filter((t) => !disabledTokens?.includes(t));
} }
export function getActiveTokenInstances(config: Config): TokenInstances {
const { tokens, disabledTokens } = config;
return Object.entries(tokens).reduce((acc, [token, instances]) => {
if (!disabledTokens?.includes(token)) {
acc[token] = instances;
}
return acc;
}, {} as TokenInstances);
}
export function getInstanceByAddress(config: Config, address: string) { export function getInstanceByAddress(config: Config, address: string) {
const { tokens, disabledTokens } = config; const { tokens, disabledTokens } = config;

@ -1,6 +1,4 @@
import type { EventEmitter } from 'stream'; import type { EventEmitter } from 'stream';
import type { RequestOptions } from 'http';
import crossFetch from 'cross-fetch';
import { import {
FetchRequest, FetchRequest,
JsonRpcApiProvider, JsonRpcApiProvider,
@ -20,10 +18,13 @@ import {
EnsPlugin, EnsPlugin,
GasCostPlugin, GasCostPlugin,
FetchCancelSignal, FetchCancelSignal,
resolveProperties,
TransactionLike,
FetchUrlFeeDataNetworkPlugin,
FeeData,
} from 'ethers'; } from 'ethers';
import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch'; import type { Dispatcher, RequestInit, fetch as undiciFetch } from 'undici-types';
// Temporary workaround until @types/node-fetch is compatible with @types/node
import type { AbortSignal as FetchAbortSignal } from 'node-fetch/externals';
import { isNode, sleep } from './utils'; import { isNode, sleep } from './utils';
import type { Config, NetIdType } from './networkConfig'; import type { Config, NetIdType } from './networkConfig';
@ -36,73 +37,34 @@ declare global {
// Update this for every Tor Browser release // Update this for every Tor Browser release
export const defaultUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0'; export const defaultUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0';
export type nodeFetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>; export type DispatcherFunc = (retry?: number) => Dispatcher;
export type fetchDataOptions = RequestInit & { export interface fetchDataOptions extends Omit<RequestInit, 'headers'> {
/**
* Overriding RequestInit params
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
headers?: HeadersInit | any; headers?: HeadersInit | any;
/**
* Expanding RequestInit params
*/
maxRetry?: number; maxRetry?: number;
retryOn?: number; retryOn?: number;
userAgent?: string; userAgent?: string;
timeout?: number; timeout?: number;
proxy?: string;
torPort?: number;
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
debug?: Function; debug?: Function;
returnResponse?: boolean; returnResponse?: boolean;
cancelSignal?: FetchCancelSignal; cancelSignal?: FetchCancelSignal;
}; dispatcherFunc?: DispatcherFunc;
export type NodeAgent = RequestOptions['agent'] | ((parsedUrl: URL) => RequestOptions['agent']);
export function getHttpAgent({
fetchUrl,
proxyUrl,
torPort,
retry,
}: {
fetchUrl: string;
proxyUrl?: string;
torPort?: number;
retry: number;
}): NodeAgent | undefined {
/* eslint-disable @typescript-eslint/no-require-imports */
const { HttpProxyAgent } = require('http-proxy-agent');
const { HttpsProxyAgent } = require('https-proxy-agent');
const { SocksProxyAgent } = require('socks-proxy-agent');
/* eslint-enable @typescript-eslint/no-require-imports */
if (torPort) {
return new SocksProxyAgent(`socks5h://tor${retry}@127.0.0.1:${torPort}`);
}
if (!proxyUrl) {
return;
}
const isHttps = fetchUrl.includes('https://');
if (proxyUrl.includes('socks://') || proxyUrl.includes('socks4://') || proxyUrl.includes('socks5://')) {
return new SocksProxyAgent(proxyUrl);
}
if (proxyUrl.includes('http://') || proxyUrl.includes('https://')) {
if (isHttps) {
return new HttpsProxyAgent(proxyUrl);
}
return new HttpProxyAgent(proxyUrl);
}
} }
export async function fetchData(url: string, options: fetchDataOptions = {}) { export async function fetchData<T>(url: string, options: fetchDataOptions = {}): Promise<T> {
const MAX_RETRY = options.maxRetry ?? 3; const MAX_RETRY = options.maxRetry ?? 3;
const RETRY_ON = options.retryOn ?? 500; const RETRY_ON = options.retryOn ?? 500;
const userAgent = options.userAgent ?? defaultUserAgent; const userAgent = options.userAgent ?? defaultUserAgent;
const fetch = ((globalThis as unknown as { useGlobalFetch?: boolean }).useGlobalFetch
? globalThis.fetch
: crossFetch) as unknown as nodeFetch;
let retry = 0; let retry = 0;
let errorObject; let errorObject;
@ -122,14 +84,17 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
options.headers['User-Agent'] = userAgent; options.headers['User-Agent'] = userAgent;
} }
if (typeof globalThis.fetch !== 'function') {
throw new Error('Fetch API is not available, use latest browser or nodejs installation!');
}
while (retry < MAX_RETRY + 1) { while (retry < MAX_RETRY + 1) {
let timeout; let timeout;
if (!options.signal && options.timeout) { if (!options.signal && options.timeout) {
const controller = new AbortController(); const controller = new AbortController();
// Temporary workaround until @types/node-fetch is compatible with @types/node options.signal = controller.signal;
options.signal = controller.signal as FetchAbortSignal;
// Define timeout in seconds // Define timeout in seconds
timeout = setTimeout(() => { timeout = setTimeout(() => {
@ -149,16 +114,7 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
} }
} }
if (!options.agent && isNode && (options.proxy || options.torPort)) { if (typeof options.debug === 'function') {
options.agent = getHttpAgent({
fetchUrl: url,
proxyUrl: options.proxy,
torPort: options.torPort,
retry,
});
}
if (options.debug && typeof options.debug === 'function') {
options.debug('request', { options.debug('request', {
url, url,
retry, retry,
@ -168,13 +124,11 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
} }
try { try {
const resp = await fetch(url, { const dispatcher = options.dispatcherFunc ? options.dispatcherFunc(retry) : options.dispatcher;
method: options.method,
headers: options.headers, const resp = await (globalThis.fetch as unknown as typeof undiciFetch)(url, {
body: options.body, ...options,
redirect: options.redirect, dispatcher,
signal: options.signal,
agent: options.agent,
}); });
if (options.debug && typeof options.debug === 'function') { if (options.debug && typeof options.debug === 'function') {
@ -187,23 +141,23 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
} }
if (options.returnResponse) { if (options.returnResponse) {
return resp; return resp as T;
} }
const contentType = resp.headers.get('content-type'); const contentType = resp.headers.get('content-type');
// If server returns JSON object, parse it and return as an object // If server returns JSON object, parse it and return as an object
if (contentType?.includes('application/json')) { if (contentType?.includes('application/json')) {
return await resp.json(); return (await resp.json()) as T;
} }
// Else if the server returns text parse it as a string // Else if the server returns text parse it as a string
if (contentType?.includes('text')) { if (contentType?.includes('text')) {
return await resp.text(); return (await resp.text()) as T;
} }
// Return as a response object https://developer.mozilla.org/en-US/docs/Web/API/Response // Return as a response object https://developer.mozilla.org/en-US/docs/Web/API/Response
return resp; return resp as T;
} catch (error) { } catch (error) {
if (timeout) { if (timeout) {
clearTimeout(timeout); clearTimeout(timeout);
@ -242,7 +196,7 @@ export const fetchGetUrlFunc =
returnResponse: true, returnResponse: true,
}; };
const resp = await fetchData(req.url, init); const resp = await fetchData<Response>(req.url, init);
const headers = {} as Record<string, any>; const headers = {} as Record<string, any>;
resp.headers.forEach((value: any, key: string) => { resp.headers.forEach((value: any, key: string) => {
@ -267,20 +221,36 @@ export type getProviderOptions = fetchDataOptions & {
pollingInterval?: number; pollingInterval?: number;
}; };
export const FeeDataNetworkPluginName = new FetchUrlFeeDataNetworkPlugin(
'',
() => new Promise((resolve) => resolve(new FeeData())),
).name;
export async function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider> { export async function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider> {
// Use our own fetchGetUrlFunc to support proxies and retries
const fetchReq = new FetchRequest(rpcUrl); const fetchReq = new FetchRequest(rpcUrl);
fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions); fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions);
const staticNetwork = await new JsonRpcProvider(fetchReq).getNetwork(); const fetchedNetwork = await new JsonRpcProvider(fetchReq).getNetwork();
const chainId = Number(staticNetwork.chainId); // Audit if we are connected to right network
const chainId = Number(fetchedNetwork.chainId);
if (fetchOptions?.netId && fetchOptions.netId !== chainId) { if (fetchOptions?.netId && fetchOptions.netId !== chainId) {
const errMsg = `Wrong network for ${rpcUrl}, wants ${fetchOptions.netId} got ${chainId}`; const errMsg = `Wrong network for ${rpcUrl}, wants ${fetchOptions.netId} got ${chainId}`;
throw new Error(errMsg); throw new Error(errMsg);
} }
// Clone to new network to exclude polygon gas station plugin
const staticNetwork = new Network(fetchedNetwork.name, fetchedNetwork.chainId);
fetchedNetwork.plugins.forEach((plugin) => {
if (plugin.name !== FeeDataNetworkPluginName) {
staticNetwork.attachPlugin(plugin.clone());
}
});
return new JsonRpcProvider(fetchReq, staticNetwork, { return new JsonRpcProvider(fetchReq, staticNetwork, {
staticNetwork, staticNetwork,
pollingInterval: fetchOptions?.pollingInterval || 1000, pollingInterval: fetchOptions?.pollingInterval || 1000,
@ -327,7 +297,7 @@ export const populateTransaction = async (
const [feeData, nonce] = await Promise.all([ const [feeData, nonce] = await Promise.all([
tx.maxFeePerGas || tx.gasPrice ? undefined : provider.getFeeData(), tx.maxFeePerGas || tx.gasPrice ? undefined : provider.getFeeData(),
tx.nonce ? undefined : provider.getTransactionCount(signer.address, 'pending'), tx.nonce || tx.nonce === 0 ? undefined : provider.getTransactionCount(signer.address, 'pending'),
]); ]);
if (feeData) { if (feeData) {
@ -350,7 +320,7 @@ export const populateTransaction = async (
} }
} }
if (nonce) { if (nonce || nonce === 0) {
tx.nonce = nonce; tx.nonce = nonce;
} }
@ -373,7 +343,7 @@ export const populateTransaction = async (
} }
} }
return tx; return resolveProperties(tx);
}; };
export interface TornadoWalletOptions { export interface TornadoWalletOptions {
@ -414,8 +384,7 @@ export class TornadoWallet extends Wallet {
async populateTransaction(tx: TransactionRequest) { async populateTransaction(tx: TransactionRequest) {
const txObject = await populateTransaction(this, tx); const txObject = await populateTransaction(this, tx);
this.nonce = Number(txObject.nonce); this.nonce = Number(txObject.nonce);
return txObject as Promise<TransactionLike<string>>;
return super.populateTransaction(txObject);
} }
} }
@ -443,8 +412,7 @@ export class TornadoVoidSigner extends VoidSigner {
async populateTransaction(tx: TransactionRequest) { async populateTransaction(tx: TransactionRequest) {
const txObject = await populateTransaction(this, tx); const txObject = await populateTransaction(this, tx);
this.nonce = Number(txObject.nonce); this.nonce = Number(txObject.nonce);
return txObject as Promise<TransactionLike<string>>;
return super.populateTransaction(txObject);
} }
} }

@ -1,6 +1,6 @@
import { getAddress, parseEther } from 'ethers'; import { getAddress, parseEther } from 'ethers';
import { sleep } from './utils'; import { sleep } from './utils';
import { NetId, NetIdType, Config } from './networkConfig'; import { NetIdType, Config } from './networkConfig';
import { fetchData, fetchDataOptions } from './providers'; import { fetchData, fetchDataOptions } from './providers';
import { ajv, jobsSchema, jobRequestSchema, getStatusSchema } from './schemas'; import { ajv, jobsSchema, jobRequestSchema, getStatusSchema } from './schemas';
import type { snarkProofs } from './websnark'; import type { snarkProofs } from './websnark';
@ -196,13 +196,10 @@ export class RelayerClient {
async askRelayerStatus({ async askRelayerStatus({
hostname, hostname,
url, url,
relayerAddress,
}: { }: {
hostname?: string; hostname?: string;
// optional url if entered manually // optional url if entered manually
url?: string; url?: string;
// relayerAddress from registry contract to prevent cheating
relayerAddress?: string;
}): Promise<RelayerStatus> { }): Promise<RelayerStatus> {
if (!url && hostname) { if (!url && hostname) {
url = `https://${!hostname.endsWith('/') ? hostname + '/' : hostname}`; url = `https://${!hostname.endsWith('/') ? hostname + '/' : hostname}`;
@ -212,14 +209,14 @@ export class RelayerClient {
url = ''; url = '';
} }
const rawStatus = (await fetchData(`${url}status`, { const rawStatus = await fetchData<RelayerStatus>(`${url}status`, {
...this.fetchDataOptions, ...this.fetchDataOptions,
headers: { headers: {
'Content-Type': 'application/json, application/x-www-form-urlencoded', 'Content-Type': 'application/json, application/x-www-form-urlencoded',
}, },
timeout: 30000, timeout: 30000,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0, maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0,
})) as object; });
const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish)); const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish));
@ -240,9 +237,11 @@ export class RelayerClient {
throw new Error('This relayer serves a different network'); throw new Error('This relayer serves a different network');
} }
/**
if (relayerAddress && this.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) { if (relayerAddress && this.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) {
throw new Error('The Relayer reward address must match registered address'); throw new Error('The Relayer reward address must match registered address');
} }
**/
return status; return status;
} }
@ -258,7 +257,6 @@ export class RelayerClient {
try { try {
const status = await this.askRelayerStatus({ const status = await this.askRelayerStatus({
hostname, hostname,
relayerAddress,
}); });
return { return {
@ -325,7 +323,7 @@ export class RelayerClient {
* Request new job * Request new job
*/ */
const withdrawResponse = (await fetchData(`${url}v1/tornadoWithdraw`, { const withdrawResponse = await fetchData<RelayerTornadoWithdraw>(`${url}v1/tornadoWithdraw`, {
...this.fetchDataOptions, ...this.fetchDataOptions,
method: 'POST', method: 'POST',
headers: { headers: {
@ -336,7 +334,7 @@ export class RelayerClient {
proof, proof,
args, args,
}), }),
})) as RelayerTornadoWithdraw; });
const { id, error } = withdrawResponse; const { id, error } = withdrawResponse;
@ -366,7 +364,7 @@ export class RelayerClient {
console.log(`Job submitted: ${jobUrl}\n`); console.log(`Job submitted: ${jobUrl}\n`);
while (!relayerStatus || !['FAILED', 'CONFIRMED'].includes(relayerStatus)) { while (!relayerStatus || !['FAILED', 'CONFIRMED'].includes(relayerStatus)) {
const jobResponse = await fetchData(jobUrl, { const jobResponse = await fetchData<RelayerTornadoJobs>(jobUrl, {
...this.fetchDataOptions, ...this.fetchDataOptions,
method: 'GET', method: 'GET',
headers: { headers: {
@ -385,7 +383,7 @@ export class RelayerClient {
throw new Error(errMsg); throw new Error(errMsg);
} }
const { status, txHash, confirmations, failedReason } = jobResponse as unknown as RelayerTornadoJobs; const { status, txHash, confirmations, failedReason } = jobResponse;
if (relayerStatus !== status) { if (relayerStatus !== status) {
if (status === 'FAILED') { if (status === 'FAILED') {

@ -78,7 +78,6 @@ export class TovarishClient extends RelayerClient {
async askRelayerStatus({ async askRelayerStatus({
hostname, hostname,
url, url,
relayerAddress,
}: { }: {
hostname?: string; hostname?: string;
// optional url if entered manually // optional url if entered manually
@ -89,7 +88,6 @@ export class TovarishClient extends RelayerClient {
const status = (await super.askRelayerStatus({ const status = (await super.askRelayerStatus({
hostname, hostname,
url, url,
relayerAddress,
})) as TovarishStatus; })) as TovarishStatus;
if (!status.version.includes('tovarish')) { if (!status.version.includes('tovarish')) {
@ -121,14 +119,14 @@ export class TovarishClient extends RelayerClient {
url = ''; url = '';
} }
const statusArray = (await fetchData(`${url}status`, { const statusArray = await fetchData<TovarishStatus[]>(`${url}status`, {
...this.fetchDataOptions, ...this.fetchDataOptions,
headers: { headers: {
'Content-Type': 'application/json, application/x-www-form-urlencoded', 'Content-Type': 'application/json, application/x-www-form-urlencoded',
}, },
timeout: 30000, timeout: 30000,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0, maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0,
})) as object; });
if (!Array.isArray(statusArray)) { if (!Array.isArray(statusArray)) {
return []; return [];
@ -137,27 +135,19 @@ export class TovarishClient extends RelayerClient {
const tovarishStatus: TovarishStatus[] = []; const tovarishStatus: TovarishStatus[] = [];
for (const rawStatus of statusArray) { for (const rawStatus of statusArray) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any const netId = rawStatus?.netId as NetIdType;
const netId = (rawStatus as any).netId as NetIdType;
const config = getConfig(netId); const config = getConfig(netId);
const statusValidator = ajv.compile( const statusValidator = ajv.compile(getStatusSchema(rawStatus?.netId, config, this.tovarish));
getStatusSchema(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(rawStatus as any).netId,
config,
this.tovarish,
),
);
if (!statusValidator) { if (!statusValidator(rawStatus)) {
continue; continue;
} }
const status = { const status = {
...rawStatus, ...rawStatus,
url: `${url}${netId}/`, url: `${url}${netId}/`,
} as TovarishStatus; };
if (status.currentQueue > 5) { if (status.currentQueue > 5) {
throw new Error('Withdrawal queue is overloaded'); throw new Error('Withdrawal queue is overloaded');

@ -1,5 +1,15 @@
import { zip, unzip, AsyncZippable, Unzipped, ZipAttributes } from 'fflate'; import {
import { fetchData } from './providers'; zip,
unzip,
AsyncZippable,
Unzipped,
ZipAttributes,
zlib,
unzlib,
AsyncZlibOptions,
AsyncUnzlibOptions,
} from 'fflate';
import { fetchData, fetchDataOptions } from './providers';
import { bytesToBase64, digest } from './utils'; import { bytesToBase64, digest } from './utils';
export function zipAsync(file: AsyncZippable, options?: ZipAttributes): Promise<Uint8Array> { export function zipAsync(file: AsyncZippable, options?: ZipAttributes): Promise<Uint8Array> {
@ -26,20 +36,47 @@ export function unzipAsync(data: Uint8Array): Promise<Unzipped> {
}); });
} }
export function zlibAsync(data: Uint8Array, options?: AsyncZlibOptions): Promise<Uint8Array> {
return new Promise((res, rej) => {
zlib(data, { ...(options || {}) }, (err, data) => {
if (err) {
rej(err);
return;
}
res(data);
});
});
}
export function unzlibAsync(data: Uint8Array, options?: AsyncUnzlibOptions): Promise<Uint8Array> {
return new Promise((res, rej) => {
unzlib(data, { ...(options || {}) }, (err, data) => {
if (err) {
rej(err);
return;
}
res(data);
});
});
}
export async function downloadZip<T>({ export async function downloadZip<T>({
staticUrl = '', staticUrl = '',
zipName, zipName,
zipDigest, zipDigest,
parseJson = true, parseJson = true,
fetchOptions,
}: { }: {
staticUrl?: string; staticUrl?: string;
zipName: string; zipName: string;
zipDigest?: string; zipDigest?: string;
parseJson?: boolean; parseJson?: boolean;
fetchOptions?: fetchDataOptions;
}): Promise<T> { }): Promise<T> {
const url = `${staticUrl}/${zipName}.zip`; const url = `${staticUrl}/${zipName}.zip`;
const resp = (await fetchData(url, { const resp = (await fetchData(url, {
...(fetchOptions || {}),
method: 'GET', method: 'GET',
returnResponse: true, returnResponse: true,
})) as Response; })) as Response;

@ -1,4 +1,4 @@
const { BannerPlugin } = require('webpack'); const { BannerPlugin, ProvidePlugin } = require('webpack');
const path = require('path'); const path = require('path');
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
@ -46,11 +46,18 @@ module.exports = [
}, },
plugins: [ plugins: [
new NodePolyfillPlugin(), new NodePolyfillPlugin(),
new ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer']
}),
], ],
resolve: { resolve: {
extensions: ['.tsx', '.ts', '.js'], extensions: ['.tsx', '.ts', '.js'],
alias: { alias: {
...commonAlias, ...commonAlias,
},
fallback: {
'process/browser': require.resolve('process/browser'),
} }
}, },
optimization: { optimization: {
@ -71,11 +78,18 @@ module.exports = [
}, },
plugins: [ plugins: [
new NodePolyfillPlugin(), new NodePolyfillPlugin(),
new ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer']
}),
], ],
resolve: { resolve: {
extensions: ['.tsx', '.ts', '.js'], extensions: ['.tsx', '.ts', '.js'],
alias: { alias: {
...commonAlias, ...commonAlias,
},
fallback: {
'process/browser': require.resolve('process/browser'),
} }
}, },
}, },
@ -92,6 +106,10 @@ module.exports = [
}, },
plugins: [ plugins: [
new NodePolyfillPlugin(), new NodePolyfillPlugin(),
new ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer']
}),
new BannerPlugin({ new BannerPlugin({
banner: 'globalThis.process = { browser: true, env: {}, };\n', banner: 'globalThis.process = { browser: true, env: {}, };\n',
raw: true, raw: true,
@ -101,6 +119,9 @@ module.exports = [
extensions: ['.tsx', '.ts', '.js'], extensions: ['.tsx', '.ts', '.js'],
alias: { alias: {
...commonAlias, ...commonAlias,
},
fallback: {
'process/browser': require.resolve('process/browser'),
} }
}, },
optimization: { optimization: {
@ -120,6 +141,10 @@ module.exports = [
}, },
plugins: [ plugins: [
new NodePolyfillPlugin(), new NodePolyfillPlugin(),
new ProvidePlugin({
process: 'process/browser',
Buffer: ['buffer', 'Buffer']
}),
new BannerPlugin({ new BannerPlugin({
banner: 'globalThis.process = { browser: true, env: {}, };', banner: 'globalThis.process = { browser: true, env: {}, };',
raw: true, raw: true,
@ -129,6 +154,9 @@ module.exports = [
extensions: ['.tsx', '.ts', '.js'], extensions: ['.tsx', '.ts', '.js'],
alias: { alias: {
...commonAlias, ...commonAlias,
},
fallback: {
'process/browser': require.resolve('process/browser'),
} }
}, },
}, },

@ -1440,14 +1440,6 @@
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433"
integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==
"@types/node-fetch@^2.6.12":
version "2.6.12"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.12.tgz#8ab5c3ef8330f13100a7479e2cd56d3386830a03"
integrity sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==
dependencies:
"@types/node" "*"
form-data "^4.0.0"
"@types/node@*": "@types/node@*":
version "22.5.5" version "22.5.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44" resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.5.tgz#52f939dd0f65fc552a4ad0b392f3c466cc5d7a44"
@ -2665,13 +2657,6 @@ create-require@^1.1.0, create-require@^1.1.1:
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
cross-fetch@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.1.0.tgz#8f69355007ee182e47fa692ecbaa37a52e43c3d2"
integrity sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==
dependencies:
node-fetch "^2.7.0"
cross-spawn@^7.0.0, cross-spawn@^7.0.3: cross-spawn@^7.0.0, cross-spawn@^7.0.3:
version "7.0.3" version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@ -5125,13 +5110,6 @@ node-emoji@^1.10.0:
dependencies: dependencies:
lodash "^4.17.21" lodash "^4.17.21"
node-fetch@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"
node-gyp-build@^4.2.0, node-gyp-build@^4.2.2: node-gyp-build@^4.2.0, node-gyp-build@^4.2.2:
version "4.8.2" version "4.8.2"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.2.tgz#4f802b71c1ab2ca16af830e6c1ea7dd1ad9496fa" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.2.tgz#4f802b71c1ab2ca16af830e6c1ea7dd1ad9496fa"
@ -6502,11 +6480,6 @@ toidentifier@1.0.1:
"@openzeppelin/contracts-v3" "npm:@openzeppelin/contracts@3.2.0-rc.0" "@openzeppelin/contracts-v3" "npm:@openzeppelin/contracts@3.2.0-rc.0"
ethers "^6.13.4" ethers "^6.13.4"
tr46@~0.0.3:
version "0.0.3"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
ts-api-utils@^1.3.0: ts-api-utils@^1.3.0:
version "1.3.0" version "1.3.0"
resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1"
@ -6921,11 +6894,6 @@ web3-utils@^1.3.6:
randombytes "^2.1.0" randombytes "^2.1.0"
utf8 "3.0.0" utf8 "3.0.0"
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
webpack-cli@^6.0.1: webpack-cli@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-6.0.1.tgz#a1ce25da5ba077151afd73adfa12e208e5089207" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-6.0.1.tgz#a1ce25da5ba077151afd73adfa12e208e5089207"
@ -7002,14 +6970,6 @@ webpack@^5.97.1:
dependencies: dependencies:
big-integer "1.6.52" big-integer "1.6.52"
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
dependencies:
tr46 "~0.0.3"
webidl-conversions "^3.0.0"
which-boxed-primitive@^1.0.2: which-boxed-primitive@^1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"