Compare commits
12 Commits
722c426fcb
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
e132275d33
|
|||
|
bf432161fb
|
|||
|
a93fa4a8be
|
|||
|
8d5658ee7a
|
|||
|
d688f8a2b5
|
|||
|
0aa9f00383
|
|||
|
e19f5a1373
|
|||
|
5bfef2a2ae
|
|||
|
53cb3ac414
|
|||
|
f4382f4e78
|
|||
|
20bb8c25a1
|
|||
|
d143bc2923
|
44
.eslintrc.js
44
.eslintrc.js
@@ -1,44 +0,0 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
es2021: true,
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
'prettier',
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
overrides: [
|
||||
{
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
files: ['.eslintrc.{js,cjs}'],
|
||||
parserOptions: {
|
||||
sourceType: 'script',
|
||||
},
|
||||
},
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'prettier'],
|
||||
rules: {
|
||||
'prettier/prettier': [
|
||||
'error',
|
||||
{
|
||||
tabWidth: 4,
|
||||
printWidth: 120,
|
||||
singleQuote: true,
|
||||
},
|
||||
],
|
||||
'import/order': ['error'],
|
||||
'@typescript-eslint/no-unused-vars': ['warn'],
|
||||
'@typescript-eslint/no-unused-expressions': ['off'],
|
||||
},
|
||||
};
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1 +1 @@
|
||||
dist/* linguist-vendored
|
||||
dist/**/* linguist-vendored
|
||||
1
.npmrc
1
.npmrc
@@ -1 +0,0 @@
|
||||
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/
|
||||
10
Dockerfile
10
Dockerfile
@@ -1,13 +1,13 @@
|
||||
# Dockefile from https://notes.ethereum.org/@GW1ZUbNKR5iRjjKYx6_dJQ/Bk8zsJ9xj
|
||||
# FROM node:20.18.0-bullseye-slim
|
||||
FROM node@sha256:9b558df8f10198fcd1f48cf344c55c4442c3446b8a9a69487523b3d890a4a59e
|
||||
# FROM node:22.12.0-bullseye-slim
|
||||
FROM node@sha256:9f385b101f66ecdf9ed9218d000cd5a35600722f0aab8112632371765109c065
|
||||
|
||||
# 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
|
||||
ENV GIT_REPOSITORY=https://github.com/tornadocontrib/tornado-scripts.git
|
||||
# From main branch, double check with git.tornado.ws and codeberg.org
|
||||
ENV GIT_COMMIT_HASH=8d5658ee7aedbaa2413868c4c9e0fb453a92ae64
|
||||
|
||||
# clone the repository
|
||||
RUN mkdir /app/
|
||||
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Tornado Cash
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
<img src="./logo2.png">
|
||||
|
||||
# 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
|
||||
# Tornado Scripts (tornado-scripts)
|
||||
|
||||
🛠 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)
|
||||
|
||||
@@ -12,9 +10,9 @@
|
||||
|
||||
</div>
|
||||
|
||||
### About Tornado Core
|
||||
### About Tornado Scripts
|
||||
|
||||
Tornado Core is a modern building block for Privacy Pools to build anything from custom UI or CLI tools
|
||||
Tornado Scripts is a modern building block for Privacy Pools to build anything from custom UI or CLI tools
|
||||
|
||||
+ Written in [TypeScript](https://www.typescriptlang.org/)
|
||||
|
||||
|
||||
2
dist/contracts.d.ts
vendored
2
dist/contracts.d.ts
vendored
@@ -1,2 +1,2 @@
|
||||
export * from '@tornado/contracts';
|
||||
export * from 'tornado-contracts';
|
||||
export { Multicall, Multicall__factory, OffchainOracle, OffchainOracle__factory, OvmGasPriceOracle, OvmGasPriceOracle__factory, ReverseRecords, ReverseRecords__factory, ENSNameWrapper, ENSNameWrapper__factory, ENSRegistry, ENSRegistry__factory, ENSResolver, ENSResolver__factory, } from './typechain';
|
||||
|
||||
12
dist/ens.d.ts
vendored
12
dist/ens.d.ts
vendored
@@ -8,13 +8,11 @@ export declare function makeLabelNodeAndParent(name: string): {
|
||||
labelhash: string;
|
||||
parentNode: string;
|
||||
};
|
||||
export declare const EnsContracts: {
|
||||
[key: NetIdType]: {
|
||||
ensRegistry: string;
|
||||
ensPublicResolver: string;
|
||||
ensNameWrapper: string;
|
||||
};
|
||||
};
|
||||
export declare const EnsContracts: Record<NetIdType, {
|
||||
ensRegistry: string;
|
||||
ensPublicResolver: string;
|
||||
ensNameWrapper: string;
|
||||
}>;
|
||||
/**
|
||||
* ENSUtils to manage on-chain registered relayers
|
||||
*/
|
||||
|
||||
60
dist/events/base.d.ts
vendored
60
dist/events/base.d.ts
vendored
@@ -1,9 +1,9 @@
|
||||
import { BaseContract, Provider, EventLog } from 'ethers';
|
||||
import { Tornado, TornadoRouter, TornadoProxyLight, Governance, RelayerRegistry, Echoer, Aggregator } from '@tornado/contracts';
|
||||
import { Tornado, TornadoRouter, TornadoProxyLight, Governance, RelayerRegistry, Echoer, TovarishAggregator } from 'tornado-contracts';
|
||||
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 { TornadoConfig, type NetIdType, type SubdomainMap } from '../networkConfig';
|
||||
import { RelayerParams } from '../relayerClient';
|
||||
import type { TovarishClient } from '../tovarishClient';
|
||||
import type { ERC20, ReverseRecords } from '../typechain';
|
||||
@@ -98,16 +98,12 @@ export declare class BaseTornadoService extends BaseEventsService<DepositsEvents
|
||||
}): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>>;
|
||||
}
|
||||
export interface BaseMultiTornadoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
instances: {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
instances: Record<string, DepositType>;
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
}
|
||||
export declare class BaseMultiTornadoService extends BaseEventsService<MultiDepositsEvents | MultiWithdrawalsEvents> {
|
||||
instances: {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
instances: Record<string, DepositType>;
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
batchTransactionService: BatchTransactionService;
|
||||
@@ -143,9 +139,7 @@ export declare class BaseEncryptedNotesService extends BaseEventsService<Encrypt
|
||||
getTovarishType(): string;
|
||||
formatEvents(events: EventLog[]): Promise<EncryptedNotesEvents[]>;
|
||||
}
|
||||
export declare const proposalState: {
|
||||
[key: string]: string;
|
||||
};
|
||||
export declare const proposalState: Record<string, string>;
|
||||
export interface GovernanceProposals extends GovernanceProposalCreatedEvents {
|
||||
title: string;
|
||||
proposerName?: string;
|
||||
@@ -164,12 +158,12 @@ export interface GovernanceVotes extends GovernanceVotedEvents {
|
||||
}
|
||||
export interface BaseGovernanceServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
Aggregator: TovarishAggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
}
|
||||
export declare class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
Aggregator: TovarishAggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
batchTransactionService: BatchTransactionService;
|
||||
constructor(serviceConstructor: BaseGovernanceServiceConstructor);
|
||||
@@ -182,14 +176,11 @@ export declare class BaseGovernanceService extends BaseEventsService<AllGovernan
|
||||
delegatedAccs: string[];
|
||||
undelegatedAccs: string[];
|
||||
uniq: string[];
|
||||
uniqNames: {
|
||||
[key: string]: string;
|
||||
};
|
||||
uniqNames: Record<string, string>;
|
||||
balances: bigint[];
|
||||
balance: bigint;
|
||||
}>;
|
||||
}
|
||||
export declare function getTovarishNetworks(registryService: BaseRegistryService, relayers: CachedRelayerInfo[]): Promise<void>;
|
||||
/**
|
||||
* Essential params:
|
||||
* ensName, relayerAddress, hostnames
|
||||
@@ -197,49 +188,26 @@ export declare function getTovarishNetworks(registryService: BaseRegistryService
|
||||
*/
|
||||
export interface CachedRelayerInfo extends RelayerParams {
|
||||
isRegistered?: boolean;
|
||||
registeredAddress?: string;
|
||||
isPrior?: boolean;
|
||||
stakeBalance?: string;
|
||||
hostnames: SubdomainMap;
|
||||
tovarishHost?: string;
|
||||
tovarishNetworks?: number[];
|
||||
}
|
||||
export interface CachedRelayers {
|
||||
lastBlock: number;
|
||||
timestamp: number;
|
||||
relayers: CachedRelayerInfo[];
|
||||
fromCache?: boolean;
|
||||
}
|
||||
export interface BaseRegistryServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
tornadoConfig: TornadoConfig;
|
||||
RelayerRegistry: RelayerRegistry;
|
||||
Aggregator: Aggregator;
|
||||
relayerEnsSubdomains: SubdomainMap;
|
||||
Aggregator: TovarishAggregator;
|
||||
}
|
||||
export declare class BaseRegistryService extends BaseEventsService<AllRelayerRegistryEvents> {
|
||||
Aggregator: Aggregator;
|
||||
relayerEnsSubdomains: SubdomainMap;
|
||||
tornadoConfig: TornadoConfig;
|
||||
Aggregator: TovarishAggregator;
|
||||
updateInterval: number;
|
||||
constructor(serviceConstructor: BaseRegistryServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getTovarishType(): string;
|
||||
formatEvents(events: EventLog[]): Promise<AllRelayerRegistryEvents[]>;
|
||||
/**
|
||||
* Get saved or cached relayers
|
||||
*/
|
||||
getRelayersFromDB(): Promise<CachedRelayers>;
|
||||
/**
|
||||
* Relayers from remote cache (Either from local cache, CDN, or from IPFS)
|
||||
*/
|
||||
getRelayersFromCache(): Promise<CachedRelayers>;
|
||||
getSavedRelayers(): Promise<CachedRelayers>;
|
||||
getLatestRelayers(): Promise<CachedRelayers>;
|
||||
/**
|
||||
* Handle saving relayers
|
||||
*/
|
||||
saveRelayers({ lastBlock, timestamp, relayers }: CachedRelayers): Promise<void>;
|
||||
/**
|
||||
* Get cached or latest relayer and save to local
|
||||
*/
|
||||
updateRelayers(): Promise<CachedRelayers>;
|
||||
getLatestRelayers(knownRelayers?: string[]): Promise<CachedRelayerInfo[]>;
|
||||
}
|
||||
export interface BaseRevenueServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
RelayerRegistry: RelayerRegistry;
|
||||
|
||||
6
dist/events/db.d.ts
vendored
6
dist/events/db.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { IndexedDB } from '../idb';
|
||||
import { BaseTornadoService, BaseTornadoServiceConstructor, BaseEchoService, BaseEchoServiceConstructor, BaseEncryptedNotesService, BaseEncryptedNotesServiceConstructor, BaseGovernanceService, BaseGovernanceServiceConstructor, BaseRegistryService, BaseRegistryServiceConstructor, BaseRevenueService, BaseRevenueServiceConstructor, CachedRelayers, BaseMultiTornadoService, BaseMultiTornadoServiceConstructor } from './base';
|
||||
import { BaseTornadoService, BaseTornadoServiceConstructor, BaseEchoService, BaseEchoServiceConstructor, BaseEncryptedNotesService, BaseEncryptedNotesServiceConstructor, BaseGovernanceService, BaseGovernanceServiceConstructor, BaseRegistryService, BaseRegistryServiceConstructor, BaseRevenueService, BaseRevenueServiceConstructor, 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;
|
||||
@@ -100,16 +100,12 @@ export declare class DBRegistryService extends BaseRegistryService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
relayerJsonDigest?: string;
|
||||
constructor(params: DBRegistryServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<AllRelayerRegistryEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<AllRelayerRegistryEvents>>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<AllRelayerRegistryEvents> & {
|
||||
newEvents: AllRelayerRegistryEvents[];
|
||||
}): Promise<void>;
|
||||
getRelayersFromDB(): Promise<CachedRelayers>;
|
||||
getRelayersFromCache(): Promise<CachedRelayers>;
|
||||
saveRelayers(cachedRelayers: CachedRelayers): Promise<void>;
|
||||
}
|
||||
export interface DBRevenueServiceConstructor extends BaseRevenueServiceConstructor {
|
||||
staticUrl: string;
|
||||
|
||||
8
dist/gaszip.d.ts
vendored
8
dist/gaszip.d.ts
vendored
@@ -1,10 +1,6 @@
|
||||
import { NetIdType } from './networkConfig';
|
||||
export declare const gasZipInbounds: {
|
||||
[key in NetIdType]: string;
|
||||
};
|
||||
export declare const gasZipID: {
|
||||
[key in NetIdType]: number;
|
||||
};
|
||||
export declare const gasZipInbounds: Record<NetIdType, string>;
|
||||
export declare const gasZipID: Record<NetIdType, number>;
|
||||
export declare function gasZipInput(to: string, shorts: number[]): string | null;
|
||||
export declare function gasZipMinMax(ethUsd: number): {
|
||||
min: number;
|
||||
|
||||
4
dist/graphql/index.d.ts
vendored
4
dist/graphql/index.d.ts
vendored
@@ -12,9 +12,7 @@ export interface queryGraphParams {
|
||||
graphApi: string;
|
||||
subgraphName: string;
|
||||
query: string;
|
||||
variables?: {
|
||||
[key: string]: string | number;
|
||||
};
|
||||
variables?: Record<string, string | number>;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
}
|
||||
export declare function queryGraph<T>({ graphApi, subgraphName, query, variables, fetchDataOptions, }: queryGraphParams): Promise<T>;
|
||||
|
||||
18
dist/hashes.json
vendored
18
dist/hashes.json
vendored
@@ -1,11 +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"
|
||||
"dist/index.js": "sha384-ILYwPMkfXtfslWBdxqmKYYq4yDnJf3tKKgW5Am0P4NnpLW9z5m/wlLBuITa51727",
|
||||
"dist/index.mjs": "sha384-bgbAMKtG/iKiZKdITr1E+i14xCVp17/Yj8/O5bCE8BMnqlwTY/XvmLe8+EWmvB/s",
|
||||
"dist/merkleTreeWorker.js": "sha384-CJID2MqR6z42NYw9ZXhHAZ05+7YrQg0YJDwJLB/qhOhIJYt3am2wVZdR/W7njnuZ",
|
||||
"dist/merkleTreeWorker.umd.js": "sha384-6uVyasRLcNVbdsuJSbgzxfSQ/0yRURWhP6oULhW6jffTNJzpMWay6/ie9pQVUj78",
|
||||
"dist/merkleTreeWorker.umd.min.js": "sha384-LUERJw4t5HapI287NVtz3VtnqjXXrC7yBdxMQHpkTX8ZGOjp5fyEqYb1KENzNY9R",
|
||||
"dist/tornado.umd.js": "sha384-IXBljLi80UVwQj0arsdDbOLEQlHfXFAKbAencbqDgqyUaRs7mjsYJDFe+wPgB/ie",
|
||||
"dist/tornado.umd.min.js": "sha384-FwrFV3WOdr2uBRdFyPIKJU+gCybthzvw6+D9GDTRAYflL+Kh8C3hUyk7qsJJGGvq",
|
||||
"dist/tornadoContracts.umd.js": "sha384-wOj+yVI78CBtmwvEn3l/ko3CEbtaqHXbx69pKraBOLOkz98HlJSSTcKs/spf0Ods",
|
||||
"dist/tornadoContracts.umd.min.js": "sha384-LMcw1ogbZefmFD6HUNEOnhIYizZEWtRW2FqUIglSxk5i1qoDq1+iZolSaGheQfx9"
|
||||
}
|
||||
12
dist/idb.d.ts
vendored
12
dist/idb.d.ts
vendored
@@ -1,5 +1,11 @@
|
||||
import { OpenDBCallbacks, IDBPDatabase } from 'idb';
|
||||
import { NetIdType } from './networkConfig';
|
||||
import type * as idb from 'idb';
|
||||
import type { OpenDBCallbacks, IDBPDatabase } from 'idb';
|
||||
import type { NetIdType, TornadoConfig } from './networkConfig';
|
||||
declare global {
|
||||
interface Window {
|
||||
idb: typeof idb;
|
||||
}
|
||||
}
|
||||
export declare const INDEX_DB_ERROR = "A mutation operation was attempted on a database that did not allow mutations.";
|
||||
export interface IDBIndex {
|
||||
name: string;
|
||||
@@ -81,4 +87,4 @@ export declare class IndexedDB {
|
||||
/**
|
||||
* Should check if DB is initialized well
|
||||
*/
|
||||
export declare function getIndexedDB(netId?: NetIdType): Promise<IndexedDB>;
|
||||
export declare function getIndexedDB(netId?: NetIdType, tornadoConfig?: TornadoConfig): Promise<IndexedDB>;
|
||||
|
||||
2100
dist/index.js
vendored
2100
dist/index.js
vendored
File diff suppressed because it is too large
Load Diff
2077
dist/index.mjs
vendored
2077
dist/index.mjs
vendored
File diff suppressed because it is too large
Load Diff
16
dist/ip.d.ts
vendored
16
dist/ip.d.ts
vendored
@@ -1,6 +1,20 @@
|
||||
import { fetchDataOptions } from './providers';
|
||||
export interface IPResult {
|
||||
ip: string;
|
||||
iso?: string;
|
||||
country?: string;
|
||||
country_iso?: string;
|
||||
tor?: boolean;
|
||||
}
|
||||
export declare function fetchIp(ipEcho: string): Promise<IPResult>;
|
||||
export declare function fetchIp(ipEcho: string, fetchOptions?: fetchDataOptions): Promise<IPResult>;
|
||||
export interface IPResultFuck {
|
||||
YourFuckingIPAddress: string;
|
||||
YourFuckingLocation: string;
|
||||
YourFuckingHostname: string;
|
||||
YourFuckingISP: string;
|
||||
YourFuckingTorExit: boolean;
|
||||
YourFuckingCity?: string;
|
||||
YourFuckingCountry: string;
|
||||
YourFuckingCountryCode: string;
|
||||
}
|
||||
export declare function fetchFuckingIp(ipFuck?: string, fetchOptions?: fetchDataOptions): Promise<IPResultFuck>;
|
||||
|
||||
2
dist/merkleTree.d.ts
vendored
2
dist/merkleTree.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from 'fixed-merkle-tree';
|
||||
import type { Tornado } from '@tornado/contracts';
|
||||
import type { Tornado } from 'tornado-contracts';
|
||||
import type { DepositType } from './deposits';
|
||||
import type { DepositsEvents } from './events';
|
||||
import type { NetIdType } from './networkConfig';
|
||||
|
||||
7508
dist/merkleTreeWorker.js
vendored
7508
dist/merkleTreeWorker.js
vendored
File diff suppressed because it is too large
Load Diff
133706
dist/merkleTreeWorker.umd.js
vendored
133706
dist/merkleTreeWorker.umd.js
vendored
File diff suppressed because one or more lines are too long
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
9
dist/merkleTreeWorker.umd.min.js.LICENSE.txt
vendored
9
dist/merkleTreeWorker.umd.min.js.LICENSE.txt
vendored
@@ -15,12 +15,3 @@
|
||||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/**
|
||||
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
||||
*
|
||||
* @version 0.8.0
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2015-2018
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
173
dist/networkConfig.d.ts
vendored
173
dist/networkConfig.d.ts
vendored
@@ -1,4 +1,12 @@
|
||||
import type { DepositType } from './deposits';
|
||||
export declare const MERKLE_TREE_HEIGHT = 20;
|
||||
export declare const EMPTY_ELEMENT = "21663839004416932945382355908790599225266501822907911457504978515578255421292";
|
||||
export declare const MULTICALL_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
||||
export declare const ONEINCH_ORACLE_ADDRESS = "0x00000000000D6FFc74A8feb35aF5827bf57f6786";
|
||||
export declare const TORNADO_PROXY_LIGHT_ADDRESS = "0x0D5550d52428E7e3175bfc9550207e4ad3859b17";
|
||||
export declare const ECHOER_ADDRESS = "0xa75BF2815618872f155b7C4B0C81bF990f5245E4";
|
||||
export declare const TOVARISH_REGISTRY_ADDRESS = "0xc9D5C487c10bC755d34029b1135FA1c190d80f9b";
|
||||
export declare const TOVARISH_AGGREGATOR_ADDRESS = "0x7A51f64A277d3597475Ea28283d0423764613231";
|
||||
/**
|
||||
* Type of default supported networks
|
||||
*/
|
||||
@@ -15,52 +23,76 @@ export declare enum NetId {
|
||||
SEPOLIA = 11155111
|
||||
}
|
||||
export type NetIdType = NetId | number;
|
||||
export interface RpcUrl {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
export interface RpcUrls {
|
||||
[key: string]: RpcUrl;
|
||||
}
|
||||
export interface SubgraphUrl {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
export interface SubgraphUrls {
|
||||
[key: string]: SubgraphUrl;
|
||||
}
|
||||
export interface TornadoInstance {
|
||||
instanceAddress: {
|
||||
[key: string]: string;
|
||||
};
|
||||
export interface TornadoInstances {
|
||||
instanceAddress: Record<string, string>;
|
||||
instanceApproval?: boolean;
|
||||
optionalInstances?: string[];
|
||||
isOptional?: boolean;
|
||||
isDisabled?: boolean;
|
||||
tokenAddress?: string;
|
||||
tokenGasLimit?: number;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
gasLimit?: number;
|
||||
}
|
||||
export interface TokenInstances {
|
||||
[key: string]: TornadoInstance;
|
||||
export interface TornadoSingleInstance {
|
||||
netId: NetId;
|
||||
instanceAddress: string;
|
||||
instanceApproval?: boolean;
|
||||
isOptional?: boolean;
|
||||
isDisabled?: boolean;
|
||||
tokenAddress?: string;
|
||||
tokenGasLimit?: number;
|
||||
currency: string;
|
||||
amount: string;
|
||||
decimals: number;
|
||||
gasLimit?: number;
|
||||
}
|
||||
export interface Config {
|
||||
rpcCallRetryAttempt?: number;
|
||||
gasPrices: {
|
||||
instant: number;
|
||||
fast?: number;
|
||||
standard?: number;
|
||||
low?: number;
|
||||
maxPriorityFeePerGas?: number;
|
||||
};
|
||||
nativeCurrency: string;
|
||||
currencyName: string;
|
||||
explorerUrl: string;
|
||||
merkleTreeHeight: number;
|
||||
emptyElement: string;
|
||||
export type TokenInstances = Record<string, TornadoInstances>;
|
||||
export type SubdomainMap = Record<NetIdType, string>;
|
||||
export interface ConfigParams {
|
||||
netId: NetIdType;
|
||||
networkName: string;
|
||||
currencyName: string;
|
||||
nativeCurrency?: string;
|
||||
explorerUrl: string;
|
||||
homepageUrl: string;
|
||||
blockTime: number;
|
||||
deployedBlock: number;
|
||||
rpcUrls: RpcUrls;
|
||||
merkleTreeHeight?: number;
|
||||
emptyElement?: string;
|
||||
stablecoin: string;
|
||||
multicallContract?: string;
|
||||
routerContract?: string;
|
||||
echoContract?: string;
|
||||
offchainOracleContract?: string;
|
||||
tornContract?: string;
|
||||
governanceContract?: string;
|
||||
stakingRewardsContract?: string;
|
||||
registryContract?: string;
|
||||
tovarishRegistryContract?: string;
|
||||
aggregatorContract?: string;
|
||||
reverseRecordsContract?: string;
|
||||
ovmGasPriceOracleContract?: string;
|
||||
relayerEnsSubdomain: string;
|
||||
tornadoSubgraph?: string;
|
||||
registrySubgraph?: string;
|
||||
governanceSubgraph?: string;
|
||||
subgraphs?: string[];
|
||||
rpcUrls: string[];
|
||||
tokens: TokenInstances;
|
||||
}
|
||||
export declare class Config {
|
||||
netId: NetIdType;
|
||||
networkName: string;
|
||||
currencyName: string;
|
||||
nativeCurrency: string;
|
||||
explorerUrl: string;
|
||||
homepageUrl: string;
|
||||
blockTime: number;
|
||||
deployedBlock: number;
|
||||
merkleTreeHeight?: number;
|
||||
emptyElement?: string;
|
||||
stablecoin: string;
|
||||
multicallContract: string;
|
||||
routerContract: string;
|
||||
@@ -70,59 +102,36 @@ export interface Config {
|
||||
governanceContract?: string;
|
||||
stakingRewardsContract?: string;
|
||||
registryContract?: string;
|
||||
tovarishRegistryContract?: string;
|
||||
aggregatorContract?: string;
|
||||
reverseRecordsContract?: string;
|
||||
ovmGasPriceOracleContract?: string;
|
||||
tornadoSubgraph: string;
|
||||
relayerEnsSubdomain: string;
|
||||
tornadoSubgraph?: string;
|
||||
registrySubgraph?: string;
|
||||
governanceSubgraph?: string;
|
||||
subgraphs: SubgraphUrls;
|
||||
subgraphs?: string[];
|
||||
rpcUrls: string[];
|
||||
tokens: TokenInstances;
|
||||
optionalTokens?: string[];
|
||||
disabledTokens?: string[];
|
||||
relayerEnsSubdomain: string;
|
||||
pollInterval: number;
|
||||
constants: {
|
||||
GOVERNANCE_BLOCK?: number;
|
||||
NOTE_ACCOUNT_BLOCK?: number;
|
||||
ENCRYPTED_NOTES_BLOCK?: number;
|
||||
REGISTRY_BLOCK?: number;
|
||||
MINING_BLOCK_TIME?: number;
|
||||
};
|
||||
constructor(configParams: ConfigParams);
|
||||
toJSON(): ConfigParams;
|
||||
get allTokens(): string[];
|
||||
get allSymbols(): string[];
|
||||
getInstance(currency: string, amount: string): TornadoSingleInstance;
|
||||
getInstanceByAddress(instanceAddress: string): TornadoSingleInstance;
|
||||
get depositTypes(): Record<string, DepositType>;
|
||||
}
|
||||
export interface networkConfig {
|
||||
[key: NetIdType]: Config;
|
||||
export interface TornadoConfigParams {
|
||||
configs?: Record<NetIdType, ConfigParams>;
|
||||
governanceNetwork?: NetIdType;
|
||||
relayerNetwork?: NetIdType;
|
||||
}
|
||||
export interface SubdomainMap {
|
||||
[key: NetIdType]: string;
|
||||
export declare class TornadoConfig {
|
||||
configs: Record<NetIdType, Config>;
|
||||
governanceNetwork: NetIdType;
|
||||
relayerNetwork: NetIdType;
|
||||
constructor(configParams?: TornadoConfigParams);
|
||||
get chains(): NetIdType[];
|
||||
getConfig(netId: NetIdType): Config;
|
||||
}
|
||||
export declare const defaultConfig: networkConfig;
|
||||
export declare const enabledChains: NetIdType[];
|
||||
/**
|
||||
* Custom config object to extend default config
|
||||
*
|
||||
* Inspired by getUrlFunc from ethers.js
|
||||
* https://github.com/ethers-io/ethers.js/blob/v6/src.ts/utils/fetch.ts#L59
|
||||
*/
|
||||
export declare let customConfig: networkConfig;
|
||||
/**
|
||||
* Add or override existing network config object
|
||||
*
|
||||
* Could be also called on the UI hook so that the UI could allow people to use custom privacy pools
|
||||
*/
|
||||
export declare function addNetwork(newConfig: networkConfig): void;
|
||||
export declare function getNetworkConfig(): networkConfig;
|
||||
export declare function getConfig(netId: NetIdType): Config;
|
||||
export declare function getActiveTokens(config: Config): string[];
|
||||
export declare function getActiveTokenInstances(config: Config): TokenInstances;
|
||||
export declare function getInstanceByAddress(config: Config, address: string): {
|
||||
amount: string;
|
||||
currency: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
tokenAddress: string | undefined;
|
||||
} | undefined;
|
||||
export declare function getRelayerEnsSubdomains(): SubdomainMap;
|
||||
export declare function getMultiInstances(netId: NetIdType, config: Config): {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
export declare const defaultConfig: Record<NetIdType, ConfigParams>;
|
||||
|
||||
6
dist/permit.d.ts
vendored
6
dist/permit.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { ERC20Permit, ERC20Mock, TORN } from '@tornado/contracts';
|
||||
import { ERC20Permit, ERC20Mock, TORN } from 'tornado-contracts';
|
||||
import { Signature, Signer, TypedDataField } from 'ethers';
|
||||
export interface PermitValue {
|
||||
spender: string;
|
||||
@@ -18,9 +18,7 @@ export declare const permit2Address = "0x000000000022D473030F116dDEE9F6B43aC78BA
|
||||
*/
|
||||
export interface Witness {
|
||||
witnessTypeName: string;
|
||||
witnessType: {
|
||||
[key: string]: TypedDataField[];
|
||||
};
|
||||
witnessType: Record<string, TypedDataField[]>;
|
||||
witness: any;
|
||||
}
|
||||
export declare function getPermitSignature({ Token, signer, spender, value, nonce, deadline, }: PermitValue & {
|
||||
|
||||
56
dist/providers.d.ts
vendored
56
dist/providers.d.ts
vendored
@@ -1,7 +1,6 @@
|
||||
import type { EventEmitter } from 'stream';
|
||||
import type { RequestOptions } from 'http';
|
||||
import { JsonRpcApiProvider, JsonRpcProvider, Wallet, FetchGetUrlFunc, Provider, SigningKey, TransactionRequest, JsonRpcSigner, BrowserProvider, Networkish, Eip1193Provider, VoidSigner, FetchCancelSignal } from 'ethers';
|
||||
import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch';
|
||||
import { JsonRpcApiProvider, JsonRpcProvider, Wallet, FetchGetUrlFunc, Provider, SigningKey, TransactionRequest, JsonRpcSigner, BrowserProvider, Networkish, Eip1193Provider, VoidSigner, FetchCancelSignal, TransactionLike } from 'ethers';
|
||||
import type { Dispatcher, RequestInit } from 'undici-types';
|
||||
import type { Config, NetIdType } from './networkConfig';
|
||||
declare global {
|
||||
interface Window {
|
||||
@@ -9,35 +8,54 @@ declare global {
|
||||
}
|
||||
}
|
||||
export declare const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0";
|
||||
export type nodeFetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>;
|
||||
export type fetchDataOptions = RequestInit & {
|
||||
export type DispatcherFunc = (retry?: number) => Dispatcher;
|
||||
export interface fetchDataOptions extends Omit<RequestInit, 'headers'> {
|
||||
/**
|
||||
* Overriding RequestInit params
|
||||
*/
|
||||
headers?: HeadersInit | any;
|
||||
/**
|
||||
* Expanding RequestInit params
|
||||
*/
|
||||
maxRetry?: number;
|
||||
retryOn?: number;
|
||||
userAgent?: string;
|
||||
timeout?: number;
|
||||
proxy?: string;
|
||||
torPort?: number;
|
||||
debug?: Function;
|
||||
returnResponse?: boolean;
|
||||
cancelSignal?: FetchCancelSignal;
|
||||
};
|
||||
export type NodeAgent = RequestOptions['agent'] | ((parsedUrl: URL) => RequestOptions['agent']);
|
||||
export declare function getHttpAgent({ fetchUrl, proxyUrl, torPort, retry, }: {
|
||||
fetchUrl: string;
|
||||
proxyUrl?: string;
|
||||
torPort?: number;
|
||||
retry: number;
|
||||
}): NodeAgent | undefined;
|
||||
export declare function fetchData(url: string, options?: fetchDataOptions): Promise<any>;
|
||||
dispatcherFunc?: DispatcherFunc;
|
||||
}
|
||||
export declare function fetchData<T>(url: string, options?: fetchDataOptions): Promise<T>;
|
||||
export declare const fetchGetUrlFunc: (options?: fetchDataOptions) => FetchGetUrlFunc;
|
||||
export type getProviderOptions = fetchDataOptions & {
|
||||
netId?: NetIdType;
|
||||
pollingInterval?: number;
|
||||
};
|
||||
export declare const FeeDataNetworkPluginName: string;
|
||||
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 declare const populateTransaction: (signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner, tx: TransactionRequest) => Promise<{
|
||||
type?: null | number | undefined;
|
||||
to?: string | import("ethers").Addressable | null | undefined;
|
||||
from?: string | import("ethers").Addressable | null | undefined;
|
||||
nonce?: null | number | undefined;
|
||||
gasLimit?: string | number | bigint | null | undefined;
|
||||
gasPrice?: string | number | bigint | null | undefined;
|
||||
maxPriorityFeePerGas?: string | number | bigint | null | undefined;
|
||||
maxFeePerGas?: string | number | bigint | null | undefined;
|
||||
data?: null | string | undefined;
|
||||
value?: string | number | bigint | null | undefined;
|
||||
chainId?: string | number | bigint | null | undefined;
|
||||
accessList?: import("ethers").AccessList | [string, string[]][] | Record<string, string[]> | null | undefined;
|
||||
customData?: any;
|
||||
blockTag?: string | number | bigint | undefined;
|
||||
enableCcipRead?: boolean | undefined;
|
||||
blobVersionedHashes?: (null | Array<string>) | undefined;
|
||||
maxFeePerBlobGas?: string | number | bigint | null | undefined;
|
||||
blobs?: (null | Array<import("ethers").BlobLike>) | undefined;
|
||||
kzg?: (null | import("ethers").KzgLibrary) | undefined;
|
||||
}>;
|
||||
export interface TornadoWalletOptions {
|
||||
gasPriceBump?: number;
|
||||
gasLimitBump?: number;
|
||||
@@ -53,7 +71,7 @@ export declare class TornadoWallet extends Wallet {
|
||||
bumpNonce: boolean;
|
||||
constructor(key: string | SigningKey, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
static fromMnemonic(mneomnic: string, provider: Provider, index?: number, options?: TornadoWalletOptions): TornadoWallet;
|
||||
populateTransaction(tx: TransactionRequest): Promise<import("ethers").TransactionLike<string>>;
|
||||
populateTransaction(tx: TransactionRequest): Promise<TransactionLike<string>>;
|
||||
}
|
||||
export declare class TornadoVoidSigner extends VoidSigner {
|
||||
nonce?: number;
|
||||
@@ -62,7 +80,7 @@ export declare class TornadoVoidSigner extends VoidSigner {
|
||||
gasFailover: boolean;
|
||||
bumpNonce: boolean;
|
||||
constructor(address: string, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
populateTransaction(tx: TransactionRequest): Promise<import("ethers").TransactionLike<string>>;
|
||||
populateTransaction(tx: TransactionRequest): Promise<TransactionLike<string>>;
|
||||
}
|
||||
export declare class TornadoRpcSigner extends JsonRpcSigner {
|
||||
nonce?: number;
|
||||
|
||||
52
dist/relayerClient.d.ts
vendored
52
dist/relayerClient.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { NetIdType, Config } from './networkConfig';
|
||||
import type { NetIdType, TornadoConfig } from './networkConfig';
|
||||
import { fetchDataOptions } from './providers';
|
||||
import type { snarkProofs } from './websnark';
|
||||
import type { CachedRelayerInfo } from './events';
|
||||
@@ -20,9 +20,7 @@ export interface RelayerInfo extends RelayerParams {
|
||||
instances: string[];
|
||||
stakeBalance?: string;
|
||||
gasPrice?: number;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
ethPrices?: Record<string, string>;
|
||||
currentQueue: number;
|
||||
tornadoServiceFee: number;
|
||||
}
|
||||
@@ -35,24 +33,18 @@ export interface RelayerError {
|
||||
export interface RelayerStatus {
|
||||
url: string;
|
||||
rewardAccount: string;
|
||||
instances: {
|
||||
[key in string]: {
|
||||
instanceAddress: {
|
||||
[key in string]: string;
|
||||
};
|
||||
tokenAddress?: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
};
|
||||
};
|
||||
instances: Record<string, {
|
||||
instanceAddress: Record<string, string>;
|
||||
tokenAddress?: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
}>;
|
||||
gasPrices?: {
|
||||
fast: number;
|
||||
additionalProperties?: number;
|
||||
};
|
||||
netId: NetIdType;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
ethPrices?: Record<string, string>;
|
||||
tornadoServiceFee: number;
|
||||
latestBlock?: number;
|
||||
version: string;
|
||||
@@ -111,34 +103,28 @@ 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 interface RelayerInstanceList {
|
||||
[key: string]: {
|
||||
instanceAddress: {
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
export type RelayerInstanceList = Record<string, {
|
||||
instanceAddress: Record<string, string>;
|
||||
}>;
|
||||
export declare function getSupportedInstances(instanceList: RelayerInstanceList): string[];
|
||||
export declare function pickWeightedRandomRelayer(relayers: RelayerInfo[]): RelayerInfo;
|
||||
export interface RelayerClientConstructor {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
tornadoConfig: TornadoConfig;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
}
|
||||
export declare class RelayerClient {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
tornadoConfig: TornadoConfig;
|
||||
selectedRelayer?: RelayerInfo;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
tovarish: boolean;
|
||||
constructor({ netId, config, fetchDataOptions }: RelayerClientConstructor);
|
||||
askRelayerStatus({ hostname, url, relayerAddress, }: {
|
||||
constructor({ tornadoConfig, fetchDataOptions }: RelayerClientConstructor);
|
||||
askRelayerStatus({ netId, hostname, url, }: {
|
||||
netId: NetIdType;
|
||||
hostname?: string;
|
||||
url?: string;
|
||||
relayerAddress?: string;
|
||||
}): Promise<RelayerStatus>;
|
||||
filterRelayer(relayer: CachedRelayerInfo): Promise<RelayerInfo | RelayerError | undefined>;
|
||||
getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
filterRelayer(netId: NetIdType, relayer: CachedRelayerInfo): Promise<RelayerInfo | RelayerError | undefined>;
|
||||
getValidRelayers(netId: NetIdType, relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: RelayerInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}>;
|
||||
|
||||
26
dist/schemas/status.d.ts
vendored
26
dist/schemas/status.d.ts
vendored
@@ -1,18 +1,16 @@
|
||||
import { Config, NetIdType } from '../networkConfig';
|
||||
import { Config } from '../networkConfig';
|
||||
import { addressSchemaType, bnSchemaType } from '.';
|
||||
export interface statusInstanceType {
|
||||
type: string;
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof addressSchemaType;
|
||||
};
|
||||
properties: Record<string, typeof addressSchemaType>;
|
||||
required: string[];
|
||||
};
|
||||
tokenAddress?: typeof addressSchemaType;
|
||||
symbol?: {
|
||||
enum: string[];
|
||||
type: string;
|
||||
};
|
||||
decimals: {
|
||||
enum: number[];
|
||||
@@ -22,16 +20,12 @@ export interface statusInstanceType {
|
||||
}
|
||||
export interface statusInstancesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: statusInstanceType;
|
||||
};
|
||||
properties: Record<string, statusInstanceType>;
|
||||
required: string[];
|
||||
}
|
||||
export interface statusEthPricesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof bnSchemaType;
|
||||
};
|
||||
properties: Record<string, typeof bnSchemaType>;
|
||||
required?: string[];
|
||||
}
|
||||
export interface statusSchema {
|
||||
@@ -41,11 +35,9 @@ export interface statusSchema {
|
||||
instances?: statusInstancesType;
|
||||
gasPrices: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
properties: Record<string, {
|
||||
type: string;
|
||||
}>;
|
||||
required: string[];
|
||||
};
|
||||
netId: {
|
||||
@@ -103,4 +95,4 @@ export interface statusSchema {
|
||||
};
|
||||
required: string[];
|
||||
}
|
||||
export declare function getStatusSchema(netId: NetIdType, config: Config, tovarish: boolean): statusSchema;
|
||||
export declare function getStatusSchema(config: Config, tovarish: boolean): statusSchema;
|
||||
|
||||
334812
dist/tornado.umd.js
vendored
334812
dist/tornado.umd.js
vendored
File diff suppressed because one or more lines are too long
12
dist/tornado.umd.min.js
vendored
12
dist/tornado.umd.min.js
vendored
File diff suppressed because one or more lines are too long
9
dist/tornado.umd.min.js.LICENSE.txt
vendored
9
dist/tornado.umd.min.js.LICENSE.txt
vendored
@@ -23,12 +23,3 @@
|
||||
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
|
||||
/**
|
||||
* [js-sha3]{@link https://github.com/emn178/js-sha3}
|
||||
*
|
||||
* @version 0.8.0
|
||||
* @author Chen, Yi-Cyuan [emn178@gmail.com]
|
||||
* @copyright Chen, Yi-Cyuan 2015-2018
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
14870
dist/tornadoContracts.umd.js
vendored
14870
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
8
dist/tovarishClient.d.ts
vendored
8
dist/tovarishClient.d.ts
vendored
@@ -1,5 +1,6 @@
|
||||
import { RelayerClient, RelayerClientConstructor, RelayerError, RelayerInfo, RelayerStatus } from './relayerClient';
|
||||
import { CachedRelayerInfo, MinimalEvents } from './events';
|
||||
import { NetIdType } from './networkConfig';
|
||||
export declare const MAX_TOVARISH_EVENTS = 5000;
|
||||
export interface EventsStatus {
|
||||
events: number;
|
||||
@@ -45,7 +46,8 @@ export interface BaseTovarishEvents<T> {
|
||||
export declare class TovarishClient extends RelayerClient {
|
||||
selectedRelayer?: TovarishInfo;
|
||||
constructor(clientConstructor: RelayerClientConstructor);
|
||||
askRelayerStatus({ hostname, url, relayerAddress, }: {
|
||||
askRelayerStatus({ netId, hostname, url, }: {
|
||||
netId: NetIdType;
|
||||
hostname?: string;
|
||||
url?: string;
|
||||
relayerAddress?: string;
|
||||
@@ -58,8 +60,8 @@ export declare class TovarishClient extends RelayerClient {
|
||||
url?: string;
|
||||
relayerAddress?: string;
|
||||
}): Promise<TovarishStatus[]>;
|
||||
filterRelayer(relayer: CachedRelayerInfo): Promise<TovarishInfo | RelayerError | undefined>;
|
||||
getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
filterRelayer(netId: NetIdType, relayer: CachedRelayerInfo): Promise<TovarishInfo | RelayerError | undefined>;
|
||||
getValidRelayers(netId: NetIdType, relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: TovarishInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}>;
|
||||
|
||||
12
dist/utils.d.ts
vendored
12
dist/utils.d.ts
vendored
@@ -8,22 +8,22 @@ export declare const chunk: <T>(arr: T[], size: number) => T[][];
|
||||
export declare function sleep(ms: number): Promise<unknown>;
|
||||
export declare function validateUrl(url: string, protocols?: string[]): boolean;
|
||||
export declare function concatBytes(...arrays: Uint8Array[]): Uint8Array;
|
||||
export declare function bufferToBytes(b: Buffer): Uint8Array;
|
||||
export declare function bufferToBytes(b: Buffer): Uint8Array<ArrayBufferLike>;
|
||||
export declare function bytesToBase64(bytes: Uint8Array): string;
|
||||
export declare function base64ToBytes(base64: string): Uint8Array;
|
||||
export declare function base64ToBytes(base64: string): Uint8Array<ArrayBuffer>;
|
||||
export declare function bytesToHex(bytes: Uint8Array): string;
|
||||
export declare function hexToBytes(hexString: string): Uint8Array;
|
||||
export declare function hexToBytes(hexString: string): Uint8Array<ArrayBuffer>;
|
||||
export declare function bytesToBN(bytes: Uint8Array): bigint;
|
||||
export declare function bnToBytes(bigint: bigint | string): Uint8Array;
|
||||
export declare function bnToBytes(bigint: bigint | string): Uint8Array<ArrayBuffer>;
|
||||
export declare function leBuff2Int(bytes: Uint8Array): BN;
|
||||
export declare function leInt2Buff(bigint: bnInput | bigint): Uint8Array;
|
||||
export declare function leInt2Buff(bigint: bnInput | bigint): Uint8Array<ArrayBuffer>;
|
||||
export declare function toFixedHex(numberish: BigNumberish, length?: number): string;
|
||||
export declare function toFixedLength(string: string, length?: number): string;
|
||||
export declare function rBigInt(nbytes?: number): bigint;
|
||||
export declare function rHex(nbytes?: number): string;
|
||||
export declare function bigIntReplacer(key: any, value: any): any;
|
||||
export declare function substring(str: string, length?: number): string;
|
||||
export declare function digest(bytes: Uint8Array, algo?: string): Promise<Uint8Array>;
|
||||
export declare function digest(bytes: Uint8Array, algo?: string): Promise<Uint8Array<ArrayBuffer>>;
|
||||
export declare function numberFormatter(num: string | number | bigint, digits?: number): string;
|
||||
export declare function isHex(value: string): boolean;
|
||||
export declare function toContentHash(ipfsUrl: string): any;
|
||||
|
||||
8
dist/zip.d.ts
vendored
8
dist/zip.d.ts
vendored
@@ -1,9 +1,13 @@
|
||||
import { AsyncZippable, Unzipped, ZipAttributes } from 'fflate';
|
||||
import { AsyncZippable, Unzipped, ZipAttributes, AsyncZlibOptions, AsyncUnzlibOptions } from 'fflate';
|
||||
import { fetchDataOptions } from './providers';
|
||||
export declare function zipAsync(file: AsyncZippable, options?: ZipAttributes): Promise<Uint8Array>;
|
||||
export declare function unzipAsync(data: Uint8Array): Promise<Unzipped>;
|
||||
export declare function downloadZip<T>({ staticUrl, zipName, zipDigest, parseJson, }: {
|
||||
export declare function zlibAsync(data: Uint8Array, options?: AsyncZlibOptions): Promise<Uint8Array>;
|
||||
export declare function unzlibAsync(data: Uint8Array, options?: AsyncUnzlibOptions): Promise<Uint8Array>;
|
||||
export declare function downloadZip<T>({ staticUrl, zipName, zipDigest, parseJson, fetchOptions, }: {
|
||||
staticUrl?: string;
|
||||
zipName: string;
|
||||
zipDigest?: string;
|
||||
parseJson?: boolean;
|
||||
fetchOptions?: fetchDataOptions;
|
||||
}): Promise<T>;
|
||||
|
||||
55
eslint.config.mjs
Normal file
55
eslint.config.mjs
Normal file
@@ -0,0 +1,55 @@
|
||||
import eslint from '@eslint/js';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import importPlugin from 'eslint-plugin-import';
|
||||
import prettierRecommendedConfig from 'eslint-plugin-prettier/recommended';
|
||||
|
||||
export default tseslint.config(
|
||||
{
|
||||
files: ['**/*.js', '**/*.mjs', '**/*.ts', '**/*.tsx'],
|
||||
extends: [eslint.configs.recommended, prettierRecommendedConfig],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'prettier/prettier': [
|
||||
'error',
|
||||
{
|
||||
tabWidth: 4,
|
||||
printWidth: 120,
|
||||
singleQuote: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.ts', '**/*.tsx'],
|
||||
extends: [
|
||||
...tseslint.configs.recommended,
|
||||
...tseslint.configs.stylistic,
|
||||
importPlugin.flatConfigs.recommended,
|
||||
importPlugin.flatConfigs.typescript,
|
||||
],
|
||||
rules: {
|
||||
'import/order': ['error'],
|
||||
'@typescript-eslint/no-unused-vars': ['warn'],
|
||||
'@typescript-eslint/no-unused-expressions': ['off'],
|
||||
'@typescript-eslint/no-empty-function': ['off'],
|
||||
},
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
typescript: {
|
||||
alwaysTryTypes: true,
|
||||
project: './tsconfig.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
103
package.json
103
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@tornado/core",
|
||||
"version": "1.0.19",
|
||||
"name": "tornado-scripts",
|
||||
"version": "1.0.23",
|
||||
"description": "An SDK for building applications on top of Privacy Pools",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
@@ -10,98 +10,99 @@
|
||||
"scripts": {
|
||||
"typechain": "typechain --target ethers-v6 --out-dir src/typechain src/abi/*.json",
|
||||
"types": "tsc --declaration --emitDeclarationOnly -p tsconfig.build.json",
|
||||
"lint": "eslint src/**/*.ts test/**/*.ts --ext .ts --ignore-pattern src/typechain",
|
||||
"lint": "eslint src/**/*.ts test/**/*.ts --ignore-pattern src/typechain",
|
||||
"build:node": "rollup -c",
|
||||
"build:web": "webpack",
|
||||
"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'"
|
||||
"docker:build": "docker build -t tornado-scripts .",
|
||||
"docker:hash": "docker container run --rm -it --entrypoint cat tornado-scripts /app/dist/hashes.json",
|
||||
"test": "nyc mocha --require ts-node/register --require source-map-support/register --timeout 300000 --recursive test/**/*.ts"
|
||||
},
|
||||
"author": "",
|
||||
"author": "Tornado Contrib",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist",
|
||||
"scripts",
|
||||
"src",
|
||||
".eslintrc.js",
|
||||
"test",
|
||||
".gitattributes",
|
||||
".gitignore",
|
||||
".npmrc",
|
||||
"Dockerfile",
|
||||
"eslint.config.mjs",
|
||||
"hardhat.config.ts",
|
||||
"LICENSE",
|
||||
"logo.png",
|
||||
"logo2.png",
|
||||
"rollup.config.mjs",
|
||||
"tsconfig.build.json",
|
||||
"tsconfig.json",
|
||||
"webpack.config.js",
|
||||
"yarn.lock"
|
||||
],
|
||||
"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#093ae2210e1f1b016b756b4db200c4a1b3308408",
|
||||
"@metamask/eth-sig-util": "^8.2.0",
|
||||
"ajv": "^8.17.1",
|
||||
"bn.js": "^5.2.1",
|
||||
"circomlibjs": "0.1.7",
|
||||
"cross-fetch": "^4.0.0",
|
||||
"ethers": "^6.13.4",
|
||||
"ffjavascript": "0.2.48",
|
||||
"circomlibjs": "git+https://github.com/tornadocontrib/circomlibjs.git#2aef7aade8e2b8d103250e4b24c7f1526cf1dd8d",
|
||||
"ethers": "^6.13.5",
|
||||
"ffjavascript": "git+https://github.com/tornadocontrib/ffjavascript.git#fc766f09818d46967d1329c0fc8e361d8b349109",
|
||||
"fflate": "^0.8.2",
|
||||
"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"
|
||||
"tornado-contracts": "git+https://github.com/tornadocontrib/tornado-contracts.git#a1c8fbd2919996a642a7de1abec86548ff64449b",
|
||||
"websnark": "git+https://github.com/tornadocontrib/websnark.git#e5a79cca905d1ffb61a69739492be58d438c9f17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.7",
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.8",
|
||||
"@nomicfoundation/hardhat-ethers": "^3.0.8",
|
||||
"@nomicfoundation/hardhat-ignition": "^0.15.5",
|
||||
"@nomicfoundation/hardhat-ignition-ethers": "^0.15.5",
|
||||
"@nomicfoundation/hardhat-network-helpers": "^1.0.11",
|
||||
"@nomicfoundation/hardhat-ignition": "^0.15.11",
|
||||
"@nomicfoundation/hardhat-ignition-ethers": "^0.15.11",
|
||||
"@nomicfoundation/hardhat-network-helpers": "^1.0.12",
|
||||
"@nomicfoundation/hardhat-toolbox": "^5.0.0",
|
||||
"@nomicfoundation/hardhat-verify": "^2.0.10",
|
||||
"@nomicfoundation/ignition-core": "^0.15.5",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@nomicfoundation/hardhat-verify": "^2.0.13",
|
||||
"@rollup/plugin-commonjs": "^28.0.3",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@typechain/ethers-v6": "^0.5.1",
|
||||
"@typechain/hardhat": "^9.1.0",
|
||||
"@types/bn.js": "^5.1.6",
|
||||
"@types/chai": "^4.2.0",
|
||||
"@types/chai": "^5.2.1",
|
||||
"@types/circomlibjs": "^0.1.6",
|
||||
"@types/mocha": "^10.0.9",
|
||||
"@types/node": "^22.8.0",
|
||||
"@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",
|
||||
"eslint-import-resolver-typescript": "^3.6.3",
|
||||
"@types/mocha": "^10.0.10",
|
||||
"@types/node": "^22.14.1",
|
||||
"chai": "^4.5.0",
|
||||
"esbuild-loader": "^4.3.0",
|
||||
"eslint": "^9.24.0",
|
||||
"eslint-config-prettier": "^10.1.2",
|
||||
"eslint-import-resolver-typescript": "^4.3.2",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"fetch-mock": "^12.0.2",
|
||||
"hardhat": "^2.22.10",
|
||||
"hardhat-gas-reporter": "^2.2.1",
|
||||
"mocha": "^10.7.3",
|
||||
"node-polyfill-webpack-plugin": "^4.0.0",
|
||||
"eslint-plugin-prettier": "^5.2.6",
|
||||
"fetch-mock": "^12.5.2",
|
||||
"hardhat": "^2.23.0",
|
||||
"hardhat-gas-reporter": "^2.2.3",
|
||||
"idb": "^8.0.2",
|
||||
"mocha": "^11.1.0",
|
||||
"node-polyfill-webpack-plugin": "^4.1.0",
|
||||
"nyc": "^17.1.0",
|
||||
"prettier": "^3.3.3",
|
||||
"rollup": "^4.24.0",
|
||||
"rollup-plugin-esbuild": "^6.1.1",
|
||||
"solidity-coverage": "^0.8.13",
|
||||
"prettier": "^3.5.3",
|
||||
"rollup": "^4.40.0",
|
||||
"rollup-plugin-esbuild": "^6.2.1",
|
||||
"solidity-coverage": "^0.8.15",
|
||||
"ts-node": "^10.9.2",
|
||||
"tsc": "^2.0.4",
|
||||
"typechain": "^8.3.2",
|
||||
"typescript": "^5.6.3",
|
||||
"webpack": "^5.95.0",
|
||||
"webpack-cli": "^5.1.4"
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.30.1",
|
||||
"webpack": "^5.99.5",
|
||||
"webpack-cli": "^6.0.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"strip-ansi": "6.0.1",
|
||||
"@adraffy/ens-normalize": "1.10.1",
|
||||
"@noble/curves": "1.2.0",
|
||||
"@noble/hashes": "1.3.2",
|
||||
"big-integer": "1.6.52",
|
||||
"ffjavascript": "0.2.48"
|
||||
"ffjavascript": "git+https://github.com/tornadocontrib/ffjavascript.git#fc766f09818d46967d1329c0fc8e361d8b349109"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ export async function getSubInfo(
|
||||
tag: string;
|
||||
topics: TopicFilter;
|
||||
}> {
|
||||
let topics: Array<null | string | Array<string>>;
|
||||
let topics: (null | string | string[])[];
|
||||
let fragment: null | EventFragment = null;
|
||||
|
||||
// Convert named events to topicHash and get the fragment for
|
||||
@@ -242,7 +242,6 @@ export class BatchBlockService {
|
||||
let retries = 0;
|
||||
let err;
|
||||
|
||||
// eslint-disable-next-line no-unmodified-loop-condition
|
||||
while ((!this.shouldRetry && retries === 0) || (this.shouldRetry && retries < this.retryMax)) {
|
||||
try {
|
||||
return await Promise.all(blocks.map((b) => this.getBlock(b)));
|
||||
@@ -346,7 +345,6 @@ export class BatchTransactionService {
|
||||
let retries = 0;
|
||||
let err;
|
||||
|
||||
// eslint-disable-next-line no-unmodified-loop-condition
|
||||
while ((!this.shouldRetry && retries === 0) || (this.shouldRetry && retries < this.retryMax)) {
|
||||
try {
|
||||
if (!receipt) {
|
||||
@@ -491,7 +489,6 @@ export class BatchEventsService {
|
||||
let err;
|
||||
let retries = 0;
|
||||
|
||||
// eslint-disable-next-line no-unmodified-loop-condition
|
||||
while ((!this.shouldRetry && retries === 0) || (this.shouldRetry && retries < this.retryMax)) {
|
||||
try {
|
||||
if (this.address) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from '@tornado/contracts';
|
||||
export * from 'tornado-contracts';
|
||||
export {
|
||||
Multicall,
|
||||
Multicall__factory,
|
||||
|
||||
12
src/ens.ts
12
src/ens.ts
@@ -40,13 +40,14 @@ export function makeLabelNodeAndParent(name: string) {
|
||||
}
|
||||
|
||||
// https://github.com/ensdomains/ensjs/blob/main/packages/ensjs/src/contracts/consts.ts
|
||||
export const EnsContracts: {
|
||||
[key: NetIdType]: {
|
||||
export const EnsContracts: Record<
|
||||
NetIdType,
|
||||
{
|
||||
ensRegistry: string;
|
||||
ensPublicResolver: string;
|
||||
ensNameWrapper: string;
|
||||
};
|
||||
} = {
|
||||
}
|
||||
> = {
|
||||
[NetId.MAINNET]: {
|
||||
ensRegistry: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
|
||||
ensPublicResolver: '0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63',
|
||||
@@ -75,7 +76,8 @@ export class ENSUtils {
|
||||
async getContracts() {
|
||||
const { chainId } = await this.provider.getNetwork();
|
||||
|
||||
const { ensRegistry, ensPublicResolver, ensNameWrapper } = EnsContracts[Number(chainId)];
|
||||
const { ensRegistry, ensPublicResolver, ensNameWrapper } =
|
||||
EnsContracts[Number(chainId)] || EnsContracts[NetId.MAINNET];
|
||||
|
||||
this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider);
|
||||
this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider);
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
EventLog,
|
||||
TransactionResponse,
|
||||
getAddress,
|
||||
namehash,
|
||||
formatEther,
|
||||
AbiCoder,
|
||||
dataLength,
|
||||
@@ -18,9 +17,9 @@ import {
|
||||
Governance,
|
||||
RelayerRegistry,
|
||||
Echoer,
|
||||
Aggregator,
|
||||
Tornado__factory,
|
||||
} from '@tornado/contracts';
|
||||
TovarishAggregator,
|
||||
} from 'tornado-contracts';
|
||||
|
||||
import type { MerkleTree } from 'fixed-merkle-tree';
|
||||
import {
|
||||
@@ -31,8 +30,8 @@ import {
|
||||
BatchBlockOnProgress,
|
||||
} from '../batch';
|
||||
|
||||
import { fetchData, fetchDataOptions } from '../providers';
|
||||
import { enabledChains, type NetIdType, type SubdomainMap } from '../networkConfig';
|
||||
import { fetchDataOptions } from '../providers';
|
||||
import { TornadoConfig, type NetIdType, type SubdomainMap } from '../networkConfig';
|
||||
import { RelayerParams, MIN_STAKE_BALANCE } from '../relayerClient';
|
||||
import type { TovarishClient } from '../tovarishClient';
|
||||
|
||||
@@ -131,7 +130,6 @@ export class BaseEventsService<EventType extends MinimalEvents> {
|
||||
/* eslint-enable @typescript-eslint/no-unused-vars */
|
||||
|
||||
async formatEvents(events: EventLog[]): Promise<EventType[]> {
|
||||
// eslint-disable-next-line no-return-await
|
||||
return await new Promise((resolve) => resolve(events as unknown as EventType[]));
|
||||
}
|
||||
|
||||
@@ -440,17 +438,13 @@ export class BaseTornadoService extends BaseEventsService<DepositsEvents | Withd
|
||||
}
|
||||
|
||||
export interface BaseMultiTornadoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
instances: {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
instances: Record<string, DepositType>;
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
}
|
||||
|
||||
export class BaseMultiTornadoService extends BaseEventsService<MultiDepositsEvents | MultiWithdrawalsEvents> {
|
||||
instances: {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
instances: Record<string, DepositType>;
|
||||
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
@@ -717,7 +711,7 @@ export class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesE
|
||||
|
||||
const abiCoder = AbiCoder.defaultAbiCoder();
|
||||
|
||||
export const proposalState: { [key: string]: string } = {
|
||||
export const proposalState: Record<string, string> = {
|
||||
0: 'Pending',
|
||||
1: 'Active',
|
||||
2: 'Defeated',
|
||||
@@ -821,13 +815,13 @@ export interface GovernanceVotes extends GovernanceVotedEvents {
|
||||
|
||||
export interface BaseGovernanceServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
Aggregator: TovarishAggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
}
|
||||
|
||||
export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
Aggregator: TovarishAggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
|
||||
batchTransactionService: BatchTransactionService;
|
||||
@@ -955,7 +949,7 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
|
||||
const [QUORUM_VOTES, proposalStatus, proposerNameRecords] = await Promise.all([
|
||||
this.Governance.QUORUM_VOTES(),
|
||||
this.Aggregator.getAllProposals(this.Governance.target),
|
||||
this.Aggregator.getAllProposals(),
|
||||
this.ReverseRecords.getNames(allProposers),
|
||||
]);
|
||||
|
||||
@@ -966,7 +960,7 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: string },
|
||||
{} as Record<string, string>,
|
||||
);
|
||||
|
||||
return proposalEvents.map((event, index) => {
|
||||
@@ -1018,7 +1012,7 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: string },
|
||||
{} as Record<string, string>,
|
||||
);
|
||||
|
||||
const votes = votedEvents.map((event) => {
|
||||
@@ -1066,7 +1060,7 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
});
|
||||
|
||||
const [balances, uniqNameRecords] = await Promise.all([
|
||||
this.Aggregator.getGovernanceBalances(this.Governance.target, uniq),
|
||||
this.Aggregator.getGovernanceBalances(uniq),
|
||||
this.ReverseRecords.getNames(uniq),
|
||||
]);
|
||||
|
||||
@@ -1077,7 +1071,7 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{} as { [key: string]: string },
|
||||
{} as Record<string, string>,
|
||||
);
|
||||
|
||||
return {
|
||||
@@ -1091,28 +1085,6 @@ export class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents
|
||||
}
|
||||
}
|
||||
|
||||
export async function getTovarishNetworks(registryService: BaseRegistryService, relayers: CachedRelayerInfo[]) {
|
||||
await Promise.all(
|
||||
relayers
|
||||
.filter((r) => r.tovarishHost)
|
||||
.map(async (relayer) => {
|
||||
try {
|
||||
relayer.tovarishNetworks = await fetchData(relayer.tovarishHost as string, {
|
||||
...registryService.fetchDataOptions,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
timeout: 30000,
|
||||
maxRetry: registryService.fetchDataOptions?.torPort ? 2 : 0,
|
||||
});
|
||||
} catch {
|
||||
// Ignore error and disable relayer
|
||||
relayer.tovarishNetworks = [];
|
||||
}
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Essential params:
|
||||
* ensName, relayerAddress, hostnames
|
||||
@@ -1120,55 +1092,26 @@ export async function getTovarishNetworks(registryService: BaseRegistryService,
|
||||
*/
|
||||
export interface CachedRelayerInfo extends RelayerParams {
|
||||
isRegistered?: boolean;
|
||||
registeredAddress?: string;
|
||||
isPrior?: boolean;
|
||||
stakeBalance?: string;
|
||||
hostnames: SubdomainMap;
|
||||
tovarishHost?: string;
|
||||
tovarishNetworks?: number[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Static relayer provided by tornadowithdraw.eth
|
||||
* This relayer isn't compatible with the current UI (tornadocash.eth) and only works as experimental mode
|
||||
* Once DAO approves changes to UI to support new Tovarish Relayer software register relayer and remove static list
|
||||
*/
|
||||
const staticRelayers: CachedRelayerInfo[] = [
|
||||
{
|
||||
ensName: 'tornadowithdraw.eth',
|
||||
relayerAddress: '0x40c3d1656a26C9266f4A10fed0D87EFf79F54E64',
|
||||
hostnames: {},
|
||||
tovarishHost: 'tornadowithdraw.com',
|
||||
tovarishNetworks: enabledChains,
|
||||
},
|
||||
{
|
||||
ensName: 'rpc.tornadowithdraw.eth',
|
||||
relayerAddress: '0xFF787B7A5cd8a88508361E3B7bcE791Aa2796526',
|
||||
hostnames: {},
|
||||
tovarishHost: 'tornadocash-rpc.com',
|
||||
tovarishNetworks: enabledChains,
|
||||
},
|
||||
];
|
||||
|
||||
export interface CachedRelayers {
|
||||
lastBlock: number;
|
||||
timestamp: number;
|
||||
relayers: CachedRelayerInfo[];
|
||||
fromCache?: boolean;
|
||||
}
|
||||
|
||||
export interface BaseRegistryServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
tornadoConfig: TornadoConfig;
|
||||
RelayerRegistry: RelayerRegistry;
|
||||
Aggregator: Aggregator;
|
||||
relayerEnsSubdomains: SubdomainMap;
|
||||
Aggregator: TovarishAggregator;
|
||||
}
|
||||
|
||||
export class BaseRegistryService extends BaseEventsService<AllRelayerRegistryEvents> {
|
||||
Aggregator: Aggregator;
|
||||
relayerEnsSubdomains: SubdomainMap;
|
||||
tornadoConfig: TornadoConfig;
|
||||
Aggregator: TovarishAggregator;
|
||||
updateInterval: number;
|
||||
|
||||
constructor(serviceConstructor: BaseRegistryServiceConstructor) {
|
||||
const { RelayerRegistry: contract, Aggregator, relayerEnsSubdomains } = serviceConstructor;
|
||||
const { RelayerRegistry: contract, tornadoConfig, Aggregator } = serviceConstructor;
|
||||
|
||||
super({
|
||||
...serviceConstructor,
|
||||
@@ -1176,8 +1119,8 @@ export class BaseRegistryService extends BaseEventsService<AllRelayerRegistryEve
|
||||
type: '*',
|
||||
});
|
||||
|
||||
this.tornadoConfig = tornadoConfig;
|
||||
this.Aggregator = Aggregator;
|
||||
this.relayerEnsSubdomains = relayerEnsSubdomains;
|
||||
|
||||
this.updateInterval = 86400;
|
||||
}
|
||||
@@ -1254,141 +1197,100 @@ export class BaseRegistryService extends BaseEventsService<AllRelayerRegistryEve
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get saved or cached relayers
|
||||
*/
|
||||
async getRelayersFromDB(): Promise<CachedRelayers> {
|
||||
return {
|
||||
lastBlock: 0,
|
||||
timestamp: 0,
|
||||
relayers: [],
|
||||
};
|
||||
}
|
||||
async getLatestRelayers(knownRelayers?: string[]): Promise<CachedRelayerInfo[]> {
|
||||
const newRelayers: string[] = [];
|
||||
|
||||
/**
|
||||
* Relayers from remote cache (Either from local cache, CDN, or from IPFS)
|
||||
*/
|
||||
async getRelayersFromCache(): Promise<CachedRelayers> {
|
||||
return {
|
||||
lastBlock: 0,
|
||||
timestamp: 0,
|
||||
relayers: [],
|
||||
fromCache: true,
|
||||
};
|
||||
}
|
||||
if (knownRelayers?.length) {
|
||||
const { events: allEvents } = await this.updateEvents();
|
||||
|
||||
async getSavedRelayers(): Promise<CachedRelayers> {
|
||||
let cachedRelayers = await this.getRelayersFromDB();
|
||||
const events = allEvents.filter((e) => e.event === 'RelayerRegistered') as RelayerRegisteredEvents[];
|
||||
|
||||
if (!cachedRelayers || !cachedRelayers.relayers.length) {
|
||||
cachedRelayers = await this.getRelayersFromCache();
|
||||
for (const { ensName } of events) {
|
||||
if (!newRelayers.includes(ensName) && !knownRelayers?.includes(ensName)) {
|
||||
newRelayers.push(ensName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cachedRelayers;
|
||||
}
|
||||
|
||||
async getLatestRelayers(): Promise<CachedRelayers> {
|
||||
const { events: allEvents, lastBlock } = await this.updateEvents();
|
||||
|
||||
const events = allEvents.filter((e) => e.event === 'RelayerRegistered') as RelayerRegisteredEvents[];
|
||||
|
||||
const subdomains = Object.values(this.relayerEnsSubdomains);
|
||||
|
||||
const registerSet = new Set();
|
||||
|
||||
const uniqueRegisters = events.filter(({ ensName }) => {
|
||||
if (!registerSet.has(ensName)) {
|
||||
registerSet.add(ensName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const relayerNameHashes = uniqueRegisters.map((r) => namehash(r.ensName));
|
||||
|
||||
const [relayersData, timestamp] = await Promise.all([
|
||||
this.Aggregator.relayersData.staticCall(relayerNameHashes, subdomains.concat('tovarish-relayer')),
|
||||
this.provider.getBlock(lastBlock).then((b) => Number(b?.timestamp)),
|
||||
const [chains, relayersData] = await Promise.all([
|
||||
this.Aggregator.getChainIds.staticCall(),
|
||||
this.Aggregator.relayersData.staticCall(newRelayers),
|
||||
]);
|
||||
|
||||
const relayers = relayersData
|
||||
.map(({ owner, balance: stakeBalance, records, isRegistered }, index) => {
|
||||
const { ensName, relayerAddress } = uniqueRegisters[index];
|
||||
.map(
|
||||
({
|
||||
ensName,
|
||||
owner,
|
||||
balance: stakeBalance,
|
||||
isRegistered,
|
||||
isPrior,
|
||||
tovarishHost,
|
||||
tovarishChains,
|
||||
records,
|
||||
}) => {
|
||||
const hostnames = records.reduce((acc, record, recordIndex) => {
|
||||
if (record) {
|
||||
// tovarish-relayer.relayer.eth
|
||||
if (recordIndex === records.length - 1) {
|
||||
tovarishHost = record;
|
||||
return acc;
|
||||
}
|
||||
|
||||
let tovarishHost = undefined;
|
||||
|
||||
const hostnames = records.reduce((acc, record, recordIndex) => {
|
||||
if (record) {
|
||||
// tovarish-relayer.relayer.eth
|
||||
if (recordIndex === records.length - 1) {
|
||||
tovarishHost = record;
|
||||
return acc;
|
||||
acc[Number(chains[recordIndex])] = record;
|
||||
}
|
||||
return acc;
|
||||
}, {} as SubdomainMap);
|
||||
|
||||
acc[Number(Object.keys(this.relayerEnsSubdomains)[recordIndex])] = record;
|
||||
const hasMinBalance = stakeBalance >= MIN_STAKE_BALANCE;
|
||||
|
||||
const tovarishNetworks = [
|
||||
...new Set(
|
||||
tovarishChains
|
||||
.split(',')
|
||||
.map((c) => Number(c))
|
||||
.filter((c) => c && this.tornadoConfig.chains.includes(c)),
|
||||
),
|
||||
];
|
||||
|
||||
const preCondition =
|
||||
(isRegistered && hasMinBalance && Object.keys(hostnames).length) ||
|
||||
(tovarishHost.length && tovarishNetworks.length);
|
||||
|
||||
if (preCondition) {
|
||||
return {
|
||||
ensName,
|
||||
relayerAddress: owner,
|
||||
isPrior,
|
||||
isRegistered,
|
||||
stakeBalance: formatEther(stakeBalance),
|
||||
hostnames,
|
||||
tovarishHost,
|
||||
tovarishNetworks,
|
||||
} as CachedRelayerInfo;
|
||||
}
|
||||
return acc;
|
||||
}, {} as SubdomainMap);
|
||||
|
||||
const hasMinBalance = stakeBalance >= MIN_STAKE_BALANCE;
|
||||
|
||||
const preCondition = Object.keys(hostnames).length && isRegistered && hasMinBalance;
|
||||
|
||||
if (preCondition) {
|
||||
return {
|
||||
ensName,
|
||||
relayerAddress: owner,
|
||||
registeredAddress: owner !== relayerAddress ? relayerAddress : undefined,
|
||||
isRegistered,
|
||||
stakeBalance: formatEther(stakeBalance),
|
||||
hostnames,
|
||||
tovarishHost,
|
||||
} as CachedRelayerInfo;
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
.filter((r) => r) as CachedRelayerInfo[];
|
||||
|
||||
await getTovarishNetworks(this, relayers);
|
||||
const sortedRelayers = relayers.sort((a, b) => {
|
||||
// Scoring => isTovarishRelayer => hasMoreStakedBalance
|
||||
// When it is tovarish relayer, it will compare with staked balance as well
|
||||
const getPriorityScore = (i: CachedRelayerInfo) => (i.tovarishHost?.length || 0) + (i.isPrior ? 1 : 0);
|
||||
|
||||
const allRelayers = [...staticRelayers, ...relayers];
|
||||
const tovarishRelayers = allRelayers.filter((r) => r.tovarishHost);
|
||||
const classicRelayers = allRelayers.filter((r) => !r.tovarishHost);
|
||||
const [aScore, bScore] = [getPriorityScore(a), getPriorityScore(b)];
|
||||
|
||||
return {
|
||||
lastBlock,
|
||||
timestamp,
|
||||
relayers: [...tovarishRelayers, ...classicRelayers],
|
||||
};
|
||||
}
|
||||
if (aScore === bScore) {
|
||||
// Sort by staked balance
|
||||
const [aBalance, bBalance] = [Number(a.stakeBalance || 0), Number(b.stakeBalance || 0)];
|
||||
|
||||
/**
|
||||
* Handle saving relayers
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async saveRelayers({ lastBlock, timestamp, relayers }: CachedRelayers) {}
|
||||
return bBalance - aBalance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cached or latest relayer and save to local
|
||||
*/
|
||||
async updateRelayers(): Promise<CachedRelayers> {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { lastBlock, timestamp, relayers, fromCache } = await this.getSavedRelayers();
|
||||
return bScore - aScore;
|
||||
});
|
||||
|
||||
let shouldSave = fromCache ?? false;
|
||||
|
||||
if (!relayers.length || timestamp + this.updateInterval < Math.floor(Date.now() / 1000)) {
|
||||
console.log('\nUpdating relayers from registry\n');
|
||||
|
||||
({ lastBlock, timestamp, relayers } = await this.getLatestRelayers());
|
||||
|
||||
shouldSave = true;
|
||||
}
|
||||
|
||||
if (shouldSave) {
|
||||
await this.saveRelayers({ lastBlock, timestamp, relayers });
|
||||
}
|
||||
|
||||
return { lastBlock, timestamp, relayers };
|
||||
return sortedRelayers;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { downloadZip } from '../zip';
|
||||
import { IndexedDB } from '../idb';
|
||||
|
||||
import { bytesToBase64, digest } from '../utils';
|
||||
import { fetchData } from '../providers';
|
||||
import {
|
||||
BaseTornadoService,
|
||||
BaseTornadoServiceConstructor,
|
||||
@@ -16,7 +14,6 @@ import {
|
||||
BaseRegistryServiceConstructor,
|
||||
BaseRevenueService,
|
||||
BaseRevenueServiceConstructor,
|
||||
CachedRelayers,
|
||||
BaseMultiTornadoService,
|
||||
BaseMultiTornadoServiceConstructor,
|
||||
} from './base';
|
||||
@@ -403,7 +400,6 @@ export class DBRegistryService extends BaseRegistryService {
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
relayerJsonDigest?: string;
|
||||
|
||||
constructor(params: DBRegistryServiceConstructor) {
|
||||
super(params);
|
||||
@@ -439,78 +435,6 @@ export class DBRegistryService extends BaseRegistryService {
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
|
||||
async getRelayersFromDB(): Promise<CachedRelayers> {
|
||||
try {
|
||||
const allCachedRelayers = await this.idb.getAll<CachedRelayers[]>({
|
||||
storeName: `relayers_${this.netId}`,
|
||||
});
|
||||
|
||||
if (!allCachedRelayers?.length) {
|
||||
return {
|
||||
lastBlock: 0,
|
||||
timestamp: 0,
|
||||
relayers: [],
|
||||
};
|
||||
}
|
||||
|
||||
return allCachedRelayers.slice(-1)[0];
|
||||
} catch (err) {
|
||||
console.log('Method getRelayersFromDB has error');
|
||||
console.log(err);
|
||||
|
||||
return {
|
||||
lastBlock: 0,
|
||||
timestamp: 0,
|
||||
relayers: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async getRelayersFromCache(): Promise<CachedRelayers> {
|
||||
const url = `${this.staticUrl}/relayers.json`;
|
||||
|
||||
try {
|
||||
const resp = await fetchData(url, {
|
||||
method: 'GET',
|
||||
returnResponse: true,
|
||||
});
|
||||
|
||||
const data = new Uint8Array(await resp.arrayBuffer());
|
||||
|
||||
if (this.relayerJsonDigest) {
|
||||
const hash = 'sha384-' + bytesToBase64(await digest(data));
|
||||
|
||||
if (hash !== this.relayerJsonDigest) {
|
||||
const errMsg = `Invalid digest hash for ${url}, wants ${this.relayerJsonDigest} has ${hash}`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.parse(new TextDecoder().decode(data)) as CachedRelayers;
|
||||
} catch (err) {
|
||||
console.log('Method getRelayersFromCache has error');
|
||||
console.log(err);
|
||||
|
||||
return {
|
||||
lastBlock: 0,
|
||||
timestamp: 0,
|
||||
relayers: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async saveRelayers(cachedRelayers: CachedRelayers): Promise<void> {
|
||||
try {
|
||||
await this.idb.putItem({
|
||||
data: cachedRelayers,
|
||||
storeName: `relayers_${this.netId}`,
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Method saveRelayers has error');
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBRevenueServiceConstructor extends BaseRevenueServiceConstructor {
|
||||
|
||||
@@ -17,7 +17,7 @@ const DUMMY_WITHDRAW_DATA =
|
||||
export function convertETHToTokenAmount(
|
||||
amountInWei: BigNumberish,
|
||||
tokenPriceInWei: BigNumberish,
|
||||
tokenDecimals: number = 18,
|
||||
tokenDecimals = 18,
|
||||
): bigint {
|
||||
const tokenDecimalsMultiplier = BigInt(10 ** Number(tokenDecimals));
|
||||
return (BigInt(amountInWei) * tokenDecimalsMultiplier) / BigInt(tokenPriceInWei);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { isAddress } from 'ethers';
|
||||
import { NetId, NetIdType } from './networkConfig';
|
||||
|
||||
// https://dev.gas.zip/gas/chain-support/inbound
|
||||
export const gasZipInbounds: { [key in NetIdType]: string } = {
|
||||
export const gasZipInbounds: Record<NetIdType, string> = {
|
||||
[NetId.MAINNET]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.BSC]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.POLYGON]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
@@ -15,7 +15,7 @@ export const gasZipInbounds: { [key in NetIdType]: string } = {
|
||||
};
|
||||
|
||||
// https://dev.gas.zip/gas/chain-support/outbound
|
||||
export const gasZipID: { [key in NetIdType]: number } = {
|
||||
export const gasZipID: Record<NetIdType, number> = {
|
||||
[NetId.MAINNET]: 255,
|
||||
[NetId.BSC]: 14,
|
||||
[NetId.POLYGON]: 17,
|
||||
|
||||
@@ -49,9 +49,7 @@ export interface queryGraphParams {
|
||||
graphApi: string;
|
||||
subgraphName: string;
|
||||
query: string;
|
||||
variables?: {
|
||||
[key: string]: string | number;
|
||||
};
|
||||
variables?: Record<string, string | number>;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
}
|
||||
|
||||
@@ -64,7 +62,8 @@ export async function queryGraph<T>({
|
||||
}: queryGraphParams): Promise<T> {
|
||||
const graphUrl = `${graphApi}/subgraphs/name/${subgraphName}`;
|
||||
|
||||
const { data, errors } = await fetchData(graphUrl, {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const { data, errors } = await fetchData<{ data: T & { _meta: any }; errors: any }>(graphUrl, {
|
||||
...fetchDataOptions,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -270,7 +269,6 @@ export async function getAllRegisters({
|
||||
const events = [];
|
||||
let lastSyncBlock = fromBlock;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
let {
|
||||
relayers: result,
|
||||
@@ -406,7 +404,6 @@ export async function getAllDeposits({
|
||||
const events = [];
|
||||
let lastSyncBlock = fromBlock;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
let {
|
||||
deposits: result,
|
||||
@@ -552,7 +549,6 @@ export async function getAllWithdrawals({
|
||||
const events = [];
|
||||
let lastSyncBlock = fromBlock;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
let {
|
||||
withdrawals: result,
|
||||
@@ -756,7 +752,6 @@ export async function getAllGraphEchoEvents({
|
||||
const events = [];
|
||||
let lastSyncBlock = fromBlock;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
let {
|
||||
noteAccounts: result,
|
||||
@@ -888,7 +883,6 @@ export async function getAllEncryptedNotes({
|
||||
const events = [];
|
||||
let lastSyncBlock = fromBlock;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
let {
|
||||
encryptedNotes: result,
|
||||
@@ -1046,7 +1040,6 @@ export async function getAllGovernanceEvents({
|
||||
|
||||
let lastSyncBlock = fromBlock;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const {
|
||||
proposals,
|
||||
|
||||
36
src/idb.ts
36
src/idb.ts
@@ -1,6 +1,13 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { openDB, deleteDB, OpenDBCallbacks, IDBPDatabase } from 'idb';
|
||||
import { getConfig, NetIdType } from './networkConfig';
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any, import/no-duplicates */
|
||||
import type * as idb from 'idb';
|
||||
import type { OpenDBCallbacks, IDBPDatabase } from 'idb';
|
||||
import type { NetIdType, TornadoConfig } from './networkConfig';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
idb: typeof idb;
|
||||
}
|
||||
}
|
||||
|
||||
export const INDEX_DB_ERROR = 'A mutation operation was attempted on a database that did not allow mutations.';
|
||||
|
||||
@@ -64,7 +71,7 @@ export class IndexedDB {
|
||||
return;
|
||||
}
|
||||
|
||||
this.db = await openDB(this.dbName, this.dbVersion, this.options);
|
||||
this.db = await window?.idb?.openDB(this.dbName, this.dbVersion, this.options);
|
||||
this.db.addEventListener('onupgradeneeded', async () => {
|
||||
await this._removeExist();
|
||||
});
|
||||
@@ -89,7 +96,7 @@ export class IndexedDB {
|
||||
}
|
||||
|
||||
async _removeExist() {
|
||||
await deleteDB(this.dbName);
|
||||
await window?.idb?.deleteDB(this.dbName);
|
||||
this.dbExists = false;
|
||||
|
||||
await this.initDB();
|
||||
@@ -314,10 +321,10 @@ export class IndexedDB {
|
||||
/**
|
||||
* Should check if DB is initialized well
|
||||
*/
|
||||
export async function getIndexedDB(netId?: NetIdType) {
|
||||
export async function getIndexedDB(netId?: NetIdType, tornadoConfig?: TornadoConfig) {
|
||||
// key-value db for settings
|
||||
if (!netId) {
|
||||
const idb = new IndexedDB({ dbName: 'tornado-core' });
|
||||
if (!netId || !tornadoConfig) {
|
||||
const idb = new IndexedDB({ dbName: 'tornado-scripts' });
|
||||
await idb.initDB();
|
||||
return idb;
|
||||
}
|
||||
@@ -363,7 +370,7 @@ export async function getIndexedDB(netId?: NetIdType) {
|
||||
},
|
||||
];
|
||||
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = getConfig(netId);
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = tornadoConfig.getConfig(netId);
|
||||
|
||||
const stores = [...defaultState];
|
||||
|
||||
@@ -380,17 +387,6 @@ export async function getIndexedDB(netId?: NetIdType) {
|
||||
],
|
||||
});
|
||||
|
||||
stores.push({
|
||||
name: `relayers_${netId}`,
|
||||
keyPath: 'timestamp',
|
||||
indexes: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
stores.push({
|
||||
name: `revenue_${netId}`,
|
||||
keyPath: 'timestamp',
|
||||
|
||||
31
src/ip.ts
31
src/ip.ts
@@ -1,14 +1,37 @@
|
||||
import { fetchData } from './providers';
|
||||
import { fetchData, fetchDataOptions } from './providers';
|
||||
|
||||
export interface IPResult {
|
||||
ip: string;
|
||||
iso?: string;
|
||||
country?: string;
|
||||
country_iso?: string;
|
||||
tor?: boolean;
|
||||
}
|
||||
|
||||
export async function fetchIp(ipEcho: string) {
|
||||
return (await fetchData(ipEcho, {
|
||||
export function fetchIp(ipEcho: string, fetchOptions?: fetchDataOptions) {
|
||||
return fetchData<IPResult>(ipEcho, {
|
||||
...(fetchOptions || {}),
|
||||
method: 'GET',
|
||||
timeout: 30000,
|
||||
})) as IPResult;
|
||||
});
|
||||
}
|
||||
|
||||
// 🖕
|
||||
export interface IPResultFuck {
|
||||
YourFuckingIPAddress: string;
|
||||
YourFuckingLocation: string;
|
||||
YourFuckingHostname: string;
|
||||
YourFuckingISP: string;
|
||||
YourFuckingTorExit: boolean;
|
||||
YourFuckingCity?: string;
|
||||
YourFuckingCountry: string;
|
||||
YourFuckingCountryCode: string;
|
||||
}
|
||||
|
||||
export function fetchFuckingIp(ipFuck = 'https://myip.wtf/json', fetchOptions?: fetchDataOptions) {
|
||||
return fetchData<IPResultFuck>(ipFuck, {
|
||||
...(fetchOptions || {}),
|
||||
method: 'GET',
|
||||
timeout: 30000,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Worker as NodeWorker } from 'worker_threads';
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from 'fixed-merkle-tree';
|
||||
import type { Tornado } from '@tornado/contracts';
|
||||
import type { Tornado } from 'tornado-contracts';
|
||||
import { isNode, toFixedHex } from './utils';
|
||||
import { mimc } from './mimc';
|
||||
import type { DepositType } from './deposits';
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
import { ERC20Permit, ERC20Mock, TORN } from '@tornado/contracts';
|
||||
import { ERC20Permit, ERC20Mock, TORN } from 'tornado-contracts';
|
||||
import { MaxUint256, Provider, Signature, Signer, TypedDataField } from 'ethers';
|
||||
|
||||
export interface PermitValue {
|
||||
@@ -22,9 +22,7 @@ export const permit2Address = '0x000000000022D473030F116dDEE9F6B43aC78BA3';
|
||||
*/
|
||||
export interface Witness {
|
||||
witnessTypeName: string;
|
||||
witnessType: {
|
||||
[key: string]: TypedDataField[];
|
||||
};
|
||||
witnessType: Record<string, TypedDataField[]>;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
witness: any;
|
||||
}
|
||||
|
||||
157
src/providers.ts
157
src/providers.ts
@@ -1,6 +1,4 @@
|
||||
import type { EventEmitter } from 'stream';
|
||||
import type { RequestOptions } from 'http';
|
||||
import crossFetch from 'cross-fetch';
|
||||
import {
|
||||
FetchRequest,
|
||||
JsonRpcApiProvider,
|
||||
@@ -20,10 +18,13 @@ import {
|
||||
EnsPlugin,
|
||||
GasCostPlugin,
|
||||
FetchCancelSignal,
|
||||
resolveProperties,
|
||||
TransactionLike,
|
||||
FetchUrlFeeDataNetworkPlugin,
|
||||
FeeData,
|
||||
} from 'ethers';
|
||||
import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch';
|
||||
// Temporary workaround until @types/node-fetch is compatible with @types/node
|
||||
import type { AbortSignal as FetchAbortSignal } from 'node-fetch/externals';
|
||||
import type { Dispatcher, RequestInit, fetch as undiciFetch } from 'undici-types';
|
||||
|
||||
import { isNode, sleep } from './utils';
|
||||
import type { Config, NetIdType } from './networkConfig';
|
||||
|
||||
@@ -36,73 +37,34 @@ declare global {
|
||||
// Update this for every Tor Browser release
|
||||
export const defaultUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0';
|
||||
|
||||
export type nodeFetch = (url: RequestInfo, init?: RequestInit) => Promise<Response>;
|
||||
export type DispatcherFunc = (retry?: number) => Dispatcher;
|
||||
|
||||
export type fetchDataOptions = RequestInit & {
|
||||
export interface fetchDataOptions extends Omit<RequestInit, 'headers'> {
|
||||
/**
|
||||
* Overriding RequestInit params
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
headers?: HeadersInit | any;
|
||||
|
||||
/**
|
||||
* Expanding RequestInit params
|
||||
*/
|
||||
maxRetry?: number;
|
||||
retryOn?: number;
|
||||
userAgent?: string;
|
||||
timeout?: number;
|
||||
proxy?: string;
|
||||
torPort?: number;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||
debug?: Function;
|
||||
returnResponse?: boolean;
|
||||
cancelSignal?: FetchCancelSignal;
|
||||
};
|
||||
|
||||
export type NodeAgent = RequestOptions['agent'] | ((parsedUrl: URL) => RequestOptions['agent']);
|
||||
|
||||
export function getHttpAgent({
|
||||
fetchUrl,
|
||||
proxyUrl,
|
||||
torPort,
|
||||
retry,
|
||||
}: {
|
||||
fetchUrl: string;
|
||||
proxyUrl?: string;
|
||||
torPort?: number;
|
||||
retry: number;
|
||||
}): NodeAgent | undefined {
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
const { HttpProxyAgent } = require('http-proxy-agent');
|
||||
const { HttpsProxyAgent } = require('https-proxy-agent');
|
||||
const { SocksProxyAgent } = require('socks-proxy-agent');
|
||||
/* eslint-enable @typescript-eslint/no-require-imports */
|
||||
|
||||
if (torPort) {
|
||||
return new SocksProxyAgent(`socks5h://tor${retry}@127.0.0.1:${torPort}`);
|
||||
}
|
||||
|
||||
if (!proxyUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isHttps = fetchUrl.includes('https://');
|
||||
|
||||
if (proxyUrl.includes('socks://') || proxyUrl.includes('socks4://') || proxyUrl.includes('socks5://')) {
|
||||
return new SocksProxyAgent(proxyUrl);
|
||||
}
|
||||
|
||||
if (proxyUrl.includes('http://') || proxyUrl.includes('https://')) {
|
||||
if (isHttps) {
|
||||
return new HttpsProxyAgent(proxyUrl);
|
||||
}
|
||||
return new HttpProxyAgent(proxyUrl);
|
||||
}
|
||||
dispatcherFunc?: DispatcherFunc;
|
||||
}
|
||||
|
||||
export async function fetchData(url: string, options: fetchDataOptions = {}) {
|
||||
export async function fetchData<T>(url: string, options: fetchDataOptions = {}): Promise<T> {
|
||||
const MAX_RETRY = options.maxRetry ?? 3;
|
||||
const RETRY_ON = options.retryOn ?? 500;
|
||||
const userAgent = options.userAgent ?? defaultUserAgent;
|
||||
|
||||
const fetch = ((globalThis as unknown as { useGlobalFetch?: boolean }).useGlobalFetch
|
||||
? globalThis.fetch
|
||||
: crossFetch) as unknown as nodeFetch;
|
||||
|
||||
let retry = 0;
|
||||
let errorObject;
|
||||
|
||||
@@ -122,14 +84,17 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
|
||||
options.headers['User-Agent'] = userAgent;
|
||||
}
|
||||
|
||||
if (typeof globalThis.fetch !== 'function') {
|
||||
throw new Error('Fetch API is not available, use latest browser or nodejs installation!');
|
||||
}
|
||||
|
||||
while (retry < MAX_RETRY + 1) {
|
||||
let timeout;
|
||||
|
||||
if (!options.signal && options.timeout) {
|
||||
const controller = new AbortController();
|
||||
|
||||
// Temporary workaround until @types/node-fetch is compatible with @types/node
|
||||
options.signal = controller.signal as FetchAbortSignal;
|
||||
options.signal = controller.signal;
|
||||
|
||||
// Define timeout in seconds
|
||||
timeout = setTimeout(() => {
|
||||
@@ -149,16 +114,7 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.agent && isNode && (options.proxy || options.torPort)) {
|
||||
options.agent = getHttpAgent({
|
||||
fetchUrl: url,
|
||||
proxyUrl: options.proxy,
|
||||
torPort: options.torPort,
|
||||
retry,
|
||||
});
|
||||
}
|
||||
|
||||
if (options.debug && typeof options.debug === 'function') {
|
||||
if (typeof options.debug === 'function') {
|
||||
options.debug('request', {
|
||||
url,
|
||||
retry,
|
||||
@@ -168,13 +124,11 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
|
||||
}
|
||||
|
||||
try {
|
||||
const resp = await fetch(url, {
|
||||
method: options.method,
|
||||
headers: options.headers,
|
||||
body: options.body,
|
||||
redirect: options.redirect,
|
||||
signal: options.signal,
|
||||
agent: options.agent,
|
||||
const dispatcher = options.dispatcherFunc ? options.dispatcherFunc(retry) : options.dispatcher;
|
||||
|
||||
const resp = await (globalThis.fetch as unknown as typeof undiciFetch)(url, {
|
||||
...options,
|
||||
dispatcher,
|
||||
});
|
||||
|
||||
if (options.debug && typeof options.debug === 'function') {
|
||||
@@ -187,23 +141,23 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
|
||||
}
|
||||
|
||||
if (options.returnResponse) {
|
||||
return resp;
|
||||
return resp as T;
|
||||
}
|
||||
|
||||
const contentType = resp.headers.get('content-type');
|
||||
|
||||
// If server returns JSON object, parse it and return as an object
|
||||
if (contentType?.includes('application/json')) {
|
||||
return await resp.json();
|
||||
return (await resp.json()) as T;
|
||||
}
|
||||
|
||||
// Else if the server returns text parse it as a string
|
||||
if (contentType?.includes('text')) {
|
||||
return await resp.text();
|
||||
return (await resp.text()) as T;
|
||||
}
|
||||
|
||||
// Return as a response object https://developer.mozilla.org/en-US/docs/Web/API/Response
|
||||
return resp;
|
||||
return resp as T;
|
||||
} catch (error) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
@@ -242,9 +196,9 @@ export const fetchGetUrlFunc =
|
||||
returnResponse: true,
|
||||
};
|
||||
|
||||
const resp = await fetchData(req.url, init);
|
||||
const resp = await fetchData<Response>(req.url, init);
|
||||
|
||||
const headers = {} as { [key in string]: any };
|
||||
const headers = {} as Record<string, any>;
|
||||
resp.headers.forEach((value: any, key: string) => {
|
||||
headers[key.toLowerCase()] = value;
|
||||
});
|
||||
@@ -267,20 +221,36 @@ export type getProviderOptions = fetchDataOptions & {
|
||||
pollingInterval?: number;
|
||||
};
|
||||
|
||||
export const FeeDataNetworkPluginName = new FetchUrlFeeDataNetworkPlugin(
|
||||
'',
|
||||
() => new Promise((resolve) => resolve(new FeeData())),
|
||||
).name;
|
||||
|
||||
export async function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider> {
|
||||
// Use our own fetchGetUrlFunc to support proxies and retries
|
||||
const fetchReq = new FetchRequest(rpcUrl);
|
||||
|
||||
fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions);
|
||||
|
||||
const staticNetwork = await new JsonRpcProvider(fetchReq).getNetwork();
|
||||
const fetchedNetwork = await new JsonRpcProvider(fetchReq).getNetwork();
|
||||
|
||||
const chainId = Number(staticNetwork.chainId);
|
||||
// Audit if we are connected to right network
|
||||
const chainId = Number(fetchedNetwork.chainId);
|
||||
|
||||
if (fetchOptions?.netId && fetchOptions.netId !== chainId) {
|
||||
const errMsg = `Wrong network for ${rpcUrl}, wants ${fetchOptions.netId} got ${chainId}`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
// Clone to new network to exclude polygon gas station plugin
|
||||
const staticNetwork = new Network(fetchedNetwork.name, fetchedNetwork.chainId);
|
||||
|
||||
fetchedNetwork.plugins.forEach((plugin) => {
|
||||
if (plugin.name !== FeeDataNetworkPluginName) {
|
||||
staticNetwork.attachPlugin(plugin.clone());
|
||||
}
|
||||
});
|
||||
|
||||
return new JsonRpcProvider(fetchReq, staticNetwork, {
|
||||
staticNetwork,
|
||||
pollingInterval: fetchOptions?.pollingInterval || 1000,
|
||||
@@ -293,7 +263,7 @@ export function getProviderWithNetId(
|
||||
config: Config,
|
||||
fetchOptions?: getProviderOptions,
|
||||
): JsonRpcProvider {
|
||||
const { networkName, reverseRecordsContract, pollInterval } = config;
|
||||
const { networkName, reverseRecordsContract, blockTime } = config;
|
||||
const hasEns = Boolean(reverseRecordsContract);
|
||||
|
||||
const fetchReq = new FetchRequest(rpcUrl);
|
||||
@@ -306,7 +276,7 @@ export function getProviderWithNetId(
|
||||
|
||||
const provider = new JsonRpcProvider(fetchReq, staticNetwork, {
|
||||
staticNetwork,
|
||||
pollingInterval: fetchOptions?.pollingInterval || pollInterval * 1000,
|
||||
pollingInterval: fetchOptions?.pollingInterval || blockTime * 1000,
|
||||
});
|
||||
|
||||
return provider;
|
||||
@@ -325,11 +295,16 @@ export const populateTransaction = async (
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
const [feeData, nonce] = await Promise.all([
|
||||
const [chainId, feeData, nonce] = await Promise.all([
|
||||
tx.chainId || tx.chainId === 0n ? undefined : provider.getNetwork().then((n) => Number(n.chainId)),
|
||||
tx.maxFeePerGas || tx.gasPrice ? undefined : provider.getFeeData(),
|
||||
tx.nonce ? undefined : provider.getTransactionCount(signer.address, 'pending'),
|
||||
tx.nonce || tx.nonce === 0 ? undefined : provider.getTransactionCount(signer.address, 'pending'),
|
||||
]);
|
||||
|
||||
if (chainId) {
|
||||
tx.chainId = chainId;
|
||||
}
|
||||
|
||||
if (feeData) {
|
||||
// EIP-1559
|
||||
if (feeData.maxFeePerGas) {
|
||||
@@ -350,7 +325,7 @@ export const populateTransaction = async (
|
||||
}
|
||||
}
|
||||
|
||||
if (nonce) {
|
||||
if (nonce || nonce === 0) {
|
||||
tx.nonce = nonce;
|
||||
}
|
||||
|
||||
@@ -373,7 +348,7 @@ export const populateTransaction = async (
|
||||
}
|
||||
}
|
||||
|
||||
return tx;
|
||||
return resolveProperties(tx);
|
||||
};
|
||||
|
||||
export interface TornadoWalletOptions {
|
||||
@@ -414,8 +389,7 @@ export class TornadoWallet extends Wallet {
|
||||
async populateTransaction(tx: TransactionRequest) {
|
||||
const txObject = await populateTransaction(this, tx);
|
||||
this.nonce = Number(txObject.nonce);
|
||||
|
||||
return super.populateTransaction(txObject);
|
||||
return txObject as Promise<TransactionLike<string>>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,8 +417,7 @@ export class TornadoVoidSigner extends VoidSigner {
|
||||
async populateTransaction(tx: TransactionRequest) {
|
||||
const txObject = await populateTransaction(this, tx);
|
||||
this.nonce = Number(txObject.nonce);
|
||||
|
||||
return super.populateTransaction(txObject);
|
||||
return txObject as Promise<TransactionLike<string>>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getAddress, parseEther } from 'ethers';
|
||||
import { sleep } from './utils';
|
||||
import { NetId, NetIdType, Config } from './networkConfig';
|
||||
import type { NetIdType, TornadoConfig } from './networkConfig';
|
||||
import { fetchData, fetchDataOptions } from './providers';
|
||||
import { ajv, jobsSchema, jobRequestSchema, getStatusSchema } from './schemas';
|
||||
import type { snarkProofs } from './websnark';
|
||||
@@ -28,9 +28,7 @@ export interface RelayerInfo extends RelayerParams {
|
||||
instances: string[];
|
||||
stakeBalance?: string;
|
||||
gasPrice?: number;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
ethPrices?: Record<string, string>;
|
||||
currentQueue: number;
|
||||
tornadoServiceFee: number;
|
||||
}
|
||||
@@ -45,24 +43,21 @@ export interface RelayerError {
|
||||
export interface RelayerStatus {
|
||||
url: string;
|
||||
rewardAccount: string;
|
||||
instances: {
|
||||
[key in string]: {
|
||||
instanceAddress: {
|
||||
[key in string]: string;
|
||||
};
|
||||
instances: Record<
|
||||
string,
|
||||
{
|
||||
instanceAddress: Record<string, string>;
|
||||
tokenAddress?: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
>;
|
||||
gasPrices?: {
|
||||
fast: number;
|
||||
additionalProperties?: number;
|
||||
};
|
||||
netId: NetIdType;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
ethPrices?: Record<string, string>;
|
||||
tornadoServiceFee: number;
|
||||
latestBlock?: number;
|
||||
version: string;
|
||||
@@ -149,13 +144,12 @@ export function getWeightRandom(weightsScores: bigint[], random: bigint) {
|
||||
return Math.floor(Math.random() * weightsScores.length);
|
||||
}
|
||||
|
||||
export interface RelayerInstanceList {
|
||||
[key: string]: {
|
||||
instanceAddress: {
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
export type RelayerInstanceList = Record<
|
||||
string,
|
||||
{
|
||||
instanceAddress: Record<string, string>;
|
||||
}
|
||||
>;
|
||||
|
||||
export function getSupportedInstances(instanceList: RelayerInstanceList) {
|
||||
const rawList = Object.values(instanceList)
|
||||
@@ -180,35 +174,31 @@ export function pickWeightedRandomRelayer(relayers: RelayerInfo[]) {
|
||||
}
|
||||
|
||||
export interface RelayerClientConstructor {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
tornadoConfig: TornadoConfig;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
}
|
||||
|
||||
export class RelayerClient {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
tornadoConfig: TornadoConfig;
|
||||
selectedRelayer?: RelayerInfo;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
tovarish: boolean;
|
||||
|
||||
constructor({ netId, config, fetchDataOptions }: RelayerClientConstructor) {
|
||||
this.netId = netId;
|
||||
this.config = config;
|
||||
constructor({ tornadoConfig, fetchDataOptions }: RelayerClientConstructor) {
|
||||
this.tornadoConfig = tornadoConfig;
|
||||
this.fetchDataOptions = fetchDataOptions;
|
||||
this.tovarish = false;
|
||||
}
|
||||
|
||||
async askRelayerStatus({
|
||||
netId,
|
||||
hostname,
|
||||
url,
|
||||
relayerAddress,
|
||||
}: {
|
||||
netId: NetIdType;
|
||||
hostname?: string;
|
||||
// optional url if entered manually
|
||||
url?: string;
|
||||
// relayerAddress from registry contract to prevent cheating
|
||||
relayerAddress?: string;
|
||||
}): Promise<RelayerStatus> {
|
||||
if (!url && hostname) {
|
||||
url = `https://${!hostname.endsWith('/') ? hostname + '/' : hostname}`;
|
||||
@@ -218,16 +208,18 @@ export class RelayerClient {
|
||||
url = '';
|
||||
}
|
||||
|
||||
const rawStatus = (await fetchData(`${url}status`, {
|
||||
const rawStatus = await fetchData<RelayerStatus>(`${url}status`, {
|
||||
...this.fetchDataOptions,
|
||||
headers: {
|
||||
'Content-Type': 'application/json, application/x-www-form-urlencoded',
|
||||
},
|
||||
timeout: 30000,
|
||||
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0,
|
||||
})) as object;
|
||||
maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0,
|
||||
});
|
||||
|
||||
const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish));
|
||||
const config = this.tornadoConfig.getConfig(netId);
|
||||
|
||||
const statusValidator = ajv.compile(getStatusSchema(config, this.tovarish));
|
||||
|
||||
if (!statusValidator(rawStatus)) {
|
||||
throw new Error('Invalid status schema');
|
||||
@@ -242,19 +234,21 @@ export class RelayerClient {
|
||||
throw new Error('Withdrawal queue is overloaded');
|
||||
}
|
||||
|
||||
if (status.netId !== this.netId) {
|
||||
if (status.netId !== netId) {
|
||||
throw new Error('This relayer serves a different network');
|
||||
}
|
||||
|
||||
/**
|
||||
if (relayerAddress && this.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) {
|
||||
throw new Error('The Relayer reward address must match registered address');
|
||||
}
|
||||
**/
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
async filterRelayer(relayer: CachedRelayerInfo): Promise<RelayerInfo | RelayerError | undefined> {
|
||||
const hostname = relayer.hostnames[this.netId];
|
||||
async filterRelayer(netId: NetIdType, relayer: CachedRelayerInfo): Promise<RelayerInfo | RelayerError | undefined> {
|
||||
const hostname = relayer.hostnames[netId];
|
||||
const { ensName, relayerAddress } = relayer;
|
||||
|
||||
if (!hostname) {
|
||||
@@ -263,8 +257,8 @@ export class RelayerClient {
|
||||
|
||||
try {
|
||||
const status = await this.askRelayerStatus({
|
||||
netId,
|
||||
hostname,
|
||||
relayerAddress,
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -292,13 +286,16 @@ export class RelayerClient {
|
||||
}
|
||||
}
|
||||
|
||||
async getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
async getValidRelayers(
|
||||
netId: NetIdType,
|
||||
relayers: CachedRelayerInfo[],
|
||||
): Promise<{
|
||||
validRelayers: RelayerInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}> {
|
||||
const invalidRelayers: RelayerError[] = [];
|
||||
|
||||
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
|
||||
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(netId, relayer)))).filter(
|
||||
(r) => {
|
||||
if (!r) {
|
||||
return false;
|
||||
@@ -331,7 +328,7 @@ export class RelayerClient {
|
||||
* Request new job
|
||||
*/
|
||||
|
||||
const withdrawResponse = (await fetchData(`${url}v1/tornadoWithdraw`, {
|
||||
const withdrawResponse = await fetchData<RelayerTornadoWithdraw>(`${url}v1/tornadoWithdraw`, {
|
||||
...this.fetchDataOptions,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -342,7 +339,7 @@ export class RelayerClient {
|
||||
proof,
|
||||
args,
|
||||
}),
|
||||
})) as RelayerTornadoWithdraw;
|
||||
});
|
||||
|
||||
const { id, error } = withdrawResponse;
|
||||
|
||||
@@ -372,7 +369,7 @@ export class RelayerClient {
|
||||
console.log(`Job submitted: ${jobUrl}\n`);
|
||||
|
||||
while (!relayerStatus || !['FAILED', 'CONFIRMED'].includes(relayerStatus)) {
|
||||
const jobResponse = await fetchData(jobUrl, {
|
||||
const jobResponse = await fetchData<RelayerTornadoJobs>(jobUrl, {
|
||||
...this.fetchDataOptions,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
@@ -391,7 +388,7 @@ export class RelayerClient {
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
const { status, txHash, confirmations, failedReason } = jobResponse as unknown as RelayerTornadoJobs;
|
||||
const { status, txHash, confirmations, failedReason } = jobResponse;
|
||||
|
||||
if (relayerStatus !== status) {
|
||||
if (status === 'FAILED') {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Config, NetId, NetIdType } from '../networkConfig';
|
||||
import { Config } from '../networkConfig';
|
||||
import { addressSchemaType, bnSchemaType } from '.';
|
||||
|
||||
export interface statusInstanceType {
|
||||
@@ -6,13 +6,12 @@ export interface statusInstanceType {
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof addressSchemaType;
|
||||
};
|
||||
properties: Record<string, typeof addressSchemaType>;
|
||||
required: string[];
|
||||
};
|
||||
tokenAddress?: typeof addressSchemaType;
|
||||
symbol?: { enum: string[] };
|
||||
//symbol?: { enum: string[] };
|
||||
symbol?: { type: string };
|
||||
decimals: { enum: number[] };
|
||||
};
|
||||
required: string[];
|
||||
@@ -20,17 +19,13 @@ export interface statusInstanceType {
|
||||
|
||||
export interface statusInstancesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: statusInstanceType;
|
||||
};
|
||||
properties: Record<string, statusInstanceType>;
|
||||
required: string[];
|
||||
}
|
||||
|
||||
export interface statusEthPricesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof bnSchemaType;
|
||||
};
|
||||
properties: Record<string, typeof bnSchemaType>;
|
||||
required?: string[];
|
||||
}
|
||||
|
||||
@@ -41,11 +36,12 @@ export interface statusSchema {
|
||||
instances?: statusInstancesType;
|
||||
gasPrices: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: {
|
||||
properties: Record<
|
||||
string,
|
||||
{
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
>;
|
||||
required: string[];
|
||||
};
|
||||
netId: {
|
||||
@@ -132,15 +128,23 @@ const statusSchema: statusSchema = {
|
||||
required: ['rewardAccount', 'instances', 'netId', 'tornadoServiceFee', 'version', 'health', 'currentQueue'],
|
||||
};
|
||||
|
||||
export function getStatusSchema(netId: NetIdType, config: Config, tovarish: boolean) {
|
||||
const { tokens, optionalTokens, disabledTokens, nativeCurrency } = config;
|
||||
export function getStatusSchema(config: Config, tovarish: boolean) {
|
||||
const { tokens, nativeCurrency } = config;
|
||||
|
||||
// deep copy schema
|
||||
const schema = JSON.parse(JSON.stringify(statusSchema)) as statusSchema;
|
||||
|
||||
const instances = Object.keys(tokens).reduce(
|
||||
(acc: statusInstancesType, token) => {
|
||||
const { instanceAddress, tokenAddress, symbol, decimals, optionalInstances = [] } = tokens[token];
|
||||
const {
|
||||
isOptional,
|
||||
isDisabled,
|
||||
instanceAddress,
|
||||
tokenAddress,
|
||||
symbol,
|
||||
decimals,
|
||||
optionalInstances = [],
|
||||
} = tokens[token];
|
||||
const amounts = Object.keys(instanceAddress);
|
||||
|
||||
const instanceProperties: statusInstanceType = {
|
||||
@@ -148,18 +152,10 @@ export function getStatusSchema(netId: NetIdType, config: Config, tovarish: bool
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: 'object',
|
||||
properties: amounts.reduce(
|
||||
(
|
||||
acc: {
|
||||
[key in string]: typeof addressSchemaType;
|
||||
},
|
||||
cur,
|
||||
) => {
|
||||
acc[cur] = addressSchemaType;
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
),
|
||||
properties: amounts.reduce((acc: Record<string, typeof addressSchemaType>, cur) => {
|
||||
acc[cur] = addressSchemaType;
|
||||
return acc;
|
||||
}, {}),
|
||||
required: amounts.filter((amount) => !optionalInstances.includes(amount)),
|
||||
},
|
||||
decimals: { enum: [decimals] },
|
||||
@@ -173,12 +169,14 @@ export function getStatusSchema(netId: NetIdType, config: Config, tovarish: bool
|
||||
if (tokenAddress) {
|
||||
instanceProperties.properties.tokenAddress = addressSchemaType;
|
||||
}
|
||||
|
||||
if (symbol) {
|
||||
instanceProperties.properties.symbol = { enum: [symbol] };
|
||||
// instanceProperties.properties.symbol = { enum: [symbol] };
|
||||
instanceProperties.properties.symbol = { type: 'string' };
|
||||
}
|
||||
|
||||
acc.properties[token] = instanceProperties;
|
||||
if (!optionalTokens?.includes(token) && !disabledTokens?.includes(token)) {
|
||||
if (!isOptional && !isDisabled) {
|
||||
acc.required.push(token);
|
||||
}
|
||||
return acc;
|
||||
@@ -192,18 +190,12 @@ export function getStatusSchema(netId: NetIdType, config: Config, tovarish: bool
|
||||
|
||||
schema.properties.instances = instances;
|
||||
|
||||
const _tokens = Object.keys(tokens).filter(
|
||||
(t) => t !== nativeCurrency && !config.optionalTokens?.includes(t) && !config.disabledTokens?.includes(t),
|
||||
);
|
||||
|
||||
if (netId === NetId.MAINNET) {
|
||||
_tokens.push('torn');
|
||||
}
|
||||
const _tokens = instances.required.filter((t) => t !== nativeCurrency);
|
||||
|
||||
if (_tokens.length) {
|
||||
const ethPrices: statusEthPricesType = {
|
||||
type: 'object',
|
||||
properties: _tokens.reduce((acc: { [key in string]: typeof bnSchemaType }, token: string) => {
|
||||
properties: _tokens.reduce((acc: Record<string, typeof bnSchemaType>, token: string) => {
|
||||
acc[token] = bnSchemaType;
|
||||
return acc;
|
||||
}, {}),
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
import { fetchData } from './providers';
|
||||
import { CachedRelayerInfo, MinimalEvents } from './events';
|
||||
import { ajv, getEventsSchemaValidator, getStatusSchema } from './schemas';
|
||||
import { enabledChains, getConfig, NetId, NetIdType } from './networkConfig';
|
||||
import { NetId, NetIdType } from './networkConfig';
|
||||
|
||||
// Return no more than 5K events per query
|
||||
export const MAX_TOVARISH_EVENTS = 5000;
|
||||
@@ -76,10 +76,11 @@ export class TovarishClient extends RelayerClient {
|
||||
}
|
||||
|
||||
async askRelayerStatus({
|
||||
netId,
|
||||
hostname,
|
||||
url,
|
||||
relayerAddress,
|
||||
}: {
|
||||
netId: NetIdType;
|
||||
hostname?: string;
|
||||
// optional url if entered manually
|
||||
url?: string;
|
||||
@@ -87,9 +88,9 @@ export class TovarishClient extends RelayerClient {
|
||||
relayerAddress?: string;
|
||||
}): Promise<TovarishStatus> {
|
||||
const status = (await super.askRelayerStatus({
|
||||
netId,
|
||||
hostname,
|
||||
url,
|
||||
relayerAddress,
|
||||
})) as TovarishStatus;
|
||||
|
||||
if (!status.version.includes('tovarish')) {
|
||||
@@ -121,14 +122,14 @@ export class TovarishClient extends RelayerClient {
|
||||
url = '';
|
||||
}
|
||||
|
||||
const statusArray = (await fetchData(`${url}status`, {
|
||||
const statusArray = await fetchData<TovarishStatus[]>(`${url}status`, {
|
||||
...this.fetchDataOptions,
|
||||
headers: {
|
||||
'Content-Type': 'application/json, application/x-www-form-urlencoded',
|
||||
},
|
||||
timeout: 30000,
|
||||
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0,
|
||||
})) as object;
|
||||
maxRetry: this.fetchDataOptions?.dispatcher ? 2 : 0,
|
||||
});
|
||||
|
||||
if (!Array.isArray(statusArray)) {
|
||||
return [];
|
||||
@@ -137,33 +138,25 @@ export class TovarishClient extends RelayerClient {
|
||||
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);
|
||||
const netId = rawStatus?.netId as NetIdType;
|
||||
const config = this.tornadoConfig.getConfig(netId);
|
||||
|
||||
const statusValidator = ajv.compile(
|
||||
getStatusSchema(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(rawStatus as any).netId,
|
||||
config,
|
||||
this.tovarish,
|
||||
),
|
||||
);
|
||||
const statusValidator = ajv.compile(getStatusSchema(config, this.tovarish));
|
||||
|
||||
if (!statusValidator) {
|
||||
if (!statusValidator(rawStatus)) {
|
||||
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)) {
|
||||
if (!this.tornadoConfig.chains.includes(status.netId)) {
|
||||
throw new Error('This relayer serves a different network');
|
||||
}
|
||||
|
||||
@@ -181,17 +174,21 @@ export class TovarishClient extends RelayerClient {
|
||||
return tovarishStatus;
|
||||
}
|
||||
|
||||
async filterRelayer(relayer: CachedRelayerInfo): Promise<TovarishInfo | RelayerError | undefined> {
|
||||
async filterRelayer(
|
||||
netId: NetIdType,
|
||||
relayer: CachedRelayerInfo,
|
||||
): Promise<TovarishInfo | RelayerError | undefined> {
|
||||
const { ensName, relayerAddress, tovarishHost, tovarishNetworks } = relayer;
|
||||
|
||||
if (!tovarishHost || !tovarishNetworks?.includes(this.netId)) {
|
||||
if (!tovarishHost || !tovarishNetworks?.includes(netId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hostname = `${tovarishHost}/${this.netId}`;
|
||||
const hostname = `${tovarishHost}/${netId}`;
|
||||
|
||||
try {
|
||||
const status = await this.askRelayerStatus({
|
||||
netId,
|
||||
hostname,
|
||||
relayerAddress,
|
||||
});
|
||||
@@ -228,13 +225,16 @@ export class TovarishClient extends RelayerClient {
|
||||
}
|
||||
}
|
||||
|
||||
async getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
async getValidRelayers(
|
||||
netId: NetIdType,
|
||||
relayers: CachedRelayerInfo[],
|
||||
): Promise<{
|
||||
validRelayers: TovarishInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}> {
|
||||
const invalidRelayers: RelayerError[] = [];
|
||||
|
||||
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
|
||||
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(netId, relayer)))).filter(
|
||||
(r) => {
|
||||
if (!r) {
|
||||
return false;
|
||||
@@ -327,7 +327,6 @@ export class TovarishClient extends RelayerClient {
|
||||
const events = [];
|
||||
let lastSyncBlock = fromBlock;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let { events: fetchedEvents, lastSyncBlock: currentBlock } = (await fetchData(url, {
|
||||
|
||||
14
src/utils.ts
14
src/utils.ts
@@ -112,7 +112,7 @@ export function leInt2Buff(bigint: bnInput | bigint) {
|
||||
return Uint8Array.from(new BN(bigint as bnInput).toArray('le', 31));
|
||||
}
|
||||
|
||||
// Inherited from tornado-core and tornado-cli
|
||||
// Inherited from tornado-scripts and tornado-cli
|
||||
export function toFixedHex(numberish: BigNumberish, length = 32) {
|
||||
return (
|
||||
'0x' +
|
||||
@@ -122,17 +122,17 @@ export function toFixedHex(numberish: BigNumberish, length = 32) {
|
||||
);
|
||||
}
|
||||
|
||||
export function toFixedLength(string: string, length: number = 32) {
|
||||
export function toFixedLength(string: string, length = 32) {
|
||||
string = string.replace('0x', '');
|
||||
return '0x' + string.padStart(length * 2, '0');
|
||||
}
|
||||
|
||||
// Random BigInt in a range of bytes
|
||||
export function rBigInt(nbytes: number = 31) {
|
||||
export function rBigInt(nbytes = 31) {
|
||||
return bytesToBN(crypto.getRandomValues(new Uint8Array(nbytes)));
|
||||
}
|
||||
|
||||
export function rHex(nbytes: number = 32) {
|
||||
export function rHex(nbytes = 32) {
|
||||
return bytesToHex(crypto.getRandomValues(new Uint8Array(nbytes)));
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ export function bigIntReplacer(key: any, value: any) {
|
||||
return typeof value === 'bigint' ? value.toString() : value;
|
||||
}
|
||||
|
||||
export function substring(str: string, length: number = 10) {
|
||||
export function substring(str: string, length = 10) {
|
||||
if (str.length < length * 2) {
|
||||
return str;
|
||||
}
|
||||
@@ -150,11 +150,11 @@ export function substring(str: string, length: number = 10) {
|
||||
return `${str.substring(0, length)}...${str.substring(str.length - length)}`;
|
||||
}
|
||||
|
||||
export async function digest(bytes: Uint8Array, algo: string = 'SHA-384') {
|
||||
export async function digest(bytes: Uint8Array, algo = 'SHA-384') {
|
||||
return new Uint8Array(await crypto.subtle.digest(algo, bytes));
|
||||
}
|
||||
|
||||
export function numberFormatter(num: string | number | bigint, digits: number = 3): string {
|
||||
export function numberFormatter(num: string | number | bigint, digits = 3): string {
|
||||
const lookup = [
|
||||
{ value: 1, symbol: '' },
|
||||
{ value: 1e3, symbol: 'K' },
|
||||
|
||||
41
src/zip.ts
41
src/zip.ts
@@ -1,5 +1,15 @@
|
||||
import { zip, unzip, AsyncZippable, Unzipped, ZipAttributes } from 'fflate';
|
||||
import { fetchData } from './providers';
|
||||
import {
|
||||
zip,
|
||||
unzip,
|
||||
AsyncZippable,
|
||||
Unzipped,
|
||||
ZipAttributes,
|
||||
zlib,
|
||||
unzlib,
|
||||
AsyncZlibOptions,
|
||||
AsyncUnzlibOptions,
|
||||
} from 'fflate';
|
||||
import { fetchData, fetchDataOptions } from './providers';
|
||||
import { bytesToBase64, digest } from './utils';
|
||||
|
||||
export function zipAsync(file: AsyncZippable, options?: ZipAttributes): Promise<Uint8Array> {
|
||||
@@ -26,20 +36,47 @@ export function unzipAsync(data: Uint8Array): Promise<Unzipped> {
|
||||
});
|
||||
}
|
||||
|
||||
export function zlibAsync(data: Uint8Array, options?: AsyncZlibOptions): Promise<Uint8Array> {
|
||||
return new Promise((res, rej) => {
|
||||
zlib(data, { ...(options || {}) }, (err, data) => {
|
||||
if (err) {
|
||||
rej(err);
|
||||
return;
|
||||
}
|
||||
res(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function unzlibAsync(data: Uint8Array, options?: AsyncUnzlibOptions): Promise<Uint8Array> {
|
||||
return new Promise((res, rej) => {
|
||||
unzlib(data, { ...(options || {}) }, (err, data) => {
|
||||
if (err) {
|
||||
rej(err);
|
||||
return;
|
||||
}
|
||||
res(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function downloadZip<T>({
|
||||
staticUrl = '',
|
||||
zipName,
|
||||
zipDigest,
|
||||
parseJson = true,
|
||||
fetchOptions,
|
||||
}: {
|
||||
staticUrl?: string;
|
||||
zipName: string;
|
||||
zipDigest?: string;
|
||||
parseJson?: boolean;
|
||||
fetchOptions?: fetchDataOptions;
|
||||
}): Promise<T> {
|
||||
const url = `${staticUrl}/${zipName}.zip`;
|
||||
|
||||
const resp = (await fetchData(url, {
|
||||
...(fetchOptions || {}),
|
||||
method: 'GET',
|
||||
returnResponse: true,
|
||||
})) as Response;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ethers } from 'hardhat';
|
||||
import { expect } from 'chai';
|
||||
import { formatEther } from 'ethers';
|
||||
|
||||
import { ETHTornado__factory, Verifier__factory } from '@tornado/contracts';
|
||||
import { ETHTornado__factory, Verifier__factory } from 'tornado-contracts';
|
||||
import { Deposit, deployHasher } from '../src';
|
||||
|
||||
const { getSigners } = ethers;
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["./src/**/*"],
|
||||
"exclude": ["./test/**/*"],
|
||||
"files": []
|
||||
}
|
||||
@@ -110,6 +110,9 @@
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
},
|
||||
"include": ["./src/**/*"],
|
||||
"include": [
|
||||
"./src/**/*",
|
||||
"./test/**/*"
|
||||
],
|
||||
"files": ["./hardhat.config.ts"]
|
||||
}
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
const { BannerPlugin } = require('webpack');
|
||||
const { BannerPlugin, ProvidePlugin } = require('webpack');
|
||||
const path = require('path');
|
||||
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
|
||||
|
||||
const esbuildLoader = {
|
||||
test: /\.ts?$/,
|
||||
loader: 'esbuild-loader',
|
||||
options: {
|
||||
loader: 'ts',
|
||||
target: 'es2022',
|
||||
const commonRules = [
|
||||
{
|
||||
test: /\.ts?$/,
|
||||
loader: 'esbuild-loader',
|
||||
options: {
|
||||
loader: 'ts',
|
||||
target: 'es2022',
|
||||
}
|
||||
},
|
||||
// Disable strict dependency resolution for ESM modules, so that polyfill plugin can handle the rest
|
||||
{
|
||||
test: /\.m?js$/,
|
||||
resolve: {
|
||||
fullySpecified: false
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const commonAlias = {
|
||||
fs: false,
|
||||
@@ -26,7 +35,7 @@ module.exports = [
|
||||
{
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [esbuildLoader]
|
||||
rules: [...commonRules]
|
||||
},
|
||||
entry: './src/index.ts',
|
||||
output: {
|
||||
@@ -37,11 +46,18 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
new NodePolyfillPlugin(),
|
||||
new ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
Buffer: ['buffer', 'Buffer']
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
alias: {
|
||||
...commonAlias,
|
||||
},
|
||||
fallback: {
|
||||
'process/browser': require.resolve('process/browser'),
|
||||
}
|
||||
},
|
||||
optimization: {
|
||||
@@ -51,7 +67,7 @@ module.exports = [
|
||||
{
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [esbuildLoader]
|
||||
rules: [...commonRules]
|
||||
},
|
||||
entry: './src/index.ts',
|
||||
output: {
|
||||
@@ -62,18 +78,25 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
new NodePolyfillPlugin(),
|
||||
new ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
Buffer: ['buffer', 'Buffer']
|
||||
}),
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
alias: {
|
||||
...commonAlias,
|
||||
},
|
||||
fallback: {
|
||||
'process/browser': require.resolve('process/browser'),
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [esbuildLoader]
|
||||
rules: [...commonRules]
|
||||
},
|
||||
entry: './src/merkleTreeWorker.ts',
|
||||
output: {
|
||||
@@ -83,6 +106,10 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
new NodePolyfillPlugin(),
|
||||
new ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
Buffer: ['buffer', 'Buffer']
|
||||
}),
|
||||
new BannerPlugin({
|
||||
banner: 'globalThis.process = { browser: true, env: {}, };\n',
|
||||
raw: true,
|
||||
@@ -92,6 +119,9 @@ module.exports = [
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
alias: {
|
||||
...commonAlias,
|
||||
},
|
||||
fallback: {
|
||||
'process/browser': require.resolve('process/browser'),
|
||||
}
|
||||
},
|
||||
optimization: {
|
||||
@@ -101,7 +131,7 @@ module.exports = [
|
||||
{
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [esbuildLoader]
|
||||
rules: [...commonRules]
|
||||
},
|
||||
entry: './src/merkleTreeWorker.ts',
|
||||
output: {
|
||||
@@ -111,6 +141,10 @@ module.exports = [
|
||||
},
|
||||
plugins: [
|
||||
new NodePolyfillPlugin(),
|
||||
new ProvidePlugin({
|
||||
process: 'process/browser',
|
||||
Buffer: ['buffer', 'Buffer']
|
||||
}),
|
||||
new BannerPlugin({
|
||||
banner: 'globalThis.process = { browser: true, env: {}, };',
|
||||
raw: true,
|
||||
@@ -120,13 +154,16 @@ module.exports = [
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
alias: {
|
||||
...commonAlias,
|
||||
},
|
||||
fallback: {
|
||||
'process/browser': require.resolve('process/browser'),
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [esbuildLoader]
|
||||
rules: [...commonRules]
|
||||
},
|
||||
entry: './src/contracts.ts',
|
||||
output: {
|
||||
@@ -151,7 +188,7 @@ module.exports = [
|
||||
{
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [esbuildLoader]
|
||||
rules: [...commonRules]
|
||||
},
|
||||
entry: './src/contracts.ts',
|
||||
output: {
|
||||
|
||||
Reference in New Issue
Block a user