Compare commits

...

265 Commits
v5.1.2 ... Beta

Author SHA1 Message Date
Richard Moore
948f77050d admin: fixed update scripts to not conflict with reticulate used in v6 2022-04-13 00:26:24 -04:00
Richard Moore
9e57e71dc0 admin: updated dist files. 2022-04-13 00:25:25 -04:00
Richard Moore
dab6ede226 Mimic Hardhard error strings in CALL_EXCEPTION for popular matchers (#2849, #2862). 2022-04-12 23:54:39 -04:00
Richard Moore
1f6c0ab281 admin: Added more environment options to bug issue to help identify network. 2022-04-12 17:05:49 -04:00
Richard Moore
056d7c8bfc Fix pocket API key not being passed in for default provider (#2890). 2022-04-12 16:20:32 -04:00
Richard Moore
47c41143cb admin: added issue template for v6 beta 2022-04-12 13:46:15 -04:00
Richard Moore
ef1b28e958 admin: updated dist files 2022-03-25 17:56:35 -04:00
Richard Moore
e192903050 Fixed left-padding in arrayify (#2833). 2022-03-25 17:47:46 -04:00
Richard Moore
9d9b14b952 More robust JSON-RPC error handling for reverted executions (#2603). 2022-03-25 17:40:45 -04:00
Richard Moore
bc400c7b87 admin: updated spell-check dictionary 2022-03-25 04:33:51 -04:00
Richard Moore
120dcd024a admin: added enhancement tag for feature request issues. 2022-03-25 04:33:20 -04:00
Richard Moore
04f7a9f3b7 admin: updated dist files. 2022-03-25 04:32:41 -04:00
Richard Moore
e70f3fe26f Added IPNS support for ENS contenthash. 2022-03-25 03:57:43 -04:00
Richard Moore
ef529dc5e6 admin: updated issue templates 2022-03-19 05:48:01 -04:00
Richard Moore
9f0967f21f admin: updated issue forms 2022-03-19 05:44:40 -04:00
Richard Moore
774c310389 admin: updated issue templates 2022-03-19 05:41:13 -04:00
Richard Moore
21fae9f0ba admin: updating issue templates 2022-03-19 05:39:31 -04:00
Richard Moore
ce85a7e976 admin: updated issue form for bugs 2022-03-19 03:28:16 -04:00
Richard Moore
7c4a9083c2 admin: updated issue form for bugs 2022-03-19 03:27:24 -04:00
Richard Moore
7becc93ed0 admin: update issue template 2022-03-19 03:02:06 -04:00
Richard Moore
540a670f94 admin: updated spell-check dictionary 2022-03-19 03:00:15 -04:00
Richard Moore
ab628c285e admin: updated dist files 2022-03-19 02:59:38 -04:00
Richard Moore
9bff2cb3d9 docs: updated API key info 2022-03-19 02:48:17 -04:00
Richard Moore
96de58122a Added initial AnkrProvider 2022-03-19 02:45:59 -04:00
Richard Moore
b1c7f5c21a admin: updated dist files. 2022-03-16 01:25:22 -04:00
Richard Moore
905e98aa39 Update test cases for CCIP Read fix (#2478). 2022-03-16 01:20:11 -04:00
Richard Moore
dca0d14d38 admin: updated dist files 2022-03-15 22:04:05 -04:00
Richard Moore
5998fea53d Fix issue with CCIP Read using wrong sender (#2478). 2022-03-15 21:33:06 -04:00
Richard Moore
dfaa8ee7e6 admin: updated dist files 2022-03-09 14:58:07 -05:00
Richard Moore
fa4a29028d Tweaked test case to re-order transaction after event listeners added. 2022-03-09 14:51:48 -05:00
Richard Moore
f46aa75ef1 Fix events getting blocked from fix for missed events (#1798, #1814, #1830, #2274, #2652). 2022-03-09 14:49:37 -05:00
Richard Moore
d160bac273 Ignore errors when resolving ENS resolver properties. 2022-03-09 14:31:16 -05:00
Richard Moore
be518c32ec Enable CCIP Read for ENS resolvers (#2478). 2022-03-09 14:00:23 -05:00
Richard Moore
26cdbab59b admin: Updated spell check file 2022-03-09 02:56:46 -05:00
Richard Moore
b8cda5dffd admin: updated dist files 2022-03-09 02:56:08 -05:00
Richard Moore
f67a9a8569 Fix missing events on certain network conditions (#1798, #1814, #1830, #2274, #2652). 2022-03-09 02:08:37 -05:00
Richard Moore
bae215eb7f Added defaultProvider option to omit specific Providers. 2022-03-08 17:21:29 -05:00
Richard Moore
54e6e57fce Add support for pending blocks (#2225). 2022-03-08 17:16:32 -05:00
Richard Moore
38e825cee6 Updated help for errors (#2489). 2022-03-08 14:34:47 -05:00
Richard Moore
16007d4d1e Fixed typo in testcase string. 2022-03-04 16:39:55 -05:00
Richard Moore
cf47ec5fd5 docs: fixed typo (#2760). 2022-03-04 16:17:26 -05:00
Richard Moore
ae23bb76a9 Added CCIP support to provider.call (#2478). 2022-03-04 16:15:47 -05:00
Richard Moore
33a029e457 Adjust default maxPriorityFeePerGas to 1.5 gwei. 2022-03-02 11:33:27 -05:00
Richard Moore
c2a6a012bf Fix contracts when name resolution fails without any checks (#2737). 2022-02-24 03:51:53 -05:00
Richard Moore
6807a76b8d Preserve explicit chainId in JsonRpcProvider during transaction serialization (#2691). 2022-02-22 03:53:34 -05:00
Richard Moore
5f26fd55c9 Fixed eth_chainId response for Eip1193Bridge (#2711). 2022-02-22 03:51:37 -05:00
Richard Moore
c562150d26 Tweaked error URLs (#2489). 2022-02-21 14:16:25 -05:00
Richard Moore
4e8f004e9e Remove spurious console.log from Interface (#2714). 2022-02-19 02:29:34 -05:00
Richard Moore
9aac785395 Allow raw WebSocket to be passed into WebSocketProvider (#2562, #2644). 2022-02-19 01:57:45 -05:00
Richard Moore
1651389571 docs: added skipFetchSetup to ConnectionInfo (#1886). 2022-02-19 01:40:49 -05:00
Richard Moore
2d98b4fca1 Added Cloudflare Worker support (#1886). 2022-02-19 01:31:03 -05:00
Richard Moore
f26074b92b Add support for EIP-2098 compact signatures (#2246). 2022-02-18 18:54:00 -05:00
Richard Moore
eb91d708ac Merge branch 'v5.4' 2022-02-18 18:23:02 -05:00
Richard Moore
83891f9258 Add EIP-2544 Wildcard support (#2477, #2582, #2583). 2022-02-18 18:15:03 -05:00
Richard Moore
7b134bd5c9 docs: added more searchable wording. 2022-02-03 16:36:52 -05:00
Richard Moore
e175448380 docs: added BaseProvider (#2625). 2022-02-03 16:31:40 -05:00
Richard Moore
1d419b5829 docs: more explicitly describe the id function (#2115). 2022-02-03 16:08:15 -05:00
Richard Moore
95b2c72b12 docs: updated API provider supported networks (#2242). 2022-02-03 15:55:50 -05:00
Richard Moore
7b0d02d30e docs: fixed typos (#2289). 2022-02-03 15:46:18 -05:00
Richard Moore
0c72e0f1fd docs: added effectiveGasPrice to receipts (#2311). 2022-02-03 15:44:18 -05:00
Richard Moore
315ecfd19e docs: fixed typs (#2354). 2022-02-03 15:38:14 -05:00
Richard Moore
c61f3bc2a0 docs: fixed import typo (#2397). 2022-02-03 15:36:34 -05:00
Richard Moore
1be096130c docs: fixed typos (#2400). 2022-02-03 15:34:40 -05:00
Richard Moore
9eed04a6d5 docs: fixed typos (#2407). 2022-02-03 15:31:43 -05:00
Richard Moore
82d6dcbdde docs: fix typos (#2430). 2022-02-03 15:30:19 -05:00
Richard Moore
4935f93015 docs: add MetaMask request info (#2535). 2022-02-03 15:28:04 -05:00
Richard Moore
3df0e06c64 docs: fixed typos (#2522). 2022-02-03 15:25:26 -05:00
Richard Moore
18d8d1f34d docs: fixed typos (#2531). 2022-02-03 15:24:09 -05:00
Richard Moore
7b80ba20fe docs: fixed typos (#2614). 2022-02-03 15:23:20 -05:00
Richard Moore
f635af2684 docs: added getAvatar (#2591). 2022-01-30 22:58:43 -05:00
Richard Moore
813fcef4ad docs: added jsonRpcProvider.connection (#2611) 2022-01-30 22:45:46 -05:00
Richard Moore
32c9a09762 admin: update dist files 2022-01-24 21:33:40 -05:00
Richard Moore
03545aa78b Support invalid but popular IPFS URI format (#2271, #2527, #2590). 2022-01-24 16:39:50 -05:00
Richard Moore
03152ea014 Include trouble-shooting URLs in errors (#2489). 2022-01-24 16:32:41 -05:00
Richard Moore
0578a88efa Updated dist files. 2022-01-06 03:53:52 -05:00
Richard Moore
3f5bc6ddc1 Fixed case-folding in schemes for ENS avatars (#2500). 2022-01-06 03:46:02 -05:00
Richard Moore
ab13887cda Added Kintsugi network (#2434). 2022-01-06 03:37:13 -05:00
Richard Moore
28f383300c admin: updated dist files 2021-12-24 03:09:45 -05:00
Richard Moore
4ba63acc10 Fix browser random in WebWorkers (#2405). 2021-12-24 02:05:10 -05:00
Richard Moore
3d6a7ec020 Add support for IPFS metadata imageUrl in getAvatar (#2426). 2021-12-24 01:41:41 -05:00
Richard Moore
2f57c6a4ab Do not swallow ENS not supported errors (#2387). 2021-12-24 01:08:54 -05:00
Richard Moore
d3d2953e8d docs: fixed and expanded explanation of fees (#2321) 2021-12-01 13:09:14 -05:00
Richard Moore
0403314023 docs: added note about pure/view for constant methods. 2021-12-01 12:56:21 -05:00
Richard Moore
eb432aa1f4 admin: updated dist files 2021-11-30 19:16:49 -05:00
Richard Moore
617714d196 Fixed test case for getAvatar; url has moved 2021-11-30 19:11:44 -05:00
Richard Moore
42784b8d38 Added basic redirect support. 2021-11-30 19:11:03 -05:00
Richard Moore
50d712d6af admin: updated dist files 2021-11-30 11:19:37 -05:00
Richard Moore
c7e9715758 docs: Fixed ContractFactory.connect return type (#2224, #2257) 2021-11-30 10:24:06 -05:00
Richard Moore
0844de4eb4 Added arbitrum and optimism to networks and providers (#2335). 2021-11-30 10:20:26 -05:00
Richard Moore
caa1983665 docs: Add view/pure to docs (#2336) 2021-11-30 10:03:43 -05:00
Richard Moore
b8391b0e61 Added support for data URLs for avatar metadata. 2021-10-31 00:53:49 -04:00
Richard Moore
1e1c93effa Fixed getAvatar for unconfigured ENS names. 2021-10-31 00:05:27 -04:00
Richard Moore
b145898976 admin: updated dist files 2021-10-20 04:00:49 -04:00
Richard Moore
1bd91615ee Fixed abstract Provider signature issue (#2190). 2021-10-20 03:54:24 -04:00
Richard Moore
d3079745c5 admin: updated dist files 2021-10-19 00:01:37 -04:00
Richard Moore
ecce86125d Added ENS avatar support to provider (#2185). 2021-10-18 23:53:37 -04:00
Richard Moore
5899c8aec0 admin: updated dist files 2021-10-17 23:03:30 -04:00
Richard Moore
3de1b81501 Fixed splitSignature logic for verifying EIP-2930 and EIP-1559 v (#2084). 2021-10-17 22:56:57 -04:00
Richard Moore
ab319f2f4c Include events on ContractFactory deployment transactions (#1334). 2021-10-17 21:38:47 -04:00
Richard Moore
5b94ce2966 admin: updated dist files 2021-10-17 16:23:46 -04:00
Richard Moore
91c577b611 Removed non-english tests from the browser. 2021-10-17 16:18:22 -04:00
Richard Moore
2f363da5ff admin: add changelog 2021-10-16 02:31:02 -04:00
Richard Moore
73a46efea3 admin: updated dist files 2021-10-16 02:29:27 -04:00
Richard Moore
8f3d71dc5f admin: fixed alias script (#1494). 2021-10-16 01:53:12 -04:00
Richard Moore
a5c6a468f4 Better errors when non-string address or ENS name is passed into Contracts or provider methods (#1051). 2021-10-16 01:30:06 -04:00
Richard Moore
8947fd405e Use personal_sign instead of eth_sign for message signing with JsonRpcSigner; added _legacySignMessage for legacy support (#1542, #1840). 2021-10-16 01:11:53 -04:00
Richard Moore
cb43a99405 Removed extra wordlists from the dist files (#2058, #2077). 2021-10-15 22:34:03 -04:00
Richard Moore
b7e61bd67e admin: use https endpoints for NPM registry 2021-10-15 22:03:35 -04:00
Richard Moore
0a8be37b08 Fix issue when Solidity method collises with JavaScript prototype (#1432, #2054, #2120). 2021-10-15 21:32:48 -04:00
Richard Moore
6582ede1ce Add support for Cloudflare Workers (#1886). 2021-10-05 16:57:51 -04:00
Richard Moore
f3c6d819f3 Added more information to some invalid argument errors (#1130). 2021-10-05 16:05:40 -04:00
Richard Moore
bee76a49b2 Fix compile-time error in new TypeScript version. 2021-10-05 15:48:14 -04:00
Richard Moore
68095a48ae Adding customData support to transactions to assist L2 chains (#1761). 2021-10-05 15:47:26 -04:00
Richard Moore
0e5419ec79 Added some explicit null results to previously implicit null results for ENS (#1850). 2021-10-04 12:19:48 -04:00
Richard Moore
a48552a4fb Added BigNumber _difficulty to Block results (#2001, #2036). 2021-10-04 12:09:44 -04:00
Richard Moore
ab806cad15 docs: fixed typo (#1770). 2021-10-04 11:49:33 -04:00
Richard Moore
d5b41ce210 Removed redundant call to normalizing blockTag (1838). 2021-10-04 11:48:36 -04:00
Richard Moore
fb6d141723 docs: fixed typos in comments; h/t @ly0va (#1838). 2021-10-04 11:46:24 -04:00
Richard Moore
7a404fb8ed Fixed isBytes check for invalid length or elements (#1964). 2021-10-04 11:21:43 -04:00
Richard Moore
f8adf82e16 Fixed randomBytes not rejecting NaN as a length (#1977). 2021-10-04 11:08:58 -04:00
Richard Moore
8395cc146f docs: fixed typo in providers README (#1979). 2021-10-04 10:59:37 -04:00
Richard Moore
8fc5914c5a docs: fixed typo in cookbook (#2011). 2021-10-04 10:58:10 -04:00
Richard Moore
cc250b2060 Allow any Networkish for getDefaultProvider (#2031). 2021-10-04 10:57:00 -04:00
Richard Moore
375627f6b1 docs: updated signer prefix info (#2032). 2021-10-04 10:54:31 -04:00
Richard Moore
d67f8fb778 docs: fixed capitalization of MetaMask (#2033). 2021-10-04 10:52:34 -04:00
Richard Moore
45f367512d Stop allowing commas in fixed numbers; left over from legacy comma support (#2083). 2021-10-04 10:48:27 -04:00
Richard Moore
ad87b718a9 docs: fixed typos in comments (#2087). 2021-10-04 10:46:35 -04:00
Richard Moore
48c9e0bf39 Export FallbackProviderConfig (#2121). 2021-10-04 10:44:24 -04:00
Richard Moore
d1d636b503 docs: fixed typo (#2125). 2021-10-04 10:41:54 -04:00
Richard Moore
4166b2753d Updated dist files. 2021-09-16 13:19:43 -04:00
Richard Moore
32a6b2a362 Fix parseUints with excess zeros and fix ReDoS issue (#2016, #1975, #1976). 2021-09-16 13:04:32 -04:00
Richard Moore
f2a32d0d5b docs: added provider.FeeData 2021-08-27 15:35:23 -04:00
Richard Moore
5762a1f83d updated dist files. 2021-08-27 15:34:47 -04:00
Richard Moore
8320d534d7 Temporarily remove the block miner for clique-based networks from CI testing (#1967). 2021-08-27 15:29:52 -04:00
Richard Moore
c41b89a0c1 updated dist files. 2021-08-24 16:15:51 -03:00
Richard Moore
b6a061e7bf More readable errors involving Uint8Arrays. 2021-08-24 16:08:27 -03:00
Richard Moore
a662490e82 Added Deferred Error support to Description objects to extent Interface parse methods (#1894). 2021-08-24 16:03:12 -03:00
Richard Moore
bdb54ac52b docs: added cookbook entry to compute raw transaction (#1857). 2021-08-24 14:54:15 -03:00
Richard Moore
32a90b66f0 docs: added Alchemy tutorial 2021-08-24 14:43:27 -03:00
Richard Moore
95b87f61a6 docs: added BigNumber.toBigInt (#1799). 2021-08-24 14:42:38 -03:00
Richard Moore
017b1feba2 Fix address coder to prepare non-hexdatastring addresses as hexdatastring (#1906). 2021-08-24 14:33:04 -03:00
Richard Moore
accb85268c Removed temporary code for better errors needed until Alchemy added EIP-1559 support (#1893). 2021-08-23 23:02:32 -03:00
Richard Moore
f0b3bc32d5 Updated dist files. 2021-08-18 03:05:48 -03:00
Richard Moore
78e4273a32 Fxied getBlockWithTransactions results (1858). 2021-08-18 02:59:47 -03:00
Richard Moore
dd09bf0735 docs: dded code examples for Contract (#982). 2021-08-10 00:20:16 -03:00
Richard Moore
4b163e9e73 docs: added dynamic localSigner 2021-08-09 17:49:24 -03:00
Richard Moore
aacb95cd6b docs: added struct encoding example (#1147, #1301, #1302). 2021-08-09 17:47:33 -03:00
Richard Moore
e6315a6b3c docs: remove need to restart dev node after each run. 2021-08-09 17:46:33 -03:00
Richard Moore
3ac91a414c docs: added StaticJsonRpcProvider (#1514, #1531). 2021-08-09 16:02:37 -03:00
Richard Moore
2dd5c1a6d2 docs: Fixed topicset example (#1538). 2021-08-09 15:48:02 -03:00
Richard Moore
2653449f3c docs: updated transactions for EIP-1559. 2021-08-09 15:42:33 -03:00
Richard Moore
cddb03880a docs: added API for custom error coding. 2021-08-09 15:41:36 -03:00
Richard Moore
e80f8dd4e6 docs: updates for EIP-1559 (#1777). 2021-08-09 15:40:37 -03:00
Richard Moore
1b4bc7a6a6 docs: Fix listAccounts return type (#1851). 2021-08-09 15:35:43 -03:00
Richard Moore
4e9394554b Updated dist files. 2021-08-04 01:39:05 -03:00
Richard Moore
1d27d95670 Fixed Etherscan API key in default provider (#1807). 2021-08-04 01:32:30 -03:00
Richard Moore
2e431a5002 Temporarily remove Pocket fro provider tests. 2021-08-04 01:28:54 -03:00
Richard Moore
da4e107268 Update dist files. 2021-08-02 22:57:45 -03:00
Richard Moore
7175e2e99c Adjust default masPriorityFeePerGas to account for MEV-heavy blocks (#1817). 2021-08-02 22:52:29 -03:00
Richard Moore
68229ac0af Updated dist files. 2021-07-29 23:30:17 -04:00
Richard Moore
7274cd06cf Fixed JsonRpcProvider for pre-EIP-2930 chains (#1766). 2021-07-29 23:20:56 -04:00
Richard Moore
be3854e648 Forward some missing EIP-1559 fields to call and estimateGas (#1766). 2021-07-29 23:12:29 -04:00
Richard Moore
63f8b28223 Fixed possible UnhandledPromiseException for bad ENS names. 2021-07-29 23:11:06 -04:00
Richard Moore
593b4886ff Prevent overriding value for non-payble constructors (#1785). 2021-07-29 17:25:19 -04:00
Richard Moore
6d1904c379 Updated dist files. 2021-07-23 17:24:05 -04:00
Richard Moore
0aafca71db Fix test case for new transactions responses. 2021-07-23 17:17:43 -04:00
Richard Moore
0d40156fcb Updated dist files. 2021-07-23 02:21:24 -04:00
Richard Moore
576e9b54ab Added matic support to INFURA and Alchemy (#1546). 2021-07-23 02:13:35 -04:00
Richard Moore
bc5cc2e7e3 Added string change to coalesce errors on some clients. 2021-07-23 01:52:43 -04:00
Richard Moore
660e69db71 Added wait to transactions returned by getBlockWithTransactions (#971). 2021-07-22 20:04:07 -04:00
Richard Moore
551cfa0062 Fixed floor, ceiling and round for FixedNumber for non-default Formats (#1749). 2021-07-22 19:40:49 -04:00
Richard Moore
0f0d0c00d3 Fixed null confirmations in Wallet transaction (#1706). 2021-07-06 00:07:32 -04:00
Richard Moore
a1f8d188a7 Fixed Etherscan string change and enabled all tests. 2021-07-03 00:45:03 -04:00
Richard Moore
bde861436e updated dist files. 2021-07-02 01:49:02 -04:00
Richard Moore
6e8a39ec35 Added Pocket back into Homestead defaultProvider and skip certain EtherscanProvider tests affected by outage. 2021-07-02 01:42:16 -04:00
Richard Moore
ecae793edf Fixed EtherscanProvider NONCE_EXPIRED matching string update. 2021-07-02 00:18:53 -04:00
Richard Moore
bac684c5a0 docs: fixd type 2021-07-01 23:32:53 -04:00
Richard Moore
53671d0b17 docs: fixed typo (#1727) 2021-07-01 23:25:01 -04:00
Richard Moore
25c8b8b3e6 docs: fixed typo (#1729) 2021-07-01 23:22:14 -04:00
Richard Moore
a0fa92c075 updated dist files. 2021-06-29 12:25:07 -04:00
Richard Moore
72feee8f58 Fixed explicit EIP-1559 keys for JsonRpcSigner. 2021-06-29 11:57:53 -04:00
Richard Moore
71b7547f10 Update dist files. 2021-06-26 01:55:19 -04:00
Richard Moore
4970385e7b Fixing up testcases for non-eip-1559 ready platforms (#1610). 2021-06-26 01:44:12 -04:00
Richard Moore
0364dd9368 Added some provider-specific adjustments to deal with eip-1559 (#1610). 2021-06-25 22:58:55 -04:00
Richard Moore
e95708eedc Updated gasPrice to be optional for eip-1559 (#1610). 2021-06-25 22:58:01 -04:00
Richard Moore
ba6854bdd5 Added effectiveGasPrice to receipt. 2021-06-25 22:57:05 -04:00
Richard Moore
1e31b34a5a Fixed ENS names for JsonRpcSigner. 2021-06-25 00:02:08 -04:00
Richard Moore
7deb4c174a Added EIP-2930 and EIP-1559 transaction tests. 2021-06-24 23:49:59 -04:00
Richard Moore
f053a7ad58 Renamed Interface error coding methods. 2021-06-24 19:34:27 -04:00
Richard Moore
b1affdbc10 Fixed documentation on FallbackProvider priority (#1713). 2021-06-24 18:07:33 -04:00
Richard Moore
c2c0ce7503 Updated dist files. 2021-06-24 02:13:06 -04:00
Richard Moore
7efc36df29 Added ConstructorFragment to exports. 2021-06-24 01:29:13 -04:00
Richard Moore
720bde7719 Added error utilities to Interface. 2021-06-24 01:25:31 -04:00
Richard Moore
319987ec3e Fixed EIP-1559 from address calculation bug (#1610). 2021-06-24 00:46:53 -04:00
Richard Moore
2a7ce0e72a merged master including transaction type 0 legacy constant (#1610). 2021-06-24 00:02:50 -04:00
Richard Moore
8ba64af29f admin: updated Flatworm version 2021-06-23 23:42:00 -04:00
Richard Moore
17af9f812f docs: fixed typos and updated examples 2021-06-23 23:40:50 -04:00
Richard Moore
d001901c8c Added type to TransactionResponse and TrnsactionReceipt (#1687). 2021-06-23 23:39:57 -04:00
Richard Moore
91951dc825 Trap CALL_EXCEPTION errors when resolving ENS entries (#1690). 2021-06-21 23:25:37 -04:00
Richard Moore
8277f5a62a Fixed transaction serialization with explicit null type (#1628). 2021-06-21 21:21:35 -04:00
Richard Moore
e615e51fbf admin: updated spell check dictionary 2021-06-21 21:15:39 -04:00
Richard Moore
99422c1c7c admin: fixed typo in docs (#1686). 2021-06-21 21:15:01 -04:00
Richard Moore
e8a0144b7a Fix issue with loading JSON ABI with internalType property (#728). 2021-06-21 21:12:25 -04:00
Richard Moore
f9d09645e7 docs: Added info on signMessage (#1343). 2021-06-18 16:17:26 -04:00
Richard Moore
91fff1449d Better baseFee calculation (#1610). 2021-06-14 23:42:11 -04:00
Richard Moore
c5bca7767e Refactored eip-1559 logic (#1610). 2021-06-14 22:24:14 -04:00
Richard Moore
79c5bf6bcb docs: added more examples 2021-06-11 17:13:46 -04:00
Richard Moore
412bbe2939 Updated dist files. 2021-06-10 18:29:05 -04:00
Richard Moore
ee82e86ccc Fixed replacement transaction detection for JsonRpcSigner (#1658). 2021-06-10 18:22:02 -04:00
Richard Moore
376cf3cdbf Added Matic testnet info to networks (#1546). 2021-06-10 18:01:23 -04:00
Richard Moore
89bae3bd63 docs: grammar fix (#1594). 2021-06-10 17:48:55 -04:00
Richard Moore
a6e128f5cc Match Solidity identifier regex (#1657). 2021-06-10 17:47:17 -04:00
Richard Moore
5456c35924 Added EIP-1559 overrides to contracts (#1610). 2021-06-10 17:42:20 -04:00
Richard Moore
be20e28de1 docs: adding more examples 2021-06-10 17:38:38 -04:00
Richard Moore
30c0c97270 docs: added more examples and moved to new flatworm evaler format. 2021-06-04 01:17:56 -04:00
Richard Moore
4e6d121fb8 Updated dist files. 2021-05-31 19:06:24 -04:00
Richard Moore
bfcd05fcbb Added MinInt256 and MaxInt256 constants (#1576). 2021-05-31 18:32:33 -04:00
Richard Moore
819b1ace5c Version bumps for bn.js and hash.js to match elliptic and fix some build tools (#1478). 2021-05-31 18:29:26 -04:00
Richard Moore
4b331148d9 Removed Hangul checks in shims which crashes Android (#1519). 2021-05-31 18:20:32 -04:00
Richard Moore
7adcf3b154 Fixed ENS namehash with leading and trailing dots (#1605). 2021-05-31 18:16:30 -04:00
Richard Moore
630656e949 Fixed broken variable in template string (#1624, #1626). 2021-05-31 17:40:32 -04:00
Richard Moore
8681cd5969 Fixed FixedNumber rounding for non-default formats (#1629). 2021-05-31 17:37:56 -04:00
Richard Moore
470551e4ee Update ws dependency version to fix security (#1633, #1634). 2021-05-31 15:46:47 -04:00
Richard Moore
7a12216cfb Initial EIP-1559 support (#1610). 2021-05-30 17:47:04 -04:00
Richard Moore
d395d16fa3 admin: flags for karma to prevent timeout 2021-05-19 01:30:12 -04:00
Richard Moore
8077ce0aae Updated dist files. 2021-05-19 00:05:36 -04:00
Richard Moore
2fe78ad7e3 ci: Removing Pocket network from the default provider and tests as it is not currently reliable 2021-05-19 00:00:10 -04:00
Richard Moore
5f1f2c5e2c Updated dist files 2021-05-18 16:02:27 -04:00
Richard Moore
3c79ee8cef admin: added words to spellcheck 2021-05-18 15:56:01 -04:00
Richard Moore
772067a3c9 admin: added words to spellchecker 2021-05-18 15:53:15 -04:00
Richard Moore
621897f249 More resiliant testing. 2021-05-18 15:52:32 -04:00
Richard Moore
d3b7130ed6 Merge branch 'master' of github.com:ethers-io/ethers.js 2021-05-17 16:29:33 -04:00
Richard Moore
dad3829c2e Updated dist files. 2021-05-17 16:19:36 -04:00
Richard Moore
de4d683f6d admin: moved some changelog links around 2021-05-17 16:13:35 -04:00
Richard Moore
ebe4cc90f5 admin: updated Changelog 2021-05-13 23:51:01 -04:00
Richard Moore
35e3bf9d11 admin: dependency security audit updates 2021-05-13 23:50:24 -04:00
Richard Moore
2d717dcef8 docs: updated banner version. 2021-05-13 23:49:30 -04:00
Richard Moore
3316468e3e More aggresively check for mempool transactions sent from JsonRpcSigner. 2021-05-13 23:29:59 -04:00
Richard Moore
5144acf456 Added initial support for detecting replacement transactions (#1477). 2021-05-13 23:28:47 -04:00
Richard Moore
aadc5cd3d6 Added convenience method for HD path derivation. 2021-05-13 23:02:00 -04:00
Richard Moore
6e088099ad Added mnemonicPath option to cli. 2021-05-13 22:59:16 -04:00
Richard Moore
b6370f1360 Added some popular Ethereum-compatible chains to networks. 2021-05-13 22:58:16 -04:00
Richard Moore
26464c5425 Added debug event to Web3Provider. 2021-05-13 22:27:13 -04:00
Richard Moore
37a9c77ab2 Abstracted EtherscanProivder to more easily fascilitate other Etherscan-supported chains (#1204, #1473). 2021-05-07 00:31:15 -04:00
Richard Moore
4898e7baac admin: update issue templates 2021-04-27 18:43:54 -04:00
Richard Moore
c71bbbe7db admin: fixed config.yml filename 2021-04-27 18:40:44 -04:00
Richard Moore
c8fecbbc29 admin: fixed duplicate files GitHub UI created. 2021-04-27 18:38:22 -04:00
Richard Moore
b4df28dddd Update issue templates 2021-04-27 18:32:06 -04:00
Richard Moore
483d67f55c Added EIP-838 error name as well as error signature (#1498). 2021-04-26 17:46:16 -04:00
Richard Moore
987bec87af Added new error for replaced transactions (#1477). 2021-04-26 12:06:37 -04:00
Richard Moore
a9cdbe1238 More flexible FixedNumber input and output for strings with no decimals (#1019, #1291, #1463). 2021-04-23 18:41:00 -04:00
Richard Moore
4e9abfdee4 Added hex support for bigint (#1472). 2021-04-23 17:44:22 -04:00
Richard Moore
3bb5fbf533 Added support for null entries in EventFilter (#1499). 2021-04-23 17:43:27 -04:00
Richard Moore
cadccc3060 Add bigint to allowed BigNumberish types (#1472). 2021-04-22 22:34:06 -04:00
Richard Moore
65196097f6 Support for EIP-838 custom contract errors (#1498). 2021-04-22 22:29:30 -04:00
Richard Moore
8e22e0260e Minor version bump. 2021-04-22 22:10:56 -04:00
Richard Moore
de7da421b3 docs: updated versions and dates 2021-04-22 06:34:44 -04:00
Richard Moore
a9f7957550 Updated dist files. 2021-04-22 06:34:02 -04:00
Richard Moore
bd2d44eecf docs: updated script links in README. 2021-04-22 06:28:46 -04:00
Richard Moore
bd05aed070 Do not throw on ABI _error_ type (#1493, #1497). 2021-04-22 06:26:56 -04:00
Richard Moore
ce8f1e4015 Updated dist files. 2021-04-19 21:30:28 -04:00
Richard Moore
58488e78f9 Fixed JsonRpcProvider event-loop caching when using any network (#1484). 2021-04-19 20:56:18 -04:00
Richard Moore
29116593ba Updated experimental Eip1193Bridge to support final EIP-1193 API. 2021-04-19 20:52:50 -04:00
Richard Moore
51f0e1a52f Fail early for ABI decoding that will obviously run out of data (#1486). 2021-04-19 20:26:05 -04:00
Richard Moore
c086962302 Fixed BigNumber toBigInt return type (#1485). 2021-04-19 20:09:39 -04:00
829 changed files with 22017 additions and 10327 deletions

74
.github/ISSUE_TEMPLATE/beta-issue.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: Beta (v6) Bug
description: Open an issue for a bug in the v6 beta
title: "Title Here"
labels: ["v6-beta"]
assignees:
- ricmoo
body:
- type: markdown
attributes:
value: |
This form is **only** for issues in the **v6 beta**, which you
can access using either the `v6-beta` tag in the repository or
install using `ethers@beta` with `npm`.
The v6 branch will be very lively, undergoing a lot of changes,
including backwards compatible changes between beta versions.
Before opening an issue, please make sure you have
**fully updated to the latest version** by removing the
`node_modules/` and `package-lock.json` and then running a
fresh `npm install`. Otherwise you may end up with incompatible
versions which may conflict with each other.
Thanks for trying out the v6 beta! Cheers!
- type: input
id: version
attributes:
label: Ethers Version
description: What version of ethers are you using? Before opening an issue, please make sure you are using the latest beta.
placeholder: x.y.z
validations:
required: true
- type: textarea
id: about-the-bug
attributes:
label: Describe the Problem
description: Please describe what you expected to happen vs what did happen?
placeholder: What happened?
validations:
required: true
- type: textarea
id: code-snippet
attributes:
label: Code Snippet
description: If possible, please include a **short and concise** code snippets that can reproduce this issue. Ideally code that can be pasted into the [Ethers Playground](https://playground.ethers.org).
placeholder: e.g. provider.getBlockNumber()
render: shell
- type: textarea
id: errors
attributes:
label: Errors
description: If there is an error, please include the **entire error** (redacting any sensitive information).
placeholder: "e.g. Error: invalid name (code='INVALID_ARGUMENT, ...)"
render: shell
- type: dropdown
id: environment
attributes:
label: Environment
description: What environment, platforms or frameworks are you using? Select all that apply.
multiple: true
options:
- node.js
- Browser (Chrome, Safari, etc)
- React Native/Expo/JavaScriptCore
- Hardhat
- Geth
- Parity
- Ganache
- Other (please specify)
- type: input
id: other-envrionment
attributes:
label: Environment (Other)
placeholder: anything else?

81
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,81 @@
name: Bug Report
description: Open an issue for a bug in Ethers
title: "Bug Report Title"
labels: ["investigate"]
assignees:
- ricmoo
body:
- type: markdown
attributes:
value: |
**READ THIS FIRST** and follow all instructions, please. `:)`
Thank you for taking the time to report an issue. This form is for reporting **bugs within ethers**.
If you are **new to ethers** or *uncertain* whether this is a bug in ethers, a bug in another framework or a bug in your own code, please [start a discussion](https://github.com/ethers-io/ethers.js/discussions) first.
- type: input
id: version
attributes:
label: Ethers Version
description: What version of ethers are you using? Before opening an issue, please make sure you are up to date.
placeholder: x.y.z
validations:
required: true
- type: input
id: search-terms
attributes:
label: Search Terms
description: Have you searched for answers [in the documentation](https://docs.ethers.io), through [the issues](https://github.com/ethers-io/ethers.js/issues) and [on the discusions](https://github.com/ethers-io/ethers.js/discussions)? Please include the search terms you have tried. This helps us add more keywords where needed.
placeholder: e.g. abi, network, utf8
- type: textarea
id: about-the-bug
attributes:
label: Describe the Problem
description: Please describe what you expected to happen vs what did happen?
placeholder: What happened?
validations:
required: true
- type: textarea
id: code-snippet
attributes:
label: Code Snippet
description: If possible, please include a **short and concise** code snippets that can reproduce this issue. Ideally code that can be pasted into the [Ethers Playground](https://playground.ethers.org).
placeholder: e.g. provider.getBlockNumber()
render: shell
- type: textarea
id: contract-abi
attributes:
label: Contract ABI
description: If this involves a contract, please include any **concise and relevant** ABI fragments.
placeholder: e.g. [ 'function balanceOf(address owner) view returns (uint)' ]
render: shell
- type: textarea
id: errors
attributes:
label: Errors
description: If there is an error, please include the **entire error** (redacting any sensitive information).
placeholder: "e.g. Error: invalid name (code='INVALID_ARGUMENT, ...)"
render: shell
- type: dropdown
id: environment
attributes:
label: Environment
description: What environment, platforms or frameworks are you using? Select all that apply.
multiple: true
options:
- Ethereum (mainnet, ropsten, rinkeby, goerli, etc.)
- Altcoin (Matic, BNB, etc.)
- node.js (v12 or newer)
- node.js (older than v12)
- Browser (Chrome, Safari, etc)
- React Native/Expo/JavaScriptCore
- Hardhat
- Geth
- Parity
- Ganache
- Other (please specify)
- type: input
id: other-envrionment
attributes:
label: Environment (Other)
placeholder: anything else?

View File

@@ -1,22 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: investigate
assignees: ''
---
Note: Not all sections may be relevant, but please be as thorough while remaining concise as possible. Remove this Notice and any sections that don't feel pertinent.
**Describe the bug**
A clear and concise description of what the bug is.
**Reproduction steps**
Please include code snippets, with console.log output, any contract ABI, contract address, network and the full error.
**Environment:**
Please include anything that may be useful in diagnosing the issue. Node vs Browser? Geth vs Parity vs Ganache? Third Party tools, like Hardhat? Mobile vs. Desktop?
**Search Terms**
Often similar issues have come up before. Include any search terms you have tried in this repository's Issues (including closed issues) and Discussions, so if there are matching issues, we can be sure to add those keywords to make it easier for people to find in the future.

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -0,0 +1,23 @@
name: Documentation
description: Documentation update, change or suggestion
title: "Documentation Title"
labels: ["documentation"]
body:
- type: markdown
attributes:
value: |
Please include anything about the [documentation](https://docs.ethers.io) you would like to see improved.
- Missing information or details?
- Spelling or Grammar mistakes?
- Wrong Information?
- Dead or wrong links?
- Something needs code examples?
- General feedback or anything else?
- type: textarea
id: suggestion
attributes:
label: Suggestion
placeholder: e.g. please add an example for ropsten
validations:
required: true

View File

@@ -1,22 +0,0 @@
---
name: Feature Request
about: Suggest a new feature for ethers
title: ''
labels: ''
assignees: ''
---
Note: The best place to start a Feature Request is usually in the Discussions, to mull through the desired feature, current options and think through the impact on the library overall.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -0,0 +1,26 @@
name: Feature Request
description: Suggest a new feature or addition to Ethers
title: "Feature Request Title"
labels: [ "enhancement" ]
body:
- type: markdown
attributes:
value: |
The best place to start a new feature request is by starting an [Idea discussion](https://github.com/ethers-io/ethers.js/discussions), to mull over the feature, discuss current options and think through the impact on the overall library.
Keep in mind that features increase the library size, and may require additional dependencies. Ethers strives to remain lean and the number of dependencies low, so many features may make more sense as ancillary packages.
- type: textarea
id: about-the-feature
attributes:
label: Describe the Feature
description: Please describe the feature, the problem it is solving, your solution and alternatives you've considered.
placeholder: e.g. I want Ethers to be more/less magical.
validations:
required: true
- type: textarea
id: code-example
attributes:
label: Code Example
description: Optionally, provide an example of how the feature would be used in code.
placeholder: e.g. provider.doMagic()
render: shell

27
.github/ISSUE_TEMPLATE/other.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Other
description: Open a general issue
title: Other Issue Title
body:
- type: markdown
attributes:
value: |
**READ THIS FIRST**
This form should almost **NEVER** be used. Consider closely why your issue does not fit into one of the [other categories](https://github.com/ethers-io/ethers.js/issues/new/choose).
You almost certainly wish to use [the discussions](https://github.com/ethers-io/ethers.js/discussions) instead, to ask a question or seek further guidance.
- type: textarea
id: about
attributes:
label: Describe your Issue
description: Please include as much relevant context as possible, be concise and clearly explain what you are looking for.
placeholder: e.g. What is the answer to life, the universe and everything?
validations:
required: true
- type: checkboxes
attributes:
label: This is an exception issue
description: This form is **only** for *exceptional issues*, which do not match any [other categoeries](https://github.com/ethers-io/ethers.js/issues/new/choose).
options:
- label: I understand this form is for exceptional issues and believe my issue qualifies.
required: true

View File

@@ -15,7 +15,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: [ 8.x, 10.x, 12.x, 13.x ]
node-version: [ 12.x, 14.x, 16.x ]
steps:
- name: Use Node.js ${{ matrix.node-version }}

View File

@@ -3,6 +3,213 @@ Changelog
This change log is managed by `admin/cmds/update-versions` but may be manually updated.
ethers/v5.6.3 (2022-04-13 00:23)
--------------------------------
- Mimic Hardhard error strings in CALL_EXCEPTION for popular matchers. ([#2849](https://github.com/ethers-io/ethers.js/issues/2849), [#2862](https://github.com/ethers-io/ethers.js/issues/2862); [dab6ede](https://github.com/ethers-io/ethers.js/commit/dab6ede226e572706655e2865d4c953e37741a5c))
- Fix pocket API key not being passed in for default provider. ([#2890](https://github.com/ethers-io/ethers.js/issues/2890); [056d7c8](https://github.com/ethers-io/ethers.js/commit/056d7c8bfc5896759c383d7cfae8ed0ec5c5eefb))
ethers/v5.6.2 (2022-03-25 17:56)
--------------------------------
- Fixed left-padding in arrayify. ([#2833](https://github.com/ethers-io/ethers.js/issues/2833); [e192903](https://github.com/ethers-io/ethers.js/commit/e19290305080ebdfa2cb2ab2719cb53fee5a6cc7))
- More robust JSON-RPC error handling for reverted executions. ([#2603](https://github.com/ethers-io/ethers.js/issues/2603); [9d9b14b](https://github.com/ethers-io/ethers.js/commit/9d9b14b95299b793c1a0f4cb8f42e4e0252fed1c))
- Added IPNS support for ENS contenthash. ([e70f3fe](https://github.com/ethers-io/ethers.js/commit/e70f3fe26f3b0dfd44fdbc163e2cc6c8eb9433f8))
- Added initial AnkrProvider ([96de581](https://github.com/ethers-io/ethers.js/commit/96de58122af57be761e431e9268958eeaa352480))
ethers/v5.6.1 (2022-03-16 01:25)
--------------------------------
- Fix issue with CCIP Read using wrong sender. ([#2478](https://github.com/ethers-io/ethers.js/issues/2478); [5998fea](https://github.com/ethers-io/ethers.js/commit/5998fea53d5ea26358c2f10939dfdf0bc679936d), [905e98a](https://github.com/ethers-io/ethers.js/commit/905e98aa392e2a52d6b0339b21bfce5237fd8662))
ethers/v5.6.0 (2022-03-09 14:57)
--------------------------------
- Tweaked test case to re-order transaction after event listeners added. ([fa4a290](https://github.com/ethers-io/ethers.js/commit/fa4a29028d97d598b43b2f5ff98077e8cadf56a4))
- Ignore errors when resolving ENS resolver properties. ([d160bac](https://github.com/ethers-io/ethers.js/commit/d160bac273775f928a9441b0275dbdb6032368fa))
- Enable CCIP Read for ENS resolvers. ([#2478](https://github.com/ethers-io/ethers.js/issues/2478); [be518c3](https://github.com/ethers-io/ethers.js/commit/be518c32ec7db9dd4769b57cdf130eb333aebb72))
- Fix missing events on certain network conditions. ([#1798](https://github.com/ethers-io/ethers.js/issues/1798), [#1814](https://github.com/ethers-io/ethers.js/issues/1814), [#1830](https://github.com/ethers-io/ethers.js/issues/1830), [#2274](https://github.com/ethers-io/ethers.js/issues/2274), [#2652](https://github.com/ethers-io/ethers.js/issues/2652); [f67a9a8](https://github.com/ethers-io/ethers.js/commit/f67a9a8569cdfd0ef9ce5fbf09866aab6e4814d4), [f46aa75](https://github.com/ethers-io/ethers.js/commit/f46aa75ef1f3428e640cd046db3f080d264b32f3))
- Added defaultProvider option to omit specific Providers. ([bae215e](https://github.com/ethers-io/ethers.js/commit/bae215eb7fb3efea8473a544579abac1bebb7ef0))
- Add support for pending blocks. ([#2225](https://github.com/ethers-io/ethers.js/issues/2225); [54e6e57](https://github.com/ethers-io/ethers.js/commit/54e6e57fcece4c1718a577ecbeb1af97998e8bdc))
- Help URLs for errors. ([#2489](https://github.com/ethers-io/ethers.js/issues/2489); [38e825c](https://github.com/ethers-io/ethers.js/commit/38e825cee624ff935ec6b70023cf288126a6bb85), [c562150](https://github.com/ethers-io/ethers.js/commit/c562150d2678710f50e5ee3ffa88d0e62d6f696f))
- Added CCIP support to provider.call. ([#2478](https://github.com/ethers-io/ethers.js/issues/2478); [ae23bb7](https://github.com/ethers-io/ethers.js/commit/ae23bb76a937924bf57baf679e6efd8cdf59bc47))
- Adjust default maxPriorityFeePerGas to 1.5 gwei. ([33a029e](https://github.com/ethers-io/ethers.js/commit/33a029e457320a226c68a01f4cfa2d110125a8b8))
- Fix contracts when name resolution fails without any checks. ([#2737](https://github.com/ethers-io/ethers.js/issues/2737); [c2a6a01](https://github.com/ethers-io/ethers.js/commit/c2a6a012bf1d8fcd5805e45754cebdfe211c6933))
- Preserve explicit chainId in JsonRpcProvider during transaction serialization. ([#2691](https://github.com/ethers-io/ethers.js/issues/2691); [6807a76](https://github.com/ethers-io/ethers.js/commit/6807a76b8ddfdd121f98b21e269de3b195a7673e))
- Fixed eth_chainId response for Eip1193Bridge. ([#2711](https://github.com/ethers-io/ethers.js/issues/2711); [5f26fd5](https://github.com/ethers-io/ethers.js/commit/5f26fd55c9d010c00f830a4c83a480a54773858d))
- Remove spurious console.log from Interface. ([#2714](https://github.com/ethers-io/ethers.js/issues/2714); [4e8f004](https://github.com/ethers-io/ethers.js/commit/4e8f004e9e42892840663311cafe042c0b24c61e))
- Allow raw WebSocket to be passed into WebSocketProvider. ([#2562](https://github.com/ethers-io/ethers.js/issues/2562), [#2644](https://github.com/ethers-io/ethers.js/issues/2644); [9aac785](https://github.com/ethers-io/ethers.js/commit/9aac785395e9b47655477a3ba7baf05df3274de9))
- Added Cloudflare Worker support. ([#1886](https://github.com/ethers-io/ethers.js/issues/1886); [2d98b4f](https://github.com/ethers-io/ethers.js/commit/2d98b4fca1eb2544fec728f7c1c7b0d450e0dbee), [1651389](https://github.com/ethers-io/ethers.js/commit/1651389571b5dd16c1c056dcd94729b48a4bdd85))
- Add support for EIP-2098 compact signatures. ([#2246](https://github.com/ethers-io/ethers.js/issues/2246); [f26074b](https://github.com/ethers-io/ethers.js/commit/f26074b92b0fc8efd3d85c68e84cc6ff8897e4a8))
- Add EIP-2544 Wildcard support. ([#2477](https://github.com/ethers-io/ethers.js/issues/2477), [#2582](https://github.com/ethers-io/ethers.js/issues/2582), [#2583](https://github.com/ethers-io/ethers.js/issues/2583); [83891f9](https://github.com/ethers-io/ethers.js/commit/83891f9258492f9801aa579ac50764b6491b6180))
ethers/v5.5.4 (2022-01-24 16:45)
--------------------------------
- Support invalid but popular IPFS URI format. ([#2271](https://github.com/ethers-io/ethers.js/issues/2271), [#2527](https://github.com/ethers-io/ethers.js/issues/2527), [#2590](https://github.com/ethers-io/ethers.js/issues/2590); [03545aa](https://github.com/ethers-io/ethers.js/commit/03545aa78b0e7bd177e22432e4842b0580a11d7d))
ethers/v5.5.3 (2022-01-06 03:52)
--------------------------------
- Fixed case-folding in schemes for ENS avatars. ([#2500](https://github.com/ethers-io/ethers.js/issues/2500); [3f5bc6d](https://github.com/ethers-io/ethers.js/commit/3f5bc6ddc1013f0a5974f2ee6f542d6c91480c13))
- Added Kintsugi network. ([#2434](https://github.com/ethers-io/ethers.js/issues/2434); [ab13887](https://github.com/ethers-io/ethers.js/commit/ab13887cda3939703dc1f7e27d139ef6001b7dd2))
- Fix browser random in WebWorkers. ([#2405](https://github.com/ethers-io/ethers.js/issues/2405); [4ba63ac](https://github.com/ethers-io/ethers.js/commit/4ba63acc107fdd0a6d6ef3e27349e65edb007447))
- Add support for IPFS metadata imageUrl in getAvatar. ([#2426](https://github.com/ethers-io/ethers.js/issues/2426); [3d6a7ec](https://github.com/ethers-io/ethers.js/commit/3d6a7ec020eacd993b4b0fd3274574de3ddcc257))
- Do not swallow ENS not supported errors. ([#2387](https://github.com/ethers-io/ethers.js/issues/2387); [2f57c6a](https://github.com/ethers-io/ethers.js/commit/2f57c6a4ab44083b2c03f5e57b2702ab7078d286))
ethers/v5.5.2 (2021-11-30 19:16)
--------------------------------
- Fixed test case for getAvatar; url has moved ([617714d](https://github.com/ethers-io/ethers.js/commit/617714d19632c7b4789f042ef8357f858421fbae))
- Added basic redirect support. ([42784b8](https://github.com/ethers-io/ethers.js/commit/42784b8d38a96170d19ea8adcbc42ebf7415804c))
- Added arbitrum and optimism to networks and providers. ([#2335](https://github.com/ethers-io/ethers.js/issues/2335); [0844de4](https://github.com/ethers-io/ethers.js/commit/0844de4eb45eb4170fafb6f2a239b53b6be22f1c))
- Added support for data URLs for avatar metadata. ([b8391b0](https://github.com/ethers-io/ethers.js/commit/b8391b0e61bf3627702668920c4fd6506f9bdc60))
- Fixed getAvatar for unconfigured ENS names. ([1e1c93e](https://github.com/ethers-io/ethers.js/commit/1e1c93effa083765be52f3dee10400a9b3eeb003))
ethers/v5.5.1 (2021-10-20 03:59)
--------------------------------
- Fixed abstract Provider signature issue. ([#2190](https://github.com/ethers-io/ethers.js/issues/2190); [1bd9161](https://github.com/ethers-io/ethers.js/commit/1bd91615eedcb34a24fca04aa93a9aac394968ed))
ethers/v5.5.0 (2021-10-19 00:01)
--------------------------------
- Added ENS avatar support to provider. ([#2185](https://github.com/ethers-io/ethers.js/issues/2185); [ecce861](https://github.com/ethers-io/ethers.js/commit/ecce86125d87ef5258406bde2fff5bc8c9ff3141))
- Fixed splitSignature logic for verifying EIP-2930 and EIP-1559 v. ([#2084](https://github.com/ethers-io/ethers.js/issues/2084); [3de1b81](https://github.com/ethers-io/ethers.js/commit/3de1b815014b10d223a42e524fe9c25f9087293b))
- Include events on ContractFactory deployment transactions. ([#1334](https://github.com/ethers-io/ethers.js/issues/1334); [ab319f2](https://github.com/ethers-io/ethers.js/commit/ab319f2f4c365d4cd1b1e17e577ecd18a7a89276))
- admin: fixed alias script. ([#1494](https://github.com/ethers-io/ethers.js/issues/1494); [8f3d71d](https://github.com/ethers-io/ethers.js/commit/8f3d71dc5fd0e91407737a4b82c58c31269ed2be))
- Better errors when non-string address or ENS name is passed into Contracts or provider methods. ([#1051](https://github.com/ethers-io/ethers.js/issues/1051); [a5c6a46](https://github.com/ethers-io/ethers.js/commit/a5c6a468f4a7ad29fb5277e08c6b8b208383a575))
- Use personal_sign instead of eth_sign for message signing with JsonRpcSigner; added _legacySignMessage for legacy support. ([#1542](https://github.com/ethers-io/ethers.js/issues/1542), [#1840](https://github.com/ethers-io/ethers.js/issues/1840); [8947fd4](https://github.com/ethers-io/ethers.js/commit/8947fd405e3aea07f6db958d89a3ad39abe3a25a))
- Removed extra wordlists from the dist files. ([#2058](https://github.com/ethers-io/ethers.js/issues/2058), [#2077](https://github.com/ethers-io/ethers.js/issues/2077); [cb43a99](https://github.com/ethers-io/ethers.js/commit/cb43a99405cdc5bdcc875efc1821e00e55447791))
- Fix issue when Solidity method collises with JavaScript prototype. ([#1432](https://github.com/ethers-io/ethers.js/issues/1432), [#2054](https://github.com/ethers-io/ethers.js/issues/2054), [#2120](https://github.com/ethers-io/ethers.js/issues/2120); [0a8be37](https://github.com/ethers-io/ethers.js/commit/0a8be37b087470d9354f387d7c439cb0166eaf4d))
- Add support for Cloudflare Workers. ([#1886](https://github.com/ethers-io/ethers.js/issues/1886); [6582ede](https://github.com/ethers-io/ethers.js/commit/6582ede1ce46be0b3abafb120e052b95a2d172b3))
- Added more information to some invalid argument errors. ([#1130](https://github.com/ethers-io/ethers.js/issues/1130); [f3c6d81](https://github.com/ethers-io/ethers.js/commit/f3c6d819f34b6d93f53d98b9f337ade5aa37a594))
- Fix compile-time error in new TypeScript version. ([bee76a4](https://github.com/ethers-io/ethers.js/commit/bee76a49b2e5f95ea2eab49aabf5e44cb4ca794b))
- Adding customData support to transactions to assist L2 chains. ([#1761](https://github.com/ethers-io/ethers.js/issues/1761); [68095a4](https://github.com/ethers-io/ethers.js/commit/68095a48ae19ed06cbcf2f415f1fcbda90d4b2ae))
- Added some explicit null results to previously implicit null results for ENS. ([#1850](https://github.com/ethers-io/ethers.js/issues/1850); [0e5419e](https://github.com/ethers-io/ethers.js/commit/0e5419ec79cb18d82bab8c47bfa3ab4a21cfd293))
- Added BigNumber _difficulty to Block results. ([#2001](https://github.com/ethers-io/ethers.js/issues/2001), [#2036](https://github.com/ethers-io/ethers.js/issues/2036); [a48552a](https://github.com/ethers-io/ethers.js/commit/a48552a4fb85a08178d07437a3934db98b7d0736))
- Removed redundant call to normalizing blockTag (1838). ([d5b41ce](https://github.com/ethers-io/ethers.js/commit/d5b41ce210c0f22dd795749810f6ce798f71a00f))
- Fixed isBytes check for invalid length or elements. ([#1964](https://github.com/ethers-io/ethers.js/issues/1964); [7a404fb](https://github.com/ethers-io/ethers.js/commit/7a404fb8ed95a99baab8f3b384f438b697fa5d76))
- Fixed randomBytes not rejecting NaN as a length. ([#1977](https://github.com/ethers-io/ethers.js/issues/1977); [f8adf82](https://github.com/ethers-io/ethers.js/commit/f8adf82e16aaad1a7c1750e7f2e3a9f8073b73e1))
- Allow any Networkish for getDefaultProvider. ([#2031](https://github.com/ethers-io/ethers.js/issues/2031); [cc250b2](https://github.com/ethers-io/ethers.js/commit/cc250b2060451e0ee6b1cf3edb6b005f9eee9c61))
- Stop allowing commas in fixed numbers; left over from legacy comma support. ([#2083](https://github.com/ethers-io/ethers.js/issues/2083); [45f3675](https://github.com/ethers-io/ethers.js/commit/45f367512d1d5dccfd06fad9cc8688e4d0cccdb8))
- Export FallbackProviderConfig. ([#2121](https://github.com/ethers-io/ethers.js/issues/2121); [48c9e0b](https://github.com/ethers-io/ethers.js/commit/48c9e0bf39eec9b5b30ab7cd5685effdccaa1b1a))
ethers/v5.4.7 (2021-09-16 13:17)
--------------------------------
- Fix parseUints with excess zeros and fix ReDoS issue. ([#2016](https://github.com/ethers-io/ethers.js/issues/2016), [#1975](https://github.com/ethers-io/ethers.js/issues/1975), [#1976](https://github.com/ethers-io/ethers.js/issues/1976); [32a6b2a](https://github.com/ethers-io/ethers.js/commit/32a6b2a362815eb85ce3f3abad5adf92f2b80e10))
ethers/v5.4.6 (2021-08-27 15:34)
--------------------------------
- Temporarily remove the block miner for clique-based networks from CI testing. ([#1967](https://github.com/ethers-io/ethers.js/issues/1967); [8320d53](https://github.com/ethers-io/ethers.js/commit/8320d534d78173dfa8ecb4def634a00483a6aa9c))
- More readable errors involving Uint8Arrays. ([b6a061e](https://github.com/ethers-io/ethers.js/commit/b6a061e7bfd14c1f2df1418df37f704275908e8b))
- Added Deferred Error support to Description objects to extent Interface parse methods. ([#1894](https://github.com/ethers-io/ethers.js/issues/1894); [a662490](https://github.com/ethers-io/ethers.js/commit/a662490e82a9b71b5f6dee0a8242e6fa78409d79))
- Fix address coder to prepare non-hexdatastring addresses as hexdatastring. ([#1906](https://github.com/ethers-io/ethers.js/issues/1906); [017b1fe](https://github.com/ethers-io/ethers.js/commit/017b1feba2c9dea88f078b299d211cbd58d43b49))
- Removed temporary code for better errors needed until Alchemy added EIP-1559 support. ([#1893](https://github.com/ethers-io/ethers.js/issues/1893); [accb852](https://github.com/ethers-io/ethers.js/commit/accb85268c92fa894e769ec1dca322e117d33e5f))
ethers/v5.4.5 (2021-08-18 03:05)
--------------------------------
- Fxied getBlockWithTransactions results (#1858). ([78e4273](https://github.com/ethers-io/ethers.js/commit/78e4273a327d12da9a1ec008d3f2146d97385921))
ethers/v5.4.4 (2021-08-04 01:37)
--------------------------------
- Fixed Etherscan API key in default provider. ([#1807](https://github.com/ethers-io/ethers.js/issues/1807); [1d27d95](https://github.com/ethers-io/ethers.js/commit/1d27d95670ee3a51879393fed44297128c4a42a3))
- Adjust default masPriorityFeePerGas to account for MEV-heavy blocks. ([#1817](https://github.com/ethers-io/ethers.js/issues/1817); [7175e2e](https://github.com/ethers-io/ethers.js/commit/7175e2e99c2747e8d2314feb407bf0a0f9371ece))
ethers/v5.4.3 (2021-07-29 23:26)
--------------------------------
- Fixed JsonRpcProvider for pre-EIP-2930 chains. ([#1766](https://github.com/ethers-io/ethers.js/issues/1766); [7274cd0](https://github.com/ethers-io/ethers.js/commit/7274cd06cf3f6f31c6df3fd6636706d8536b7ee2))
- Forward some missing EIP-1559 fields to call and estimateGas. ([#1766](https://github.com/ethers-io/ethers.js/issues/1766); [be3854e](https://github.com/ethers-io/ethers.js/commit/be3854e648fdef0478db8a64c26be6d9e90cf453))
- Fixed possible UnhandledPromiseException for bad ENS names. ([63f8b28](https://github.com/ethers-io/ethers.js/commit/63f8b2822318d1e0fcc41f4662feb6e5ae338f3d))
- Prevent overriding value for non-payble constructors. ([#1785](https://github.com/ethers-io/ethers.js/issues/1785); [593b488](https://github.com/ethers-io/ethers.js/commit/593b4886ff607d00d656b8131b843933eb48838e))
ethers/v5.4.2 (2021-07-23 17:22)
--------------------------------
- Fix test case for new transactions responses. ([0aafca7](https://github.com/ethers-io/ethers.js/commit/0aafca71dbc019beb398e1b5a0f24936a4fd215a))
- Added matic support to INFURA and Alchemy. ([#1546](https://github.com/ethers-io/ethers.js/issues/1546); [576e9b5](https://github.com/ethers-io/ethers.js/commit/576e9b54abc3ff048113f93f765aa3177bf3b819))
- Added string change to coalesce errors on some clients. ([bc5cc2e](https://github.com/ethers-io/ethers.js/commit/bc5cc2e7e34f6cc69c43c1665be9c18854fb26b8))
- Added wait to transactions returned by getBlockWithTransactions. ([#971](https://github.com/ethers-io/ethers.js/issues/971); [660e69d](https://github.com/ethers-io/ethers.js/commit/660e69db71d42084b1fe791d864d13f0111f84fb))
- Fixed floor, ceiling and round for FixedNumber for non-default Formats. ([#1749](https://github.com/ethers-io/ethers.js/issues/1749); [551cfa0](https://github.com/ethers-io/ethers.js/commit/551cfa0062ec1645c9310335e0e6cbd250bb3788))
- Fixed null confirmations in Wallet transaction. ([#1706](https://github.com/ethers-io/ethers.js/issues/1706); [0f0d0c0](https://github.com/ethers-io/ethers.js/commit/0f0d0c00d3fc14e5454169d42a9286b1d8b0abef))
- Fixed Etherscan string change and enabled all tests. ([a1f8d18](https://github.com/ethers-io/ethers.js/commit/a1f8d188a7bc0b0d11426b7ef0d018cc1b7b399d))
ethers/v5.4.1 (2021-07-02 01:47)
--------------------------------
- Added Pocket back into Homestead defaultProvider and skip certain EtherscanProvider tests affected by outage. ([6e8a39e](https://github.com/ethers-io/ethers.js/commit/6e8a39ec35123e681e47807f54ef9b9122635ea0))
- Fixed EtherscanProvider NONCE_EXPIRED matching string update. ([ecae793](https://github.com/ethers-io/ethers.js/commit/ecae793edff172a885e5ee014a8ad0b28b68c1e5))
- Fixed explicit EIP-1559 keys for JsonRpcSigner. ([72feee8](https://github.com/ethers-io/ethers.js/commit/72feee8f5841febdab0d15f09baa69539d95e199))
ethers/v5.4.0 (2021-06-26 01:50)
--------------------------------
- Added EIP-1559 support. ([#1610](https://github.com/ethers-io/ethers.js/issues/1610); [319987e](https://github.com/ethers-io/ethers.js/commit/319987ec3e1d0e8787f98f525e5fc07875bf5570), [91fff14](https://github.com/ethers-io/ethers.js/commit/91fff1449df5e337fd3b4681b5a04b151d92f5a1), [c5bca77](https://github.com/ethers-io/ethers.js/commit/c5bca7767e3f3d43e3d0bd3c9e9420321ee9907a), [5456c35](https://github.com/ethers-io/ethers.js/commit/5456c359245d9eef5d2abdc05ccedb5269576c94), [7a12216](https://github.com/ethers-io/ethers.js/commit/7a12216cfbd3f86b917451924957471b8be21a8b), [e95708e](https://github.com/ethers-io/ethers.js/commit/e95708eedc130aeb92820a2234398970a987c507))
- Added effectiveGasPrice to receipt. ([ba6854b](https://github.com/ethers-io/ethers.js/commit/ba6854bdd5a912fe873d5da494cb5c62c190adde))
- Fixed ENS names for JsonRpcSigner. ([1e31b34](https://github.com/ethers-io/ethers.js/commit/1e31b34a5a3a269867a45b519662db85f0c86654))
- Added EIP-2930 and EIP-1559 transaction tests. ([7deb4c1](https://github.com/ethers-io/ethers.js/commit/7deb4c174a30b75f8419b8661829add4e5cb69d6))
- Added ConstructorFragment to exports. ([7efc36d](https://github.com/ethers-io/ethers.js/commit/7efc36df294ddd333e37793cad712cbd587bc686))
- Added error utilities to Interface. ([720bde7](https://github.com/ethers-io/ethers.js/commit/720bde7719d9a2fbc7e859f8952b7918e7164b87), [f053a7a](https://github.com/ethers-io/ethers.js/commit/f053a7ad58866c8192a64e1e335a2613358385be))
- merged master including transaction type 0 legacy constant. ([#1610](https://github.com/ethers-io/ethers.js/issues/1610); [2a7ce0e](https://github.com/ethers-io/ethers.js/commit/2a7ce0e72a1e0c9469e10392b0329e75e341cf18))
- Added type to TransactionResponse and TrnsactionReceipt. ([#1687](https://github.com/ethers-io/ethers.js/issues/1687); [d001901](https://github.com/ethers-io/ethers.js/commit/d001901c8c0541c823eb9638b9b309a316b00757))
- Trap CALL_EXCEPTION errors when resolving ENS entries. ([#1690](https://github.com/ethers-io/ethers.js/issues/1690); [91951dc](https://github.com/ethers-io/ethers.js/commit/91951dc825af42d4440d2d3b43cfa7a601b20342))
- Fixed transaction serialization with explicit null type. ([#1628](https://github.com/ethers-io/ethers.js/issues/1628); [8277f5a](https://github.com/ethers-io/ethers.js/commit/8277f5a62a6739a05ae6682da6956fb490b81e4a))
- Fix issue with loading JSON ABI with internalType property. ([#728](https://github.com/ethers-io/ethers.js/issues/728); [e8a0144](https://github.com/ethers-io/ethers.js/commit/e8a0144b7aa95add967578d9629d70bf01fc55cf))
ethers/v5.3.1 (2021-06-10 18:28)
--------------------------------
- Fixed replacement transaction detection for JsonRpcSigner. ([#1658](https://github.com/ethers-io/ethers.js/issues/1658); [ee82e86](https://github.com/ethers-io/ethers.js/commit/ee82e86ccc439825259d20825a00050217890ad3))
- Added Matic testnet info to networks. ([#1546](https://github.com/ethers-io/ethers.js/issues/1546); [376cf3c](https://github.com/ethers-io/ethers.js/commit/376cf3cdbf6d2281331d36c5742414a425927318))
- Match Solidity identifier regex. ([#1657](https://github.com/ethers-io/ethers.js/issues/1657); [a6e128f](https://github.com/ethers-io/ethers.js/commit/a6e128f5cc566d291b722cca1734ba41aae6c548))
ethers/v5.3.0 (2021-05-31 18:41)
--------------------------------
- Added MinInt256 and MaxInt256 constants. ([#1576](https://github.com/ethers-io/ethers.js/issues/1576); [bfcd05f](https://github.com/ethers-io/ethers.js/commit/bfcd05fcbb132d456d6f22f70c8ac9cf5b1826f7))
- Version bumps for bn.js and hash.js to match elliptic and fix some build tools. ([#1478](https://github.com/ethers-io/ethers.js/issues/1478); [819b1ac](https://github.com/ethers-io/ethers.js/commit/819b1ace5c9b16e29dc354ad80e0e5b71ac63c52))
- Removed Hangul checks in shims which crashes Android. ([#1519](https://github.com/ethers-io/ethers.js/issues/1519); [4b33114](https://github.com/ethers-io/ethers.js/commit/4b331148d980e3056ceaabdcd6e50a2aa1beb40d))
- Fixed ENS namehash with leading and trailing dots. ([#1605](https://github.com/ethers-io/ethers.js/issues/1605); [7adcf3b](https://github.com/ethers-io/ethers.js/commit/7adcf3b154669d9d1a0a66d5e15dabfbf6618180))
- Fixed broken variable in template string. ([#1624](https://github.com/ethers-io/ethers.js/issues/1624), [#1626](https://github.com/ethers-io/ethers.js/issues/1626); [630656e](https://github.com/ethers-io/ethers.js/commit/630656e949a8ffd940e4b66ec93ec07cd6ec2634))
- Fixed FixedNumber rounding for non-default formats. ([#1629](https://github.com/ethers-io/ethers.js/issues/1629); [8681cd5](https://github.com/ethers-io/ethers.js/commit/8681cd59698d02d040871aa889fc6ccc8550df98))
- Update ws dependency version to fix security. ([#1633](https://github.com/ethers-io/ethers.js/issues/1633), [#1634](https://github.com/ethers-io/ethers.js/issues/1634); [470551e](https://github.com/ethers-io/ethers.js/commit/470551e4ee3f1e343a26fc0775f9d9f7489129f8))
ethers/v5.2.0 (2021-05-17 16:18)
--------------------------------
- More aggresively check for mempool transactions sent from JsonRpcSigner. ([3316468](https://github.com/ethers-io/ethers.js/commit/3316468e3e0a5925cbecad85d894cc7d622394e7))
- Added initial support for detecting replacement transactions. ([#1477](https://github.com/ethers-io/ethers.js/issues/1477); [987bec8](https://github.com/ethers-io/ethers.js/commit/987bec87afaa365f291290a0136cedbc2b1992f2), [5144acf](https://github.com/ethers-io/ethers.js/commit/5144acf456b51c95bbe3950bd37609abecc7ebc7))
- Added convenience method for HD path derivation. ([aadc5cd](https://github.com/ethers-io/ethers.js/commit/aadc5cd3d65421e13ebd4e4d7c293ac3ece5e178))
- Added mnemonicPath option to cli. ([6e08809](https://github.com/ethers-io/ethers.js/commit/6e088099adabd7c5d2e6710062ebc62b316ba0f1))
- Added some popular Ethereum-compatible chains to networks. ([b6370f1](https://github.com/ethers-io/ethers.js/commit/b6370f13600a0c444342cbf16a83f010a929976b))
- Added debug event to Web3Provider. ([26464c5](https://github.com/ethers-io/ethers.js/commit/26464c54258f98c321638475d6cf11595186e76d))
- Abstracted EtherscanProivder to more easily fascilitate other Etherscan-supported chains. ([#1204](https://github.com/ethers-io/ethers.js/issues/1204), [#1473](https://github.com/ethers-io/ethers.js/issues/1473); [37a9c77](https://github.com/ethers-io/ethers.js/commit/37a9c77ab2acb7f75e1fc4cc918810d2fe59dd76))
- Added Custom Contract Errors. ([#1498](https://github.com/ethers-io/ethers.js/issues/1498); [6519609](https://github.com/ethers-io/ethers.js/commit/65196097f6626401638d85cf19e3d628a6223d5d), [483d67f](https://github.com/ethers-io/ethers.js/commit/483d67f55c15a76bcd853e889a0e35815d9850f7))
- More flexible FixedNumber input and output for strings with no decimals. ([#1019](https://github.com/ethers-io/ethers.js/issues/1019), [#1291](https://github.com/ethers-io/ethers.js/issues/1291), [#1463](https://github.com/ethers-io/ethers.js/issues/1463); [a9cdbe1](https://github.com/ethers-io/ethers.js/commit/a9cdbe1238c149a7167c6bb1a78f314805b52755))
- Added hex support for bigint. ([#1472](https://github.com/ethers-io/ethers.js/issues/1472); [4e9abfd](https://github.com/ethers-io/ethers.js/commit/4e9abfdee478a8423da4d55feea8c1aae78a8eb4))
- Added support for null entries in EventFilter. ([#1499](https://github.com/ethers-io/ethers.js/issues/1499); [3bb5fbf](https://github.com/ethers-io/ethers.js/commit/3bb5fbf533107e880377ecc14f30f314a5028e56))
- Add bigint to allowed BigNumberish types. ([#1472](https://github.com/ethers-io/ethers.js/issues/1472); [cadccc3](https://github.com/ethers-io/ethers.js/commit/cadccc3060b88ab2ca64aeb302717d2d1c95a897))
- Minor version bump. ([8e22e02](https://github.com/ethers-io/ethers.js/commit/8e22e0260eb70713c943c9e99ee8d66d71ebe56d))
ethers/v5.1.4 (2021-04-22 06:33)
--------------------------------
- Do not throw on ABI "error" type. ([#1493](https://github.com/ethers-io/ethers.js/issues/1493), [#1497](https://github.com/ethers-io/ethers.js/issues/1497); [bd05aed](https://github.com/ethers-io/ethers.js/commit/bd05aed070ac9e1421a3e2bff2ceea150bedf9b7))
ethers/v5.1.3 (2021-04-19 21:01)
--------------------------------
- Fixed JsonRpcProvider event-loop caching when using any network. ([#1484](https://github.com/ethers-io/ethers.js/issues/1484); [58488e7](https://github.com/ethers-io/ethers.js/commit/58488e78f9ef79715693e19b42663335aad88c03))
- Updated experimental Eip1193Bridge to support final EIP-1193 API. ([2911659](https://github.com/ethers-io/ethers.js/commit/29116593ba6c9c0fa491b13787cca8b233d4218c))
- Fail early for ABI decoding that will obviously run out of data. ([#1486](https://github.com/ethers-io/ethers.js/issues/1486); [51f0e1a](https://github.com/ethers-io/ethers.js/commit/51f0e1a52fb885e6f146f7b3b70ed487fd1c8f5a))
- Fixed BigNumber toBigInt return type. ([#1485](https://github.com/ethers-io/ethers.js/issues/1485); [c086962](https://github.com/ethers-io/ethers.js/commit/c0869623024bbf3671938dad03b131ff2ac54345))
ethers/v5.1.2 (2021-04-18 19:31)
--------------------------------

View File

@@ -26,10 +26,12 @@ A complete Ethereum wallet implementation and utilities in JavaScript (and TypeS
Keep Updated
------------
For the latest news and advisories, please follow the [@ethersproject](https://twitter.com/ethersproject)
on Twitter (low-traffic, non-marketing, important information only) as well as watch this GitHub project.
For the latest news and advisories, please follow the
[@ethersproject](https://twitter.com/ethersproject) on Twitter (low-traffic,
non-marketing, important information only) as well as watch this GitHub project.
For the latest changes, see the [CHANGELOG](https://github.com/ethers-io/ethers.js/blob/master/CHANGELOG.md).
For the latest changes, see the
[CHANGELOG](https://github.com/ethers-io/ethers.js/blob/master/CHANGELOG.md).
Installing
@@ -44,7 +46,7 @@ Installing
**browser (UMD)**
```
<script src="https://cdn.ethers.io/lib/ethers-5.0.umd.min.js" type="text/javascript">
<script src="https://cdn.ethers.io/lib/ethers-5.6.umd.min.js" type="text/javascript">
</script>
```
@@ -52,7 +54,7 @@ Installing
```
<script type="module">
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.0.esm.min.js";
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.6.esm.min.js";
</script>
```
@@ -66,7 +68,34 @@ Browse the [documentation](https://docs.ethers.io/v5/) online:
- [Full API Documentation](https://docs.ethers.io/v5/api/)
- [Various Ethereum Articles](https://blog.ricmoo.com/)
Or browse the entire documentation as a [single page](https://docs.ethers.io/v5/single-page/) to make searching easier.
Providers
---------
Ethers works closely with an ever-growing list of third-party providers
to ensure getting started is quick and easy, by providing default keys
to each service.
These built-in keys mean you can use `ethers.getDefaultProvider()` and
start developing right away.
However, the API keys provided to ethers are also shared and are
intentionally throttled to encourage developers to eventually get
their own keys, which unlock many other features, such as faster
responses, more capacity, analytics and other features like archival
data.
When you are ready to sign up and start using for your own keys, please
check out the [Provider API Keys](https://docs.ethers.io/v5/api-keys/) in
the documentation.
A special thanks to these services for providing community resources:
- [Ankr](https://www.ankr.com/)
- [Etherscan](https://etherscan.io/)
- [INFURA](https://infura.io/)
- [Alchemy](https://dashboard.alchemyapi.io/signup?referral=55a35117-028e-4b7c-9e47-e275ad0acc6d)
- [Pocket](https://pokt.network/pocket-gateway-ethereum-mainnet/)
Ancillary Packages

View File

@@ -25,7 +25,7 @@ free tier, which (depending on the service) includes many advantages:
- useful **metric tracking** for performance tuning and to analyze your customer behaviour
- more **advanced APIs**, such as archive data or advanced log queries
_subsection: Etherscan @<api-keys--etherscan>
_subsection: Etherscan @NOTE<(see the [[EtherscanProvider]])> @<api-keys--etherscan>
Etherscan is an Ethereum block explorer, which is possibly the most useful
developer tool for building and debugging Ethereum applications.
@@ -40,13 +40,17 @@ operations required to interact with the Ethereum Blockchain.
- higher rate limit (since you are not using the [shared rate limit](link-etherscan-ratelimit))
- customer usage metrics
_subsection: INFURA @<api-keys--infura>
_definition: **Networks:**
``homestead``, ``ropsten``, ``rinkeby``, ``goerli`` and ``kovan``.
_subsection: INFURA @NOTE<(see the [[InfuraProvider]])> @<api-keys--infura>
The INFURA service has been around for quite some time and is very robust
and reliable and highly recommended.
They offer a standard JSON-RPC interface and a WebSocket interface, which makes
interaction with standard tools versatile, simple and straight forward.
interaction with standard tools versatile, simple and straightforward.
[Sign up for a free Project ID on INFURA](link-infura-signup)
@@ -56,7 +60,13 @@ interaction with standard tools versatile, simple and straight forward.
- customer usage metrics
- access to archive data (requires paid upgrade)
_subsection: Alchemy @<api-keys--alchemy>
_definition: **Networks:**
``homestead``, ``ropsten``, ``rinkeby``, ``goerli``, ``kovan``, ``matic``,
``maticmum``, ``optimism``, ``optimism-kovan``, ``arbitrum`` and
``arbitrum-rinkeby``.
_subsection: Alchemy @NOTE<(see the [[AlchemyProvider]])> @<api-keys--alchemy>
The Alchemy service has been around a few years and is also very robust
and reliable.
@@ -74,9 +84,17 @@ with debugging.
- access to advanced token balance and metadata APIs
- access to advanced debugging trace and revert reason APIs
_subsection: Pocket Gateway@<api-keys--pocket-gateway>
_definition: **Networks:**
``homestead``, ``ropsten``, ``rinkeby``, ``goerli``, ``kovan``, ``matic``,
``maticmum``, ``optimism``, ``optimism-kovan``, ``arbitrum`` and
``arbitrum-rinkeby``.
_subsection: Pocket Gateway @NOTE<(see the [[PocketProvider]])> @<api-keys--pocket-gateway>
They offer a standard JSON-RPC interface using either a load-balanced
network or non-load-balanced fleet.
[Sign up for a free API key on Pocket](link-pocket-signup)
**Benefits:**
@@ -86,6 +104,26 @@ _subsection: Pocket Gateway@<api-keys--pocket-gateway>
- Stake as opposed to paying a monthly fee
- Highly redundant global set of nodes incentivized by cryptoeconomic incentives
_definition: **Networks:**
``homestead``
_subsection: Ankr @NOTE<(see the [[AnkrProvider]])> @<api-keys--ankr>
They offer a standard JSON-RPC interface and have fairly high capacity without
the need for an API key early on in the development cycle.
[See their free tier features on Ankr](link-ankr-public)
**Benefits:**
- higher rate limit
- customer usage metrics
- access to archive data (requires paid upgrade)
_definition: **Networks:**
``homestead``, ``matic`` and ``arbitrum``
_subsection: Creating a Default Provider @<api-keys--getDefaultProvider>
@@ -100,6 +138,8 @@ using the default API key for that service.
It is **highly recommended** that you provide an API for each service, to
maximize your applications performance.
If the API key ``"-"`` is used, the corresponding Provider will be omitted.
_code: Passing API Keys into getDefaultProvider @lang<script>
// Use the mainnet
@@ -122,5 +162,6 @@ const provider = ethers.getDefaultProvider(network, {
// pocket: {
// applicationId: ,
// applicationSecretKey:
// }
// },
ankr: YOUR_ANKR_API_KEY
});

View File

@@ -0,0 +1,34 @@
// Do not use this; it is only for an example in the docs
contract MyToken {
event Transfer(address indexed from, address indexed to, uint amount);
mapping (address => uint256) _balances;
constructor(uint256 totalSupply) {
emit Transfer(address(0), msg.sender, totalSupply);
_balances[msg.sender] = totalSupply;
}
// Read-Only Functions
function balanceOf(address owner) public view returns (uint256) {
return _balances[owner];
}
function decimals() public pure returns (uint8) {
return 18;
}
function symbol() public pure returns (string memory) {
return "MyToken";
}
// Authenticated Functions
function transfer(address to, uint amount) public returns (bool) {
require(_balances[msg.sender] >= amount, "insufficient token balance");
_balances[msg.sender] -= amount;
_balances[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
}

View File

@@ -23,7 +23,7 @@ Consumes the output of the Solidity compiler, extracting the ABI
and bytecode from it, allowing for the various formats the solc
compiler has emitted over its life.
_property: contractFactory.connect(signer) => [[Contract]] @<ContractFactory-connect>
_property: contractFactory.connect(signer) => [[ContractFactory]] @<ContractFactory-connect>
Returns a **new instance** of the ContractFactory with the same //interface//
and //bytecode//, but with a different //signer//.
@@ -78,12 +78,9 @@ override the endowment ``value``, transaction ``nonce``, ``gasLimit`` or
_code: Deploying a Contract @lang<javascript>
// <hide>
const signer = localSigner;
const ContractFactory = ethers.ContractFactory;
const bytecode = "608060405234801561001057600080fd5b5060405161012e38038061012e8339818101604052604081101561003357600080fd5b81019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060008190555050506088806100a66000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633fa4f24514602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220926465385af0e8706644e1ff3db7161af699dc063beaadd55405f2ccd6478d7564736f6c63430007040033";
// </hide>
//_hide: const signer = localSigner;
//_hide: const ContractFactory = ethers.ContractFactory;
//_hide: const bytecode = "608060405234801561001057600080fd5b5060405161012e38038061012e8339818101604052604081101561003357600080fd5b81019080805190602001909291908051906020019092919050505081600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508060008190555050506088806100a66000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80633fa4f24514602d575b600080fd5b60336049565b6040518082815260200191505060405180910390f35b6000805490509056fea2646970667358221220926465385af0e8706644e1ff3db7161af699dc063beaadd55405f2ccd6478d7564736f6c63430007040033";
// If your contract constructor requires parameters, the ABI
// must include the constructor
@@ -97,25 +94,26 @@ factory = new ContractFactory(abi, bytecode, signer)
// Deploy an instance of the contract
contract = await factory.deploy("ricmoo.eth", 42);
//<hide>
//! async contract
//</hide>
// The address is available immediately, but the contract
// is NOT deployed yet
//_result:
contract.address
//!
//_log:
// The transaction that the signer sent to deploy
//_result:
contract.deployTransaction
//!
//_log:
// Wait until the transaction is mined (i.e. contract is deployed)
// - returns the receipt
// - throws on failure (the reciept is on the error)
contract.deployTransaction.wait()
//!
//_result:
await contract.deployTransaction.wait()
//_log:
// Now the contract is safe to interact with
contract.value()
//!
//_result:
await contract.value()
//_log:

View File

@@ -98,11 +98,12 @@ at run-time during the **Contract** constructor.
_heading: Read-Only Methods (constant) @<Contract--readonly>
A constant method is read-only and evaluates a small amount of EVM
code against the current blockchain state and can be computed by
asking a single node, which can return a result. It is therefore
free and does not require any ether, but **cannot make changes** to
the blockchain state..
A constant method (denoted by ``pure`` or ``view`` in Solidity)
is read-only and evaluates a small amount of EVM code against the
current blockchain state and can be computed by asking a single
node, which can return a result. It is therefore free and does
not require any ether, but **cannot make changes** to the
blockchain state..
_property: contract.METHOD_NAME(...args [, overrides ]) => Promise<any> @<Contract-functionsCall>
The type of the result depends on the ABI. If the method returns a single
@@ -111,7 +112,7 @@ be returned with each parameter available positionally and if the parameter
is named, it will also be available by its name.
For values that have a simple meaning in JavaScript, the types are fairly
straight forward; strings and booleans are returned as JavaScript strings
straightforward; strings and booleans are returned as JavaScript strings
and booleans.
For numbers, if the **type** is in the JavaScript safe range (i.e. less
@@ -132,7 +133,7 @@ The //overrides// object for a read-only method may include any of:
- ``overrides.from`` - the ``msg.sender`` (or ``CALLER``) to use during the
execution of the code
- ``overrides.value`` - the ``msg.value`` (or ``CALLVALUE``) to use during the
exectuiont of the code
execution of the code
- ``overrides.gasPrice`` - the price to pay per gas (theoretically); since there
is no transaction, there is not going to be any fee charged, but the EVM still
requires a value to report to ``tx.gasprice`` (or ``GASPRICE``);

View File

@@ -1,10 +1,75 @@
_section: Example: ERC-20 Contract
The concept of Meta-Classes is somewhat confusing, so we will go
over a short example.
A meta-class is a class which is defined at run-time. A Contract
is specified by an //Application Binary Interface// (ABI), which describes
the methods and events it has. This description is passed the the
[[Contract]] object at run-time, and it creates a new Class, adding
all the methods defined in the ABI at run-time.
_subsection: Deploying a Contract
Most often, any contract you will need to interact with will already
be deployed to the blockchain, but for this example will will first
deploy the contract.
_property: new ethers.ContractFactory(abi, bytecode, signer)
Create a new [[ContractFactory]] which can deploy a contract to the
blockchain.
_code: @lang<javascript>
//_hide: const signer = localSigner;
//_hide: const parseUnits = utils.parseUnits;
const bytecode = "0x608060405234801561001057600080fd5b506040516103bc3803806103bc83398101604081905261002f9161007c565b60405181815233906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a333600090815260208190526040902055610094565b60006020828403121561008d578081fd5b5051919050565b610319806100a36000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c8063313ce5671461005157806370a082311461006557806395d89b411461009c578063a9059cbb146100c5575b600080fd5b604051601281526020015b60405180910390f35b61008e610073366004610201565b6001600160a01b031660009081526020819052604090205490565b60405190815260200161005c565b604080518082018252600781526626bcaa37b5b2b760c91b6020820152905161005c919061024b565b6100d86100d3366004610222565b6100e8565b604051901515815260200161005c565b3360009081526020819052604081205482111561014b5760405162461bcd60e51b815260206004820152601a60248201527f696e73756666696369656e7420746f6b656e2062616c616e6365000000000000604482015260640160405180910390fd5b336000908152602081905260408120805484929061016a9084906102b6565b90915550506001600160a01b0383166000908152602081905260408120805484929061019790849061029e565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350600192915050565b80356001600160a01b03811681146101fc57600080fd5b919050565b600060208284031215610212578081fd5b61021b826101e5565b9392505050565b60008060408385031215610234578081fd5b61023d836101e5565b946020939093013593505050565b6000602080835283518082850152825b818110156102775785810183015185820160400152820161025b565b818111156102885783604083870101525b50601f01601f1916929092016040019392505050565b600082198211156102b1576102b16102cd565b500190565b6000828210156102c8576102c86102cd565b500390565b634e487b7160e01b600052601160045260246000fdfea2646970667358221220d80384ce584e101c5b92e4ee9b7871262285070dbcd2d71f99601f0f4fcecd2364736f6c63430008040033";
// A Human-Readable ABI; we only need to specify relevant fragments,
// in the case of deployment this means the constructor
const abi = [
"constructor(uint totalSupply)"
];
const factory = new ethers.ContractFactory(abi, bytecode, signer)
// Deploy, setting total supply to 100 tokens (assigned to the deployer)
const contract = await factory.deploy(parseUnits("100"));
// The contract is not currentl live on the network yet, however
// its address is ready for us
//_result:
contract.address
//_log:
//_hide: _page.address = contract.address;
// Wait until the contract has been deployed before interacting
// with it; returns the receipt for the deployemnt transaction
//_result:
await contract.deployTransaction.wait();
//_log:
_subsection: Connecting to a Contract
_code: A simple ERC-20 contract @lang<javascript>
_heading: ERC20Contract @INHERIT<[[Contract]]>
// A Human-Readable ABI; any supported ABI format could be used
_property: new ethers.Contract(address, abi, providerOrSigner)
Creating a new instance of a Contract connects to an existing
contract by specifying its //address// on the blockchain,
its //abi// (used to populate the class' methods) a //providerOrSigner//.
If a [[Provider]] is given, the contract has only read-only access, while
a [[Signer]] offers access to state manipulating methods.
_code: @lang<javascript>
//_hide: const provider = localProvider;
//_hide: const signer = localSigner;
// A Human-Readable ABI; for interacting with the contract, we
// must include any fragment we wish to use
const abi = [
// Read-Only Functions
"function balanceOf(address owner) view returns (uint256)",
@@ -12,20 +77,15 @@ const abi = [
"function symbol() view returns (string)",
// Authenticated Functions
"function transfer(address to, uint amount) returns (boolean)",
"function transfer(address to, uint amount) returns (bool)",
// Events
"event Transfer(address indexed from, address indexed to, uint amount)"
];
// This can be an address or an ENS name
const address = "dai.tokens.ethers.eth";
// An example Provider
const provider = ethers.getDefaultProvider();
// An example Signer
const signer = ethers.Wallet.createRandom().connect(provider);
//_hide: const address = _page.address;
//_verbatim: `const address = ${ JSON.stringify(address) };`
// Read-Only; By connecting to a Provider, allows:
// - Any constant function
@@ -34,20 +94,13 @@ const signer = ethers.Wallet.createRandom().connect(provider);
// - Estimating Gas for non-constant (as an anonymous sender)
// - Static Calling non-constant methods (as anonymous sender)
const erc20 = new ethers.Contract(address, abi, provider);
//_hide: _page.erc20 = erc20;
// Read-Write; By connecting to a Signer, allows:
// - Everything from Read-Only (except as Signer, not anonymous)
// - Sending transactions for non-constant functions
const erc20_rw = new ethers.Contract(address, abi, signer)
_heading: ERC20Contract @INHERIT<[[Contract]]>
_property: new ethers.Contract(address, abi, providerOrSigner)
See the above code example for creating an Instance which will
(in addition to the Contact methods and properties) automatically
add the additional properties defined in //abi// to a **Contract**
connected to //address// using the //providerOrSigner//.
const erc20_rw = new ethers.Contract(address, abi, signer);
//_hide: _page.erc20_rw = erc20_rw;
_subsection: Properties @NOTE<(inheritted from [[Contract]])>
@@ -101,6 +154,8 @@ _property: Contract.isIndexed(value) => boolean
_subsection: Events @NOTE<(inheritted from [[Contract]])> @<erc20-events>
See [Meta-Class Filters](erc20-meta-events) for examples using events.
_property: erc20.queryFilter(event [ , fromBlockOrBlockHash [ , toBlock ]) => Promise<Array<Event>> @<erc20-queryfilter>
Return Events that match the //event//.
@@ -126,7 +181,7 @@ Unsubscribe all listeners for //event//. If no event is provided,
all events are unsubscribed.
_subsection: Meta-Class Methods @NOTE<(added at Runtime)>
_subsection: Meta-Class Methods @NOTE<(added at Runtime)> @<erc20-meta-methods>
Since the Contract is a Meta-Class, the methods available here depend
on the ABI which was passed into the **Contract**.
@@ -136,12 +191,35 @@ Returns the number of decimal places used by this ERC-20 token. This can be
used with [parseUnits](utils-parseUnits) when taking input from the user or
[formatUnits](utils-formatunits] when displaying the token amounts in the UI.
_code: @lang<javascript>
//_hide: const erc20 = _page.erc20;
//_result:
await erc20.decimals();
//_log:
_property: erc20.balanceOf(owner [, overrides ]) => Promise<[[BigNumber]]>
Returns the balance of //owner// for this ERC-20 token.
_code: @lang<javascript>
//_hide: const signer = localSigner;
//_hide: const erc20 = _page.erc20;
//_result:
await erc20.balanceOf(signer.getAddress())
//_log:
_property: erc20.symbol([ overrides ]) => Promise<string>
Returns the symbol of the token.
_code: @lang<javascript>
//_hide: const erc20 = _page.erc20;
//_result:
await erc20.symbol();
//_log:
_property: erc20_rw.transfer(target, amount [, overrides ]) => Promise<[[providers-TransactionResponse]]>
Transfers //amount// tokens to //target// from the current signer.
The return value (a boolean) is inaccessible during a write operation
@@ -149,20 +227,86 @@ using a transaction. Other techniques (such as events) are required
if this value is required. On-chain contracts calling the ``transfer``
function have access to this result, which is why it is possible.
_code: @lang<javascript>
//_hide: const signer = localSigner;
//_hide: const erc20_rw = _page.erc20_rw;
//_hide: const parseUnits = utils.parseUnits;
//_hide: const formatUnits = utils.formatUnits;
// Before...
//_result:
formatUnits(await erc20_rw.balanceOf(signer.getAddress()));
//_log:
// Transfer 1.23 tokens to the ENS name "ricmoo.eth"
//_result:
tx = await erc20_rw.transfer("ricmoo.eth", parseUnits("1.23"));
//_log:
// Wait for the transaction to be mined...
//_result:
await tx.wait();
//_log:
// After!
//_result:
formatUnits(await erc20_rw.balanceOf(signer.getAddress()));
//_log:
//_result:
formatUnits(await erc20_rw.balanceOf("ricmoo.eth"));
//_log:
_property: erc20.callStatic.transfer(target, amount [, overrides ]) => Promise<boolean>
Performs a dry-run of transferring //amount// tokens to //target// from
the current signer, without actually signing or sending a transaction.
This can be used to preflight check that a transaction will be successful.
_code: @lang<javascript>
//_hide: const erc20_rw = _page.erc20_rw;
//_hide: const randomWallet = ethers.Wallet.createRandom().connect(erc20_rw.provider);
//_hide: const parseUnits = utils.parseUnits;
// The signer has enough tokens to send, so true is returned
//_result:
await erc20_rw.callStatic.transfer("ricmoo.eth", parseUnits("1.23"));
//_log:
// A random address does not have enough tokens to
// send, in which case the contract throws an error
erc20_random = erc20_rw.connect(randomWallet);
//_throws:
await erc20_random.callStatic.transfer("ricmoo.eth", parseUnits("1.23"));
//_log:
_property: erc20.estimateGas.transfer(target, amount [, overrides ]) => Promise<[[BigNumber]]>
Returns an estimate for how many units of gas would be required
to transfer //amount// tokens to //target//.
_code: @lang<javascript>
//_hide: const erc20_rw = _page.erc20_rw;
//_hide: const parseUnits = utils.parseUnits;
//_result:
await erc20_rw.estimateGas.transfer("ricmoo.eth", parseUnits("1.23"));
//_log:
_property: erc20.populateTransaction.transfer(target, amount [, overrides ]) => Promise<[UnsignedTx](UnsignedTransaction)>
Returns an [[UnsignedTransaction]] which could be signed and submitted
to the network to transaction //amount// tokens to //target//.
_code: @lang<javascript>
//_hide: const erc20_rw = _page.erc20_rw;
//_hide: const parseUnits = utils.parseUnits;
//_result:
await erc20_rw.populateTransaction.transfer("ricmoo.eth", parseUnits("1.23"));
//_log:
_note: Note on Estimating and Static Calling
@@ -173,7 +317,7 @@ blockchain also means there are certain consistency modes that cannot be
known until an actual transaction is attempted.
_subsection: Meta-Class Filters @NOTE<(added at Runtime)>
_subsection: Meta-Class Filters @NOTE<(added at Runtime)> @<erc20-meta-events>
Since the Contract is a Meta-Class, the methods available here depend
on the ABI which was passed into the **Contract**.
@@ -184,3 +328,75 @@ to [subscribe/unsubscribe to events](erc20-events).
If //fromAddress// is null or not provided, then any from address matches.
If //toAddress// is null or not provided, then any to address matches.
_code: query filter *from* events @lang<javascript>
//_hide: const signer = localSigner;
//_hide: const erc20 = _page.erc20;
//_result:
filterFrom = erc20.filters.Transfer(signer.address);
//_log:
// Search for transfers *from* me in the last 10 blocks
//_result:
logsFrom = await erc20.queryFilter(filterFrom, -10, "latest");
//_log:
// Note that the args providees the details of the event, each
// parameters is available positionally, and since our ABI
// included parameter names also by name
//_result:
logsFrom[0].args
//_log:
//_hide: _page.filterFrom = filterFrom;
_code: query filter with *to* events @lang<javascript>
//_hide: const signer = localSigner;
//_hide: const erc20 = _page.erc20;
//_result:
filterTo = erc20.filters.Transfer(null, signer.address);
//_log:
// Search for transfers *to* me in the last 10 blocks
// Note: the contract transferred totalSupply tokens to us
// when it was deployed in its constructor
//_result:
logsTo = await erc20.queryFilter(filterTo, -10, "latest");
//_log:
// Note that the args providees the details of the event, each
// parameters is available positionally, and since our ABI
// included parameter names also by name
//_result:
logsTo[0].args
//_log:
//_hide: _page.filterTo = filterTo;
_code: listen for events @lang<javascript>
//_hide: const erc20 = _page.erc20;
//_hide: const filterFrom = _page.filterFrom;
//_hide: const filterTo = _page.filterTo;
// Listen to incoming events from signer:
erc20.on(filterFrom, (from, to, amount, event) => {
// The `from` will always be the signer address
});
// Listen to incoming events to signer:
erc20.on(filterTo, (from, to, amount, event) => {
// The `to` will always be the signer address
});
// Listen to all Transfer events:
erc20.on("Transfer", (from, to, amount, event) => {
// ...
});
//_hide: erc20.removeAllListeners();

View File

@@ -5,6 +5,10 @@ to be included in the base library. The API should not be considered
stable and does not follow [[link-semver]] versioning, so applications
requiring it should specify the //exact version// needed.
These features are not available in the core ethers package, so to use them
you must install the ``@ethersproject/experimental`` package and import them
from that.
_subsection: BrainWallet @<experimental-brainwallet> @INHERIT<[[Wallet]]>
Ethers removed support for BrainWallets in v4, since they are unsafe and
@@ -19,6 +23,14 @@ the generated wallet has a mnemonic.
_property: BrainWallet.generateLegacy(username, password [ , progressCallback ]) => [[experimental-brainwallet]]
Generate a brain wallet which is compatible with the ethers v3 and earlier.
_code: Importing @lang<script>
// Node
const { BrainWallet } = require("@ethersproject/experimental");
// ESM/TypeScript
import { BrainWallet } from "@ethersproject/experimental";
_subsection: EIP1193Bridge @<experimental-eip1193bridge> @INHERIT<[[link-npm-events]]>
@@ -26,6 +38,14 @@ The **EIP1193Bridge** allows a normal Ethers [[Signer]] and [[Provider]] to be
exposed in as a standard [EIP-1193 Provider](link-eip-1193), which may be useful
when interacting with other libraries.
_code: Importing @lang<script>
// Node
const { Eip1193Bridge } = require("@ethersproject/experimental");
// ESM/TypeScript
import { Eip1193Bridge } from "@ethersproject/experimental";
_subsection: NonceManager @<experimental-noncemanager> @INHERIT<[[Signer]]>
@@ -63,3 +83,11 @@ Bump the current transaction count (nonce) by //count//.
This may be useful in interacting with the signer outside of using
this class.
_code: Importing @lang<script>
// Node
const { NonceManager } = require("@ethersproject/experimental");
// ESM/TypeScript
import { NonceManager } from "@ethersproject/experimental";

View File

@@ -11,7 +11,7 @@ To mitigate these issues, it is recommended you use a
[Default Provider](providers-getDefaultProvider).
_subsection: EtherscanProvider @<EtherscanProvider> @inherit<[[Provider]]> @src<providers:class.EtherscanProvider>
_subsection: EtherscanProvider @<EtherscanProvider> @inherit<[[BaseProvider]]> @src<providers:class.EtherscanProvider>
The **EtherscanProvider** is backed by a combination of the various
[Etherscan APIs](link-etherscan-api).
@@ -39,18 +39,16 @@ It is highly recommended for production, you register with
_definition: **Supported Networks**
- Homestead (Mainnet)
- Ropsten (proof-of-work testnet)
- Rinkeby (proof-of-authority testnet)
- G&ouml;rli (clique testnet)
- Kovan (proof-of-authority testnet)
- ``homestead`` - Homestead (Mainnet)
- ``ropsten`` - Ropsten (proof-of-work testnet)
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
- ``goerli`` - G&ouml;rli (clique testnet)
- ``kovan`` - Kovan (proof-of-authority testnet)
_code: Etherscan Examples @lang<javascript>
// <hide>
const EtherscanProvider = ethers.providers.EtherscanProvider;
const apiKey = "...";
// </hide>
//_hide: const EtherscanProvider = ethers.providers.EtherscanProvider;
//_hide: const apiKey = "...";
// Connect to mainnet (homestead)
provider = new EtherscanProvider();
@@ -59,12 +57,9 @@ provider = new EtherscanProvider();
provider = new EtherscanProvider("rinkeby");
provider = new EtherscanProvider(4);
const network = ethers.providers.getNetwork("rinkeby");
// <hide>
delete network._defaultProvider;
network
// </hide>
//!
network = ethers.providers.getNetwork("rinkeby");
//_hide: delete network._defaultProvider;
//_log: network
provider = new EtherscanProvider(network);
@@ -111,19 +106,23 @@ It is highly recommended for production, you register with
_definition: **Supported Networks**
- Homestead (Mainnet)
- Ropsten (proof-of-work testnet)
- Rinkeby (proof-of-authority testnet)
- G&ouml;rli (clique testnet)
- Kovan (proof-of-authority testnet)
- ``homestead`` - Homestead (Mainnet)
- ``ropsten`` - Ropsten (proof-of-work testnet)
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
- ``goerli`` - G&ouml;rli (clique testnet)
- ``kovan`` - Kovan (proof-of-authority testnet)
- ``matic`` - Polygon
- ``maticmum`` - Polygon Mumbai Testnet
- ``optimism`` - Optimism (L2; optimistic roll-up)
- ``optimism-kovan`` - Optimism Testnet (L2; optimistic roll-up testnet)
- ``arbitrum`` - Arbitrum (L2; optimistic roll-up)
- ``arbitrum-rinkeby`` - Arbitrum Testnet (L2; optimistic roll-up testnet)
_code: INFURA Examples @lang<javascript>
// <hide>
const InfuraProvider = ethers.providers.InfuraProvider;
const projectId = "...";
const projectSecret = "...";
// </hide>
//_hide: const InfuraProvider = ethers.providers.InfuraProvider;
//_hide: const projectId = "...";
//_hide: const projectSecret = "...";
// Connect to mainnet (homestead)
provider = new InfuraProvider();
@@ -144,9 +143,7 @@ provider = new InfuraProvider("homestead", {
// Connect to the INFURA WebSocket endpoints with a WebSocketProvider
provider = InfuraProvider.getWebSocketProvider()
// <hide>
provider.destroy();
// </hide>
//_hide: await provider.destroy();
_subsection: AlchemyProvider @<AlchemyProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.AlchemyProvider>
@@ -170,18 +167,22 @@ It is highly recommended for production, you register with
_definition: **Supported Networks**
- Homestead (Mainnet)
- Ropsten (proof-of-work testnet)
- Rinkeby (proof-of-authority testnet)
- G&ouml;rli (clique testnet)
- Kovan (proof-of-authority testnet)
- ``homestead`` - Homestead (Mainnet)
- ``ropsten`` - Ropsten (proof-of-work testnet)
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
- ``goerli`` - G&ouml;rli (clique testnet)
- ``kovan`` - Kovan (proof-of-authority testnet)
- ``matic`` - Polygon
- ``maticmum`` - Polygon Mumbai Testnet
- ``optimism`` - Optimism (L2; optimistic roll-up)
- ``optimism-kovan`` - Optimism Testnet (L2; optimistic roll-up testnet)
- ``arbitrum`` - Arbitrum (L2; optimistic roll-up)
- ``arbitrum-rinkeby`` - Arbitrum Testnet (L2; optimistic roll-up testnet)
_code: Alchemy Examples @lang<javascript>
// <hide>
const AlchemyProvider = ethers.providers.AlchemyProvider;
const apiKey = "...";
// </hide>
//_hide: const AlchemyProvider = ethers.providers.AlchemyProvider;
//_hide: const apiKey = "...";
// Connect to mainnet (homestead)
provider = new AlchemyProvider();
@@ -196,9 +197,7 @@ provider = new AlchemyProvider("homestead", apiKey);
// Connect to the Alchemy WebSocket endpoints with a WebSocketProvider
provider = AlchemyProvider.getWebSocketProvider()
// <hide>
provider.destroy();
// </hide>
//_hide: provider.destroy();
_subsection: CloudflareProvider @<CloudflareProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.CloudflareProvider>
@@ -210,13 +209,106 @@ Create a new **CloudflareProvider** connected to mainnet (i.e. "homestead").
_definition: **Supported Networks**
- Homestead (Mainnet)
- ``homestead`` - Homestead (Mainnet)
_code: Cloudflare Examples @lang<javascript>
// <hide>
const CloudflareProvider = ethers.providers.CloudflareProvider;
// </hide>
//_hide: const CloudflareProvider = ethers.providers.CloudflareProvider;
// Connect to mainnet (homestead)
provider = new CloudflareProvider();
_subsection: PocketProvider @<PocketProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.PocketProvider>
The **PocketProvider** is backed by [Pocket](link-pocket).
_property: new ethers.providers.PocketProvider([ network = "homestead", [ apiKey ] ])
Create a new **PocketProvider** connected to //network// with
the optional //apiKey//.
The //network// may be specified as a **string** for a common
network name, a **number** for a common chain ID or a
[Network Object](providers-Network).
_note: Note: Default API keys
If no //apiKey// is provided, a shared API key will be used,
which may result in reduced performance and throttled requests.
It is highly recommended for production, you register with
[Pocket](link-pocket) for your own API key.
_definition: **Supported Networks**
- ``homestead`` - Homestead (Mainnet)
- ``ropsten`` - Ropsten (proof-of-work testnet)
- ``rinkeby`` - Rinkeby (proof-of-authority testnet)
- ``goerli`` - G&ouml;rli (clique testnet)
_code: Pocket Examples @lang<javascript>
//_hide: const PocketProvider = ethers.providers.PocketProvider;
//_hide: const applicationId = "...";
//_hide: const applicationSecretKey = "...";
//_hide: const loadBalancer = true;
// Connect to mainnet (homestead)
provider = new PocketProvider();
// Connect to the ropsten testnet
// (see EtherscanProvider above for other network examples)
provider = new PocketProvider("ropsten");
// Connect to mainnet with an Application ID (these are equivalent)
provider = new PocketProvider(null, applicationId);
provider = new PocketProvider("homestead", applicationId);
// Connect to mainnet with an application ID, application secret
// and specify whether to use the load balances
provider = new PocketProvider("homestead", {
applicationId: applicationId,
applicationSecretKey: applicationSecretKey,
loadBalancer: loadBalancer // true or false
});
_subsection: AnkrProvider @<AnkrProvider> @inherit<[[UrlJsonRpcProvider]]> @src<providers:class.AnkrProvider>
The **AnkrProvider** is backed by [Ankr](link-ankr).
_property: new ethers.providers.AnkrProvider([ network = "homestead", [ apiKey ] ])
Create a new **AnkrProvider** connected to //network// with
the optional //apiKey//.
The //network// may be specified as a **string** for a common
network name, a **number** for a common chain ID or a
[Network Object](providers-Network).
_note: Note: Default API keys
If no //apiKey// is provided, a shared API key will be used,
which may result in reduced performance and throttled requests.
It is highly recommended for production, you register with
[Ankr](link-ankr) for your own API key.
_definition: **Supported Networks**
- ``homestead`` - Homestead (Mainnet)
- ``matic`` - Polygon
- ``arbitrum`` - Arbitrum (L2; optimistic roll-up)
_code: Ankr Examples @lang<javascript>
//_hide: const AnkrProvider = ethers.providers.AnkrProvider;
//_hide: const apiKey = "...";
// Connect to mainnet (homestead)
provider = new AnkrProvider();
// Connect to polygont
// (see EtherscanProvider above for other network examples)
provider = new AnkrProvider("matic");
// Connect to mainnet with an API Key (these are equivalent)
provider = new AnkrProvider(null, apiKey);
provider = new AnkrProvider("homestead", apiKey);

View File

@@ -77,9 +77,33 @@ _subsection: Networks
There are several official common Ethereum networks as well as custom
networks and other compatible projects.
Any API that accept a [[providers-Networkish]] can be passed a common name (such as
``"mainnet"`` or ``"ropsten"``) to use that network definition or may specify
custom parameters.
Any API that accept a [[providers-Networkish]] can be passed a common
name (such as ``"mainnet"`` or ``"ropsten"``) or chain ID to use that
network definition or may specify custom parameters.
_property: ethers.providers.getNetwork(aNetworkish) => [[providers-Network]]
Returns the full [[providers-Network]] for the given standard
//aNetworkish// [[providers-Networkish]].
This is useful for functions and classes which wish to accept [[providers-Networkish]]
as an input parameter.
_code: @lang<javascript>
//_hide: const getNetwork = ethers.providers.getNetwork;
// By Chain Name
//_result:
getNetwork("homestead");
//_hide: delete _._defaultProvider;
//_log:
// By Chain ID
//_result:
getNetwork(1);
//_hide: delete _._defaultProvider;
//_log:
_heading: Custom ENS Contract
@@ -92,10 +116,11 @@ _code: Example: Override the ENS registry @lang<script>
const network = {
name: "dev",
chianId: 1337,
chainId: 1337,
ensAddress: customEnsAddress
};
_subsection: Provider Documentation
_toc:

View File

@@ -1,4 +1,4 @@
_section: JsonRpcProvider @<JsonRpcProvider> @INHERIT<[[Provider]]> @SRC<providers:class.JsonRpcProvider>
_section: JsonRpcProvider @<JsonRpcProvider> @INHERIT<[[BaseProvider]]> @SRC<providers:class.JsonRpcProvider>
The [JSON-RPC API](link-jsonrpc) is a popular method for interacting
with Ethereum and is available in all major Ethereum node implementations
@@ -19,6 +19,9 @@ command-line flags, configuration or settings in their UI to enable
JSON-RPC, unlock accounts or expose specific APIs. Please consult
their documentation.
_property: jsonRpcProvider.connection => [[ConnectionInfo]]
The fully formed [[ConnectionInfo]] the Provider is connected to.
_property: jsonRpcProvider.getSigner([ addressOrIndex ]) => [[JsonRpcSigner]] @<JsonRpcProvider-getSigner> @SRC<providers/json-rpc-provider>
Returns a [[JsonRpcSigner]] which is managed by this Ethereum node, at
//addressOrIndex//. If no //addressOrIndex// is provided, the first
@@ -26,7 +29,7 @@ account (account #0) is used.
_property: jsonRpcProvider.getUncheckedSigner([ addressOrIndex ]) => [[UncheckedJsonRpcSigner]] @<JsonRpcProvider-getUncheckedSigner> @SRC<providers/json-rpc-provider>
_property: jsonRpcProvider.listAccounts() => Array<string> @<JsonRpcProvider-listAccounts> @SRC<providers/json-rpc-provider>
_property: jsonRpcProvider.listAccounts() => Promise<Array<string>> @<JsonRpcProvider-listAccounts> @SRC<providers/json-rpc-provider>
Returns a list of all account addresses managed by this provider.
_property: jsonRpcProvider.send(method, params) => Promise<any> @<JsonRpcProvider-send> @SRC<providers/json-rpc-provider>
@@ -75,6 +78,25 @@ object, with most of the properties set to null, but allows access to the
transaction hash quickly, if that is all that is required.
_subsection: StaticJsonRpcProvider @<StaticJsonRpcProvider> @INHERIT<[[JsonRpcProvider]]> @SRC<providers:class.StaticJsonRpcProvider>
An ethers Provider will execute frequent ``getNetwork`` calls to ensure
the network calls and network being communicated with are consistent.
In the case of a client like MetaMask, this is desired as the network
may be changed by the user at any time, in such cases the cost of
checking the chainId is local and therefore cheap.
However, there are also many times where it is known the network cannot
change, such as when connecting to an INFURA endpoint, in which case,
the **StaticJsonRpcProvider** can be used which will indefinitely cache
the chain ID, which can reduce network traffic and reduce round-trip
queries for the chain ID.
This [[Provider]] should **only** be used when it is known the network
cannot change.
_subsection: Node-Specific Methods @<JsonRpcProvider--other>
Many methods are less common or specific to certain Ethereum Node implementations

View File

@@ -1,6 +1,6 @@
_section: Other Providers
_subsection: FallbackProvider @<FallbackProvider> @INHERIT<[[Provider]]> @SRC<providers/fallback-provider:class.FallbackProvider>
_subsection: FallbackProvider @<FallbackProvider> @INHERIT<[[BaseProvider]]> @SRC<providers/fallback-provider:class.FallbackProvider>
The **FallbackProvider** is the most advanced [[Provider]] available in
ethers.
@@ -68,6 +68,18 @@ _property: ipcProvider.path => string
The path this [[Provider]] is connected to.
_subsection: JsonRpcBatchProvider @<JsonRpcBatchProvider> @INHERIT<[[JsonRpcProvider]]> @SRC<providers:class.JsonRpcBatchProvider>
The **JsonRpcBatchProvider** operated identically to any other Provider,
except the calls are implicly batched during an event-loop and sent using
the JSON-RPC batch protocol to the backend.
This results in fewer connections and fewer requests, which may result
in lower costs or faster responses, depending on your use case.
Keep in mind some backends may not support batched requests.
_subsection: UrlJsonRpcProvider @<UrlJsonRpcProvider> @INHERIT<[[JsonRpcProvider]]> @SRC<providers:class.UrlJsonRpcProvider>
This class is intended to be sub-classed and not used directly. It
@@ -99,7 +111,7 @@ application to ethers by wrapping an existing Web3-compatible (such as a
[Web3WsProvider](link-web3-ws)) and exposing it as an ethers.js [[Provider]]
which can then be used with the rest of the library.
This may also be used to wrap a standard [EIP-1193 Provider](link-eip-1193].
This may also be used to wrap a standard [EIP-1193 Provider](link-eip-1193).
_property: new ethers.providers.Web3Provider(externalProvider [, network ])
Create a new **Web3Provider**, which wraps an [EIP-1193 Provider](link-eip-1193) or

View File

@@ -21,35 +21,41 @@ _subsection: Accounts Methods @<Provider--account-methods>
_property: provider.getBalance(address [ , blockTag = latest ]) => Promise<[[BigNumber]]> @<Provider-getBalance> @SRC<providers/base-provider>
Returns the balance of //address// as of the //blockTag// block height.
_code: @lang<javascript>
//_result:
await provider.getBalance("ricmoo.eth");
//_log:
_property: provider.getCode(address [ , blockTag = latest ]) => Promise<string<[[DataHexString]]>> @<Provider-getCode> @SRC<providers/base-provider>
Returns the contract code of //address// as of the //blockTag// block height. If there is
no contract currently deployed, the result is ``0x``.
_code: @lang<javascript>
//_result:
await provider.getCode("registrar.firefly.eth");
//_log:
_property: provider.getStorageAt(addr, pos [ , blockTag = latest ]) => Promise<string<[[DataHexString]]>> @<Provider-getStorageAt> @SRC<providers/base-provider>
Returns the ``Bytes32`` value of the position //pos// at address //addr//, as of the //blockTag//.
_code: @lang<javascript>
//_result:
await provider.getStorageAt("registrar.firefly.eth", 0)
//_log:
_property: provider.getTransactionCount(address [ , blockTag = latest ]) => Promise<number> @<Provider-getTransactionCount> @SRC<providers/base-provider>
Returns the number of transactions //address// has ever **sent**, as of //blockTag//.
This value is required to be the nonce for the next transaction from //address//
sent to the network.
_code: Account Examples @lang<javascript>
_code: @lang<javascript>
// Get the balance for an account...
provider.getBalance("ricmoo.firefly.eth");
//!
// Get the code for a contract...
provider.getCode("registrar.firefly.eth");
//!
// Get the storage value at position 0...
provider.getStorageAt("registrar.firefly.eth", 0)
//!
// Get transaction count of an account...
provider.getTransactionCount("ricmoo.firefly.eth");
//!
//_result:
await provider.getTransactionCount("ricmoo.eth");
//_log:
_subsection: Blocks Methods @<Provider--block-methods>
@@ -58,17 +64,21 @@ _property: provider.getBlock(block) => Promise<[[providers-Block]]> @<Provider-
Get the //block// from the network, where the ``result.transactions`` is a list
of transaction hashes.
_code: @lang<javascript>
//_result:
await provider.getBlock(100004)
//_log:
_property: provider.getBlockWithTransactions(block) => Promise<[[providers-BlockWithTransactions]]> @<Provider-getBlockWithTransactions> @SRC<providers/base-provider>
Get the //block// from the network, where the ``result.transactions`` is
an Array of [[providers-TransactionResponse]] objects.
_code: Block Examples @lang<javascript>
_code: @lang<javascript>
provider.getBlock(100004)
//!
provider.getBlockWithTransactions(100004)
//!
//_result:
await provider.getBlockWithTransactions(100004)
//_log:
_subsection: Ethereum Naming Service (ENS) Methods @<Provider--ens-methods>
@@ -86,29 +96,47 @@ reading and debugging much simpler.
The provider offers some basic operations to help resolve and
work with ENS names.
_property: provider.getAvatar(name) => Promise<string>
Returns the URL for the avatar associated to the ENS name, or null
if no avatar was configured.
_property: provider.getResolver(name) => Promise<[[EnsResolver]]>
Returns an EnsResolver instance which can be used to further inquire
about specific entries for an ENS name.
_code: @lang<javascript>
//_hide: provider = ethers.getDefaultProvider();
// See below (Resolver) for examples of using this object
const resolver = await provider.getResolver("ricmoo.eth");
//_hide: _page.resolver = resolver;
_property: provider.lookupAddress(address) => Promise<string> @<Provider-lookupAddress> @SRC<providers/base-provider>
Performs a reverse lookup of the //address// in ENS using the
//Reverse Registrar//. If the name does not exist, or the
forward lookup does not match, ``null`` is returned.
An ENS name requries additional configuration to setup a reverse
record, they are not automatically set up.
_code: @lang<javascript>
//_result:
await provider.lookupAddress("0x5555763613a12D8F3e73be831DFf8598089d3dCa");
//_log:
_property: provider.resolveName(name) => Promise<string<[Address](address)>> @<Provider-ResolveName> @SRC<providers/base-provider>
Looks up the address of //name//. If the name is not owned, or
does not have a //Resolver// configured, or the //Resolver// does
not have an address configured, ``null`` is returned.
_code: ENS Examples @lang<javascript>
_code: @lang<javascript>
// Reverse lookup of an ENS by address...
provider.lookupAddress("0x6fC21092DA55B392b045eD78F4732bff3C580e2c");
//!
// Lookup an address of an ENS name...
provider.resolveName("ricmoo.firefly.eth");
//!
//_result:
await provider.resolveName("ricmoo.eth");
//_log:
_subsection: EnsResolver @<EnsResolver>
@@ -124,12 +152,63 @@ Returns a Promise which resolves to the [[link-eip-2304]] multicoin address
stored for the //coinType//. By default an Ethereum [[address]]
(``coinType = 60``) will be returned.
_code: @lang<javascript>
//_hide: const resolver = _page.resolver;
// By default, looks up the Ethereum address
// (this will match provider.resolveName)
//_result:
await resolver.getAddress();
//_log:
// Specify the coinType for other coin addresses (0 = Bitcoin)
//_result:
await resolver.getAddress(0);
//_log:
_property: resolver.getAvatar() => Promise<AvatarInfo>
Returns an object the provides the URL of the avatar and the
linkage representing each stage in the avatar resolution.
If there is no avatar found (or the owner of any NFT does not
match the name owner), null is returned.
The AvatarInfo has the properties:
- ``info.linkage`` - An array of info on each step resolving the avatar
- ``info.url`` - The URL of the avatar
_property: resolver.getContentHash() => Promise<string>
Returns a Promise which resolves to any stored [[link-eip-1577]] content hash.
_code: @lang<javascript>
//_hide: const resolver = _page.resolver;
//_result:
await resolver.getContentHash();
//_log:
_property: resolver.getText(key) => Promise<string>
Returns a Promise which resolves to any stored [[link-eip-634]] text entry for //key//.
_code: @lang<javascript>
//_hide: const resolver = _page.resolver;
//_result:
await resolver.getText("email");
//_log:
//_result:
await resolver.getText("url");
//_log:
//_result:
await resolver.getText("com.twitter");
//_log:
_subsection: Logs Methods @<Provider--log-methods>
_property: provider.getLogs(filter) => Promise<Array<[[providers-Log]]>> @<Provider-getLogs> @SRC<providers/base-provider>
@@ -145,12 +224,59 @@ _subsection: Network Status Methods @<Provider--network-methods>
_property: provider.getNetwork() => Promise<[[providers-Network]]> @<Provider-getNetwork> @SRC<providers/base-provider:method.BaseProvider.getNetwork>
Returns the [[providers-Network]] this Provider is connected to.
_code: @lang<javascript>
//_result:
await provider.getNetwork()
//_hide: _ = utils.shallowCopy(_);
//_hide: delete _._defaultProvider;
//_log:
_property: provider.getBlockNumber() => Promise<number> @<Provider-getBlockNumber> @SRC<providers/base-provider>
Returns the block number (or height) of the most recently mined block.
_code: @lang<javascript>
//_result:
await provider.getBlockNumber()
//_log:
_property: provider.getGasPrice() => Promise<[[BigNumber]]> @<Provider-getGasPrice> @SRC<providers/base-provider>
Returns a //best guess// of the [[gas-price]] to use in a transaction.
_code: @lang<javascript>
// The gas price (in wei)...
gasPrice = await provider.getGasPrice()
//_log: gasPrice
// ...often this gas price is easier to understand or
// display to the user in gwei
//_result:
utils.formatUnits(gasPrice, "gwei")
//_log:
_property: provider.getFeeData() => Promise<[[providers-FeeData]]> @<Provider-getFeeData> @SRC<abstract-provider>
Returns the current recommended [[providers-FeeData]] to use in a transaction.
For an EIP-1559 transaction, the ``maxFeePerGas`` and ``maxPriorityFeePerGas``
should be used.
For legacy transactions and networks which do not support EIP-1559, the ``gasPrice``
should be used.
_code: @lang<javascript>
// The gas price (in wei)...
feeData = await provider.getFeeData()
//_log: feeData
// ...often these values are easier to understand or
// display to the user in gwei
//_result:
utils.formatUnits(feeData.maxFeePerGas, "gwei")
//_log:
_property: provider.ready => Promise<[[providers-Network]]> @<Provider-ready> @src<providers/base-provider>
Returns a Promise which will stall until the network has heen established,
ignoring errors due to the target node not being active yet.
@@ -158,31 +284,6 @@ ignoring errors due to the target node not being active yet.
This can be used for testing or attaching scripts to wait until the node is
up and running smoothly.
_code: Network Status Examples @lang<javascript>
// The network information
provider.getNetwork()
// <hide>
//!
network = utils.shallowCopy(_)
delete network._defaultProvider
network
// </hide>
//!
// The current block number
provider.getBlockNumber()
//!
// Get the current suggested gas price (in wei)...
gasPrice = await provider.getGasPrice()
//! async gasPrice
// ...often this gas price is easier to understand or
// display to the user in gwei (giga-wei, or 1e9 wei)
utils.formatUnits(gasPrice, "gwei")
//!
_subsection: Transactions Methods @<Provider--transaction-methods>
@@ -191,6 +292,18 @@ Returns the result of executing the //transaction//, using //call//. A call
does not require any ether, but cannot change any state. This is useful
for calling getters on Contracts.
_code: @lang<javascript>
//_result:
await provider.call({
// ENS public resovler address
to: "0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41",
// `function addr(namehash("ricmoo.eth")) view returns (address)`
data: "0x3b3b57debf074faa138b72c65adbdcfb329847e4f2c04bde7f7dd7fcad5a52d2f395a558"
});
//_log:
_property: provider.estimateGas(transaction) => Promise<[[BigNumber]]> @<Provider-estimateGas> @SRC<providers/base-provider>
Returns an estimate of the amount of gas that would be required to submit //transaction//
to the network.
@@ -199,6 +312,23 @@ An estimate may not be accurate since there could be another transaction
on the network that was not accounted for, but after being mined affected
relevant state.
_code: @lang<javascript>
//_hide: const parseEther = ethers.utils.parseEther;
//_result:
await provider.estimateGas({
// Wrapped ETH address
to: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
// `function deposit() payable`
data: "0xd0e30db0",
// 1 ether
value: parseEther("1.0")
});
//_log:
_property: provider.getTransaction(hash) => Promise<[[providers-TransactionResponse]]> @<Provider-getTransaction> @src<providers/base-provider>
Returns the transaction with //hash// or null if the transaction is unknown.
@@ -207,6 +337,12 @@ pool. Various backends may have more restrictive transaction pool access (e.g.
if the gas price is too low or the transaction was only recently sent and not
yet indexed) in which case this method may also return null.
_code: @lang<javascript>
//_result:
await provider.getTransaction("0x5b73e239c55d790e3c9c3bbb84092652db01bb8dbf49ccc9e4a318470419d9a0");
//_log:
_property: provider.getTransactionReceipt(hash) => Promise<[[providers-TransactionReceipt]]> @<Provider-getTransactionReceipt> @src<providers/base-provider>
Returns the transaction receipt for //hash// or null if the transaction
has not been mined.
@@ -214,11 +350,34 @@ has not been mined.
To stall until the transaction has been mined, consider the ``waitForTransaction``
method below.
_code: @lang<javascript>
//_result:
await provider.getTransactionReceipt("0x5b73e239c55d790e3c9c3bbb84092652db01bb8dbf49ccc9e4a318470419d9a0");
//_log:
_property: provider.sendTransaction(transaction) => Promise<[[providers-TransactionResponse]]> @<Provider-sendTransaction> @SRC<providers/base-provider>
Submits //transaction// to the network to be mined. The //transaction// **must** be signed,
and be valid (i.e. the nonce is correct and the account has sufficient balance to pay
for the transaction).
_code: @lang<javascript>
//_hide: const provider = localProvider;
//_hide: const wallet = new ethers.Wallet(ethers.utils.id("HelloWorld"), provider);
//_hide: const fundTx = await localSigner.sendTransaction({
//_hide: to: wallet.address,
//_hide: value: ethers.utils.parseEther("2.0")
//_hide: });
//_hide: await fundTx.wait();
//_hide: const tx = await localSigner.populateTransaction({ to: "ricmoo.eth", value: ethers.utils.parseEther("3.14159") });
//_hide: const signedTx = await localSigner.signTransaction(tx);
//_verbatim: `const signedTx = ${ JSON.stringify(signedTx) };`
//_result:
await provider.sendTransaction(signedTx);
//_log:
_property: provider.waitForTransaction(hash [ , confirms = 1 [ , timeout ] ]) => Promise<[TxReceipt](providers-TransactionReceipt)> @<Provider-waitForTransaction> @SRC<providers/base-provider>
Returns a Promise which will not resolve until //transactionHash// is mined.
@@ -331,11 +490,10 @@ $Debug: each Provider may use this to emit useful debugging information
_code: Events Example @lang<javascript>
// <hide>
const txHash = utils.id("dummy-data");
const myAddress = ethers.constants.HashZero;
const myOtherAddress = ethers.constants.HashZero;
// </hide>
//_hide: const txHash = utils.id("dummy-data");
//_hide: const myAddress = ethers.constants.HashZero;
//_hide: const myOtherAddress = ethers.constants.HashZero;
//_hide: const hexZeroPad = ethers.utils.hexZeroPad;
provider.on("block", (blockNumber) => {
// Emitted on every block change
@@ -367,8 +525,8 @@ topicSets = [
utils.id("Transfer(address,address,uint256)"),
null,
[
myAddress,
myOtherAddress
hexZeroPad(myAddress, 32),
hexZeroPad(myOtherAddress, 32)
]
]
provider.on(topicSets, (log, event) => {
@@ -385,13 +543,24 @@ provider.on("error", (tx) => {
// Emitted when any error occurs
});
// <hide>
// Make sure our documentation builds without waiting forever
provider.removeAllListeners()
// </hide>
//_hide: provider.removeAllListeners() /* Make sure the docs build without waiting forever */
_subsection: Inspection Methods @<Provider--inspection-methods>
_property: Provider.isProvider(object) => boolean @<Provider-isProvider> @SRC<abstract-provider>
Returns true if and only if //object// is a Provider.
_subsection: BaseProvider @<BaseProvider> @INHERIT<[[Provider]]> @SRC<providers:class.BaseProvider>
Most Providers available in ethers are sub-classes of BaseProvider, which
simplifies sub-classes, as it handles much of the event operations, such as
polling and formatting.
_property: provider.polling => boolean
Indicates if the Provider is currently polling. If there are no events to
poll for or polling has been explicitly disabled, this will be false.
_property: provider.pollingInterval => number
The frequency at which the provider polls.

View File

@@ -34,6 +34,23 @@ _property: network.ensAddress => string<[[address]]>
The address at which the ENS registry is deployed on this network.
_subsection: FeeData @<providers-FeeData>
A **FeeData** object encapsulates the necessary fee data required
to send a transaction, based on the best available recommendations.
_property: feeData.gasPrice => [[BigNumber]]
The gasPrice to use for legacy transactions or networks which do not
support EIP-1559.
_property: feeData.maxFeePerGas => [[BigNumber]]
The ``maxFeePerGas`` to use for a transaction. This is based on the
most recent block's ``baseFee``.
_property: feeData.maxPriorityFeePerGas => [[BigNumber]]
The ``maxPriorityFeePerGas`` to use for a transaction. This accounts
for the uncle risk and for the majority of current MEV risk.
_subsection: Block @<providers-Block>
_property: block.hash => string<[[DataHexString]]<32>>
@@ -183,18 +200,47 @@ _property: transactionRequest.nonce => number | Promise<number>
The nonce for this transaction. This should be set to the number of
transactions ever sent **from** this address.
_property: transactionRequest.gasLimit => [[BigNumber]] | Promise<[[BigNumber]]>
The maximum amount of gas this transaction is permitted to use.
_property: transactionRequest.gasPrice => [[BigNumber]] | Promise<[[BigNumber]]>
The price (in wei) per unit of gas this transaction will pay.
_property: transactionRequest.data => [[DataHexString]] | Promise<[[DataHexString]]>
The transaction data.
_property: transactionRequest.value => [[BigNumber]] | Promise<[[BigNumber]]>
The amount (in wei) this transaction is sending.
_property: transactionRequest.gasLimit => [[BigNumber]] | Promise<[[BigNumber]]>
The maximum amount of gas this transaction is permitted to use.
If left unspecified, ethers will use ``estimateGas`` to determine the value
to use. For transactions with unpredicatable gas estimates, this may be required
to specify explicitly.
_property: transactionRequest.gasPrice => [[BigNumber]] | Promise<[[BigNumber]]>
The price (in wei) per unit of gas this transaction will pay.
This may not be specified for transactions with ``type`` set to ``1`` or ``2``, or
if ``maxFeePerGas`` or ``maxPriorityFeePerGas`` is given.
_property: transactionRequest.maxFeePerGas => [[BigNumber]] | Promise<[[BigNumber]]>
The maximum price (in wei) per unit of gas this transaction will pay for the
combined [[link-eip-1559]] block's base fee and this transaction's priority fee.
Most developers should leave this unspecified and use the default value that
ethers determines from the network.
This may not be specified for transactions with ``type`` set to ``0`` or if ``gasPrice``
is specified..
_property: transactionRequest.maxPriorityFeePerGas => [[BigNumber]] | Promise<[[BigNumber]]>
The price (in wei) per unit of gas this transaction will allow in addition to
the [[link-eip-1559]] block's base fee to bribe miners into giving this transaction
priority. This is **included in** the ``maxFeePerGas``, so this will **not affect**
the total maximum cost set with ``maxFeePerGas``.
Most developers should leave this unspecified and use the default value that
ethers determines from the network.
This may not be specified for transactions with ``type`` set to ``0`` or if ``gasPrice``
is specified.
_property: transactionRequest.chainId => number | Promise<number>
The chain ID this transaction is authorized on, as specified by
[EIP-155](link-eip-155).
@@ -208,12 +254,13 @@ on recent versions of Geth and require configuration to enable.
_property: transactionRequest.type => null | number
The [[link-eip-2718]] type of this transaction envelope, or ``null``
for legacy transactions that do not have an envelope.
for to use the network default. To force using a lagacy transaction
without an envelope, use type ``0``.
_property: transactionRequest.accessList => [[providers-AccessListish]]
The [[providers-AccessList]] to include in an [[link-eip-2930]] transaction, which will
include a ``type`` of ``1``.
The [[providers-AccessList]] to include; only available for [[link-eip-2930]]
and [[link-eip-1559]] transactions.
_heading: TransactionResponse @<providers-TransactionResponse> @INHERIT<[[Transaction]]>
@@ -237,7 +284,9 @@ The number of blocks that have been mined (including the initial block) since th
transaction was mined.
_property: transaction.raw => string<[[DataHexString]]>
The serialized transaction.
The serialized transaction. This may be null as some backends do not
rpopulate it. If this is required, it can be computed from a **TransactionResponse**
object using [this cookbook recipe](cookbook--compute-raw-transaction).
_property: transaction.wait([ confirms = 1 ]) => Promise<[[providers-TransactionReceipt]]>
Resolves to the [[providers-TransactionReceipt]] once the transaction
@@ -245,22 +294,35 @@ has been included in the chain for //confirms// blocks. If //confirms//
is 0, and the transaction has not been mined, ``null`` is returned.
If the transaction execution failed (i.e. the receipt status is ``0``),
a [CALL_EXCEPTION](errors--call-exception) Error will be rejected with
a [CALL_EXCEPTION](errors--call-exception) error will be rejected with
the following properties:
- ``error.transaction`` - the original transaction
- ``error.transactionHash`` - the hash of the transaction
- ``error.receipt`` - the actual receipt, with the status of ``0``
_property: transactionRequest.type => null | number
If the transaction is replaced by another transaction, a
[TRANSACTION_REPLACED](errors--transaction-replaced) error will be rejected
with the following properties:
The [[link-eip-2718]] type of this transaction envelope, or ``null``
for legacy transactions that do not have an envelope.
- ``error.hash`` - the hash of the original transaction which was replaced
- ``error.reason`` - a string reason; one of ``"repriced"``, ``"cancelled"`` or ``"replaced"``
- ``error.cancelled`` - a boolean; a ``"repriced"`` transaction is not considered cancelled, but ``"cancelled"`` and ``"replaced"`` are
- ``error.replacement`` - the replacement transaction (a [[providers-TransactionResponse]])
- ``error.receipt`` - the receipt of the replacement transaction (a [[providers-TransactionReceipt]])
Transactions are replaced when the user uses an option in their client to
send a new transaction from the same account with the original ``nonce``.
This is usually to speed up a transaction or to cancel one, by bribing
miners with additional fees to prefer the new transaction over the original one.
_property: transactionRequest.type => number
The [[link-eip-2718]] type of this transaction. If the transaction
is a legacy transaction without an envelope, it will have the type ``0``.
_property: transactionRequest.accessList => [[providers-AccessList]]
The [[providers-AccessList]] included in an [[link-eip-2930]] transaction, which will
also have its ``type`` equal to ``1``.
The [[providers-AccessList]] included, or null for transaction types which
do not support access lists.
_heading: TransactionReceipt @<providers-TransactionReceipt>
@@ -284,6 +346,10 @@ _property: receipt.transactionIndex => number
The index of this transaction in the list of transactions included in
the block this transaction was mined in.
_property: receipt.type => number
The [[link-eip-2718]] type of this transaction. If the transaction
is a legacy transaction without an envelope, it will have the type ``0``.
_property: receipt.root => string
The intermediate state root of a receipt.
@@ -298,6 +364,16 @@ must be considered.
_property: receipt.gasUsed => [[BigNumber]]
The amount of gas actually used by this transaction.
_property: receipt.effectiveGasPrice => [[BigNumber]]
The effective gas price the transaction was charged at.
Prior to EIP-1559 or on chains that do not support it, this value will
simply be equal to the transaction ``gasPrice``.
On EIP-1559 chains, this is equal to the block ``baseFee`` for the block
that the transaction was included in, plus the transaction
``maxPriorityFeePerGas`` clamped to the transaction ``maxFeePerGas``.
_property: receipt.logsBloom => string<[[DataHexString]]>
A [bloom-filter](link-wiki-bloomfilter), which
includes all the addresses and topics included in any log in this
@@ -371,7 +447,8 @@ _code: equivalent to the AccessList example below @lang<javascript>
// Option 2:
// Array< [ Address, Array<Bytes32> ] >
[
//_hide: ;
accessList = [
[
"0x0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
[
@@ -385,17 +462,11 @@ _code: equivalent to the AccessList example below @lang<javascript>
"0x0000000000000000000000000000000000000000000000000000000000000001"
]
]
]
// <hide>
;
// </hide>
];
// Option 3:
// Record<Address, Array<Bytes32>>
// <hide>
(
// </hide>
{
accessList = {
"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e": [
"0x0000000000000000000000000000000000000000000000000000000000000004",
"0x0bcad17ecf260d6506c6b97768bdc2acfb6694445d27ffd3f9c1cfbee4a9bd6d"
@@ -403,10 +474,7 @@ _code: equivalent to the AccessList example below @lang<javascript>
"0x5FfC014343cd971B7eb70732021E26C35B744cc4": [
"0x0000000000000000000000000000000000000000000000000000000000000001"
]
}
// <hide>
)
// </hide>
};
_heading: AccessList @<providers-AccessList>
@@ -427,7 +495,7 @@ _code: example access list
// storageKey: Array< DataHexString< 32 > >
// }
[
accessList = [
{
address: "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",
storageKeys: [
@@ -441,4 +509,4 @@ _code: example access list
"0x0000000000000000000000000000000000000000000000000000000000000001"
]
}
]
];

View File

@@ -39,7 +39,7 @@ asynchronous source, such as hardware wallets.
Sub-classes **must** implement this.
_property: Signer.isSigner(object) => boolean @<Signer-isSigner> @SRC<abstract-signer>
Returns true if an only if //object// is a **Signer**.
Returns true if and only if //object// is a **Signer**.
_heading: Blockchain Methods @<Signer--blockchain-methods>
@@ -74,6 +74,12 @@ _property: signer.signMessage(message) => Promise<string<[RawSignature](signatur
This returns a Promise which resolves to the [[signature-raw]]
of //message//.
A signed message is prefixd with ``"\\x19Ethereum Signed Message:\\n"`` and
the length of the message, using the [hashMessage](utils-hashMessage)
method, so that it is [EIP-191](link-eip-191) compliant. If recovering
the address in Solidity, this prefix will be required to create a matching
hash.
Sub-classes **must** implement this, however they may throw if signing a
message is not supported, such as in a Contract-based Wallet or
Meta-Transaction-based Wallet.
@@ -126,9 +132,7 @@ it has been used in the field a bit.
_code: Typed Data Example @lang<javascript>
// <hide>
signer = new Wallet("0x1234567890123456789012345678901234567890123456789012345678901234");
// </hide>
//_hide: signer = new Wallet("0x1234567890123456789012345678901234567890123456789012345678901234");
// All properties on a domain are optional
const domain = {
@@ -164,9 +168,9 @@ const value = {
contents: 'Hello, Bob!'
};
const signature = await signer._signTypedData(domain, types, value);
//! async signature
//_result:
signature = await signer._signTypedData(domain, types, value);
//_log:
_heading: Sub-Classes @<Signer--subclassing>
@@ -224,7 +228,7 @@ does not have a secure entropy source, an error is thrown.
Wallets created using this method will have a mnemonic.
_property: ethers.Wallet.fromEncryptedJson(json, password [ , progress ]) => Promise<[[Wallet]]> @<Wallet-fromEncryptedJson> @SRC<wallet>
Create an instance from an encrypted JSON wallet.
Create an instance by decrypting an encrypted JSON wallet.
If //progress// is provided it will be called during decryption
with a value between 0 and 1 indicating the progress towards
@@ -281,35 +285,43 @@ walletMnemonic = Wallet.fromMnemonic(mnemonic)
// ...or from a private key
walletPrivateKey = new Wallet(walletMnemonic.privateKey)
//_result:
walletMnemonic.address === walletPrivateKey.address
//!
//_log:
// The address as a Promise per the Signer API
walletMnemonic.getAddress()
//!
//_result:
await walletMnemonic.getAddress()
//_log:
// A Wallet address is also available synchronously
//_result:
walletMnemonic.address
//!
//_log:
// The internal cryptographic components
//_result:
walletMnemonic.privateKey
//!
//_log:
//_result:
walletMnemonic.publicKey
//!
//_log:
// The wallet mnemonic
//_result:
walletMnemonic.mnemonic
//!
//_log:
// Note: A wallet created with a private key does not
// have a mnemonic (the derivation prevents it)
//_result:
walletPrivateKey.mnemonic
//!
//_log:
// Signing a message
walletMnemonic.signMessage("Hello World")
//!
//_result:
await walletMnemonic.signMessage("Hello World")
//_log:
tx = {
to: "0x8ba1f109551bD432803012645Ac136ddd64DBA72",
@@ -317,24 +329,29 @@ tx = {
}
// Signing a transaction
walletMnemonic.signTransaction(tx)
//!
//_result:
await walletMnemonic.signTransaction(tx)
//_log:
// The connect method returns a new instance of the
// Wallet connected to a provider
//_result:
wallet = walletMnemonic.connect(provider)
//_null:
// Querying the network
wallet.getBalance();
//!
wallet.getTransactionCount();
//!
//_result:
await wallet.getBalance();
//_log:
//_result:
await wallet.getTransactionCount();
//_log:
// Sending ether
wallet.sendTransaction(tx)
// <hide>
//! error
// </hide>
//_hide: wallet = localSigner; /* prevent insufficient funds error from blowing up the docs */
//_result:
await wallet.sendTransaction(tx)
//_log:
@@ -367,12 +384,10 @@ abi = [
]
contract = new ethers.Contract("dai.tokens.ethers.eth", abi, signer)
// <hide>
//!
// </hide>
// Get the number of tokens for this account
//_result:
tokens = await contract.balanceOf(signer.getAddress())
//! async tokens
//_log:
//
// Pre-flight (check for revert) on DAI from the signer
@@ -384,12 +399,14 @@ tokens = await contract.balanceOf(signer.getAddress())
//
// This will pass since the token balance is available
contract.callStatic.transfer("donations.ethers.eth", tokens)
//!
//_result:
await contract.callStatic.transfer("donations.ethers.eth", tokens)
//_log:
// This will fail since it is greater than the token balance
contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
//! error
//_throws:
await contract.callStatic.transfer("donations.ethers.eth", tokens.add(1))
//_log:
_subsection: ExternallyOwnedAccount @<ExternallyOwnedAccount>

View File

@@ -42,7 +42,78 @@ _property: abiCoder.encode(types, values) => string<[[DataHexString]]> @<AbiCode
Encode the array //values// according to the array of //types//, each of which may be a
string or a [[ParamType]].
_code: @lang<javascript>
//_hide: const abiCoder = utils.defaultAbiCoder;
// Encoding simple types
//_result:
abiCoder.encode([ "uint", "string" ], [ 1234, "Hello World" ]);
//_log:
//_hide: _page.example1 = _;
// Encoding with arrays types
//_result:
abiCoder.encode([ "uint[]", "string" ], [ [ 1234, 5678 ] , "Hello World" ]);
//_log:
//_hide: _page.example2 = _;
// Encoding complex structs (using positional properties)
//_result:
abiCoder.encode(
[ "uint", "tuple(uint256, string)" ],
[
1234,
[ 5678, "Hello World" ]
]
);
//_log:
//_hide: _page.example3 = _;
// Encoding complex structs (using keyword properties)
//_result:
abiCoder.encode(
[ "uint a", "tuple(uint256 b, string c) d" ],
[
1234,
{ b: 5678, c: "Hello World" }
]
);
//_log:
_property: abiCoder.decode(types, data) => [[Result]] @<AbiCoder-decode> @SRC<abi/abi-coder>
Decode the //data// according to the array of //types//, each of which may be a
string or [[ParamType]].
_code: @lang<javascript>
//_hide: const abiCoder = utils.defaultAbiCoder;
// Decoding simple types
//_hide: data = _page.example1;
//_verbatim: `data = ${ JSON.stringify(data) };`
//_result:
abiCoder.decode([ "uint", "string" ], data);
//_log:
// Decoding with arrays types
//_hide: data = _page.example2;
//_verbatim: `data = ${ JSON.stringify(data) };`
//_result:
abiCoder.decode([ "uint[]", "string" ], data);
//_log:
// Decoding complex structs; unnamed parameters allows ONLY
// positional access to values
//_hide: data = _page.example3;
//_verbatim: `data = ${ JSON.stringify(data) };`
//_result:
abiCoder.decode([ "uint", "tuple(uint256, string)" ], data);
//_log:
// Decoding complex structs; named parameters allows positional
// or keyword access to values
//_result:
abiCoder.decode([ "uint a", "tuple(uint256 b, string c) d" ], data);
//_log:

View File

@@ -1,11 +1,289 @@
_section: ABI Formats @<abi-formats>
@TODO: Expand this section
There are several formats available to specify an ABI for
a Smart Contract, which specifies to the under-lying library
what methods, events and errors exist so that encoding and
decoding the data from and to the network can be handled by
the library.
The supports ABI types are:
- [Human-Readable ABI](abi-formats--human-readable-abi)
- [Solidity JSON ABI](abi-formats--solidity)
- [Solidity Object ABI](abi-formats--object)
_subsection: Human-Readable ABI @<abi-formats--human-readable-abi>
See [Human-Readable Abi](link-ricmoo-humanreadableabi).
The **Human-Readable ABI** was [introduced early by ethers](link-ricmoo-humanreadableabi),
which allows for a Solidity signatures to be used to describe each
method, event and error.
It is important to note that a Solidity signature **fully describes**
all the properties the ABI requires:
- name
- type (constructor, event, function)
- inputs (types, nested structures and optionally names)
- outputs (types nested structures and optionally names)
- state mutability (for constructors and methods)
- payability (for constructors and methods)
- whether inputs are indexed (for events)
This allows for a simple format which is both machine-readable (since
the parser is a machine) and human-readable (at least **developer-readable**),
as well as simple for humans to type and inline into code, which improves
code readability. The Human-Readable ABI is also considerably smaller, which
helps reduce code size.
A Human-Readable ABI is simple an array of strings, where each string is
the Solidity signature.
Signatures may be minimally specified (i.e. names of inputs and outputs
may be omitted) or fully specified (i.e. with all property names) and
whitespace is ignored.
Several modifiers available in Solidity are dropped internally, as they
are not required for the ABI and used old by Solidity's semantic checking
system, such as input parameter data location like ``"calldata"``
and ``"memory"``. As such, they can be safely dropped in the ABI as well.
_code: Human-Readable ABI Example @lang<javascript>
const humanReadableAbi = [
// Simple types
"constructor(string symbol, string name)",
"function transferFrom(address from, address to, uint value)",
"function balanceOf(address owner) view returns (uint balance)",
"event Transfer(address indexed from, address indexed to, address value)",
"error InsufficientBalance(account owner, uint balance)",
// Some examples with the struct type, we use the tuple keyword:
// (note: the tuple keyword is optional, simply using additional
// parentheses accomplishes the same thing)
// struct Person {
// string name;
// uint16 age;
// }
"function addPerson(tuple(string name, uint16 age) person)",
"function addPeople(tuple(string name, uint16 age)[] person)",
"function getPerson(uint id) view returns (tuple(string name, uint16 age))",
"event PersonAdded(uint indexed id, tuple(string name, uint16 age) person)"
];
//_hide: _page.humanReadableAbi = humanReadableAbi;
_subsection: Solidity JSON ABI @<abi-formats--solidity>
See [Solidity compiler](link-solc-output).
The **Solidity JSON ABI** is a standard format that many tools export,
including the Solidity compiler. For the full specification, see
the [Solidity compiler documentation](link-solc-output).
Various versions include slightly different keys and values. For example,
early compilers included only a boolean ``"constant"`` to indicate mutability,
while newer versions include a string ``"mutabilityState"``, which encompasses
several older properties.
When creating an instance of a [Fragment](Fragment) using a JSON ABI, it will
automatically infer all legacy properties for new-age ABIs and for legacy
ABIs will infer the new-age properties. All properties will be populated, so
it will match the equivalent created using a Human-Readable ABI fragment.
_code: The same ABI as JSON ABI @lang<javascript>
const jsonAbi = `[
{
"type": "constructor",
"payable": false,
"inputs": [
{ "type": "string", "name": "symbol" },
{ "type": "string", "name": "name" }
]
},
{
"type": "function",
"name": "transferFrom",
"constant": false,
"payable": false,
"inputs": [
{ "type": "address", "name": "from" },
{ "type": "address", "name": "to" },
{ "type": "uint256", "name": "value" }
],
"outputs": [ ]
},
{
"type": "function",
"name": "balanceOf",
"constant":true,
"stateMutability": "view",
"payable":false, "inputs": [
{ "type": "address", "name": "owner"}
],
"outputs": [
{ "type": "uint256"}
]
},
{
"type": "event",
"anonymous": false,
"name": "Transfer",
"inputs": [
{ "type": "address", "name": "from", "indexed":true},
{ "type": "address", "name": "to", "indexed":true},
{ "type": "address", "name": "value"}
]
},
{
"type": "error",
"name": "InsufficientBalance",
"inputs": [
{ "type": "account", "name": "owner"},
{ "type": "uint256", "name": "balance"}
]
},
{
"type": "function",
"name": "addPerson",
"constant": false,
"payable": false,
"inputs": [
{
"type": "tuple",
"name": "person",
"components": [
{ "type": "string", "name": "name" },
{ "type": "uint16", "name": "age" }
]
}
],
"outputs": []
},
{
"type": "function",
"name": "addPeople",
"constant": false,
"payable": false,
"inputs": [
{
"type": "tuple[]",
"name": "person",
"components": [
{ "type": "string", "name": "name" },
{ "type": "uint16", "name": "age" }
]
}
],
"outputs": []
},
{
"type": "function",
"name": "getPerson",
"constant": true,
"stateMutability": "view",
"payable": false,
"inputs": [
{ "type": "uint256", "name": "id" }
],
"outputs": [
{
"type": "tuple",
"components": [
{ "type": "string", "name": "name" },
{ "type": "uint16", "name": "age" }
]
}
]
},
{
"type": "event",
"anonymous": false,
"name": "PersonAdded",
"inputs": [
{ "type": "uint256", "name": "id", "indexed": true },
{
"type": "tuple",
"name": "person",
"components": [
{ "type": "string", "name": "name", "indexed": false },
{ "type": "uint16", "name": "age", "indexed": false }
]
}
]
}
]`;
//_hide: _page.jsonAbi = jsonAbi;
_subsection: Solidity Object ABI @<abi-formats--object>
The output from parsing (using JSON.parse) a Solidity JSON ABI
is also fully compatible with the [[Interface]] class and each
method, event and error from that object are compatible with
the [[Fragment]] class.
Some developers may prefer this as it allows access to the ABI
properties as normal JavaScript objects, and closely matches the
JSON ABI that those familiar with the Solidity ABI will recognize.
_subsection: Converting Between Formats
The [[Fragment]] object makes it simple to reformat a single
method, event or error, however most developers will be interested
in converting an entire ABI.
For production code it is recommended to inline the Human-Readable
ABI as it makes it easy to see at a glance which methods, events
and errors are available. It is also highly recommend to strip out
unused parts of the ABI (such as admin methods) to further reduce
code size.
_code: Converting to Full Human-Readable ABI @lang<javascript>
//_hide: const Interface = ethers.utils.Interface;
//_hide: const FormatTypes = ethers.utils.FormatTypes;
//_hide: jsonAbi = _page.jsonAbi;
// Using the "full" format will ensure the Result objects
// have named properties, which improves code readability
const iface = new Interface(jsonAbi);
//_result:
iface.format(FormatTypes.full);
//_log:
_code: Converting to Minimal Human-Readable ABI @lang<javascript>
//_hide: const Interface = ethers.utils.Interface;
//_hide: const FormatTypes = ethers.utils.FormatTypes;
//_hide: jsonAbi = _page.jsonAbi;
// Using the "minimal" format will save a small amount of
// space, but is generally not worth it as named properties
// on Results will not be available
const iface = new Interface(jsonAbi);
//_result:
iface.format(FormatTypes.minimal);
//_log:
_code: Converting to JSON ABI @lang<javascript>
//_hide: const Interface = ethers.utils.Interface;
//_hide: const FormatTypes = ethers.utils.FormatTypes;
//_hide: humanReadableAbi = _page.humanReadableAbi;
// Sometimes you may need to export a Human-Readable ABI to
// JSON for tools that do not have Human-Readable support
// For compactness, the JSON is kept with minimal white-space
const iface = new Interface(humanReadableAbi);
//_result:
jsonAbi = iface.format(FormatTypes.json);
//_log:
// However it is easy to use JSON.parse and JSON.stringify
// with formatting parameters to assist with readability
//_result:
JSON.stringify(JSON.parse(jsonAbi), null, 2);
//_log:

View File

@@ -5,7 +5,6 @@ Explain an ABI.
_subsection: Formats
_heading: JSON String ABI (Solidity Output JSON)
The **JSON ABI Format** is the format that is
[output from the Solidity compiler](link-solc-output).
@@ -15,50 +14,74 @@ of Objects, where each Object has various properties describing the [[Fragment]]
The deserialized JSON string (which is a normal JavaScript Object) may
also be passed into any function which accepts a JSON String ABI.
_heading: Humanb-Readable ABI
_heading: Humanb-Readable ABI @<human-readable-abi>
The Human-Readable ABI was introduced by ethers in [this article](link-ricmoo-humanreadableabi)
and has since gained wider adoption.
The Human-Readable ABI was @TODO
The ABI is described by using an array of strings, where each string is the
Solidity signature of the **constructor**, **function**, **event** or **error**.
[article](link-ricmoo-humanreadableabi)
When parsing a fragment, all inferred properties will be injected (e.g. a //payable//
method will have its ``constant`` proeprty set to false).
Tuples can be specified by using the ``tuple(...)`` syntax or with bare (additional)
parenthesis, ``(...)``.
_code: Example Human-Readable ABI
const ABI = [
// Constructor
"constructor(address ens)",
// Constant functions (pure or view)
"function balanceOf(address owner) view returns (uint)",
// State-mutating functions (payable or non-payable)
"function mint(uint amount) payable",
"function transfer(address to, uint amount) returns (bool)",
// Events
"event Transfer(address indexed from, address indexed to, uint amount)",
// Errors
"error InsufficientFunds(address from, uint balance)",
]
_heading: Output Formats @<fragments--output-formats> @SRC<abi/fragments:FormatTypes>
Each [[Fragment]] and [[ParamType]] may be output using its ``format``
method.
_property: ethers.utils.FragmentTypes.full => string
_property: ethers.utils.FormatTypes.full => string
This is a full human-readable string, including all parameter names, any
optional modifiers (e.g. ``indexed``, ``public``, etc) and white-space
to aid in human readability.
_property: ethers.utils.FragmentTypes.minimal => string
_property: ethers.utils.FormatTypes.minimal => string
This is similar to ``full``, except with no unnecessary whitespace or parameter
names. This is useful for storing a minimal string which can still fully
reconstruct the original Fragment using [Fragment&thinsp;.&thinsp;from](Fragment-from).
_property: ethers.utils.FragmentTypes.json => string
_property: ethers.utils.FormatTypes.json => string
This returns a JavaScript Object which is safe to call ``JSON.stringify``
on to create a JSON string.
_property: ethers.utils.FragmentTypes.sighash => string
_property: ethers.utils.FormatTypes.sighash => string
This is a minimal output format, which is used by Solidity when computing a
signature hash or an event topic hash.
_warning: Note
The ``sighash`` format is **insufficient** to re-create the original [[Fragment]],
since it discards modifiers such as indexed, anonymous, stateMutability, etc.
It is only useful for computing the selector for a Fragment, and cannot
be used to format an Interface.
_subsection: Fragment @<Fragment> @SRC<abi/fragments:class.Fragment>
An ABI is a collection of **Fragments**, where each fragment specifies:
- An [Error](ErrorFragment)
- An [Event](EventFragment)
- A [Function](FunctionFragment)
- A [Constructor](ConstructorFragment)
@@ -66,12 +89,10 @@ An ABI is a collection of **Fragments**, where each fragment specifies:
_heading: Properties
_property: fragment.name => string
This is the name of the Event or Function. This will be null for
a [[ConstructorFragment]].
_property: fragment.type => string
This is a string which indicates the type of the [[Fragment]]. This
will be one of:
@@ -80,19 +101,20 @@ will be one of:
- ``function``
_property: fragment.inputs => Array<[[ParamType]]>
This is an array of each [[ParamType]] for the input parameters to
the Constructor, Event of Function.
_heading: Methods
_property: ethers.utils.Fragment.from(objectOrString) => [[Fragment]] @<Fragment-from> @SRC<abi/fragments:Fragment.from>
_property: fragment.format([ format = sighash]) => string @<Fragment-format> @SRC<abi/fragments:Fragment.format>
Creates a string representation of the Fragment using the available
[output formats](fragments--output-formats).
Returns a
_property: ethers.utils.Fragment.from(objectOrString) => [[Fragment]] @<Fragment-from> @SRC<abi/fragments:Fragment.from>
Creates a new **Fragment** sub-class from any compatible //objectOrString//.
_property: ethers.utils.Fragment.isFragment(object) => boolean @<Fragment-isFragment> @SRC<abi/fragments:Fragment.isFragment>
Tra lal al
Returns true if //object// is a **Fragment**.
_subsection: ConstructorFragment @<ConstructorFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.ConstructorFragment>
@@ -100,17 +122,14 @@ _subsection: ConstructorFragment @<ConstructorFragment> @INHERIT<[[Fragment]]> @
_heading: Properties
_property: fragment.gas => [[BigNumber]]
This is the gas limit that should be used during deployment. It may be
null.
_property: fragment.payable => boolean
This is whether the constructor may receive ether during deployment as
an endowment (i.e. msg.value != 0).
_property: fragment.stateMutability => string
This is the state mutability of the constructor. It can be any of:
- ``nonpayable``
@@ -119,12 +138,21 @@ This is the state mutability of the constructor. It can be any of:
_heading: Methods
_property: ethers.utils.ConstructorFragment.from(objectOrString) => [[ConstructorFragment]] @<ConstructorFragment-from> @SRC<abi/fragments:ConstructorFragment.from>
Tra la la...
Creates a new **ConstructorFragment** from any compatible //objectOrString//.
_property: ethers.utils.ConstructorFragment.isConstructorFragment(object) => boolean @<ConstructorFragment-isConstructorFragment> @SRC<abi/fragments:ConstructorFragment.isConstructorFragment>
Returns true if //object// is a **ConstructorFragment**.
Tra lal al
_subsection: ErrorFragment @<ErrorFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.ErrorFragment>
_heading: Methods
_property: ethers.utils.ErrorFragment.from(objectOrString) => [[ErrorFragment]] @<ErrorFragment-from> @SRC<abi/fragments:ErrorFragment.from>
Creates a new **ErrorFragment** from any compatible //objectOrString//.
_property: ethers.utils.ErrorFragment.isErrorFragment(object) => boolean @<ErrorFragment-isErrorFragment> @SRC<abi/fragments:ErrorFragment.isErrorFragment>
Returns true if //object// is an **ErrorFragment**.
_subsection: EventFragment @<EventFragment> @INHERIT<[[Fragment]]> @SRC<abi/fragments:class.EventFragment>
@@ -132,19 +160,16 @@ _subsection: EventFragment @<EventFragment> @INHERIT<[[Fragment]]> @SRC<abi/frag
_heading: Properties
_property: fragment.anonymous => boolean
This is whether the event is anonymous. An anonymous Event does not inject its
topic hash as topic0 when creating a log.
_heading: Methods
_property: ethers.utils.EventFragment.from(objectOrString) => [[EventFragment]] @<EventFragment-from> @SRC<abi/fragments:EventFragment.from>
Tra la la...
Creates a new **EventFragment** from any compatible //objectOrString//.
_property: ethers.utils.EventFragment.isEventFragment(object) => boolean @<EventFragment-isEventFragment> @SRC<abi/fragments:EventFragment.isEventFragment>
Tra lal al
Returns true if //object// is an **EventFragment**.
_subsection: FunctionFragment @<FunctionFragment> @INHERIT<[[ConstructorFragment]]> @SRC<abi/fragments:class.FunctionFragment>
@@ -152,12 +177,10 @@ _subsection: FunctionFragment @<FunctionFragment> @INHERIT<[[ConstructorFragment
_heading: Properties
_property: fragment.constant => boolean
This is whether the function is constant (i.e. does not change state). This
is true if the state mutability is ``pure`` or ``view``.
_property: fragment.stateMutability => string
This is the state mutability of the constructor. It can be any of:
- ``nonpayable``
@@ -166,22 +189,18 @@ This is the state mutability of the constructor. It can be any of:
- ``view``
_property: fragment.outputs => Array<[[ParamType]]>
A list of the Function output parameters.
_heading: Method
_heading: Methods
_property: ethers.utils.FunctionFragment.from(objectOrString) => [[FunctionFragment]] @<FunctionFragment-from> @SRC<abi/fragments:ConstructorFragment.from>
Tra la la...
Creates a new **FunctionFragment** from any compatible //objectOrString//.
_property: ethers.utils.FunctionFragment.isFunctionFragment(object) => boolean @<FunctionFragment-isFunctionFragment> @SRC<abi/fragments:FunctionFragment.isFunctionFragment>
Tra lal al
Returns true if //object// is a **FunctionFragment**.
_subsection: ParamType @<ParamType> @SRC<abi/fragments:class.ParamType>
The following examples will represent the Solidity parameter:
``string foobar``
@@ -189,53 +208,42 @@ The following examples will represent the Solidity parameter:
_heading: Properties
_property: paramType.name => string @<ParamType-name>
The local parameter name. This may be null for unnamed parameters. For example,
the parameter definition ``string foobar`` would be ``foobar``.
_property: paramType.type => string @<ParamType-type>
The full type of the parameter, including tuple and array symbols. This may be null
for unnamed parameters. For the above example, this would be ``foobar``.
_property: paramType.baseType => string @<ParamType-baseType>
The base type of the parameter. For primitive types (e.g. ``address``, ``uint256``, etc)
this is equal to [type](ParamType-type). For arrays, it will be the string ``array`` and for
a tuple, it will be the string ``tuple``.
_property: paramType.indexed => boolean @<ParamType-indexed>
Whether the parameter has been marked as indexed. This **only** applies
to parameters which are part of an [[EventFragment]].
_property: paramType.arrayChildren => [[ParamType]] @<ParamType-arrayChildren>
The type of children of the array. This is null for any parameter
which is not an array.
_property: paramType.arrayLength => number @<ParamType-arrayLength>
The length of the array, or ``-1`` for dynamic-length arrays. This is
null for parameters which are not arrays.
_property: paramType.components => Array<[[ParamType]]> @<ParamType-components>
The components of a tuple. This is null for non-tuple parameters.
_heading: Methods
Tra la la...
_property: paramType.format([ outputType = sighash ])
Tra la la...
Creates a string representation of the Fragment using the available
[output formats](fragments--output-formats).
_property: ethers.utils.ParamType.from(objectOrString) => [[ParamType]] @<ParamType-from> @SRC<abi/fragments:ParamType.from>
Tra la la...
Creates a new **ParamType** from any compatible //objectOrString//.
_property: ethers.utils.ParamType.isParamType(object) => boolean @<ParamType-isParamType> @SRC<abi/fragments:ParamType.isParamType>
Tra la la...
Returns true if //object// is a **ParamType**.

View File

@@ -26,11 +26,47 @@ which is a format the Ethers created to simplify manually typing the ABI
into the source and so that a Contract ABI can also be referenced easily
within the same source file.
_code: Creating an Interface instance @lang<javascript>
//_hide: const Interface = ethers.utils.Interface;
// This interface is used for the below examples
const iface = new Interface([
// Constructor
"constructor(string symbol, string name)",
// State mutating method
"function transferFrom(address from, address to, uint amount)",
// State mutating method, which is payable
"function mint(uint amount) payable",
// Constant method (i.e. "view" or "pure")
"function balanceOf(address owner) view returns (uint)",
// An Event
"event Transfer(address indexed from, address indexed to, uint256 amount)",
// A Custom Solidity Error
"error AccountLocked(address owner, uint256 balance)",
// Examples with structured types
"function addUser(tuple(string name, address addr) user) returns (uint id)",
"function addUsers(tuple(string name, address addr)[] user) returns (uint[] id)",
"function getUser(uint id) view returns (tuple(string name, address addr) user)"
]);
//_hide: _page.iface = iface;
_subsection: Properties @<Interface--properties>
_property: interface.fragments => Array<[[Fragment]]>
All the [Fragments](Fragment) in the interface.
_property: interface.errors => Array<[[ErrorFragment]]>
All the [Error Fragments](ErrorFragment) in the interface.
_property: interface.events => Array<[[EventFragment]]>
All the [Event Fragments](EventFragment) in the interface.
@@ -48,24 +84,133 @@ Return the formatted **Interface**. If the format type is ``json`` a
single string is returned, otherwise an Array of the human-readable
strings is returned.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
const FormatTypes = ethers.utils.FormatTypes;
//_result:
iface.format(FormatTypes.json)
//_log:
//_result:
iface.format(FormatTypes.full)
//_log:
//_result:
iface.format(FormatTypes.minimal)
//_log:
_subsection: Fragment Access @<Interface--fragments>
_property: interface.getFunction(fragment) => [[FunctionFragment]] @SRC<abi/interface>
Returns the [[FunctionFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// By method signature, which is normalized so whitespace
// and superfluous attributes are ignored
iface.getFunction("transferFrom(address, address, uint256)");
// By name; this ONLY works if the method is non-ambiguous
iface.getFunction("transferFrom");
// By method selector
iface.getFunction("0x23b872dd");
// Throws if the method does not exist
//_throws:
iface.getFunction("doesNotExist()");
//_log:
_property: interface.getError(fragment) => [[ErrorFragment]] @SRC<abi/interface>
Returns the [[ErrorFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// By error signature, which is normalized so whitespace
// and superfluous attributes are ignored
iface.getError("AccountLocked(address, uint256)");
// By name; this ONLY works if the error is non-ambiguous
iface.getError("AccountLocked");
// By error selector
iface.getError("0xf7c3865a");
// Throws if the error does not exist
//_throws:
iface.getError("DoesNotExist()");
//_log:
_property: interface.getEvent(fragment) => [[EventFragment]] @SRC<abi/interface>
Returns the [[EventFragment]] for //fragment// (see [[Interface--specifying-fragments]]).
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// By event signature, which is normalized so whitespace
// and superfluous attributes are ignored
iface.getEvent("Transfer(address, address, uint256)");
// By name; this ONLY works if the event is non-ambiguous
iface.getEvent("Transfer");
// By event topic hash
iface.getEvent("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef");
// Throws if the event does not exist
//_throws:
iface.getEvent("DoesNotExist()");
//_log:
_subsection: Signature and Topic Hashes @<Interface--selectors>
_property: interface.getSighash(fragment) => string<[[DataHexString]]<4>> @SRC<abi/interface:method.Interface.getSighash>
Return the sighash (or Function Selector) for //fragment// (see [[Interface--specifying-fragments]]).
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_result:
iface.getSighash("balanceOf");
//_log:
//_result:
iface.getSighash("balanceOf(address)");
//_log:
const fragment = iface.getFunction("balanceOf")
//_result:
iface.getSighash(fragment);
//_log:
_property: interface.getEventTopic(fragment) => string<[[DataHexString]]<32>> @SRC<abi/interface:method.Interface.getEventTopic>
Return the topic hash for //fragment// (see [[Interface--specifying-fragments]]).
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_result:
iface.getEventTopic("Transfer");
//_log:
//_result:
iface.getEventTopic("Transfer(address, address, uint)");
//_log:
const fragment = iface.getEvent("Transfer")
//_result:
iface.getEventTopic(fragment);
//_log:
_subsection: Encoding Data @<Interface--encoding>
@@ -74,25 +219,145 @@ Return the encoded deployment data, which can be concatenated to the
deployment bytecode of a contract to pass //values// into the contract
constructor.
_property: interface.encodeFilterTopics(fragment [ , values ]) => Array<topic | Array<topic>> @SRC<abi/interface>
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// The data that should be appended to the bytecode to pass
// parameters to the constructor during deployment
//_result:
iface.encodeDeploy([ "SYM", "Some Name" ])
//_log:
_property: interface.encodeErrorResult(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
Returns the encoded error result, which would normally be the response from
a reverted call for //fragment// (see [[Interface--specifying-fragments]]) for
the given //values//.
Most developers will not need this method, but may be useful for authors of
a mock blockchain.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// Encoding result data (like is returned by eth_call during a revert)
//_result:
iface.encodeErrorResult("AccountLocked", [
"0x8ba1f109551bD432803012645Ac136ddd64DBA72",
parseEther("1.0")
]);
//_log:
_property: interface.encodeFilterTopics(fragment, values) => Array<topic | Array<topic>> @SRC<abi/interface>
Returns the encoded topic filter, which can be passed to getLogs for //fragment//
(see [[Interface--specifying-fragments]]) for the given //values//.
Each //topic// is a 32 byte (64 nibble) [[DataHexString]].
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// Filter that matches all Transfer events
//_result:
iface.encodeFilterTopics("Transfer", [])
//_log:
// Filter that matches the sender
//_result:
iface.encodeFilterTopics("Transfer", [
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
])
//_log:
// Filter that matches the receiver
//_result:
iface.encodeFilterTopics("Transfer", [
null,
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
])
//_log:
_property: interface.encodeFunctionData(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
Returns the encoded data, which can be used as the data for a transaction for
//fragment// (see [[Interface--specifying-fragments]]) for the given //values//.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// Encoding data for the tx.data of a call or transaction
//_result:
iface.encodeFunctionData("transferFrom", [
"0x8ba1f109551bD432803012645Ac136ddd64DBA72",
"0xaB7C8803962c0f2F5BBBe3FA8bf41cd82AA1923C",
parseEther("1.0")
])
//_log:
// Encoding structured data (using positional Array)
user = [
"Richard Moore",
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
];
//_result:
iface.encodeFunctionData("addUser", [ user ]);
//_log:
// Encoding structured data, using objects. Only available
// if paramters are named.
user = {
name: "Richard Moore",
addr: "0x8ba1f109551bD432803012645Ac136ddd64DBA72"
};
//_result:
iface.encodeFunctionData("addUser", [ user ]);
//_log:
_property: interface.encodeFunctionResult(fragment [ , values ]) => string<[[DataHexString]]> @SRC<abi/interface>
Returns the encoded result, which would normally be the response from a call for
//fragment// (see [[Interface--specifying-fragments]]) for the given //values//.
Most developers will not need this method, but may be useful for authors of a mock blockchain.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
// Encoding result data (like is returned by eth_call)
//_result:
iface.encodeFunctionResult("balanceOf", [
"0x8ba1f109551bD432803012645Ac136ddd64DBA72"
])
//_log:
_subsection: Decoding Data @<Interface--decoding>
_property: interface.decodeErrorResult(fragment, data) => [[Result]] @SRC<abi/interface>
Returns the decoded values from the result of a call during a revert for
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
Most developers won't need this, as the ``decodeFunctionResult`` will automatically
decode errors if the //data// represents a revert.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// Decoding result data (e.g. from an eth_call)
errorData = "0xf7c3865a0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_result:
iface.decodeErrorResult("AccountLocked", errorData)
//_log:
_property: interface.decodeEventLog(fragment, data [ , topics ]) => [[Result]] @SRC<abi/interface>
Returns the decoded event values from an event log for
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//
@@ -100,6 +365,26 @@ with the optional //topics//.
If //topics// is not specified, placeholders will be inserted into the result.
Most develoeprs will find the [parsing methods](Interface--parsing) more
convenient for decoding event data, as they will automatically detect the
matching event.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// Decoding log data and topics (the entries in a receipt)
const data = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
const topics = [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72",
"0x000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c"
];
//_result:
iface.decodeEventLog("Transfer", data, topics);
//_log:
_property: interface.decodeFunctionData(fragment, data) => [[Result]] @SRC<abi/interface>
Returns the decoded values from transaction data for
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
@@ -107,25 +392,119 @@ Returns the decoded values from transaction data for
Most developers will not need this method, but may be useful for debugging
or inspecting transactions.
Most develoeprs will also find the [parsing methods](Interface--parsing) more
convenient for decoding transation data, as they will automatically detect the
matching function.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// Decoding function data (the value of tx.data)
const txData = "0x23b872dd0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c0000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_result:
iface.decodeFunctionData("transferFrom", txData);
//_log:
_property: interface.decodeFunctionResult(fragment, data) => [[Result]] @SRC<abi/interface>
Returns the decoded values from the result of a call for
//fragment// (see [[Interface--specifying-fragments]]) for the given //data//.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
// Decoding result data (e.g. from an eth_call)
resultData = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_result:
iface.decodeFunctionResult("balanceOf", resultData)
//_log:
// Decoding result data which was caused by a revert
// Throws a CALL_EXCEPTION, with extra details
errorData = "0xf7c3865a0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_throws:
iface.decodeFunctionResult("balanceOf", errorData)
//_log:
// Decoding structured data returns a Result object, which
// will include all values positionally and if the ABI
// included names, values will additionally be available
// by their name.
resultData = "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000400000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72000000000000000000000000000000000000000000000000000000000000000d52696368617264204d6f6f726500000000000000000000000000000000000000";
//_result:
result = iface.decodeFunctionResult("getUser", resultData);
//_log:
// Access positionally:
// The 0th output parameter, the 0th proerty of the structure
//_result:
result[0][0];
//_log:
// Access by name: (only avilable because parameters were named)
//_result:
result.user.name
//_log:
_subsection: Parsing @<Interface--parsing>
The functions are generally the most useful for most developers. They will
automatically search the ABI for a matching Event or Function and decode
the components as a fully specified description.
_property: interface.parseError(data) => [[ErrorDescription]] @SRC<abi/interface>
Search for the error that matches the error selector in //data// and parse out
the details.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
const data = "0xf7c3865a0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba720000000000000000000000000000000000000000000000000de0b6b3a7640000";
//_result:
iface.parseError(data);
//_hide: _.errorFragment = createClass("ErrorFragment");
//_log:
_property: interface.parseLog(log) => [[LogDescription]] @SRC<abi/interface>
Search the event that matches the //log// topic hash and parse the values
the log represents.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
const data = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
const topics = [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72",
"0x000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c"
];
//_result:
iface.parseLog({ data, topics });
//_hide: _.eventFragment = createClass("EventFragment");
//_log:
_property: interface.parseTransaction(transaction) => [[TransactionDescription]] @SRC<abi/interface>
Search for the function that matches the //transaction// data sighash
and parse the transaction properties.
_code: @lang<javascript>
//_hide: const iface = _page.iface;
//_hide: const parseEther = ethers.utils.parseEther;
const data = "0x23b872dd0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c0000000000000000000000000000000000000000000000000de0b6b3a7640000";
const value = parseEther("1.0");
//_result:
iface.parseTransaction({ data, value });
//_hide: _.functionFragment = createClass("FunctionFragment");
//_log:
_subsection: Types @<Interface--types>
@@ -142,6 +521,24 @@ any named value for this key is renamed to ``_length``. If there is a
name collision, only the first is available by its key.
_heading: ErrorDescription @<ErrorDescription>
_property: errorDescription.args => [[Result]]
The values of the input parameters of the error.
_property: errorDescription.errorFragment => [[ErrorFragment]]
The [[ErrorFragment]] which matches the selector in the data.
_property: errorDescription.name => string
The error name. (e.g. ``AccountLocked``)
_property: errorDescription.signature => string
The error signature. (e.g. ``AccountLocked(address,uint256)``)
_property: errorDescription.sighash => string
The selector of the error.
_heading: LogDescription @<LogDescription>
_property: logDescription.args => [[Result]]

View File

@@ -18,7 +18,6 @@ of errors introduced from typing an address or cut and paste issues.
All functions that return an Address will return a Checksum Address.
_heading: ICAP Address @<address-icap>
The **ICAP Address Format** was an early attempt to introduce a checksum
@@ -49,13 +48,72 @@ the checksum is invalid, an [INVALID_ARGUMENT](errors--invalid-argument) Error i
The value of //address// may be any supported address format.
_code: @lang<javascript>
//_hide: const getAddress = ethers.utils.getAddress;
// Injects the checksum (via upper-casing specific letters)
//_result:
getAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
//_log:
// Converts and injects the checksum
//_result:
getAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
//_log:
// Throws if a checksummed address is provided, but a
// letter is the wrong case
// ------------v (should be lower-case)
//_throws:
getAddress("0x8Ba1f109551bD432803012645Ac136ddd64DBA72")
//_log:
// Throws if the ICAP/IBAN checksum fails
//_throws:
getIcapAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK37");
//_log:
// Throws if the address is invalid, in general
//_throws:
getIcapAddress("I like turtles!");
//_log:
_property: ethers.utils.getIcapAddress(address) => string<[IcapAddress](address-icap)> @<utils-getIcapAddress> @SRC<address>
Returns //address// as an [ICAP address](link-icap).
Supports the same restrictions as [getAddress](utils-getAddress).
_code: @lang<javascript>
//_hide: const getIcapAddress = ethers.utils.getIcapAddress;
//_result:
getIcapAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
//_log:
//_result:
getIcapAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
//_log:
_property: ethers.utils.isAddress(address) => boolean @<utils-isAddress> @SRC<address>
Returns true if //address// is valid (in any supported format).
_code: @lang<javascript>
//_hide: const isAddress = ethers.utils.isAddress;
//_result:
isAddress("0x8ba1f109551bd432803012645ac136ddd64dba72");
//_log:
//_result:
isAddress("XE65GB6LDNXYOFTX0NSV3FUWKOWIXAMJK36");
//_log:
//_result:
isAddress("I like turtles.");
//_log:
_subsection: Derivation @<utils--address-derivation>
@@ -64,10 +122,49 @@ Returns the address for //publicOrPrivateKey//. A public key may be
compressed or uncompressed, and a private key will be converted
automatically to a public key for the derivation.
_code: @lang<javascript>
//_hide: const computeAddress = ethers.utils.computeAddress;
// Private Key
//_result:
computeAddress("0xb976778317b23a1385ec2d483eda6904d9319135b89f1d8eee9f6d2593e2665d");
//_log:
// Public Key (compressed)
//_result:
computeAddress("0x0376698beebe8ee5c74d8cc50ab84ac301ee8f10af6f28d0ffd6adf4d6d3b9b762");
//_log:
// Public Key (uncompressed)
//_result:
computeAddress("0x0476698beebe8ee5c74d8cc50ab84ac301ee8f10af6f28d0ffd6adf4d6d3b9b762d46ca56d3dad2ce13213a6f42278dabbb53259f2d92681ea6a0b98197a719be3");
//_log:
_property: ethers.utils.recoverAddress(digest, signature) => string<[[address]]> @<utils-recoverAddress> @SRC<transactions>
Use [[link-wiki-ecrecover]] to determine the address that signed //digest// to
which generated //signature//.
_code: @lang<javascript>
//_hide: const recoverAddress = ethers.utils.recoverAddress;
const digest = "0x7c5ea36004851c764c44143b1dcb59679b11c9a68e5f41497f6cf3d480715331";
// Using an expanded Signature
//_result:
recoverAddress(digest, {
r: "0x528459e4aec8934dc2ee94c4f3265cf6ce00d47cf42bb106afda3642c72e25eb",
s: "0x42544137118256121502784e5a6425e6183ca964421ecd577db6c66ba9bccdcf",
v: 27
});
//_log:
// Using a flat Signature
const signature = "0x528459e4aec8934dc2ee94c4f3265cf6ce00d47cf42bb106afda3642c72e25eb42544137118256121502784e5a6425e6183ca964421ecd577db6c66ba9bccdcf1b";
//_result:
recoverAddress(digest, signature);
//_log:
_subsection: Contracts Addresses @<utils--contract-addresses>
@@ -75,9 +172,33 @@ _property: ethers.utils.getContractAddress(transaction) => string<[[address]]>
Returns the contract address that would result if //transaction// was
used to deploy a contract.
_code: @lang<javascript>
//_hide: const getContractAddress = ethers.utils.getContractAddress;
const from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
const nonce = 5;
//_result:
getContractAddress({ from, nonce });
//_log:
_property: ethers.utils.getCreate2Address(from, salt, initCodeHash) => string<[[address]]> @<utils-getCreate2Address> @SRC<address>
Returns the contract address that would result from the given
[CREATE2](link-eip-1014) call.
_code: @lang<javascript>
//_hide: const getCreate2Address = ethers.utils.getCreate2Address;
//_hide: const keccak256 = ethers.utils.keccak256;
const from = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
const salt = "0x7c5ea36004851c764c44143b1dcb59679b11c9a68e5f41497f6cf3d480715331";
const initCode = "0x6394198df16000526103ff60206004601c335afa6040516060f3";
const initCodeHash = keccak256(initCode);
//_result:
getCreate2Address(from, salt, initCodeHash);
//_log:

View File

@@ -1,6 +1,6 @@
_section: BigNumber @<BigNumber>
Many operations in Ethereum operation on numbers which are
Many operations in Ethereum operate on numbers which are
[outside the range of safe values](BigNumber--notes-safenumbers) to use
in JavaScript.
@@ -49,43 +49,52 @@ _heading: Examples: @<>
_code: @lang<javascript>
// From a decimal string...
//_result:
BigNumber.from("42")
//!
//_log:
// From a HexString...
//_result:
BigNumber.from("0x2a")
//!
//_log:
// From a negative HexString...
//_result:
BigNumber.from("-0x2a")
//!
//_log:
// From an Array (or Uint8Array)...
//_result:
BigNumber.from([ 42 ])
//!
//_log:
// From an existing BigNumber...
let one1 = constants.One;
let one2 = BigNumber.from(one1)
//_result:
one2
//!
//_log:
// ...which returns the same instance
//_result:
one1 === one2
//!
//_log:
// From a (safe) number...
//_result:
BigNumber.from(42)
//!
//_log:
// From a ES2015 BigInt... (only on platforms with BigInt support)
//_result:
BigNumber.from(42n)
//!
//_log:
// Numbers outside the safe range fail:
//_throws:
BigNumber.from(Number.MAX_SAFE_INTEGER);
//! error
//_log:
_subsection: Methods @<BigNumber--methods>
@@ -159,6 +168,10 @@ Returns true if and only if the value of //BigNumber// is zero.
_heading: Conversion
_property: BigNumber.toBigInt() => bigint @SRC<bignumber>
Returns the value of //BigNumber// as a [JavaScript BigInt](link-js-bigint) value,
on platforms which support them.
_property: BigNumber.toNumber() => number @SRC<bignumber>
Returns the value of //BigNumber// as a JavaScript value.
@@ -186,8 +199,9 @@ _code: @lang<javascript>
let a = BigNumber.from(42);
let b = BigNumber.from("91");
//_result:
a.mul(b);
//!
//_log:
_subsection: Notes @<BigNumber--notes>
@@ -214,8 +228,9 @@ To demonstrate how this may be an issue in your code, consider:
_code: @lang<javascript>
//_result:
(Number.MAX_SAFE_INTEGER + 2 - 2) == (Number.MAX_SAFE_INTEGER)
//!
//_log:
_null:

View File

@@ -38,8 +38,10 @@ _heading: Signature @<Signature>
- **r** and **s** --- The x co-ordinate of **r** and the **s** value of the signature
- **v** --- The parity of the y co-ordinate of **r**
- **_vs** --- The [compact representation](link-eip-2098) of the **s** and **v**
- **yParityAndS** --- The [compact representation](link-eip-2098) of the **s** and **v**
- **_vs** --- Deprecated property; renamed to yParityAndS
- **recoveryParam** --- The normalized (i.e. 0 or 1) value of **v**
- **compact** - The full siggnature using [compact representation](link-eip-2098)
_heading: Raw Signature @<signature-raw> @inherit<string\<[[DataHexString]]\<65\>\>>
@@ -86,28 +88,34 @@ zeros.
_code: Examples @lang<javascript>
// Convert a hexstring to a Uint8Array
//_result:
arrayify("0x1234")
//!
//_log:
// Convert an Array to a hexstring
//_result:
hexlify([1, 2, 3, 4])
//!
//_log:
// Convert an Object to a hexstring
//_result:
hexlify({ length: 2, "0": 1, "1": 2 })
//!
//_log:
// Convert an Array to a hexstring
//_result:
hexlify([ 1 ])
//!
//_log:
// Convert a number to a stripped hex value
//_result:
hexValue(1)
//!
//_log:
// Convert an Array to a stripped hex value
//_result:
hexValue([ 1, 2 ])
//!
//_log:
_subsection: Array Manipulation
@@ -170,15 +178,18 @@ Return a copy of //array// shuffled using [[link-wiki-shuffle]].
_code: Examples @lang<javascript>
//_result:
utils.randomBytes(8)
//!
//_log:
const data = [ 1, 2, 3, 4, 5, 6, 7 ];
// Returns a new Array
//_result:
utils.shuffled(data);
//!
//_log:
// The Original is unscathed...
//_result:
data
//!
//_log:

View File

@@ -1,6 +1,6 @@
_section: Constants @<constants>
The **ethers.contants** Object contains commonly used values.
The **ethers.constants** Object contains commonly used values.
_subsection: Bytes

View File

@@ -53,6 +53,13 @@ _heading: Formatting @<display-logic--formatting>
_property: ethers.utils.commify(value) => string @<utils-commify> @SRC<units>
Returns a string with value grouped by 3 digits, separated by ``,``.
_code: @lang<javascript>
//_hide: const commify = ethers.utils.commify;
//_result:
commify("-1000.3000");
//_log:
_heading: Conversion @<unit-conversion>
@@ -60,13 +67,88 @@ _property: ethers.utils.formatUnits(value [ , unit = "ether" ] ) => string @<ut
Returns a string representation of //value// formatted with //unit//
digits (if it is a number) or to the unit specified (if a string).
_code: @lang<javascript>
//_hide: const formatUnits = ethers.utils.formatUnits;
//_hide: const BigNumber = ethers.BigNumber;
const oneGwei = BigNumber.from("1000000000");
const oneEther = BigNumber.from("1000000000000000000");
//_result:
formatUnits(oneGwei, 0);
//_log:
//_result:
formatUnits(oneGwei, "gwei");
//_log:
//_result:
formatUnits(oneGwei, 9);
//_log:
//_result:
formatUnits(oneEther);
//_log:
//_result:
formatUnits(oneEther, 18);
//_log:
_property: ethers.utils.formatEther(value) => string @<utils-formatEther> @SRC<units>
The equivalent to calling ``formatUnits(value, "ether")``.
_code: @lang<javascript>
//_hide: const formatEther = ethers.utils.formatEther;
//_hide: const BigNumber = ethers.BigNumber;
const value = BigNumber.from("1000000000000000000");
//_result:
formatEther(value);
//_log:
_property: ethers.utils.parseUnits(value [ , unit = "ether" ] ) => [BigNumber](BigNumber) @<utils-parseUnits> @SRC<units>
Returns a [BigNumber](BigNumber) representation of //value//, parsed with
//unit// digits (if it is a number) or from the unit specified (if
a string).
_code: @lang<javascript>
//_hide: const parseUnits = ethers.utils.parseUnits;
//_result:
parseUnits("1.0");
//_log:
//_result:
parseUnits("1.0", "ether");
//_log:
//_result:
parseUnits("1.0", 18);
//_log:
//_result:
parseUnits("121.0", "gwei");
//_log:
//_result:
parseUnits("121.0", 9);
//_log:
_property: ethers.utils.parseEther(value) => [BigNumber](BigNumber) @<utils-parseEther> @SRC<units>
The equivalent to calling ``parseUnits(value, "ether")``.
_code: @lang<javascript>
//_hide: const parseEther = ethers.utils.parseEther;
//_result:
parseEther("1.0");
//_log:
//_result:
parseEther("-0.5");
//_log:

View File

@@ -2,23 +2,63 @@ _section: Encoding Utilities @<encoding>
_subsection: Base58 @<Bse58> @SRC<basex:Base58>
_property: ethers.utils.base58.decode(textData) => Uin8Array
_property: ethers.utils.base58.decode(textData) => Uint8Array
Return a typed Uint8Array representation of //textData// decoded using
base-58 encoding.
_code: @lang<javascript>
//_hide: const base58 = ethers.utils.base58;
//_result:
base58.decode("TzMhH");
//_log:
_property: ethers.utils.base58.encode(aBytesLike) => string
Return //aBytesLike// encoded as a string using the base-58 encoding.
_code: @lang<javascript>
//_hide: const base58 = ethers.utils.base58;
//_result:
base58.encode("0x12345678");
//_log:
//_result:
base58.encode([ 0x12, 0x34, 0x56, 0x78 ]);
//_log:
_subsection: Base64 @<Base64>
_property: ethers.utils.base64.decode(textData) => Uin8Array @SRC<base64>
_property: ethers.utils.base64.decode(textData) => Uint8Array @SRC<base64>
Return a typed Uint8Array representation of //textData// decoded using
base-64 encoding.
_code: @lang<javascript>
//_hide: const base64 = ethers.utils.base64;
//_result:
base64.decode("EjQ=");
//_log:
_property: ethers.utils.base64.encode(aBytesLike) => string @SRC<base64>
Return //aBytesLike// encoded as a string using the base-64 encoding.
_code: @lang<javascript>
//_hide: const base64 = ethers.utils.base64;
//_result:
base64.encode("0x1234");
//_log:
//_result:
base64.encode([ 0x12, 0x34 ]);
//_log:
_subsection: Recursive-Length Prefix @<rlp--methods>
@@ -26,15 +66,53 @@ The [[link-rlp]] encoding is used throughout Ethereum to serialize nested
structures of Arrays and data.
_property: ethers.utils.RLP.encode(dataObject) => string<[[DataHexString]]> @<utils-rlpEncode> @SRC<rlp>
Encode a structured Data Object into its RLP-encoded representation.
Encode a structured [Data Object](rlp--dataobject) into its RLP-encoded representation.
Each Data component may be a valid [[BytesLike]].
_code: @lang<javascript>
//_hide: const RLP = ethers.utils.RLP;
//_result:
RLP.encode("0x12345678");
//_log:
//_result:
RLP.encode([ "0x12345678" ]);
//_log:
//_result:
RLP.encode([ new Uint8Array([ 0x12, 0x34, 0x56, 0x78 ]) ]);
//_log:
//_result:
RLP.encode([ [ "0x42", [ "0x43" ] ], "0x12345678", [ ] ]);
//_log:
//_result:
RLP.encode([ ]);
//_log:
_property: ethers.utils.RLP.decode(aBytesLike) => [DataObject](rlp--dataobject) @<utils.rlpDecode> @SRC<rlp>
Decode an RLP-encoded //aBytesLike// into its structured Data Object.
Decode an RLP-encoded //aBytesLike// into its structured [Data Object](rlp--dataobject).
All Data components will be returned as a [[DataHexString]].
_code: @lang<javascript>
//_hide: const RLP = ethers.utils.RLP;
//_result:
RLP.decode("0x8412345678");
//_log:
//_result:
RLP.decode("0xcac342c1438412345678c0");
//_log:
//_result:
RLP.decode("0xc0");
//_log:
_heading: Data Object @<rlp--dataobject>
A **Data Object** is a recursive structure which is used to serialize many

View File

@@ -27,14 +27,17 @@ Returns the [SHA2-512](link-wiki-sha2) digest of //aBytesLike//.
_code: KECCAK256 @lang<javascript>
//_result:
utils.keccak256([ 0x12, 0x34 ])
//!
//_log:
//_result:
utils.keccak256("0x")
//!
//_log:
//_result:
utils.keccak256("0x1234")
//!
//_log:
// The value MUST be data, such as:
// - an Array of numbers
@@ -42,16 +45,19 @@ utils.keccak256("0x1234")
// - a Uint8Array
// Do NOT use UTF-8 strings that are not a DataHexstring
//_throws:
utils.keccak256("hello world")
//! error
//_log:
// If needed, convert strings to bytes first:
//_result:
utils.keccak256(utils.toUtf8Bytes("hello world"))
//!
//_log:
// Or equivalently use the identity function:
//_result:
utils.id("hello world")
//!
//_log:
// Keep in mind that the string "0x1234" represents TWO
// bytes (i.e. [ 0x12, 0x34 ]. If you wish to compute the
@@ -61,48 +67,56 @@ utils.id("hello world")
// Consider the following examples:
// Hash of TWO (2) bytes:
//_result:
utils.keccak256("0x1234")
//!
//_log:
// Hash of TWO (2) bytes: (same result)
//_result:
utils.keccak256([ 0x12, 0x34 ])
//!
//_log:
const bytes = utils.toUtf8Bytes("0x1234")
// <hide>
bytes
// </hide>
//!
//_result:
bytes = utils.toUtf8Bytes("0x1234")
//_log:
// Hash of SIX (6) characters (different than above)
//_result:
utils.keccak256(bytes)
//!
//_log:
// Hash of SIX (6) characters (same result)
//_result:
utils.id("0x1234")
//!
//_log:
_code: RIPEMD160 @lang<javascript>
//_result:
utils.ripemd160("0x")
//!
//_log:
//_result:
utils.ripemd160("0x1234")
//!
//_log:
_code: SHA-2 @lang<javascript>
//_result:
utils.sha256("0x")
//!
//_log:
//_result:
utils.sha256("0x1234")
//!
//_log:
//_result:
utils.sha512("0x")
//!
//_log:
//_result:
utils.sha512("0x1234")
//!
//_log:
_subsection: HMAC @<utils--hmac>
@@ -123,8 +137,9 @@ _code: HMAC @lang<javascript>
const key = "0x0102"
const data = "0x1234"
//_result:
utils.computeHmac("sha256", key, data)
//!
//_log:
_subsection: Hashing Helpers @<utils--hashing-helpers>
@@ -137,12 +152,14 @@ and the length of //message//.
_code: Hashing Messages @lang<javascript>
// Hashing a string message
//_result:
utils.hashMessage("Hello World")
//!
//_log:
// Hashing binary data (also "Hello World", but as bytes)
//_result:
utils.hashMessage( [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 ])
//!
//_log:
// NOTE: It is important to understand how strings and binary
// data is handled differently. A string is ALWAYS processed
@@ -151,18 +168,21 @@ utils.hashMessage( [ 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100 ])
// Hashing a hex string is the same as hashing a STRING
// Note: this is the hash of the 4 characters [ '0', 'x', '4', '2' ]
//_result:
utils.hashMessage("0x42")
//!
//_log:
// Hashing the binary data
// Note: this is the hash of the 1 byte [ 0x42 ]
//_result:
utils.hashMessage([ 0x42 ])
//!
//_log:
// Hashing the binary data
// Note: similarly, this is the hash of the 1 byte [ 0x42 ]
//_result:
utils.hashMessage(utils.arrayify("0x42"))
//!
//_log:
_property: ethers.utils.namehash(name) => string<[[DataHexString]]<32>> @<utils-namehash> @SRC<hash>
@@ -170,17 +190,21 @@ Returns the [ENS Namehash](link-namehash) of //name//.
_code: Namehash @lang<javascript>
//_result:
utils.namehash("")
//!
//_log:
//_result:
utils.namehash("eth")
//!
//_log:
//_result:
utils.namehash("ricmoo.firefly.eth")
//!
//_log:
//_result:
utils.namehash("ricmoo.xyz")
//!
//_log:
_heading: Typed Data Encoder @<TypedDataEncoder> @SRC<hash:class.TypedDataEncoder>
@@ -244,19 +268,17 @@ been recursively replacedwith the value of calling //resolveName// with that val
_code: Typed Data Example @lang<javascript>
// <hide>
TypedDataEncoder = ethers.utils._TypedDataEncoder
// </hide>
//_hide: TypedDataEncoder = ethers.utils._TypedDataEncoder
const domain = {
domain = {
name: 'Ether Mail',
version: '1',
chainId: 1,
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
}
};
// The named list of all type definitions
const types = {
types = {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' }
@@ -266,10 +288,10 @@ const types = {
{ name: 'to', type: 'Person' },
{ name: 'contents', type: 'string' }
]
}
};
// The data to sign
const value = {
value = {
from: {
name: 'Cow',
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826'
@@ -279,23 +301,27 @@ const value = {
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
},
contents: 'Hello, Bob!'
}
};
//_result:
TypedDataEncoder.encode(domain, types, value)
//!
//_log:
//_result:
TypedDataEncoder.getPayload(domain, types, value)
//!
//_log:
//_result:
TypedDataEncoder.getPrimaryType(types)
//!
//_log:
//_result:
TypedDataEncoder.hash(domain, types, value)
//!
//_log:
//_result:
TypedDataEncoder.hashDomain(domain)
//!
//_log:
_subsection: Solidity Hashing Algorithms @<utils--solidity-hashing>
@@ -318,17 +344,21 @@ according to their respective type in //types//.
_code: Solidity Hashing @lang<javascript>
//_result:
utils.solidityPack([ "int16", "uint48" ], [ -1, 12 ])
//!
//_log:
//_result:
utils.solidityPack([ "string", "uint8" ], [ "Hello", 3 ])
//!
//_log:
//_result:
utils.solidityKeccak256([ "int16", "uint48" ], [ -1, 12 ])
//!
//_log:
//_result:
utils.soliditySha256([ "int16", "uint48" ], [ -1, 12 ])
//!
//_log:
// As a short example of the non-distinguished nature of
// Solidity tight-packing (which is why it is inappropriate
@@ -336,14 +366,18 @@ utils.soliditySha256([ "int16", "uint48" ], [ -1, 12 ])
// the following examples are all equal, despite representing
// very different values and layouts.
//_result:
utils.solidityPack([ "string", "string" ], [ "hello", "world01" ])
//!
//_log:
//_result:
utils.solidityPack([ "string", "string" ], [ "helloworld", "01" ])
//!
//_log:
//_result:
utils.solidityPack([ "string", "string", "uint16" ], [ "hell", "oworld", 0x3031 ])
//!
//_log:
//_result:
utils.solidityPack([ "uint96" ], [ "32309054545061485574011236401" ])
//!
//_log:

View File

@@ -216,6 +216,22 @@ it deals with unmined transactions, and can be configured by each node, however
to ensure a transaction is propagated to a miner it is best practice to follow
the defaults most nodes have enabled.
_property: Logger.errors.TRANSACTION_REPLACED @<errors--transaction-replaced>
When a transaction has been replaced by the user, by broadcasting a new transaction
with the same nonce as an existing in-flight (unmined) transaction in the mempool,
this error will occur while waiting if the transaction being waited for has become
invalidated by that other transaction.
This can happen for several reasons, but most commonly because the user has increased
the gas price (which changes the transaction hash) to "speed up" a transaction or if
a user has "cancelled" the transaction in their client. In either case this is
usually accomplished by bribing the miners with a higher gas priced transaction.
This error will have the additional properties, ``cancelled``, ``hash``, ``reason``,
``receipt`` and ``replacement``.
See the [[providers-TransactionResponse]] for the ``wait`` method for more details.
_property: Logger.errors.UNPREDICTABLE_GAS_LIMIT @<errors--unpredicatable-gas-limit>
When estimating the required amount of gas for a transaction, a node is queried for
its best guess.

View File

@@ -18,6 +18,12 @@ The gas limit for this transaction.
_property: unsignedTransaction.gasPrice => [[BigNumberish]]
The gas price for this transaction.
_property: unsignedTransaction.maxFeePerGas => [[BigNumberish]]
The maximum fee per unit of gas for this transaction.
_property: unsignedTransaction.maxPriorityFeePerGas => [[BigNumberish]]
The maximum priority fee per unit of gas for this transaction.
_property: unsignedTransaction.data => [[BytesLike]]
The data for this transaction.
@@ -38,7 +44,7 @@ The transaction hash, which can be used as an identifier for
//transaction//. This is the keccak256 of the serialized RLP encoded
representation of //transaction//.
_property: unsignedTransaction.to => string<[Address](address)>
_property: transaction.to => string<[Address](address)>
The address //transaction// is to.
_property: transaction.from => string<[Address](address)>
@@ -57,9 +63,21 @@ refunded at the end of the transaction, and if there is insufficient gas
to complete execution, the effects of the transaction are reverted, but
the gas is **fully consumed** and an out-of-gas error occurs.
_property: transaction.gasPrice => [[BigNumber]]
_property: transaction.gasPrice => null | [[BigNumber]]
The price (in wei) per unit of gas for //transaction//.
For [[link-eip-1559]] transactions, this will be null.
_property: transaction.maxFeePerGas => [[BigNumber]]
The maximum price (in wei) per unit of gas for //transaction//.
For transactions that are not [[link-eip-1559]] transactions, this will be null.
_property: transaction.maxPriorityFeePerGas => [[BigNumber]]
The priority fee price (in wei) per unit of gas for //transaction//.
For transactions that are not [[link-eip-1559]] transactions, this will be null.
_property: transaction.data => [[BytesLike]]
The data for //transaction//. In a contract this is the call data.

View File

@@ -33,6 +33,12 @@ How long to wait before rejecting with a //timeout// error.
_property: connection.headers => { [ key: string]: string }
Additional headers to include in the connection.
_property: connection.skipFetchSetup => boolean
Normally a connection will specify the default values for a connection
such as CORS-behavior and caching policy, to ensure compatibility across
platforms. On some services, such as Cloudflare Workers, specifying any
value (inclluding the default values) will cause failure. Setting this
to true will prevent any values being passed to the underlying API.
_heading: PollOptions @<PollOptions>

View File

@@ -57,13 +57,11 @@ $TopicABaCD: **[** (topic[0] = A) **OR** (topic[0] = B) **]** **AND**
_code: ERC-20 Transfer Filter Examples @lang<javascript>
// <hide>
const tokenAddress = ethers.constants.AddressZero;
const myAddress = ethers.constants.AddressZero;
const myOtherAddress = ethers.constants.AddressZero;
const id = ethers.utils.id;
const hexZeroPad = ethers.utils.hexZeroPad;
// </hide>
//_hide: const tokenAddress = ethers.constants.AddressZero;
//_hide: const myAddress = ethers.constants.AddressZero;
//_hide: const myOtherAddress = ethers.constants.AddressZero;
//_hide: const id = ethers.utils.id;
//_hide: const hexZeroPad = ethers.utils.hexZeroPad;
// Short example of manually creating filters for an ERC-20
// Transfer event.
@@ -93,33 +91,33 @@ const hexZeroPad = ethers.utils.hexZeroPad;
filter = {
address: tokenAddress,
topics: [
id("Transfer(address,address,uint256)"),
utils.id("Transfer(address,address,uint256)"),
hexZeroPad(myAddress, 32)
]
}
};
// List all token transfers *to* myAddress:
filter = {
address: tokenAddress,
topics: [
id("Transfer(address,address,uint256)"),
utils.id("Transfer(address,address,uint256)"),
null,
hexZeroPad(myAddress, 32)
]
}
};
// List all token transfers *to* myAddress or myOtherAddress:
filter = {
address: tokenAddress,
topics: [
id("Transfer(address,address,uint256)"),
utils.id("Transfer(address,address,uint256)"),
null,
[
hexZeroPad(myAddress, 32),
hexZeroPad(myOtherAddress, 32),
]
]
}
};
_null:
@@ -128,35 +126,37 @@ To simplify life, ..., explain here, the contract API
_code: ERC-20 Contract Filter Examples @lang<javascript>
// <hide>
const tokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; // DAI
const myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
const otherAddress = "0xEA517D5a070e6705Cc5467858681Ed953d285Eb9";
const provider = ethers.getDefaultProvider();
const Contract = ethers.Contract;
// </hide>
//_hide: const tokenAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; /* DAI */
//_hide: const myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
//_hide: const otherAddress = "0xEA517D5a070e6705Cc5467858681Ed953d285Eb9";
//_hide: const provider = ethers.getDefaultProvider();
//_hide: const Contract = ethers.Contract;
const abi = [
abi = [
"event Transfer(address indexed src, address indexed dst, uint val)"
];
const contract = new Contract(tokenAddress, abi, provider);
contract = new Contract(tokenAddress, abi, provider);
// List all token transfers *from* myAddress
//_result:
contract.filters.Transfer(myAddress)
//!
//_log:
// List all token transfers *to* myAddress:
//_result:
contract.filters.Transfer(null, myAddress)
//!
//_log:
// List all token transfers *from* myAddress *to* otherAddress:
//_result:
contract.filters.Transfer(myAddress, otherAddress)
//!
//_log:
// List all token transfers *to* myAddress OR otherAddress:
//_result:
contract.filters.Transfer(null, [ myAddress, otherAddress ])
//!
//_log:
_subsection: Solidity Topics @<events-solidity>

View File

@@ -1,5 +1,82 @@
_section: Security @<security>
While security should be a concern for all developers, in the
blockchain space developers must be additionally conscious of
many areas which can be exploited.
Once a problem has an economic incentives to exploit it, there
is a much larger risk and with blockchain apps it can become
quite valuable to attack.
In addition to many of the other security issues app developers
may have to worry about, there are a few additional vectors
that JavaScript developers should be aware of.
_subsection: Side-Channel Attacks
A [Side-Channel Attack](link-wiki-side-channel-attack) occurs
when something orthogonal to the implementation of the algorithm
used can be exploited to learn more about secure or private
information.
_heading: Released Data (Strings, Uint8Arrays, Buffers)
In JavaScript, memory may not be securely allocated, or more
importantly securely released.
[Historically](https://github.com/nodejs/node/issues/4660),
``new Buffer(16)`` would re-use old memory that had been
released. This would mean that code running later, may have
access to data that was discarded.
As an example of the dangers, imagine if you had used a Buffer
to store a private key, signed data and then returned from the
function, allowing the Buffer to be de-allocated. A future
function may be able to request a new Buffer, which would still
have that left-over private key, which it could then use to
steal the funds from that account.
There are also many debugging tools and systems designed to
assist developers inspect the memory contents of JavaScript
programs. In these cases, any //private key// or //mnemonic//
sitting in memory may be visible to other users on the system,
or malicious scripts.
_heading: Timing Attack
Timing attacks allow a malicious user or script to determine
private data through analysing how long an operation requires
to execute.
In JavaScript, //Garbage Collection// occurs periodically when the
system determines it is required. Each JavaScript implementation
is different, with a variety of strategies and and abilities.
Most Garbage Collection requires "stopping the world", or pausing
all code being executed while it runs. This adds a large delay
to any code that was currently running.
This can be exploited by attackers to "condition cause a delay".
They will set up a scenario where the system is on the edge of
needing to garbage collect, and call your code with two paths,
a simple path and complex path. The simple path won't stir things
up enough to cause a garbage collection, while the complex one
will. By timing how long the code took to execute, they now know
whether garbage collection occured and therefore whether the simple
or complex path was taken.
Advanced timing attacks are very difficult to mitigate in any
garbage-collection-based language. Most libraries where this
matters will hopefully mitigate this for you as much as possible,
but it is still good to be aware of.
_heading: General Concerns
- [Cross-Site Scripting](link-wiki-xss)
- [Cross-Site Request Forgery](link-wiki-csrf)
- [Phishing](link-wiki-phishing)
_subsection: Key Derivation Functions @<security--pbkdf>
This is not specific to Ethereum, but is a useful technique
@@ -51,7 +128,7 @@ progress callback which will be periodically called with a number between
In general a progress bar makes the experience feel faster, as well as
more comfortable since there is a clear indication how much (relative) time
is remaining. Additionally, using language like //"decrypting..."// in
a progress bar makes a user feel like there time is not being //needlessly//
a progress bar makes a user feel like their time is not being //needlessly//
wasted.
_heading: Work-Arounds (not recommended)

View File

@@ -117,10 +117,14 @@ const getSourceUrl = (function(path, include, exclude) {
}
})("../packages/", new RegExp("packages/.*/src.ts/.*\.ts$"), new RegExp("/node_modules/|src.ts/.*browser.*"));
let localSigner = null;
function codeContextify(context) {
const { inspect } = require("util");
const ethers = context.require("./packages/ethers");
if (localSigner == null) { localSigner = ethers.Wallet.createRandom(); }
context.ethers = ethers;
context.BigNumber = ethers.BigNumber;
context.constants = ethers.constants;
@@ -133,21 +137,44 @@ function codeContextify(context) {
// We use a local dev node for some signing examples, but want to
// resolve ENS names against mainnet; super hacky but makes the
// docs nicer
// docs nicer (funded in _startup)
context.localProvider = new ethers.providers.JsonRpcProvider();
context.localSigner = context.localProvider.getSigner();
context.localSigner = localSigner.connect(context.localProvider);
context.localProvider.resolveName = context.provider.resolveName.bind(context.provider);
context.BigNumber.prototype[inspect.custom] = function(depth, options) {
return `{ BigNumber: ${JSON.stringify(this.toString()) } }`;
}
context.createClass = function(name) {
let C = class{ }
Object.defineProperty(C, "name", { value: name })
return C;
}
context._inspect = function(value, depth) {
if (toString.call(value) === '[object Error]') {
// Not an error from ethers...
if (ethers.utils.Logger.errors[value.code] == null) {
return `Error: ${ value.message }`;
}
// Trim the ethers errors down on their verbosity for the docs...
if (value.message) {
value.message = value.message.split(" (")[0];
}
value.stack = undefined;
}
if (value && value.constructor && value.constructor.name === "Uint8Array") {
return `Uint8Array [ ${ Array.prototype.join.call(value, ", ") } ]`;
}
if (typeof(value) === "string" && value.indexOf("\n") >= 0) {
return "`" + value + "`";
}
//return JSON.stringify(value);
return inspect(value, {
compact: false,
@@ -156,12 +183,26 @@ function codeContextify(context) {
sorted: true,
});
}
context._startup = async function() {
console.log("Startup");
const signer = context.localProvider.getSigner();
const tx = await signer.sendTransaction({
to: localSigner.address,
value: ethers.utils.parseEther("10.0")
});
await tx.wait();
}
context._shutdown = function() {
console.log("Shutdown");
}
}
module.exports = {
title: "ethers",
subtitle: "v5.0",
subtitle: "v5.4",
description: "Documentation for ethers, a complete, tiny and simple Ethereum library.",
logo: "logo.svg",
@@ -185,6 +226,7 @@ module.exports = {
externalLinks: {
"link-mail": "mailto:me@ricmoo.com",
"link-alchemy": { name: "Alchemy", url: "https:/\/alchemyapi.io" },
"link-ankr": { name: "Ankr", url: "https:/\/www.ankr.com" },
"link-cloudflare": { name: "Cloudflare", url: "https:/\/developers.cloudflare.com/distributed-web/ethereum-gateway/" },
"link-ens": { name: "ENS", url: "https:/\/ens.domains/" },
"link-ethereum": { name: "Ethereum", url: "https:/\/ethereumorg" },
@@ -196,7 +238,7 @@ module.exports = {
"link-infura": { name: "INFURA", url: "https:/\/infura.io" },
"link-javascriptcore": { name: "JavaScriptCore", url: "https:/\/developer.apple.com/documentation/javascriptcore?language=objc" },
"link-ledger": "https:/\/www.ledger.com",
"link-metamask": { name: "Metamask", url: "https:/\/metamask.io/" },
"link-metamask": { name: "MetaMask", url: "https:/\/metamask.io/" },
"link-otto": "https:/\/github.com/robertkrimen/otto",
"link-parity": { name: "Parity", url: "https:/\/www.parity.io" },
"link-pocket": { name: "Pocket Network", url: "https:/\/pokt.network" },
@@ -204,10 +246,13 @@ module.exports = {
"link-rtd": "https:/\/github.com/readthedocs/sphinx_rtd_theme",
"link-semver": { name: "semver", url: "https:/\/semver.org" },
"link-solidity": { name: "Solidity" , url: "https:/\/solidity.readthedocs.io/" },
"link-solidity-events": "https:/\/docs.soliditylang.org/en/v0.8.1/abi-spec.html#events",
"link-solidity-errors": "https:/\/docs.soliditylang.org/en/v0.8.4/abi-spec.html#errors",
"link-solidity-events": "https:/\/docs.soliditylang.org/en/v0.8.4/abi-spec.html#events",
"link-sphinx": { name: "Sphinx", url: "https:/\/www.sphinx-doc.org/" },
"link-alchemy-signup": "https:/\/dashboard.alchemyapi.io/signup?referral=55a35117-028e-4b7c-9e47-e275ad0acc6d",
"link-ankr-public": "https:/\/www.ankr.com/protocol/public/",
"link-ankr-premium": "https:/\/www.ankr.com/protocol/plan/",
"link-etherscan-signup": "https:/\/etherscan.io/apis",
"link-etherscan-ratelimit": "https:/\/info.etherscan.com/api-return-errors/",
"link-infura-signup": "https:/\/infura.io/register",
@@ -246,7 +291,7 @@ module.exports = {
"link-ethersio": "https:/\/ethers.io/",
"link-ethers-docs": "https:/\/docs.ethers.io/",
"link-ethers-js": "https:/\/cdn.ethers.io/lib/ethers-5.0.esm.min.js",
"link-ethers-js": "https:/\/cdn.ethers.io/lib/ethers-5.1.esm.min.js",
"link-ethers-npm": "https:/\/www.npmjs.com/search?q=%40ethersproject%2F",
"link-ethers-asm-grammar": "https:/\/github.com/ethers-io/ethers.js/blob/master/packages/asm/grammar.jison",
@@ -257,6 +302,7 @@ module.exports = {
"link-eip-712": { name: "EIP-712", url: "https:/\/eips.ethereum.org/EIPS/eip-712" },
"link-eip-1014": { name: "EIP-1014", url: "https:/\/eips.ethereum.org/EIPS/eip-1014" },
"link-eip-1193": { name: "EIP-1193", url: "https:/\/eips.ethereum.org/EIPS/eip-1193" },
"link-eip-1559": { name: "EIP-1559", url: "https:/\/eips.ethereum.org/EIPS/eip-1559" },
"link-eip-1577": { name: "EIP-1577", url: "https:/\/eips.ethereum.org/EIPS/eip-1577" },
"link-eip-2098": { name: "EIP-2098", url: "https:/\/eips.ethereum.org/EIPS/eip-2098" },
"link-eip-2304": { name: "EIP-2304", url: "https:/\/eips.ethereum.org/EIPS/eip-2304" },
@@ -291,12 +337,14 @@ module.exports = {
"link-wiki-bloomfilter": { name: "Bloom Filter", url: "https:/\/en.wikipedia.org/wiki/Bloom_filter" },
"link-wiki-bruteforce": "https:/\/en.wikipedia.org/wiki/Brute-force_attack",
"link-wiki-cryptographichash": "https:/\/en.wikipedia.org/wiki/Cryptographic_hash_function",
"link-wiki-csrf": "https:/\/en.wikipedia.org/wiki/Cross-site_request_forgery",
"link-wiki-ecrecover": { name: "ECDSA Public Key Recovery", url: "https:/\/en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Public_key_recovery" },
"link-wiki-homoglyph": "https:/\/en.wikipedia.org/wiki/IDN_homograph_attack",
"link-wiki-hmac": "https:/\/en.wikipedia.org/wiki/HMAC",
"link-wiki-iban": "https:/\/en.wikipedia.org/wiki/International_Bank_Account_Number",
"link-wiki-ieee754": "https:/\/en.wikipedia.org/wiki/Double-precision_floating-point_format",
"link-wiki-observer-pattern": { name: "Obeserver Pattern", url: "https:/\/en.wikipedia.org/wiki/Observer_pattern" },
"link-wiki-observer-pattern": { name: "Observer Pattern", url: "https:/\/en.wikipedia.org/wiki/Observer_pattern" },
"link-wiki-phishing": "https:/\/en.wikipedia.org/wiki/Phishing",
"link-wiki-ripemd": "https:/\/en.m.wikipedia.org/wiki/RIPEMD",
"link-wiki-sha2": "https:/\/en.wikipedia.org/wiki/SHA-2",
"link-wiki-twoscomplement": "https:/\/en.wikipedia.org/wiki/Two%27s_complement",
@@ -304,9 +352,11 @@ module.exports = {
"link-wiki-utf8-overlong": "https:/\/en.wikipedia.org/wiki/UTF-8#Overlong_encodings",
"link-wiki-utf8-replacement": "https:/\/en.wikipedia.org/wiki/Specials_%28Unicode_block%29#Replacement_character",
"link-wiki-scrypt": "https:/\/en.wikipedia.org/wiki/Scrypt",
"link-wiki-side-channel-attack": "https:/\/en.wikipedia.org/wiki/Side-channel_attack",
"link-wiki-sha3": "https:/\/en.wikipedia.org/wiki/SHA-3",
"link-wiki-shuffle": { name: "Fisher-Yates Shuffle", url: "https:/\/en.wikipedia.org/wiki/Fisher-Yates_shuffle" },
"link-wiki-overflow": { name: "overflow", url: "https:/\/en.wikipedia.org/wiki/Integer_overflow" },
"link-wiki-underflow": { name: "arithmetic underflow", url: "https:/\/en.wikipedia.org/wiki/Arithmetic_underflow" },
"link-wiki-xss": "https:/\/en.wikipedia.org/wiki/Cross-site_scripting",
},
};

View File

@@ -31,7 +31,7 @@ have a public discussion and figure out the best way to address the problem/feat
_subsection: Building @<contributing--building>
The build process for ethers is unfortunatly not super trivial, but
I have attempted to make it as straight-forward as possible.
I have attempted to make it as straightforward as possible.
It is a mono-repo which attempts to be compatibile with a large
number of environments, build tools and platforms, which is why

View File

@@ -6,4 +6,5 @@ snippets of code that are in general useful.
_toc:
react-native
transactions

View File

@@ -0,0 +1,24 @@
_section: Transactions @<cookbook--transactions>
_subsection: Compute the raw transaction @<cookbook--compute-raw-transaction>
_code: @lang<javascript>
function getRawTransaction(tx) {
function addKey(accum, key) {
if (tx[key]) { accum[key] = tx[key]; }
return accum;
}
// Extract the relevant parts of the transaction and signature
const txFields = "accessList chainId data gasPrice gasLimit maxFeePerGas maxPriorityFeePerGas nonce to type value".split(" ");
const sigFields = "v r s".split(" ");
// Seriailze the signed transaction
const raw = utils.serializeTransaction(txFields.reduce(addKey, { }), sigFields.reduce(addKey, { }));
// Double check things went well
if (utils.keccak256(raw) !== tx.hash) { throw new Error("serializing failed!"); }
return raw;
}

View File

@@ -219,58 +219,64 @@ for displaying code samples.
_heading: JavaScript Evaluation @<flatworm--code-eval>
For JavaScript files, the file is executed with some simple substitution.
For JavaScript files, the file is transpiled and executed in a VM,
allowiung output (or exceptions) of blocks to be included in the
fragment output.
A bare ``\/\/!`` on a line is replaced with the result of the last
statement. Building will fail if an error is thrown.
The entire **code fragment** source is included in an async IIFE,
whick means ``await`` is allowed, and several special comment
directives are allowed.
A bare ``\/\/!error`` is replaced with the throw error. Building will
fail if an error is not thrown.
A ``/\/_hide:`` will include any following code directly into the
output, but will not include it in the generated output for the fragment.
Also any code included between the lines **``\/\/ <hide>``** and
**``\/\/ </hide>``** will be omitted from the output, which can be used
to setup variables.
A ``/\/_log:`` will include the value of any following expression in the
output, prefixed with a ``/\/ ``. Renderers will mark output in different
style if possible.
A ``/\/_result:`` will begin a block, assigning the contents to ``_``. The
block can be ended with a ``/\/_log:`` or ``/\/_null:``, if no value is given
to log, then ``_`` is assumed. If an error occurs, generation fails.
A ``/\/_throws:`` will begin a block, which is expected to throw assigning
the error to ``_``. The block can be ended with a ``/\/_log:`` or ``/\/_null:``,
if no value is given to log, then ``_`` is assumed. If an error do not occur,
generation fails.
_code: Code Evaluation Example @lang<text>
\_code: Result of Code Example @lang<javascript>
// <hide>
const url = require("url");
// </hide>
//_hide: const url = require("url");
//_result:
url.parse("https://www.ricmoo.com/").protocol
//!
//_log:
//_throws:
url.parse(45)
//! error
//_log:
// You want to assign (doesn't emit eval) AND display the value
const foo = 4 + 5;
// <hide>
foo
// </hide>
//!
//_log: foo
_code: Result of Code Example @lang<javascript>
// <hide>
const url = require("url");
// </hide>
//_hide: const url = require("url");
//_result:
url.parse("https://www.ricmoo.com/").protocol
//!
//_log:
//_throws:
url.parse(45)
//! error
//_log:
// You want to assign (doesn't emit eval) AND display the value
const foo = 4 + 5;
// <hide>
foo
// </hide>
//!
//_log: foo
_heading: Languages

View File

@@ -39,14 +39,14 @@ Web Applications from our CDN.
_code: ES6 in the Browser @lang<html>
<script type="module">
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.0.esm.min.js";
import { ethers } from "https://cdn.ethers.io/lib/ethers-5.2.esm.min.js";
// Your code here...
</script>
_code: ES3 (UMD) in the Browser @lang<html>
<script src="https://cdn.ethers.io/lib/ethers-5.0.umd.min.js"
<script src="https://cdn.ethers.io/lib/ethers-5.2.umd.min.js"
type="application/javascript"></script>
@@ -73,7 +73,7 @@ $Contract: A Contract is an abstraction which represents a connection to a
| **Contract** | $Contract |
_subsection: Connecting to Ethereum: Metamask @<getting-started--connecting>
_subsection: Connecting to Ethereum: MetaMask @<getting-started--connecting>
The quickest and easiest way to experiment and begin developing on
Ethereum is to use [[link-metamask]], which is a browser extension
@@ -82,13 +82,16 @@ that provides:
- A connection to the Ethereum network (a [[Provider]])
- Holds your private key and can sign things (a [[Signer]])
_code: Connecting to Metamask @lang<script>
_code: Connecting to MetaMask @lang<script>
// A Web3Provider wraps a standard Web3 provider, which is
// what Metamask injects as window.ethereum into each page
// what MetaMask injects as window.ethereum into each page
const provider = new ethers.providers.Web3Provider(window.ethereum)
// The Metamask plugin also allows signing transactions to
// MetaMask requires requesting permission to connect users accounts
await provider.send("eth_requestAccounts", []);
// The MetaMask plugin also allows signing transactions to
// send ether and pay to change state within the blockchain.
// For this, you need the account signer...
const signer = provider.getSigner()
@@ -123,22 +126,26 @@ logs, look up deployed code and so on.
_code: Basic Queries @lang<javascript>
// Look up the current block number
provider.getBlockNumber()
//!
//_result:
await provider.getBlockNumber()
//_log:
// Get the balance of an account (by address or ENS name, if supported by network)
//_result:
balance = await provider.getBalance("ethers.eth")
//! async balance
//_log:
// Often you need to format the output to something more user-friendly,
// such as in ether (instead of wei)
//_result:
ethers.utils.formatEther(balance)
//!
//_log:
// If a user enters a string in an input field, you may need
// to convert it from ether (as a string) to wei (as a BigNumber)
//_result:
ethers.utils.parseEther("1.0")
//!
//_log:
_heading: Writing to the Blockchain @<getting-started--sending>
@@ -204,38 +211,33 @@ const daiAbi = [
// The Contract object
const daiContract = new ethers.Contract(daiAddress, daiAbi, provider);
//_hide: _page.daiAbi = daiAbi;
//_hide: _page.daiContract = daiContract;
_heading: Read-Only Methods @<getting-started--reading>
_code: Querying the DAI Contract @lang<javascript>
// <hide>
const daiAbi = [
// Some simple details about the token
"function name() view returns (string)",
"function symbol() view returns (string)",
// Get the account balance
"function balanceOf(address) view returns (uint)",
];
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
// </hide>
//_hide: const daiContract = _page.daiContract;
// Get the ERC-20 token name
daiContract.name()
//!
//_result:
await daiContract.name()
//_log:
// Get the ERC-20 token symbol (for tickers and UIs)
daiContract.symbol()
//!
//_result:
await daiContract.symbol()
//_log:
// Get the balance of an address
balance = await daiContract.balanceOf("ricmoo.firefly.eth")
//! async balance
//_log: balance
// Format the DAI for displaying to the user
//_result:
ethers.utils.formatUnits(balance, 18)
//!
//_log:
_heading: State Changing Methods @<getting-started--writing>
@@ -258,13 +260,8 @@ _heading: Listening to Events @<getting-started--events>
_code: Listening to Events @lang<javascript>
// <hide>
const daiAbi = [
"event Transfer(address indexed, address indexed, uint256)"
];
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
const formatEther = ethers.utils.formatEther;
// </hide>
//_hide: const daiContract = _page.daiContract;
//_hide: const formatEther = ethers.utils.formatEther;
// Receive an event when ANY transfer occurs
daiContract.on("Transfer", (from, to, amount, event) => {
@@ -277,10 +274,7 @@ daiContract.on("Transfer", (from, to, amount, event) => {
// A filter for when a specific address receives tokens
myAddress = "0x8ba1f109551bD432803012645Ac136ddd64DBA72";
filter = daiContract.filters.Transfer(null, myAddress)
// <hide>
filter
// </hide>
//!
//_log: filter
// Receive an event when that filter occurs
daiContract.on(filter, (from, to, amount, event) => {
@@ -288,46 +282,32 @@ daiContract.on(filter, (from, to, amount, event) => {
console.log(`I got ${ formatEther(amount) } from ${ from }.`);
});
// <hide>
// Don't want to block the docs from compiling...
daiContract.removeAllListeners();
// </hide>
//_hide: daiContract.removeAllListeners(); /* Don't want to block the docs from compiling... */
_heading: Query Historic Events @<getting-started--history>
_code: Filtering Historic Events @lang<javascript>
// <hide>
const signer = new ethers.VoidSigner("0x8ba1f109551bD432803012645Ac136ddd64DBA72");
const daiAbi = [
"event Transfer(address indexed, address indexed, uint256)"
];
const daiContract = new ethers.Contract("dai.tokens.ethers.eth", daiAbi, provider);
//!
// </hide>
//_hide: const signer = new ethers.VoidSigner("0x8ba1f109551bD432803012645Ac136ddd64DBA72");
//_hide: const daiContract = _page.daiContract;
// Get the address of the Signer
myAddress = await signer.getAddress()
//! async myAddress
//_log: myAddress
// Filter for all token transfers from me
filterFrom = daiContract.filters.Transfer(myAddress, null);
// <hide>
filterFrom
// </hide>
//!
//_log: filterFrom
// Filter for all token transfers to me
filterTo = daiContract.filters.Transfer(null, myAddress);
// <hide>
filterTo
// </hide>
//!
//_log: filterTo
// List all transfers sent from me a specific block range
daiContract.queryFilter(filterFrom, 9843470, 9843480)
//!
// List all transfers sent from me in a specific block range
//_result:
await daiContract.queryFilter(filterFrom, 9843470, 9843480)
//_log:
//
// The following have had the results omitted due to the
@@ -335,26 +315,22 @@ daiContract.queryFilter(filterFrom, 9843470, 9843480)
//
// List all transfers sent in the last 10,000 blocks
daiContract.queryFilter(filterFrom, -10000)
await daiContract.queryFilter(filterFrom, -10000)
// List all transfers ever sent to me
daiContract.queryFilter(filterTo)
await daiContract.queryFilter(filterTo)
_subsection: Signing Messages @<getting-started--signing>
_code: Signing Messages @lang<javascript>
// <hide>
const signer = ethers.Wallet.createRandom();
//!
// </hide>
//_hide: const signer = ethers.Wallet.createRandom();
// To sign a simple string, which are used for
// logging into a service, such as CryptoKitties,
// pass the string in.
signature = await signer.signMessage("Hello World");
//! async signature
//_log: signature
//
// A common case is also signing a hash, which is 32
@@ -367,8 +343,8 @@ message = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
// This array representation is 32 bytes long
messageBytes = ethers.utils.arrayify(message);
//!
//_log: messageBytes
// To sign a hash, you most often want to sign the bytes
signature = await signer.signMessage(messageBytes)
//! async signature
//_log: signature

View File

@@ -7,7 +7,7 @@ of uses.
_heading: MIT License
//Copyright &copy; 2019 [Richard Moore](mailto:me@ricmoo.com).//
//Copyright &copy; 2019-2021 [Richard Moore](mailto:me@ricmoo.com).//
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -69,7 +69,7 @@ signature = await signer.signMessage('Some data')
_subsection: Contracts
A contract object is an abstraction of a smart contract on the Ethereum Network. It allows for easy interaction with the smart contact.
A contract object is an abstraction of a smart contract on the Ethereum Network. It allows for easy interaction with the smart contract.
_heading: Deploying a Contract

View File

@@ -14,4 +14,4 @@ _subsection: Tutorials
I do not manage or maintain these tutorials, but have happened across them.
If a link is dead or outdated, please [let me know](link-mail) and I'll update it.
- No links yet; send me some
- [Alchemy - How to Mint an NFT](https://docs.alchemy.com/alchemy/tutorials/how-to-create-an-nft/how-to-mint-an-nft-with-ethers)

View File

@@ -151,7 +151,7 @@ This section is still a work in progress, but will outline some of the more nuan
aspects of the test cases and their values.
There will likely be an overhaul of the test cases in the next major version, to
make code coverage testing more straight forward and to collapse some of the redundancy.
make code coverage testing more straightforward and to collapse some of the redundancy.
For example, there is no longer a need to separate the ABI and ABIv2 test case and the
accounts and transactions suites can be merged into one large collection.

View File

@@ -0,0 +1,15 @@
_section: Building @<troubleshooting-building>
@TODO
_subsection: Packages
Sometimes packages get out of sync.
_code:
/home/ethers> rm package-lock.json node_modules/
/home/ethers> rm yarn.lock
/home/ethers> npm install

View File

@@ -0,0 +1,249 @@
_section: Error Codes @<error-codes>
All errors in ethers are created by the [[Logger]] class, which includes
a number of additional properties and extra data, which can assist in
debugging and when submitting issues.
When submitting an issue, please include as much of any error as possible,
but also make sure you understand the error and have tried suggested solutions
both in this trouble-shooting document and any other issues you find when
searching the GitHub issues.
_subsection: CALL_EXCEPTION @<help-CALL_EXCEPTION>
This error occurs when a call or transaction is used to interact with
the blockchain reverts (via ``revert``, ``require``, et cetera).
Due to the overall flexibility of Ethereum and Turing Completeness,
there is a large variety of reasons this can occur and troubleshooting
requires attention.
_heading: Common Causes
- The code does not exist on-chain. This may happen if you failed to wait
until the contract was deployed, the address is incorrect or if you
are connected to a different network than the contract has been deployed.
Check the code exists using ``provider.getCode(address)``.
- The wrong code is being accessed, for example if an artifact file was
not correctly updated so an older instance of the contract is being called
- The contract is failing during a ``require`` statement. For example, if
a contract method requires an //admin account// to be used, but the
contract is connected to another [[Signer]].
- The wrong ABI is being used to interact with a contract.
_heading: Debugging
- Always double check the address and network you are connected to and use
``provider.getCode(address)`` to verify the deployed code matches your
most recent version.
- Try accessing other, simpler contract methods to verify the account is correct.
_subsection: INSUFFICIENT_FUNDS @<help-INSUFFICIENT_FUNDS>
This usually occurs when a transaction is attempted, but the sending account
does not have enough ether to cover the cost of the transaction.
A transaction has an intrinsic cost which must be met, which accounts for
the value being sent, the base fee of the transaction, additional fees per byte
of calldata and whether the transaction will create a new account (i.e. the ``to``
is empty).
This error can also happen if ``provider.estimateGas`` is used with a non-zero
fee (i.e. ``gasPrice``, ``maxFeePerGas`` or ``maxPriorityFeePerGas``). If any
fee properties are specified, the ``from`` account must have sufficient ether
to execute the transaction.
_subsection: MISSING_NEW @<help-MISSING_NEW>
Classes in ethers must be instantiated with the ``new`` operator. This
error indicates that a Class is attempting to be used as a function.
_code: Examples @lang<javascript>
//_hide: privateKey = "0x0123456789012345678901234567890123456789012345678901234567890123";
//_hide: Wallet = ethers.Wallet;
// Bad:
//_throws:
ethers.Wallet(privateKey)
//_log:
// Good:
//_result:
new ethers.Wallet(privateKey)
//_log:
_subsection: NONCE_EXPIRED @<help-NONCE_EXPIRED>
This error occurs when a transaction is being sent with a ``nonce`` that
is lower than next required ``nonce``.
Each Ethereum transaction requires a ``nonce`` property equal to the index
of that transaction for that account for all time. So, if an account has
send four transactions over its lifetime, that means the nonces 0 though 3
(inclusive) have been used. The next transaction must use a nonce of 4.
Attempting to re-use a nonce less than 4 will result in this error.
_subsection: NUMERIC_FAULT @<help-NUMERIC_FAULT>
A [numeric fault](errors--numeric-fault) is a consequence of
performing an illegal operation with numeric values, such as
dividing by zero.
The error will indicate the ``operation``, which further indicates
the reason for the error.
_heading: Overflow @<help-NUMERIC_FAULT-overflow>
JavaScript uses [IEEE 754 double-precision binary floating point](link-wiki-ieee754)
numbers to represent numeric values. As a result, there are //holes//
in the integer set after 9,007,199,254,740,991; which is
problematic for //Ethereum// because that is only around 0.009
ether (in wei), which means any value over that will begin to
experience rounding errors.
As a result, any attempt to use a number which is outside the safe
range, which would result in incorrect values, an error is thrown.
In general, numbers should be kept as strings, [[BigNumber]] instances or
using ES2020 bigints, which all can safely be used without loss of precission.
_code: Examples @lang<javascript>
// One ether is outside the safe range
//_throws:
BigNumber.from(1000000000000000000)
//_log:
// Providing the value as a string is safe
//_result:
BigNumber.from("1000000000000000000")
//_log:
// As is using a bigint (notice the `n` suffix)
//_result:
BigNumber.from(1000000000000000000n)
//_log:
// But most often, the `parseEther` function solves this
//_result:
utils.parseEther("1.0")
//_log:
_heading: Numeric Underflow @<help-NUMERIC_FAULT-underflow>
Numeric underflow sbould not be confused with overflow.
Numeric underflow occurs when the precission of a value cannot be
safely represented in the current data type.
**Common Causes**
- Using values with fractional componets (e.g. ``BigNumber.from(1.2)``).
If you require fractions, you must use the [[FixedNumber]] class.
- Parsing string values that have more decimals than the unit supports
(e.g. ``parseUints("1.33", 1)``).
_code: Examples @lang<javascript>
// BigNumbers cannot be created with a fractional component
//_throws:
BigNumber.from(1.2)
//_log:
// Parsing a value with more decimals than the type
//_throws:
utils.parseUnits("1.34", 1);
//_log:
_heading: Division by zero @<help-NUMERIC_FAULT-division-by-zero>
This error occurs when dividing by zero or attempting to take the modulo zero.
_heading: Unbound Result @<help-NUMERIC_FAULT-unbound-result>
The ethers [[BigNumber]] does not support bitwise operators
on negative numbers which can result in the need for an infinite
number of set bits.
Other implementations may use negative values to indicate this,
but this is considered out of scope for ethers.
_heading: Unsupported Operation @<help-NUMERIC_FAULT-unsupported>
The ethers [[BigNumber]] does not support negative powers or bitwise
shift operation using negative values.
_code: Examples @lang<javascript>
two = BigNumber.from(2);
//_throws:
two.pow(-2)
//_log:
// Cannot use negative values to alter shift direction
//_throws:
two.shr(-1)
//_log:
_subsection: REPLACEMENT_UNDERPRICED @<help-REPLACEMENT_UNDERPRICED>
To prevent nodes from being overloaded with junk transactions, a transaction
is only accepted into the memory pool if it has a reasonable chance of being
actually mined, which means that the account has sufficient balance, the nonce
is correct and the fee seems reasonable.
Once a transaction is in the memory pool though, to prevent an account from
flooding the network with many different transactions with the same nonce (each
of which satisfies the above criteria), to replace an existing transaction
an additional committment of a fee must be made by increasing the promised fee.
When replacing a legacy non-EIP1559 transaction, the ``gasPrice`` must be
increased. When replacing a modern, EIP-1559 transaction, the ``maxPriorityFeePerGas``
should be increased.
_subsection: TRANSACTION_REPLACED @<help-TRANSACTION_REPLACED>
This error is thrown when waiting for a transaction which has been
replaced by another, by the sender submitting a second transaction
with the same nonce, while the transaction was pending in the
transaction pool.
You can learn more about this feature in the ``.wait`` method of
[TransactionResponse](providers-TransactionResponse).
_subsection: UNPREDICTABLE_GAS_LIMIT @<help-UNPREDICTABLE_GAS_LIMIT>
During gas estimation it is possible that a transaction would actually
fail (and hence has no reasonable estimate of gas requirements) or that
the transaction is complex in a way that does not permit a node to
estiamte the gas requirements, in which case this error is thrown.
In almost all cases, this will unfortunately require you specify an
explicit ``gasLimit`` for your transaction, which will disable ether's
automatic population of the ``gasLimit`` field, which will cause this
error to go away.
To dial in an appropriate gas limit, try a value that is much higher
than you expect, and then make a few transactions to discover reasonable
values and then you can reduce this value down to that ballpark.
Keep in mind this error can also occur if the transaction would
legitimately fail, in which case the root cause must be addressed, such
as ensuring the correct [[Signer]] is being used, the appropriate allowance
for an ERC-20 token has been approved, etc.

View File

@@ -0,0 +1,62 @@
_section: Getting Help @<troubleshooting-issues>
@TODO
_subsection: Starting a discussion
Before opening an issue
_subsection: Opening an Issue
Keep in mind that opening an issue should be a last resort, as it
requires time and energy by the library developers to look at that
could otherwise be spent on improving the library, documentation
and tools.
Before opening an issue, please make sure you have searched any
public information, such as:
- Documentation
- GitHub Discussions
- GitHub Issues (including closed issues)
There are several types of issues tracked by ethers. Using the correct
one helps you receive feedback quicker and helps us keep the right
person
_heading: Feature Requests
_heading: Bugs
This type of issue is for anything you you believe to be a bug in ethers.
Keep in mind that ethers is used extensively by thousands of people every
day, so while chances are possible you found a bug, please make sure to
do your due diligence to rule out user error.
If you are new to ethers, or are doing a fairly common operation, it is
quite likely what you are experiencing is a misunderstanding of how to
use a function, method or class. You should consider opening a discussion first.
Please make sure you include as much information as is useful:
- Are you using a third-party library, like Hardhat or Truffle?
- What platform are you on, a web browser, React Native, node, etc.?
- What network are you on, such as Ethereum mainnet, Optimism, etc.?
- What backend are you using, such as Geth, INFURA, Provider Engine, etc.?
_heading: Docuementation
If you have found a typo in the documentation, a feature which isn't
documented (or documented well) or just find something described in
the documentation confusing, please feel free to create an issue and
we will try to improve it.
_heading: Other
This should never be used.

View File

@@ -0,0 +1,11 @@
_section: TroubleShooting
_toc:
building
errors
network
help
_subsection: About Trbouble-Shooting

View File

@@ -0,0 +1,9 @@
_section: Troubleshooting Network @<troubleshooting-network>
@TODO
_subsection: Links
_subsection: Cross-Origin Resource Sharing (CORS)
_subsection: Mobile Development (Device Firewalls)

View File

@@ -35,7 +35,12 @@ module.exports = function(config) {
// Cloudflare will block (on the testnet endpoints) any traffic
// from a headless chome (based on the user agent), so we lie
// This was take from Safari, because that is what I had on-hand
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15']
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
// https://stackoverflow.com/questions/58484124/karma-disconnectedreconnect-failed-before-timeout-of-with-chromeheadless
'--disable-gpu',
'--no-sandbox'
],
}
},
/*

View File

@@ -36,7 +36,12 @@ module.exports = function(config) {
// Cloudflare will block (on the testnet endpoints) any traffic
// from a headless chome (based on the user agent), so we lie
// This was take from Safari, because that is what I had on-hand
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15']
'--user-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
// https://stackoverflow.com/questions/58484124/karma-disconnectedreconnect-failed-before-timeout-of-with-chromeheadless
'--disable-gpu',
'--no-sandbox'
]
}
},
/*

View File

@@ -5,23 +5,23 @@ const path_1 = require("./path");
const utils_1 = require("./utils");
function setupConfig(outDir, moduleType, targetType) {
// Configure the tsconfit.package.json...
const path = path_1.resolve("tsconfig.package.json");
const content = utils_1.loadJson(path);
const path = (0, path_1.resolve)("tsconfig.package.json");
const content = (0, utils_1.loadJson)(path);
content.compilerOptions.module = moduleType;
content.compilerOptions.target = targetType;
utils_1.saveJson(path, content, true);
(0, utils_1.saveJson)(path, content, true);
// Configure the browser field for every pacakge, copying the
// browser.umd filed for UMD and browser.esm for ESM
path_1.dirnames.forEach((dirname) => {
const filename = path_1.getPackageJsonPath(dirname);
const info = utils_1.loadJson(filename);
const filename = (0, path_1.getPackageJsonPath)(dirname);
const info = (0, utils_1.loadJson)(filename);
if (info._ethers_nobuild) {
return;
}
let path = path_1.resolve("packages", dirname, "tsconfig.json");
let content = utils_1.loadJson(path);
let path = (0, path_1.resolve)("packages", dirname, "tsconfig.json");
let content = (0, utils_1.loadJson)(path);
content.compilerOptions.outDir = outDir;
utils_1.saveJson(path, content, true);
(0, utils_1.saveJson)(path, content, true);
});
}
function setupBuild(buildModule) {

View File

@@ -39,7 +39,7 @@ const npm = __importStar(require("./npm"));
const path_1 = require("./path");
const run_1 = require("./run");
const utils_1 = require("./utils");
const changelogPath = path_1.resolve("CHANGELOG.md");
const changelogPath = (0, path_1.resolve)("CHANGELOG.md");
function generate() {
return __awaiter(this, void 0, void 0, function* () {
const lines = fs_1.default.readFileSync(changelogPath).toString().trim().split("\n");
@@ -59,11 +59,11 @@ function generate() {
const published = yield npm.getPackage("ethers");
if (versions.indexOf(version) >= 0) {
const line = `Version ${version} already in CHANGELOG. Please edit before committing.`;
console.log(log_1.colorify.red(utils_1.repeat("=", line.length)));
console.log(log_1.colorify.red((0, utils_1.repeat)("=", line.length)));
console.log(log_1.colorify.red(line));
console.log(log_1.colorify.red(utils_1.repeat("=", line.length)));
console.log(log_1.colorify.red((0, utils_1.repeat)("=", line.length)));
}
const gitResult = yield run_1.run("git", ["log", (published.gitHead + "..")]);
const gitResult = yield (0, run_1.run)("git", ["log", (published.gitHead + "..")]);
if (!gitResult.ok) {
console.log(gitResult);
throw new Error("Error running git log");
@@ -78,7 +78,7 @@ function generate() {
});
}
else if (line.toLowerCase().substring(0, 5) === "date:") {
changes[changes.length - 1].date = utils_1.getDateTime(new Date(line.substring(5).trim()));
changes[changes.length - 1].date = (0, utils_1.getDateTime)(new Date(line.substring(5).trim()));
}
else if (line.substring(0, 1) === " ") {
line = line.trim();
@@ -92,9 +92,9 @@ function generate() {
for (let i = 0; i < firstLine; i++) {
output.push(lines[i]);
}
const newTitle = `ethers/v${version} (${utils_1.getDateTime(new Date())})`;
const newTitle = `ethers/v${version} (${(0, utils_1.getDateTime)(new Date())})`;
output.push(newTitle);
output.push(utils_1.repeat("-", newTitle.length));
output.push((0, utils_1.repeat)("-", newTitle.length));
output.push("");
changes.forEach((change) => {
let body = change.body.trim();

View File

@@ -65,7 +65,7 @@ const path_1 = require("../path");
accum[name] = version;
return accum;
}, {});
const packageJsonPath = path_1.getPackageJsonPath(dirname);
const packageJsonPath = (0, path_1.getPackageJsonPath)(dirname);
local.updateJson(packageJsonPath, {
dependencies: deps,
version: newVersion

View File

@@ -40,8 +40,8 @@ const npm = __importStar(require("../npm"));
const utils_1 = require("../utils");
(function () {
return __awaiter(this, void 0, void 0, function* () {
const common = utils_1.loadJson(path_1.resolve("package.json")).common;
const progress = log_1.getProgressBar(log_1.colorify.bold("Bumping package.json versions"));
const common = (0, utils_1.loadJson)((0, path_1.resolve)("package.json")).common;
const progress = (0, log_1.getProgressBar)(log_1.colorify.bold("Bumping package.json versions"));
const latestVersions = {};
let updated = false;
const output = [];
@@ -49,7 +49,7 @@ const utils_1 = require("../utils");
for (let i = 0; i < path_1.dirnames.length; i++) {
progress(i / path_1.dirnames.length);
const dirname = path_1.dirnames[i];
const packageJsonPath = path_1.getPackageJsonPath(dirname);
const packageJsonPath = (0, path_1.getPackageJsonPath)(dirname);
// Set the common elements to the package.json
local.updateJson(packageJsonPath, common, true);
const pLocal = local.getPackage(dirname);
@@ -68,7 +68,7 @@ const utils_1 = require("../utils");
output.push([
" ",
log_1.colorify.blue(pLocal.name),
utils_1.repeat(" ", 47 - pLocal.name.length - pNpm.version.length),
(0, utils_1.repeat)(" ", 47 - pLocal.name.length - pNpm.version.length),
pNpm.version,
log_1.colorify.bold(" => "),
log_1.colorify.green(version)
@@ -80,13 +80,13 @@ const utils_1 = require("../utils");
// Write out the _version.ts
if (!pLocal._ethers_nobuild) {
const code = "export const version = " + JSON.stringify(dirname + "/" + version) + ";\n";
fs_1.default.writeFileSync(path_1.resolve(path_1.getPackagePath(dirname), "src.ts/_version.ts"), code);
fs_1.default.writeFileSync((0, path_1.resolve)((0, path_1.getPackagePath)(dirname), "src.ts/_version.ts"), code);
}
}
progress(1);
if (updated) {
const filename = path_1.resolve("packages/ethers/package.json");
const info = utils_1.loadJson(filename);
const filename = (0, path_1.resolve)("packages/ethers/package.json");
const info = (0, utils_1.loadJson)(filename);
Object.keys(info.dependencies).forEach((name) => {
const version = latestVersions[name];
if (name == null) {
@@ -94,7 +94,7 @@ const utils_1 = require("../utils");
}
info.dependencies[name] = version;
});
utils_1.saveJson(filename, info);
(0, utils_1.saveJson)(filename, info);
}
output.forEach((line) => { console.log(line); });
});

View File

@@ -38,10 +38,10 @@ const config = {
console.log(log_1.colorify.bold(`Bundling Testcase Data...`));
const data = { "_": JSON.stringify({ name: "browser-fs", config: config }) };
config.dirs.forEach((dirname) => {
let fulldirname = path_2.resolve("packages/testcases", dirname);
let fulldirname = (0, path_2.resolve)("packages/testcases", dirname);
fs_1.default.readdirSync(fulldirname).forEach((filename) => {
const key = path_1.join(dirname, filename);
const content = fs_1.default.readFileSync(path_1.join(fulldirname, filename));
const key = (0, path_1.join)(dirname, filename);
const content = fs_1.default.readFileSync((0, path_1.join)(fulldirname, filename));
if (filename.split(".").pop() === "gz") {
const contentData = zlib_1.default.gunzipSync(content);
data[key] = String(contentData.length) + "," + zlib_1.default.deflateRawSync(contentData).toString("base64");
@@ -52,15 +52,15 @@ const config = {
//console.log(` - Added ${ key } (${ data[key].length } bytes)`);
});
});
utils_1.mkdir(path_2.resolve("packages/testcases/lib"));
utils_1.mkdir(path_2.resolve("packages/testcases/lib._esm"));
utils_1.mkdir(path_2.resolve("packages/testcases/lib.esm"));
(0, utils_1.mkdir)((0, path_2.resolve)("packages/testcases/lib"));
(0, utils_1.mkdir)((0, path_2.resolve)("packages/testcases/lib._esm"));
(0, utils_1.mkdir)((0, path_2.resolve)("packages/testcases/lib.esm"));
// We write it out to all needed places
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/lib/browser-data.json"), JSON.stringify(data));
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/lib._esm/browser-data.json"), JSON.stringify(data));
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/lib.esm/browser-data.json"), JSON.stringify(data));
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/lib/browser-data.json"), JSON.stringify(data));
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/lib._esm/browser-data.json"), JSON.stringify(data));
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/lib.esm/browser-data.json"), JSON.stringify(data));
// Write it to the TypeScript source last, in case it is running it will
// be regenerated overwriting the above files, but with identical content
fs_1.default.writeFileSync(path_2.resolve("packages/testcases/src.ts/browser-data.json"), JSON.stringify(data));
fs_1.default.writeFileSync((0, path_2.resolve)("packages/testcases/src.ts/browser-data.json"), JSON.stringify(data));
});
})();

View File

@@ -15,6 +15,6 @@ const github_1 = require("../github");
return __awaiter(this, void 0, void 0, function* () {
const user = yield config_1.config.get("github-user");
const password = yield config_1.config.get("github-readonly");
yield github_1.syncIssues(user, password);
yield (0, github_1.syncIssues)(user, password);
});
})();

View File

@@ -24,8 +24,8 @@ const log_1 = require("../log");
function alias(name) {
return __awaiter(this, void 0, void 0, function* () {
console.log(` Aliasing: ${name}`);
const baseDir = path_2.resolve("packages", name);
const info = utils_1.loadJson(path_2.resolve(baseDir, "package.json"));
const baseDir = (0, path_2.resolve)("packages", name);
const info = (0, utils_1.loadJson)((0, path_2.resolve)(baseDir, "package.json"));
const replacements = info["_ethers.alias"] || {};
const skip = Object.keys(replacements).reduce((accum, key) => {
const replace = replacements[key];
@@ -37,10 +37,10 @@ function alias(name) {
}, ({}));
const transforms = [];
const recurse = function (input, output) {
fs_1.default.readdirSync(path_1.join(baseDir, input)).forEach((filename) => {
const stat = fs_1.default.statSync(path_1.join(baseDir, input, filename));
fs_1.default.readdirSync((0, path_1.join)(baseDir, input)).forEach((filename) => {
const stat = fs_1.default.statSync((0, path_1.join)(baseDir, input, filename));
if (stat.isDirectory()) {
recurse(path_1.join(input, filename), path_1.join(output, filename));
recurse((0, path_1.join)(input, filename), (0, path_1.join)(output, filename));
return;
}
if (skip[filename]) {
@@ -61,7 +61,7 @@ function alias(name) {
if (replace) {
inputFilename = replace;
transform = function (content) {
content = content.replace(/(\/\/# sourceMappingURL=)(.*)$/g, (all, prefix, mapFilename) => {
content = content.replace(/^(\/\/# sourceMappingURL=)(.*)$/mg, (all, prefix, mapFilename) => {
return prefix + filename + ".map";
});
return content;
@@ -118,19 +118,19 @@ function alias(name) {
};
}
}
transforms.push({ input: path_1.join(input, inputFilename), output: path_1.join(output, filename), transform });
transforms.push({ input: (0, path_1.join)(input, inputFilename), output: (0, path_1.join)(output, filename), transform });
});
};
recurse("lib._esm", "lib.esm");
transforms.forEach(({ input, output, transform }) => {
const sourceFile = path_1.join(baseDir, input);
const sourceFile = (0, path_1.join)(baseDir, input);
let content = fs_1.default.readFileSync(sourceFile).toString();
if (transform) {
content = transform(content);
}
const targetFile = path_1.join(baseDir, output);
const targetDir = path_1.dirname(targetFile);
utils_1.mkdir(targetDir);
const targetFile = (0, path_1.join)(baseDir, output);
const targetDir = (0, path_1.dirname)(targetFile);
(0, utils_1.mkdir)(targetDir);
fs_1.default.writeFileSync(targetFile, content);
});
});
@@ -138,9 +138,9 @@ function alias(name) {
(function () {
return __awaiter(this, void 0, void 0, function* () {
console.log(log_1.colorify.bold(`Aliasing Node ESM to Browser ESM...`));
const dirnames = depgraph_1.getOrdered(true);
const dirnames = (0, depgraph_1.getOrdered)(true);
for (let i = 0; i < dirnames.length; i++) {
//if (dirnames[i] !== "base64") { continue; }
//if (dirnames[i] !== "signing-key") { continue; }
yield alias(dirnames[i]);
}
});

View File

@@ -14,11 +14,11 @@ const local_1 = require("../local");
const log_1 = require("../log");
(function () {
return __awaiter(this, void 0, void 0, function* () {
const dependencies = local_1.getDependencies(null, (name) => {
return !path_1.isEthers(name);
const dependencies = (0, local_1.getDependencies)(null, (name) => {
return !(0, path_1.isEthers)(name);
});
console.log(log_1.colorify.bold(`Hoisting ${Object.keys(dependencies).length} dependencies into root package...`));
local_1.updateJson(path_1.dirs.rootPackageJsonPath, { dependencies });
(0, local_1.updateJson)(path_1.dirs.rootPackageJsonPath, { dependencies });
});
})().catch((error) => {
console.log(`Error running ${process.argv[0]}: ${error.message}`);

View File

@@ -33,28 +33,28 @@ function link(existing, path) {
}
}
// Link
const dir = path_1.dirname(path);
utils_1.mkdir(dir);
const dir = (0, path_1.dirname)(path);
(0, utils_1.mkdir)(dir);
fs_1.default.symlinkSync(existing, path, "junction");
}
(function () {
return __awaiter(this, void 0, void 0, function* () {
console.log(log_1.colorify.bold(`Linking ${path_2.packages.length} package node_modules rat nests...`));
const nodeModulesBase = path_1.resolve(path_2.dirs.root, ".package_node_modules");
const nodeModulesBase = (0, path_1.resolve)(path_2.dirs.root, ".package_node_modules");
// Make a symlink in the ROOT/node_mpdules to each package in this repo
path_2.packages.forEach((name) => {
// e.g. /node_modules/@ethersproject/abi => /packages/abi
link(path_2.getPackagePath(name), path_1.resolve(path_2.dirs.root, "node_modules", name));
link((0, path_2.getPackagePath)(name), (0, path_1.resolve)(path_2.dirs.root, "node_modules", name));
// e.g. /packages/abi/node_modules => /.package_node_modules/abi/
const nodeModules = path_1.resolve(nodeModulesBase, path_2.getDirname(name));
utils_1.mkdir(nodeModules);
link(nodeModules, path_1.resolve(path_2.getPackagePath(name), "node_modules"));
const nodeModules = (0, path_1.resolve)(nodeModulesBase, (0, path_2.getDirname)(name));
(0, utils_1.mkdir)(nodeModules);
link(nodeModules, (0, path_1.resolve)((0, path_2.getPackagePath)(name), "node_modules"));
});
path_2.packages.forEach((name) => {
const nodeModules = path_1.resolve(nodeModulesBase, path_2.getDirname(name));
const deps = local_1.getDependencies(name);
const nodeModules = (0, path_1.resolve)(nodeModulesBase, (0, path_2.getDirname)(name));
const deps = (0, local_1.getDependencies)(name);
Object.keys(deps).forEach((name) => {
link(path_1.resolve(path_2.dirs.root, "node_modules", name), path_1.resolve(nodeModules, name));
link((0, path_1.resolve)(path_2.dirs.root, "node_modules", name), (0, path_1.resolve)(nodeModules, name));
});
});
});

View File

@@ -15,7 +15,7 @@ const utils_1 = require("../utils");
(function () {
return __awaiter(this, void 0, void 0, function* () {
const versions = path_1.dirnames.reduce((accum, dirname) => {
const pkg = local_1.getPackage(dirname);
const pkg = (0, local_1.getPackage)(dirname);
accum[pkg.name] = pkg.version;
return accum;
}, ({}));
@@ -25,8 +25,8 @@ const utils_1 = require("../utils");
return;
}
console.log(dirname);
const path = path_1.resolve("packages", dirname, "package.json");
const json = utils_1.loadJson(path);
const path = (0, path_1.resolve)("packages", dirname, "package.json");
const json = (0, utils_1.loadJson)(path);
for (const name in (json.dependencies || {})) {
const version = json.dependencies[name];
const target = (versions[name] ? ("^" + versions[name]) : version);
@@ -35,7 +35,7 @@ const utils_1 = require("../utils");
}
json.dependencies[name] = target;
}
utils_1.saveJson(path, json, true);
(0, utils_1.saveJson)(path, json, true);
});
});
})();

0
misc/admin/lib/cmds/peg-version.d.ts vendored Normal file
View File

View File

@@ -0,0 +1,16 @@
/*
import { dirnames, getPackage } from "../local";
import { colorify } from "../log";
const dirname = process.argv[2];
if (dirname == null) {
console.log("Usage: peg-version DIRNAME");
process.exit(1);
}
(async function(dirname) {
const { name, version } = getPackage(dirname);
console.log(colorify.bold(`Pegging ${ name } to ${ version }...`));
})(dirname);
*/

View File

@@ -89,10 +89,10 @@ function invalidate(cloudfront, distributionId) {
exports.invalidate = invalidate;
(function () {
return __awaiter(this, void 0, void 0, function* () {
const dirnames = depgraph_1.getOrdered();
const dirnames = (0, depgraph_1.getOrdered)();
// @TODO: Fail if there are any untracked files or unchecked in files
const publish = {};
const progressUpdate = log_1.getProgressBar(log_1.colorify.bold("Finding updated packages..."));
const progressUpdate = (0, log_1.getProgressBar)(log_1.colorify.bold("Finding updated packages..."));
for (let i = 0; i < dirnames.length; i++) {
progressUpdate(i / dirnames.length);
let dirname = dirnames[i];
@@ -103,8 +103,8 @@ exports.invalidate = invalidate;
continue;
}
// Get the latest commit this package was modified at
const path = path_1.resolve("packages", dirname);
const gitHead = yield git_1.getGitTag(path);
const path = (0, path_1.resolve)("packages", dirname);
const gitHead = yield (0, git_1.getGitTag)(path);
if (gitHead == null) {
throw new Error("hmmm...");
}
@@ -119,7 +119,7 @@ exports.invalidate = invalidate;
console.log(log_1.colorify.bold(`Found ${Object.keys(publish).length} updated pacakges...`));
Object.keys(publish).forEach((dirname) => {
const info = publish[dirname];
console.log(` ${log_1.colorify.blue(info.name)} ${utils_1.repeat(" ", 50 - info.name.length - info.oldVersion.length)} ${info.oldVersion} ${log_1.colorify.bold("=>")} ${log_1.colorify.green(info.newVersion)}`);
console.log(` ${log_1.colorify.blue(info.name)} ${(0, utils_1.repeat)(" ", 50 - info.name.length - info.oldVersion.length)} ${info.oldVersion} ${log_1.colorify.bold("=>")} ${log_1.colorify.green(info.newVersion)}`);
});
const publishNames = Object.keys(publish);
publishNames.sort((a, b) => (dirnames.indexOf(a) - dirnames.indexOf(b)));
@@ -149,17 +149,17 @@ exports.invalidate = invalidate;
console.log(log_1.colorify.bold("Publishing:"));
for (let i = 0; i < publishNames.length; i++) {
const dirname = publishNames[i];
const path = path_1.resolve("packages", dirname);
const pathJson = path_1.resolve("packages", dirname, "package.json");
const path = (0, path_1.resolve)("packages", dirname);
const pathJson = (0, path_1.resolve)("packages", dirname, "package.json");
const { gitHead, name, newVersion } = publish[dirname];
console.log(` ${log_1.colorify.blue(name)} @ ${log_1.colorify.green(newVersion)}`);
local.updateJson(pathJson, { gitHead: gitHead }, true);
const info = utils_1.loadJson(pathJson);
const info = (0, utils_1.loadJson)(pathJson);
yield npm.publish(path, info, options);
local.updateJson(pathJson, { gitHead: undefined }, true);
}
if (publishNames.indexOf("ethers") >= 0 || forcePublish) {
const change = changelog_1.getLatestChange();
const change = (0, changelog_1.getLatestChange)();
const patchVersion = change.version.substring(1);
const minorVersion = patchVersion.split(".").slice(0, 2).join(".");
const awsAccessId = yield config_1.config.get("aws-upload-scripts-accesskey");
@@ -169,8 +169,8 @@ exports.invalidate = invalidate;
// The password above already succeeded
const username = yield config_1.config.get("github-user");
const password = yield config_1.config.get("github-release");
const hash = createHash("sha384").update(fs_1.default.readFileSync(path_1.resolve("packages/ethers/dist/ethers.umd.min.js"))).digest("base64");
const gitCommit = yield git_1.getGitTag(path_1.resolve("CHANGELOG.md"));
const hash = createHash("sha384").update(fs_1.default.readFileSync((0, path_1.resolve)("packages/ethers/dist/ethers.umd.min.js"))).digest("base64");
const gitCommit = yield (0, git_1.getGitTag)((0, path_1.resolve)("CHANGELOG.md"));
let content = change.content.trim();
content += '\n\n----\n\n';
content += '**Embedding UMD with [SRI](https:/\/developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity):**\n';
@@ -183,7 +183,7 @@ exports.invalidate = invalidate;
content += '```';
// Publish the release
const beta = false;
const link = yield github_1.createRelease(username, password, change.version, change.title, content, beta, gitCommit);
const link = yield (0, github_1.createRelease)(username, password, change.version, change.title, content, beta, gitCommit);
console.log(`${log_1.colorify.bold("Published release:")} ${link}`);
}
// Upload libs to the CDN (as ethers-v5.1 and ethers-5.1.x)
@@ -244,7 +244,7 @@ exports.invalidate = invalidate;
const { bucketName, originRoot, filename, key, suffix } = fileInfos[i];
yield putObject(s3, {
ACL: "public-read",
Body: fs_1.default.readFileSync(path_1.resolve(filename)),
Body: fs_1.default.readFileSync((0, path_1.resolve)(filename)),
Bucket: bucketName,
ContentType: "application/javascript; charset=utf-8",
Key: (originRoot + key)

View File

@@ -42,8 +42,8 @@ function start(root, options) {
if (options.port == null) {
options.port = 8000;
}
root = path_1.resolve(root);
const server = http_1.createServer((req, resp) => {
root = (0, path_1.resolve)(root);
const server = (0, http_1.createServer)((req, resp) => {
const url = req.url.split("?")[0];
// Follow redirects in options
if (options.redirects && options.redirects[url]) {
@@ -51,7 +51,7 @@ function start(root, options) {
resp.end();
return;
}
let filename = path_1.resolve(root, "." + url);
let filename = (0, path_1.resolve)(root, "." + url);
// Make sure we aren't crawling out of our sandbox
if (url[0] !== "/" || filename.substring(0, filename.length) !== filename) {
resp.writeHead(403);
@@ -94,7 +94,7 @@ function start(root, options) {
return server;
}
exports.start = start;
start(path_2.resolve("docs"), {
start((0, path_2.resolve)("docs"), {
redirects: {
"/": "/v5/"
}

View File

@@ -19,19 +19,19 @@ const utils_1 = require("../utils");
console.log(log_1.colorify.bold("Setting Option:"), arg);
switch (arg) {
case "esm":
build_1.setupBuild(true);
(0, build_1.setupBuild)(true);
break;
case "cjs":
build_1.setupBuild(false);
(0, build_1.setupBuild)(false);
break;
// This will remove the browser field entirely, so make sure
// to set esm of cjs first as they will restore the browser
// field
case "browser-lang-all": {
const filename = path_1.getPackageJsonPath("wordlists");
const info = utils_1.loadJson(filename);
const filename = (0, path_1.getPackageJsonPath)("wordlists");
const info = (0, utils_1.loadJson)(filename);
delete info.browser;
utils_1.saveJson(filename, info, true);
(0, utils_1.saveJson)(filename, info, true);
break;
}
default:

View File

@@ -18,7 +18,7 @@ if (process.argv.length !== 3) {
const key = process.argv[2];
(function () {
return __awaiter(this, void 0, void 0, function* () {
const value = yield log_1.getPassword("Value: ");
const value = yield (0, log_1.getPassword)("Value: ");
yield config_1.config.set(key, value);
});
})().catch((error) => {

View File

@@ -16,7 +16,7 @@ const fs_1 = __importDefault(require("fs"));
const path_1 = require("../path");
const utils_1 = require("../utils");
function copy(src, dst, transform) {
let data = fs_1.default.readFileSync(path_1.resolve(src));
let data = fs_1.default.readFileSync((0, path_1.resolve)(src));
if (transform) {
data = Buffer.from(transform(data.toString()));
}
@@ -24,14 +24,14 @@ function copy(src, dst, transform) {
}
(function () {
return __awaiter(this, void 0, void 0, function* () {
yield utils_1.mkdir(path_1.resolve("output/karma"));
copy(path_1.resolve("packages/ethers/dist/ethers.esm.js"), path_1.resolve("output/karma/ethers.esm.js"));
copy(path_1.resolve("packages/tests/dist/tests.esm.js"), path_1.resolve("output/karma/tests.esm.js"), (data) => {
yield (0, utils_1.mkdir)((0, path_1.resolve)("output/karma"));
copy((0, path_1.resolve)("packages/ethers/dist/ethers.esm.js"), (0, path_1.resolve)("output/karma/ethers.esm.js"));
copy((0, path_1.resolve)("packages/tests/dist/tests.esm.js"), (0, path_1.resolve)("output/karma/tests.esm.js"), (data) => {
return data.replace(/^(import [^;]* from ')(ethers)(';)/, (all, prefix, id, suffix) => {
return prefix + "./ethers.esm.js" + suffix;
});
});
copy(path_1.resolve("packages/ethers/dist/ethers.umd.js"), path_1.resolve("output/karma/ethers.umd.js"));
copy(path_1.resolve("packages/tests/dist/tests.umd.js"), path_1.resolve("output/karma/tests.umd.js"));
copy((0, path_1.resolve)("packages/ethers/dist/ethers.umd.js"), (0, path_1.resolve)("output/karma/ethers.umd.js"));
copy((0, path_1.resolve)("packages/tests/dist/tests.umd.js"), (0, path_1.resolve)("output/karma/tests.umd.js"));
});
})();

View File

@@ -22,18 +22,18 @@ const Words = fs_1.default.readFileSync("/usr/share/dict/words").toString().spli
}, {});
`
// Words missing from the dictionary
accessing addresses aligned autofill called cancelled changed censored
clamping compiled computed configured consumed creating decoded decoding
accessing addresses aligned autofill avatar called cancelled changed censored
clamping compiled computed configured consumed contained creating decoded decoding
decreased decrypt decrypted decrypting deployed deploying deprecated detected
discontinued earliest email enabled encoded encoder encoding encrypt
encrypted encrypting entries euro exceeded existing expected
discontinued earliest email emitted enabled encoded encoder encoding encountered
encrypt encrypted encrypting entries euro exceeded existing expected
expired failed fetches formatted formatting funding generated
hardened has highly ignoring implemented implementer imported including instantiate
joined keyword labelled larger lookup matches mined modified modifies multi
named needed nested neutered numeric offline optimizer overriding owned packed
padded parsed parsing passed payload placeholder processing properties prototyping reached
recommended recovered redacted remaining replaced required reverted
serializes shared signed signing skipped stored supported tagging targetted
recommended recovered recursively redacted remaining replaced repriced required reverted
serializes shared signed signing skipped stats stored supported tagging targetted
throttled transactions typed uninstall unstake unsubscribe untyped
using verifies verifying website
@@ -41,7 +41,7 @@ using verifies verifying website
bech BIP BIP39 BIP44 btc bzz crypto eip etc hashes hmac icap
keccak ltc namehash ripemd RLP scrypt secp sha xdai
blockhash
blockhash bnb bnbt ethprice matic txlist
bitcoin ethereum finney gwei kwei mwei satoshi szabo wei weth
@@ -56,15 +56,15 @@ ABIEncoder testcase numberish Wordlist
// Common Code Strings
abi addr api app arg arrayify asm backend basex bigint bignumber bn byte
bytecode callback calldata charset checksum ciphertext cli codepoint
bytecode callback calldata ccip charset checksum ciphertext cli codepoint
commify config
contenthash ctr ctrl debug dd dklen eexist encseed eof eq ethaddr
contenthash ctr ctrl debug dd dklen eexist encseed eof eq erc ethaddr
ethseed ethers eval exec filename func gz gzip hid http https hw iv
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
info init ipc json kdf kdfparams labelhash lang lib metadata mm multihash nfc
nfkc nfd nfkd nodehash notok nowait nullish offchain oob opcode org pbkdf pc plugin
pragma pre prf recid repl rpc sighash topichash solc stdin stdout subclasses
subnode timeout todo txt typeof ufixed utc utf util url urlencoded uuid vm
vs websocket wikipedia www wx xe xpriv xpub xx yyyy zlib
vs websocket wikipedia wildcard wildcards www wx xe xpriv xpub xx yyyy zlib
// AbiV2
abiv
@@ -72,13 +72,14 @@ abiv
// Query parameters
apikey asc endblock startblock
alchemyapi Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
alchemyapi ankr arbitrum Cloudflare com Etherscan INFURA IPFS IPNS MetaMask Nodesmith
Trezor ledgerhq axic bitcoinjs browserify easyseed ethereumjs
goerli homestead kotti kovan mainnet morden mordor rinkeby
ropsten testnet lb
goerli homestead kotti kovan mainnet morden mordor rinkeby kintsugi
ropsten testnet lb maticmum
// Demo words
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
brantly ricmoose
// nameprep tags
ALCat BiDi LCat nameprep
@@ -129,7 +130,7 @@ function getStrings(source) {
const Include = new RegExp("packages/.*/src.ts/.*\.ts$");
const Exclude = new RegExp("/node_modules/|src.ts/.*browser.*");
function getAllStrings(path) {
const Root = path_1.resolve(__dirname, path);
const Root = (0, path_1.resolve)(__dirname, path);
const readdir = function (path) {
if (path.match(Exclude)) {
return [];
@@ -137,7 +138,7 @@ function getAllStrings(path) {
const stat = fs_1.default.statSync(path);
if (stat.isDirectory()) {
return fs_1.default.readdirSync(path).reduce((result, filename) => {
readdir(path_1.resolve(path, filename)).forEach((file) => {
readdir((0, path_1.resolve)(path, filename)).forEach((file) => {
result.push(file);
});
return result;
@@ -174,7 +175,7 @@ function starts(text, prefix) {
return __awaiter(this, void 0, void 0, function* () {
console.log(log_1.colorify.bold("Spell checking source code strings..."));
let count = 0;
getAllStrings(path_1.resolve(__dirname, "../../../../packages")).forEach((file) => {
getAllStrings((0, path_1.resolve)(__dirname, "../../../../packages")).forEach((file) => {
if (starts(file.filename, "/testcases/src.ts/generation-scripts")) {
return;
}

View File

@@ -19,6 +19,6 @@ const path_1 = require("../path");
(function () {
return __awaiter(this, void 0, void 0, function* () {
console.log(log_1.colorify.bold("Updating CHANGELOG.md..."));
fs_1.default.writeFileSync(path_1.resolve("CHANGELOG.md"), yield changelog_1.generate());
fs_1.default.writeFileSync((0, path_1.resolve)("CHANGELOG.md"), yield (0, changelog_1.generate)());
});
})();

View File

@@ -14,8 +14,8 @@ const path_1 = require("../path");
const local_1 = require("../local");
(function () {
return __awaiter(this, void 0, void 0, function* () {
const ordered = depgraph_1.getOrdered(true);
local_1.updateJson(path_1.resolve("tsconfig.project.json"), {
const ordered = (0, depgraph_1.getOrdered)(true);
(0, local_1.updateJson)((0, path_1.resolve)("tsconfig.project.json"), {
references: ordered.map((name) => ({ path: ("./packages/" + name) }))
});
});

View File

@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const log_1 = require("../log");
const path_1 = require("../path");
const sourceEthers = fs_1.default.readFileSync(path_1.resolve("packages/ethers/src.ts/ethers.ts")).toString();
const sourceEthers = fs_1.default.readFileSync((0, path_1.resolve)("packages/ethers/src.ts/ethers.ts")).toString();
const targets = sourceEthers.match(/export\s*{\s*((.|\s)*)}/)[1].trim();
////////////////////
// Begin template
@@ -35,4 +35,4 @@ export {
// End template
////////////////////
console.log(log_1.colorify.bold(`Flattening exports...`));
fs_1.default.writeFileSync(path_1.resolve("packages/ethers/src.ts/index.ts"), output);
fs_1.default.writeFileSync((0, path_1.resolve)("packages/ethers/src.ts/index.ts"), output);

View File

@@ -14,14 +14,14 @@ const log_1 = require("../log");
const path_1 = require("../path");
(function () {
return __awaiter(this, void 0, void 0, function* () {
const progress = log_1.getProgressBar(log_1.colorify.bold("Updating package.json hashes"));
const progress = (0, log_1.getProgressBar)(log_1.colorify.bold("Updating package.json hashes"));
// Updating all tarball hashes now that versions have been updated
for (let i = 0; i < path_1.dirnames.length; i++) {
progress(i / path_1.dirnames.length);
const dirname = path_1.dirnames[i];
//const gitHead = await getGitTag(resolve("packages", dirname));
const tarballHash = local_1.computeTarballHash(dirname);
local_1.updateJson(path_1.getPackageJsonPath(dirname), { tarballHash }, true);
const tarballHash = (0, local_1.computeTarballHash)(dirname);
(0, local_1.updateJson)((0, path_1.getPackageJsonPath)(dirname), { tarballHash }, true);
}
progress(1);
});

View File

@@ -116,7 +116,7 @@ function _getFiles(result, root) {
if (filename === '.DS_Store') {
return;
}
const fullFilename = path_1.join(root, filename);
const fullFilename = (0, path_1.join)(root, filename);
const stat = fs_1.default.statSync(fullFilename);
if (stat.isDirectory()) {
_getFiles(result, fullFilename);
@@ -150,7 +150,7 @@ function getFiles(basedir) {
secretAccessKey: awsSecretKey
});
const added = [], removed = [], changed = [], upload = [];
const basedir = path_2.resolve("docs");
const basedir = (0, path_2.resolve)("docs");
const local = yield getFiles(basedir);
const remote = yield getKeys(s3, bucket);
Object.keys(local).forEach((filename) => {
@@ -177,7 +177,7 @@ function getFiles(basedir) {
console.log('Changed: ', changed.length);
for (let i = 0; i < upload.length; i++) {
const filename = upload[i];
const content = fs_1.default.readFileSync(path_1.join(basedir, filename));
const content = fs_1.default.readFileSync((0, path_1.join)(basedir, filename));
console.log(`Uploading: ${filename} (${content.length} bytes)`);
yield putObject(s3, bucket, filename, content);
}

View File

@@ -22,15 +22,15 @@ const scrypt_js_1 = __importDefault(require("scrypt-js"));
const log_1 = require("./log");
function getRandomBytes(length) {
const result = new Uint8Array(length);
result.set(crypto_1.randomBytes(length));
result.set((0, crypto_1.randomBytes)(length));
return result;
}
function computeHmac(key, data) {
return "0x" + crypto_1.createHmac("sha512", key).update(data).digest("hex");
return "0x" + (0, crypto_1.createHmac)("sha512", key).update(data).digest("hex");
}
function getScrypt(message, password, salt) {
return __awaiter(this, void 0, void 0, function* () {
const progress = log_1.getProgressBar(message);
const progress = (0, log_1.getProgressBar)(message);
return yield scrypt_js_1.default.scrypt(Buffer.from(password), Buffer.from(salt), (1 << 17), 8, 1, 64, progress);
});
}
@@ -58,7 +58,7 @@ class Config {
}
this.canary = data.canary || "";
this.salt = data.salt;
const password = yield log_1.getPassword(log_1.colorify.bold("Password (config-store): "));
const password = yield (0, log_1.getPassword)(log_1.colorify.bold("Password (config-store): "));
this.dkey = yield getScrypt(log_1.colorify.bold("Unlocking config"), password, this.salt);
if (data.ciphertext) {
const ciphertext = Buffer.from(data.ciphertext, "base64");
@@ -113,7 +113,7 @@ class Config {
this.salt = this.dkey = null;
}
}
const _config = new Config(path_1.resolve(os_1.default.homedir(), ".ethers-dist"));
const _config = new Config((0, path_1.resolve)(os_1.default.homedir(), ".ethers-dist"));
exports.config = {
get: function (key) {
return _config.get(key);

View File

@@ -47,7 +47,7 @@ function getOrdered(skipNobuild) {
};
for (let i = 0; i < path_1.dirnames.length; i++) {
let dirname = path_1.dirnames[i];
let info = local_1.getPackage(dirname);
let info = (0, local_1.getPackage)(dirname);
if (skipNobuild && info._ethers_nobuild) {
continue;
}
@@ -91,8 +91,8 @@ exports.getOrdered = getOrdered;
function sort(dirnames) {
let ordered = getOrdered();
dirnames.sort((a, b) => {
let ai = ordered.indexOf(local_1.getPackage(a).name);
let bi = ordered.indexOf(local_1.getPackage(b).name);
let ai = ordered.indexOf((0, local_1.getPackage)(a).name);
let bi = ordered.indexOf((0, local_1.getPackage)(b).name);
if (ai === -1 || bi === -1) {
throw new Error("unknown dirname - " + [a, b].join(", "));
}

View File

@@ -73,9 +73,9 @@ function _getUrl(href, options) {
options = {};
}
// @TODO: Once we drop support for node 8, we can pass the href
// firectly into request and skip adding the components
// directly into request and skip adding the components
// to this request object
const url = url_1.parse(href);
const url = (0, url_1.parse)(href);
const request = {
protocol: nonnull(url.protocol),
hostname: nonnull(url.hostname),

View File

@@ -14,7 +14,7 @@ const run_1 = require("./run");
// Returns the most recent git commit hash for a given filename
function getGitTag(filename) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield run_1.run("git", ["log", "-n", "1", "--", filename]);
const result = yield (0, run_1.run)("git", ["log", "-n", "1", "--", filename]);
if (!result.ok) {
throw new Error(`git log error`);
}

View File

@@ -22,7 +22,7 @@ function _fetchGitHub(user, password, getUrlFunc, url) {
return __awaiter(this, void 0, void 0, function* () {
const result = [];
while (true) {
const filename = path_1.resolve("github-cache", Buffer.from(js_sha3_1.keccak_256.create().update(Buffer.from(url)).digest()).toString("hex").substring(0, 12));
const filename = (0, path_1.resolve)("github-cache", Buffer.from(js_sha3_1.keccak_256.create().update(Buffer.from(url)).digest()).toString("hex").substring(0, 12));
const headers = {
"User-Agent": "ethers-io",
};
@@ -41,7 +41,7 @@ function _fetchGitHub(user, password, getUrlFunc, url) {
throw error;
}
}
const response = yield geturl_1.getUrl(url, { headers, user, password });
const response = yield (0, geturl_1.getUrl)(url, { headers, user, password });
console.log(response.statusCode);
// Cached response is good; use it!
if (response.statusCode !== 304) {
@@ -129,7 +129,7 @@ function syncIssues(user, password) {
exports.syncIssues = syncIssues;
function createRelease(user, password, tagName, title, body, prerelease, commit) {
return __awaiter(this, void 0, void 0, function* () {
const result = yield geturl_1.getUrl("https:/\/api.github.com/repos/ethers-io/ethers.js/releases", {
const result = yield (0, geturl_1.getUrl)("https:/\/api.github.com/repos/ethers-io/ethers.js/releases", {
body: Buffer.from(JSON.stringify({
tag_name: tagName,
target_commitish: (commit || "master"),

View File

@@ -9,7 +9,7 @@ const path_1 = require("./path");
const run_1 = require("./run");
const utils_1 = require("./utils");
function getPackage(name) {
const value = utils_1.loadJson(path_1.getPackageJsonPath(name));
const value = (0, utils_1.loadJson)((0, path_1.getPackageJsonPath)(name));
return {
name: value.name,
version: value.version,
@@ -23,7 +23,7 @@ function getPackage(name) {
}
exports.getPackage = getPackage;
function updateJson(path, replace, sort) {
const values = utils_1.loadJson(path);
const values = (0, utils_1.loadJson)(path);
Object.keys(replace).forEach((key) => {
const value = replace[key];
if (value === undefined) {
@@ -33,12 +33,12 @@ function updateJson(path, replace, sort) {
values[key] = replace[key];
}
});
utils_1.saveJson(path, values, !!sort);
(0, utils_1.saveJson)(path, values, !!sort);
}
exports.updateJson = updateJson;
function getDependencies(name, filter) {
if (name) {
return utils_1.sortRecords(getPackage(name).dependencies);
return (0, utils_1.sortRecords)(getPackage(name).dependencies);
}
// Find all versions for each package dependency
const deps = path_1.dirnames.reduce((accum, dirname) => {
@@ -55,7 +55,7 @@ function getDependencies(name, filter) {
return accum;
}, {});
// Make sure each package dependency only has 1 version
return utils_1.sortRecords(Object.keys(deps).reduce((accum, name) => {
return (0, utils_1.sortRecords)(Object.keys(deps).reduce((accum, name) => {
const versions = Object.keys(deps[name]);
if (versions.length > 1) {
throw new Error(`cannot depend on multiple versions for ${JSON.stringify(name)}: ${versions.map(v => JSON.stringify(v)).join(", ")}`);
@@ -66,7 +66,7 @@ function getDependencies(name, filter) {
}
exports.getDependencies = getDependencies;
function getPackList(name) {
const result = run_1.run("npm", ["pack", "--json", path_1.getPackagePath(name), "--dry-run"]);
const result = (0, run_1.run)("npm", ["pack", "--json", (0, path_1.getPackagePath)(name), "--dry-run"]);
if (!result.ok) {
const error = new Error(`failed to run npm pack: ${name}`);
error.result = result;
@@ -118,9 +118,9 @@ function computeTarballHash(name) {
const files = getPackList(name);
files.sort();
// Compute the hash for each file
const packageRoot = path_1.getPackagePath(name);
const packageRoot = (0, path_1.getPackagePath)(name);
const hashes = files.reduce((accum, filename) => {
let content = fs_1.default.readFileSync(path_1.resolve(packageRoot, filename));
let content = fs_1.default.readFileSync((0, path_1.resolve)(packageRoot, filename));
// The package.json includes the hash, so we need to nix it to get a consistent hash
if (filename === "package.json") {
const info = JSON.parse(content.toString());
@@ -128,10 +128,10 @@ function computeTarballHash(name) {
delete info.tarballHash;
content = Buffer.from(JSON.stringify(info, null, 2));
}
accum[filename] = utils_1.sha256(content);
accum[filename] = (0, utils_1.sha256)(content);
return accum;
}, {});
return utils_1.sha256(Buffer.from("{" + files.map((filename) => {
return (0, utils_1.sha256)(Buffer.from("{" + files.map((filename) => {
return `${JSON.stringify(filename)}:"${hashes[filename]}"`;
}).join(",") + "}"));
}

View File

@@ -98,7 +98,7 @@ function _getPrompt(prompt, options, callback) {
(process.stdout).clearLine();
(process.stdout).cursorTo(0);
if (options.mask) {
process.stdout.write(prompt + utils_1.repeat(options.mask, message.length));
process.stdout.write(prompt + (0, utils_1.repeat)(options.mask, message.length));
}
else {
process.stdout.write(prompt + message);

View File

@@ -22,10 +22,10 @@ const cache = {};
function getPackageInfo(name) {
return __awaiter(this, void 0, void 0, function* () {
// Convert dirname to package if needed
name = local_1.getPackage(name).name;
name = (0, local_1.getPackage)(name).name;
if (!cache[name]) {
try {
const result = yield geturl_1.getUrl("http:/" + "/registry.npmjs.org/" + name);
const result = yield (0, geturl_1.getUrl)("https:/\/registry.npmjs.org/" + name);
cache[name] = JSON.parse(Buffer.from(result.body).toString("utf8"));
}
catch (error) {
@@ -47,7 +47,11 @@ function getPackage(name, version) {
if (version == null) {
const versions = Object.keys(infos.versions);
versions.sort(semver_1.default.compare);
version = versions.pop();
// HACK: So v5 continues working while v6 is managed by reticulate
version = "6.0.0";
while (version.indexOf("beta") >= 0 || semver_1.default.gte(version, "6.0.0")) {
version = versions.pop();
}
}
const info = infos.versions[version];
return {
@@ -66,12 +70,12 @@ exports.getPackage = getPackage;
function publish(path, manifest, options) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield libnpmpublish_1.publish(path, manifest, options);
yield (0, libnpmpublish_1.publish)(path, manifest, options);
}
catch (error) {
// We need an OTP
if (error.code === "EOTP") {
const otp = yield log_1.getPrompt(log_1.colorify.bold("Enter OTP: "));
const otp = yield (0, log_1.getPrompt)(log_1.colorify.bold("Enter OTP: "));
options.otp = otp.replace(" ", "");
// Retry with the new OTP
return yield publish(path, manifest, options);

View File

@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.isEthers = exports.getPackageJsonPath = exports.getDirname = exports.getPackagePath = exports.packages = exports.dirnames = exports.dirs = exports.resolve = exports.root = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = require("path");
exports.root = path_1.resolve(__dirname, "../../../");
exports.root = (0, path_1.resolve)(__dirname, "../../../");
function resolve(...args) {
args.unshift(exports.root);
return path_1.resolve.apply(null, args);
@@ -23,8 +23,8 @@ exports.dirnames = Object.freeze(fs_1.default.readdirSync(exports.dirs.packages)
return (dirname[0] !== ".");
}));
const packageLookup = exports.dirnames.reduce((accum, dirname) => {
const packagePath = path_1.resolve(exports.dirs.packages, dirname);
const packageJsonPath = path_1.resolve(packagePath, "package.json");
const packagePath = (0, path_1.resolve)(exports.dirs.packages, dirname);
const packageJsonPath = (0, path_1.resolve)(packagePath, "package.json");
const info = JSON.parse(fs_1.default.readFileSync(packageJsonPath).toString());
const packageName = info.name;
const version = info.version;

View File

@@ -10,7 +10,7 @@ function run(progname, args, currentWorkingDirectory) {
if (currentWorkingDirectory) {
options.cwd = currentWorkingDirectory;
}
const child = child_process_1.spawnSync(progname, args, options);
const child = (0, child_process_1.spawnSync)(progname, args, options);
const result = {
_stderr: child.stderr,
stderr: (child.stderr.toString() || null),

View File

@@ -28,7 +28,7 @@ function repeat(char, length) {
}
exports.repeat = repeat;
function sha256(content) {
const hasher = crypto_1.createHash("sha256");
const hasher = (0, crypto_1.createHash)("sha256");
hasher.update(content);
return "0x" + hasher.digest("hex");
}
@@ -43,7 +43,7 @@ function sortRecords(record) {
}
exports.sortRecords = sortRecords;
function atomicWrite(path, value) {
const tmp = path_1.resolve(__dirname, "../../../.atomic-tmp");
const tmp = (0, path_1.resolve)(__dirname, "../../../.atomic-tmp");
fs_1.default.writeFileSync(tmp, value);
fs_1.default.renameSync(tmp, path);
}
@@ -96,7 +96,7 @@ function mkdir(path) {
break;
}
dirs.push(path);
path = path_1.dirname(path);
path = (0, path_1.dirname)(path);
}
while (dirs.length) {
fs_1.default.mkdirSync(dirs.pop());

View File

@@ -52,7 +52,7 @@ async function alias(name: string): Promise<void> {
if (replace) {
inputFilename = replace;
transform = function(content: string) {
content = content.replace(/(\/\/# sourceMappingURL=)(.*)$/g, (all, prefix, mapFilename) => {
content = content.replace(/^(\/\/# sourceMappingURL=)(.*)$/mg, (all, prefix, mapFilename) => {
return prefix + filename + ".map";
});
return content;
@@ -132,7 +132,7 @@ async function alias(name: string): Promise<void> {
console.log(colorify.bold(`Aliasing Node ESM to Browser ESM...`));
const dirnames = getOrdered(true);
for (let i = 0; i < dirnames.length; i++) {
//if (dirnames[i] !== "base64") { continue; }
//if (dirnames[i] !== "signing-key") { continue; }
await alias(dirnames[i]);
}
})();

View File

@@ -0,0 +1,16 @@
/*
import { dirnames, getPackage } from "../local";
import { colorify } from "../log";
const dirname = process.argv[2];
if (dirname == null) {
console.log("Usage: peg-version DIRNAME");
process.exit(1);
}
(async function(dirname) {
const { name, version } = getPackage(dirname);
console.log(colorify.bold(`Pegging ${ name } to ${ version }...`));
})(dirname);
*/

View File

@@ -13,18 +13,18 @@ const Words = fs.readFileSync("/usr/share/dict/words").toString().split("\n").re
`
// Words missing from the dictionary
accessing addresses aligned autofill called cancelled changed censored
clamping compiled computed configured consumed creating decoded decoding
accessing addresses aligned autofill avatar called cancelled changed censored
clamping compiled computed configured consumed contained creating decoded decoding
decreased decrypt decrypted decrypting deployed deploying deprecated detected
discontinued earliest email enabled encoded encoder encoding encrypt
encrypted encrypting entries euro exceeded existing expected
discontinued earliest email emitted enabled encoded encoder encoding encountered
encrypt encrypted encrypting entries euro exceeded existing expected
expired failed fetches formatted formatting funding generated
hardened has highly ignoring implemented implementer imported including instantiate
joined keyword labelled larger lookup matches mined modified modifies multi
named needed nested neutered numeric offline optimizer overriding owned packed
padded parsed parsing passed payload placeholder processing properties prototyping reached
recommended recovered redacted remaining replaced required reverted
serializes shared signed signing skipped stored supported tagging targetted
recommended recovered recursively redacted remaining replaced repriced required reverted
serializes shared signed signing skipped stats stored supported tagging targetted
throttled transactions typed uninstall unstake unsubscribe untyped
using verifies verifying website
@@ -32,7 +32,7 @@ using verifies verifying website
bech BIP BIP39 BIP44 btc bzz crypto eip etc hashes hmac icap
keccak ltc namehash ripemd RLP scrypt secp sha xdai
blockhash
blockhash bnb bnbt ethprice matic txlist
bitcoin ethereum finney gwei kwei mwei satoshi szabo wei weth
@@ -47,15 +47,15 @@ ABIEncoder testcase numberish Wordlist
// Common Code Strings
abi addr api app arg arrayify asm backend basex bigint bignumber bn byte
bytecode callback calldata charset checksum ciphertext cli codepoint
bytecode callback calldata ccip charset checksum ciphertext cli codepoint
commify config
contenthash ctr ctrl debug dd dklen eexist encseed eof eq ethaddr
contenthash ctr ctrl debug dd dklen eexist encseed eof eq erc ethaddr
ethseed ethers eval exec filename func gz gzip hid http https hw iv
info init ipc json kdf kdfparams labelhash lang lib mm multihash nfc
nfkc nfd nfkd nodehash notok nowait nullish oob opcode pbkdf pc plugin
info init ipc json kdf kdfparams labelhash lang lib metadata mm multihash nfc
nfkc nfd nfkd nodehash notok nowait nullish offchain oob opcode org pbkdf pc plugin
pragma pre prf recid repl rpc sighash topichash solc stdin stdout subclasses
subnode timeout todo txt typeof ufixed utc utf util url urlencoded uuid vm
vs websocket wikipedia www wx xe xpriv xpub xx yyyy zlib
vs websocket wikipedia wildcard wildcards www wx xe xpriv xpub xx yyyy zlib
// AbiV2
abiv
@@ -63,13 +63,14 @@ abiv
// Query parameters
apikey asc endblock startblock
alchemyapi Cloudflare Etherscan INFURA IPFS MetaMask Nodesmith
alchemyapi ankr arbitrum Cloudflare com Etherscan INFURA IPFS IPNS MetaMask Nodesmith
Trezor ledgerhq axic bitcoinjs browserify easyseed ethereumjs
goerli homestead kotti kovan mainnet morden mordor rinkeby
ropsten testnet lb
goerli homestead kotti kovan mainnet morden mordor rinkeby kintsugi
ropsten testnet lb maticmum
// Demo words
args foo eth foo foobar ll localhost passwd ricmoo tx xxx yna
brantly ricmoose
// nameprep tags
ALCat BiDi LCat nameprep

View File

@@ -79,7 +79,7 @@ async function _getUrl(href: string, options?: Options): Promise<GetUrlResponse>
if (options == null) { options = { }; }
// @TODO: Once we drop support for node 8, we can pass the href
// firectly into request and skip adding the components
// directly into request and skip adding the components
// to this request object
const url = parse(href);

View File

@@ -15,7 +15,7 @@ async function getPackageInfo(name: string): Promise<any> {
if (!cache[name]) {
try {
const result = await getUrl("http:/" + "/registry.npmjs.org/" + name);
const result = await getUrl("https:/\/registry.npmjs.org/" + name);
cache[name] = JSON.parse(Buffer.from(result.body).toString("utf8"));
} catch (error) {
if (error.status === 404) { return null; }
@@ -32,7 +32,12 @@ export async function getPackage(name: string, version?: string): Promise<Packag
if (version == null) {
const versions = Object.keys(infos.versions);
versions.sort(semver.compare);
version = versions.pop();
// HACK: So v5 continues working while v6 is managed by reticulate
version = "6.0.0";
while (version.indexOf("beta") >= 0 || semver.gte(version, "6.0.0")) {
version = versions.pop();
}
}
const info = infos.versions[version];

3185
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -65,22 +65,22 @@
"@types/node": "^12.7.4",
"@types/semver": "^7.3.4",
"aes-js": "3.0.0",
"aws-sdk": "2.137.0",
"aws-sdk": "2.1039.0",
"diff": "4.0.1",
"flatworm": "0.0.2-beta.5",
"flatworm": "0.0.2-beta.7",
"jison": "0.4.18",
"karma": "5.2.3",
"karma": "6.3.17",
"karma-chrome-launcher": "3.1.0",
"karma-mocha": "2.0.1",
"libnpmpublish": "3.0.1",
"mocha": "^7.1.1",
"mocha": "^9.1.3",
"nyc": "15.1.0",
"rollup": "2.33.2",
"rollup-plugin-node-polyfills": "0.2.1",
"rollup-plugin-sourcemaps": "0.6.3",
"scrypt-js": "3.0.1",
"semver": "^5.6.0",
"typescript": "4.2.2",
"typescript": "4.4.4",
"uglify-es": "3.3.9"
},
"dependencies": {
@@ -92,13 +92,13 @@
"@types/mocha": "^5.2.0",
"aes-js": "3.0.0",
"bech32": "1.1.4",
"bn.js": "^4.4.0",
"bn.js": "^4.11.9",
"elliptic": "6.5.4",
"hash.js": "1.1.3",
"js-sha3": "0.5.7",
"hash.js": "1.1.7",
"js-sha3": "0.8.0",
"scrypt-js": "3.0.1",
"solc": "0.7.1",
"tiny-inflate": "1.0.3",
"ws": "7.2.3"
"ws": "7.4.6"
}
}

View File

@@ -1,2 +1,2 @@
export declare const version = "abi/5.1.0";
export declare const version = "abi/5.6.1";
//# sourceMappingURL=_version.d.ts.map

View File

@@ -1,2 +1,2 @@
export const version = "abi/5.1.0";
export const version = "abi/5.6.1";
//# sourceMappingURL=_version.js.map

Some files were not shown because too many files have changed in this diff Show More