Compare commits
10 Commits
68fcf07c2a
...
722c426fcb
Author | SHA1 | Date | |
---|---|---|---|
722c426fcb | |||
63be1b2d14 | |||
f16bb2ed12 | |||
960321e9bd | |||
309a53600c | |||
6d5f2681f4 | |||
93a2049879 | |||
8b6887108f | |||
b35e53ebdb | |||
2337892195 |
DockerfileREADME.mdpackage.jsonrollup.config.mjsyarn.lock
dist
events
fees.d.tshashes.jsonindex.jsindex.mjsmerkleTree.d.tsmerkleTreeWorker.jsmerkleTreeWorker.umd.jsmerkleTreeWorker.umd.min.jsmimc.d.tsnetworkConfig.d.tspermit.d.tsproviders.d.tstornado.umd.jstornado.umd.min.jstornadoContracts.umd.jstornadoContracts.umd.min.jswebsnark.d.tsscripts
src
events
fees.tsgaszip.tsidb.tsmerkleTree.tsmerkleTreeWorker.tsmimc.tsnetworkConfig.tspermit.tsproviders.tswebsnark.ts
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@ -0,0 +1,25 @@
|
||||
# Dockefile from https://notes.ethereum.org/@GW1ZUbNKR5iRjjKYx6_dJQ/Bk8zsJ9xj
|
||||
# FROM node:20.18.0-bullseye-slim
|
||||
FROM node@sha256:9b558df8f10198fcd1f48cf344c55c4442c3446b8a9a69487523b3d890a4a59e
|
||||
|
||||
# install wget, git and necessary certificates
|
||||
RUN apt update && apt install --yes --no-install-recommends wget git apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GIT_REPOSITORY=https://git.tornado.ws/tornadocontrib/tornado-core.git
|
||||
# From development branch, double check with tornado.ws
|
||||
ENV GIT_COMMIT_HASH=f16bb2ed12464dce4f31aa5a237bb1643989e02d
|
||||
|
||||
# clone the repository
|
||||
RUN mkdir /app/
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Simple hack to fetch only commit and nothing more (no need to download 1GB sized repo, only 100MB would be enough)
|
||||
RUN git init && \
|
||||
git remote add origin $GIT_REPOSITORY && \
|
||||
git fetch --depth 1 origin $GIT_COMMIT_HASH && \
|
||||
git checkout $GIT_COMMIT_HASH
|
||||
|
||||
# install, build and prep for deployment
|
||||
RUN yarn install --frozen-lockfile --ignore-scripts
|
||||
RUN yarn build
|
@ -4,6 +4,8 @@
|
||||
|
||||
# Tornado Core (@tornado/core)
|
||||
|
||||
### Notice: Repository migrated to [tornado-scripts](https://github.com/tornadocontrib/tornado-scripts) to avoid naming conflict with legacy tornado-core repository
|
||||
|
||||
🛠 An SDK for building applications on top of [Privacy Pools](https://www.forbes.com/sites/tomerniv/2023/09/07/privacy-pools-bridging-the-gap-between-blockchain-and-regulatory-compliance)
|
||||
|
||||
[](https://t.me/tornadoofficial) [](https://element.tornadocash.social) [](https://forum.tornado.ws/)
|
||||
|
16
dist/events/base.d.ts
vendored
16
dist/events/base.d.ts
vendored
@ -1,15 +1,15 @@
|
||||
import { BaseContract, Provider, EventLog } from 'ethers';
|
||||
import { Tornado, TornadoRouter, TornadoProxyLight, Governance, RelayerRegistry, Echoer, Aggregator } from '@tornado/contracts';
|
||||
import type { MerkleTree } from '@tornado/fixed-merkle-tree';
|
||||
import type { MerkleTree } from 'fixed-merkle-tree';
|
||||
import { BatchEventsService, BatchBlockService, BatchTransactionService, BatchEventOnProgress, BatchBlockOnProgress } from '../batch';
|
||||
import { fetchDataOptions } from '../providers';
|
||||
import { type NetIdType, type SubdomainMap } from '../networkConfig';
|
||||
import { RelayerParams } from '../relayerClient';
|
||||
import type { TovarishClient } from '../tovarishClient';
|
||||
import type { ReverseRecords } from '../typechain';
|
||||
import type { ERC20, ReverseRecords } from '../typechain';
|
||||
import type { MerkleTreeService } from '../merkleTree';
|
||||
import type { DepositType } from '../deposits';
|
||||
import type { BaseEvents, CachedEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, GovernanceProposalCreatedEvents, GovernanceVotedEvents, EchoEvents, AllRelayerRegistryEvents, StakeBurnedEvents, MultiDepositsEvents, MultiWithdrawalsEvents } from './types';
|
||||
import type { BaseEvents, CachedEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, GovernanceProposalCreatedEvents, GovernanceVotedEvents, EchoEvents, AllRelayerRegistryEvents, StakeBurnedEvents, MultiDepositsEvents, MultiWithdrawalsEvents, TransferEvents } from './types';
|
||||
export interface BaseEventsServiceConstructor {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
@ -44,6 +44,9 @@ export declare class BaseEventsService<EventType extends MinimalEvents> {
|
||||
* Events from remote cache (Either from local cache, CDN, or from IPFS)
|
||||
*/
|
||||
getEventsFromCache(): Promise<CachedEvents<EventType>>;
|
||||
/**
|
||||
* This may not return in sorted events when called from browser, make sure to sort it again when directly called
|
||||
*/
|
||||
getSavedEvents(): Promise<BaseEvents<EventType> | CachedEvents<EventType>>;
|
||||
getEventsFromRpc({ fromBlock, toBlock, }: {
|
||||
fromBlock: number;
|
||||
@ -252,3 +255,10 @@ export declare class BaseRevenueService extends BaseEventsService<StakeBurnedEve
|
||||
getTovarishType(): string;
|
||||
formatEvents(events: EventLog[]): Promise<StakeBurnedEvents[]>;
|
||||
}
|
||||
export interface BaseTransferServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Token: ERC20;
|
||||
}
|
||||
export declare class BaseTransferService extends BaseEventsService<TransferEvents> {
|
||||
constructor(serviceConstructor: BaseTransferServiceConstructor);
|
||||
formatEvents(events: EventLog[]): Promise<TransferEvents[]>;
|
||||
}
|
||||
|
47
dist/events/db.d.ts
vendored
47
dist/events/db.d.ts
vendored
@ -1,10 +1,10 @@
|
||||
import { IndexedDB } from '../idb';
|
||||
import { BaseTornadoService, BaseTornadoServiceConstructor, BaseEchoService, BaseEchoServiceConstructor, BaseEncryptedNotesService, BaseEncryptedNotesServiceConstructor, BaseGovernanceService, BaseGovernanceServiceConstructor, BaseRegistryService, BaseRegistryServiceConstructor, BaseRevenueService, BaseRevenueServiceConstructor, CachedRelayers } from './base';
|
||||
import { BaseEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, CachedEvents, EchoEvents, EncryptedNotesEvents, AllGovernanceEvents, AllRelayerRegistryEvents, StakeBurnedEvents } from './types';
|
||||
export declare function saveDBEvents<T extends MinimalEvents>({ idb, instanceName, events, lastBlock, }: {
|
||||
import { BaseTornadoService, BaseTornadoServiceConstructor, BaseEchoService, BaseEchoServiceConstructor, BaseEncryptedNotesService, BaseEncryptedNotesServiceConstructor, BaseGovernanceService, BaseGovernanceServiceConstructor, BaseRegistryService, BaseRegistryServiceConstructor, BaseRevenueService, BaseRevenueServiceConstructor, CachedRelayers, BaseMultiTornadoService, BaseMultiTornadoServiceConstructor } from './base';
|
||||
import { BaseEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, CachedEvents, EchoEvents, EncryptedNotesEvents, AllGovernanceEvents, AllRelayerRegistryEvents, StakeBurnedEvents, MultiDepositsEvents, MultiWithdrawalsEvents } from './types';
|
||||
export declare function saveDBEvents<T extends MinimalEvents>({ idb, instanceName, newEvents, lastBlock, }: {
|
||||
idb: IndexedDB;
|
||||
instanceName: string;
|
||||
events: T[];
|
||||
newEvents: T[];
|
||||
lastBlock: number;
|
||||
}): Promise<void>;
|
||||
export declare function loadDBEvents<T extends MinimalEvents>({ idb, instanceName, }: {
|
||||
@ -28,7 +28,24 @@ export declare class DBTornadoService extends BaseTornadoService {
|
||||
constructor(params: DBTornadoServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<DepositsEvents | WithdrawalsEvents>>;
|
||||
saveEvents({ events, lastBlock }: BaseEvents<DepositsEvents | WithdrawalsEvents>): Promise<void>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<DepositsEvents | WithdrawalsEvents> & {
|
||||
newEvents: (DepositsEvents | WithdrawalsEvents)[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBMultiTornadoServiceConstructor extends BaseMultiTornadoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
export declare class DBMultiTornadoService extends BaseMultiTornadoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
constructor(params: DBMultiTornadoServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<MultiDepositsEvents | MultiWithdrawalsEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<MultiDepositsEvents | MultiWithdrawalsEvents>>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<MultiDepositsEvents | MultiWithdrawalsEvents> & {
|
||||
newEvents: (MultiDepositsEvents | MultiWithdrawalsEvents)[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBEchoServiceConstructor extends BaseEchoServiceConstructor {
|
||||
staticUrl: string;
|
||||
@ -41,7 +58,9 @@ export declare class DBEchoService extends BaseEchoService {
|
||||
constructor(params: DBEchoServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<EchoEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<EchoEvents>>;
|
||||
saveEvents({ events, lastBlock }: BaseEvents<EchoEvents>): Promise<void>;
|
||||
saveEvents({ newEvents, lastBlock }: BaseEvents<EchoEvents> & {
|
||||
newEvents: EchoEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBEncryptedNotesServiceConstructor extends BaseEncryptedNotesServiceConstructor {
|
||||
staticUrl: string;
|
||||
@ -54,7 +73,9 @@ export declare class DBEncryptedNotesService extends BaseEncryptedNotesService {
|
||||
constructor(params: DBEncryptedNotesServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<EncryptedNotesEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<EncryptedNotesEvents>>;
|
||||
saveEvents({ events, lastBlock }: BaseEvents<EncryptedNotesEvents>): Promise<void>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<EncryptedNotesEvents> & {
|
||||
newEvents: EncryptedNotesEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBGovernanceServiceConstructor extends BaseGovernanceServiceConstructor {
|
||||
staticUrl: string;
|
||||
@ -67,7 +88,9 @@ export declare class DBGovernanceService extends BaseGovernanceService {
|
||||
constructor(params: DBGovernanceServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<AllGovernanceEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<AllGovernanceEvents>>;
|
||||
saveEvents({ events, lastBlock }: BaseEvents<AllGovernanceEvents>): Promise<void>;
|
||||
saveEvents({ newEvents, lastBlock }: BaseEvents<AllGovernanceEvents> & {
|
||||
newEvents: AllGovernanceEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBRegistryServiceConstructor extends BaseRegistryServiceConstructor {
|
||||
staticUrl: string;
|
||||
@ -81,7 +104,9 @@ export declare class DBRegistryService extends BaseRegistryService {
|
||||
constructor(params: DBRegistryServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<AllRelayerRegistryEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<AllRelayerRegistryEvents>>;
|
||||
saveEvents({ events, lastBlock }: BaseEvents<AllRelayerRegistryEvents>): Promise<void>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<AllRelayerRegistryEvents> & {
|
||||
newEvents: AllRelayerRegistryEvents[];
|
||||
}): Promise<void>;
|
||||
getRelayersFromDB(): Promise<CachedRelayers>;
|
||||
getRelayersFromCache(): Promise<CachedRelayers>;
|
||||
saveRelayers(cachedRelayers: CachedRelayers): Promise<void>;
|
||||
@ -98,5 +123,7 @@ export declare class DBRevenueService extends BaseRevenueService {
|
||||
constructor(params: DBRevenueServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<StakeBurnedEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<StakeBurnedEvents>>;
|
||||
saveEvents({ events, lastBlock }: BaseEvents<StakeBurnedEvents>): Promise<void>;
|
||||
saveEvents({ newEvents, lastBlock }: BaseEvents<StakeBurnedEvents> & {
|
||||
newEvents: StakeBurnedEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
|
5
dist/events/types.d.ts
vendored
5
dist/events/types.d.ts
vendored
@ -99,3 +99,8 @@ export interface EchoEvents extends MinimalEvents {
|
||||
export interface EncryptedNotesEvents extends MinimalEvents {
|
||||
encryptedNote: string;
|
||||
}
|
||||
export interface TransferEvents extends MinimalEvents {
|
||||
from: string;
|
||||
to: string;
|
||||
value: bigint;
|
||||
}
|
||||
|
2
dist/fees.d.ts
vendored
2
dist/fees.d.ts
vendored
@ -29,7 +29,7 @@ export declare class TornadoFeeOracle {
|
||||
* (A single block can bump 12.5% of fees, see the methodology https://hackmd.io/@tvanepps/1559-wallets)
|
||||
* (Still it is recommended to use 100% premium for sending transactions to prevent stucking it)
|
||||
*/
|
||||
gasPrice(): Promise<bigint>;
|
||||
gasPrice(premium?: number): Promise<bigint>;
|
||||
/**
|
||||
* Calculate L1 fee for op-stack chains
|
||||
*
|
||||
|
11
dist/hashes.json
vendored
Normal file
11
dist/hashes.json
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"dist/index.js": "sha384-txpjgDLxNbeXsLgVCyNAwpaJRS0SmFN/ITfadSo8+xzSvLqwa5bQ9GoxQ1Su8QEr",
|
||||
"dist/index.mjs": "sha384-CrEHmX4zKIv/68CKWElNzvKk6FWRMMkKV8JmqL1KqYCxO73LPEAjDqxTYpxUuDBy",
|
||||
"dist/merkleTreeWorker.js": "sha384-XVv9HRGDZlaF0LeEZNQygle31UY6yvIwsZ4GWCTZUX7O/hZ7N5Zwpi3GqnHSBYzW",
|
||||
"dist/merkleTreeWorker.umd.js": "sha384-e5B65ZZ4IxKVOU1o02K6IL2tjJof20QCcEtD+vKe1cPmyfW2BPCHWDPIbPksIpvJ",
|
||||
"dist/merkleTreeWorker.umd.min.js": "sha384-AxQv1da+lSi3gMYkdGQuR1WN1+4HB8IT3cPFa17HBj14+ZzdZN6SS1fCw5Izc2rr",
|
||||
"dist/tornado.umd.js": "sha384-xTUkkUTm3aBsnHCUnVGxRgieAu3z4wCwrKT1DFj8VyCk/eZZO9nq+yP4/McLRfB4",
|
||||
"dist/tornado.umd.min.js": "sha384-ubqr6m6jEOPf7LQz0pXKmEo7tCCbNUAE+iSZWK6X/f7i4wt14rYW7pUcSzw5glth",
|
||||
"dist/tornadoContracts.umd.js": "sha384-bFq/cemb0bP0JbIq8p75n0UR8smQ/2Yh69pjegzSuu0upawO3sKOjehY8SjX85Xh",
|
||||
"dist/tornadoContracts.umd.min.js": "sha384-4ay7cmK0auAgZH1xfAsqyN6GtnHBNNgh9C22qy0rHxKicDzNtTsnNZDbz0qmd9GI"
|
||||
}
|
531
dist/index.js
vendored
531
dist/index.js
vendored
@ -12,9 +12,9 @@ var circomlibjs = require('circomlibjs');
|
||||
var ethSigUtil = require('@metamask/eth-sig-util');
|
||||
var idb = require('idb');
|
||||
var worker_threads = require('worker_threads');
|
||||
var fixedMerkleTree = require('@tornado/fixed-merkle-tree');
|
||||
var websnarkUtils = require('@tornado/websnark/src/utils');
|
||||
var websnarkGroth = require('@tornado/websnark/src/groth16');
|
||||
var fixedMerkleTree = require('fixed-merkle-tree');
|
||||
var websnarkUtils = require('websnark/src/utils');
|
||||
var websnarkGroth = require('websnark/src/groth16');
|
||||
|
||||
function _interopNamespaceDefault(e) {
|
||||
var n = Object.create(null);
|
||||
@ -699,7 +699,7 @@ function getProviderWithNetId(netId, rpcUrl, config, fetchOptions) {
|
||||
return provider;
|
||||
}
|
||||
const populateTransaction = async (signer, tx) => {
|
||||
const provider = signer.provider;
|
||||
const provider = signer.readonlyProvider || signer.provider;
|
||||
if (!tx.from) {
|
||||
tx.from = signer.address;
|
||||
} else if (tx.from !== signer.address) {
|
||||
@ -794,12 +794,14 @@ class TornadoRpcSigner extends ethers.JsonRpcSigner {
|
||||
gasLimitBump;
|
||||
gasFailover;
|
||||
bumpNonce;
|
||||
constructor(provider, address, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce } = {}) {
|
||||
readonlyProvider;
|
||||
constructor(provider, address, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce, readonlyProvider } = {}) {
|
||||
super(provider, address);
|
||||
this.gasPriceBump = gasPriceBump ?? 0;
|
||||
this.gasLimitBump = gasLimitBump ?? 3e3;
|
||||
this.gasFailover = gasFailover ?? false;
|
||||
this.bumpNonce = bumpNonce ?? false;
|
||||
this.readonlyProvider = readonlyProvider;
|
||||
}
|
||||
async sendUncheckedTransaction(tx) {
|
||||
return super.sendUncheckedTransaction(await populateTransaction(this, tx));
|
||||
@ -835,6 +837,8 @@ var NetId = /* @__PURE__ */ ((NetId2) => {
|
||||
NetId2[NetId2["POLYGON"] = 137] = "POLYGON";
|
||||
NetId2[NetId2["OPTIMISM"] = 10] = "OPTIMISM";
|
||||
NetId2[NetId2["ARBITRUM"] = 42161] = "ARBITRUM";
|
||||
NetId2[NetId2["BASE"] = 8453] = "BASE";
|
||||
NetId2[NetId2["BLAST"] = 81457] = "BLAST";
|
||||
NetId2[NetId2["GNOSIS"] = 100] = "GNOSIS";
|
||||
NetId2[NetId2["AVALANCHE"] = 43114] = "AVALANCHE";
|
||||
NetId2[NetId2["SEPOLIA"] = 11155111] = "SEPOLIA";
|
||||
@ -861,6 +865,10 @@ const defaultConfig = {
|
||||
name: "MEV Blocker",
|
||||
url: "https://rpc.mevblocker.io"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com"
|
||||
},
|
||||
keydonix: {
|
||||
name: "Horswap ( Keydonix )",
|
||||
url: "https://ethereum.keydonix.com/v1/mainnet"
|
||||
@ -980,10 +988,10 @@ const defaultConfig = {
|
||||
[56 /* BSC */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 5,
|
||||
fast: 5,
|
||||
standard: 5,
|
||||
low: 5
|
||||
instant: 3,
|
||||
fast: 1,
|
||||
standard: 1,
|
||||
low: 1
|
||||
},
|
||||
nativeCurrency: "bnb",
|
||||
currencyName: "BNB",
|
||||
@ -1008,6 +1016,10 @@ const defaultConfig = {
|
||||
name: "BNB Chain 2",
|
||||
url: "https://bsc-dataseed1.ninicoin.io"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com/bsc"
|
||||
},
|
||||
nodereal: {
|
||||
name: "NodeReal",
|
||||
url: "https://binance.nodereal.io"
|
||||
@ -1031,10 +1043,39 @@ const defaultConfig = {
|
||||
},
|
||||
symbol: "BNB",
|
||||
decimals: 18
|
||||
},
|
||||
usdt: {
|
||||
instanceAddress: {
|
||||
"10": "0x261fB4f84bb0BdEe7E035B6a8a08e5c35AdacdDD",
|
||||
"100": "0x3957861d4897d883C9b944C0b4E22bBd0DDE6e21",
|
||||
"1000": "0x6D180403AdFb39F70983eB51A033C5e52eb9BB69",
|
||||
"10000": "0x3722662D8AaB07B216B14C02eF0ee940d14A4200"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x55d398326f99059fF775485246999027B3197955",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "USDT",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
},
|
||||
btcb: {
|
||||
instanceAddress: {
|
||||
"0.0001": "0x736dABbFc8101Ae75287104eCcf67e45D7369Ae1",
|
||||
"0.001": "0x82c7Ce6f1F158cEC5536d591a2BC19864b3CA823",
|
||||
"0.01": "0x8284c96679037d8081E498d8F767cA5a140BFAAf",
|
||||
"0.1": "0x2bcD128Ce23ee30Ee945E613ff129c4DE1102C79"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "BTCB",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
}
|
||||
},
|
||||
optionalTokens: ["usdt", "btcb"],
|
||||
relayerEnsSubdomain: "bsc-tornado",
|
||||
pollInterval: 10,
|
||||
pollInterval: 3,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 8159269,
|
||||
ENCRYPTED_NOTES_BLOCK: 8159269
|
||||
@ -1043,9 +1084,9 @@ const defaultConfig = {
|
||||
[137 /* POLYGON */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 100,
|
||||
fast: 75,
|
||||
standard: 50,
|
||||
instant: 60,
|
||||
fast: 30,
|
||||
standard: 30,
|
||||
low: 30
|
||||
},
|
||||
nativeCurrency: "matic",
|
||||
@ -1085,7 +1126,7 @@ const defaultConfig = {
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "polygon-tornado",
|
||||
pollInterval: 10,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 16257996,
|
||||
ENCRYPTED_NOTES_BLOCK: 16257996
|
||||
@ -1127,17 +1168,20 @@ const defaultConfig = {
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
"100": "0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD"
|
||||
},
|
||||
optionalInstances: ["0.001", "0.01"],
|
||||
symbol: "ETH",
|
||||
decimals: 18
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "optimism-tornado",
|
||||
pollInterval: 15,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 2243694,
|
||||
ENCRYPTED_NOTES_BLOCK: 2243694
|
||||
@ -1146,10 +1190,10 @@ const defaultConfig = {
|
||||
[42161 /* ARBITRUM */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 4,
|
||||
fast: 3,
|
||||
standard: 2.52,
|
||||
low: 2.29
|
||||
instant: 0.02,
|
||||
fast: 0.02,
|
||||
standard: 0.02,
|
||||
low: 0.02
|
||||
},
|
||||
nativeCurrency: "eth",
|
||||
currencyName: "ETH",
|
||||
@ -1170,6 +1214,10 @@ const defaultConfig = {
|
||||
name: "Arbitrum",
|
||||
url: "https://arb1.arbitrum.io/rpc"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com/arbitrum"
|
||||
},
|
||||
stackup: {
|
||||
name: "Stackup",
|
||||
url: "https://public.stackup.sh/api/v1/node/arbitrum-one"
|
||||
@ -1182,6 +1230,150 @@ const defaultConfig = {
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
"100": "0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD"
|
||||
},
|
||||
optionalInstances: ["0.001", "0.01"],
|
||||
symbol: "ETH",
|
||||
decimals: 18
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "arbitrum-tornado",
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 3430605,
|
||||
ENCRYPTED_NOTES_BLOCK: 3430605
|
||||
}
|
||||
},
|
||||
[8453 /* BASE */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 0.1,
|
||||
fast: 0.06,
|
||||
standard: 0.05,
|
||||
low: 0.02
|
||||
},
|
||||
nativeCurrency: "eth",
|
||||
currencyName: "ETH",
|
||||
explorerUrl: "https://basescan.org",
|
||||
merkleTreeHeight: 20,
|
||||
emptyElement: "21663839004416932945382355908790599225266501822907911457504978515578255421292",
|
||||
networkName: "Base",
|
||||
deployedBlock: 23149794,
|
||||
stablecoin: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
||||
multicallContract: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
||||
routerContract: "0x0D5550d52428E7e3175bfc9550207e4ad3859b17",
|
||||
echoContract: "0xa75BF2815618872f155b7C4B0C81bF990f5245E4",
|
||||
offchainOracleContract: "0x00000000000D6FFc74A8feb35aF5827bf57f6786",
|
||||
ovmGasPriceOracleContract: "0x420000000000000000000000000000000000000F",
|
||||
tornadoSubgraph: "tornadocash/base-tornado-subgraph",
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
Base: {
|
||||
name: "Base",
|
||||
url: "https://mainnet.base.org"
|
||||
},
|
||||
stackup: {
|
||||
name: "Stackup",
|
||||
url: "https://public.stackup.sh/api/v1/node/base-mainnet"
|
||||
},
|
||||
oneRpc: {
|
||||
name: "1RPC",
|
||||
url: "https://1rpc.io/base"
|
||||
}
|
||||
},
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
"100": "0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD"
|
||||
},
|
||||
symbol: "ETH",
|
||||
decimals: 18
|
||||
},
|
||||
dai: {
|
||||
instanceAddress: {
|
||||
"10": "0x70CC374aE7D1549a4666b7172B78dDCF672B74f7",
|
||||
"100": "0xD063894588177B8362Dda6C0A7EF09BF6fDF851c",
|
||||
"1000": "0xa7513fdfF61fc83a9C5c08CE31266e6dd400C54E",
|
||||
"10000": "0x8f05eDE57098D843F30bE74AC25c292F87b7f775",
|
||||
"100000": "0xeB7fc86c32e9a5E9DD2a0a78C091b8b625cbee24"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "DAI",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
},
|
||||
tbtc: {
|
||||
instanceAddress: {
|
||||
"0.0001": "0x5465800D7Be34dAe2c1572d2227De94dE93B4432",
|
||||
"0.001": "0xf2d3404c03C8cC0b120bd6E8edD6F69226F03c6d",
|
||||
"0.01": "0x4261d5209A285410DEa8173B6FE1A0e7BCf20f7c",
|
||||
"0.1": "0x9FB147F49bFE17D19789547187EAE2406590b217",
|
||||
"1": "0x2A8515F39716B0C160a3eB32D24E4cbeB76932d2"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x236aa50979D5f3De3Bd1Eeb40E81137F22ab794b",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "tBTC",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "base-tornado",
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 23149794,
|
||||
ENCRYPTED_NOTES_BLOCK: 23149794
|
||||
}
|
||||
},
|
||||
[81457 /* BLAST */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 1e-3,
|
||||
fast: 1e-3,
|
||||
standard: 1e-3,
|
||||
low: 1e-3
|
||||
},
|
||||
nativeCurrency: "eth",
|
||||
currencyName: "ETH",
|
||||
explorerUrl: "https://blastscan.io",
|
||||
merkleTreeHeight: 20,
|
||||
emptyElement: "21663839004416932945382355908790599225266501822907911457504978515578255421292",
|
||||
networkName: "Blast",
|
||||
deployedBlock: 12144065,
|
||||
stablecoin: "0x4300000000000000000000000000000000000003",
|
||||
multicallContract: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
||||
routerContract: "0x0D5550d52428E7e3175bfc9550207e4ad3859b17",
|
||||
echoContract: "0xa75BF2815618872f155b7C4B0C81bF990f5245E4",
|
||||
ovmGasPriceOracleContract: "0x420000000000000000000000000000000000000F",
|
||||
tornadoSubgraph: "tornadocash/blast-tornado-subgraph",
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
Blast: {
|
||||
name: "Blast",
|
||||
url: "https://rpc.blast.io"
|
||||
},
|
||||
blastApi: {
|
||||
name: "BlastApi",
|
||||
url: "https://blastl2-mainnet.public.blastapi.io"
|
||||
}
|
||||
},
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
@ -1191,11 +1383,11 @@ const defaultConfig = {
|
||||
decimals: 18
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "arbitrum-tornado",
|
||||
pollInterval: 15,
|
||||
relayerEnsSubdomain: "blast-tornado",
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 3430605,
|
||||
ENCRYPTED_NOTES_BLOCK: 3430605
|
||||
NOTE_ACCOUNT_BLOCK: 12144065,
|
||||
ENCRYPTED_NOTES_BLOCK: 12144065
|
||||
}
|
||||
},
|
||||
[100 /* GNOSIS */]: {
|
||||
@ -1243,7 +1435,7 @@ const defaultConfig = {
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "gnosis-tornado",
|
||||
pollInterval: 15,
|
||||
pollInterval: 5,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 17754564,
|
||||
ENCRYPTED_NOTES_BLOCK: 17754564
|
||||
@ -1293,7 +1485,7 @@ const defaultConfig = {
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "avalanche-tornado",
|
||||
pollInterval: 10,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 4429813,
|
||||
ENCRYPTED_NOTES_BLOCK: 4429813
|
||||
@ -1328,6 +1520,14 @@ const defaultConfig = {
|
||||
tornadoSubgraph: "tornadocash/sepolia-tornado-subgraph",
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
oneRpc: {
|
||||
name: "1RPC",
|
||||
url: "https://1rpc.io/sepolia"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com/sepolia"
|
||||
},
|
||||
sepolia: {
|
||||
name: "Sepolia RPC",
|
||||
url: "https://rpc.sepolia.org"
|
||||
@ -1336,10 +1536,6 @@ const defaultConfig = {
|
||||
name: "Stackup",
|
||||
url: "https://public.stackup.sh/api/v1/node/ethereum-sepolia"
|
||||
},
|
||||
oneRpc: {
|
||||
name: "1RPC",
|
||||
url: "https://1rpc.io/sepolia"
|
||||
},
|
||||
ethpandaops: {
|
||||
name: "ethpandaops",
|
||||
url: "https://rpc.sepolia.ethpandaops.io"
|
||||
@ -2233,6 +2429,9 @@ class BaseEventsService {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This may not return in sorted events when called from browser, make sure to sort it again when directly called
|
||||
*/
|
||||
async getSavedEvents() {
|
||||
let dbEvents = await this.getEventsFromDB();
|
||||
if (!dbEvents.lastBlock) {
|
||||
@ -2578,7 +2777,10 @@ class BaseMultiTornadoService extends BaseEventsService {
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
{
|
||||
depositEvents: [],
|
||||
withdrawalEvents: []
|
||||
}
|
||||
);
|
||||
return {
|
||||
depositEvents,
|
||||
@ -2856,7 +3058,12 @@ class BaseGovernanceService extends BaseEventsService {
|
||||
});
|
||||
}
|
||||
async getVotes(proposalId) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const events = (await this.getSavedEvents()).events.sort((a, b) => {
|
||||
if (a.blockNumber === b.blockNumber) {
|
||||
return a.logIndex - b.logIndex;
|
||||
}
|
||||
return a.blockNumber - b.blockNumber;
|
||||
});
|
||||
const votedEvents = events.filter(
|
||||
(e) => e.event === "Voted" && e.proposalId === proposalId
|
||||
);
|
||||
@ -2885,7 +3092,12 @@ class BaseGovernanceService extends BaseEventsService {
|
||||
return votes;
|
||||
}
|
||||
async getDelegatedBalance(ethAccount) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const events = (await this.getSavedEvents()).events.sort((a, b) => {
|
||||
if (a.blockNumber === b.blockNumber) {
|
||||
return a.logIndex - b.logIndex;
|
||||
}
|
||||
return a.blockNumber - b.blockNumber;
|
||||
});
|
||||
const delegatedAccs = events.filter((e) => e.event === "Delegated" && e.delegateTo === ethAccount).map((e) => e.account);
|
||||
const undelegatedAccs = events.filter((e) => e.event === "Undelegated" && e.delegateFrom === ethAccount).map((e) => e.account);
|
||||
const undel = [...undelegatedAccs];
|
||||
@ -2945,6 +3157,13 @@ const staticRelayers = [
|
||||
hostnames: {},
|
||||
tovarishHost: "tornadowithdraw.com",
|
||||
tovarishNetworks: enabledChains
|
||||
},
|
||||
{
|
||||
ensName: "rpc.tornadowithdraw.eth",
|
||||
relayerAddress: "0xFF787B7A5cd8a88508361E3B7bcE791Aa2796526",
|
||||
hostnames: {},
|
||||
tovarishHost: "tornadocash-rpc.com",
|
||||
tovarishNetworks: enabledChains
|
||||
}
|
||||
];
|
||||
class BaseRegistryService extends BaseEventsService {
|
||||
@ -3204,6 +3423,31 @@ RevenueService: Mismatch on withdrawal logs (${withdrawalLogs.length} ) and even
|
||||
});
|
||||
}
|
||||
}
|
||||
class BaseTransferService extends BaseEventsService {
|
||||
constructor(serviceConstructor) {
|
||||
super({
|
||||
...serviceConstructor,
|
||||
contract: serviceConstructor.Token,
|
||||
type: "Transfer"
|
||||
});
|
||||
}
|
||||
async formatEvents(events) {
|
||||
return events.map(({ blockNumber, index: logIndex, transactionHash, args }) => {
|
||||
const { from, to, value } = args;
|
||||
const eventObjects = {
|
||||
blockNumber,
|
||||
logIndex,
|
||||
transactionHash
|
||||
};
|
||||
return {
|
||||
...eventObjects,
|
||||
from,
|
||||
to,
|
||||
value
|
||||
};
|
||||
}).filter((e) => e);
|
||||
}
|
||||
}
|
||||
|
||||
function zipAsync(file, options) {
|
||||
return new Promise((res, rej) => {
|
||||
@ -3257,11 +3501,11 @@ async function downloadZip({
|
||||
async function saveDBEvents({
|
||||
idb,
|
||||
instanceName,
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
try {
|
||||
const formattedEvents = events.map((e) => {
|
||||
const formattedEvents = newEvents.map((e) => {
|
||||
return {
|
||||
eid: `${e.transactionHash}_${e.logIndex}`,
|
||||
...e
|
||||
@ -3372,11 +3616,49 @@ class DBTornadoService extends BaseTornadoService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
}
|
||||
class DBMultiTornadoService extends BaseMultiTornadoService {
|
||||
staticUrl;
|
||||
idb;
|
||||
zipDigest;
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName()
|
||||
});
|
||||
}
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3404,11 +3686,11 @@ class DBEchoService extends BaseEchoService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({ newEvents, lastBlock }) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3436,11 +3718,14 @@ class DBEncryptedNotesService extends BaseEncryptedNotesService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3468,11 +3753,11 @@ class DBGovernanceService extends BaseGovernanceService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({ newEvents, lastBlock }) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3501,11 +3786,14 @@ class DBRegistryService extends BaseRegistryService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3594,11 +3882,11 @@ class DBRevenueService extends BaseRevenueService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({ newEvents, lastBlock }) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -9341,7 +9629,7 @@ class TornadoFeeOracle {
|
||||
* (A single block can bump 12.5% of fees, see the methodology https://hackmd.io/@tvanepps/1559-wallets)
|
||||
* (Still it is recommended to use 100% premium for sending transactions to prevent stucking it)
|
||||
*/
|
||||
async gasPrice() {
|
||||
async gasPrice(premium) {
|
||||
const [block, getGasPrice, getPriorityFee] = await Promise.all([
|
||||
this.provider.getBlock("latest"),
|
||||
(async () => {
|
||||
@ -9359,14 +9647,14 @@ class TornadoFeeOracle {
|
||||
}
|
||||
})()
|
||||
]);
|
||||
return block?.baseFeePerGas ? block.baseFeePerGas * BigInt(15) / BigInt(10) + getPriorityFee : getGasPrice;
|
||||
return block?.baseFeePerGas ? block.baseFeePerGas * BigInt(1e4 * (100 + (premium || 50))) / BigInt(1e4 * 100) + getPriorityFee : getGasPrice;
|
||||
}
|
||||
/**
|
||||
* Calculate L1 fee for op-stack chains
|
||||
*
|
||||
* This is required since relayers would pay the full transaction fees for users
|
||||
*/
|
||||
fetchL1OptimismFee(tx) {
|
||||
async fetchL1OptimismFee(tx) {
|
||||
if (!this.ovmGasPriceOracle) {
|
||||
return new Promise((resolve) => resolve(BigInt(0)));
|
||||
}
|
||||
@ -9380,7 +9668,7 @@ class TornadoFeeOracle {
|
||||
to: DUMMY_ADDRESS
|
||||
};
|
||||
}
|
||||
return this.ovmGasPriceOracle.getL1Fee.staticCall(ethers.Transaction.from(tx).unsignedSerialized);
|
||||
return await this.ovmGasPriceOracle.getL1Fee.staticCall(ethers.Transaction.from(tx).unsignedSerialized) * 12n / 10n;
|
||||
}
|
||||
/**
|
||||
* We don't need to distinguish default refunds by tokens since most users interact with other defi protocols after withdrawal
|
||||
@ -9428,6 +9716,8 @@ const gasZipInbounds = {
|
||||
[NetId.POLYGON]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.OPTIMISM]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.ARBITRUM]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.BASE]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.BLAST]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.GNOSIS]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.AVALANCHE]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604"
|
||||
};
|
||||
@ -9437,6 +9727,8 @@ const gasZipID = {
|
||||
[NetId.POLYGON]: 17,
|
||||
[NetId.OPTIMISM]: 55,
|
||||
[NetId.ARBITRUM]: 57,
|
||||
[NetId.BASE]: 54,
|
||||
[NetId.BLAST]: 96,
|
||||
[NetId.GNOSIS]: 16,
|
||||
[NetId.AVALANCHE]: 15,
|
||||
[NetId.SEPOLIA]: 102
|
||||
@ -9502,7 +9794,7 @@ class IndexedDB {
|
||||
}
|
||||
};
|
||||
this.dbName = dbName;
|
||||
this.dbVersion = 35;
|
||||
this.dbVersion = 36;
|
||||
}
|
||||
async initDB() {
|
||||
try {
|
||||
@ -9698,15 +9990,16 @@ async function getIndexedDB(netId) {
|
||||
}
|
||||
const minimalIndexes = [
|
||||
{
|
||||
name: "blockNumber",
|
||||
unique: false
|
||||
},
|
||||
{
|
||||
name: "transactionHash",
|
||||
unique: false
|
||||
name: "eid",
|
||||
unique: true
|
||||
}
|
||||
];
|
||||
const defaultState = [
|
||||
{
|
||||
name: `tornado_${netId}`,
|
||||
keyPath: "eid",
|
||||
indexes: [...minimalIndexes]
|
||||
},
|
||||
{
|
||||
name: `echo_${netId}`,
|
||||
keyPath: "eid",
|
||||
@ -9734,8 +10027,7 @@ async function getIndexedDB(netId) {
|
||||
]
|
||||
}
|
||||
];
|
||||
const config = getConfig(netId);
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = config;
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = getConfig(netId);
|
||||
const stores = [...defaultState];
|
||||
if (registryContract) {
|
||||
stores.push({
|
||||
@ -10079,122 +10371,6 @@ async function getPermitSignature({
|
||||
})
|
||||
);
|
||||
}
|
||||
async function getPermitCommitmentsSignature({
|
||||
PermitTornado: PermitTornado2,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = ethers.solidityPackedKeccak256(["bytes32[]"], [commitments]);
|
||||
return await getPermitSignature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado2.target,
|
||||
value,
|
||||
nonce,
|
||||
deadline: BigInt(commitmentsHash)
|
||||
});
|
||||
}
|
||||
async function getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender,
|
||||
value: amount,
|
||||
nonce,
|
||||
deadline,
|
||||
witness
|
||||
}) {
|
||||
const sigSigner = signer || Token.runner;
|
||||
const provider = sigSigner.provider;
|
||||
const domain = {
|
||||
name: "Permit2",
|
||||
chainId: (await provider.getNetwork()).chainId,
|
||||
verifyingContract: permit2Address
|
||||
};
|
||||
const types = !witness ? {
|
||||
PermitTransferFrom: [
|
||||
{ name: "permitted", type: "TokenPermissions" },
|
||||
{ name: "spender", type: "address" },
|
||||
{ name: "nonce", type: "uint256" },
|
||||
{ name: "deadline", type: "uint256" }
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: "token", type: "address" },
|
||||
{ name: "amount", type: "uint256" }
|
||||
]
|
||||
} : {
|
||||
PermitWitnessTransferFrom: [
|
||||
{ name: "permitted", type: "TokenPermissions" },
|
||||
{ name: "spender", type: "address" },
|
||||
{ name: "nonce", type: "uint256" },
|
||||
{ name: "deadline", type: "uint256" },
|
||||
{ name: "witness", type: witness.witnessTypeName }
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: "token", type: "address" },
|
||||
{ name: "amount", type: "uint256" }
|
||||
],
|
||||
...witness.witnessType
|
||||
};
|
||||
const values = {
|
||||
permitted: {
|
||||
token: Token.target,
|
||||
amount
|
||||
},
|
||||
spender,
|
||||
// Sorted nonce are not required for Permit2
|
||||
nonce: nonce || rBigInt(16),
|
||||
deadline: deadline || ethers.MaxUint256
|
||||
};
|
||||
if (witness) {
|
||||
values.witness = witness.witness;
|
||||
}
|
||||
const hash = new ethers.TypedDataEncoder(types).hash(values);
|
||||
const signature = ethers.Signature.from(await sigSigner.signTypedData(domain, types, values));
|
||||
return {
|
||||
domain,
|
||||
types,
|
||||
values,
|
||||
hash,
|
||||
signature
|
||||
};
|
||||
}
|
||||
async function getPermit2CommitmentsSignature({
|
||||
PermitTornado: PermitTornado2,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
deadline
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = ethers.solidityPackedKeccak256(["bytes32[]"], [commitments]);
|
||||
return await getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado2.target,
|
||||
value,
|
||||
nonce,
|
||||
deadline,
|
||||
witness: {
|
||||
witnessTypeName: "PermitCommitments",
|
||||
witnessType: {
|
||||
PermitCommitments: [
|
||||
{ name: "instance", type: "address" },
|
||||
{ name: "commitmentsHash", type: "bytes32" }
|
||||
]
|
||||
},
|
||||
witness: {
|
||||
instance: PermitTornado2.target,
|
||||
commitmentsHash
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class TokenPriceOracle {
|
||||
oracle;
|
||||
@ -10635,12 +10811,14 @@ exports.BaseMultiTornadoService = BaseMultiTornadoService;
|
||||
exports.BaseRegistryService = BaseRegistryService;
|
||||
exports.BaseRevenueService = BaseRevenueService;
|
||||
exports.BaseTornadoService = BaseTornadoService;
|
||||
exports.BaseTransferService = BaseTransferService;
|
||||
exports.BatchBlockService = BatchBlockService;
|
||||
exports.BatchEventsService = BatchEventsService;
|
||||
exports.BatchTransactionService = BatchTransactionService;
|
||||
exports.DBEchoService = DBEchoService;
|
||||
exports.DBEncryptedNotesService = DBEncryptedNotesService;
|
||||
exports.DBGovernanceService = DBGovernanceService;
|
||||
exports.DBMultiTornadoService = DBMultiTornadoService;
|
||||
exports.DBRegistryService = DBRegistryService;
|
||||
exports.DBRevenueService = DBRevenueService;
|
||||
exports.DBTornadoService = DBTornadoService;
|
||||
@ -10725,9 +10903,6 @@ exports.getIndexedDB = getIndexedDB;
|
||||
exports.getInstanceByAddress = getInstanceByAddress;
|
||||
exports.getMultiInstances = getMultiInstances;
|
||||
exports.getNetworkConfig = getNetworkConfig;
|
||||
exports.getPermit2CommitmentsSignature = getPermit2CommitmentsSignature;
|
||||
exports.getPermit2Signature = getPermit2Signature;
|
||||
exports.getPermitCommitmentsSignature = getPermitCommitmentsSignature;
|
||||
exports.getPermitSignature = getPermitSignature;
|
||||
exports.getProvider = getProvider;
|
||||
exports.getProviderWithNetId = getProviderWithNetId;
|
||||
|
530
dist/index.mjs
vendored
530
dist/index.mjs
vendored
@ -1,4 +1,4 @@
|
||||
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, solidityPackedKeccak256, TypedDataEncoder, ZeroAddress } from 'ethers';
|
||||
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 { Tornado__factory } from '@tornado/contracts';
|
||||
import { webcrypto } from 'crypto';
|
||||
import BN from 'bn.js';
|
||||
@ -10,9 +10,9 @@ import { buildPedersenHash, buildMimcSponge } from 'circomlibjs';
|
||||
import { getEncryptionPublicKey, encrypt, decrypt } from '@metamask/eth-sig-util';
|
||||
import { openDB, deleteDB } from 'idb';
|
||||
import { Worker as Worker$1 } from 'worker_threads';
|
||||
import { MerkleTree, PartialMerkleTree } from '@tornado/fixed-merkle-tree';
|
||||
import * as websnarkUtils from '@tornado/websnark/src/utils';
|
||||
import websnarkGroth from '@tornado/websnark/src/groth16';
|
||||
import { MerkleTree, PartialMerkleTree } from 'fixed-merkle-tree';
|
||||
import * as websnarkUtils from 'websnark/src/utils';
|
||||
import websnarkGroth from 'websnark/src/groth16';
|
||||
|
||||
BigInt.prototype.toJSON = function() {
|
||||
return this.toString();
|
||||
@ -677,7 +677,7 @@ function getProviderWithNetId(netId, rpcUrl, config, fetchOptions) {
|
||||
return provider;
|
||||
}
|
||||
const populateTransaction = async (signer, tx) => {
|
||||
const provider = signer.provider;
|
||||
const provider = signer.readonlyProvider || signer.provider;
|
||||
if (!tx.from) {
|
||||
tx.from = signer.address;
|
||||
} else if (tx.from !== signer.address) {
|
||||
@ -772,12 +772,14 @@ class TornadoRpcSigner extends JsonRpcSigner {
|
||||
gasLimitBump;
|
||||
gasFailover;
|
||||
bumpNonce;
|
||||
constructor(provider, address, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce } = {}) {
|
||||
readonlyProvider;
|
||||
constructor(provider, address, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce, readonlyProvider } = {}) {
|
||||
super(provider, address);
|
||||
this.gasPriceBump = gasPriceBump ?? 0;
|
||||
this.gasLimitBump = gasLimitBump ?? 3e3;
|
||||
this.gasFailover = gasFailover ?? false;
|
||||
this.bumpNonce = bumpNonce ?? false;
|
||||
this.readonlyProvider = readonlyProvider;
|
||||
}
|
||||
async sendUncheckedTransaction(tx) {
|
||||
return super.sendUncheckedTransaction(await populateTransaction(this, tx));
|
||||
@ -813,6 +815,8 @@ var NetId = /* @__PURE__ */ ((NetId2) => {
|
||||
NetId2[NetId2["POLYGON"] = 137] = "POLYGON";
|
||||
NetId2[NetId2["OPTIMISM"] = 10] = "OPTIMISM";
|
||||
NetId2[NetId2["ARBITRUM"] = 42161] = "ARBITRUM";
|
||||
NetId2[NetId2["BASE"] = 8453] = "BASE";
|
||||
NetId2[NetId2["BLAST"] = 81457] = "BLAST";
|
||||
NetId2[NetId2["GNOSIS"] = 100] = "GNOSIS";
|
||||
NetId2[NetId2["AVALANCHE"] = 43114] = "AVALANCHE";
|
||||
NetId2[NetId2["SEPOLIA"] = 11155111] = "SEPOLIA";
|
||||
@ -839,6 +843,10 @@ const defaultConfig = {
|
||||
name: "MEV Blocker",
|
||||
url: "https://rpc.mevblocker.io"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com"
|
||||
},
|
||||
keydonix: {
|
||||
name: "Horswap ( Keydonix )",
|
||||
url: "https://ethereum.keydonix.com/v1/mainnet"
|
||||
@ -958,10 +966,10 @@ const defaultConfig = {
|
||||
[56 /* BSC */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 5,
|
||||
fast: 5,
|
||||
standard: 5,
|
||||
low: 5
|
||||
instant: 3,
|
||||
fast: 1,
|
||||
standard: 1,
|
||||
low: 1
|
||||
},
|
||||
nativeCurrency: "bnb",
|
||||
currencyName: "BNB",
|
||||
@ -986,6 +994,10 @@ const defaultConfig = {
|
||||
name: "BNB Chain 2",
|
||||
url: "https://bsc-dataseed1.ninicoin.io"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com/bsc"
|
||||
},
|
||||
nodereal: {
|
||||
name: "NodeReal",
|
||||
url: "https://binance.nodereal.io"
|
||||
@ -1009,10 +1021,39 @@ const defaultConfig = {
|
||||
},
|
||||
symbol: "BNB",
|
||||
decimals: 18
|
||||
},
|
||||
usdt: {
|
||||
instanceAddress: {
|
||||
"10": "0x261fB4f84bb0BdEe7E035B6a8a08e5c35AdacdDD",
|
||||
"100": "0x3957861d4897d883C9b944C0b4E22bBd0DDE6e21",
|
||||
"1000": "0x6D180403AdFb39F70983eB51A033C5e52eb9BB69",
|
||||
"10000": "0x3722662D8AaB07B216B14C02eF0ee940d14A4200"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x55d398326f99059fF775485246999027B3197955",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "USDT",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
},
|
||||
btcb: {
|
||||
instanceAddress: {
|
||||
"0.0001": "0x736dABbFc8101Ae75287104eCcf67e45D7369Ae1",
|
||||
"0.001": "0x82c7Ce6f1F158cEC5536d591a2BC19864b3CA823",
|
||||
"0.01": "0x8284c96679037d8081E498d8F767cA5a140BFAAf",
|
||||
"0.1": "0x2bcD128Ce23ee30Ee945E613ff129c4DE1102C79"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "BTCB",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
}
|
||||
},
|
||||
optionalTokens: ["usdt", "btcb"],
|
||||
relayerEnsSubdomain: "bsc-tornado",
|
||||
pollInterval: 10,
|
||||
pollInterval: 3,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 8159269,
|
||||
ENCRYPTED_NOTES_BLOCK: 8159269
|
||||
@ -1021,9 +1062,9 @@ const defaultConfig = {
|
||||
[137 /* POLYGON */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 100,
|
||||
fast: 75,
|
||||
standard: 50,
|
||||
instant: 60,
|
||||
fast: 30,
|
||||
standard: 30,
|
||||
low: 30
|
||||
},
|
||||
nativeCurrency: "matic",
|
||||
@ -1063,7 +1104,7 @@ const defaultConfig = {
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "polygon-tornado",
|
||||
pollInterval: 10,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 16257996,
|
||||
ENCRYPTED_NOTES_BLOCK: 16257996
|
||||
@ -1105,17 +1146,20 @@ const defaultConfig = {
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
"100": "0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD"
|
||||
},
|
||||
optionalInstances: ["0.001", "0.01"],
|
||||
symbol: "ETH",
|
||||
decimals: 18
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "optimism-tornado",
|
||||
pollInterval: 15,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 2243694,
|
||||
ENCRYPTED_NOTES_BLOCK: 2243694
|
||||
@ -1124,10 +1168,10 @@ const defaultConfig = {
|
||||
[42161 /* ARBITRUM */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 4,
|
||||
fast: 3,
|
||||
standard: 2.52,
|
||||
low: 2.29
|
||||
instant: 0.02,
|
||||
fast: 0.02,
|
||||
standard: 0.02,
|
||||
low: 0.02
|
||||
},
|
||||
nativeCurrency: "eth",
|
||||
currencyName: "ETH",
|
||||
@ -1148,6 +1192,10 @@ const defaultConfig = {
|
||||
name: "Arbitrum",
|
||||
url: "https://arb1.arbitrum.io/rpc"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com/arbitrum"
|
||||
},
|
||||
stackup: {
|
||||
name: "Stackup",
|
||||
url: "https://public.stackup.sh/api/v1/node/arbitrum-one"
|
||||
@ -1160,6 +1208,150 @@ const defaultConfig = {
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
"100": "0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD"
|
||||
},
|
||||
optionalInstances: ["0.001", "0.01"],
|
||||
symbol: "ETH",
|
||||
decimals: 18
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "arbitrum-tornado",
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 3430605,
|
||||
ENCRYPTED_NOTES_BLOCK: 3430605
|
||||
}
|
||||
},
|
||||
[8453 /* BASE */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 0.1,
|
||||
fast: 0.06,
|
||||
standard: 0.05,
|
||||
low: 0.02
|
||||
},
|
||||
nativeCurrency: "eth",
|
||||
currencyName: "ETH",
|
||||
explorerUrl: "https://basescan.org",
|
||||
merkleTreeHeight: 20,
|
||||
emptyElement: "21663839004416932945382355908790599225266501822907911457504978515578255421292",
|
||||
networkName: "Base",
|
||||
deployedBlock: 23149794,
|
||||
stablecoin: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
||||
multicallContract: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
||||
routerContract: "0x0D5550d52428E7e3175bfc9550207e4ad3859b17",
|
||||
echoContract: "0xa75BF2815618872f155b7C4B0C81bF990f5245E4",
|
||||
offchainOracleContract: "0x00000000000D6FFc74A8feb35aF5827bf57f6786",
|
||||
ovmGasPriceOracleContract: "0x420000000000000000000000000000000000000F",
|
||||
tornadoSubgraph: "tornadocash/base-tornado-subgraph",
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
Base: {
|
||||
name: "Base",
|
||||
url: "https://mainnet.base.org"
|
||||
},
|
||||
stackup: {
|
||||
name: "Stackup",
|
||||
url: "https://public.stackup.sh/api/v1/node/base-mainnet"
|
||||
},
|
||||
oneRpc: {
|
||||
name: "1RPC",
|
||||
url: "https://1rpc.io/base"
|
||||
}
|
||||
},
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
"100": "0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD"
|
||||
},
|
||||
symbol: "ETH",
|
||||
decimals: 18
|
||||
},
|
||||
dai: {
|
||||
instanceAddress: {
|
||||
"10": "0x70CC374aE7D1549a4666b7172B78dDCF672B74f7",
|
||||
"100": "0xD063894588177B8362Dda6C0A7EF09BF6fDF851c",
|
||||
"1000": "0xa7513fdfF61fc83a9C5c08CE31266e6dd400C54E",
|
||||
"10000": "0x8f05eDE57098D843F30bE74AC25c292F87b7f775",
|
||||
"100000": "0xeB7fc86c32e9a5E9DD2a0a78C091b8b625cbee24"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "DAI",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
},
|
||||
tbtc: {
|
||||
instanceAddress: {
|
||||
"0.0001": "0x5465800D7Be34dAe2c1572d2227De94dE93B4432",
|
||||
"0.001": "0xf2d3404c03C8cC0b120bd6E8edD6F69226F03c6d",
|
||||
"0.01": "0x4261d5209A285410DEa8173B6FE1A0e7BCf20f7c",
|
||||
"0.1": "0x9FB147F49bFE17D19789547187EAE2406590b217",
|
||||
"1": "0x2A8515F39716B0C160a3eB32D24E4cbeB76932d2"
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: "0x236aa50979D5f3De3Bd1Eeb40E81137F22ab794b",
|
||||
tokenGasLimit: 7e4,
|
||||
symbol: "tBTC",
|
||||
decimals: 18,
|
||||
gasLimit: 7e5
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "base-tornado",
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 23149794,
|
||||
ENCRYPTED_NOTES_BLOCK: 23149794
|
||||
}
|
||||
},
|
||||
[81457 /* BLAST */]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 1e-3,
|
||||
fast: 1e-3,
|
||||
standard: 1e-3,
|
||||
low: 1e-3
|
||||
},
|
||||
nativeCurrency: "eth",
|
||||
currencyName: "ETH",
|
||||
explorerUrl: "https://blastscan.io",
|
||||
merkleTreeHeight: 20,
|
||||
emptyElement: "21663839004416932945382355908790599225266501822907911457504978515578255421292",
|
||||
networkName: "Blast",
|
||||
deployedBlock: 12144065,
|
||||
stablecoin: "0x4300000000000000000000000000000000000003",
|
||||
multicallContract: "0xcA11bde05977b3631167028862bE2a173976CA11",
|
||||
routerContract: "0x0D5550d52428E7e3175bfc9550207e4ad3859b17",
|
||||
echoContract: "0xa75BF2815618872f155b7C4B0C81bF990f5245E4",
|
||||
ovmGasPriceOracleContract: "0x420000000000000000000000000000000000000F",
|
||||
tornadoSubgraph: "tornadocash/blast-tornado-subgraph",
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
Blast: {
|
||||
name: "Blast",
|
||||
url: "https://rpc.blast.io"
|
||||
},
|
||||
blastApi: {
|
||||
name: "BlastApi",
|
||||
url: "https://blastl2-mainnet.public.blastapi.io"
|
||||
}
|
||||
},
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
"0.001": "0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76",
|
||||
"0.01": "0xA287c40411685438750a247Ca67488DEBe56EE32",
|
||||
"0.1": "0x84443CFd09A48AF6eF360C6976C5392aC5023a1F",
|
||||
"1": "0xd47438C816c9E7f2E2888E060936a499Af9582b3",
|
||||
"10": "0x330bdFADE01eE9bF63C209Ee33102DD334618e0a",
|
||||
@ -1169,11 +1361,11 @@ const defaultConfig = {
|
||||
decimals: 18
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "arbitrum-tornado",
|
||||
pollInterval: 15,
|
||||
relayerEnsSubdomain: "blast-tornado",
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 3430605,
|
||||
ENCRYPTED_NOTES_BLOCK: 3430605
|
||||
NOTE_ACCOUNT_BLOCK: 12144065,
|
||||
ENCRYPTED_NOTES_BLOCK: 12144065
|
||||
}
|
||||
},
|
||||
[100 /* GNOSIS */]: {
|
||||
@ -1221,7 +1413,7 @@ const defaultConfig = {
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "gnosis-tornado",
|
||||
pollInterval: 15,
|
||||
pollInterval: 5,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 17754564,
|
||||
ENCRYPTED_NOTES_BLOCK: 17754564
|
||||
@ -1271,7 +1463,7 @@ const defaultConfig = {
|
||||
}
|
||||
},
|
||||
relayerEnsSubdomain: "avalanche-tornado",
|
||||
pollInterval: 10,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 4429813,
|
||||
ENCRYPTED_NOTES_BLOCK: 4429813
|
||||
@ -1306,6 +1498,14 @@ const defaultConfig = {
|
||||
tornadoSubgraph: "tornadocash/sepolia-tornado-subgraph",
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
oneRpc: {
|
||||
name: "1RPC",
|
||||
url: "https://1rpc.io/sepolia"
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: "Tornado RPC",
|
||||
url: "https://tornadocash-rpc.com/sepolia"
|
||||
},
|
||||
sepolia: {
|
||||
name: "Sepolia RPC",
|
||||
url: "https://rpc.sepolia.org"
|
||||
@ -1314,10 +1514,6 @@ const defaultConfig = {
|
||||
name: "Stackup",
|
||||
url: "https://public.stackup.sh/api/v1/node/ethereum-sepolia"
|
||||
},
|
||||
oneRpc: {
|
||||
name: "1RPC",
|
||||
url: "https://1rpc.io/sepolia"
|
||||
},
|
||||
ethpandaops: {
|
||||
name: "ethpandaops",
|
||||
url: "https://rpc.sepolia.ethpandaops.io"
|
||||
@ -2211,6 +2407,9 @@ class BaseEventsService {
|
||||
fromCache: true
|
||||
};
|
||||
}
|
||||
/**
|
||||
* This may not return in sorted events when called from browser, make sure to sort it again when directly called
|
||||
*/
|
||||
async getSavedEvents() {
|
||||
let dbEvents = await this.getEventsFromDB();
|
||||
if (!dbEvents.lastBlock) {
|
||||
@ -2556,7 +2755,10 @@ class BaseMultiTornadoService extends BaseEventsService {
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{}
|
||||
{
|
||||
depositEvents: [],
|
||||
withdrawalEvents: []
|
||||
}
|
||||
);
|
||||
return {
|
||||
depositEvents,
|
||||
@ -2834,7 +3036,12 @@ class BaseGovernanceService extends BaseEventsService {
|
||||
});
|
||||
}
|
||||
async getVotes(proposalId) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const events = (await this.getSavedEvents()).events.sort((a, b) => {
|
||||
if (a.blockNumber === b.blockNumber) {
|
||||
return a.logIndex - b.logIndex;
|
||||
}
|
||||
return a.blockNumber - b.blockNumber;
|
||||
});
|
||||
const votedEvents = events.filter(
|
||||
(e) => e.event === "Voted" && e.proposalId === proposalId
|
||||
);
|
||||
@ -2863,7 +3070,12 @@ class BaseGovernanceService extends BaseEventsService {
|
||||
return votes;
|
||||
}
|
||||
async getDelegatedBalance(ethAccount) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const events = (await this.getSavedEvents()).events.sort((a, b) => {
|
||||
if (a.blockNumber === b.blockNumber) {
|
||||
return a.logIndex - b.logIndex;
|
||||
}
|
||||
return a.blockNumber - b.blockNumber;
|
||||
});
|
||||
const delegatedAccs = events.filter((e) => e.event === "Delegated" && e.delegateTo === ethAccount).map((e) => e.account);
|
||||
const undelegatedAccs = events.filter((e) => e.event === "Undelegated" && e.delegateFrom === ethAccount).map((e) => e.account);
|
||||
const undel = [...undelegatedAccs];
|
||||
@ -2923,6 +3135,13 @@ const staticRelayers = [
|
||||
hostnames: {},
|
||||
tovarishHost: "tornadowithdraw.com",
|
||||
tovarishNetworks: enabledChains
|
||||
},
|
||||
{
|
||||
ensName: "rpc.tornadowithdraw.eth",
|
||||
relayerAddress: "0xFF787B7A5cd8a88508361E3B7bcE791Aa2796526",
|
||||
hostnames: {},
|
||||
tovarishHost: "tornadocash-rpc.com",
|
||||
tovarishNetworks: enabledChains
|
||||
}
|
||||
];
|
||||
class BaseRegistryService extends BaseEventsService {
|
||||
@ -3182,6 +3401,31 @@ RevenueService: Mismatch on withdrawal logs (${withdrawalLogs.length} ) and even
|
||||
});
|
||||
}
|
||||
}
|
||||
class BaseTransferService extends BaseEventsService {
|
||||
constructor(serviceConstructor) {
|
||||
super({
|
||||
...serviceConstructor,
|
||||
contract: serviceConstructor.Token,
|
||||
type: "Transfer"
|
||||
});
|
||||
}
|
||||
async formatEvents(events) {
|
||||
return events.map(({ blockNumber, index: logIndex, transactionHash, args }) => {
|
||||
const { from, to, value } = args;
|
||||
const eventObjects = {
|
||||
blockNumber,
|
||||
logIndex,
|
||||
transactionHash
|
||||
};
|
||||
return {
|
||||
...eventObjects,
|
||||
from,
|
||||
to,
|
||||
value
|
||||
};
|
||||
}).filter((e) => e);
|
||||
}
|
||||
}
|
||||
|
||||
function zipAsync(file, options) {
|
||||
return new Promise((res, rej) => {
|
||||
@ -3235,11 +3479,11 @@ async function downloadZip({
|
||||
async function saveDBEvents({
|
||||
idb,
|
||||
instanceName,
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
try {
|
||||
const formattedEvents = events.map((e) => {
|
||||
const formattedEvents = newEvents.map((e) => {
|
||||
return {
|
||||
eid: `${e.transactionHash}_${e.logIndex}`,
|
||||
...e
|
||||
@ -3350,11 +3594,49 @@ class DBTornadoService extends BaseTornadoService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
}
|
||||
class DBMultiTornadoService extends BaseMultiTornadoService {
|
||||
staticUrl;
|
||||
idb;
|
||||
zipDigest;
|
||||
constructor(params) {
|
||||
super(params);
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName()
|
||||
});
|
||||
}
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3382,11 +3664,11 @@ class DBEchoService extends BaseEchoService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({ newEvents, lastBlock }) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3414,11 +3696,14 @@ class DBEncryptedNotesService extends BaseEncryptedNotesService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3446,11 +3731,11 @@ class DBGovernanceService extends BaseGovernanceService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({ newEvents, lastBlock }) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3479,11 +3764,14 @@ class DBRegistryService extends BaseRegistryService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock
|
||||
}) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -3572,11 +3860,11 @@ class DBRevenueService extends BaseRevenueService {
|
||||
zipDigest: this.zipDigest
|
||||
});
|
||||
}
|
||||
async saveEvents({ events, lastBlock }) {
|
||||
async saveEvents({ newEvents, lastBlock }) {
|
||||
await saveDBEvents({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock
|
||||
});
|
||||
}
|
||||
@ -9319,7 +9607,7 @@ class TornadoFeeOracle {
|
||||
* (A single block can bump 12.5% of fees, see the methodology https://hackmd.io/@tvanepps/1559-wallets)
|
||||
* (Still it is recommended to use 100% premium for sending transactions to prevent stucking it)
|
||||
*/
|
||||
async gasPrice() {
|
||||
async gasPrice(premium) {
|
||||
const [block, getGasPrice, getPriorityFee] = await Promise.all([
|
||||
this.provider.getBlock("latest"),
|
||||
(async () => {
|
||||
@ -9337,14 +9625,14 @@ class TornadoFeeOracle {
|
||||
}
|
||||
})()
|
||||
]);
|
||||
return block?.baseFeePerGas ? block.baseFeePerGas * BigInt(15) / BigInt(10) + getPriorityFee : getGasPrice;
|
||||
return block?.baseFeePerGas ? block.baseFeePerGas * BigInt(1e4 * (100 + (premium || 50))) / BigInt(1e4 * 100) + getPriorityFee : getGasPrice;
|
||||
}
|
||||
/**
|
||||
* Calculate L1 fee for op-stack chains
|
||||
*
|
||||
* This is required since relayers would pay the full transaction fees for users
|
||||
*/
|
||||
fetchL1OptimismFee(tx) {
|
||||
async fetchL1OptimismFee(tx) {
|
||||
if (!this.ovmGasPriceOracle) {
|
||||
return new Promise((resolve) => resolve(BigInt(0)));
|
||||
}
|
||||
@ -9358,7 +9646,7 @@ class TornadoFeeOracle {
|
||||
to: DUMMY_ADDRESS
|
||||
};
|
||||
}
|
||||
return this.ovmGasPriceOracle.getL1Fee.staticCall(Transaction.from(tx).unsignedSerialized);
|
||||
return await this.ovmGasPriceOracle.getL1Fee.staticCall(Transaction.from(tx).unsignedSerialized) * 12n / 10n;
|
||||
}
|
||||
/**
|
||||
* We don't need to distinguish default refunds by tokens since most users interact with other defi protocols after withdrawal
|
||||
@ -9406,6 +9694,8 @@ const gasZipInbounds = {
|
||||
[NetId.POLYGON]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.OPTIMISM]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.ARBITRUM]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.BASE]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.BLAST]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.GNOSIS]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604",
|
||||
[NetId.AVALANCHE]: "0x391E7C679d29bD940d63be94AD22A25d25b5A604"
|
||||
};
|
||||
@ -9415,6 +9705,8 @@ const gasZipID = {
|
||||
[NetId.POLYGON]: 17,
|
||||
[NetId.OPTIMISM]: 55,
|
||||
[NetId.ARBITRUM]: 57,
|
||||
[NetId.BASE]: 54,
|
||||
[NetId.BLAST]: 96,
|
||||
[NetId.GNOSIS]: 16,
|
||||
[NetId.AVALANCHE]: 15,
|
||||
[NetId.SEPOLIA]: 102
|
||||
@ -9480,7 +9772,7 @@ class IndexedDB {
|
||||
}
|
||||
};
|
||||
this.dbName = dbName;
|
||||
this.dbVersion = 35;
|
||||
this.dbVersion = 36;
|
||||
}
|
||||
async initDB() {
|
||||
try {
|
||||
@ -9676,15 +9968,16 @@ async function getIndexedDB(netId) {
|
||||
}
|
||||
const minimalIndexes = [
|
||||
{
|
||||
name: "blockNumber",
|
||||
unique: false
|
||||
},
|
||||
{
|
||||
name: "transactionHash",
|
||||
unique: false
|
||||
name: "eid",
|
||||
unique: true
|
||||
}
|
||||
];
|
||||
const defaultState = [
|
||||
{
|
||||
name: `tornado_${netId}`,
|
||||
keyPath: "eid",
|
||||
indexes: [...minimalIndexes]
|
||||
},
|
||||
{
|
||||
name: `echo_${netId}`,
|
||||
keyPath: "eid",
|
||||
@ -9712,8 +10005,7 @@ async function getIndexedDB(netId) {
|
||||
]
|
||||
}
|
||||
];
|
||||
const config = getConfig(netId);
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = config;
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = getConfig(netId);
|
||||
const stores = [...defaultState];
|
||||
if (registryContract) {
|
||||
stores.push({
|
||||
@ -10057,122 +10349,6 @@ async function getPermitSignature({
|
||||
})
|
||||
);
|
||||
}
|
||||
async function getPermitCommitmentsSignature({
|
||||
PermitTornado: PermitTornado2,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(["bytes32[]"], [commitments]);
|
||||
return await getPermitSignature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado2.target,
|
||||
value,
|
||||
nonce,
|
||||
deadline: BigInt(commitmentsHash)
|
||||
});
|
||||
}
|
||||
async function getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender,
|
||||
value: amount,
|
||||
nonce,
|
||||
deadline,
|
||||
witness
|
||||
}) {
|
||||
const sigSigner = signer || Token.runner;
|
||||
const provider = sigSigner.provider;
|
||||
const domain = {
|
||||
name: "Permit2",
|
||||
chainId: (await provider.getNetwork()).chainId,
|
||||
verifyingContract: permit2Address
|
||||
};
|
||||
const types = !witness ? {
|
||||
PermitTransferFrom: [
|
||||
{ name: "permitted", type: "TokenPermissions" },
|
||||
{ name: "spender", type: "address" },
|
||||
{ name: "nonce", type: "uint256" },
|
||||
{ name: "deadline", type: "uint256" }
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: "token", type: "address" },
|
||||
{ name: "amount", type: "uint256" }
|
||||
]
|
||||
} : {
|
||||
PermitWitnessTransferFrom: [
|
||||
{ name: "permitted", type: "TokenPermissions" },
|
||||
{ name: "spender", type: "address" },
|
||||
{ name: "nonce", type: "uint256" },
|
||||
{ name: "deadline", type: "uint256" },
|
||||
{ name: "witness", type: witness.witnessTypeName }
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: "token", type: "address" },
|
||||
{ name: "amount", type: "uint256" }
|
||||
],
|
||||
...witness.witnessType
|
||||
};
|
||||
const values = {
|
||||
permitted: {
|
||||
token: Token.target,
|
||||
amount
|
||||
},
|
||||
spender,
|
||||
// Sorted nonce are not required for Permit2
|
||||
nonce: nonce || rBigInt(16),
|
||||
deadline: deadline || MaxUint256
|
||||
};
|
||||
if (witness) {
|
||||
values.witness = witness.witness;
|
||||
}
|
||||
const hash = new TypedDataEncoder(types).hash(values);
|
||||
const signature = Signature.from(await sigSigner.signTypedData(domain, types, values));
|
||||
return {
|
||||
domain,
|
||||
types,
|
||||
values,
|
||||
hash,
|
||||
signature
|
||||
};
|
||||
}
|
||||
async function getPermit2CommitmentsSignature({
|
||||
PermitTornado: PermitTornado2,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
deadline
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(["bytes32[]"], [commitments]);
|
||||
return await getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado2.target,
|
||||
value,
|
||||
nonce,
|
||||
deadline,
|
||||
witness: {
|
||||
witnessTypeName: "PermitCommitments",
|
||||
witnessType: {
|
||||
PermitCommitments: [
|
||||
{ name: "instance", type: "address" },
|
||||
{ name: "commitmentsHash", type: "bytes32" }
|
||||
]
|
||||
},
|
||||
witness: {
|
||||
instance: PermitTornado2.target,
|
||||
commitmentsHash
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
class TokenPriceOracle {
|
||||
oracle;
|
||||
@ -10605,4 +10781,4 @@ async function calculateSnarkProof(input, circuit, provingKey) {
|
||||
return { proof, args };
|
||||
}
|
||||
|
||||
export { BaseEchoService, BaseEncryptedNotesService, BaseEventsService, BaseGovernanceService, BaseMultiTornadoService, BaseRegistryService, BaseRevenueService, BaseTornadoService, BatchBlockService, BatchEventsService, BatchTransactionService, DBEchoService, DBEncryptedNotesService, DBGovernanceService, 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, getPermit2CommitmentsSignature, getPermit2Signature, getPermitCommitmentsSignature, 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, 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 };
|
||||
|
2
dist/merkleTree.d.ts
vendored
2
dist/merkleTree.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from '@tornado/fixed-merkle-tree';
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from 'fixed-merkle-tree';
|
||||
import type { Tornado } from '@tornado/contracts';
|
||||
import type { DepositType } from './deposits';
|
||||
import type { DepositsEvents } from './events';
|
||||
|
19033
dist/merkleTreeWorker.js
vendored
19033
dist/merkleTreeWorker.js
vendored
File diff suppressed because it is too large
Load Diff
29869
dist/merkleTreeWorker.umd.js
vendored
29869
dist/merkleTreeWorker.umd.js
vendored
File diff suppressed because it is too large
Load Diff
2
dist/merkleTreeWorker.umd.min.js
vendored
2
dist/merkleTreeWorker.umd.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/mimc.d.ts
vendored
2
dist/mimc.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
import { MimcSponge } from 'circomlibjs';
|
||||
import type { Element, HashFunction } from '@tornado/fixed-merkle-tree';
|
||||
import type { Element, HashFunction } from 'fixed-merkle-tree';
|
||||
export declare class Mimc {
|
||||
sponge?: MimcSponge;
|
||||
hash?: HashFunction<Element>;
|
||||
|
3
dist/networkConfig.d.ts
vendored
3
dist/networkConfig.d.ts
vendored
@ -8,6 +8,8 @@ export declare enum NetId {
|
||||
POLYGON = 137,
|
||||
OPTIMISM = 10,
|
||||
ARBITRUM = 42161,
|
||||
BASE = 8453,
|
||||
BLAST = 81457,
|
||||
GNOSIS = 100,
|
||||
AVALANCHE = 43114,
|
||||
SEPOLIA = 11155111
|
||||
@ -31,6 +33,7 @@ export interface TornadoInstance {
|
||||
instanceAddress: {
|
||||
[key: string]: string;
|
||||
};
|
||||
instanceApproval?: boolean;
|
||||
optionalInstances?: string[];
|
||||
tokenAddress?: string;
|
||||
tokenGasLimit?: number;
|
||||
|
176
dist/permit.d.ts
vendored
176
dist/permit.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
import { ERC20Permit, ERC20Mock, TORN, PermitTornado } from '@tornado/contracts';
|
||||
import { BaseContract, Signature, Signer, TypedDataField } from 'ethers';
|
||||
import { ERC20Permit, ERC20Mock, TORN } from '@tornado/contracts';
|
||||
import { Signature, Signer, TypedDataField } from 'ethers';
|
||||
export interface PermitValue {
|
||||
spender: string;
|
||||
value: bigint;
|
||||
@ -27,25 +27,85 @@ export declare function getPermitSignature({ Token, signer, spender, value, nonc
|
||||
Token: ERC20Permit | ERC20Mock | TORN;
|
||||
signer?: Signer;
|
||||
}): Promise<Signature>;
|
||||
export declare function getPermitCommitmentsSignature({ PermitTornado, Token, signer, denomination, commitments, nonce, }: PermitCommitments & {
|
||||
/**
|
||||
export async function getPermitCommitmentsSignature({
|
||||
PermitTornado,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
}: PermitCommitments & {
|
||||
PermitTornado: PermitTornado;
|
||||
Token: ERC20Permit | ERC20Mock | TORN;
|
||||
signer?: Signer;
|
||||
}): Promise<Signature>;
|
||||
export declare function getPermit2Signature({ Token, signer, spender, value: amount, nonce, deadline, witness, }: PermitValue & {
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(['bytes32[]'], [commitments]);
|
||||
|
||||
return await getPermitSignature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado.target as string,
|
||||
value,
|
||||
nonce,
|
||||
deadline: BigInt(commitmentsHash),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender,
|
||||
value: amount,
|
||||
nonce,
|
||||
deadline,
|
||||
witness,
|
||||
}: PermitValue & {
|
||||
Token: BaseContract;
|
||||
signer?: Signer;
|
||||
witness?: Witness;
|
||||
}): Promise<{
|
||||
domain: {
|
||||
name: string;
|
||||
chainId: bigint;
|
||||
verifyingContract: string;
|
||||
}) {
|
||||
const sigSigner = (signer || Token.runner) as Signer & { address: string };
|
||||
const provider = sigSigner.provider as Provider;
|
||||
|
||||
const domain = {
|
||||
name: 'Permit2',
|
||||
chainId: (await provider.getNetwork()).chainId,
|
||||
verifyingContract: permit2Address,
|
||||
};
|
||||
types: {
|
||||
|
||||
const types: {
|
||||
[key: string]: TypedDataField[];
|
||||
};
|
||||
values: {
|
||||
} = !witness
|
||||
? {
|
||||
PermitTransferFrom: [
|
||||
{ name: 'permitted', type: 'TokenPermissions' },
|
||||
{ name: 'spender', type: 'address' },
|
||||
{ name: 'nonce', type: 'uint256' },
|
||||
{ name: 'deadline', type: 'uint256' },
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: 'token', type: 'address' },
|
||||
{ name: 'amount', type: 'uint256' },
|
||||
],
|
||||
}
|
||||
: {
|
||||
PermitWitnessTransferFrom: [
|
||||
{ name: 'permitted', type: 'TokenPermissions' },
|
||||
{ name: 'spender', type: 'address' },
|
||||
{ name: 'nonce', type: 'uint256' },
|
||||
{ name: 'deadline', type: 'uint256' },
|
||||
{ name: 'witness', type: witness.witnessTypeName },
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: 'token', type: 'address' },
|
||||
{ name: 'amount', type: 'uint256' },
|
||||
],
|
||||
...witness.witnessType,
|
||||
};
|
||||
|
||||
const values: {
|
||||
permitted: {
|
||||
token: string;
|
||||
amount: bigint;
|
||||
@ -53,34 +113,72 @@ export declare function getPermit2Signature({ Token, signer, spender, value: amo
|
||||
spender: string;
|
||||
nonce: bigint;
|
||||
deadline: bigint;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
witness?: any;
|
||||
} = {
|
||||
permitted: {
|
||||
token: Token.target as string,
|
||||
amount,
|
||||
},
|
||||
spender,
|
||||
// Sorted nonce are not required for Permit2
|
||||
nonce: nonce || rBigInt(16),
|
||||
deadline: deadline || MaxUint256,
|
||||
};
|
||||
hash: string;
|
||||
signature: Signature;
|
||||
}>;
|
||||
export declare function getPermit2CommitmentsSignature({ PermitTornado, Token, signer, denomination, commitments, nonce, deadline, }: PermitCommitments & {
|
||||
|
||||
if (witness) {
|
||||
values.witness = witness.witness;
|
||||
}
|
||||
|
||||
const hash = new TypedDataEncoder(types).hash(values);
|
||||
|
||||
const signature = Signature.from(await sigSigner.signTypedData(domain, types, values));
|
||||
|
||||
return {
|
||||
domain,
|
||||
types,
|
||||
values,
|
||||
hash,
|
||||
signature,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getPermit2CommitmentsSignature({
|
||||
PermitTornado,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
deadline,
|
||||
}: PermitCommitments & {
|
||||
PermitTornado: PermitTornado;
|
||||
Token: BaseContract;
|
||||
signer?: Signer;
|
||||
}): Promise<{
|
||||
domain: {
|
||||
name: string;
|
||||
chainId: bigint;
|
||||
verifyingContract: string;
|
||||
};
|
||||
types: {
|
||||
[key: string]: TypedDataField[];
|
||||
};
|
||||
values: {
|
||||
permitted: {
|
||||
token: string;
|
||||
amount: bigint;
|
||||
};
|
||||
spender: string;
|
||||
nonce: bigint;
|
||||
deadline: bigint;
|
||||
witness?: any;
|
||||
};
|
||||
hash: string;
|
||||
signature: Signature;
|
||||
}>;
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(['bytes32[]'], [commitments]);
|
||||
|
||||
return await getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado.target as string,
|
||||
value,
|
||||
nonce,
|
||||
deadline,
|
||||
witness: {
|
||||
witnessTypeName: 'PermitCommitments',
|
||||
witnessType: {
|
||||
PermitCommitments: [
|
||||
{ name: 'instance', type: 'address' },
|
||||
{ name: 'commitmentsHash', type: 'bytes32' },
|
||||
],
|
||||
},
|
||||
witness: {
|
||||
instance: PermitTornado.target,
|
||||
commitmentsHash,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
**/
|
||||
|
4
dist/providers.d.ts
vendored
4
dist/providers.d.ts
vendored
@ -43,6 +43,7 @@ export interface TornadoWalletOptions {
|
||||
gasLimitBump?: number;
|
||||
gasFailover?: boolean;
|
||||
bumpNonce?: boolean;
|
||||
readonlyProvider?: Provider;
|
||||
}
|
||||
export declare class TornadoWallet extends Wallet {
|
||||
nonce?: number;
|
||||
@ -69,7 +70,8 @@ export declare class TornadoRpcSigner extends JsonRpcSigner {
|
||||
gasLimitBump: number;
|
||||
gasFailover: boolean;
|
||||
bumpNonce: boolean;
|
||||
constructor(provider: JsonRpcApiProvider, address: string, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
readonlyProvider?: Provider;
|
||||
constructor(provider: JsonRpcApiProvider, address: string, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce, readonlyProvider }?: TornadoWalletOptions);
|
||||
sendUncheckedTransaction(tx: TransactionRequest): Promise<string>;
|
||||
}
|
||||
export type connectWalletFunc = (...args: any[]) => Promise<void>;
|
||||
|
45136
dist/tornado.umd.js
vendored
45136
dist/tornado.umd.js
vendored
File diff suppressed because one or more lines are too long
6
dist/tornado.umd.min.js
vendored
6
dist/tornado.umd.min.js
vendored
File diff suppressed because one or more lines are too long
9737
dist/tornadoContracts.umd.js
vendored
9737
dist/tornadoContracts.umd.js
vendored
File diff suppressed because one or more lines are too long
2
dist/tornadoContracts.umd.min.js
vendored
2
dist/tornadoContracts.umd.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/websnark.d.ts
vendored
2
dist/websnark.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import type { Element } from '@tornado/fixed-merkle-tree';
|
||||
import type { Element } from 'fixed-merkle-tree';
|
||||
export interface snarkInputs {
|
||||
root: Element;
|
||||
nullifierHex: string;
|
||||
|
20
package.json
20
package.json
@ -13,7 +13,10 @@
|
||||
"lint": "eslint src/**/*.ts test/**/*.ts --ext .ts --ignore-pattern src/typechain",
|
||||
"build:node": "rollup -c",
|
||||
"build:web": "webpack",
|
||||
"build": "yarn types && yarn build:node && yarn build:web",
|
||||
"build:hash": "ts-node scripts/hash.ts",
|
||||
"build": "yarn types && yarn build:node && yarn build:web && yarn build:hash",
|
||||
"ipfs:build": "docker build -t tornado-core .",
|
||||
"ipfs:hash": "docker container run --rm -it --entrypoint cat tornado-core /app/dist/hashes.json",
|
||||
"test": "nyc mocha --require ts-node/register --require source-map-support/register --recursive 'test/**/*.ts' --timeout '300000'"
|
||||
},
|
||||
"author": "",
|
||||
@ -34,10 +37,7 @@
|
||||
"dependencies": {
|
||||
"@ensdomains/content-hash": "2.5.7",
|
||||
"@metamask/eth-sig-util": "^8.0.0",
|
||||
"@tornado/contracts": "git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#1b1d707878c16a3dc60d295299d4f0e7ce6ba831",
|
||||
"@tornado/fixed-merkle-tree": "^0.7.3",
|
||||
"@tornado/snarkjs": "^0.1.20",
|
||||
"@tornado/websnark": "^0.0.4",
|
||||
"@tornado/contracts": "git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#093ae2210e1f1b016b756b4db200c4a1b3308408",
|
||||
"ajv": "^8.17.1",
|
||||
"bn.js": "^5.2.1",
|
||||
"circomlibjs": "0.1.7",
|
||||
@ -45,7 +45,10 @@
|
||||
"ethers": "^6.13.4",
|
||||
"ffjavascript": "0.2.48",
|
||||
"fflate": "^0.8.2",
|
||||
"idb": "^8.0.0"
|
||||
"fixed-merkle-tree": "0.7.3",
|
||||
"idb": "^8.0.0",
|
||||
"snarkjs": "git+https://github.com/tornadocontrib/snarkjs.git#2c964b3fe6019e057acab04cc17705d1f7fdaf9a",
|
||||
"websnark": "git+https://github.com/tornadocontrib/websnark.git#f0ddbf34b3045cac9e6d3e4d977bf3b439869fae"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.7",
|
||||
@ -69,6 +72,7 @@
|
||||
"@types/node-fetch": "^2.6.11",
|
||||
"@typescript-eslint/eslint-plugin": "^8.11.0",
|
||||
"@typescript-eslint/parser": "^8.11.0",
|
||||
"chai": "4.5.0",
|
||||
"esbuild-loader": "^4.2.2",
|
||||
"eslint": "8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
@ -96,6 +100,8 @@
|
||||
"strip-ansi": "6.0.1",
|
||||
"@adraffy/ens-normalize": "1.10.1",
|
||||
"@noble/curves": "1.2.0",
|
||||
"@noble/hashes": "1.3.2"
|
||||
"@noble/hashes": "1.3.2",
|
||||
"big-integer": "1.6.52",
|
||||
"ffjavascript": "0.2.48"
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ const external = Object.keys(pkgJson.dependencies).concat(
|
||||
'http-proxy-agent',
|
||||
'https-proxy-agent',
|
||||
'socks-proxy-agent',
|
||||
'@tornado/websnark/src/utils',
|
||||
'@tornado/websnark/src/groth16',
|
||||
'websnark/src/utils',
|
||||
'websnark/src/groth16',
|
||||
]
|
||||
);
|
||||
|
||||
|
36
scripts/hash.ts
Normal file
36
scripts/hash.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import path from 'path'
|
||||
import { readFile, readdir, writeFile } from 'fs/promises';
|
||||
import { bytesToBase64, digest } from '../src';
|
||||
|
||||
async function content(file: string) {
|
||||
const content = new Uint8Array(await readFile(file));
|
||||
|
||||
const hash = 'sha384-' + bytesToBase64(await digest(content));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
async function hash() {
|
||||
const staticFiles = await readdir('dist');
|
||||
|
||||
const hashes = {} as {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
for (const filePath of staticFiles) {
|
||||
const file = path.join('dist', filePath).replaceAll(path.sep, path.posix.sep);
|
||||
|
||||
if (!['.js', '.mjs'].includes(path.extname(file))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const hash = await content(file);
|
||||
|
||||
hashes[file] = hash;
|
||||
}
|
||||
|
||||
await writeFile('dist/hashes.json', JSON.stringify(hashes, null, 2));
|
||||
|
||||
console.log('hashes', hashes);
|
||||
}
|
||||
hash();
|
@ -22,7 +22,7 @@ import {
|
||||
Tornado__factory,
|
||||
} from '@tornado/contracts';
|
||||
|
||||
import type { MerkleTree } from '@tornado/fixed-merkle-tree';
|
||||
import type { MerkleTree } from 'fixed-merkle-tree';
|
||||
import {
|
||||
BatchEventsService,
|
||||
BatchBlockService,
|
||||
@ -36,7 +36,7 @@ import { enabledChains, type NetIdType, type SubdomainMap } from '../networkConf
|
||||
import { RelayerParams, MIN_STAKE_BALANCE } from '../relayerClient';
|
||||
import type { TovarishClient } from '../tovarishClient';
|
||||
|
||||
import type { ReverseRecords } from '../typechain';
|
||||
import type { ERC20, ReverseRecords } from '../typechain';
|
||||
import type { MerkleTreeService } from '../merkleTree';
|
||||
import type { DepositType } from '../deposits';
|
||||
import type {
|
||||
@ -60,6 +60,7 @@ import type {
|
||||
StakeBurnedEvents,
|
||||
MultiDepositsEvents,
|
||||
MultiWithdrawalsEvents,
|
||||
TransferEvents,
|
||||
} from './types';
|
||||
|
||||
export interface BaseEventsServiceConstructor {
|
||||
@ -156,6 +157,9 @@ export class BaseEventsService<EventType extends MinimalEvents> {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This may not return in sorted events when called from browser, make sure to sort it again when directly called
|
||||
*/
|
||||
async getSavedEvents(): Promise<BaseEvents<EventType> | CachedEvents<EventType>> {
|
||||
let dbEvents = await this.getEventsFromDB();
|
||||
|
||||
@ -613,9 +617,9 @@ export class BaseMultiTornadoService extends BaseEventsService<MultiDepositsEven
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as {
|
||||
depositEvents: MultiDepositsEvents[];
|
||||
withdrawalEvents: MultiWithdrawalsEvents[];
|
||||
{
|
||||
depositEvents: [] as MultiDepositsEvents[],
|
||||
withdrawalEvents: [] as MultiWithdrawalsEvents[],
|
||||
},
|
||||
);
|
||||
|
||||
@ -992,7 +996,12 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
}
|
||||
|
||||
async getVotes(proposalId: number): Promise<GovernanceVotes[]> {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const events = (await this.getSavedEvents()).events.sort((a, b) => {
|
||||
if (a.blockNumber === b.blockNumber) {
|
||||
return a.logIndex - b.logIndex;
|
||||
}
|
||||
return a.blockNumber - b.blockNumber;
|
||||
});
|
||||
|
||||
const votedEvents = events.filter(
|
||||
(e) => e.event === 'Voted' && (e as GovernanceVotedEvents).proposalId === proposalId,
|
||||
@ -1030,7 +1039,12 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
}
|
||||
|
||||
async getDelegatedBalance(ethAccount: string) {
|
||||
const { events } = await this.getSavedEvents();
|
||||
const events = (await this.getSavedEvents()).events.sort((a, b) => {
|
||||
if (a.blockNumber === b.blockNumber) {
|
||||
return a.logIndex - b.logIndex;
|
||||
}
|
||||
return a.blockNumber - b.blockNumber;
|
||||
});
|
||||
|
||||
const delegatedAccs = events
|
||||
.filter((e) => e.event === 'Delegated' && (e as GovernanceDelegatedEvents).delegateTo === ethAccount)
|
||||
@ -1126,6 +1140,13 @@ const staticRelayers: CachedRelayerInfo[] = [
|
||||
tovarishHost: 'tornadowithdraw.com',
|
||||
tovarishNetworks: enabledChains,
|
||||
},
|
||||
{
|
||||
ensName: 'rpc.tornadowithdraw.eth',
|
||||
relayerAddress: '0xFF787B7A5cd8a88508361E3B7bcE791Aa2796526',
|
||||
hostnames: {},
|
||||
tovarishHost: 'tornadocash-rpc.com',
|
||||
tovarishNetworks: enabledChains,
|
||||
},
|
||||
];
|
||||
|
||||
export interface CachedRelayers {
|
||||
@ -1484,3 +1505,38 @@ export class BaseRevenueService extends BaseEventsService<StakeBurnedEvents> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface BaseTransferServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Token: ERC20;
|
||||
}
|
||||
|
||||
export class BaseTransferService extends BaseEventsService<TransferEvents> {
|
||||
constructor(serviceConstructor: BaseTransferServiceConstructor) {
|
||||
super({
|
||||
...serviceConstructor,
|
||||
contract: serviceConstructor.Token,
|
||||
type: 'Transfer',
|
||||
});
|
||||
}
|
||||
|
||||
async formatEvents(events: EventLog[]) {
|
||||
return events
|
||||
.map(({ blockNumber, index: logIndex, transactionHash, args }) => {
|
||||
const { from, to, value } = args;
|
||||
|
||||
const eventObjects = {
|
||||
blockNumber,
|
||||
logIndex,
|
||||
transactionHash,
|
||||
};
|
||||
|
||||
return {
|
||||
...eventObjects,
|
||||
from,
|
||||
to,
|
||||
value,
|
||||
};
|
||||
})
|
||||
.filter((e) => e) as TransferEvents[];
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,8 @@ import {
|
||||
BaseRevenueService,
|
||||
BaseRevenueServiceConstructor,
|
||||
CachedRelayers,
|
||||
BaseMultiTornadoService,
|
||||
BaseMultiTornadoServiceConstructor,
|
||||
} from './base';
|
||||
|
||||
import {
|
||||
@ -30,21 +32,23 @@ import {
|
||||
AllGovernanceEvents,
|
||||
AllRelayerRegistryEvents,
|
||||
StakeBurnedEvents,
|
||||
MultiDepositsEvents,
|
||||
MultiWithdrawalsEvents,
|
||||
} from './types';
|
||||
|
||||
export async function saveDBEvents<T extends MinimalEvents>({
|
||||
idb,
|
||||
instanceName,
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: {
|
||||
idb: IndexedDB;
|
||||
instanceName: string;
|
||||
events: T[];
|
||||
newEvents: T[];
|
||||
lastBlock: number;
|
||||
}) {
|
||||
try {
|
||||
const formattedEvents = events.map((e) => {
|
||||
const formattedEvents = newEvents.map((e) => {
|
||||
return {
|
||||
eid: `${e.transactionHash}_${e.logIndex}`,
|
||||
...e,
|
||||
@ -192,11 +196,63 @@ export class DBTornadoService extends BaseTornadoService {
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ events, lastBlock }: BaseEvents<DepositsEvents | WithdrawalsEvents>) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<DepositsEvents | WithdrawalsEvents> & { newEvents: (DepositsEvents | WithdrawalsEvents)[] }) {
|
||||
await saveDBEvents<DepositsEvents | WithdrawalsEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBMultiTornadoServiceConstructor extends BaseMultiTornadoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBMultiTornadoService extends BaseMultiTornadoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
|
||||
constructor(params: DBMultiTornadoServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<MultiDepositsEvents | MultiWithdrawalsEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<MultiDepositsEvents | MultiWithdrawalsEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<MultiDepositsEvents | MultiWithdrawalsEvents> & {
|
||||
newEvents: (MultiDepositsEvents | MultiWithdrawalsEvents)[];
|
||||
}) {
|
||||
await saveDBEvents<MultiDepositsEvents | MultiWithdrawalsEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
@ -236,11 +292,11 @@ export class DBEchoService extends BaseEchoService {
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ events, lastBlock }: BaseEvents<EchoEvents>) {
|
||||
async saveEvents({ newEvents, lastBlock }: BaseEvents<EchoEvents> & { newEvents: EchoEvents[] }) {
|
||||
await saveDBEvents<EchoEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
@ -280,11 +336,14 @@ export class DBEncryptedNotesService extends BaseEncryptedNotesService {
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ events, lastBlock }: BaseEvents<EncryptedNotesEvents>) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<EncryptedNotesEvents> & { newEvents: EncryptedNotesEvents[] }) {
|
||||
await saveDBEvents<EncryptedNotesEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
@ -324,11 +383,11 @@ export class DBGovernanceService extends BaseGovernanceService {
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ events, lastBlock }: BaseEvents<AllGovernanceEvents>) {
|
||||
async saveEvents({ newEvents, lastBlock }: BaseEvents<AllGovernanceEvents> & { newEvents: AllGovernanceEvents[] }) {
|
||||
await saveDBEvents<AllGovernanceEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
@ -369,11 +428,14 @@ export class DBRegistryService extends BaseRegistryService {
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ events, lastBlock }: BaseEvents<AllRelayerRegistryEvents>) {
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<AllRelayerRegistryEvents> & { newEvents: AllRelayerRegistryEvents[] }) {
|
||||
await saveDBEvents<AllRelayerRegistryEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
@ -486,11 +548,11 @@ export class DBRevenueService extends BaseRevenueService {
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ events, lastBlock }: BaseEvents<StakeBurnedEvents>) {
|
||||
async saveEvents({ newEvents, lastBlock }: BaseEvents<StakeBurnedEvents> & { newEvents: StakeBurnedEvents[] }) {
|
||||
await saveDBEvents<StakeBurnedEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
events,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
|
@ -132,3 +132,9 @@ export interface EchoEvents extends MinimalEvents {
|
||||
export interface EncryptedNotesEvents extends MinimalEvents {
|
||||
encryptedNote: string;
|
||||
}
|
||||
|
||||
export interface TransferEvents extends MinimalEvents {
|
||||
from: string;
|
||||
to: string;
|
||||
value: bigint;
|
||||
}
|
||||
|
12
src/fees.ts
12
src/fees.ts
@ -55,7 +55,7 @@ export class TornadoFeeOracle {
|
||||
* (A single block can bump 12.5% of fees, see the methodology https://hackmd.io/@tvanepps/1559-wallets)
|
||||
* (Still it is recommended to use 100% premium for sending transactions to prevent stucking it)
|
||||
*/
|
||||
async gasPrice() {
|
||||
async gasPrice(premium?: number) {
|
||||
const [block, getGasPrice, getPriorityFee] = await Promise.all([
|
||||
this.provider.getBlock('latest'),
|
||||
(async () => {
|
||||
@ -74,7 +74,9 @@ export class TornadoFeeOracle {
|
||||
})(),
|
||||
]);
|
||||
|
||||
return block?.baseFeePerGas ? (block.baseFeePerGas * BigInt(15)) / BigInt(10) + getPriorityFee : getGasPrice;
|
||||
return block?.baseFeePerGas
|
||||
? (block.baseFeePerGas * BigInt(10000 * (100 + (premium || 50)))) / BigInt(10000 * 100) + getPriorityFee
|
||||
: getGasPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,7 +84,7 @@ export class TornadoFeeOracle {
|
||||
*
|
||||
* This is required since relayers would pay the full transaction fees for users
|
||||
*/
|
||||
fetchL1OptimismFee(tx?: TransactionLike): Promise<bigint> {
|
||||
async fetchL1OptimismFee(tx?: TransactionLike): Promise<bigint> {
|
||||
if (!this.ovmGasPriceOracle) {
|
||||
return new Promise((resolve) => resolve(BigInt(0)));
|
||||
}
|
||||
@ -100,7 +102,9 @@ export class TornadoFeeOracle {
|
||||
};
|
||||
}
|
||||
|
||||
return this.ovmGasPriceOracle.getL1Fee.staticCall(Transaction.from(tx).unsignedSerialized);
|
||||
return (
|
||||
((await this.ovmGasPriceOracle.getL1Fee.staticCall(Transaction.from(tx).unsignedSerialized)) * 12n) / 10n
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,8 @@ export const gasZipInbounds: { [key in NetIdType]: string } = {
|
||||
[NetId.POLYGON]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.OPTIMISM]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.ARBITRUM]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.BASE]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.BLAST]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.GNOSIS]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.AVALANCHE]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
};
|
||||
@ -19,6 +21,8 @@ export const gasZipID: { [key in NetIdType]: number } = {
|
||||
[NetId.POLYGON]: 17,
|
||||
[NetId.OPTIMISM]: 55,
|
||||
[NetId.ARBITRUM]: 57,
|
||||
[NetId.BASE]: 54,
|
||||
[NetId.BLAST]: 96,
|
||||
[NetId.GNOSIS]: 16,
|
||||
[NetId.AVALANCHE]: 15,
|
||||
[NetId.SEPOLIA]: 102,
|
||||
|
19
src/idb.ts
19
src/idb.ts
@ -55,7 +55,7 @@ export class IndexedDB {
|
||||
};
|
||||
|
||||
this.dbName = dbName;
|
||||
this.dbVersion = 35;
|
||||
this.dbVersion = 36;
|
||||
}
|
||||
|
||||
async initDB() {
|
||||
@ -324,16 +324,17 @@ export async function getIndexedDB(netId?: NetIdType) {
|
||||
|
||||
const minimalIndexes = [
|
||||
{
|
||||
name: 'blockNumber',
|
||||
unique: false,
|
||||
},
|
||||
{
|
||||
name: 'transactionHash',
|
||||
unique: false,
|
||||
name: 'eid',
|
||||
unique: true,
|
||||
},
|
||||
];
|
||||
|
||||
const defaultState = [
|
||||
{
|
||||
name: `tornado_${netId}`,
|
||||
keyPath: 'eid',
|
||||
indexes: [...minimalIndexes],
|
||||
},
|
||||
{
|
||||
name: `echo_${netId}`,
|
||||
keyPath: 'eid',
|
||||
@ -362,9 +363,7 @@ export async function getIndexedDB(netId?: NetIdType) {
|
||||
},
|
||||
];
|
||||
|
||||
const config = getConfig(netId);
|
||||
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = config;
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = getConfig(netId);
|
||||
|
||||
const stores = [...defaultState];
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Worker as NodeWorker } from 'worker_threads';
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from '@tornado/fixed-merkle-tree';
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from 'fixed-merkle-tree';
|
||||
import type { Tornado } from '@tornado/contracts';
|
||||
import { isNode, toFixedHex } from './utils';
|
||||
import { mimc } from './mimc';
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import workerThreads from 'worker_threads';
|
||||
import { MerkleTree, Element, TreeEdge, PartialMerkleTree } from '@tornado/fixed-merkle-tree';
|
||||
import { MerkleTree, Element, TreeEdge, PartialMerkleTree } from 'fixed-merkle-tree';
|
||||
import { mimc } from './mimc';
|
||||
import { isNode } from './utils';
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MimcSponge, buildMimcSponge } from 'circomlibjs';
|
||||
import type { Element, HashFunction } from '@tornado/fixed-merkle-tree';
|
||||
import type { Element, HashFunction } from 'fixed-merkle-tree';
|
||||
|
||||
export class Mimc {
|
||||
sponge?: MimcSponge;
|
||||
|
@ -9,6 +9,8 @@ export enum NetId {
|
||||
POLYGON = 137,
|
||||
OPTIMISM = 10,
|
||||
ARBITRUM = 42161,
|
||||
BASE = 8453,
|
||||
BLAST = 81457,
|
||||
GNOSIS = 100,
|
||||
AVALANCHE = 43114,
|
||||
SEPOLIA = 11155111,
|
||||
@ -38,6 +40,7 @@ export interface TornadoInstance {
|
||||
instanceAddress: {
|
||||
[key: string]: string;
|
||||
};
|
||||
instanceApproval?: boolean;
|
||||
optionalInstances?: string[];
|
||||
tokenAddress?: string;
|
||||
tokenGasLimit?: number;
|
||||
@ -132,6 +135,10 @@ export const defaultConfig: networkConfig = {
|
||||
name: 'MEV Blocker',
|
||||
url: 'https://rpc.mevblocker.io',
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://tornadocash-rpc.com',
|
||||
},
|
||||
keydonix: {
|
||||
name: 'Horswap ( Keydonix )',
|
||||
url: 'https://ethereum.keydonix.com/v1/mainnet',
|
||||
@ -251,10 +258,10 @@ export const defaultConfig: networkConfig = {
|
||||
[NetId.BSC]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 5,
|
||||
fast: 5,
|
||||
standard: 5,
|
||||
low: 5,
|
||||
instant: 3,
|
||||
fast: 1,
|
||||
standard: 1,
|
||||
low: 1,
|
||||
},
|
||||
nativeCurrency: 'bnb',
|
||||
currencyName: 'BNB',
|
||||
@ -279,6 +286,10 @@ export const defaultConfig: networkConfig = {
|
||||
name: 'BNB Chain 2',
|
||||
url: 'https://bsc-dataseed1.ninicoin.io',
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://tornadocash-rpc.com/bsc',
|
||||
},
|
||||
nodereal: {
|
||||
name: 'NodeReal',
|
||||
url: 'https://binance.nodereal.io',
|
||||
@ -303,9 +314,38 @@ export const defaultConfig: networkConfig = {
|
||||
symbol: 'BNB',
|
||||
decimals: 18,
|
||||
},
|
||||
usdt: {
|
||||
instanceAddress: {
|
||||
'10': '0x261fB4f84bb0BdEe7E035B6a8a08e5c35AdacdDD',
|
||||
'100': '0x3957861d4897d883C9b944C0b4E22bBd0DDE6e21',
|
||||
'1000': '0x6D180403AdFb39F70983eB51A033C5e52eb9BB69',
|
||||
'10000': '0x3722662D8AaB07B216B14C02eF0ee940d14A4200',
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: '0x55d398326f99059fF775485246999027B3197955',
|
||||
tokenGasLimit: 70_000,
|
||||
symbol: 'USDT',
|
||||
decimals: 18,
|
||||
gasLimit: 700_000,
|
||||
},
|
||||
btcb: {
|
||||
instanceAddress: {
|
||||
'0.0001': '0x736dABbFc8101Ae75287104eCcf67e45D7369Ae1',
|
||||
'0.001': '0x82c7Ce6f1F158cEC5536d591a2BC19864b3CA823',
|
||||
'0.01': '0x8284c96679037d8081E498d8F767cA5a140BFAAf',
|
||||
'0.1': '0x2bcD128Ce23ee30Ee945E613ff129c4DE1102C79',
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: '0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c',
|
||||
tokenGasLimit: 70_000,
|
||||
symbol: 'BTCB',
|
||||
decimals: 18,
|
||||
gasLimit: 700_000,
|
||||
},
|
||||
},
|
||||
optionalTokens: ['usdt', 'btcb'],
|
||||
relayerEnsSubdomain: 'bsc-tornado',
|
||||
pollInterval: 10,
|
||||
pollInterval: 3,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 8159269,
|
||||
ENCRYPTED_NOTES_BLOCK: 8159269,
|
||||
@ -314,9 +354,9 @@ export const defaultConfig: networkConfig = {
|
||||
[NetId.POLYGON]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 100,
|
||||
fast: 75,
|
||||
standard: 50,
|
||||
instant: 60,
|
||||
fast: 30,
|
||||
standard: 30,
|
||||
low: 30,
|
||||
},
|
||||
nativeCurrency: 'matic',
|
||||
@ -356,7 +396,7 @@ export const defaultConfig: networkConfig = {
|
||||
},
|
||||
},
|
||||
relayerEnsSubdomain: 'polygon-tornado',
|
||||
pollInterval: 10,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 16257996,
|
||||
ENCRYPTED_NOTES_BLOCK: 16257996,
|
||||
@ -398,17 +438,20 @@ export const defaultConfig: networkConfig = {
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
'0.001': '0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76',
|
||||
'0.01': '0xA287c40411685438750a247Ca67488DEBe56EE32',
|
||||
'0.1': '0x84443CFd09A48AF6eF360C6976C5392aC5023a1F',
|
||||
'1': '0xd47438C816c9E7f2E2888E060936a499Af9582b3',
|
||||
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD',
|
||||
},
|
||||
optionalInstances: ['0.001', '0.01'],
|
||||
symbol: 'ETH',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
relayerEnsSubdomain: 'optimism-tornado',
|
||||
pollInterval: 15,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 2243694,
|
||||
ENCRYPTED_NOTES_BLOCK: 2243694,
|
||||
@ -417,10 +460,10 @@ export const defaultConfig: networkConfig = {
|
||||
[NetId.ARBITRUM]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 4,
|
||||
fast: 3,
|
||||
standard: 2.52,
|
||||
low: 2.29,
|
||||
instant: 0.02,
|
||||
fast: 0.02,
|
||||
standard: 0.02,
|
||||
low: 0.02,
|
||||
},
|
||||
nativeCurrency: 'eth',
|
||||
currencyName: 'ETH',
|
||||
@ -441,6 +484,10 @@ export const defaultConfig: networkConfig = {
|
||||
name: 'Arbitrum',
|
||||
url: 'https://arb1.arbitrum.io/rpc',
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://tornadocash-rpc.com/arbitrum',
|
||||
},
|
||||
stackup: {
|
||||
name: 'Stackup',
|
||||
url: 'https://public.stackup.sh/api/v1/node/arbitrum-one',
|
||||
@ -453,6 +500,150 @@ export const defaultConfig: networkConfig = {
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
'0.001': '0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76',
|
||||
'0.01': '0xA287c40411685438750a247Ca67488DEBe56EE32',
|
||||
'0.1': '0x84443CFd09A48AF6eF360C6976C5392aC5023a1F',
|
||||
'1': '0xd47438C816c9E7f2E2888E060936a499Af9582b3',
|
||||
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD',
|
||||
},
|
||||
optionalInstances: ['0.001', '0.01'],
|
||||
symbol: 'ETH',
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
relayerEnsSubdomain: 'arbitrum-tornado',
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 3430605,
|
||||
ENCRYPTED_NOTES_BLOCK: 3430605,
|
||||
},
|
||||
},
|
||||
[NetId.BASE]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 0.1,
|
||||
fast: 0.06,
|
||||
standard: 0.05,
|
||||
low: 0.02,
|
||||
},
|
||||
nativeCurrency: 'eth',
|
||||
currencyName: 'ETH',
|
||||
explorerUrl: 'https://basescan.org',
|
||||
merkleTreeHeight: 20,
|
||||
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||
networkName: 'Base',
|
||||
deployedBlock: 23149794,
|
||||
stablecoin: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
|
||||
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
||||
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
|
||||
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
offchainOracleContract: '0x00000000000D6FFc74A8feb35aF5827bf57f6786',
|
||||
ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
|
||||
tornadoSubgraph: 'tornadocash/base-tornado-subgraph',
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
Base: {
|
||||
name: 'Base',
|
||||
url: 'https://mainnet.base.org',
|
||||
},
|
||||
stackup: {
|
||||
name: 'Stackup',
|
||||
url: 'https://public.stackup.sh/api/v1/node/base-mainnet',
|
||||
},
|
||||
oneRpc: {
|
||||
name: '1RPC',
|
||||
url: 'https://1rpc.io/base',
|
||||
},
|
||||
},
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
'0.001': '0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76',
|
||||
'0.01': '0xA287c40411685438750a247Ca67488DEBe56EE32',
|
||||
'0.1': '0x84443CFd09A48AF6eF360C6976C5392aC5023a1F',
|
||||
'1': '0xd47438C816c9E7f2E2888E060936a499Af9582b3',
|
||||
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||
'100': '0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD',
|
||||
},
|
||||
symbol: 'ETH',
|
||||
decimals: 18,
|
||||
},
|
||||
dai: {
|
||||
instanceAddress: {
|
||||
'10': '0x70CC374aE7D1549a4666b7172B78dDCF672B74f7',
|
||||
'100': '0xD063894588177B8362Dda6C0A7EF09BF6fDF851c',
|
||||
'1000': '0xa7513fdfF61fc83a9C5c08CE31266e6dd400C54E',
|
||||
'10000': '0x8f05eDE57098D843F30bE74AC25c292F87b7f775',
|
||||
'100000': '0xeB7fc86c32e9a5E9DD2a0a78C091b8b625cbee24',
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: '0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb',
|
||||
tokenGasLimit: 70_000,
|
||||
symbol: 'DAI',
|
||||
decimals: 18,
|
||||
gasLimit: 700_000,
|
||||
},
|
||||
tbtc: {
|
||||
instanceAddress: {
|
||||
'0.0001': '0x5465800D7Be34dAe2c1572d2227De94dE93B4432',
|
||||
'0.001': '0xf2d3404c03C8cC0b120bd6E8edD6F69226F03c6d',
|
||||
'0.01': '0x4261d5209A285410DEa8173B6FE1A0e7BCf20f7c',
|
||||
'0.1': '0x9FB147F49bFE17D19789547187EAE2406590b217',
|
||||
'1': '0x2A8515F39716B0C160a3eB32D24E4cbeB76932d2',
|
||||
},
|
||||
instanceApproval: true,
|
||||
tokenAddress: '0x236aa50979D5f3De3Bd1Eeb40E81137F22ab794b',
|
||||
tokenGasLimit: 70_000,
|
||||
symbol: 'tBTC',
|
||||
decimals: 18,
|
||||
gasLimit: 700_000,
|
||||
},
|
||||
},
|
||||
relayerEnsSubdomain: 'base-tornado',
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 23149794,
|
||||
ENCRYPTED_NOTES_BLOCK: 23149794,
|
||||
},
|
||||
},
|
||||
[NetId.BLAST]: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
gasPrices: {
|
||||
instant: 0.001,
|
||||
fast: 0.001,
|
||||
standard: 0.001,
|
||||
low: 0.001,
|
||||
},
|
||||
nativeCurrency: 'eth',
|
||||
currencyName: 'ETH',
|
||||
explorerUrl: 'https://blastscan.io',
|
||||
merkleTreeHeight: 20,
|
||||
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||
networkName: 'Blast',
|
||||
deployedBlock: 12144065,
|
||||
stablecoin: '0x4300000000000000000000000000000000000003',
|
||||
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
|
||||
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
|
||||
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
|
||||
tornadoSubgraph: 'tornadocash/blast-tornado-subgraph',
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
Blast: {
|
||||
name: 'Blast',
|
||||
url: 'https://rpc.blast.io',
|
||||
},
|
||||
blastApi: {
|
||||
name: 'BlastApi',
|
||||
url: 'https://blastl2-mainnet.public.blastapi.io',
|
||||
},
|
||||
},
|
||||
tokens: {
|
||||
eth: {
|
||||
instanceAddress: {
|
||||
'0.001': '0x82859DC3697062c16422E9b5e8Ba1B6a6EC72c76',
|
||||
'0.01': '0xA287c40411685438750a247Ca67488DEBe56EE32',
|
||||
'0.1': '0x84443CFd09A48AF6eF360C6976C5392aC5023a1F',
|
||||
'1': '0xd47438C816c9E7f2E2888E060936a499Af9582b3',
|
||||
'10': '0x330bdFADE01eE9bF63C209Ee33102DD334618e0a',
|
||||
@ -462,11 +653,11 @@ export const defaultConfig: networkConfig = {
|
||||
decimals: 18,
|
||||
},
|
||||
},
|
||||
relayerEnsSubdomain: 'arbitrum-tornado',
|
||||
pollInterval: 15,
|
||||
relayerEnsSubdomain: 'blast-tornado',
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 3430605,
|
||||
ENCRYPTED_NOTES_BLOCK: 3430605,
|
||||
NOTE_ACCOUNT_BLOCK: 12144065,
|
||||
ENCRYPTED_NOTES_BLOCK: 12144065,
|
||||
},
|
||||
},
|
||||
[NetId.GNOSIS]: {
|
||||
@ -514,7 +705,7 @@ export const defaultConfig: networkConfig = {
|
||||
},
|
||||
},
|
||||
relayerEnsSubdomain: 'gnosis-tornado',
|
||||
pollInterval: 15,
|
||||
pollInterval: 5,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 17754564,
|
||||
ENCRYPTED_NOTES_BLOCK: 17754564,
|
||||
@ -564,7 +755,7 @@ export const defaultConfig: networkConfig = {
|
||||
},
|
||||
},
|
||||
relayerEnsSubdomain: 'avalanche-tornado',
|
||||
pollInterval: 10,
|
||||
pollInterval: 2,
|
||||
constants: {
|
||||
NOTE_ACCOUNT_BLOCK: 4429813,
|
||||
ENCRYPTED_NOTES_BLOCK: 4429813,
|
||||
@ -599,6 +790,14 @@ export const defaultConfig: networkConfig = {
|
||||
tornadoSubgraph: 'tornadocash/sepolia-tornado-subgraph',
|
||||
subgraphs: {},
|
||||
rpcUrls: {
|
||||
oneRpc: {
|
||||
name: '1RPC',
|
||||
url: 'https://1rpc.io/sepolia',
|
||||
},
|
||||
tornadoRpc: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://tornadocash-rpc.com/sepolia',
|
||||
},
|
||||
sepolia: {
|
||||
name: 'Sepolia RPC',
|
||||
url: 'https://rpc.sepolia.org',
|
||||
@ -607,10 +806,6 @@ export const defaultConfig: networkConfig = {
|
||||
name: 'Stackup',
|
||||
url: 'https://public.stackup.sh/api/v1/node/ethereum-sepolia',
|
||||
},
|
||||
oneRpc: {
|
||||
name: '1RPC',
|
||||
url: 'https://1rpc.io/sepolia',
|
||||
},
|
||||
ethpandaops: {
|
||||
name: 'ethpandaops',
|
||||
url: 'https://rpc.sepolia.ethpandaops.io',
|
||||
|
@ -1,15 +1,5 @@
|
||||
import { ERC20Permit, ERC20Mock, TORN, PermitTornado } from '@tornado/contracts';
|
||||
import {
|
||||
BaseContract,
|
||||
MaxUint256,
|
||||
Provider,
|
||||
Signature,
|
||||
Signer,
|
||||
solidityPackedKeccak256,
|
||||
TypedDataEncoder,
|
||||
TypedDataField,
|
||||
} from 'ethers';
|
||||
import { rBigInt } from './utils';
|
||||
import { ERC20Permit, ERC20Mock, TORN } from '@tornado/contracts';
|
||||
import { MaxUint256, Provider, Signature, Signer, TypedDataField } from 'ethers';
|
||||
|
||||
export interface PermitValue {
|
||||
spender: string;
|
||||
@ -87,6 +77,7 @@ export async function getPermitSignature({
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
export async function getPermitCommitmentsSignature({
|
||||
PermitTornado,
|
||||
Token,
|
||||
@ -240,3 +231,4 @@ export async function getPermit2CommitmentsSignature({
|
||||
},
|
||||
});
|
||||
}
|
||||
**/
|
||||
|
@ -316,7 +316,7 @@ export const populateTransaction = async (
|
||||
signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner,
|
||||
tx: TransactionRequest,
|
||||
) => {
|
||||
const provider = signer.provider as Provider;
|
||||
const provider = ((signer as TornadoRpcSigner).readonlyProvider || signer.provider) as Provider;
|
||||
|
||||
if (!tx.from) {
|
||||
tx.from = signer.address;
|
||||
@ -381,6 +381,7 @@ export interface TornadoWalletOptions {
|
||||
gasLimitBump?: number;
|
||||
gasFailover?: boolean;
|
||||
bumpNonce?: boolean;
|
||||
readonlyProvider?: Provider;
|
||||
}
|
||||
|
||||
export class TornadoWallet extends Wallet {
|
||||
@ -453,10 +454,11 @@ export class TornadoRpcSigner extends JsonRpcSigner {
|
||||
gasLimitBump: number;
|
||||
gasFailover: boolean;
|
||||
bumpNonce: boolean;
|
||||
readonlyProvider?: Provider;
|
||||
constructor(
|
||||
provider: JsonRpcApiProvider,
|
||||
address: string,
|
||||
{ gasPriceBump, gasLimitBump, gasFailover, bumpNonce }: TornadoWalletOptions = {},
|
||||
{ gasPriceBump, gasLimitBump, gasFailover, bumpNonce, readonlyProvider }: TornadoWalletOptions = {},
|
||||
) {
|
||||
super(provider, address);
|
||||
// 10% bump from the recommended fee
|
||||
@ -466,6 +468,7 @@ export class TornadoRpcSigner extends JsonRpcSigner {
|
||||
this.gasFailover = gasFailover ?? false;
|
||||
// turn off bumpNonce feature for browser wallet
|
||||
this.bumpNonce = bumpNonce ?? false;
|
||||
this.readonlyProvider = readonlyProvider;
|
||||
}
|
||||
|
||||
async sendUncheckedTransaction(tx: TransactionRequest) {
|
||||
|
@ -1,8 +1,8 @@
|
||||
// @ts-expect-error no-websnark-types
|
||||
import * as websnarkUtils from '@tornado/websnark/src/utils';
|
||||
import * as websnarkUtils from 'websnark/src/utils';
|
||||
// @ts-expect-error no-websnark-types
|
||||
import websnarkGroth from '@tornado/websnark/src/groth16';
|
||||
import type { Element } from '@tornado/fixed-merkle-tree';
|
||||
import websnarkGroth from 'websnark/src/groth16';
|
||||
import type { Element } from 'fixed-merkle-tree';
|
||||
import { toFixedHex } from './utils';
|
||||
|
||||
export interface snarkInputs {
|
||||
|
Loading…
x
Reference in New Issue
Block a user