Compare commits

...

2 Commits

Author SHA1 Message Date
f3a8438187
built files 2024-10-16 14:19:49 +00:00
666b0eba66
es2022, use interfaces, minor func addition 2024-10-16 14:17:22 +00:00
46 changed files with 10218 additions and 10295 deletions

4
dist/batch.d.ts vendored

@ -62,11 +62,11 @@ export type BatchEventOnProgress = ({ percentage, type, fromBlock, toBlock, coun
toBlock?: number;
count?: number;
}) => void;
export type EventInput = {
export interface EventInput {
fromBlock: number;
toBlock: number;
type: ContractEventName;
};
}
/**
* Fetch events from web3 provider on bulk
*/

32
dist/deposits.d.ts vendored

@ -1,36 +1,28 @@
import type { NetIdType } from './networkConfig';
export type DepositType = {
export interface DepositType {
currency: string;
amount: string;
netId: NetIdType;
};
export type createDepositParams = {
}
export interface createDepositParams {
nullifier: bigint;
secret: bigint;
};
export type createDepositObject = {
}
export interface createDepositObject {
preimage: Uint8Array;
noteHex: string;
commitment: bigint;
commitmentHex: string;
nullifierHash: bigint;
nullifierHex: string;
};
export type createNoteParams = DepositType & {
}
export interface createNoteParams extends DepositType {
nullifier?: bigint;
secret?: bigint;
};
export type parsedNoteExec = DepositType & {
}
export interface parsedNoteExec extends DepositType {
note: string;
};
export type depositTx = {
from: string;
transactionHash: string;
};
export type withdrawalTx = {
to: string;
transactionHash: string;
};
}
export declare function createDeposit({ nullifier, secret }: createDepositParams): Promise<createDepositObject>;
export interface DepositConstructor {
currency: string;
@ -60,9 +52,9 @@ export declare class Deposit {
static createNote({ currency, amount, netId, nullifier, secret }: createNoteParams): Promise<Deposit>;
static parseNote(noteString: string): Promise<Deposit>;
}
export type parsedInvoiceExec = DepositType & {
export interface parsedInvoiceExec extends DepositType {
commitment: string;
};
}
export declare class Invoice {
currency: string;
amount: string;

75
dist/events/base.d.ts vendored

@ -8,29 +8,29 @@ import type { TovarishClient } from '../tovarishClient';
import type { BaseEvents, CachedEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, RegistersEvents, EchoEvents } from './types';
export declare const DEPOSIT = "deposit";
export declare const WITHDRAWAL = "withdrawal";
export type BaseEventsServiceConstructor = {
export interface BaseEventsServiceConstructor {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
contract: BaseContract;
type?: string;
type: string;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export type BatchGraphOnProgress = ({ type, fromBlock, toBlock, count, }: {
type?: ContractEventName;
fromBlock?: number;
toBlock?: number;
count?: number;
}) => void;
export type BaseGraphParams = {
export interface BaseGraphParams {
graphApi: string;
subgraphName: string;
fetchDataOptions?: fetchDataOptions;
onProgress?: BatchGraphOnProgress;
};
}
export declare class BaseEventsService<EventType extends MinimalEvents> {
netId: NetIdType;
provider: Provider;
@ -89,29 +89,20 @@ export declare class BaseEventsService<EventType extends MinimalEvents> {
lastBlock: number;
}>;
}
export type BaseTornadoServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseTornadoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract'> {
Tornado: Tornado;
type: string;
amount: string;
currency: string;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
export type DepositsGraphParams = BaseGraphParams & {
}
export interface DepositsGraphParams extends BaseGraphParams {
amount: string;
currency: string;
};
}
export declare class BaseTornadoService extends BaseEventsService<DepositsEvents | WithdrawalsEvents> {
amount: string;
currency: string;
batchTransactionService: BatchTransactionService;
batchBlockService: BatchBlockService;
tovarishClient?: TovarishClient;
constructor({ netId, provider, graphApi, subgraphName, Tornado, type, amount, currency, deployedBlock, fetchDataOptions, tovarishClient, }: BaseTornadoServiceConstructor);
getInstanceName(): string;
getGraphMethod(): string;
@ -124,59 +115,35 @@ export declare class BaseTornadoService extends BaseEventsService<DepositsEvents
fromBlock: number;
}): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>>;
}
export type BaseEchoServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseEchoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
Echoer: Echoer;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export declare class BaseEchoService extends BaseEventsService<EchoEvents> {
constructor({ netId, provider, graphApi, subgraphName, Echoer, deployedBlock, fetchDataOptions, tovarishClient, }: BaseEchoServiceConstructor);
getInstanceName(): string;
getType(): string;
getGraphMethod(): string;
formatEvents(events: EventLog[]): Promise<EchoEvents[]>;
getEventsFromGraph({ fromBlock }: {
fromBlock: number;
}): Promise<BaseEvents<EchoEvents>>;
}
export type BaseEncryptedNotesServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseEncryptedNotesServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
Router: TornadoRouter | TornadoProxyLight;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export declare class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesEvents> {
constructor({ netId, provider, graphApi, subgraphName, Router, deployedBlock, fetchDataOptions, tovarishClient, }: BaseEncryptedNotesServiceConstructor);
getInstanceName(): string;
getType(): string;
getTovarishType(): string;
getGraphMethod(): string;
formatEvents(events: EventLog[]): Promise<EncryptedNotesEvents[]>;
}
export type BaseGovernanceServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseGovernanceServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
Governance: Governance;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export declare class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents> {
batchTransactionService: BatchTransactionService;
constructor({ netId, provider, graphApi, subgraphName, Governance, deployedBlock, fetchDataOptions, tovarishClient, }: BaseGovernanceServiceConstructor);
getInstanceName(): string;
getType(): string;
getTovarishType(): string;
getGraphMethod(): string;
formatEvents(events: EventLog[]): Promise<AllGovernanceEvents[]>;
@ -204,25 +171,17 @@ export interface CachedRelayers {
relayers: CachedRelayerInfo[];
fromCache?: boolean;
}
export type BaseRegistryServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseRegistryServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
RelayerRegistry: RelayerRegistry;
Aggregator: Aggregator;
relayerEnsSubdomains: SubdomainMap;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export declare class BaseRegistryService extends BaseEventsService<RegistersEvents> {
Aggregator: Aggregator;
relayerEnsSubdomains: SubdomainMap;
updateInterval: number;
constructor({ netId, provider, graphApi, subgraphName, RelayerRegistry, Aggregator, relayerEnsSubdomains, deployedBlock, fetchDataOptions, tovarishClient, }: BaseRegistryServiceConstructor);
getInstanceName(): string;
getType(): string;
getTovarishType(): string;
getGraphMethod(): string;
formatEvents(events: EventLog[]): Promise<{

@ -15,51 +15,51 @@ export interface MinimalEvents {
logIndex: number;
transactionHash: string;
}
export type GovernanceEvents = MinimalEvents & {
export interface GovernanceEvents extends MinimalEvents {
event: string;
};
export type GovernanceProposalCreatedEvents = GovernanceEvents & {
}
export interface GovernanceProposalCreatedEvents extends GovernanceEvents {
id: number;
proposer: string;
target: string;
startTime: number;
endTime: number;
description: string;
};
export type GovernanceVotedEvents = GovernanceEvents & {
}
export interface GovernanceVotedEvents extends GovernanceEvents {
proposalId: number;
voter: string;
support: boolean;
votes: string;
from: string;
input: string;
};
export type GovernanceDelegatedEvents = GovernanceEvents & {
}
export interface GovernanceDelegatedEvents extends GovernanceEvents {
account: string;
delegateTo: string;
};
export type GovernanceUndelegatedEvents = GovernanceEvents & {
}
export interface GovernanceUndelegatedEvents extends GovernanceEvents {
account: string;
delegateFrom: string;
};
}
export type AllGovernanceEvents = GovernanceProposalCreatedEvents | GovernanceVotedEvents | GovernanceDelegatedEvents | GovernanceUndelegatedEvents;
export type RegistersEvents = MinimalEvents & RelayerParams;
export type DepositsEvents = MinimalEvents & {
export interface DepositsEvents extends MinimalEvents {
commitment: string;
leafIndex: number;
timestamp: number;
from: string;
};
export type WithdrawalsEvents = MinimalEvents & {
}
export interface WithdrawalsEvents extends MinimalEvents {
nullifierHash: string;
to: string;
fee: string;
timestamp: number;
};
export type EchoEvents = MinimalEvents & {
}
export interface EchoEvents extends MinimalEvents {
address: string;
encryptedAccount: string;
};
export type EncryptedNotesEvents = MinimalEvents & {
}
export interface EncryptedNotesEvents extends MinimalEvents {
encryptedNote: string;
};
}

13
dist/gaszip.d.ts vendored Normal file

@ -0,0 +1,13 @@
import { NetIdType } from './networkConfig';
export declare const gasZipInbounds: {
[key in NetIdType]: string;
};
export declare const gasZipID: {
[key in NetIdType]: number;
};
export declare function gasZipInput(to: string, shorts: number[]): string | null;
export declare function gasZipMinMax(ethUsd: number): {
min: number;
max: number;
ethUsd: number;
};

@ -1,7 +1,7 @@
import { fetchDataOptions } from '../providers';
import type { BaseGraphEvents, RegistersEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, BatchGraphOnProgress, EchoEvents, AllGovernanceEvents } from '../events';
export * from './queries';
export type queryGraphParams = {
export interface queryGraphParams {
graphApi: string;
subgraphName: string;
query: string;
@ -9,7 +9,7 @@ export type queryGraphParams = {
[key: string]: string | number;
};
fetchDataOptions?: fetchDataOptions;
};
}
export declare function queryGraph<T>({ graphApi, subgraphName, query, variables, fetchDataOptions, }: queryGraphParams): Promise<T>;
export interface GraphStatistic {
deposits: {

1
dist/index.d.ts vendored

@ -6,6 +6,7 @@ export * from './batch';
export * from './deposits';
export * from './encryptedNotes';
export * from './fees';
export * from './gaszip';
export * from './idb';
export * from './merkleTree';
export * from './mimc';

1953
dist/index.js vendored

File diff suppressed because it is too large Load Diff

1952
dist/index.mjs vendored

File diff suppressed because it is too large Load Diff

@ -3,13 +3,13 @@ import type { Tornado } from '@tornado/contracts';
import type { DepositType } from './deposits';
import type { DepositsEvents } from './events';
import type { NetIdType } from './networkConfig';
export type MerkleTreeConstructor = DepositType & {
export interface MerkleTreeConstructor extends DepositType {
Tornado: Tornado;
commitmentHex?: string;
merkleTreeHeight?: number;
emptyElement?: string;
merkleWorkerPath?: string;
};
}
export declare class MerkleTreeService {
currency: string;
amount: string;

@ -1805,47 +1805,23 @@ class MimcSponge {
}
}
var __async$1 = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
class Mimc {
sponge;
hash;
mimcPromise;
constructor() {
this.mimcPromise = this.initMimc();
}
initMimc() {
return __async$1(this, null, function* () {
this.sponge = yield buildMimcSponge();
this.hash = (left, right) => {
var _a, _b;
return (_b = this.sponge) == null ? void 0 : _b.F.toString((_a = this.sponge) == null ? void 0 : _a.multiHash([BigInt(left), BigInt(right)]));
};
});
async initMimc() {
this.sponge = await buildMimcSponge();
this.hash = (left, right) => this.sponge?.F.toString(this.sponge?.multiHash([BigInt(left), BigInt(right)]));
}
getHash() {
return __async$1(this, null, function* () {
yield this.mimcPromise;
async getHash() {
await this.mimcPromise;
return {
sponge: this.sponge,
hash: this.hash
};
});
}
}
const mimc = new Mimc();
@ -1855,29 +1831,8 @@ BigInt.prototype.toJSON = function() {
};
const isNode = !process.browser && typeof globalThis.window === "undefined";
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
function nodePostWork() {
return __async(this, null, function* () {
const { hash: hashFunction } = yield mimc.getHash();
async function nodePostWork() {
const { hash: hashFunction } = await mimc.getHash();
const { merkleTreeHeight, edge, elements, zeroElement } = workerThreads.workerData;
if (edge) {
const merkleTree2 = new libExports.PartialMerkleTree(merkleTreeHeight, edge, elements, {
@ -1892,19 +1847,18 @@ function nodePostWork() {
hashFunction
});
workerThreads.parentPort.postMessage(merkleTree.toString());
});
}
if (isNode && workerThreads) {
nodePostWork();
} else if (!isNode && typeof addEventListener === "function" && typeof postMessage === "function") {
addEventListener("message", (e) => __async(undefined, null, function* () {
addEventListener("message", async (e) => {
let data;
if (e.data) {
data = e.data;
} else {
data = e;
}
const { hash: hashFunction } = yield mimc.getHash();
const { hash: hashFunction } = await mimc.getHash();
const { merkleTreeHeight, edge, elements, zeroElement } = data;
if (edge) {
const merkleTree2 = new libExports.PartialMerkleTree(merkleTreeHeight, edge, elements, {
@ -1919,7 +1873,7 @@ if (isNode && workerThreads) {
hashFunction
});
postMessage(merkleTree.toString());
}));
});
} else {
throw new Error("This browser / environment does not support workers!");
}

@ -101976,48 +101976,24 @@ const poseidonContract=(/* unused pure expression or super */ null && (_poseidon
;// ./src/mimc.ts
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
class Mimc {
sponge;
hash;
mimcPromise;
constructor() {
this.mimcPromise = this.initMimc();
}
initMimc() {
return __async(this, null, function* () {
this.sponge = yield mimcsponge_buildMimcSponge();
this.hash = (left, right) => {
var _a, _b;
return (_b = this.sponge) == null ? void 0 : _b.F.toString((_a = this.sponge) == null ? void 0 : _a.multiHash([BigInt(left), BigInt(right)]));
};
});
async initMimc() {
this.sponge = await mimcsponge_buildMimcSponge();
this.hash = (left, right) => this.sponge?.F.toString(this.sponge?.multiHash([BigInt(left), BigInt(right)]));
}
getHash() {
return __async(this, null, function* () {
yield this.mimcPromise;
async getHash() {
await this.mimcPromise;
return {
sponge: this.sponge,
hash: this.hash
};
});
}
}
const mimc = new Mimc();
@ -102028,26 +102004,6 @@ var crypto_browserify = __webpack_require__(1565);
var bn = __webpack_require__(9404);
;// ./src/utils.ts
var utils_async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
BigInt.prototype.toJSON = function() {
@ -102066,7 +102022,7 @@ function validateUrl(url, protocols) {
return protocols.map((p) => p.toLowerCase()).includes(parsedUrl.protocol);
}
return true;
} catch (e) {
} catch {
return false;
}
}
@ -102138,41 +102094,18 @@ function substring(str, length = 10) {
}
return `${str.substring(0, length)}...${str.substring(str.length - length)}`;
}
function digest(bytes, algo = "SHA-384") {
return utils_async(this, null, function* () {
return new Uint8Array(yield utils_crypto.subtle.digest(algo, bytes));
});
async function digest(bytes, algo = "SHA-384") {
return new Uint8Array(await utils_crypto.subtle.digest(algo, bytes));
}
;// ./src/merkleTreeWorker.ts
var merkleTreeWorker_async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
function nodePostWork() {
return merkleTreeWorker_async(this, null, function* () {
const { hash: hashFunction } = yield mimc.getHash();
async function nodePostWork() {
const { hash: hashFunction } = await mimc.getHash();
const { merkleTreeHeight, edge, elements, zeroElement } = (worker_threads_ignored_default()).workerData;
if (edge) {
const merkleTree2 = new lib.PartialMerkleTree(merkleTreeHeight, edge, elements, {
@ -102187,19 +102120,18 @@ function nodePostWork() {
hashFunction
});
worker_threads_ignored_default().parentPort.postMessage(merkleTree.toString());
});
}
if (isNode && (worker_threads_ignored_default())) {
nodePostWork();
} else if (!isNode && typeof addEventListener === "function" && typeof postMessage === "function") {
addEventListener("message", (e) => merkleTreeWorker_async(undefined, null, function* () {
addEventListener("message", async (e) => {
let data;
if (e.data) {
data = e.data;
} else {
data = e;
}
const { hash: hashFunction } = yield mimc.getHash();
const { hash: hashFunction } = await mimc.getHash();
const { merkleTreeHeight, edge, elements, zeroElement } = data;
if (edge) {
const merkleTree2 = new lib.PartialMerkleTree(merkleTreeHeight, edge, elements, {
@ -102214,7 +102146,7 @@ if (isNode && (worker_threads_ignored_default())) {
hashFunction
});
postMessage(merkleTree.toString());
}));
});
} else {
throw new Error("This browser / environment does not support workers!");
}

File diff suppressed because one or more lines are too long

@ -16,19 +16,19 @@ export interface RpcUrl {
name: string;
url: string;
}
export type RpcUrls = {
[key in string]: RpcUrl;
};
export interface RpcUrls {
[key: string]: RpcUrl;
}
export interface SubgraphUrl {
name: string;
url: string;
}
export type SubgraphUrls = {
[key in string]: SubgraphUrl;
};
export type TornadoInstance = {
export interface SubgraphUrls {
[key: string]: SubgraphUrl;
}
export interface TornadoInstance {
instanceAddress: {
[key in string]: string;
[key: string]: string;
};
optionalInstances?: string[];
tokenAddress?: string;
@ -36,11 +36,11 @@ export type TornadoInstance = {
symbol: string;
decimals: number;
gasLimit?: number;
};
export type TokenInstances = {
[key in string]: TornadoInstance;
};
export type Config = {
}
export interface TokenInstances {
[key: string]: TornadoInstance;
}
export interface Config {
rpcCallRetryAttempt?: number;
gasPrices: {
instant: number;
@ -57,6 +57,7 @@ export type Config = {
networkName: string;
deployedBlock: number;
rpcUrls: RpcUrls;
stablecoin: string;
multicallContract: string;
routerContract: string;
echoContract: string;
@ -84,13 +85,13 @@ export type Config = {
REGISTRY_BLOCK?: number;
MINING_BLOCK_TIME?: number;
};
};
export type networkConfig = {
[key in NetIdType]: Config;
};
export type SubdomainMap = {
[key in NetIdType]: string;
};
}
export interface networkConfig {
[key: NetIdType]: Config;
}
export interface SubdomainMap {
[key: NetIdType]: string;
}
export declare const defaultConfig: networkConfig;
export declare const enabledChains: NetIdType[];
/**

10
dist/prices.d.ts vendored

@ -1,12 +1,20 @@
import { type Provider } from 'ethers';
import type { OffchainOracle, Multicall } from './typechain';
import { OffchainOracle, Multicall } from './typechain';
import { Call3 } from './multicall';
export declare class TokenPriceOracle {
oracle?: OffchainOracle;
multicall: Multicall;
provider: Provider;
constructor(provider: Provider, multicall: Multicall, oracle?: OffchainOracle);
buildCalls(tokens: {
tokenAddress: string;
decimals: number;
}[]): Call3[];
buildStable(stablecoinAddress: string): Call3[];
fetchPrice(tokenAddress: string, decimals: number): Promise<bigint>;
fetchPrices(tokens: {
tokenAddress: string;
decimals: number;
}[]): Promise<bigint[]>;
fetchEthUSD(stablecoinAddress: string): Promise<number>;
}

8
dist/providers.d.ts vendored

@ -38,12 +38,12 @@ export type getProviderOptions = fetchDataOptions & {
export declare function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider>;
export declare function getProviderWithNetId(netId: NetIdType, rpcUrl: string, config: Config, fetchOptions?: getProviderOptions): JsonRpcProvider;
export declare const populateTransaction: (signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner, tx: TransactionRequest) => Promise<TransactionRequest>;
export type TornadoWalletOptions = {
export interface TornadoWalletOptions {
gasPriceBump?: number;
gasLimitBump?: number;
gasFailover?: boolean;
bumpNonce?: boolean;
};
}
export declare class TornadoWallet extends Wallet {
nonce?: number;
gasPriceBump: number;
@ -74,13 +74,13 @@ export declare class TornadoRpcSigner extends JsonRpcSigner {
}
export type connectWalletFunc = (...args: any[]) => Promise<void>;
export type handleWalletFunc = (...args: any[]) => void;
export type TornadoBrowserProviderOptions = TornadoWalletOptions & {
export interface TornadoBrowserProviderOptions extends TornadoWalletOptions {
netId?: NetIdType;
connectWallet?: connectWalletFunc;
handleNetworkChanges?: handleWalletFunc;
handleAccountChanges?: handleWalletFunc;
handleAccountDisconnect?: handleWalletFunc;
};
}
export declare class TornadoBrowserProvider extends BrowserProvider {
options?: TornadoBrowserProviderOptions;
constructor(ethereum: Eip1193Provider, network?: Networkish, options?: TornadoBrowserProviderOptions);

@ -12,7 +12,7 @@ export interface RelayerParams {
/**
* Info from relayer status
*/
export type RelayerInfo = RelayerParams & {
export interface RelayerInfo extends RelayerParams {
netId: NetIdType;
url: string;
hostname: string;
@ -25,13 +25,13 @@ export type RelayerInfo = RelayerParams & {
};
currentQueue: number;
tornadoServiceFee: number;
};
export type RelayerError = {
}
export interface RelayerError {
hostname: string;
relayerAddress?: string;
errorMessage?: string;
hasError: boolean;
};
}
export interface RelayerStatus {
url: string;
rewardAccount: string;
@ -63,9 +63,9 @@ export interface RelayerStatus {
};
currentQueue: number;
}
export type TornadoWithdrawParams = snarkProofs & {
export interface TornadoWithdrawParams extends snarkProofs {
contract: string;
};
}
export interface RelayerTornadoWithdraw {
id?: string;
error?: string;
@ -111,13 +111,13 @@ export function isRelayerUpdated(relayerVersion: string, netId: NetIdType) {
**/
export declare function calculateScore({ stakeBalance, tornadoServiceFee }: RelayerInfo): bigint;
export declare function getWeightRandom(weightsScores: bigint[], random: bigint): number;
export type RelayerInstanceList = {
[key in string]: {
export interface RelayerInstanceList {
[key: string]: {
instanceAddress: {
[key in string]: string;
};
[key: string]: string;
};
};
}
export declare function getSupportedInstances(instanceList: RelayerInstanceList): string[];
export declare function pickWeightedRandomRelayer(relayers: RelayerInfo[]): RelayerInfo;
export interface RelayerClientConstructor {
@ -143,5 +143,5 @@ export declare class RelayerClient {
invalidRelayers: RelayerError[];
}>;
pickWeightedRandomRelayer(relayers: RelayerInfo[]): RelayerInfo;
tornadoWithdraw({ contract, proof, args }: TornadoWithdrawParams, callback?: (jobResp: RelayerTornadoJobs) => void): Promise<void>;
tornadoWithdraw({ contract, proof, args }: TornadoWithdrawParams, callback?: (jobResp: RelayerTornadoWithdraw | RelayerTornadoJobs) => void): Promise<void>;
}

@ -1,4 +1,4 @@
export type jobsSchema = {
export interface jobsSchema {
type: string;
properties: {
error: {
@ -36,5 +36,6 @@ export type jobsSchema = {
};
};
required: string[];
};
}
export declare const jobsSchema: jobsSchema;
export declare const jobRequestSchema: jobsSchema;

@ -1,6 +1,6 @@
import { Config, NetIdType } from '../networkConfig';
import { addressSchemaType, bnSchemaType } from '.';
export type statusInstanceType = {
export interface statusInstanceType {
type: string;
properties: {
instanceAddress: {
@ -19,22 +19,22 @@ export type statusInstanceType = {
};
};
required: string[];
};
export type statusInstancesType = {
}
export interface statusInstancesType {
type: string;
properties: {
[key in string]: statusInstanceType;
};
required: string[];
};
export type statusEthPricesType = {
}
export interface statusEthPricesType {
type: string;
properties: {
[key in string]: typeof bnSchemaType;
};
required?: string[];
};
export type statusSchema = {
}
export interface statusSchema {
type: string;
properties: {
rewardAccount: typeof addressSchemaType;
@ -102,5 +102,5 @@ export type statusSchema = {
};
};
required: string[];
};
}
export declare function getStatusSchema(netId: NetIdType, config: Config, tovarish: boolean): statusSchema;

2169
dist/tornado.umd.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -62,10 +62,22 @@ export declare class TovarishClient extends RelayerClient {
url?: string;
relayerAddress?: string;
}): Promise<TovarishStatus>;
/**
* Ask status for all enabled chains for tovarish relayer
*/
askAllStatus({ hostname, url, relayerAddress, }: {
hostname?: string;
url?: string;
relayerAddress?: string;
}): Promise<TovarishStatus[]>;
filterRelayer(relayer: CachedRelayerInfo): Promise<TovarishInfo | RelayerError | undefined>;
getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
validRelayers: TovarishInfo[];
invalidRelayers: RelayerError[];
}>;
getTovarishRelayers(relayers: CachedRelayerInfo[]): Promise<{
validRelayers: TovarishInfo[];
invalidRelayers: RelayerError[];
}>;
getEvents<T extends MinimalEvents>({ type, currency, amount, fromBlock, recent, }: TovarishEventsQuery): Promise<BaseTovarishEvents<T>>;
}

8
dist/websnark.d.ts vendored

@ -1,5 +1,5 @@
import type { Element } from '@tornado/fixed-merkle-tree';
export type snarkInputs = {
export interface snarkInputs {
root: Element;
nullifierHex: string;
recipient: string;
@ -10,7 +10,7 @@ export type snarkInputs = {
secret: bigint;
pathElements: Element[];
pathIndices: Element[];
};
}
export type snarkArgs = [
_root: string,
_nullifierHash: string,
@ -19,9 +19,9 @@ export type snarkArgs = [
_fee: string,
_refund: string
];
export type snarkProofs = {
export interface snarkProofs {
proof: string;
args: snarkArgs;
};
}
export declare function initGroth16(): Promise<void>;
export declare function calculateSnarkProof(input: snarkInputs, circuit: object, provingKey: ArrayBuffer): Promise<snarkProofs>;

@ -32,7 +32,7 @@
],
"dependencies": {
"@metamask/eth-sig-util": "^7.0.3",
"@tornado/contracts": "^1.0.1",
"@tornado/contracts": "git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#ece511f424dc811c3aec149a4bf0e3731c0598a4",
"@tornado/fixed-merkle-tree": "^0.7.3",
"@tornado/snarkjs": "^0.1.20",
"@tornado/websnark": "^0.0.4",
@ -40,13 +40,13 @@
"bn.js": "^5.2.1",
"circomlibjs": "0.1.7",
"cross-fetch": "^4.0.0",
"ethers": "^6.13.3",
"ethers": "^6.13.4",
"ffjavascript": "0.2.48",
"fflate": "^0.8.2",
"idb": "^8.0.0"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^28.0.0",
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.3.0",
"@typechain/ethers-v6": "^0.5.1",
@ -54,8 +54,8 @@
"@types/circomlibjs": "^0.1.6",
"@types/node": "^22.7.5",
"@types/node-fetch": "^2.6.11",
"@typescript-eslint/eslint-plugin": "^8.8.1",
"@typescript-eslint/parser": "^8.8.1",
"@typescript-eslint/eslint-plugin": "^8.9.0",
"@typescript-eslint/parser": "^8.9.0",
"esbuild-loader": "^4.2.2",
"eslint": "8.57.0",
"eslint-config-prettier": "^9.1.0",

@ -33,7 +33,7 @@ const config = [
include: /\.[jt]sx?$/,
minify: false,
sourceMap: true,
target: 'es2016',
target: 'es2022',
}),
commonjs(),
nodeResolve(),
@ -54,7 +54,7 @@ const config = [
include: /\.[jt]sx?$/,
minify: false,
sourceMap: true,
target: 'es2016',
target: 'es2022',
}),
nodeResolve(),
json()
@ -75,7 +75,7 @@ const config = [
include: /\.[jt]sx?$/,
minify: false,
sourceMap: true,
target: 'es2016',
target: 'es2022',
}),
commonjs(),
nodeResolve(),

@ -225,11 +225,11 @@ export type BatchEventOnProgress = ({
}) => void;
// To enable iteration only numbers are accepted for fromBlock input
export type EventInput = {
export interface EventInput {
fromBlock: number;
toBlock: number;
type: ContractEventName;
};
}
/**
* Fetch events from web3 provider on bulk

@ -2,44 +2,34 @@ import { bnToBytes, bytesToBN, leBuff2Int, leInt2Buff, rBigInt, toFixedHex } fro
import { buffPedersenHash } from './pedersen';
import type { NetIdType } from './networkConfig';
export type DepositType = {
export interface DepositType {
currency: string;
amount: string;
netId: NetIdType;
};
}
export type createDepositParams = {
export interface createDepositParams {
nullifier: bigint;
secret: bigint;
};
}
export type createDepositObject = {
export interface createDepositObject {
preimage: Uint8Array;
noteHex: string;
commitment: bigint;
commitmentHex: string;
nullifierHash: bigint;
nullifierHex: string;
};
}
export type createNoteParams = DepositType & {
export interface createNoteParams extends DepositType {
nullifier?: bigint;
secret?: bigint;
};
}
export type parsedNoteExec = DepositType & {
export interface parsedNoteExec extends DepositType {
note: string;
};
export type depositTx = {
from: string;
transactionHash: string;
};
export type withdrawalTx = {
to: string;
transactionHash: string;
};
}
export async function createDeposit({ nullifier, secret }: createDepositParams): Promise<createDepositObject> {
const preimage = new Uint8Array([...leInt2Buff(nullifier), ...leInt2Buff(secret)]);
@ -199,9 +189,9 @@ export class Deposit {
}
}
export type parsedInvoiceExec = DepositType & {
export interface parsedInvoiceExec extends DepositType {
commitment: string;
};
}
export class Invoice {
currency: string;

@ -55,17 +55,17 @@ import type {
export const DEPOSIT = 'deposit';
export const WITHDRAWAL = 'withdrawal';
export type BaseEventsServiceConstructor = {
export interface BaseEventsServiceConstructor {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
contract: BaseContract;
type?: string;
type: string;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export type BatchGraphOnProgress = ({
type,
@ -79,12 +79,12 @@ export type BatchGraphOnProgress = ({
count?: number;
}) => void;
export type BaseGraphParams = {
export interface BaseGraphParams {
graphApi: string;
subgraphName: string;
fetchDataOptions?: fetchDataOptions;
onProgress?: BatchGraphOnProgress;
};
}
export class BaseEventsService<EventType extends MinimalEvents> {
netId: NetIdType;
@ -347,31 +347,22 @@ export class BaseEventsService<EventType extends MinimalEvents> {
}
}
export type BaseTornadoServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseTornadoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract'> {
Tornado: Tornado;
type: string;
amount: string;
currency: string;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export type DepositsGraphParams = BaseGraphParams & {
export interface DepositsGraphParams extends BaseGraphParams {
amount: string;
currency: string;
};
}
export class BaseTornadoService extends BaseEventsService<DepositsEvents | WithdrawalsEvents> {
amount: string;
currency: string;
batchTransactionService: BatchTransactionService;
batchBlockService: BatchBlockService;
tovarishClient?: TovarishClient;
constructor({
netId,
@ -520,16 +511,9 @@ export class BaseTornadoService extends BaseEventsService<DepositsEvents | Withd
}
}
export type BaseEchoServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseEchoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
Echoer: Echoer;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export class BaseEchoService extends BaseEventsService<EchoEvents> {
constructor({
@ -548,6 +532,7 @@ export class BaseEchoService extends BaseEventsService<EchoEvents> {
graphApi,
subgraphName,
contract: Echoer,
type: 'Echo',
deployedBlock,
fetchDataOptions,
tovarishClient,
@ -558,10 +543,6 @@ export class BaseEchoService extends BaseEventsService<EchoEvents> {
return `echo_${this.netId}`;
}
getType(): string {
return 'Echo';
}
getGraphMethod(): string {
return 'getAllGraphEchoEvents';
}
@ -601,16 +582,9 @@ export class BaseEchoService extends BaseEventsService<EchoEvents> {
}
}
export type BaseEncryptedNotesServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseEncryptedNotesServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
Router: TornadoRouter | TornadoProxyLight;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesEvents> {
constructor({
@ -629,6 +603,7 @@ export class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesE
graphApi,
subgraphName,
contract: Router,
type: 'EncryptedNote',
deployedBlock,
fetchDataOptions,
tovarishClient,
@ -639,10 +614,6 @@ export class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesE
return `encrypted_notes_${this.netId}`;
}
getType(): string {
return 'EncryptedNote';
}
getTovarishType(): string {
return 'encrypted_notes';
}
@ -673,16 +644,9 @@ export class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesE
}
}
export type BaseGovernanceServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseGovernanceServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
Governance: Governance;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents> {
batchTransactionService: BatchTransactionService;
@ -703,6 +667,7 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
graphApi,
subgraphName,
contract: Governance,
type: '*',
deployedBlock,
fetchDataOptions,
tovarishClient,
@ -718,10 +683,6 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
return `governance_${this.netId}`;
}
getType() {
return '*';
}
getTovarishType(): string {
return 'governance';
}
@ -841,7 +802,7 @@ export async function getTovarishNetworks(registryService: BaseRegistryService,
headers: {
'Content-Type': 'application/json',
},
timeout: 60000,
timeout: 30000,
maxRetry: registryService.fetchDataOptions?.torPort ? 2 : 0,
});
} catch {
@ -888,18 +849,11 @@ export interface CachedRelayers {
fromCache?: boolean;
}
export type BaseRegistryServiceConstructor = {
netId: NetIdType;
provider: Provider;
graphApi?: string;
subgraphName?: string;
export interface BaseRegistryServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
RelayerRegistry: RelayerRegistry;
Aggregator: Aggregator;
relayerEnsSubdomains: SubdomainMap;
deployedBlock?: number;
fetchDataOptions?: fetchDataOptions;
tovarishClient?: TovarishClient;
};
}
export class BaseRegistryService extends BaseEventsService<RegistersEvents> {
Aggregator: Aggregator;
@ -924,6 +878,7 @@ export class BaseRegistryService extends BaseEventsService<RegistersEvents> {
graphApi,
subgraphName,
contract: RelayerRegistry,
type: 'RelayerRegistered',
deployedBlock,
fetchDataOptions,
tovarishClient,
@ -939,11 +894,6 @@ export class BaseRegistryService extends BaseEventsService<RegistersEvents> {
return `registered_${this.netId}`;
}
// Name of type used for events
getType() {
return 'RelayerRegistered';
}
getTovarishType(): string {
return 'registered';
}

@ -20,37 +20,37 @@ export interface MinimalEvents {
transactionHash: string;
}
export type GovernanceEvents = MinimalEvents & {
export interface GovernanceEvents extends MinimalEvents {
event: string;
};
}
export type GovernanceProposalCreatedEvents = GovernanceEvents & {
export interface GovernanceProposalCreatedEvents extends GovernanceEvents {
id: number;
proposer: string;
target: string;
startTime: number;
endTime: number;
description: string;
};
}
export type GovernanceVotedEvents = GovernanceEvents & {
export interface GovernanceVotedEvents extends GovernanceEvents {
proposalId: number;
voter: string;
support: boolean;
votes: string;
from: string;
input: string;
};
}
export type GovernanceDelegatedEvents = GovernanceEvents & {
export interface GovernanceDelegatedEvents extends GovernanceEvents {
account: string;
delegateTo: string;
};
}
export type GovernanceUndelegatedEvents = GovernanceEvents & {
export interface GovernanceUndelegatedEvents extends GovernanceEvents {
account: string;
delegateFrom: string;
};
}
export type AllGovernanceEvents =
| GovernanceProposalCreatedEvents
@ -60,25 +60,25 @@ export type AllGovernanceEvents =
export type RegistersEvents = MinimalEvents & RelayerParams;
export type DepositsEvents = MinimalEvents & {
export interface DepositsEvents extends MinimalEvents {
commitment: string;
leafIndex: number;
timestamp: number;
from: string;
};
}
export type WithdrawalsEvents = MinimalEvents & {
export interface WithdrawalsEvents extends MinimalEvents {
nullifierHash: string;
to: string;
fee: string;
timestamp: number;
};
}
export type EchoEvents = MinimalEvents & {
export interface EchoEvents extends MinimalEvents {
address: string;
encryptedAccount: string;
};
}
export type EncryptedNotesEvents = MinimalEvents & {
export interface EncryptedNotesEvents extends MinimalEvents {
encryptedNote: string;
};
}

54
src/gaszip.ts Normal file

@ -0,0 +1,54 @@
import { isAddress } from 'ethers';
import { NetId, NetIdType } from './networkConfig';
// https://dev.gas.zip/gas/chain-support/inbound
export const gasZipInbounds: { [key in NetIdType]: string } = {
[NetId.MAINNET]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
[NetId.BSC]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
[NetId.POLYGON]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
[NetId.OPTIMISM]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
[NetId.ARBITRUM]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
[NetId.GNOSIS]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
[NetId.AVALANCHE]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
};
// https://dev.gas.zip/gas/chain-support/outbound
export const gasZipID: { [key in NetIdType]: number } = {
[NetId.MAINNET]: 255,
[NetId.BSC]: 14,
[NetId.POLYGON]: 17,
[NetId.OPTIMISM]: 55,
[NetId.ARBITRUM]: 57,
[NetId.GNOSIS]: 16,
[NetId.AVALANCHE]: 15,
[NetId.SEPOLIA]: 102,
};
// https://dev.gas.zip/gas/code-examples/eoaDeposit
export function gasZipInput(to: string, shorts: number[]): string | null {
let data = '0x';
if (isAddress(to)) {
if (to.length === 42) {
data += '02';
data += to.slice(2);
} else {
return null;
}
} else {
data += '01'; // to == sender
}
for (const i in shorts) {
data += '0x' + Number(shorts[i]).toString(16).slice(2).padStart(4, '0');
}
return data;
}
export function gasZipMinMax(ethUsd: number) {
return {
min: 1 / ethUsd,
max: 50 / ethUsd,
ethUsd,
};
}

@ -34,7 +34,7 @@ const isEmptyArray = (arr: object) => !Array.isArray(arr) || !arr.length;
// https://thegraph.com/docs/en/developing/developer-faqs/#23-is-there-a-limit-to-how-many-objects-the-graph-can-return-per-query
const GRAPHQL_LIMIT = 1000;
export type queryGraphParams = {
export interface queryGraphParams {
graphApi: string;
subgraphName: string;
query: string;
@ -42,7 +42,7 @@ export type queryGraphParams = {
[key: string]: string | number;
};
fetchDataOptions?: fetchDataOptions;
};
}
export async function queryGraph<T>({
graphApi,

@ -6,6 +6,7 @@ export * from './batch';
export * from './deposits';
export * from './encryptedNotes';
export * from './fees';
export * from './gaszip';
export * from './idb';
export * from './merkleTree';
export * from './mimc';

@ -7,13 +7,13 @@ import type { DepositType } from './deposits';
import type { DepositsEvents } from './events';
import type { NetIdType } from './networkConfig';
export type MerkleTreeConstructor = DepositType & {
export interface MerkleTreeConstructor extends DepositType {
Tornado: Tornado;
commitmentHex?: string;
merkleTreeHeight?: number;
emptyElement?: string;
merkleWorkerPath?: string;
};
}
export class MerkleTreeService {
currency: string;

@ -19,22 +19,22 @@ export interface RpcUrl {
url: string;
}
export type RpcUrls = {
[key in string]: RpcUrl;
};
export interface RpcUrls {
[key: string]: RpcUrl;
}
export interface SubgraphUrl {
name: string;
url: string;
}
export type SubgraphUrls = {
[key in string]: SubgraphUrl;
};
export interface SubgraphUrls {
[key: string]: SubgraphUrl;
}
export type TornadoInstance = {
export interface TornadoInstance {
instanceAddress: {
[key in string]: string;
[key: string]: string;
};
optionalInstances?: string[];
tokenAddress?: string;
@ -42,13 +42,13 @@ export type TornadoInstance = {
symbol: string;
decimals: number;
gasLimit?: number;
};
}
export type TokenInstances = {
[key in string]: TornadoInstance;
};
export interface TokenInstances {
[key: string]: TornadoInstance;
}
export type Config = {
export interface Config {
rpcCallRetryAttempt?: number;
// Should be in gwei
gasPrices: {
@ -68,6 +68,8 @@ export type Config = {
networkName: string;
deployedBlock: number;
rpcUrls: RpcUrls;
// Contract Address of stablecoin token, used for fiat conversion
stablecoin: string;
multicallContract: string;
routerContract: string;
echoContract: string;
@ -97,15 +99,15 @@ export type Config = {
// Should be in seconds
MINING_BLOCK_TIME?: number;
};
};
}
export type networkConfig = {
[key in NetIdType]: Config;
};
export interface networkConfig {
[key: NetIdType]: Config;
}
export type SubdomainMap = {
[key in NetIdType]: string;
};
export interface SubdomainMap {
[key: NetIdType]: string;
}
export const defaultConfig: networkConfig = {
[NetId.MAINNET]: {
@ -140,11 +142,12 @@ export const defaultConfig: networkConfig = {
name: 'Stackup RPC',
url: 'https://public.stackup.sh/api/v1/node/ethereum-mainnet',
},
oneRPC: {
oneRpc: {
name: '1RPC',
url: 'https://1rpc.io/eth',
},
},
stablecoin: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
echoContract: '0x9B27DD5Bb15d42DC224FCD0B7caEbBe16161Df42',
@ -258,6 +261,7 @@ export const defaultConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Binance Smart Chain',
deployedBlock: 8158799,
stablecoin: '0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
@ -281,7 +285,7 @@ export const defaultConfig: networkConfig = {
name: 'Stackup RPC',
url: 'https://public.stackup.sh/api/v1/node/bsc-mainnet',
},
oneRPC: {
oneRpc: {
name: '1RPC',
url: 'https://1rpc.io/bnb',
},
@ -320,6 +324,7 @@ export const defaultConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Polygon (Matic) Network',
deployedBlock: 16257962,
stablecoin: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
@ -370,6 +375,7 @@ export const defaultConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Optimism',
deployedBlock: 2243689,
stablecoin: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
@ -378,18 +384,14 @@ export const defaultConfig: networkConfig = {
tornadoSubgraph: 'tornadocash/optimism-tornado-subgraph',
subgraphs: {},
rpcUrls: {
optimism: {
name: 'Optimism',
url: 'https://mainnet.optimism.io',
oneRpc: {
name: '1RPC',
url: 'https://1rpc.io/op',
},
stackup: {
name: 'Stackup RPC',
url: 'https://public.stackup.sh/api/v1/node/optimism-mainnet',
},
oneRpc: {
name: '1RPC',
url: 'https://1rpc.io/op',
},
},
tokens: {
eth: {
@ -425,6 +427,7 @@ export const defaultConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Arbitrum One',
deployedBlock: 3430648,
stablecoin: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
@ -441,7 +444,7 @@ export const defaultConfig: networkConfig = {
url: 'https://public.stackup.sh/api/v1/node/arbitrum-one',
},
oneRpc: {
name: '1rpc',
name: '1RPC',
url: 'https://1rpc.io/arb',
},
},
@ -479,6 +482,7 @@ export const defaultConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Gnosis Chain',
deployedBlock: 17754561,
stablecoin: '0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
@ -490,12 +494,8 @@ export const defaultConfig: networkConfig = {
name: 'Gnosis',
url: 'https://rpc.gnosischain.com',
},
blockPi: {
name: 'BlockPi',
url: 'https://gnosis.blockpi.network/v1/rpc/public',
},
oneRpc: {
name: '1rpc',
name: '1RPC',
url: 'https://1rpc.io/gnosis',
},
},
@ -533,6 +533,7 @@ export const defaultConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Avalanche Mainnet',
deployedBlock: 4429818,
stablecoin: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
@ -540,14 +541,14 @@ export const defaultConfig: networkConfig = {
tornadoSubgraph: 'tornadocash/avalanche-tornado-subgraph',
subgraphs: {},
rpcUrls: {
publicRpc: {
name: 'Avalanche RPC',
url: 'https://api.avax.network/ext/bc/C/rpc',
},
oneRPC: {
name: 'OneRPC',
oneRpc: {
name: '1RPC',
url: 'https://1rpc.io/avax/c',
},
stackup: {
name: 'Stackup RPC',
url: 'https://public.stackup.sh/api/v1/node/avalanche-mainnet',
},
},
tokens: {
avax: {
@ -582,6 +583,7 @@ export const defaultConfig: networkConfig = {
emptyElement: '21663839004416932945382355908790599225266501822907911457504978515578255421292',
networkName: 'Ethereum Sepolia',
deployedBlock: 5594395,
stablecoin: '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238',
multicallContract: '0xcA11bde05977b3631167028862bE2a173976CA11',
routerContract: '0x1572AFE6949fdF51Cb3E0856216670ae9Ee160Ee',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
@ -602,8 +604,8 @@ export const defaultConfig: networkConfig = {
name: 'Stackup',
url: 'https://public.stackup.sh/api/v1/node/ethereum-sepolia',
},
onerpc: {
name: '1rpc',
oneRpc: {
name: '1RPC',
url: 'https://1rpc.io/sepolia',
},
ethpandaops: {

@ -1,6 +1,6 @@
import { parseEther, type Provider } from 'ethers';
import type { OffchainOracle, Multicall } from './typechain';
import { multicall } from './multicall';
import { formatEther, parseEther, type Provider } from 'ethers';
import { ERC20__factory, OffchainOracle, Multicall } from './typechain';
import { multicall, Call3 } from './multicall';
export class TokenPriceOracle {
oracle?: OffchainOracle;
@ -13,6 +13,46 @@ export class TokenPriceOracle {
this.oracle = oracle;
}
buildCalls(
tokens: {
tokenAddress: string;
decimals: number;
}[],
): Call3[] {
return tokens.map(({ tokenAddress }) => ({
contract: this.oracle,
name: 'getRateToEth',
params: [tokenAddress, true],
}));
}
buildStable(stablecoinAddress: string): Call3[] {
const stablecoin = ERC20__factory.connect(stablecoinAddress, this.provider);
return [
{
contract: stablecoin,
name: 'decimals',
},
{
contract: this.oracle,
name: 'getRateToEth',
params: [stablecoin.target, true],
},
];
}
async fetchPrice(tokenAddress: string, decimals: number): Promise<bigint> {
// setup mock price for testnets
if (!this.oracle) {
return new Promise((resolve) => resolve(parseEther('0.0001')));
}
const price = await this.oracle.getRateToEth(tokenAddress, true);
return (price * BigInt(10 ** decimals)) / BigInt(10 ** 18);
}
async fetchPrices(
tokens: {
tokenAddress: string;
@ -24,17 +64,24 @@ export class TokenPriceOracle {
return new Promise((resolve) => resolve(tokens.map(() => parseEther('0.0001'))));
}
const prices = (await multicall(
this.multicall,
tokens.map(({ tokenAddress }) => ({
contract: this.oracle,
name: 'getRateToEth',
params: [tokenAddress, true],
})),
)) as bigint[];
const prices = (await multicall(this.multicall, this.buildCalls(tokens))) as bigint[];
return prices.map((price, index) => {
return (price * BigInt(10 ** tokens[index].decimals)) / BigInt(10 ** 18);
});
}
async fetchEthUSD(stablecoinAddress: string): Promise<number> {
// setup mock price for testnets
if (!this.oracle) {
return new Promise((resolve) => resolve(10000));
}
const [decimals, price] = await multicall(this.multicall, this.buildStable(stablecoinAddress));
// eth wei price of usdc token
const ethPrice = (price * BigInt(10n ** decimals)) / BigInt(10 ** 18);
return 1 / Number(formatEther(ethPrice));
}
}

@ -371,12 +371,12 @@ export const populateTransaction = async (
return tx;
};
export type TornadoWalletOptions = {
export interface TornadoWalletOptions {
gasPriceBump?: number;
gasLimitBump?: number;
gasFailover?: boolean;
bumpNonce?: boolean;
};
}
export class TornadoWallet extends Wallet {
nonce?: number;
@ -474,13 +474,13 @@ export type connectWalletFunc = (...args: any[]) => Promise<void>;
export type handleWalletFunc = (...args: any[]) => void;
/* eslint-enable @typescript-eslint/no-explicit-any */
export type TornadoBrowserProviderOptions = TornadoWalletOptions & {
export interface TornadoBrowserProviderOptions extends TornadoWalletOptions {
netId?: NetIdType;
connectWallet?: connectWalletFunc;
handleNetworkChanges?: handleWalletFunc;
handleAccountChanges?: handleWalletFunc;
handleAccountDisconnect?: handleWalletFunc;
};
}
export class TornadoBrowserProvider extends BrowserProvider {
options?: TornadoBrowserProviderOptions;

@ -2,7 +2,7 @@ import { getAddress, parseEther } from 'ethers';
import { sleep } from './utils';
import { NetId, NetIdType, Config } from './networkConfig';
import { fetchData, fetchDataOptions } from './providers';
import { ajv, jobsSchema, getStatusSchema } from './schemas';
import { ajv, jobsSchema, jobRequestSchema, getStatusSchema } from './schemas';
import type { snarkProofs } from './websnark';
import type { CachedRelayerInfo } from './events';
@ -20,7 +20,7 @@ export interface RelayerParams {
/**
* Info from relayer status
*/
export type RelayerInfo = RelayerParams & {
export interface RelayerInfo extends RelayerParams {
netId: NetIdType;
url: string;
hostname: string;
@ -33,14 +33,14 @@ export type RelayerInfo = RelayerParams & {
};
currentQueue: number;
tornadoServiceFee: number;
};
}
export type RelayerError = {
export interface RelayerError {
hostname: string;
relayerAddress?: string;
errorMessage?: string;
hasError: boolean;
};
}
export interface RelayerStatus {
url: string;
@ -75,9 +75,9 @@ export interface RelayerStatus {
currentQueue: number;
}
export type TornadoWithdrawParams = snarkProofs & {
export interface TornadoWithdrawParams extends snarkProofs {
contract: string;
};
}
export interface RelayerTornadoWithdraw {
id?: string;
@ -149,13 +149,13 @@ export function getWeightRandom(weightsScores: bigint[], random: bigint) {
return Math.floor(Math.random() * weightsScores.length);
}
export type RelayerInstanceList = {
[key in string]: {
export interface RelayerInstanceList {
[key: string]: {
instanceAddress: {
[key in string]: string;
};
[key: string]: string;
};
};
}
export function getSupportedInstances(instanceList: RelayerInstanceList) {
const rawList = Object.values(instanceList)
@ -223,7 +223,7 @@ export class RelayerClient {
headers: {
'Content-Type': 'application/json, application/x-www-form-urlencoded',
},
timeout: 60000,
timeout: 30000,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0,
})) as object;
@ -318,10 +318,14 @@ export class RelayerClient {
async tornadoWithdraw(
{ contract, proof, args }: TornadoWithdrawParams,
callback?: (jobResp: RelayerTornadoJobs) => void,
callback?: (jobResp: RelayerTornadoWithdraw | RelayerTornadoJobs) => void,
) {
const { url } = this.selectedRelayer as RelayerInfo;
/**
* Request new job
*/
const withdrawResponse = (await fetchData(`${url}v1/tornadoWithdraw`, {
...this.fetchDataOptions,
method: 'POST',
@ -341,6 +345,21 @@ export class RelayerClient {
throw new Error(error);
}
const jobValidator = ajv.compile(jobRequestSchema);
if (!jobValidator(withdrawResponse)) {
const errMsg = `${url}v1/tornadoWithdraw has an invalid job response`;
throw new Error(errMsg);
}
if (typeof callback === 'function') {
callback(withdrawResponse as unknown as RelayerTornadoWithdraw);
}
/**
* Get job status
*/
let relayerStatus: string | undefined;
const jobUrl = `${url}v1/jobs/${id}`;

@ -1,4 +1,4 @@
export type jobsSchema = {
export interface jobsSchema {
type: string;
properties: {
error: {
@ -36,7 +36,7 @@ export type jobsSchema = {
};
};
required: string[];
};
}
export const jobsSchema: jobsSchema = {
type: 'object',
@ -57,3 +57,8 @@ export const jobsSchema: jobsSchema = {
},
required: ['id', 'status'],
};
export const jobRequestSchema: jobsSchema = {
...jobsSchema,
required: ['id'],
};

@ -1,7 +1,7 @@
import { Config, NetId, NetIdType } from '../networkConfig';
import { addressSchemaType, bnSchemaType } from '.';
export type statusInstanceType = {
export interface statusInstanceType {
type: string;
properties: {
instanceAddress: {
@ -16,25 +16,25 @@ export type statusInstanceType = {
decimals: { enum: number[] };
};
required: string[];
};
}
export type statusInstancesType = {
export interface statusInstancesType {
type: string;
properties: {
[key in string]: statusInstanceType;
};
required: string[];
};
}
export type statusEthPricesType = {
export interface statusEthPricesType {
type: string;
properties: {
[key in string]: typeof bnSchemaType;
};
required?: string[];
};
}
export type statusSchema = {
export interface statusSchema {
type: string;
properties: {
rewardAccount: typeof addressSchemaType;
@ -90,7 +90,7 @@ export type statusSchema = {
};
};
required: string[];
};
}
const statusSchema: statusSchema = {
type: 'object',

@ -10,7 +10,8 @@ import {
} from './relayerClient';
import { fetchData } from './providers';
import { CachedRelayerInfo, MinimalEvents } from './events';
import { getEventsSchemaValidator } from './schemas';
import { ajv, getEventsSchemaValidator, getStatusSchema } from './schemas';
import { enabledChains, getConfig, NetId, NetIdType } from './networkConfig';
// Return no more than 5K events per query
export const MAX_TOVARISH_EVENTS = 5000;
@ -81,7 +82,7 @@ export interface BaseTovarishEvents<T> {
}
export class TovarishClient extends RelayerClient {
selectedRelayer?: TovarishInfo;
declare selectedRelayer?: TovarishInfo;
constructor({ netId, config, fetchDataOptions }: RelayerClientConstructor) {
super({ netId, config, fetchDataOptions });
@ -108,6 +109,82 @@ export class TovarishClient extends RelayerClient {
return status;
}
/**
* Ask status for all enabled chains for tovarish relayer
*/
async askAllStatus({
hostname,
url,
relayerAddress,
}: {
hostname?: string;
// optional url if entered manually
url?: string;
// relayerAddress from registry contract to prevent cheating
relayerAddress?: string;
}): Promise<TovarishStatus[]> {
if (!url && hostname) {
url = `https://${!hostname.endsWith('/') ? hostname + '/' : hostname}`;
} else if (url && !url.endsWith('/')) {
url += '/';
} else {
url = '';
}
const statusArray = (await fetchData(`${url}status`, {
...this.fetchDataOptions,
headers: {
'Content-Type': 'application/json, application/x-www-form-urlencoded',
},
timeout: 30000,
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0,
})) as object;
if (!Array.isArray(statusArray)) {
return [];
}
const tovarishStatus: TovarishStatus[] = [];
for (const rawStatus of statusArray) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const netId = (rawStatus as any).netId as NetIdType;
const config = getConfig(netId);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const statusValidator = ajv.compile(getStatusSchema((rawStatus as any).netId, config, this.tovarish));
if (!statusValidator) {
continue;
}
const status = {
...rawStatus,
url: `${url}${netId}/`,
} as TovarishStatus;
if (status.currentQueue > 5) {
throw new Error('Withdrawal queue is overloaded');
}
if (!enabledChains.includes(status.netId)) {
throw new Error('This relayer serves a different network');
}
if (relayerAddress && status.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) {
throw new Error('The Relayer reward address must match registered address');
}
if (!status.version.includes('tovarish')) {
throw new Error('Not a tovarish relayer!');
}
tovarishStatus.push(status);
}
return tovarishStatus;
}
async filterRelayer(relayer: CachedRelayerInfo): Promise<TovarishInfo | RelayerError | undefined> {
const { ensName, relayerAddress, tovarishHost, tovarishNetworks } = relayer;
@ -175,6 +252,62 @@ export class TovarishClient extends RelayerClient {
};
}
async getTovarishRelayers(relayers: CachedRelayerInfo[]): Promise<{
validRelayers: TovarishInfo[];
invalidRelayers: RelayerError[];
}> {
const validRelayers: TovarishInfo[] = [];
const invalidRelayers: RelayerError[] = [];
await Promise.all(
relayers
.filter((r) => r.tovarishHost && r.tovarishNetworks?.length)
.map(async (relayer) => {
const { ensName, relayerAddress, tovarishHost } = relayer;
try {
const statusArray = await this.askAllStatus({ hostname: tovarishHost as string, relayerAddress });
for (const status of statusArray) {
validRelayers.push({
netId: status.netId,
url: status.url,
hostname: tovarishHost as string,
ensName,
relayerAddress,
rewardAccount: getAddress(status.rewardAccount),
instances: getSupportedInstances(status.instances),
stakeBalance: relayer.stakeBalance,
gasPrice: status.gasPrices?.fast,
ethPrices: status.ethPrices,
currentQueue: status.currentQueue,
tornadoServiceFee: status.tornadoServiceFee,
// Additional fields for tovarish relayer
latestBlock: Number(status.latestBlock),
latestBalance: status.latestBalance,
version: status.version,
events: status.events,
syncStatus: status.syncStatus,
});
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
invalidRelayers.push({
hostname: tovarishHost as string,
relayerAddress,
errorMessage: err.message,
hasError: true,
});
}
}),
);
return {
validRelayers,
invalidRelayers,
};
}
async getEvents<T extends MinimalEvents>({
type,
currency,
@ -213,6 +346,13 @@ export class TovarishClient extends RelayerClient {
throw new Error(errMsg);
}
if (recent) {
return {
events: fetchedEvents,
lastSyncBlock: currentBlock,
};
}
lastSyncBlock = currentBlock;
if (!Array.isArray(fetchedEvents) || !fetchedEvents.length) {

@ -5,7 +5,7 @@ import websnarkGroth from '@tornado/websnark/src/groth16';
import type { Element } from '@tornado/fixed-merkle-tree';
import { toFixedHex } from './utils';
export type snarkInputs = {
export interface snarkInputs {
// Public snark inputs
root: Element;
nullifierHex: string;
@ -19,7 +19,7 @@ export type snarkInputs = {
secret: bigint;
pathElements: Element[];
pathIndices: Element[];
};
}
export type snarkArgs = [
_root: string,
@ -30,10 +30,10 @@ export type snarkArgs = [
_refund: string,
];
export type snarkProofs = {
export interface snarkProofs {
proof: string;
args: snarkArgs;
};
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let groth16: any;

@ -15,7 +15,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2018", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"target": "es2022", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */

@ -7,7 +7,7 @@ const esbuildLoader = {
loader: 'esbuild-loader',
options: {
loader: 'ts',
target: 'es2016',
target: 'es2022',
}
}

160
yarn.lock

@ -725,18 +725,18 @@
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31"
integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==
"@rollup/plugin-commonjs@^28.0.0":
version "28.0.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.0.tgz#44b5e49cb5d5e6233f1e4996013a8649fdbb9557"
integrity sha512-BJcu+a+Mpq476DMXG+hevgPSl56bkUoi88dKT8t3RyUp8kGuOh+2bU8Gs7zXDlu+fyZggnJ+iOBGrb/O1SorYg==
"@rollup/plugin-commonjs@^28.0.1":
version "28.0.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz#e2138e31cc0637676dc3d5cae7739131f7cd565e"
integrity sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==
dependencies:
"@rollup/pluginutils" "^5.0.1"
commondir "^1.0.1"
estree-walker "^2.0.2"
fdir "^6.1.1"
fdir "^6.2.0"
is-reference "1.2.1"
magic-string "^0.30.3"
picomatch "^2.3.1"
picomatch "^4.0.2"
"@rollup/plugin-json@^6.1.0":
version "6.1.0"
@ -872,14 +872,13 @@
"@noble/hashes" "~1.4.0"
"@scure/base" "~1.1.6"
"@tornado/contracts@^1.0.1":
version "1.0.1"
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fcontracts/-/1.0.1/contracts-1.0.1.tgz#4ce0bb721c602155f087bc5526afb22b2dd05b31"
integrity sha512-5PHi2y/WybAF4uMjLenOEtqmaJ+sHkGYJJ9bHlOPlzbKooVzqVPpESKg1MEjofSpTLGG8XZAKEsXedyHX7+6qw==
"@tornado/contracts@git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#ece511f424dc811c3aec149a4bf0e3731c0598a4":
version "1.0.2"
resolved "git+https://git.tornado.ws/tornadocontrib/tornado-contracts.git#ece511f424dc811c3aec149a4bf0e3731c0598a4"
dependencies:
"@openzeppelin/contracts" "5.0.2"
"@openzeppelin/contracts-v3" "npm:@openzeppelin/contracts@3.2.0-rc.0"
ethers "^6.4.0"
ethers "^6.13.4"
"@tornado/fixed-merkle-tree@^0.7.3":
version "0.7.3"
@ -968,12 +967,7 @@
dependencies:
undici-types "~6.19.2"
"@types/node@18.15.13":
version "18.15.13"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469"
integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==
"@types/node@^22.7.5":
"@types/node@22.7.5", "@types/node@^22.7.5":
version "22.7.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b"
integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==
@ -990,62 +984,62 @@
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975"
integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==
"@typescript-eslint/eslint-plugin@^8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz#9364b756d4d78bcbdf6fd3e9345e6924c68ad371"
integrity sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==
"@typescript-eslint/eslint-plugin@^8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.9.0.tgz#bf0b25305b0bf014b4b194a6919103d7ac2a7907"
integrity sha512-Y1n621OCy4m7/vTXNlCbMVp87zSd7NH0L9cXD8aIpOaNlzeWxIK4+Q19A68gSmTNRZn92UjocVUWDthGxtqHFg==
dependencies:
"@eslint-community/regexpp" "^4.10.0"
"@typescript-eslint/scope-manager" "8.8.1"
"@typescript-eslint/type-utils" "8.8.1"
"@typescript-eslint/utils" "8.8.1"
"@typescript-eslint/visitor-keys" "8.8.1"
"@typescript-eslint/scope-manager" "8.9.0"
"@typescript-eslint/type-utils" "8.9.0"
"@typescript-eslint/utils" "8.9.0"
"@typescript-eslint/visitor-keys" "8.9.0"
graphemer "^1.4.0"
ignore "^5.3.1"
natural-compare "^1.4.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/parser@^8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.8.1.tgz#5952ba2a83bd52024b872f3fdc8ed2d3636073b8"
integrity sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==
"@typescript-eslint/parser@^8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.9.0.tgz#0cecda6def8aef95d7c7098359c0fda5a362d6ad"
integrity sha512-U+BLn2rqTTHnc4FL3FJjxaXptTxmf9sNftJK62XLz4+GxG3hLHm/SUNaaXP5Y4uTiuYoL5YLy4JBCJe3+t8awQ==
dependencies:
"@typescript-eslint/scope-manager" "8.8.1"
"@typescript-eslint/types" "8.8.1"
"@typescript-eslint/typescript-estree" "8.8.1"
"@typescript-eslint/visitor-keys" "8.8.1"
"@typescript-eslint/scope-manager" "8.9.0"
"@typescript-eslint/types" "8.9.0"
"@typescript-eslint/typescript-estree" "8.9.0"
"@typescript-eslint/visitor-keys" "8.9.0"
debug "^4.3.4"
"@typescript-eslint/scope-manager@8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz#b4bea1c0785aaebfe3c4ab059edaea1c4977e7ff"
integrity sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==
"@typescript-eslint/scope-manager@8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.9.0.tgz#c98fef0c4a82a484e6a1eb610a55b154d14d46f3"
integrity sha512-bZu9bUud9ym1cabmOYH9S6TnbWRzpklVmwqICeOulTCZ9ue2/pczWzQvt/cGj2r2o1RdKoZbuEMalJJSYw3pHQ==
dependencies:
"@typescript-eslint/types" "8.8.1"
"@typescript-eslint/visitor-keys" "8.8.1"
"@typescript-eslint/types" "8.9.0"
"@typescript-eslint/visitor-keys" "8.9.0"
"@typescript-eslint/type-utils@8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz#31f59ec46e93a02b409fb4d406a368a59fad306e"
integrity sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==
"@typescript-eslint/type-utils@8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.9.0.tgz#aa86da3e4555fe7c8b42ab75e13561c4b5a8dfeb"
integrity sha512-JD+/pCqlKqAk5961vxCluK+clkppHY07IbV3vett97KOV+8C6l+CPEPwpUuiMwgbOz/qrN3Ke4zzjqbT+ls+1Q==
dependencies:
"@typescript-eslint/typescript-estree" "8.8.1"
"@typescript-eslint/utils" "8.8.1"
"@typescript-eslint/typescript-estree" "8.9.0"
"@typescript-eslint/utils" "8.9.0"
debug "^4.3.4"
ts-api-utils "^1.3.0"
"@typescript-eslint/types@8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.8.1.tgz#ebe85e0fa4a8e32a24a56adadf060103bef13bd1"
integrity sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==
"@typescript-eslint/types@8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.9.0.tgz#b733af07fb340b32e962c6c63b1062aec2dc0fe6"
integrity sha512-SjgkvdYyt1FAPhU9c6FiYCXrldwYYlIQLkuc+LfAhCna6ggp96ACncdtlbn8FmnG72tUkXclrDExOpEYf1nfJQ==
"@typescript-eslint/typescript-estree@8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz#34649f4e28d32ee49152193bc7dedc0e78e5d1ec"
integrity sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==
"@typescript-eslint/typescript-estree@8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.9.0.tgz#1714f167e9063062dc0df49c1d25afcbc7a96199"
integrity sha512-9iJYTgKLDG6+iqegehc5+EqE6sqaee7kb8vWpmHZ86EqwDjmlqNNHeqDVqb9duh+BY6WCNHfIGvuVU3Tf9Db0g==
dependencies:
"@typescript-eslint/types" "8.8.1"
"@typescript-eslint/visitor-keys" "8.8.1"
"@typescript-eslint/types" "8.9.0"
"@typescript-eslint/visitor-keys" "8.9.0"
debug "^4.3.4"
fast-glob "^3.3.2"
is-glob "^4.0.3"
@ -1053,22 +1047,22 @@
semver "^7.6.0"
ts-api-utils "^1.3.0"
"@typescript-eslint/utils@8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.8.1.tgz#9e29480fbfa264c26946253daa72181f9f053c9d"
integrity sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==
"@typescript-eslint/utils@8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.9.0.tgz#748bbe3ea5bee526d9786d9405cf1b0df081c299"
integrity sha512-PKgMmaSo/Yg/F7kIZvrgrWa1+Vwn036CdNUvYFEkYbPwOH4i8xvkaRlu148W3vtheWK9ckKRIz7PBP5oUlkrvQ==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
"@typescript-eslint/scope-manager" "8.8.1"
"@typescript-eslint/types" "8.8.1"
"@typescript-eslint/typescript-estree" "8.8.1"
"@typescript-eslint/scope-manager" "8.9.0"
"@typescript-eslint/types" "8.9.0"
"@typescript-eslint/typescript-estree" "8.9.0"
"@typescript-eslint/visitor-keys@8.8.1":
version "8.8.1"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz#0fb1280f381149fc345dfde29f7542ff4e587fc5"
integrity sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==
"@typescript-eslint/visitor-keys@8.9.0":
version "8.9.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.9.0.tgz#5f11f4d9db913f37da42776893ffe0dd1ae78f78"
integrity sha512-Ht4y38ubk4L5/U8xKUBfKNYGmvKvA1CANoxiTRMM+tOLk3lbF3DvzZCxJCRSE+2GdCMSh6zq9VZJc3asc1XuAA==
dependencies:
"@typescript-eslint/types" "8.8.1"
"@typescript-eslint/types" "8.9.0"
eslint-visitor-keys "^3.4.3"
"@ungap/structured-clone@^1.2.0":
@ -2602,17 +2596,17 @@ ethers@^5.5.1:
"@ethersproject/web" "5.7.1"
"@ethersproject/wordlists" "5.7.0"
ethers@^6.13.3, ethers@^6.4.0:
version "6.13.3"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.3.tgz#b87afdadb91cc8df5f56b9c59c96e5b206f4a600"
integrity sha512-/DzbZOLVtoO4fKvvQwpEucHAQgIwBGWuRvBdwE/lMXgXvvHHTSkn7XqAQ2b+gjJzZDJjWA9OD05bVceVOsBHbg==
ethers@^6.13.4:
version "6.13.4"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.13.4.tgz#bd3e1c3dc1e7dc8ce10f9ffb4ee40967a651b53c"
integrity sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA==
dependencies:
"@adraffy/ens-normalize" "1.10.1"
"@noble/curves" "1.2.0"
"@noble/hashes" "1.3.2"
"@types/node" "18.15.13"
"@types/node" "22.7.5"
aes-js "4.0.0-beta.5"
tslib "2.4.0"
tslib "2.7.0"
ws "8.17.1"
event-target-shim@^5.0.0:
@ -2703,7 +2697,7 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
fdir@^6.1.1:
fdir@^6.2.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.0.tgz#8e80ab4b18a2ac24beebf9d20d71e1bc2627dbae"
integrity sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==
@ -4072,6 +4066,11 @@ picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
picomatch@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
pkg-dir@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
@ -4866,21 +4865,16 @@ tsconfig-paths@^3.15.0:
minimist "^1.2.6"
strip-bom "^3.0.0"
tslib@2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
tslib@2.7.0, tslib@^2.6.2:
version "2.7.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
tslib@^1.9.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
tslib@^2.6.2:
version "2.7.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01"
integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==
tty-browserify@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"