tornado-core 1.0.3

* Removed polygon gas oracle and use default oracle provided by ethers.js

* Simplify events saving process

* Use codeberg.org to fetch dependencies

* Update dependencies
This commit is contained in:
Tornado Contrib 2024-09-19 17:49:25 +00:00
parent 84b6ed368e
commit 95dbf208c3
Signed by: tornadocontrib
GPG Key ID: 60B4DF1A076C64B1
26 changed files with 37280 additions and 62507 deletions

1
.npmrc

@ -1 +0,0 @@
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/

10
dist/events/base.d.ts vendored

@ -3,7 +3,7 @@ import type { Tornado, TornadoRouter, TornadoProxyLight, Governance, RelayerRegi
import { BatchEventsService, BatchBlockService, BatchTransactionService, BatchEventOnProgress, BatchBlockOnProgress } from '../batch'; import { BatchEventsService, BatchBlockService, BatchTransactionService, BatchEventOnProgress, BatchBlockOnProgress } from '../batch';
import { fetchDataOptions } from '../providers'; import { fetchDataOptions } from '../providers';
import type { NetIdType } from '../networkConfig'; import type { NetIdType } from '../networkConfig';
import type { BaseEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, RegistersEvents, EchoEvents } from './types'; import type { BaseEvents, CachedEvents, MinimalEvents, DepositsEvents, WithdrawalsEvents, EncryptedNotesEvents, AllGovernanceEvents, RegistersEvents, EchoEvents } from './types';
export declare const DEPOSIT = "deposit"; export declare const DEPOSIT = "deposit";
export declare const WITHDRAWAL = "withdrawal"; export declare const WITHDRAWAL = "withdrawal";
export type BaseEventsServiceConstructor = { export type BaseEventsServiceConstructor = {
@ -38,7 +38,6 @@ export declare class BaseEventsService<EventType extends MinimalEvents> {
deployedBlock: number; deployedBlock: number;
batchEventsService: BatchEventsService; batchEventsService: BatchEventsService;
fetchDataOptions?: fetchDataOptions; fetchDataOptions?: fetchDataOptions;
saveEventsPromise?: Promise<void>;
constructor({ netId, provider, graphApi, subgraphName, contract, type, deployedBlock, fetchDataOptions, }: BaseEventsServiceConstructor); constructor({ netId, provider, graphApi, subgraphName, contract, type, deployedBlock, fetchDataOptions, }: BaseEventsServiceConstructor);
getInstanceName(): string; getInstanceName(): string;
getType(): string; getType(): string;
@ -53,8 +52,11 @@ export declare class BaseEventsService<EventType extends MinimalEvents> {
* Get saved or cached events * Get saved or cached events
*/ */
getEventsFromDB(): Promise<BaseEvents<EventType>>; getEventsFromDB(): Promise<BaseEvents<EventType>>;
getEventsFromCache(): Promise<BaseEvents<EventType>>; /**
getSavedEvents(): Promise<BaseEvents<EventType>>; * Events from remote cache (Either from local cache, CDN, or from IPFS)
*/
getEventsFromCache(): Promise<CachedEvents<EventType>>;
getSavedEvents(): Promise<BaseEvents<EventType> | CachedEvents<EventType>>;
/** /**
* Get latest events * Get latest events
*/ */

@ -3,6 +3,9 @@ export interface BaseEvents<T> {
events: T[]; events: T[];
lastBlock: number | null; lastBlock: number | null;
} }
export interface CachedEvents<T> extends BaseEvents<T> {
fromCache: boolean;
}
export interface BaseGraphEvents<T> { export interface BaseGraphEvents<T> {
events: T[]; events: T[];
lastSyncBlock: number; lastSyncBlock: number;

6425
dist/index.js vendored

File diff suppressed because it is too large Load Diff

6427
dist/index.mjs vendored

File diff suppressed because it is too large Load Diff

37861
dist/index.umd.js vendored

File diff suppressed because one or more lines are too long

18865
dist/merkleTreeWorker.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -67,8 +67,6 @@ export type Config = {
registryContract?: string; registryContract?: string;
aggregatorContract?: string; aggregatorContract?: string;
reverseRecordsContract?: string; reverseRecordsContract?: string;
gasPriceOracleContract?: string;
gasStationApi?: string;
ovmGasPriceOracleContract?: string; ovmGasPriceOracleContract?: string;
tornadoSubgraph: string; tornadoSubgraph: string;
registrySubgraph?: string; registrySubgraph?: string;
@ -90,7 +88,7 @@ export type networkConfig = {
[key in NetIdType]: Config; [key in NetIdType]: Config;
}; };
export declare const defaultConfig: networkConfig; export declare const defaultConfig: networkConfig;
export declare const enabledChains: number[]; export declare const enabledChains: NetIdType[];
/** /**
* Custom config object to extend default config * Custom config object to extend default config
* *

8
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 { EventEmitter } from 'stream';
import type { RequestOptions } from 'http'; 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 } from 'ethers';
import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch'; import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch';
import type { Config, NetIdType } from './networkConfig'; import type { Config, NetIdType } from './networkConfig';
declare global { declare global {
@ -36,10 +33,7 @@ export declare function fetchData(url: string, options?: fetchDataOptions): Prom
export declare const fetchGetUrlFunc: (options?: fetchDataOptions) => FetchGetUrlFunc; export declare const fetchGetUrlFunc: (options?: fetchDataOptions) => FetchGetUrlFunc;
export type getProviderOptions = fetchDataOptions & { export type getProviderOptions = fetchDataOptions & {
pollingInterval?: number; 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 getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider>;
export declare function getProviderWithNetId(netId: NetIdType, rpcUrl: string, config: Config, fetchOptions?: getProviderOptions): JsonRpcProvider; export declare function getProviderWithNetId(netId: NetIdType, rpcUrl: string, config: Config, fetchOptions?: getProviderOptions): JsonRpcProvider;
export declare const populateTransaction: (signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner, tx: TransactionRequest) => Promise<TransactionRequest>; export declare const populateTransaction: (signer: TornadoWallet | TornadoVoidSigner | TornadoRpcSigner, tx: TransactionRequest) => Promise<TransactionRequest>;

@ -1,6 +1,5 @@
export { ENS__factory } from "./ENS__factory"; export { ENS__factory } from "./ENS__factory";
export { ERC20__factory } from "./ERC20__factory"; export { ERC20__factory } from "./ERC20__factory";
export { GasPriceOracle__factory } from "./GasPriceOracle__factory";
export { Multicall__factory } from "./Multicall__factory"; export { Multicall__factory } from "./Multicall__factory";
export { OffchainOracle__factory } from "./OffchainOracle__factory"; export { OffchainOracle__factory } from "./OffchainOracle__factory";
export { OvmGasPriceOracle__factory } from "./OvmGasPriceOracle__factory"; export { OvmGasPriceOracle__factory } from "./OvmGasPriceOracle__factory";

@ -1,6 +1,5 @@
export type { ENS } from "./ENS"; export type { ENS } from "./ENS";
export type { ERC20 } from "./ERC20"; export type { ERC20 } from "./ERC20";
export type { GasPriceOracle } from "./GasPriceOracle";
export type { Multicall } from "./Multicall"; export type { Multicall } from "./Multicall";
export type { OffchainOracle } from "./OffchainOracle"; export type { OffchainOracle } from "./OffchainOracle";
export type { OvmGasPriceOracle } from "./OvmGasPriceOracle"; export type { OvmGasPriceOracle } from "./OvmGasPriceOracle";
@ -8,7 +7,6 @@ export type { ReverseRecords } from "./ReverseRecords";
export * as factories from "./factories"; export * as factories from "./factories";
export { ENS__factory } from "./factories/ENS__factory"; export { ENS__factory } from "./factories/ENS__factory";
export { ERC20__factory } from "./factories/ERC20__factory"; export { ERC20__factory } from "./factories/ERC20__factory";
export { GasPriceOracle__factory } from "./factories/GasPriceOracle__factory";
export { Multicall__factory } from "./factories/Multicall__factory"; export { Multicall__factory } from "./factories/Multicall__factory";
export { OffchainOracle__factory } from "./factories/OffchainOracle__factory"; export { OffchainOracle__factory } from "./factories/OffchainOracle__factory";
export { OvmGasPriceOracle__factory } from "./factories/OvmGasPriceOracle__factory"; export { OvmGasPriceOracle__factory } from "./factories/OvmGasPriceOracle__factory";

2
dist/utils.d.ts vendored

@ -1,5 +1,3 @@
/// <reference types="node" />
/// <reference types="node" />
import { webcrypto } from 'crypto'; import { webcrypto } from 'crypto';
import BN from 'bn.js'; import BN from 'bn.js';
import type { BigNumberish } from 'ethers'; import type { BigNumberish } from 'ethers';

@ -1,6 +1,6 @@
{ {
"name": "@tornado/core", "name": "@tornado/core",
"version": "1.0.2", "version": "1.0.3",
"description": "An SDK for building applications on top of Privacy Pools", "description": "An SDK for building applications on top of Privacy Pools",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.mjs", "module": "./dist/index.mjs",
@ -31,46 +31,44 @@
"yarn.lock" "yarn.lock"
], ],
"dependencies": { "dependencies": {
"@metamask/eth-sig-util": "^7.0.1", "@metamask/eth-sig-util": "^7.0.3",
"@tornado/contracts": "^1.0.0", "@tornado/contracts": "git+https://codeberg.org/tornadocash/tornado-contracts.git#6741664a898c1654e742459a2c20e52e4bc104fa",
"@tornado/fixed-merkle-tree": "^0.7.3", "@tornado/fixed-merkle-tree": "git+https://codeberg.org/tornadocash/fixed-merkle-tree.git#5c3fca4cb11255760ad5f4fd95d7c6eb45c1fc99",
"@tornado/snarkjs": "^0.1.20", "@tornado/snarkjs": "git+https://codeberg.org/tornadocash/snarkjs.git#d3915a760c437cde7bd317f9ea2c627954900656",
"@tornado/websnark": "^0.0.4", "@tornado/websnark": "git+https://codeberg.org/tornadocash/websnark.git#b0c9fce5359ceba55167a2ad01a29d1e137843ec",
"ajv": "^8.12.0", "ajv": "^8.17.1",
"bn.js": "^5.2.1", "bn.js": "^5.2.1",
"circomlibjs": "0.1.7", "circomlibjs": "0.1.7",
"cross-fetch": "^4.0.0", "cross-fetch": "^4.0.0",
"ethers": "^6.4.0", "ethers": "^6.13.2",
"ffjavascript": "0.2.48", "ffjavascript": "0.2.48",
"fflate": "^0.8.2" "fflate": "^0.8.2"
}, },
"optionalDependencies": {},
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^26.0.1",
"@rollup/plugin-json": "^6.1.0", "@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@typechain/ethers-v6": "^0.5.1", "@typechain/ethers-v6": "^0.5.1",
"@types/bn.js": "^5.1.5", "@types/bn.js": "^5.1.6",
"@types/circomlibjs": "^0.1.6", "@types/circomlibjs": "^0.1.6",
"@types/node": "^20.12.5", "@types/node": "^22.5.5",
"@types/node-fetch": "^2.6.11", "@types/node-fetch": "^2.6.11",
"@typescript-eslint/eslint-plugin": "^7.6.0", "@typescript-eslint/eslint-plugin": "8.6.0",
"@typescript-eslint/parser": "^7.6.0", "@typescript-eslint/parser": "^8.6.0",
"esbuild": "^0.20.2", "esbuild-loader": "^4.2.2",
"esbuild-loader": "^4.1.0", "eslint": "8.57.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0", "eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1", "eslint-import-resolver-typescript": "^3.6.3",
"eslint-plugin-import": "^2.29.1", "eslint-plugin-import": "^2.30.0",
"eslint-plugin-prettier": "^5.1.3", "eslint-plugin-prettier": "^5.2.1",
"node-polyfill-webpack-plugin": "^3.0.0", "node-polyfill-webpack-plugin": "^4.0.0",
"prettier": "^3.2.5", "prettier": "^3.3.3",
"rollup": "^4.14.1", "rollup": "^4.22.0",
"rollup-plugin-esbuild": "^6.1.1", "rollup-plugin-esbuild": "^6.1.1",
"tsc": "^2.0.4", "tsc": "^2.0.4",
"typechain": "^8.3.2", "typechain": "^8.3.2",
"typescript": "^5.4.4", "typescript": "^5.6.2",
"webpack": "^5.91.0", "webpack": "^5.94.0",
"webpack-cli": "^5.1.4" "webpack-cli": "^5.1.4"
} }
} }

@ -7,7 +7,7 @@ import { readFileSync } from 'fs';
const pkgJson = JSON.parse(readFileSync("./package.json")); const pkgJson = JSON.parse(readFileSync("./package.json"));
const external = Object.keys(pkgJson.dependencies).concat( const external = Object.keys(pkgJson.dependencies).concat(
Object.keys(pkgJson.optionalDependencies), Object.keys(pkgJson.optionalDependencies || {}),
[ [
'http-proxy-agent', 'http-proxy-agent',
'https-proxy-agent', 'https-proxy-agent',

@ -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"
}
]

@ -19,6 +19,7 @@ import { fetchDataOptions } from '../providers';
import type { NetIdType } from '../networkConfig'; import type { NetIdType } from '../networkConfig';
import type { import type {
BaseEvents, BaseEvents,
CachedEvents,
MinimalEvents, MinimalEvents,
DepositsEvents, DepositsEvents,
WithdrawalsEvents, WithdrawalsEvents,
@ -77,8 +78,6 @@ export class BaseEventsService<EventType extends MinimalEvents> {
batchEventsService: BatchEventsService; batchEventsService: BatchEventsService;
fetchDataOptions?: fetchDataOptions; fetchDataOptions?: fetchDataOptions;
saveEventsPromise?: Promise<void>;
constructor({ constructor({
netId, netId,
provider, provider,
@ -153,14 +152,18 @@ export class BaseEventsService<EventType extends MinimalEvents> {
}; };
} }
async getEventsFromCache(): Promise<BaseEvents<EventType>> { /**
* Events from remote cache (Either from local cache, CDN, or from IPFS)
*/
async getEventsFromCache(): Promise<CachedEvents<EventType>> {
return { return {
events: [], events: [],
lastBlock: null, lastBlock: null,
fromCache: true,
}; };
} }
async getSavedEvents(): Promise<BaseEvents<EventType>> { async getSavedEvents(): Promise<BaseEvents<EventType> | CachedEvents<EventType>> {
let cachedEvents = await this.getEventsFromDB(); let cachedEvents = await this.getEventsFromDB();
if (!cachedEvents || !cachedEvents.events.length) { if (!cachedEvents || !cachedEvents.events.length) {
@ -317,7 +320,10 @@ export class BaseEventsService<EventType extends MinimalEvents> {
this.validateEvents({ events: allEvents, lastBlock }); this.validateEvents({ events: allEvents, lastBlock });
this.saveEventsPromise = this.saveEvents({ events: allEvents, lastBlock }); // If the events are loaded from cache or we have found new events, save them
if ((savedEvents as CachedEvents<EventType>).fromCache || newEvents.events.length) {
await this.saveEvents({ events: allEvents, lastBlock });
}
return { return {
events: allEvents, events: allEvents,

@ -5,6 +5,10 @@ export interface BaseEvents<T> {
lastBlock: number | null; lastBlock: number | null;
} }
export interface CachedEvents<T> extends BaseEvents<T> {
fromCache: boolean;
}
export interface BaseGraphEvents<T> { export interface BaseGraphEvents<T> {
events: T[]; events: T[];
lastSyncBlock: number; lastSyncBlock: number;

@ -78,8 +78,6 @@ export type Config = {
registryContract?: string; registryContract?: string;
aggregatorContract?: string; aggregatorContract?: string;
reverseRecordsContract?: string; reverseRecordsContract?: string;
gasPriceOracleContract?: string;
gasStationApi?: string;
ovmGasPriceOracleContract?: string; ovmGasPriceOracleContract?: string;
tornadoSubgraph: string; tornadoSubgraph: string;
registrySubgraph?: string; registrySubgraph?: string;
@ -314,7 +312,6 @@ export const defaultConfig: networkConfig = {
routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17', routerContract: '0x0D5550d52428E7e3175bfc9550207e4ad3859b17',
echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', echoContract: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
offchainOracleContract: '0x0AdDd25a91563696D8567Df78D5A01C9a991F9B8', offchainOracleContract: '0x0AdDd25a91563696D8567Df78D5A01C9a991F9B8',
gasPriceOracleContract: '0xF81A8D8D3581985D3969fe53bFA67074aDFa8F3C',
tornadoSubgraph: 'tornadocash/matic-tornado-subgraph', tornadoSubgraph: 'tornadocash/matic-tornado-subgraph',
subgraphs: { subgraphs: {
tornado, tornado,

@ -17,17 +17,15 @@ import {
Eip1193Provider, Eip1193Provider,
VoidSigner, VoidSigner,
Network, Network,
parseUnits,
FetchUrlFeeDataNetworkPlugin,
FeeData, FeeData,
EnsPlugin, EnsPlugin,
GasCostPlugin, GasCostPlugin,
} from 'ethers'; } from 'ethers';
import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch'; import type { RequestInfo, RequestInit, Response, HeadersInit } from 'node-fetch';
import { GasPriceOracle, GasPriceOracle__factory, Multicall, Multicall__factory } from './typechain'; // Temporary workaround until @types/node-fetch is compatible with @types/node
import type { AbortSignal as FetchAbortSignal } from 'node-fetch/externals';
import { isNode, sleep } from './utils'; import { isNode, sleep } from './utils';
import type { Config, NetIdType } from './networkConfig'; import type { Config, NetIdType } from './networkConfig';
import { multicall } from './multicall';
declare global { declare global {
interface Window { interface Window {
@ -51,7 +49,7 @@ export type fetchDataOptions = RequestInit & {
timeout?: number; timeout?: number;
proxy?: string; proxy?: string;
torPort?: number; torPort?: number;
// eslint-disable-next-line @typescript-eslint/ban-types // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
debug?: Function; debug?: Function;
returnResponse?: boolean; returnResponse?: boolean;
}; };
@ -69,11 +67,11 @@ export function getHttpAgent({
torPort?: number; torPort?: number;
retry: number; retry: number;
}): NodeAgent | undefined { }): NodeAgent | undefined {
/* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-require-imports */
const { HttpProxyAgent } = require('http-proxy-agent'); const { HttpProxyAgent } = require('http-proxy-agent');
const { HttpsProxyAgent } = require('https-proxy-agent'); const { HttpsProxyAgent } = require('https-proxy-agent');
const { SocksProxyAgent } = require('socks-proxy-agent'); const { SocksProxyAgent } = require('socks-proxy-agent');
/* eslint-enable @typescript-eslint/no-var-requires */ /* eslint-enable @typescript-eslint/no-require-imports */
if (torPort) { if (torPort) {
return new SocksProxyAgent(`socks5h://tor${retry}@127.0.0.1:${torPort}`); return new SocksProxyAgent(`socks5h://tor${retry}@127.0.0.1:${torPort}`);
@ -128,7 +126,8 @@ export async function fetchData(url: string, options: fetchDataOptions = {}) {
if (!options.signal && options.timeout) { if (!options.signal && options.timeout) {
const controller = new AbortController(); const controller = new AbortController();
options.signal = controller.signal; // Temporary workaround until @types/node-fetch is compatible with @types/node
options.signal = controller.signal as FetchAbortSignal;
// Define timeout in seconds // Define timeout in seconds
timeout = setTimeout(() => { timeout = setTimeout(() => {
@ -223,7 +222,8 @@ export const fetchGetUrlFunc =
if (_signal) { if (_signal) {
const controller = new AbortController(); const controller = new AbortController();
signal = controller.signal; // Temporary workaround until @types/node-fetch is compatible with @types/node
signal = controller.signal as FetchAbortSignal;
_signal.addListener(() => { _signal.addListener(() => {
controller.abort(); controller.abort();
}); });
@ -257,113 +257,18 @@ export const fetchGetUrlFunc =
}; };
/* eslint-enable @typescript-eslint/no-explicit-any */ /* eslint-enable @typescript-eslint/no-explicit-any */
// caching to improve performance
const oracleMapper = new Map();
const multicallMapper = new Map();
export type getProviderOptions = fetchDataOptions & { export type getProviderOptions = fetchDataOptions & {
pollingInterval?: number; pollingInterval?: number;
gasPriceOracle?: string;
gasStationApi?: string;
}; };
export function getGasOraclePlugin(networkKey: string, fetchOptions?: getProviderOptions) {
const gasStationApi = fetchOptions?.gasStationApi || 'https://gasstation.polygon.technology/v2';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return new FetchUrlFeeDataNetworkPlugin(gasStationApi, async (fetchFeeData, provider, request) => {
if (!oracleMapper.has(networkKey)) {
oracleMapper.set(networkKey, GasPriceOracle__factory.connect(fetchOptions?.gasPriceOracle as string, provider));
}
if (!multicallMapper.has(networkKey)) {
multicallMapper.set(
networkKey,
Multicall__factory.connect('0xcA11bde05977b3631167028862bE2a173976CA11', provider),
);
}
const Oracle = oracleMapper.get(networkKey) as GasPriceOracle;
const Multicall = multicallMapper.get(networkKey) as Multicall;
const [timestamp, heartbeat, feePerGas, priorityFeePerGas] = await multicall(Multicall, [
{
contract: Oracle,
name: 'timestamp',
},
{
contract: Oracle,
name: 'heartbeat',
},
{
contract: Oracle,
name: 'maxFeePerGas',
},
{
contract: Oracle,
name: 'maxPriorityFeePerGas',
},
]);
const isOutdated = Number(timestamp) <= Date.now() / 1000 - Number(heartbeat);
if (!isOutdated) {
const maxPriorityFeePerGas = (priorityFeePerGas * BigInt(13)) / BigInt(10);
const maxFeePerGas = feePerGas * BigInt(2) + maxPriorityFeePerGas;
return {
gasPrice: maxFeePerGas,
maxFeePerGas,
maxPriorityFeePerGas,
};
}
const fetchReq = new FetchRequest(gasStationApi);
fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions);
if (isNode) {
// Prevent Cloudflare from blocking our request in node.js
fetchReq.setHeader('User-Agent', 'ethers');
}
const [
{
bodyJson: { fast },
},
{ gasPrice },
] = await Promise.all([fetchReq.send(), fetchFeeData()]);
return {
gasPrice,
maxFeePerGas: parseUnits(`${fast.maxFee}`, 9),
maxPriorityFeePerGas: parseUnits(`${fast.maxPriorityFee}`, 9),
};
});
}
export async function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider> { export async function getProvider(rpcUrl: string, fetchOptions?: getProviderOptions): Promise<JsonRpcProvider> {
const fetchReq = new FetchRequest(rpcUrl); const fetchReq = new FetchRequest(rpcUrl);
fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions); fetchReq.getUrlFunc = fetchGetUrlFunc(fetchOptions);
// omit network plugins and mimic registerEth function (required for polygon) const staticNetwork = await new JsonRpcProvider(fetchReq).getNetwork();
const _staticNetwork = await new JsonRpcProvider(fetchReq).getNetwork();
const ensPlugin = _staticNetwork.getPlugin('org.ethers.plugins.network.Ens');
const gasCostPlugin = _staticNetwork.getPlugin('org.ethers.plugins.network.GasCost');
const gasStationPlugin = <FetchUrlFeeDataNetworkPlugin>(
_staticNetwork.getPlugin('org.ethers.plugins.network.FetchUrlFeeDataPlugin')
);
const staticNetwork = new Network(_staticNetwork.name, _staticNetwork.chainId);
if (ensPlugin) {
staticNetwork.attachPlugin(ensPlugin);
}
if (gasCostPlugin) {
staticNetwork.attachPlugin(gasCostPlugin);
}
if (fetchOptions?.gasPriceOracle) {
staticNetwork.attachPlugin(getGasOraclePlugin(`${_staticNetwork.chainId}_${rpcUrl}`, fetchOptions));
} else if (gasStationPlugin) {
staticNetwork.attachPlugin(gasStationPlugin);
}
const provider = new JsonRpcProvider(fetchReq, staticNetwork, { const provider = new JsonRpcProvider(fetchReq, staticNetwork, {
staticNetwork, staticNetwork,
pollingInterval: fetchOptions?.pollingInterval || 1000,
}); });
provider.pollingInterval = fetchOptions?.pollingInterval || 1000;
return provider; return provider;
} }
@ -373,7 +278,7 @@ export function getProviderWithNetId(
config: Config, config: Config,
fetchOptions?: getProviderOptions, fetchOptions?: getProviderOptions,
): JsonRpcProvider { ): JsonRpcProvider {
const { networkName, reverseRecordsContract, gasPriceOracleContract, gasStationApi, pollInterval } = config; const { networkName, reverseRecordsContract, pollInterval } = config;
const hasEns = Boolean(reverseRecordsContract); const hasEns = Boolean(reverseRecordsContract);
const fetchReq = new FetchRequest(rpcUrl); const fetchReq = new FetchRequest(rpcUrl);
@ -382,24 +287,13 @@ export function getProviderWithNetId(
if (hasEns) { if (hasEns) {
staticNetwork.attachPlugin(new EnsPlugin(null, Number(netId))); staticNetwork.attachPlugin(new EnsPlugin(null, Number(netId)));
} }
staticNetwork.attachPlugin(new GasCostPlugin()); staticNetwork.attachPlugin(new GasCostPlugin());
if (gasPriceOracleContract) {
staticNetwork.attachPlugin(
getGasOraclePlugin(`${netId}_${rpcUrl}`, {
gasPriceOracle: gasPriceOracleContract,
gasStationApi,
}),
);
}
const provider = new JsonRpcProvider(fetchReq, staticNetwork, { const provider = new JsonRpcProvider(fetchReq, staticNetwork, {
staticNetwork, staticNetwork,
pollingInterval: fetchOptions?.pollingInterval || pollInterval * 1000,
}); });
provider.pollingInterval = fetchOptions?.pollingInterval || pollInterval * 1000;
return provider; return provider;
} }

@ -10,7 +10,7 @@ ajv.addKeyword({
try { try {
BigInt(data); BigInt(data);
return true; return true;
} catch (e) { } catch {
return false; return false;
} }
}, },

@ -3,7 +3,6 @@
/* eslint-disable */ /* eslint-disable */
export { ENS__factory } from "./ENS__factory"; export { ENS__factory } from "./ENS__factory";
export { ERC20__factory } from "./ERC20__factory"; export { ERC20__factory } from "./ERC20__factory";
export { GasPriceOracle__factory } from "./GasPriceOracle__factory";
export { Multicall__factory } from "./Multicall__factory"; export { Multicall__factory } from "./Multicall__factory";
export { OffchainOracle__factory } from "./OffchainOracle__factory"; export { OffchainOracle__factory } from "./OffchainOracle__factory";
export { OvmGasPriceOracle__factory } from "./OvmGasPriceOracle__factory"; export { OvmGasPriceOracle__factory } from "./OvmGasPriceOracle__factory";

@ -3,7 +3,6 @@
/* eslint-disable */ /* eslint-disable */
export type { ENS } from "./ENS"; export type { ENS } from "./ENS";
export type { ERC20 } from "./ERC20"; export type { ERC20 } from "./ERC20";
export type { GasPriceOracle } from "./GasPriceOracle";
export type { Multicall } from "./Multicall"; export type { Multicall } from "./Multicall";
export type { OffchainOracle } from "./OffchainOracle"; export type { OffchainOracle } from "./OffchainOracle";
export type { OvmGasPriceOracle } from "./OvmGasPriceOracle"; export type { OvmGasPriceOracle } from "./OvmGasPriceOracle";
@ -11,7 +10,6 @@ export type { ReverseRecords } from "./ReverseRecords";
export * as factories from "./factories"; export * as factories from "./factories";
export { ENS__factory } from "./factories/ENS__factory"; export { ENS__factory } from "./factories/ENS__factory";
export { ERC20__factory } from "./factories/ERC20__factory"; export { ERC20__factory } from "./factories/ERC20__factory";
export { GasPriceOracle__factory } from "./factories/GasPriceOracle__factory";
export { Multicall__factory } from "./factories/Multicall__factory"; export { Multicall__factory } from "./factories/Multicall__factory";
export { OffchainOracle__factory } from "./factories/OffchainOracle__factory"; export { OffchainOracle__factory } from "./factories/OffchainOracle__factory";
export { OvmGasPriceOracle__factory } from "./factories/OvmGasPriceOracle__factory"; export { OvmGasPriceOracle__factory } from "./factories/OvmGasPriceOracle__factory";

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

@ -1,4 +1,3 @@
const esbuild = require('esbuild');
const path = require('path'); const path = require('path');
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
@ -8,7 +7,6 @@ const esbuildLoader = {
options: { options: {
loader: 'ts', loader: 'ts',
target: 'es2016', target: 'es2016',
implementation: esbuild
} }
} }

1629
yarn.lock

File diff suppressed because it is too large Load Diff