From a23903637728bae6328d7be49f96df7e77e92149 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Wed, 9 Oct 2024 17:19:18 +0200 Subject: [PATCH 1/9] replace ethers 5.7 dependency with @metamask/utils and ethereum-cryptography --- package-lock.json | 714 ++++++++++++++++++------------------------- package.json | 7 +- src/bytes.ts | 10 +- src/core.test.ts | 5 +- src/core.ts | 6 +- src/hashes.ts | 12 +- src/simple.test.ts | 7 +- src/simple.ts | 4 +- src/standard.test.ts | 6 +- 9 files changed, 338 insertions(+), 433 deletions(-) diff --git a/package-lock.json b/package-lock.json index a297841..017d00e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,9 @@ "version": "1.0.7", "license": "MIT", "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0" + "@metamask/abi-utils": "^2.0.4", + "@metamask/utils": "^9.3.0", + "ethereum-cryptography": "^3.0.0" }, "devDependencies": { "@fast-check/ava": "^1.2.1", @@ -113,378 +112,167 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/common": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-3.2.0.tgz", + "integrity": "sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==", "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" + "@ethereumjs/util": "^8.1.0", + "crc-32": "^1.2.0" } }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" + "node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/tx": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-4.2.0.tgz", + "integrity": "sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==", "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" + "@ethereumjs/common": "^3.2.0", + "@ethereumjs/rlp": "^4.0.1", + "@ethereumjs/util": "^8.1.0", + "ethereum-cryptography": "^2.0.0" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/tx/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dependencies": { - "@ethersproject/bytes": "^5.7.0" + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "bn.js": "^5.2.1" + "node_modules/@ethereumjs/tx/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/tx/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", "dependencies": { - "@ethersproject/logger": "^5.7.0" + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/tx/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", "dependencies": { - "@ethersproject/bignumber": "^5.7.0" + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/tx/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "js-sha3": "0.8.0" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, - "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ] - }, - "node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", "dependencies": { - "@ethersproject/logger": "^5.7.0" + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/util/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dependencies": { - "@ethersproject/logger": "^5.7.0" + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/util/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "bn.js": "^5.2.1", - "elliptic": "6.5.4", - "hash.js": "1.1.7" + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/util/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, "node_modules/@fast-check/ava": { @@ -731,6 +519,81 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@metamask/abi-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@metamask/abi-utils/-/abi-utils-2.0.4.tgz", + "integrity": "sha512-StnIgUB75x7a7AgUhiaUZDpCsqGp7VkNnZh2XivXkJ6mPkE83U8ARGQj5MbRis7VJY8BC5V1AbB1fjdh0hupPQ==", + "dependencies": { + "@metamask/superstruct": "^3.1.0", + "@metamask/utils": "^9.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/superstruct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@metamask/superstruct/-/superstruct-3.1.0.tgz", + "integrity": "sha512-N08M56HdOgBfRKkrgCMZvQppkZGcArEop3kixNEtVbJKm6P9Cfg0YkI6X0s1g78sNrj2fWUwvJADdZuzJgFttA==", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/utils": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-9.3.0.tgz", + "integrity": "sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==", + "dependencies": { + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.1.0", + "@noble/hashes": "^1.3.1", + "@scure/base": "^1.1.3", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "pony-cause": "^2.1.10", + "semver": "^7.5.4", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@noble/ciphers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.0.0.tgz", + "integrity": "sha512-wH5EHOmLi0rEazphPbecAzmjd12I6/Yv/SiHdkA9LSycsQk7RuuTp7am5/o62qYr0RScE7Pc9icXGBbsr6cesA==", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/curves": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.6.0.tgz", + "integrity": "sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==", + "dependencies": { + "@noble/hashes": "1.5.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", + "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -801,6 +664,39 @@ "node": ">= 8.0.0" } }, + "node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.5.0.tgz", + "integrity": "sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==", + "dependencies": { + "@noble/curves": "~1.6.0", + "@noble/hashes": "~1.5.0", + "@scure/base": "~1.1.7" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.4.0.tgz", + "integrity": "sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==", + "dependencies": { + "@noble/hashes": "~1.5.0", + "@scure/base": "~1.1.8" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@sindresorhus/merge-streams": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", @@ -837,6 +733,14 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -849,6 +753,11 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, "node_modules/@types/node": { "version": "20.10.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz", @@ -1521,11 +1430,6 @@ "integrity": "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==", "dev": true }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1548,11 +1452,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" - }, "node_modules/c8": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz", @@ -1838,6 +1737,17 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -1886,7 +1796,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -1902,8 +1811,7 @@ "node_modules/debug/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/deep-is": { "version": "0.1.4", @@ -1965,25 +1873,6 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, "node_modules/emittery": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/emittery/-/emittery-1.0.3.tgz", @@ -2238,6 +2127,22 @@ "node": ">=0.10.0" } }, + "node_modules/ethereum-cryptography": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-3.0.0.tgz", + "integrity": "sha512-Ij7U9OgVZc4MAui8BttPCEaWUrAXy+eo2IbVfIxZyfzfFxMQrbIWXRUbrsRBqRrIhJ75T8P+KQRKpKTaG0Du8Q==", + "dependencies": { + "@noble/ciphers": "1.0.0", + "@noble/curves": "1.6.0", + "@noble/hashes": "1.5.0", + "@scure/bip32": "1.5.0", + "@scure/bip39": "1.4.0" + }, + "engines": { + "node": "^14.21.3 || >=16", + "npm": ">=9" + } + }, "node_modules/fast-check": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.15.0.tgz", @@ -2619,25 +2524,6 @@ "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", "dev": true }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -2734,7 +2620,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/irregular-plurals": { "version": "3.5.0", @@ -2868,11 +2755,6 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" - }, "node_modules/js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -2977,7 +2859,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -3069,6 +2950,11 @@ "node": ">= 8" } }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==" + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -3094,16 +2980,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3458,6 +3334,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/pony-cause": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-2.1.11.tgz", + "integrity": "sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3747,7 +3631,6 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -4266,6 +4149,18 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -4423,8 +4318,7 @@ "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/yargs": { "version": "16.2.0", diff --git a/package.json b/package.json index 389c57d..f009b3f 100644 --- a/package.json +++ b/package.json @@ -26,10 +26,9 @@ "author": "Francisco Giordano ", "license": "MIT", "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0" + "@metamask/abi-utils": "^2.0.4", + "@metamask/utils": "^9.3.0", + "ethereum-cryptography": "^3.0.0" }, "devDependencies": { "@fast-check/ava": "^1.2.1", diff --git a/src/bytes.ts b/src/bytes.ts index 938c013..c7c8c48 100644 --- a/src/bytes.ts +++ b/src/bytes.ts @@ -1,7 +1,11 @@ -import type { BytesLike } from '@ethersproject/bytes'; -type HexString = string; +import type { BytesLike } from '@metamask/utils'; +type HexString = `0x${string}`; -import { arrayify as toBytes, hexlify as toHex, concat } from '@ethersproject/bytes'; +import { + createBytes as toBytes, + createHex as toHex, + concatBytes as concat, +} from '@metamask/utils'; function compare(a: BytesLike, b: BytesLike): number { const diff = BigInt(toHex(a)) - BigInt(toHex(b)); diff --git a/src/core.test.ts b/src/core.test.ts index 53d8f4c..abfc389 100644 --- a/src/core.test.ts +++ b/src/core.test.ts @@ -1,5 +1,4 @@ import { test, testProp, fc } from '@fast-check/ava'; -import { HashZero as zero } from '@ethersproject/constants'; import { makeMerkleTree, getProof, @@ -9,9 +8,11 @@ import { isValidMerkleTree, renderMerkleTree, } from './core'; -import { toHex } from './bytes'; +import { HexString, toHex } from './bytes'; import { InvalidArgumentError, InvariantError } from './utils/errors'; +const zero: HexString = '0x0000000000000000000000000000000000000000000000000000000000000000'; + const leaf = fc.uint8Array({ minLength: 32, maxLength: 32 }); const leaves = fc.array(leaf, { minLength: 1 }); const leavesAndIndex = leaves.chain(xs => fc.tuple(fc.constant(xs), fc.nat({ max: xs.length - 1 }))); diff --git a/src/core.ts b/src/core.ts index c02d267..3754348 100644 --- a/src/core.ts +++ b/src/core.ts @@ -36,7 +36,7 @@ export function makeMerkleTree(leaves: BytesLike[], nodeHash: NodeHash = standar export function getProof(tree: BytesLike[], index: number): HexString[] { checkLeafNode(tree, index); - const proof = []; + const proof: HexString[] = []; while (index > 0) { proof.push(toHex(tree[siblingIndex(index)]!)); index = parentIndex(index); @@ -67,7 +67,7 @@ export function getMultiProof(tree: BytesLike[], indices: number[]): MultiProof< ); const stack = Array.from(indices); // copy - const proof = []; + const proof: HexString[] = []; const proofFlags = []; while (stack.length > 0 && stack[0]! > 0) { @@ -145,7 +145,7 @@ export function isValidMerkleTree(tree: BytesLike[], nodeHash: NodeHash = standa return tree.length > 0; } -export function renderMerkleTree(tree: BytesLike[]): HexString { +export function renderMerkleTree(tree: BytesLike[]): string { validateArgument(tree.length !== 0, 'Expected non-zero number of nodes'); const stack: [number, number[]][] = [[0, []]]; diff --git a/src/hashes.ts b/src/hashes.ts index fcda8b6..5e83628 100644 --- a/src/hashes.ts +++ b/src/hashes.ts @@ -1,12 +1,16 @@ -import { defaultAbiCoder } from '@ethersproject/abi'; -import { keccak256 } from '@ethersproject/keccak256'; -import { BytesLike, HexString, concat, compare } from './bytes'; +import { encode } from '@metamask/abi-utils'; +import { keccak256 as _keccak256 } from "ethereum-cryptography/keccak.js"; +import { BytesLike, HexString, toHex, toBytes, concat, compare } from './bytes'; export type LeafHash = (leaf: T) => HexString; export type NodeHash = (left: BytesLike, right: BytesLike) => HexString; + +export function keccak256(input: BytesLike): HexString { + return toHex(_keccak256(toBytes(input))); +} export function standardLeafHash(types: string[], value: T): HexString { - return keccak256(keccak256(defaultAbiCoder.encode(types, value))); + return keccak256(keccak256(encode(types, value))); } export function standardNodeHash(a: BytesLike, b: BytesLike): HexString { diff --git a/src/simple.test.ts b/src/simple.test.ts index 5bfb64c..fbcddac 100644 --- a/src/simple.test.ts +++ b/src/simple.test.ts @@ -1,10 +1,11 @@ import { test, testProp, fc } from '@fast-check/ava'; -import { HashZero as zero } from '@ethersproject/constants'; -import { keccak256 } from '@ethersproject/keccak256'; import { SimpleMerkleTree } from './simple'; import { BytesLike, HexString, concat, compare, toHex } from './bytes'; +import { keccak256 } from './hashes'; import { InvalidArgumentError, InvariantError } from './utils/errors'; +const zero: HexString = '0x0000000000000000000000000000000000000000000000000000000000000000'; + fc.configureGlobal({ numRuns: process.env.CI ? 5000 : 100 }); const reverseNodeHash = (a: BytesLike, b: BytesLike): HexString => keccak256(concat([a, b].sort(compare).reverse())); @@ -149,7 +150,7 @@ testProp('reject loading dump with wrong node hash', [fc.array(leaf, { minLength test('reject invalid leaf size', t => { const invalidLeaf = '0x000000000000000000000000000000000000000000000000000000000000000000'; t.throws(() => SimpleMerkleTree.of([invalidLeaf]), { - message: `incorrect data length (argument=null, value="${invalidLeaf}", code=INVALID_ARGUMENT, version=abi/5.7.0)`, + message: 'Unable to encode value: Expected a value of length 32, but received a value of length 33.', }); }); diff --git a/src/simple.ts b/src/simple.ts index ff1d550..861d6f2 100644 --- a/src/simple.ts +++ b/src/simple.ts @@ -1,4 +1,4 @@ -import { defaultAbiCoder } from '@ethersproject/abi'; +import { encode } from '@metamask/abi-utils'; import { BytesLike, HexString, toHex } from './bytes'; import { MultiProof, processProof, processMultiProof } from './core'; import { MerkleTreeData, MerkleTreeImpl } from './merkletree'; @@ -16,7 +16,7 @@ export interface SimpleMerkleTreeOptions extends MerkleTreeOptions { } export function formatLeaf(value: BytesLike): HexString { - return defaultAbiCoder.encode(['bytes32'], [value]); + return toHex(encode(['bytes32'], [value])); } export class SimpleMerkleTree extends MerkleTreeImpl { diff --git a/src/standard.test.ts b/src/standard.test.ts index 6d7f404..64f0177 100644 --- a/src/standard.test.ts +++ b/src/standard.test.ts @@ -1,9 +1,11 @@ import { test, testProp, fc } from '@fast-check/ava'; -import { HashZero as zero } from '@ethersproject/constants'; -import { keccak256 } from '@ethersproject/keccak256'; import { StandardMerkleTree } from './standard'; +import { HexString } from './bytes'; +import { keccak256 } from './hashes'; import { InvalidArgumentError, InvariantError } from './utils/errors'; +const zero: HexString = '0x0000000000000000000000000000000000000000000000000000000000000000'; + fc.configureGlobal({ numRuns: process.env.CI ? 5000 : 100 }); const leafEncoding = ['uint256', 'string[]']; From 8ae80a2e034f6515fce215bc437ac03c540d7f96 Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Wed, 9 Oct 2024 17:20:48 +0200 Subject: [PATCH 2/9] fix lint --- src/bytes.ts | 6 +----- src/hashes.ts | 3 +-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/bytes.ts b/src/bytes.ts index c7c8c48..b35961a 100644 --- a/src/bytes.ts +++ b/src/bytes.ts @@ -1,11 +1,7 @@ import type { BytesLike } from '@metamask/utils'; type HexString = `0x${string}`; -import { - createBytes as toBytes, - createHex as toHex, - concatBytes as concat, -} from '@metamask/utils'; +import { createBytes as toBytes, createHex as toHex, concatBytes as concat } from '@metamask/utils'; function compare(a: BytesLike, b: BytesLike): number { const diff = BigInt(toHex(a)) - BigInt(toHex(b)); diff --git a/src/hashes.ts b/src/hashes.ts index 5e83628..594c499 100644 --- a/src/hashes.ts +++ b/src/hashes.ts @@ -1,11 +1,10 @@ import { encode } from '@metamask/abi-utils'; -import { keccak256 as _keccak256 } from "ethereum-cryptography/keccak.js"; +import { keccak256 as _keccak256 } from 'ethereum-cryptography/keccak.js'; import { BytesLike, HexString, toHex, toBytes, concat, compare } from './bytes'; export type LeafHash = (leaf: T) => HexString; export type NodeHash = (left: BytesLike, right: BytesLike) => HexString; - export function keccak256(input: BytesLike): HexString { return toHex(_keccak256(toBytes(input))); } From 3c246f721dad594ed63236692d2b7936c9e4e49d Mon Sep 17 00:00:00 2001 From: Hadrien Croubois Date: Wed, 9 Oct 2024 17:32:24 +0200 Subject: [PATCH 3/9] Update hashes.ts --- src/hashes.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hashes.ts b/src/hashes.ts index 594c499..754a491 100644 --- a/src/hashes.ts +++ b/src/hashes.ts @@ -8,6 +8,7 @@ export type NodeHash = (left: BytesLike, right: BytesLike) => HexString; export function keccak256(input: BytesLike): HexString { return toHex(_keccak256(toBytes(input))); } + export function standardLeafHash(types: string[], value: T): HexString { return keccak256(keccak256(encode(types, value))); } From dae516dffee50b4d9bf8fdd89dfbf53bf0609b9b Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Sat, 2 Nov 2024 12:03:47 -0300 Subject: [PATCH 4/9] ensure backwards compatibility of type signatures --- src/bytes.ts | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/bytes.ts b/src/bytes.ts index b35961a..17a66ce 100644 --- a/src/bytes.ts +++ b/src/bytes.ts @@ -1,12 +1,33 @@ -import type { BytesLike } from '@metamask/utils'; -type HexString = `0x${string}`; +type Bytes = Uint8Array; +type BytesLike = ArrayLike | string; +type HexString = string; -import { createBytes as toBytes, createHex as toHex, concatBytes as concat } from '@metamask/utils'; +import { createBytes, createHex, concatBytes, type BytesLike as StrictBytesLike } from '@metamask/utils'; + +function toBytes(value: BytesLike): Bytes { + if (Array.isArray(value)) { + return createBytes(new Uint8Array(value)); + } else { + return createBytes(value as StrictBytesLike); + } +} + +function toHex(value: BytesLike): `0x${string}` { + if (Array.isArray(value)) { + return createHex(new Uint8Array(value)); + } else { + return createHex(value as StrictBytesLike); + } +} + +function concat(values: BytesLike[]): Bytes { + return concatBytes(values.map(toBytes)); +} function compare(a: BytesLike, b: BytesLike): number { const diff = BigInt(toHex(a)) - BigInt(toHex(b)); return diff > 0 ? 1 : diff < 0 ? -1 : 0; } -export type { HexString, BytesLike }; +export type { HexString, BytesLike, Bytes }; export { toBytes, toHex, concat, compare }; From 6d8567c8a1ac802634e0702f5c35fb23f597db0b Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Sat, 2 Nov 2024 12:05:15 -0300 Subject: [PATCH 5/9] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30fd571..85c715d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.0.8 + +- Remove dependencies with advisories. + ## 1.0.7 - Added `SimpleMerkleTree` class that supports `bytes32` leaves with no extra hashing. From 4b00bc28f82e9f9507e7577f6278908cee28ac61 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Sat, 2 Nov 2024 12:21:04 -0300 Subject: [PATCH 6/9] remove metamask/utils --- package.json | 1 - src/bytes.ts | 25 +++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index f009b3f..aaa8cca 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,6 @@ "license": "MIT", "dependencies": { "@metamask/abi-utils": "^2.0.4", - "@metamask/utils": "^9.3.0", "ethereum-cryptography": "^3.0.0" }, "devDependencies": { diff --git a/src/bytes.ts b/src/bytes.ts index 17a66ce..eac41c5 100644 --- a/src/bytes.ts +++ b/src/bytes.ts @@ -1,27 +1,32 @@ type Bytes = Uint8Array; -type BytesLike = ArrayLike | string; +type BytesLike = readonly number[] | Uint8Array | string; type HexString = string; -import { createBytes, createHex, concatBytes, type BytesLike as StrictBytesLike } from '@metamask/utils'; +import { hexToBytes, bytesToHex, concatBytes } from 'ethereum-cryptography/utils'; function toBytes(value: BytesLike): Bytes { - if (Array.isArray(value)) { - return createBytes(new Uint8Array(value)); + if (value instanceof Uint8Array) { + return value; + } else if (typeof value === 'string') { + return hexToBytes(value); } else { - return createBytes(value as StrictBytesLike); + return new Uint8Array(value); } } -function toHex(value: BytesLike): `0x${string}` { - if (Array.isArray(value)) { - return createHex(new Uint8Array(value)); +function toHex(value: BytesLike): string { + if (typeof value === 'string') { + hexToBytes(value); // assert hex string + return value; + } else if (value instanceof Uint8Array) { + return bytesToHex(value); } else { - return createHex(value as StrictBytesLike); + return bytesToHex(new Uint8Array(value)); } } function concat(values: BytesLike[]): Bytes { - return concatBytes(values.map(toBytes)); + return concatBytes(...values.map(toBytes)); } function compare(a: BytesLike, b: BytesLike): number { From c25898fb2b231cefda6b5d2d04225ac16bc6e252 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Sat, 2 Nov 2024 12:22:34 -0300 Subject: [PATCH 7/9] fix hex strings --- src/bytes.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bytes.ts b/src/bytes.ts index eac41c5..75992e5 100644 --- a/src/bytes.ts +++ b/src/bytes.ts @@ -19,9 +19,9 @@ function toHex(value: BytesLike): string { hexToBytes(value); // assert hex string return value; } else if (value instanceof Uint8Array) { - return bytesToHex(value); + return '0x' + bytesToHex(value); } else { - return bytesToHex(new Uint8Array(value)); + return '0x' + bytesToHex(new Uint8Array(value)); } } From 151be1d2335e57404a2d56add7489cae81faa3d3 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Sat, 2 Nov 2024 12:32:21 -0300 Subject: [PATCH 8/9] cleanup --- src/bytes.ts | 4 ++-- src/core.ts | 2 +- src/hashes.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bytes.ts b/src/bytes.ts index 75992e5..53700e4 100644 --- a/src/bytes.ts +++ b/src/bytes.ts @@ -14,10 +14,10 @@ function toBytes(value: BytesLike): Bytes { } } -function toHex(value: BytesLike): string { +function toHex(value: BytesLike): HexString { if (typeof value === 'string') { hexToBytes(value); // assert hex string - return value; + return value.replace(/^(0x)?/, '0x'); } else if (value instanceof Uint8Array) { return '0x' + bytesToHex(value); } else { diff --git a/src/core.ts b/src/core.ts index 3754348..4717b15 100644 --- a/src/core.ts +++ b/src/core.ts @@ -145,7 +145,7 @@ export function isValidMerkleTree(tree: BytesLike[], nodeHash: NodeHash = standa return tree.length > 0; } -export function renderMerkleTree(tree: BytesLike[]): string { +export function renderMerkleTree(tree: BytesLike[]): HexString { validateArgument(tree.length !== 0, 'Expected non-zero number of nodes'); const stack: [number, number[]][] = [[0, []]]; diff --git a/src/hashes.ts b/src/hashes.ts index 754a491..57c1021 100644 --- a/src/hashes.ts +++ b/src/hashes.ts @@ -1,5 +1,5 @@ import { encode } from '@metamask/abi-utils'; -import { keccak256 as _keccak256 } from 'ethereum-cryptography/keccak.js'; +import { keccak256 as _keccak256 } from 'ethereum-cryptography/keccak'; import { BytesLike, HexString, toHex, toBytes, concat, compare } from './bytes'; export type LeafHash = (leaf: T) => HexString; From 3eee926cbad94bb764905492a0948be9bb4e4ab0 Mon Sep 17 00:00:00 2001 From: Francisco Giordano Date: Sat, 2 Nov 2024 12:43:16 -0300 Subject: [PATCH 9/9] test --- src/bytes.test.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/bytes.test.ts diff --git a/src/bytes.test.ts b/src/bytes.test.ts new file mode 100644 index 0000000..b49ae30 --- /dev/null +++ b/src/bytes.test.ts @@ -0,0 +1,25 @@ +import test from 'ava'; + +import * as bytes from './bytes'; + +test('toBytes', t => { + const empty = Uint8Array.of(); + t.deepEqual(bytes.toBytes('0x'), empty); + t.deepEqual(bytes.toBytes([]), empty); + + const onetwothree = Uint8Array.of(1, 2, 3); + t.deepEqual(bytes.toBytes('0x010203'), onetwothree); + t.deepEqual(bytes.toBytes('010203'), onetwothree); + t.deepEqual(bytes.toBytes([1, 2, 3]), onetwothree); + t.deepEqual(bytes.toBytes(Uint8Array.of(1, 2, 3)), onetwothree); +}); + +test('toHex', t => { + t.is(bytes.toHex('0x'), '0x'); + t.is(bytes.toHex([]), '0x'); + + t.is(bytes.toHex('0x010203'), '0x010203'); + t.is(bytes.toHex('010203'), '0x010203'); + t.is(bytes.toHex([1, 2, 3]), '0x010203'); + t.is(bytes.toHex(Uint8Array.of(1, 2, 3)), '0x010203'); +});