From 0db5207b6e3e9360d1fa7992c7ba37340dcd80a7 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 15:51:25 +0200 Subject: [PATCH 01/42] chore: bump keyring API to v2 and update module resolution --- packages/bitcoin-wallet-snap/package.json | 11 +- packages/bitcoin-wallet-snap/tsconfig.json | 4 +- yarn.lock | 318 +++++++++++++++++++-- 3 files changed, 307 insertions(+), 26 deletions(-) diff --git a/packages/bitcoin-wallet-snap/package.json b/packages/bitcoin-wallet-snap/package.json index a3ea13a1..16862c9c 100644 --- a/packages/bitcoin-wallet-snap/package.json +++ b/packages/bitcoin-wallet-snap/package.json @@ -59,12 +59,13 @@ "@metamask/auto-changelog": "^6.1.0", "@metamask/bitcoindevkit": "^0.1.13", "@metamask/key-tree": "^10.1.1", - "@metamask/keyring-api": "^22.0.0", - "@metamask/keyring-snap-sdk": "^8.0.0", + "@metamask/keyring-api": "^23.5.0", + "@metamask/keyring-snap-sdk": "^9.2.0", "@metamask/slip44": "^4.2.0", - "@metamask/snaps-cli": "^8.3.0", - "@metamask/snaps-jest": "^9.8.0", - "@metamask/snaps-sdk": "^11.0.0", + "@metamask/snaps-cli": "^8.4.1", + "@metamask/snaps-jest": "^10.2.0", + "@metamask/snaps-sdk": "^11.2.0", + "@metamask/superstruct": "^3.4.1", "@metamask/utils": "^11.9.0", "bip322-js": "^3.0.0", "concurrently": "^10.0.3", diff --git a/packages/bitcoin-wallet-snap/tsconfig.json b/packages/bitcoin-wallet-snap/tsconfig.json index 6aeb6e95..6b93f13f 100644 --- a/packages/bitcoin-wallet-snap/tsconfig.json +++ b/packages/bitcoin-wallet-snap/tsconfig.json @@ -10,8 +10,8 @@ "noErrorTruncation": true, "noUncheckedIndexedAccess": true, "skipLibCheck": true, - "module": "CommonJS", - "moduleResolution": "node", + "module": "ESNext", + "moduleResolution": "bundler", "types": ["jest"] }, "include": ["**/*.ts", "**/*.tsx", "locales/*.json"] diff --git a/yarn.lock b/yarn.lock index 598c6c87..fdc7dc73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1667,6 +1667,26 @@ __metadata: languageName: node linkType: hard +"@metamask/analytics-controller@npm:^1.1.1": + version: 1.2.1 + resolution: "@metamask/analytics-controller@npm:1.2.1" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/utils": "npm:^11.11.0" + lodash: "npm:^4.17.21" + uuid: "npm:^8.3.2" + checksum: 10/378bdfe9663c532587fc397f0e80368d02a51b443b0af89ef7c0b78dd158ad59531415a2ad26673bfde1d302954655561e00fa16d41e3099f67fd3a5bdec3d04 + languageName: node + linkType: hard + +"@metamask/api-specs@npm:^0.15.0": + version: 0.15.0 + resolution: "@metamask/api-specs@npm:0.15.0" + checksum: 10/3ebc586d690c6e9746e01b7194765efac59332dece3a3fd2b347d08d3392de937b334641147b338f3278720ab1ccb69f0ff79f21753cd346c6c0eaedaf3408ed + languageName: node + linkType: hard + "@metamask/approval-controller@npm:^8.0.0": version: 8.0.0 resolution: "@metamask/approval-controller@npm:8.0.0" @@ -1693,6 +1713,19 @@ __metadata: languageName: node linkType: hard +"@metamask/approval-controller@npm:^9.0.2": + version: 9.0.2 + resolution: "@metamask/approval-controller@npm:9.0.2" + dependencies: + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/utils": "npm:^11.9.0" + nanoid: "npm:^3.3.8" + checksum: 10/f27d75901a1a8367a8972b30ebb097a063282c8eb40f3188a6255ed1e043313085de6d5feb9300660366d4d93c822ebe6b37219978806db0492c4fed761d3c6a + languageName: node + linkType: hard + "@metamask/auto-changelog@npm:^6.1.0, @metamask/auto-changelog@npm:^6.1.1": version: 6.1.1 resolution: "@metamask/auto-changelog@npm:6.1.1" @@ -1735,12 +1768,13 @@ __metadata: "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/bitcoindevkit": "npm:^0.1.13" "@metamask/key-tree": "npm:^10.1.1" - "@metamask/keyring-api": "npm:^22.0.0" - "@metamask/keyring-snap-sdk": "npm:^8.0.0" + "@metamask/keyring-api": "npm:^23.5.0" + "@metamask/keyring-snap-sdk": "npm:^9.2.0" "@metamask/slip44": "npm:^4.2.0" - "@metamask/snaps-cli": "npm:^8.3.0" - "@metamask/snaps-jest": "npm:^9.8.0" - "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-cli": "npm:^8.4.1" + "@metamask/snaps-jest": "npm:^10.2.0" + "@metamask/snaps-sdk": "npm:^11.2.0" + "@metamask/superstruct": "npm:^3.4.1" "@metamask/utils": "npm:^11.9.0" bip322-js: "npm:^3.0.0" concurrently: "npm:^10.0.3" @@ -1773,6 +1807,20 @@ __metadata: languageName: node linkType: hard +"@metamask/chain-agnostic-permission@npm:^1.6.2": + version: 1.7.0 + resolution: "@metamask/chain-agnostic-permission@npm:1.7.0" + dependencies: + "@metamask/api-specs": "npm:^0.15.0" + "@metamask/controller-utils": "npm:^12.3.0" + "@metamask/permission-controller": "npm:^13.1.1" + "@metamask/rpc-errors": "npm:^7.0.2" + "@metamask/utils": "npm:^11.11.0" + lodash: "npm:^4.17.21" + checksum: 10/25de22b86057c64828b12c4424770c7a4668ca7eb54186e06fb4c8a5f56d1d1e625686f7834fdfee47733e9a64d1f2213f5efef5e3488d9b541b1218da11789c + languageName: node + linkType: hard + "@metamask/connectivity-controller@npm:^0.2.0": version: 0.2.0 resolution: "@metamask/connectivity-controller@npm:0.2.0" @@ -1825,6 +1873,28 @@ __metadata: languageName: node linkType: hard +"@metamask/controller-utils@npm:^12.3.0": + version: 12.3.0 + resolution: "@metamask/controller-utils@npm:12.3.0" + dependencies: + "@ethersproject/abi": "npm:^5.7.0" + "@metamask/eth-query": "npm:^4.0.0" + "@metamask/ethjs-unit": "npm:^0.3.0" + "@metamask/utils": "npm:^11.11.0" + "@spruceid/siwe-parser": "npm:2.1.0" + "@types/bn.js": "npm:^5.1.5" + bignumber.js: "npm:^9.1.2" + bn.js: "npm:^5.2.1" + cockatiel: "npm:^3.1.2" + eth-ens-namehash: "npm:^2.0.8" + fast-deep-equal: "npm:^3.1.3" + lodash: "npm:^4.17.21" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/4f67b480a8522f3f89e1988631f57cfde5a7fca6c6df68f4f88e1cdcb54efccb4239befd3a8b3b7b2735479a47733b99eb059d8a0c7ddf28bdc85be4b8c04afb + languageName: node + linkType: hard + "@metamask/core-backend@npm:^6.1.1": version: 6.3.2 resolution: "@metamask/core-backend@npm:6.3.2" @@ -2353,6 +2423,18 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-api@npm:^23.5.0": + version: 23.5.0 + resolution: "@metamask/keyring-api@npm:23.5.0" + dependencies: + "@metamask/keyring-utils": "npm:^3.3.1" + "@metamask/superstruct": "npm:^3.3.0" + "@metamask/utils": "npm:^11.11.0" + bitcoin-address-validation: "npm:^2.2.3" + checksum: 10/2d8a4b378f5bad77284feb58bc7f3b64d541751527c693e43f7e4d860333bc55593e27fc5264fc908d719912b374f77dabec3f5e491bb49f72501fd2f5c43e68 + languageName: node + linkType: hard + "@metamask/keyring-controller@npm:^25.2.0": version: 25.5.0 resolution: "@metamask/keyring-controller@npm:25.5.0" @@ -2513,35 +2595,35 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-snap-sdk@npm:^8.0.0": - version: 8.0.0 - resolution: "@metamask/keyring-snap-sdk@npm:8.0.0" +"@metamask/keyring-snap-sdk@npm:^9.0.2": + version: 9.0.2 + resolution: "@metamask/keyring-snap-sdk@npm:9.0.2" dependencies: - "@metamask/keyring-utils": "npm:^3.2.0" + "@metamask/keyring-utils": "npm:^3.3.1" "@metamask/snaps-sdk": "npm:^11.0.0" "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" + "@metamask/utils": "npm:^11.11.0" webextension-polyfill: "npm:^0.12.0" peerDependencies: - "@metamask/keyring-api": ^22.0.0 + "@metamask/keyring-api": ^23.0.0 "@metamask/providers": ^19.0.0 - checksum: 10/271b4f84d214813c0312ffbbe3fb6201b66172210da4d06a155c3ddb359403ed1fa4c7afa424cd34fa9db04e3c876f30f69afb676bb7a905d392552d871ebd57 + checksum: 10/a3fa4c306b058f484042e4460f8d19d509c4725cb49c40328dd905555bae33e07e29262891500acbcb845891af3721a562a36914286fc876f37668ce63f1bee1 languageName: node linkType: hard -"@metamask/keyring-snap-sdk@npm:^9.0.2": - version: 9.0.2 - resolution: "@metamask/keyring-snap-sdk@npm:9.0.2" +"@metamask/keyring-snap-sdk@npm:^9.2.0": + version: 9.2.0 + resolution: "@metamask/keyring-snap-sdk@npm:9.2.0" dependencies: "@metamask/keyring-utils": "npm:^3.3.1" "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/superstruct": "npm:^3.1.0" + "@metamask/superstruct": "npm:^3.3.0" "@metamask/utils": "npm:^11.11.0" webextension-polyfill: "npm:^0.12.0" peerDependencies: "@metamask/keyring-api": ^23.0.0 "@metamask/providers": ^19.0.0 - checksum: 10/a3fa4c306b058f484042e4460f8d19d509c4725cb49c40328dd905555bae33e07e29262891500acbcb845891af3721a562a36914286fc876f37668ce63f1bee1 + checksum: 10/2fcce104e314f9dcea3125741d50875c26b4b9d0241f66568e513e221abd121af88f6842c2a459f7984d9147158936c58ae9936561d703429fbc4d2eccd9611c languageName: node linkType: hard @@ -2594,6 +2676,17 @@ __metadata: languageName: node linkType: hard +"@metamask/messenger@npm:^2.0.0": + version: 2.0.0 + resolution: "@metamask/messenger@npm:2.0.0" + dependencies: + "@metamask/utils": "npm:^11.11.0" + peerDependencies: + typescript: ">=5.0.0" + checksum: 10/c387511edd89db73b774f631fb4bb382c9254af2dd7f80f9bd45f776e618cf90f653cc0e9744b1bf491f71f99c8318b16e8230a847f619a4fca655ea3f6a08e1 + languageName: node + linkType: hard + "@metamask/metamask-eth-abis@npm:^3.1.1": version: 3.1.1 resolution: "@metamask/metamask-eth-abis@npm:3.1.1" @@ -2870,14 +2963,14 @@ __metadata: languageName: node linkType: hard -"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.3.0, @metamask/slip44@npm:^4.4.0": +"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.3.0, @metamask/slip44@npm:^4.4.0, @metamask/slip44@npm:^4.5.0": version: 4.5.0 resolution: "@metamask/slip44@npm:4.5.0" checksum: 10/8450d4f5afa98e8f57c67a39f12aa413888c423505f22c05a3dc181be223f7742db017f54a99852acc3826abe74b22bf7247bccd78b810e509321c075e67516f languageName: node linkType: hard -"@metamask/snaps-cli@npm:^8.3.0": +"@metamask/snaps-cli@npm:^8.3.0, @metamask/snaps-cli@npm:^8.4.1": version: 8.4.1 resolution: "@metamask/snaps-cli@npm:8.4.1" dependencies: @@ -3016,6 +3109,50 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-controllers@npm:^21.0.0": + version: 21.0.0 + resolution: "@metamask/snaps-controllers@npm:21.0.0" + dependencies: + "@metamask/analytics-controller": "npm:^1.1.1" + "@metamask/approval-controller": "npm:^9.0.2" + "@metamask/base-controller": "npm:^9.1.0" + "@metamask/json-rpc-engine": "npm:^10.5.0" + "@metamask/json-rpc-middleware-stream": "npm:^8.0.8" + "@metamask/key-tree": "npm:^10.1.1" + "@metamask/messenger": "npm:^1.2.0" + "@metamask/object-multiplex": "npm:^2.1.0" + "@metamask/permission-controller": "npm:^13.1.1" + "@metamask/post-message-stream": "npm:^10.0.0" + "@metamask/rpc-errors": "npm:^7.0.3" + "@metamask/snaps-registry": "npm:^4.0.0" + "@metamask/snaps-rpc-methods": "npm:^17.0.0" + "@metamask/snaps-sdk": "npm:^11.1.1" + "@metamask/snaps-utils": "npm:^12.2.1" + "@metamask/storage-service": "npm:^1.0.2" + "@metamask/superstruct": "npm:^3.2.1" + "@metamask/utils": "npm:^11.11.0" + "@xstate/fsm": "npm:^2.0.0" + async-mutex: "npm:^0.5.0" + concat-stream: "npm:^2.0.0" + cron-parser: "npm:^4.5.0" + fast-deep-equal: "npm:^3.1.3" + get-npm-tarball-url: "npm:^2.0.3" + immer: "npm:^9.0.21" + luxon: "npm:^3.5.0" + nanoid: "npm:^3.3.10" + readable-stream: "npm:^3.6.2" + readable-web-to-node-stream: "npm:^3.0.2" + semver: "npm:^7.5.4" + tar-stream: "npm:^3.1.7" + peerDependencies: + "@metamask/snaps-execution-environments": ^11.1.1 + peerDependenciesMeta: + "@metamask/snaps-execution-environments": + optional: true + checksum: 10/349fa04143a181ff52f68b6c3217157e09f0821eed0f4a2898af0c2897d221faf41f734a78c65dcbaa2666904fcde4d0880a8e38ca5496fec5f24add1de24219 + languageName: node + linkType: hard + "@metamask/snaps-execution-environments@npm:^10.3.0": version: 10.4.1 resolution: "@metamask/snaps-execution-environments@npm:10.4.1" @@ -3034,6 +3171,44 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-execution-environments@npm:^11.1.1": + version: 11.2.0 + resolution: "@metamask/snaps-execution-environments@npm:11.2.0" + dependencies: + "@metamask/json-rpc-engine": "npm:^10.5.0" + "@metamask/object-multiplex": "npm:^2.1.0" + "@metamask/post-message-stream": "npm:^10.0.0" + "@metamask/providers": "npm:^22.1.1" + "@metamask/rpc-errors": "npm:^7.0.3" + "@metamask/snaps-sdk": "npm:^11.2.0" + "@metamask/snaps-utils": "npm:^12.4.0" + "@metamask/superstruct": "npm:^3.3.0" + "@metamask/utils": "npm:^11.11.0" + readable-stream: "npm:^3.6.2" + checksum: 10/531d4d73927d4e11b750d15d871450139042cf35813e4b322de82f17239297462390f338cff331e335daa9ce44eda737ff42010586aed1c40beca7df5182fe3b + languageName: node + linkType: hard + +"@metamask/snaps-jest@npm:^10.2.0": + version: 10.2.0 + resolution: "@metamask/snaps-jest@npm:10.2.0" + dependencies: + "@jest/environment": "npm:^29.5.0" + "@jest/expect": "npm:^29.5.0" + "@jest/globals": "npm:^29.5.0" + "@metamask/snaps-controllers": "npm:^21.0.0" + "@metamask/snaps-sdk": "npm:^11.2.0" + "@metamask/snaps-simulation": "npm:^4.3.0" + "@metamask/superstruct": "npm:^3.3.0" + "@metamask/utils": "npm:^11.11.0" + express: "npm:^5.1.0" + jest-environment-node: "npm:^29.5.0" + jest-matcher-utils: "npm:^29.5.0" + redux: "npm:^4.2.1" + checksum: 10/020c095b5672541ff840bf02f3e90178978fb14c2c6e35be0146748213f818975df6cce07e8ccf935875c11a38004787aebcc13f2175bda511f9ccc1c6488ca0 + languageName: node + linkType: hard + "@metamask/snaps-jest@npm:^9.8.0": version: 9.8.0 resolution: "@metamask/snaps-jest@npm:9.8.0" @@ -3100,6 +3275,23 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-rpc-methods@npm:^17.0.0, @metamask/snaps-rpc-methods@npm:^17.1.0": + version: 17.1.0 + resolution: "@metamask/snaps-rpc-methods@npm:17.1.0" + dependencies: + "@metamask/key-tree": "npm:^10.1.1" + "@metamask/permission-controller": "npm:^13.1.1" + "@metamask/rpc-errors": "npm:^7.0.3" + "@metamask/snaps-sdk": "npm:^11.2.0" + "@metamask/snaps-utils": "npm:^12.3.0" + "@metamask/superstruct": "npm:^3.3.0" + "@metamask/utils": "npm:^11.11.0" + "@noble/hashes": "npm:^1.7.1" + async-mutex: "npm:^0.5.0" + checksum: 10/0afcd10f7f45611b74845c757bf9cad49044b51bfa1cf4043690f2084ad422684405aac405abed2b1c7f314857a6d208e902204dc82055d40f3a40c49c00c81d + languageName: node + linkType: hard + "@metamask/snaps-sandbox@npm:^1.0.1": version: 1.0.1 resolution: "@metamask/snaps-sandbox@npm:1.0.1" @@ -3150,6 +3342,35 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-simulation@npm:^4.3.0": + version: 4.3.0 + resolution: "@metamask/snaps-simulation@npm:4.3.0" + dependencies: + "@metamask/chain-agnostic-permission": "npm:^1.6.2" + "@metamask/json-rpc-engine": "npm:^10.5.0" + "@metamask/json-rpc-middleware-stream": "npm:^8.0.8" + "@metamask/key-tree": "npm:^10.1.1" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/permission-controller": "npm:^13.1.1" + "@metamask/rpc-errors": "npm:^7.0.3" + "@metamask/snaps-controllers": "npm:^21.0.0" + "@metamask/snaps-execution-environments": "npm:^11.1.1" + "@metamask/snaps-rpc-methods": "npm:^17.1.0" + "@metamask/snaps-sdk": "npm:^11.2.0" + "@metamask/snaps-utils": "npm:^12.3.0" + "@metamask/superstruct": "npm:^3.3.0" + "@metamask/utils": "npm:^11.11.0" + "@reduxjs/toolkit": "npm:^1.9.5" + ethers: "npm:^6.16.0" + fast-deep-equal: "npm:^3.1.3" + immer: "npm:^9.0.21" + mime: "npm:^3.0.0" + readable-stream: "npm:^3.6.2" + redux-saga: "npm:^1.2.3" + checksum: 10/0e20af44e41a0fa35016df2a7b625f7fd5ee33158d476828d63416879f5967b47395d2fee1c5e5967963fffec0d73d976acdd2c5397dcb4aada5a2e9af1a2a77 + languageName: node + linkType: hard + "@metamask/snaps-utils@npm:^11.7.1": version: 11.7.1 resolution: "@metamask/snaps-utils@npm:11.7.1" @@ -3212,6 +3433,37 @@ __metadata: languageName: node linkType: hard +"@metamask/snaps-utils@npm:^12.2.1, @metamask/snaps-utils@npm:^12.3.0, @metamask/snaps-utils@npm:^12.4.0": + version: 12.4.0 + resolution: "@metamask/snaps-utils@npm:12.4.0" + dependencies: + "@babel/core": "npm:^7.23.2" + "@babel/types": "npm:^7.23.0" + "@metamask/key-tree": "npm:^10.1.1" + "@metamask/messenger": "npm:^2.0.0" + "@metamask/permission-controller": "npm:^13.1.1" + "@metamask/rpc-errors": "npm:^7.0.3" + "@metamask/slip44": "npm:^4.5.0" + "@metamask/snaps-registry": "npm:^4.0.0" + "@metamask/snaps-sdk": "npm:^11.2.0" + "@metamask/superstruct": "npm:^3.3.0" + "@metamask/utils": "npm:^11.11.0" + "@scure/base": "npm:^1.1.1" + chalk: "npm:^4.1.2" + cron-parser: "npm:^4.5.0" + fast-deep-equal: "npm:^3.1.3" + fast-json-stable-stringify: "npm:^2.1.0" + fast-xml-parser: "npm:^5.5.6" + luxon: "npm:^3.5.0" + marked: "npm:^12.0.1" + rfdc: "npm:^1.3.0" + semver: "npm:^7.5.4" + ses: "npm:^2.1.0" + validate-npm-package-name: "npm:^5.0.0" + checksum: 10/8b430dabbcd6aa033ced988d91f6ad91c906015c5d43ec66adb805e057bed607e8d1fefce010b767372f933089fcd048922d58c70f19b77987c26f85ffd89d93 + languageName: node + linkType: hard + "@metamask/snaps-webpack-plugin@npm:^5.1.2": version: 5.1.2 resolution: "@metamask/snaps-webpack-plugin@npm:5.1.2" @@ -3237,6 +3489,16 @@ __metadata: languageName: node linkType: hard +"@metamask/storage-service@npm:^1.0.2": + version: 1.0.2 + resolution: "@metamask/storage-service@npm:1.0.2" + dependencies: + "@metamask/messenger": "npm:^1.2.0" + "@metamask/utils": "npm:^11.9.0" + checksum: 10/dda8f1a6c63c98bbd8fa61cd5863e54f8e9801389a96efc69fd8d10011cd194370990bac5b8693c7861e23769237e617946e0304a1dc9ea4da83b8d3fb6c8942 + languageName: node + linkType: hard + "@metamask/superstruct@npm:^3.1.0, @metamask/superstruct@npm:^3.2.1": version: 3.2.1 resolution: "@metamask/superstruct@npm:3.2.1" @@ -3244,6 +3506,13 @@ __metadata: languageName: node linkType: hard +"@metamask/superstruct@npm:^3.3.0, @metamask/superstruct@npm:^3.4.1": + version: 3.4.1 + resolution: "@metamask/superstruct@npm:3.4.1" + checksum: 10/d37b5662dc9bbe0d99e06eb951167fa745829ae3abfa103423e9d8c05e8712f1451376f8479d484722e1e1c1d881732da1efddccaca8868b530a786264b903b5 + languageName: node + linkType: hard + "@metamask/swappable-obj-proxy@npm:^2.3.0": version: 2.3.0 resolution: "@metamask/swappable-obj-proxy@npm:2.3.0" @@ -11700,6 +11969,17 @@ __metadata: languageName: node linkType: hard +"ses@npm:^2.1.0": + version: 2.2.0 + resolution: "ses@npm:2.2.0" + dependencies: + "@endo/cache-map": "npm:^1.1.0" + "@endo/env-options": "npm:^1.1.11" + "@endo/immutable-arraybuffer": "npm:^1.1.2" + checksum: 10/c74889dded06a760f164aac9d69cf02b019256167fa0efd3d9c2ee1083fe1d230e41ab6aaf32266fcda9e3b8903a8ff0313cae1a63b095808fe9c15c7b33a8b9 + languageName: node + linkType: hard + "set-function-length@npm:^1.2.2": version: 1.2.2 resolution: "set-function-length@npm:1.2.2" From eac224beb341043d7c532a9349cbe5d0ce03c34c Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 15:51:33 +0200 Subject: [PATCH 02/42] feat: migrate KeyringHandler to keyring API v2 --- .../bitcoin-wallet-snap/snap.manifest.json | 20 +- .../src/handlers/KeyringHandler.ts | 574 ++++++------------ packages/bitcoin-wallet-snap/src/index.ts | 5 +- 3 files changed, 203 insertions(+), 396 deletions(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index 21ee8591..cd35b432 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -31,7 +31,25 @@ }, "initialPermissions": { "endowment:webassembly": {}, - "endowment:keyring": {}, + "endowment:keyring": { + "allowedOrigins": [], + "capabilities": { + "scopes": ["bip122:000000000019d6689c085ae165831e93"], + "privateKey": { + "exportFormats": [ + { + "encoding": "base58" + } + ] + }, + "bip44": { + "deriveIndex": true, + "deriveIndexRange": true, + "derivePath": true, + "discover": true + } + } + }, "snap_getBip32Entropy": [ { "path": ["m", "44'", "0'"], diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 1f64694a..93a66994 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -3,95 +3,62 @@ import { Amount } from '@metamask/bitcoindevkit'; import { AccountCreationType, assertCreateAccountOptionIsSupported, - BtcAccountType, - BtcScope, - CreateAccountRequestStruct, - CreateAccountsRequestStruct, - DeleteAccountRequestStruct, - DiscoverAccountsRequestStruct, - FilterAccountChainsStruct, - GetAccountBalancesRequestStruct, - GetAccountRequestStruct, - KeyringRpcMethod, - ListAccountAssetsRequestStruct, - ListAccountsRequestStruct, - ListAccountTransactionsRequestStruct, - MetaMaskOptionsStruct, - ResolveAccountAddressRequestStruct, - SetSelectedAccountsRequestStruct, - SubmitRequestRequestStruct, } from '@metamask/keyring-api'; import type { - CreateAccountOptions, - Keyring, - KeyringAccount, - KeyringResponse, Balance, + BtcScope, CaipAssetType, CaipAssetTypeOrId, + CreateAccountOptions, + KeyringAccount, + KeyringRequest, + KeyringResponse, Paginated, - Transaction, Pagination, - MetaMaskOptions, - DiscoveredAccount, - KeyringRequest, ResolvedAccountAddress, + Transaction, } from '@metamask/keyring-api'; -import type { CaipChainId, Json, JsonRpcRequest } from '@metamask/snaps-sdk'; -import { - assert, - boolean, - enums, - number, - object, - optional, - string, -} from 'superstruct'; +import type { + ExportAccountOptions, + ExportedAccount, + KeyringSnapRpc, +} from '@metamask/keyring-api/v2'; +import { SnapError } from '@metamask/snaps-sdk'; +import type { CaipChainId, JsonRpcRequest } from '@metamask/snaps-sdk'; +import { sensitive } from '@metamask/superstruct'; +import { assert, is, string } from 'superstruct'; +import { encode } from 'wif'; import { computeDisplayBalanceSats, FormatError, - InexistentMethodError, + type Logger, networkToCurrencyUnit, - Purpose, - purposeToAddressType, + type SnapClient, } from '../entities'; -import type { BitcoinAccount, Logger, SnapClient } from '../entities'; +import { NetworkStruct, networkToCaip19, scopeToNetwork } from './caip'; +import { CronMethod } from './CronHandler'; +import type { KeyringRequestHandler } from './KeyringRequestHandler'; +import { mapToKeyringAccount, mapToTransaction } from './mappings'; +import { parseDerivationPath } from './parsers'; +import { BtcWalletRequestStruct, validateSelectedAccounts } from './validation'; +import snapManifest from '../../snap.manifest.json'; import type { AccountUseCases, CreateAccountParams, } from '../use-cases/AccountUseCases'; -import { - networkToCaip19, - caipToAddressType, - scopeToNetwork, - networkToScope, - NetworkStruct, -} from './caip'; -import { CronMethod } from './CronHandler'; -import type { KeyringRequestHandler } from './KeyringRequestHandler'; -import { - mapToDiscoveredAccount, - mapToKeyringAccount, - mapToTransaction, -} from './mappings'; -import { BtcWalletRequestStruct, validateSelectedAccounts } from './validation'; - -export const CreateAccountRequest = object({ - scope: enums(Object.values(BtcScope)), - addressType: optional(enums(Object.values(BtcAccountType))), - entropySource: optional(string()), - accountNameSuggestion: optional(string()), - synchronize: optional(boolean()), - index: optional(number()), - derivationPath: optional(string()), - ...MetaMaskOptionsStruct.schema, -}); /** Maximum number of accounts to create in one internal createMany call. */ const MAX_CREATE_ACCOUNTS_PER_BATCH = 100; -export class KeyringHandler implements Keyring { +/** + * Scopes declared in the snap manifest's keyring capabilities block. + * Used to determine which networks are supported for account discovery. + */ +const SUPPORTED_SCOPES = snapManifest.initialPermissions['endowment:keyring'] + .capabilities.scopes as readonly BtcScope[]; + +export class KeyringHandler implements KeyringSnapRpc { readonly #accountsUseCases: AccountUseCases; readonly #keyringRequest: KeyringRequestHandler; @@ -116,85 +83,7 @@ export class KeyringHandler implements Keyring { this.#logger = logger; } - async route(request: JsonRpcRequest): Promise { - switch (request.method) { - case `${KeyringRpcMethod.ListAccounts}`: { - assert(request, ListAccountsRequestStruct); - return this.listAccounts(); - } - case `${KeyringRpcMethod.GetAccount}`: { - assert(request, GetAccountRequestStruct); - return this.getAccount(request.params.id); - } - case `${KeyringRpcMethod.CreateAccount}`: { - assert(request, CreateAccountRequestStruct); - return this.createAccount(request.params.options); - } - case `${KeyringRpcMethod.CreateAccounts}`: { - assert(request, CreateAccountsRequestStruct); - return this.createAccounts(request.params.options); - } - case `${KeyringRpcMethod.DiscoverAccounts}`: { - assert(request, DiscoverAccountsRequestStruct); - return this.discoverAccounts( - request.params.scopes as BtcScope[], - request.params.entropySource, - request.params.groupIndex, - ); - } - case `${KeyringRpcMethod.ListAccountTransactions}`: { - assert(request, ListAccountTransactionsRequestStruct); - return this.listAccountTransactions( - request.params.id, - request.params.pagination, - ); - } - case `${KeyringRpcMethod.ListAccountAssets}`: { - assert(request, ListAccountAssetsRequestStruct); - return this.listAccountAssets(request.params.id); - } - case `${KeyringRpcMethod.GetAccountBalances}`: { - assert(request, GetAccountBalancesRequestStruct); - return this.getAccountBalances(request.params.id); - } - case `${KeyringRpcMethod.FilterAccountChains}`: { - assert(request, FilterAccountChainsStruct); - return this.filterAccountChains( - request.params.id, - request.params.chains, - ); - } - case `${KeyringRpcMethod.DeleteAccount}`: { - assert(request, DeleteAccountRequestStruct); - await this.deleteAccount(request.params.id); - return null; - } - case `${KeyringRpcMethod.SubmitRequest}`: { - assert(request, SubmitRequestRequestStruct); - return this.submitRequest(request.params); - } - case `${KeyringRpcMethod.SetSelectedAccounts}`: { - assert(request, SetSelectedAccountsRequestStruct); - await this.setSelectedAccounts(request.params.accounts); - return null; - } - case `${KeyringRpcMethod.ResolveAccountAddress}`: { - assert(request, ResolveAccountAddressRequestStruct); - return this.resolveAccountAddress( - request.params.scope, - request.params.request, - ); - } - - default: { - throw new InexistentMethodError('Keyring method not supported', { - method: request.method, - }); - } - } - } - - async listAccounts(): Promise { + async getAccounts(): Promise { const accounts = await this.#accountsUseCases.list(); return accounts.map(mapToKeyringAccount); } @@ -204,126 +93,18 @@ export class KeyringHandler implements Keyring { return mapToKeyringAccount(account); } - async createAccount( - options: Record & MetaMaskOptions, - ): Promise { - assert(options, CreateAccountRequest); - - const traceName = 'Create Bitcoin Account'; - const traceStarted = await this.#snapClient.startTrace(traceName); - - try { - const { - metamask, - scope, - entropySource = 'm', - index, - derivationPath, - addressType, - synchronize = false, - accountNameSuggestion, - } = options; - - let resolvedIndex = derivationPath - ? this.#extractAccountIndex(derivationPath) - : index; - - let resolvedAddressType: AddressType; - if (addressType) { - // only support P2WPKH addresses for v1 - if (addressType !== BtcAccountType.P2wpkh) { - throw new FormatError( - 'Only native segwit (P2WPKH) addresses are supported', - ); - } - resolvedAddressType = caipToAddressType[addressType]; - - // if both addressType and derivationPath are provided, validate they match - if (derivationPath) { - const pathAddressType = this.#extractAddressType(derivationPath); - if (pathAddressType !== resolvedAddressType) { - throw new FormatError('Address type and derivation path mismatch'); - } - } - } else if (derivationPath) { - resolvedAddressType = this.#extractAddressType(derivationPath); - } else { - resolvedAddressType = this.#defaultAddressType; - // validate default address type is P2WPKH just to be sure - if (resolvedAddressType !== 'p2wpkh') { - throw new FormatError( - 'Only native segwit (P2WPKH) addresses are supported', - ); - } - } - - // FIXME: This if should be removed ASAP as the index should always be defined or be 0 - // The Snap automatically increasing the index per request creates significant issues - // such as: concurrency, lack of idempotency, dangling state (if MM crashes before saving the account), etc. - if (resolvedIndex === undefined || resolvedIndex === null) { - const accounts = (await this.#accountsUseCases.list()).filter( - (acc) => - acc.entropySource === entropySource && - acc.network === scopeToNetwork[scope] && - acc.addressType === resolvedAddressType, - ); - - resolvedIndex = this.#getLowestUnusedIndex(accounts); - } - - const account = await this.#accountsUseCases.create({ - network: scopeToNetwork[scope], - entropySource, - index: resolvedIndex, - addressType: resolvedAddressType, - correlationId: metamask?.correlationId, - synchronize, - accountName: accountNameSuggestion, - }); - - return mapToKeyringAccount(account); - } finally { - if (traceStarted) { - await this.#snapClient.endTrace(traceName); - } - } - } - async createAccounts( options: CreateAccountOptions, ): Promise { assertCreateAccountOptionIsSupported(options, [ + `${AccountCreationType.Bip44DerivePath}`, `${AccountCreationType.Bip44DeriveIndex}`, `${AccountCreationType.Bip44DeriveIndexRange}`, + `${AccountCreationType.Bip44Discover}`, ]); const { entropySource } = options; - const range = - options.type === AccountCreationType.Bip44DeriveIndex - ? { from: options.groupIndex, to: options.groupIndex } - : options.range; - - if ( - !Number.isSafeInteger(range.from) || - !Number.isSafeInteger(range.to) || - range.from < 0 || - range.to < 0 - ) { - throw new FormatError( - 'Account index range is invalid: from and to must be non-negative integers', - ); - } - - if (range.from > range.to) { - throw new FormatError( - 'Account index range is invalid: from must be less than or equal to to', - ); - } - - // Only P2WPKH (BIP-84) on bitcoin mainnet is supported for v1, mirroring - // the defaults used by `createAccount` when no scope is provided. - const network = scopeToNetwork[BtcScope.Mainnet]; const addressType = this.#defaultAddressType; if (addressType !== 'p2wpkh') { throw new FormatError( @@ -335,39 +116,109 @@ export class KeyringHandler implements Keyring { const traceStarted = await this.#snapClient.startTrace(traceName); try { - // `AccountUseCases.createMany` is idempotent: if an account already exists - // for the resolved derivation path, it will be returned as-is. - const accounts: BitcoinAccount[] = []; - let chunkFrom = range.from; - - while (chunkFrom <= range.to) { - const chunkTo = Math.min( - chunkFrom + MAX_CREATE_ACCOUNTS_PER_BATCH - 1, - range.to, - ); - const chunkRequests: CreateAccountParams[] = []; + if (options.type === AccountCreationType.Bip44DerivePath) { + const { index, network } = parseDerivationPath(options.derivationPath); - for (let index = chunkFrom; index <= chunkTo; index += 1) { - chunkRequests.push({ + const created = await this.#accountsUseCases.createMany([ + { network, entropySource, index, addressType, synchronize: false, + }, + ]); + + return created.map(mapToKeyringAccount); + } + + if (options.type === AccountCreationType.Bip44Discover) { + // For each supported scope, discover at this index. Accounts with + // on-chain activity are kept; those without are deleted. Returning [] + // signals end-of-discovery to the client. + const discovered: KeyringAccount[] = []; + + for (const scope of SUPPORTED_SCOPES) { + const network = scopeToNetwork[scope]; + const account = await this.#accountsUseCases.discover({ + network, + entropySource, + index: options.groupIndex, + addressType, }); + + if (account.listTransactions().length === 0) { + await this.#accountsUseCases.delete(account.id); + } else { + discovered.push(mapToKeyringAccount(account)); + } } - accounts.push( - ...(await this.#accountsUseCases.createMany(chunkRequests)), + return discovered; + } + + // Build the index range. For Bip44DeriveIndex the range is a single + // element; for Bip44DeriveIndexRange it comes from the options directly. + // At this point the discover branch has already returned, so this + // discriminant is exhaustive. + const range = + options.type === AccountCreationType.Bip44DeriveIndex + ? { from: options.groupIndex, to: options.groupIndex } + : options.range; + + if ( + !Number.isSafeInteger(range.from) || + !Number.isSafeInteger(range.to) || + range.from < 0 || + range.to < 0 + ) { + throw new FormatError( + 'Account index range is invalid: from and to must be non-negative integers', + ); + } + + if (range.from > range.to) { + throw new FormatError( + 'Account index range is invalid: from must be less than or equal to to', ); + } + + // `AccountUseCases.createMany` is idempotent: if an account already + // exists for the resolved derivation path, it will be returned as-is. + const created: KeyringAccount[] = []; + + for (const scope of SUPPORTED_SCOPES) { + const network = scopeToNetwork[scope]; + let chunkFrom = range.from; - if (chunkTo === range.to) { - break; + while (chunkFrom <= range.to) { + const chunkTo = Math.min( + chunkFrom + MAX_CREATE_ACCOUNTS_PER_BATCH - 1, + range.to, + ); + const chunkRequests: CreateAccountParams[] = []; + + for (let index = chunkFrom; index <= chunkTo; index += 1) { + chunkRequests.push({ + network, + entropySource, + index, + addressType, + synchronize: false, + }); + } + + const chunk = await this.#accountsUseCases.createMany(chunkRequests); + created.push(...chunk.map(mapToKeyringAccount)); + + chunkFrom = chunkTo + 1; } - chunkFrom = chunkTo + 1; } - return accounts.map(mapToKeyringAccount); + return created; + } catch (error: unknown) { + this.#logger.error({ error }, 'Error creating accounts batch'); + throw new SnapError(error as Error); } finally { if (traceStarted) { await this.#snapClient.endTrace(traceName); @@ -375,29 +226,58 @@ export class KeyringHandler implements Keyring { } } - async discoverAccounts( - scopes: BtcScope[], - entropySource: string, - groupIndex: number, - ): Promise { - const accounts = await Promise.all( - scopes.flatMap((scope) => - // only discover P2WPKH addresses - [BtcAccountType.P2wpkh].map(async (addressType) => - this.#accountsUseCases.discover({ - network: scopeToNetwork[scope], - entropySource, - index: groupIndex, - addressType: caipToAddressType[addressType], - }), - ), - ), + async exportAccount( + accountId: string, + options?: ExportAccountOptions, + ): Promise { + // TODO: update to `"wif"` once the accounts repo adds WIF as a named + // encoding. WIF is Base58Check (not plain base58), so we treat the current + // `"base58"` wire value as a WIF request in the meantime. + const encoding = options?.encoding ?? 'base58'; + if (encoding !== 'base58') { + throw new Error( + `Only base58 (WIF) private key export is supported, got: ${encoding}`, + ); + } + + const account = await this.#accountsUseCases.get(accountId); + + const entropy = await this.#snapClient.getPrivateEntropy( + // Export the private key for address index 0 (the primary address). + account.derivationPath.concat(['0', '0']), ); - // Return only accounts with history. - return accounts - .filter((account) => account.listTransactions().length > 0) - .map(mapToDiscoveredAccount); + if (!entropy.privateKey) { + throw new Error('Failed to get private entropy'); + } + + try { + // Private key is returned in "0x..." format; transform to WIF (Base58Check). + const wifPrivateKey = encode({ + version: account.network === 'bitcoin' ? 128 : 239, // 128 mainnet, 239 testnets + // eslint-disable-next-line no-restricted-globals + privateKey: Buffer.from(entropy.privateKey.slice(2), 'hex'), + compressed: true, + }); + + // SECURITY: use is() not assert() to avoid embedding the private key in a + // StructError message if encoding validation fails. + // TODO: replace string() with a WIF-specific struct once the accounts + // repo exports one. + if (!is(wifPrivateKey, sensitive(string()))) { + throw new Error('Derived private key failed encoding validation'); + } + + return { + type: 'private-key', + encoding, + privateKey: wifPrivateKey, + }; + } catch { + const errorMsg = 'Error exporting account'; + this.#logger.error(errorMsg); + throw new SnapError(errorMsg); + } } async getAccountBalances( @@ -416,33 +296,22 @@ export class KeyringHandler implements Keyring { }; } - async filterAccountChains(id: string, chains: string[]): Promise { - const account = await this.#accountsUseCases.get(id); - const accountChain = networkToScope[account.network]; - return chains.includes(accountChain) ? [accountChain] : []; - } - - async updateAccount(): Promise { - throw new InexistentMethodError('Method not supported.'); - } - async deleteAccount(id: string): Promise { await this.#accountsUseCases.delete(id); } - async listAccountAssets(id: string): Promise { + async getAccountAssets(id: string): Promise { const account = await this.#accountsUseCases.get(id); return [networkToCaip19[account.network]]; } - async listAccountTransactions( + async getAccountTransactions( id: string, { limit, next }: Pagination, ): Promise> { const account = await this.#accountsUseCases.get(id); const transactions = account.listTransactions(); - // Find starting index based on provided cursor let startIndex = 0; if (next) { const cursorIndex = transactions.findIndex( @@ -455,8 +324,7 @@ export class KeyringHandler implements Keyring { const hasMore = startIndex + limit < transactions.length; const nextCursor = hasMore && paginatedTxs.length > 0 - ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - paginatedTxs[paginatedTxs.length - 1]!.txid.toString() + ? (paginatedTxs[paginatedTxs.length - 1]?.txid.toString() ?? null) : null; return { @@ -478,7 +346,6 @@ export class KeyringHandler implements Keyring { allAccounts.map((acc) => acc.id), ); - // Schedule immediate background job to perform full scan await this.#snapClient.scheduleBackgroundEvent({ duration: 'PT1S', method: CronMethod.SyncSelectedAccounts, @@ -495,7 +362,7 @@ export class KeyringHandler implements Keyring { * @param scope - Request's scope (CAIP-2). * @param request - Signing request object. * @returns A Promise that resolves to the account address that must - * be used to process this signing request, or null if none candidates + * be used to process this signing request, or null if no candidates * could be found. */ async resolveAccountAddress( @@ -509,7 +376,7 @@ export class KeyringHandler implements Keyring { const requestWithoutCommonHeader = { method, params }; assert(requestWithoutCommonHeader, BtcWalletRequestStruct); - const allAccounts = await this.listAccounts(); + const allAccounts = await this.getAccounts(); const accountsWithThisScope = allAccounts.filter((account) => account.scopes.includes(scope), @@ -538,85 +405,4 @@ export class KeyringHandler implements Keyring { return null; } } - - #extractAddressType(path: string): AddressType { - const segments = path.split('/'); - if (segments.length < 4) { - throw new FormatError(`Invalid derivation path: ${path}`); - } - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const purposePart = segments[1]!; - const match = purposePart.match(/^(\d+)/u); - if (!match) { - throw new FormatError(`Invalid purpose segment: ${purposePart}`); - } - - const purpose = Number(match[1]); - if (!Object.values(Purpose).includes(purpose)) { - throw new FormatError(`Invalid BIP-purpose: ${purpose}`); - } - - // only support native segwit (BIP-84) derivation paths for now - if ((purpose as Purpose) !== Purpose.NativeSegwit) { - throw new FormatError( - `Only native segwit (BIP-84) derivation paths are supported`, - ); - } - - const addressType = purposeToAddressType[purpose as Purpose]; - if (!addressType) { - throw new FormatError(`No address-type mapping for purpose: ${purpose}`); - } - - return addressType; - } - - #extractAccountIndex(path: string): number { - const segments = path.split('/'); - if (segments.length < 4) { - throw new FormatError(`Invalid derivation path: ${path}`); - } - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const accountPart = segments[3]!; - const match = accountPart.match(/^(\d+)/u); - if (!match) { - throw new FormatError(`Invalid account index: ${accountPart}`); - } - - const index = Number(match[1]); - if (!Number.isInteger(index) || index < 0) { - throw new FormatError( - `Account index must be a non-negative integer, got: ${index}`, - ); - } - - return index; - } - - #getLowestUnusedIndex(accounts: BitcoinAccount[]): number { - if (accounts.length === 0) { - return 0; - } - - const usedIndices = accounts - .map((acc) => acc.accountIndex) - .sort((idxA, idxB) => idxA - idxB); - - let lowestUnusedIndex = 0; - - for (const usedIndex of usedIndices) { - /** - * From lower to higher, the moment we find a gap, we can use it - */ - if (usedIndex !== lowestUnusedIndex) { - break; - } - - lowestUnusedIndex += 1; - } - - return lowestUnusedIndex; - } } diff --git a/packages/bitcoin-wallet-snap/src/index.ts b/packages/bitcoin-wallet-snap/src/index.ts index 7751ca0f..3f2d1542 100644 --- a/packages/bitcoin-wallet-snap/src/index.ts +++ b/packages/bitcoin-wallet-snap/src/index.ts @@ -1,3 +1,4 @@ +import { handleKeyringRequest } from '@metamask/keyring-snap-sdk/v2'; import type { OnAssetsConversionHandler, OnAssetsLookupHandler, @@ -123,7 +124,9 @@ export const onClientRequest: OnClientRequestHandler = async ({ request }) => middleware.handle(async () => rpcHandler.route('metamask', request)); export const onKeyringRequest: OnKeyringRequestHandler = async ({ request }) => - middleware.handle(async () => keyringHandler.route(request)); + middleware.handle( + async () => (await handleKeyringRequest(keyringHandler, request)) ?? null, + ); export const onUserInput: OnUserInputHandler = async ({ id, event, context }) => middleware.handle(async () => userInputHandler.route(id, event, context)); From af4d823b93f052b60cd174349565885ae2e92464 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 15:51:38 +0200 Subject: [PATCH 03/42] feat: add parseDerivationPath for bip44:derive-path handler --- .../src/handlers/parsers.test.ts | 54 +++++++++++++++++++ .../src/handlers/parsers.ts | 50 +++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts diff --git a/packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts b/packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts new file mode 100644 index 00000000..9222859c --- /dev/null +++ b/packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts @@ -0,0 +1,54 @@ +import { FormatError } from '../entities'; +import { parseDerivationPath } from './parsers'; + +jest.mock('@metamask/bitcoindevkit', () => ({ + // eslint-disable-next-line @typescript-eslint/naming-convention + Psbt: { from_string: jest.fn() }, +})); + +describe('parseDerivationPath', () => { + describe('valid paths', () => { + it.each([ + { + path: "m/84'/0'/0'", + expected: { index: 0, network: 'bitcoin' }, + }, + { + path: "m/84'/0'/5'", + expected: { index: 5, network: 'bitcoin' }, + }, + { + path: "m/84'/1'/0'", + expected: { index: 0, network: 'regtest' }, + }, + { + path: "m/84'/1'/99'", + expected: { index: 99, network: 'regtest' }, + }, + ])('parses $path correctly', ({ path, expected }) => { + expect(parseDerivationPath(path)).toStrictEqual(expected); + }); + }); + + describe('invalid paths', () => { + it('throws for a path with fewer than 4 segments', () => { + expect(() => parseDerivationPath("m/84'/0'")).toThrow(FormatError); + }); + + it('throws for a non-BIP-84 purpose', () => { + expect(() => parseDerivationPath("m/44'/0'/0'")).toThrow(FormatError); + }); + + it('throws for an unsupported coin type', () => { + expect(() => parseDerivationPath("m/84'/60'/0'")).toThrow(FormatError); + }); + + it('throws for a non-numeric account index', () => { + expect(() => parseDerivationPath("m/84'/0'/abc'")).toThrow(FormatError); + }); + + it('throws for a negative account index', () => { + expect(() => parseDerivationPath("m/84'/0'/-1'")).toThrow(FormatError); + }); + }); +}); diff --git a/packages/bitcoin-wallet-snap/src/handlers/parsers.ts b/packages/bitcoin-wallet-snap/src/handlers/parsers.ts index 3b96a918..eb1cf62b 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/parsers.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/parsers.ts @@ -1,7 +1,57 @@ +import type { Network } from '@metamask/bitcoindevkit'; import { Psbt } from '@metamask/bitcoindevkit'; import { FormatError } from '../entities'; +type ParsedDerivationPath = { + index: number; + network: Network; +}; + +/** + * Parses and validates a BIP-44 derivation path string into its components. + * + * Only BIP-84 (native segwit) paths with coin type 0 (mainnet) or 1 (regtest) + * are accepted. + * + * @param path - A derivation path string, e.g. `m/84'/0'/2'` + * @returns The account index and network derived from the path. + * @throws {FormatError} If the path is malformed or uses an unsupported purpose or coin type. + */ +export function parseDerivationPath(path: string): ParsedDerivationPath { + const parts = path.split('/'); + if (parts.length < 4) { + throw new FormatError( + 'Invalid derivation path: expected at least 4 segments (m/purpose/coinType/accountIndex)', + ); + } + + const purpose = parts[1]?.replace("'", ''); + const coinType = parts[2]?.replace("'", ''); + const accountSegment = parts[3]?.replace("'", ''); + + if (purpose !== '84') { + throw new FormatError( + 'Only native segwit (BIP-84) derivation paths are supported', + ); + } + + if (coinType !== '0' && coinType !== '1') { + throw new FormatError( + 'Unsupported coin type: only coin type 0 (mainnet) and 1 (regtest) are supported', + ); + } + + const index = parseInt(accountSegment ?? '', 10); + if (!Number.isInteger(index) || index < 0) { + throw new FormatError( + 'Invalid derivation path: account index must be a non-negative integer', + ); + } + + return { index, network: coinType === '0' ? 'bitcoin' : 'regtest' }; +} + /** * Parses a PSBT encoded as a base64 string into a PSBT object. * From 4255e880a64c30b89b9d8f38761f9e906af532b2 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 15:51:44 +0200 Subject: [PATCH 04/42] fix: mark accounts as exportable in keyring account mapping --- packages/bitcoin-wallet-snap/src/handlers/mappings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/mappings.ts b/packages/bitcoin-wallet-snap/src/handlers/mappings.ts index 6c8131a8..e454750d 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/mappings.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/mappings.ts @@ -73,7 +73,7 @@ export function mapToKeyringAccount(account: BitcoinAccount): KeyringAccount { address: account.publicAddress.toString(), options: { entropySource: account.entropySource, // TODO: Legacy field. To be removed once multichain accounts are out. - exportable: false, + exportable: true, entropy: { type: 'mnemonic', id: account.entropySource, From ab1e7fd0209e7d7c1b0adb950b0f2df5da8cf72b Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 15:51:49 +0200 Subject: [PATCH 05/42] test: update KeyringHandler unit tests for keyring API v2 --- .../src/handlers/KeyringHandler.test.ts | 711 ++++++------------ 1 file changed, 231 insertions(+), 480 deletions(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts index c9d2658f..0603a56f 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts @@ -10,7 +10,6 @@ import type { } from '@metamask/bitcoindevkit'; import { Address } from '@metamask/bitcoindevkit'; import type { - DiscoveredAccount, KeyringAccount, KeyringResponse, Transaction as KeyringTransaction, @@ -26,26 +25,21 @@ import { mock } from 'jest-mock-extended'; import { assert } from 'superstruct'; import type { BitcoinAccount, Logger, SnapClient } from '../entities'; -import { - AccountCapability, - CurrencyUnit, - Purpose, - FormatError, -} from '../entities'; -import type { - AccountUseCases, - CreateAccountParams, -} from '../use-cases/AccountUseCases'; -import { scopeToNetwork, caipToAddressType, Caip19Asset } from './caip'; -import { KeyringHandler, CreateAccountRequest } from './KeyringHandler'; +import { AccountCapability, CurrencyUnit } from '../entities'; +import { Caip19Asset } from './caip'; +import { KeyringHandler } from './KeyringHandler'; import type { KeyringRequestHandler } from './KeyringRequestHandler'; -import { mapToDiscoveredAccount } from './mappings'; +import type { AccountUseCases } from '../use-cases/AccountUseCases'; jest.mock('superstruct', () => ({ ...jest.requireActual('superstruct'), assert: jest.fn(), })); +jest.mock('wif', () => ({ + encode: jest.fn(() => 'K1WIFprivateKeyMockValue'), +})); + // TODO: enable when this is merged: https://github.com/rustwasm/wasm-bindgen/issues/1818 /* eslint-disable @typescript-eslint/naming-convention */ jest.mock('@metamask/bitcoindevkit', () => { @@ -109,325 +103,7 @@ describe('KeyringHandler', () => { ); beforeEach(() => { - mockAccounts.create.mockResolvedValue(mockAccount); - }); - - describe('createAccount', () => { - const entropySource = 'some-source'; - const index = 1; - const correlationId = 'correlation-id'; - - // non-P2WPKH address types as we are not supporting them for v1 - // eslint-disable-next-line jest/no-disabled-tests - it.skip('respects provided params', async () => { - const options = { - scope: BtcScope.Signet, - entropySource, - index, - addressType: BtcAccountType.P2pkh, - metamask: { - correlationId, - }, - accountNameSuggestion: 'My account', - synchronize: false, - }; - const expectedCreateParams: CreateAccountParams = { - network: scopeToNetwork[BtcScope.Signet], - entropySource, - index, - addressType: 'p2pkh', - synchronize: false, - correlationId, - accountName: 'My account', - }; - - await handler.createAccount(options); - - expect(assert).toHaveBeenCalledWith(options, CreateAccountRequest); - expect(mockAccounts.create).toHaveBeenCalledWith(expectedCreateParams); - expect(mockAccounts.fullScan).not.toHaveBeenCalled(); - }); - - // only P2WPKH (BIP-84) derivation paths are now supported for v1 - // eslint-disable-next-line jest/no-disabled-tests - it.skip('extracts index from derivationPath', async () => { - const options = { - scope: BtcScope.Signet, - derivationPath: "m/44'/0'/5'/*/*", // change and address indexes can be anything - }; - const expectedCreateParams: CreateAccountParams = { - network: 'signet', - index: 5, - addressType: 'p2pkh', - entropySource: 'm', - synchronize: true, - }; - - await handler.createAccount(options); - expect(mockAccounts.create).toHaveBeenCalledWith(expectedCreateParams); - - // Test with a valid derivationPath without change and address index - await handler.createAccount({ - ...options, - derivationPath: "m/44'/0'/3'", - }); - expect(mockAccounts.create).toHaveBeenCalledWith({ - ...expectedCreateParams, - index: 3, - }); - }); - - it('auto increment index', async () => { - // We should get index 1 - mockAccounts.list.mockResolvedValue([ - mock({ - entropySource: 'entropy1', - accountIndex: 1, - addressType: 'p2wpkh', - network: 'signet', - }), - mock({ - entropySource: 'entropy2', - accountIndex: 2, - addressType: 'p2wpkh', - network: 'signet', - }), - mock({ - entropySource: 'entropy2', - accountIndex: 0, - addressType: 'p2wpkh', - network: 'signet', - }), - mock({ - entropySource: 'entropy2', - accountIndex: 3, - addressType: 'p2tr', - network: 'bitcoin', - }), - ]); - - const options = { - scope: BtcScope.Signet, - index: null, - entropySource: 'entropy2', - }; - const expectedCreateParams: CreateAccountParams = { - network: 'signet', - index: 1, - addressType: 'p2wpkh', - entropySource: 'entropy2', - synchronize: false, - }; - - await handler.createAccount(options); - - expect(mockAccounts.list).toHaveBeenCalled(); - expect(mockAccounts.create).toHaveBeenCalledWith(expectedCreateParams); - }); - - it.each([{ purpose: Purpose.NativeSegwit, addressType: 'p2wpkh' }] as { - purpose: Purpose; - addressType: AddressType; - }[])( - 'extracts P2WPKH address type from derivationPath: %s', - async ({ purpose, addressType }) => { - const options = { - scope: BtcScope.Signet, - derivationPath: `m/${purpose}'/0'/0'`, - }; - const expectedCreateParams: CreateAccountParams = { - network: 'signet', - index: 0, - addressType, - entropySource: 'm', - synchronize: false, - }; - - await handler.createAccount(options); - expect(mockAccounts.create).toHaveBeenCalledWith(expectedCreateParams); - }, - ); - - // skip non-P2WPKH address types as they are not supported on v1 - // eslint-disable-next-line jest/no-disabled-tests - it.skip.each([ - { purpose: Purpose.Legacy, addressType: 'p2pkh' }, - { purpose: Purpose.Segwit, addressType: 'p2sh' }, - { purpose: Purpose.Taproot, addressType: 'p2tr' }, - { purpose: Purpose.Multisig, addressType: 'p2wsh' }, - ] as { purpose: Purpose; addressType: AddressType }[])( - 'extracts address type from derivationPath: %s', - async ({ purpose, addressType }) => { - const options = { - scope: BtcScope.Signet, - derivationPath: `m/${purpose}'/0'/0'`, - }; - const expectedCreateParams: CreateAccountParams = { - network: 'signet', - index: 0, - addressType, - entropySource: 'm', - synchronize: true, - }; - - await handler.createAccount(options); - expect(mockAccounts.create).toHaveBeenCalledWith(expectedCreateParams); - }, - ); - - it('fails if derivationPath is invalid', async () => { - const options = { - scope: BtcScope.Signet, - derivationPath: "m/44'/0'/NaN'", - }; - - await expect(handler.createAccount(options)).rejects.toThrow( - 'Invalid account index: NaN', - ); - - await expect( - handler.createAccount({ ...options, derivationPath: "m/60'/0'/0'" }), // unknown purpose - ).rejects.toThrow('Invalid BIP-purpose: 60'); - - await expect( - handler.createAccount({ ...options, derivationPath: "m/44'/0'/-1'" }), // negative index - ).rejects.toThrow("Invalid account index: -1'"); - - await expect( - handler.createAccount({ ...options, derivationPath: "m/44'" }), // missing segments - ).rejects.toThrow("Invalid derivation path: m/44'"); - }); - - it('fails when addressType and derivationPath mismatch', async () => { - const options = { - scope: BtcScope.Signet, - addressType: BtcAccountType.P2wpkh, - derivationPath: "m/44'/0'/0'", // Legacy path (P2PKH) - }; - - // The error comes from #extractAddressType which validates the derivation path first - await expect(handler.createAccount(options)).rejects.toThrow( - new FormatError( - 'Only native segwit (BIP-84) derivation paths are supported', - ), - ); - }); - - it('succeeds when addressType and derivationPath both indicate P2WPKH', async () => { - const options = { - scope: BtcScope.Signet, - addressType: BtcAccountType.P2wpkh, - derivationPath: "m/84'/0'/5'", // Native segwit path - }; - const expectedCreateParams: CreateAccountParams = { - network: 'signet', - index: 5, - addressType: 'p2wpkh', - entropySource: 'm', - synchronize: false, - }; - - await handler.createAccount(options); - expect(mockAccounts.create).toHaveBeenCalledWith(expectedCreateParams); - }); - - it('propagates errors from createAccount', async () => { - const error = new Error('createAccount error'); - mockAccounts.create.mockRejectedValue(error); - - await expect( - handler.createAccount({ scopes: [BtcScope.Mainnet], index: 0 }), - ).rejects.toThrow(error); - expect(mockAccounts.create).toHaveBeenCalled(); - }); - - describe('tracing', () => { - const options = { - scope: BtcScope.Mainnet, - index: 0, - }; - - beforeEach(() => { - mockSnapClient.startTrace.mockResolvedValue(true); - mockSnapClient.endTrace.mockResolvedValue(undefined); - }); - - it('calls startTrace and endTrace with correct trace name', async () => { - await handler.createAccount(options); - - expect(mockSnapClient.startTrace).toHaveBeenCalledWith( - 'Create Bitcoin Account', - ); - expect(mockSnapClient.endTrace).toHaveBeenCalledWith( - 'Create Bitcoin Account', - ); - }); - - it('calls startTrace before creating account', async () => { - const callOrder: string[] = []; - mockSnapClient.startTrace.mockImplementation(async () => { - callOrder.push('startTrace'); - return true; - }); - mockAccounts.create.mockImplementation(async () => { - callOrder.push('createAccount'); - return mockAccount; - }); - - await handler.createAccount(options); - - expect(callOrder).toStrictEqual(['startTrace', 'createAccount']); - }); - - it('calls endTrace after creating account', async () => { - const callOrder: string[] = []; - mockAccounts.create.mockImplementation(async () => { - callOrder.push('createAccount'); - return mockAccount; - }); - mockSnapClient.endTrace.mockImplementation(async () => { - callOrder.push('endTrace'); - }); - - await handler.createAccount(options); - - expect(callOrder).toStrictEqual(['createAccount', 'endTrace']); - }); - - it('creates account even if startTrace fails', async () => { - mockSnapClient.startTrace.mockResolvedValue(false); - - const result = await handler.createAccount(options); - - expect(result).toBeDefined(); - expect(mockAccounts.create).toHaveBeenCalled(); - expect(mockSnapClient.startTrace).toHaveBeenCalled(); - }); - - it('calls endTrace when startTrace returns true', async () => { - mockSnapClient.startTrace.mockResolvedValue(true); - - await handler.createAccount(options); - - expect(mockSnapClient.startTrace).toHaveBeenCalledWith( - 'Create Bitcoin Account', - ); - expect(mockSnapClient.endTrace).toHaveBeenCalledWith( - 'Create Bitcoin Account', - ); - }); - - it('does not call endTrace when startTrace returns false', async () => { - mockSnapClient.startTrace.mockResolvedValue(false); - - await handler.createAccount(options); - - expect(mockSnapClient.startTrace).toHaveBeenCalledWith( - 'Create Bitcoin Account', - ); - expect(mockSnapClient.endTrace).not.toHaveBeenCalled(); - }); - }); + jest.resetAllMocks(); }); describe('createAccounts', () => { @@ -651,16 +327,96 @@ describe('KeyringHandler', () => { }); it('rejects unsupported creation types', async () => { + await expect( + handler.createAccounts({ + type: 'bip44:unknown' as AccountCreationType, + entropySource, + } as Parameters[0]), + ).rejects.toThrow(/not supported|unsupported/iu); + expect(mockAccounts.createMany).not.toHaveBeenCalled(); + }); + + it('creates an account for Bip44DerivePath on mainnet', async () => { + const bitcoinAccount = buildMockAccount(0); + mockAccounts.createMany.mockResolvedValue([bitcoinAccount]); + + const result = await handler.createAccounts({ + type: AccountCreationType.Bip44DerivePath, + derivationPath: "m/84'/0'/0'", + entropySource, + }); + + expect(mockAccounts.createMany).toHaveBeenCalledWith([ + expect.objectContaining({ network: 'bitcoin', index: 0 }), + ]); + expect(result).toHaveLength(1); + }); + + it('creates an account for Bip44DerivePath on regtest', async () => { + const bitcoinAccount = buildMockAccount(3); + mockAccounts.createMany.mockResolvedValue([bitcoinAccount]); + + const result = await handler.createAccounts({ + type: AccountCreationType.Bip44DerivePath, + derivationPath: "m/84'/1'/3'", + entropySource, + }); + + expect(mockAccounts.createMany).toHaveBeenCalledWith([ + expect.objectContaining({ network: 'regtest', index: 3 }), + ]); + expect(result).toHaveLength(1); + }); + + it('rejects Bip44DerivePath with non-BIP84 purpose', async () => { await expect( handler.createAccounts({ type: AccountCreationType.Bip44DerivePath, - derivationPath: "m/84'/0'/0'", + derivationPath: "m/44'/0'/0'", entropySource, }), - ).rejects.toThrow(/not supported|unsupported/iu); + ).rejects.toThrow(/Only native segwit \(BIP-84\)/iu); + expect(mockAccounts.createMany).not.toHaveBeenCalled(); + }); + + it('rejects Bip44DerivePath with unsupported coin type', async () => { + await expect( + handler.createAccounts({ + type: AccountCreationType.Bip44DerivePath, + derivationPath: "m/84'/2'/0'", + entropySource, + }), + ).rejects.toThrow(/Unsupported coin type/iu); expect(mockAccounts.createMany).not.toHaveBeenCalled(); }); + it.each([ + { + label: 'missing account segment', + derivationPath: "m/84'/0'" as `m/${string}`, + }, + { + label: 'non-integer index', + derivationPath: "m/84'/0'/abc'" as `m/${string}`, + }, + { + label: 'negative index', + derivationPath: "m/84'/0'/-1'" as `m/${string}`, + }, + ])( + 'rejects Bip44DerivePath with invalid account index ($label)', + async ({ derivationPath }) => { + await expect( + handler.createAccounts({ + type: AccountCreationType.Bip44DerivePath, + derivationPath, + entropySource, + }), + ).rejects.toThrow(/Invalid derivation path/iu); + expect(mockAccounts.createMany).not.toHaveBeenCalled(); + }, + ); + it('propagates errors from createMany', async () => { const error = new Error('create error'); mockAccounts.createMany.mockRejectedValue(error); @@ -674,6 +430,72 @@ describe('KeyringHandler', () => { ).rejects.toThrow(error); }); + describe('bip44:discover', () => { + const buildDiscoveredAccount = (hasTxs: boolean): BitcoinAccount => + mock({ + id: 'discovered-id', + addressType: 'p2wpkh', + network: 'bitcoin', + derivationPath: ['myEntropy', "84'", "0'", "0'"], + entropySource: 'myEntropy', + accountIndex: 0, + publicAddress: mockAddress, + capabilities: [ + AccountCapability.SignPsbt, + AccountCapability.ComputeFee, + ], + listTransactions: jest.fn().mockReturnValue(hasTxs ? [{}] : []), + }); + + it('discovers then returns the account when it has on-chain history', async () => { + mockAccounts.discover.mockResolvedValue(buildDiscoveredAccount(true)); + + const result = await handler.createAccounts({ + type: AccountCreationType.Bip44Discover, + groupIndex: 0, + entropySource, + }); + + expect(mockAccounts.discover).toHaveBeenCalledWith({ + network: 'bitcoin', + entropySource, + index: 0, + addressType: 'p2wpkh', + }); + expect(mockAccounts.delete).not.toHaveBeenCalled(); + expect(result).toHaveLength(1); + expect(result[0]?.id).toBe('discovered-id'); + }); + + it('deletes the account and returns empty array when no on-chain history', async () => { + const inactiveAccount = buildDiscoveredAccount(false); + mockAccounts.discover.mockResolvedValue(inactiveAccount); + + const result = await handler.createAccounts({ + type: AccountCreationType.Bip44Discover, + groupIndex: 0, + entropySource, + }); + + expect(mockAccounts.discover).toHaveBeenCalled(); + expect(mockAccounts.delete).toHaveBeenCalledWith(inactiveAccount.id); + expect(result).toHaveLength(0); + }); + + it('propagates errors from discover as SnapError', async () => { + const error = new Error('discover error'); + mockAccounts.discover.mockRejectedValue(error); + + await expect( + handler.createAccounts({ + type: AccountCreationType.Bip44Discover, + groupIndex: 0, + entropySource, + }), + ).rejects.toThrow('discover error'); + }); + }); + describe('tracing', () => { const options = { type: AccountCreationType.Bip44DeriveIndex as const, @@ -720,107 +542,76 @@ describe('KeyringHandler', () => { }); }); - describe('discoverAccounts', () => { - const entropySource = 'some-source'; - const groupIndex = 0; - const scopes = Object.values(BtcScope); - - it('creates, scans and returns accounts for every scope/addressType combination', async () => { - // only P2WPKH is now supported for v1 - const addressTypes = [BtcAccountType.P2wpkh]; - const totalCombinations = scopes.length * addressTypes.length; - - const expected: DiscoveredAccount[] = []; - scopes.forEach((scope) => { - addressTypes.forEach((addrType) => { - const acc = mock({ - addressType: caipToAddressType[addrType], - network: scopeToNetwork[scope], - listTransactions: jest.fn().mockReturnValue([{}]), // has history - derivationPath: ['m', "84'", "0'", "0'"], - }); - - expected.push(mapToDiscoveredAccount(acc)); - mockAccounts.discover.mockResolvedValueOnce(acc); - }); - }); + describe('exportAccount', () => { + const accountId = 'some-id'; + const fakeWif = 'K1WIFprivateKeyMockValue'; + const fakePrivateKey = + '0xdeadbeefcafe0000000000000000000000000000000000000000000000000001'; - const discovered = await handler.discoverAccounts( - scopes, - entropySource, - groupIndex, - ); + beforeEach(() => { + mockAccounts.get.mockResolvedValue(mockAccount); + mockSnapClient.getPrivateEntropy.mockResolvedValue({ + privateKey: fakePrivateKey, + } as never); + const { encode } = jest.requireMock<{ encode: jest.Mock }>('wif'); + encode.mockReturnValue(fakeWif); + }); - expect(mockAccounts.discover).toHaveBeenCalledTimes(totalCombinations); + it('exports account as WIF (base58) private key by default', async () => { + const result = await handler.exportAccount(accountId); - // validate each individual create() call arguments - scopes.forEach((scope, sIdx) => { - addressTypes.forEach((addrType, aIdx) => { - const callIdx = sIdx * addressTypes.length + aIdx; - expect(mockAccounts.discover).toHaveBeenNthCalledWith(callIdx + 1, { - network: scopeToNetwork[scope], - entropySource, - index: groupIndex, - addressType: caipToAddressType[addrType], - }); - }); + expect(mockAccounts.get).toHaveBeenCalledWith(accountId); + expect(mockSnapClient.getPrivateEntropy).toHaveBeenCalledWith( + mockAccount.derivationPath.concat(['0', '0']), + ); + expect(result).toStrictEqual({ + type: 'private-key', + encoding: 'base58', + privateKey: fakeWif, }); - - // Order is not guaranteed, so compare as sets - expect(discovered).toHaveLength(expected.length); - expect(discovered).toStrictEqual(expect.arrayContaining(expected)); }); - it('returns mix of accounts with and without history, filtering correctly', async () => { - // create mock accounts - some with history, some without - const accountWithHistory1 = mock({ - addressType: 'p2wpkh', - network: 'bitcoin', - listTransactions: jest.fn().mockReturnValue([{}, {}]), // has 2 transactions - derivationPath: ['m', "84'", "0'", "0'"], + it('exports account with explicit base58 encoding option', async () => { + const result = await handler.exportAccount(accountId, { + type: 'private-key', + encoding: 'base58', }); - const accountWithoutHistory = mock({ - addressType: 'p2wpkh', - network: 'testnet', - listTransactions: jest.fn().mockReturnValue([]), // no history - derivationPath: ['m', "84'", "1'", "0'"], - }); + expect(result.encoding).toBe('base58'); + expect(result.privateKey).toBe(fakeWif); + }); - const accountWithHistory2 = mock({ - addressType: 'p2wpkh', - network: 'signet', - listTransactions: jest.fn().mockReturnValue([{}]), // has 1 transaction - derivationPath: ['m', "84'", "1'", "0'"], - }); + it('throws for unsupported encoding', async () => { + await expect( + handler.exportAccount(accountId, { + type: 'private-key', + encoding: 'hexadecimal', + }), + ).rejects.toThrow('Only base58 (WIF) private key export is supported'); + }); - mockAccounts.discover - .mockResolvedValueOnce(accountWithHistory1) - .mockResolvedValueOnce(accountWithoutHistory) - .mockResolvedValueOnce(accountWithHistory2); + it('throws when private entropy is not available', async () => { + mockSnapClient.getPrivateEntropy.mockResolvedValue({ + privateKey: undefined, + } as never); - const discovered = await handler.discoverAccounts( - [BtcScope.Mainnet, BtcScope.Testnet, BtcScope.Signet], - entropySource, - groupIndex, + await expect(handler.exportAccount(accountId)).rejects.toThrow( + 'Failed to get private entropy', ); - - expect(mockAccounts.discover).toHaveBeenCalledTimes(3); - expect(discovered).toHaveLength(2); - expect(discovered).toStrictEqual([ - mapToDiscoveredAccount(accountWithHistory1), - mapToDiscoveredAccount(accountWithHistory2), - ]); }); - it('propagates errors from discover', async () => { - const error = new Error('discover error'); - mockAccounts.discover.mockRejectedValue(error); + it('wraps wif encoding errors in SnapError without leaking private key', async () => { + const { encode } = jest.requireMock<{ encode: jest.Mock }>('wif'); + encode.mockImplementation(() => { + throw new Error('encoding failed: privatekey=SENSITIVE'); + }); - await expect( - handler.discoverAccounts(scopes, entropySource, groupIndex), - ).rejects.toThrow(error); - expect(mockAccounts.discover).toHaveBeenCalled(); + const error = await handler + .exportAccount(accountId) + .catch((caughtError) => caughtError); + // The SnapError message must not contain the sensitive encoding error + expect(error.message).not.toContain('SENSITIVE'); + expect(error.message).toContain('exporting account'); }); }); @@ -866,7 +657,7 @@ describe('KeyringHandler', () => { id: 'myEntropy', type: 'mnemonic', }, - exportable: false, + exportable: true, }, methods: mockAccount.capabilities, }; @@ -885,7 +676,7 @@ describe('KeyringHandler', () => { }); }); - describe('listAccounts', () => { + describe('getAccounts', () => { it('lists accounts', async () => { mockAccounts.list.mockResolvedValue([mockAccount]); const expectedKeyringAccounts = [ @@ -902,13 +693,13 @@ describe('KeyringHandler', () => { id: 'myEntropy', type: 'mnemonic', }, - exportable: false, + exportable: true, }, methods: mockAccount.capabilities, }, ]; - const result = await handler.listAccounts(); + const result = await handler.getAccounts(); expect(mockAccounts.list).toHaveBeenCalled(); expect(result).toStrictEqual(expectedKeyringAccounts); }); @@ -917,43 +708,11 @@ describe('KeyringHandler', () => { const error = new Error(); mockAccounts.list.mockRejectedValue(error); - await expect(handler.listAccounts()).rejects.toThrow(error); + await expect(handler.getAccounts()).rejects.toThrow(error); expect(mockAccounts.list).toHaveBeenCalled(); }); }); - describe('filterAccountChains', () => { - it('includes chain if account network corresponds', async () => { - mockAccounts.get.mockResolvedValue(mockAccount); - - const result = await handler.filterAccountChains('some-id', [ - BtcScope.Mainnet, - ]); - expect(mockAccounts.get).toHaveBeenCalledWith('some-id'); - expect(result).toStrictEqual([BtcScope.Mainnet]); - }); - - it('does not include chain if account network does not correspond', async () => { - mockAccounts.get.mockResolvedValue(mockAccount); - - const result = await handler.filterAccountChains('some-id', [ - BtcScope.Testnet, - ]); - expect(mockAccounts.get).toHaveBeenCalledWith('some-id'); - expect(result).toStrictEqual([]); - }); - - it('propagates errors from get', async () => { - const error = new Error(); - mockAccounts.get.mockRejectedValue(error); - - await expect( - handler.filterAccountChains('some-id', [BtcScope.Mainnet]), - ).rejects.toThrow(error); - expect(mockAccounts.get).toHaveBeenCalled(); - }); - }); - describe('deleteAccount', () => { it('deletes account', async () => { await handler.deleteAccount('some-id'); @@ -969,7 +728,7 @@ describe('KeyringHandler', () => { }); }); - describe('listAccountAssets', () => { + describe('getAccountAssets', () => { it.each([ { tNetwork: 'bitcoin', caip19: Caip19Asset.Bitcoin }, { tNetwork: 'testnet', caip19: Caip19Asset.Testnet }, @@ -983,7 +742,7 @@ describe('KeyringHandler', () => { network: tNetwork, } as unknown as BitcoinAccount); - const result = await handler.listAccountAssets('some-id'); + const result = await handler.getAccountAssets('some-id'); expect(mockAccounts.get).toHaveBeenCalledWith('some-id'); expect(result).toStrictEqual([caip19]); @@ -994,12 +753,12 @@ describe('KeyringHandler', () => { const error = new Error(); mockAccounts.get.mockRejectedValue(error); - await expect(handler.listAccountAssets('some-id')).rejects.toThrow(error); + await expect(handler.getAccountAssets('some-id')).rejects.toThrow(error); expect(mockAccounts.get).toHaveBeenCalled(); }); }); - describe('listAccountTransactions', () => { + describe('getAccountTransactions', () => { const pagination = { limit: 10, next: null }; const mockAmount = mock({ @@ -1082,7 +841,7 @@ describe('KeyringHandler', () => { it('lists transactions successfully: send', async () => { const id = 'some-id'; - const result = await handler.listAccountTransactions(id, pagination); + const result = await handler.getAccountTransactions(id, pagination); expect(mockAccounts.get).toHaveBeenCalledWith(id); expect(result.data).toStrictEqual([expectedResult]); @@ -1092,7 +851,7 @@ describe('KeyringHandler', () => { const id = 'some-id'; mockAccount.isMine.mockReturnValueOnce(true); - const result = await handler.listAccountTransactions(id, pagination); + const result = await handler.getAccountTransactions(id, pagination); expect(mockAccounts.get).toHaveBeenCalledWith(id); expect(result.data).toStrictEqual([{ ...expectedResult, to: [] }]); @@ -1107,7 +866,7 @@ describe('KeyringHandler', () => { ]); mockAccount.isMine.mockReturnValueOnce(true); - const result = await handler.listAccountTransactions(id, pagination); + const result = await handler.getAccountTransactions(id, pagination); expect(mockAccounts.get).toHaveBeenCalledWith(id); expect(result.data).toStrictEqual([ @@ -1126,7 +885,7 @@ describe('KeyringHandler', () => { mockAccount.listTransactions.mockReturnValue(mockTransactions); - const result = await handler.listAccountTransactions(id, pagination); + const result = await handler.getAccountTransactions(id, pagination); expect(result.data).toHaveLength(pagination.limit); expect(result.next).toBe('txid-9'); @@ -1143,7 +902,7 @@ describe('KeyringHandler', () => { mockAccount.listTransactions.mockReturnValue(mockTransactions); - const result = await handler.listAccountTransactions(id, { + const result = await handler.getAccountTransactions(id, { ...pagination, next: 'txid-9', }); @@ -1155,14 +914,6 @@ describe('KeyringHandler', () => { }); }); - describe('updateAccount', () => { - it('throws not supported', async () => { - await expect(handler.updateAccount()).rejects.toThrow( - 'Method not supported.', - ); - }); - }); - describe('submitRequest', () => { it('calls KeyringRequestHandler', async () => { const mockRequest = mock(); @@ -1204,7 +955,7 @@ describe('KeyringHandler', () => { }; jest - .spyOn(handler, 'listAccounts') + .spyOn(handler, 'getAccounts') .mockResolvedValueOnce([mockKeyringAccount1, mockKeyringAccount2]); const result = await handler.resolveAccountAddress( @@ -1212,7 +963,7 @@ describe('KeyringHandler', () => { request, ); - expect(handler.listAccounts).toHaveBeenCalled(); + expect(handler.getAccounts).toHaveBeenCalled(); expect(result).toStrictEqual({ address: `${BtcScope.Regtest}:test123`, }); @@ -1230,7 +981,7 @@ describe('KeyringHandler', () => { }; jest - .spyOn(handler, 'listAccounts') + .spyOn(handler, 'getAccounts') .mockResolvedValue([mockKeyringAccount1, mockKeyringAccount2]); const result = await handler.resolveAccountAddress( @@ -1259,7 +1010,7 @@ describe('KeyringHandler', () => { }); jest - .spyOn(handler, 'listAccounts') + .spyOn(handler, 'getAccounts') .mockResolvedValue([accountWithDifferentScope]); const result = await handler.resolveAccountAddress( @@ -1304,7 +1055,7 @@ describe('KeyringHandler', () => { }; jest - .spyOn(handler, 'listAccounts') + .spyOn(handler, 'getAccounts') .mockResolvedValue([mockKeyringAccount1, mockKeyringAccount2]); // First assert (scope) passes, second assert (request struct) throws From 99e9dfe28f16923c1d5d0a47fd3c5e5b2b7edeea Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 15:51:53 +0200 Subject: [PATCH 06/42] test: update integration tests for keyring API v2 --- .../integration-test/client-request.test.ts | 14 +- .../integration-test/cron-sync.test.ts | 15 +- .../integration-test/keyring-request.test.ts | 73 ++---- .../integration-test/keyring.test.ts | 242 ++++++------------ 4 files changed, 117 insertions(+), 227 deletions(-) diff --git a/packages/bitcoin-wallet-snap/integration-test/client-request.test.ts b/packages/bitcoin-wallet-snap/integration-test/client-request.test.ts index 6a576dbc..f984332a 100644 --- a/packages/bitcoin-wallet-snap/integration-test/client-request.test.ts +++ b/packages/bitcoin-wallet-snap/integration-test/client-request.test.ts @@ -52,18 +52,18 @@ describe('OnClientRequestHandler', () => { const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', + method: 'keyring_createAccounts', params: { - options: { - scope: BtcScope.Regtest, - synchronize: false, - index: ACCOUNT_INDEX, - }, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, }, }); if ('result' in response.response) { - account = response.response.result as KeyringAccount; + account = ( + response.response.result as KeyringAccount[] + )[0] as KeyringAccount; createdAccountId = account.id; } diff --git a/packages/bitcoin-wallet-snap/integration-test/cron-sync.test.ts b/packages/bitcoin-wallet-snap/integration-test/cron-sync.test.ts index 273e00ff..e489c5ef 100644 --- a/packages/bitcoin-wallet-snap/integration-test/cron-sync.test.ts +++ b/packages/bitcoin-wallet-snap/integration-test/cron-sync.test.ts @@ -60,22 +60,19 @@ describe('CronHandler', () => { // create account without initial sync const createResponse = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', + method: 'keyring_createAccounts', params: { - options: { - scope: BtcScope.Regtest, - addressType: BtcAccountType.P2wpkh, - synchronize: false, - index: ACCOUNT_INDEX, - }, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, }, }); expect(createResponse.response).toBeDefined(); expect('result' in createResponse.response).toBe(true); - const account = (createResponse.response as { result: KeyringAccount }) - .result; + const account = (createResponse.response as { result: KeyringAccount[] }) + .result[0] as KeyringAccount; accountsToSync.push(account.id); diff --git a/packages/bitcoin-wallet-snap/integration-test/keyring-request.test.ts b/packages/bitcoin-wallet-snap/integration-test/keyring-request.test.ts index f777d740..b698dbe5 100644 --- a/packages/bitcoin-wallet-snap/integration-test/keyring-request.test.ts +++ b/packages/bitcoin-wallet-snap/integration-test/keyring-request.test.ts @@ -50,18 +50,18 @@ describe('KeyringRequestHandler', () => { const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', + method: 'keyring_createAccounts', params: { - options: { - scope: BtcScope.Regtest, - synchronize: false, - index: ACCOUNT_INDEX, - }, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, }, }); if ('result' in response.response) { - account = response.response.result as KeyringAccount; + account = ( + response.response.result as KeyringAccount[] + )[0] as KeyringAccount; createdAccountId = account.id; } @@ -86,9 +86,9 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32000, + code: -32603, message: - 'Invalid format: At path: params.account -- Expected a value of type `UuidV4`, but received: `"notAUUID"`', + 'At path: params.account -- Expected a value of type `UuidV4`, but received: `"notAUUID"`', stack: expect.anything(), }); }); @@ -109,14 +109,8 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32601, - data: { - account: account.id, - cause: null, - method: 'invalidMethod', - }, - message: - 'Method not implemented or not supported: Unrecognized Bitcoin account capability', + code: -32603, + message: 'Unrecognized Bitcoin account capability', stack: expect.anything(), }); }); @@ -381,12 +375,8 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32000, - message: 'Invalid format: Invalid PSBT', - data: { - cause: null, - transaction: 'notAPsbt', - }, + code: -32603, + message: 'Invalid PSBT', stack: expect.anything(), }); }); @@ -415,9 +405,9 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32000, + code: -32603, message: - 'Invalid format: At path: account -- Expected an object, but received: undefined', + 'At path: account -- Expected an object, but received: undefined', stack: expect.anything(), }); }); @@ -442,9 +432,9 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32000, + code: -32603, message: - 'Invalid format: At path: options -- Expected an object, but received: undefined', + 'At path: options -- Expected an object, but received: undefined', stack: expect.anything(), }); }); @@ -503,12 +493,8 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32000, - message: 'Invalid format: Invalid PSBT', - data: { - cause: null, - transaction: 'notAPsbt', - }, + code: -32603, + message: 'Invalid PSBT', stack: expect.anything(), }); }); @@ -567,12 +553,8 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32000, - message: 'Invalid format: Invalid PSBT', - data: { - cause: null, - transaction: 'notAPsbt', - }, + code: -32603, + message: 'Invalid PSBT', stack: expect.anything(), }); }); @@ -665,12 +647,8 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32000, - message: 'Invalid format: Invalid PSBT', - data: { - cause: null, - transaction: 'notAPsbt', - }, + code: -32603, + message: 'Invalid PSBT', stack: expect.anything(), }); }); @@ -737,9 +715,8 @@ describe('KeyringRequestHandler', () => { }); expect(response).toRespondWithError({ - code: -32602, - data: { address: 'notAnAddress', amount: '1000', cause: null }, - message: 'Validation failed: Invalid recipient', + code: -32603, + message: 'Invalid recipient', stack: expect.anything(), }); }); diff --git a/packages/bitcoin-wallet-snap/integration-test/keyring.test.ts b/packages/bitcoin-wallet-snap/integration-test/keyring.test.ts index 0908ade2..ff7e3745 100644 --- a/packages/bitcoin-wallet-snap/integration-test/keyring.test.ts +++ b/packages/bitcoin-wallet-snap/integration-test/keyring.test.ts @@ -53,61 +53,41 @@ describe('Keyring', () => { }); }); - it('discover accounts successfully', async () => { + it('creates account at explicit derivation path', async () => { const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_discoverAccounts', + method: 'keyring_createAccounts', params: { - scopes: [BtcScope.Regtest], // avoid using other networks than Regtest as real external calls will be performed - entropySource: 'm', // we don't know the real entropy source so "m" acts as the default - groupIndex: 0, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, }, }); - // We should get 1 account, the p2wpkh one of Regtest expect(response).toRespondWith([ { - type: 'bip44', - scopes: [BtcScope.Regtest], - derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, - }, - ]); - }); - - it('creates discovered account', async () => { - const response = await snap.onKeyringRequest({ - origin: ORIGIN, - method: 'keyring_createAccount', - params: { + type: BtcAccountType.P2wpkh, + id: expect.anything(), + address: TEST_ADDRESS_REGTEST, options: { - derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, - scope: BtcScope.Regtest, - synchronize: true, - }, - }, - }); - - expect(response).toRespondWith({ - type: BtcAccountType.P2wpkh, - id: expect.anything(), - address: TEST_ADDRESS_REGTEST, - options: { - entropySource: 'm', - entropy: { - type: 'mnemonic', - id: 'm', - groupIndex: ACCOUNT_INDEX, - derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, + entropySource: 'm', + entropy: { + type: 'mnemonic', + id: 'm', + groupIndex: ACCOUNT_INDEX, + derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, + }, + exportable: true, }, - exportable: false, + scopes: [BtcScope.Regtest], + methods: Object.values(AccountCapability), }, - scopes: [BtcScope.Regtest], - methods: Object.values(AccountCapability), - }); + ]); if ('result' in response.response) { - accounts[TEST_ADDRESS_REGTEST] = response.response - .result as KeyringAccount; + accounts[TEST_ADDRESS_REGTEST] = ( + response.response.result as KeyringAccount[] + )[0]!; await snap.onCronjob({ method: 'fullScanAccount', @@ -133,32 +113,41 @@ describe('Keyring', () => { ])( 'creates a P2WPKH account: %s', async ({ expectedAddress, ...requestOpts }) => { + const derivationPath = `m/${accountTypeToPurpose[requestOpts.addressType]}/${scopeToCoinType[requestOpts.scope]}/${requestOpts.index}'`; const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', - params: { options: { ...requestOpts, synchronize: false } }, + method: 'keyring_createAccounts', + params: { + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath, + }, }); - expect(response).toRespondWith({ - type: requestOpts.addressType, - id: expect.anything(), - address: expectedAddress, - options: { - entropySource: 'm', - entropy: { - type: 'mnemonic', - id: 'm', - groupIndex: requestOpts.index, - derivationPath: `m/${accountTypeToPurpose[requestOpts.addressType]}/${scopeToCoinType[requestOpts.scope]}/${requestOpts.index}'`, + expect(response).toRespondWith([ + { + type: requestOpts.addressType, + id: expect.anything(), + address: expectedAddress, + options: { + entropySource: 'm', + entropy: { + type: 'mnemonic', + id: 'm', + groupIndex: requestOpts.index, + derivationPath, + }, + exportable: true, }, - exportable: false, + scopes: [requestOpts.scope], + methods: Object.values(AccountCapability), }, - scopes: [requestOpts.scope], - methods: Object.values(AccountCapability), - }); + ]); if ('result' in response.response) { - accounts[expectedAddress] = response.response.result as KeyringAccount; + accounts[expectedAddress] = ( + response.response.result as KeyringAccount[] + )[0] as KeyringAccount; } }, ); @@ -222,7 +211,7 @@ describe('Keyring', () => { groupIndex: requestOpts.index, derivationPath: `m/${accountTypeToPurpose[requestOpts.addressType]}/${scopeToCoinType[requestOpts.scope]}/${requestOpts.index}'`, }, - exportable: false, + exportable: true, }, scopes: [requestOpts.scope], methods: Object.values(AccountCapability), @@ -237,76 +226,32 @@ describe('Keyring', () => { // Account already exists so we should get the same account const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', + method: 'keyring_createAccounts', params: { - options: { - scope: BtcScope.Regtest, - addressType: BtcAccountType.P2wpkh, - derivationPath: "m/84'/1'/0'", - }, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath: "m/84'/1'/0'", }, }); - expect(response).toRespondWith(accounts[TEST_ADDRESS_REGTEST]); + expect(response).toRespondWith([accounts[TEST_ADDRESS_REGTEST]]); }); - it('returns the same account if already exists', async () => { + it('returns the same account if already exists by index', async () => { + // Create at same path again — idempotent const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', + method: 'keyring_createAccounts', params: { - options: { - scope: BtcScope.Regtest, - addressType: BtcAccountType.P2wpkh, - index: ACCOUNT_INDEX, - }, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath: `m/84'/1'/${ACCOUNT_INDEX}'`, }, }); - expect(response).toRespondWith(accounts[TEST_ADDRESS_REGTEST]); + expect(response).toRespondWith([accounts[TEST_ADDRESS_REGTEST]]); }); - it.each([ - { - addressType: BtcAccountType.P2pkh, - scope: BtcScope.Mainnet, - expectedError: 'Only native segwit (P2WPKH) addresses are supported', - }, - { - addressType: BtcAccountType.P2sh, - scope: BtcScope.Testnet, - expectedError: 'Only native segwit (P2WPKH) addresses are supported', - }, - { - addressType: BtcAccountType.P2tr, - scope: BtcScope.Mainnet, - expectedError: 'Only native segwit (P2WPKH) addresses are supported', - }, - ])( - 'rejects creation of non-P2WPKH account: $addressType', - async ({ addressType, scope, expectedError }) => { - const response = await snap.onKeyringRequest({ - origin: ORIGIN, - method: 'keyring_createAccount', - params: { - options: { - scope, - addressType, - index: 0, - synchronize: false, - }, - }, - }); - - expect(response.response).toMatchObject({ - error: { - code: -32000, - message: `Invalid format: ${expectedError}`, - }, - }); - }, - ); - it.each([ { derivationPath: "m/44'/0'/0'", // (P2PKH) @@ -328,67 +273,39 @@ describe('Keyring', () => { async ({ derivationPath, expectedError }) => { const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', + method: 'keyring_createAccounts', params: { - options: { - scope: BtcScope.Regtest, - derivationPath, - synchronize: false, - }, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath, }, }); expect(response.response).toMatchObject({ error: { - code: -32000, - message: `Invalid format: ${expectedError}`, + code: -32603, + message: expectedError, }, }); }, ); - it('rejects creation when addressType and derivationPath mismatch', async () => { - const response = await snap.onKeyringRequest({ - origin: ORIGIN, - method: 'keyring_createAccount', - params: { - options: { - scope: BtcScope.Regtest, - addressType: BtcAccountType.P2wpkh, // Native segwit - derivationPath: "m/44'/0'/0'", // Legacy path (P2PKH) - synchronize: false, - }, - }, - }); - - expect(response.response).toMatchObject({ - error: { - code: -32000, - message: - 'Invalid format: Only native segwit (BIP-84) derivation paths are supported', - }, - }); - }); - - it('accepts creation when addressType and derivationPath both indicate P2WPKH', async () => { + it('accepts creation with BIP-84 derivation path', async () => { const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_createAccount', + method: 'keyring_createAccounts', params: { - options: { - scope: BtcScope.Regtest, - addressType: BtcAccountType.P2wpkh, - derivationPath: "m/84'/1'/10'", // Native segwit path matching P2WPKH - synchronize: false, - }, + type: 'bip44:derive-path', + entropySource: 'm', + derivationPath: "m/84'/1'/10'", }, }); expect(response.response).toHaveProperty('result'); - const account: KeyringAccount = ( - response.response as { result: KeyringAccount } - ).result; + const { result } = response.response as { result: KeyringAccount[] }; + expect(result).toHaveLength(1); + const account = result[0] as KeyringAccount; expect(account.address).toMatch(/^bcrt1/u); // Native segwit address expect((account.options.entropy as { groupIndex: number }).groupIndex).toBe( 10, @@ -419,7 +336,7 @@ describe('Keyring', () => { it('lists all accounts', async () => { const response = await snap.onKeyringRequest({ origin: ORIGIN, - method: 'keyring_listAccounts', + method: 'keyring_getAccounts', }); expect(response).toRespondWith(Object.values(accounts)); @@ -503,9 +420,8 @@ describe('Keyring', () => { }); expect(response).toRespondWithError({ - code: -32001, - message: `Resource not found: Account not found`, - data: { id, cause: null }, + code: -32603, + message: 'Account not found', stack: expect.anything(), }); }); From 006fe70bf927d4ecb917aa493f318e5922752740 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 15:51:58 +0200 Subject: [PATCH 07/42] chore: fix formatting --- packages/bitcoin-wallet-snap/scripts/populate-en-locale.js | 2 +- packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/bitcoin-wallet-snap/scripts/populate-en-locale.js b/packages/bitcoin-wallet-snap/scripts/populate-en-locale.js index e3f1ee6c..69eb821b 100644 --- a/packages/bitcoin-wallet-snap/scripts/populate-en-locale.js +++ b/packages/bitcoin-wallet-snap/scripts/populate-en-locale.js @@ -17,7 +17,7 @@ const englishLocale = { try { writeFileSync( join(__dirname, '../locales/en.json'), - JSON.stringify(englishLocale, null, 2), + `${JSON.stringify(englishLocale, null, 2)}\n`, ); console.log('[populate-en-locale] - en locale populated'); } catch (error) { diff --git a/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts b/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts index 44d1232d..02c1b61a 100644 --- a/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts +++ b/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts @@ -93,8 +93,7 @@ export class BdkAccountRepository implements BitcoinAccountRepository { async getAll(): Promise { const accounts = (await this.#snapClient.getState('accounts')) as - | SnapState['accounts'] - | null; + SnapState['accounts'] | null; if (!accounts) { return []; } From bab37ae414529b1d868fda7d341743a5fbc77107 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 16:17:29 +0200 Subject: [PATCH 08/42] docs: update changelog for keyring API v2 migration --- packages/bitcoin-wallet-snap/CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/bitcoin-wallet-snap/CHANGELOG.md b/packages/bitcoin-wallet-snap/CHANGELOG.md index 13994e80..23af9fb3 100644 --- a/packages/bitcoin-wallet-snap/CHANGELOG.md +++ b/packages/bitcoin-wallet-snap/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add support for keyring API v2, including `bip44:derive-path`, `bip44:derive-index`, `bip44:derive-index-range`, and `bip44:discover` account creation types +- Add `exportAccount` method supporting WIF (base58) private key export +- Add `parseDerivationPath` to validate and parse BIP-44 derivation paths for native segwit (BIP-84) accounts + +### Changed + +- Migrate `KeyringHandler` to implement `KeyringSnapRpc` from `@metamask/keyring-api/v2` +- Update `snap.manifest.json` to declare `derivePath` capability in the `bip44` keyring block +- Mark accounts as exportable in the keyring account mapping + ## [1.15.2] ### Fixed From e5f223f61ef5480275b2eddde78c1fb4e4abef65 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 22 Jul 2026 16:30:10 +0200 Subject: [PATCH 09/42] fix: upgrade sample-snap snaps dependencies to match bitcoin-wallet-snap and update shasum --- .../bitcoin-wallet-snap/snap.manifest.json | 2 +- packages/sample-snap/package.json | 6 +- yarn.lock | 1696 +---------------- 3 files changed, 41 insertions(+), 1663 deletions(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index cd35b432..cee65a72 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "Qta8TaWAkq4E1E/+ZWwROzSbx5/7mxAMaPCo2hV+6oU=", + "shasum": "C9X038OBAsMzCepnsYCBE/PrF1cOwBA4ZJiC95SeeQE=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/sample-snap/package.json b/packages/sample-snap/package.json index 514374f0..9578a393 100644 --- a/packages/sample-snap/package.json +++ b/packages/sample-snap/package.json @@ -46,9 +46,9 @@ "devDependencies": { "@jest/globals": "^29.5.0", "@metamask/auto-changelog": "^6.1.0", - "@metamask/snaps-cli": "^8.3.0", - "@metamask/snaps-jest": "^9.8.0", - "@metamask/snaps-sdk": "^11.0.0", + "@metamask/snaps-cli": "^8.4.1", + "@metamask/snaps-jest": "^10.2.0", + "@metamask/snaps-sdk": "^11.2.0", "@types/react": "18.2.4", "@types/react-dom": "18.2.4", "eslint": "^9.39.1", diff --git a/yarn.lock b/yarn.lock index fdc7dc73..3397059a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -795,7 +795,7 @@ __metadata: languageName: node linkType: hard -"@ethersproject/abi@npm:^5.7.0, @ethersproject/abi@npm:^5.8.0": +"@ethersproject/abi@npm:^5.7.0": version: 5.8.0 resolution: "@ethersproject/abi@npm:5.8.0" dependencies: @@ -862,16 +862,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/basex@npm:^5.8.0": - version: 5.8.0 - resolution: "@ethersproject/basex@npm:5.8.0" - dependencies: - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/properties": "npm:^5.8.0" - checksum: 10/1a8d48a9397461ea42ec43b69a15a0d13ba0b9192695713750d9d391503c55b258cca435fa78a4014d23a813053f1a471593b89c7c0d89351639a78d50a12ef2 - languageName: node - linkType: hard - "@ethersproject/bignumber@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/bignumber@npm:5.8.0" @@ -901,24 +891,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/contracts@npm:^5.7.0": - version: 5.8.0 - resolution: "@ethersproject/contracts@npm:5.8.0" - dependencies: - "@ethersproject/abi": "npm:^5.8.0" - "@ethersproject/abstract-provider": "npm:^5.8.0" - "@ethersproject/abstract-signer": "npm:^5.8.0" - "@ethersproject/address": "npm:^5.8.0" - "@ethersproject/bignumber": "npm:^5.8.0" - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/constants": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - "@ethersproject/properties": "npm:^5.8.0" - "@ethersproject/transactions": "npm:^5.8.0" - checksum: 10/839f8211f5e560f15468ae843ba316ffeacab5cebcece1eec76bc5714472ebfe3453484f283d3e46b9d3faaffef1e17cc3583cf24e01638a1fd52f69012cf8d4 - languageName: node - linkType: hard - "@ethersproject/hash@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/hash@npm:5.8.0" @@ -936,47 +908,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/hdnode@npm:^5.8.0": - version: 5.8.0 - resolution: "@ethersproject/hdnode@npm:5.8.0" - dependencies: - "@ethersproject/abstract-signer": "npm:^5.8.0" - "@ethersproject/basex": "npm:^5.8.0" - "@ethersproject/bignumber": "npm:^5.8.0" - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - "@ethersproject/pbkdf2": "npm:^5.8.0" - "@ethersproject/properties": "npm:^5.8.0" - "@ethersproject/sha2": "npm:^5.8.0" - "@ethersproject/signing-key": "npm:^5.8.0" - "@ethersproject/strings": "npm:^5.8.0" - "@ethersproject/transactions": "npm:^5.8.0" - "@ethersproject/wordlists": "npm:^5.8.0" - checksum: 10/55b35cf30f0dd40e2d5ecd4b2f005ebea82a85a440717a61d4a483074f652d2c7063e9c704272b894bfdd500f7883aa36692931c6808591f702c1da7107ebb61 - languageName: node - linkType: hard - -"@ethersproject/json-wallets@npm:^5.8.0": - version: 5.8.0 - resolution: "@ethersproject/json-wallets@npm:5.8.0" - dependencies: - "@ethersproject/abstract-signer": "npm:^5.8.0" - "@ethersproject/address": "npm:^5.8.0" - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/hdnode": "npm:^5.8.0" - "@ethersproject/keccak256": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - "@ethersproject/pbkdf2": "npm:^5.8.0" - "@ethersproject/properties": "npm:^5.8.0" - "@ethersproject/random": "npm:^5.8.0" - "@ethersproject/strings": "npm:^5.8.0" - "@ethersproject/transactions": "npm:^5.8.0" - aes-js: "npm:3.0.0" - scrypt-js: "npm:3.0.1" - checksum: 10/5cbf7e698ee7f26f54fceb672d9824b01816cd785182e638cb5cd1eaed5d80d8a4576e3cad92af46ac6d23404a806a47a72d5dee908af42322d091553a0d8da6 - languageName: node - linkType: hard - "@ethersproject/keccak256@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/keccak256@npm:5.8.0" @@ -1003,16 +934,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/pbkdf2@npm:^5.8.0": - version: 5.8.0 - resolution: "@ethersproject/pbkdf2@npm:5.8.0" - dependencies: - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/sha2": "npm:^5.8.0" - checksum: 10/203bb992eec3042256702f4c8259a37202af7b341cc6e370614cdc52541042fc3b795fb040592bd6be8b67376a798c45312ca1e6d5d179c3e8eb7431882f1fd1 - languageName: node - linkType: hard - "@ethersproject/properties@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/properties@npm:5.8.0" @@ -1022,44 +943,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/providers@npm:^5.7.0, @ethersproject/providers@npm:^5.7.2": - version: 5.8.0 - resolution: "@ethersproject/providers@npm:5.8.0" - dependencies: - "@ethersproject/abstract-provider": "npm:^5.8.0" - "@ethersproject/abstract-signer": "npm:^5.8.0" - "@ethersproject/address": "npm:^5.8.0" - "@ethersproject/base64": "npm:^5.8.0" - "@ethersproject/basex": "npm:^5.8.0" - "@ethersproject/bignumber": "npm:^5.8.0" - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/constants": "npm:^5.8.0" - "@ethersproject/hash": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - "@ethersproject/networks": "npm:^5.8.0" - "@ethersproject/properties": "npm:^5.8.0" - "@ethersproject/random": "npm:^5.8.0" - "@ethersproject/rlp": "npm:^5.8.0" - "@ethersproject/sha2": "npm:^5.8.0" - "@ethersproject/strings": "npm:^5.8.0" - "@ethersproject/transactions": "npm:^5.8.0" - "@ethersproject/web": "npm:^5.8.0" - bech32: "npm:1.1.4" - ws: "npm:8.18.0" - checksum: 10/7d40fc0abb78fc9e69b71cb560beb2a93cf1da2cf978a061031a34c0ed76c2f5936ed8c0bdb9aa1307fe5308d0159e429b83b779dbd550639a886a88d6d17817 - languageName: node - linkType: hard - -"@ethersproject/random@npm:^5.8.0": - version: 5.8.0 - resolution: "@ethersproject/random@npm:5.8.0" - dependencies: - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - checksum: 10/47c34a72c81183ac13a1b4635bb9d5cf1456e6329276f50c9e12711f404a9eb4536db824537ed05ef8839a0a358883dc3342d3ea83147b8bafeb767dc8f57e23 - languageName: node - linkType: hard - "@ethersproject/rlp@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/rlp@npm:5.8.0" @@ -1070,17 +953,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/sha2@npm:^5.8.0": - version: 5.8.0 - resolution: "@ethersproject/sha2@npm:5.8.0" - dependencies: - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - hash.js: "npm:1.1.7" - checksum: 10/ef8916e3033502476fba9358ba1993722ac3bb99e756d5681e4effa3dfa0f0bf0c29d3fa338662830660b45dd359cccb06ba40bc7b62cfd44f4a177b25829404 - languageName: node - linkType: hard - "@ethersproject/signing-key@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/signing-key@npm:5.8.0" @@ -1123,29 +995,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/wallet@npm:^5.7.0": - version: 5.8.0 - resolution: "@ethersproject/wallet@npm:5.8.0" - dependencies: - "@ethersproject/abstract-provider": "npm:^5.8.0" - "@ethersproject/abstract-signer": "npm:^5.8.0" - "@ethersproject/address": "npm:^5.8.0" - "@ethersproject/bignumber": "npm:^5.8.0" - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/hash": "npm:^5.8.0" - "@ethersproject/hdnode": "npm:^5.8.0" - "@ethersproject/json-wallets": "npm:^5.8.0" - "@ethersproject/keccak256": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - "@ethersproject/properties": "npm:^5.8.0" - "@ethersproject/random": "npm:^5.8.0" - "@ethersproject/signing-key": "npm:^5.8.0" - "@ethersproject/transactions": "npm:^5.8.0" - "@ethersproject/wordlists": "npm:^5.8.0" - checksum: 10/354c8985a74b1bb0a8ba80f374c1af882f7657716b974dda235184ee98151e30741b24f58a93c84693aa6e72a8a5c3ae62143966967f40f52f62093559388e6a - languageName: node - linkType: hard - "@ethersproject/web@npm:^5.8.0": version: 5.8.0 resolution: "@ethersproject/web@npm:5.8.0" @@ -1159,19 +1008,6 @@ __metadata: languageName: node linkType: hard -"@ethersproject/wordlists@npm:^5.8.0": - version: 5.8.0 - resolution: "@ethersproject/wordlists@npm:5.8.0" - dependencies: - "@ethersproject/bytes": "npm:^5.8.0" - "@ethersproject/hash": "npm:^5.8.0" - "@ethersproject/logger": "npm:^5.8.0" - "@ethersproject/properties": "npm:^5.8.0" - "@ethersproject/strings": "npm:^5.8.0" - checksum: 10/b8e6aa7d2195bb568847f360f6525ddc3d145404fbd4553e2e05daf4a95f58167591feb69e16e3398a28114ea85e1895fc8f5bd1c0cbf8b578123d7c1d21c32d - languageName: node - linkType: hard - "@humanfs/core@npm:^0.19.1": version: 0.19.1 resolution: "@humanfs/core@npm:0.19.1" @@ -1576,74 +1412,6 @@ __metadata: languageName: node linkType: hard -"@metamask/abi-utils@npm:^3.0.0": - version: 3.0.0 - resolution: "@metamask/abi-utils@npm:3.0.0" - dependencies: - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.0.1" - checksum: 10/068b98185148b9e185b4af4392c6a6f82f1d4b1ff60013c57679c618f37afe9030e3ccc940e1a8b690be6f62ea91115ab18b73f3c3c09f4eff1794e31ababb9b - languageName: node - linkType: hard - -"@metamask/accounts-controller@npm:^37.0.0": - version: 37.2.0 - resolution: "@metamask/accounts-controller@npm:37.2.0" - dependencies: - "@ethereumjs/util": "npm:^9.1.0" - "@metamask/base-controller": "npm:^9.0.1" - "@metamask/eth-snap-keyring": "npm:^19.0.0" - "@metamask/keyring-api": "npm:^21.6.0" - "@metamask/keyring-controller": "npm:^25.2.0" - "@metamask/keyring-internal-api": "npm:^10.0.0" - "@metamask/keyring-utils": "npm:^3.1.0" - "@metamask/messenger": "npm:^1.0.0" - "@metamask/network-controller": "npm:^30.0.1" - "@metamask/snaps-controllers": "npm:^19.0.0" - "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/snaps-utils": "npm:^12.1.2" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.9.0" - deepmerge: "npm:^4.2.2" - ethereum-cryptography: "npm:^2.1.2" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/providers": ^22.0.0 - webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 - checksum: 10/01d07434687732e08a865f26b913e4bcff429e2aab32a851b53a95b068295c97ae7c178ae4915b9ea13cb2924cca1ff3dce9232add8c84202d56d6fdc2965ea9 - languageName: node - linkType: hard - -"@metamask/accounts-controller@npm:^39.0.0": - version: 39.0.0 - resolution: "@metamask/accounts-controller@npm:39.0.0" - dependencies: - "@ethereumjs/util": "npm:^9.1.0" - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/eth-snap-keyring": "npm:^22.0.1" - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-controller": "npm:^26.0.0" - "@metamask/keyring-internal-api": "npm:^11.0.1" - "@metamask/keyring-sdk": "npm:^2.1.1" - "@metamask/keyring-utils": "npm:^3.2.1" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/network-controller": "npm:^32.0.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.9.0" - deepmerge: "npm:^4.2.2" - ethereum-cryptography: "npm:^2.1.2" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - uuid: "npm:^8.3.2" - peerDependencies: - "@metamask/providers": ^22.0.0 - webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 - checksum: 10/1cdaae1818af96e1cccfb95452a54a936299f6aadc1f8f39a5651dbe409eced0379bcd959c2e944caad3fbba91a3b7c7e4a954a8a1eb9804302bfa0336ad7ac6 - languageName: node - linkType: hard - "@metamask/action-utils@npm:^1.0.0": version: 1.1.1 resolution: "@metamask/action-utils@npm:1.1.1" @@ -1655,18 +1423,6 @@ __metadata: languageName: node linkType: hard -"@metamask/address-book-controller@npm:^7.1.2": - version: 7.1.2 - resolution: "@metamask/address-book-controller@npm:7.1.2" - dependencies: - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/controller-utils": "npm:^12.0.0" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/utils": "npm:^11.9.0" - checksum: 10/e15140418452a80d51fec783003144add72a50a4fe362377481de83c7858860f641a3cfb1575f4b802b1eb1e873b3efd03bb4183afcbee77f95c7525e05aaed4 - languageName: node - linkType: hard - "@metamask/analytics-controller@npm:^1.1.1": version: 1.2.1 resolution: "@metamask/analytics-controller@npm:1.2.1" @@ -1687,19 +1443,6 @@ __metadata: languageName: node linkType: hard -"@metamask/approval-controller@npm:^8.0.0": - version: 8.0.0 - resolution: "@metamask/approval-controller@npm:8.0.0" - dependencies: - "@metamask/base-controller": "npm:^9.0.0" - "@metamask/messenger": "npm:^0.3.0" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/utils": "npm:^11.8.1" - nanoid: "npm:^3.3.8" - checksum: 10/356fa411f2b077a31ea7565ffafaa4ecd68100ed93c26027ef4c30c55f7bf49a9f76a819bee05925756b0d4890d01a0ea0983b3b57bab3bf5b9ec2336f1a40e9 - languageName: node - linkType: hard - "@metamask/approval-controller@npm:^9.0.1": version: 9.0.1 resolution: "@metamask/approval-controller@npm:9.0.1" @@ -1749,7 +1492,7 @@ __metadata: languageName: node linkType: hard -"@metamask/base-controller@npm:^9.0.0, @metamask/base-controller@npm:^9.0.1, @metamask/base-controller@npm:^9.1.0": +"@metamask/base-controller@npm:^9.0.1, @metamask/base-controller@npm:^9.1.0": version: 9.1.0 resolution: "@metamask/base-controller@npm:9.1.0" dependencies: @@ -1798,15 +1541,6 @@ __metadata: languageName: node linkType: hard -"@metamask/browser-passworder@npm:^6.0.0": - version: 6.0.0 - resolution: "@metamask/browser-passworder@npm:6.0.0" - dependencies: - "@metamask/utils": "npm:^11.0.1" - checksum: 10/44b31729ccd52e62df27a948fbea2320a11861d6465128b1626a723fc47e25f9e3a8c3bdc09329f3f270b5d9e023107cb439cfb6961a3614c6daa58ea4524f00 - languageName: node - linkType: hard - "@metamask/chain-agnostic-permission@npm:^1.6.2": version: 1.7.0 resolution: "@metamask/chain-agnostic-permission@npm:1.7.0" @@ -1821,17 +1555,7 @@ __metadata: languageName: node linkType: hard -"@metamask/connectivity-controller@npm:^0.2.0": - version: 0.2.0 - resolution: "@metamask/connectivity-controller@npm:0.2.0" - dependencies: - "@metamask/base-controller": "npm:^9.0.1" - "@metamask/messenger": "npm:^1.0.0" - checksum: 10/586c80931341375c713aa5a474725ec88174e6e885d5f75d23b6458b734ec0e912a8c47996bea94a82f9549c9598ba982ac99aaeccac1fd92002c35a38f5397f - languageName: node - linkType: hard - -"@metamask/controller-utils@npm:^11.18.0, @metamask/controller-utils@npm:^11.19.0, @metamask/controller-utils@npm:^11.20.0": +"@metamask/controller-utils@npm:^11.19.0": version: 11.20.0 resolution: "@metamask/controller-utils@npm:11.20.0" dependencies: @@ -1852,7 +1576,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^12.0.0, @metamask/controller-utils@npm:^12.1.0": +"@metamask/controller-utils@npm:^12.0.0": version: 12.1.0 resolution: "@metamask/controller-utils@npm:12.1.0" dependencies: @@ -1895,23 +1619,6 @@ __metadata: languageName: node linkType: hard -"@metamask/core-backend@npm:^6.1.1": - version: 6.3.2 - resolution: "@metamask/core-backend@npm:6.3.2" - dependencies: - "@metamask/accounts-controller": "npm:^39.0.0" - "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/keyring-controller": "npm:^26.0.0" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/profile-sync-controller": "npm:^28.1.1" - "@metamask/utils": "npm:^11.9.0" - "@tanstack/query-core": "npm:^5.62.16" - async-mutex: "npm:^0.5.0" - uuid: "npm:^8.3.2" - checksum: 10/97965ba67fc3574b857a8f18b66450e141d3ee58afe0a2788d08e55253183692421373c0c076ae75e5763f5206eb7be1af4235d4ab480881a9b80fcec6538541 - languageName: node - linkType: hard - "@metamask/create-release-branch@npm:^4.2.1": version: 4.2.1 resolution: "@metamask/create-release-branch@npm:4.2.1" @@ -2006,93 +1713,6 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-block-tracker@npm:^15.0.1": - version: 15.0.1 - resolution: "@metamask/eth-block-tracker@npm:15.0.1" - dependencies: - "@metamask/eth-json-rpc-provider": "npm:^6.0.0" - "@metamask/safe-event-emitter": "npm:^3.0.0" - "@metamask/utils": "npm:^11.9.0" - json-rpc-random-id: "npm:^1.0.1" - checksum: 10/8c0e0f5bde00fb40aa240fc562c29d0ce84156402132705d387c95453c6f265b3b738c9b649510771965d8b5b8036c2bdc6406142ff634383bf60df3741bdbfe - languageName: node - linkType: hard - -"@metamask/eth-hd-keyring@npm:^14.1.1": - version: 14.1.1 - resolution: "@metamask/eth-hd-keyring@npm:14.1.1" - dependencies: - "@ethereumjs/tx": "npm:^5.4.0" - "@ethereumjs/util": "npm:^9.1.0" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/key-tree": "npm:^10.0.2" - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-sdk": "npm:^2.0.2" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/scure-bip39": "npm:^2.1.1" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.11.0" - ethereum-cryptography: "npm:^2.2.1" - checksum: 10/f711742682a77990310272013523595822e29bfb61980828d1460ab8af888d7c344bb50f04d2611d801d63438e31532d3d66698c595b4fd3ad512b02056b7234 - languageName: node - linkType: hard - -"@metamask/eth-json-rpc-infura@npm:^10.3.0": - version: 10.3.0 - resolution: "@metamask/eth-json-rpc-infura@npm:10.3.0" - dependencies: - "@metamask/eth-json-rpc-provider": "npm:^5.0.0" - "@metamask/json-rpc-engine": "npm:^10.1.0" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/utils": "npm:^11.0.1" - checksum: 10/164c9ef1285a0895db668f3949d9258df721d348c857c4337b964f147000221d69fd103851c6483d8dd6bfe851c76cc5299155a8818eac0b92334469c40ccaef - languageName: node - linkType: hard - -"@metamask/eth-json-rpc-middleware@npm:^23.1.3": - version: 23.1.3 - resolution: "@metamask/eth-json-rpc-middleware@npm:23.1.3" - dependencies: - "@metamask/eth-block-tracker": "npm:^15.0.1" - "@metamask/eth-json-rpc-provider": "npm:^6.0.1" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/json-rpc-engine": "npm:^10.2.4" - "@metamask/message-manager": "npm:^14.1.1" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.9.0" - klona: "npm:^2.0.6" - pify: "npm:^5.0.0" - safe-stable-stringify: "npm:^2.4.3" - checksum: 10/aee4866afa78cb21aed9daa1211ee9a3515cb9549d9b325d5904b8769fb54790296224b58ec3555eb34a7125d2fd5180d6cba915bb1ca8dc3f04bf75e502c6b0 - languageName: node - linkType: hard - -"@metamask/eth-json-rpc-provider@npm:^5.0.0": - version: 5.0.1 - resolution: "@metamask/eth-json-rpc-provider@npm:5.0.1" - dependencies: - "@metamask/json-rpc-engine": "npm:^10.1.1" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/safe-event-emitter": "npm:^3.0.0" - "@metamask/utils": "npm:^11.8.1" - uuid: "npm:^8.3.2" - checksum: 10/1b874b04a0d8c53edf7036c8dbf4403101afba548cfd3bfc1fa969b893905a72e44c36a17b60ccb202f14a8e012b08031b4649c2ee77d604dc84dfbc6c88b812 - languageName: node - linkType: hard - -"@metamask/eth-json-rpc-provider@npm:^6.0.0, @metamask/eth-json-rpc-provider@npm:^6.0.1": - version: 6.0.1 - resolution: "@metamask/eth-json-rpc-provider@npm:6.0.1" - dependencies: - "@metamask/json-rpc-engine": "npm:^10.2.4" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/utils": "npm:^11.9.0" - nanoid: "npm:^3.3.8" - checksum: 10/06078a9e43b02f35387a3ccfe09733c7eeac2a732dee1f1be53254fc05719e230776b8512b13702a178fb692088fc7da46f727c5064550d65f51ac59d44f9d83 - languageName: node - linkType: hard - "@metamask/eth-query@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/eth-query@npm:4.0.0" @@ -2103,192 +1723,15 @@ __metadata: languageName: node linkType: hard -"@metamask/eth-sig-util@npm:^8.2.0": - version: 8.2.0 - resolution: "@metamask/eth-sig-util@npm:8.2.0" +"@metamask/ethjs-unit@npm:^0.3.0": + version: 0.3.0 + resolution: "@metamask/ethjs-unit@npm:0.3.0" dependencies: - "@ethereumjs/rlp": "npm:^4.0.1" - "@ethereumjs/util": "npm:^8.1.0" - "@metamask/abi-utils": "npm:^3.0.0" - "@metamask/utils": "npm:^11.0.1" - "@scure/base": "npm:~1.1.3" - ethereum-cryptography: "npm:^2.1.2" - tweetnacl: "npm:^1.0.3" - checksum: 10/385df1ec541116e1bd725a1df1a519996bad167f99d1b2677126e398cdfda6fc3f03d2ff8f1ca523966bc0aae3ea92a9050953a45d5a7711f4128aacf9242bfc - languageName: node - linkType: hard - -"@metamask/eth-simple-keyring@npm:^12.0.2": - version: 12.0.2 - resolution: "@metamask/eth-simple-keyring@npm:12.0.2" - dependencies: - "@ethereumjs/util": "npm:^9.1.0" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-sdk": "npm:^2.0.2" - "@metamask/utils": "npm:^11.11.0" - ethereum-cryptography: "npm:^2.2.1" - randombytes: "npm:^2.1.0" - checksum: 10/ac8a3a5871fb1b7503ae8714beaad07102ad473522f1c65cf09786a3f3498564763d96a51569ed712702f3a62dfaada4c9342def4d48e2c5a1f0985b5cd49725 - languageName: node - linkType: hard - -"@metamask/eth-snap-keyring@npm:^19.0.0": - version: 19.0.0 - resolution: "@metamask/eth-snap-keyring@npm:19.0.0" - dependencies: - "@ethereumjs/tx": "npm:^5.4.0" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-api": "npm:^21.4.0" - "@metamask/keyring-internal-api": "npm:^10.0.0" - "@metamask/keyring-internal-snap-client": "npm:^9.0.0" - "@metamask/keyring-snap-sdk": "npm:^7.2.0" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/messenger": "npm:^0.3.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - "@types/uuid": "npm:^9.0.8" - async-mutex: "npm:^0.5.0" - uuid: "npm:^9.0.1" - peerDependencies: - "@metamask/keyring-api": ^21.4.0 - checksum: 10/6e307295cb15ab44aba4ff89fb1886ad8c0ea6636748e5d84c87250fbaff9d5a3c316e63b614d7b472e4027aad0a7912109b36981e978e978bf31deea7980726 - languageName: node - linkType: hard - -"@metamask/eth-snap-keyring@npm:^22.0.1": - version: 22.2.0 - resolution: "@metamask/eth-snap-keyring@npm:22.2.0" - dependencies: - "@ethereumjs/tx": "npm:^5.4.0" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-internal-api": "npm:^11.0.1" - "@metamask/keyring-internal-snap-client": "npm:^10.0.3" - "@metamask/keyring-sdk": "npm:^2.2.0" - "@metamask/keyring-snap-sdk": "npm:^9.0.2" - "@metamask/keyring-utils": "npm:^3.3.1" - "@metamask/messenger": "npm:^1.1.1" - "@metamask/snaps-controllers": "npm:^19.0.1" - "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/snaps-utils": "npm:^12.1.3" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.11.0" - "@types/uuid": "npm:^9.0.8" - async-mutex: "npm:^0.5.0" - uuid: "npm:^9.0.1" - peerDependencies: - "@metamask/keyring-api": ^23.0.0 - checksum: 10/7f9ef7cbb454102f2e59d8380b1707e9b814179d3c132a45bd54102e9b2f3e9a5edd18a49f1238d928058e59f39ba4701fd684d5a6b5bc45779f8caadb54a130 - languageName: node - linkType: hard - -"@metamask/ethjs-contract@npm:^0.4.1": - version: 0.4.1 - resolution: "@metamask/ethjs-contract@npm:0.4.1" - dependencies: - "@metamask/ethjs-filter": "npm:^0.3.0" - "@metamask/ethjs-util": "npm:^0.3.0" - ethjs-abi: "npm:^0.2.0" - js-sha3: "npm:^0.9.2" - promise-to-callback: "npm:^1.0.0" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/2187f62336c2afd46b51bda87b96e1537dd7dfe0f621defc3cb5ccb68add482004674f3c11ced95c65b7ecbe845592541f1b268c97b0b42c939d8d5677523097 - languageName: node - linkType: hard - -"@metamask/ethjs-filter@npm:^0.3.0": - version: 0.3.0 - resolution: "@metamask/ethjs-filter@npm:0.3.0" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/1b7565045e638f60d39ae8d8ca020b6e3ac2e4e91f220f343e499b09a7adeb9e4273249e3c3f7366acc2e44bc0b7fe3dd3ac84c66e9a0853352bfb0e116c1d87 - languageName: node - linkType: hard - -"@metamask/ethjs-format@npm:^0.3.0": - version: 0.3.0 - resolution: "@metamask/ethjs-format@npm:0.3.0" - dependencies: - "@metamask/ethjs-util": "npm:^0.3.0" - "@metamask/number-to-bn": "npm:^1.7.1" - bn.js: "npm:^5.2.1" - ethjs-schema: "npm:0.2.1" - is-hex-prefixed: "npm:1.0.0" - strip-hex-prefix: "npm:1.0.0" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/4ae73716e0dd76f7b780ede79b3989d241ee8654b7aa9ec23678529a1916f77ab101552f7aabe56c8e26506a33f34181f40624a68a317e7cd3ae45fb0da2fa73 - languageName: node - linkType: hard - -"@metamask/ethjs-query@npm:^0.7.1": - version: 0.7.1 - resolution: "@metamask/ethjs-query@npm:0.7.1" - dependencies: - "@metamask/ethjs-format": "npm:^0.3.0" - "@metamask/ethjs-rpc": "npm:^0.4.0" - promise-to-callback: "npm:^1.0.0" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/a9d54677cf062267f7e781996edfadfc2a5a2f3589266b7f20386e8109b7cecdfdc47c6aba4bb68d0c4cb387cfdb463d6316d506c06138531ca1e81ab201e5dc - languageName: node - linkType: hard - -"@metamask/ethjs-rpc@npm:^0.4.0": - version: 0.4.0 - resolution: "@metamask/ethjs-rpc@npm:0.4.0" - dependencies: - promise-to-callback: "npm:^1.0.0" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/e126535ff7599ef584b0084dae846294d505b69141a143543d7580cdce4b297646e796fbd0cecc5a824dce8b5e3b179bb177ceff06fd50ad584e7fce00ab081f - languageName: node - linkType: hard - -"@metamask/ethjs-unit@npm:^0.3.0": - version: 0.3.0 - resolution: "@metamask/ethjs-unit@npm:0.3.0" - dependencies: - "@metamask/number-to-bn": "npm:^1.7.1" - bn.js: "npm:^5.2.1" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/a027d69d66b7eb45666c3bffbedd76dc25dbdd11b177a6b0a7c6735a06d1f123cd4c4c2e301149f6068450a49d41c24c6f93d665552757408fafefbd8720346e - languageName: node - linkType: hard - -"@metamask/ethjs-util@npm:^0.3.0": - version: 0.3.0 - resolution: "@metamask/ethjs-util@npm:0.3.0" - dependencies: - is-hex-prefixed: "npm:1.0.0" - strip-hex-prefix: "npm:1.0.0" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/aaecae091dd16362f048cbba27629d67d10530c704facf80f430db546c8ea32fa627cd9560bd3eca1e6ce651d2b7a7df9fdc3677e0ae2814954e3c950cee70da - languageName: node - linkType: hard - -"@metamask/gas-fee-controller@npm:^26.0.3": - version: 26.2.2 - resolution: "@metamask/gas-fee-controller@npm:26.2.2" - dependencies: - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/ethjs-unit": "npm:^0.3.0" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/network-controller": "npm:^32.0.0" - "@metamask/polling-controller": "npm:^16.0.6" - "@metamask/utils": "npm:^11.9.0" - "@types/bn.js": "npm:^5.1.5" - "@types/uuid": "npm:^8.3.0" - bn.js: "npm:^5.2.1" - uuid: "npm:^8.3.2" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/deba95b314bd7fe9908743f3905873bde204d0e26c3863201b884aff59f5dd974919f7c0b024143de53faf846e6cece0e99b4a065c8322721c375d6c11181be1 + "@metamask/number-to-bn": "npm:^1.7.1" + bn.js: "npm:^5.2.1" + peerDependencies: + "@babel/runtime": ^7.0.0 + checksum: 10/a027d69d66b7eb45666c3bffbedd76dc25dbdd11b177a6b0a7c6735a06d1f123cd4c4c2e301149f6068450a49d41c24c6f93d665552757408fafefbd8720346e languageName: node linkType: hard @@ -2342,7 +1785,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/json-rpc-engine@npm:^10.0.2, @metamask/json-rpc-engine@npm:^10.1.0, @metamask/json-rpc-engine@npm:^10.1.1, @metamask/json-rpc-engine@npm:^10.2.1, @metamask/json-rpc-engine@npm:^10.2.4, @metamask/json-rpc-engine@npm:^10.5.0": +"@metamask/json-rpc-engine@npm:^10.0.2, @metamask/json-rpc-engine@npm:^10.1.1, @metamask/json-rpc-engine@npm:^10.2.4, @metamask/json-rpc-engine@npm:^10.5.0": version: 10.5.0 resolution: "@metamask/json-rpc-engine@npm:10.5.0" dependencies: @@ -2369,7 +1812,7 @@ __metadata: languageName: node linkType: hard -"@metamask/key-tree@npm:^10.0.2, @metamask/key-tree@npm:^10.1.1": +"@metamask/key-tree@npm:^10.1.1": version: 10.1.1 resolution: "@metamask/key-tree@npm:10.1.1" dependencies: @@ -2382,47 +1825,6 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^21.4.0, @metamask/keyring-api@npm:^21.6.0": - version: 21.6.0 - resolution: "@metamask/keyring-api@npm:21.6.0" - dependencies: - "@ethereumjs/tx": "npm:^5.4.0" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - "@types/uuid": "npm:^9.0.8" - async-mutex: "npm:^0.5.0" - bitcoin-address-validation: "npm:^2.2.3" - uuid: "npm:^9.0.1" - checksum: 10/ecd482ec83fbdb16da5f0c548db29931edd4718c57550547aed9f3532c8e60ec39a6894571c96a819e5f205e53ec149e6b52710194ac0610960aa51834f15dd8 - languageName: node - linkType: hard - -"@metamask/keyring-api@npm:^22.0.0": - version: 22.0.0 - resolution: "@metamask/keyring-api@npm:22.0.0" - dependencies: - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/ff1e9537c7219fb906b61d6755de28890239ec44f634732bd8571801c662e8b801671e98961a1c5047e079cef314353297499a52f7091a2b5391325d575ec4f9 - languageName: node - linkType: hard - -"@metamask/keyring-api@npm:^23.0.1, @metamask/keyring-api@npm:^23.1.0, @metamask/keyring-api@npm:^23.2.0": - version: 23.2.0 - resolution: "@metamask/keyring-api@npm:23.2.0" - dependencies: - "@metamask/keyring-utils": "npm:^3.3.1" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.11.0" - bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/31c3d14da1d24e7b0e1d1a73f22dc265a8223e3bccda546f4069f7ae6e6ac54e063640bed04a2934413cc85b8d5e914a4492d5f8a094a5d6ddf706182967dfa0 - languageName: node - linkType: hard - "@metamask/keyring-api@npm:^23.5.0": version: 23.5.0 resolution: "@metamask/keyring-api@npm:23.5.0" @@ -2435,182 +1837,6 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-controller@npm:^25.2.0": - version: 25.5.0 - resolution: "@metamask/keyring-controller@npm:25.5.0" - dependencies: - "@ethereumjs/util": "npm:^9.1.0" - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/browser-passworder": "npm:^6.0.0" - "@metamask/eth-hd-keyring": "npm:^14.1.1" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/eth-simple-keyring": "npm:^12.0.2" - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-internal-api": "npm:^11.0.1" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/utils": "npm:^11.9.0" - async-mutex: "npm:^0.5.0" - ethereumjs-wallet: "npm:^1.0.1" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - ulid: "npm:^2.3.0" - checksum: 10/1ca02ea62e8d235a6343a054cc58cad42039242a319a982bcadb9dd0d7df0d1f06852dd5e3e91ee208b9c42df6580e776f76de1f49ce458b8c49029284caedad - languageName: node - linkType: hard - -"@metamask/keyring-controller@npm:^26.0.0": - version: 26.0.0 - resolution: "@metamask/keyring-controller@npm:26.0.0" - dependencies: - "@ethereumjs/util": "npm:^9.1.0" - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/browser-passworder": "npm:^6.0.0" - "@metamask/eth-hd-keyring": "npm:^14.1.1" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/eth-simple-keyring": "npm:^12.0.2" - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-internal-api": "npm:^11.0.1" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/utils": "npm:^11.9.0" - async-mutex: "npm:^0.5.0" - ethereumjs-wallet: "npm:^1.0.1" - immer: "npm:^9.0.6" - lodash: "npm:^4.17.21" - ulid: "npm:^2.3.0" - checksum: 10/3ca8a86b97fb9568debdc7b574d42cf98a6c3ff76695e72679980169738ff9e4b9626c9ee59a91f3aa57e3e89003ecccfd5f2e9fa7c2775ff1b545e12a47933f - languageName: node - linkType: hard - -"@metamask/keyring-internal-api@npm:^10.0.0, @metamask/keyring-internal-api@npm:^10.0.1": - version: 10.1.1 - resolution: "@metamask/keyring-internal-api@npm:10.1.1" - dependencies: - "@metamask/keyring-api": "npm:^23.0.1" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/superstruct": "npm:^3.1.0" - checksum: 10/056f1e957e07e0622a0d61abfb567f2020e94fb2bc68d3db599b2ec74fa222c874642a6eaef6ccfd1923619e1353ba819fdad729c989b9dc0df6c3127cc14a59 - languageName: node - linkType: hard - -"@metamask/keyring-internal-api@npm:^11.0.1": - version: 11.0.1 - resolution: "@metamask/keyring-internal-api@npm:11.0.1" - dependencies: - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/superstruct": "npm:^3.1.0" - checksum: 10/d35a5b45887566f47e41c1109e9f4eca5108fd1b8402773d40a882c904de0f33cc70e0cc7d1e1a34397ae434646c597d9793c31dbedc83cdf64e41f8e719ccc4 - languageName: node - linkType: hard - -"@metamask/keyring-internal-snap-client@npm:^10.0.3": - version: 10.0.3 - resolution: "@metamask/keyring-internal-snap-client@npm:10.0.3" - dependencies: - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-internal-api": "npm:^11.0.1" - "@metamask/keyring-snap-client": "npm:^9.0.2" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/messenger": "npm:^1.1.1" - checksum: 10/30c00a2f39125e7f99bd6513096f23fa243f30cd7ce4e77aa96f52c66fa99c077dfba0544d2693e16c283a2a5610f6b844eaa39130d1f760390d6ca1f53f0507 - languageName: node - linkType: hard - -"@metamask/keyring-internal-snap-client@npm:^9.0.0": - version: 9.0.1 - resolution: "@metamask/keyring-internal-snap-client@npm:9.0.1" - dependencies: - "@metamask/keyring-api": "npm:^22.0.0" - "@metamask/keyring-internal-api": "npm:^10.0.1" - "@metamask/keyring-snap-client": "npm:^8.2.1" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/messenger": "npm:^0.3.0" - checksum: 10/fb683a7826856612d2d89a8f6eb83bd14a20e27c18dddb5c50699d0fefce7475ff9e3077b65296820cf0911ee49d4daf3014932d1b1d7bfd330612229e02e6f4 - languageName: node - linkType: hard - -"@metamask/keyring-sdk@npm:^2.0.2, @metamask/keyring-sdk@npm:^2.1.1, @metamask/keyring-sdk@npm:^2.2.0": - version: 2.2.0 - resolution: "@metamask/keyring-sdk@npm:2.2.0" - dependencies: - "@ethereumjs/tx": "npm:^5.4.0" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/keyring-api": "npm:^23.2.0" - "@metamask/keyring-utils": "npm:^3.3.1" - "@metamask/scure-bip39": "npm:^2.1.1" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.11.0" - async-mutex: "npm:^0.5.0" - ethereum-cryptography: "npm:^2.2.1" - uuid: "npm:^9.0.1" - checksum: 10/5cb7f2496f0fc95e85eb97932b69da9c02c232e2310b5f390bfc7c56996bf8516d15db54260e68288f6d6f5604bfacc19b4b82b9b28b7f794a3ab5ee9a1f10d1 - languageName: node - linkType: hard - -"@metamask/keyring-snap-client@npm:^8.2.1": - version: 8.2.1 - resolution: "@metamask/keyring-snap-client@npm:8.2.1" - dependencies: - "@metamask/keyring-api": "npm:^22.0.0" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/superstruct": "npm:^3.1.0" - "@types/uuid": "npm:^9.0.8" - uuid: "npm:^9.0.1" - webextension-polyfill: "npm:^0.12.0" - peerDependencies: - "@metamask/providers": ^19.0.0 - checksum: 10/f69dcb56d3089dfd1bd902ad409c017288e31d3631a2024f42f6b6ee1b4f6e663ad4d7bdfd5d3bcf6c9827190d3bad6983c89f7c821959d305f6ba8f4aae0d7c - languageName: node - linkType: hard - -"@metamask/keyring-snap-client@npm:^9.0.2": - version: 9.0.2 - resolution: "@metamask/keyring-snap-client@npm:9.0.2" - dependencies: - "@metamask/keyring-api": "npm:^23.1.0" - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/superstruct": "npm:^3.1.0" - "@types/uuid": "npm:^9.0.8" - uuid: "npm:^9.0.1" - webextension-polyfill: "npm:^0.12.0" - peerDependencies: - "@metamask/providers": ^19.0.0 - checksum: 10/f4de52be334d941fffafb6458260875706a09315d68856577a66dd36b069de00260632cfcd0fe9b56528382512dee2c226f61430aafb619869f1b1711d3ffffd - languageName: node - linkType: hard - -"@metamask/keyring-snap-sdk@npm:^7.2.0": - version: 7.2.1 - resolution: "@metamask/keyring-snap-sdk@npm:7.2.1" - dependencies: - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/snaps-sdk": "npm:^10.4.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - webextension-polyfill: "npm:^0.12.0" - peerDependencies: - "@metamask/keyring-api": ^21.5.0 - "@metamask/providers": ^19.0.0 - checksum: 10/e314e56d3d82e0306564a3f6c2a3e207b36e51a43b9589780331a2fa67cc9e6a65d6008e3c81c3ffbea29c93950f6a8c9329694fcdd0136786d957baa7cd48df - languageName: node - linkType: hard - -"@metamask/keyring-snap-sdk@npm:^9.0.2": - version: 9.0.2 - resolution: "@metamask/keyring-snap-sdk@npm:9.0.2" - dependencies: - "@metamask/keyring-utils": "npm:^3.3.1" - "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.11.0" - webextension-polyfill: "npm:^0.12.0" - peerDependencies: - "@metamask/keyring-api": ^23.0.0 - "@metamask/providers": ^19.0.0 - checksum: 10/a3fa4c306b058f484042e4460f8d19d509c4725cb49c40328dd905555bae33e07e29262891500acbcb845891af3721a562a36914286fc876f37668ce63f1bee1 - languageName: node - linkType: hard - "@metamask/keyring-snap-sdk@npm:^9.2.0": version: 9.2.0 resolution: "@metamask/keyring-snap-sdk@npm:9.2.0" @@ -2627,7 +1853,7 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-utils@npm:^3.1.0, @metamask/keyring-utils@npm:^3.2.0, @metamask/keyring-utils@npm:^3.2.1, @metamask/keyring-utils@npm:^3.3.1": +"@metamask/keyring-utils@npm:^3.3.1": version: 3.3.1 resolution: "@metamask/keyring-utils@npm:3.3.1" dependencies: @@ -2639,30 +1865,7 @@ __metadata: languageName: node linkType: hard -"@metamask/message-manager@npm:^14.1.1": - version: 14.1.2 - resolution: "@metamask/message-manager@npm:14.1.2" - dependencies: - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/controller-utils": "npm:^12.0.0" - "@metamask/eth-sig-util": "npm:^8.2.0" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/utils": "npm:^11.9.0" - "@types/uuid": "npm:^8.3.0" - jsonschema: "npm:^1.4.1" - uuid: "npm:^8.3.2" - checksum: 10/82e3965069f0eb34e2141ca4dff452c118f54502d0b5d6b832af1906c6413ba1d923b13f1ed6af7f8a7b3087ef7f3b1a700bcffa56b10b06df53972ff2cf9a4f - languageName: node - linkType: hard - -"@metamask/messenger@npm:^0.3.0": - version: 0.3.0 - resolution: "@metamask/messenger@npm:0.3.0" - checksum: 10/84e9f4193646d749c7260a4958b13974b3c8738cc2e414116279ed31734e1edba687ff56ddbfdb75033bce30aaa9eeb7c391bccb87a66dbc99a902882271f673 - languageName: node - linkType: hard - -"@metamask/messenger@npm:^1.0.0, @metamask/messenger@npm:^1.1.0, @metamask/messenger@npm:^1.1.1, @metamask/messenger@npm:^1.2.0": +"@metamask/messenger@npm:^1.0.0, @metamask/messenger@npm:^1.1.1, @metamask/messenger@npm:^1.2.0": version: 1.2.0 resolution: "@metamask/messenger@npm:1.2.0" dependencies: @@ -2687,79 +1890,6 @@ __metadata: languageName: node linkType: hard -"@metamask/metamask-eth-abis@npm:^3.1.1": - version: 3.1.1 - resolution: "@metamask/metamask-eth-abis@npm:3.1.1" - checksum: 10/2d456882c5180eaf02d07f578ee8b8806d18639349d086a6b3b68c87e7ea294749efc332bfe7c1d5fb700933e71f31a46d3cd07b94c4e91c80faea5f9729bf0d - languageName: node - linkType: hard - -"@metamask/network-controller@npm:^30.0.0, @metamask/network-controller@npm:^30.0.1": - version: 30.1.0 - resolution: "@metamask/network-controller@npm:30.1.0" - dependencies: - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/connectivity-controller": "npm:^0.2.0" - "@metamask/controller-utils": "npm:^11.20.0" - "@metamask/eth-block-tracker": "npm:^15.0.1" - "@metamask/eth-json-rpc-infura": "npm:^10.3.0" - "@metamask/eth-json-rpc-middleware": "npm:^23.1.3" - "@metamask/eth-json-rpc-provider": "npm:^6.0.1" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/json-rpc-engine": "npm:^10.2.4" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/swappable-obj-proxy": "npm:^2.3.0" - "@metamask/utils": "npm:^11.9.0" - async-mutex: "npm:^0.5.0" - fast-deep-equal: "npm:^3.1.3" - immer: "npm:^9.0.6" - loglevel: "npm:^1.8.1" - reselect: "npm:^5.1.1" - uri-js: "npm:^4.4.1" - uuid: "npm:^8.3.2" - checksum: 10/b2947c3c34d8f2f326c3ed1504e1d194b5af77db1e07c4b25f8f8c4b1e9e16cd30ab54a8a8f716d731f989c8f1119e9aeefa30ed26d89928a9110c21ce3968d5 - languageName: node - linkType: hard - -"@metamask/network-controller@npm:^32.0.0": - version: 32.0.0 - resolution: "@metamask/network-controller@npm:32.0.0" - dependencies: - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/connectivity-controller": "npm:^0.2.0" - "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/eth-block-tracker": "npm:^15.0.1" - "@metamask/eth-json-rpc-infura": "npm:^10.3.0" - "@metamask/eth-json-rpc-middleware": "npm:^23.1.3" - "@metamask/eth-json-rpc-provider": "npm:^6.0.1" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/json-rpc-engine": "npm:^10.5.0" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/swappable-obj-proxy": "npm:^2.3.0" - "@metamask/utils": "npm:^11.9.0" - async-mutex: "npm:^0.5.0" - fast-deep-equal: "npm:^3.1.3" - immer: "npm:^9.0.6" - loglevel: "npm:^1.8.1" - reselect: "npm:^5.1.1" - uri-js: "npm:^4.4.1" - uuid: "npm:^8.3.2" - checksum: 10/263f6355aac3e2014f2d18c2c10b20b83e12823845cf9a12e74dea09d31d5f81be9bd396d9f3b5b7dbaa99ce5ed7f3b0ec4c537656f884f586c349965569ad07 - languageName: node - linkType: hard - -"@metamask/nonce-tracker@npm:^6.0.0": - version: 6.1.0 - resolution: "@metamask/nonce-tracker@npm:6.1.0" - dependencies: - "@ethersproject/providers": "npm:^5.7.2" - async-mutex: "npm:^0.5.0" - checksum: 10/a20cf7084348ef7bdcd9e57e873ca34bf8e04ee43a2ab08634a3ad47fddb632d0e170c1dff03b4ca5bac34a24c35c542fcec509f3c23ce483834082f41b50e4a - languageName: node - linkType: hard - "@metamask/number-to-bn@npm:^1.7.1": version: 1.7.1 resolution: "@metamask/number-to-bn@npm:1.7.1" @@ -2780,7 +1910,7 @@ __metadata: languageName: node linkType: hard -"@metamask/permission-controller@npm:^12.2.0, @metamask/permission-controller@npm:^12.3.0": +"@metamask/permission-controller@npm:^12.2.0": version: 12.3.0 resolution: "@metamask/permission-controller@npm:12.3.0" dependencies: @@ -2818,38 +1948,6 @@ __metadata: languageName: node linkType: hard -"@metamask/phishing-controller@npm:^16.1.0": - version: 16.3.0 - resolution: "@metamask/phishing-controller@npm:16.3.0" - dependencies: - "@metamask/base-controller": "npm:^9.0.0" - "@metamask/controller-utils": "npm:^11.18.0" - "@metamask/messenger": "npm:^0.3.0" - "@metamask/transaction-controller": "npm:^62.17.0" - "@noble/hashes": "npm:^1.8.0" - "@types/punycode": "npm:^2.1.0" - ethereum-cryptography: "npm:^2.1.2" - fastest-levenshtein: "npm:^1.0.16" - punycode: "npm:^2.1.1" - checksum: 10/a2c38aa69c5158d4bec2b1e37af449e7f9f67f24d151dcf4b6cd7e5a65567236b360488d91f4efde4898703de39eed5cc79e0c36369bf96dbedfed05daf41ecc - languageName: node - linkType: hard - -"@metamask/polling-controller@npm:^16.0.6": - version: 16.0.6 - resolution: "@metamask/polling-controller@npm:16.0.6" - dependencies: - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/network-controller": "npm:^32.0.0" - "@metamask/utils": "npm:^11.9.0" - "@types/uuid": "npm:^8.3.0" - fast-json-stable-stringify: "npm:^2.1.0" - uuid: "npm:^8.3.2" - checksum: 10/12990b447a5188072e5614b17ae6baa1f30911878f995e566387f53e4309d8729a6768b61d1e042462b9d65541c3f0d7caf1df3aeb8a41756bbef7bafd1b8dab - languageName: node - linkType: hard - "@metamask/post-message-stream@npm:^10.0.0": version: 10.0.0 resolution: "@metamask/post-message-stream@npm:10.0.0" @@ -2860,30 +1958,6 @@ __metadata: languageName: node linkType: hard -"@metamask/profile-sync-controller@npm:^28.1.1": - version: 28.1.1 - resolution: "@metamask/profile-sync-controller@npm:28.1.1" - dependencies: - "@metamask/address-book-controller": "npm:^7.1.2" - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/keyring-controller": "npm:^26.0.0" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/snaps-controllers": "npm:^19.0.0" - "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/snaps-utils": "npm:^12.1.2" - "@metamask/utils": "npm:^11.9.0" - "@noble/ciphers": "npm:^1.3.0" - "@noble/hashes": "npm:^1.8.0" - immer: "npm:^9.0.6" - loglevel: "npm:^1.8.1" - siwe: "npm:^2.3.2" - peerDependencies: - "@metamask/providers": ^22.0.0 - webextension-polyfill: ^0.10.0 || ^0.11.0 || ^0.12.0 - checksum: 10/0fd175ee7f3327eaaf9d019ca1044aa10d98df1025c8f2d1fbd9c24f8ee0d5183a695aed32a9a6ff18fe94247edd18967ad7d9c2872bc9999d70c39a5794b523 - languageName: node - linkType: hard - "@metamask/providers@npm:^22.1.1": version: 22.1.1 resolution: "@metamask/providers@npm:22.1.1" @@ -2905,19 +1979,6 @@ __metadata: languageName: node linkType: hard -"@metamask/remote-feature-flag-controller@npm:^4.1.0": - version: 4.2.2 - resolution: "@metamask/remote-feature-flag-controller@npm:4.2.2" - dependencies: - "@metamask/base-controller": "npm:^9.1.0" - "@metamask/controller-utils": "npm:^12.1.0" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/utils": "npm:^11.9.0" - uuid: "npm:^8.3.2" - checksum: 10/ed03ff1ba63c7a0f2b221c3514eb71a8be4200ec543b90676a44930dc731920ac2c92dcc2b13a32ed4e4e8e7e7b28a26db443af9f4bf30f5e2b5785580b286ab - languageName: node - linkType: hard - "@metamask/rpc-errors@npm:^7.0.2, @metamask/rpc-errors@npm:^7.0.3": version: 7.0.3 resolution: "@metamask/rpc-errors@npm:7.0.3" @@ -2941,9 +2002,9 @@ __metadata: dependencies: "@jest/globals": "npm:^29.5.0" "@metamask/auto-changelog": "npm:^6.1.0" - "@metamask/snaps-cli": "npm:^8.3.0" - "@metamask/snaps-jest": "npm:^9.8.0" - "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/snaps-cli": "npm:^8.4.1" + "@metamask/snaps-jest": "npm:^10.2.0" + "@metamask/snaps-sdk": "npm:^11.2.0" "@types/react": "npm:18.2.4" "@types/react-dom": "npm:18.2.4" eslint: "npm:^9.39.1" @@ -2963,14 +2024,14 @@ __metadata: languageName: node linkType: hard -"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.3.0, @metamask/slip44@npm:^4.4.0, @metamask/slip44@npm:^4.5.0": +"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.4.0, @metamask/slip44@npm:^4.5.0": version: 4.5.0 resolution: "@metamask/slip44@npm:4.5.0" checksum: 10/8450d4f5afa98e8f57c67a39f12aa413888c423505f22c05a3dc181be223f7742db017f54a99852acc3826abe74b22bf7247bccd78b810e509321c075e67516f languageName: node linkType: hard -"@metamask/snaps-cli@npm:^8.3.0, @metamask/snaps-cli@npm:^8.4.1": +"@metamask/snaps-cli@npm:^8.4.1": version: 8.4.1 resolution: "@metamask/snaps-cli@npm:8.4.1" dependencies: @@ -3023,92 +2084,6 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-controllers@npm:^17.2.1": - version: 17.2.1 - resolution: "@metamask/snaps-controllers@npm:17.2.1" - dependencies: - "@metamask/approval-controller": "npm:^8.0.0" - "@metamask/base-controller": "npm:^9.0.0" - "@metamask/json-rpc-engine": "npm:^10.1.0" - "@metamask/json-rpc-middleware-stream": "npm:^8.0.8" - "@metamask/key-tree": "npm:^10.1.1" - "@metamask/messenger": "npm:^0.3.0" - "@metamask/object-multiplex": "npm:^2.1.0" - "@metamask/permission-controller": "npm:^12.2.0" - "@metamask/phishing-controller": "npm:^16.1.0" - "@metamask/post-message-stream": "npm:^10.0.0" - "@metamask/rpc-errors": "npm:^7.0.3" - "@metamask/snaps-registry": "npm:^4.0.0" - "@metamask/snaps-rpc-methods": "npm:^14.1.1" - "@metamask/snaps-sdk": "npm:^10.3.0" - "@metamask/snaps-utils": "npm:^11.7.1" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.9.0" - "@xstate/fsm": "npm:^2.0.0" - async-mutex: "npm:^0.5.0" - concat-stream: "npm:^2.0.0" - cron-parser: "npm:^4.5.0" - fast-deep-equal: "npm:^3.1.3" - get-npm-tarball-url: "npm:^2.0.3" - immer: "npm:^9.0.21" - luxon: "npm:^3.5.0" - nanoid: "npm:^3.3.10" - readable-stream: "npm:^3.6.2" - readable-web-to-node-stream: "npm:^3.0.2" - semver: "npm:^7.5.4" - tar-stream: "npm:^3.1.7" - peerDependencies: - "@metamask/snaps-execution-environments": ^10.3.0 - peerDependenciesMeta: - "@metamask/snaps-execution-environments": - optional: true - checksum: 10/867f23054e2c08c0ca67d35a6853a1700ac7f0bab3f7d17b3dbcd10f0043331a5063a6086fa787ee4cb8dfebd4ec54ee9bbfdd1a2b6d7ac75ba31ce2d0957f89 - languageName: node - linkType: hard - -"@metamask/snaps-controllers@npm:^19.0.0, @metamask/snaps-controllers@npm:^19.0.1": - version: 19.0.1 - resolution: "@metamask/snaps-controllers@npm:19.0.1" - dependencies: - "@metamask/approval-controller": "npm:^9.0.1" - "@metamask/base-controller": "npm:^9.0.1" - "@metamask/json-rpc-engine": "npm:^10.2.4" - "@metamask/json-rpc-middleware-stream": "npm:^8.0.8" - "@metamask/key-tree": "npm:^10.1.1" - "@metamask/messenger": "npm:^1.1.0" - "@metamask/object-multiplex": "npm:^2.1.0" - "@metamask/permission-controller": "npm:^12.3.0" - "@metamask/post-message-stream": "npm:^10.0.0" - "@metamask/rpc-errors": "npm:^7.0.3" - "@metamask/snaps-registry": "npm:^4.0.0" - "@metamask/snaps-rpc-methods": "npm:^15.0.2" - "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/snaps-utils": "npm:^12.1.3" - "@metamask/storage-service": "npm:^1.0.1" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.10.0" - "@xstate/fsm": "npm:^2.0.0" - async-mutex: "npm:^0.5.0" - concat-stream: "npm:^2.0.0" - cron-parser: "npm:^4.5.0" - fast-deep-equal: "npm:^3.1.3" - get-npm-tarball-url: "npm:^2.0.3" - immer: "npm:^9.0.21" - luxon: "npm:^3.5.0" - nanoid: "npm:^3.3.10" - readable-stream: "npm:^3.6.2" - readable-web-to-node-stream: "npm:^3.0.2" - semver: "npm:^7.5.4" - tar-stream: "npm:^3.1.7" - peerDependencies: - "@metamask/snaps-execution-environments": ^11.0.2 - peerDependenciesMeta: - "@metamask/snaps-execution-environments": - optional: true - checksum: 10/e7cee816b1af1e2c4cbd25a81afff779427e6d738c1fe283a1ca9b23f67c62b5a983d6ed35e91acf0b15016e6825074557f3376d322a518c1acfc36728d36509 - languageName: node - linkType: hard - "@metamask/snaps-controllers@npm:^21.0.0": version: 21.0.0 resolution: "@metamask/snaps-controllers@npm:21.0.0" @@ -3153,24 +2128,6 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-execution-environments@npm:^10.3.0": - version: 10.4.1 - resolution: "@metamask/snaps-execution-environments@npm:10.4.1" - dependencies: - "@metamask/json-rpc-engine": "npm:^10.2.1" - "@metamask/object-multiplex": "npm:^2.1.0" - "@metamask/post-message-stream": "npm:^10.0.0" - "@metamask/providers": "npm:^22.1.1" - "@metamask/rpc-errors": "npm:^7.0.3" - "@metamask/snaps-sdk": "npm:^10.4.0" - "@metamask/snaps-utils": "npm:^12.0.1" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.9.0" - readable-stream: "npm:^3.6.2" - checksum: 10/485bf89abfcf0c8f66f682ef0990a180f935c6a25915305243635c481b04755862791fdd4b64ed9100ba8d1dde29bdd745721f6f707092a64167bf4f2246e566 - languageName: node - linkType: hard - "@metamask/snaps-execution-environments@npm:^11.1.1": version: 11.2.0 resolution: "@metamask/snaps-execution-environments@npm:11.2.0" @@ -3209,26 +2166,6 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-jest@npm:^9.8.0": - version: 9.8.0 - resolution: "@metamask/snaps-jest@npm:9.8.0" - dependencies: - "@jest/environment": "npm:^29.5.0" - "@jest/expect": "npm:^29.5.0" - "@jest/globals": "npm:^29.5.0" - "@metamask/snaps-controllers": "npm:^17.2.1" - "@metamask/snaps-sdk": "npm:^10.3.0" - "@metamask/snaps-simulation": "npm:^3.8.0" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.9.0" - express: "npm:^5.1.0" - jest-environment-node: "npm:^29.5.0" - jest-matcher-utils: "npm:^29.5.0" - redux: "npm:^4.2.1" - checksum: 10/db40b3e23db84d9dd9872c6987b14441fee3a984e2f1f29cee667120689a9aca4ece44552a5e2796f17a9814d2ba26ca55aed3e64060fadacf727c9ae5829601 - languageName: node - linkType: hard - "@metamask/snaps-registry@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/snaps-registry@npm:4.0.0" @@ -3241,7 +2178,7 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-rpc-methods@npm:^14.1.1, @metamask/snaps-rpc-methods@npm:^14.2.0, @metamask/snaps-rpc-methods@npm:^14.3.0": +"@metamask/snaps-rpc-methods@npm:^14.2.0, @metamask/snaps-rpc-methods@npm:^14.3.0": version: 14.3.0 resolution: "@metamask/snaps-rpc-methods@npm:14.3.0" dependencies: @@ -3258,23 +2195,6 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-rpc-methods@npm:^15.0.2": - version: 15.1.1 - resolution: "@metamask/snaps-rpc-methods@npm:15.1.1" - dependencies: - "@metamask/key-tree": "npm:^10.1.1" - "@metamask/permission-controller": "npm:^12.3.0" - "@metamask/rpc-errors": "npm:^7.0.3" - "@metamask/snaps-sdk": "npm:^11.1.0" - "@metamask/snaps-utils": "npm:^12.2.0" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.11.0" - "@noble/hashes": "npm:^1.7.1" - async-mutex: "npm:^0.5.0" - checksum: 10/906eafa8a2d4944e50d73b8aa4d32a7070c33367ad3d58843e892e62b3bd8facb0a02e1d88a9245c18a281637435d97266212b7706ef67ee6a68db85a5991ea3 - languageName: node - linkType: hard - "@metamask/snaps-rpc-methods@npm:^17.0.0, @metamask/snaps-rpc-methods@npm:^17.1.0": version: 17.1.0 resolution: "@metamask/snaps-rpc-methods@npm:17.1.0" @@ -3313,35 +2233,6 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-simulation@npm:^3.8.0": - version: 3.8.0 - resolution: "@metamask/snaps-simulation@npm:3.8.0" - dependencies: - "@metamask/json-rpc-engine": "npm:^10.1.0" - "@metamask/json-rpc-middleware-stream": "npm:^8.0.8" - "@metamask/key-tree": "npm:^10.1.1" - "@metamask/messenger": "npm:^0.3.0" - "@metamask/permission-controller": "npm:^12.2.0" - "@metamask/phishing-controller": "npm:^16.1.0" - "@metamask/rpc-errors": "npm:^7.0.3" - "@metamask/snaps-controllers": "npm:^17.2.1" - "@metamask/snaps-execution-environments": "npm:^10.3.0" - "@metamask/snaps-rpc-methods": "npm:^14.1.1" - "@metamask/snaps-sdk": "npm:^10.3.0" - "@metamask/snaps-utils": "npm:^11.7.1" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.9.0" - "@reduxjs/toolkit": "npm:^1.9.5" - ethers: "npm:^6.16.0" - fast-deep-equal: "npm:^3.1.3" - immer: "npm:^9.0.21" - mime: "npm:^3.0.0" - readable-stream: "npm:^3.6.2" - redux-saga: "npm:^1.2.3" - checksum: 10/244735ec69002d472d5d5814675ae7257f94b24d5b6c6c2c3652922b6cf28d73ad0fe39786c507f312a859d99d0fb5b54d292476e83dcf30c70be4cd32e25e42 - languageName: node - linkType: hard - "@metamask/snaps-simulation@npm:^4.3.0": version: 4.3.0 resolution: "@metamask/snaps-simulation@npm:4.3.0" @@ -3371,38 +2262,7 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-utils@npm:^11.7.1": - version: 11.7.1 - resolution: "@metamask/snaps-utils@npm:11.7.1" - dependencies: - "@babel/core": "npm:^7.23.2" - "@babel/types": "npm:^7.23.0" - "@metamask/key-tree": "npm:^10.1.1" - "@metamask/messenger": "npm:^0.3.0" - "@metamask/permission-controller": "npm:^12.2.0" - "@metamask/rpc-errors": "npm:^7.0.3" - "@metamask/slip44": "npm:^4.3.0" - "@metamask/snaps-registry": "npm:^4.0.0" - "@metamask/snaps-sdk": "npm:^10.3.0" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.9.0" - "@scure/base": "npm:^1.1.1" - chalk: "npm:^4.1.2" - cron-parser: "npm:^4.5.0" - fast-deep-equal: "npm:^3.1.3" - fast-json-stable-stringify: "npm:^2.1.0" - fast-xml-parser: "npm:^4.4.1" - luxon: "npm:^3.5.0" - marked: "npm:^12.0.1" - rfdc: "npm:^1.3.0" - semver: "npm:^7.5.4" - ses: "npm:^1.14.0" - validate-npm-package-name: "npm:^5.0.0" - checksum: 10/4f1ebf14df5eef4344aef8367923176b02f68c58a76c2776aef3015e36f1f889f6463a6b991c78e5810424cf117e20972511a12fcc3436839b0f6100cbb8f09e - languageName: node - linkType: hard - -"@metamask/snaps-utils@npm:^12.0.0, @metamask/snaps-utils@npm:^12.0.1, @metamask/snaps-utils@npm:^12.1.0, @metamask/snaps-utils@npm:^12.1.2, @metamask/snaps-utils@npm:^12.1.3, @metamask/snaps-utils@npm:^12.2.0": +"@metamask/snaps-utils@npm:^12.0.0, @metamask/snaps-utils@npm:^12.1.0": version: 12.2.1 resolution: "@metamask/snaps-utils@npm:12.2.1" dependencies: @@ -3479,16 +2339,6 @@ __metadata: languageName: node linkType: hard -"@metamask/storage-service@npm:^1.0.1": - version: 1.0.1 - resolution: "@metamask/storage-service@npm:1.0.1" - dependencies: - "@metamask/messenger": "npm:^1.0.0" - "@metamask/utils": "npm:^11.9.0" - checksum: 10/3ec18b85ae80d13c4928be327abb1ee0548a6c44afdb7f709434a6621c876c3de95e145ca2603bdf178772982c76f546ec1cac58f28c0a9c74e020342d171349 - languageName: node - linkType: hard - "@metamask/storage-service@npm:^1.0.2": version: 1.0.2 resolution: "@metamask/storage-service@npm:1.0.2" @@ -3513,53 +2363,7 @@ __metadata: languageName: node linkType: hard -"@metamask/swappable-obj-proxy@npm:^2.3.0": - version: 2.3.0 - resolution: "@metamask/swappable-obj-proxy@npm:2.3.0" - checksum: 10/1255c599de9237f06df2390719d6dfcb1f168873df61bbaad5ce376efbc057e2030260b94855569313faeb412b7df9b062d209f4b0b163a3dc02f29d42139e1f - languageName: node - linkType: hard - -"@metamask/transaction-controller@npm:^62.17.0": - version: 62.22.0 - resolution: "@metamask/transaction-controller@npm:62.22.0" - dependencies: - "@ethereumjs/common": "npm:^4.4.0" - "@ethereumjs/tx": "npm:^5.4.0" - "@ethereumjs/util": "npm:^9.1.0" - "@ethersproject/abi": "npm:^5.7.0" - "@ethersproject/contracts": "npm:^5.7.0" - "@ethersproject/providers": "npm:^5.7.0" - "@ethersproject/wallet": "npm:^5.7.0" - "@metamask/accounts-controller": "npm:^37.0.0" - "@metamask/approval-controller": "npm:^8.0.0" - "@metamask/base-controller": "npm:^9.0.0" - "@metamask/controller-utils": "npm:^11.19.0" - "@metamask/core-backend": "npm:^6.1.1" - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/gas-fee-controller": "npm:^26.0.3" - "@metamask/messenger": "npm:^0.3.0" - "@metamask/metamask-eth-abis": "npm:^3.1.1" - "@metamask/network-controller": "npm:^30.0.0" - "@metamask/nonce-tracker": "npm:^6.0.0" - "@metamask/remote-feature-flag-controller": "npm:^4.1.0" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/utils": "npm:^11.9.0" - async-mutex: "npm:^0.5.0" - bignumber.js: "npm:^9.1.2" - bn.js: "npm:^5.2.1" - eth-method-registry: "npm:^4.0.0" - fast-json-patch: "npm:^3.1.1" - lodash: "npm:^4.17.21" - uuid: "npm:^8.3.2" - peerDependencies: - "@babel/runtime": ^7.0.0 - "@metamask/eth-block-tracker": ">=9" - checksum: 10/84d7fffb169bcb7b97844339f167972161f1f3ea14b396f6888e709269d4e126a4a896fcc526a32980a624b934a5afbf5e482a8263cf3be692d9ba6e159dca29 - languageName: node - linkType: hard - -"@metamask/utils@npm:^11.0.1, @metamask/utils@npm:^11.1.0, @metamask/utils@npm:^11.10.0, @metamask/utils@npm:^11.11.0, @metamask/utils@npm:^11.4.0, @metamask/utils@npm:^11.4.2, @metamask/utils@npm:^11.8.1, @metamask/utils@npm:^11.9.0": +"@metamask/utils@npm:^11.0.1, @metamask/utils@npm:^11.10.0, @metamask/utils@npm:^11.11.0, @metamask/utils@npm:^11.4.0, @metamask/utils@npm:^11.4.2, @metamask/utils@npm:^11.8.1, @metamask/utils@npm:^11.9.0": version: 11.11.0 resolution: "@metamask/utils@npm:11.11.0" dependencies: @@ -3595,13 +2399,6 @@ __metadata: languageName: node linkType: hard -"@noble/ciphers@npm:^1.3.0": - version: 1.3.0 - resolution: "@noble/ciphers@npm:1.3.0" - checksum: 10/051660051e3e9e2ca5fb9dece2885532b56b7e62946f89afa7284a0fb8bc02e2bd1c06554dba68162ff42d295b54026456084198610f63c296873b2f1cd7a586 - languageName: node - linkType: hard - "@noble/curves@npm:1.2.0": version: 1.2.0 resolution: "@noble/curves@npm:1.2.0" @@ -3643,7 +2440,7 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.1.2, @noble/hashes@npm:^1.2.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.3.2, @noble/hashes@npm:^1.7.1, @noble/hashes@npm:^1.8.0": +"@noble/hashes@npm:1.8.0, @noble/hashes@npm:^1.1.2, @noble/hashes@npm:^1.2.0, @noble/hashes@npm:^1.3.1, @noble/hashes@npm:^1.3.2, @noble/hashes@npm:^1.7.1": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" checksum: 10/474b7f56bc6fb2d5b3a42132561e221b0ea4f91e590f4655312ca13667840896b34195e2b53b7f097ec080a1fdd3b58d902c2a8d0fbdf51d2e238b53808a177e @@ -4207,51 +3004,6 @@ __metadata: languageName: node linkType: hard -"@spruceid/siwe-parser@npm:^2.1.2": - version: 2.1.2 - resolution: "@spruceid/siwe-parser@npm:2.1.2" - dependencies: - "@noble/hashes": "npm:^1.1.2" - apg-js: "npm:^4.3.0" - uri-js: "npm:^4.4.1" - valid-url: "npm:^1.0.9" - checksum: 10/48459fe3b4d4b3091375ee87af700864c9023d4a1271d34850c6d27475e5d93a45d1efe8a71da367ad838b6921ced60c387d54737edd0a7a0d8e4e0a3cc2b8b7 - languageName: node - linkType: hard - -"@stablelib/binary@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/binary@npm:1.0.1" - dependencies: - "@stablelib/int": "npm:^1.0.1" - checksum: 10/c5ed769e2b5d607a5cdb72d325fcf98db437627862fade839daad934bd9ccf02a6f6e34f9de8cb3b18d72fce2ba6cc019a5d22398187d7d69d2607165f27f8bf - languageName: node - linkType: hard - -"@stablelib/int@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/int@npm:1.0.1" - checksum: 10/65bfbf50a382eea70c68e05366bf379cfceff8fbc076f1c267ef2f2411d7aed64fd140c415cb6c29f19a3910d3b8b7805d4b32ad5721a5007a8e744a808c7ae3 - languageName: node - linkType: hard - -"@stablelib/random@npm:^1.0.1": - version: 1.0.2 - resolution: "@stablelib/random@npm:1.0.2" - dependencies: - "@stablelib/binary": "npm:^1.0.1" - "@stablelib/wipe": "npm:^1.0.1" - checksum: 10/f5ace0a588dc4c21f01cb85837892d4c872e994ae77a58a8eb7dd61aa0b26fb1e9b46b0445e71af57d963ef7d9f5965c64258fc0d04df7b2947bc48f2d3560c5 - languageName: node - linkType: hard - -"@stablelib/wipe@npm:^1.0.1": - version: 1.0.1 - resolution: "@stablelib/wipe@npm:1.0.1" - checksum: 10/287802eb146810a46ba72af70b82022caf83a8aeebde23605f5ee0decf64fe2b97a60c856e43b6617b5801287c30cfa863cfb0469e7fcde6f02d143cf0c6cbf4 - languageName: node - linkType: hard - "@swc/core-darwin-arm64@npm:1.11.31": version: 1.11.31 resolution: "@swc/core-darwin-arm64@npm:1.11.31" @@ -4384,13 +3136,6 @@ __metadata: languageName: node linkType: hard -"@tanstack/query-core@npm:^5.62.16": - version: 5.101.0 - resolution: "@tanstack/query-core@npm:5.101.0" - checksum: 10/9144f3365897c3902d983d3314e0eab888a46295356d654eab475045188ba336269e540f6d4ea807f5724c87af347fcd48ce1dc09b95b51d650c645c11db5235 - languageName: node - linkType: hard - "@types/babel__core@npm:^7.1.14": version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" @@ -4432,7 +3177,7 @@ __metadata: languageName: node linkType: hard -"@types/bn.js@npm:^5.1.0, @types/bn.js@npm:^5.1.5": +"@types/bn.js@npm:^5.1.5": version: 5.2.0 resolution: "@types/bn.js@npm:5.2.0" dependencies: @@ -4566,15 +3311,6 @@ __metadata: languageName: node linkType: hard -"@types/pbkdf2@npm:^3.0.0": - version: 3.1.2 - resolution: "@types/pbkdf2@npm:3.1.2" - dependencies: - "@types/node": "npm:*" - checksum: 10/bebe1e596cbbe5f7d2726a58859e61986c5a42459048e29cb7f2d4d764be6bbb0844572fd5d70ca8955a8a17e8b4ed80984fc4903e165d9efb8807a3fbb051aa - languageName: node - linkType: hard - "@types/prop-types@npm:*": version: 15.7.15 resolution: "@types/prop-types@npm:15.7.15" @@ -4582,13 +3318,6 @@ __metadata: languageName: node linkType: hard -"@types/punycode@npm:^2.1.0": - version: 2.1.4 - resolution: "@types/punycode@npm:2.1.4" - checksum: 10/16637bdd8e4f830243072668125f83b93b728085a05140ccc3e7801528d78c62cce5426b07d5cdc75e4f797e1644807c762777f651d1cd071ad0128835cdce5e - languageName: node - linkType: hard - "@types/react-dom@npm:18.2.4": version: 18.2.4 resolution: "@types/react-dom@npm:18.2.4" @@ -4625,15 +3354,6 @@ __metadata: languageName: node linkType: hard -"@types/secp256k1@npm:^4.0.1": - version: 4.0.7 - resolution: "@types/secp256k1@npm:4.0.7" - dependencies: - "@types/node": "npm:*" - checksum: 10/bcf7adbd953d2cb829ae98a3cd2f8eeb1e2316f4f6de720ee3863da90bd98899c08fa8c42748e8701cad16ede0898df69a6e7f22660d1fb3cb276d5c771069db - languageName: node - linkType: hard - "@types/semver@npm:^7, @types/semver@npm:^7.3.6": version: 7.5.8 resolution: "@types/semver@npm:7.5.8" @@ -4648,20 +3368,6 @@ __metadata: languageName: node linkType: hard -"@types/uuid@npm:^8.3.0": - version: 8.3.4 - resolution: "@types/uuid@npm:8.3.4" - checksum: 10/6f11f3ff70f30210edaa8071422d405e9c1d4e53abbe50fdce365150d3c698fe7bbff65c1e71ae080cbfb8fded860dbb5e174da96fdbbdfcaa3fb3daa474d20f - languageName: node - linkType: hard - -"@types/uuid@npm:^9.0.8": - version: 9.0.8 - resolution: "@types/uuid@npm:9.0.8" - checksum: 10/b8c60b7ba8250356b5088302583d1704a4e1a13558d143c549c408bf8920535602ffc12394ede77f8a8083511b023704bc66d1345792714002bfa261b17c5275 - languageName: node - linkType: hard - "@types/yargs-parser@npm:*": version: 21.0.3 resolution: "@types/yargs-parser@npm:21.0.3" @@ -5132,13 +3838,6 @@ __metadata: languageName: node linkType: hard -"aes-js@npm:3.0.0": - version: 3.0.0 - resolution: "aes-js@npm:3.0.0" - checksum: 10/1b3772e5ba74abdccb6c6b99bf7f50b49057b38c0db1612b46c7024414f16e65ba7f1643b2d6e38490b1870bdf3ba1b87b35e2c831fd3fdaeff015f08aad19d1 - languageName: node - linkType: hard - "aes-js@npm:4.0.0-beta.5": version: 4.0.0-beta.5 resolution: "aes-js@npm:4.0.0-beta.5" @@ -5146,13 +3845,6 @@ __metadata: languageName: node linkType: hard -"aes-js@npm:^3.1.2": - version: 3.1.2 - resolution: "aes-js@npm:3.1.2" - checksum: 10/b65916767034a51375a3ac5aad62af452d89a386c1ae7b607bb9145d0bb8b8823bf2f3eba85bdfa52d61c65d5aed90ba90f677b8c826bfa1a8b7ae2fa3b54d91 - languageName: node - linkType: hard - "agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": version: 7.1.1 resolution: "agent-base@npm:7.1.1" @@ -5286,7 +3978,7 @@ __metadata: languageName: node linkType: hard -"apg-js@npm:^4.1.1, apg-js@npm:^4.3.0": +"apg-js@npm:^4.1.1": version: 4.4.0 resolution: "apg-js@npm:4.4.0" checksum: 10/425f19096026742f5f156f26542b68f55602aa60f0c4ae2d72a0a888cf15fe9622223191202262dd8979d76a6125de9d8fd164d56c95fb113f49099f405eb08c @@ -5627,7 +4319,7 @@ __metadata: languageName: node linkType: hard -"bech32@npm:1.1.4, bech32@npm:^1.1.3": +"bech32@npm:^1.1.3": version: 1.1.4 resolution: "bech32@npm:1.1.4" checksum: 10/63ff37c0ce43be914c685ce89700bba1589c319af0dac1ea04f51b33d0e5ecfd40d14c24f527350b94f0a4e236385373bb9122ec276410f354ddcdbf29ca13f4 @@ -5757,20 +4449,6 @@ __metadata: languageName: node linkType: hard -"blakejs@npm:^1.1.0": - version: 1.2.1 - resolution: "blakejs@npm:1.2.1" - checksum: 10/0638b1bd058b21892633929c43005aa6a4cc4b2ac5b338a146c3c076622f1b360795bd7a4d1f077c9b01863ed2df0c1504a81c5b520d164179120434847e6cd7 - languageName: node - linkType: hard - -"bn.js@npm:4.11.6": - version: 4.11.6 - resolution: "bn.js@npm:4.11.6" - checksum: 10/22741b015c9fff60fce32fc9988331b298eb9b6db5bfb801babb23b846eaaf894e440e0d067b2b3ae4e46aab754e90972f8f333b31bf94a686bbcb054bfa7b14 - languageName: node - linkType: hard - "bn.js@npm:5.2.1": version: 5.2.1 resolution: "bn.js@npm:5.2.1" @@ -5785,7 +4463,7 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^5.1.2, bn.js@npm:^5.2.0, bn.js@npm:^5.2.1, bn.js@npm:^5.2.3": +"bn.js@npm:^5.2.1, bn.js@npm:^5.2.3": version: 5.2.5 resolution: "bn.js@npm:5.2.5" checksum: 10/10b1ac91e76fd828c1187cf65a9f1a0374e7afb9acd167e19c2d7c4108f6216841007c1e3aef145fa95cc7b3d07f705236a707184af1537667362b3a842d01ac @@ -7592,42 +6270,7 @@ __metadata: languageName: node linkType: hard -"eth-method-registry@npm:^4.0.0": - version: 4.0.0 - resolution: "eth-method-registry@npm:4.0.0" - dependencies: - "@metamask/ethjs-contract": "npm:^0.4.1" - "@metamask/ethjs-query": "npm:^0.7.1" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/959e833327960f40fab8693997e071def75103a694e931ab11313e642b6958d4f2878000d91ddfd6ba3c158bdc3f381c63eae0dd26738790e2aca5004ceb0387 - languageName: node - linkType: hard - -"ethereum-cryptography@npm:^0.1.3": - version: 0.1.3 - resolution: "ethereum-cryptography@npm:0.1.3" - dependencies: - "@types/pbkdf2": "npm:^3.0.0" - "@types/secp256k1": "npm:^4.0.1" - blakejs: "npm:^1.1.0" - browserify-aes: "npm:^1.2.0" - bs58check: "npm:^2.1.2" - create-hash: "npm:^1.2.0" - create-hmac: "npm:^1.1.7" - hash.js: "npm:^1.1.7" - keccak: "npm:^3.0.0" - pbkdf2: "npm:^3.0.17" - randombytes: "npm:^2.1.0" - safe-buffer: "npm:^5.1.2" - scrypt-js: "npm:^3.0.0" - secp256k1: "npm:^4.0.1" - setimmediate: "npm:^1.0.5" - checksum: 10/975e476782746acd97d5b37366801ae622a52fb31e5d83f600804be230a61ef7b9d289dcecd9c308fb441967caf3a6e3768dd7c8add6441fcc60c398175d5a96 - languageName: node - linkType: hard - -"ethereum-cryptography@npm:^2.0.0, ethereum-cryptography@npm:^2.1.2, ethereum-cryptography@npm:^2.2.1": +"ethereum-cryptography@npm:^2.0.0, ethereum-cryptography@npm:^2.2.1": version: 2.2.1 resolution: "ethereum-cryptography@npm:2.2.1" dependencies: @@ -7639,35 +6282,6 @@ __metadata: languageName: node linkType: hard -"ethereumjs-util@npm:^7.1.2": - version: 7.1.5 - resolution: "ethereumjs-util@npm:7.1.5" - dependencies: - "@types/bn.js": "npm:^5.1.0" - bn.js: "npm:^5.1.2" - create-hash: "npm:^1.1.2" - ethereum-cryptography: "npm:^0.1.3" - rlp: "npm:^2.2.4" - checksum: 10/f28fc1ebb8f35bf9e418f76f51be737d94d603b912c3e014c4e87cd45ccd1b10bdfef764c8f152574b57e9faa260a18773cbc110f9e0a754d6b3730699e54dc9 - languageName: node - linkType: hard - -"ethereumjs-wallet@npm:^1.0.1": - version: 1.0.2 - resolution: "ethereumjs-wallet@npm:1.0.2" - dependencies: - aes-js: "npm:^3.1.2" - bs58check: "npm:^2.1.2" - ethereum-cryptography: "npm:^0.1.3" - ethereumjs-util: "npm:^7.1.2" - randombytes: "npm:^2.1.0" - scrypt-js: "npm:^3.0.1" - utf8: "npm:^3.0.0" - uuid: "npm:^8.3.2" - checksum: 10/0a9ad0ac0930627c15e6fa6115dde8d1dd81160e57fbdf81ef0bcd1e0edd750fe9e8b00992651e694cabefee29eef2ad651dce8b24ae5253861927d0e19b6c90 - languageName: node - linkType: hard - "ethers@npm:^6.16.0": version: 6.16.0 resolution: "ethers@npm:6.16.0" @@ -7683,24 +6297,6 @@ __metadata: languageName: node linkType: hard -"ethjs-abi@npm:^0.2.0": - version: 0.2.1 - resolution: "ethjs-abi@npm:0.2.1" - dependencies: - bn.js: "npm:4.11.6" - js-sha3: "npm:0.5.5" - number-to-bn: "npm:1.7.0" - checksum: 10/733b2b95ae102f0813ad70848d42424b4b6204598892bee0e0fb435aafc7d356e479e489ee2d6b81fb2bd6e5ae6a9cdc0479bc35244b2efbe1a00a8da6735fbb - languageName: node - linkType: hard - -"ethjs-schema@npm:0.2.1": - version: 0.2.1 - resolution: "ethjs-schema@npm:0.2.1" - checksum: 10/9e2806518e208650a035aa2bc1e508a57c31ff629b46b63de4c7101e760f5e6987e6f8b70522eb44cf4a97d2c4c6348d1adaeea56915e75e4deadd1e176d5aa9 - languageName: node - linkType: hard - "event-target-shim@npm:^5.0.0": version: 5.0.1 resolution: "event-target-shim@npm:5.0.1" @@ -7925,13 +6521,6 @@ __metadata: languageName: node linkType: hard -"fast-json-patch@npm:^3.1.1": - version: 3.1.1 - resolution: "fast-json-patch@npm:3.1.1" - checksum: 10/3e56304e1c95ad1862a50e5b3f557a74c65c0ff2ba5b15caab983b43e70e86ddbc5bc887e9f7064f0aacfd0f0435a29ab2f000fe463379e72b906486345e6671 - languageName: node - linkType: hard - "fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" @@ -7977,17 +6566,6 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^4.4.1": - version: 4.5.6 - resolution: "fast-xml-parser@npm:4.5.6" - dependencies: - strnum: "npm:^1.0.5" - bin: - fxparser: src/cli/cli.js - checksum: 10/dd77cce4b1b322400339147b72b2d315bddc12c6ed3ca82bfc87543ced6dd8d81a6e0b429489e2f048f39258aa2023580654c8934881c633b9d58a6e79672349 - languageName: node - linkType: hard - "fast-xml-parser@npm:^5.5.6": version: 5.8.0 resolution: "fast-xml-parser@npm:5.8.0" @@ -8003,13 +6581,6 @@ __metadata: languageName: node linkType: hard -"fastest-levenshtein@npm:^1.0.16": - version: 1.0.16 - resolution: "fastest-levenshtein@npm:1.0.16" - checksum: 10/ee85d33b5cef592033f70e1c13ae8624055950b4eb832435099cd56aa313d7f251b873bedbc06a517adfaff7b31756d139535991e2406967438e03a1bf1b008e - languageName: node - linkType: hard - "fastq@npm:^1.6.0": version: 1.17.1 resolution: "fastq@npm:1.17.1" @@ -8579,7 +7150,7 @@ __metadata: languageName: node linkType: hard -"hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3, hash.js@npm:^1.1.7": +"hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": version: 1.1.7 resolution: "hash.js@npm:1.1.7" dependencies: @@ -8912,13 +7483,6 @@ __metadata: languageName: node linkType: hard -"is-fn@npm:^1.0.0": - version: 1.0.0 - resolution: "is-fn@npm:1.0.0" - checksum: 10/eeea1e536716f93a92dc1a8550b2c0909fe74bb5144d0fb6d65e0d31eb9c06c30559f69d83a9351d2288cc7293b43bc074e0fab5fae19e312ff38aa0c7672827 - languageName: node - linkType: hard - "is-fullwidth-code-point@npm:^3.0.0": version: 3.0.0 resolution: "is-fullwidth-code-point@npm:3.0.0" @@ -9696,13 +8260,6 @@ __metadata: languageName: node linkType: hard -"js-sha3@npm:0.5.5": - version: 0.5.5 - resolution: "js-sha3@npm:0.5.5" - checksum: 10/9ce8bfabdba2cfb94b911125fc278e2f46cc01b6590c98833d9361199e2c2b4bca0427d04da6aa083f05c2c3982029200964a3d6e417b0c126c80f2e32c2d5eb - languageName: node - linkType: hard - "js-sha3@npm:0.8.0": version: 0.8.0 resolution: "js-sha3@npm:0.8.0" @@ -9717,13 +8274,6 @@ __metadata: languageName: node linkType: hard -"js-sha3@npm:^0.9.2": - version: 0.9.3 - resolution: "js-sha3@npm:0.9.3" - checksum: 10/8daacb93b18609a0dc081f2f6199b80a96df36f9975b4b9c7476ae92822e07100b9e1969fc76f4b58e703cd6175f0de7656a99cbb2335cfb554c66f988fbead5 - languageName: node - linkType: hard - "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -9798,7 +8348,7 @@ __metadata: languageName: node linkType: hard -"json-rpc-random-id@npm:^1.0.0, json-rpc-random-id@npm:^1.0.1": +"json-rpc-random-id@npm:^1.0.0": version: 1.0.1 resolution: "json-rpc-random-id@npm:1.0.1" checksum: 10/fcd2e884193a129ace4002bd65a86e9cdb206733b4693baea77bd8b372cf8de3043fbea27716a2c9a716581a908ca8d978d9dfec4847eb2cf77edb4cf4b2252c @@ -9855,25 +8405,6 @@ __metadata: languageName: node linkType: hard -"jsonschema@npm:^1.4.1": - version: 1.5.0 - resolution: "jsonschema@npm:1.5.0" - checksum: 10/46bf49b388ba922073bcb3c8d5e90af9d29fc8303dc866fd440182c88d6b4fd2807679fd39cdefb4113156d104ea47da9c0ff4bbcb0032c9fa29461cb1a92182 - languageName: node - linkType: hard - -"keccak@npm:^3.0.0": - version: 3.0.4 - resolution: "keccak@npm:3.0.4" - dependencies: - node-addon-api: "npm:^2.0.0" - node-gyp: "npm:latest" - node-gyp-build: "npm:^4.2.0" - readable-stream: "npm:^3.6.0" - checksum: 10/45478bb0a57e44d0108646499b8360914b0fbc8b0e088f1076659cb34faaa9eb829c40f6dd9dadb3460bb86cc33153c41fed37fe5ce09465a60e71e78c23fa55 - languageName: node - linkType: hard - "keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -9991,13 +8522,6 @@ __metadata: languageName: node linkType: hard -"loglevel@npm:^1.8.1": - version: 1.9.2 - resolution: "loglevel@npm:1.9.2" - checksum: 10/6153d8db308323f7ee20130bc40309e7a976c30a10379d8666b596d9c6441965c3e074c8d7ee3347fe5cfc059c0375b6f3e8a10b93d5b813cc5547f5aa412a29 - languageName: node - linkType: hard - "lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -10499,15 +9023,6 @@ __metadata: languageName: node linkType: hard -"node-addon-api@npm:^2.0.0": - version: 2.0.2 - resolution: "node-addon-api@npm:2.0.2" - dependencies: - node-gyp: "npm:latest" - checksum: 10/e4ce4daac5b2fefa6b94491b86979a9c12d9cceba571d2c6df1eb5859f9da68e5dc198f128798e1785a88aafee6e11f4992dcccd4bf86bec90973927d158bd60 - languageName: node - linkType: hard - "node-addon-api@npm:^5.0.0": version: 5.1.0 resolution: "node-addon-api@npm:5.1.0" @@ -10663,16 +9178,6 @@ __metadata: languageName: node linkType: hard -"number-to-bn@npm:1.7.0": - version: 1.7.0 - resolution: "number-to-bn@npm:1.7.0" - dependencies: - bn.js: "npm:4.11.6" - strip-hex-prefix: "npm:1.0.0" - checksum: 10/702e8f00b6b90abd23f711056005179c3bd5ce3b063c47d468250f63ab3b9b4b82e27bff3b4642a9e71e06c717d5ed359873501746df0a64c3db1fa6d704e704 - languageName: node - linkType: hard - "object-inspect@npm:^1.13.3, object-inspect@npm:^1.13.4": version: 1.13.4 resolution: "object-inspect@npm:1.13.4" @@ -11079,7 +9584,7 @@ __metadata: languageName: node linkType: hard -"pbkdf2@npm:^3.0.17, pbkdf2@npm:^3.1.2, pbkdf2@npm:^3.1.5": +"pbkdf2@npm:^3.1.2, pbkdf2@npm:^3.1.5": version: 3.1.6 resolution: "pbkdf2@npm:3.1.6" dependencies: @@ -11114,13 +9619,6 @@ __metadata: languageName: node linkType: hard -"pify@npm:^5.0.0": - version: 5.0.0 - resolution: "pify@npm:5.0.0" - checksum: 10/443e3e198ad6bfa8c0c533764cf75c9d5bc976387a163792fb553ffe6ce923887cf14eebf5aea9b7caa8eab930da8c33612990ae85bd8c2bc18bedb9eae94ecb - languageName: node - linkType: hard - "pirates@npm:^4.0.4": version: 4.0.6 resolution: "pirates@npm:4.0.6" @@ -11254,16 +9752,6 @@ __metadata: languageName: node linkType: hard -"promise-to-callback@npm:^1.0.0": - version: 1.0.0 - resolution: "promise-to-callback@npm:1.0.0" - dependencies: - is-fn: "npm:^1.0.0" - set-immediate-shim: "npm:^1.0.1" - checksum: 10/d756ad74f7a202a6725c4281813c1052896327e4036c553adb8e3bbb91d0b1ff501965e7b00997827c016609caefbf24a5efc117dccca6000b8cbbc477b31cbf - languageName: node - linkType: hard - "prompts@npm:^2.0.1": version: 2.4.2 resolution: "prompts@npm:2.4.2" @@ -11319,7 +9807,7 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0, punycode@npm:^2.1.1, punycode@npm:^2.3.0": +"punycode@npm:^2.1.0, punycode@npm:^2.3.0": version: 2.3.1 resolution: "punycode@npm:2.3.1" checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 @@ -11540,13 +10028,6 @@ __metadata: languageName: node linkType: hard -"reselect@npm:^5.1.1": - version: 5.2.0 - resolution: "reselect@npm:5.2.0" - checksum: 10/e53d37a35f84132682b0a819d942ff7debea90fe126f4bb5eef0f21b1f48f45dec89d27990f2ef5865f5e05d64bb88fb41e4341eb276674aee6f1f7f7362c3e8 - languageName: node - linkType: hard - "resolve-cwd@npm:^3.0.0": version: 3.0.0 resolution: "resolve-cwd@npm:3.0.0" @@ -11710,17 +10191,6 @@ __metadata: languageName: node linkType: hard -"rlp@npm:^2.2.4": - version: 2.2.7 - resolution: "rlp@npm:2.2.7" - dependencies: - bn.js: "npm:^5.2.0" - bin: - rlp: bin/rlp - checksum: 10/cf1919a2dc99f336191b3363b76299db567c192b7ee3c6f5c722728c34f65577883c9c88eeb7a1bfcbc26693c8a4f1fb0662e79ee86f0c98dd258d6987303498 - languageName: node - linkType: hard - "router@npm:^2.2.0": version: 2.2.0 resolution: "router@npm:2.2.0" @@ -11784,13 +10254,6 @@ __metadata: languageName: node linkType: hard -"safe-stable-stringify@npm:^2.4.3": - version: 2.5.0 - resolution: "safe-stable-stringify@npm:2.5.0" - checksum: 10/2697fa186c17c38c3ca5309637b4ac6de2f1c3d282da27cd5e1e3c88eca0fb1f9aea568a6aabdf284111592c8782b94ee07176f17126031be72ab1313ed46c5c - languageName: node - linkType: hard - "safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" @@ -11821,13 +10284,6 @@ __metadata: languageName: node linkType: hard -"scrypt-js@npm:3.0.1, scrypt-js@npm:^3.0.0, scrypt-js@npm:^3.0.1": - version: 3.0.1 - resolution: "scrypt-js@npm:3.0.1" - checksum: 10/2f8aa72b7f76a6f9c446bbec5670f80d47497bccce98474203d89b5667717223eeb04a50492ae685ed7adc5a060fc2d8f9fd988f8f7ebdaf3341967f3aeff116 - languageName: node - linkType: hard - "secp256k1@npm:^3.0.1": version: 3.8.1 resolution: "secp256k1@npm:3.8.1" @@ -11845,18 +10301,6 @@ __metadata: languageName: node linkType: hard -"secp256k1@npm:^4.0.1": - version: 4.0.4 - resolution: "secp256k1@npm:4.0.4" - dependencies: - elliptic: "npm:^6.5.7" - node-addon-api: "npm:^5.0.0" - node-gyp: "npm:latest" - node-gyp-build: "npm:^4.2.0" - checksum: 10/45000f348c853df7c1e2b67c48efb062ae78c0620ab1a5cfb02fa20d3aad39c641f4e7a18b3de3b54a7c0cc1e0addeb8ecd9d88bc332e92df17a92b60c36122a - languageName: node - linkType: hard - "secp256k1@npm:^5.0.1": version: 5.0.1 resolution: "secp256k1@npm:5.0.1" @@ -11958,7 +10402,7 @@ __metadata: languageName: node linkType: hard -"ses@npm:^1.14.0, ses@npm:^1.15.0": +"ses@npm:^1.15.0": version: 1.15.0 resolution: "ses@npm:1.15.0" dependencies: @@ -11994,14 +10438,7 @@ __metadata: languageName: node linkType: hard -"set-immediate-shim@npm:^1.0.1": - version: 1.0.1 - resolution: "set-immediate-shim@npm:1.0.1" - checksum: 10/98c4d6778c98363436690a340077142ef11c1a8c8c6a78118242340c8e82bb2d66a1563707ef3f5455e7ff5cbee21c87e898b333cf3e7ed241bab12d19e9eab1 - languageName: node - linkType: hard - -"setimmediate@npm:^1.0.4, setimmediate@npm:^1.0.5": +"setimmediate@npm:^1.0.4": version: 1.0.5 resolution: "setimmediate@npm:1.0.5" checksum: 10/76e3f5d7f4b581b6100ff819761f04a984fa3f3990e72a6554b57188ded53efce2d3d6c0932c10f810b7c59414f85e2ab3c11521877d1dea1ce0b56dc906f485 @@ -12156,20 +10593,6 @@ __metadata: languageName: node linkType: hard -"siwe@npm:^2.3.2": - version: 2.3.2 - resolution: "siwe@npm:2.3.2" - dependencies: - "@spruceid/siwe-parser": "npm:^2.1.2" - "@stablelib/random": "npm:^1.0.1" - uri-js: "npm:^4.4.1" - valid-url: "npm:^1.0.9" - peerDependencies: - ethers: ^5.6.8 || ^6.0.8 - checksum: 10/6ea5ad9a9046fa916f85bf9d3092bc898f7e339d9c552714ea53ecc17daa4f78300c3cf7cc9c70fe57baf77dcee5cb38c6e1d692400b874cd84d297b1261918c - languageName: node - linkType: hard - "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -12485,13 +10908,6 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^1.0.5": - version: 1.1.2 - resolution: "strnum@npm:1.1.2" - checksum: 10/ccd6297a1fdaf0fc8ea0ea904acdae76878d49a4b0d98a70155df4bc081fd88eac5ec99fb150f3d1d1af065c1898d38420705259ba6c39aa850c671bcd54e35d - languageName: node - linkType: hard - "strnum@npm:^2.3.0": version: 2.3.0 resolution: "strnum@npm:2.3.0" @@ -12856,13 +11272,6 @@ __metadata: languageName: node linkType: hard -"tweetnacl@npm:^1.0.3": - version: 1.0.3 - resolution: "tweetnacl@npm:1.0.3" - checksum: 10/ca122c2f86631f3c0f6d28efb44af2a301d4a557a62a3e2460286b08e97567b258c2212e4ad1cfa22bd6a57edcdc54ba76ebe946847450ab0999e6d48ccae332 - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -12983,15 +11392,6 @@ __metadata: languageName: node linkType: hard -"ulid@npm:^2.3.0": - version: 2.4.0 - resolution: "ulid@npm:2.4.0" - bin: - ulid: bin/cli.js - checksum: 10/409ad0a703ea9f25d2a35cf790b767030a2c7b5ca0df6acb73669628156ab63bb97925a3fd7aaaf0b2384d39bd3ed2f7cd2c2de9f1171df6bc79b8c097865d92 - languageName: node - linkType: hard - "undici-types@npm:~6.19.2": version: 6.19.8 resolution: "undici-types@npm:6.19.8" @@ -13071,13 +11471,6 @@ __metadata: languageName: node linkType: hard -"utf8@npm:^3.0.0": - version: 3.0.0 - resolution: "utf8@npm:3.0.0" - checksum: 10/31d19c4faacbb65b09ebc1c21c32b20bdb0919c6f6773cee5001b99bb83f8e503e7233c08fc71ebb34f7cfebd95cec3243b81d90176097aa2f286cccb4ce866e - languageName: node - linkType: hard - "util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -13498,21 +11891,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.18.0": - version: 8.18.0 - resolution: "ws@npm:8.18.0" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 10/70dfe53f23ff4368d46e4c0b1d4ca734db2c4149c6f68bc62cb16fc21f753c47b35fcc6e582f3bdfba0eaeb1c488cddab3c2255755a5c3eecb251431e42b3ff6 - languageName: node - linkType: hard - "ws@npm:^7.3.1": version: 7.5.11 resolution: "ws@npm:7.5.11" From e3e8d202d6675afd37716a7bcb65987919ea74cc Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Fri, 24 Jul 2026 06:30:13 +0200 Subject: [PATCH 10/42] chore: recalculate shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index cee65a72..5c10e893 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "C9X038OBAsMzCepnsYCBE/PrF1cOwBA4ZJiC95SeeQE=", + "shasum": "gfNb9EXkuOELLw+o3V8RuwJBgcKJ5GxmFxtgYYMBfbE=", "location": { "npm": { "filePath": "dist/bundle.js", From 69b943d454d2e1323b018394b990c806b388e765 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Fri, 24 Jul 2026 06:30:33 +0200 Subject: [PATCH 11/42] fix: yarn dedupe --- yarn.lock | 93 +++---------------------------------------------------- 1 file changed, 5 insertions(+), 88 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3397059a..2f71630a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1443,20 +1443,7 @@ __metadata: languageName: node linkType: hard -"@metamask/approval-controller@npm:^9.0.1": - version: 9.0.1 - resolution: "@metamask/approval-controller@npm:9.0.1" - dependencies: - "@metamask/base-controller": "npm:^9.0.1" - "@metamask/messenger": "npm:^1.0.0" - "@metamask/rpc-errors": "npm:^7.0.2" - "@metamask/utils": "npm:^11.9.0" - nanoid: "npm:^3.3.8" - checksum: 10/980e7ded7022a887c11693226922f9814d160c93fe5297380addafebe9b6e9191ba3acc7bf54775c8c8eeb7e07bcfcaaf79cc90361ff18fa04c1d449eab2ed33 - languageName: node - linkType: hard - -"@metamask/approval-controller@npm:^9.0.2": +"@metamask/approval-controller@npm:^9.0.1, @metamask/approval-controller@npm:^9.0.2": version: 9.0.2 resolution: "@metamask/approval-controller@npm:9.0.2" dependencies: @@ -1576,28 +1563,7 @@ __metadata: languageName: node linkType: hard -"@metamask/controller-utils@npm:^12.0.0": - version: 12.1.0 - resolution: "@metamask/controller-utils@npm:12.1.0" - dependencies: - "@metamask/eth-query": "npm:^4.0.0" - "@metamask/ethjs-unit": "npm:^0.3.0" - "@metamask/utils": "npm:^11.9.0" - "@spruceid/siwe-parser": "npm:2.1.0" - "@types/bn.js": "npm:^5.1.5" - bignumber.js: "npm:^9.1.2" - bn.js: "npm:^5.2.1" - cockatiel: "npm:^3.1.2" - eth-ens-namehash: "npm:^2.0.8" - fast-deep-equal: "npm:^3.1.3" - lodash: "npm:^4.17.21" - peerDependencies: - "@babel/runtime": ^7.0.0 - checksum: 10/421b9685faefa481529e611a11cf005cd94ced8f4a15a6ea1aacd885417be0de6191ee414e0bcb0fff7ecade9e356a4d0f3d7c826e798ba47d65e412aa1df049 - languageName: node - linkType: hard - -"@metamask/controller-utils@npm:^12.3.0": +"@metamask/controller-utils@npm:^12.0.0, @metamask/controller-utils@npm:^12.3.0": version: 12.3.0 resolution: "@metamask/controller-utils@npm:12.3.0" dependencies: @@ -2024,7 +1990,7 @@ __metadata: languageName: node linkType: hard -"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.4.0, @metamask/slip44@npm:^4.5.0": +"@metamask/slip44@npm:^4.2.0, @metamask/slip44@npm:^4.5.0": version: 4.5.0 resolution: "@metamask/slip44@npm:4.5.0" checksum: 10/8450d4f5afa98e8f57c67a39f12aa413888c423505f22c05a3dc181be223f7742db017f54a99852acc3826abe74b22bf7247bccd78b810e509321c075e67516f @@ -2262,38 +2228,7 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-utils@npm:^12.0.0, @metamask/snaps-utils@npm:^12.1.0": - version: 12.2.1 - resolution: "@metamask/snaps-utils@npm:12.2.1" - dependencies: - "@babel/core": "npm:^7.23.2" - "@babel/types": "npm:^7.23.0" - "@metamask/key-tree": "npm:^10.1.1" - "@metamask/messenger": "npm:^1.2.0" - "@metamask/permission-controller": "npm:^13.1.1" - "@metamask/rpc-errors": "npm:^7.0.3" - "@metamask/slip44": "npm:^4.4.0" - "@metamask/snaps-registry": "npm:^4.0.0" - "@metamask/snaps-sdk": "npm:^11.1.1" - "@metamask/superstruct": "npm:^3.2.1" - "@metamask/utils": "npm:^11.11.0" - "@scure/base": "npm:^1.1.1" - chalk: "npm:^4.1.2" - cron-parser: "npm:^4.5.0" - fast-deep-equal: "npm:^3.1.3" - fast-json-stable-stringify: "npm:^2.1.0" - fast-xml-parser: "npm:^5.5.6" - luxon: "npm:^3.5.0" - marked: "npm:^12.0.1" - rfdc: "npm:^1.3.0" - semver: "npm:^7.5.4" - ses: "npm:^1.15.0" - validate-npm-package-name: "npm:^5.0.0" - checksum: 10/fda8caefa414d9755a2305b345b5bbbf30ee614215a49070449f314d5d906c645457cf0d7f4881a82f69d398aff5ad2fe9c648bbb2a5003c29c2d01e2f42f199 - languageName: node - linkType: hard - -"@metamask/snaps-utils@npm:^12.2.1, @metamask/snaps-utils@npm:^12.3.0, @metamask/snaps-utils@npm:^12.4.0": +"@metamask/snaps-utils@npm:^12.0.0, @metamask/snaps-utils@npm:^12.1.0, @metamask/snaps-utils@npm:^12.2.1, @metamask/snaps-utils@npm:^12.3.0, @metamask/snaps-utils@npm:^12.4.0": version: 12.4.0 resolution: "@metamask/snaps-utils@npm:12.4.0" dependencies: @@ -2349,14 +2284,7 @@ __metadata: languageName: node linkType: hard -"@metamask/superstruct@npm:^3.1.0, @metamask/superstruct@npm:^3.2.1": - version: 3.2.1 - resolution: "@metamask/superstruct@npm:3.2.1" - checksum: 10/9e29380f2cf8b129283ccb2b568296d92682b705109ba62dbd7739ffd6a1982fe38c7228cdcf3cbee94dbcdd5fcc1c846ab9d1dd3582167154f914422fcff547 - languageName: node - linkType: hard - -"@metamask/superstruct@npm:^3.3.0, @metamask/superstruct@npm:^3.4.1": +"@metamask/superstruct@npm:^3.1.0, @metamask/superstruct@npm:^3.2.1, @metamask/superstruct@npm:^3.3.0, @metamask/superstruct@npm:^3.4.1": version: 3.4.1 resolution: "@metamask/superstruct@npm:3.4.1" checksum: 10/d37b5662dc9bbe0d99e06eb951167fa745829ae3abfa103423e9d8c05e8712f1451376f8479d484722e1e1c1d881732da1efddccaca8868b530a786264b903b5 @@ -10402,17 +10330,6 @@ __metadata: languageName: node linkType: hard -"ses@npm:^1.15.0": - version: 1.15.0 - resolution: "ses@npm:1.15.0" - dependencies: - "@endo/cache-map": "npm:^1.1.0" - "@endo/env-options": "npm:^1.1.11" - "@endo/immutable-arraybuffer": "npm:^1.1.2" - checksum: 10/494894d35de847103ca0e4357632d80436c0e3dbc0e0bf98448a962d2257cb9045db9c6e7737b4003846a690318fcf5c06ef5a9a51c8b47cd4ffeaf2fa330155 - languageName: node - linkType: hard - "ses@npm:^2.1.0": version: 2.2.0 resolution: "ses@npm:2.2.0" From 9c9e31eb685cbfb32ba08ae244e4aaadd5c9c698 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Fri, 24 Jul 2026 06:31:32 +0200 Subject: [PATCH 12/42] fix: lint errors, formatting, dedupe, and shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- .../src/handlers/KeyringHandler.test.ts | 2 +- .../src/handlers/KeyringHandler.ts | 13 ++++++------- .../src/handlers/parsers.test.ts | 1 - .../src/store/BdkAccountRepository.ts | 3 ++- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index 5c10e893..f2efa374 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "gfNb9EXkuOELLw+o3V8RuwJBgcKJ5GxmFxtgYYMBfbE=", + "shasum": "Og6WiO8hv0+dpZLlwpO0seuLw9tO7y1G7f7oAWvazZ0=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts index 0603a56f..347a5180 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts @@ -26,10 +26,10 @@ import { assert } from 'superstruct'; import type { BitcoinAccount, Logger, SnapClient } from '../entities'; import { AccountCapability, CurrencyUnit } from '../entities'; +import type { AccountUseCases } from '../use-cases/AccountUseCases'; import { Caip19Asset } from './caip'; import { KeyringHandler } from './KeyringHandler'; import type { KeyringRequestHandler } from './KeyringRequestHandler'; -import type { AccountUseCases } from '../use-cases/AccountUseCases'; jest.mock('superstruct', () => ({ ...jest.requireActual('superstruct'), diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 93a66994..6c68dc98 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -29,24 +29,23 @@ import { sensitive } from '@metamask/superstruct'; import { assert, is, string } from 'superstruct'; import { encode } from 'wif'; +import snapManifest from '../../snap.manifest.json'; +import type { Logger, SnapClient } from '../entities'; import { computeDisplayBalanceSats, FormatError, - type Logger, networkToCurrencyUnit, - type SnapClient, } from '../entities'; +import type { + AccountUseCases, + CreateAccountParams, +} from '../use-cases/AccountUseCases'; import { NetworkStruct, networkToCaip19, scopeToNetwork } from './caip'; import { CronMethod } from './CronHandler'; import type { KeyringRequestHandler } from './KeyringRequestHandler'; import { mapToKeyringAccount, mapToTransaction } from './mappings'; import { parseDerivationPath } from './parsers'; import { BtcWalletRequestStruct, validateSelectedAccounts } from './validation'; -import snapManifest from '../../snap.manifest.json'; -import type { - AccountUseCases, - CreateAccountParams, -} from '../use-cases/AccountUseCases'; /** Maximum number of accounts to create in one internal createMany call. */ const MAX_CREATE_ACCOUNTS_PER_BATCH = 100; diff --git a/packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts b/packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts index 9222859c..069684da 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/parsers.test.ts @@ -2,7 +2,6 @@ import { FormatError } from '../entities'; import { parseDerivationPath } from './parsers'; jest.mock('@metamask/bitcoindevkit', () => ({ - // eslint-disable-next-line @typescript-eslint/naming-convention Psbt: { from_string: jest.fn() }, })); diff --git a/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts b/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts index 02c1b61a..44d1232d 100644 --- a/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts +++ b/packages/bitcoin-wallet-snap/src/store/BdkAccountRepository.ts @@ -93,7 +93,8 @@ export class BdkAccountRepository implements BitcoinAccountRepository { async getAll(): Promise { const accounts = (await this.#snapClient.getState('accounts')) as - SnapState['accounts'] | null; + | SnapState['accounts'] + | null; if (!accounts) { return []; } From c5280b21fea4c4f92525af88f21fe46ab5cc01a9 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Fri, 24 Jul 2026 06:32:47 +0200 Subject: [PATCH 13/42] docs: add PR links to changelog entries --- packages/bitcoin-wallet-snap/CHANGELOG.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/bitcoin-wallet-snap/CHANGELOG.md b/packages/bitcoin-wallet-snap/CHANGELOG.md index 23af9fb3..bdd7460f 100644 --- a/packages/bitcoin-wallet-snap/CHANGELOG.md +++ b/packages/bitcoin-wallet-snap/CHANGELOG.md @@ -9,15 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Add support for keyring API v2, including `bip44:derive-path`, `bip44:derive-index`, `bip44:derive-index-range`, and `bip44:discover` account creation types -- Add `exportAccount` method supporting WIF (base58) private key export -- Add `parseDerivationPath` to validate and parse BIP-44 derivation paths for native segwit (BIP-84) accounts +- Add support for keyring API v2, including `bip44:derive-path`, `bip44:derive-index`, `bip44:derive-index-range`, and `bip44:discover` account creation types ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Add `exportAccount` method supporting WIF (base58) private key export ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Add `parseDerivationPath` to validate and parse BIP-44 derivation paths for native segwit (BIP-84) accounts ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) ### Changed -- Migrate `KeyringHandler` to implement `KeyringSnapRpc` from `@metamask/keyring-api/v2` -- Update `snap.manifest.json` to declare `derivePath` capability in the `bip44` keyring block -- Mark accounts as exportable in the keyring account mapping +- Migrate `KeyringHandler` to implement `KeyringSnapRpc` from `@metamask/keyring-api/v2` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Update `snap.manifest.json` to declare `derivePath` capability in the `bip44` keyring block ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Mark accounts as exportable in the keyring account mapping ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) ## [1.15.2] From 62785316981115b73bcbf17bc421a2c984672a12 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Fri, 24 Jul 2026 06:37:07 +0200 Subject: [PATCH 14/42] fix: use replaceAll to strip hardening apostrophes in parseDerivationPath --- packages/bitcoin-wallet-snap/src/handlers/parsers.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/parsers.ts b/packages/bitcoin-wallet-snap/src/handlers/parsers.ts index eb1cf62b..b313f378 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/parsers.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/parsers.ts @@ -26,9 +26,9 @@ export function parseDerivationPath(path: string): ParsedDerivationPath { ); } - const purpose = parts[1]?.replace("'", ''); - const coinType = parts[2]?.replace("'", ''); - const accountSegment = parts[3]?.replace("'", ''); + const purpose = parts[1]?.replaceAll("'", ''); + const coinType = parts[2]?.replaceAll("'", ''); + const accountSegment = parts[3]?.replaceAll("'", ''); if (purpose !== '84') { throw new FormatError( From 1dcdc910d259d5a739d9b65765c28787c8074404 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Fri, 24 Jul 2026 06:43:58 +0200 Subject: [PATCH 15/42] chore: recalculate shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index f2efa374..38b2ee44 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "Og6WiO8hv0+dpZLlwpO0seuLw9tO7y1G7f7oAWvazZ0=", + "shasum": "08ziFABi7aVkKWheElPHudZtReVStSb9R1d7KEKDPX0=", "location": { "npm": { "filePath": "dist/bundle.js", From 4ede53f9fcafc2423a8b073b6b47855b79e2dc6d Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Fri, 24 Jul 2026 22:51:24 +0200 Subject: [PATCH 16/42] chore: update keyring-api --- packages/bitcoin-wallet-snap/package.json | 2 +- yarn.lock | 26 +++++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/bitcoin-wallet-snap/package.json b/packages/bitcoin-wallet-snap/package.json index 16862c9c..3cea30c4 100644 --- a/packages/bitcoin-wallet-snap/package.json +++ b/packages/bitcoin-wallet-snap/package.json @@ -59,7 +59,7 @@ "@metamask/auto-changelog": "^6.1.0", "@metamask/bitcoindevkit": "^0.1.13", "@metamask/key-tree": "^10.1.1", - "@metamask/keyring-api": "^23.5.0", + "@metamask/keyring-api": "^23.7.0", "@metamask/keyring-snap-sdk": "^9.2.0", "@metamask/slip44": "^4.2.0", "@metamask/snaps-cli": "^8.4.1", diff --git a/yarn.lock b/yarn.lock index 2f71630a..188298ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1498,7 +1498,7 @@ __metadata: "@metamask/auto-changelog": "npm:^6.1.0" "@metamask/bitcoindevkit": "npm:^0.1.13" "@metamask/key-tree": "npm:^10.1.1" - "@metamask/keyring-api": "npm:^23.5.0" + "@metamask/keyring-api": "npm:^23.7.0" "@metamask/keyring-snap-sdk": "npm:^9.2.0" "@metamask/slip44": "npm:^4.2.0" "@metamask/snaps-cli": "npm:^8.4.1" @@ -1791,15 +1791,15 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^23.5.0": - version: 23.5.0 - resolution: "@metamask/keyring-api@npm:23.5.0" +"@metamask/keyring-api@npm:^23.7.0": + version: 23.7.0 + resolution: "@metamask/keyring-api@npm:23.7.0" dependencies: - "@metamask/keyring-utils": "npm:^3.3.1" - "@metamask/superstruct": "npm:^3.3.0" + "@metamask/keyring-utils": "npm:^4.0.0" + "@metamask/superstruct": "npm:^3.4.1" "@metamask/utils": "npm:^11.11.0" bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/2d8a4b378f5bad77284feb58bc7f3b64d541751527c693e43f7e4d860333bc55593e27fc5264fc908d719912b374f77dabec3f5e491bb49f72501fd2f5c43e68 + checksum: 10/3c1aea064e017be0b99202a4e59b7ed9e1965aeb732b04ad5cb252dfa6b443487284f8b4253986ca325d8b45fd7977cef93f470f95f0342d377551d4b93738c3 languageName: node linkType: hard @@ -1831,6 +1831,18 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-utils@npm:^4.0.0": + version: 4.0.0 + resolution: "@metamask/keyring-utils@npm:4.0.0" + dependencies: + "@ethereumjs/tx": "npm:^5.4.0" + "@metamask/superstruct": "npm:^3.4.1" + "@metamask/utils": "npm:^11.11.0" + bitcoin-address-validation: "npm:^2.2.3" + checksum: 10/a4299fafadd4a4f2f1a4475a7f4e6c4d268ccfa82e505cdd4cf4a1ff5cc6ca485edd7422650c498409db93d4fe32429db7bd02276ce6fee80aac5f6a64439578 + languageName: node + linkType: hard + "@metamask/messenger@npm:^1.0.0, @metamask/messenger@npm:^1.1.1, @metamask/messenger@npm:^1.2.0": version: 1.2.0 resolution: "@metamask/messenger@npm:1.2.0" From 6022074bc8c8f73c976c7770850db8cc90641f77 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 11:30:00 +0200 Subject: [PATCH 17/42] refactor: move entropy assignment into try/catch --- .../src/handlers/KeyringHandler.ts | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 6c68dc98..2874dad5 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -241,21 +241,23 @@ export class KeyringHandler implements KeyringSnapRpc { const account = await this.#accountsUseCases.get(accountId); - const entropy = await this.#snapClient.getPrivateEntropy( - // Export the private key for address index 0 (the primary address). - account.derivationPath.concat(['0', '0']), - ); - - if (!entropy.privateKey) { - throw new Error('Failed to get private entropy'); - } + let privateKey; try { + const entropy = await this.#snapClient.getPrivateEntropy( + // Export the private key for address index 0 (the primary address). + account.derivationPath.concat(['0', '0']), + ); + + if (!entropy.privateKey) { + throw new Error('Failed to get private entropy'); + } + privateKey = entropy.privateKey; // Private key is returned in "0x..." format; transform to WIF (Base58Check). const wifPrivateKey = encode({ version: account.network === 'bitcoin' ? 128 : 239, // 128 mainnet, 239 testnets // eslint-disable-next-line no-restricted-globals - privateKey: Buffer.from(entropy.privateKey.slice(2), 'hex'), + privateKey: Buffer.from(privateKey.slice(2), 'hex'), compressed: true, }); From 3bce0bab4a6c3a68dc83418d7c47d611decf9525 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 12:05:37 +0200 Subject: [PATCH 18/42] chore: recalculate shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index 38b2ee44..e763819d 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "08ziFABi7aVkKWheElPHudZtReVStSb9R1d7KEKDPX0=", + "shasum": "D5PoAKktMf8UglPvKeZCc+9PCOnLRyY99CGB4r6uyOM=", "location": { "npm": { "filePath": "dist/bundle.js", From eac6f8254ebc2c5980786aabede08902204a31b3 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 12:17:48 +0200 Subject: [PATCH 19/42] fix: update test --- .../bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts index 347a5180..b14a97b4 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts @@ -596,7 +596,7 @@ describe('KeyringHandler', () => { } as never); await expect(handler.exportAccount(accountId)).rejects.toThrow( - 'Failed to get private entropy', + 'Error exporting account', ); }); From cbc90056843f58e5c0afb7a90208779c65ff1963 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 16:24:30 +0200 Subject: [PATCH 20/42] chore: add breaking entry in changelog --- packages/bitcoin-wallet-snap/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/bitcoin-wallet-snap/CHANGELOG.md b/packages/bitcoin-wallet-snap/CHANGELOG.md index bdd7460f..a21d70a7 100644 --- a/packages/bitcoin-wallet-snap/CHANGELOG.md +++ b/packages/bitcoin-wallet-snap/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **BREAKING** Remove v1 keyring API support (`createAccount`, v1 `Keyring` interface) in favour of v2 ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) - Migrate `KeyringHandler` to implement `KeyringSnapRpc` from `@metamask/keyring-api/v2` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) - Update `snap.manifest.json` to declare `derivePath` capability in the `bip44` keyring block ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) - Mark accounts as exportable in the keyring account mapping ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) From 43b40814abbf7729ea55742573305a11b9948a21 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 16:29:20 +0200 Subject: [PATCH 21/42] fix: merge conflicts --- packages/bitcoin-wallet-snap/package.json | 6 - .../bitcoin-wallet-snap/snap.manifest.json | 4 - yarn.lock | 119 +----------------- 3 files changed, 5 insertions(+), 124 deletions(-) diff --git a/packages/bitcoin-wallet-snap/package.json b/packages/bitcoin-wallet-snap/package.json index dfeb3eff..b3505340 100644 --- a/packages/bitcoin-wallet-snap/package.json +++ b/packages/bitcoin-wallet-snap/package.json @@ -55,16 +55,10 @@ "@metamask/keyring-api": "^23.7.0", "@metamask/keyring-snap-sdk": "^9.2.0", "@metamask/slip44": "^4.2.0", -<<<<<<< HEAD "@metamask/snaps-cli": "^8.4.1", "@metamask/snaps-jest": "^10.2.0", "@metamask/snaps-sdk": "^11.2.0", "@metamask/superstruct": "^3.4.1", -======= - "@metamask/snaps-cli": "^8.3.0", - "@metamask/snaps-jest": "^10.2.0", - "@metamask/snaps-sdk": "^11.0.0", ->>>>>>> origin/main "@metamask/utils": "^11.9.0", "bip322-js": "^3.0.0", "concurrently": "^10.0.3", diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index deb5b206..e763819d 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,11 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { -<<<<<<< HEAD "shasum": "D5PoAKktMf8UglPvKeZCc+9PCOnLRyY99CGB4r6uyOM=", -======= - "shasum": "/dethkzXlpMwXncvw8la75osM09uRRleSemtosb149Y=", ->>>>>>> origin/main "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/yarn.lock b/yarn.lock index 827f7955..d295094f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1725,16 +1725,10 @@ __metadata: "@metamask/keyring-api": "npm:^23.7.0" "@metamask/keyring-snap-sdk": "npm:^9.2.0" "@metamask/slip44": "npm:^4.2.0" -<<<<<<< HEAD "@metamask/snaps-cli": "npm:^8.4.1" "@metamask/snaps-jest": "npm:^10.2.0" "@metamask/snaps-sdk": "npm:^11.2.0" "@metamask/superstruct": "npm:^3.4.1" -======= - "@metamask/snaps-cli": "npm:^8.3.0" - "@metamask/snaps-jest": "npm:^10.2.0" - "@metamask/snaps-sdk": "npm:^11.0.0" ->>>>>>> origin/main "@metamask/utils": "npm:^11.9.0" bip322-js: "npm:^3.0.0" concurrently: "npm:^10.0.3" @@ -2021,7 +2015,6 @@ __metadata: languageName: node linkType: hard -<<<<<<< HEAD "@metamask/keyring-api@npm:^23.7.0": version: 23.7.0 resolution: "@metamask/keyring-api@npm:23.7.0" @@ -2035,65 +2028,21 @@ __metadata: linkType: hard "@metamask/keyring-snap-sdk@npm:^9.2.0": - version: 9.2.0 - resolution: "@metamask/keyring-snap-sdk@npm:9.2.0" + version: 9.2.1 + resolution: "@metamask/keyring-snap-sdk@npm:9.2.1" dependencies: - "@metamask/keyring-utils": "npm:^3.3.1" + "@metamask/keyring-utils": "npm:^4.0.0" "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/superstruct": "npm:^3.3.0" + "@metamask/superstruct": "npm:^3.4.1" "@metamask/utils": "npm:^11.11.0" webextension-polyfill: "npm:^0.12.0" peerDependencies: "@metamask/keyring-api": ^23.0.0 "@metamask/providers": ^19.0.0 - checksum: 10/2fcce104e314f9dcea3125741d50875c26b4b9d0241f66568e513e221abd121af88f6842c2a459f7984d9147158936c58ae9936561d703429fbc4d2eccd9611c - languageName: node - linkType: hard - -"@metamask/keyring-utils@npm:^3.3.1": -======= -"@metamask/keyring-api@npm:^22.0.0": - version: 22.0.0 - resolution: "@metamask/keyring-api@npm:22.0.0" - dependencies: - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/ff1e9537c7219fb906b61d6755de28890239ec44f634732bd8571801c662e8b801671e98961a1c5047e079cef314353297499a52f7091a2b5391325d575ec4f9 - languageName: node - linkType: hard - -"@metamask/keyring-snap-sdk@npm:^8.0.0": - version: 8.0.0 - resolution: "@metamask/keyring-snap-sdk@npm:8.0.0" - dependencies: - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - webextension-polyfill: "npm:^0.12.0" - peerDependencies: - "@metamask/keyring-api": ^22.0.0 - "@metamask/providers": ^19.0.0 - checksum: 10/271b4f84d214813c0312ffbbe3fb6201b66172210da4d06a155c3ddb359403ed1fa4c7afa424cd34fa9db04e3c876f30f69afb676bb7a905d392552d871ebd57 + checksum: 10/90b01fca9cc1d055b3830e8a7d2503b40421c9ddc4e20b0db25fade73c430ac56bb482f340cd82a08a5013d76e0b8d8265c953b71f5e29be2c5e538d5cedd9e4 languageName: node linkType: hard -"@metamask/keyring-utils@npm:^3.2.0": ->>>>>>> origin/main - version: 3.3.1 - resolution: "@metamask/keyring-utils@npm:3.3.1" - dependencies: - "@ethereumjs/tx": "npm:^5.4.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.11.0" - bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/d0917b2f634d9eb2f563827739fca00c1675ee90674ec49b2b68afcb604aee843d6c5be5d79e9780fa22d29f71fc876f40b2d3d0ed4cab7f5948937ddd276691 - languageName: node - linkType: hard - -<<<<<<< HEAD "@metamask/keyring-utils@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/keyring-utils@npm:4.0.0" @@ -2106,8 +2055,6 @@ __metadata: languageName: node linkType: hard -======= ->>>>>>> origin/main "@metamask/messenger@npm:^1.0.0, @metamask/messenger@npm:^1.1.1, @metamask/messenger@npm:^1.2.0": version: 1.2.0 resolution: "@metamask/messenger@npm:1.2.0" @@ -2245,15 +2192,9 @@ __metadata: dependencies: "@jest/globals": "npm:^29.5.0" "@metamask/auto-changelog": "npm:^6.1.0" -<<<<<<< HEAD "@metamask/snaps-cli": "npm:^8.4.1" "@metamask/snaps-jest": "npm:^10.2.0" "@metamask/snaps-sdk": "npm:^11.2.0" -======= - "@metamask/snaps-cli": "npm:^8.3.0" - "@metamask/snaps-jest": "npm:^10.2.0" - "@metamask/snaps-sdk": "npm:^11.0.0" ->>>>>>> origin/main "@types/react": "npm:18.2.4" "@types/react-dom": "npm:18.2.4" eslint: "npm:^9.39.1" @@ -2567,22 +2508,14 @@ __metadata: languageName: node linkType: hard -<<<<<<< HEAD "@metamask/superstruct@npm:^3.1.0, @metamask/superstruct@npm:^3.2.1, @metamask/superstruct@npm:^3.3.0, @metamask/superstruct@npm:^3.4.1": -======= -"@metamask/superstruct@npm:^3.1.0, @metamask/superstruct@npm:^3.2.1, @metamask/superstruct@npm:^3.3.0": ->>>>>>> origin/main version: 3.4.1 resolution: "@metamask/superstruct@npm:3.4.1" checksum: 10/d37b5662dc9bbe0d99e06eb951167fa745829ae3abfa103423e9d8c05e8712f1451376f8479d484722e1e1c1d881732da1efddccaca8868b530a786264b903b5 languageName: node linkType: hard -<<<<<<< HEAD "@metamask/utils@npm:^11.0.1, @metamask/utils@npm:^11.10.0, @metamask/utils@npm:^11.11.0, @metamask/utils@npm:^11.4.0, @metamask/utils@npm:^11.4.2, @metamask/utils@npm:^11.8.1, @metamask/utils@npm:^11.9.0": -======= -"@metamask/utils@npm:^11.0.1, @metamask/utils@npm:^11.1.0, @metamask/utils@npm:^11.10.0, @metamask/utils@npm:^11.11.0, @metamask/utils@npm:^11.4.0, @metamask/utils@npm:^11.4.2, @metamask/utils@npm:^11.8.1, @metamask/utils@npm:^11.9.0": ->>>>>>> origin/main version: 11.11.0 resolution: "@metamask/utils@npm:11.11.0" dependencies: @@ -2618,8 +2551,6 @@ __metadata: languageName: node linkType: hard -<<<<<<< HEAD -======= "@napi-rs/wasm-runtime@npm:^1.1.4": version: 1.1.6 resolution: "@napi-rs/wasm-runtime@npm:1.1.6" @@ -2632,7 +2563,6 @@ __metadata: languageName: node linkType: hard ->>>>>>> origin/main "@noble/curves@npm:1.2.0": version: 1.2.0 resolution: "@noble/curves@npm:1.2.0" @@ -3393,9 +3323,6 @@ __metadata: languageName: node linkType: hard -<<<<<<< HEAD -"@types/babel__core@npm:^7.1.14": -======= "@tybys/wasm-util@npm:^0.10.3": version: 0.10.3 resolution: "@tybys/wasm-util@npm:0.10.3" @@ -3406,7 +3333,6 @@ __metadata: linkType: hard "@types/babel__core@npm:^7.20.5": ->>>>>>> origin/main version: 7.20.5 resolution: "@types/babel__core@npm:7.20.5" dependencies: @@ -8950,13 +8876,8 @@ __metadata: node-notifier: optional: true bin: -<<<<<<< HEAD - jest: bin/jest.js - checksum: 10/97023d78446098c586faaa467fbf2c6b07ff06e2c85a19e3926adb5b0effe9ac60c4913ae03e2719f9c01ae8ffd8d92f6b262cedb9555ceeb5d19263d8c6362a -======= jest: ./bin/jest.js checksum: 10/69b569854a92fa8ab06d97807177323997864bd2bf2b330b504a29bb8c3cfd51a914d42ccb72987ac3763b8c055dd31b80526a2d5092e1bbf101714b37611fb6 ->>>>>>> origin/main languageName: node linkType: hard @@ -10321,17 +10242,10 @@ __metadata: languageName: node linkType: hard -<<<<<<< HEAD -"pirates@npm:^4.0.4": - version: 4.0.6 - resolution: "pirates@npm:4.0.6" - checksum: 10/d02dda76f4fec1cbdf395c36c11cf26f76a644f9f9a1bfa84d3167d0d3154d5289aacc72677aa20d599bb4a6937a471de1b65c995e2aea2d8687cbcd7e43ea5f -======= "pirates@npm:^4.0.4, pirates@npm:^4.0.7": version: 4.0.7 resolution: "pirates@npm:4.0.7" checksum: 10/2427f371366081ae42feb58214f04805d6b41d6b84d74480ebcc9e0ddbd7105a139f7c653daeaf83ad8a1a77214cf07f64178e76de048128fec501eab3305a96 ->>>>>>> origin/main languageName: node linkType: hard @@ -10484,19 +10398,6 @@ __metadata: languageName: node linkType: hard -<<<<<<< HEAD -"prompts@npm:^2.0.1": - version: 2.4.2 - resolution: "prompts@npm:2.4.2" - dependencies: - kleur: "npm:^3.0.3" - sisteransi: "npm:^1.0.5" - checksum: 10/c52536521a4d21eff4f2f2aa4572446cad227464066365a7167e52ccf8d9839c099f9afec1aba0eed3d5a2514b3e79e0b3e7a1dc326b9acde6b75d27ed74b1a9 - languageName: node - linkType: hard - -======= ->>>>>>> origin/main "propagate@npm:^2.0.0": version: 2.0.1 resolution: "propagate@npm:2.0.1" @@ -11310,16 +11211,6 @@ __metadata: languageName: node linkType: hard -<<<<<<< HEAD -"sisteransi@npm:^1.0.5": - version: 1.0.5 - resolution: "sisteransi@npm:1.0.5" - checksum: 10/aba6438f46d2bfcef94cf112c835ab395172c75f67453fe05c340c770d3c402363018ae1ab4172a1026a90c47eaccf3af7b6ff6fa749a680c2929bd7fa2b37a4 - languageName: node - linkType: hard - -======= ->>>>>>> origin/main "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" From 88e471022d986c7f79cbcb2c474626073f71f7a9 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 17:09:05 +0200 Subject: [PATCH 22/42] feat: add defensive measure for account export --- .../bitcoin-wallet-snap/src/handlers/KeyringHandler.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 2874dad5..21b45d84 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -3,6 +3,7 @@ import { Amount } from '@metamask/bitcoindevkit'; import { AccountCreationType, assertCreateAccountOptionIsSupported, + BtcAccountType, } from '@metamask/keyring-api'; import type { Balance, @@ -241,6 +242,13 @@ export class KeyringHandler implements KeyringSnapRpc { const account = await this.#accountsUseCases.get(accountId); + const accountType = account.addressType ?? 'p2wpkh'; + if (accountType !== 'p2wpkh') { + throw new SnapError( + `Only native segwit (${BtcAccountType.P2wpkh}) accounts are supported for private key export`, + ); + } + let privateKey; try { From 156ee6d2a7225d9ef09e1af698cad4a5235770c1 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 17:09:41 +0200 Subject: [PATCH 23/42] chore: recalculate shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index e763819d..af5ab48b 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "D5PoAKktMf8UglPvKeZCc+9PCOnLRyY99CGB4r6uyOM=", + "shasum": "PSyOnLVTpo71RYfiMKEyjODYb3smyUa9aWdR9XPAdpk=", "location": { "npm": { "filePath": "dist/bundle.js", From aa59faeebcf1b3cad3d94bf0998f514b885bdb4c Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 17:17:51 +0200 Subject: [PATCH 24/42] chore: bump keyring-snap-sdk --- packages/bitcoin-wallet-snap/package.json | 2 +- yarn.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/bitcoin-wallet-snap/package.json b/packages/bitcoin-wallet-snap/package.json index b3505340..938f78a1 100644 --- a/packages/bitcoin-wallet-snap/package.json +++ b/packages/bitcoin-wallet-snap/package.json @@ -53,7 +53,7 @@ "@metamask/bitcoindevkit": "^0.1.13", "@metamask/key-tree": "^10.1.1", "@metamask/keyring-api": "^23.7.0", - "@metamask/keyring-snap-sdk": "^9.2.0", + "@metamask/keyring-snap-sdk": "^9.2.1", "@metamask/slip44": "^4.2.0", "@metamask/snaps-cli": "^8.4.1", "@metamask/snaps-jest": "^10.2.0", diff --git a/yarn.lock b/yarn.lock index d295094f..d5ed05c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1723,7 +1723,7 @@ __metadata: "@metamask/bitcoindevkit": "npm:^0.1.13" "@metamask/key-tree": "npm:^10.1.1" "@metamask/keyring-api": "npm:^23.7.0" - "@metamask/keyring-snap-sdk": "npm:^9.2.0" + "@metamask/keyring-snap-sdk": "npm:^9.2.1" "@metamask/slip44": "npm:^4.2.0" "@metamask/snaps-cli": "npm:^8.4.1" "@metamask/snaps-jest": "npm:^10.2.0" @@ -2027,7 +2027,7 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-snap-sdk@npm:^9.2.0": +"@metamask/keyring-snap-sdk@npm:^9.2.1": version: 9.2.1 resolution: "@metamask/keyring-snap-sdk@npm:9.2.1" dependencies: From 452aaf4f61bce982f58e6a4a574e24c85f99709b Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 17:29:28 +0200 Subject: [PATCH 25/42] refactor: use defaultAddressType --- packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 21b45d84..8e66c61f 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -242,7 +242,7 @@ export class KeyringHandler implements KeyringSnapRpc { const account = await this.#accountsUseCases.get(accountId); - const accountType = account.addressType ?? 'p2wpkh'; + const accountType = this.#defaultAddressType; if (accountType !== 'p2wpkh') { throw new SnapError( `Only native segwit (${BtcAccountType.P2wpkh}) accounts are supported for private key export`, From 27e9e9b1bf87de0aa8e9ff1cf6d17aaa09971d9b Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 17:30:01 +0200 Subject: [PATCH 26/42] chore: recalculate shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index af5ab48b..405b539f 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "PSyOnLVTpo71RYfiMKEyjODYb3smyUa9aWdR9XPAdpk=", + "shasum": "c3/aY+CjrrduY/wOCuyPYBMk1XYW2pLyMHVpAeCTy6U=", "location": { "npm": { "filePath": "dist/bundle.js", From 7ea0b51597589156b30526874e26caf9acc779f9 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 17:35:02 +0200 Subject: [PATCH 27/42] fix: update logic --- packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 8e66c61f..9ae3cf67 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -242,8 +242,8 @@ export class KeyringHandler implements KeyringSnapRpc { const account = await this.#accountsUseCases.get(accountId); - const accountType = this.#defaultAddressType; - if (accountType !== 'p2wpkh') { + const addressType = account.addressType ?? this.#defaultAddressType; + if (addressType !== this.#defaultAddressType) { throw new SnapError( `Only native segwit (${BtcAccountType.P2wpkh}) accounts are supported for private key export`, ); From c679f168325b56aa5c46595adf215e9c2adfaba1 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 17:37:48 +0200 Subject: [PATCH 28/42] chore: recalculate shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index 405b539f..c5658e1d 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "c3/aY+CjrrduY/wOCuyPYBMk1XYW2pLyMHVpAeCTy6U=", + "shasum": "XVnF6TxUvFTKki46XYiQxWqKjHasd+EVkaG3mNTyzlY=", "location": { "npm": { "filePath": "dist/bundle.js", From 088d00aaef4a965eeddf1fe325c437843f678eb7 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 18:16:17 +0200 Subject: [PATCH 29/42] refactor: apply code review --- .../bitcoin-wallet-snap/snap.manifest.json | 2 +- .../src/handlers/KeyringHandler.test.ts | 44 +++++++++++++++++++ .../src/handlers/KeyringHandler.ts | 8 ++-- 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index c5658e1d..9a16afa2 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "XVnF6TxUvFTKki46XYiQxWqKjHasd+EVkaG3mNTyzlY=", + "shasum": "5mng4zvBOdIisHsMOZyV3V1gH+Qbognb7q/elfNYTG8=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts index b14a97b4..533f7b7f 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts @@ -613,6 +613,50 @@ describe('KeyringHandler', () => { expect(error.message).not.toContain('SENSITIVE'); expect(error.message).toContain('exporting account'); }); + + it('throws when account type is not p2wpkh', async () => { + mockAccounts.get.mockResolvedValue( + mock({ ...mockAccount, addressType: 'p2pkh' }), + ); + + await expect(handler.exportAccount(accountId)).rejects.toThrow( + 'Only p2wpkh accounts are supported for private key export', + ); + }); + + it('produces a valid WIF-encoded private key using the real encoder', async () => { + const { encode: realEncode } = jest.requireActual<{ + encode: (wif: { + version: number; + privateKey: Uint8Array; + compressed: boolean; + }) => string; + }>('wif'); + jest.requireMock<{ encode: jest.Mock }>('wif').encode.mockImplementation(realEncode); + + // Known 32-byte secp256k1 private key (from Bitcoin wiki WIF test vector) + const privateKeyHex = + '0c28fca386c7a227600b2fe50b7cae11ec86d3bf1fbe471be89827e19d72aa1d'; + mockSnapClient.getPrivateEntropy.mockResolvedValue({ + privateKey: `0x${privateKeyHex}`, + } as never); + + const expectedWif = realEncode({ + version: 0x80, // mainnet — matches mockAccount.network === 'bitcoin' + privateKey: Buffer.from(privateKeyHex, 'hex'), + compressed: true, + }); + + const result = await handler.exportAccount(accountId); + + expect(result).toStrictEqual({ + type: 'private-key', + encoding: 'base58', + privateKey: expectedWif, + }); + // Mainnet compressed WIF always starts with 'K' or 'L' + expect(result.privateKey).toMatch(/^[KL]/u); + }); }); describe('getAccountBalances', () => { diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 9ae3cf67..8d913856 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -245,12 +245,10 @@ export class KeyringHandler implements KeyringSnapRpc { const addressType = account.addressType ?? this.#defaultAddressType; if (addressType !== this.#defaultAddressType) { throw new SnapError( - `Only native segwit (${BtcAccountType.P2wpkh}) accounts are supported for private key export`, + `Only ${this.#defaultAddressType} accounts are supported for private key export`, ); } - let privateKey; - try { const entropy = await this.#snapClient.getPrivateEntropy( // Export the private key for address index 0 (the primary address). @@ -260,10 +258,10 @@ export class KeyringHandler implements KeyringSnapRpc { if (!entropy.privateKey) { throw new Error('Failed to get private entropy'); } - privateKey = entropy.privateKey; + const { privateKey } = entropy; // Private key is returned in "0x..." format; transform to WIF (Base58Check). const wifPrivateKey = encode({ - version: account.network === 'bitcoin' ? 128 : 239, // 128 mainnet, 239 testnets + version: account.network === 'bitcoin' ? 0x80 : 0xef, // 0x80 mainnet, 0xef testnets // eslint-disable-next-line no-restricted-globals privateKey: Buffer.from(privateKey.slice(2), 'hex'), compressed: true, From fa4e741e0cda5da8ef1a625fdf6b9402c2ddd258 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 18:18:44 +0200 Subject: [PATCH 30/42] fix: lint fix --- .../bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts index 533f7b7f..c1cb0a19 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts @@ -632,7 +632,9 @@ describe('KeyringHandler', () => { compressed: boolean; }) => string; }>('wif'); - jest.requireMock<{ encode: jest.Mock }>('wif').encode.mockImplementation(realEncode); + jest + .requireMock<{ encode: jest.Mock }>('wif') + .encode.mockImplementation(realEncode); // Known 32-byte secp256k1 private key (from Bitcoin wiki WIF test vector) const privateKeyHex = From 0a2a0f1d714638b19239fb56418bd271fe04177f Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Mon, 27 Jul 2026 18:32:35 +0200 Subject: [PATCH 31/42] fix: lint fix --- packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 8d913856..0283bc2f 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -3,7 +3,6 @@ import { Amount } from '@metamask/bitcoindevkit'; import { AccountCreationType, assertCreateAccountOptionIsSupported, - BtcAccountType, } from '@metamask/keyring-api'; import type { Balance, From 64fe7d3678c5464d47ce5dccaed7b81c5147363e Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 29 Jul 2026 16:07:05 +0200 Subject: [PATCH 32/42] fix: yarn.lock --- packages/sample-snap/package.json | 2 +- yarn.lock | 32 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/packages/sample-snap/package.json b/packages/sample-snap/package.json index 56f257e7..caea9590 100644 --- a/packages/sample-snap/package.json +++ b/packages/sample-snap/package.json @@ -41,10 +41,10 @@ }, "devDependencies": { "@jest/globals": "^29.5.0", + "@metamask/auto-changelog": "^6.1.1", "@metamask/snaps-cli": "^8.4.1", "@metamask/snaps-jest": "^10.2.0", "@metamask/snaps-sdk": "^11.2.0", - "@metamask/auto-changelog": "^6.1.1", "@types/react": "18.2.4", "@types/react-dom": "18.2.4", "eslint": "^9.39.1", diff --git a/yarn.lock b/yarn.lock index 720c77e3..742ae80d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2069,7 +2069,7 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^23.7.0": +"@metamask/keyring-api@npm:^23.2.0, @metamask/keyring-api@npm:^23.7.0": version: 23.7.0 resolution: "@metamask/keyring-api@npm:23.7.0" dependencies: @@ -2081,6 +2081,22 @@ __metadata: languageName: node linkType: hard +"@metamask/keyring-snap-sdk@npm:^8.0.0": + version: 8.0.0 + resolution: "@metamask/keyring-snap-sdk@npm:8.0.0" + dependencies: + "@metamask/keyring-utils": "npm:^3.2.0" + "@metamask/snaps-sdk": "npm:^11.0.0" + "@metamask/superstruct": "npm:^3.1.0" + "@metamask/utils": "npm:^11.1.0" + webextension-polyfill: "npm:^0.12.0" + peerDependencies: + "@metamask/keyring-api": ^22.0.0 + "@metamask/providers": ^19.0.0 + checksum: 10/271b4f84d214813c0312ffbbe3fb6201b66172210da4d06a155c3ddb359403ed1fa4c7afa424cd34fa9db04e3c876f30f69afb676bb7a905d392552d871ebd57 + languageName: node + linkType: hard + "@metamask/keyring-snap-sdk@npm:^9.2.1": version: 9.2.1 resolution: "@metamask/keyring-snap-sdk@npm:9.2.1" @@ -2097,15 +2113,15 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-utils@npm:^4.0.0": - version: 4.0.0 - resolution: "@metamask/keyring-utils@npm:4.0.0" +"@metamask/keyring-utils@npm:^3.2.0": + version: 3.3.1 + resolution: "@metamask/keyring-utils@npm:3.3.1" dependencies: "@ethereumjs/tx": "npm:^5.4.0" - "@metamask/superstruct": "npm:^3.4.1" + "@metamask/superstruct": "npm:^3.1.0" "@metamask/utils": "npm:^11.11.0" bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/a4299fafadd4a4f2f1a4475a7f4e6c4d268ccfa82e505cdd4cf4a1ff5cc6ca485edd7422650c498409db93d4fe32429db7bd02276ce6fee80aac5f6a64439578 + checksum: 10/d0917b2f634d9eb2f563827739fca00c1675ee90674ec49b2b68afcb604aee843d6c5be5d79e9780fa22d29f71fc876f40b2d3d0ed4cab7f5948937ddd276691 languageName: node linkType: hard @@ -2257,10 +2273,10 @@ __metadata: resolution: "@metamask/sample-snap@workspace:packages/sample-snap" dependencies: "@jest/globals": "npm:^29.5.0" + "@metamask/auto-changelog": "npm:^6.1.1" "@metamask/snaps-cli": "npm:^8.4.1" "@metamask/snaps-jest": "npm:^10.2.0" "@metamask/snaps-sdk": "npm:^11.2.0" - "@metamask/auto-changelog": "npm:^6.1.1" "@types/react": "npm:18.2.4" "@types/react-dom": "npm:18.2.4" eslint: "npm:^9.39.1" @@ -2287,7 +2303,7 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-cli@npm:^8.4.1": +"@metamask/snaps-cli@npm:^8.3.0, @metamask/snaps-cli@npm:^8.4.1": version: 8.4.1 resolution: "@metamask/snaps-cli@npm:8.4.1" dependencies: From 31d9fdeb2c8c7490377af3a534d8521bb0bc06d6 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 29 Jul 2026 16:16:54 +0200 Subject: [PATCH 33/42] fix: update deps and shasum --- .../bitcoin-wallet-snap/snap.manifest.json | 2 +- packages/tron-wallet-snap/package.json | 10 ++--- yarn.lock | 44 ++++--------------- 3 files changed, 14 insertions(+), 42 deletions(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index 182bb43b..ebb242f9 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "5mng4zvBOdIisHsMOZyV3V1gH+Qbognb7q/elfNYTG8=", + "shasum": "mhGqdFrlxwSN7VSPOlIQkE7Ja+FHOQ74m090oy+yA/I=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/tron-wallet-snap/package.json b/packages/tron-wallet-snap/package.json index 6840f8a6..98d02e45 100644 --- a/packages/tron-wallet-snap/package.json +++ b/packages/tron-wallet-snap/package.json @@ -50,12 +50,12 @@ "devDependencies": { "@metamask/auto-changelog": "^6.1.1", "@metamask/key-tree": "^10.1.1", - "@metamask/keyring-api": "^23.2.0", - "@metamask/keyring-snap-sdk": "^8.0.0", - "@metamask/snaps-cli": "^8.3.0", + "@metamask/keyring-api": "^23.7.0", + "@metamask/keyring-snap-sdk": "^9.2.1", + "@metamask/snaps-cli": "^8.4.1", "@metamask/snaps-jest": "^10.2.0", - "@metamask/snaps-sdk": "11.1.1", - "@metamask/superstruct": "^3.2.1", + "@metamask/snaps-sdk": "^11.2.0", + "@metamask/superstruct": "^3.4.1", "async-mutex": "^0.5.0", "bignumber.js": "^9.3.1", "concurrently": "^10.0.3", diff --git a/yarn.lock b/yarn.lock index 742ae80d..e15e823b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2069,7 +2069,7 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-api@npm:^23.2.0, @metamask/keyring-api@npm:^23.7.0": +"@metamask/keyring-api@npm:^23.7.0": version: 23.7.0 resolution: "@metamask/keyring-api@npm:23.7.0" dependencies: @@ -2081,22 +2081,6 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-snap-sdk@npm:^8.0.0": - version: 8.0.0 - resolution: "@metamask/keyring-snap-sdk@npm:8.0.0" - dependencies: - "@metamask/keyring-utils": "npm:^3.2.0" - "@metamask/snaps-sdk": "npm:^11.0.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.1.0" - webextension-polyfill: "npm:^0.12.0" - peerDependencies: - "@metamask/keyring-api": ^22.0.0 - "@metamask/providers": ^19.0.0 - checksum: 10/271b4f84d214813c0312ffbbe3fb6201b66172210da4d06a155c3ddb359403ed1fa4c7afa424cd34fa9db04e3c876f30f69afb676bb7a905d392552d871ebd57 - languageName: node - linkType: hard - "@metamask/keyring-snap-sdk@npm:^9.2.1": version: 9.2.1 resolution: "@metamask/keyring-snap-sdk@npm:9.2.1" @@ -2113,18 +2097,6 @@ __metadata: languageName: node linkType: hard -"@metamask/keyring-utils@npm:^3.2.0": - version: 3.3.1 - resolution: "@metamask/keyring-utils@npm:3.3.1" - dependencies: - "@ethereumjs/tx": "npm:^5.4.0" - "@metamask/superstruct": "npm:^3.1.0" - "@metamask/utils": "npm:^11.11.0" - bitcoin-address-validation: "npm:^2.2.3" - checksum: 10/d0917b2f634d9eb2f563827739fca00c1675ee90674ec49b2b68afcb604aee843d6c5be5d79e9780fa22d29f71fc876f40b2d3d0ed4cab7f5948937ddd276691 - languageName: node - linkType: hard - "@metamask/keyring-utils@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/keyring-utils@npm:4.0.0" @@ -2303,7 +2275,7 @@ __metadata: languageName: node linkType: hard -"@metamask/snaps-cli@npm:^8.3.0, @metamask/snaps-cli@npm:^8.4.1": +"@metamask/snaps-cli@npm:^8.4.1": version: 8.4.1 resolution: "@metamask/snaps-cli@npm:8.4.1" dependencies: @@ -2604,12 +2576,12 @@ __metadata: dependencies: "@metamask/auto-changelog": "npm:^6.1.1" "@metamask/key-tree": "npm:^10.1.1" - "@metamask/keyring-api": "npm:^23.2.0" - "@metamask/keyring-snap-sdk": "npm:^8.0.0" - "@metamask/snaps-cli": "npm:^8.3.0" + "@metamask/keyring-api": "npm:^23.7.0" + "@metamask/keyring-snap-sdk": "npm:^9.2.1" + "@metamask/snaps-cli": "npm:^8.4.1" "@metamask/snaps-jest": "npm:^10.2.0" - "@metamask/snaps-sdk": "npm:11.1.1" - "@metamask/superstruct": "npm:^3.2.1" + "@metamask/snaps-sdk": "npm:^11.2.0" + "@metamask/superstruct": "npm:^3.4.1" async-mutex: "npm:^0.5.0" bignumber.js: "npm:^9.3.1" concurrently: "npm:^10.0.3" @@ -2624,7 +2596,7 @@ __metadata: languageName: unknown linkType: soft -"@metamask/utils@npm:^11.0.1, @metamask/utils@npm:^11.1.0, @metamask/utils@npm:^11.10.0, @metamask/utils@npm:^11.11.0, @metamask/utils@npm:^11.4.0, @metamask/utils@npm:^11.4.2, @metamask/utils@npm:^11.8.1, @metamask/utils@npm:^11.9.0": +"@metamask/utils@npm:^11.0.1, @metamask/utils@npm:^11.10.0, @metamask/utils@npm:^11.11.0, @metamask/utils@npm:^11.4.0, @metamask/utils@npm:^11.4.2, @metamask/utils@npm:^11.8.1, @metamask/utils@npm:^11.9.0": version: 11.11.0 resolution: "@metamask/utils@npm:11.11.0" dependencies: From 9579085df1b18d1d31ed35d2745d2823aea832f0 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 29 Jul 2026 16:24:04 +0200 Subject: [PATCH 34/42] chore: update tron shasum --- packages/tron-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index f92f4471..0a619302 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "UObpwCGWof6C+7xwsB2Z0rPs36HRvPEEOOL1ZJ5ZOeA=", + "shasum": "TX7ID3twkWQlYUz8G7KU3ZHrE9sRMQAR0Wl32qms8Zs=", "location": { "npm": { "filePath": "dist/bundle.js", From df4666613e27d236e489cd5f6e973d9b3c0af21e Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 29 Jul 2026 16:29:05 +0200 Subject: [PATCH 35/42] fix: shasum --- packages/tron-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index 0a619302..066007d9 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "TX7ID3twkWQlYUz8G7KU3ZHrE9sRMQAR0Wl32qms8Zs=", + "shasum": "83y66B4a9awX0MoxVkfv7HV+Jt5S04octhhc5dUELM4=", "location": { "npm": { "filePath": "dist/bundle.js", From 288a9596cc8d1e310213f972467f1cebcb2aea9b Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 29 Jul 2026 16:34:10 +0200 Subject: [PATCH 36/42] chore: add tron changelog entries --- packages/tron-wallet-snap/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/tron-wallet-snap/CHANGELOG.md b/packages/tron-wallet-snap/CHANGELOG.md index e22ebbd0..97d255b1 100644 --- a/packages/tron-wallet-snap/CHANGELOG.md +++ b/packages/tron-wallet-snap/CHANGELOG.md @@ -10,5 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - This package was migrated from [snap-tron-wallet](https://github.com/MetaMask/snap-tron-wallet). See the source repository for the original [changelog](https://github.com/MetaMask/snap-tron-wallet/blob/main/packages/snap/CHANGELOG.md). +- Bump `@metamask/keyring-api` from `^23.2.0` to `^23.7.0` [#43](https://github.com/MetaMask/internal-snaps/pull/43) +- Bump `@metamask/keyring-snap-sdk` from `^8.0.0` to `^9.2.1` [#43](https://github.com/MetaMask/internal-snaps/pull/43) +- Bump `@metamask/snaps-cli` from `^8.3.0` to `^8.4.1` [#43](https://github.com/MetaMask/internal-snaps/pull/43) +- Bump `@metamask/snaps-sdk` from `^11.1.1` to `^11.2.0` [#43](https://github.com/MetaMask/internal-snaps/pull/43) +- Bump `@metamask/superstruct` from `^3.2.1` to `^3.4.1` [#43](https://github.com/MetaMask/internal-snaps/pull/43) + [Unreleased]: https://github.com/MetaMask/internal-snaps/ From a36f0703afa59f46b023d17be57aa4efba9e96e1 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 29 Jul 2026 16:38:30 +0200 Subject: [PATCH 37/42] fix: lint fix --- packages/tron-wallet-snap/CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/tron-wallet-snap/CHANGELOG.md b/packages/tron-wallet-snap/CHANGELOG.md index 97d255b1..7330e913 100644 --- a/packages/tron-wallet-snap/CHANGELOG.md +++ b/packages/tron-wallet-snap/CHANGELOG.md @@ -16,5 +16,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/snaps-sdk` from `^11.1.1` to `^11.2.0` [#43](https://github.com/MetaMask/internal-snaps/pull/43) - Bump `@metamask/superstruct` from `^3.2.1` to `^3.4.1` [#43](https://github.com/MetaMask/internal-snaps/pull/43) - [Unreleased]: https://github.com/MetaMask/internal-snaps/ From 06663c378d2aa7d63d9f990c7be80a79024bfd50 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Wed, 29 Jul 2026 16:59:47 +0200 Subject: [PATCH 38/42] fix: update entries --- packages/tron-wallet-snap/CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/tron-wallet-snap/CHANGELOG.md b/packages/tron-wallet-snap/CHANGELOG.md index 7330e913..471ddd4c 100644 --- a/packages/tron-wallet-snap/CHANGELOG.md +++ b/packages/tron-wallet-snap/CHANGELOG.md @@ -10,10 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - This package was migrated from [snap-tron-wallet](https://github.com/MetaMask/snap-tron-wallet). See the source repository for the original [changelog](https://github.com/MetaMask/snap-tron-wallet/blob/main/packages/snap/CHANGELOG.md). -- Bump `@metamask/keyring-api` from `^23.2.0` to `^23.7.0` [#43](https://github.com/MetaMask/internal-snaps/pull/43) -- Bump `@metamask/keyring-snap-sdk` from `^8.0.0` to `^9.2.1` [#43](https://github.com/MetaMask/internal-snaps/pull/43) -- Bump `@metamask/snaps-cli` from `^8.3.0` to `^8.4.1` [#43](https://github.com/MetaMask/internal-snaps/pull/43) -- Bump `@metamask/snaps-sdk` from `^11.1.1` to `^11.2.0` [#43](https://github.com/MetaMask/internal-snaps/pull/43) -- Bump `@metamask/superstruct` from `^3.2.1` to `^3.4.1` [#43](https://github.com/MetaMask/internal-snaps/pull/43) +- Bump `@metamask/keyring-api` from `^23.2.0` to `^23.7.0` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Bump `@metamask/keyring-snap-sdk` from `^8.0.0` to `^9.2.1` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Bump `@metamask/snaps-cli` from `^8.3.0` to `^8.4.1` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Bump `@metamask/snaps-sdk` from `^11.1.1` to `^11.2.0` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) +- Bump `@metamask/superstruct` from `^3.2.1` to `^3.4.1` ([#43](https://github.com/MetaMask/internal-snaps/pull/43)) [Unreleased]: https://github.com/MetaMask/internal-snaps/ From e96ca6df67eceb7440d787e71fc49da0b535ae97 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Thu, 30 Jul 2026 11:47:13 +0200 Subject: [PATCH 39/42] fix: undo deletion after discovery --- .../src/handlers/KeyringHandler.test.ts | 7 +++---- .../bitcoin-wallet-snap/src/handlers/KeyringHandler.ts | 8 +++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts index c1cb0a19..a94d33f5 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.test.ts @@ -467,9 +467,8 @@ describe('KeyringHandler', () => { expect(result[0]?.id).toBe('discovered-id'); }); - it('deletes the account and returns empty array when no on-chain history', async () => { - const inactiveAccount = buildDiscoveredAccount(false); - mockAccounts.discover.mockResolvedValue(inactiveAccount); + it('returns empty array when no on-chain history', async () => { + mockAccounts.discover.mockResolvedValue(buildDiscoveredAccount(false)); const result = await handler.createAccounts({ type: AccountCreationType.Bip44Discover, @@ -478,7 +477,7 @@ describe('KeyringHandler', () => { }); expect(mockAccounts.discover).toHaveBeenCalled(); - expect(mockAccounts.delete).toHaveBeenCalledWith(inactiveAccount.id); + expect(mockAccounts.delete).not.toHaveBeenCalled(); expect(result).toHaveLength(0); }); diff --git a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts index 0283bc2f..903427ef 100644 --- a/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts +++ b/packages/bitcoin-wallet-snap/src/handlers/KeyringHandler.ts @@ -133,8 +133,8 @@ export class KeyringHandler implements KeyringSnapRpc { if (options.type === AccountCreationType.Bip44Discover) { // For each supported scope, discover at this index. Accounts with - // on-chain activity are kept; those without are deleted. Returning [] - // signals end-of-discovery to the client. + // on-chain activity are kept; those without are discarded in-memory. + // Returning [] signals end-of-discovery to the client. const discovered: KeyringAccount[] = []; for (const scope of SUPPORTED_SCOPES) { @@ -146,9 +146,7 @@ export class KeyringHandler implements KeyringSnapRpc { addressType, }); - if (account.listTransactions().length === 0) { - await this.#accountsUseCases.delete(account.id); - } else { + if (account.listTransactions().length > 0) { discovered.push(mapToKeyringAccount(account)); } } From 35db48634c4877ebc623370bffb94efdeee86dea Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Thu, 30 Jul 2026 11:48:35 +0200 Subject: [PATCH 40/42] chore: update shasum --- packages/bitcoin-wallet-snap/snap.manifest.json | 2 +- packages/tron-wallet-snap/snap.manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/bitcoin-wallet-snap/snap.manifest.json b/packages/bitcoin-wallet-snap/snap.manifest.json index ebb242f9..25170faa 100644 --- a/packages/bitcoin-wallet-snap/snap.manifest.json +++ b/packages/bitcoin-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "mhGqdFrlxwSN7VSPOlIQkE7Ja+FHOQ74m090oy+yA/I=", + "shasum": "o8/OvZvhYYpLZ1tndeGYlWOlUKCqO1V+T6e6bL8YAg8=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index 066007d9..0a619302 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "83y66B4a9awX0MoxVkfv7HV+Jt5S04octhhc5dUELM4=", + "shasum": "TX7ID3twkWQlYUz8G7KU3ZHrE9sRMQAR0Wl32qms8Zs=", "location": { "npm": { "filePath": "dist/bundle.js", From cfe22310b2a0652bd3e02c7414fccef5d610d166 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Thu, 30 Jul 2026 11:53:02 +0200 Subject: [PATCH 41/42] chore: recalculate shasum --- packages/tron-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index aba4ffb8..68608420 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "TX7ID3twkWQlYUz8G7KU3ZHrE9sRMQAR0Wl32qms8Zs=", + "shasum": "kDDLNI7OY9sloPAl1yc8bdQaRmRP/5WqXBMOuun3Pgs=", "location": { "npm": { "filePath": "dist/bundle.js", From 777c1a48140c07de061ecfeafe3009ee03632003 Mon Sep 17 00:00:00 2001 From: Hassan Malik Date: Thu, 30 Jul 2026 12:01:52 +0200 Subject: [PATCH 42/42] fix: tron shasum --- packages/tron-wallet-snap/snap.manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tron-wallet-snap/snap.manifest.json b/packages/tron-wallet-snap/snap.manifest.json index 68608420..e13773c8 100644 --- a/packages/tron-wallet-snap/snap.manifest.json +++ b/packages/tron-wallet-snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "https://github.com/MetaMask/internal-snaps.git" }, "source": { - "shasum": "kDDLNI7OY9sloPAl1yc8bdQaRmRP/5WqXBMOuun3Pgs=", + "shasum": "tcnp/6xxntfergEzeQYc7k96SfveVo+5kBQHGEXqZkQ=", "location": { "npm": { "filePath": "dist/bundle.js",