Compare commits
75 Commits
main
...
960321e9bd
| Author | SHA1 | Date | |
|---|---|---|---|
|
960321e9bd
|
|||
|
309a53600c
|
|||
|
6d5f2681f4
|
|||
|
93a2049879
|
|||
|
8b6887108f
|
|||
|
b35e53ebdb
|
|||
|
2337892195
|
|||
|
68fcf07c2a
|
|||
|
69f89ae597
|
|||
|
72c6b92b07
|
|||
|
b65998fca5
|
|||
|
092989ebaa
|
|||
|
94a62e6193
|
|||
|
88b6e20aa1
|
|||
|
df54da689c
|
|||
|
efda9143dd
|
|||
|
f411159f15
|
|||
|
68f2e006ce
|
|||
|
b9fa95f5be
|
|||
|
69066e4fd1
|
|||
|
34d687c319
|
|||
|
55d62f7973
|
|||
|
e3dc748020
|
|||
|
9f4044d110
|
|||
|
6549fac5dd
|
|||
|
3d3b987635
|
|||
|
dfb20aa617
|
|||
|
ddf306a835
|
|||
|
75f57937e3
|
|||
|
6ab73c7d59
|
|||
|
8600bd8842
|
|||
|
0e2da438ca
|
|||
|
f3a8438187
|
|||
|
666b0eba66
|
|||
|
4f0aaea790
|
|||
|
d87e6c51f7
|
|||
|
0ebd4d175f
|
|||
|
fb33815290
|
|||
|
901281a59d
|
|||
|
b9f891644d
|
|||
|
4517393017
|
|||
|
51f737b728
|
|||
|
58b3110125
|
|||
|
42db44ca3b
|
|||
|
f73b9ecbff
|
|||
|
2092214da2
|
|||
|
4a884e4f41
|
|||
|
6aa7ecd311
|
|||
|
0d159939d9
|
|||
|
61266bdb6e
|
|||
|
a00dab8d06
|
|||
|
be0e2419aa
|
|||
|
bdcf48db73
|
|||
|
df1fcebfe3
|
|||
|
82aeabd739
|
|||
|
c155649719
|
|||
|
69faa7a974
|
|||
|
f7fdf7db0a
|
|||
|
d0b032d7be
|
|||
|
20368b243b
|
|||
|
29744cfce4
|
|||
|
48bb7aed82
|
|||
|
d6cfea1d19
|
|||
|
0bd87f9b67
|
|||
|
2bd991aa45
|
|||
|
700426acb7
|
|||
|
ef56beb29b
|
|||
|
e506c373de
|
|||
|
3df238e55f
|
|||
|
95dbf208c3
|
|||
|
84b6ed368e
|
|||
|
391ca0df37
|
|||
|
cf9e32f46d
|
|||
|
29bd7dc66e
|
|||
|
b32cf2dbbc
|
103
.eslintrc.js
103
.eslintrc.js
@@ -1,65 +1,44 @@
|
||||
module.exports = {
|
||||
"env": {
|
||||
"es2021": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:import/recommended",
|
||||
"plugin:import/typescript",
|
||||
"prettier",
|
||||
"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",
|
||||
{
|
||||
singleQuote: true,
|
||||
printWidth: 120
|
||||
}
|
||||
env: {
|
||||
es2021: true,
|
||||
node: true,
|
||||
},
|
||||
extends: [
|
||||
'prettier',
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:prettier/recommended',
|
||||
],
|
||||
"import/order": ["error"],
|
||||
/**
|
||||
"indent": [
|
||||
"error",
|
||||
2
|
||||
overrides: [
|
||||
{
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
files: ['.eslintrc.{js,cjs}'],
|
||||
parserOptions: {
|
||||
sourceType: 'script',
|
||||
},
|
||||
},
|
||||
],
|
||||
**/
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
"unix"
|
||||
],
|
||||
"quotes": [
|
||||
"error",
|
||||
"single"
|
||||
],
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": ["warn"]
|
||||
}
|
||||
}
|
||||
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'],
|
||||
},
|
||||
};
|
||||
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,7 +1,7 @@
|
||||
node_modules
|
||||
.env
|
||||
/events
|
||||
/trees
|
||||
backup-tornado-*
|
||||
backup-tornadoInvoice-*
|
||||
backup-note-account-*
|
||||
|
||||
# coverage files
|
||||
/coverage
|
||||
/coverage.json
|
||||
.nyc_output
|
||||
13
.nycrc
Normal file
13
.nycrc
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"all": true,
|
||||
"extension": [".ts"],
|
||||
"report-dir": "coverage",
|
||||
"reporter": [
|
||||
"html",
|
||||
"lcov",
|
||||
"text",
|
||||
"text-summary"
|
||||
],
|
||||
"include": ["src/**/*.ts"],
|
||||
"exclude": ["src/typechain/**/*"]
|
||||
}
|
||||
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
||||
# Dockefile from https://notes.ethereum.org/@GW1ZUbNKR5iRjjKYx6_dJQ/Bk8zsJ9xj
|
||||
# FROM node:20.18.0-bullseye-slim
|
||||
FROM node@sha256:9b558df8f10198fcd1f48cf344c55c4442c3446b8a9a69487523b3d890a4a59e
|
||||
|
||||
# install wget, git and necessary certificates
|
||||
RUN apt update && apt install --yes --no-install-recommends wget git apt-transport-https ca-certificates && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV GIT_REPOSITORY=https://git.tornado.ws/tornadocontrib/tornado-core.git
|
||||
# From development branch, double check with tornado.ws
|
||||
ENV GIT_COMMIT_HASH=309a53600ce4e17b8d3225ca5923bdf280edaaf0
|
||||
|
||||
# clone the repository
|
||||
RUN mkdir /app/
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Simple hack to fetch only commit and nothing more (no need to download 1GB sized repo, only 100MB would be enough)
|
||||
RUN git init && \
|
||||
git remote add origin $GIT_REPOSITORY && \
|
||||
git fetch --depth 1 origin $GIT_COMMIT_HASH && \
|
||||
git checkout $GIT_COMMIT_HASH
|
||||
|
||||
# install, build and prep for deployment
|
||||
RUN yarn install --frozen-lockfile --ignore-scripts
|
||||
RUN yarn build
|
||||
24
dist/batch.d.ts
vendored
24
dist/batch.d.ts
vendored
@@ -1,4 +1,14 @@
|
||||
import type { Provider, BlockTag, Block, TransactionResponse, BaseContract, ContractEventName, EventLog } from 'ethers';
|
||||
import { Provider, BlockTag, Block, TransactionResponse, BaseContract, ContractEventName, EventLog, TransactionReceipt, EventFragment, TopicFilter, Interface, Log } from 'ethers';
|
||||
/**
|
||||
* Copied from ethers.js as they don't export this function
|
||||
* https://github.com/ethers-io/ethers.js/blob/main/src.ts/contract/contract.ts#L464
|
||||
*/
|
||||
export declare function getSubInfo(abiInterface: Interface, event: ContractEventName): Promise<{
|
||||
fragment: null | EventFragment;
|
||||
tag: string;
|
||||
topics: TopicFilter;
|
||||
}>;
|
||||
export declare function multiQueryFilter(address: string | string[], contract: BaseContract, event: ContractEventName, fromBlock?: BlockTag, toBlock?: BlockTag): Promise<Log[]>;
|
||||
export interface BatchBlockServiceConstructor {
|
||||
provider: Provider;
|
||||
onProgress?: BatchBlockOnProgress;
|
||||
@@ -42,12 +52,15 @@ export declare class BatchTransactionService {
|
||||
retryOn: number;
|
||||
constructor({ provider, onProgress, concurrencySize, batchSize, shouldRetry, retryMax, retryOn, }: BatchBlockServiceConstructor);
|
||||
getTransaction(txHash: string): Promise<TransactionResponse>;
|
||||
createBatchRequest(batchArray: string[][]): Promise<TransactionResponse[]>[];
|
||||
getTransactionReceipt(txHash: string): Promise<TransactionReceipt>;
|
||||
createBatchRequest(batchArray: string[][], receipt?: boolean): Promise<TransactionResponse[] | TransactionReceipt[]>[];
|
||||
getBatchTransactions(txs: string[]): Promise<TransactionResponse[]>;
|
||||
getBatchReceipt(txs: string[]): Promise<TransactionReceipt[]>;
|
||||
}
|
||||
export interface BatchEventServiceConstructor {
|
||||
provider: Provider;
|
||||
contract: BaseContract;
|
||||
address?: string | string[];
|
||||
onProgress?: BatchEventOnProgress;
|
||||
concurrencySize?: number;
|
||||
blocksPerRequest?: number;
|
||||
@@ -62,24 +75,25 @@ export type BatchEventOnProgress = ({ percentage, type, fromBlock, toBlock, coun
|
||||
toBlock?: number;
|
||||
count?: number;
|
||||
}) => void;
|
||||
export type EventInput = {
|
||||
export interface EventInput {
|
||||
fromBlock: number;
|
||||
toBlock: number;
|
||||
type: ContractEventName;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Fetch events from web3 provider on bulk
|
||||
*/
|
||||
export declare class BatchEventsService {
|
||||
provider: Provider;
|
||||
contract: BaseContract;
|
||||
address?: string | string[];
|
||||
onProgress?: BatchEventOnProgress;
|
||||
concurrencySize: number;
|
||||
blocksPerRequest: number;
|
||||
shouldRetry: boolean;
|
||||
retryMax: number;
|
||||
retryOn: number;
|
||||
constructor({ provider, contract, onProgress, concurrencySize, blocksPerRequest, shouldRetry, retryMax, retryOn, }: BatchEventServiceConstructor);
|
||||
constructor({ provider, contract, address, onProgress, concurrencySize, blocksPerRequest, shouldRetry, retryMax, retryOn, }: BatchEventServiceConstructor);
|
||||
getPastEvents({ fromBlock, toBlock, type }: EventInput): Promise<EventLog[]>;
|
||||
createBatchRequest(batchArray: EventInput[]): Promise<EventLog[]>[];
|
||||
getBatchEvents({ fromBlock, toBlock, type }: EventInput): Promise<EventLog[]>;
|
||||
|
||||
2
dist/contracts.d.ts
vendored
Normal file
2
dist/contracts.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
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';
|
||||
40
dist/deposits.d.ts
vendored
40
dist/deposits.d.ts
vendored
@@ -1,36 +1,35 @@
|
||||
import type { NetIdType } from './networkConfig';
|
||||
export type DepositType = {
|
||||
export interface DepositType {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
};
|
||||
export type createDepositParams = {
|
||||
}
|
||||
export interface createDepositParams {
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
};
|
||||
export type createDepositObject = {
|
||||
}
|
||||
export interface createDepositObject {
|
||||
preimage: Uint8Array;
|
||||
noteHex: string;
|
||||
commitment: bigint;
|
||||
commitmentHex: string;
|
||||
nullifierHash: bigint;
|
||||
nullifierHex: string;
|
||||
};
|
||||
export type createNoteParams = DepositType & {
|
||||
}
|
||||
export interface createNoteParams extends DepositType {
|
||||
nullifier?: bigint;
|
||||
secret?: bigint;
|
||||
};
|
||||
export type parsedNoteExec = DepositType & {
|
||||
}
|
||||
export interface parsedNoteExec extends DepositType {
|
||||
note: string;
|
||||
};
|
||||
export type depositTx = {
|
||||
from: string;
|
||||
transactionHash: string;
|
||||
};
|
||||
export type withdrawalTx = {
|
||||
to: string;
|
||||
transactionHash: string;
|
||||
};
|
||||
noteHex: string;
|
||||
}
|
||||
export interface parsedInvoiceExec extends DepositType {
|
||||
invoice: string;
|
||||
commitmentHex: string;
|
||||
}
|
||||
export declare function parseNote(noteString: string): parsedNoteExec | undefined;
|
||||
export declare function parseInvoice(invoiceString: string): parsedInvoiceExec | undefined;
|
||||
export declare function createDeposit({ nullifier, secret }: createDepositParams): Promise<createDepositObject>;
|
||||
export interface DepositConstructor {
|
||||
currency: string;
|
||||
@@ -60,14 +59,11 @@ export declare class Deposit {
|
||||
static createNote({ currency, amount, netId, nullifier, secret }: createNoteParams): Promise<Deposit>;
|
||||
static parseNote(noteString: string): Promise<Deposit>;
|
||||
}
|
||||
export type parsedInvoiceExec = DepositType & {
|
||||
commitment: string;
|
||||
};
|
||||
export declare class Invoice {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
commitment: string;
|
||||
commitmentHex: string;
|
||||
invoice: string;
|
||||
constructor(invoiceString: string);
|
||||
toString(): string;
|
||||
|
||||
14
dist/encryptedNotes.d.ts
vendored
14
dist/encryptedNotes.d.ts
vendored
@@ -1,8 +1,6 @@
|
||||
import { EthEncryptedData } from '@metamask/eth-sig-util';
|
||||
import { Echoer } from '@tornado/contracts';
|
||||
import { Wallet } from 'ethers';
|
||||
import { Signer, Wallet } from 'ethers';
|
||||
import { EchoEvents, EncryptedNotesEvents } from './events';
|
||||
import type { NetIdType } from './networkConfig';
|
||||
export interface NoteToEncrypt {
|
||||
address: string;
|
||||
noteHex: string;
|
||||
@@ -17,24 +15,20 @@ export declare function unpackEncryptedMessage(encryptedMessage: string): EthEnc
|
||||
messageBuff: string;
|
||||
};
|
||||
export interface NoteAccountConstructor {
|
||||
netId: NetIdType;
|
||||
blockNumber?: number;
|
||||
recoveryKey?: string;
|
||||
Echoer: Echoer;
|
||||
}
|
||||
export declare class NoteAccount {
|
||||
netId: NetIdType;
|
||||
blockNumber?: number;
|
||||
recoveryKey: string;
|
||||
recoveryAddress: string;
|
||||
recoveryPublicKey: string;
|
||||
Echoer: Echoer;
|
||||
constructor({ netId, blockNumber, recoveryKey, Echoer }: NoteAccountConstructor);
|
||||
constructor({ blockNumber, recoveryKey }: NoteAccountConstructor);
|
||||
/**
|
||||
* Intends to mock eth_getEncryptionPublicKey behavior from MetaMask
|
||||
* In order to make the recoveryKey retrival from Echoer possible from the bare private key
|
||||
*/
|
||||
static getWalletPublicKey(wallet: Wallet): string;
|
||||
static getSignerPublicKey(signer: Signer | Wallet): Promise<string>;
|
||||
getEncryptedAccount(walletPublicKey: string): {
|
||||
encryptedData: EthEncryptedData;
|
||||
data: string;
|
||||
@@ -42,7 +36,7 @@ export declare class NoteAccount {
|
||||
/**
|
||||
* Decrypt Echoer backuped note encryption account with private keys
|
||||
*/
|
||||
decryptAccountsWithWallet(wallet: Wallet, events: EchoEvents[]): NoteAccount[];
|
||||
static decryptSignerNoteAccounts(signer: Signer | Wallet, events: EchoEvents[]): Promise<NoteAccount[]>;
|
||||
decryptNotes(events: EncryptedNotesEvents[]): DecryptedNotes[];
|
||||
encryptNote({ address, noteHex }: NoteToEncrypt): string;
|
||||
}
|
||||
|
||||
34
dist/ens.d.ts
vendored
Normal file
34
dist/ens.d.ts
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import { EnsResolver, AbstractProvider, Signer } from 'ethers';
|
||||
import { ENSNameWrapper, ENSRegistry, ENSResolver } from './typechain';
|
||||
import { NetIdType } from './networkConfig';
|
||||
export declare function encodedLabelToLabelhash(label: string): string | null;
|
||||
export declare function labelhash(label: string): string;
|
||||
export declare function makeLabelNodeAndParent(name: string): {
|
||||
label: string;
|
||||
labelhash: string;
|
||||
parentNode: string;
|
||||
};
|
||||
export declare const EnsContracts: {
|
||||
[key: NetIdType]: {
|
||||
ensRegistry: string;
|
||||
ensPublicResolver: string;
|
||||
ensNameWrapper: string;
|
||||
};
|
||||
};
|
||||
/**
|
||||
* ENSUtils to manage on-chain registered relayers
|
||||
*/
|
||||
export declare class ENSUtils {
|
||||
ENSRegistry?: ENSRegistry;
|
||||
ENSResolver?: ENSResolver;
|
||||
ENSNameWrapper?: ENSNameWrapper;
|
||||
provider: AbstractProvider;
|
||||
constructor(provider: AbstractProvider);
|
||||
getContracts(): Promise<void>;
|
||||
getOwner(name: string): Promise<string>;
|
||||
unwrap(signer: Signer, name: string): Promise<import("ethers").ContractTransactionResponse>;
|
||||
setSubnodeRecord(signer: Signer, name: string): Promise<import("ethers").ContractTransactionResponse>;
|
||||
getResolver(name: string): Promise<EnsResolver | null>;
|
||||
getText(name: string, key: string): Promise<string | null>;
|
||||
setText(signer: Signer, name: string, key: string, value: string): Promise<import("ethers").ContractTransactionResponse>;
|
||||
}
|
||||
324
dist/events/base.d.ts
vendored
324
dist/events/base.d.ts
vendored
@@ -1,67 +1,53 @@
|
||||
import { BaseContract, Provider, EventLog, ContractEventName } from 'ethers';
|
||||
import type { Tornado, TornadoRouter, TornadoProxyLight, Governance, RelayerRegistry, Echoer } from '@tornado/contracts';
|
||||
import { BaseContract, Provider, EventLog } from 'ethers';
|
||||
import { Tornado, TornadoRouter, TornadoProxyLight, Governance, RelayerRegistry, Echoer, Aggregator } 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 } from '../networkConfig';
|
||||
import type { BaseEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, RegistersEvents, EchoEvents } from './types';
|
||||
export declare const DEPOSIT = "deposit";
|
||||
export declare const WITHDRAWAL = "withdrawal";
|
||||
export type BaseEventsServiceConstructor = {
|
||||
import { type NetIdType, type SubdomainMap } from '../networkConfig';
|
||||
import { RelayerParams } from '../relayerClient';
|
||||
import type { TovarishClient } from '../tovarishClient';
|
||||
import type { ERC20, ReverseRecords } from '../typechain';
|
||||
import type { MerkleTreeService } from '../merkleTree';
|
||||
import type { DepositType } from '../deposits';
|
||||
import type { BaseEvents, CachedEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, GovernanceProposalCreatedEvents, GovernanceVotedEvents, EchoEvents, AllRelayerRegistryEvents, StakeBurnedEvents, MultiDepositsEvents, MultiWithdrawalsEvents, TransferEvents } from './types';
|
||||
export interface BaseEventsServiceConstructor {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
graphApi?: string;
|
||||
subgraphName?: string;
|
||||
contract: BaseContract;
|
||||
type?: string;
|
||||
type: string;
|
||||
deployedBlock?: number;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
};
|
||||
export type BatchGraphOnProgress = ({ type, fromBlock, toBlock, count, }: {
|
||||
type?: ContractEventName;
|
||||
fromBlock?: number;
|
||||
toBlock?: number;
|
||||
count?: number;
|
||||
}) => void;
|
||||
export type BaseGraphParams = {
|
||||
graphApi: string;
|
||||
subgraphName: string;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
onProgress?: BatchGraphOnProgress;
|
||||
};
|
||||
tovarishClient?: TovarishClient;
|
||||
}
|
||||
export declare class BaseEventsService<EventType extends MinimalEvents> {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
graphApi?: string;
|
||||
subgraphName?: string;
|
||||
contract: BaseContract;
|
||||
type: string;
|
||||
deployedBlock: number;
|
||||
batchEventsService: BatchEventsService;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
saveEventsPromise?: Promise<void>;
|
||||
constructor({ netId, provider, graphApi, subgraphName, contract, type, deployedBlock, fetchDataOptions, }: BaseEventsServiceConstructor);
|
||||
tovarishClient?: TovarishClient;
|
||||
constructor({ netId, provider, contract, type, deployedBlock, fetchDataOptions, tovarishClient, }: BaseEventsServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getType(): string;
|
||||
getGraphMethod(): string;
|
||||
getGraphParams(): BaseGraphParams;
|
||||
getTovarishType(): string;
|
||||
updateEventProgress({ percentage, type, fromBlock, toBlock, count }: Parameters<BatchEventOnProgress>[0]): void;
|
||||
updateBlockProgress({ percentage, currentIndex, totalIndex }: Parameters<BatchBlockOnProgress>[0]): void;
|
||||
updateTransactionProgress({ percentage, currentIndex, totalIndex }: Parameters<BatchBlockOnProgress>[0]): void;
|
||||
updateGraphProgress({ type, fromBlock, toBlock, count }: Parameters<BatchGraphOnProgress>[0]): void;
|
||||
formatEvents(events: EventLog[]): Promise<EventType[]>;
|
||||
/**
|
||||
* Get saved or cached events
|
||||
*/
|
||||
getEventsFromDB(): Promise<BaseEvents<EventType>>;
|
||||
getEventsFromCache(): Promise<BaseEvents<EventType>>;
|
||||
getSavedEvents(): Promise<BaseEvents<EventType>>;
|
||||
/**
|
||||
* Get latest events
|
||||
* Events from remote cache (Either from local cache, CDN, or from IPFS)
|
||||
*/
|
||||
getEventsFromGraph({ fromBlock, methodName, }: {
|
||||
fromBlock: number;
|
||||
methodName?: string;
|
||||
}): Promise<BaseEvents<EventType>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<EventType>>;
|
||||
/**
|
||||
* This may not return in sorted events when called from browser, make sure to sort it again when directly called
|
||||
*/
|
||||
getSavedEvents(): Promise<BaseEvents<EventType> | CachedEvents<EventType>>;
|
||||
getEventsFromRpc({ fromBlock, toBlock, }: {
|
||||
fromBlock: number;
|
||||
toBlock?: number;
|
||||
@@ -69,124 +55,210 @@ export declare class BaseEventsService<EventType extends MinimalEvents> {
|
||||
getLatestEvents({ fromBlock }: {
|
||||
fromBlock: number;
|
||||
}): Promise<BaseEvents<EventType>>;
|
||||
validateEvents({ events, lastBlock }: BaseEvents<EventType>): void;
|
||||
validateEvents<S>({ events, newEvents, lastBlock, }: BaseEvents<EventType> & {
|
||||
newEvents: EventType[];
|
||||
}): Promise<S>;
|
||||
/**
|
||||
* Handle saving events
|
||||
*/
|
||||
saveEvents({ events, lastBlock }: BaseEvents<EventType>): Promise<void>;
|
||||
saveEvents({ events, newEvents, lastBlock }: BaseEvents<EventType> & {
|
||||
newEvents: EventType[];
|
||||
}): Promise<void>;
|
||||
/**
|
||||
* Trigger saving and receiving latest events
|
||||
*/
|
||||
updateEvents(): Promise<{
|
||||
updateEvents<S>(): Promise<{
|
||||
events: EventType[];
|
||||
lastBlock: number | null;
|
||||
lastBlock: number;
|
||||
validateResult: Awaited<S>;
|
||||
}>;
|
||||
}
|
||||
export type BaseTornadoServiceConstructor = {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
graphApi?: string;
|
||||
subgraphName?: string;
|
||||
export interface BaseTornadoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract'> {
|
||||
Tornado: Tornado;
|
||||
type: string;
|
||||
amount: string;
|
||||
currency: string;
|
||||
deployedBlock?: number;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
};
|
||||
export type DepositsGraphParams = BaseGraphParams & {
|
||||
amount: string;
|
||||
currency: string;
|
||||
};
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
}
|
||||
export declare class BaseTornadoService extends BaseEventsService<DepositsEvents | WithdrawalsEvents> {
|
||||
amount: string;
|
||||
currency: string;
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
batchTransactionService: BatchTransactionService;
|
||||
batchBlockService: BatchBlockService;
|
||||
constructor({ netId, provider, graphApi, subgraphName, Tornado, type, amount, currency, deployedBlock, fetchDataOptions, }: BaseTornadoServiceConstructor);
|
||||
constructor(serviceConstructor: BaseTornadoServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getGraphMethod(): string;
|
||||
getGraphParams(): DepositsGraphParams;
|
||||
formatEvents(events: EventLog[]): Promise<(DepositsEvents | WithdrawalsEvents)[]>;
|
||||
validateEvents({ events }: {
|
||||
events: (DepositsEvents | WithdrawalsEvents)[];
|
||||
}): void;
|
||||
}
|
||||
export type BaseEchoServiceConstructor = {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
graphApi?: string;
|
||||
subgraphName?: string;
|
||||
Echoer: Echoer;
|
||||
deployedBlock?: number;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
};
|
||||
export declare class BaseEchoService extends BaseEventsService<EchoEvents> {
|
||||
constructor({ netId, provider, graphApi, subgraphName, Echoer, deployedBlock, fetchDataOptions, }: BaseEchoServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getType(): string;
|
||||
getGraphMethod(): string;
|
||||
formatEvents(events: EventLog[]): Promise<EchoEvents[]>;
|
||||
getEventsFromGraph({ fromBlock }: {
|
||||
validateEvents<S>({ events, newEvents, }: BaseEvents<DepositsEvents | WithdrawalsEvents> & {
|
||||
newEvents: (DepositsEvents | WithdrawalsEvents)[];
|
||||
}): Promise<S>;
|
||||
getLatestEvents({ fromBlock, }: {
|
||||
fromBlock: number;
|
||||
}): Promise<BaseEvents<EchoEvents>>;
|
||||
}): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>>;
|
||||
}
|
||||
export type BaseEncryptedNotesServiceConstructor = {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
graphApi?: string;
|
||||
subgraphName?: string;
|
||||
Router: TornadoRouter | TornadoProxyLight;
|
||||
deployedBlock?: number;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
};
|
||||
export declare class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesEvents> {
|
||||
constructor({ netId, provider, graphApi, subgraphName, Router, deployedBlock, fetchDataOptions, }: BaseEncryptedNotesServiceConstructor);
|
||||
export interface BaseMultiTornadoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
instances: {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
}
|
||||
export declare class BaseMultiTornadoService extends BaseEventsService<MultiDepositsEvents | MultiWithdrawalsEvents> {
|
||||
instances: {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
optionalTree?: boolean;
|
||||
merkleTreeService?: MerkleTreeService;
|
||||
batchTransactionService: BatchTransactionService;
|
||||
batchBlockService: BatchBlockService;
|
||||
constructor(serviceConstructor: BaseMultiTornadoServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getType(): string;
|
||||
getGraphMethod(): string;
|
||||
getTovarishType(): string;
|
||||
formatEvents(events: EventLog[]): Promise<(MultiDepositsEvents | MultiWithdrawalsEvents)[]>;
|
||||
validateEvents<S>({ events, newEvents, }: BaseEvents<MultiDepositsEvents | MultiWithdrawalsEvents> & {
|
||||
newEvents: (MultiDepositsEvents | MultiWithdrawalsEvents)[];
|
||||
}): Promise<S>;
|
||||
getEvents(instanceAddress: string): Promise<{
|
||||
depositEvents: MultiDepositsEvents[];
|
||||
withdrawalEvents: MultiWithdrawalsEvents[];
|
||||
tree: MerkleTree | undefined;
|
||||
lastBlock: number;
|
||||
}>;
|
||||
}
|
||||
export interface BaseEchoServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Echoer: Echoer;
|
||||
}
|
||||
export declare class BaseEchoService extends BaseEventsService<EchoEvents> {
|
||||
constructor(serviceConstructor: BaseEchoServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
formatEvents(events: EventLog[]): Promise<EchoEvents[]>;
|
||||
}
|
||||
export interface BaseEncryptedNotesServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Router: TornadoRouter | TornadoProxyLight;
|
||||
}
|
||||
export declare class BaseEncryptedNotesService extends BaseEventsService<EncryptedNotesEvents> {
|
||||
constructor(serviceConstructor: BaseEncryptedNotesServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getTovarishType(): string;
|
||||
formatEvents(events: EventLog[]): Promise<EncryptedNotesEvents[]>;
|
||||
}
|
||||
export type BaseGovernanceServiceConstructor = {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
graphApi?: string;
|
||||
subgraphName?: string;
|
||||
export declare const proposalState: {
|
||||
[key: string]: string;
|
||||
};
|
||||
export interface GovernanceProposals extends GovernanceProposalCreatedEvents {
|
||||
title: string;
|
||||
proposerName?: string;
|
||||
forVotes: bigint;
|
||||
againstVotes: bigint;
|
||||
executed: boolean;
|
||||
extended: boolean;
|
||||
quorum: string;
|
||||
state: string;
|
||||
}
|
||||
export interface GovernanceVotes extends GovernanceVotedEvents {
|
||||
contact: string;
|
||||
message: string;
|
||||
fromName?: string;
|
||||
voterName?: string;
|
||||
}
|
||||
export interface BaseGovernanceServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Governance: Governance;
|
||||
deployedBlock?: number;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
};
|
||||
Aggregator: Aggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
}
|
||||
export declare class BaseGovernanceService extends BaseEventsService<AllGovernanceEvents> {
|
||||
Governance: Governance;
|
||||
Aggregator: Aggregator;
|
||||
ReverseRecords: ReverseRecords;
|
||||
batchTransactionService: BatchTransactionService;
|
||||
constructor({ netId, provider, graphApi, subgraphName, Governance, deployedBlock, fetchDataOptions, }: BaseGovernanceServiceConstructor);
|
||||
constructor(serviceConstructor: BaseGovernanceServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getType(): string;
|
||||
getGraphMethod(): string;
|
||||
getTovarishType(): string;
|
||||
formatEvents(events: EventLog[]): Promise<AllGovernanceEvents[]>;
|
||||
getEventsFromGraph({ fromBlock }: {
|
||||
fromBlock: number;
|
||||
}): Promise<BaseEvents<AllGovernanceEvents>>;
|
||||
getAllProposals(): Promise<GovernanceProposals[]>;
|
||||
getVotes(proposalId: number): Promise<GovernanceVotes[]>;
|
||||
getDelegatedBalance(ethAccount: string): Promise<{
|
||||
delegatedAccs: string[];
|
||||
undelegatedAccs: string[];
|
||||
uniq: string[];
|
||||
uniqNames: {
|
||||
[key: string]: string;
|
||||
};
|
||||
balances: bigint[];
|
||||
balance: bigint;
|
||||
}>;
|
||||
}
|
||||
export type BaseRegistryServiceConstructor = {
|
||||
netId: NetIdType;
|
||||
provider: Provider;
|
||||
graphApi?: string;
|
||||
subgraphName?: string;
|
||||
export declare function getTovarishNetworks(registryService: BaseRegistryService, relayers: CachedRelayerInfo[]): Promise<void>;
|
||||
/**
|
||||
* Essential params:
|
||||
* ensName, relayerAddress, hostnames
|
||||
* Other data is for historic purpose from relayer registry
|
||||
*/
|
||||
export interface CachedRelayerInfo extends RelayerParams {
|
||||
isRegistered?: boolean;
|
||||
registeredAddress?: string;
|
||||
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'> {
|
||||
RelayerRegistry: RelayerRegistry;
|
||||
deployedBlock?: number;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
};
|
||||
export declare class BaseRegistryService extends BaseEventsService<RegistersEvents> {
|
||||
constructor({ netId, provider, graphApi, subgraphName, RelayerRegistry, deployedBlock, fetchDataOptions, }: BaseRegistryServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getType(): string;
|
||||
getGraphMethod(): string;
|
||||
formatEvents(events: EventLog[]): Promise<{
|
||||
ensName: any;
|
||||
relayerAddress: any;
|
||||
blockNumber: number;
|
||||
logIndex: number;
|
||||
transactionHash: string;
|
||||
}[]>;
|
||||
fetchRelayers(): Promise<RegistersEvents[]>;
|
||||
Aggregator: Aggregator;
|
||||
relayerEnsSubdomains: SubdomainMap;
|
||||
}
|
||||
export declare class BaseRegistryService extends BaseEventsService<AllRelayerRegistryEvents> {
|
||||
Aggregator: Aggregator;
|
||||
relayerEnsSubdomains: SubdomainMap;
|
||||
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>;
|
||||
}
|
||||
export interface BaseRevenueServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
RelayerRegistry: RelayerRegistry;
|
||||
}
|
||||
/**
|
||||
* Tracks TORN burned events from RelayerRegistry contract
|
||||
*/
|
||||
export declare class BaseRevenueService extends BaseEventsService<StakeBurnedEvents> {
|
||||
batchTransactionService: BatchTransactionService;
|
||||
batchBlockService: BatchBlockService;
|
||||
constructor(serviceConstructor: BaseRevenueServiceConstructor);
|
||||
getInstanceName(): string;
|
||||
getTovarishType(): string;
|
||||
formatEvents(events: EventLog[]): Promise<StakeBurnedEvents[]>;
|
||||
}
|
||||
export interface BaseTransferServiceConstructor extends Omit<BaseEventsServiceConstructor, 'contract' | 'type'> {
|
||||
Token: ERC20;
|
||||
}
|
||||
export declare class BaseTransferService extends BaseEventsService<TransferEvents> {
|
||||
constructor(serviceConstructor: BaseTransferServiceConstructor);
|
||||
formatEvents(events: EventLog[]): Promise<TransferEvents[]>;
|
||||
}
|
||||
|
||||
129
dist/events/db.d.ts
vendored
Normal file
129
dist/events/db.d.ts
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
import { IndexedDB } from '../idb';
|
||||
import { BaseTornadoService, BaseTornadoServiceConstructor, BaseEchoService, BaseEchoServiceConstructor, BaseEncryptedNotesService, BaseEncryptedNotesServiceConstructor, BaseGovernanceService, BaseGovernanceServiceConstructor, BaseRegistryService, BaseRegistryServiceConstructor, BaseRevenueService, BaseRevenueServiceConstructor, CachedRelayers, BaseMultiTornadoService, BaseMultiTornadoServiceConstructor } from './base';
|
||||
import { BaseEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, CachedEvents, EchoEvents, EncryptedNotesEvents, AllGovernanceEvents, AllRelayerRegistryEvents, StakeBurnedEvents, MultiDepositsEvents, MultiWithdrawalsEvents } from './types';
|
||||
export declare function saveDBEvents<T extends MinimalEvents>({ idb, instanceName, newEvents, lastBlock, }: {
|
||||
idb: IndexedDB;
|
||||
instanceName: string;
|
||||
newEvents: T[];
|
||||
lastBlock: number;
|
||||
}): Promise<void>;
|
||||
export declare function loadDBEvents<T extends MinimalEvents>({ idb, instanceName, }: {
|
||||
idb: IndexedDB;
|
||||
instanceName: string;
|
||||
}): Promise<BaseEvents<T>>;
|
||||
export declare function loadRemoteEvents<T extends MinimalEvents>({ staticUrl, instanceName, deployedBlock, zipDigest, }: {
|
||||
staticUrl: string;
|
||||
instanceName: string;
|
||||
deployedBlock: number;
|
||||
zipDigest?: string;
|
||||
}): Promise<CachedEvents<T>>;
|
||||
export interface DBTornadoServiceConstructor extends BaseTornadoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
export declare class DBTornadoService extends BaseTornadoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
constructor(params: DBTornadoServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<DepositsEvents | WithdrawalsEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<DepositsEvents | WithdrawalsEvents>>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<DepositsEvents | WithdrawalsEvents> & {
|
||||
newEvents: (DepositsEvents | WithdrawalsEvents)[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBMultiTornadoServiceConstructor extends BaseMultiTornadoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
export declare class DBMultiTornadoService extends BaseMultiTornadoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
constructor(params: DBMultiTornadoServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<MultiDepositsEvents | MultiWithdrawalsEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<MultiDepositsEvents | MultiWithdrawalsEvents>>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<MultiDepositsEvents | MultiWithdrawalsEvents> & {
|
||||
newEvents: (MultiDepositsEvents | MultiWithdrawalsEvents)[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBEchoServiceConstructor extends BaseEchoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
export declare class DBEchoService extends BaseEchoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
constructor(params: DBEchoServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<EchoEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<EchoEvents>>;
|
||||
saveEvents({ newEvents, lastBlock }: BaseEvents<EchoEvents> & {
|
||||
newEvents: EchoEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBEncryptedNotesServiceConstructor extends BaseEncryptedNotesServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
export declare class DBEncryptedNotesService extends BaseEncryptedNotesService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
constructor(params: DBEncryptedNotesServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<EncryptedNotesEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<EncryptedNotesEvents>>;
|
||||
saveEvents({ newEvents, lastBlock, }: BaseEvents<EncryptedNotesEvents> & {
|
||||
newEvents: EncryptedNotesEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBGovernanceServiceConstructor extends BaseGovernanceServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
export declare class DBGovernanceService extends BaseGovernanceService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
constructor(params: DBGovernanceServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<AllGovernanceEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<AllGovernanceEvents>>;
|
||||
saveEvents({ newEvents, lastBlock }: BaseEvents<AllGovernanceEvents> & {
|
||||
newEvents: AllGovernanceEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
export interface DBRegistryServiceConstructor extends BaseRegistryServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
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;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
export declare class DBRevenueService extends BaseRevenueService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
zipDigest?: string;
|
||||
relayerJsonDigest?: string;
|
||||
constructor(params: DBRevenueServiceConstructor);
|
||||
getEventsFromDB(): Promise<BaseEvents<StakeBurnedEvents>>;
|
||||
getEventsFromCache(): Promise<CachedEvents<StakeBurnedEvents>>;
|
||||
saveEvents({ newEvents, lastBlock }: BaseEvents<StakeBurnedEvents> & {
|
||||
newEvents: StakeBurnedEvents[];
|
||||
}): Promise<void>;
|
||||
}
|
||||
1
dist/events/index.d.ts
vendored
1
dist/events/index.d.ts
vendored
@@ -1,2 +1,3 @@
|
||||
export * from './types';
|
||||
export * from './base';
|
||||
export * from './db';
|
||||
|
||||
82
dist/events/types.d.ts
vendored
82
dist/events/types.d.ts
vendored
@@ -1,7 +1,10 @@
|
||||
import { RelayerParams } from '../relayerClient';
|
||||
export interface BaseEvents<T> {
|
||||
events: T[];
|
||||
lastBlock: number | null;
|
||||
lastBlock: number;
|
||||
}
|
||||
export interface CachedEvents<T> extends BaseEvents<T> {
|
||||
fromCache: boolean;
|
||||
}
|
||||
export interface BaseGraphEvents<T> {
|
||||
events: T[];
|
||||
@@ -12,51 +15,92 @@ export interface MinimalEvents {
|
||||
logIndex: number;
|
||||
transactionHash: string;
|
||||
}
|
||||
export type GovernanceEvents = MinimalEvents & {
|
||||
export interface GovernanceEvents extends MinimalEvents {
|
||||
event: string;
|
||||
};
|
||||
export type GovernanceProposalCreatedEvents = GovernanceEvents & {
|
||||
}
|
||||
export interface GovernanceProposalCreatedEvents extends GovernanceEvents {
|
||||
id: number;
|
||||
proposer: string;
|
||||
target: string;
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
description: string;
|
||||
};
|
||||
export type GovernanceVotedEvents = GovernanceEvents & {
|
||||
}
|
||||
export interface GovernanceVotedEvents extends GovernanceEvents {
|
||||
proposalId: number;
|
||||
voter: string;
|
||||
support: boolean;
|
||||
votes: string;
|
||||
from: string;
|
||||
input: string;
|
||||
};
|
||||
export type GovernanceDelegatedEvents = GovernanceEvents & {
|
||||
}
|
||||
export interface GovernanceDelegatedEvents extends GovernanceEvents {
|
||||
account: string;
|
||||
delegateTo: string;
|
||||
};
|
||||
export type GovernanceUndelegatedEvents = GovernanceEvents & {
|
||||
}
|
||||
export interface GovernanceUndelegatedEvents extends GovernanceEvents {
|
||||
account: string;
|
||||
delegateFrom: string;
|
||||
};
|
||||
}
|
||||
export type AllGovernanceEvents = GovernanceProposalCreatedEvents | GovernanceVotedEvents | GovernanceDelegatedEvents | GovernanceUndelegatedEvents;
|
||||
export interface RelayerRegistryEvents extends MinimalEvents {
|
||||
event: string;
|
||||
}
|
||||
export interface RelayerRegisteredEvents extends RelayerRegistryEvents, RelayerParams {
|
||||
ensHash: string;
|
||||
stakedAmount: string;
|
||||
}
|
||||
export interface RelayerUnregisteredEvents extends RelayerRegistryEvents {
|
||||
relayerAddress: string;
|
||||
}
|
||||
export interface WorkerRegisteredEvents extends RelayerRegistryEvents {
|
||||
relayerAddress: string;
|
||||
workerAddress: string;
|
||||
}
|
||||
export interface WorkerUnregisteredEvents extends RelayerRegistryEvents {
|
||||
relayerAddress: string;
|
||||
workerAddress: string;
|
||||
}
|
||||
export type AllRelayerRegistryEvents = RelayerRegisteredEvents | RelayerUnregisteredEvents | WorkerRegisteredEvents | WorkerUnregisteredEvents;
|
||||
export interface StakeBurnedEvents extends MinimalEvents {
|
||||
relayerAddress: string;
|
||||
amountBurned: string;
|
||||
instanceAddress: string;
|
||||
gasFee: string;
|
||||
relayerFee: string;
|
||||
timestamp: number;
|
||||
}
|
||||
export type RegistersEvents = MinimalEvents & RelayerParams;
|
||||
export type DepositsEvents = MinimalEvents & {
|
||||
export interface DepositsEvents extends MinimalEvents {
|
||||
commitment: string;
|
||||
leafIndex: number;
|
||||
timestamp: number;
|
||||
from: string;
|
||||
};
|
||||
export type WithdrawalsEvents = MinimalEvents & {
|
||||
}
|
||||
export interface WithdrawalsEvents extends MinimalEvents {
|
||||
nullifierHash: string;
|
||||
to: string;
|
||||
fee: string;
|
||||
timestamp: number;
|
||||
};
|
||||
export type EchoEvents = MinimalEvents & {
|
||||
}
|
||||
export interface BaseMultiTornadoEvents {
|
||||
event: string;
|
||||
instanceAddress: string;
|
||||
}
|
||||
export interface MultiDepositsEvents extends BaseMultiTornadoEvents, DepositsEvents {
|
||||
}
|
||||
export interface MultiWithdrawalsEvents extends BaseMultiTornadoEvents, WithdrawalsEvents {
|
||||
relayerAddress: string;
|
||||
}
|
||||
export interface EchoEvents extends MinimalEvents {
|
||||
address: string;
|
||||
encryptedAccount: string;
|
||||
};
|
||||
export type EncryptedNotesEvents = MinimalEvents & {
|
||||
}
|
||||
export interface EncryptedNotesEvents extends MinimalEvents {
|
||||
encryptedNote: string;
|
||||
};
|
||||
}
|
||||
export interface TransferEvents extends MinimalEvents {
|
||||
from: string;
|
||||
to: string;
|
||||
value: bigint;
|
||||
}
|
||||
|
||||
13
dist/fees.d.ts
vendored
13
dist/fees.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import type { BigNumberish, TransactionLike } from 'ethers';
|
||||
import type { BigNumberish, JsonRpcApiProvider, TransactionLike } from 'ethers';
|
||||
import { OvmGasPriceOracle } from './typechain';
|
||||
/**
|
||||
* Example:
|
||||
@@ -19,8 +19,17 @@ export interface RelayerFeeParams {
|
||||
premiumPercent?: number;
|
||||
}
|
||||
export declare class TornadoFeeOracle {
|
||||
provider: JsonRpcApiProvider;
|
||||
ovmGasPriceOracle?: OvmGasPriceOracle;
|
||||
constructor(ovmGasPriceOracle?: OvmGasPriceOracle);
|
||||
constructor(provider: JsonRpcApiProvider, ovmGasPriceOracle?: OvmGasPriceOracle);
|
||||
/**
|
||||
* Calculates Gas Price
|
||||
* We apply 50% premium of EIP-1559 network fees instead of 100% from ethers.js
|
||||
* (This should cover up to 4 full blocks which is equivalent of minute)
|
||||
* (A single block can bump 12.5% of fees, see the methodology https://hackmd.io/@tvanepps/1559-wallets)
|
||||
* (Still it is recommended to use 100% premium for sending transactions to prevent stucking it)
|
||||
*/
|
||||
gasPrice(premium?: number): Promise<bigint>;
|
||||
/**
|
||||
* Calculate L1 fee for op-stack chains
|
||||
*
|
||||
|
||||
13
dist/gaszip.d.ts
vendored
Normal file
13
dist/gaszip.d.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { NetIdType } from './networkConfig';
|
||||
export declare const gasZipInbounds: {
|
||||
[key in NetIdType]: string;
|
||||
};
|
||||
export declare const gasZipID: {
|
||||
[key in NetIdType]: number;
|
||||
};
|
||||
export declare function gasZipInput(to: string, shorts: number[]): string | null;
|
||||
export declare function gasZipMinMax(ethUsd: number): {
|
||||
min: number;
|
||||
max: number;
|
||||
ethUsd: number;
|
||||
};
|
||||
13
dist/graphql/index.d.ts
vendored
13
dist/graphql/index.d.ts
vendored
@@ -1,7 +1,14 @@
|
||||
import { ContractEventName } from 'ethers';
|
||||
import { fetchDataOptions } from '../providers';
|
||||
import type { BaseGraphEvents, RegistersEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, BatchGraphOnProgress, EchoEvents, AllGovernanceEvents } from '../events';
|
||||
import type { BaseGraphEvents, RegistersEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, EchoEvents, AllGovernanceEvents } from '../events';
|
||||
export * from './queries';
|
||||
export type queryGraphParams = {
|
||||
export type BatchGraphOnProgress = ({ type, fromBlock, toBlock, count, }: {
|
||||
type?: ContractEventName;
|
||||
fromBlock?: number;
|
||||
toBlock?: number;
|
||||
count?: number;
|
||||
}) => void;
|
||||
export interface queryGraphParams {
|
||||
graphApi: string;
|
||||
subgraphName: string;
|
||||
query: string;
|
||||
@@ -9,7 +16,7 @@ export type queryGraphParams = {
|
||||
[key: string]: string | number;
|
||||
};
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
};
|
||||
}
|
||||
export declare function queryGraph<T>({ graphApi, subgraphName, query, variables, fetchDataOptions, }: queryGraphParams): Promise<T>;
|
||||
export interface GraphStatistic {
|
||||
deposits: {
|
||||
|
||||
3
dist/hasher.d.ts
vendored
Normal file
3
dist/hasher.d.ts
vendored
Normal file
File diff suppressed because one or more lines are too long
11
dist/hashes.json
vendored
Normal file
11
dist/hashes.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"dist/index.js": "sha384-txpjgDLxNbeXsLgVCyNAwpaJRS0SmFN/ITfadSo8+xzSvLqwa5bQ9GoxQ1Su8QEr",
|
||||
"dist/index.mjs": "sha384-CrEHmX4zKIv/68CKWElNzvKk6FWRMMkKV8JmqL1KqYCxO73LPEAjDqxTYpxUuDBy",
|
||||
"dist/merkleTreeWorker.js": "sha384-XVv9HRGDZlaF0LeEZNQygle31UY6yvIwsZ4GWCTZUX7O/hZ7N5Zwpi3GqnHSBYzW",
|
||||
"dist/merkleTreeWorker.umd.js": "sha384-e5B65ZZ4IxKVOU1o02K6IL2tjJof20QCcEtD+vKe1cPmyfW2BPCHWDPIbPksIpvJ",
|
||||
"dist/merkleTreeWorker.umd.min.js": "sha384-AxQv1da+lSi3gMYkdGQuR1WN1+4HB8IT3cPFa17HBj14+ZzdZN6SS1fCw5Izc2rr",
|
||||
"dist/tornado.umd.js": "sha384-xTUkkUTm3aBsnHCUnVGxRgieAu3z4wCwrKT1DFj8VyCk/eZZO9nq+yP4/McLRfB4",
|
||||
"dist/tornado.umd.min.js": "sha384-ubqr6m6jEOPf7LQz0pXKmEo7tCCbNUAE+iSZWK6X/f7i4wt14rYW7pUcSzw5glth",
|
||||
"dist/tornadoContracts.umd.js": "sha384-bFq/cemb0bP0JbIq8p75n0UR8smQ/2Yh69pjegzSuu0upawO3sKOjehY8SjX85Xh",
|
||||
"dist/tornadoContracts.umd.min.js": "sha384-4ay7cmK0auAgZH1xfAsqyN6GtnHBNNgh9C22qy0rHxKicDzNtTsnNZDbz0qmd9GI"
|
||||
}
|
||||
84
dist/idb.d.ts
vendored
Normal file
84
dist/idb.d.ts
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
import { OpenDBCallbacks, IDBPDatabase } from 'idb';
|
||||
import { NetIdType } from './networkConfig';
|
||||
export declare const INDEX_DB_ERROR = "A mutation operation was attempted on a database that did not allow mutations.";
|
||||
export interface IDBIndex {
|
||||
name: string;
|
||||
unique?: boolean;
|
||||
}
|
||||
export interface IDBStores {
|
||||
name: string;
|
||||
keyPath?: string;
|
||||
indexes?: IDBIndex[];
|
||||
}
|
||||
export interface IDBConstructor {
|
||||
dbName: string;
|
||||
stores?: IDBStores[];
|
||||
}
|
||||
export declare class IndexedDB {
|
||||
dbExists: boolean;
|
||||
isBlocked: boolean;
|
||||
options: OpenDBCallbacks<any>;
|
||||
dbName: string;
|
||||
dbVersion: number;
|
||||
db?: IDBPDatabase<any>;
|
||||
constructor({ dbName, stores }: IDBConstructor);
|
||||
initDB(): Promise<void>;
|
||||
_removeExist(): Promise<void>;
|
||||
getFromIndex<T>({ storeName, indexName, key, }: {
|
||||
storeName: string;
|
||||
indexName: string;
|
||||
key?: string;
|
||||
}): Promise<T | undefined>;
|
||||
getAllFromIndex<T>({ storeName, indexName, key, count, }: {
|
||||
storeName: string;
|
||||
indexName: string;
|
||||
key?: string;
|
||||
count?: number;
|
||||
}): Promise<T>;
|
||||
getItem<T>({ storeName, key }: {
|
||||
storeName: string;
|
||||
key: string;
|
||||
}): Promise<T | undefined>;
|
||||
addItem({ storeName, data, key }: {
|
||||
storeName: string;
|
||||
data: any;
|
||||
key: string;
|
||||
}): Promise<void>;
|
||||
putItem({ storeName, data, key }: {
|
||||
storeName: string;
|
||||
data: any;
|
||||
key?: string;
|
||||
}): Promise<void>;
|
||||
deleteItem({ storeName, key }: {
|
||||
storeName: string;
|
||||
key: string;
|
||||
}): Promise<void>;
|
||||
getAll<T>({ storeName }: {
|
||||
storeName: string;
|
||||
}): Promise<T>;
|
||||
/**
|
||||
* Simple key-value store inspired by idb-keyval package
|
||||
*/
|
||||
getValue<T>(key: string): Promise<T | undefined>;
|
||||
setValue(key: string, data: any): Promise<void>;
|
||||
delValue(key: string): Promise<void>;
|
||||
clearStore({ storeName, mode }: {
|
||||
storeName: string;
|
||||
mode: IDBTransactionMode;
|
||||
}): Promise<void>;
|
||||
createTransactions({ storeName, data, mode, }: {
|
||||
storeName: string;
|
||||
data: any;
|
||||
mode: IDBTransactionMode;
|
||||
}): Promise<void>;
|
||||
createMultipleTransactions({ storeName, data, index, mode, }: {
|
||||
storeName: string;
|
||||
data: any[];
|
||||
index?: any;
|
||||
mode?: IDBTransactionMode;
|
||||
}): Promise<void>;
|
||||
}
|
||||
/**
|
||||
* Should check if DB is initialized well
|
||||
*/
|
||||
export declare function getIndexedDB(netId?: NetIdType): Promise<IndexedDB>;
|
||||
9
dist/index.d.ts
vendored
9
dist/index.d.ts
vendored
@@ -1,19 +1,26 @@
|
||||
export * from './events';
|
||||
export * from './graphql';
|
||||
export * from './schemas';
|
||||
export * from './typechain';
|
||||
export * from './batch';
|
||||
export * from './deposits';
|
||||
export * from './encryptedNotes';
|
||||
export * from './ens';
|
||||
export * from './fees';
|
||||
export * from './gaszip';
|
||||
export * from './hasher';
|
||||
export * from './idb';
|
||||
export * from './ip';
|
||||
export * from './merkleTree';
|
||||
export * from './mimc';
|
||||
export * from './multicall';
|
||||
export * from './networkConfig';
|
||||
export * from './pedersen';
|
||||
export * from './permit';
|
||||
export * from './prices';
|
||||
export * from './providers';
|
||||
export * from './relayerClient';
|
||||
export * from './tokens';
|
||||
export * from './tovarishClient';
|
||||
export * from './utils';
|
||||
export * from './websnark';
|
||||
export * from './zip';
|
||||
|
||||
12363
dist/index.js
vendored
12363
dist/index.js
vendored
File diff suppressed because one or more lines are too long
12239
dist/index.mjs
vendored
12239
dist/index.mjs
vendored
File diff suppressed because one or more lines are too long
6
dist/ip.d.ts
vendored
Normal file
6
dist/ip.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export interface IPResult {
|
||||
ip: string;
|
||||
iso?: string;
|
||||
tor?: boolean;
|
||||
}
|
||||
export declare function fetchIp(ipEcho: string): Promise<IPResult>;
|
||||
6
dist/merkleTree.d.ts
vendored
6
dist/merkleTree.d.ts
vendored
@@ -1,15 +1,15 @@
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from '@tornado/fixed-merkle-tree';
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from 'fixed-merkle-tree';
|
||||
import type { Tornado } from '@tornado/contracts';
|
||||
import type { DepositType } from './deposits';
|
||||
import type { DepositsEvents } from './events';
|
||||
import type { NetIdType } from './networkConfig';
|
||||
export type MerkleTreeConstructor = DepositType & {
|
||||
export interface MerkleTreeConstructor extends DepositType {
|
||||
Tornado: Tornado;
|
||||
commitmentHex?: string;
|
||||
merkleTreeHeight?: number;
|
||||
emptyElement?: string;
|
||||
merkleWorkerPath?: string;
|
||||
};
|
||||
}
|
||||
export declare class MerkleTreeService {
|
||||
currency: string;
|
||||
amount: string;
|
||||
|
||||
29702
dist/merkleTreeWorker.js
vendored
29702
dist/merkleTreeWorker.js
vendored
File diff suppressed because it is too large
Load Diff
10246
dist/merkleTreeWorker.umd.js
vendored
10246
dist/merkleTreeWorker.umd.js
vendored
File diff suppressed because one or more lines are too long
2
dist/merkleTreeWorker.umd.min.js
vendored
Normal file
2
dist/merkleTreeWorker.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
26
dist/merkleTreeWorker.umd.min.js.LICENSE.txt
vendored
Normal file
26
dist/merkleTreeWorker.umd.min.js.LICENSE.txt
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <https://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*! 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
|
||||
*/
|
||||
2
dist/mimc.d.ts
vendored
2
dist/mimc.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import { MimcSponge } from 'circomlibjs';
|
||||
import type { Element, HashFunction } from '@tornado/fixed-merkle-tree';
|
||||
import type { Element, HashFunction } from 'fixed-merkle-tree';
|
||||
export declare class Mimc {
|
||||
sponge?: MimcSponge;
|
||||
hash?: HashFunction<Element>;
|
||||
|
||||
62
dist/networkConfig.d.ts
vendored
62
dist/networkConfig.d.ts
vendored
@@ -1,3 +1,4 @@
|
||||
import type { DepositType } from './deposits';
|
||||
/**
|
||||
* Type of default supported networks
|
||||
*/
|
||||
@@ -7,6 +8,8 @@ export declare enum NetId {
|
||||
POLYGON = 137,
|
||||
OPTIMISM = 10,
|
||||
ARBITRUM = 42161,
|
||||
BASE = 8453,
|
||||
BLAST = 81457,
|
||||
GNOSIS = 100,
|
||||
AVALANCHE = 43114,
|
||||
SEPOLIA = 11155111
|
||||
@@ -16,31 +19,32 @@ export interface RpcUrl {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
export type RpcUrls = {
|
||||
[key in string]: RpcUrl;
|
||||
};
|
||||
export interface RpcUrls {
|
||||
[key: string]: RpcUrl;
|
||||
}
|
||||
export interface SubgraphUrl {
|
||||
name: string;
|
||||
url: string;
|
||||
}
|
||||
export type SubgraphUrls = {
|
||||
[key in string]: SubgraphUrl;
|
||||
};
|
||||
export type TornadoInstance = {
|
||||
export interface SubgraphUrls {
|
||||
[key: string]: SubgraphUrl;
|
||||
}
|
||||
export interface TornadoInstance {
|
||||
instanceAddress: {
|
||||
[key in string]: string;
|
||||
[key: string]: string;
|
||||
};
|
||||
instanceApproval?: boolean;
|
||||
optionalInstances?: string[];
|
||||
tokenAddress?: string;
|
||||
tokenGasLimit?: number;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
gasLimit?: number;
|
||||
};
|
||||
export type TokenInstances = {
|
||||
[key in string]: TornadoInstance;
|
||||
};
|
||||
export type Config = {
|
||||
}
|
||||
export interface TokenInstances {
|
||||
[key: string]: TornadoInstance;
|
||||
}
|
||||
export interface Config {
|
||||
rpcCallRetryAttempt?: number;
|
||||
gasPrices: {
|
||||
instant: number;
|
||||
@@ -57,6 +61,7 @@ export type Config = {
|
||||
networkName: string;
|
||||
deployedBlock: number;
|
||||
rpcUrls: RpcUrls;
|
||||
stablecoin: string;
|
||||
multicallContract: string;
|
||||
routerContract: string;
|
||||
echoContract: string;
|
||||
@@ -67,8 +72,6 @@ export type Config = {
|
||||
registryContract?: string;
|
||||
aggregatorContract?: string;
|
||||
reverseRecordsContract?: string;
|
||||
gasPriceOracleContract?: string;
|
||||
gasStationApi?: string;
|
||||
ovmGasPriceOracleContract?: string;
|
||||
tornadoSubgraph: string;
|
||||
registrySubgraph?: string;
|
||||
@@ -76,6 +79,7 @@ export type Config = {
|
||||
subgraphs: SubgraphUrls;
|
||||
tokens: TokenInstances;
|
||||
optionalTokens?: string[];
|
||||
disabledTokens?: string[];
|
||||
relayerEnsSubdomain: string;
|
||||
pollInterval: number;
|
||||
constants: {
|
||||
@@ -85,12 +89,15 @@ export type Config = {
|
||||
REGISTRY_BLOCK?: number;
|
||||
MINING_BLOCK_TIME?: number;
|
||||
};
|
||||
};
|
||||
export type networkConfig = {
|
||||
[key in NetIdType]: Config;
|
||||
};
|
||||
}
|
||||
export interface networkConfig {
|
||||
[key: NetIdType]: Config;
|
||||
}
|
||||
export interface SubdomainMap {
|
||||
[key: NetIdType]: string;
|
||||
}
|
||||
export declare const defaultConfig: networkConfig;
|
||||
export declare const enabledChains: number[];
|
||||
export declare const enabledChains: NetIdType[];
|
||||
/**
|
||||
* Custom config object to extend default config
|
||||
*
|
||||
@@ -106,11 +113,16 @@ export declare let customConfig: networkConfig;
|
||||
export declare function addNetwork(newConfig: networkConfig): void;
|
||||
export declare function getNetworkConfig(): networkConfig;
|
||||
export declare function getConfig(netId: NetIdType): Config;
|
||||
export declare function getInstanceByAddress({ netId, address }: {
|
||||
netId: NetIdType;
|
||||
address: string;
|
||||
}): {
|
||||
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 getSubdomains(): string[];
|
||||
export declare function getRelayerEnsSubdomains(): SubdomainMap;
|
||||
export declare function getMultiInstances(netId: NetIdType, config: Config): {
|
||||
[key in string]: DepositType;
|
||||
};
|
||||
|
||||
184
dist/permit.d.ts
vendored
Normal file
184
dist/permit.d.ts
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
import { ERC20Permit, ERC20Mock, TORN } from '@tornado/contracts';
|
||||
import { Signature, Signer, TypedDataField } from 'ethers';
|
||||
export interface PermitValue {
|
||||
spender: string;
|
||||
value: bigint;
|
||||
nonce?: bigint;
|
||||
deadline?: bigint;
|
||||
}
|
||||
export interface PermitCommitments {
|
||||
denomination: bigint;
|
||||
commitments: string[];
|
||||
nonce?: bigint;
|
||||
deadline?: bigint;
|
||||
}
|
||||
export declare const permit2Address = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
||||
/**
|
||||
* From @uniswap/permit2-sdk ported for ethers.js v6
|
||||
*/
|
||||
export interface Witness {
|
||||
witnessTypeName: string;
|
||||
witnessType: {
|
||||
[key: string]: TypedDataField[];
|
||||
};
|
||||
witness: any;
|
||||
}
|
||||
export declare function getPermitSignature({ Token, signer, spender, value, nonce, deadline, }: PermitValue & {
|
||||
Token: ERC20Permit | ERC20Mock | TORN;
|
||||
signer?: Signer;
|
||||
}): Promise<Signature>;
|
||||
/**
|
||||
export async function getPermitCommitmentsSignature({
|
||||
PermitTornado,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
}: PermitCommitments & {
|
||||
PermitTornado: PermitTornado;
|
||||
Token: ERC20Permit | ERC20Mock | TORN;
|
||||
signer?: Signer;
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(['bytes32[]'], [commitments]);
|
||||
|
||||
return await getPermitSignature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado.target as string,
|
||||
value,
|
||||
nonce,
|
||||
deadline: BigInt(commitmentsHash),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender,
|
||||
value: amount,
|
||||
nonce,
|
||||
deadline,
|
||||
witness,
|
||||
}: PermitValue & {
|
||||
Token: BaseContract;
|
||||
signer?: Signer;
|
||||
witness?: Witness;
|
||||
}) {
|
||||
const sigSigner = (signer || Token.runner) as Signer & { address: string };
|
||||
const provider = sigSigner.provider as Provider;
|
||||
|
||||
const domain = {
|
||||
name: 'Permit2',
|
||||
chainId: (await provider.getNetwork()).chainId,
|
||||
verifyingContract: permit2Address,
|
||||
};
|
||||
|
||||
const types: {
|
||||
[key: string]: TypedDataField[];
|
||||
} = !witness
|
||||
? {
|
||||
PermitTransferFrom: [
|
||||
{ name: 'permitted', type: 'TokenPermissions' },
|
||||
{ name: 'spender', type: 'address' },
|
||||
{ name: 'nonce', type: 'uint256' },
|
||||
{ name: 'deadline', type: 'uint256' },
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: 'token', type: 'address' },
|
||||
{ name: 'amount', type: 'uint256' },
|
||||
],
|
||||
}
|
||||
: {
|
||||
PermitWitnessTransferFrom: [
|
||||
{ name: 'permitted', type: 'TokenPermissions' },
|
||||
{ name: 'spender', type: 'address' },
|
||||
{ name: 'nonce', type: 'uint256' },
|
||||
{ name: 'deadline', type: 'uint256' },
|
||||
{ name: 'witness', type: witness.witnessTypeName },
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: 'token', type: 'address' },
|
||||
{ name: 'amount', type: 'uint256' },
|
||||
],
|
||||
...witness.witnessType,
|
||||
};
|
||||
|
||||
const values: {
|
||||
permitted: {
|
||||
token: string;
|
||||
amount: bigint;
|
||||
};
|
||||
spender: string;
|
||||
nonce: bigint;
|
||||
deadline: bigint;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
witness?: any;
|
||||
} = {
|
||||
permitted: {
|
||||
token: Token.target as string,
|
||||
amount,
|
||||
},
|
||||
spender,
|
||||
// Sorted nonce are not required for Permit2
|
||||
nonce: nonce || rBigInt(16),
|
||||
deadline: deadline || MaxUint256,
|
||||
};
|
||||
|
||||
if (witness) {
|
||||
values.witness = witness.witness;
|
||||
}
|
||||
|
||||
const hash = new TypedDataEncoder(types).hash(values);
|
||||
|
||||
const signature = Signature.from(await sigSigner.signTypedData(domain, types, values));
|
||||
|
||||
return {
|
||||
domain,
|
||||
types,
|
||||
values,
|
||||
hash,
|
||||
signature,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getPermit2CommitmentsSignature({
|
||||
PermitTornado,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
deadline,
|
||||
}: PermitCommitments & {
|
||||
PermitTornado: PermitTornado;
|
||||
Token: BaseContract;
|
||||
signer?: Signer;
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(['bytes32[]'], [commitments]);
|
||||
|
||||
return await getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado.target as string,
|
||||
value,
|
||||
nonce,
|
||||
deadline,
|
||||
witness: {
|
||||
witnessTypeName: 'PermitCommitments',
|
||||
witnessType: {
|
||||
PermitCommitments: [
|
||||
{ name: 'instance', type: 'address' },
|
||||
{ name: 'commitmentsHash', type: 'bytes32' },
|
||||
],
|
||||
},
|
||||
witness: {
|
||||
instance: PermitTornado.target,
|
||||
commitmentsHash,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
**/
|
||||
11
dist/prices.d.ts
vendored
11
dist/prices.d.ts
vendored
@@ -1,12 +1,21 @@
|
||||
import { type Provider } from 'ethers';
|
||||
import type { OffchainOracle, Multicall } from './typechain';
|
||||
import { OffchainOracle, Multicall } from './typechain';
|
||||
import { Call3 } from './multicall';
|
||||
export declare class TokenPriceOracle {
|
||||
oracle?: OffchainOracle;
|
||||
multicall: Multicall;
|
||||
provider: Provider;
|
||||
fallbackPrice: bigint;
|
||||
constructor(provider: Provider, multicall: Multicall, oracle?: OffchainOracle);
|
||||
buildCalls(tokens: {
|
||||
tokenAddress: string;
|
||||
decimals: number;
|
||||
}[]): Call3[];
|
||||
buildStable(stablecoinAddress: string): Call3[];
|
||||
fetchPrice(tokenAddress: string, decimals: number): Promise<bigint>;
|
||||
fetchPrices(tokens: {
|
||||
tokenAddress: string;
|
||||
decimals: number;
|
||||
}[]): Promise<bigint[]>;
|
||||
fetchEthUSD(stablecoinAddress: string): Promise<number>;
|
||||
}
|
||||
|
||||
37
dist/providers.d.ts
vendored
37
dist/providers.d.ts
vendored
@@ -1,9 +1,6 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import type { EventEmitter } from 'stream';
|
||||
import type { RequestOptions } from 'http';
|
||||
import { JsonRpcApiProvider, JsonRpcProvider, Wallet, FetchGetUrlFunc, Provider, SigningKey, TransactionRequest, JsonRpcSigner, BrowserProvider, Networkish, Eip1193Provider, VoidSigner, FetchUrlFeeDataNetworkPlugin } from 'ethers';
|
||||
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 type { Config, NetIdType } from './networkConfig';
|
||||
declare global {
|
||||
@@ -11,8 +8,7 @@ declare global {
|
||||
ethereum?: Eip1193Provider & EventEmitter;
|
||||
}
|
||||
}
|
||||
export declare const defaultUserAgent = "Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0";
|
||||
export declare const fetch: nodeFetch;
|
||||
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 & {
|
||||
headers?: HeadersInit | any;
|
||||
@@ -24,6 +20,7 @@ export type fetchDataOptions = RequestInit & {
|
||||
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, }: {
|
||||
@@ -35,57 +32,57 @@ export declare function getHttpAgent({ fetchUrl, proxyUrl, torPort, retry, }: {
|
||||
export declare function fetchData(url: string, options?: fetchDataOptions): Promise<any>;
|
||||
export declare const fetchGetUrlFunc: (options?: fetchDataOptions) => FetchGetUrlFunc;
|
||||
export type getProviderOptions = fetchDataOptions & {
|
||||
netId?: NetIdType;
|
||||
pollingInterval?: number;
|
||||
gasPriceOracle?: string;
|
||||
gasStationApi?: string;
|
||||
};
|
||||
export declare function getGasOraclePlugin(networkKey: string, fetchOptions?: getProviderOptions): FetchUrlFeeDataNetworkPlugin;
|
||||
export declare function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider>;
|
||||
export declare function getProviderWithNetId(netId: NetIdType, rpcUrl: string, config: Config, fetchOptions?: getProviderOptions): JsonRpcProvider;
|
||||
export declare const populateTransaction: (signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner, tx: TransactionRequest) => Promise<TransactionRequest>;
|
||||
export type TornadoWalletOptions = {
|
||||
export interface TornadoWalletOptions {
|
||||
gasPriceBump?: number;
|
||||
gasLimitBump?: number;
|
||||
gasFailover?: boolean;
|
||||
bumpNonce?: boolean;
|
||||
};
|
||||
readonlyProvider?: Provider;
|
||||
}
|
||||
export declare class TornadoWallet extends Wallet {
|
||||
nonce?: number | null;
|
||||
nonce?: number;
|
||||
gasPriceBump: number;
|
||||
gasLimitBump: number;
|
||||
gasFailover: boolean;
|
||||
bumpNonce: boolean;
|
||||
constructor(key: string | SigningKey, provider?: null | Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
constructor(key: string | SigningKey, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
static fromMnemonic(mneomnic: string, provider: Provider, index?: number, options?: TornadoWalletOptions): TornadoWallet;
|
||||
populateTransaction(tx: TransactionRequest): Promise<import("ethers").TransactionLike<string>>;
|
||||
}
|
||||
export declare class TornadoVoidSigner extends VoidSigner {
|
||||
nonce?: number | null;
|
||||
nonce?: number;
|
||||
gasPriceBump: number;
|
||||
gasLimitBump: number;
|
||||
gasFailover: boolean;
|
||||
bumpNonce: boolean;
|
||||
constructor(address: string, provider?: null | Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
constructor(address: string, provider?: Provider, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
populateTransaction(tx: TransactionRequest): Promise<import("ethers").TransactionLike<string>>;
|
||||
}
|
||||
export declare class TornadoRpcSigner extends JsonRpcSigner {
|
||||
nonce?: number | null;
|
||||
nonce?: number;
|
||||
gasPriceBump: number;
|
||||
gasLimitBump: number;
|
||||
gasFailover: boolean;
|
||||
bumpNonce: boolean;
|
||||
constructor(provider: JsonRpcApiProvider, address: string, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce }?: TornadoWalletOptions);
|
||||
readonlyProvider?: Provider;
|
||||
constructor(provider: JsonRpcApiProvider, address: string, { gasPriceBump, gasLimitBump, gasFailover, bumpNonce, readonlyProvider }?: TornadoWalletOptions);
|
||||
sendUncheckedTransaction(tx: TransactionRequest): Promise<string>;
|
||||
}
|
||||
export type connectWalletFunc = (...args: any[]) => Promise<void>;
|
||||
export type handleWalletFunc = (...args: any[]) => void;
|
||||
export type TornadoBrowserProviderOptions = TornadoWalletOptions & {
|
||||
webChainId?: NetIdType;
|
||||
export interface TornadoBrowserProviderOptions extends TornadoWalletOptions {
|
||||
netId?: NetIdType;
|
||||
connectWallet?: connectWalletFunc;
|
||||
handleNetworkChanges?: handleWalletFunc;
|
||||
handleAccountChanges?: handleWalletFunc;
|
||||
handleAccountDisconnect?: handleWalletFunc;
|
||||
};
|
||||
}
|
||||
export declare class TornadoBrowserProvider extends BrowserProvider {
|
||||
options?: TornadoBrowserProviderOptions;
|
||||
constructor(ethereum: Eip1193Provider, network?: Networkish, options?: TornadoBrowserProviderOptions);
|
||||
|
||||
91
dist/relayerClient.d.ts
vendored
91
dist/relayerClient.d.ts
vendored
@@ -1,19 +1,24 @@
|
||||
import type { Aggregator } from '@tornado/contracts';
|
||||
import type { RelayerStructOutput } from '@tornado/contracts/dist/contracts/Governance/Aggregator/Aggregator';
|
||||
import { NetIdType, Config } from './networkConfig';
|
||||
import { fetchDataOptions } from './providers';
|
||||
import type { snarkProofs } from './websnark';
|
||||
import type { CachedRelayerInfo } from './events';
|
||||
export declare const MIN_FEE = 0.1;
|
||||
export declare const MAX_FEE = 0.9;
|
||||
export declare const MIN_STAKE_BALANCE: bigint;
|
||||
export interface RelayerParams {
|
||||
ensName: string;
|
||||
relayerAddress?: string;
|
||||
relayerAddress: string;
|
||||
}
|
||||
export interface Relayer {
|
||||
/**
|
||||
* Info from relayer status
|
||||
*/
|
||||
export interface RelayerInfo extends RelayerParams {
|
||||
netId: NetIdType;
|
||||
url: string;
|
||||
hostname: string;
|
||||
rewardAccount: string;
|
||||
instances: string[];
|
||||
stakeBalance?: string;
|
||||
gasPrice?: number;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
@@ -21,16 +26,12 @@ export interface Relayer {
|
||||
currentQueue: number;
|
||||
tornadoServiceFee: number;
|
||||
}
|
||||
export type RelayerInfo = Relayer & {
|
||||
ensName: string;
|
||||
stakeBalance: bigint;
|
||||
relayerAddress: string;
|
||||
};
|
||||
export type RelayerError = {
|
||||
export interface RelayerError {
|
||||
hostname: string;
|
||||
relayerAddress?: string;
|
||||
errorMessage?: string;
|
||||
};
|
||||
hasError: boolean;
|
||||
}
|
||||
export interface RelayerStatus {
|
||||
url: string;
|
||||
rewardAccount: string;
|
||||
@@ -62,6 +63,9 @@ export interface RelayerStatus {
|
||||
};
|
||||
currentQueue: number;
|
||||
}
|
||||
export interface TornadoWithdrawParams extends snarkProofs {
|
||||
contract: string;
|
||||
}
|
||||
export interface RelayerTornadoWithdraw {
|
||||
id?: string;
|
||||
error?: string;
|
||||
@@ -78,51 +82,66 @@ export interface RelayerTornadoJobs {
|
||||
confirmations?: number;
|
||||
failedReason?: string;
|
||||
}
|
||||
/**
|
||||
const semVerRegex =
|
||||
/^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
||||
|
||||
export interface semanticVersion {
|
||||
major: string;
|
||||
minor: string;
|
||||
patch: string;
|
||||
prerelease?: string;
|
||||
buildmetadata?: string;
|
||||
major: string;
|
||||
minor: string;
|
||||
patch: string;
|
||||
prerelease?: string;
|
||||
buildmetadata?: string;
|
||||
}
|
||||
export declare function parseSemanticVersion(version: string): semanticVersion;
|
||||
export declare function isRelayerUpdated(relayerVersion: string, netId: NetIdType): boolean;
|
||||
export declare function calculateScore({ stakeBalance, tornadoServiceFee }: RelayerInfo, minFee?: number, maxFee?: number): bigint;
|
||||
|
||||
export function parseSemanticVersion(version: string) {
|
||||
const { groups } = semVerRegex.exec(version) as RegExpExecArray;
|
||||
return groups as unknown as semanticVersion;
|
||||
}
|
||||
|
||||
export function isRelayerUpdated(relayerVersion: string, netId: NetIdType) {
|
||||
const { major, patch, prerelease } = parseSemanticVersion(relayerVersion);
|
||||
// Save backwards compatibility with V4 relayers for Ethereum Mainnet
|
||||
const requiredMajor = netId === NetId.MAINNET ? '4' : '5';
|
||||
const isUpdatedMajor = major === requiredMajor;
|
||||
|
||||
if (prerelease) return false;
|
||||
return isUpdatedMajor && (Number(patch) >= 5 || netId !== NetId.MAINNET); // Patch checking - also backwards compatibility for Mainnet
|
||||
}
|
||||
**/
|
||||
export declare function calculateScore({ stakeBalance, tornadoServiceFee }: RelayerInfo): bigint;
|
||||
export declare function getWeightRandom(weightsScores: bigint[], random: bigint): number;
|
||||
export type RelayerInstanceList = {
|
||||
[key in string]: {
|
||||
export interface RelayerInstanceList {
|
||||
[key: string]: {
|
||||
instanceAddress: {
|
||||
[key in string]: string;
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
export declare function getSupportedInstances(instanceList: RelayerInstanceList): string[];
|
||||
export declare function pickWeightedRandomRelayer(relayers: RelayerInfo[], netId: NetIdType): RelayerInfo;
|
||||
export declare function pickWeightedRandomRelayer(relayers: RelayerInfo[]): RelayerInfo;
|
||||
export interface RelayerClientConstructor {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
Aggregator: Aggregator;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
}
|
||||
export type RelayerClientWithdraw = snarkProofs & {
|
||||
contract: string;
|
||||
};
|
||||
export declare class RelayerClient {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
Aggregator: Aggregator;
|
||||
selectedRelayer?: Relayer;
|
||||
selectedRelayer?: RelayerInfo;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
constructor({ netId, config, Aggregator, fetchDataOptions }: RelayerClientConstructor);
|
||||
askRelayerStatus({ hostname, relayerAddress, }: {
|
||||
hostname: string;
|
||||
tovarish: boolean;
|
||||
constructor({ netId, config, fetchDataOptions }: RelayerClientConstructor);
|
||||
askRelayerStatus({ hostname, url, relayerAddress, }: {
|
||||
hostname?: string;
|
||||
url?: string;
|
||||
relayerAddress?: string;
|
||||
}): Promise<RelayerStatus>;
|
||||
filterRelayer(curr: RelayerStructOutput, relayer: RelayerParams, subdomains: string[], debugRelayer?: boolean): Promise<RelayerInfo | RelayerError>;
|
||||
getValidRelayers(relayers: RelayerParams[], subdomains: string[], debugRelayer?: boolean): Promise<{
|
||||
filterRelayer(relayer: CachedRelayerInfo): Promise<RelayerInfo | RelayerError | undefined>;
|
||||
getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: RelayerInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}>;
|
||||
pickWeightedRandomRelayer(relayers: RelayerInfo[]): RelayerInfo;
|
||||
tornadoWithdraw({ contract, proof, args }: RelayerClientWithdraw): Promise<void>;
|
||||
tornadoWithdraw({ contract, proof, args }: TornadoWithdrawParams, callback?: (jobResp: RelayerTornadoWithdraw | RelayerTornadoJobs) => void): Promise<void>;
|
||||
}
|
||||
|
||||
2
dist/schemas/ajv.d.ts
vendored
Normal file
2
dist/schemas/ajv.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import Ajv from 'ajv';
|
||||
export declare const ajv: Ajv;
|
||||
492
dist/schemas/events.d.ts
vendored
Normal file
492
dist/schemas/events.d.ts
vendored
Normal file
@@ -0,0 +1,492 @@
|
||||
export declare const governanceEventsSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly anyOf: readonly [{
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly id: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly proposer: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly target: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly startTime: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly endTime: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly description: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "event", "id", "proposer", "target", "startTime", "endTime", "description"];
|
||||
readonly additionalProperties: false;
|
||||
}, {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly proposalId: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly voter: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly support: {
|
||||
readonly type: "boolean";
|
||||
};
|
||||
readonly votes: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly from: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly input: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "event", "proposalId", "voter", "support", "votes", "from", "input"];
|
||||
readonly additionalProperties: false;
|
||||
}, {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly account: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly delegateTo: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "account", "delegateTo"];
|
||||
readonly additionalProperties: false;
|
||||
}, {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly account: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly delegateFrom: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "account", "delegateFrom"];
|
||||
readonly additionalProperties: false;
|
||||
}];
|
||||
};
|
||||
};
|
||||
export declare const relayerRegistryEventsSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly anyOf: readonly [{
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly ensName: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly relayerAddress: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly ensHash: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly stakedAmount: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "event", "ensName", "relayerAddress", "ensHash", "stakedAmount"];
|
||||
readonly additionalProperties: false;
|
||||
}, {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly relayerAddress: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "event", "relayerAddress"];
|
||||
readonly additionalProperties: false;
|
||||
}, {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly relayerAddress: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly workerAddress: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "event", "relayerAddress", "workerAddress"];
|
||||
readonly additionalProperties: false;
|
||||
}];
|
||||
};
|
||||
};
|
||||
export declare const stakeBurnedEventsSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly relayerAddress: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly amountBurned: {
|
||||
readonly type: "string";
|
||||
readonly BN: true;
|
||||
};
|
||||
readonly instanceAddress: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly gasFee: {
|
||||
readonly type: "string";
|
||||
readonly BN: true;
|
||||
};
|
||||
readonly relayerFee: {
|
||||
readonly type: "string";
|
||||
readonly BN: true;
|
||||
};
|
||||
readonly timestamp: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "relayerAddress", "amountBurned", "instanceAddress", "gasFee", "relayerFee", "timestamp"];
|
||||
readonly additionalProperties: false;
|
||||
};
|
||||
};
|
||||
export declare const depositsEventsSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly commitment: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
readonly leafIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly timestamp: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly from: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "commitment", "leafIndex", "timestamp", "from"];
|
||||
readonly additionalProperties: false;
|
||||
};
|
||||
};
|
||||
export declare const withdrawalsEventsSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly nullifierHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
readonly to: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly fee: {
|
||||
readonly type: "string";
|
||||
readonly BN: true;
|
||||
};
|
||||
readonly timestamp: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "nullifierHash", "to", "fee", "timestamp"];
|
||||
readonly additionalProperties: false;
|
||||
};
|
||||
};
|
||||
export declare const tornadoEventsSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly anyOf: readonly [{
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly instanceAddress: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly commitment: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
readonly leafIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly timestamp: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly from: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "event", "instanceAddress", "commitment", "leafIndex", "timestamp", "from"];
|
||||
readonly additionalProperties: false;
|
||||
}, {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly event: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly instanceAddress: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly nullifierHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
readonly to: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly relayerAddress: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly fee: {
|
||||
readonly type: "string";
|
||||
readonly BN: true;
|
||||
};
|
||||
readonly timestamp: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "event", "instanceAddress", "nullifierHash", "to", "relayerAddress", "fee", "timestamp"];
|
||||
readonly additionalProperties: false;
|
||||
}];
|
||||
};
|
||||
};
|
||||
export declare const echoEventsSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly address: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
readonly encryptedAccount: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "address", "encryptedAccount"];
|
||||
readonly additionalProperties: false;
|
||||
};
|
||||
};
|
||||
export declare const encryptedNotesSchema: {
|
||||
readonly type: "array";
|
||||
readonly items: {
|
||||
readonly type: "object";
|
||||
readonly properties: {
|
||||
readonly encryptedNote: {
|
||||
readonly type: "string";
|
||||
};
|
||||
readonly blockNumber: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly logIndex: {
|
||||
readonly type: "number";
|
||||
};
|
||||
readonly transactionHash: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
};
|
||||
readonly required: readonly [...string[], "encryptedNote"];
|
||||
readonly additionalProperties: false;
|
||||
};
|
||||
};
|
||||
export declare function getEventsSchemaValidator(type: string): import("ajv").ValidateFunction<unknown>;
|
||||
5
dist/schemas/index.d.ts
vendored
5
dist/schemas/index.d.ts
vendored
@@ -1,4 +1,5 @@
|
||||
import Ajv from 'ajv';
|
||||
export declare const ajv: Ajv;
|
||||
export * from './ajv';
|
||||
export * from './events';
|
||||
export * from './status';
|
||||
export * from './jobs';
|
||||
export * from './types';
|
||||
|
||||
5
dist/schemas/jobs.d.ts
vendored
5
dist/schemas/jobs.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
export type jobsSchema = {
|
||||
export interface jobsSchema {
|
||||
type: string;
|
||||
properties: {
|
||||
error: {
|
||||
@@ -36,5 +36,6 @@ export type jobsSchema = {
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
}
|
||||
export declare const jobsSchema: jobsSchema;
|
||||
export declare const jobRequestSchema: jobsSchema;
|
||||
|
||||
60
dist/schemas/status.d.ts
vendored
60
dist/schemas/status.d.ts
vendored
@@ -1,15 +1,16 @@
|
||||
import { Config, NetIdType } from '../networkConfig';
|
||||
export type statusInstanceType = {
|
||||
import { addressSchemaType, bnSchemaType } from '.';
|
||||
export interface statusInstanceType {
|
||||
type: string;
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof addressType;
|
||||
[key in string]: typeof addressSchemaType;
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
tokenAddress?: typeof addressType;
|
||||
tokenAddress?: typeof addressSchemaType;
|
||||
symbol?: {
|
||||
enum: string[];
|
||||
};
|
||||
@@ -18,25 +19,25 @@ export type statusInstanceType = {
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
export type statusInstancesType = {
|
||||
}
|
||||
export interface statusInstancesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: statusInstanceType;
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
export type statusEthPricesType = {
|
||||
}
|
||||
export interface statusEthPricesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof bnType;
|
||||
[key in string]: typeof bnSchemaType;
|
||||
};
|
||||
required?: string[];
|
||||
};
|
||||
export type statusSchema = {
|
||||
}
|
||||
export interface statusSchema {
|
||||
type: string;
|
||||
properties: {
|
||||
rewardAccount: typeof addressType;
|
||||
rewardAccount: typeof addressSchemaType;
|
||||
instances?: statusInstancesType;
|
||||
gasPrices: {
|
||||
type: string;
|
||||
@@ -56,9 +57,13 @@ export type statusSchema = {
|
||||
maximum: number;
|
||||
minimum: number;
|
||||
};
|
||||
latestBlock?: {
|
||||
latestBlock: {
|
||||
type: string;
|
||||
};
|
||||
latestBalance: {
|
||||
type: string;
|
||||
BN: boolean;
|
||||
};
|
||||
version: {
|
||||
type: string;
|
||||
};
|
||||
@@ -74,19 +79,28 @@ export type statusSchema = {
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
syncStatus: {
|
||||
type: string;
|
||||
properties: {
|
||||
events: {
|
||||
type: string;
|
||||
};
|
||||
tokenPrice: {
|
||||
type: string;
|
||||
};
|
||||
gasPrice: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
onSyncEvents: {
|
||||
type: string;
|
||||
};
|
||||
currentQueue: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
declare const addressType: {
|
||||
type: string;
|
||||
pattern: string;
|
||||
};
|
||||
declare const bnType: {
|
||||
type: string;
|
||||
BN: boolean;
|
||||
};
|
||||
export declare function getStatusSchema(netId: NetIdType, config: Config): statusSchema;
|
||||
export {};
|
||||
}
|
||||
export declare function getStatusSchema(netId: NetIdType, config: Config, tovarish: boolean): statusSchema;
|
||||
|
||||
22
dist/schemas/types.d.ts
vendored
Normal file
22
dist/schemas/types.d.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
export declare const addressSchemaType: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{40}$";
|
||||
readonly isAddress: true;
|
||||
};
|
||||
export declare const bnSchemaType: {
|
||||
readonly type: "string";
|
||||
readonly BN: true;
|
||||
};
|
||||
export declare const proofSchemaType: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{512}$";
|
||||
};
|
||||
export declare const bytes32SchemaType: {
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
export declare const bytes32BNSchemaType: {
|
||||
readonly BN: true;
|
||||
readonly type: "string";
|
||||
readonly pattern: "^0x[a-fA-F0-9]{64}$";
|
||||
};
|
||||
81951
dist/index.umd.js → dist/tornado.umd.js
vendored
81951
dist/index.umd.js → dist/tornado.umd.js
vendored
File diff suppressed because one or more lines are too long
8
dist/tornado.umd.min.js
vendored
Normal file
8
dist/tornado.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
34
dist/tornado.umd.min.js.LICENSE.txt
vendored
Normal file
34
dist/tornado.umd.min.js.LICENSE.txt
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
* The buffer module from node.js, for the browser.
|
||||
*
|
||||
* @author Feross Aboukhadijeh <https://feross.org>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
/*! MIT License. Copyright 2015-2022 Richard Moore <me@ricmoo.com>. See LICENSE.txt. */
|
||||
|
||||
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
|
||||
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
|
||||
/*! 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
|
||||
*/
|
||||
45121
dist/tornadoContracts.umd.js
vendored
Normal file
45121
dist/tornadoContracts.umd.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/tornadoContracts.umd.min.js
vendored
Normal file
1
dist/tornadoContracts.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
71
dist/tovarishClient.d.ts
vendored
Normal file
71
dist/tovarishClient.d.ts
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
import { RelayerClient, RelayerClientConstructor, RelayerError, RelayerInfo, RelayerStatus } from './relayerClient';
|
||||
import { CachedRelayerInfo, MinimalEvents } from './events';
|
||||
export declare const MAX_TOVARISH_EVENTS = 5000;
|
||||
export interface EventsStatus {
|
||||
events: number;
|
||||
lastBlock: number;
|
||||
}
|
||||
export interface TovarishEventsStatus {
|
||||
governance?: EventsStatus;
|
||||
registry?: EventsStatus;
|
||||
revenue?: EventsStatus;
|
||||
echo: EventsStatus;
|
||||
encrypted_notes: EventsStatus;
|
||||
tornado: EventsStatus;
|
||||
}
|
||||
export interface TovarishSyncStatus {
|
||||
events: boolean;
|
||||
tokenPrice: boolean;
|
||||
gasPrice: boolean;
|
||||
}
|
||||
export interface TovarishStatus extends RelayerStatus {
|
||||
latestBalance: string;
|
||||
events: TovarishEventsStatus;
|
||||
syncStatus: TovarishSyncStatus;
|
||||
onSyncEvents: boolean;
|
||||
}
|
||||
export interface TovarishInfo extends RelayerInfo {
|
||||
latestBlock: number;
|
||||
latestBalance: string;
|
||||
version: string;
|
||||
events: TovarishEventsStatus;
|
||||
syncStatus: TovarishSyncStatus;
|
||||
}
|
||||
export interface TovarishEventsQuery {
|
||||
type: string;
|
||||
currency?: string;
|
||||
amount?: string;
|
||||
fromBlock: number;
|
||||
recent?: boolean;
|
||||
}
|
||||
export interface BaseTovarishEvents<T> {
|
||||
events: T[];
|
||||
lastSyncBlock: number;
|
||||
}
|
||||
export declare class TovarishClient extends RelayerClient {
|
||||
selectedRelayer?: TovarishInfo;
|
||||
constructor(clientConstructor: RelayerClientConstructor);
|
||||
askRelayerStatus({ hostname, url, relayerAddress, }: {
|
||||
hostname?: string;
|
||||
url?: string;
|
||||
relayerAddress?: string;
|
||||
}): Promise<TovarishStatus>;
|
||||
/**
|
||||
* Ask status for all enabled chains for tovarish relayer
|
||||
*/
|
||||
askAllStatus({ hostname, url, relayerAddress, }: {
|
||||
hostname?: string;
|
||||
url?: string;
|
||||
relayerAddress?: string;
|
||||
}): Promise<TovarishStatus[]>;
|
||||
filterRelayer(relayer: CachedRelayerInfo): Promise<TovarishInfo | RelayerError | undefined>;
|
||||
getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: TovarishInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}>;
|
||||
getTovarishRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: TovarishInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}>;
|
||||
getEvents<T extends MinimalEvents>({ type, currency, amount, fromBlock, recent, }: TovarishEventsQuery): Promise<BaseTovarishEvents<T>>;
|
||||
}
|
||||
847
dist/typechain/ENSNameWrapper.d.ts
vendored
Normal file
847
dist/typechain/ENSNameWrapper.d.ts
vendored
Normal file
@@ -0,0 +1,847 @@
|
||||
import type { BaseContract, BigNumberish, BytesLike, FunctionFragment, Result, Interface, EventFragment, AddressLike, ContractRunner, ContractMethod, Listener } from "ethers";
|
||||
import type { TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog, TypedLogDescription, TypedListener, TypedContractMethod } from "./common";
|
||||
export interface ENSNameWrapperInterface extends Interface {
|
||||
getFunction(nameOrSignature: "_tokens" | "allFusesBurned" | "approve" | "balanceOf" | "balanceOfBatch" | "canExtendSubnames" | "canModifyName" | "controllers" | "ens" | "extendExpiry" | "getApproved" | "getData" | "isApprovedForAll" | "isWrapped(bytes32,bytes32)" | "isWrapped(bytes32)" | "metadataService" | "name" | "names" | "onERC721Received" | "owner" | "ownerOf" | "recoverFunds" | "registerAndWrapETH2LD" | "registrar" | "renew" | "renounceOwnership" | "safeBatchTransferFrom" | "safeTransferFrom" | "setApprovalForAll" | "setChildFuses" | "setController" | "setFuses" | "setMetadataService" | "setRecord" | "setResolver" | "setSubnodeOwner" | "setSubnodeRecord" | "setTTL" | "setUpgradeContract" | "supportsInterface" | "transferOwnership" | "unwrap" | "unwrapETH2LD" | "upgrade" | "upgradeContract" | "uri" | "wrap" | "wrapETH2LD"): FunctionFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "Approval" | "ApprovalForAll" | "ControllerChanged" | "ExpiryExtended" | "FusesSet" | "NameUnwrapped" | "NameWrapped" | "OwnershipTransferred" | "TransferBatch" | "TransferSingle" | "URI"): EventFragment;
|
||||
encodeFunctionData(functionFragment: "_tokens", values: [BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "allFusesBurned", values: [BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "approve", values: [AddressLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "balanceOf", values: [AddressLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "balanceOfBatch", values: [AddressLike[], BigNumberish[]]): string;
|
||||
encodeFunctionData(functionFragment: "canExtendSubnames", values: [BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "canModifyName", values: [BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "controllers", values: [AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "ens", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "extendExpiry", values: [BytesLike, BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "getApproved", values: [BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "getData", values: [BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "isApprovedForAll", values: [AddressLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "isWrapped(bytes32,bytes32)", values: [BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "isWrapped(bytes32)", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "metadataService", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "name", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "names", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "onERC721Received", values: [AddressLike, AddressLike, BigNumberish, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "owner", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "ownerOf", values: [BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "recoverFunds", values: [AddressLike, AddressLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "registerAndWrapETH2LD", values: [string, AddressLike, BigNumberish, AddressLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "registrar", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "renew", values: [BigNumberish, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "renounceOwnership", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "safeBatchTransferFrom", values: [
|
||||
AddressLike,
|
||||
AddressLike,
|
||||
BigNumberish[],
|
||||
BigNumberish[],
|
||||
BytesLike
|
||||
]): string;
|
||||
encodeFunctionData(functionFragment: "safeTransferFrom", values: [AddressLike, AddressLike, BigNumberish, BigNumberish, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setApprovalForAll", values: [AddressLike, boolean]): string;
|
||||
encodeFunctionData(functionFragment: "setChildFuses", values: [BytesLike, BytesLike, BigNumberish, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "setController", values: [AddressLike, boolean]): string;
|
||||
encodeFunctionData(functionFragment: "setFuses", values: [BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "setMetadataService", values: [AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "setRecord", values: [BytesLike, AddressLike, AddressLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "setResolver", values: [BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "setSubnodeOwner", values: [BytesLike, string, AddressLike, BigNumberish, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "setSubnodeRecord", values: [
|
||||
BytesLike,
|
||||
string,
|
||||
AddressLike,
|
||||
AddressLike,
|
||||
BigNumberish,
|
||||
BigNumberish,
|
||||
BigNumberish
|
||||
]): string;
|
||||
encodeFunctionData(functionFragment: "setTTL", values: [BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "setUpgradeContract", values: [AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "supportsInterface", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "transferOwnership", values: [AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "unwrap", values: [BytesLike, BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "unwrapETH2LD", values: [BytesLike, AddressLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "upgrade", values: [BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "upgradeContract", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "uri", values: [BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "wrap", values: [BytesLike, AddressLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "wrapETH2LD", values: [string, AddressLike, BigNumberish, AddressLike]): string;
|
||||
decodeFunctionResult(functionFragment: "_tokens", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "allFusesBurned", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "approve", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "balanceOf", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "balanceOfBatch", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "canExtendSubnames", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "canModifyName", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "controllers", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "ens", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "extendExpiry", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "getApproved", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "getData", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "isApprovedForAll", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "isWrapped(bytes32,bytes32)", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "isWrapped(bytes32)", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "metadataService", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "name", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "names", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "onERC721Received", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "ownerOf", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "recoverFunds", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "registerAndWrapETH2LD", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "registrar", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "renew", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "renounceOwnership", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "safeBatchTransferFrom", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "safeTransferFrom", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setApprovalForAll", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setChildFuses", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setController", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setFuses", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setMetadataService", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setRecord", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setResolver", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setSubnodeOwner", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setSubnodeRecord", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setTTL", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setUpgradeContract", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "supportsInterface", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "transferOwnership", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "unwrap", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "unwrapETH2LD", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "upgrade", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "upgradeContract", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "uri", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "wrap", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "wrapETH2LD", data: BytesLike): Result;
|
||||
}
|
||||
export declare namespace ApprovalEvent {
|
||||
type InputTuple = [
|
||||
owner: AddressLike,
|
||||
approved: AddressLike,
|
||||
tokenId: BigNumberish
|
||||
];
|
||||
type OutputTuple = [owner: string, approved: string, tokenId: bigint];
|
||||
interface OutputObject {
|
||||
owner: string;
|
||||
approved: string;
|
||||
tokenId: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace ApprovalForAllEvent {
|
||||
type InputTuple = [
|
||||
account: AddressLike,
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
];
|
||||
type OutputTuple = [
|
||||
account: string,
|
||||
operator: string,
|
||||
approved: boolean
|
||||
];
|
||||
interface OutputObject {
|
||||
account: string;
|
||||
operator: string;
|
||||
approved: boolean;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace ControllerChangedEvent {
|
||||
type InputTuple = [controller: AddressLike, active: boolean];
|
||||
type OutputTuple = [controller: string, active: boolean];
|
||||
interface OutputObject {
|
||||
controller: string;
|
||||
active: boolean;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace ExpiryExtendedEvent {
|
||||
type InputTuple = [node: BytesLike, expiry: BigNumberish];
|
||||
type OutputTuple = [node: string, expiry: bigint];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
expiry: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace FusesSetEvent {
|
||||
type InputTuple = [node: BytesLike, fuses: BigNumberish];
|
||||
type OutputTuple = [node: string, fuses: bigint];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
fuses: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace NameUnwrappedEvent {
|
||||
type InputTuple = [node: BytesLike, owner: AddressLike];
|
||||
type OutputTuple = [node: string, owner: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
owner: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace NameWrappedEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
name: BytesLike,
|
||||
owner: AddressLike,
|
||||
fuses: BigNumberish,
|
||||
expiry: BigNumberish
|
||||
];
|
||||
type OutputTuple = [
|
||||
node: string,
|
||||
name: string,
|
||||
owner: string,
|
||||
fuses: bigint,
|
||||
expiry: bigint
|
||||
];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
name: string;
|
||||
owner: string;
|
||||
fuses: bigint;
|
||||
expiry: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace OwnershipTransferredEvent {
|
||||
type InputTuple = [previousOwner: AddressLike, newOwner: AddressLike];
|
||||
type OutputTuple = [previousOwner: string, newOwner: string];
|
||||
interface OutputObject {
|
||||
previousOwner: string;
|
||||
newOwner: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace TransferBatchEvent {
|
||||
type InputTuple = [
|
||||
operator: AddressLike,
|
||||
from: AddressLike,
|
||||
to: AddressLike,
|
||||
ids: BigNumberish[],
|
||||
values: BigNumberish[]
|
||||
];
|
||||
type OutputTuple = [
|
||||
operator: string,
|
||||
from: string,
|
||||
to: string,
|
||||
ids: bigint[],
|
||||
values: bigint[]
|
||||
];
|
||||
interface OutputObject {
|
||||
operator: string;
|
||||
from: string;
|
||||
to: string;
|
||||
ids: bigint[];
|
||||
values: bigint[];
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace TransferSingleEvent {
|
||||
type InputTuple = [
|
||||
operator: AddressLike,
|
||||
from: AddressLike,
|
||||
to: AddressLike,
|
||||
id: BigNumberish,
|
||||
value: BigNumberish
|
||||
];
|
||||
type OutputTuple = [
|
||||
operator: string,
|
||||
from: string,
|
||||
to: string,
|
||||
id: bigint,
|
||||
value: bigint
|
||||
];
|
||||
interface OutputObject {
|
||||
operator: string;
|
||||
from: string;
|
||||
to: string;
|
||||
id: bigint;
|
||||
value: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace URIEvent {
|
||||
type InputTuple = [value: string, id: BigNumberish];
|
||||
type OutputTuple = [value: string, id: bigint];
|
||||
interface OutputObject {
|
||||
value: string;
|
||||
id: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export interface ENSNameWrapper extends BaseContract {
|
||||
connect(runner?: ContractRunner | null): ENSNameWrapper;
|
||||
waitForDeployment(): Promise<this>;
|
||||
interface: ENSNameWrapperInterface;
|
||||
queryFilter<TCEvent extends TypedContractEvent>(event: TCEvent, fromBlockOrBlockhash?: string | number | undefined, toBlock?: string | number | undefined): Promise<Array<TypedEventLog<TCEvent>>>;
|
||||
queryFilter<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, fromBlockOrBlockhash?: string | number | undefined, toBlock?: string | number | undefined): Promise<Array<TypedEventLog<TCEvent>>>;
|
||||
on<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
on<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
once<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
once<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
listeners<TCEvent extends TypedContractEvent>(event: TCEvent): Promise<Array<TypedListener<TCEvent>>>;
|
||||
listeners(eventName?: string): Promise<Array<Listener>>;
|
||||
removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>;
|
||||
_tokens: TypedContractMethod<[arg0: BigNumberish], [bigint], "view">;
|
||||
allFusesBurned: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
fuseMask: BigNumberish
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
approve: TypedContractMethod<[
|
||||
to: AddressLike,
|
||||
tokenId: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
balanceOf: TypedContractMethod<[
|
||||
account: AddressLike,
|
||||
id: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "view">;
|
||||
balanceOfBatch: TypedContractMethod<[
|
||||
accounts: AddressLike[],
|
||||
ids: BigNumberish[]
|
||||
], [
|
||||
bigint[]
|
||||
], "view">;
|
||||
canExtendSubnames: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
addr: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
canModifyName: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
addr: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
controllers: TypedContractMethod<[arg0: AddressLike], [boolean], "view">;
|
||||
ens: TypedContractMethod<[], [string], "view">;
|
||||
extendExpiry: TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
getApproved: TypedContractMethod<[id: BigNumberish], [string], "view">;
|
||||
getData: TypedContractMethod<[
|
||||
id: BigNumberish
|
||||
], [
|
||||
[
|
||||
string,
|
||||
bigint,
|
||||
bigint
|
||||
] & {
|
||||
owner: string;
|
||||
fuses: bigint;
|
||||
expiry: bigint;
|
||||
}
|
||||
], "view">;
|
||||
isApprovedForAll: TypedContractMethod<[
|
||||
account: AddressLike,
|
||||
operator: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
"isWrapped(bytes32,bytes32)": TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
"isWrapped(bytes32)": TypedContractMethod<[
|
||||
node: BytesLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
metadataService: TypedContractMethod<[], [string], "view">;
|
||||
name: TypedContractMethod<[], [string], "view">;
|
||||
names: TypedContractMethod<[arg0: BytesLike], [string], "view">;
|
||||
onERC721Received: TypedContractMethod<[
|
||||
to: AddressLike,
|
||||
arg1: AddressLike,
|
||||
tokenId: BigNumberish,
|
||||
data: BytesLike
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
owner: TypedContractMethod<[], [string], "view">;
|
||||
ownerOf: TypedContractMethod<[id: BigNumberish], [string], "view">;
|
||||
recoverFunds: TypedContractMethod<[
|
||||
_token: AddressLike,
|
||||
_to: AddressLike,
|
||||
_amount: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
registerAndWrapETH2LD: TypedContractMethod<[
|
||||
label: string,
|
||||
wrappedOwner: AddressLike,
|
||||
duration: BigNumberish,
|
||||
resolver: AddressLike,
|
||||
ownerControlledFuses: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
registrar: TypedContractMethod<[], [string], "view">;
|
||||
renew: TypedContractMethod<[
|
||||
tokenId: BigNumberish,
|
||||
duration: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
renounceOwnership: TypedContractMethod<[], [void], "nonpayable">;
|
||||
safeBatchTransferFrom: TypedContractMethod<[
|
||||
from: AddressLike,
|
||||
to: AddressLike,
|
||||
ids: BigNumberish[],
|
||||
amounts: BigNumberish[],
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
safeTransferFrom: TypedContractMethod<[
|
||||
from: AddressLike,
|
||||
to: AddressLike,
|
||||
id: BigNumberish,
|
||||
amount: BigNumberish,
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setApprovalForAll: TypedContractMethod<[
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setChildFuses: TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike,
|
||||
fuses: BigNumberish,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setController: TypedContractMethod<[
|
||||
controller: AddressLike,
|
||||
active: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setFuses: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
ownerControlledFuses: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
setMetadataService: TypedContractMethod<[
|
||||
_metadataService: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setRecord: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setResolver: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setSubnodeOwner: TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
label: string,
|
||||
owner: AddressLike,
|
||||
fuses: BigNumberish,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
setSubnodeRecord: TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
label: string,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish,
|
||||
fuses: BigNumberish,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
setTTL: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setUpgradeContract: TypedContractMethod<[
|
||||
_upgradeAddress: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
supportsInterface: TypedContractMethod<[
|
||||
interfaceId: BytesLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
transferOwnership: TypedContractMethod<[
|
||||
newOwner: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
unwrap: TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike,
|
||||
controller: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
unwrapETH2LD: TypedContractMethod<[
|
||||
labelhash: BytesLike,
|
||||
registrant: AddressLike,
|
||||
controller: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
upgrade: TypedContractMethod<[
|
||||
name: BytesLike,
|
||||
extraData: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
upgradeContract: TypedContractMethod<[], [string], "view">;
|
||||
uri: TypedContractMethod<[tokenId: BigNumberish], [string], "view">;
|
||||
wrap: TypedContractMethod<[
|
||||
name: BytesLike,
|
||||
wrappedOwner: AddressLike,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
wrapETH2LD: TypedContractMethod<[
|
||||
label: string,
|
||||
wrappedOwner: AddressLike,
|
||||
ownerControlledFuses: BigNumberish,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T;
|
||||
getFunction(nameOrSignature: "_tokens"): TypedContractMethod<[arg0: BigNumberish], [bigint], "view">;
|
||||
getFunction(nameOrSignature: "allFusesBurned"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
fuseMask: BigNumberish
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "approve"): TypedContractMethod<[
|
||||
to: AddressLike,
|
||||
tokenId: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "balanceOf"): TypedContractMethod<[
|
||||
account: AddressLike,
|
||||
id: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "balanceOfBatch"): TypedContractMethod<[
|
||||
accounts: AddressLike[],
|
||||
ids: BigNumberish[]
|
||||
], [
|
||||
bigint[]
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "canExtendSubnames"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
addr: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "canModifyName"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
addr: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "controllers"): TypedContractMethod<[arg0: AddressLike], [boolean], "view">;
|
||||
getFunction(nameOrSignature: "ens"): TypedContractMethod<[], [string], "view">;
|
||||
getFunction(nameOrSignature: "extendExpiry"): TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "getApproved"): TypedContractMethod<[id: BigNumberish], [string], "view">;
|
||||
getFunction(nameOrSignature: "getData"): TypedContractMethod<[
|
||||
id: BigNumberish
|
||||
], [
|
||||
[
|
||||
string,
|
||||
bigint,
|
||||
bigint
|
||||
] & {
|
||||
owner: string;
|
||||
fuses: bigint;
|
||||
expiry: bigint;
|
||||
}
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "isApprovedForAll"): TypedContractMethod<[
|
||||
account: AddressLike,
|
||||
operator: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "isWrapped(bytes32,bytes32)"): TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "isWrapped(bytes32)"): TypedContractMethod<[node: BytesLike], [boolean], "view">;
|
||||
getFunction(nameOrSignature: "metadataService"): TypedContractMethod<[], [string], "view">;
|
||||
getFunction(nameOrSignature: "name"): TypedContractMethod<[], [string], "view">;
|
||||
getFunction(nameOrSignature: "names"): TypedContractMethod<[arg0: BytesLike], [string], "view">;
|
||||
getFunction(nameOrSignature: "onERC721Received"): TypedContractMethod<[
|
||||
to: AddressLike,
|
||||
arg1: AddressLike,
|
||||
tokenId: BigNumberish,
|
||||
data: BytesLike
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "owner"): TypedContractMethod<[], [string], "view">;
|
||||
getFunction(nameOrSignature: "ownerOf"): TypedContractMethod<[id: BigNumberish], [string], "view">;
|
||||
getFunction(nameOrSignature: "recoverFunds"): TypedContractMethod<[
|
||||
_token: AddressLike,
|
||||
_to: AddressLike,
|
||||
_amount: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "registerAndWrapETH2LD"): TypedContractMethod<[
|
||||
label: string,
|
||||
wrappedOwner: AddressLike,
|
||||
duration: BigNumberish,
|
||||
resolver: AddressLike,
|
||||
ownerControlledFuses: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "registrar"): TypedContractMethod<[], [string], "view">;
|
||||
getFunction(nameOrSignature: "renew"): TypedContractMethod<[
|
||||
tokenId: BigNumberish,
|
||||
duration: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "renounceOwnership"): TypedContractMethod<[], [void], "nonpayable">;
|
||||
getFunction(nameOrSignature: "safeBatchTransferFrom"): TypedContractMethod<[
|
||||
from: AddressLike,
|
||||
to: AddressLike,
|
||||
ids: BigNumberish[],
|
||||
amounts: BigNumberish[],
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "safeTransferFrom"): TypedContractMethod<[
|
||||
from: AddressLike,
|
||||
to: AddressLike,
|
||||
id: BigNumberish,
|
||||
amount: BigNumberish,
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setApprovalForAll"): TypedContractMethod<[
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setChildFuses"): TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike,
|
||||
fuses: BigNumberish,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setController"): TypedContractMethod<[
|
||||
controller: AddressLike,
|
||||
active: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setFuses"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
ownerControlledFuses: BigNumberish
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setMetadataService"): TypedContractMethod<[_metadataService: AddressLike], [void], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setRecord"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setResolver"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setSubnodeOwner"): TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
label: string,
|
||||
owner: AddressLike,
|
||||
fuses: BigNumberish,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setSubnodeRecord"): TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
label: string,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish,
|
||||
fuses: BigNumberish,
|
||||
expiry: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setTTL"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setUpgradeContract"): TypedContractMethod<[_upgradeAddress: AddressLike], [void], "nonpayable">;
|
||||
getFunction(nameOrSignature: "supportsInterface"): TypedContractMethod<[interfaceId: BytesLike], [boolean], "view">;
|
||||
getFunction(nameOrSignature: "transferOwnership"): TypedContractMethod<[newOwner: AddressLike], [void], "nonpayable">;
|
||||
getFunction(nameOrSignature: "unwrap"): TypedContractMethod<[
|
||||
parentNode: BytesLike,
|
||||
labelhash: BytesLike,
|
||||
controller: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "unwrapETH2LD"): TypedContractMethod<[
|
||||
labelhash: BytesLike,
|
||||
registrant: AddressLike,
|
||||
controller: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "upgrade"): TypedContractMethod<[
|
||||
name: BytesLike,
|
||||
extraData: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "upgradeContract"): TypedContractMethod<[], [string], "view">;
|
||||
getFunction(nameOrSignature: "uri"): TypedContractMethod<[tokenId: BigNumberish], [string], "view">;
|
||||
getFunction(nameOrSignature: "wrap"): TypedContractMethod<[
|
||||
name: BytesLike,
|
||||
wrappedOwner: AddressLike,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "wrapETH2LD"): TypedContractMethod<[
|
||||
label: string,
|
||||
wrappedOwner: AddressLike,
|
||||
ownerControlledFuses: BigNumberish,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
bigint
|
||||
], "nonpayable">;
|
||||
getEvent(key: "Approval"): TypedContractEvent<ApprovalEvent.InputTuple, ApprovalEvent.OutputTuple, ApprovalEvent.OutputObject>;
|
||||
getEvent(key: "ApprovalForAll"): TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
getEvent(key: "ControllerChanged"): TypedContractEvent<ControllerChangedEvent.InputTuple, ControllerChangedEvent.OutputTuple, ControllerChangedEvent.OutputObject>;
|
||||
getEvent(key: "ExpiryExtended"): TypedContractEvent<ExpiryExtendedEvent.InputTuple, ExpiryExtendedEvent.OutputTuple, ExpiryExtendedEvent.OutputObject>;
|
||||
getEvent(key: "FusesSet"): TypedContractEvent<FusesSetEvent.InputTuple, FusesSetEvent.OutputTuple, FusesSetEvent.OutputObject>;
|
||||
getEvent(key: "NameUnwrapped"): TypedContractEvent<NameUnwrappedEvent.InputTuple, NameUnwrappedEvent.OutputTuple, NameUnwrappedEvent.OutputObject>;
|
||||
getEvent(key: "NameWrapped"): TypedContractEvent<NameWrappedEvent.InputTuple, NameWrappedEvent.OutputTuple, NameWrappedEvent.OutputObject>;
|
||||
getEvent(key: "OwnershipTransferred"): TypedContractEvent<OwnershipTransferredEvent.InputTuple, OwnershipTransferredEvent.OutputTuple, OwnershipTransferredEvent.OutputObject>;
|
||||
getEvent(key: "TransferBatch"): TypedContractEvent<TransferBatchEvent.InputTuple, TransferBatchEvent.OutputTuple, TransferBatchEvent.OutputObject>;
|
||||
getEvent(key: "TransferSingle"): TypedContractEvent<TransferSingleEvent.InputTuple, TransferSingleEvent.OutputTuple, TransferSingleEvent.OutputObject>;
|
||||
getEvent(key: "URI"): TypedContractEvent<URIEvent.InputTuple, URIEvent.OutputTuple, URIEvent.OutputObject>;
|
||||
filters: {
|
||||
"Approval(address,address,uint256)": TypedContractEvent<ApprovalEvent.InputTuple, ApprovalEvent.OutputTuple, ApprovalEvent.OutputObject>;
|
||||
Approval: TypedContractEvent<ApprovalEvent.InputTuple, ApprovalEvent.OutputTuple, ApprovalEvent.OutputObject>;
|
||||
"ApprovalForAll(address,address,bool)": TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
ApprovalForAll: TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
"ControllerChanged(address,bool)": TypedContractEvent<ControllerChangedEvent.InputTuple, ControllerChangedEvent.OutputTuple, ControllerChangedEvent.OutputObject>;
|
||||
ControllerChanged: TypedContractEvent<ControllerChangedEvent.InputTuple, ControllerChangedEvent.OutputTuple, ControllerChangedEvent.OutputObject>;
|
||||
"ExpiryExtended(bytes32,uint64)": TypedContractEvent<ExpiryExtendedEvent.InputTuple, ExpiryExtendedEvent.OutputTuple, ExpiryExtendedEvent.OutputObject>;
|
||||
ExpiryExtended: TypedContractEvent<ExpiryExtendedEvent.InputTuple, ExpiryExtendedEvent.OutputTuple, ExpiryExtendedEvent.OutputObject>;
|
||||
"FusesSet(bytes32,uint32)": TypedContractEvent<FusesSetEvent.InputTuple, FusesSetEvent.OutputTuple, FusesSetEvent.OutputObject>;
|
||||
FusesSet: TypedContractEvent<FusesSetEvent.InputTuple, FusesSetEvent.OutputTuple, FusesSetEvent.OutputObject>;
|
||||
"NameUnwrapped(bytes32,address)": TypedContractEvent<NameUnwrappedEvent.InputTuple, NameUnwrappedEvent.OutputTuple, NameUnwrappedEvent.OutputObject>;
|
||||
NameUnwrapped: TypedContractEvent<NameUnwrappedEvent.InputTuple, NameUnwrappedEvent.OutputTuple, NameUnwrappedEvent.OutputObject>;
|
||||
"NameWrapped(bytes32,bytes,address,uint32,uint64)": TypedContractEvent<NameWrappedEvent.InputTuple, NameWrappedEvent.OutputTuple, NameWrappedEvent.OutputObject>;
|
||||
NameWrapped: TypedContractEvent<NameWrappedEvent.InputTuple, NameWrappedEvent.OutputTuple, NameWrappedEvent.OutputObject>;
|
||||
"OwnershipTransferred(address,address)": TypedContractEvent<OwnershipTransferredEvent.InputTuple, OwnershipTransferredEvent.OutputTuple, OwnershipTransferredEvent.OutputObject>;
|
||||
OwnershipTransferred: TypedContractEvent<OwnershipTransferredEvent.InputTuple, OwnershipTransferredEvent.OutputTuple, OwnershipTransferredEvent.OutputObject>;
|
||||
"TransferBatch(address,address,address,uint256[],uint256[])": TypedContractEvent<TransferBatchEvent.InputTuple, TransferBatchEvent.OutputTuple, TransferBatchEvent.OutputObject>;
|
||||
TransferBatch: TypedContractEvent<TransferBatchEvent.InputTuple, TransferBatchEvent.OutputTuple, TransferBatchEvent.OutputObject>;
|
||||
"TransferSingle(address,address,address,uint256,uint256)": TypedContractEvent<TransferSingleEvent.InputTuple, TransferSingleEvent.OutputTuple, TransferSingleEvent.OutputObject>;
|
||||
TransferSingle: TypedContractEvent<TransferSingleEvent.InputTuple, TransferSingleEvent.OutputTuple, TransferSingleEvent.OutputObject>;
|
||||
"URI(string,uint256)": TypedContractEvent<URIEvent.InputTuple, URIEvent.OutputTuple, URIEvent.OutputObject>;
|
||||
URI: TypedContractEvent<URIEvent.InputTuple, URIEvent.OutputTuple, URIEvent.OutputObject>;
|
||||
};
|
||||
}
|
||||
256
dist/typechain/ENSRegistry.d.ts
vendored
Normal file
256
dist/typechain/ENSRegistry.d.ts
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
import type { BaseContract, BigNumberish, BytesLike, FunctionFragment, Result, Interface, EventFragment, AddressLike, ContractRunner, ContractMethod, Listener } from "ethers";
|
||||
import type { TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog, TypedLogDescription, TypedListener, TypedContractMethod } from "./common";
|
||||
export interface ENSRegistryInterface extends Interface {
|
||||
getFunction(nameOrSignature: "isApprovedForAll" | "old" | "owner" | "recordExists" | "resolver" | "setApprovalForAll" | "setOwner" | "setRecord" | "setResolver" | "setSubnodeOwner" | "setSubnodeRecord" | "setTTL" | "ttl"): FunctionFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "ApprovalForAll" | "NewOwner" | "NewResolver" | "NewTTL" | "Transfer"): EventFragment;
|
||||
encodeFunctionData(functionFragment: "isApprovedForAll", values: [AddressLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "old", values?: undefined): string;
|
||||
encodeFunctionData(functionFragment: "owner", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "recordExists", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "resolver", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setApprovalForAll", values: [AddressLike, boolean]): string;
|
||||
encodeFunctionData(functionFragment: "setOwner", values: [BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "setRecord", values: [BytesLike, AddressLike, AddressLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "setResolver", values: [BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "setSubnodeOwner", values: [BytesLike, BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "setSubnodeRecord", values: [BytesLike, BytesLike, AddressLike, AddressLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "setTTL", values: [BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "ttl", values: [BytesLike]): string;
|
||||
decodeFunctionResult(functionFragment: "isApprovedForAll", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "old", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "recordExists", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "resolver", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setApprovalForAll", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setOwner", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setRecord", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setResolver", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setSubnodeOwner", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setSubnodeRecord", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setTTL", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "ttl", data: BytesLike): Result;
|
||||
}
|
||||
export declare namespace ApprovalForAllEvent {
|
||||
type InputTuple = [
|
||||
owner: AddressLike,
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
];
|
||||
type OutputTuple = [
|
||||
owner: string,
|
||||
operator: string,
|
||||
approved: boolean
|
||||
];
|
||||
interface OutputObject {
|
||||
owner: string;
|
||||
operator: string;
|
||||
approved: boolean;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace NewOwnerEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
label: BytesLike,
|
||||
owner: AddressLike
|
||||
];
|
||||
type OutputTuple = [node: string, label: string, owner: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
label: string;
|
||||
owner: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace NewResolverEvent {
|
||||
type InputTuple = [node: BytesLike, resolver: AddressLike];
|
||||
type OutputTuple = [node: string, resolver: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
resolver: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace NewTTLEvent {
|
||||
type InputTuple = [node: BytesLike, ttl: BigNumberish];
|
||||
type OutputTuple = [node: string, ttl: bigint];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
ttl: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace TransferEvent {
|
||||
type InputTuple = [node: BytesLike, owner: AddressLike];
|
||||
type OutputTuple = [node: string, owner: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
owner: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export interface ENSRegistry extends BaseContract {
|
||||
connect(runner?: ContractRunner | null): ENSRegistry;
|
||||
waitForDeployment(): Promise<this>;
|
||||
interface: ENSRegistryInterface;
|
||||
queryFilter<TCEvent extends TypedContractEvent>(event: TCEvent, fromBlockOrBlockhash?: string | number | undefined, toBlock?: string | number | undefined): Promise<Array<TypedEventLog<TCEvent>>>;
|
||||
queryFilter<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, fromBlockOrBlockhash?: string | number | undefined, toBlock?: string | number | undefined): Promise<Array<TypedEventLog<TCEvent>>>;
|
||||
on<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
on<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
once<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
once<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
listeners<TCEvent extends TypedContractEvent>(event: TCEvent): Promise<Array<TypedListener<TCEvent>>>;
|
||||
listeners(eventName?: string): Promise<Array<Listener>>;
|
||||
removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>;
|
||||
isApprovedForAll: TypedContractMethod<[
|
||||
owner: AddressLike,
|
||||
operator: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
old: TypedContractMethod<[], [string], "view">;
|
||||
owner: TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
recordExists: TypedContractMethod<[node: BytesLike], [boolean], "view">;
|
||||
resolver: TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
setApprovalForAll: TypedContractMethod<[
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setOwner: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
owner: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setRecord: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setResolver: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setSubnodeOwner: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
label: BytesLike,
|
||||
owner: AddressLike
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
setSubnodeRecord: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
label: BytesLike,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setTTL: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
ttl: TypedContractMethod<[node: BytesLike], [bigint], "view">;
|
||||
getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T;
|
||||
getFunction(nameOrSignature: "isApprovedForAll"): TypedContractMethod<[
|
||||
owner: AddressLike,
|
||||
operator: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "old"): TypedContractMethod<[], [string], "view">;
|
||||
getFunction(nameOrSignature: "owner"): TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
getFunction(nameOrSignature: "recordExists"): TypedContractMethod<[node: BytesLike], [boolean], "view">;
|
||||
getFunction(nameOrSignature: "resolver"): TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
getFunction(nameOrSignature: "setApprovalForAll"): TypedContractMethod<[
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setOwner"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
owner: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setRecord"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setResolver"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
resolver: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setSubnodeOwner"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
label: BytesLike,
|
||||
owner: AddressLike
|
||||
], [
|
||||
string
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setSubnodeRecord"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
label: BytesLike,
|
||||
owner: AddressLike,
|
||||
resolver: AddressLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setTTL"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
ttl: BigNumberish
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "ttl"): TypedContractMethod<[node: BytesLike], [bigint], "view">;
|
||||
getEvent(key: "ApprovalForAll"): TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
getEvent(key: "NewOwner"): TypedContractEvent<NewOwnerEvent.InputTuple, NewOwnerEvent.OutputTuple, NewOwnerEvent.OutputObject>;
|
||||
getEvent(key: "NewResolver"): TypedContractEvent<NewResolverEvent.InputTuple, NewResolverEvent.OutputTuple, NewResolverEvent.OutputObject>;
|
||||
getEvent(key: "NewTTL"): TypedContractEvent<NewTTLEvent.InputTuple, NewTTLEvent.OutputTuple, NewTTLEvent.OutputObject>;
|
||||
getEvent(key: "Transfer"): TypedContractEvent<TransferEvent.InputTuple, TransferEvent.OutputTuple, TransferEvent.OutputObject>;
|
||||
filters: {
|
||||
"ApprovalForAll(address,address,bool)": TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
ApprovalForAll: TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
"NewOwner(bytes32,bytes32,address)": TypedContractEvent<NewOwnerEvent.InputTuple, NewOwnerEvent.OutputTuple, NewOwnerEvent.OutputObject>;
|
||||
NewOwner: TypedContractEvent<NewOwnerEvent.InputTuple, NewOwnerEvent.OutputTuple, NewOwnerEvent.OutputObject>;
|
||||
"NewResolver(bytes32,address)": TypedContractEvent<NewResolverEvent.InputTuple, NewResolverEvent.OutputTuple, NewResolverEvent.OutputObject>;
|
||||
NewResolver: TypedContractEvent<NewResolverEvent.InputTuple, NewResolverEvent.OutputTuple, NewResolverEvent.OutputObject>;
|
||||
"NewTTL(bytes32,uint64)": TypedContractEvent<NewTTLEvent.InputTuple, NewTTLEvent.OutputTuple, NewTTLEvent.OutputObject>;
|
||||
NewTTL: TypedContractEvent<NewTTLEvent.InputTuple, NewTTLEvent.OutputTuple, NewTTLEvent.OutputObject>;
|
||||
"Transfer(bytes32,address)": TypedContractEvent<TransferEvent.InputTuple, TransferEvent.OutputTuple, TransferEvent.OutputObject>;
|
||||
Transfer: TypedContractEvent<TransferEvent.InputTuple, TransferEvent.OutputTuple, TransferEvent.OutputObject>;
|
||||
};
|
||||
}
|
||||
660
dist/typechain/ENSResolver.d.ts
vendored
Normal file
660
dist/typechain/ENSResolver.d.ts
vendored
Normal file
@@ -0,0 +1,660 @@
|
||||
import type { BaseContract, BigNumberish, BytesLike, FunctionFragment, Result, Interface, EventFragment, AddressLike, ContractRunner, ContractMethod, Listener } from "ethers";
|
||||
import type { TypedContractEvent, TypedDeferredTopicFilter, TypedEventLog, TypedLogDescription, TypedListener, TypedContractMethod } from "./common";
|
||||
export interface ENSResolverInterface extends Interface {
|
||||
getFunction(nameOrSignature: "ABI" | "addr(bytes32)" | "addr(bytes32,uint256)" | "approve" | "clearRecords" | "contenthash" | "dnsRecord" | "hasDNSRecords" | "interfaceImplementer" | "isApprovedFor" | "isApprovedForAll" | "multicall" | "multicallWithNodeCheck" | "name" | "pubkey" | "recordVersions" | "setABI" | "setAddr(bytes32,uint256,bytes)" | "setAddr(bytes32,address)" | "setApprovalForAll" | "setContenthash" | "setDNSRecords" | "setInterface" | "setName" | "setPubkey" | "setText" | "setZonehash" | "supportsInterface" | "text" | "zonehash"): FunctionFragment;
|
||||
getEvent(nameOrSignatureOrTopic: "ABIChanged" | "AddrChanged" | "AddressChanged" | "ApprovalForAll" | "Approved" | "ContenthashChanged" | "DNSRecordChanged" | "DNSRecordDeleted" | "DNSZonehashChanged" | "InterfaceChanged" | "NameChanged" | "PubkeyChanged" | "TextChanged" | "VersionChanged"): EventFragment;
|
||||
encodeFunctionData(functionFragment: "ABI", values: [BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "addr(bytes32)", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "addr(bytes32,uint256)", values: [BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "approve", values: [BytesLike, AddressLike, boolean]): string;
|
||||
encodeFunctionData(functionFragment: "clearRecords", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "contenthash", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "dnsRecord", values: [BytesLike, BytesLike, BigNumberish]): string;
|
||||
encodeFunctionData(functionFragment: "hasDNSRecords", values: [BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "interfaceImplementer", values: [BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "isApprovedFor", values: [AddressLike, BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "isApprovedForAll", values: [AddressLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "multicall", values: [BytesLike[]]): string;
|
||||
encodeFunctionData(functionFragment: "multicallWithNodeCheck", values: [BytesLike, BytesLike[]]): string;
|
||||
encodeFunctionData(functionFragment: "name", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "pubkey", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "recordVersions", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setABI", values: [BytesLike, BigNumberish, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setAddr(bytes32,uint256,bytes)", values: [BytesLike, BigNumberish, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setAddr(bytes32,address)", values: [BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "setApprovalForAll", values: [AddressLike, boolean]): string;
|
||||
encodeFunctionData(functionFragment: "setContenthash", values: [BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setDNSRecords", values: [BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setInterface", values: [BytesLike, BytesLike, AddressLike]): string;
|
||||
encodeFunctionData(functionFragment: "setName", values: [BytesLike, string]): string;
|
||||
encodeFunctionData(functionFragment: "setPubkey", values: [BytesLike, BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "setText", values: [BytesLike, string, string]): string;
|
||||
encodeFunctionData(functionFragment: "setZonehash", values: [BytesLike, BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "supportsInterface", values: [BytesLike]): string;
|
||||
encodeFunctionData(functionFragment: "text", values: [BytesLike, string]): string;
|
||||
encodeFunctionData(functionFragment: "zonehash", values: [BytesLike]): string;
|
||||
decodeFunctionResult(functionFragment: "ABI", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "addr(bytes32)", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "addr(bytes32,uint256)", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "approve", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "clearRecords", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "contenthash", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "dnsRecord", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "hasDNSRecords", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "interfaceImplementer", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "isApprovedFor", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "isApprovedForAll", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "multicall", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "multicallWithNodeCheck", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "name", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "pubkey", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "recordVersions", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setABI", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setAddr(bytes32,uint256,bytes)", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setAddr(bytes32,address)", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setApprovalForAll", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setContenthash", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setDNSRecords", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setInterface", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setName", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setPubkey", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setText", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "setZonehash", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "supportsInterface", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "text", data: BytesLike): Result;
|
||||
decodeFunctionResult(functionFragment: "zonehash", data: BytesLike): Result;
|
||||
}
|
||||
export declare namespace ABIChangedEvent {
|
||||
type InputTuple = [node: BytesLike, contentType: BigNumberish];
|
||||
type OutputTuple = [node: string, contentType: bigint];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
contentType: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace AddrChangedEvent {
|
||||
type InputTuple = [node: BytesLike, a: AddressLike];
|
||||
type OutputTuple = [node: string, a: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
a: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace AddressChangedEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
coinType: BigNumberish,
|
||||
newAddress: BytesLike
|
||||
];
|
||||
type OutputTuple = [
|
||||
node: string,
|
||||
coinType: bigint,
|
||||
newAddress: string
|
||||
];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
coinType: bigint;
|
||||
newAddress: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace ApprovalForAllEvent {
|
||||
type InputTuple = [
|
||||
owner: AddressLike,
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
];
|
||||
type OutputTuple = [
|
||||
owner: string,
|
||||
operator: string,
|
||||
approved: boolean
|
||||
];
|
||||
interface OutputObject {
|
||||
owner: string;
|
||||
operator: string;
|
||||
approved: boolean;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace ApprovedEvent {
|
||||
type InputTuple = [
|
||||
owner: AddressLike,
|
||||
node: BytesLike,
|
||||
delegate: AddressLike,
|
||||
approved: boolean
|
||||
];
|
||||
type OutputTuple = [
|
||||
owner: string,
|
||||
node: string,
|
||||
delegate: string,
|
||||
approved: boolean
|
||||
];
|
||||
interface OutputObject {
|
||||
owner: string;
|
||||
node: string;
|
||||
delegate: string;
|
||||
approved: boolean;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace ContenthashChangedEvent {
|
||||
type InputTuple = [node: BytesLike, hash: BytesLike];
|
||||
type OutputTuple = [node: string, hash: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
hash: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace DNSRecordChangedEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
name: BytesLike,
|
||||
resource: BigNumberish,
|
||||
record: BytesLike
|
||||
];
|
||||
type OutputTuple = [
|
||||
node: string,
|
||||
name: string,
|
||||
resource: bigint,
|
||||
record: string
|
||||
];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
name: string;
|
||||
resource: bigint;
|
||||
record: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace DNSRecordDeletedEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
name: BytesLike,
|
||||
resource: BigNumberish
|
||||
];
|
||||
type OutputTuple = [node: string, name: string, resource: bigint];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
name: string;
|
||||
resource: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace DNSZonehashChangedEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
lastzonehash: BytesLike,
|
||||
zonehash: BytesLike
|
||||
];
|
||||
type OutputTuple = [
|
||||
node: string,
|
||||
lastzonehash: string,
|
||||
zonehash: string
|
||||
];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
lastzonehash: string;
|
||||
zonehash: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace InterfaceChangedEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
interfaceID: BytesLike,
|
||||
implementer: AddressLike
|
||||
];
|
||||
type OutputTuple = [
|
||||
node: string,
|
||||
interfaceID: string,
|
||||
implementer: string
|
||||
];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
interfaceID: string;
|
||||
implementer: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace NameChangedEvent {
|
||||
type InputTuple = [node: BytesLike, name: string];
|
||||
type OutputTuple = [node: string, name: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
name: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace PubkeyChangedEvent {
|
||||
type InputTuple = [node: BytesLike, x: BytesLike, y: BytesLike];
|
||||
type OutputTuple = [node: string, x: string, y: string];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
x: string;
|
||||
y: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace TextChangedEvent {
|
||||
type InputTuple = [
|
||||
node: BytesLike,
|
||||
indexedKey: string,
|
||||
key: string,
|
||||
value: string
|
||||
];
|
||||
type OutputTuple = [
|
||||
node: string,
|
||||
indexedKey: string,
|
||||
key: string,
|
||||
value: string
|
||||
];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
indexedKey: string;
|
||||
key: string;
|
||||
value: string;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export declare namespace VersionChangedEvent {
|
||||
type InputTuple = [node: BytesLike, newVersion: BigNumberish];
|
||||
type OutputTuple = [node: string, newVersion: bigint];
|
||||
interface OutputObject {
|
||||
node: string;
|
||||
newVersion: bigint;
|
||||
}
|
||||
type Event = TypedContractEvent<InputTuple, OutputTuple, OutputObject>;
|
||||
type Filter = TypedDeferredTopicFilter<Event>;
|
||||
type Log = TypedEventLog<Event>;
|
||||
type LogDescription = TypedLogDescription<Event>;
|
||||
}
|
||||
export interface ENSResolver extends BaseContract {
|
||||
connect(runner?: ContractRunner | null): ENSResolver;
|
||||
waitForDeployment(): Promise<this>;
|
||||
interface: ENSResolverInterface;
|
||||
queryFilter<TCEvent extends TypedContractEvent>(event: TCEvent, fromBlockOrBlockhash?: string | number | undefined, toBlock?: string | number | undefined): Promise<Array<TypedEventLog<TCEvent>>>;
|
||||
queryFilter<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, fromBlockOrBlockhash?: string | number | undefined, toBlock?: string | number | undefined): Promise<Array<TypedEventLog<TCEvent>>>;
|
||||
on<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
on<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
once<TCEvent extends TypedContractEvent>(event: TCEvent, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
once<TCEvent extends TypedContractEvent>(filter: TypedDeferredTopicFilter<TCEvent>, listener: TypedListener<TCEvent>): Promise<this>;
|
||||
listeners<TCEvent extends TypedContractEvent>(event: TCEvent): Promise<Array<TypedListener<TCEvent>>>;
|
||||
listeners(eventName?: string): Promise<Array<Listener>>;
|
||||
removeAllListeners<TCEvent extends TypedContractEvent>(event?: TCEvent): Promise<this>;
|
||||
ABI: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
contentTypes: BigNumberish
|
||||
], [
|
||||
[bigint, string]
|
||||
], "view">;
|
||||
"addr(bytes32)": TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
"addr(bytes32,uint256)": TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
coinType: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "view">;
|
||||
approve: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
delegate: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
clearRecords: TypedContractMethod<[node: BytesLike], [void], "nonpayable">;
|
||||
contenthash: TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
dnsRecord: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
name: BytesLike,
|
||||
resource: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "view">;
|
||||
hasDNSRecords: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
name: BytesLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
interfaceImplementer: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
interfaceID: BytesLike
|
||||
], [
|
||||
string
|
||||
], "view">;
|
||||
isApprovedFor: TypedContractMethod<[
|
||||
owner: AddressLike,
|
||||
node: BytesLike,
|
||||
delegate: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
isApprovedForAll: TypedContractMethod<[
|
||||
account: AddressLike,
|
||||
operator: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
multicall: TypedContractMethod<[data: BytesLike[]], [string[]], "nonpayable">;
|
||||
multicallWithNodeCheck: TypedContractMethod<[
|
||||
nodehash: BytesLike,
|
||||
data: BytesLike[]
|
||||
], [
|
||||
string[]
|
||||
], "nonpayable">;
|
||||
name: TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
pubkey: TypedContractMethod<[
|
||||
node: BytesLike
|
||||
], [
|
||||
[string, string] & {
|
||||
x: string;
|
||||
y: string;
|
||||
}
|
||||
], "view">;
|
||||
recordVersions: TypedContractMethod<[arg0: BytesLike], [bigint], "view">;
|
||||
setABI: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
contentType: BigNumberish,
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
"setAddr(bytes32,uint256,bytes)": TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
coinType: BigNumberish,
|
||||
a: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
"setAddr(bytes32,address)": TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
a: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setApprovalForAll: TypedContractMethod<[
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setContenthash: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
hash: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setDNSRecords: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setInterface: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
interfaceID: BytesLike,
|
||||
implementer: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setName: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
newName: string
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setPubkey: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
x: BytesLike,
|
||||
y: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setText: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
key: string,
|
||||
value: string
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
setZonehash: TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
hash: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
supportsInterface: TypedContractMethod<[
|
||||
interfaceID: BytesLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
text: TypedContractMethod<[node: BytesLike, key: string], [string], "view">;
|
||||
zonehash: TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
getFunction<T extends ContractMethod = ContractMethod>(key: string | FunctionFragment): T;
|
||||
getFunction(nameOrSignature: "ABI"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
contentTypes: BigNumberish
|
||||
], [
|
||||
[bigint, string]
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "addr(bytes32)"): TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
getFunction(nameOrSignature: "addr(bytes32,uint256)"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
coinType: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "approve"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
delegate: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "clearRecords"): TypedContractMethod<[node: BytesLike], [void], "nonpayable">;
|
||||
getFunction(nameOrSignature: "contenthash"): TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
getFunction(nameOrSignature: "dnsRecord"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
name: BytesLike,
|
||||
resource: BigNumberish
|
||||
], [
|
||||
string
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "hasDNSRecords"): TypedContractMethod<[node: BytesLike, name: BytesLike], [boolean], "view">;
|
||||
getFunction(nameOrSignature: "interfaceImplementer"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
interfaceID: BytesLike
|
||||
], [
|
||||
string
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "isApprovedFor"): TypedContractMethod<[
|
||||
owner: AddressLike,
|
||||
node: BytesLike,
|
||||
delegate: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "isApprovedForAll"): TypedContractMethod<[
|
||||
account: AddressLike,
|
||||
operator: AddressLike
|
||||
], [
|
||||
boolean
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "multicall"): TypedContractMethod<[data: BytesLike[]], [string[]], "nonpayable">;
|
||||
getFunction(nameOrSignature: "multicallWithNodeCheck"): TypedContractMethod<[
|
||||
nodehash: BytesLike,
|
||||
data: BytesLike[]
|
||||
], [
|
||||
string[]
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "name"): TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
getFunction(nameOrSignature: "pubkey"): TypedContractMethod<[
|
||||
node: BytesLike
|
||||
], [
|
||||
[string, string] & {
|
||||
x: string;
|
||||
y: string;
|
||||
}
|
||||
], "view">;
|
||||
getFunction(nameOrSignature: "recordVersions"): TypedContractMethod<[arg0: BytesLike], [bigint], "view">;
|
||||
getFunction(nameOrSignature: "setABI"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
contentType: BigNumberish,
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setAddr(bytes32,uint256,bytes)"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
coinType: BigNumberish,
|
||||
a: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setAddr(bytes32,address)"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
a: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setApprovalForAll"): TypedContractMethod<[
|
||||
operator: AddressLike,
|
||||
approved: boolean
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setContenthash"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
hash: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setDNSRecords"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
data: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setInterface"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
interfaceID: BytesLike,
|
||||
implementer: AddressLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setName"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
newName: string
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setPubkey"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
x: BytesLike,
|
||||
y: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setText"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
key: string,
|
||||
value: string
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "setZonehash"): TypedContractMethod<[
|
||||
node: BytesLike,
|
||||
hash: BytesLike
|
||||
], [
|
||||
void
|
||||
], "nonpayable">;
|
||||
getFunction(nameOrSignature: "supportsInterface"): TypedContractMethod<[interfaceID: BytesLike], [boolean], "view">;
|
||||
getFunction(nameOrSignature: "text"): TypedContractMethod<[node: BytesLike, key: string], [string], "view">;
|
||||
getFunction(nameOrSignature: "zonehash"): TypedContractMethod<[node: BytesLike], [string], "view">;
|
||||
getEvent(key: "ABIChanged"): TypedContractEvent<ABIChangedEvent.InputTuple, ABIChangedEvent.OutputTuple, ABIChangedEvent.OutputObject>;
|
||||
getEvent(key: "AddrChanged"): TypedContractEvent<AddrChangedEvent.InputTuple, AddrChangedEvent.OutputTuple, AddrChangedEvent.OutputObject>;
|
||||
getEvent(key: "AddressChanged"): TypedContractEvent<AddressChangedEvent.InputTuple, AddressChangedEvent.OutputTuple, AddressChangedEvent.OutputObject>;
|
||||
getEvent(key: "ApprovalForAll"): TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
getEvent(key: "Approved"): TypedContractEvent<ApprovedEvent.InputTuple, ApprovedEvent.OutputTuple, ApprovedEvent.OutputObject>;
|
||||
getEvent(key: "ContenthashChanged"): TypedContractEvent<ContenthashChangedEvent.InputTuple, ContenthashChangedEvent.OutputTuple, ContenthashChangedEvent.OutputObject>;
|
||||
getEvent(key: "DNSRecordChanged"): TypedContractEvent<DNSRecordChangedEvent.InputTuple, DNSRecordChangedEvent.OutputTuple, DNSRecordChangedEvent.OutputObject>;
|
||||
getEvent(key: "DNSRecordDeleted"): TypedContractEvent<DNSRecordDeletedEvent.InputTuple, DNSRecordDeletedEvent.OutputTuple, DNSRecordDeletedEvent.OutputObject>;
|
||||
getEvent(key: "DNSZonehashChanged"): TypedContractEvent<DNSZonehashChangedEvent.InputTuple, DNSZonehashChangedEvent.OutputTuple, DNSZonehashChangedEvent.OutputObject>;
|
||||
getEvent(key: "InterfaceChanged"): TypedContractEvent<InterfaceChangedEvent.InputTuple, InterfaceChangedEvent.OutputTuple, InterfaceChangedEvent.OutputObject>;
|
||||
getEvent(key: "NameChanged"): TypedContractEvent<NameChangedEvent.InputTuple, NameChangedEvent.OutputTuple, NameChangedEvent.OutputObject>;
|
||||
getEvent(key: "PubkeyChanged"): TypedContractEvent<PubkeyChangedEvent.InputTuple, PubkeyChangedEvent.OutputTuple, PubkeyChangedEvent.OutputObject>;
|
||||
getEvent(key: "TextChanged"): TypedContractEvent<TextChangedEvent.InputTuple, TextChangedEvent.OutputTuple, TextChangedEvent.OutputObject>;
|
||||
getEvent(key: "VersionChanged"): TypedContractEvent<VersionChangedEvent.InputTuple, VersionChangedEvent.OutputTuple, VersionChangedEvent.OutputObject>;
|
||||
filters: {
|
||||
"ABIChanged(bytes32,uint256)": TypedContractEvent<ABIChangedEvent.InputTuple, ABIChangedEvent.OutputTuple, ABIChangedEvent.OutputObject>;
|
||||
ABIChanged: TypedContractEvent<ABIChangedEvent.InputTuple, ABIChangedEvent.OutputTuple, ABIChangedEvent.OutputObject>;
|
||||
"AddrChanged(bytes32,address)": TypedContractEvent<AddrChangedEvent.InputTuple, AddrChangedEvent.OutputTuple, AddrChangedEvent.OutputObject>;
|
||||
AddrChanged: TypedContractEvent<AddrChangedEvent.InputTuple, AddrChangedEvent.OutputTuple, AddrChangedEvent.OutputObject>;
|
||||
"AddressChanged(bytes32,uint256,bytes)": TypedContractEvent<AddressChangedEvent.InputTuple, AddressChangedEvent.OutputTuple, AddressChangedEvent.OutputObject>;
|
||||
AddressChanged: TypedContractEvent<AddressChangedEvent.InputTuple, AddressChangedEvent.OutputTuple, AddressChangedEvent.OutputObject>;
|
||||
"ApprovalForAll(address,address,bool)": TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
ApprovalForAll: TypedContractEvent<ApprovalForAllEvent.InputTuple, ApprovalForAllEvent.OutputTuple, ApprovalForAllEvent.OutputObject>;
|
||||
"Approved(address,bytes32,address,bool)": TypedContractEvent<ApprovedEvent.InputTuple, ApprovedEvent.OutputTuple, ApprovedEvent.OutputObject>;
|
||||
Approved: TypedContractEvent<ApprovedEvent.InputTuple, ApprovedEvent.OutputTuple, ApprovedEvent.OutputObject>;
|
||||
"ContenthashChanged(bytes32,bytes)": TypedContractEvent<ContenthashChangedEvent.InputTuple, ContenthashChangedEvent.OutputTuple, ContenthashChangedEvent.OutputObject>;
|
||||
ContenthashChanged: TypedContractEvent<ContenthashChangedEvent.InputTuple, ContenthashChangedEvent.OutputTuple, ContenthashChangedEvent.OutputObject>;
|
||||
"DNSRecordChanged(bytes32,bytes,uint16,bytes)": TypedContractEvent<DNSRecordChangedEvent.InputTuple, DNSRecordChangedEvent.OutputTuple, DNSRecordChangedEvent.OutputObject>;
|
||||
DNSRecordChanged: TypedContractEvent<DNSRecordChangedEvent.InputTuple, DNSRecordChangedEvent.OutputTuple, DNSRecordChangedEvent.OutputObject>;
|
||||
"DNSRecordDeleted(bytes32,bytes,uint16)": TypedContractEvent<DNSRecordDeletedEvent.InputTuple, DNSRecordDeletedEvent.OutputTuple, DNSRecordDeletedEvent.OutputObject>;
|
||||
DNSRecordDeleted: TypedContractEvent<DNSRecordDeletedEvent.InputTuple, DNSRecordDeletedEvent.OutputTuple, DNSRecordDeletedEvent.OutputObject>;
|
||||
"DNSZonehashChanged(bytes32,bytes,bytes)": TypedContractEvent<DNSZonehashChangedEvent.InputTuple, DNSZonehashChangedEvent.OutputTuple, DNSZonehashChangedEvent.OutputObject>;
|
||||
DNSZonehashChanged: TypedContractEvent<DNSZonehashChangedEvent.InputTuple, DNSZonehashChangedEvent.OutputTuple, DNSZonehashChangedEvent.OutputObject>;
|
||||
"InterfaceChanged(bytes32,bytes4,address)": TypedContractEvent<InterfaceChangedEvent.InputTuple, InterfaceChangedEvent.OutputTuple, InterfaceChangedEvent.OutputObject>;
|
||||
InterfaceChanged: TypedContractEvent<InterfaceChangedEvent.InputTuple, InterfaceChangedEvent.OutputTuple, InterfaceChangedEvent.OutputObject>;
|
||||
"NameChanged(bytes32,string)": TypedContractEvent<NameChangedEvent.InputTuple, NameChangedEvent.OutputTuple, NameChangedEvent.OutputObject>;
|
||||
NameChanged: TypedContractEvent<NameChangedEvent.InputTuple, NameChangedEvent.OutputTuple, NameChangedEvent.OutputObject>;
|
||||
"PubkeyChanged(bytes32,bytes32,bytes32)": TypedContractEvent<PubkeyChangedEvent.InputTuple, PubkeyChangedEvent.OutputTuple, PubkeyChangedEvent.OutputObject>;
|
||||
PubkeyChanged: TypedContractEvent<PubkeyChangedEvent.InputTuple, PubkeyChangedEvent.OutputTuple, PubkeyChangedEvent.OutputObject>;
|
||||
"TextChanged(bytes32,string,string,string)": TypedContractEvent<TextChangedEvent.InputTuple, TextChangedEvent.OutputTuple, TextChangedEvent.OutputObject>;
|
||||
TextChanged: TypedContractEvent<TextChangedEvent.InputTuple, TextChangedEvent.OutputTuple, TextChangedEvent.OutputObject>;
|
||||
"VersionChanged(bytes32,uint64)": TypedContractEvent<VersionChangedEvent.InputTuple, VersionChangedEvent.OutputTuple, VersionChangedEvent.OutputObject>;
|
||||
VersionChanged: TypedContractEvent<VersionChangedEvent.InputTuple, VersionChangedEvent.OutputTuple, VersionChangedEvent.OutputObject>;
|
||||
};
|
||||
}
|
||||
1127
dist/typechain/factories/ENSNameWrapper__factory.d.ts
vendored
Normal file
1127
dist/typechain/factories/ENSNameWrapper__factory.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load Diff
337
dist/typechain/factories/ENSRegistry__factory.d.ts
vendored
Normal file
337
dist/typechain/factories/ENSRegistry__factory.d.ts
vendored
Normal file
@@ -0,0 +1,337 @@
|
||||
import { type ContractRunner } from "ethers";
|
||||
import type { ENSRegistry, ENSRegistryInterface } from "../ENSRegistry";
|
||||
export declare class ENSRegistry__factory {
|
||||
static readonly abi: readonly [{
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "contract ENS";
|
||||
readonly name: "_old";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "constructor";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "address";
|
||||
readonly name: "operator";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bool";
|
||||
readonly name: "approved";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly name: "ApprovalForAll";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "label";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "NewOwner";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "address";
|
||||
readonly name: "resolver";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "NewResolver";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "uint64";
|
||||
readonly name: "ttl";
|
||||
readonly type: "uint64";
|
||||
}];
|
||||
readonly name: "NewTTL";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "Transfer";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly constant: true;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "operator";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "isApprovedForAll";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bool";
|
||||
readonly name: "";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: true;
|
||||
readonly inputs: readonly [];
|
||||
readonly name: "old";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "contract ENS";
|
||||
readonly name: "";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: true;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "owner";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: true;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "recordExists";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bool";
|
||||
readonly name: "";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: true;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "resolver";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "operator";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "bool";
|
||||
readonly name: "approved";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly name: "setApprovalForAll";
|
||||
readonly outputs: readonly [];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "setOwner";
|
||||
readonly outputs: readonly [];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "resolver";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "uint64";
|
||||
readonly name: "ttl";
|
||||
readonly type: "uint64";
|
||||
}];
|
||||
readonly name: "setRecord";
|
||||
readonly outputs: readonly [];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "resolver";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "setResolver";
|
||||
readonly outputs: readonly [];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "label";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "setSubnodeOwner";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "label";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "resolver";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "uint64";
|
||||
readonly name: "ttl";
|
||||
readonly type: "uint64";
|
||||
}];
|
||||
readonly name: "setSubnodeRecord";
|
||||
readonly outputs: readonly [];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "uint64";
|
||||
readonly name: "ttl";
|
||||
readonly type: "uint64";
|
||||
}];
|
||||
readonly name: "setTTL";
|
||||
readonly outputs: readonly [];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly constant: true;
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "ttl";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "uint64";
|
||||
readonly name: "";
|
||||
readonly type: "uint64";
|
||||
}];
|
||||
readonly payable: false;
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}];
|
||||
static createInterface(): ENSRegistryInterface;
|
||||
static connect(address: string, runner?: ContractRunner | null): ENSRegistry;
|
||||
}
|
||||
789
dist/typechain/factories/ENSResolver__factory.d.ts
vendored
Normal file
789
dist/typechain/factories/ENSResolver__factory.d.ts
vendored
Normal file
@@ -0,0 +1,789 @@
|
||||
import { type ContractRunner } from "ethers";
|
||||
import type { ENSResolver, ENSResolverInterface } from "../ENSResolver";
|
||||
export declare class ENSResolver__factory {
|
||||
static readonly abi: readonly [{
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "contract ENS";
|
||||
readonly name: "_ens";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "contract INameWrapper";
|
||||
readonly name: "wrapperAddress";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "_trustedETHController";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "_trustedReverseRegistrar";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "constructor";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "uint256";
|
||||
readonly name: "contentType";
|
||||
readonly type: "uint256";
|
||||
}];
|
||||
readonly name: "ABIChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "address";
|
||||
readonly name: "a";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "AddrChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "uint256";
|
||||
readonly name: "coinType";
|
||||
readonly type: "uint256";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "newAddress";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "AddressChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "address";
|
||||
readonly name: "operator";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bool";
|
||||
readonly name: "approved";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly name: "ApprovalForAll";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: false;
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "address";
|
||||
readonly name: "delegate";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bool";
|
||||
readonly name: "approved";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly name: "Approved";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "hash";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "ContenthashChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "name";
|
||||
readonly type: "bytes";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "uint16";
|
||||
readonly name: "resource";
|
||||
readonly type: "uint16";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "record";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "DNSRecordChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "name";
|
||||
readonly type: "bytes";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "uint16";
|
||||
readonly name: "resource";
|
||||
readonly type: "uint16";
|
||||
}];
|
||||
readonly name: "DNSRecordDeleted";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "lastzonehash";
|
||||
readonly type: "bytes";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "zonehash";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "DNSZonehashChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes4";
|
||||
readonly name: "interfaceID";
|
||||
readonly type: "bytes4";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "address";
|
||||
readonly name: "implementer";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "InterfaceChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "string";
|
||||
readonly name: "name";
|
||||
readonly type: "string";
|
||||
}];
|
||||
readonly name: "NameChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "x";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "y";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "PubkeyChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: true;
|
||||
readonly internalType: "string";
|
||||
readonly name: "indexedKey";
|
||||
readonly type: "string";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "string";
|
||||
readonly name: "key";
|
||||
readonly type: "string";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "string";
|
||||
readonly name: "value";
|
||||
readonly type: "string";
|
||||
}];
|
||||
readonly name: "TextChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly anonymous: false;
|
||||
readonly inputs: readonly [{
|
||||
readonly indexed: true;
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly indexed: false;
|
||||
readonly internalType: "uint64";
|
||||
readonly name: "newVersion";
|
||||
readonly type: "uint64";
|
||||
}];
|
||||
readonly name: "VersionChanged";
|
||||
readonly type: "event";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "uint256";
|
||||
readonly name: "contentTypes";
|
||||
readonly type: "uint256";
|
||||
}];
|
||||
readonly name: "ABI";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "uint256";
|
||||
readonly name: "";
|
||||
readonly type: "uint256";
|
||||
}, {
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "addr";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "address payable";
|
||||
readonly name: "";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "uint256";
|
||||
readonly name: "coinType";
|
||||
readonly type: "uint256";
|
||||
}];
|
||||
readonly name: "addr";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "delegate";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "bool";
|
||||
readonly name: "approved";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly name: "approve";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "clearRecords";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "contenthash";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "name";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "uint16";
|
||||
readonly name: "resource";
|
||||
readonly type: "uint16";
|
||||
}];
|
||||
readonly name: "dnsRecord";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "name";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "hasDNSRecords";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bool";
|
||||
readonly name: "";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes4";
|
||||
readonly name: "interfaceID";
|
||||
readonly type: "bytes4";
|
||||
}];
|
||||
readonly name: "interfaceImplementer";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "owner";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "delegate";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "isApprovedFor";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bool";
|
||||
readonly name: "";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "account";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "operator";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "isApprovedForAll";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bool";
|
||||
readonly name: "";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes[]";
|
||||
readonly name: "data";
|
||||
readonly type: "bytes[]";
|
||||
}];
|
||||
readonly name: "multicall";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes[]";
|
||||
readonly name: "results";
|
||||
readonly type: "bytes[]";
|
||||
}];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "nodehash";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes[]";
|
||||
readonly name: "data";
|
||||
readonly type: "bytes[]";
|
||||
}];
|
||||
readonly name: "multicallWithNodeCheck";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes[]";
|
||||
readonly name: "results";
|
||||
readonly type: "bytes[]";
|
||||
}];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "name";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "string";
|
||||
readonly name: "";
|
||||
readonly type: "string";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "pubkey";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "x";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "y";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "recordVersions";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "uint64";
|
||||
readonly name: "";
|
||||
readonly type: "uint64";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "uint256";
|
||||
readonly name: "contentType";
|
||||
readonly type: "uint256";
|
||||
}, {
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "data";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "setABI";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "uint256";
|
||||
readonly name: "coinType";
|
||||
readonly type: "uint256";
|
||||
}, {
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "a";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "setAddr";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "a";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "setAddr";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "address";
|
||||
readonly name: "operator";
|
||||
readonly type: "address";
|
||||
}, {
|
||||
readonly internalType: "bool";
|
||||
readonly name: "approved";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly name: "setApprovalForAll";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "hash";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "setContenthash";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "data";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "setDNSRecords";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes4";
|
||||
readonly name: "interfaceID";
|
||||
readonly type: "bytes4";
|
||||
}, {
|
||||
readonly internalType: "address";
|
||||
readonly name: "implementer";
|
||||
readonly type: "address";
|
||||
}];
|
||||
readonly name: "setInterface";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "string";
|
||||
readonly name: "newName";
|
||||
readonly type: "string";
|
||||
}];
|
||||
readonly name: "setName";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "x";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "y";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "setPubkey";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "string";
|
||||
readonly name: "key";
|
||||
readonly type: "string";
|
||||
}, {
|
||||
readonly internalType: "string";
|
||||
readonly name: "value";
|
||||
readonly type: "string";
|
||||
}];
|
||||
readonly name: "setText";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "hash";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly name: "setZonehash";
|
||||
readonly outputs: readonly [];
|
||||
readonly stateMutability: "nonpayable";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes4";
|
||||
readonly name: "interfaceID";
|
||||
readonly type: "bytes4";
|
||||
}];
|
||||
readonly name: "supportsInterface";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bool";
|
||||
readonly name: "";
|
||||
readonly type: "bool";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}, {
|
||||
readonly internalType: "string";
|
||||
readonly name: "key";
|
||||
readonly type: "string";
|
||||
}];
|
||||
readonly name: "text";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "string";
|
||||
readonly name: "";
|
||||
readonly type: "string";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}, {
|
||||
readonly inputs: readonly [{
|
||||
readonly internalType: "bytes32";
|
||||
readonly name: "node";
|
||||
readonly type: "bytes32";
|
||||
}];
|
||||
readonly name: "zonehash";
|
||||
readonly outputs: readonly [{
|
||||
readonly internalType: "bytes";
|
||||
readonly name: "";
|
||||
readonly type: "bytes";
|
||||
}];
|
||||
readonly stateMutability: "view";
|
||||
readonly type: "function";
|
||||
}];
|
||||
static createInterface(): ENSResolverInterface;
|
||||
static connect(address: string, runner?: ContractRunner | null): ENSResolver;
|
||||
}
|
||||
4
dist/typechain/factories/index.d.ts
vendored
4
dist/typechain/factories/index.d.ts
vendored
@@ -1,6 +1,8 @@
|
||||
export { ENS__factory } from "./ENS__factory";
|
||||
export { ENSNameWrapper__factory } from "./ENSNameWrapper__factory";
|
||||
export { ENSRegistry__factory } from "./ENSRegistry__factory";
|
||||
export { ENSResolver__factory } from "./ENSResolver__factory";
|
||||
export { ERC20__factory } from "./ERC20__factory";
|
||||
export { GasPriceOracle__factory } from "./GasPriceOracle__factory";
|
||||
export { Multicall__factory } from "./Multicall__factory";
|
||||
export { OffchainOracle__factory } from "./OffchainOracle__factory";
|
||||
export { OvmGasPriceOracle__factory } from "./OvmGasPriceOracle__factory";
|
||||
|
||||
8
dist/typechain/index.d.ts
vendored
8
dist/typechain/index.d.ts
vendored
@@ -1,14 +1,18 @@
|
||||
export type { ENS } from "./ENS";
|
||||
export type { ENSNameWrapper } from "./ENSNameWrapper";
|
||||
export type { ENSRegistry } from "./ENSRegistry";
|
||||
export type { ENSResolver } from "./ENSResolver";
|
||||
export type { ERC20 } from "./ERC20";
|
||||
export type { GasPriceOracle } from "./GasPriceOracle";
|
||||
export type { Multicall } from "./Multicall";
|
||||
export type { OffchainOracle } from "./OffchainOracle";
|
||||
export type { OvmGasPriceOracle } from "./OvmGasPriceOracle";
|
||||
export type { ReverseRecords } from "./ReverseRecords";
|
||||
export * as factories from "./factories";
|
||||
export { ENS__factory } from "./factories/ENS__factory";
|
||||
export { ENSNameWrapper__factory } from "./factories/ENSNameWrapper__factory";
|
||||
export { ENSRegistry__factory } from "./factories/ENSRegistry__factory";
|
||||
export { ENSResolver__factory } from "./factories/ENSResolver__factory";
|
||||
export { ERC20__factory } from "./factories/ERC20__factory";
|
||||
export { GasPriceOracle__factory } from "./factories/GasPriceOracle__factory";
|
||||
export { Multicall__factory } from "./factories/Multicall__factory";
|
||||
export { OffchainOracle__factory } from "./factories/OffchainOracle__factory";
|
||||
export { OvmGasPriceOracle__factory } from "./factories/OvmGasPriceOracle__factory";
|
||||
|
||||
8
dist/utils.d.ts
vendored
8
dist/utils.d.ts
vendored
@@ -1,5 +1,3 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { webcrypto } from 'crypto';
|
||||
import BN from 'bn.js';
|
||||
import type { BigNumberish } from 'ethers';
|
||||
@@ -22,6 +20,12 @@ export declare function leInt2Buff(bigint: bnInput | bigint): Uint8Array;
|
||||
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 numberFormatter(num: string | number | bigint, digits?: number): string;
|
||||
export declare function isHex(value: string): boolean;
|
||||
export declare function toContentHash(ipfsUrl: string): any;
|
||||
export declare function fromContentHash(contentHash: string): any;
|
||||
export {};
|
||||
|
||||
29
dist/websnark.d.ts
vendored
29
dist/websnark.d.ts
vendored
@@ -1,28 +1,27 @@
|
||||
import type { Element } from '@tornado/fixed-merkle-tree';
|
||||
import type { AddressLike, BytesLike, BigNumberish } from 'ethers';
|
||||
export type snarkInputs = {
|
||||
import type { Element } from 'fixed-merkle-tree';
|
||||
export interface snarkInputs {
|
||||
root: Element;
|
||||
nullifierHex: string;
|
||||
recipient: AddressLike;
|
||||
relayer: AddressLike;
|
||||
recipient: string;
|
||||
relayer: string;
|
||||
fee: bigint;
|
||||
refund: bigint;
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
pathElements: Element[];
|
||||
pathIndices: Element[];
|
||||
};
|
||||
}
|
||||
export type snarkArgs = [
|
||||
_root: BytesLike,
|
||||
_nullifierHash: BytesLike,
|
||||
_recipient: AddressLike,
|
||||
_relayer: AddressLike,
|
||||
_fee: BigNumberish,
|
||||
_refund: BigNumberish
|
||||
_root: string,
|
||||
_nullifierHash: string,
|
||||
_recipient: string,
|
||||
_relayer: string,
|
||||
_fee: string,
|
||||
_refund: string
|
||||
];
|
||||
export type snarkProofs = {
|
||||
proof: BytesLike;
|
||||
export interface snarkProofs {
|
||||
proof: string;
|
||||
args: snarkArgs;
|
||||
};
|
||||
}
|
||||
export declare function initGroth16(): Promise<void>;
|
||||
export declare function calculateSnarkProof(input: snarkInputs, circuit: object, provingKey: ArrayBuffer): Promise<snarkProofs>;
|
||||
|
||||
9
dist/zip.d.ts
vendored
Normal file
9
dist/zip.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import { AsyncZippable, Unzipped, ZipAttributes } from 'fflate';
|
||||
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, }: {
|
||||
staticUrl?: string;
|
||||
zipName: string;
|
||||
zipDigest?: string;
|
||||
parseJson?: boolean;
|
||||
}): Promise<T>;
|
||||
9
hardhat.config.ts
Normal file
9
hardhat.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { HardhatUserConfig } from 'hardhat/types';
|
||||
import '@nomicfoundation/hardhat-toolbox';
|
||||
import '@nomicfoundation/hardhat-ethers';
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
solidity: '0.8.28',
|
||||
};
|
||||
|
||||
export default config;
|
||||
179
package.json
179
package.json
@@ -1,76 +1,107 @@
|
||||
{
|
||||
"name": "@tornado/core",
|
||||
"version": "1.0.1",
|
||||
"description": "An SDK for building applications on top of Privacy Pools",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"unpkg": "./dist/index.umd.js",
|
||||
"jsdelivr": "./dist/index.umd.js",
|
||||
"scripts": {
|
||||
"typechain": "typechain --target ethers-v6 --out-dir src/typechain src/abi/*.json",
|
||||
"types": "tsc --declaration --emitDeclarationOnly",
|
||||
"lint": "eslint src/**/*.ts --ext .ts --ignore-pattern src/typechain",
|
||||
"build:node": "rollup -c",
|
||||
"build:web": "webpack",
|
||||
"build": "yarn types && yarn build:node && yarn build:web"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
".eslintrc.js",
|
||||
".gitattributes",
|
||||
".gitignore",
|
||||
".npmrc",
|
||||
"logo.png",
|
||||
"logo2.png",
|
||||
"rollup.config.mjs",
|
||||
"tsconfig.json",
|
||||
"yarn.lock"
|
||||
],
|
||||
"dependencies": {
|
||||
"@metamask/eth-sig-util": "^7.0.1",
|
||||
"@tornado/contracts": "^1.0.0",
|
||||
"@tornado/fixed-merkle-tree": "^0.7.3",
|
||||
"@tornado/snarkjs": "^0.1.20",
|
||||
"@tornado/websnark": "^0.0.4",
|
||||
"ajv": "^8.12.0",
|
||||
"bn.js": "^5.2.1",
|
||||
"circomlibjs": "0.1.7",
|
||||
"cross-fetch": "^4.0.0",
|
||||
"ethers": "^6.4.0",
|
||||
"ffjavascript": "0.2.48",
|
||||
"fflate": "^0.8.2"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@typechain/ethers-v6": "^0.5.1",
|
||||
"@types/bn.js": "^5.1.5",
|
||||
"@types/circomlibjs": "^0.1.6",
|
||||
"@types/node": "^20.12.5",
|
||||
"@types/node-fetch": "^2.6.11",
|
||||
"@typescript-eslint/eslint-plugin": "^7.6.0",
|
||||
"@typescript-eslint/parser": "^7.6.0",
|
||||
"esbuild": "^0.20.2",
|
||||
"esbuild-loader": "^4.1.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-import-resolver-typescript": "^3.6.1",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"node-polyfill-webpack-plugin": "^3.0.0",
|
||||
"prettier": "^3.2.5",
|
||||
"rollup": "^4.14.1",
|
||||
"rollup-plugin-esbuild": "^6.1.1",
|
||||
"tsc": "^2.0.4",
|
||||
"typechain": "^8.3.2",
|
||||
"typescript": "^5.4.4",
|
||||
"webpack": "^5.91.0",
|
||||
"webpack-cli": "^5.1.4"
|
||||
}
|
||||
"name": "@tornado/core",
|
||||
"version": "1.0.19",
|
||||
"description": "An SDK for building applications on top of Privacy Pools",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./dist/index.d.ts",
|
||||
"unpkg": "./dist/tornado.umd.min.js",
|
||||
"jsdelivr": "./dist/tornado.umd.min.js",
|
||||
"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",
|
||||
"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'"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
".eslintrc.js",
|
||||
".gitattributes",
|
||||
".gitignore",
|
||||
".npmrc",
|
||||
"logo.png",
|
||||
"logo2.png",
|
||||
"rollup.config.mjs",
|
||||
"tsconfig.json",
|
||||
"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",
|
||||
"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",
|
||||
"fflate": "^0.8.2",
|
||||
"fixed-merkle-tree": "0.7.3",
|
||||
"idb": "^8.0.0",
|
||||
"snarkjs": "git+https://github.com/MicahZoltu/snarkjs.git#2c964b3fe6019e057acab04cc17705d1f7fdaf9a",
|
||||
"websnark": "git+https://github.com/MicahZoltu/websnark.git#f0ddbf34b3045cac9e6d3e4d977bf3b439869fae"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^2.0.7",
|
||||
"@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-toolbox": "^5.0.0",
|
||||
"@nomicfoundation/hardhat-verify": "^2.0.10",
|
||||
"@nomicfoundation/ignition-core": "^0.15.5",
|
||||
"@rollup/plugin-commonjs": "^28.0.1",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^15.3.0",
|
||||
"@typechain/ethers-v6": "^0.5.1",
|
||||
"@typechain/hardhat": "^9.1.0",
|
||||
"@types/bn.js": "^5.1.6",
|
||||
"@types/chai": "^4.2.0",
|
||||
"@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",
|
||||
"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",
|
||||
"nyc": "^17.1.0",
|
||||
"prettier": "^3.3.3",
|
||||
"rollup": "^4.24.0",
|
||||
"rollup-plugin-esbuild": "^6.1.1",
|
||||
"solidity-coverage": "^0.8.13",
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,81 +7,81 @@ import { readFileSync } from 'fs';
|
||||
const pkgJson = JSON.parse(readFileSync("./package.json"));
|
||||
|
||||
const external = Object.keys(pkgJson.dependencies).concat(
|
||||
Object.keys(pkgJson.optionalDependencies),
|
||||
[
|
||||
'http-proxy-agent',
|
||||
'https-proxy-agent',
|
||||
'socks-proxy-agent',
|
||||
'@tornado/websnark/src/utils',
|
||||
'@tornado/websnark/src/groth16',
|
||||
]
|
||||
Object.keys(pkgJson.optionalDependencies || {}),
|
||||
[
|
||||
'http-proxy-agent',
|
||||
'https-proxy-agent',
|
||||
'socks-proxy-agent',
|
||||
'websnark/src/utils',
|
||||
'websnark/src/groth16',
|
||||
]
|
||||
);
|
||||
|
||||
const config = [
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: [
|
||||
{
|
||||
file: pkgJson.main,
|
||||
format: "cjs",
|
||||
esModule: false,
|
||||
},
|
||||
],
|
||||
external,
|
||||
plugins: [
|
||||
esbuild({
|
||||
include: /\.[jt]sx?$/,
|
||||
minify: false,
|
||||
sourceMap: true,
|
||||
target: 'es2016',
|
||||
}),
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
json()
|
||||
],
|
||||
},
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: [
|
||||
{
|
||||
file: pkgJson.module,
|
||||
format: "esm",
|
||||
},
|
||||
],
|
||||
external,
|
||||
plugins: [
|
||||
esbuild({
|
||||
include: /\.[jt]sx?$/,
|
||||
minify: false,
|
||||
sourceMap: true,
|
||||
target: 'es2016',
|
||||
}),
|
||||
nodeResolve(),
|
||||
json()
|
||||
],
|
||||
},
|
||||
{
|
||||
input: 'src/merkleTreeWorker.ts',
|
||||
output: [
|
||||
{
|
||||
file: 'dist/merkleTreeWorker.js',
|
||||
format: "cjs",
|
||||
esModule: false,
|
||||
},
|
||||
],
|
||||
treeshake: 'smallest',
|
||||
plugins: [
|
||||
esbuild({
|
||||
include: /\.[jt]sx?$/,
|
||||
minify: false,
|
||||
sourceMap: true,
|
||||
target: 'es2016',
|
||||
}),
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
json()
|
||||
],
|
||||
}
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: [
|
||||
{
|
||||
file: pkgJson.main,
|
||||
format: "cjs",
|
||||
esModule: false,
|
||||
},
|
||||
],
|
||||
external,
|
||||
plugins: [
|
||||
esbuild({
|
||||
include: /\.[jt]sx?$/,
|
||||
minify: false,
|
||||
sourceMap: true,
|
||||
target: 'es2022',
|
||||
}),
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
json()
|
||||
],
|
||||
},
|
||||
{
|
||||
input: 'src/index.ts',
|
||||
output: [
|
||||
{
|
||||
file: pkgJson.module,
|
||||
format: "esm",
|
||||
},
|
||||
],
|
||||
external,
|
||||
plugins: [
|
||||
esbuild({
|
||||
include: /\.[jt]sx?$/,
|
||||
minify: false,
|
||||
sourceMap: true,
|
||||
target: 'es2022',
|
||||
}),
|
||||
nodeResolve(),
|
||||
json()
|
||||
],
|
||||
},
|
||||
{
|
||||
input: 'src/merkleTreeWorker.ts',
|
||||
output: [
|
||||
{
|
||||
file: 'dist/merkleTreeWorker.js',
|
||||
format: "cjs",
|
||||
esModule: false,
|
||||
},
|
||||
],
|
||||
treeshake: 'smallest',
|
||||
plugins: [
|
||||
esbuild({
|
||||
include: /\.[jt]sx?$/,
|
||||
minify: false,
|
||||
sourceMap: true,
|
||||
target: 'es2022',
|
||||
}),
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
json()
|
||||
],
|
||||
}
|
||||
]
|
||||
|
||||
export default config;
|
||||
36
scripts/hash.ts
Normal file
36
scripts/hash.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import path from 'path'
|
||||
import { readFile, readdir, writeFile } from 'fs/promises';
|
||||
import { bytesToBase64, digest } from '../src';
|
||||
|
||||
async function content(file: string) {
|
||||
const content = new Uint8Array(await readFile(file));
|
||||
|
||||
const hash = 'sha384-' + bytesToBase64(await digest(content));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
async function hash() {
|
||||
const staticFiles = await readdir('dist');
|
||||
|
||||
const hashes = {} as {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
for (const filePath of staticFiles) {
|
||||
const file = path.join('dist', filePath).replaceAll(path.sep, path.posix.sep);
|
||||
|
||||
if (!['.js', '.mjs'].includes(path.extname(file))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const hash = await content(file);
|
||||
|
||||
hashes[file] = hash;
|
||||
}
|
||||
|
||||
await writeFile('dist/hashes.json', JSON.stringify(hashes, null, 2));
|
||||
|
||||
console.log('hashes', hashes);
|
||||
}
|
||||
hash();
|
||||
1
src/abi/ENSNameWrapper.json
Normal file
1
src/abi/ENSNameWrapper.json
Normal file
File diff suppressed because one or more lines are too long
1
src/abi/ENSRegistry.json
Normal file
1
src/abi/ENSRegistry.json
Normal file
@@ -0,0 +1 @@
|
||||
[{"inputs":[{"internalType":"contract ENS","name":"_old","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"label","type":"bytes32"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"resolver","type":"address"}],"name":"NewResolver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"NewTTL","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"old","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"recordExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setRecord","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"setSubnodeOwner","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setSubnodeRecord","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setTTL","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"ttl","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"}]
|
||||
1
src/abi/ENSResolver.json
Normal file
1
src/abi/ENSResolver.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,189 +0,0 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "GAS_UNIT",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "_derivationThresold",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"name": "changeDerivationThresold",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "_gasUnit",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"name": "changeGasUnit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "_heartbeat",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"name": "changeHeartbeat",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "changeOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "derivationThresold",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "gasPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "heartbeat",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "maxFeePerGas",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "maxPriorityFeePerGas",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "pastGasPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "_gasPrice",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"name": "setGasPrice",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "timestamp",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint32",
|
||||
"name": "",
|
||||
"type": "uint32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
791
src/batch.ts
791
src/batch.ts
@@ -1,339 +1,572 @@
|
||||
import type { Provider, BlockTag, Block, TransactionResponse, BaseContract, ContractEventName, EventLog } from 'ethers';
|
||||
import {
|
||||
Provider,
|
||||
BlockTag,
|
||||
Block,
|
||||
TransactionResponse,
|
||||
BaseContract,
|
||||
ContractEventName,
|
||||
EventLog,
|
||||
TransactionReceipt,
|
||||
isHexString,
|
||||
assert,
|
||||
assertArgument,
|
||||
DeferredTopicFilter,
|
||||
EventFragment,
|
||||
TopicFilter,
|
||||
Interface,
|
||||
UndecodedEventLog,
|
||||
Log,
|
||||
} from 'ethers';
|
||||
import { chunk, sleep } from './utils';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
function isDeferred(value: any): value is DeferredTopicFilter {
|
||||
return (
|
||||
value &&
|
||||
typeof value === 'object' &&
|
||||
'getTopicFilter' in value &&
|
||||
typeof value.getTopicFilter === 'function' &&
|
||||
value.fragment
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from ethers.js as they don't export this function
|
||||
* https://github.com/ethers-io/ethers.js/blob/main/src.ts/contract/contract.ts#L464
|
||||
*/
|
||||
export async function getSubInfo(
|
||||
abiInterface: Interface,
|
||||
event: ContractEventName,
|
||||
): Promise<{
|
||||
fragment: null | EventFragment;
|
||||
tag: string;
|
||||
topics: TopicFilter;
|
||||
}> {
|
||||
let topics: Array<null | string | Array<string>>;
|
||||
let fragment: null | EventFragment = null;
|
||||
|
||||
// Convert named events to topicHash and get the fragment for
|
||||
// events which need deconstructing.
|
||||
|
||||
if (Array.isArray(event)) {
|
||||
const topicHashify = function (name: string): string {
|
||||
if (isHexString(name, 32)) {
|
||||
return name;
|
||||
}
|
||||
const fragment = abiInterface.getEvent(name);
|
||||
assertArgument(fragment, 'unknown fragment', 'name', name);
|
||||
return fragment.topicHash;
|
||||
};
|
||||
|
||||
// Array of Topics and Names; e.g. `[ "0x1234...89ab", "Transfer(address)" ]`
|
||||
topics = event.map((e) => {
|
||||
if (e == null) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(e)) {
|
||||
return e.map(topicHashify);
|
||||
}
|
||||
return topicHashify(e);
|
||||
});
|
||||
} else if (event === '*') {
|
||||
topics = [null];
|
||||
} else if (typeof event === 'string') {
|
||||
if (isHexString(event, 32)) {
|
||||
// Topic Hash
|
||||
topics = [event];
|
||||
} else {
|
||||
// Name or Signature; e.g. `"Transfer", `"Transfer(address)"`
|
||||
fragment = abiInterface.getEvent(event);
|
||||
assertArgument(fragment, 'unknown fragment', 'event', event);
|
||||
topics = [fragment.topicHash];
|
||||
}
|
||||
} else if (isDeferred(event)) {
|
||||
// Deferred Topic Filter; e.g. `contract.filter.Transfer(from)`
|
||||
topics = await event.getTopicFilter();
|
||||
} else if ('fragment' in event) {
|
||||
// ContractEvent; e.g. `contract.filter.Transfer`
|
||||
fragment = event.fragment;
|
||||
topics = [fragment.topicHash];
|
||||
} else {
|
||||
assertArgument(false, 'unknown event name', 'event', event);
|
||||
}
|
||||
|
||||
// Normalize topics and sort TopicSets
|
||||
topics = topics.map((t) => {
|
||||
if (t == null) {
|
||||
return null;
|
||||
}
|
||||
if (Array.isArray(t)) {
|
||||
const items = Array.from(new Set(t.map((t) => t.toLowerCase())).values());
|
||||
if (items.length === 1) {
|
||||
return items[0];
|
||||
}
|
||||
items.sort();
|
||||
return items;
|
||||
}
|
||||
return t.toLowerCase();
|
||||
});
|
||||
|
||||
const tag = topics
|
||||
.map((t) => {
|
||||
if (t == null) {
|
||||
return 'null';
|
||||
}
|
||||
if (Array.isArray(t)) {
|
||||
return t.join('|');
|
||||
}
|
||||
return t;
|
||||
})
|
||||
.join('&');
|
||||
|
||||
return { fragment, tag, topics };
|
||||
}
|
||||
|
||||
export async function multiQueryFilter(
|
||||
// Single address will scan for a single contract, array for multiple, and * for all contracts with event topic
|
||||
address: string | string[],
|
||||
contract: BaseContract,
|
||||
event: ContractEventName,
|
||||
fromBlock?: BlockTag,
|
||||
toBlock?: BlockTag,
|
||||
) {
|
||||
if (fromBlock == null) {
|
||||
fromBlock = 0;
|
||||
}
|
||||
if (toBlock == null) {
|
||||
toBlock = 'latest';
|
||||
}
|
||||
|
||||
const { fragment, topics } = await getSubInfo(contract.interface, event);
|
||||
|
||||
const filter = {
|
||||
address: address === '*' ? undefined : address,
|
||||
topics,
|
||||
fromBlock,
|
||||
toBlock,
|
||||
};
|
||||
|
||||
const provider = contract.runner as Provider | null;
|
||||
|
||||
assert(provider, 'contract runner does not have a provider', 'UNSUPPORTED_OPERATION', { operation: 'queryFilter' });
|
||||
|
||||
return (await provider.getLogs(filter)).map((log) => {
|
||||
let foundFragment = fragment;
|
||||
if (foundFragment == null) {
|
||||
try {
|
||||
foundFragment = contract.interface.getEvent(log.topics[0]);
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (foundFragment) {
|
||||
try {
|
||||
return new EventLog(log, contract.interface, foundFragment);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (error: any) {
|
||||
return new UndecodedEventLog(log, error);
|
||||
}
|
||||
}
|
||||
|
||||
return new Log(log, provider);
|
||||
});
|
||||
}
|
||||
|
||||
export interface BatchBlockServiceConstructor {
|
||||
provider: Provider;
|
||||
onProgress?: BatchBlockOnProgress;
|
||||
concurrencySize?: number;
|
||||
batchSize?: number;
|
||||
shouldRetry?: boolean;
|
||||
retryMax?: number;
|
||||
retryOn?: number;
|
||||
provider: Provider;
|
||||
onProgress?: BatchBlockOnProgress;
|
||||
concurrencySize?: number;
|
||||
batchSize?: number;
|
||||
shouldRetry?: boolean;
|
||||
retryMax?: number;
|
||||
retryOn?: number;
|
||||
}
|
||||
|
||||
export type BatchBlockOnProgress = ({
|
||||
percentage,
|
||||
currentIndex,
|
||||
totalIndex,
|
||||
percentage,
|
||||
currentIndex,
|
||||
totalIndex,
|
||||
}: {
|
||||
percentage: number;
|
||||
currentIndex?: number;
|
||||
totalIndex?: number;
|
||||
percentage: number;
|
||||
currentIndex?: number;
|
||||
totalIndex?: number;
|
||||
}) => void;
|
||||
|
||||
/**
|
||||
* Fetch blocks from web3 provider on batches
|
||||
*/
|
||||
export class BatchBlockService {
|
||||
provider: Provider;
|
||||
onProgress?: BatchBlockOnProgress;
|
||||
concurrencySize: number;
|
||||
batchSize: number;
|
||||
shouldRetry: boolean;
|
||||
retryMax: number;
|
||||
retryOn: number;
|
||||
constructor({
|
||||
provider,
|
||||
onProgress,
|
||||
concurrencySize = 10,
|
||||
batchSize = 10,
|
||||
shouldRetry = true,
|
||||
retryMax = 5,
|
||||
retryOn = 500,
|
||||
}: BatchBlockServiceConstructor) {
|
||||
this.provider = provider;
|
||||
this.onProgress = onProgress;
|
||||
this.concurrencySize = concurrencySize;
|
||||
this.batchSize = batchSize;
|
||||
this.shouldRetry = shouldRetry;
|
||||
this.retryMax = retryMax;
|
||||
this.retryOn = retryOn;
|
||||
}
|
||||
|
||||
async getBlock(blockTag: BlockTag): Promise<Block> {
|
||||
const blockObject = await this.provider.getBlock(blockTag);
|
||||
|
||||
// if the provider returns null (which they have corrupted block data for one of their nodes) throw and retry
|
||||
if (!blockObject) {
|
||||
const errMsg = `No block for ${blockTag}`;
|
||||
throw new Error(errMsg);
|
||||
provider: Provider;
|
||||
onProgress?: BatchBlockOnProgress;
|
||||
concurrencySize: number;
|
||||
batchSize: number;
|
||||
shouldRetry: boolean;
|
||||
retryMax: number;
|
||||
retryOn: number;
|
||||
constructor({
|
||||
provider,
|
||||
onProgress,
|
||||
concurrencySize = 10,
|
||||
batchSize = 10,
|
||||
shouldRetry = true,
|
||||
retryMax = 5,
|
||||
retryOn = 500,
|
||||
}: BatchBlockServiceConstructor) {
|
||||
this.provider = provider;
|
||||
this.onProgress = onProgress;
|
||||
this.concurrencySize = concurrencySize;
|
||||
this.batchSize = batchSize;
|
||||
this.shouldRetry = shouldRetry;
|
||||
this.retryMax = retryMax;
|
||||
this.retryOn = retryOn;
|
||||
}
|
||||
|
||||
return blockObject;
|
||||
}
|
||||
async getBlock(blockTag: BlockTag): Promise<Block> {
|
||||
const blockObject = await this.provider.getBlock(blockTag);
|
||||
|
||||
createBatchRequest(batchArray: BlockTag[][]): Promise<Block[]>[] {
|
||||
return batchArray.map(async (blocks: BlockTag[], index: number) => {
|
||||
// send batch requests on milliseconds to avoid including them on a single batch request
|
||||
await sleep(20 * index);
|
||||
|
||||
return (async () => {
|
||||
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)));
|
||||
} catch (e) {
|
||||
retries++;
|
||||
err = e;
|
||||
|
||||
// retry on 0.5 seconds
|
||||
await sleep(this.retryOn);
|
||||
}
|
||||
// if the provider returns null (which they have corrupted block data for one of their nodes) throw and retry
|
||||
if (!blockObject) {
|
||||
const errMsg = `No block for ${blockTag}`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
throw err;
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
async getBatchBlocks(blocks: BlockTag[]): Promise<Block[]> {
|
||||
let blockCount = 0;
|
||||
const results: Block[] = [];
|
||||
|
||||
for (const chunks of chunk(blocks, this.concurrencySize * this.batchSize)) {
|
||||
const chunksResult = (await Promise.all(this.createBatchRequest(chunk(chunks, this.batchSize)))).flat();
|
||||
|
||||
results.push(...chunksResult);
|
||||
|
||||
blockCount += chunks.length;
|
||||
|
||||
if (typeof this.onProgress === 'function') {
|
||||
this.onProgress({
|
||||
percentage: blockCount / blocks.length,
|
||||
currentIndex: blockCount,
|
||||
totalIndex: blocks.length,
|
||||
});
|
||||
}
|
||||
return blockObject;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
createBatchRequest(batchArray: BlockTag[][]): Promise<Block[]>[] {
|
||||
return batchArray.map(async (blocks: BlockTag[], index: number) => {
|
||||
// send batch requests on milliseconds to avoid including them on a single batch request
|
||||
await sleep(40 * index);
|
||||
|
||||
return (async () => {
|
||||
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)));
|
||||
} catch (e) {
|
||||
retries++;
|
||||
err = e;
|
||||
|
||||
// retry on 0.5 seconds
|
||||
await sleep(this.retryOn);
|
||||
}
|
||||
}
|
||||
|
||||
throw err;
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
async getBatchBlocks(blocks: BlockTag[]): Promise<Block[]> {
|
||||
let blockCount = 0;
|
||||
const results: Block[] = [];
|
||||
|
||||
for (const chunks of chunk(blocks, this.concurrencySize * this.batchSize)) {
|
||||
const chunksResult = (await Promise.all(this.createBatchRequest(chunk(chunks, this.batchSize)))).flat();
|
||||
|
||||
results.push(...chunksResult);
|
||||
|
||||
blockCount += chunks.length;
|
||||
|
||||
if (typeof this.onProgress === 'function') {
|
||||
this.onProgress({
|
||||
percentage: blockCount / blocks.length,
|
||||
currentIndex: blockCount,
|
||||
totalIndex: blocks.length,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch transactions from web3 provider on batches
|
||||
*/
|
||||
export class BatchTransactionService {
|
||||
provider: Provider;
|
||||
onProgress?: BatchBlockOnProgress;
|
||||
concurrencySize: number;
|
||||
batchSize: number;
|
||||
shouldRetry: boolean;
|
||||
retryMax: number;
|
||||
retryOn: number;
|
||||
constructor({
|
||||
provider,
|
||||
onProgress,
|
||||
concurrencySize = 10,
|
||||
batchSize = 10,
|
||||
shouldRetry = true,
|
||||
retryMax = 5,
|
||||
retryOn = 500,
|
||||
}: BatchBlockServiceConstructor) {
|
||||
this.provider = provider;
|
||||
this.onProgress = onProgress;
|
||||
this.concurrencySize = concurrencySize;
|
||||
this.batchSize = batchSize;
|
||||
this.shouldRetry = shouldRetry;
|
||||
this.retryMax = retryMax;
|
||||
this.retryOn = retryOn;
|
||||
}
|
||||
|
||||
async getTransaction(txHash: string): Promise<TransactionResponse> {
|
||||
const txObject = await this.provider.getTransaction(txHash);
|
||||
|
||||
if (!txObject) {
|
||||
const errMsg = `No transaction for ${txHash}`;
|
||||
throw new Error(errMsg);
|
||||
provider: Provider;
|
||||
onProgress?: BatchBlockOnProgress;
|
||||
concurrencySize: number;
|
||||
batchSize: number;
|
||||
shouldRetry: boolean;
|
||||
retryMax: number;
|
||||
retryOn: number;
|
||||
constructor({
|
||||
provider,
|
||||
onProgress,
|
||||
concurrencySize = 10,
|
||||
batchSize = 10,
|
||||
shouldRetry = true,
|
||||
retryMax = 5,
|
||||
retryOn = 500,
|
||||
}: BatchBlockServiceConstructor) {
|
||||
this.provider = provider;
|
||||
this.onProgress = onProgress;
|
||||
this.concurrencySize = concurrencySize;
|
||||
this.batchSize = batchSize;
|
||||
this.shouldRetry = shouldRetry;
|
||||
this.retryMax = retryMax;
|
||||
this.retryOn = retryOn;
|
||||
}
|
||||
|
||||
return txObject;
|
||||
}
|
||||
async getTransaction(txHash: string): Promise<TransactionResponse> {
|
||||
const txObject = await this.provider.getTransaction(txHash);
|
||||
|
||||
createBatchRequest(batchArray: string[][]): Promise<TransactionResponse[]>[] {
|
||||
return batchArray.map(async (txs: string[], index: number) => {
|
||||
await sleep(20 * index);
|
||||
|
||||
return (async () => {
|
||||
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(txs.map((tx) => this.getTransaction(tx)));
|
||||
} catch (e) {
|
||||
retries++;
|
||||
err = e;
|
||||
|
||||
// retry on 0.5 seconds
|
||||
await sleep(this.retryOn);
|
||||
}
|
||||
if (!txObject) {
|
||||
const errMsg = `No transaction for ${txHash}`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
throw err;
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
async getBatchTransactions(txs: string[]): Promise<TransactionResponse[]> {
|
||||
let txCount = 0;
|
||||
const results = [];
|
||||
|
||||
for (const chunks of chunk(txs, this.concurrencySize * this.batchSize)) {
|
||||
const chunksResult = (await Promise.all(this.createBatchRequest(chunk(chunks, this.batchSize)))).flat();
|
||||
|
||||
results.push(...chunksResult);
|
||||
|
||||
txCount += chunks.length;
|
||||
|
||||
if (typeof this.onProgress === 'function') {
|
||||
this.onProgress({ percentage: txCount / txs.length, currentIndex: txCount, totalIndex: txs.length });
|
||||
}
|
||||
return txObject;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
async getTransactionReceipt(txHash: string): Promise<TransactionReceipt> {
|
||||
const txObject = await this.provider.getTransactionReceipt(txHash);
|
||||
|
||||
if (!txObject) {
|
||||
const errMsg = `No transaction receipt for ${txHash}`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
return txObject;
|
||||
}
|
||||
|
||||
createBatchRequest(
|
||||
batchArray: string[][],
|
||||
receipt?: boolean,
|
||||
): Promise<TransactionResponse[] | TransactionReceipt[]>[] {
|
||||
return batchArray.map(async (txs: string[], index: number) => {
|
||||
await sleep(40 * index);
|
||||
|
||||
return (async () => {
|
||||
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) {
|
||||
return await Promise.all(txs.map((tx) => this.getTransaction(tx)));
|
||||
} else {
|
||||
return await Promise.all(txs.map((tx) => this.getTransactionReceipt(tx)));
|
||||
}
|
||||
} catch (e) {
|
||||
retries++;
|
||||
err = e;
|
||||
|
||||
// retry on 0.5 seconds
|
||||
await sleep(this.retryOn);
|
||||
}
|
||||
}
|
||||
|
||||
throw err;
|
||||
})();
|
||||
});
|
||||
}
|
||||
|
||||
async getBatchTransactions(txs: string[]): Promise<TransactionResponse[]> {
|
||||
let txCount = 0;
|
||||
const results = [];
|
||||
|
||||
for (const chunks of chunk(txs, this.concurrencySize * this.batchSize)) {
|
||||
const chunksResult = (
|
||||
await Promise.all(this.createBatchRequest(chunk(chunks, this.batchSize)))
|
||||
).flat() as TransactionResponse[];
|
||||
|
||||
results.push(...chunksResult);
|
||||
|
||||
txCount += chunks.length;
|
||||
|
||||
if (typeof this.onProgress === 'function') {
|
||||
this.onProgress({
|
||||
percentage: txCount / txs.length,
|
||||
currentIndex: txCount,
|
||||
totalIndex: txs.length,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
async getBatchReceipt(txs: string[]): Promise<TransactionReceipt[]> {
|
||||
let txCount = 0;
|
||||
const results = [];
|
||||
|
||||
for (const chunks of chunk(txs, this.concurrencySize * this.batchSize)) {
|
||||
const chunksResult = (
|
||||
await Promise.all(this.createBatchRequest(chunk(chunks, this.batchSize), true))
|
||||
).flat() as TransactionReceipt[];
|
||||
|
||||
results.push(...chunksResult);
|
||||
|
||||
txCount += chunks.length;
|
||||
|
||||
if (typeof this.onProgress === 'function') {
|
||||
this.onProgress({
|
||||
percentage: txCount / txs.length,
|
||||
currentIndex: txCount,
|
||||
totalIndex: txs.length,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
export interface BatchEventServiceConstructor {
|
||||
provider: Provider;
|
||||
contract: BaseContract;
|
||||
onProgress?: BatchEventOnProgress;
|
||||
concurrencySize?: number;
|
||||
blocksPerRequest?: number;
|
||||
shouldRetry?: boolean;
|
||||
retryMax?: number;
|
||||
retryOn?: number;
|
||||
provider: Provider;
|
||||
contract: BaseContract;
|
||||
address?: string | string[];
|
||||
onProgress?: BatchEventOnProgress;
|
||||
concurrencySize?: number;
|
||||
blocksPerRequest?: number;
|
||||
shouldRetry?: boolean;
|
||||
retryMax?: number;
|
||||
retryOn?: number;
|
||||
}
|
||||
|
||||
export type BatchEventOnProgress = ({
|
||||
percentage,
|
||||
type,
|
||||
fromBlock,
|
||||
toBlock,
|
||||
count,
|
||||
percentage,
|
||||
type,
|
||||
fromBlock,
|
||||
toBlock,
|
||||
count,
|
||||
}: {
|
||||
percentage: number;
|
||||
type?: ContractEventName;
|
||||
fromBlock?: number;
|
||||
toBlock?: number;
|
||||
count?: number;
|
||||
percentage: number;
|
||||
type?: ContractEventName;
|
||||
fromBlock?: number;
|
||||
toBlock?: number;
|
||||
count?: number;
|
||||
}) => void;
|
||||
|
||||
// To enable iteration only numbers are accepted for fromBlock input
|
||||
export type EventInput = {
|
||||
fromBlock: number;
|
||||
toBlock: number;
|
||||
type: ContractEventName;
|
||||
};
|
||||
export interface EventInput {
|
||||
fromBlock: number;
|
||||
toBlock: number;
|
||||
type: ContractEventName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch events from web3 provider on bulk
|
||||
*/
|
||||
export class BatchEventsService {
|
||||
provider: Provider;
|
||||
contract: BaseContract;
|
||||
onProgress?: BatchEventOnProgress;
|
||||
concurrencySize: number;
|
||||
blocksPerRequest: number;
|
||||
shouldRetry: boolean;
|
||||
retryMax: number;
|
||||
retryOn: number;
|
||||
constructor({
|
||||
provider,
|
||||
contract,
|
||||
onProgress,
|
||||
concurrencySize = 10,
|
||||
blocksPerRequest = 2000,
|
||||
shouldRetry = true,
|
||||
retryMax = 5,
|
||||
retryOn = 500,
|
||||
}: BatchEventServiceConstructor) {
|
||||
this.provider = provider;
|
||||
this.contract = contract;
|
||||
this.onProgress = onProgress;
|
||||
this.concurrencySize = concurrencySize;
|
||||
this.blocksPerRequest = blocksPerRequest;
|
||||
this.shouldRetry = shouldRetry;
|
||||
this.retryMax = retryMax;
|
||||
this.retryOn = retryOn;
|
||||
}
|
||||
provider: Provider;
|
||||
contract: BaseContract;
|
||||
address?: string | string[];
|
||||
onProgress?: BatchEventOnProgress;
|
||||
concurrencySize: number;
|
||||
blocksPerRequest: number;
|
||||
shouldRetry: boolean;
|
||||
retryMax: number;
|
||||
retryOn: number;
|
||||
constructor({
|
||||
provider,
|
||||
contract,
|
||||
address,
|
||||
onProgress,
|
||||
concurrencySize = 10,
|
||||
blocksPerRequest = 5000,
|
||||
shouldRetry = true,
|
||||
retryMax = 5,
|
||||
retryOn = 500,
|
||||
}: BatchEventServiceConstructor) {
|
||||
this.provider = provider;
|
||||
this.contract = contract;
|
||||
this.address = address;
|
||||
this.onProgress = onProgress;
|
||||
this.concurrencySize = concurrencySize;
|
||||
this.blocksPerRequest = blocksPerRequest;
|
||||
this.shouldRetry = shouldRetry;
|
||||
this.retryMax = retryMax;
|
||||
this.retryOn = retryOn;
|
||||
}
|
||||
|
||||
async getPastEvents({ fromBlock, toBlock, type }: EventInput): Promise<EventLog[]> {
|
||||
let err;
|
||||
let retries = 0;
|
||||
async getPastEvents({ fromBlock, toBlock, type }: EventInput): Promise<EventLog[]> {
|
||||
let err;
|
||||
let retries = 0;
|
||||
|
||||
// eslint-disable-next-line no-unmodified-loop-condition
|
||||
while ((!this.shouldRetry && retries === 0) || (this.shouldRetry && retries < this.retryMax)) {
|
||||
try {
|
||||
return (await this.contract.queryFilter(type, fromBlock, toBlock)) as EventLog[];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
err = e;
|
||||
retries++;
|
||||
// eslint-disable-next-line no-unmodified-loop-condition
|
||||
while ((!this.shouldRetry && retries === 0) || (this.shouldRetry && retries < this.retryMax)) {
|
||||
try {
|
||||
if (this.address) {
|
||||
return (await multiQueryFilter(
|
||||
this.address,
|
||||
this.contract,
|
||||
type,
|
||||
fromBlock,
|
||||
toBlock,
|
||||
)) as EventLog[];
|
||||
}
|
||||
return (await this.contract.queryFilter(type, fromBlock, toBlock)) as EventLog[];
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (e: any) {
|
||||
err = e;
|
||||
retries++;
|
||||
|
||||
// If provider.getBlockNumber returned last block that isn't accepted (happened on Avalanche/Gnosis),
|
||||
// get events to last accepted block
|
||||
if (e.message.includes('after last accepted block')) {
|
||||
const acceptedBlock = parseInt(e.message.split('after last accepted block ')[1]);
|
||||
toBlock = acceptedBlock;
|
||||
// If provider.getBlockNumber returned last block that isn't accepted (happened on Avalanche/Gnosis),
|
||||
// get events to last accepted block
|
||||
if (e.message.includes('after last accepted block')) {
|
||||
const acceptedBlock = parseInt(e.message.split('after last accepted block ')[1]);
|
||||
toBlock = acceptedBlock;
|
||||
}
|
||||
|
||||
// retry on 0.5 seconds
|
||||
await sleep(this.retryOn);
|
||||
}
|
||||
}
|
||||
|
||||
// retry on 0.5 seconds
|
||||
await sleep(this.retryOn);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
createBatchRequest(batchArray: EventInput[]): Promise<EventLog[]>[] {
|
||||
return batchArray.map(async (event: EventInput, index: number) => {
|
||||
await sleep(10 * index);
|
||||
|
||||
createBatchRequest(batchArray: EventInput[]): Promise<EventLog[]>[] {
|
||||
return batchArray.map(async (event: EventInput, index: number) => {
|
||||
await sleep(20 * index);
|
||||
|
||||
return this.getPastEvents(event);
|
||||
});
|
||||
}
|
||||
|
||||
async getBatchEvents({ fromBlock, toBlock, type = '*' }: EventInput): Promise<EventLog[]> {
|
||||
if (!toBlock) {
|
||||
toBlock = await this.provider.getBlockNumber();
|
||||
}
|
||||
|
||||
const eventsToSync = [];
|
||||
|
||||
for (let i = fromBlock; i < toBlock; i += this.blocksPerRequest) {
|
||||
const j = i + this.blocksPerRequest - 1 > toBlock ? toBlock : i + this.blocksPerRequest - 1;
|
||||
|
||||
eventsToSync.push({ fromBlock: i, toBlock: j, type });
|
||||
}
|
||||
|
||||
const events = [];
|
||||
const eventChunk = chunk(eventsToSync, this.concurrencySize);
|
||||
|
||||
let chunkCount = 0;
|
||||
|
||||
for (const chunk of eventChunk) {
|
||||
chunkCount++;
|
||||
|
||||
const fetchedEvents = (await Promise.all(this.createBatchRequest(chunk))).flat();
|
||||
events.push(...fetchedEvents);
|
||||
|
||||
if (typeof this.onProgress === 'function') {
|
||||
this.onProgress({
|
||||
percentage: chunkCount / eventChunk.length,
|
||||
type,
|
||||
fromBlock: chunk[0].fromBlock,
|
||||
toBlock: chunk[chunk.length - 1].toBlock,
|
||||
count: fetchedEvents.length,
|
||||
return this.getPastEvents(event);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
async getBatchEvents({ fromBlock, toBlock, type = '*' }: EventInput): Promise<EventLog[]> {
|
||||
if (!toBlock) {
|
||||
toBlock = await this.provider.getBlockNumber();
|
||||
}
|
||||
|
||||
const eventsToSync = [];
|
||||
|
||||
for (let i = fromBlock; i < toBlock; i += this.blocksPerRequest) {
|
||||
const j = i + this.blocksPerRequest - 1 > toBlock ? toBlock : i + this.blocksPerRequest - 1;
|
||||
|
||||
eventsToSync.push({ fromBlock: i, toBlock: j, type });
|
||||
}
|
||||
|
||||
const events = [];
|
||||
const eventChunk = chunk(eventsToSync, this.concurrencySize);
|
||||
|
||||
let chunkCount = 0;
|
||||
|
||||
for (const chunk of eventChunk) {
|
||||
chunkCount++;
|
||||
|
||||
const fetchedEvents = (await Promise.all(this.createBatchRequest(chunk))).flat();
|
||||
events.push(...fetchedEvents);
|
||||
|
||||
if (typeof this.onProgress === 'function') {
|
||||
this.onProgress({
|
||||
percentage: chunkCount / eventChunk.length,
|
||||
type,
|
||||
fromBlock: chunk[0].fromBlock,
|
||||
toBlock: chunk[chunk.length - 1].toBlock,
|
||||
count: fetchedEvents.length,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
}
|
||||
|
||||
17
src/contracts.ts
Normal file
17
src/contracts.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
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';
|
||||
435
src/deposits.ts
435
src/deposits.ts
@@ -2,246 +2,271 @@ import { bnToBytes, bytesToBN, leBuff2Int, leInt2Buff, rBigInt, toFixedHex } fro
|
||||
import { buffPedersenHash } from './pedersen';
|
||||
import type { NetIdType } from './networkConfig';
|
||||
|
||||
export type DepositType = {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
};
|
||||
export interface DepositType {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
}
|
||||
|
||||
export type createDepositParams = {
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
};
|
||||
export interface createDepositParams {
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
}
|
||||
|
||||
export type createDepositObject = {
|
||||
preimage: Uint8Array;
|
||||
noteHex: string;
|
||||
commitment: bigint;
|
||||
commitmentHex: string;
|
||||
nullifierHash: bigint;
|
||||
nullifierHex: string;
|
||||
};
|
||||
export interface createDepositObject {
|
||||
preimage: Uint8Array;
|
||||
noteHex: string;
|
||||
commitment: bigint;
|
||||
commitmentHex: string;
|
||||
nullifierHash: bigint;
|
||||
nullifierHex: string;
|
||||
}
|
||||
|
||||
export type createNoteParams = DepositType & {
|
||||
nullifier?: bigint;
|
||||
secret?: bigint;
|
||||
};
|
||||
export interface createNoteParams extends DepositType {
|
||||
nullifier?: bigint;
|
||||
secret?: bigint;
|
||||
}
|
||||
|
||||
export type parsedNoteExec = DepositType & {
|
||||
note: string;
|
||||
};
|
||||
export interface parsedNoteExec extends DepositType {
|
||||
note: string;
|
||||
noteHex: string;
|
||||
}
|
||||
|
||||
export type depositTx = {
|
||||
from: string;
|
||||
transactionHash: string;
|
||||
};
|
||||
export interface parsedInvoiceExec extends DepositType {
|
||||
invoice: string;
|
||||
commitmentHex: string;
|
||||
}
|
||||
|
||||
export type withdrawalTx = {
|
||||
to: string;
|
||||
transactionHash: string;
|
||||
};
|
||||
export function parseNote(noteString: string): parsedNoteExec | undefined {
|
||||
const noteRegex = /tornado-(?<currency>\w+)-(?<amount>[\d.]+)-(?<netId>\d+)-0x(?<noteHex>[0-9a-fA-F]{124})/g;
|
||||
const match = noteRegex.exec(noteString);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { currency, amount, netId, noteHex } = match.groups as unknown as parsedNoteExec;
|
||||
|
||||
return {
|
||||
currency: currency.toLowerCase(),
|
||||
amount,
|
||||
netId: Number(netId),
|
||||
noteHex: '0x' + noteHex,
|
||||
note: noteString,
|
||||
};
|
||||
}
|
||||
|
||||
export function parseInvoice(invoiceString: string): parsedInvoiceExec | undefined {
|
||||
const invoiceRegex =
|
||||
/tornadoInvoice-(?<currency>\w+)-(?<amount>[\d.]+)-(?<netId>\d+)-0x(?<commitmentHex>[0-9a-fA-F]{64})/g;
|
||||
const match = invoiceRegex.exec(invoiceString);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { currency, amount, netId, commitmentHex } = match.groups as unknown as parsedInvoiceExec;
|
||||
|
||||
return {
|
||||
currency: currency.toLowerCase(),
|
||||
amount,
|
||||
netId: Number(netId),
|
||||
commitmentHex: '0x' + commitmentHex,
|
||||
invoice: invoiceString,
|
||||
};
|
||||
}
|
||||
|
||||
export async function createDeposit({ nullifier, secret }: createDepositParams): Promise<createDepositObject> {
|
||||
const preimage = new Uint8Array([...leInt2Buff(nullifier), ...leInt2Buff(secret)]);
|
||||
const noteHex = toFixedHex(bytesToBN(preimage), 62);
|
||||
const commitment = BigInt(await buffPedersenHash(preimage));
|
||||
const commitmentHex = toFixedHex(commitment);
|
||||
const nullifierHash = BigInt(await buffPedersenHash(leInt2Buff(nullifier)));
|
||||
const nullifierHex = toFixedHex(nullifierHash);
|
||||
const preimage = new Uint8Array([...leInt2Buff(nullifier), ...leInt2Buff(secret)]);
|
||||
const noteHex = toFixedHex(bytesToBN(preimage), 62);
|
||||
const commitment = BigInt(await buffPedersenHash(preimage));
|
||||
const commitmentHex = toFixedHex(commitment);
|
||||
const nullifierHash = BigInt(await buffPedersenHash(leInt2Buff(nullifier)));
|
||||
const nullifierHex = toFixedHex(nullifierHash);
|
||||
|
||||
return {
|
||||
preimage,
|
||||
noteHex,
|
||||
commitment,
|
||||
commitmentHex,
|
||||
nullifierHash,
|
||||
nullifierHex,
|
||||
};
|
||||
return {
|
||||
preimage,
|
||||
noteHex,
|
||||
commitment,
|
||||
commitmentHex,
|
||||
nullifierHash,
|
||||
nullifierHex,
|
||||
};
|
||||
}
|
||||
|
||||
export interface DepositConstructor {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
note: string;
|
||||
noteHex: string;
|
||||
invoice: string;
|
||||
commitmentHex: string;
|
||||
nullifierHex: string;
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
note: string;
|
||||
noteHex: string;
|
||||
invoice: string;
|
||||
commitmentHex: string;
|
||||
nullifierHex: string;
|
||||
}
|
||||
|
||||
export class Deposit {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
nullifier: bigint;
|
||||
secret: bigint;
|
||||
|
||||
note: string;
|
||||
noteHex: string;
|
||||
invoice: string;
|
||||
note: string;
|
||||
noteHex: string;
|
||||
invoice: string;
|
||||
|
||||
commitmentHex: string;
|
||||
nullifierHex: string;
|
||||
commitmentHex: string;
|
||||
nullifierHex: string;
|
||||
|
||||
constructor({
|
||||
currency,
|
||||
amount,
|
||||
netId,
|
||||
nullifier,
|
||||
secret,
|
||||
note,
|
||||
noteHex,
|
||||
invoice,
|
||||
commitmentHex,
|
||||
nullifierHex,
|
||||
}: DepositConstructor) {
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
this.netId = netId;
|
||||
constructor({
|
||||
currency,
|
||||
amount,
|
||||
netId,
|
||||
nullifier,
|
||||
secret,
|
||||
note,
|
||||
noteHex,
|
||||
invoice,
|
||||
commitmentHex,
|
||||
nullifierHex,
|
||||
}: DepositConstructor) {
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
this.netId = netId;
|
||||
|
||||
this.nullifier = nullifier;
|
||||
this.secret = secret;
|
||||
this.nullifier = nullifier;
|
||||
this.secret = secret;
|
||||
|
||||
this.note = note;
|
||||
this.noteHex = noteHex;
|
||||
this.invoice = invoice;
|
||||
this.note = note;
|
||||
this.noteHex = noteHex;
|
||||
this.invoice = invoice;
|
||||
|
||||
this.commitmentHex = commitmentHex;
|
||||
this.nullifierHex = nullifierHex;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return JSON.stringify(
|
||||
{
|
||||
currency: this.currency,
|
||||
amount: this.amount,
|
||||
netId: this.netId,
|
||||
nullifier: this.nullifier,
|
||||
secret: this.secret,
|
||||
note: this.note,
|
||||
noteHex: this.noteHex,
|
||||
invoice: this.invoice,
|
||||
commitmentHex: this.commitmentHex,
|
||||
nullifierHex: this.nullifierHex,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
static async createNote({ currency, amount, netId, nullifier, secret }: createNoteParams): Promise<Deposit> {
|
||||
if (!nullifier) {
|
||||
nullifier = rBigInt(31);
|
||||
}
|
||||
if (!secret) {
|
||||
secret = rBigInt(31);
|
||||
this.commitmentHex = commitmentHex;
|
||||
this.nullifierHex = nullifierHex;
|
||||
}
|
||||
|
||||
const depositObject = await createDeposit({
|
||||
nullifier,
|
||||
secret,
|
||||
});
|
||||
|
||||
const newDeposit = new Deposit({
|
||||
currency: currency.toLowerCase(),
|
||||
amount: amount,
|
||||
netId,
|
||||
note: `tornado-${currency.toLowerCase()}-${amount}-${netId}-${depositObject.noteHex}`,
|
||||
noteHex: depositObject.noteHex,
|
||||
invoice: `tornadoInvoice-${currency.toLowerCase()}-${amount}-${netId}-${depositObject.commitmentHex}`,
|
||||
nullifier: nullifier,
|
||||
secret: secret,
|
||||
commitmentHex: depositObject.commitmentHex,
|
||||
nullifierHex: depositObject.nullifierHex,
|
||||
});
|
||||
|
||||
return newDeposit;
|
||||
}
|
||||
|
||||
static async parseNote(noteString: string): Promise<Deposit> {
|
||||
const noteRegex = /tornado-(?<currency>\w+)-(?<amount>[\d.]+)-(?<netId>\d+)-0x(?<note>[0-9a-fA-F]{124})/g;
|
||||
const match = noteRegex.exec(noteString);
|
||||
if (!match) {
|
||||
throw new Error('The note has invalid format');
|
||||
toString() {
|
||||
return JSON.stringify(
|
||||
{
|
||||
currency: this.currency,
|
||||
amount: this.amount,
|
||||
netId: this.netId,
|
||||
nullifier: this.nullifier,
|
||||
secret: this.secret,
|
||||
note: this.note,
|
||||
noteHex: this.noteHex,
|
||||
invoice: this.invoice,
|
||||
commitmentHex: this.commitmentHex,
|
||||
nullifierHex: this.nullifierHex,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
const matchGroup = match?.groups as unknown as parsedNoteExec;
|
||||
|
||||
const currency = matchGroup.currency.toLowerCase();
|
||||
const amount = matchGroup.amount;
|
||||
const netId = Number(matchGroup.netId);
|
||||
static async createNote({ currency, amount, netId, nullifier, secret }: createNoteParams): Promise<Deposit> {
|
||||
if (!nullifier) {
|
||||
nullifier = rBigInt(31);
|
||||
}
|
||||
if (!secret) {
|
||||
secret = rBigInt(31);
|
||||
}
|
||||
|
||||
const bytes = bnToBytes('0x' + matchGroup.note);
|
||||
const nullifier = BigInt(leBuff2Int(bytes.slice(0, 31)).toString());
|
||||
const secret = BigInt(leBuff2Int(bytes.slice(31, 62)).toString());
|
||||
const depositObject = await createDeposit({
|
||||
nullifier,
|
||||
secret,
|
||||
});
|
||||
|
||||
const depositObject = await createDeposit({ nullifier, secret });
|
||||
const newDeposit = new Deposit({
|
||||
currency: currency.toLowerCase(),
|
||||
amount: amount,
|
||||
netId,
|
||||
note: `tornado-${currency.toLowerCase()}-${amount}-${netId}-${depositObject.noteHex}`,
|
||||
noteHex: depositObject.noteHex,
|
||||
invoice: `tornadoInvoice-${currency.toLowerCase()}-${amount}-${netId}-${depositObject.commitmentHex}`,
|
||||
nullifier: nullifier,
|
||||
secret: secret,
|
||||
commitmentHex: depositObject.commitmentHex,
|
||||
nullifierHex: depositObject.nullifierHex,
|
||||
});
|
||||
|
||||
const invoice = `tornadoInvoice-${currency}-${amount}-${netId}-${depositObject.commitmentHex}`;
|
||||
return newDeposit;
|
||||
}
|
||||
|
||||
const newDeposit = new Deposit({
|
||||
currency,
|
||||
amount,
|
||||
netId,
|
||||
note: noteString,
|
||||
noteHex: depositObject.noteHex,
|
||||
invoice,
|
||||
nullifier,
|
||||
secret,
|
||||
commitmentHex: depositObject.commitmentHex,
|
||||
nullifierHex: depositObject.nullifierHex,
|
||||
});
|
||||
static async parseNote(noteString: string): Promise<Deposit> {
|
||||
const parsedNote = parseNote(noteString);
|
||||
|
||||
return newDeposit;
|
||||
}
|
||||
if (!parsedNote) {
|
||||
throw new Error('The note has invalid format');
|
||||
}
|
||||
|
||||
const { currency, amount, netId, note, noteHex: parsedNoteHex } = parsedNote;
|
||||
|
||||
const bytes = bnToBytes(parsedNoteHex);
|
||||
const nullifier = BigInt(leBuff2Int(bytes.slice(0, 31)).toString());
|
||||
const secret = BigInt(leBuff2Int(bytes.slice(31, 62)).toString());
|
||||
|
||||
const { noteHex, commitmentHex, nullifierHex } = await createDeposit({
|
||||
nullifier,
|
||||
secret,
|
||||
});
|
||||
|
||||
const invoice = `tornadoInvoice-${currency}-${amount}-${netId}-${commitmentHex}`;
|
||||
|
||||
const newDeposit = new Deposit({
|
||||
currency,
|
||||
amount,
|
||||
netId,
|
||||
note,
|
||||
noteHex,
|
||||
invoice,
|
||||
nullifier,
|
||||
secret,
|
||||
commitmentHex,
|
||||
nullifierHex,
|
||||
});
|
||||
|
||||
return newDeposit;
|
||||
}
|
||||
}
|
||||
|
||||
export type parsedInvoiceExec = DepositType & {
|
||||
commitment: string;
|
||||
};
|
||||
|
||||
export class Invoice {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
commitment: string;
|
||||
invoice: string;
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
commitmentHex: string;
|
||||
invoice: string;
|
||||
|
||||
constructor(invoiceString: string) {
|
||||
const invoiceRegex =
|
||||
/tornadoInvoice-(?<currency>\w+)-(?<amount>[\d.]+)-(?<netId>\d+)-0x(?<commitment>[0-9a-fA-F]{64})/g;
|
||||
const match = invoiceRegex.exec(invoiceString);
|
||||
if (!match) {
|
||||
throw new Error('The note has invalid format');
|
||||
constructor(invoiceString: string) {
|
||||
const parsedInvoice = parseInvoice(invoiceString);
|
||||
|
||||
if (!parsedInvoice) {
|
||||
throw new Error('The invoice has invalid format');
|
||||
}
|
||||
|
||||
const { currency, amount, netId, invoice, commitmentHex } = parsedInvoice;
|
||||
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
this.netId = netId;
|
||||
|
||||
this.commitmentHex = commitmentHex;
|
||||
this.invoice = invoice;
|
||||
}
|
||||
const matchGroup = match?.groups as unknown as parsedInvoiceExec;
|
||||
|
||||
const currency = matchGroup.currency.toLowerCase();
|
||||
const amount = matchGroup.amount;
|
||||
const netId = Number(matchGroup.netId);
|
||||
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
this.netId = netId;
|
||||
|
||||
this.commitment = '0x' + matchGroup.commitment;
|
||||
this.invoice = invoiceString;
|
||||
}
|
||||
|
||||
toString() {
|
||||
return JSON.stringify(
|
||||
{
|
||||
currency: this.currency,
|
||||
amount: this.amount,
|
||||
netId: this.netId,
|
||||
commitment: this.commitment,
|
||||
invoice: this.invoice,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
toString() {
|
||||
return JSON.stringify(
|
||||
{
|
||||
currency: this.currency,
|
||||
amount: this.amount,
|
||||
netId: this.netId,
|
||||
commitmentHex: this.commitmentHex,
|
||||
invoice: this.invoice,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,189 +1,209 @@
|
||||
import { getEncryptionPublicKey, encrypt, decrypt, EthEncryptedData } from '@metamask/eth-sig-util';
|
||||
import { Echoer } from '@tornado/contracts';
|
||||
import { Wallet, computeAddress, getAddress } from 'ethers';
|
||||
import { crypto, base64ToBytes, bytesToBase64, bytesToHex, hexToBytes, toFixedHex, concatBytes } from './utils';
|
||||
import { JsonRpcApiProvider, Signer, Wallet, computeAddress, getAddress } from 'ethers';
|
||||
import { base64ToBytes, bytesToBase64, bytesToHex, hexToBytes, toFixedHex, concatBytes, rHex } from './utils';
|
||||
import { EchoEvents, EncryptedNotesEvents } from './events';
|
||||
import type { NetIdType } from './networkConfig';
|
||||
|
||||
export interface NoteToEncrypt {
|
||||
address: string;
|
||||
noteHex: string;
|
||||
address: string;
|
||||
noteHex: string;
|
||||
}
|
||||
|
||||
export interface DecryptedNotes {
|
||||
blockNumber: number;
|
||||
address: string;
|
||||
noteHex: string;
|
||||
blockNumber: number;
|
||||
address: string;
|
||||
noteHex: string;
|
||||
}
|
||||
|
||||
export function packEncryptedMessage({ nonce, ephemPublicKey, ciphertext }: EthEncryptedData) {
|
||||
const nonceBuf = toFixedHex(bytesToHex(base64ToBytes(nonce)), 24);
|
||||
const ephemPublicKeyBuf = toFixedHex(bytesToHex(base64ToBytes(ephemPublicKey)), 32);
|
||||
const ciphertextBuf = bytesToHex(base64ToBytes(ciphertext));
|
||||
const nonceBuf = toFixedHex(bytesToHex(base64ToBytes(nonce)), 24);
|
||||
const ephemPublicKeyBuf = toFixedHex(bytesToHex(base64ToBytes(ephemPublicKey)), 32);
|
||||
const ciphertextBuf = bytesToHex(base64ToBytes(ciphertext));
|
||||
|
||||
const messageBuff = concatBytes(hexToBytes(nonceBuf), hexToBytes(ephemPublicKeyBuf), hexToBytes(ciphertextBuf));
|
||||
const messageBuff = concatBytes(hexToBytes(nonceBuf), hexToBytes(ephemPublicKeyBuf), hexToBytes(ciphertextBuf));
|
||||
|
||||
return bytesToHex(messageBuff);
|
||||
return bytesToHex(messageBuff);
|
||||
}
|
||||
|
||||
export function unpackEncryptedMessage(encryptedMessage: string) {
|
||||
const messageBuff = hexToBytes(encryptedMessage);
|
||||
const nonceBuf = bytesToBase64(messageBuff.slice(0, 24));
|
||||
const ephemPublicKeyBuf = bytesToBase64(messageBuff.slice(24, 56));
|
||||
const ciphertextBuf = bytesToBase64(messageBuff.slice(56));
|
||||
const messageBuff = hexToBytes(encryptedMessage);
|
||||
const nonceBuf = bytesToBase64(messageBuff.slice(0, 24));
|
||||
const ephemPublicKeyBuf = bytesToBase64(messageBuff.slice(24, 56));
|
||||
const ciphertextBuf = bytesToBase64(messageBuff.slice(56));
|
||||
|
||||
return {
|
||||
messageBuff: bytesToHex(messageBuff),
|
||||
version: 'x25519-xsalsa20-poly1305',
|
||||
nonce: nonceBuf,
|
||||
ephemPublicKey: ephemPublicKeyBuf,
|
||||
ciphertext: ciphertextBuf,
|
||||
} as EthEncryptedData & {
|
||||
messageBuff: string;
|
||||
};
|
||||
return {
|
||||
messageBuff: bytesToHex(messageBuff),
|
||||
version: 'x25519-xsalsa20-poly1305',
|
||||
nonce: nonceBuf,
|
||||
ephemPublicKey: ephemPublicKeyBuf,
|
||||
ciphertext: ciphertextBuf,
|
||||
} as EthEncryptedData & {
|
||||
messageBuff: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface NoteAccountConstructor {
|
||||
netId: NetIdType;
|
||||
blockNumber?: number;
|
||||
// hex
|
||||
recoveryKey?: string;
|
||||
Echoer: Echoer;
|
||||
blockNumber?: number;
|
||||
// hex
|
||||
recoveryKey?: string;
|
||||
}
|
||||
|
||||
export class NoteAccount {
|
||||
netId: NetIdType;
|
||||
blockNumber?: number;
|
||||
// Dedicated 32 bytes private key only used for note encryption, backed up to an Echoer and local for future derivation
|
||||
// Note that unlike the private key it shouldn't have the 0x prefix
|
||||
recoveryKey: string;
|
||||
// Address derived from recoveryKey, only used for frontend UI
|
||||
recoveryAddress: string;
|
||||
// Note encryption public key derived from recoveryKey
|
||||
recoveryPublicKey: string;
|
||||
Echoer: Echoer;
|
||||
blockNumber?: number;
|
||||
// Dedicated 32 bytes private key only used for note encryption, backed up to an Echoer and local for future derivation
|
||||
// Note that unlike the private key it shouldn't have the 0x prefix
|
||||
recoveryKey: string;
|
||||
// Address derived from recoveryKey, only used for frontend UI
|
||||
recoveryAddress: string;
|
||||
// Note encryption public key derived from recoveryKey
|
||||
recoveryPublicKey: string;
|
||||
|
||||
constructor({ netId, blockNumber, recoveryKey, Echoer }: NoteAccountConstructor) {
|
||||
if (!recoveryKey) {
|
||||
recoveryKey = bytesToHex(crypto.getRandomValues(new Uint8Array(32))).slice(2);
|
||||
constructor({ blockNumber, recoveryKey }: NoteAccountConstructor) {
|
||||
if (!recoveryKey) {
|
||||
recoveryKey = rHex(32).slice(2);
|
||||
}
|
||||
|
||||
this.blockNumber = blockNumber;
|
||||
this.recoveryKey = recoveryKey;
|
||||
this.recoveryAddress = computeAddress('0x' + recoveryKey);
|
||||
this.recoveryPublicKey = getEncryptionPublicKey(recoveryKey);
|
||||
}
|
||||
|
||||
this.netId = Math.floor(Number(netId));
|
||||
this.blockNumber = blockNumber;
|
||||
this.recoveryKey = recoveryKey;
|
||||
this.recoveryAddress = computeAddress('0x' + recoveryKey);
|
||||
this.recoveryPublicKey = getEncryptionPublicKey(recoveryKey);
|
||||
this.Echoer = Echoer;
|
||||
}
|
||||
/**
|
||||
* Intends to mock eth_getEncryptionPublicKey behavior from MetaMask
|
||||
* In order to make the recoveryKey retrival from Echoer possible from the bare private key
|
||||
*/
|
||||
static async getSignerPublicKey(signer: Signer | Wallet) {
|
||||
if ((signer as Wallet).privateKey) {
|
||||
const wallet = signer as Wallet;
|
||||
const privateKey = wallet.privateKey.slice(0, 2) === '0x' ? wallet.privateKey.slice(2) : wallet.privateKey;
|
||||
|
||||
/**
|
||||
* Intends to mock eth_getEncryptionPublicKey behavior from MetaMask
|
||||
* In order to make the recoveryKey retrival from Echoer possible from the bare private key
|
||||
*/
|
||||
static getWalletPublicKey(wallet: Wallet) {
|
||||
let { privateKey } = wallet;
|
||||
// Should return base64 encoded public key
|
||||
return getEncryptionPublicKey(privateKey);
|
||||
}
|
||||
|
||||
if (privateKey.startsWith('0x')) {
|
||||
privateKey = privateKey.replace('0x', '');
|
||||
const provider = signer.provider as JsonRpcApiProvider;
|
||||
|
||||
return (await provider.send('eth_getEncryptionPublicKey', [
|
||||
(signer as Signer & { address: string }).address,
|
||||
])) as string;
|
||||
}
|
||||
|
||||
// Should return base64 encoded public key
|
||||
return getEncryptionPublicKey(privateKey);
|
||||
}
|
||||
|
||||
// This function intends to provide an encrypted value of recoveryKey for an on-chain Echoer backup purpose
|
||||
// Thus, the pubKey should be derived by a Wallet instance or from Web3 wallets
|
||||
// pubKey: base64 encoded 32 bytes key from https://docs.metamask.io/wallet/reference/eth_getencryptionpublickey/
|
||||
getEncryptedAccount(walletPublicKey: string) {
|
||||
const encryptedData = encrypt({
|
||||
publicKey: walletPublicKey,
|
||||
data: this.recoveryKey,
|
||||
version: 'x25519-xsalsa20-poly1305',
|
||||
});
|
||||
|
||||
const data = packEncryptedMessage(encryptedData);
|
||||
|
||||
return {
|
||||
// Use this later to save hexPrivateKey generated with
|
||||
// Buffer.from(JSON.stringify(encryptedData)).toString('hex')
|
||||
// As we don't use buffer with this library we should leave UI to do the rest
|
||||
encryptedData,
|
||||
// Data that could be used as an echo(data) params
|
||||
data,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt Echoer backuped note encryption account with private keys
|
||||
*/
|
||||
decryptAccountsWithWallet(wallet: Wallet, events: EchoEvents[]): NoteAccount[] {
|
||||
let { privateKey } = wallet;
|
||||
|
||||
if (privateKey.startsWith('0x')) {
|
||||
privateKey = privateKey.replace('0x', '');
|
||||
}
|
||||
|
||||
const decryptedEvents = [];
|
||||
|
||||
for (const event of events) {
|
||||
try {
|
||||
const unpackedMessage = unpackEncryptedMessage(event.encryptedAccount);
|
||||
|
||||
const recoveryKey = decrypt({
|
||||
encryptedData: unpackedMessage,
|
||||
privateKey,
|
||||
// This function intends to provide an encrypted value of recoveryKey for an on-chain Echoer backup purpose
|
||||
// Thus, the pubKey should be derived by a Wallet instance or from Web3 wallets
|
||||
// pubKey: base64 encoded 32 bytes key from https://docs.metamask.io/wallet/reference/eth_getencryptionpublickey/
|
||||
getEncryptedAccount(walletPublicKey: string) {
|
||||
const encryptedData = encrypt({
|
||||
publicKey: walletPublicKey,
|
||||
data: this.recoveryKey,
|
||||
version: 'x25519-xsalsa20-poly1305',
|
||||
});
|
||||
|
||||
decryptedEvents.push(
|
||||
new NoteAccount({
|
||||
netId: this.netId,
|
||||
blockNumber: event.blockNumber,
|
||||
recoveryKey,
|
||||
Echoer: this.Echoer,
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
// decryption may fail for invalid accounts
|
||||
continue;
|
||||
}
|
||||
const data = packEncryptedMessage(encryptedData);
|
||||
|
||||
return {
|
||||
// Use this later to save hexPrivateKey generated with
|
||||
// Buffer.from(JSON.stringify(encryptedData)).toString('hex')
|
||||
// As we don't use buffer with this library we should leave UI to do the rest
|
||||
encryptedData,
|
||||
// Data that could be used as an echo(data) params
|
||||
data,
|
||||
};
|
||||
}
|
||||
|
||||
return decryptedEvents;
|
||||
}
|
||||
/**
|
||||
* Decrypt Echoer backuped note encryption account with private keys
|
||||
*/
|
||||
static async decryptSignerNoteAccounts(signer: Signer | Wallet, events: EchoEvents[]): Promise<NoteAccount[]> {
|
||||
const signerAddress = (signer as (Signer & { address: string }) | Wallet).address;
|
||||
|
||||
decryptNotes(events: EncryptedNotesEvents[]): DecryptedNotes[] {
|
||||
const decryptedEvents = [];
|
||||
const decryptedEvents = [];
|
||||
|
||||
for (const event of events) {
|
||||
try {
|
||||
const unpackedMessage = unpackEncryptedMessage(event.encryptedNote);
|
||||
for (const event of events) {
|
||||
if (event.address !== signerAddress) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const [address, noteHex] = decrypt({
|
||||
encryptedData: unpackedMessage,
|
||||
privateKey: this.recoveryKey,
|
||||
}).split('-');
|
||||
try {
|
||||
const unpackedMessage = unpackEncryptedMessage(event.encryptedAccount);
|
||||
|
||||
decryptedEvents.push({
|
||||
blockNumber: event.blockNumber,
|
||||
address: getAddress(address),
|
||||
noteHex,
|
||||
let recoveryKey;
|
||||
|
||||
if ((signer as Wallet).privateKey) {
|
||||
const wallet = signer as Wallet;
|
||||
const privateKey =
|
||||
wallet.privateKey.slice(0, 2) === '0x' ? wallet.privateKey.slice(2) : wallet.privateKey;
|
||||
|
||||
recoveryKey = decrypt({
|
||||
encryptedData: unpackedMessage,
|
||||
privateKey,
|
||||
});
|
||||
} else {
|
||||
const { version, nonce, ephemPublicKey, ciphertext } = unpackedMessage;
|
||||
|
||||
const unpackedBuffer = bytesToHex(
|
||||
new TextEncoder().encode(
|
||||
JSON.stringify({
|
||||
version,
|
||||
nonce,
|
||||
ephemPublicKey,
|
||||
ciphertext,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
const provider = signer.provider as JsonRpcApiProvider;
|
||||
|
||||
recoveryKey = await provider.send('eth_decrypt', [unpackedBuffer, signerAddress]);
|
||||
}
|
||||
|
||||
decryptedEvents.push(
|
||||
new NoteAccount({
|
||||
blockNumber: event.blockNumber,
|
||||
recoveryKey,
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
// decryption may fail for invalid accounts
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return decryptedEvents;
|
||||
}
|
||||
|
||||
decryptNotes(events: EncryptedNotesEvents[]): DecryptedNotes[] {
|
||||
const decryptedEvents = [];
|
||||
|
||||
for (const event of events) {
|
||||
try {
|
||||
const unpackedMessage = unpackEncryptedMessage(event.encryptedNote);
|
||||
|
||||
const [address, noteHex] = decrypt({
|
||||
encryptedData: unpackedMessage,
|
||||
privateKey: this.recoveryKey,
|
||||
}).split('-');
|
||||
|
||||
decryptedEvents.push({
|
||||
blockNumber: event.blockNumber,
|
||||
address: getAddress(address),
|
||||
noteHex,
|
||||
});
|
||||
} catch {
|
||||
// decryption may fail for foreign notes
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return decryptedEvents;
|
||||
}
|
||||
|
||||
encryptNote({ address, noteHex }: NoteToEncrypt) {
|
||||
const encryptedData = encrypt({
|
||||
publicKey: this.recoveryPublicKey,
|
||||
data: `${address}-${noteHex}`,
|
||||
version: 'x25519-xsalsa20-poly1305',
|
||||
});
|
||||
} catch {
|
||||
// decryption may fail for foreign notes
|
||||
continue;
|
||||
}
|
||||
|
||||
return packEncryptedMessage(encryptedData);
|
||||
}
|
||||
|
||||
return decryptedEvents;
|
||||
}
|
||||
|
||||
encryptNote({ address, noteHex }: NoteToEncrypt) {
|
||||
const encryptedData = encrypt({
|
||||
publicKey: this.recoveryPublicKey,
|
||||
data: `${address}-${noteHex}`,
|
||||
version: 'x25519-xsalsa20-poly1305',
|
||||
});
|
||||
|
||||
return packEncryptedMessage(encryptedData);
|
||||
}
|
||||
}
|
||||
|
||||
145
src/ens.ts
Normal file
145
src/ens.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
import { namehash, EnsResolver, AbstractProvider, keccak256, Signer } from 'ethers';
|
||||
|
||||
import {
|
||||
ENSNameWrapper,
|
||||
ENSNameWrapper__factory,
|
||||
ENSRegistry,
|
||||
ENSRegistry__factory,
|
||||
ENSResolver,
|
||||
ENSResolver__factory,
|
||||
} from './typechain';
|
||||
import { bytesToHex, isHex } from './utils';
|
||||
import { NetId, NetIdType } from './networkConfig';
|
||||
|
||||
export function encodedLabelToLabelhash(label: string): string | null {
|
||||
if (label.length !== 66) return null;
|
||||
if (label.indexOf('[') !== 0) return null;
|
||||
if (label.indexOf(']') !== 65) return null;
|
||||
const hash = `0x${label.slice(1, 65)}`;
|
||||
if (!isHex(hash)) return null;
|
||||
return hash;
|
||||
}
|
||||
|
||||
export function labelhash(label: string) {
|
||||
if (!label) {
|
||||
return bytesToHex(new Uint8Array(32).fill(0));
|
||||
}
|
||||
return encodedLabelToLabelhash(label) || keccak256(new TextEncoder().encode(label));
|
||||
}
|
||||
|
||||
export function makeLabelNodeAndParent(name: string) {
|
||||
const labels = name.split('.');
|
||||
const label = labels.shift() as string;
|
||||
const parentNode = namehash(labels.join('.'));
|
||||
|
||||
return {
|
||||
label,
|
||||
labelhash: labelhash(label),
|
||||
parentNode,
|
||||
};
|
||||
}
|
||||
|
||||
// https://github.com/ensdomains/ensjs/blob/main/packages/ensjs/src/contracts/consts.ts
|
||||
export const EnsContracts: {
|
||||
[key: NetIdType]: {
|
||||
ensRegistry: string;
|
||||
ensPublicResolver: string;
|
||||
ensNameWrapper: string;
|
||||
};
|
||||
} = {
|
||||
[NetId.MAINNET]: {
|
||||
ensRegistry: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
|
||||
ensPublicResolver: '0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63',
|
||||
ensNameWrapper: '0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401',
|
||||
},
|
||||
[NetId.SEPOLIA]: {
|
||||
ensRegistry: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
|
||||
ensPublicResolver: '0x8FADE66B79cC9f707aB26799354482EB93a5B7dD',
|
||||
ensNameWrapper: '0x0635513f179D50A207757E05759CbD106d7dFcE8',
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* ENSUtils to manage on-chain registered relayers
|
||||
*/
|
||||
export class ENSUtils {
|
||||
ENSRegistry?: ENSRegistry;
|
||||
ENSResolver?: ENSResolver;
|
||||
ENSNameWrapper?: ENSNameWrapper;
|
||||
provider: AbstractProvider;
|
||||
|
||||
constructor(provider: AbstractProvider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
async getContracts() {
|
||||
const { chainId } = await this.provider.getNetwork();
|
||||
|
||||
const { ensRegistry, ensPublicResolver, ensNameWrapper } = EnsContracts[Number(chainId)];
|
||||
|
||||
this.ENSRegistry = ENSRegistry__factory.connect(ensRegistry, this.provider);
|
||||
this.ENSResolver = ENSResolver__factory.connect(ensPublicResolver, this.provider);
|
||||
this.ENSNameWrapper = ENSNameWrapper__factory.connect(ensNameWrapper, this.provider);
|
||||
}
|
||||
|
||||
async getOwner(name: string) {
|
||||
if (!this.ENSRegistry) {
|
||||
await this.getContracts();
|
||||
}
|
||||
|
||||
return (this.ENSRegistry as ENSRegistry).owner(namehash(name));
|
||||
}
|
||||
|
||||
// nameWrapper connected with wallet signer
|
||||
async unwrap(signer: Signer, name: string) {
|
||||
if (!this.ENSNameWrapper) {
|
||||
await this.getContracts();
|
||||
}
|
||||
|
||||
const owner = (signer as unknown as { address: string }).address;
|
||||
|
||||
const nameWrapper = (this.ENSNameWrapper as ENSNameWrapper).connect(signer);
|
||||
|
||||
const { labelhash } = makeLabelNodeAndParent(name);
|
||||
|
||||
return nameWrapper.unwrapETH2LD(labelhash, owner, owner);
|
||||
}
|
||||
|
||||
// https://github.com/ensdomains/ensjs/blob/main/packages/ensjs/src/functions/wallet/createSubname.ts
|
||||
async setSubnodeRecord(signer: Signer, name: string) {
|
||||
if (!this.ENSResolver) {
|
||||
await this.getContracts();
|
||||
}
|
||||
|
||||
const resolver = this.ENSResolver as ENSResolver;
|
||||
const registry = (this.ENSRegistry as ENSRegistry).connect(signer);
|
||||
|
||||
const owner = (signer as unknown as { address: string }).address;
|
||||
|
||||
const { labelhash, parentNode } = makeLabelNodeAndParent(name);
|
||||
|
||||
return registry.setSubnodeRecord(parentNode, labelhash, owner, resolver.target, BigInt(0));
|
||||
}
|
||||
|
||||
getResolver(name: string) {
|
||||
return EnsResolver.fromName(this.provider, name);
|
||||
}
|
||||
|
||||
async getText(name: string, key: string) {
|
||||
const resolver = await this.getResolver(name);
|
||||
|
||||
// Retuns null if the name doesn't exist
|
||||
if (!resolver) {
|
||||
return resolver;
|
||||
}
|
||||
|
||||
return (await resolver.getText(key)) || '';
|
||||
}
|
||||
|
||||
// https://github.com/ensdomains/ensjs/blob/main/packages/ensjs/src/functions/wallet/setTextRecord.ts
|
||||
async setText(signer: Signer, name: string, key: string, value: string) {
|
||||
const resolver = ENSResolver__factory.connect((await this.getResolver(name))?.address as string, signer);
|
||||
|
||||
return resolver.setText(namehash(name), key, value);
|
||||
}
|
||||
}
|
||||
2206
src/events/base.ts
2206
src/events/base.ts
File diff suppressed because it is too large
Load Diff
559
src/events/db.ts
Normal file
559
src/events/db.ts
Normal file
@@ -0,0 +1,559 @@
|
||||
import { downloadZip } from '../zip';
|
||||
import { IndexedDB } from '../idb';
|
||||
|
||||
import { bytesToBase64, digest } from '../utils';
|
||||
import { fetchData } from '../providers';
|
||||
import {
|
||||
BaseTornadoService,
|
||||
BaseTornadoServiceConstructor,
|
||||
BaseEchoService,
|
||||
BaseEchoServiceConstructor,
|
||||
BaseEncryptedNotesService,
|
||||
BaseEncryptedNotesServiceConstructor,
|
||||
BaseGovernanceService,
|
||||
BaseGovernanceServiceConstructor,
|
||||
BaseRegistryService,
|
||||
BaseRegistryServiceConstructor,
|
||||
BaseRevenueService,
|
||||
BaseRevenueServiceConstructor,
|
||||
CachedRelayers,
|
||||
BaseMultiTornadoService,
|
||||
BaseMultiTornadoServiceConstructor,
|
||||
} from './base';
|
||||
|
||||
import {
|
||||
BaseEvents,
|
||||
MinimalEvents,
|
||||
DepositsEvents,
|
||||
WithdrawalsEvents,
|
||||
CachedEvents,
|
||||
EchoEvents,
|
||||
EncryptedNotesEvents,
|
||||
AllGovernanceEvents,
|
||||
AllRelayerRegistryEvents,
|
||||
StakeBurnedEvents,
|
||||
MultiDepositsEvents,
|
||||
MultiWithdrawalsEvents,
|
||||
} from './types';
|
||||
|
||||
export async function saveDBEvents<T extends MinimalEvents>({
|
||||
idb,
|
||||
instanceName,
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: {
|
||||
idb: IndexedDB;
|
||||
instanceName: string;
|
||||
newEvents: T[];
|
||||
lastBlock: number;
|
||||
}) {
|
||||
try {
|
||||
const formattedEvents = newEvents.map((e) => {
|
||||
return {
|
||||
eid: `${e.transactionHash}_${e.logIndex}`,
|
||||
...e,
|
||||
};
|
||||
});
|
||||
|
||||
await idb.createMultipleTransactions({
|
||||
data: formattedEvents,
|
||||
storeName: instanceName,
|
||||
});
|
||||
|
||||
await idb.putItem({
|
||||
data: {
|
||||
blockNumber: lastBlock,
|
||||
name: instanceName,
|
||||
},
|
||||
storeName: 'lastEvents',
|
||||
});
|
||||
} catch (err) {
|
||||
console.log('Method saveDBEvents has error');
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadDBEvents<T extends MinimalEvents>({
|
||||
idb,
|
||||
instanceName,
|
||||
}: {
|
||||
idb: IndexedDB;
|
||||
instanceName: string;
|
||||
}): Promise<BaseEvents<T>> {
|
||||
try {
|
||||
const lastBlockStore = await idb.getItem<{
|
||||
blockNumber: number;
|
||||
name: string;
|
||||
}>({
|
||||
storeName: 'lastEvents',
|
||||
key: instanceName,
|
||||
});
|
||||
|
||||
if (!lastBlockStore?.blockNumber) {
|
||||
return {
|
||||
events: [],
|
||||
lastBlock: 0,
|
||||
};
|
||||
}
|
||||
|
||||
const events = (
|
||||
await idb.getAll<(T & { eid?: string })[]>({
|
||||
storeName: instanceName,
|
||||
})
|
||||
).map((e) => {
|
||||
delete e.eid;
|
||||
return e;
|
||||
});
|
||||
|
||||
return {
|
||||
events,
|
||||
lastBlock: lastBlockStore.blockNumber,
|
||||
};
|
||||
} catch (err) {
|
||||
console.log('Method loadDBEvents has error');
|
||||
console.log(err);
|
||||
|
||||
return {
|
||||
events: [],
|
||||
lastBlock: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadRemoteEvents<T extends MinimalEvents>({
|
||||
staticUrl,
|
||||
instanceName,
|
||||
deployedBlock,
|
||||
zipDigest,
|
||||
}: {
|
||||
staticUrl: string;
|
||||
instanceName: string;
|
||||
deployedBlock: number;
|
||||
zipDigest?: string;
|
||||
}): Promise<CachedEvents<T>> {
|
||||
try {
|
||||
const zipName = `${instanceName}.json`.toLowerCase();
|
||||
|
||||
const events = await downloadZip<T[]>({
|
||||
staticUrl,
|
||||
zipName,
|
||||
zipDigest,
|
||||
});
|
||||
|
||||
if (!Array.isArray(events)) {
|
||||
const errStr = `Invalid events from ${staticUrl}/${zipName}`;
|
||||
throw new Error(errStr);
|
||||
}
|
||||
|
||||
return {
|
||||
events,
|
||||
lastBlock: events[events.length - 1]?.blockNumber || deployedBlock,
|
||||
fromCache: true,
|
||||
};
|
||||
} catch (err) {
|
||||
console.log('Method loadRemoteEvents has error');
|
||||
console.log(err);
|
||||
|
||||
return {
|
||||
events: [],
|
||||
lastBlock: deployedBlock,
|
||||
fromCache: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBTornadoServiceConstructor extends BaseTornadoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBTornadoService extends BaseTornadoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
|
||||
constructor(params: DBTornadoServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<DepositsEvents | WithdrawalsEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<DepositsEvents | WithdrawalsEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<DepositsEvents | WithdrawalsEvents> & { newEvents: (DepositsEvents | WithdrawalsEvents)[] }) {
|
||||
await saveDBEvents<DepositsEvents | WithdrawalsEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBMultiTornadoServiceConstructor extends BaseMultiTornadoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBMultiTornadoService extends BaseMultiTornadoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
|
||||
constructor(params: DBMultiTornadoServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<MultiDepositsEvents | MultiWithdrawalsEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<MultiDepositsEvents | MultiWithdrawalsEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<MultiDepositsEvents | MultiWithdrawalsEvents> & {
|
||||
newEvents: (MultiDepositsEvents | MultiWithdrawalsEvents)[];
|
||||
}) {
|
||||
await saveDBEvents<MultiDepositsEvents | MultiWithdrawalsEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBEchoServiceConstructor extends BaseEchoServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBEchoService extends BaseEchoService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
|
||||
constructor(params: DBEchoServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<EchoEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<EchoEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ newEvents, lastBlock }: BaseEvents<EchoEvents> & { newEvents: EchoEvents[] }) {
|
||||
await saveDBEvents<EchoEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBEncryptedNotesServiceConstructor extends BaseEncryptedNotesServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBEncryptedNotesService extends BaseEncryptedNotesService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
|
||||
constructor(params: DBEncryptedNotesServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<EncryptedNotesEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<EncryptedNotesEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<EncryptedNotesEvents> & { newEvents: EncryptedNotesEvents[] }) {
|
||||
await saveDBEvents<EncryptedNotesEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBGovernanceServiceConstructor extends BaseGovernanceServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBGovernanceService extends BaseGovernanceService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
|
||||
constructor(params: DBGovernanceServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<AllGovernanceEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<AllGovernanceEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ newEvents, lastBlock }: BaseEvents<AllGovernanceEvents> & { newEvents: AllGovernanceEvents[] }) {
|
||||
await saveDBEvents<AllGovernanceEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export interface DBRegistryServiceConstructor extends BaseRegistryServiceConstructor {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBRegistryService extends BaseRegistryService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
relayerJsonDigest?: string;
|
||||
|
||||
constructor(params: DBRegistryServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<AllRelayerRegistryEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<AllRelayerRegistryEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({
|
||||
newEvents,
|
||||
lastBlock,
|
||||
}: BaseEvents<AllRelayerRegistryEvents> & { newEvents: AllRelayerRegistryEvents[] }) {
|
||||
await saveDBEvents<AllRelayerRegistryEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
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 {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
}
|
||||
|
||||
export class DBRevenueService extends BaseRevenueService {
|
||||
staticUrl: string;
|
||||
idb: IndexedDB;
|
||||
|
||||
zipDigest?: string;
|
||||
relayerJsonDigest?: string;
|
||||
|
||||
constructor(params: DBRevenueServiceConstructor) {
|
||||
super(params);
|
||||
|
||||
this.staticUrl = params.staticUrl;
|
||||
this.idb = params.idb;
|
||||
}
|
||||
|
||||
async getEventsFromDB() {
|
||||
return await loadDBEvents<StakeBurnedEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
});
|
||||
}
|
||||
|
||||
async getEventsFromCache() {
|
||||
return await loadRemoteEvents<StakeBurnedEvents>({
|
||||
staticUrl: this.staticUrl,
|
||||
instanceName: this.getInstanceName(),
|
||||
deployedBlock: this.deployedBlock,
|
||||
zipDigest: this.zipDigest,
|
||||
});
|
||||
}
|
||||
|
||||
async saveEvents({ newEvents, lastBlock }: BaseEvents<StakeBurnedEvents> & { newEvents: StakeBurnedEvents[] }) {
|
||||
await saveDBEvents<StakeBurnedEvents>({
|
||||
idb: this.idb,
|
||||
instanceName: this.getInstanceName(),
|
||||
newEvents,
|
||||
lastBlock,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from './types';
|
||||
export * from './base';
|
||||
export * from './db';
|
||||
|
||||
@@ -1,80 +1,140 @@
|
||||
import { RelayerParams } from '../relayerClient';
|
||||
|
||||
export interface BaseEvents<T> {
|
||||
events: T[];
|
||||
lastBlock: number | null;
|
||||
events: T[];
|
||||
lastBlock: number;
|
||||
}
|
||||
|
||||
export interface CachedEvents<T> extends BaseEvents<T> {
|
||||
fromCache: boolean;
|
||||
}
|
||||
|
||||
export interface BaseGraphEvents<T> {
|
||||
events: T[];
|
||||
lastSyncBlock: number;
|
||||
events: T[];
|
||||
lastSyncBlock: number;
|
||||
}
|
||||
|
||||
export interface MinimalEvents {
|
||||
blockNumber: number;
|
||||
logIndex: number;
|
||||
transactionHash: string;
|
||||
blockNumber: number;
|
||||
logIndex: number;
|
||||
transactionHash: string;
|
||||
}
|
||||
|
||||
export type GovernanceEvents = MinimalEvents & {
|
||||
event: string;
|
||||
};
|
||||
export interface GovernanceEvents extends MinimalEvents {
|
||||
event: string;
|
||||
}
|
||||
|
||||
export type GovernanceProposalCreatedEvents = GovernanceEvents & {
|
||||
id: number;
|
||||
proposer: string;
|
||||
target: string;
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
description: string;
|
||||
};
|
||||
export interface GovernanceProposalCreatedEvents extends GovernanceEvents {
|
||||
id: number;
|
||||
proposer: string;
|
||||
target: string;
|
||||
startTime: number;
|
||||
endTime: number;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export type GovernanceVotedEvents = GovernanceEvents & {
|
||||
proposalId: number;
|
||||
voter: string;
|
||||
support: boolean;
|
||||
votes: string;
|
||||
from: string;
|
||||
input: string;
|
||||
};
|
||||
export interface GovernanceVotedEvents extends GovernanceEvents {
|
||||
proposalId: number;
|
||||
voter: string;
|
||||
support: boolean;
|
||||
votes: string;
|
||||
from: string;
|
||||
input: string;
|
||||
}
|
||||
|
||||
export type GovernanceDelegatedEvents = GovernanceEvents & {
|
||||
account: string;
|
||||
delegateTo: string;
|
||||
};
|
||||
export interface GovernanceDelegatedEvents extends GovernanceEvents {
|
||||
account: string;
|
||||
delegateTo: string;
|
||||
}
|
||||
|
||||
export type GovernanceUndelegatedEvents = GovernanceEvents & {
|
||||
account: string;
|
||||
delegateFrom: string;
|
||||
};
|
||||
export interface GovernanceUndelegatedEvents extends GovernanceEvents {
|
||||
account: string;
|
||||
delegateFrom: string;
|
||||
}
|
||||
|
||||
export type AllGovernanceEvents =
|
||||
| GovernanceProposalCreatedEvents
|
||||
| GovernanceVotedEvents
|
||||
| GovernanceDelegatedEvents
|
||||
| GovernanceUndelegatedEvents;
|
||||
| GovernanceProposalCreatedEvents
|
||||
| GovernanceVotedEvents
|
||||
| GovernanceDelegatedEvents
|
||||
| GovernanceUndelegatedEvents;
|
||||
|
||||
export interface RelayerRegistryEvents extends MinimalEvents {
|
||||
event: string;
|
||||
}
|
||||
|
||||
export interface RelayerRegisteredEvents extends RelayerRegistryEvents, RelayerParams {
|
||||
ensHash: string;
|
||||
stakedAmount: string;
|
||||
}
|
||||
|
||||
export interface RelayerUnregisteredEvents extends RelayerRegistryEvents {
|
||||
relayerAddress: string;
|
||||
}
|
||||
|
||||
export interface WorkerRegisteredEvents extends RelayerRegistryEvents {
|
||||
relayerAddress: string;
|
||||
workerAddress: string;
|
||||
}
|
||||
|
||||
export interface WorkerUnregisteredEvents extends RelayerRegistryEvents {
|
||||
relayerAddress: string;
|
||||
workerAddress: string;
|
||||
}
|
||||
|
||||
export type AllRelayerRegistryEvents =
|
||||
| RelayerRegisteredEvents
|
||||
| RelayerUnregisteredEvents
|
||||
| WorkerRegisteredEvents
|
||||
| WorkerUnregisteredEvents;
|
||||
|
||||
export interface StakeBurnedEvents extends MinimalEvents {
|
||||
relayerAddress: string;
|
||||
amountBurned: string;
|
||||
instanceAddress: string;
|
||||
gasFee: string;
|
||||
relayerFee: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
// Deprecated type
|
||||
export type RegistersEvents = MinimalEvents & RelayerParams;
|
||||
|
||||
export type DepositsEvents = MinimalEvents & {
|
||||
commitment: string;
|
||||
leafIndex: number;
|
||||
timestamp: number;
|
||||
from: string;
|
||||
};
|
||||
export interface DepositsEvents extends MinimalEvents {
|
||||
commitment: string;
|
||||
leafIndex: number;
|
||||
timestamp: number;
|
||||
from: string;
|
||||
}
|
||||
|
||||
export type WithdrawalsEvents = MinimalEvents & {
|
||||
nullifierHash: string;
|
||||
to: string;
|
||||
fee: string;
|
||||
timestamp: number;
|
||||
};
|
||||
export interface WithdrawalsEvents extends MinimalEvents {
|
||||
nullifierHash: string;
|
||||
to: string;
|
||||
fee: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
export type EchoEvents = MinimalEvents & {
|
||||
address: string;
|
||||
encryptedAccount: string;
|
||||
};
|
||||
export interface BaseMultiTornadoEvents {
|
||||
event: string;
|
||||
instanceAddress: string;
|
||||
}
|
||||
|
||||
export type EncryptedNotesEvents = MinimalEvents & {
|
||||
encryptedNote: string;
|
||||
};
|
||||
export interface MultiDepositsEvents extends BaseMultiTornadoEvents, DepositsEvents {}
|
||||
|
||||
export interface MultiWithdrawalsEvents extends BaseMultiTornadoEvents, WithdrawalsEvents {
|
||||
relayerAddress: string;
|
||||
}
|
||||
|
||||
export interface EchoEvents extends MinimalEvents {
|
||||
address: string;
|
||||
encryptedAccount: string;
|
||||
}
|
||||
|
||||
export interface EncryptedNotesEvents extends MinimalEvents {
|
||||
encryptedNote: string;
|
||||
}
|
||||
|
||||
export interface TransferEvents extends MinimalEvents {
|
||||
from: string;
|
||||
to: string;
|
||||
value: bigint;
|
||||
}
|
||||
|
||||
217
src/fees.ts
217
src/fees.ts
@@ -1,13 +1,13 @@
|
||||
import { Transaction, parseUnits } from 'ethers';
|
||||
import type { BigNumberish, TransactionLike } from 'ethers';
|
||||
import type { BigNumberish, JsonRpcApiProvider, TransactionLike } from 'ethers';
|
||||
import { OvmGasPriceOracle } from './typechain';
|
||||
|
||||
const DUMMY_ADDRESS = '0x1111111111111111111111111111111111111111';
|
||||
|
||||
const DUMMY_NONCE = '0x1111111111111111111111111111111111111111111111111111111111111111';
|
||||
const DUMMY_NONCE = 1024;
|
||||
|
||||
const DUMMY_WITHDRAW_DATA =
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111';
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111';
|
||||
|
||||
/**
|
||||
* Example:
|
||||
@@ -15,110 +15,145 @@ const DUMMY_WITHDRAW_DATA =
|
||||
* amountInWei (0.1 ETH) * tokenDecimals (18) * tokenPriceInWei (0.0008) = 125 TOKEN
|
||||
*/
|
||||
export function convertETHToTokenAmount(
|
||||
amountInWei: BigNumberish,
|
||||
tokenPriceInWei: BigNumberish,
|
||||
tokenDecimals: number = 18,
|
||||
amountInWei: BigNumberish,
|
||||
tokenPriceInWei: BigNumberish,
|
||||
tokenDecimals: number = 18,
|
||||
): bigint {
|
||||
const tokenDecimalsMultiplier = BigInt(10 ** Number(tokenDecimals));
|
||||
return (BigInt(amountInWei) * tokenDecimalsMultiplier) / BigInt(tokenPriceInWei);
|
||||
const tokenDecimalsMultiplier = BigInt(10 ** Number(tokenDecimals));
|
||||
return (BigInt(amountInWei) * tokenDecimalsMultiplier) / BigInt(tokenPriceInWei);
|
||||
}
|
||||
|
||||
export interface RelayerFeeParams {
|
||||
gasPrice: BigNumberish;
|
||||
gasLimit?: BigNumberish;
|
||||
l1Fee?: BigNumberish;
|
||||
denomination: BigNumberish;
|
||||
ethRefund: BigNumberish;
|
||||
tokenPriceInWei: BigNumberish;
|
||||
tokenDecimals: number;
|
||||
relayerFeePercent?: number;
|
||||
isEth?: boolean;
|
||||
premiumPercent?: number;
|
||||
gasPrice: BigNumberish;
|
||||
gasLimit?: BigNumberish;
|
||||
l1Fee?: BigNumberish;
|
||||
denomination: BigNumberish;
|
||||
ethRefund: BigNumberish;
|
||||
tokenPriceInWei: BigNumberish;
|
||||
tokenDecimals: number;
|
||||
relayerFeePercent?: number;
|
||||
isEth?: boolean;
|
||||
premiumPercent?: number;
|
||||
}
|
||||
|
||||
export class TornadoFeeOracle {
|
||||
ovmGasPriceOracle?: OvmGasPriceOracle;
|
||||
provider: JsonRpcApiProvider;
|
||||
ovmGasPriceOracle?: OvmGasPriceOracle;
|
||||
|
||||
constructor(ovmGasPriceOracle?: OvmGasPriceOracle) {
|
||||
if (ovmGasPriceOracle) {
|
||||
this.ovmGasPriceOracle = ovmGasPriceOracle;
|
||||
}
|
||||
}
|
||||
constructor(provider: JsonRpcApiProvider, ovmGasPriceOracle?: OvmGasPriceOracle) {
|
||||
this.provider = provider;
|
||||
|
||||
/**
|
||||
* Calculate L1 fee for op-stack chains
|
||||
*
|
||||
* This is required since relayers would pay the full transaction fees for users
|
||||
*/
|
||||
fetchL1OptimismFee(tx?: TransactionLike): Promise<bigint> {
|
||||
if (!this.ovmGasPriceOracle) {
|
||||
return new Promise((resolve) => resolve(BigInt(0)));
|
||||
if (ovmGasPriceOracle) {
|
||||
this.ovmGasPriceOracle = ovmGasPriceOracle;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tx) {
|
||||
// this tx is only used to simulate bytes size of the encoded tx so has nothing to with the accuracy
|
||||
// inspired by the old style classic-ui calculation
|
||||
tx = {
|
||||
type: 0,
|
||||
gasLimit: 1_000_000,
|
||||
nonce: Number(DUMMY_NONCE),
|
||||
data: DUMMY_WITHDRAW_DATA,
|
||||
gasPrice: parseUnits('1', 'gwei'),
|
||||
from: DUMMY_ADDRESS,
|
||||
to: DUMMY_ADDRESS,
|
||||
};
|
||||
/**
|
||||
* Calculates Gas Price
|
||||
* We apply 50% premium of EIP-1559 network fees instead of 100% from ethers.js
|
||||
* (This should cover up to 4 full blocks which is equivalent of minute)
|
||||
* (A single block can bump 12.5% of fees, see the methodology https://hackmd.io/@tvanepps/1559-wallets)
|
||||
* (Still it is recommended to use 100% premium for sending transactions to prevent stucking it)
|
||||
*/
|
||||
async gasPrice(premium?: number) {
|
||||
const [block, getGasPrice, getPriorityFee] = await Promise.all([
|
||||
this.provider.getBlock('latest'),
|
||||
(async () => {
|
||||
try {
|
||||
return BigInt(await this.provider.send('eth_gasPrice', []));
|
||||
} catch {
|
||||
return parseUnits('1', 'gwei');
|
||||
}
|
||||
})(),
|
||||
(async () => {
|
||||
try {
|
||||
return BigInt(await this.provider.send('eth_maxPriorityFeePerGas', []));
|
||||
} catch {
|
||||
return BigInt(0);
|
||||
}
|
||||
})(),
|
||||
]);
|
||||
|
||||
return block?.baseFeePerGas
|
||||
? (block.baseFeePerGas * BigInt(10000 * (100 + (premium || 50)))) / BigInt(10000 * 100) + getPriorityFee
|
||||
: getGasPrice;
|
||||
}
|
||||
|
||||
return this.ovmGasPriceOracle.getL1Fee.staticCall(Transaction.from(tx).unsignedSerialized);
|
||||
}
|
||||
/**
|
||||
* Calculate L1 fee for op-stack chains
|
||||
*
|
||||
* This is required since relayers would pay the full transaction fees for users
|
||||
*/
|
||||
async fetchL1OptimismFee(tx?: TransactionLike): Promise<bigint> {
|
||||
if (!this.ovmGasPriceOracle) {
|
||||
return new Promise((resolve) => resolve(BigInt(0)));
|
||||
}
|
||||
|
||||
/**
|
||||
* We don't need to distinguish default refunds by tokens since most users interact with other defi protocols after withdrawal
|
||||
* So we default with 1M gas which is enough for two or three swaps
|
||||
* Using 30 gwei for default but it is recommended to supply cached gasPrice value from the UI
|
||||
*/
|
||||
defaultEthRefund(gasPrice?: BigNumberish, gasLimit?: BigNumberish): bigint {
|
||||
return (gasPrice ? BigInt(gasPrice) : parseUnits('30', 'gwei')) * BigInt(gasLimit || 1_000_000);
|
||||
}
|
||||
if (!tx) {
|
||||
// this tx is only used to simulate bytes size of the encoded tx so has nothing to with the accuracy
|
||||
// inspired by the old style classic-ui calculation
|
||||
tx = {
|
||||
type: 0,
|
||||
gasLimit: 1_000_000,
|
||||
nonce: DUMMY_NONCE,
|
||||
data: DUMMY_WITHDRAW_DATA,
|
||||
gasPrice: parseUnits('1', 'gwei'),
|
||||
to: DUMMY_ADDRESS,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates token amount for required ethRefund purchases required to calculate fees
|
||||
*/
|
||||
calculateTokenAmount(ethRefund: BigNumberish, tokenPriceInEth: BigNumberish, tokenDecimals?: number): bigint {
|
||||
return convertETHToTokenAmount(ethRefund, tokenPriceInEth, tokenDecimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: For tokens you need to check if the fees are above denomination
|
||||
* (Usually happens for small denomination pool or if the gas price is high)
|
||||
*/
|
||||
calculateRelayerFee({
|
||||
gasPrice,
|
||||
gasLimit = 600_000,
|
||||
l1Fee = 0,
|
||||
denomination,
|
||||
ethRefund = BigInt(0),
|
||||
tokenPriceInWei,
|
||||
tokenDecimals = 18,
|
||||
relayerFeePercent = 0.33,
|
||||
isEth = true,
|
||||
premiumPercent = 20,
|
||||
}: RelayerFeeParams): bigint {
|
||||
const gasCosts = BigInt(gasPrice) * BigInt(gasLimit) + BigInt(l1Fee);
|
||||
|
||||
const relayerFee = (BigInt(denomination) * BigInt(Math.floor(10000 * relayerFeePercent))) / BigInt(10000 * 100);
|
||||
|
||||
if (isEth) {
|
||||
// Add 20% premium
|
||||
return ((gasCosts + relayerFee) * BigInt(premiumPercent ? 100 + premiumPercent : 100)) / BigInt(100);
|
||||
return (
|
||||
((await this.ovmGasPriceOracle.getL1Fee.staticCall(Transaction.from(tx).unsignedSerialized)) * 12n) / 10n
|
||||
);
|
||||
}
|
||||
|
||||
const feeInEth = gasCosts + BigInt(ethRefund);
|
||||
/**
|
||||
* We don't need to distinguish default refunds by tokens since most users interact with other defi protocols after withdrawal
|
||||
* So we default with 1M gas which is enough for two or three swaps
|
||||
* Using 30 gwei for default but it is recommended to supply cached gasPrice value from the UI
|
||||
*/
|
||||
defaultEthRefund(gasPrice?: BigNumberish, gasLimit?: BigNumberish): bigint {
|
||||
return (gasPrice ? BigInt(gasPrice) : parseUnits('30', 'gwei')) * BigInt(gasLimit || 1_000_000);
|
||||
}
|
||||
|
||||
return (
|
||||
((convertETHToTokenAmount(feeInEth, tokenPriceInWei, tokenDecimals) + relayerFee) *
|
||||
BigInt(premiumPercent ? 100 + premiumPercent : 100)) /
|
||||
BigInt(100)
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Calculates token amount for required ethRefund purchases required to calculate fees
|
||||
*/
|
||||
calculateTokenAmount(ethRefund: BigNumberish, tokenPriceInEth: BigNumberish, tokenDecimals?: number): bigint {
|
||||
return convertETHToTokenAmount(ethRefund, tokenPriceInEth, tokenDecimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* Warning: For tokens you need to check if the fees are above denomination
|
||||
* (Usually happens for small denomination pool or if the gas price is high)
|
||||
*/
|
||||
calculateRelayerFee({
|
||||
gasPrice,
|
||||
gasLimit = 600_000,
|
||||
l1Fee = 0,
|
||||
denomination,
|
||||
ethRefund = BigInt(0),
|
||||
tokenPriceInWei,
|
||||
tokenDecimals = 18,
|
||||
relayerFeePercent = 0.33,
|
||||
isEth = true,
|
||||
premiumPercent = 20,
|
||||
}: RelayerFeeParams): bigint {
|
||||
const gasCosts = BigInt(gasPrice) * BigInt(gasLimit) + BigInt(l1Fee);
|
||||
|
||||
const relayerFee = (BigInt(denomination) * BigInt(Math.floor(10000 * relayerFeePercent))) / BigInt(10000 * 100);
|
||||
|
||||
if (isEth) {
|
||||
// Add 20% premium
|
||||
return ((gasCosts + relayerFee) * BigInt(premiumPercent ? 100 + premiumPercent : 100)) / BigInt(100);
|
||||
}
|
||||
|
||||
const feeInEth = gasCosts + BigInt(ethRefund);
|
||||
|
||||
return (
|
||||
((convertETHToTokenAmount(feeInEth, tokenPriceInWei, tokenDecimals) + relayerFee) *
|
||||
BigInt(premiumPercent ? 100 + premiumPercent : 100)) /
|
||||
BigInt(100)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
58
src/gaszip.ts
Normal file
58
src/gaszip.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { isAddress } from 'ethers';
|
||||
import { NetId, NetIdType } from './networkConfig';
|
||||
|
||||
// https://dev.gas.zip/gas/chain-support/inbound
|
||||
export const gasZipInbounds: { [key in NetIdType]: string } = {
|
||||
[NetId.MAINNET]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.BSC]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.POLYGON]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.OPTIMISM]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.ARBITRUM]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.BASE]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.BLAST]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.GNOSIS]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
[NetId.AVALANCHE]: '0x391E7C679d29bD940d63be94AD22A25d25b5A604',
|
||||
};
|
||||
|
||||
// https://dev.gas.zip/gas/chain-support/outbound
|
||||
export const gasZipID: { [key in NetIdType]: number } = {
|
||||
[NetId.MAINNET]: 255,
|
||||
[NetId.BSC]: 14,
|
||||
[NetId.POLYGON]: 17,
|
||||
[NetId.OPTIMISM]: 55,
|
||||
[NetId.ARBITRUM]: 57,
|
||||
[NetId.BASE]: 54,
|
||||
[NetId.BLAST]: 96,
|
||||
[NetId.GNOSIS]: 16,
|
||||
[NetId.AVALANCHE]: 15,
|
||||
[NetId.SEPOLIA]: 102,
|
||||
};
|
||||
|
||||
// https://dev.gas.zip/gas/code-examples/eoaDeposit
|
||||
export function gasZipInput(to: string, shorts: number[]): string | null {
|
||||
let data = '0x';
|
||||
if (isAddress(to)) {
|
||||
if (to.length === 42) {
|
||||
data += '02';
|
||||
data += to.slice(2);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
data += '01'; // to == sender
|
||||
}
|
||||
|
||||
for (const i in shorts) {
|
||||
data += Number(shorts[i]).toString(16).padStart(4, '0');
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
export function gasZipMinMax(ethUsd: number) {
|
||||
return {
|
||||
min: 1 / ethUsd,
|
||||
max: 50 / ethUsd,
|
||||
ethUsd,
|
||||
};
|
||||
}
|
||||
1881
src/graphql/index.ts
1881
src/graphql/index.ts
File diff suppressed because it is too large
Load Diff
8
src/hasher.ts
Normal file
8
src/hasher.ts
Normal file
File diff suppressed because one or more lines are too long
472
src/idb.ts
Normal file
472
src/idb.ts
Normal file
@@ -0,0 +1,472 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { openDB, deleteDB, OpenDBCallbacks, IDBPDatabase } from 'idb';
|
||||
import { getConfig, NetIdType } from './networkConfig';
|
||||
|
||||
export const INDEX_DB_ERROR = 'A mutation operation was attempted on a database that did not allow mutations.';
|
||||
|
||||
export interface IDBIndex {
|
||||
name: string;
|
||||
unique?: boolean;
|
||||
}
|
||||
|
||||
export interface IDBStores {
|
||||
name: string;
|
||||
keyPath?: string;
|
||||
indexes?: IDBIndex[];
|
||||
}
|
||||
|
||||
export interface IDBConstructor {
|
||||
dbName: string;
|
||||
stores?: IDBStores[];
|
||||
}
|
||||
|
||||
export class IndexedDB {
|
||||
dbExists: boolean;
|
||||
isBlocked: boolean;
|
||||
// todo: TestDBSchema on any
|
||||
options: OpenDBCallbacks<any>;
|
||||
dbName: string;
|
||||
dbVersion: number;
|
||||
db?: IDBPDatabase<any>;
|
||||
|
||||
constructor({ dbName, stores }: IDBConstructor) {
|
||||
this.dbExists = false;
|
||||
this.isBlocked = false;
|
||||
|
||||
this.options = {
|
||||
upgrade(db) {
|
||||
Object.values(db.objectStoreNames).forEach((value) => {
|
||||
db.deleteObjectStore(value);
|
||||
});
|
||||
|
||||
[{ name: 'keyval' }, ...(stores || [])].forEach(({ name, keyPath, indexes }) => {
|
||||
const store = db.createObjectStore(name, {
|
||||
keyPath,
|
||||
autoIncrement: true,
|
||||
});
|
||||
|
||||
if (Array.isArray(indexes)) {
|
||||
indexes.forEach(({ name, unique = false }) => {
|
||||
store.createIndex(name, name, { unique });
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
this.dbName = dbName;
|
||||
this.dbVersion = 36;
|
||||
}
|
||||
|
||||
async initDB() {
|
||||
try {
|
||||
if (this.dbExists || this.isBlocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.db = await openDB(this.dbName, this.dbVersion, this.options);
|
||||
this.db.addEventListener('onupgradeneeded', async () => {
|
||||
await this._removeExist();
|
||||
});
|
||||
|
||||
this.dbExists = true;
|
||||
} catch (err: any) {
|
||||
// needed for private mode firefox browser
|
||||
if (err.message.includes(INDEX_DB_ERROR)) {
|
||||
console.log('This browser does not support IndexedDB!');
|
||||
this.isBlocked = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (err.message.includes('less than the existing version')) {
|
||||
console.log(`Upgrading DB ${this.dbName} to ${this.dbVersion}`);
|
||||
await this._removeExist();
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(`Method initDB has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async _removeExist() {
|
||||
await deleteDB(this.dbName);
|
||||
this.dbExists = false;
|
||||
|
||||
await this.initDB();
|
||||
}
|
||||
|
||||
async getFromIndex<T>({
|
||||
storeName,
|
||||
indexName,
|
||||
key,
|
||||
}: {
|
||||
storeName: string;
|
||||
indexName: string;
|
||||
key?: string;
|
||||
}): Promise<T | undefined> {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
return (await this.db.getFromIndex(storeName, indexName, key)) as T;
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method getFromIndex has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getAllFromIndex<T>({
|
||||
storeName,
|
||||
indexName,
|
||||
key,
|
||||
count,
|
||||
}: {
|
||||
storeName: string;
|
||||
indexName: string;
|
||||
key?: string;
|
||||
count?: number;
|
||||
}): Promise<T> {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return [] as T;
|
||||
}
|
||||
|
||||
try {
|
||||
return (await this.db.getAllFromIndex(storeName, indexName, key, count)) as T;
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method getAllFromIndex has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getItem<T>({ storeName, key }: { storeName: string; key: string }): Promise<T | undefined> {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const store = this.db.transaction(storeName).objectStore(storeName);
|
||||
|
||||
return (await store.get(key)) as T;
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method getItem has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async addItem({ storeName, data, key = '' }: { storeName: string; data: any; key: string }) {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const tx = this.db.transaction(storeName, 'readwrite');
|
||||
const isExist = await tx.objectStore(storeName).get(key);
|
||||
|
||||
if (!isExist) {
|
||||
await tx.objectStore(storeName).add(data);
|
||||
}
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method addItem has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async putItem({ storeName, data, key }: { storeName: string; data: any; key?: string }) {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const tx = this.db.transaction(storeName, 'readwrite');
|
||||
|
||||
await tx.objectStore(storeName).put(data, key);
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method putItem has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async deleteItem({ storeName, key }: { storeName: string; key: string }) {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const tx = this.db.transaction(storeName, 'readwrite');
|
||||
|
||||
await tx.objectStore(storeName).delete(key);
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method deleteItem has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async getAll<T>({ storeName }: { storeName: string }): Promise<T> {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return [] as T;
|
||||
}
|
||||
|
||||
try {
|
||||
const tx = this.db.transaction(storeName, 'readonly');
|
||||
|
||||
return (await tx.objectStore(storeName).getAll()) as T;
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method getAll has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple key-value store inspired by idb-keyval package
|
||||
*/
|
||||
getValue<T>(key: string) {
|
||||
return this.getItem<T>({ storeName: 'keyval', key });
|
||||
}
|
||||
|
||||
setValue(key: string, data: any) {
|
||||
return this.putItem({ storeName: 'keyval', key, data });
|
||||
}
|
||||
|
||||
delValue(key: string) {
|
||||
return this.deleteItem({ storeName: 'keyval', key });
|
||||
}
|
||||
|
||||
async clearStore({ storeName, mode = 'readwrite' }: { storeName: string; mode: IDBTransactionMode }) {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const tx = this.db.transaction(storeName, mode);
|
||||
|
||||
await (tx.objectStore(storeName).clear as () => Promise<void>)();
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method clearStore has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async createTransactions({
|
||||
storeName,
|
||||
data,
|
||||
mode = 'readwrite',
|
||||
}: {
|
||||
storeName: string;
|
||||
data: any;
|
||||
mode: IDBTransactionMode;
|
||||
}) {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const tx = this.db.transaction(storeName, mode);
|
||||
|
||||
await (tx.objectStore(storeName).add as (value: any, key?: any) => Promise<any>)(data);
|
||||
await tx.done;
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method createTransactions has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
async createMultipleTransactions({
|
||||
storeName,
|
||||
data,
|
||||
index,
|
||||
mode = 'readwrite',
|
||||
}: {
|
||||
storeName: string;
|
||||
data: any[];
|
||||
index?: any;
|
||||
mode?: IDBTransactionMode;
|
||||
}) {
|
||||
await this.initDB();
|
||||
|
||||
if (!this.db) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const tx = this.db.transaction(storeName, mode);
|
||||
|
||||
for (const item of data) {
|
||||
if (item) {
|
||||
await (tx.store.put as (value: any, key?: any) => Promise<any>)({ ...item, ...index });
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
throw new Error(`Method createMultipleTransactions has error: ${err.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should check if DB is initialized well
|
||||
*/
|
||||
export async function getIndexedDB(netId?: NetIdType) {
|
||||
// key-value db for settings
|
||||
if (!netId) {
|
||||
const idb = new IndexedDB({ dbName: 'tornado-core' });
|
||||
await idb.initDB();
|
||||
return idb;
|
||||
}
|
||||
|
||||
const minimalIndexes = [
|
||||
{
|
||||
name: 'eid',
|
||||
unique: true,
|
||||
},
|
||||
];
|
||||
|
||||
const defaultState = [
|
||||
{
|
||||
name: `tornado_${netId}`,
|
||||
keyPath: 'eid',
|
||||
indexes: [...minimalIndexes],
|
||||
},
|
||||
{
|
||||
name: `echo_${netId}`,
|
||||
keyPath: 'eid',
|
||||
indexes: [
|
||||
...minimalIndexes,
|
||||
{
|
||||
name: 'address',
|
||||
unique: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: `encrypted_notes_${netId}`,
|
||||
keyPath: 'eid',
|
||||
indexes: minimalIndexes,
|
||||
},
|
||||
{
|
||||
name: 'lastEvents',
|
||||
keyPath: 'name',
|
||||
indexes: [
|
||||
{
|
||||
name: 'name',
|
||||
unique: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const { tokens, nativeCurrency, registryContract, governanceContract } = getConfig(netId);
|
||||
|
||||
const stores = [...defaultState];
|
||||
|
||||
if (registryContract) {
|
||||
stores.push({
|
||||
name: `registry_${netId}`,
|
||||
keyPath: 'ensName',
|
||||
indexes: [
|
||||
...minimalIndexes,
|
||||
{
|
||||
name: 'event',
|
||||
unique: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
stores.push({
|
||||
name: `relayers_${netId}`,
|
||||
keyPath: 'timestamp',
|
||||
indexes: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
stores.push({
|
||||
name: `revenue_${netId}`,
|
||||
keyPath: 'timestamp',
|
||||
indexes: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
if (governanceContract) {
|
||||
stores.push({
|
||||
name: `governance_${netId}`,
|
||||
keyPath: 'eid',
|
||||
indexes: [
|
||||
...minimalIndexes,
|
||||
{
|
||||
name: 'event',
|
||||
unique: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
Object.entries(tokens).forEach(([token, { instanceAddress }]) => {
|
||||
Object.keys(instanceAddress).forEach((amount) => {
|
||||
if (nativeCurrency === token) {
|
||||
stores.push(
|
||||
{
|
||||
name: `stringify_bloom_${netId}_${token}_${amount}`,
|
||||
keyPath: 'hashBloom',
|
||||
indexes: [],
|
||||
},
|
||||
{
|
||||
name: `stringify_tree_${netId}_${token}_${amount}`,
|
||||
keyPath: 'hashTree',
|
||||
indexes: [],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
stores.push(
|
||||
{
|
||||
name: `deposits_${netId}_${token}_${amount}`,
|
||||
keyPath: 'leafIndex', // the key by which it refers to the object must be in all instances of the storage
|
||||
indexes: [
|
||||
...minimalIndexes,
|
||||
{
|
||||
name: 'commitment',
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: `withdrawals_${netId}_${token}_${amount}`,
|
||||
keyPath: 'eid',
|
||||
indexes: [
|
||||
...minimalIndexes,
|
||||
{
|
||||
name: 'nullifierHash',
|
||||
unique: true,
|
||||
}, // keys on which the index is created
|
||||
],
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const idb = new IndexedDB({
|
||||
dbName: `tornado_core_${netId}`,
|
||||
stores,
|
||||
});
|
||||
|
||||
await idb.initDB();
|
||||
|
||||
return idb;
|
||||
}
|
||||
10
src/index.ts
10
src/index.ts
@@ -1,19 +1,27 @@
|
||||
export * from './events';
|
||||
export * from './graphql';
|
||||
//export * from './graphql';
|
||||
export * from './schemas';
|
||||
export * from './typechain';
|
||||
export * from './batch';
|
||||
export * from './deposits';
|
||||
export * from './encryptedNotes';
|
||||
export * from './ens';
|
||||
export * from './fees';
|
||||
export * from './gaszip';
|
||||
export * from './hasher';
|
||||
export * from './idb';
|
||||
export * from './ip';
|
||||
export * from './merkleTree';
|
||||
export * from './mimc';
|
||||
export * from './multicall';
|
||||
export * from './networkConfig';
|
||||
export * from './pedersen';
|
||||
export * from './permit';
|
||||
export * from './prices';
|
||||
export * from './providers';
|
||||
export * from './relayerClient';
|
||||
export * from './tokens';
|
||||
export * from './tovarishClient';
|
||||
export * from './utils';
|
||||
export * from './websnark';
|
||||
export * from './zip';
|
||||
|
||||
14
src/ip.ts
Normal file
14
src/ip.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { fetchData } from './providers';
|
||||
|
||||
export interface IPResult {
|
||||
ip: string;
|
||||
iso?: string;
|
||||
tor?: boolean;
|
||||
}
|
||||
|
||||
export async function fetchIp(ipEcho: string) {
|
||||
return (await fetchData(ipEcho, {
|
||||
method: 'GET',
|
||||
timeout: 30000,
|
||||
})) as IPResult;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Worker as NodeWorker } from 'worker_threads';
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from '@tornado/fixed-merkle-tree';
|
||||
import { MerkleTree, PartialMerkleTree, Element, TreeEdge } from 'fixed-merkle-tree';
|
||||
import type { Tornado } from '@tornado/contracts';
|
||||
import { isNode, toFixedHex } from './utils';
|
||||
import { mimc } from './mimc';
|
||||
@@ -7,193 +7,196 @@ import type { DepositType } from './deposits';
|
||||
import type { DepositsEvents } from './events';
|
||||
import type { NetIdType } from './networkConfig';
|
||||
|
||||
export type MerkleTreeConstructor = DepositType & {
|
||||
Tornado: Tornado;
|
||||
commitmentHex?: string;
|
||||
merkleTreeHeight?: number;
|
||||
emptyElement?: string;
|
||||
merkleWorkerPath?: string;
|
||||
};
|
||||
export interface MerkleTreeConstructor extends DepositType {
|
||||
Tornado: Tornado;
|
||||
commitmentHex?: string;
|
||||
merkleTreeHeight?: number;
|
||||
emptyElement?: string;
|
||||
merkleWorkerPath?: string;
|
||||
}
|
||||
|
||||
export class MerkleTreeService {
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
Tornado: Tornado;
|
||||
commitmentHex?: string;
|
||||
instanceName: string;
|
||||
currency: string;
|
||||
amount: string;
|
||||
netId: NetIdType;
|
||||
Tornado: Tornado;
|
||||
commitmentHex?: string;
|
||||
instanceName: string;
|
||||
|
||||
merkleTreeHeight: number;
|
||||
emptyElement: string;
|
||||
merkleTreeHeight: number;
|
||||
emptyElement: string;
|
||||
|
||||
merkleWorkerPath?: string;
|
||||
merkleWorkerPath?: string;
|
||||
|
||||
constructor({
|
||||
netId,
|
||||
amount,
|
||||
currency,
|
||||
Tornado,
|
||||
commitmentHex,
|
||||
merkleTreeHeight = 20,
|
||||
emptyElement = '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||
merkleWorkerPath,
|
||||
}: MerkleTreeConstructor) {
|
||||
const instanceName = `${netId}_${currency}_${amount}`;
|
||||
constructor({
|
||||
netId,
|
||||
amount,
|
||||
currency,
|
||||
Tornado,
|
||||
commitmentHex,
|
||||
merkleTreeHeight = 20,
|
||||
emptyElement = '21663839004416932945382355908790599225266501822907911457504978515578255421292',
|
||||
merkleWorkerPath,
|
||||
}: MerkleTreeConstructor) {
|
||||
const instanceName = `${netId}_${currency}_${amount}`;
|
||||
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
this.netId = Number(netId);
|
||||
this.currency = currency;
|
||||
this.amount = amount;
|
||||
this.netId = Number(netId);
|
||||
|
||||
this.Tornado = Tornado;
|
||||
this.instanceName = instanceName;
|
||||
this.commitmentHex = commitmentHex;
|
||||
this.Tornado = Tornado;
|
||||
this.instanceName = instanceName;
|
||||
this.commitmentHex = commitmentHex;
|
||||
|
||||
this.merkleTreeHeight = merkleTreeHeight;
|
||||
this.emptyElement = emptyElement;
|
||||
this.merkleWorkerPath = merkleWorkerPath;
|
||||
}
|
||||
this.merkleTreeHeight = merkleTreeHeight;
|
||||
this.emptyElement = emptyElement;
|
||||
this.merkleWorkerPath = merkleWorkerPath;
|
||||
}
|
||||
|
||||
async createTree(events: Element[]) {
|
||||
const { hash: hashFunction } = await mimc.getHash();
|
||||
async createTree(events: Element[]) {
|
||||
const { hash: hashFunction } = await mimc.getHash();
|
||||
|
||||
if (this.merkleWorkerPath) {
|
||||
console.log('Using merkleWorker\n');
|
||||
if (this.merkleWorkerPath) {
|
||||
console.log('Using merkleWorker\n');
|
||||
|
||||
try {
|
||||
if (isNode) {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
const worker = new NodeWorker(this.merkleWorkerPath as string, {
|
||||
workerData: {
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
elements: events,
|
||||
zeroElement: this.emptyElement,
|
||||
},
|
||||
});
|
||||
worker.on('message', resolve);
|
||||
worker.on('error', reject);
|
||||
worker.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Worker stopped with exit code ${code}`));
|
||||
}
|
||||
});
|
||||
}) as Promise<string>;
|
||||
try {
|
||||
if (isNode) {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
const worker = new NodeWorker(this.merkleWorkerPath as string, {
|
||||
workerData: {
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
elements: events,
|
||||
zeroElement: this.emptyElement,
|
||||
},
|
||||
});
|
||||
worker.on('message', resolve);
|
||||
worker.on('error', reject);
|
||||
worker.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Worker stopped with exit code ${code}`));
|
||||
}
|
||||
});
|
||||
}) as Promise<string>;
|
||||
|
||||
return MerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
} else {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const worker = new (Worker as any)(this.merkleWorkerPath);
|
||||
return MerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
} else {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const worker = new (Worker as any)(this.merkleWorkerPath);
|
||||
|
||||
worker.onmessage = (e: { data: string }) => {
|
||||
resolve(e.data);
|
||||
};
|
||||
worker.onmessage = (e: { data: string }) => {
|
||||
resolve(e.data);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
worker.onerror = (e: any) => {
|
||||
reject(e);
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
worker.onerror = (e: any) => {
|
||||
reject(e);
|
||||
};
|
||||
|
||||
worker.postMessage({
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
elements: events,
|
||||
zeroElement: this.emptyElement,
|
||||
});
|
||||
}) as Promise<string>;
|
||||
worker.postMessage({
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
elements: events,
|
||||
zeroElement: this.emptyElement,
|
||||
});
|
||||
}) as Promise<string>;
|
||||
|
||||
return MerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
return MerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('merkleWorker failed, falling back to synchronous merkle tree');
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('merkleWorker failed, falling back to synchronous merkle tree');
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
return new MerkleTree(this.merkleTreeHeight, events, {
|
||||
zeroElement: this.emptyElement,
|
||||
hashFunction,
|
||||
});
|
||||
}
|
||||
|
||||
return new MerkleTree(this.merkleTreeHeight, events, {
|
||||
zeroElement: this.emptyElement,
|
||||
hashFunction,
|
||||
});
|
||||
}
|
||||
async createPartialTree({ edge, elements }: { edge: TreeEdge; elements: Element[] }) {
|
||||
const { hash: hashFunction } = await mimc.getHash();
|
||||
|
||||
async createPartialTree({ edge, elements }: { edge: TreeEdge; elements: Element[] }) {
|
||||
const { hash: hashFunction } = await mimc.getHash();
|
||||
if (this.merkleWorkerPath) {
|
||||
console.log('Using merkleWorker\n');
|
||||
|
||||
if (this.merkleWorkerPath) {
|
||||
console.log('Using merkleWorker\n');
|
||||
try {
|
||||
if (isNode) {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
const worker = new NodeWorker(this.merkleWorkerPath as string, {
|
||||
workerData: {
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
edge,
|
||||
elements,
|
||||
zeroElement: this.emptyElement,
|
||||
},
|
||||
});
|
||||
worker.on('message', resolve);
|
||||
worker.on('error', reject);
|
||||
worker.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Worker stopped with exit code ${code}`));
|
||||
}
|
||||
});
|
||||
}) as Promise<string>;
|
||||
|
||||
try {
|
||||
if (isNode) {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
const worker = new NodeWorker(this.merkleWorkerPath as string, {
|
||||
workerData: {
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
edge,
|
||||
elements,
|
||||
zeroElement: this.emptyElement,
|
||||
},
|
||||
});
|
||||
worker.on('message', resolve);
|
||||
worker.on('error', reject);
|
||||
worker.on('exit', (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Worker stopped with exit code ${code}`));
|
||||
}
|
||||
});
|
||||
}) as Promise<string>;
|
||||
return PartialMerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
} else {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const worker = new (Worker as any)(this.merkleWorkerPath);
|
||||
|
||||
return PartialMerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
} else {
|
||||
const merkleWorkerPromise = new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const worker = new (Worker as any)(this.merkleWorkerPath);
|
||||
worker.onmessage = (e: { data: string }) => {
|
||||
resolve(e.data);
|
||||
};
|
||||
|
||||
worker.onmessage = (e: { data: string }) => {
|
||||
resolve(e.data);
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
worker.onerror = (e: any) => {
|
||||
reject(e);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
worker.onerror = (e: any) => {
|
||||
reject(e);
|
||||
};
|
||||
worker.postMessage({
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
edge,
|
||||
elements,
|
||||
zeroElement: this.emptyElement,
|
||||
});
|
||||
}) as Promise<string>;
|
||||
|
||||
worker.postMessage({
|
||||
merkleTreeHeight: this.merkleTreeHeight,
|
||||
edge,
|
||||
elements,
|
||||
zeroElement: this.emptyElement,
|
||||
});
|
||||
}) as Promise<string>;
|
||||
|
||||
return PartialMerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
return PartialMerkleTree.deserialize(JSON.parse(await merkleWorkerPromise), hashFunction);
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('merkleWorker failed, falling back to synchronous merkle tree');
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('merkleWorker failed, falling back to synchronous merkle tree');
|
||||
console.log(err);
|
||||
}
|
||||
|
||||
return new PartialMerkleTree(this.merkleTreeHeight, edge, elements, {
|
||||
zeroElement: this.emptyElement,
|
||||
hashFunction,
|
||||
});
|
||||
}
|
||||
|
||||
return new PartialMerkleTree(this.merkleTreeHeight, edge, elements, {
|
||||
zeroElement: this.emptyElement,
|
||||
hashFunction,
|
||||
});
|
||||
}
|
||||
async verifyTree(events: DepositsEvents[]) {
|
||||
console.log(
|
||||
`\nCreating deposit tree for ${this.netId} ${this.amount} ${this.currency.toUpperCase()} would take a while\n`,
|
||||
);
|
||||
|
||||
async verifyTree(events: DepositsEvents[]) {
|
||||
console.log(
|
||||
`\nCreating deposit tree for ${this.netId} ${this.amount} ${this.currency.toUpperCase()} would take a while\n`,
|
||||
);
|
||||
const timeStart = Date.now();
|
||||
|
||||
console.time('Created tree in');
|
||||
const tree = await this.createTree(events.map(({ commitment }) => commitment));
|
||||
console.timeEnd('Created tree in');
|
||||
console.log('');
|
||||
const tree = await this.createTree(events.map(({ commitment }) => commitment));
|
||||
|
||||
const isKnownRoot = await this.Tornado.isKnownRoot(toFixedHex(BigInt(tree.root)));
|
||||
const isKnownRoot = await this.Tornado.isKnownRoot(toFixedHex(BigInt(tree.root)));
|
||||
|
||||
if (!isKnownRoot) {
|
||||
const errMsg = `Deposit Event ${this.netId} ${this.amount} ${this.currency} is invalid`;
|
||||
throw new Error(errMsg);
|
||||
if (!isKnownRoot) {
|
||||
const errMsg = `Deposit Event ${this.netId} ${this.amount} ${this.currency} is invalid`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
console.log(
|
||||
`\nCreated ${this.netId} ${this.amount} ${this.currency.toUpperCase()} tree in ${Date.now() - timeStart}ms\n`,
|
||||
);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
return tree;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,70 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import workerThreads from 'worker_threads';
|
||||
import { MerkleTree, Element, TreeEdge, PartialMerkleTree } from '@tornado/fixed-merkle-tree';
|
||||
import { MerkleTree, Element, TreeEdge, PartialMerkleTree } from 'fixed-merkle-tree';
|
||||
import { mimc } from './mimc';
|
||||
import { isNode } from './utils';
|
||||
|
||||
interface WorkData {
|
||||
merkleTreeHeight: number;
|
||||
edge?: TreeEdge;
|
||||
elements: Element[];
|
||||
zeroElement: string;
|
||||
merkleTreeHeight: number;
|
||||
edge?: TreeEdge;
|
||||
elements: Element[];
|
||||
zeroElement: string;
|
||||
}
|
||||
|
||||
async function nodePostWork() {
|
||||
const { hash: hashFunction } = await mimc.getHash();
|
||||
const { merkleTreeHeight, edge, elements, zeroElement } = workerThreads.workerData as WorkData;
|
||||
|
||||
if (edge) {
|
||||
const merkleTree = new PartialMerkleTree(merkleTreeHeight, edge, elements, {
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
});
|
||||
|
||||
(workerThreads.parentPort as workerThreads.MessagePort).postMessage(merkleTree.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
const merkleTree = new MerkleTree(merkleTreeHeight, elements, {
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
});
|
||||
|
||||
(workerThreads.parentPort as workerThreads.MessagePort).postMessage(merkleTree.toString());
|
||||
}
|
||||
|
||||
if (isNode && workerThreads) {
|
||||
nodePostWork();
|
||||
} else if (!isNode && typeof addEventListener === 'function' && typeof postMessage === 'function') {
|
||||
addEventListener('message', async (e: any) => {
|
||||
let data;
|
||||
|
||||
if (e.data) {
|
||||
data = e.data;
|
||||
} else {
|
||||
data = e;
|
||||
}
|
||||
|
||||
const { hash: hashFunction } = await mimc.getHash();
|
||||
const { merkleTreeHeight, edge, elements, zeroElement } = data as WorkData;
|
||||
const { merkleTreeHeight, edge, elements, zeroElement } = workerThreads.workerData as WorkData;
|
||||
|
||||
if (edge) {
|
||||
const merkleTree = new PartialMerkleTree(merkleTreeHeight, edge, elements, {
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
});
|
||||
const merkleTree = new PartialMerkleTree(merkleTreeHeight, edge, elements, {
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
});
|
||||
|
||||
postMessage(merkleTree.toString());
|
||||
return;
|
||||
(workerThreads.parentPort as workerThreads.MessagePort).postMessage(merkleTree.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
const merkleTree = new MerkleTree(merkleTreeHeight, elements, {
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
});
|
||||
|
||||
postMessage(merkleTree.toString());
|
||||
});
|
||||
} else {
|
||||
throw new Error('This browser / environment does not support workers!');
|
||||
(workerThreads.parentPort as workerThreads.MessagePort).postMessage(merkleTree.toString());
|
||||
}
|
||||
|
||||
if (isNode && workerThreads) {
|
||||
nodePostWork();
|
||||
} else if (!isNode && typeof addEventListener === 'function' && typeof postMessage === 'function') {
|
||||
addEventListener('message', async (e: any) => {
|
||||
let data;
|
||||
|
||||
if (e.data) {
|
||||
data = e.data;
|
||||
} else {
|
||||
data = e;
|
||||
}
|
||||
|
||||
const { hash: hashFunction } = await mimc.getHash();
|
||||
const { merkleTreeHeight, edge, elements, zeroElement } = data as WorkData;
|
||||
|
||||
if (edge) {
|
||||
const merkleTree = new PartialMerkleTree(merkleTreeHeight, edge, elements, {
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
});
|
||||
|
||||
postMessage(merkleTree.toString());
|
||||
return;
|
||||
}
|
||||
|
||||
const merkleTree = new MerkleTree(merkleTreeHeight, elements, {
|
||||
zeroElement,
|
||||
hashFunction,
|
||||
});
|
||||
|
||||
postMessage(merkleTree.toString());
|
||||
});
|
||||
} else {
|
||||
throw new Error('This browser / environment does not support workers!');
|
||||
}
|
||||
|
||||
36
src/mimc.ts
36
src/mimc.ts
@@ -1,28 +1,28 @@
|
||||
import { MimcSponge, buildMimcSponge } from 'circomlibjs';
|
||||
import type { Element, HashFunction } from '@tornado/fixed-merkle-tree';
|
||||
import type { Element, HashFunction } from 'fixed-merkle-tree';
|
||||
|
||||
export class Mimc {
|
||||
sponge?: MimcSponge;
|
||||
hash?: HashFunction<Element>;
|
||||
mimcPromise: Promise<void>;
|
||||
sponge?: MimcSponge;
|
||||
hash?: HashFunction<Element>;
|
||||
mimcPromise: Promise<void>;
|
||||
|
||||
constructor() {
|
||||
this.mimcPromise = this.initMimc();
|
||||
}
|
||||
constructor() {
|
||||
this.mimcPromise = this.initMimc();
|
||||
}
|
||||
|
||||
async initMimc() {
|
||||
this.sponge = await buildMimcSponge();
|
||||
this.hash = (left, right) => this.sponge?.F.toString(this.sponge?.multiHash([BigInt(left), BigInt(right)]));
|
||||
}
|
||||
async initMimc() {
|
||||
this.sponge = await buildMimcSponge();
|
||||
this.hash = (left, right) => this.sponge?.F.toString(this.sponge?.multiHash([BigInt(left), BigInt(right)]));
|
||||
}
|
||||
|
||||
async getHash() {
|
||||
await this.mimcPromise;
|
||||
async getHash() {
|
||||
await this.mimcPromise;
|
||||
|
||||
return {
|
||||
sponge: this.sponge,
|
||||
hash: this.hash,
|
||||
};
|
||||
}
|
||||
return {
|
||||
sponge: this.sponge,
|
||||
hash: this.hash,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const mimc = new Mimc();
|
||||
|
||||
@@ -2,36 +2,36 @@ import { BaseContract, Interface } from 'ethers';
|
||||
import { Multicall } from './typechain';
|
||||
|
||||
export interface Call3 {
|
||||
contract?: BaseContract;
|
||||
address?: string;
|
||||
interface?: Interface;
|
||||
name: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
params?: any[];
|
||||
allowFailure?: boolean;
|
||||
contract?: BaseContract;
|
||||
address?: string;
|
||||
interface?: Interface;
|
||||
name: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
params?: any[];
|
||||
allowFailure?: boolean;
|
||||
}
|
||||
|
||||
export async function multicall(Multicall: Multicall, calls: Call3[]) {
|
||||
const calldata = calls.map((call) => {
|
||||
const target = (call.contract?.target || call.address) as string;
|
||||
const callInterface = (call.contract?.interface || call.interface) as Interface;
|
||||
const calldata = calls.map((call) => {
|
||||
const target = (call.contract?.target || call.address) as string;
|
||||
const callInterface = (call.contract?.interface || call.interface) as Interface;
|
||||
|
||||
return {
|
||||
target,
|
||||
callData: callInterface.encodeFunctionData(call.name, call.params),
|
||||
allowFailure: call.allowFailure ?? false,
|
||||
};
|
||||
});
|
||||
return {
|
||||
target,
|
||||
callData: callInterface.encodeFunctionData(call.name, call.params),
|
||||
allowFailure: call.allowFailure ?? false,
|
||||
};
|
||||
});
|
||||
|
||||
const returnData = await Multicall.aggregate3.staticCall(calldata);
|
||||
const returnData = await Multicall.aggregate3.staticCall(calldata);
|
||||
|
||||
const res = returnData.map((call, i) => {
|
||||
const callInterface = (calls[i].contract?.interface || calls[i].interface) as Interface;
|
||||
const [result, data] = call;
|
||||
const decodeResult =
|
||||
result && data && data !== '0x' ? callInterface.decodeFunctionResult(calls[i].name, data) : null;
|
||||
return !decodeResult ? null : decodeResult.length === 1 ? decodeResult[0] : decodeResult;
|
||||
});
|
||||
const res = returnData.map((call, i) => {
|
||||
const callInterface = (calls[i].contract?.interface || calls[i].interface) as Interface;
|
||||
const [result, data] = call;
|
||||
const decodeResult =
|
||||
result && data && data !== '0x' ? callInterface.decodeFunctionResult(calls[i].name, data) : null;
|
||||
return !decodeResult ? null : decodeResult.length === 1 ? decodeResult[0] : decodeResult;
|
||||
});
|
||||
|
||||
return res;
|
||||
return res;
|
||||
}
|
||||
|
||||
1560
src/networkConfig.ts
1560
src/networkConfig.ts
File diff suppressed because it is too large
Load Diff
@@ -1,32 +1,32 @@
|
||||
import { BabyJub, PedersenHash, Point, buildPedersenHash } from 'circomlibjs';
|
||||
|
||||
export class Pedersen {
|
||||
pedersenHash?: PedersenHash;
|
||||
babyJub?: BabyJub;
|
||||
pedersenPromise: Promise<void>;
|
||||
pedersenHash?: PedersenHash;
|
||||
babyJub?: BabyJub;
|
||||
pedersenPromise: Promise<void>;
|
||||
|
||||
constructor() {
|
||||
this.pedersenPromise = this.initPedersen();
|
||||
}
|
||||
constructor() {
|
||||
this.pedersenPromise = this.initPedersen();
|
||||
}
|
||||
|
||||
async initPedersen() {
|
||||
this.pedersenHash = await buildPedersenHash();
|
||||
this.babyJub = this.pedersenHash.babyJub;
|
||||
}
|
||||
async initPedersen() {
|
||||
this.pedersenHash = await buildPedersenHash();
|
||||
this.babyJub = this.pedersenHash.babyJub;
|
||||
}
|
||||
|
||||
async unpackPoint(buffer: Uint8Array) {
|
||||
await this.pedersenPromise;
|
||||
return this.babyJub?.unpackPoint(this.pedersenHash?.hash(buffer) as Uint8Array);
|
||||
}
|
||||
async unpackPoint(buffer: Uint8Array) {
|
||||
await this.pedersenPromise;
|
||||
return this.babyJub?.unpackPoint(this.pedersenHash?.hash(buffer) as Uint8Array);
|
||||
}
|
||||
|
||||
toStringBuffer(buffer: Uint8Array): string {
|
||||
return this.babyJub?.F.toString(buffer);
|
||||
}
|
||||
toStringBuffer(buffer: Uint8Array): string {
|
||||
return this.babyJub?.F.toString(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
export const pedersen = new Pedersen();
|
||||
|
||||
export async function buffPedersenHash(buffer: Uint8Array): Promise<string> {
|
||||
const [hash] = (await pedersen.unpackPoint(buffer)) as Point;
|
||||
return pedersen.toStringBuffer(hash);
|
||||
const [hash] = (await pedersen.unpackPoint(buffer)) as Point;
|
||||
return pedersen.toStringBuffer(hash);
|
||||
}
|
||||
|
||||
234
src/permit.ts
Normal file
234
src/permit.ts
Normal file
@@ -0,0 +1,234 @@
|
||||
import { ERC20Permit, ERC20Mock, TORN } from '@tornado/contracts';
|
||||
import { MaxUint256, Provider, Signature, Signer, TypedDataField } from 'ethers';
|
||||
|
||||
export interface PermitValue {
|
||||
spender: string;
|
||||
value: bigint;
|
||||
nonce?: bigint;
|
||||
deadline?: bigint;
|
||||
}
|
||||
|
||||
export interface PermitCommitments {
|
||||
denomination: bigint;
|
||||
commitments: string[];
|
||||
nonce?: bigint;
|
||||
deadline?: bigint;
|
||||
}
|
||||
|
||||
export const permit2Address = '0x000000000022D473030F116dDEE9F6B43aC78BA3';
|
||||
|
||||
/**
|
||||
* From @uniswap/permit2-sdk ported for ethers.js v6
|
||||
*/
|
||||
export interface Witness {
|
||||
witnessTypeName: string;
|
||||
witnessType: {
|
||||
[key: string]: TypedDataField[];
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
witness: any;
|
||||
}
|
||||
|
||||
export async function getPermitSignature({
|
||||
Token,
|
||||
signer,
|
||||
spender,
|
||||
value,
|
||||
nonce,
|
||||
deadline,
|
||||
}: PermitValue & {
|
||||
Token: ERC20Permit | ERC20Mock | TORN;
|
||||
signer?: Signer;
|
||||
}) {
|
||||
const sigSigner = (signer || Token.runner) as Signer & { address: string };
|
||||
const provider = sigSigner.provider as Provider;
|
||||
|
||||
const [name, lastNonce, { chainId }] = await Promise.all([
|
||||
Token.name(),
|
||||
Token.nonces(sigSigner.address),
|
||||
provider.getNetwork(),
|
||||
]);
|
||||
|
||||
const DOMAIN_SEPARATOR = {
|
||||
name,
|
||||
version: '1',
|
||||
chainId,
|
||||
verifyingContract: Token.target as string,
|
||||
};
|
||||
|
||||
const PERMIT_TYPE = {
|
||||
Permit: [
|
||||
{ name: 'owner', type: 'address' },
|
||||
{ name: 'spender', type: 'address' },
|
||||
{ name: 'value', type: 'uint256' },
|
||||
{ name: 'nonce', type: 'uint256' },
|
||||
{ name: 'deadline', type: 'uint256' },
|
||||
],
|
||||
};
|
||||
|
||||
return Signature.from(
|
||||
await sigSigner.signTypedData(DOMAIN_SEPARATOR, PERMIT_TYPE, {
|
||||
owner: sigSigner.address,
|
||||
spender,
|
||||
value,
|
||||
nonce: nonce || lastNonce,
|
||||
deadline: deadline || MaxUint256,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
export async function getPermitCommitmentsSignature({
|
||||
PermitTornado,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
}: PermitCommitments & {
|
||||
PermitTornado: PermitTornado;
|
||||
Token: ERC20Permit | ERC20Mock | TORN;
|
||||
signer?: Signer;
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(['bytes32[]'], [commitments]);
|
||||
|
||||
return await getPermitSignature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado.target as string,
|
||||
value,
|
||||
nonce,
|
||||
deadline: BigInt(commitmentsHash),
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender,
|
||||
value: amount,
|
||||
nonce,
|
||||
deadline,
|
||||
witness,
|
||||
}: PermitValue & {
|
||||
Token: BaseContract;
|
||||
signer?: Signer;
|
||||
witness?: Witness;
|
||||
}) {
|
||||
const sigSigner = (signer || Token.runner) as Signer & { address: string };
|
||||
const provider = sigSigner.provider as Provider;
|
||||
|
||||
const domain = {
|
||||
name: 'Permit2',
|
||||
chainId: (await provider.getNetwork()).chainId,
|
||||
verifyingContract: permit2Address,
|
||||
};
|
||||
|
||||
const types: {
|
||||
[key: string]: TypedDataField[];
|
||||
} = !witness
|
||||
? {
|
||||
PermitTransferFrom: [
|
||||
{ name: 'permitted', type: 'TokenPermissions' },
|
||||
{ name: 'spender', type: 'address' },
|
||||
{ name: 'nonce', type: 'uint256' },
|
||||
{ name: 'deadline', type: 'uint256' },
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: 'token', type: 'address' },
|
||||
{ name: 'amount', type: 'uint256' },
|
||||
],
|
||||
}
|
||||
: {
|
||||
PermitWitnessTransferFrom: [
|
||||
{ name: 'permitted', type: 'TokenPermissions' },
|
||||
{ name: 'spender', type: 'address' },
|
||||
{ name: 'nonce', type: 'uint256' },
|
||||
{ name: 'deadline', type: 'uint256' },
|
||||
{ name: 'witness', type: witness.witnessTypeName },
|
||||
],
|
||||
TokenPermissions: [
|
||||
{ name: 'token', type: 'address' },
|
||||
{ name: 'amount', type: 'uint256' },
|
||||
],
|
||||
...witness.witnessType,
|
||||
};
|
||||
|
||||
const values: {
|
||||
permitted: {
|
||||
token: string;
|
||||
amount: bigint;
|
||||
};
|
||||
spender: string;
|
||||
nonce: bigint;
|
||||
deadline: bigint;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
witness?: any;
|
||||
} = {
|
||||
permitted: {
|
||||
token: Token.target as string,
|
||||
amount,
|
||||
},
|
||||
spender,
|
||||
// Sorted nonce are not required for Permit2
|
||||
nonce: nonce || rBigInt(16),
|
||||
deadline: deadline || MaxUint256,
|
||||
};
|
||||
|
||||
if (witness) {
|
||||
values.witness = witness.witness;
|
||||
}
|
||||
|
||||
const hash = new TypedDataEncoder(types).hash(values);
|
||||
|
||||
const signature = Signature.from(await sigSigner.signTypedData(domain, types, values));
|
||||
|
||||
return {
|
||||
domain,
|
||||
types,
|
||||
values,
|
||||
hash,
|
||||
signature,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getPermit2CommitmentsSignature({
|
||||
PermitTornado,
|
||||
Token,
|
||||
signer,
|
||||
denomination,
|
||||
commitments,
|
||||
nonce,
|
||||
deadline,
|
||||
}: PermitCommitments & {
|
||||
PermitTornado: PermitTornado;
|
||||
Token: BaseContract;
|
||||
signer?: Signer;
|
||||
}) {
|
||||
const value = BigInt(commitments.length) * denomination;
|
||||
const commitmentsHash = solidityPackedKeccak256(['bytes32[]'], [commitments]);
|
||||
|
||||
return await getPermit2Signature({
|
||||
Token,
|
||||
signer,
|
||||
spender: PermitTornado.target as string,
|
||||
value,
|
||||
nonce,
|
||||
deadline,
|
||||
witness: {
|
||||
witnessTypeName: 'PermitCommitments',
|
||||
witnessType: {
|
||||
PermitCommitments: [
|
||||
{ name: 'instance', type: 'address' },
|
||||
{ name: 'commitmentsHash', type: 'bytes32' },
|
||||
],
|
||||
},
|
||||
witness: {
|
||||
instance: PermitTornado.target,
|
||||
commitmentsHash,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
**/
|
||||
127
src/prices.ts
127
src/prices.ts
@@ -1,40 +1,103 @@
|
||||
import { parseEther, type Provider } from 'ethers';
|
||||
import type { OffchainOracle, Multicall } from './typechain';
|
||||
import { multicall } from './multicall';
|
||||
import { formatEther, parseEther, type Provider } from 'ethers';
|
||||
import { ERC20__factory, OffchainOracle, Multicall } from './typechain';
|
||||
import { multicall, Call3 } from './multicall';
|
||||
|
||||
export class TokenPriceOracle {
|
||||
oracle?: OffchainOracle;
|
||||
multicall: Multicall;
|
||||
provider: Provider;
|
||||
oracle?: OffchainOracle;
|
||||
multicall: Multicall;
|
||||
provider: Provider;
|
||||
|
||||
constructor(provider: Provider, multicall: Multicall, oracle?: OffchainOracle) {
|
||||
this.provider = provider;
|
||||
this.multicall = multicall;
|
||||
this.oracle = oracle;
|
||||
}
|
||||
fallbackPrice: bigint;
|
||||
|
||||
async fetchPrices(
|
||||
tokens: {
|
||||
tokenAddress: string;
|
||||
decimals: number;
|
||||
}[],
|
||||
): Promise<bigint[]> {
|
||||
// setup mock price for testnets
|
||||
if (!this.oracle) {
|
||||
return new Promise((resolve) => resolve(tokens.map(() => parseEther('0.0001'))));
|
||||
constructor(provider: Provider, multicall: Multicall, oracle?: OffchainOracle) {
|
||||
this.provider = provider;
|
||||
this.multicall = multicall;
|
||||
this.oracle = oracle;
|
||||
this.fallbackPrice = parseEther('0.0001');
|
||||
}
|
||||
|
||||
const prices = (await multicall(
|
||||
this.multicall,
|
||||
tokens.map(({ tokenAddress }) => ({
|
||||
contract: this.oracle,
|
||||
name: 'getRateToEth',
|
||||
params: [tokenAddress, true],
|
||||
})),
|
||||
)) as bigint[];
|
||||
buildCalls(
|
||||
tokens: {
|
||||
tokenAddress: string;
|
||||
decimals: number;
|
||||
}[],
|
||||
): Call3[] {
|
||||
return tokens.map(({ tokenAddress }) => ({
|
||||
contract: this.oracle,
|
||||
name: 'getRateToEth',
|
||||
params: [tokenAddress, true],
|
||||
allowFailure: true,
|
||||
}));
|
||||
}
|
||||
|
||||
return prices.map((price, index) => {
|
||||
return (price * BigInt(10 ** tokens[index].decimals)) / BigInt(10 ** 18);
|
||||
});
|
||||
}
|
||||
buildStable(stablecoinAddress: string): Call3[] {
|
||||
const stablecoin = ERC20__factory.connect(stablecoinAddress, this.provider);
|
||||
|
||||
return [
|
||||
{
|
||||
contract: stablecoin,
|
||||
name: 'decimals',
|
||||
},
|
||||
{
|
||||
contract: this.oracle,
|
||||
name: 'getRateToEth',
|
||||
params: [stablecoin.target, true],
|
||||
allowFailure: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
async fetchPrice(tokenAddress: string, decimals: number): Promise<bigint> {
|
||||
// setup mock price for testnets
|
||||
if (!this.oracle) {
|
||||
return new Promise((resolve) => resolve(this.fallbackPrice));
|
||||
}
|
||||
|
||||
try {
|
||||
const price = await this.oracle.getRateToEth(tokenAddress, true);
|
||||
|
||||
return (price * BigInt(10 ** decimals)) / BigInt(10 ** 18);
|
||||
} catch (err) {
|
||||
console.log(
|
||||
`Failed to fetch oracle price for ${tokenAddress}, will use fallback price ${this.fallbackPrice}`,
|
||||
);
|
||||
console.log(err);
|
||||
return this.fallbackPrice;
|
||||
}
|
||||
}
|
||||
|
||||
async fetchPrices(
|
||||
tokens: {
|
||||
tokenAddress: string;
|
||||
decimals: number;
|
||||
}[],
|
||||
): Promise<bigint[]> {
|
||||
// setup mock price for testnets
|
||||
if (!this.oracle) {
|
||||
return new Promise((resolve) => resolve(tokens.map(() => this.fallbackPrice)));
|
||||
}
|
||||
|
||||
const prices = (await multicall(this.multicall, this.buildCalls(tokens))) as (bigint | null)[];
|
||||
|
||||
return prices.map((price, index) => {
|
||||
if (!price) {
|
||||
price = this.fallbackPrice;
|
||||
}
|
||||
return (price * BigInt(10 ** tokens[index].decimals)) / BigInt(10 ** 18);
|
||||
});
|
||||
}
|
||||
|
||||
async fetchEthUSD(stablecoinAddress: string): Promise<number> {
|
||||
// setup mock price for testnets
|
||||
if (!this.oracle) {
|
||||
return new Promise((resolve) => resolve(10 ** 18 / Number(this.fallbackPrice)));
|
||||
}
|
||||
|
||||
const [decimals, price] = await multicall(this.multicall, this.buildStable(stablecoinAddress));
|
||||
|
||||
// eth wei price of usdc token
|
||||
const ethPrice = ((price || this.fallbackPrice) * BigInt(10n ** decimals)) / BigInt(10 ** 18);
|
||||
|
||||
return 1 / Number(formatEther(ethPrice));
|
||||
}
|
||||
}
|
||||
|
||||
973
src/providers.ts
973
src/providers.ts
File diff suppressed because it is too large
Load Diff
@@ -1,96 +1,103 @@
|
||||
import { getAddress, namehash, parseEther } from 'ethers';
|
||||
import type { Aggregator } from '@tornado/contracts';
|
||||
import type { RelayerStructOutput } from '@tornado/contracts/dist/contracts/Governance/Aggregator/Aggregator';
|
||||
import { getAddress, parseEther } from 'ethers';
|
||||
import { sleep } from './utils';
|
||||
import { NetId, NetIdType, Config } from './networkConfig';
|
||||
import { fetchData, fetchDataOptions } from './providers';
|
||||
import { ajv, jobsSchema, getStatusSchema } from './schemas';
|
||||
import { ajv, jobsSchema, jobRequestSchema, getStatusSchema } from './schemas';
|
||||
import type { snarkProofs } from './websnark';
|
||||
import type { CachedRelayerInfo } from './events';
|
||||
|
||||
export const MIN_FEE = 0.1;
|
||||
|
||||
export const MAX_FEE = 0.9;
|
||||
|
||||
export const MIN_STAKE_BALANCE = parseEther('500');
|
||||
|
||||
export interface RelayerParams {
|
||||
ensName: string;
|
||||
relayerAddress?: string;
|
||||
ensName: string;
|
||||
relayerAddress: string;
|
||||
}
|
||||
|
||||
export interface Relayer {
|
||||
netId: NetIdType;
|
||||
url: string;
|
||||
hostname: string;
|
||||
rewardAccount: string;
|
||||
instances: string[];
|
||||
gasPrice?: number;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
currentQueue: number;
|
||||
tornadoServiceFee: number;
|
||||
/**
|
||||
* Info from relayer status
|
||||
*/
|
||||
export interface RelayerInfo extends RelayerParams {
|
||||
netId: NetIdType;
|
||||
url: string;
|
||||
hostname: string;
|
||||
rewardAccount: string;
|
||||
instances: string[];
|
||||
stakeBalance?: string;
|
||||
gasPrice?: number;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
currentQueue: number;
|
||||
tornadoServiceFee: number;
|
||||
}
|
||||
|
||||
export type RelayerInfo = Relayer & {
|
||||
ensName: string;
|
||||
stakeBalance: bigint;
|
||||
relayerAddress: string;
|
||||
};
|
||||
|
||||
export type RelayerError = {
|
||||
hostname: string;
|
||||
relayerAddress?: string;
|
||||
errorMessage?: string;
|
||||
};
|
||||
export interface RelayerError {
|
||||
hostname: string;
|
||||
relayerAddress?: string;
|
||||
errorMessage?: string;
|
||||
hasError: boolean;
|
||||
}
|
||||
|
||||
export interface RelayerStatus {
|
||||
url: string;
|
||||
rewardAccount: string;
|
||||
instances: {
|
||||
[key in string]: {
|
||||
instanceAddress: {
|
||||
[key in string]: string;
|
||||
};
|
||||
tokenAddress?: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
url: string;
|
||||
rewardAccount: string;
|
||||
instances: {
|
||||
[key in string]: {
|
||||
instanceAddress: {
|
||||
[key in string]: string;
|
||||
};
|
||||
tokenAddress?: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
gasPrices?: {
|
||||
fast: number;
|
||||
additionalProperties?: number;
|
||||
};
|
||||
netId: NetIdType;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
tornadoServiceFee: number;
|
||||
latestBlock?: number;
|
||||
version: string;
|
||||
health: {
|
||||
status: string;
|
||||
error: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
errorsLog: any[];
|
||||
};
|
||||
currentQueue: number;
|
||||
gasPrices?: {
|
||||
fast: number;
|
||||
additionalProperties?: number;
|
||||
};
|
||||
netId: NetIdType;
|
||||
ethPrices?: {
|
||||
[key in string]: string;
|
||||
};
|
||||
tornadoServiceFee: number;
|
||||
latestBlock?: number;
|
||||
version: string;
|
||||
health: {
|
||||
status: string;
|
||||
error: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
errorsLog: any[];
|
||||
};
|
||||
currentQueue: number;
|
||||
}
|
||||
|
||||
export interface TornadoWithdrawParams extends snarkProofs {
|
||||
contract: string;
|
||||
}
|
||||
|
||||
export interface RelayerTornadoWithdraw {
|
||||
id?: string;
|
||||
error?: string;
|
||||
id?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
export interface RelayerTornadoJobs {
|
||||
error?: string;
|
||||
id: string;
|
||||
type?: string;
|
||||
status: string;
|
||||
contract?: string;
|
||||
proof?: string;
|
||||
args?: string[];
|
||||
txHash?: string;
|
||||
confirmations?: number;
|
||||
failedReason?: string;
|
||||
error?: string;
|
||||
id: string;
|
||||
type?: string;
|
||||
status: string;
|
||||
contract?: string;
|
||||
proof?: string;
|
||||
args?: string[];
|
||||
txHash?: string;
|
||||
confirmations?: number;
|
||||
failedReason?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
const semVerRegex =
|
||||
/^(?<major>0|[1-9]\d*)\.(?<minor>0|[1-9]\d*)\.(?<patch>0|[1-9]\d*)(?:-(?<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
||||
|
||||
@@ -116,319 +123,298 @@ export function isRelayerUpdated(relayerVersion: string, netId: NetIdType) {
|
||||
if (prerelease) return false;
|
||||
return isUpdatedMajor && (Number(patch) >= 5 || netId !== NetId.MAINNET); // Patch checking - also backwards compatibility for Mainnet
|
||||
}
|
||||
**/
|
||||
|
||||
export function calculateScore({ stakeBalance, tornadoServiceFee }: RelayerInfo, minFee = 0.33, maxFee = 0.53) {
|
||||
if (tornadoServiceFee < minFee) {
|
||||
tornadoServiceFee = minFee;
|
||||
} else if (tornadoServiceFee >= maxFee) {
|
||||
return BigInt(0);
|
||||
}
|
||||
export function calculateScore({ stakeBalance, tornadoServiceFee }: RelayerInfo) {
|
||||
if (tornadoServiceFee < MIN_FEE) {
|
||||
tornadoServiceFee = MIN_FEE;
|
||||
} else if (tornadoServiceFee >= MAX_FEE) {
|
||||
return BigInt(0);
|
||||
}
|
||||
|
||||
const serviceFeeCoefficient = (tornadoServiceFee - minFee) ** 2;
|
||||
const feeDiffCoefficient = 1 / (maxFee - minFee) ** 2;
|
||||
const coefficientsMultiplier = 1 - feeDiffCoefficient * serviceFeeCoefficient;
|
||||
const serviceFeeCoefficient = (tornadoServiceFee - MIN_FEE) ** 2;
|
||||
const feeDiffCoefficient = 1 / (MAX_FEE - MIN_FEE) ** 2;
|
||||
const coefficientsMultiplier = 1 - feeDiffCoefficient * serviceFeeCoefficient;
|
||||
|
||||
return BigInt(Math.floor(Number(stakeBalance) * coefficientsMultiplier));
|
||||
return BigInt(Math.floor(Number(stakeBalance || '0') * coefficientsMultiplier));
|
||||
}
|
||||
|
||||
export function getWeightRandom(weightsScores: bigint[], random: bigint) {
|
||||
for (let i = 0; i < weightsScores.length; i++) {
|
||||
if (random < weightsScores[i]) {
|
||||
return i;
|
||||
for (let i = 0; i < weightsScores.length; i++) {
|
||||
if (random < weightsScores[i]) {
|
||||
return i;
|
||||
}
|
||||
random = random - weightsScores[i];
|
||||
}
|
||||
random = random - weightsScores[i];
|
||||
}
|
||||
return Math.floor(Math.random() * weightsScores.length);
|
||||
return Math.floor(Math.random() * weightsScores.length);
|
||||
}
|
||||
|
||||
export type RelayerInstanceList = {
|
||||
[key in string]: {
|
||||
instanceAddress: {
|
||||
[key in string]: string;
|
||||
export interface RelayerInstanceList {
|
||||
[key: string]: {
|
||||
instanceAddress: {
|
||||
[key: string]: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export function getSupportedInstances(instanceList: RelayerInstanceList) {
|
||||
const rawList = Object.values(instanceList)
|
||||
.map(({ instanceAddress }) => {
|
||||
return Object.values(instanceAddress);
|
||||
})
|
||||
.flat();
|
||||
const rawList = Object.values(instanceList)
|
||||
.map(({ instanceAddress }) => {
|
||||
return Object.values(instanceAddress);
|
||||
})
|
||||
.flat();
|
||||
|
||||
return rawList.map((l) => getAddress(l));
|
||||
return rawList.map((l) => getAddress(l));
|
||||
}
|
||||
|
||||
export function pickWeightedRandomRelayer(relayers: RelayerInfo[], netId: NetIdType) {
|
||||
let minFee: number, maxFee: number;
|
||||
export function pickWeightedRandomRelayer(relayers: RelayerInfo[]) {
|
||||
const weightsScores = relayers.map((el) => calculateScore(el));
|
||||
const totalWeight = weightsScores.reduce((acc, curr) => {
|
||||
return (acc = acc + curr);
|
||||
}, BigInt('0'));
|
||||
|
||||
if (netId !== NetId.MAINNET) {
|
||||
minFee = 0.01;
|
||||
maxFee = 0.3;
|
||||
}
|
||||
const random = BigInt(Math.floor(Number(totalWeight) * Math.random()));
|
||||
const weightRandomIndex = getWeightRandom(weightsScores, random);
|
||||
|
||||
const weightsScores = relayers.map((el) => calculateScore(el, minFee, maxFee));
|
||||
const totalWeight = weightsScores.reduce((acc, curr) => {
|
||||
return (acc = acc + curr);
|
||||
}, BigInt('0'));
|
||||
|
||||
const random = BigInt(Number(totalWeight) * Math.random());
|
||||
const weightRandomIndex = getWeightRandom(weightsScores, random);
|
||||
|
||||
return relayers[weightRandomIndex];
|
||||
return relayers[weightRandomIndex];
|
||||
}
|
||||
|
||||
export interface RelayerClientConstructor {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
Aggregator: Aggregator;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
}
|
||||
|
||||
export type RelayerClientWithdraw = snarkProofs & {
|
||||
contract: string;
|
||||
};
|
||||
|
||||
export class RelayerClient {
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
Aggregator: Aggregator;
|
||||
selectedRelayer?: Relayer;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
netId: NetIdType;
|
||||
config: Config;
|
||||
selectedRelayer?: RelayerInfo;
|
||||
fetchDataOptions?: fetchDataOptions;
|
||||
tovarish: boolean;
|
||||
|
||||
constructor({ netId, config, Aggregator, fetchDataOptions }: RelayerClientConstructor) {
|
||||
this.netId = netId;
|
||||
this.config = config;
|
||||
this.Aggregator = Aggregator;
|
||||
this.fetchDataOptions = fetchDataOptions;
|
||||
}
|
||||
|
||||
async askRelayerStatus({
|
||||
hostname,
|
||||
relayerAddress,
|
||||
}: {
|
||||
hostname: string;
|
||||
relayerAddress?: string;
|
||||
}): Promise<RelayerStatus> {
|
||||
const url = `https://${!hostname.endsWith('/') ? hostname + '/' : hostname}`;
|
||||
|
||||
const rawStatus = (await fetchData(`${url}status`, {
|
||||
...this.fetchDataOptions,
|
||||
headers: {
|
||||
'Content-Type': 'application/json, application/x-www-form-urlencoded',
|
||||
},
|
||||
timeout: this.fetchDataOptions?.torPort ? 10000 : 3000,
|
||||
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0,
|
||||
})) as object;
|
||||
|
||||
const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config));
|
||||
|
||||
if (!statusValidator(rawStatus)) {
|
||||
throw new Error('Invalid status schema');
|
||||
constructor({ netId, config, fetchDataOptions }: RelayerClientConstructor) {
|
||||
this.netId = netId;
|
||||
this.config = config;
|
||||
this.fetchDataOptions = fetchDataOptions;
|
||||
this.tovarish = false;
|
||||
}
|
||||
|
||||
const status = {
|
||||
...rawStatus,
|
||||
url,
|
||||
} as RelayerStatus;
|
||||
|
||||
if (status.currentQueue > 5) {
|
||||
throw new Error('Withdrawal queue is overloaded');
|
||||
}
|
||||
|
||||
if (status.netId !== this.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');
|
||||
}
|
||||
|
||||
if (!isRelayerUpdated(status.version, this.netId)) {
|
||||
throw new Error('Outdated version.');
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
async filterRelayer(
|
||||
curr: RelayerStructOutput,
|
||||
relayer: RelayerParams,
|
||||
subdomains: string[],
|
||||
debugRelayer: boolean = false,
|
||||
): Promise<RelayerInfo | RelayerError> {
|
||||
const { relayerEnsSubdomain } = this.config;
|
||||
const subdomainIndex = subdomains.indexOf(relayerEnsSubdomain);
|
||||
const mainnetSubdomain = curr.records[0];
|
||||
const hostname = curr.records[subdomainIndex];
|
||||
const isHostWithProtocol = hostname.includes('http');
|
||||
|
||||
const { owner, balance: stakeBalance, isRegistered } = curr;
|
||||
const { ensName, relayerAddress } = relayer;
|
||||
|
||||
const isOwner = !relayerAddress || relayerAddress === owner;
|
||||
const hasMinBalance = stakeBalance >= MIN_STAKE_BALANCE;
|
||||
|
||||
const preCondition =
|
||||
hostname && isOwner && mainnetSubdomain && isRegistered && hasMinBalance && !isHostWithProtocol;
|
||||
|
||||
if (preCondition || debugRelayer) {
|
||||
try {
|
||||
const status = await this.askRelayerStatus({ hostname, relayerAddress });
|
||||
|
||||
return {
|
||||
netId: status.netId,
|
||||
url: status.url,
|
||||
hostname,
|
||||
ensName,
|
||||
stakeBalance,
|
||||
relayerAddress,
|
||||
rewardAccount: getAddress(status.rewardAccount),
|
||||
instances: getSupportedInstances(status.instances),
|
||||
gasPrice: status.gasPrices?.fast,
|
||||
ethPrices: status.ethPrices,
|
||||
currentQueue: status.currentQueue,
|
||||
tornadoServiceFee: status.tornadoServiceFee,
|
||||
} as RelayerInfo;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
if (debugRelayer) {
|
||||
throw err;
|
||||
}
|
||||
return {
|
||||
hostname,
|
||||
relayerAddress,
|
||||
errorMessage: err.message,
|
||||
} as RelayerError;
|
||||
}
|
||||
} else {
|
||||
if (debugRelayer) {
|
||||
const errMsg = `Relayer ${hostname} condition not met`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
return {
|
||||
async askRelayerStatus({
|
||||
hostname,
|
||||
url,
|
||||
relayerAddress,
|
||||
errorMessage: `Relayer ${hostname} condition not met`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async getValidRelayers(
|
||||
// this should be ascending order of events
|
||||
relayers: RelayerParams[],
|
||||
subdomains: string[],
|
||||
debugRelayer: boolean = false,
|
||||
): Promise<{
|
||||
validRelayers: RelayerInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}> {
|
||||
const relayersSet = new Set();
|
||||
|
||||
const uniqueRelayers = relayers.reverse().filter(({ ensName }) => {
|
||||
if (!relayersSet.has(ensName)) {
|
||||
relayersSet.add(ensName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const relayerNameHashes = uniqueRelayers.map((r) => namehash(r.ensName));
|
||||
|
||||
const relayersData = await this.Aggregator.relayersData.staticCall(relayerNameHashes, subdomains);
|
||||
|
||||
const invalidRelayers: RelayerError[] = [];
|
||||
|
||||
const validRelayers = (
|
||||
await Promise.all(
|
||||
relayersData.map((curr, index) => this.filterRelayer(curr, uniqueRelayers[index], subdomains, debugRelayer)),
|
||||
)
|
||||
).filter((r) => {
|
||||
if ((r as RelayerError).errorMessage) {
|
||||
invalidRelayers.push(r);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}) as RelayerInfo[];
|
||||
|
||||
return {
|
||||
validRelayers,
|
||||
invalidRelayers,
|
||||
};
|
||||
}
|
||||
|
||||
pickWeightedRandomRelayer(relayers: RelayerInfo[]) {
|
||||
return pickWeightedRandomRelayer(relayers, this.netId);
|
||||
}
|
||||
|
||||
async tornadoWithdraw({ contract, proof, args }: RelayerClientWithdraw) {
|
||||
const { url } = this.selectedRelayer as Relayer;
|
||||
|
||||
const withdrawResponse = (await fetchData(`${url}v1/tornadoWithdraw`, {
|
||||
...this.fetchDataOptions,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
contract,
|
||||
proof,
|
||||
args,
|
||||
}),
|
||||
})) as RelayerTornadoWithdraw;
|
||||
|
||||
const { id, error } = withdrawResponse;
|
||||
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
let relayerStatus: string | undefined;
|
||||
|
||||
const jobUrl = `${url}v1/jobs/${id}`;
|
||||
|
||||
console.log(`Job submitted: ${jobUrl}\n`);
|
||||
|
||||
while (!relayerStatus || !['FAILED', 'CONFIRMED'].includes(relayerStatus)) {
|
||||
const jobResponse = await fetchData(jobUrl, {
|
||||
...this.fetchDataOptions,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (jobResponse.error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
const jobValidator = ajv.compile(jobsSchema);
|
||||
|
||||
if (!jobValidator(jobResponse)) {
|
||||
const errMsg = `${jobUrl} has an invalid job response`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
const { status, txHash, confirmations, failedReason } = jobResponse as unknown as RelayerTornadoJobs;
|
||||
|
||||
if (relayerStatus !== status) {
|
||||
if (status === 'FAILED') {
|
||||
const errMsg = `Job ${status}: ${jobUrl} failed reason: ${failedReason}`;
|
||||
throw new Error(errMsg);
|
||||
} else if (status === 'SENT') {
|
||||
console.log(`Job ${status}: ${jobUrl}, txhash: ${txHash}\n`);
|
||||
} else if (status === 'MINED') {
|
||||
console.log(`Job ${status}: ${jobUrl}, txhash: ${txHash}, confirmations: ${confirmations}\n`);
|
||||
} else if (status === 'CONFIRMED') {
|
||||
console.log(`Job ${status}: ${jobUrl}, txhash: ${txHash}, confirmations: ${confirmations}\n`);
|
||||
}: {
|
||||
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}`;
|
||||
} else if (url && !url.endsWith('/')) {
|
||||
url += '/';
|
||||
} else {
|
||||
console.log(`Job ${status}: ${jobUrl}\n`);
|
||||
url = '';
|
||||
}
|
||||
|
||||
relayerStatus = status;
|
||||
}
|
||||
const rawStatus = (await fetchData(`${url}status`, {
|
||||
...this.fetchDataOptions,
|
||||
headers: {
|
||||
'Content-Type': 'application/json, application/x-www-form-urlencoded',
|
||||
},
|
||||
timeout: 30000,
|
||||
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0,
|
||||
})) as object;
|
||||
|
||||
await sleep(3000);
|
||||
const statusValidator = ajv.compile(getStatusSchema(this.netId, this.config, this.tovarish));
|
||||
|
||||
if (!statusValidator(rawStatus)) {
|
||||
throw new Error('Invalid status schema');
|
||||
}
|
||||
|
||||
const status = {
|
||||
...rawStatus,
|
||||
url,
|
||||
} as RelayerStatus;
|
||||
|
||||
if (status.currentQueue > 5) {
|
||||
throw new Error('Withdrawal queue is overloaded');
|
||||
}
|
||||
|
||||
if (status.netId !== this.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];
|
||||
const { ensName, relayerAddress } = relayer;
|
||||
|
||||
if (!hostname) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const status = await this.askRelayerStatus({
|
||||
hostname,
|
||||
relayerAddress,
|
||||
});
|
||||
|
||||
return {
|
||||
netId: status.netId,
|
||||
url: status.url,
|
||||
hostname,
|
||||
ensName,
|
||||
relayerAddress,
|
||||
rewardAccount: getAddress(status.rewardAccount),
|
||||
instances: getSupportedInstances(status.instances),
|
||||
stakeBalance: relayer.stakeBalance,
|
||||
gasPrice: status.gasPrices?.fast,
|
||||
ethPrices: status.ethPrices,
|
||||
currentQueue: status.currentQueue,
|
||||
tornadoServiceFee: status.tornadoServiceFee,
|
||||
} as RelayerInfo;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
return {
|
||||
hostname,
|
||||
relayerAddress,
|
||||
errorMessage: err.message,
|
||||
hasError: true,
|
||||
} as RelayerError;
|
||||
}
|
||||
}
|
||||
|
||||
async getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: RelayerInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}> {
|
||||
const invalidRelayers: RelayerError[] = [];
|
||||
|
||||
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
|
||||
(r) => {
|
||||
if (!r) {
|
||||
return false;
|
||||
}
|
||||
if ((r as RelayerError).hasError) {
|
||||
invalidRelayers.push(r as RelayerError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
) as RelayerInfo[];
|
||||
|
||||
return {
|
||||
validRelayers,
|
||||
invalidRelayers,
|
||||
};
|
||||
}
|
||||
|
||||
pickWeightedRandomRelayer(relayers: RelayerInfo[]) {
|
||||
return pickWeightedRandomRelayer(relayers);
|
||||
}
|
||||
|
||||
async tornadoWithdraw(
|
||||
{ contract, proof, args }: TornadoWithdrawParams,
|
||||
callback?: (jobResp: RelayerTornadoWithdraw | RelayerTornadoJobs) => void,
|
||||
) {
|
||||
const { url } = this.selectedRelayer as RelayerInfo;
|
||||
|
||||
/**
|
||||
* Request new job
|
||||
*/
|
||||
|
||||
const withdrawResponse = (await fetchData(`${url}v1/tornadoWithdraw`, {
|
||||
...this.fetchDataOptions,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
contract,
|
||||
proof,
|
||||
args,
|
||||
}),
|
||||
})) as RelayerTornadoWithdraw;
|
||||
|
||||
const { id, error } = withdrawResponse;
|
||||
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
const jobValidator = ajv.compile(jobRequestSchema);
|
||||
|
||||
if (!jobValidator(withdrawResponse)) {
|
||||
const errMsg = `${url}v1/tornadoWithdraw has an invalid job response`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback(withdrawResponse as unknown as RelayerTornadoWithdraw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get job status
|
||||
*/
|
||||
|
||||
let relayerStatus: string | undefined;
|
||||
|
||||
const jobUrl = `${url}v1/jobs/${id}`;
|
||||
|
||||
console.log(`Job submitted: ${jobUrl}\n`);
|
||||
|
||||
while (!relayerStatus || !['FAILED', 'CONFIRMED'].includes(relayerStatus)) {
|
||||
const jobResponse = await fetchData(jobUrl, {
|
||||
...this.fetchDataOptions,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (jobResponse.error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
|
||||
const jobValidator = ajv.compile(jobsSchema);
|
||||
|
||||
if (!jobValidator(jobResponse)) {
|
||||
const errMsg = `${jobUrl} has an invalid job response`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
const { status, txHash, confirmations, failedReason } = jobResponse as unknown as RelayerTornadoJobs;
|
||||
|
||||
if (relayerStatus !== status) {
|
||||
if (status === 'FAILED') {
|
||||
const errMsg = `Job ${status}: ${jobUrl} failed reason: ${failedReason}`;
|
||||
throw new Error(errMsg);
|
||||
} else if (status === 'SENT') {
|
||||
console.log(`Job ${status}: ${jobUrl}, txhash: ${txHash}\n`);
|
||||
} else if (status === 'MINED') {
|
||||
console.log(`Job ${status}: ${jobUrl}, txhash: ${txHash}, confirmations: ${confirmations}\n`);
|
||||
} else if (status === 'CONFIRMED') {
|
||||
console.log(`Job ${status}: ${jobUrl}, txhash: ${txHash}, confirmations: ${confirmations}\n`);
|
||||
} else {
|
||||
console.log(`Job ${status}: ${jobUrl}\n`);
|
||||
}
|
||||
|
||||
relayerStatus = status;
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback(jobResponse as unknown as RelayerTornadoJobs);
|
||||
}
|
||||
}
|
||||
|
||||
await sleep(3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
31
src/schemas/ajv.ts
Normal file
31
src/schemas/ajv.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import Ajv from 'ajv';
|
||||
import { BigNumberish, isAddress } from 'ethers';
|
||||
|
||||
export const ajv = new Ajv({ allErrors: true });
|
||||
|
||||
ajv.addKeyword({
|
||||
keyword: 'BN',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
validate: (schema: any, data: BigNumberish) => {
|
||||
try {
|
||||
BigInt(data);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
errors: true,
|
||||
});
|
||||
|
||||
ajv.addKeyword({
|
||||
keyword: 'isAddress',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
validate: (schema: any, data: string) => {
|
||||
try {
|
||||
return isAddress(data);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
errors: true,
|
||||
});
|
||||
321
src/schemas/events.ts
Normal file
321
src/schemas/events.ts
Normal file
@@ -0,0 +1,321 @@
|
||||
import { ajv } from './ajv';
|
||||
import { addressSchemaType, bnSchemaType, bytes32SchemaType } from './types';
|
||||
|
||||
const baseEventsSchemaProperty = {
|
||||
blockNumber: {
|
||||
type: 'number',
|
||||
},
|
||||
logIndex: {
|
||||
type: 'number',
|
||||
},
|
||||
transactionHash: bytes32SchemaType,
|
||||
} as const;
|
||||
|
||||
const baseEventsSchemaRequired = Object.keys(baseEventsSchemaProperty) as string[];
|
||||
|
||||
export const governanceEventsSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
anyOf: [
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
id: { type: 'number' },
|
||||
proposer: addressSchemaType,
|
||||
target: addressSchemaType,
|
||||
startTime: { type: 'number' },
|
||||
endTime: { type: 'number' },
|
||||
description: { type: 'string' },
|
||||
},
|
||||
required: [
|
||||
...baseEventsSchemaRequired,
|
||||
'event',
|
||||
'id',
|
||||
'proposer',
|
||||
'target',
|
||||
'startTime',
|
||||
'endTime',
|
||||
'description',
|
||||
],
|
||||
additionalProperties: false,
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
proposalId: { type: 'number' },
|
||||
voter: addressSchemaType,
|
||||
support: { type: 'boolean' },
|
||||
votes: { type: 'string' },
|
||||
from: addressSchemaType,
|
||||
input: { type: 'string' },
|
||||
},
|
||||
required: [
|
||||
...baseEventsSchemaRequired,
|
||||
'event',
|
||||
'proposalId',
|
||||
'voter',
|
||||
'support',
|
||||
'votes',
|
||||
'from',
|
||||
'input',
|
||||
],
|
||||
additionalProperties: false,
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
account: addressSchemaType,
|
||||
delegateTo: addressSchemaType,
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'account', 'delegateTo'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
account: addressSchemaType,
|
||||
delegateFrom: addressSchemaType,
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'account', 'delegateFrom'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const relayerRegistryEventsSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
anyOf: [
|
||||
// RelayerRegisteredEvents
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
ensName: { type: 'string' },
|
||||
relayerAddress: addressSchemaType,
|
||||
ensHash: { type: 'string' },
|
||||
stakedAmount: { type: 'string' },
|
||||
},
|
||||
required: [
|
||||
...baseEventsSchemaRequired,
|
||||
'event',
|
||||
'ensName',
|
||||
'relayerAddress',
|
||||
'ensHash',
|
||||
'stakedAmount',
|
||||
],
|
||||
additionalProperties: false,
|
||||
},
|
||||
// RelayerUnregisteredEvents
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
relayerAddress: addressSchemaType,
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'event', 'relayerAddress'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
// WorkerRegisteredEvents & WorkerUnregisteredEvents
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
relayerAddress: addressSchemaType,
|
||||
workerAddress: addressSchemaType,
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'event', 'relayerAddress', 'workerAddress'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const stakeBurnedEventsSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
relayerAddress: addressSchemaType,
|
||||
amountBurned: bnSchemaType,
|
||||
instanceAddress: addressSchemaType,
|
||||
gasFee: bnSchemaType,
|
||||
relayerFee: bnSchemaType,
|
||||
timestamp: { type: 'number' },
|
||||
},
|
||||
required: [
|
||||
...baseEventsSchemaRequired,
|
||||
'relayerAddress',
|
||||
'amountBurned',
|
||||
'instanceAddress',
|
||||
'gasFee',
|
||||
'relayerFee',
|
||||
'timestamp',
|
||||
],
|
||||
additionalProperties: false,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const depositsEventsSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
commitment: bytes32SchemaType,
|
||||
leafIndex: { type: 'number' },
|
||||
timestamp: { type: 'number' },
|
||||
from: addressSchemaType,
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'commitment', 'leafIndex', 'timestamp', 'from'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const withdrawalsEventsSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
nullifierHash: bytes32SchemaType,
|
||||
to: addressSchemaType,
|
||||
fee: bnSchemaType,
|
||||
timestamp: { type: 'number' },
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'nullifierHash', 'to', 'fee', 'timestamp'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const tornadoEventsSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
anyOf: [
|
||||
// depositsEvents
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
instanceAddress: { type: 'string' },
|
||||
commitment: bytes32SchemaType,
|
||||
leafIndex: { type: 'number' },
|
||||
timestamp: { type: 'number' },
|
||||
from: addressSchemaType,
|
||||
},
|
||||
required: [
|
||||
...baseEventsSchemaRequired,
|
||||
'event',
|
||||
'instanceAddress',
|
||||
'commitment',
|
||||
'leafIndex',
|
||||
'timestamp',
|
||||
'from',
|
||||
],
|
||||
additionalProperties: false,
|
||||
},
|
||||
// withdrawalEvents
|
||||
{
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
event: { type: 'string' },
|
||||
instanceAddress: { type: 'string' },
|
||||
nullifierHash: bytes32SchemaType,
|
||||
to: addressSchemaType,
|
||||
relayerAddress: addressSchemaType,
|
||||
fee: bnSchemaType,
|
||||
timestamp: { type: 'number' },
|
||||
},
|
||||
required: [
|
||||
...baseEventsSchemaRequired,
|
||||
'event',
|
||||
'instanceAddress',
|
||||
'nullifierHash',
|
||||
'to',
|
||||
'relayerAddress',
|
||||
'fee',
|
||||
'timestamp',
|
||||
],
|
||||
additionalProperties: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const echoEventsSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
address: addressSchemaType,
|
||||
encryptedAccount: { type: 'string' },
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'address', 'encryptedAccount'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const encryptedNotesSchema = {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
...baseEventsSchemaProperty,
|
||||
encryptedNote: { type: 'string' },
|
||||
},
|
||||
required: [...baseEventsSchemaRequired, 'encryptedNote'],
|
||||
additionalProperties: false,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export function getEventsSchemaValidator(type: string) {
|
||||
if (type === 'tornado') {
|
||||
return ajv.compile(tornadoEventsSchema);
|
||||
}
|
||||
|
||||
if (type === 'deposit') {
|
||||
return ajv.compile(depositsEventsSchema);
|
||||
}
|
||||
|
||||
if (type === 'withdrawal') {
|
||||
return ajv.compile(withdrawalsEventsSchema);
|
||||
}
|
||||
|
||||
if (type === 'governance') {
|
||||
return ajv.compile(governanceEventsSchema);
|
||||
}
|
||||
|
||||
if (type === 'registry') {
|
||||
return ajv.compile(relayerRegistryEventsSchema);
|
||||
}
|
||||
|
||||
if (type === 'revenue') {
|
||||
return ajv.compile(stakeBurnedEventsSchema);
|
||||
}
|
||||
|
||||
if (type === 'echo') {
|
||||
return ajv.compile(echoEventsSchema);
|
||||
}
|
||||
|
||||
if (type === 'encrypted_notes') {
|
||||
return ajv.compile(encryptedNotesSchema);
|
||||
}
|
||||
|
||||
throw new Error('Unsupported event type for schema validation');
|
||||
}
|
||||
@@ -1,21 +1,5 @@
|
||||
import Ajv from 'ajv';
|
||||
import type { BigNumberish } from 'ethers';
|
||||
|
||||
export const ajv = new Ajv({ allErrors: true });
|
||||
|
||||
ajv.addKeyword({
|
||||
keyword: 'BN',
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
validate: (schema: any, data: BigNumberish) => {
|
||||
try {
|
||||
BigInt(data);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
errors: true,
|
||||
});
|
||||
|
||||
export * from './ajv';
|
||||
export * from './events';
|
||||
export * from './status';
|
||||
export * from './jobs';
|
||||
export * from './types';
|
||||
|
||||
@@ -1,59 +1,64 @@
|
||||
export type jobsSchema = {
|
||||
type: string;
|
||||
properties: {
|
||||
error: {
|
||||
type: string;
|
||||
export interface jobsSchema {
|
||||
type: string;
|
||||
properties: {
|
||||
error: {
|
||||
type: string;
|
||||
};
|
||||
id: {
|
||||
type: string;
|
||||
};
|
||||
type: {
|
||||
type: string;
|
||||
};
|
||||
status: {
|
||||
type: string;
|
||||
};
|
||||
contract: {
|
||||
type: string;
|
||||
};
|
||||
proof: {
|
||||
type: string;
|
||||
};
|
||||
args: {
|
||||
type: string;
|
||||
items: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
txHash: {
|
||||
type: string;
|
||||
};
|
||||
confirmations: {
|
||||
type: string;
|
||||
};
|
||||
failedReason: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
id: {
|
||||
type: string;
|
||||
};
|
||||
type: {
|
||||
type: string;
|
||||
};
|
||||
status: {
|
||||
type: string;
|
||||
};
|
||||
contract: {
|
||||
type: string;
|
||||
};
|
||||
proof: {
|
||||
type: string;
|
||||
};
|
||||
args: {
|
||||
type: string;
|
||||
items: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
txHash: {
|
||||
type: string;
|
||||
};
|
||||
confirmations: {
|
||||
type: string;
|
||||
};
|
||||
failedReason: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
required: string[];
|
||||
}
|
||||
|
||||
export const jobsSchema: jobsSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
error: { type: 'string' },
|
||||
id: { type: 'string' },
|
||||
type: { type: 'string' },
|
||||
status: { type: 'string' },
|
||||
contract: { type: 'string' },
|
||||
proof: { type: 'string' },
|
||||
args: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
type: 'object',
|
||||
properties: {
|
||||
error: { type: 'string' },
|
||||
id: { type: 'string' },
|
||||
type: { type: 'string' },
|
||||
status: { type: 'string' },
|
||||
contract: { type: 'string' },
|
||||
proof: { type: 'string' },
|
||||
args: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
},
|
||||
txHash: { type: 'string' },
|
||||
confirmations: { type: 'number' },
|
||||
failedReason: { type: 'string' },
|
||||
},
|
||||
txHash: { type: 'string' },
|
||||
confirmations: { type: 'number' },
|
||||
failedReason: { type: 'string' },
|
||||
},
|
||||
required: ['id', 'status'],
|
||||
required: ['id', 'status'],
|
||||
};
|
||||
|
||||
export const jobRequestSchema: jobsSchema = {
|
||||
...jobsSchema,
|
||||
required: ['id'],
|
||||
};
|
||||
|
||||
@@ -1,181 +1,221 @@
|
||||
import { Config, NetId, NetIdType } from '../networkConfig';
|
||||
import { addressSchemaType, bnSchemaType } from '.';
|
||||
|
||||
export type statusInstanceType = {
|
||||
type: string;
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof addressType;
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
tokenAddress?: typeof addressType;
|
||||
symbol?: { enum: string[] };
|
||||
decimals: { enum: number[] };
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
|
||||
export type statusInstancesType = {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: statusInstanceType;
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
|
||||
export type statusEthPricesType = {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof bnType;
|
||||
};
|
||||
required?: string[];
|
||||
};
|
||||
|
||||
export type statusSchema = {
|
||||
type: string;
|
||||
properties: {
|
||||
rewardAccount: typeof addressType;
|
||||
instances?: statusInstancesType;
|
||||
gasPrices: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: {
|
||||
type: string;
|
||||
export interface statusInstanceType {
|
||||
type: string;
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof addressSchemaType;
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
tokenAddress?: typeof addressSchemaType;
|
||||
symbol?: { enum: string[] };
|
||||
decimals: { enum: number[] };
|
||||
};
|
||||
netId: {
|
||||
type: string;
|
||||
};
|
||||
ethPrices?: statusEthPricesType;
|
||||
tornadoServiceFee?: {
|
||||
type: string;
|
||||
maximum: number;
|
||||
minimum: number;
|
||||
};
|
||||
latestBlock?: {
|
||||
type: string;
|
||||
};
|
||||
version: {
|
||||
type: string;
|
||||
};
|
||||
health: {
|
||||
type: string;
|
||||
properties: {
|
||||
status: { const: string };
|
||||
error: { type: string };
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
currentQueue: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
required: string[];
|
||||
}
|
||||
|
||||
const addressType = { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$' };
|
||||
export interface statusInstancesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: statusInstanceType;
|
||||
};
|
||||
required: string[];
|
||||
}
|
||||
|
||||
const bnType = { type: 'string', BN: true };
|
||||
export interface statusEthPricesType {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: typeof bnSchemaType;
|
||||
};
|
||||
required?: string[];
|
||||
}
|
||||
|
||||
export interface statusSchema {
|
||||
type: string;
|
||||
properties: {
|
||||
rewardAccount: typeof addressSchemaType;
|
||||
instances?: statusInstancesType;
|
||||
gasPrices: {
|
||||
type: string;
|
||||
properties: {
|
||||
[key in string]: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
netId: {
|
||||
type: string;
|
||||
};
|
||||
ethPrices?: statusEthPricesType;
|
||||
tornadoServiceFee?: {
|
||||
type: string;
|
||||
maximum: number;
|
||||
minimum: number;
|
||||
};
|
||||
latestBlock: {
|
||||
type: string;
|
||||
};
|
||||
latestBalance: {
|
||||
type: string;
|
||||
BN: boolean;
|
||||
};
|
||||
version: {
|
||||
type: string;
|
||||
};
|
||||
health: {
|
||||
type: string;
|
||||
properties: {
|
||||
status: { const: string };
|
||||
error: { type: string };
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
syncStatus: {
|
||||
type: string;
|
||||
properties: {
|
||||
events: { type: string };
|
||||
tokenPrice: { type: string };
|
||||
gasPrice: { type: string };
|
||||
};
|
||||
required: string[];
|
||||
};
|
||||
onSyncEvents: { type: string };
|
||||
currentQueue: {
|
||||
type: string;
|
||||
};
|
||||
};
|
||||
required: string[];
|
||||
}
|
||||
|
||||
const statusSchema: statusSchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
rewardAccount: addressType,
|
||||
gasPrices: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
fast: { type: 'number' },
|
||||
additionalProperties: { type: 'number' },
|
||||
},
|
||||
required: ['fast'],
|
||||
type: 'object',
|
||||
properties: {
|
||||
rewardAccount: addressSchemaType,
|
||||
gasPrices: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
fast: { type: 'number' },
|
||||
additionalProperties: { type: 'number' },
|
||||
},
|
||||
required: ['fast'],
|
||||
},
|
||||
netId: { type: 'integer' },
|
||||
tornadoServiceFee: { type: 'number', maximum: 20, minimum: 0 },
|
||||
latestBlock: { type: 'number' },
|
||||
latestBalance: bnSchemaType,
|
||||
version: { type: 'string' },
|
||||
health: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
status: { const: 'true' },
|
||||
error: { type: 'string' },
|
||||
},
|
||||
required: ['status'],
|
||||
},
|
||||
syncStatus: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
events: { type: 'boolean' },
|
||||
tokenPrice: { type: 'boolean' },
|
||||
gasPrice: { type: 'boolean' },
|
||||
},
|
||||
required: ['events', 'tokenPrice', 'gasPrice'],
|
||||
},
|
||||
onSyncEvents: { type: 'boolean' },
|
||||
currentQueue: { type: 'number' },
|
||||
},
|
||||
netId: { type: 'integer' },
|
||||
tornadoServiceFee: { type: 'number', maximum: 20, minimum: 0 },
|
||||
latestBlock: { type: 'number' },
|
||||
version: { type: 'string' },
|
||||
health: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
status: { const: 'true' },
|
||||
error: { type: 'string' },
|
||||
},
|
||||
required: ['status'],
|
||||
},
|
||||
currentQueue: { type: 'number' },
|
||||
},
|
||||
required: ['rewardAccount', 'instances', 'netId', 'tornadoServiceFee', 'version', 'health'],
|
||||
required: ['rewardAccount', 'instances', 'netId', 'tornadoServiceFee', 'version', 'health', 'currentQueue'],
|
||||
};
|
||||
|
||||
export function getStatusSchema(netId: NetIdType, config: Config) {
|
||||
const { tokens, optionalTokens = [], nativeCurrency } = config;
|
||||
export function getStatusSchema(netId: NetIdType, config: Config, tovarish: boolean) {
|
||||
const { tokens, optionalTokens, disabledTokens, nativeCurrency } = config;
|
||||
|
||||
// deep copy schema
|
||||
const schema = JSON.parse(JSON.stringify(statusSchema)) as statusSchema;
|
||||
// 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 amounts = Object.keys(instanceAddress);
|
||||
const instances = Object.keys(tokens).reduce(
|
||||
(acc: statusInstancesType, token) => {
|
||||
const { instanceAddress, tokenAddress, symbol, decimals, optionalInstances = [] } = tokens[token];
|
||||
const amounts = Object.keys(instanceAddress);
|
||||
|
||||
const instanceProperties: statusInstanceType = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: 'object',
|
||||
properties: amounts.reduce((acc: { [key in string]: typeof addressType }, cur) => {
|
||||
acc[cur] = addressType;
|
||||
return acc;
|
||||
}, {}),
|
||||
required: amounts.filter((amount) => !optionalInstances.includes(amount)),
|
||||
},
|
||||
decimals: { enum: [decimals] },
|
||||
const instanceProperties: statusInstanceType = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
instanceAddress: {
|
||||
type: 'object',
|
||||
properties: amounts.reduce(
|
||||
(
|
||||
acc: {
|
||||
[key in string]: typeof addressSchemaType;
|
||||
},
|
||||
cur,
|
||||
) => {
|
||||
acc[cur] = addressSchemaType;
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
),
|
||||
required: amounts.filter((amount) => !optionalInstances.includes(amount)),
|
||||
},
|
||||
decimals: { enum: [decimals] },
|
||||
},
|
||||
required: ['instanceAddress', 'decimals'].concat(
|
||||
tokenAddress ? ['tokenAddress'] : [],
|
||||
symbol ? ['symbol'] : [],
|
||||
),
|
||||
};
|
||||
|
||||
if (tokenAddress) {
|
||||
instanceProperties.properties.tokenAddress = addressSchemaType;
|
||||
}
|
||||
if (symbol) {
|
||||
instanceProperties.properties.symbol = { enum: [symbol] };
|
||||
}
|
||||
|
||||
acc.properties[token] = instanceProperties;
|
||||
if (!optionalTokens?.includes(token) && !disabledTokens?.includes(token)) {
|
||||
acc.required.push(token);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
required: ['instanceAddress', 'decimals'].concat(
|
||||
tokenAddress ? ['tokenAddress'] : [],
|
||||
symbol ? ['symbol'] : [],
|
||||
),
|
||||
};
|
||||
{
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
},
|
||||
);
|
||||
|
||||
if (tokenAddress) {
|
||||
instanceProperties.properties.tokenAddress = addressType;
|
||||
}
|
||||
if (symbol) {
|
||||
instanceProperties.properties.symbol = { enum: [symbol] };
|
||||
}
|
||||
schema.properties.instances = instances;
|
||||
|
||||
acc.properties[token] = instanceProperties;
|
||||
if (!optionalTokens.includes(token)) {
|
||||
acc.required.push(token);
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
properties: {},
|
||||
required: [],
|
||||
},
|
||||
);
|
||||
const _tokens = Object.keys(tokens).filter(
|
||||
(t) => t !== nativeCurrency && !config.optionalTokens?.includes(t) && !config.disabledTokens?.includes(t),
|
||||
);
|
||||
|
||||
schema.properties.instances = instances;
|
||||
if (netId === NetId.MAINNET) {
|
||||
_tokens.push('torn');
|
||||
}
|
||||
|
||||
if (netId === NetId.MAINNET) {
|
||||
const _tokens = Object.keys(tokens).filter((t) => t !== nativeCurrency);
|
||||
if (_tokens.length) {
|
||||
const ethPrices: statusEthPricesType = {
|
||||
type: 'object',
|
||||
properties: _tokens.reduce((acc: { [key in string]: typeof bnSchemaType }, token: string) => {
|
||||
acc[token] = bnSchemaType;
|
||||
return acc;
|
||||
}, {}),
|
||||
required: _tokens,
|
||||
};
|
||||
schema.properties.ethPrices = ethPrices;
|
||||
schema.required.push('ethPrices');
|
||||
}
|
||||
|
||||
const ethPrices: statusEthPricesType = {
|
||||
type: 'object',
|
||||
properties: _tokens.reduce((acc: { [key in string]: typeof bnType }, token: string) => {
|
||||
acc[token] = bnType;
|
||||
return acc;
|
||||
}, {}),
|
||||
// required: _tokens
|
||||
};
|
||||
schema.properties.ethPrices = ethPrices;
|
||||
// schema.required.push('ethPrices')
|
||||
}
|
||||
if (tovarish) {
|
||||
schema.required.push('gasPrices', 'latestBlock', 'latestBalance', 'syncStatus', 'onSyncEvents');
|
||||
}
|
||||
|
||||
return schema;
|
||||
return schema;
|
||||
}
|
||||
|
||||
15
src/schemas/types.ts
Normal file
15
src/schemas/types.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export const addressSchemaType = {
|
||||
type: 'string',
|
||||
pattern: '^0x[a-fA-F0-9]{40}$',
|
||||
isAddress: true,
|
||||
} as const;
|
||||
export const bnSchemaType = { type: 'string', BN: true } as const;
|
||||
export const proofSchemaType = {
|
||||
type: 'string',
|
||||
pattern: '^0x[a-fA-F0-9]{512}$',
|
||||
} as const;
|
||||
export const bytes32SchemaType = {
|
||||
type: 'string',
|
||||
pattern: '^0x[a-fA-F0-9]{64}$',
|
||||
} as const;
|
||||
export const bytes32BNSchemaType = { ...bytes32SchemaType, BN: true } as const;
|
||||
146
src/tokens.ts
146
src/tokens.ts
@@ -4,87 +4,87 @@ import { chunk } from './utils';
|
||||
import { Call3, multicall } from './multicall';
|
||||
|
||||
export interface tokenBalances {
|
||||
address: string;
|
||||
name: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
balance: bigint;
|
||||
address: string;
|
||||
name: string;
|
||||
symbol: string;
|
||||
decimals: number;
|
||||
balance: bigint;
|
||||
}
|
||||
|
||||
export async function getTokenBalances({
|
||||
provider,
|
||||
Multicall,
|
||||
currencyName,
|
||||
userAddress,
|
||||
tokenAddresses = [],
|
||||
provider,
|
||||
Multicall,
|
||||
currencyName,
|
||||
userAddress,
|
||||
tokenAddresses = [],
|
||||
}: {
|
||||
provider: Provider;
|
||||
Multicall: Multicall;
|
||||
currencyName: string;
|
||||
userAddress: string;
|
||||
tokenAddresses: string[];
|
||||
provider: Provider;
|
||||
Multicall: Multicall;
|
||||
currencyName: string;
|
||||
userAddress: string;
|
||||
tokenAddresses: string[];
|
||||
}): Promise<tokenBalances[]> {
|
||||
const tokenCalls = tokenAddresses
|
||||
.map((tokenAddress) => {
|
||||
const Token = ERC20__factory.connect(tokenAddress, provider);
|
||||
const tokenCalls = tokenAddresses
|
||||
.map((tokenAddress) => {
|
||||
const Token = ERC20__factory.connect(tokenAddress, provider);
|
||||
|
||||
return [
|
||||
return [
|
||||
{
|
||||
contract: Token,
|
||||
name: 'balanceOf',
|
||||
params: [userAddress],
|
||||
},
|
||||
{
|
||||
contract: Token,
|
||||
name: 'name',
|
||||
},
|
||||
{
|
||||
contract: Token,
|
||||
name: 'symbol',
|
||||
},
|
||||
{
|
||||
contract: Token,
|
||||
name: 'decimals',
|
||||
},
|
||||
];
|
||||
})
|
||||
.flat() as Call3[];
|
||||
|
||||
const multicallResults = await multicall(Multicall, [
|
||||
{
|
||||
contract: Token,
|
||||
name: 'balanceOf',
|
||||
params: [userAddress],
|
||||
contract: Multicall,
|
||||
name: 'getEthBalance',
|
||||
params: [userAddress],
|
||||
},
|
||||
...(tokenCalls.length ? tokenCalls : []),
|
||||
]);
|
||||
|
||||
const ethResults = multicallResults[0];
|
||||
const tokenResults = multicallResults.slice(1).length
|
||||
? chunk(multicallResults.slice(1), tokenCalls.length / tokenAddresses.length)
|
||||
: [];
|
||||
|
||||
const tokenBalances = tokenResults.map((tokenResult, index) => {
|
||||
const [tokenBalance, tokenName, tokenSymbol, tokenDecimals] = tokenResult;
|
||||
const tokenAddress = tokenAddresses[index];
|
||||
|
||||
return {
|
||||
address: tokenAddress,
|
||||
name: tokenName,
|
||||
symbol: tokenSymbol,
|
||||
decimals: Number(tokenDecimals),
|
||||
balance: tokenBalance,
|
||||
};
|
||||
});
|
||||
|
||||
return [
|
||||
{
|
||||
contract: Token,
|
||||
name: 'name',
|
||||
address: ZeroAddress,
|
||||
name: currencyName,
|
||||
symbol: currencyName,
|
||||
decimals: 18,
|
||||
balance: ethResults,
|
||||
},
|
||||
{
|
||||
contract: Token,
|
||||
name: 'symbol',
|
||||
},
|
||||
{
|
||||
contract: Token,
|
||||
name: 'decimals',
|
||||
},
|
||||
];
|
||||
})
|
||||
.flat() as Call3[];
|
||||
|
||||
const multicallResults = await multicall(Multicall, [
|
||||
{
|
||||
contract: Multicall,
|
||||
name: 'getEthBalance',
|
||||
params: [userAddress],
|
||||
},
|
||||
...(tokenCalls.length ? tokenCalls : []),
|
||||
]);
|
||||
|
||||
const ethResults = multicallResults[0];
|
||||
const tokenResults = multicallResults.slice(1).length
|
||||
? chunk(multicallResults.slice(1), tokenCalls.length / tokenAddresses.length)
|
||||
: [];
|
||||
|
||||
const tokenBalances = tokenResults.map((tokenResult, index) => {
|
||||
const [tokenBalance, tokenName, tokenSymbol, tokenDecimals] = tokenResult;
|
||||
const tokenAddress = tokenAddresses[index];
|
||||
|
||||
return {
|
||||
address: tokenAddress,
|
||||
name: tokenName,
|
||||
symbol: tokenSymbol,
|
||||
decimals: Number(tokenDecimals),
|
||||
balance: tokenBalance,
|
||||
};
|
||||
});
|
||||
|
||||
return [
|
||||
{
|
||||
address: ZeroAddress,
|
||||
name: currencyName,
|
||||
symbol: currencyName,
|
||||
decimals: 18,
|
||||
balance: ethResults,
|
||||
},
|
||||
...tokenBalances,
|
||||
];
|
||||
...tokenBalances,
|
||||
];
|
||||
}
|
||||
|
||||
399
src/tovarishClient.ts
Normal file
399
src/tovarishClient.ts
Normal file
@@ -0,0 +1,399 @@
|
||||
import { getAddress } from 'ethers';
|
||||
|
||||
import {
|
||||
RelayerClient,
|
||||
RelayerClientConstructor,
|
||||
RelayerError,
|
||||
RelayerInfo,
|
||||
RelayerStatus,
|
||||
getSupportedInstances,
|
||||
} from './relayerClient';
|
||||
import { fetchData } from './providers';
|
||||
import { CachedRelayerInfo, MinimalEvents } from './events';
|
||||
import { ajv, getEventsSchemaValidator, getStatusSchema } from './schemas';
|
||||
import { enabledChains, getConfig, NetId, NetIdType } from './networkConfig';
|
||||
|
||||
// Return no more than 5K events per query
|
||||
export const MAX_TOVARISH_EVENTS = 5000;
|
||||
|
||||
export interface EventsStatus {
|
||||
events: number;
|
||||
lastBlock: number;
|
||||
}
|
||||
|
||||
export interface TovarishEventsStatus {
|
||||
governance?: EventsStatus;
|
||||
registry?: EventsStatus;
|
||||
revenue?: EventsStatus;
|
||||
echo: EventsStatus;
|
||||
encrypted_notes: EventsStatus;
|
||||
tornado: EventsStatus;
|
||||
}
|
||||
|
||||
export interface TovarishSyncStatus {
|
||||
events: boolean;
|
||||
tokenPrice: boolean;
|
||||
gasPrice: boolean;
|
||||
}
|
||||
|
||||
// Expected response from /status endpoint
|
||||
export interface TovarishStatus extends RelayerStatus {
|
||||
latestBalance: string;
|
||||
events: TovarishEventsStatus;
|
||||
syncStatus: TovarishSyncStatus;
|
||||
onSyncEvents: boolean;
|
||||
}
|
||||
|
||||
// Formatted TovarishStatus for Frontend usage
|
||||
export interface TovarishInfo extends RelayerInfo {
|
||||
latestBlock: number;
|
||||
latestBalance: string;
|
||||
version: string;
|
||||
events: TovarishEventsStatus;
|
||||
syncStatus: TovarishSyncStatus;
|
||||
}
|
||||
|
||||
// Query input for TovarishEvents
|
||||
export interface TovarishEventsQuery {
|
||||
type: string;
|
||||
currency?: string;
|
||||
amount?: string;
|
||||
fromBlock: number;
|
||||
recent?: boolean;
|
||||
}
|
||||
|
||||
export interface BaseTovarishEvents<T> {
|
||||
events: T[];
|
||||
lastSyncBlock: number;
|
||||
}
|
||||
|
||||
export class TovarishClient extends RelayerClient {
|
||||
declare selectedRelayer?: TovarishInfo;
|
||||
|
||||
constructor(clientConstructor: RelayerClientConstructor) {
|
||||
super(clientConstructor);
|
||||
this.tovarish = true;
|
||||
}
|
||||
|
||||
async askRelayerStatus({
|
||||
hostname,
|
||||
url,
|
||||
relayerAddress,
|
||||
}: {
|
||||
hostname?: string;
|
||||
// optional url if entered manually
|
||||
url?: string;
|
||||
// relayerAddress from registry contract to prevent cheating
|
||||
relayerAddress?: string;
|
||||
}): Promise<TovarishStatus> {
|
||||
const status = (await super.askRelayerStatus({
|
||||
hostname,
|
||||
url,
|
||||
relayerAddress,
|
||||
})) as TovarishStatus;
|
||||
|
||||
if (!status.version.includes('tovarish')) {
|
||||
throw new Error('Not a tovarish relayer!');
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask status for all enabled chains for tovarish relayer
|
||||
*/
|
||||
async askAllStatus({
|
||||
hostname,
|
||||
url,
|
||||
relayerAddress,
|
||||
}: {
|
||||
hostname?: string;
|
||||
// optional url if entered manually
|
||||
url?: string;
|
||||
// relayerAddress from registry contract to prevent cheating
|
||||
relayerAddress?: string;
|
||||
}): Promise<TovarishStatus[]> {
|
||||
if (!url && hostname) {
|
||||
url = `https://${!hostname.endsWith('/') ? hostname + '/' : hostname}`;
|
||||
} else if (url && !url.endsWith('/')) {
|
||||
url += '/';
|
||||
} else {
|
||||
url = '';
|
||||
}
|
||||
|
||||
const statusArray = (await fetchData(`${url}status`, {
|
||||
...this.fetchDataOptions,
|
||||
headers: {
|
||||
'Content-Type': 'application/json, application/x-www-form-urlencoded',
|
||||
},
|
||||
timeout: 30000,
|
||||
maxRetry: this.fetchDataOptions?.torPort ? 2 : 0,
|
||||
})) as object;
|
||||
|
||||
if (!Array.isArray(statusArray)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const tovarishStatus: TovarishStatus[] = [];
|
||||
|
||||
for (const rawStatus of statusArray) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const netId = (rawStatus as any).netId as NetIdType;
|
||||
const config = getConfig(netId);
|
||||
|
||||
const statusValidator = ajv.compile(
|
||||
getStatusSchema(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(rawStatus as any).netId,
|
||||
config,
|
||||
this.tovarish,
|
||||
),
|
||||
);
|
||||
|
||||
if (!statusValidator) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const status = {
|
||||
...rawStatus,
|
||||
url: `${url}${netId}/`,
|
||||
} as TovarishStatus;
|
||||
|
||||
if (status.currentQueue > 5) {
|
||||
throw new Error('Withdrawal queue is overloaded');
|
||||
}
|
||||
|
||||
if (!enabledChains.includes(status.netId)) {
|
||||
throw new Error('This relayer serves a different network');
|
||||
}
|
||||
|
||||
if (relayerAddress && status.netId === NetId.MAINNET && status.rewardAccount !== relayerAddress) {
|
||||
throw new Error('The Relayer reward address must match registered address');
|
||||
}
|
||||
|
||||
if (!status.version.includes('tovarish')) {
|
||||
throw new Error('Not a tovarish relayer!');
|
||||
}
|
||||
|
||||
tovarishStatus.push(status);
|
||||
}
|
||||
|
||||
return tovarishStatus;
|
||||
}
|
||||
|
||||
async filterRelayer(relayer: CachedRelayerInfo): Promise<TovarishInfo | RelayerError | undefined> {
|
||||
const { ensName, relayerAddress, tovarishHost, tovarishNetworks } = relayer;
|
||||
|
||||
if (!tovarishHost || !tovarishNetworks?.includes(this.netId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const hostname = `${tovarishHost}/${this.netId}`;
|
||||
|
||||
try {
|
||||
const status = await this.askRelayerStatus({
|
||||
hostname,
|
||||
relayerAddress,
|
||||
});
|
||||
|
||||
return {
|
||||
netId: status.netId,
|
||||
url: status.url,
|
||||
hostname,
|
||||
ensName,
|
||||
relayerAddress,
|
||||
rewardAccount: getAddress(status.rewardAccount),
|
||||
instances: getSupportedInstances(status.instances),
|
||||
stakeBalance: relayer.stakeBalance,
|
||||
gasPrice: status.gasPrices?.fast,
|
||||
ethPrices: status.ethPrices,
|
||||
currentQueue: status.currentQueue,
|
||||
tornadoServiceFee: status.tornadoServiceFee,
|
||||
// Additional fields for tovarish relayer
|
||||
latestBlock: Number(status.latestBlock),
|
||||
latestBalance: status.latestBalance,
|
||||
version: status.version,
|
||||
events: status.events,
|
||||
syncStatus: status.syncStatus,
|
||||
} as TovarishInfo;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
return {
|
||||
hostname,
|
||||
relayerAddress,
|
||||
errorMessage: err.message,
|
||||
hasError: true,
|
||||
} as RelayerError;
|
||||
}
|
||||
}
|
||||
|
||||
async getValidRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: TovarishInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}> {
|
||||
const invalidRelayers: RelayerError[] = [];
|
||||
|
||||
const validRelayers = (await Promise.all(relayers.map((relayer) => this.filterRelayer(relayer)))).filter(
|
||||
(r) => {
|
||||
if (!r) {
|
||||
return false;
|
||||
}
|
||||
if ((r as RelayerError).hasError) {
|
||||
invalidRelayers.push(r as RelayerError);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
) as TovarishInfo[];
|
||||
|
||||
return {
|
||||
validRelayers,
|
||||
invalidRelayers,
|
||||
};
|
||||
}
|
||||
|
||||
async getTovarishRelayers(relayers: CachedRelayerInfo[]): Promise<{
|
||||
validRelayers: TovarishInfo[];
|
||||
invalidRelayers: RelayerError[];
|
||||
}> {
|
||||
const validRelayers: TovarishInfo[] = [];
|
||||
const invalidRelayers: RelayerError[] = [];
|
||||
|
||||
await Promise.all(
|
||||
relayers
|
||||
.filter((r) => r.tovarishHost && r.tovarishNetworks?.length)
|
||||
.map(async (relayer) => {
|
||||
const { ensName, relayerAddress, tovarishHost } = relayer;
|
||||
|
||||
try {
|
||||
const statusArray = await this.askAllStatus({
|
||||
hostname: tovarishHost as string,
|
||||
relayerAddress,
|
||||
});
|
||||
|
||||
for (const status of statusArray) {
|
||||
validRelayers.push({
|
||||
netId: status.netId,
|
||||
url: status.url,
|
||||
hostname: tovarishHost as string,
|
||||
ensName,
|
||||
relayerAddress,
|
||||
rewardAccount: getAddress(status.rewardAccount),
|
||||
instances: getSupportedInstances(status.instances),
|
||||
stakeBalance: relayer.stakeBalance,
|
||||
gasPrice: status.gasPrices?.fast,
|
||||
ethPrices: status.ethPrices,
|
||||
currentQueue: status.currentQueue,
|
||||
tornadoServiceFee: status.tornadoServiceFee,
|
||||
// Additional fields for tovarish relayer
|
||||
latestBlock: Number(status.latestBlock),
|
||||
latestBalance: status.latestBalance,
|
||||
version: status.version,
|
||||
events: status.events,
|
||||
syncStatus: status.syncStatus,
|
||||
});
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (err: any) {
|
||||
invalidRelayers.push({
|
||||
hostname: tovarishHost as string,
|
||||
relayerAddress,
|
||||
errorMessage: err.message,
|
||||
hasError: true,
|
||||
});
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
validRelayers,
|
||||
invalidRelayers,
|
||||
};
|
||||
}
|
||||
|
||||
async getEvents<T extends MinimalEvents>({
|
||||
type,
|
||||
currency,
|
||||
amount,
|
||||
fromBlock,
|
||||
recent,
|
||||
}: TovarishEventsQuery): Promise<BaseTovarishEvents<T>> {
|
||||
const url = `${this.selectedRelayer?.url}events`;
|
||||
|
||||
const schemaValidator = getEventsSchemaValidator(type);
|
||||
|
||||
try {
|
||||
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, {
|
||||
...this.fetchDataOptions,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
type,
|
||||
currency,
|
||||
amount,
|
||||
fromBlock,
|
||||
recent,
|
||||
}),
|
||||
})) as BaseTovarishEvents<T>;
|
||||
|
||||
if (!schemaValidator(fetchedEvents)) {
|
||||
const errMsg = `Schema validation failed for ${type} events`;
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
|
||||
if (recent) {
|
||||
return {
|
||||
events: fetchedEvents,
|
||||
lastSyncBlock: currentBlock,
|
||||
};
|
||||
}
|
||||
|
||||
lastSyncBlock = currentBlock;
|
||||
|
||||
if (!Array.isArray(fetchedEvents) || !fetchedEvents.length) {
|
||||
break;
|
||||
}
|
||||
|
||||
fetchedEvents = fetchedEvents.sort((a, b) => {
|
||||
if (a.blockNumber === b.blockNumber) {
|
||||
return a.logIndex - b.logIndex;
|
||||
}
|
||||
return a.blockNumber - b.blockNumber;
|
||||
});
|
||||
|
||||
const [lastEvent] = fetchedEvents.slice(-1);
|
||||
|
||||
if (fetchedEvents.length < MAX_TOVARISH_EVENTS - 100) {
|
||||
events.push(...fetchedEvents);
|
||||
break;
|
||||
}
|
||||
|
||||
fetchedEvents = fetchedEvents.filter((e) => e.blockNumber !== lastEvent.blockNumber);
|
||||
fromBlock = Number(lastEvent.blockNumber);
|
||||
|
||||
events.push(...fetchedEvents);
|
||||
}
|
||||
|
||||
return {
|
||||
events,
|
||||
lastSyncBlock,
|
||||
};
|
||||
} catch (err) {
|
||||
console.log('Error from TovarishClient events endpoint');
|
||||
console.log(err);
|
||||
return {
|
||||
events: [],
|
||||
lastSyncBlock: fromBlock,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
1486
src/typechain/ENSNameWrapper.ts
Normal file
1486
src/typechain/ENSNameWrapper.ts
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user