diff --git a/packages/keyring-eth-qr/CHANGELOG.md b/packages/keyring-eth-qr/CHANGELOG.md new file mode 100644 index 00000000..4dc68c6f --- /dev/null +++ b/packages/keyring-eth-qr/CHANGELOG.md @@ -0,0 +1,2 @@ +# Changelog + diff --git a/packages/keyring-eth-qr/LICENSE b/packages/keyring-eth-qr/LICENSE new file mode 100644 index 00000000..b5ed1b9c --- /dev/null +++ b/packages/keyring-eth-qr/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2020 MetaMask + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/packages/keyring-eth-qr/README.md b/packages/keyring-eth-qr/README.md new file mode 100644 index 00000000..54ae5e09 --- /dev/null +++ b/packages/keyring-eth-qr/README.md @@ -0,0 +1 @@ +# QR Keyring diff --git a/packages/keyring-eth-qr/jest.config.js b/packages/keyring-eth-qr/jest.config.js new file mode 100644 index 00000000..fdd7e10c --- /dev/null +++ b/packages/keyring-eth-qr/jest.config.js @@ -0,0 +1,29 @@ +/* + * For a detailed explanation regarding each configuration property and type check, visit: + * https://jestjs.io/docs/configuration + */ + +const merge = require('deepmerge'); +const path = require('path'); + +const baseConfig = require('../../jest.config.packages'); + +const displayName = path.basename(__dirname); + +module.exports = merge(baseConfig, { + // The display name when running multiple projects + displayName, + + // An array of regexp pattern strings used to skip coverage collection + coveragePathIgnorePatterns: ['./src/tests'], + + // An object that configures minimum threshold enforcement for coverage results + coverageThreshold: { + global: { + branches: 100, + functions: 100, + lines: 100, + statements: 100, + }, + }, +}); diff --git a/packages/keyring-eth-qr/package.json b/packages/keyring-eth-qr/package.json new file mode 100644 index 00000000..b0d1f15b --- /dev/null +++ b/packages/keyring-eth-qr/package.json @@ -0,0 +1,76 @@ +{ + "name": "@metamask/eth-qr-keyring", + "version": "1.0.0", + "description": "A simple standard interface for a series of Ethereum private keys.", + "keywords": [ + "ethereum", + "keyring", + "qr", + "metamask" + ], + "homepage": "https://github.com/MetaMask/accounts/packages/keyring-eth-qr#readme", + "bugs": { + "url": "https://github.com/MetaMask/accounts/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/MetaMask/accounts.git" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist/" + ], + "scripts": { + "build": "tsc --build tsconfig.build.json", + "build:clean": "rimraf dist && yarn build", + "build:docs": "typedoc", + "build:force": "tsc --build tsconfig.build.json --force", + "changelog:update": "../../scripts/update-changelog.sh @metamask/eth-simple-keyring", + "changelog:validate": "../../scripts/validate-changelog.sh @metamask/eth-simple-keyring", + "publish:preview": "yarn npm publish --tag preview", + "sample": "ts-node src/sample.ts", + "test": "jest", + "test:clean": "jest --clearCache", + "test:verbose": "jest --verbose", + "test:watch": "jest --watch" + }, + "dependencies": { + "@ethereumjs/util": "^9.1.0", + "@keystonehq/bc-ur-registry-eth": "^0.21.0", + "@keystonehq/ur-decoder": "^0.12.2", + "@metamask/utils": "^9.2.1", + "@ngraveio/bc-ur": "^1.1.13", + "hdkey": "^2.1.0" + }, + "devDependencies": { + "@lavamoat/allow-scripts": "^3.2.1", + "@metamask/auto-changelog": "^3.4.4", + "@types/hdkey": "^2.0.1", + "@types/jest": "^29.5.12", + "@types/node": "^20.12.12", + "deepmerge": "^4.2.2", + "depcheck": "^1.4.7", + "jest": "^29.5.0", + "ts-jest": "^29.0.5", + "ts-node": "^10.9.2", + "typedoc": "^0.25.13", + "typescript": "~4.8.4" + }, + "engines": { + "node": "^18.18 || >=20" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "lavamoat": { + "allowScripts": { + "keccak": true, + "secp256k1": true, + "@lavamoat/preinstall-always-fail": false, + "ethereumjs-tx>ethereumjs-util>ethereum-cryptography>keccak": false, + "ethereumjs-tx>ethereumjs-util>ethereum-cryptography>secp256k1": false + } + } +} diff --git a/packages/keyring-eth-qr/src/account-deriver.ts b/packages/keyring-eth-qr/src/account-deriver.ts new file mode 100644 index 00000000..7a7a569d --- /dev/null +++ b/packages/keyring-eth-qr/src/account-deriver.ts @@ -0,0 +1,91 @@ +import { pubToAddress } from '@ethereumjs/util'; +import { + CryptoAccount, + type CryptoHDKey, + type CryptoOutput, +} from '@keystonehq/bc-ur-registry-eth'; +import { add0x, getChecksumAddress, type Hex } from '@metamask/utils'; +import HDKey from 'hdkey'; + +export type RootAccount = { fingerprint: Hex } & ( + | { + type: 'hd'; + hdPath: string; + childrenPath: string; + bip32xPub: string; + } + | { + type: 'account'; + addressPaths: Record; + } +); + +export class AccountDeriver { + #root?: RootAccount; + + init(source: CryptoAccount | CryptoHDKey) { + const fingerprint = this.#getFingerprintFromSource(source); + if (source instanceof CryptoAccount) { + this.#root = { + fingerprint, + type: 'account', + addressPaths: this.#getPathsFromCryptoOutputDescriptors( + source.getOutputDescriptors(), + ), + }; + } else { + this.#root = { + fingerprint, + type: 'hd', + hdPath: `m/${source.getOrigin().getPath()}`, + childrenPath: source.getChildren().getPath(), + bip32xPub: source.getBip32Key(), + }; + } + } + + deriveIndex(index: number): Hex { + if (!this.#root) { + throw new Error('AccountDeriver not initialized'); + } + + if (this.#root.type === 'account') { + const address = Object.keys(this.#root.addressPaths)[index]; + if (!address) { + throw new Error(`Address not found for index ${index}`); + } + return add0x(address); + } else { + const hdKey = HDKey.fromExtendedKey(this.#root.bip32xPub); + hdKey.derive(`m/${index}`); + const address = getChecksumAddress( + add0x(Buffer.from(pubToAddress(hdKey.publicKey, true)).toString('hex')), + ); + return add0x(address); + } + } + + #getFingerprintFromSource(source: CryptoAccount | CryptoHDKey): Hex { + return source instanceof CryptoAccount + ? add0x(source.getMasterFingerprint().toString('hex')) + : add0x(source.getOrigin().getSourceFingerprint().toString('hex')); + } + + #getPathsFromCryptoOutputDescriptors( + descriptors: CryptoOutput[], + ): Record { + return descriptors.reduce((paths: Record, current) => { + const hdKey = current.getHDKey(); + if (hdKey) { + const path = `M/${hdKey.getOrigin().getPath()}`; + const address = getChecksumAddress( + add0x( + Buffer.from(pubToAddress(hdKey.getKey(), true)).toString('hex'), + ), + ); + paths[address] = path; + } + return paths; + }, {}); + } +} diff --git a/packages/keyring-eth-qr/src/index.ts b/packages/keyring-eth-qr/src/index.ts new file mode 100644 index 00000000..bea7d1d3 --- /dev/null +++ b/packages/keyring-eth-qr/src/index.ts @@ -0,0 +1 @@ +export * from './qr-keyring'; diff --git a/packages/keyring-eth-qr/src/qr-keyring.ts b/packages/keyring-eth-qr/src/qr-keyring.ts new file mode 100644 index 00000000..805d055b --- /dev/null +++ b/packages/keyring-eth-qr/src/qr-keyring.ts @@ -0,0 +1,76 @@ +import { CryptoAccount, CryptoHDKey } from '@keystonehq/bc-ur-registry-eth'; +import { URRegistryDecoder } from '@keystonehq/ur-decoder'; +import type { Hex, Keyring } from '@metamask/utils'; +import { UR } from '@ngraveio/bc-ur'; +import { AccountDeriver } from './account-deriver'; + +export const QR_KEYRING_TYPE = 'QrKeyring' as const; + +export const SUPPORTED_UR_TYPE = { + CRYPTO_HDKEY: 'crypto-hdkey', + CRYPTO_ACCOUNT: 'crypto-account', + ETH_SIGNATURE: 'eth-signature', +}; + +/** + * The state of the QrKeyring + * + * @property accounts - The accounts in the QrKeyring + */ +export type QrKeyringState = { + accounts: Record; + cbor?: Hex; +}; + +export class QrKeyring implements Keyring { + type = QR_KEYRING_TYPE; + + #accounts: Record = {}; + + #deriver: AccountDeriver = new AccountDeriver(); + + async serialize(): Promise { + return { + accounts: Object.values(this.#accounts), + cbor: '', // TODO: Serialize deriver + }; + } + + async deserialize(state: QrKeyringState): Promise { + this.#accounts = state.accounts; + if (state.cbor) { + this.submitCBOR(state.cbor); + } + } + + async addAccounts(_accountsToAdd: number): Promise { + // TODO: Implement + } + + async getAccounts(): Promise { + return Object.values(this.#accounts); + } + + submitCBOR(cbor: Hex) { + const ur = URRegistryDecoder.decode(cbor); + const bufferedCbor = Buffer.from(cbor, 'hex'); + let derivationSource: CryptoHDKey | CryptoAccount; + + switch (ur.type) { + case SUPPORTED_UR_TYPE.CRYPTO_HDKEY: + derivationSource = CryptoHDKey.fromCBOR(bufferedCbor); + break; + case SUPPORTED_UR_TYPE.CRYPTO_ACCOUNT: + derivationSource = CryptoAccount.fromCBOR(bufferedCbor); + break; + default: + throw new Error('Unsupported UR type'); + } + + this.#deriver.init(derivationSource); + } + + async setAccountToUnlock(index: number): Promise { + // TODO: Implement + } +} diff --git a/packages/keyring-eth-qr/tsconfig.build.json b/packages/keyring-eth-qr/tsconfig.build.json new file mode 100644 index 00000000..ccb5cea3 --- /dev/null +++ b/packages/keyring-eth-qr/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.packages.build.json", + "compilerOptions": { + "baseUrl": "./", + "outDir": "dist", + "rootDir": "src", + "target": "es2020" + }, + "include": ["./src/**/*.ts"], + "exclude": ["./src/**/*.test.ts", "./src/sample.ts"] +} diff --git a/packages/keyring-eth-qr/tsconfig.json b/packages/keyring-eth-qr/tsconfig.json new file mode 100644 index 00000000..bba26c34 --- /dev/null +++ b/packages/keyring-eth-qr/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.packages.json", + "compilerOptions": { + "baseUrl": "./" + }, + "include": ["./src"], + "exclude": ["./dist/**/*"] +} diff --git a/packages/keyring-eth-qr/typedoc.json b/packages/keyring-eth-qr/typedoc.json new file mode 100644 index 00000000..b527b625 --- /dev/null +++ b/packages/keyring-eth-qr/typedoc.json @@ -0,0 +1,6 @@ +{ + "entryPoints": ["./src/index.ts"], + "excludePrivate": true, + "hideGenerator": true, + "out": "docs" +} diff --git a/tsconfig.build.json b/tsconfig.build.json index d8d7df0f..64894d61 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -2,6 +2,7 @@ "references": [ { "path": "./packages/keyring-api/tsconfig.build.json" }, { "path": "./packages/keyring-eth-ledger-bridge/tsconfig.build.json" }, + { "path": "./packages/keyring-eth-qr/tsconfig.build.json" }, { "path": "./packages/keyring-eth-simple/tsconfig.build.json" }, { "path": "./packages/keyring-eth-trezor/tsconfig.build.json" }, { "path": "./packages/keyring-snap-bridge/tsconfig.build.json" } diff --git a/yarn.lock b/yarn.lock index b724881c..7a1098e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -666,7 +666,7 @@ __metadata: languageName: node linkType: hard -"@ethereumjs/util@npm:^9.1.0": +"@ethereumjs/util@npm:^9.0.3, @ethereumjs/util@npm:^9.1.0": version: 9.1.0 resolution: "@ethereumjs/util@npm:9.1.0" dependencies: @@ -1449,6 +1449,69 @@ __metadata: languageName: node linkType: hard +"@keystonehq/alias-sampling@npm:^0.1.1": + version: 0.1.2 + resolution: "@keystonehq/alias-sampling@npm:0.1.2" + checksum: 10/4dfdfb91e070b1d9f28058c92b5b8fad81696ac63bd432cd6bd359f2ab92eb50df75e8c5da1f75a351756387e9902f043b3ecc2cbf662c9c9456ecacc848abfd + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-eth@npm:^0.21.0": + version: 0.21.0 + resolution: "@keystonehq/bc-ur-registry-eth@npm:0.21.0" + dependencies: + "@ethereumjs/util": "npm:^9.0.3" + "@keystonehq/bc-ur-registry": "npm:^0.7.0" + hdkey: "npm:^2.0.1" + uuid: "npm:^8.3.2" + checksum: 10/2f694957c5e5d93db5523af59e5ed582dbbd9d08cc9c165ebe79b4f953ab2401b6212bb5c931e41ff9e5e6e8469f18c1aff90ff88b0ff85d093cd5794ddbdbbc + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry-eth@npm:^0.6.12": + version: 0.6.14 + resolution: "@keystonehq/bc-ur-registry-eth@npm:0.6.14" + dependencies: + "@keystonehq/bc-ur-registry": "npm:^0.4.4" + ethereumjs-util: "npm:^7.0.8" + hdkey: "npm:^2.0.1" + uuid: "npm:^8.3.2" + checksum: 10/d705d7d0d11a82db1417df9666f8a6bc5996eb46b543dc5f979d39d7694910d09c178a1acb6859caf2f93c902f3cc4614eb856936db84ea0b310ac18e5ab139d + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry@npm:^0.4.4": + version: 0.4.4 + resolution: "@keystonehq/bc-ur-registry@npm:0.4.4" + dependencies: + "@ngraveio/bc-ur": "npm:^1.1.5" + base58check: "npm:^2.0.0" + tslib: "npm:^2.3.0" + checksum: 10/640c5ef55e34713d338ecc29fef779203f2488041d54dd2f036ccd56f01dda1859ff20853b4eda53933a1f08f01d3f3e4c2fdc7b2e63886c88a40755da3a562e + languageName: node + linkType: hard + +"@keystonehq/bc-ur-registry@npm:^0.7.0": + version: 0.7.0 + resolution: "@keystonehq/bc-ur-registry@npm:0.7.0" + dependencies: + "@ngraveio/bc-ur": "npm:^1.1.5" + bs58check: "npm:^2.1.2" + tslib: "npm:^2.3.0" + checksum: 10/44bb60d0e8471ec3148fab47bc3484406ea43b378c4e5bfbadc8978ed898ed387ad5d1c4f6b2983dced8ead4c26414e28a3b80c45364b6d066e0050a910e89d4 + languageName: node + linkType: hard + +"@keystonehq/ur-decoder@npm:^0.12.2": + version: 0.12.2 + resolution: "@keystonehq/ur-decoder@npm:0.12.2" + dependencies: + "@keystonehq/bc-ur-registry-eth": "npm:^0.6.12" + "@ngraveio/bc-ur": "npm:^1.1.6" + checksum: 10/0904492775842dc01035bcf5fc1355918548c3e1ab9f0be677a55301d72bb87fea0377ee866bfa401568b99572114ac10b72d4b2d6cbc22a87a9d3eea2df9c37 + languageName: node + linkType: hard + "@lavamoat/aa@npm:^4.3.0": version: 4.3.0 resolution: "@lavamoat/aa@npm:4.3.0" @@ -1920,6 +1983,31 @@ __metadata: languageName: unknown linkType: soft +"@metamask/eth-qr-keyring@workspace:packages/keyring-eth-qr": + version: 0.0.0-use.local + resolution: "@metamask/eth-qr-keyring@workspace:packages/keyring-eth-qr" + dependencies: + "@ethereumjs/util": "npm:^9.1.0" + "@keystonehq/bc-ur-registry-eth": "npm:^0.21.0" + "@keystonehq/ur-decoder": "npm:^0.12.2" + "@lavamoat/allow-scripts": "npm:^3.2.1" + "@metamask/auto-changelog": "npm:^3.4.4" + "@metamask/utils": "npm:^9.2.1" + "@ngraveio/bc-ur": "npm:^1.1.13" + "@types/hdkey": "npm:^2.0.1" + "@types/jest": "npm:^29.5.12" + "@types/node": "npm:^20.12.12" + deepmerge: "npm:^4.2.2" + depcheck: "npm:^1.4.7" + hdkey: "npm:^2.1.0" + jest: "npm:^29.5.0" + ts-jest: "npm:^29.0.5" + ts-node: "npm:^10.9.2" + typedoc: "npm:^0.25.13" + typescript: "npm:~4.8.4" + languageName: unknown + linkType: soft + "@metamask/eth-query@npm:^4.0.0": version: 4.0.0 resolution: "@metamask/eth-query@npm:4.0.0" @@ -2426,6 +2514,21 @@ __metadata: languageName: node linkType: hard +"@ngraveio/bc-ur@npm:^1.1.13, @ngraveio/bc-ur@npm:^1.1.5, @ngraveio/bc-ur@npm:^1.1.6": + version: 1.1.13 + resolution: "@ngraveio/bc-ur@npm:1.1.13" + dependencies: + "@keystonehq/alias-sampling": "npm:^0.1.1" + assert: "npm:^2.0.0" + bignumber.js: "npm:^9.0.1" + cbor-sync: "npm:^1.0.4" + crc: "npm:^3.8.0" + jsbi: "npm:^3.1.5" + sha.js: "npm:^2.4.11" + checksum: 10/0d3301b673a0bd9a069dae1f017cfd03010fddf19c1449d1a9e986b9b879ee4611f5af690ace9f59b75707573d1d3d6a4983166207db743425974a736689c6a0 + languageName: node + linkType: hard + "@noble/curves@npm:1.4.2, @noble/curves@npm:~1.4.0": version: 1.4.2 resolution: "@noble/curves@npm:1.4.2" @@ -4181,6 +4284,13 @@ __metadata: languageName: node linkType: hard +"base-x@npm:^1.1.0": + version: 1.1.0 + resolution: "base-x@npm:1.1.0" + checksum: 10/ca5f485f3868579e908187ccd50f4295a3ed3bd56a5d5dd266ba59a70c391155eabe50cd7976e6b696b5f7eca512019a886fcc6f27b4a738da1611249b3446f7 + languageName: node + linkType: hard + "base-x@npm:^3.0.2, base-x@npm:^3.0.9": version: 3.0.10 resolution: "base-x@npm:3.0.10" @@ -4197,6 +4307,15 @@ __metadata: languageName: node linkType: hard +"base58check@npm:^2.0.0": + version: 2.0.0 + resolution: "base58check@npm:2.0.0" + dependencies: + bs58: "npm:^3.0.0" + checksum: 10/19f77522a38d66d5c9cc16411880e258899a6807b31477e3ac33ebaa64555126e9b29e7d5d2be88748aae8b1d05f91e5eb3aef4847a033af25b8a0c0f995b037 + languageName: node + linkType: hard + "base64-js@npm:^1.3.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" @@ -4254,7 +4373,7 @@ __metadata: languageName: node linkType: hard -"bignumber.js@npm:^9.0.0, bignumber.js@npm:^9.1.2": +"bignumber.js@npm:^9.0.0, bignumber.js@npm:^9.0.1, bignumber.js@npm:^9.1.2": version: 9.1.2 resolution: "bignumber.js@npm:9.1.2" checksum: 10/d89b8800a987225d2c00dcbf8a69dc08e92aa0880157c851c287b307d31ceb2fc2acb0c62c3e3a3d42b6c5fcae9b004035f13eb4386e56d529d7edac18d5c9d8 @@ -4423,6 +4542,15 @@ __metadata: languageName: node linkType: hard +"bs58@npm:^3.0.0": + version: 3.1.0 + resolution: "bs58@npm:3.1.0" + dependencies: + base-x: "npm:^1.1.0" + checksum: 10/6d757a49958c43bc630f3b327511ce3ee065307c24240aa86189f72df0a4a8245c7ce7e7abad209b637f155006952c7b8f04bb4aa6ee4212a891882424bca82e + languageName: node + linkType: hard + "bs58@npm:^4.0.0, bs58@npm:^4.0.1": version: 4.0.1 resolution: "bs58@npm:4.0.1" @@ -4495,6 +4623,16 @@ __metadata: languageName: node linkType: hard +"buffer@npm:^5.1.0": + version: 5.7.1 + resolution: "buffer@npm:5.7.1" + dependencies: + base64-js: "npm:^1.3.1" + ieee754: "npm:^1.1.13" + checksum: 10/997434d3c6e3b39e0be479a80288875f71cd1c07d75a3855e6f08ef848a3c966023f79534e22e415ff3a5112708ce06127277ab20e527146d55c84566405c7c6 + languageName: node + linkType: hard + "bufferutil@npm:^4.0.1": version: 4.0.8 resolution: "bufferutil@npm:4.0.8" @@ -4628,6 +4766,13 @@ __metadata: languageName: node linkType: hard +"cbor-sync@npm:^1.0.4": + version: 1.0.4 + resolution: "cbor-sync@npm:1.0.4" + checksum: 10/bdad5fbf442b5b2478ba59433cab145ad823f963f674ec42f3b730689e679327ec8a6dfab97724b63295badac915574139984e702475ff8025d7cb175e50e9ae + languageName: node + linkType: hard + "chalk-template@npm:1.1.0": version: 1.1.0 resolution: "chalk-template@npm:1.1.0" @@ -4935,6 +5080,15 @@ __metadata: languageName: node linkType: hard +"crc@npm:^3.8.0": + version: 3.8.0 + resolution: "crc@npm:3.8.0" + dependencies: + buffer: "npm:^5.1.0" + checksum: 10/3a43061e692113d60fbaf5e438c5f6aa3374fe2368244a75cc083ecee6762513bcee8583f67c2c56feea0b0c72b41b7304fbd3c1e26cfcfaec310b9a18543fa8 + languageName: node + linkType: hard + "create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": version: 1.2.0 resolution: "create-hash@npm:1.2.0" @@ -6091,7 +6245,7 @@ __metadata: languageName: node linkType: hard -"ethereumjs-util@npm:^7.0.9, ethereumjs-util@npm:^7.1.2": +"ethereumjs-util@npm:^7.0.8, ethereumjs-util@npm:^7.0.9, ethereumjs-util@npm:^7.1.2": version: 7.1.5 resolution: "ethereumjs-util@npm:7.1.5" dependencies: @@ -6982,7 +7136,7 @@ __metadata: languageName: node linkType: hard -"hdkey@npm:^2.1.0": +"hdkey@npm:^2.0.1, hdkey@npm:^2.1.0": version: 2.1.0 resolution: "hdkey@npm:2.1.0" dependencies: @@ -7144,7 +7298,7 @@ __metadata: languageName: node linkType: hard -"ieee754@npm:^1.2.1": +"ieee754@npm:^1.1.13, ieee754@npm:^1.2.1": version: 1.2.1 resolution: "ieee754@npm:1.2.1" checksum: 10/d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4 @@ -8262,6 +8416,13 @@ __metadata: languageName: node linkType: hard +"jsbi@npm:^3.1.5": + version: 3.2.5 + resolution: "jsbi@npm:3.2.5" + checksum: 10/2cceb3a06dcb16493e936aa22384d912dd5f0a1fd474b97b5c6705011bd0aac8214d9a392a730b3f3ffb61a8fbe910a34d0fe881329be6a02857520d7a61ace6 + languageName: node + linkType: hard + "jsbn@npm:1.1.0": version: 1.1.0 resolution: "jsbn@npm:1.1.0" @@ -10444,7 +10605,7 @@ __metadata: languageName: node linkType: hard -"sha.js@npm:^2.4.0, sha.js@npm:^2.4.8": +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": version: 2.4.11 resolution: "sha.js@npm:2.4.11" dependencies: @@ -11276,7 +11437,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.1.0, tslib@npm:^2.4.0": +"tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0": version: 2.7.0 resolution: "tslib@npm:2.7.0" checksum: 10/9a5b47ddac65874fa011c20ff76db69f97cf90c78cff5934799ab8894a5342db2d17b4e7613a087046bc1d133d21547ddff87ac558abeec31ffa929c88b7fce6