-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprovider.mjs
103 lines (92 loc) · 3.06 KB
/
provider.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* @typedef {number|'earliest'|'latest'|'safe'|'finalized'|'pending'} BlockTag
*/
/**
* Simple JSON-RPC provider.
*/
export class Provider {
constructor(url = 'http://127.0.0.1:8545') {
this.url = url;
this._id = 1;
}
/**
* Returns the current block number.
*
* See also https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_blocknumber.
*
* @returns {Promise<number>} The current block number.
*/
async blockNumber() {
return parseInt(await this.post('eth_blockNumber', []), 16);
}
/**
* Returns the current chain id.
*
* See also https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_chainId
*
* @returns {Promise<number>}
*/
async chainId() {
return parseInt(await this.post('eth_chainId', []), 16);
}
/**
* Returns the receipts of a given block.
*
* @param {number} blockNumber
* @returns {Promise<{transactionHash: string, contractAddress?: string}[]>}
*/
getBlockReceipts(blockNumber) {
return this.post('eth_getBlockReceipts', [blockNumber]);
}
/**
* Returns the code at a given account address and block number.
*
* See also https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_getcode.
*
* @param {string} address 20-byte account address.
* @param {BlockTag} blockNumber The block number or tag at which to make the request.
* See also https://ethereum.org/en/developers/docs/apis/json-rpc/#default-block.
* @returns {Promise<string>}
*/
getCode(address, blockNumber = 'latest') {
return this.post('eth_getCode', [address, blockNumber]);
}
/**
* Returns the current client version.
*
* See also https://ethereum.org/en/developers/docs/apis/json-rpc/#web3_clientversion.
*
* @returns {Promise<string>}
*/
async clientVersion() {
return await this.post('web3_clientVersion', []);
}
/**
* Sends a JSON-RPC `POST` request to the provider.
*
* @template T
* @param {'eth_blockNumber'|'eth_chainId'|'eth_getBlockReceipts'|'eth_getCode'|'web3_clientVersion'} method
* @param {unknown[]} params
* @returns {Promise<T>} The `result` of the request.
*/
async post(method, params) {
/** @typedef {{jsonrpc: string, id: number, error: unknown, result: unknown}} JsonRpcResponse */
const id = this._id++;
const resp = await fetch(this.url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: '2.0',
method,
params,
id,
}),
});
const json = /** @type {JsonRpcResponse} */(await resp.json());
if (resp.status === 200 && json.jsonrpc === '2.0' && json.id === id && json.error === undefined)
return /** @type {T} */ (json.result);
throw new Error(`Invalid JSON-RPC response: ${JSON.stringify(json)}`);
}
}