@subql/node-ethereum 0.4.1-9 → 0.4.1-storeCache-0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -0
- package/README.md +3 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/ethereum/api.ethereum.d.ts +4 -1
- package/dist/ethereum/api.ethereum.js +31 -5
- package/dist/ethereum/api.ethereum.js.map +1 -1
- package/dist/ethereum/api.service.ethereum.js +1 -1
- package/dist/ethereum/api.service.ethereum.js.map +1 -1
- package/dist/ethereum/ethers/json-rpc-batch-provider.d.ts +21 -0
- package/dist/ethereum/ethers/json-rpc-batch-provider.js +102 -0
- package/dist/ethereum/ethers/json-rpc-batch-provider.js.map +1 -0
- package/dist/ethereum/ethers/json-rpc-provider.d.ts +7 -0
- package/dist/ethereum/ethers/json-rpc-provider.js +68 -0
- package/dist/ethereum/ethers/json-rpc-provider.js.map +1 -0
- package/dist/ethereum/ethers/web/_version.d.ts +1 -0
- package/dist/ethereum/ethers/web/_version.js +6 -0
- package/dist/ethereum/ethers/web/_version.js.map +1 -0
- package/dist/ethereum/ethers/web/geturl.d.ts +3 -0
- package/dist/ethereum/ethers/web/geturl.js +116 -0
- package/dist/ethereum/ethers/web/geturl.js.map +1 -0
- package/dist/ethereum/ethers/web/index.d.ts +49 -0
- package/dist/ethereum/ethers/web/index.js +433 -0
- package/dist/ethereum/ethers/web/index.js.map +1 -0
- package/dist/ethereum/ethers/web/types.d.ts +26 -0
- package/dist/ethereum/ethers/web/types.js +4 -0
- package/dist/ethereum/ethers/web/types.js.map +1 -0
- package/dist/ethereum/utils.ethereum.js +7 -5
- package/dist/ethereum/utils.ethereum.js.map +1 -1
- package/dist/indexer/blockDispatcher/block-dispatcher.service.d.ts +8 -15
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js +20 -108
- package/dist/indexer/blockDispatcher/block-dispatcher.service.js.map +1 -1
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.d.ts +4 -0
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.js +5 -0
- package/dist/indexer/blockDispatcher/ethereum-block-dispatcher.js.map +1 -0
- package/dist/indexer/blockDispatcher/index.d.ts +2 -2
- package/dist/indexer/blockDispatcher/index.js.map +1 -1
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.d.ts +12 -17
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js +48 -134
- package/dist/indexer/blockDispatcher/worker-block-dispatcher.service.js.map +1 -1
- package/dist/indexer/dynamic-ds.service.d.ts +3 -22
- package/dist/indexer/dynamic-ds.service.js +4 -91
- package/dist/indexer/dynamic-ds.service.js.map +1 -1
- package/dist/indexer/fetch.module.js +24 -6
- package/dist/indexer/fetch.module.js.map +1 -1
- package/dist/indexer/fetch.service.d.ts +3 -3
- package/dist/indexer/fetch.service.js +40 -39
- package/dist/indexer/fetch.service.js.map +1 -1
- package/dist/indexer/indexer.manager.d.ts +4 -16
- package/dist/indexer/indexer.manager.js +22 -61
- package/dist/indexer/indexer.manager.js.map +1 -1
- package/dist/indexer/indexer.module.js +25 -2
- package/dist/indexer/indexer.module.js.map +1 -1
- package/dist/indexer/project.service.d.ts +4 -10
- package/dist/indexer/project.service.js +45 -100
- package/dist/indexer/project.service.js.map +1 -1
- package/dist/indexer/sandbox.service.js +6 -1
- package/dist/indexer/sandbox.service.js.map +1 -1
- package/dist/indexer/unfinalizedBlocks.service.d.ts +12 -12
- package/dist/indexer/unfinalizedBlocks.service.js +33 -38
- package/dist/indexer/unfinalizedBlocks.service.js.map +1 -1
- package/dist/indexer/unfinalizedBlocks.spec.js +41 -34
- package/dist/indexer/unfinalizedBlocks.spec.js.map +1 -1
- package/dist/indexer/worker/worker.d.ts +22 -8
- package/dist/indexer/worker/worker.js +14 -7
- package/dist/indexer/worker/worker.js.map +1 -1
- package/dist/indexer/worker/worker.service.d.ts +2 -2
- package/dist/indexer/worker/worker.service.js +11 -4
- package/dist/indexer/worker/worker.service.js.map +1 -1
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.d.ts +11 -0
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js +32 -0
- package/dist/indexer/worker/worker.unfinalizedBlocks.service.js.map +1 -0
- package/dist/init.js +2 -2
- package/dist/init.js.map +1 -1
- package/dist/meta/meta.module.js +8 -0
- package/dist/meta/meta.module.js.map +1 -1
- package/dist/meta/meta.service.d.ts +18 -3
- package/dist/meta/meta.service.js +89 -5
- package/dist/meta/meta.service.js.map +1 -1
- package/dist/subcommands/forceClean.service.js +8 -4
- package/dist/subcommands/forceClean.service.js.map +1 -1
- package/dist/subcommands/reindex.init.js +5 -1
- package/dist/subcommands/reindex.init.js.map +1 -1
- package/dist/subcommands/reindex.module.js +8 -0
- package/dist/subcommands/reindex.module.js.map +1 -1
- package/dist/subcommands/reindex.service.d.ts +4 -1
- package/dist/subcommands/reindex.service.js +21 -10
- package/dist/subcommands/reindex.service.js.map +1 -1
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/reindex.d.ts +2 -1
- package/dist/utils/reindex.js +6 -2
- package/dist/utils/reindex.js.map +1 -1
- package/dist/utils/string.js +10 -2
- package/dist/utils/string.js.map +1 -1
- package/dist/yargs.d.ts +85 -53
- package/dist/yargs.js +103 -71
- package/dist/yargs.js.map +1 -1
- package/package.json +9 -9
- package/dist/indexer/blockDispatcher/base-block-dispatcher.d.ts +0 -40
- package/dist/indexer/blockDispatcher/base-block-dispatcher.js +0 -99
- package/dist/indexer/blockDispatcher/base-block-dispatcher.js.map +0 -1
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { Block, TransactionReceipt } from '@ethersproject/abstract-provider';
|
|
2
|
+
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
2
3
|
import { RuntimeDataSourceV0_2_0 } from '@subql/common-ethereum';
|
|
3
4
|
import { ApiWrapper, BlockWrapper, EthereumBlockWrapper, EthereumTransaction, EthereumResult, EthereumLog } from '@subql/types-ethereum';
|
|
4
5
|
import { EthereumBlockWrapped } from './block.ethereum';
|
|
5
6
|
export declare class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {
|
|
6
7
|
private endpoint;
|
|
8
|
+
private eventEmitter;
|
|
7
9
|
private client;
|
|
8
10
|
private genesisBlock;
|
|
9
11
|
private contractInterfaces;
|
|
10
12
|
private chainId;
|
|
11
13
|
private supportsFinalization;
|
|
12
|
-
constructor(endpoint: string);
|
|
14
|
+
constructor(endpoint: string, eventEmitter: EventEmitter2);
|
|
13
15
|
init(): Promise<void>;
|
|
16
|
+
private injectClient;
|
|
14
17
|
getFinalizedBlockHeight(): Promise<number>;
|
|
15
18
|
getBestBlockHeight(): Promise<number>;
|
|
16
19
|
getRuntimeChain(): string;
|
|
@@ -7,12 +7,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.EthereumApi = void 0;
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const http_1 = __importDefault(require("http"));
|
|
11
|
+
const https_1 = __importDefault(require("https"));
|
|
10
12
|
const abi_1 = require("@ethersproject/abi");
|
|
11
13
|
const providers_1 = require("@ethersproject/providers");
|
|
12
14
|
const node_core_1 = require("@subql/node-core");
|
|
13
15
|
const utils_1 = require("ethers/lib/utils");
|
|
14
16
|
const project_1 = require("../utils/project");
|
|
15
17
|
const block_ethereum_1 = require("./block.ethereum");
|
|
18
|
+
const json_rpc_batch_provider_1 = require("./ethers/json-rpc-batch-provider");
|
|
16
19
|
const safe_api_1 = __importDefault(require("./safe-api"));
|
|
17
20
|
const utils_ethereum_1 = require("./utils.ethereum");
|
|
18
21
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
@@ -34,25 +37,33 @@ async function loadAssets(ds) {
|
|
|
34
37
|
return res;
|
|
35
38
|
}
|
|
36
39
|
class EthereumApi {
|
|
37
|
-
constructor(endpoint) {
|
|
40
|
+
constructor(endpoint, eventEmitter) {
|
|
38
41
|
this.endpoint = endpoint;
|
|
42
|
+
this.eventEmitter = eventEmitter;
|
|
39
43
|
this.contractInterfaces = {};
|
|
40
44
|
// Ethereum POS
|
|
41
45
|
this.supportsFinalization = true;
|
|
42
46
|
const { hostname, pathname, port, protocol, searchParams } = new URL(endpoint);
|
|
43
47
|
const protocolStr = protocol.replace(':', '');
|
|
44
|
-
logger.info(
|
|
48
|
+
logger.info(`Api host: ${hostname}, method: ${protocolStr}`);
|
|
45
49
|
if (protocolStr === 'https' || protocolStr === 'http') {
|
|
46
50
|
const connection = {
|
|
47
51
|
url: this.endpoint.split('?')[0],
|
|
48
52
|
headers: {
|
|
49
53
|
'User-Agent': `Subquery-Node ${packageVersion}`,
|
|
50
54
|
},
|
|
55
|
+
allowGzip: true,
|
|
56
|
+
throttleLimit: 5,
|
|
57
|
+
throttleSlotInterval: 1,
|
|
58
|
+
agents: {
|
|
59
|
+
http: new http_1.default.Agent({ keepAlive: true /*, maxSockets: 100*/ }),
|
|
60
|
+
https: new https_1.default.Agent({ keepAlive: true /*, maxSockets: 100*/ }),
|
|
61
|
+
},
|
|
51
62
|
};
|
|
52
63
|
searchParams.forEach((value, name, searchParams) => {
|
|
53
64
|
connection.headers[name] = value;
|
|
54
65
|
});
|
|
55
|
-
this.client = new
|
|
66
|
+
this.client = new json_rpc_batch_provider_1.JsonRpcBatchProvider(connection);
|
|
56
67
|
}
|
|
57
68
|
else if (protocolStr === 'ws' || protocolStr === 'wss') {
|
|
58
69
|
this.client = new providers_1.WebSocketProvider(this.endpoint);
|
|
@@ -62,9 +73,19 @@ class EthereumApi {
|
|
|
62
73
|
}
|
|
63
74
|
}
|
|
64
75
|
async init() {
|
|
76
|
+
this.injectClient();
|
|
65
77
|
this.genesisBlock = await this.client.getBlock(0);
|
|
66
78
|
this.chainId = (await this.client.getNetwork()).chainId;
|
|
67
79
|
}
|
|
80
|
+
injectClient() {
|
|
81
|
+
const orig = this.client.send.bind(this.client);
|
|
82
|
+
Object.defineProperty(this.client, 'send', {
|
|
83
|
+
value: (...args) => {
|
|
84
|
+
this.eventEmitter.emit('rpcCall');
|
|
85
|
+
return orig(...args);
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
}
|
|
68
89
|
async getFinalizedBlockHeight() {
|
|
69
90
|
try {
|
|
70
91
|
if (this.supportsFinalization) {
|
|
@@ -104,7 +125,10 @@ class EthereumApi {
|
|
|
104
125
|
return this.client.getBlock(heightOrHash);
|
|
105
126
|
}
|
|
106
127
|
async getBlockPromise(num, includeTx = true) {
|
|
107
|
-
const rawBlock = await
|
|
128
|
+
const rawBlock = await this.client.send('eth_getBlockByNumber', [
|
|
129
|
+
(0, utils_1.hexValue)(num),
|
|
130
|
+
includeTx,
|
|
131
|
+
]);
|
|
108
132
|
const block = (0, utils_ethereum_1.formatBlock)(rawBlock);
|
|
109
133
|
block.stateRoot = this.client.formatter.hash(block.stateRoot);
|
|
110
134
|
return block;
|
|
@@ -120,11 +144,13 @@ class EthereumApi {
|
|
|
120
144
|
toBlock: (0, utils_1.hexValue)(blockNumber),
|
|
121
145
|
}),
|
|
122
146
|
]);
|
|
123
|
-
|
|
147
|
+
const ret = new block_ethereum_1.EthereumBlockWrapped(block, includeTx
|
|
124
148
|
? block.transactions.map((tx) => (Object.assign(Object.assign({}, (0, utils_ethereum_1.formatTransaction)(tx)), {
|
|
125
149
|
// TODO memoise
|
|
126
150
|
receipt: () => this.getTransactionReceipt(tx).then((r) => (0, utils_ethereum_1.formatReceipt)(r, block)) })))
|
|
127
151
|
: [], logs.map((l) => (0, utils_ethereum_1.formatLog)(l, block)));
|
|
152
|
+
this.eventEmitter.emit('fetchBlock');
|
|
153
|
+
return ret;
|
|
128
154
|
}
|
|
129
155
|
async fetchBlocks(bufferBlocks) {
|
|
130
156
|
return Promise.all(bufferBlocks.map(async (num) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.ethereum.js","sourceRoot":"","sources":["../../src/ethereum/api.ethereum.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport fs from 'fs';\nimport { Interface } from '@ethersproject/abi';\nimport { Block, TransactionReceipt } from '@ethersproject/abstract-provider';\nimport { JsonRpcProvider, WebSocketProvider } from '@ethersproject/providers';\nimport { RuntimeDataSourceV0_2_0 } from '@subql/common-ethereum';\nimport { getLogger } from '@subql/node-core';\nimport {\n ApiWrapper,\n BlockWrapper,\n EthereumBlockWrapper,\n EthereumTransaction,\n EthereumResult,\n EthereumLog,\n} from '@subql/types-ethereum';\nimport { ConnectionInfo, hexDataSlice, hexValue } from 'ethers/lib/utils';\nimport { retryOnFailEth } from '../utils/project';\nimport { EthereumBlockWrapped } from './block.ethereum';\nimport SafeEthProvider from './safe-api';\nimport {\n formatBlock,\n formatLog,\n formatReceipt,\n formatTransaction,\n} from './utils.ethereum';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.ethereum');\n\nasync function loadAssets(\n ds: RuntimeDataSourceV0_2_0,\n): Promise<Record<string, string>> {\n if (!ds.assets) {\n return {};\n }\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of Object.entries(ds.assets)) {\n try {\n res[name] = await fs.promises.readFile(file, { encoding: 'utf8' });\n } catch (e) {\n throw new Error(`Failed to load datasource asset ${file}`);\n }\n }\n\n return res;\n}\n\nexport class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {\n private client: JsonRpcProvider;\n private genesisBlock: Record<string, any>;\n private contractInterfaces: Record<string, Interface> = {};\n private chainId: number;\n\n // Ethereum POS\n private supportsFinalization = true;\n\n constructor(private endpoint: string) {\n const { hostname, pathname, port, protocol, searchParams } = new URL(\n endpoint,\n );\n\n const protocolStr = protocol.replace(':', '');\n\n logger.info(this.endpoint.split('?')[0]);\n if (protocolStr === 'https' || protocolStr === 'http') {\n const connection: ConnectionInfo = {\n url: this.endpoint.split('?')[0],\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n },\n };\n searchParams.forEach((value, name, searchParams) => {\n (connection.headers as any)[name] = value;\n });\n this.client = new JsonRpcProvider(connection);\n } else if (protocolStr === 'ws' || protocolStr === 'wss') {\n this.client = new WebSocketProvider(this.endpoint);\n } else {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n }\n\n async init(): Promise<void> {\n this.genesisBlock = await this.client.getBlock(0);\n\n this.chainId = (await this.client.getNetwork()).chainId;\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n try {\n if (this.supportsFinalization) {\n return (await this.client.getBlock('finalised')).number;\n } else {\n // TODO make number of blocks finalised configurable\n return (await this.getBestBlockHeight()) - 15; // Consider 15 blocks finalized\n }\n } catch (e) {\n // TODO handle specific error for this\n this.supportsFinalization = false;\n return this.getFinalizedBlockHeight();\n }\n }\n\n async getBestBlockHeight(): Promise<number> {\n const tag = this.supportsFinalization ? 'safe' : 'latest';\n return (await this.client.getBlock(tag)).number;\n }\n\n getRuntimeChain(): string {\n return 'ethereum';\n }\n\n getChainId(): number {\n return this.chainId;\n }\n\n getGenesisHash(): string {\n return this.genesisBlock.hash;\n }\n\n getSpecName(): string {\n return 'ethereum';\n }\n\n async getBlockByHeightOrHash(heightOrHash: number | string): Promise<Block> {\n if (typeof heightOrHash === 'number') {\n heightOrHash = hexValue(heightOrHash);\n }\n return this.client.getBlock(heightOrHash);\n }\n\n private async getBlockPromise(num: number, includeTx = true): Promise<any> {\n const rawBlock = await retryOnFailEth(() =>\n this.client.send('eth_getBlockByNumber', [hexValue(num), includeTx]),\n );\n\n const block = formatBlock(rawBlock);\n\n block.stateRoot = this.client.formatter.hash(block.stateRoot);\n\n return block;\n }\n\n async getTransactionReceipt(\n transactionHash: string | Promise<string>,\n ): Promise<TransactionReceipt> {\n return retryOnFailEth<TransactionReceipt>(\n this.client.getTransactionReceipt.bind(this.client, transactionHash),\n );\n }\n\n async fetchBlock(\n blockNumber: number,\n includeTx?: boolean,\n ): Promise<EthereumBlockWrapped> {\n const [block, logs] = await Promise.all([\n this.getBlockPromise(blockNumber, includeTx),\n this.client.getLogs({\n fromBlock: hexValue(blockNumber),\n toBlock: hexValue(blockNumber),\n }),\n ]);\n\n return new EthereumBlockWrapped(\n block,\n includeTx\n ? block.transactions.map((tx) => ({\n ...formatTransaction(tx),\n // TODO memoise\n receipt: () =>\n this.getTransactionReceipt(tx).then((r) =>\n formatReceipt(r, block),\n ),\n }))\n : [],\n logs.map((l) => formatLog(l, block)),\n );\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<EthereumBlockWrapper[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => {\n try {\n // Fetch Block\n return await this.fetchBlock(num, true);\n } catch (e) {\n // Wrap error from an axios error to fix issue with error being undefined\n const error = new Error(e.message);\n logger.error(e, `Failed to fetch block at height ${num}`);\n throw error;\n }\n }),\n );\n }\n\n freezeApi(processor: any, blockContent: BlockWrapper): void {\n processor.freeze(\n new SafeEthProvider(this.client, blockContent.blockHeight),\n 'api',\n );\n }\n\n private buildInterface(\n abiName: string,\n assets: Record<string, string>,\n ): Interface | undefined {\n if (!assets[abiName]) {\n throw new Error(`ABI named \"${abiName}\" not referenced in assets`);\n }\n\n // This assumes that all datasources have a different abi name or they are the same abi\n if (!this.contractInterfaces[abiName]) {\n // Constructing the interface validates the ABI\n try {\n let abiObj = JSON.parse(assets[abiName]);\n\n /*\n * Allows parsing JSON artifacts as well as ABIs\n * https://trufflesuite.github.io/artifact-updates/background.html#what-are-artifacts\n */\n if (!Array.isArray(abiObj) && abiObj.abi) {\n abiObj = abiObj.abi;\n }\n\n this.contractInterfaces[abiName] = new Interface(abiObj);\n } catch (e) {\n logger.error(`Unable to parse ABI: ${e.message}`);\n throw new Error('ABI is invalid');\n }\n }\n\n return this.contractInterfaces[abiName];\n }\n\n async parseLog<T extends EthereumResult = EthereumResult>(\n log: EthereumLog,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumLog<T> | EthereumLog> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return log;\n }\n const iface = this.buildInterface(ds.options.abi, await loadAssets(ds));\n return {\n ...log,\n args: iface?.parseLog(log).args as T,\n };\n } catch (e) {\n logger.warn(`Failed to parse log data: ${e.message}`);\n return log;\n }\n }\n\n async parseTransaction<T extends EthereumResult = EthereumResult>(\n transaction: EthereumTransaction,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumTransaction<T> | EthereumTransaction> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return transaction;\n }\n const assets = await loadAssets(ds);\n const iface = this.buildInterface(ds.options.abi, assets);\n const func = iface.getFunction(hexDataSlice(transaction.input, 0, 4));\n const args = iface.decodeFunctionData(func, transaction.input) as T;\n return {\n ...transaction,\n args,\n };\n } catch (e) {\n logger.warn(`Failed to parse transaction data: ${e.message}`);\n return transaction;\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"api.ethereum.js","sourceRoot":"","sources":["../../src/ethereum/api.ethereum.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport fs from 'fs';\nimport http from 'http';\nimport https from 'https';\nimport { Interface } from '@ethersproject/abi';\nimport { Block, TransactionReceipt } from '@ethersproject/abstract-provider';\nimport { WebSocketProvider } from '@ethersproject/providers';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { RuntimeDataSourceV0_2_0 } from '@subql/common-ethereum';\nimport { getLogger } from '@subql/node-core';\nimport {\n ApiWrapper,\n BlockWrapper,\n EthereumBlockWrapper,\n EthereumTransaction,\n EthereumResult,\n EthereumLog,\n} from '@subql/types-ethereum';\nimport { hexDataSlice, hexValue } from 'ethers/lib/utils';\nimport { retryOnFailEth } from '../utils/project';\nimport { EthereumBlockWrapped } from './block.ethereum';\nimport { JsonRpcBatchProvider } from './ethers/json-rpc-batch-provider';\nimport { JsonRpcProvider } from './ethers/json-rpc-provider';\nimport { ConnectionInfo } from './ethers/web';\nimport SafeEthProvider from './safe-api';\nimport {\n formatBlock,\n formatLog,\n formatReceipt,\n formatTransaction,\n} from './utils.ethereum';\n\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version: packageVersion } = require('../../package.json');\n\nconst logger = getLogger('api.ethereum');\n\nasync function loadAssets(\n ds: RuntimeDataSourceV0_2_0,\n): Promise<Record<string, string>> {\n if (!ds.assets) {\n return {};\n }\n const res: Record<string, string> = {};\n\n for (const [name, { file }] of Object.entries(ds.assets)) {\n try {\n res[name] = await fs.promises.readFile(file, { encoding: 'utf8' });\n } catch (e) {\n throw new Error(`Failed to load datasource asset ${file}`);\n }\n }\n\n return res;\n}\n\nexport class EthereumApi implements ApiWrapper<EthereumBlockWrapper> {\n private client: JsonRpcProvider;\n private genesisBlock: Record<string, any>;\n private contractInterfaces: Record<string, Interface> = {};\n private chainId: number;\n\n // Ethereum POS\n private supportsFinalization = true;\n\n constructor(private endpoint: string, private eventEmitter: EventEmitter2) {\n const { hostname, pathname, port, protocol, searchParams } = new URL(\n endpoint,\n );\n\n const protocolStr = protocol.replace(':', '');\n\n logger.info(`Api host: ${hostname}, method: ${protocolStr}`);\n if (protocolStr === 'https' || protocolStr === 'http') {\n const connection: ConnectionInfo = {\n url: this.endpoint.split('?')[0],\n headers: {\n 'User-Agent': `Subquery-Node ${packageVersion}`,\n },\n allowGzip: true,\n throttleLimit: 5,\n throttleSlotInterval: 1,\n agents: {\n http: new http.Agent({ keepAlive: true /*, maxSockets: 100*/ }),\n https: new https.Agent({ keepAlive: true /*, maxSockets: 100*/ }),\n },\n };\n searchParams.forEach((value, name, searchParams) => {\n (connection.headers as any)[name] = value;\n });\n this.client = new JsonRpcBatchProvider(connection);\n } else if (protocolStr === 'ws' || protocolStr === 'wss') {\n this.client = new WebSocketProvider(this.endpoint);\n } else {\n throw new Error(`Unsupported protocol: ${protocol}`);\n }\n }\n\n async init(): Promise<void> {\n this.injectClient();\n this.genesisBlock = await this.client.getBlock(0);\n\n this.chainId = (await this.client.getNetwork()).chainId;\n }\n\n private injectClient(): void {\n const orig = this.client.send.bind(this.client);\n Object.defineProperty(this.client, 'send', {\n value: (...args) => {\n this.eventEmitter.emit('rpcCall');\n return orig(...args);\n },\n });\n }\n\n async getFinalizedBlockHeight(): Promise<number> {\n try {\n if (this.supportsFinalization) {\n return (await this.client.getBlock('finalised')).number;\n } else {\n // TODO make number of blocks finalised configurable\n return (await this.getBestBlockHeight()) - 15; // Consider 15 blocks finalized\n }\n } catch (e) {\n // TODO handle specific error for this\n this.supportsFinalization = false;\n return this.getFinalizedBlockHeight();\n }\n }\n\n async getBestBlockHeight(): Promise<number> {\n const tag = this.supportsFinalization ? 'safe' : 'latest';\n return (await this.client.getBlock(tag)).number;\n }\n\n getRuntimeChain(): string {\n return 'ethereum';\n }\n\n getChainId(): number {\n return this.chainId;\n }\n\n getGenesisHash(): string {\n return this.genesisBlock.hash;\n }\n\n getSpecName(): string {\n return 'ethereum';\n }\n\n async getBlockByHeightOrHash(heightOrHash: number | string): Promise<Block> {\n if (typeof heightOrHash === 'number') {\n heightOrHash = hexValue(heightOrHash);\n }\n return this.client.getBlock(heightOrHash);\n }\n\n private async getBlockPromise(num: number, includeTx = true): Promise<any> {\n const rawBlock = await this.client.send('eth_getBlockByNumber', [\n hexValue(num),\n includeTx,\n ]);\n\n const block = formatBlock(rawBlock);\n\n block.stateRoot = this.client.formatter.hash(block.stateRoot);\n\n return block;\n }\n\n async getTransactionReceipt(\n transactionHash: string | Promise<string>,\n ): Promise<TransactionReceipt> {\n return retryOnFailEth<TransactionReceipt>(\n this.client.getTransactionReceipt.bind(this.client, transactionHash),\n );\n }\n\n async fetchBlock(\n blockNumber: number,\n includeTx?: boolean,\n ): Promise<EthereumBlockWrapped> {\n const [block, logs] = await Promise.all([\n this.getBlockPromise(blockNumber, includeTx),\n this.client.getLogs({\n fromBlock: hexValue(blockNumber),\n toBlock: hexValue(blockNumber),\n }),\n ]);\n\n const ret = new EthereumBlockWrapped(\n block,\n includeTx\n ? block.transactions.map((tx) => ({\n ...formatTransaction(tx),\n // TODO memoise\n receipt: () =>\n this.getTransactionReceipt(tx).then((r) =>\n formatReceipt(r, block),\n ),\n }))\n : [],\n logs.map((l) => formatLog(l, block)),\n );\n this.eventEmitter.emit('fetchBlock');\n return ret;\n }\n\n async fetchBlocks(bufferBlocks: number[]): Promise<EthereumBlockWrapper[]> {\n return Promise.all(\n bufferBlocks.map(async (num) => {\n try {\n // Fetch Block\n return await this.fetchBlock(num, true);\n } catch (e) {\n // Wrap error from an axios error to fix issue with error being undefined\n const error = new Error(e.message);\n logger.error(e, `Failed to fetch block at height ${num}`);\n throw error;\n }\n }),\n );\n }\n\n freezeApi(processor: any, blockContent: BlockWrapper): void {\n processor.freeze(\n new SafeEthProvider(this.client, blockContent.blockHeight),\n 'api',\n );\n }\n\n private buildInterface(\n abiName: string,\n assets: Record<string, string>,\n ): Interface | undefined {\n if (!assets[abiName]) {\n throw new Error(`ABI named \"${abiName}\" not referenced in assets`);\n }\n\n // This assumes that all datasources have a different abi name or they are the same abi\n if (!this.contractInterfaces[abiName]) {\n // Constructing the interface validates the ABI\n try {\n let abiObj = JSON.parse(assets[abiName]);\n\n /*\n * Allows parsing JSON artifacts as well as ABIs\n * https://trufflesuite.github.io/artifact-updates/background.html#what-are-artifacts\n */\n if (!Array.isArray(abiObj) && abiObj.abi) {\n abiObj = abiObj.abi;\n }\n\n this.contractInterfaces[abiName] = new Interface(abiObj);\n } catch (e) {\n logger.error(`Unable to parse ABI: ${e.message}`);\n throw new Error('ABI is invalid');\n }\n }\n\n return this.contractInterfaces[abiName];\n }\n\n async parseLog<T extends EthereumResult = EthereumResult>(\n log: EthereumLog,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumLog<T> | EthereumLog> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return log;\n }\n const iface = this.buildInterface(ds.options.abi, await loadAssets(ds));\n return {\n ...log,\n args: iface?.parseLog(log).args as T,\n };\n } catch (e) {\n logger.warn(`Failed to parse log data: ${e.message}`);\n return log;\n }\n }\n\n async parseTransaction<T extends EthereumResult = EthereumResult>(\n transaction: EthereumTransaction,\n ds: RuntimeDataSourceV0_2_0,\n ): Promise<EthereumTransaction<T> | EthereumTransaction> {\n try {\n if (!ds?.options?.abi) {\n logger.warn('No ABI provided for datasource');\n return transaction;\n }\n const assets = await loadAssets(ds);\n const iface = this.buildInterface(ds.options.abi, assets);\n const func = iface.getFunction(hexDataSlice(transaction.input, 0, 4));\n const args = iface.decodeFunctionData(func, transaction.input) as T;\n return {\n ...transaction,\n args,\n };\n } catch (e) {\n logger.warn(`Failed to parse transaction data: ${e.message}`);\n return transaction;\n }\n }\n}\n"]}
|
|
@@ -36,7 +36,7 @@ let EthereumApiService = class EthereumApiService extends node_core_1.ApiService
|
|
|
36
36
|
logger.error(Object.keys(e));
|
|
37
37
|
process.exit(1);
|
|
38
38
|
}
|
|
39
|
-
this.api = new api_ethereum_1.EthereumApi(network.endpoint);
|
|
39
|
+
this.api = new api_ethereum_1.EthereumApi(network.endpoint, this.eventEmitter);
|
|
40
40
|
await this.api.init();
|
|
41
41
|
this.networkMeta = {
|
|
42
42
|
chain: this.api.getRuntimeChain(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.service.ethereum.js","sourceRoot":"","sources":["../../src/ethereum/api.service.ethereum.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,2CAAoD;AACpD,yDAAsD;AAEtD,gDAAyD;AACzD,kEAA+D;AAC/D,iDAA6C;AAE7C,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,KAAK,CAAC,CAAC;AAGzB,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,sBAAU;IAChD,YAC8B,OAAwB,EAC5C,YAA2B;QAEnC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFP,iBAAY,GAAZ,YAAY,CAAe;IAGrC,CAAC;IAGD,KAAK,CAAC,IAAI;QACR,IAAI;YACF,IAAI,OAA6B,CAAC;YAClC,IAAI;gBACF,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;aAChC;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;YAED,IAAI,CAAC,GAAG,GAAG,IAAI,0BAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"api.service.ethereum.js","sourceRoot":"","sources":["../../src/ethereum/api.service.ethereum.ts"],"names":[],"mappings":";AAAA,gEAAgE;AAChE,sCAAsC;;;;;;;;;;;;;;;AAEtC,2CAAoD;AACpD,yDAAsD;AAEtD,gDAAyD;AACzD,kEAA+D;AAC/D,iDAA6C;AAE7C,MAAM,MAAM,GAAG,IAAA,qBAAS,EAAC,KAAK,CAAC,CAAC;AAGzB,IAAM,kBAAkB,GAAxB,MAAM,kBAAmB,SAAQ,sBAAU;IAChD,YAC8B,OAAwB,EAC5C,YAA2B;QAEnC,KAAK,CAAC,OAAO,CAAC,CAAC;QAFP,iBAAY,GAAZ,YAAY,CAAe;IAGrC,CAAC;IAGD,KAAK,CAAC,IAAI;QACR,IAAI;YACF,IAAI,OAA6B,CAAC;YAClC,IAAI;gBACF,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;aAChC;YAAC,OAAO,CAAC,EAAE;gBACV,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;aACjB;YAED,IAAI,CAAC,GAAG,GAAG,IAAI,0BAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YAEhE,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,WAAW,GAAG;gBACjB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE;gBACjC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;gBAChC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE;aACvC,CAAC;YAEF,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE;gBACxD,MAAM,GAAG,GAAG,IAAI,KAAK,CACnB,6DACE,OAAO,CAAC,OACV,aAAa,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CACrC,CAAC;gBACF,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC/B,MAAM,GAAG,CAAC;aACX;YAED,OAAO,IAAI,CAAC;SACb;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,4BAA4B,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;SACjB;IACH,CAAC;IAED,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,IAAY,GAAG,CAAC,KAAkB;QAChC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC;IACpB,CAAC;CACF,CAAA;AApDY,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,kBAAkB,CAAC,CAAA;qCAAU,iCAAe;QAC9B,6BAAa;GAH1B,kBAAkB,CAoD9B;AApDY,gDAAkB","sourcesContent":["// Copyright 2020-2022 OnFinality Limited authors & contributors\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Inject, Injectable } from '@nestjs/common';\nimport { EventEmitter2 } from '@nestjs/event-emitter';\nimport { ProjectNetworkV1_0_0 } from '@subql/common-ethereum';\nimport { ApiService, getLogger } from '@subql/node-core';\nimport { SubqueryProject } from '../configure/SubqueryProject';\nimport { EthereumApi } from './api.ethereum';\n\nconst logger = getLogger('api');\n\n@Injectable()\nexport class EthereumApiService extends ApiService {\n constructor(\n @Inject('ISubqueryProject') project: SubqueryProject,\n private eventEmitter: EventEmitter2,\n ) {\n super(project);\n }\n private _api: EthereumApi;\n\n async init(): Promise<EthereumApiService> {\n try {\n let network: ProjectNetworkV1_0_0;\n try {\n network = this.project.network;\n } catch (e) {\n logger.error(Object.keys(e));\n process.exit(1);\n }\n\n this.api = new EthereumApi(network.endpoint, this.eventEmitter);\n\n await this.api.init();\n this.networkMeta = {\n chain: this.api.getRuntimeChain(),\n specName: this.api.getSpecName(),\n genesisHash: this.api.getGenesisHash(),\n };\n\n if (network.chainId !== this.api.getChainId().toString()) {\n const err = new Error(\n `Network chainId doesn't match expected chainId. expected=\"${\n network.chainId\n }\" actual=\"${this.api.getChainId()}`,\n );\n logger.error(err, err.message);\n throw err;\n }\n\n return this;\n } catch (e) {\n logger.error(e, 'Failed to init api service');\n process.exit(1);\n }\n }\n\n get api(): EthereumApi {\n return this._api;\n }\n\n private set api(value: EthereumApi) {\n this._api = value;\n }\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { JsonRpcProvider } from '@ethersproject/providers';
|
|
3
|
+
import { Networkish } from '@ethersproject/networks';
|
|
4
|
+
import { ConnectionInfo } from './web';
|
|
5
|
+
export declare class JsonRpcBatchProvider extends JsonRpcProvider {
|
|
6
|
+
_pendingBatchAggregator: NodeJS.Timer;
|
|
7
|
+
_pendingBatch: Array<{
|
|
8
|
+
request: {
|
|
9
|
+
method: string;
|
|
10
|
+
params: Array<any>;
|
|
11
|
+
id: number;
|
|
12
|
+
jsonrpc: '2.0';
|
|
13
|
+
};
|
|
14
|
+
resolve: (result: any) => void;
|
|
15
|
+
reject: (error: Error) => void;
|
|
16
|
+
}>;
|
|
17
|
+
constructor(url: string | ConnectionInfo, network?: Networkish);
|
|
18
|
+
send(method: string, params: Array<any>): Promise<any>;
|
|
19
|
+
flush(): void;
|
|
20
|
+
private runRequests;
|
|
21
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JsonRpcBatchProvider = void 0;
|
|
4
|
+
/* eslint-disable */
|
|
5
|
+
const properties_1 = require("@ethersproject/properties");
|
|
6
|
+
const web_1 = require("@ethersproject/web");
|
|
7
|
+
const providers_1 = require("@ethersproject/providers");
|
|
8
|
+
// Experimental
|
|
9
|
+
class JsonRpcBatchProvider extends providers_1.JsonRpcProvider {
|
|
10
|
+
constructor(url, network) {
|
|
11
|
+
super(url, network);
|
|
12
|
+
}
|
|
13
|
+
send(method, params) {
|
|
14
|
+
const request = {
|
|
15
|
+
method: method,
|
|
16
|
+
params: params,
|
|
17
|
+
id: this._nextId++,
|
|
18
|
+
jsonrpc: '2.0',
|
|
19
|
+
};
|
|
20
|
+
if (this._pendingBatch == null) {
|
|
21
|
+
this._pendingBatch = [];
|
|
22
|
+
}
|
|
23
|
+
const inflightRequest = { request, resolve: null, reject: null };
|
|
24
|
+
const promise = new Promise((resolve, reject) => {
|
|
25
|
+
inflightRequest.resolve = resolve;
|
|
26
|
+
inflightRequest.reject = reject;
|
|
27
|
+
});
|
|
28
|
+
this._pendingBatch.push(inflightRequest);
|
|
29
|
+
if (!this._pendingBatchAggregator) {
|
|
30
|
+
// Schedule batch for next event loop + short duration
|
|
31
|
+
this._pendingBatchAggregator = setTimeout(() => {
|
|
32
|
+
this.runRequests();
|
|
33
|
+
}, 1);
|
|
34
|
+
}
|
|
35
|
+
if (this._pendingBatch.length > 10) {
|
|
36
|
+
this.flush();
|
|
37
|
+
}
|
|
38
|
+
return promise;
|
|
39
|
+
}
|
|
40
|
+
flush() {
|
|
41
|
+
if (this._pendingBatchAggregator) {
|
|
42
|
+
clearTimeout(this._pendingBatchAggregator);
|
|
43
|
+
this.runRequests();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
runRequests() {
|
|
47
|
+
// Get teh current batch and clear it, so new requests
|
|
48
|
+
// go into the next batch
|
|
49
|
+
const batch = this._pendingBatch;
|
|
50
|
+
this._pendingBatch = null;
|
|
51
|
+
this._pendingBatchAggregator = null;
|
|
52
|
+
// Get the request as an array of requests
|
|
53
|
+
const request = batch.map((inflight) => inflight.request);
|
|
54
|
+
this.emit('debug', {
|
|
55
|
+
action: 'requestBatch',
|
|
56
|
+
request: (0, properties_1.deepCopy)(request),
|
|
57
|
+
provider: this,
|
|
58
|
+
});
|
|
59
|
+
return (0, web_1.fetchJson)(this.connection, JSON.stringify(request)).then((result) => {
|
|
60
|
+
this.emit('debug', {
|
|
61
|
+
action: 'response',
|
|
62
|
+
request: request,
|
|
63
|
+
response: result,
|
|
64
|
+
provider: this,
|
|
65
|
+
});
|
|
66
|
+
// if (!Array.isArray(result)) {
|
|
67
|
+
// result = [result];
|
|
68
|
+
// }
|
|
69
|
+
// https://github.com/ethers-io/ethers.js/pull/2657
|
|
70
|
+
const resultMap = result.reduce((resultMap, payload) => {
|
|
71
|
+
resultMap[payload.id] = payload;
|
|
72
|
+
return resultMap;
|
|
73
|
+
}, {});
|
|
74
|
+
// For each result, feed it to the correct Promise, depending
|
|
75
|
+
// on whether it was a success or error
|
|
76
|
+
batch.forEach((inflightRequest) => {
|
|
77
|
+
const payload = resultMap[inflightRequest.request.id];
|
|
78
|
+
if (payload.error) {
|
|
79
|
+
const error = new Error(payload.error.message);
|
|
80
|
+
error.code = payload.error.code;
|
|
81
|
+
error.data = payload.error.data;
|
|
82
|
+
inflightRequest.reject(error);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
inflightRequest.resolve(payload.result);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
} /*).catch(*/, (error) => {
|
|
89
|
+
this.emit('debug', {
|
|
90
|
+
action: 'response',
|
|
91
|
+
error: error,
|
|
92
|
+
request: request,
|
|
93
|
+
provider: this,
|
|
94
|
+
});
|
|
95
|
+
batch.forEach((inflightRequest) => {
|
|
96
|
+
inflightRequest.reject(error);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.JsonRpcBatchProvider = JsonRpcBatchProvider;
|
|
102
|
+
//# sourceMappingURL=json-rpc-batch-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-rpc-batch-provider.js","sourceRoot":"","sources":["../../../src/ethereum/ethers/json-rpc-batch-provider.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable */\nimport { deepCopy } from '@ethersproject/properties';\nimport { fetchJson } from '@ethersproject/web';\n\nimport { JsonRpcProvider } from '@ethersproject/providers';\nimport { Networkish } from '@ethersproject/networks';\nimport { ConnectionInfo } from './web';\n\ninterface RpcResult {\n jsonrpc: '2.0';\n id: number;\n result?: string;\n error?: {\n code: number;\n message: string;\n data?: any;\n };\n}\n\n// Experimental\n\nexport class JsonRpcBatchProvider extends JsonRpcProvider {\n _pendingBatchAggregator: NodeJS.Timer;\n _pendingBatch: Array<{\n request: { method: string; params: Array<any>; id: number; jsonrpc: '2.0' };\n resolve: (result: any) => void;\n reject: (error: Error) => void;\n }>;\n\n constructor(url: string | ConnectionInfo, network?: Networkish) {\n super(url, network);\n }\n\n send(method: string, params: Array<any>): Promise<any> {\n const request = {\n method: method,\n params: params,\n id: this._nextId++,\n jsonrpc: '2.0',\n };\n\n if (this._pendingBatch == null) {\n this._pendingBatch = [];\n }\n\n const inflightRequest: any = { request, resolve: null, reject: null };\n\n const promise = new Promise((resolve, reject) => {\n inflightRequest.resolve = resolve;\n inflightRequest.reject = reject;\n });\n\n this._pendingBatch.push(inflightRequest);\n\n if (!this._pendingBatchAggregator) {\n // Schedule batch for next event loop + short duration\n this._pendingBatchAggregator = setTimeout(() => {\n this.runRequests();\n }, 1);\n }\n\n if (this._pendingBatch.length > 10) {\n this.flush();\n }\n\n return promise;\n }\n\n flush(): void {\n if (this._pendingBatchAggregator) {\n clearTimeout(this._pendingBatchAggregator);\n this.runRequests();\n }\n }\n\n private runRequests() {\n // Get teh current batch and clear it, so new requests\n // go into the next batch\n const batch = this._pendingBatch;\n this._pendingBatch = null;\n this._pendingBatchAggregator = null;\n\n // Get the request as an array of requests\n const request = batch.map((inflight) => inflight.request);\n\n this.emit('debug', {\n action: 'requestBatch',\n request: deepCopy(request),\n provider: this,\n });\n\n return fetchJson(this.connection, JSON.stringify(request)).then(\n (result: RpcResult[]) => {\n this.emit('debug', {\n action: 'response',\n request: request,\n response: result,\n provider: this,\n });\n\n // if (!Array.isArray(result)) {\n // result = [result];\n // }\n\n // https://github.com/ethers-io/ethers.js/pull/2657\n const resultMap = result.reduce((resultMap, payload) => {\n resultMap[payload.id] = payload;\n return resultMap;\n }, {} as Record<number, RpcResult>);\n\n // For each result, feed it to the correct Promise, depending\n // on whether it was a success or error\n batch.forEach((inflightRequest) => {\n const payload = resultMap[inflightRequest.request.id];\n if (payload.error) {\n const error = new Error(payload.error.message);\n (<any>error).code = payload.error.code;\n (<any>error).data = payload.error.data;\n inflightRequest.reject(error);\n } else {\n inflightRequest.resolve(payload.result);\n }\n });\n } /*).catch(*/,\n (error) => {\n this.emit('debug', {\n action: 'response',\n error: error,\n request: request,\n provider: this,\n });\n\n batch.forEach((inflightRequest) => {\n inflightRequest.reject(error);\n });\n },\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { JsonRpcProvider as BaseJsonRpcProvider } from '@ethersproject/providers';
|
|
2
|
+
import { Networkish } from '@ethersproject/networks';
|
|
3
|
+
import { ConnectionInfo } from './web';
|
|
4
|
+
export declare class JsonRpcProvider extends BaseJsonRpcProvider {
|
|
5
|
+
constructor(url: string | ConnectionInfo, network?: Networkish);
|
|
6
|
+
send(method: string, params: Array<any>): Promise<any>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JsonRpcProvider = void 0;
|
|
4
|
+
/* eslint-disable */
|
|
5
|
+
const properties_1 = require("@ethersproject/properties");
|
|
6
|
+
const web_1 = require("@ethersproject/web");
|
|
7
|
+
const providers_1 = require("@ethersproject/providers");
|
|
8
|
+
function getResult(payload) {
|
|
9
|
+
if (payload.error) {
|
|
10
|
+
// @TODO: not any
|
|
11
|
+
const error = new Error(payload.error.message);
|
|
12
|
+
error.code = payload.error.code;
|
|
13
|
+
error.data = payload.error.data;
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
return payload.result;
|
|
17
|
+
}
|
|
18
|
+
class JsonRpcProvider extends providers_1.JsonRpcProvider {
|
|
19
|
+
constructor(url, network) {
|
|
20
|
+
super(url, network);
|
|
21
|
+
}
|
|
22
|
+
send(method, params) {
|
|
23
|
+
const request = {
|
|
24
|
+
method: method,
|
|
25
|
+
params: params,
|
|
26
|
+
id: this._nextId++,
|
|
27
|
+
jsonrpc: '2.0',
|
|
28
|
+
};
|
|
29
|
+
this.emit('debug', {
|
|
30
|
+
action: 'request',
|
|
31
|
+
request: (0, properties_1.deepCopy)(request),
|
|
32
|
+
provider: this,
|
|
33
|
+
});
|
|
34
|
+
// We can expand this in the future to any call, but for now these
|
|
35
|
+
// are the biggest wins and do not require any serializing parameters.
|
|
36
|
+
const cache = ['eth_chainId', 'eth_blockNumber'].indexOf(method) >= 0;
|
|
37
|
+
if (cache && this._cache[method]) {
|
|
38
|
+
return this._cache[method];
|
|
39
|
+
}
|
|
40
|
+
const result = (0, web_1.fetchJson)(this.connection, JSON.stringify(request), getResult).then((result) => {
|
|
41
|
+
this.emit('debug', {
|
|
42
|
+
action: 'response',
|
|
43
|
+
request: request,
|
|
44
|
+
response: result,
|
|
45
|
+
provider: this,
|
|
46
|
+
});
|
|
47
|
+
return result;
|
|
48
|
+
}, (error) => {
|
|
49
|
+
this.emit('debug', {
|
|
50
|
+
action: 'response',
|
|
51
|
+
error: error,
|
|
52
|
+
request: request,
|
|
53
|
+
provider: this,
|
|
54
|
+
});
|
|
55
|
+
throw error;
|
|
56
|
+
});
|
|
57
|
+
// Cache the fetch, but clear it on the next event loop
|
|
58
|
+
if (cache) {
|
|
59
|
+
this._cache[method] = result;
|
|
60
|
+
setTimeout(() => {
|
|
61
|
+
this._cache[method] = null;
|
|
62
|
+
}, 0);
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.JsonRpcProvider = JsonRpcProvider;
|
|
68
|
+
//# sourceMappingURL=json-rpc-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-rpc-provider.js","sourceRoot":"","sources":["../../../src/ethereum/ethers/json-rpc-provider.ts"],"names":[],"mappings":";;;AAAA,oBAAoB;AACpB,0DAAqD;AACrD,4CAA+C;AAE/C,wDAAkF;AAIlF,SAAS,SAAS,CAAC,OAGlB;IACC,IAAI,OAAO,CAAC,KAAK,EAAE;QACjB,iBAAiB;QACjB,MAAM,KAAK,GAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;QAChC,MAAM,KAAK,CAAC;KACb;IAED,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,CAAC;AAED,MAAa,eAAgB,SAAQ,2BAAmB;IACtD,YAAY,GAA4B,EAAE,OAAoB;QAC5D,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtB,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,MAAkB;QACrC,MAAM,OAAO,GAAG;YACd,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,MAAM;YACd,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE;YAClB,OAAO,EAAE,KAAK;SACf,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,IAAA,qBAAQ,EAAC,OAAO,CAAC;YAC1B,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,kEAAkE;QAClE,sEAAsE;QACtE,MAAM,KAAK,GAAG,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtE,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YAChC,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SAC5B;QAED,MAAM,MAAM,GAAG,IAAA,eAAS,EACtB,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EACvB,SAAS,CACV,CAAC,IAAI,CACJ,CAAC,MAAM,EAAE,EAAE;YACT,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;gBACjB,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,OAAO;gBAChB,QAAQ,EAAE,MAAM;gBAChB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QAChB,CAAC,EACD,CAAC,KAAK,EAAE,EAAE;YACR,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;gBACjB,MAAM,EAAE,UAAU;gBAClB,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,OAAO;gBAChB,QAAQ,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,MAAM,KAAK,CAAC;QACd,CAAC,CACF,CAAC;QAEF,uDAAuD;QACvD,IAAI,KAAK,EAAE;YACT,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;YAC7B,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;YAC7B,CAAC,EAAE,CAAC,CAAC,CAAC;SACP;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA/DD,0CA+DC","sourcesContent":["/* eslint-disable */\nimport { deepCopy } from '@ethersproject/properties';\nimport { fetchJson } from '@ethersproject/web';\n\nimport { JsonRpcProvider as BaseJsonRpcProvider } from '@ethersproject/providers';\nimport { Networkish } from '@ethersproject/networks';\nimport { ConnectionInfo } from './web';\n\nfunction getResult(payload: {\n error?: { code?: number; data?: any; message?: string };\n result?: any;\n}): any {\n if (payload.error) {\n // @TODO: not any\n const error: any = new Error(payload.error.message);\n error.code = payload.error.code;\n error.data = payload.error.data;\n throw error;\n }\n\n return payload.result;\n}\n\nexport class JsonRpcProvider extends BaseJsonRpcProvider {\n constructor(url: string | ConnectionInfo, network?: Networkish) {\n super(url, network);\n }\n\n send(method: string, params: Array<any>): Promise<any> {\n const request = {\n method: method,\n params: params,\n id: this._nextId++,\n jsonrpc: '2.0',\n };\n\n this.emit('debug', {\n action: 'request',\n request: deepCopy(request),\n provider: this,\n });\n\n // We can expand this in the future to any call, but for now these\n // are the biggest wins and do not require any serializing parameters.\n const cache = ['eth_chainId', 'eth_blockNumber'].indexOf(method) >= 0;\n if (cache && this._cache[method]) {\n return this._cache[method];\n }\n\n const result = fetchJson(\n this.connection,\n JSON.stringify(request),\n getResult,\n ).then(\n (result) => {\n this.emit('debug', {\n action: 'response',\n request: request,\n response: result,\n provider: this,\n });\n\n return result;\n },\n (error) => {\n this.emit('debug', {\n action: 'response',\n error: error,\n request: request,\n provider: this,\n });\n\n throw error;\n },\n );\n\n // Cache the fetch, but clear it on the next event loop\n if (cache) {\n this._cache[method] = result;\n setTimeout(() => {\n this._cache[method] = null;\n }, 0);\n }\n\n return result;\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const version = "web/5.7.1";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_version.js","sourceRoot":"","sources":["../../../../src/ethereum/ethers/web/_version.ts"],"names":[],"mappings":";;;AAAA,oBAAoB;AACP,QAAA,OAAO,GAAG,WAAW,CAAC","sourcesContent":["/* eslint-disable */\nexport const version = 'web/5.7.1';\n"]}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
'use strict';
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.getUrl = void 0;
|
|
8
|
+
const http_1 = __importDefault(require("http"));
|
|
9
|
+
const https_1 = __importDefault(require("https"));
|
|
10
|
+
const zlib_1 = require("zlib");
|
|
11
|
+
const url_1 = require("url");
|
|
12
|
+
const bytes_1 = require("@ethersproject/bytes");
|
|
13
|
+
const properties_1 = require("@ethersproject/properties");
|
|
14
|
+
const logger_1 = require("@ethersproject/logger");
|
|
15
|
+
const _version_1 = require("./_version");
|
|
16
|
+
const logger = new logger_1.Logger(_version_1.version);
|
|
17
|
+
function getResponse(request) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
request.once('response', (resp) => {
|
|
20
|
+
const response = {
|
|
21
|
+
statusCode: resp.statusCode,
|
|
22
|
+
statusMessage: resp.statusMessage,
|
|
23
|
+
headers: Object.keys(resp.headers).reduce((accum, name) => {
|
|
24
|
+
let value = resp.headers[name];
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
value = value.join(', ');
|
|
27
|
+
}
|
|
28
|
+
accum[name] = value;
|
|
29
|
+
return accum;
|
|
30
|
+
}, {}),
|
|
31
|
+
body: null,
|
|
32
|
+
};
|
|
33
|
+
//resp.setEncoding("utf8");
|
|
34
|
+
resp.on('data', (chunk) => {
|
|
35
|
+
if (response.body == null) {
|
|
36
|
+
response.body = new Uint8Array(0);
|
|
37
|
+
}
|
|
38
|
+
response.body = (0, bytes_1.concat)([response.body, chunk]);
|
|
39
|
+
});
|
|
40
|
+
resp.on('end', () => {
|
|
41
|
+
if (response.headers['content-encoding'] === 'gzip') {
|
|
42
|
+
//const size = response.body.length;
|
|
43
|
+
response.body = (0, bytes_1.arrayify)((0, zlib_1.gunzipSync)(response.body));
|
|
44
|
+
//console.log("Delta:", response.body.length - size, Buffer.from(response.body).toString());
|
|
45
|
+
}
|
|
46
|
+
resolve(response);
|
|
47
|
+
});
|
|
48
|
+
resp.on('error', (error) => {
|
|
49
|
+
/* istanbul ignore next */
|
|
50
|
+
error.response = response;
|
|
51
|
+
reject(error);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
request.on('error', (error) => {
|
|
55
|
+
reject(error);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// The URL.parse uses null instead of the empty string
|
|
60
|
+
function nonnull(value) {
|
|
61
|
+
if (value == null) {
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
return value;
|
|
65
|
+
}
|
|
66
|
+
async function getUrl(href, options) {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
if (options == null) {
|
|
69
|
+
options = {};
|
|
70
|
+
}
|
|
71
|
+
// @TODO: Once we drop support for node 8, we can pass the href
|
|
72
|
+
// directly into request and skip adding the components
|
|
73
|
+
// to this request object
|
|
74
|
+
const url = (0, url_1.parse)(href);
|
|
75
|
+
const request = {
|
|
76
|
+
protocol: nonnull(url.protocol),
|
|
77
|
+
hostname: nonnull(url.hostname),
|
|
78
|
+
port: nonnull(url.port),
|
|
79
|
+
path: nonnull(url.pathname) + nonnull(url.search),
|
|
80
|
+
method: options.method || 'GET',
|
|
81
|
+
headers: (0, properties_1.shallowCopy)(options.headers || {}),
|
|
82
|
+
agent: null,
|
|
83
|
+
};
|
|
84
|
+
if (options.allowGzip) {
|
|
85
|
+
request.headers['accept-encoding'] = 'gzip';
|
|
86
|
+
}
|
|
87
|
+
let req = null;
|
|
88
|
+
switch (nonnull(url.protocol)) {
|
|
89
|
+
case 'http:':
|
|
90
|
+
if ((_a = options === null || options === void 0 ? void 0 : options.agents) === null || _a === void 0 ? void 0 : _a.http) {
|
|
91
|
+
request.agent = options.agents.http;
|
|
92
|
+
}
|
|
93
|
+
req = http_1.default.request(request);
|
|
94
|
+
break;
|
|
95
|
+
case 'https:':
|
|
96
|
+
if ((_b = options === null || options === void 0 ? void 0 : options.agents) === null || _b === void 0 ? void 0 : _b.https) {
|
|
97
|
+
request.agent = options.agents.https;
|
|
98
|
+
}
|
|
99
|
+
req = https_1.default.request(request);
|
|
100
|
+
break;
|
|
101
|
+
default:
|
|
102
|
+
/* istanbul ignore next */
|
|
103
|
+
logger.throwError(`unsupported protocol ${url.protocol}`, logger_1.Logger.errors.UNSUPPORTED_OPERATION, {
|
|
104
|
+
protocol: url.protocol,
|
|
105
|
+
operation: 'request',
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (options.body) {
|
|
109
|
+
req.write(Buffer.from(options.body));
|
|
110
|
+
}
|
|
111
|
+
req.end();
|
|
112
|
+
const response = await getResponse(req);
|
|
113
|
+
return response;
|
|
114
|
+
}
|
|
115
|
+
exports.getUrl = getUrl;
|
|
116
|
+
//# sourceMappingURL=geturl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geturl.js","sourceRoot":"","sources":["../../../../src/ethereum/ethers/web/geturl.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable */\n'use strict';\n\nimport http from 'http';\nimport https from 'https';\nimport { gunzipSync } from 'zlib';\nimport { parse } from 'url';\n\nimport { arrayify, concat } from '@ethersproject/bytes';\nimport { shallowCopy } from '@ethersproject/properties';\n\nimport type { GetUrlResponse, Options } from './types';\n\nimport { Logger } from '@ethersproject/logger';\nimport { version } from './_version';\nconst logger = new Logger(version);\n\nexport { GetUrlResponse, Options };\n\nfunction getResponse(request: http.ClientRequest): Promise<GetUrlResponse> {\n return new Promise((resolve, reject) => {\n request.once('response', (resp: http.IncomingMessage) => {\n const response: GetUrlResponse = {\n statusCode: resp.statusCode,\n statusMessage: resp.statusMessage,\n headers: Object.keys(resp.headers).reduce((accum, name) => {\n let value = resp.headers[name];\n if (Array.isArray(value)) {\n value = value.join(', ');\n }\n accum[name] = value;\n return accum;\n }, <{ [name: string]: string }>{}),\n body: null,\n };\n //resp.setEncoding(\"utf8\");\n\n resp.on('data', (chunk: Uint8Array) => {\n if (response.body == null) {\n response.body = new Uint8Array(0);\n }\n response.body = concat([response.body, chunk]);\n });\n\n resp.on('end', () => {\n if (response.headers['content-encoding'] === 'gzip') {\n //const size = response.body.length;\n response.body = arrayify(gunzipSync(response.body));\n //console.log(\"Delta:\", response.body.length - size, Buffer.from(response.body).toString());\n }\n resolve(response);\n });\n\n resp.on('error', (error) => {\n /* istanbul ignore next */\n (<any>error).response = response;\n reject(error);\n });\n });\n\n request.on('error', (error) => {\n reject(error);\n });\n });\n}\n\n// The URL.parse uses null instead of the empty string\nfunction nonnull(value: string): string {\n if (value == null) {\n return '';\n }\n return value;\n}\n\nexport async function getUrl(\n href: string,\n options?: Options,\n): Promise<GetUrlResponse> {\n if (options == null) {\n options = {};\n }\n\n // @TODO: Once we drop support for node 8, we can pass the href\n // directly into request and skip adding the components\n // to this request object\n const url = parse(href);\n\n const request = {\n protocol: nonnull(url.protocol),\n hostname: nonnull(url.hostname),\n port: nonnull(url.port),\n path: nonnull(url.pathname) + nonnull(url.search),\n\n method: options.method || 'GET',\n headers: shallowCopy(options.headers || {}),\n agent: null,\n };\n\n if (options.allowGzip) {\n request.headers['accept-encoding'] = 'gzip';\n }\n\n let req: http.ClientRequest = null;\n switch (nonnull(url.protocol)) {\n case 'http:':\n if (options?.agents?.http) {\n request.agent = options.agents.http;\n }\n req = http.request(request);\n break;\n case 'https:':\n if (options?.agents?.https) {\n request.agent = options.agents.https;\n }\n req = https.request(request);\n break;\n default:\n /* istanbul ignore next */\n logger.throwError(\n `unsupported protocol ${url.protocol}`,\n Logger.errors.UNSUPPORTED_OPERATION,\n {\n protocol: url.protocol,\n operation: 'request',\n },\n );\n }\n\n if (options.body) {\n req.write(Buffer.from(options.body));\n }\n req.end();\n\n const response = await getResponse(req);\n return response;\n}\n"]}
|