@metamask/eth-hd-keyring 13.1.0 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -1
- package/dist/index.cjs +1 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +0 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +0 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +0 -1
- package/dist/index.mjs.map +1 -1
- package/dist/{hd-keyring-v2.cjs → v2/hd-keyring.cjs} +26 -24
- package/dist/v2/hd-keyring.cjs.map +1 -0
- package/dist/{hd-keyring-v2.d.mts → v2/hd-keyring.d.cts} +10 -8
- package/dist/v2/hd-keyring.d.cts.map +1 -0
- package/dist/{hd-keyring-v2.d.cts → v2/hd-keyring.d.mts} +10 -8
- package/dist/v2/hd-keyring.d.mts.map +1 -0
- package/dist/{hd-keyring-v2.mjs → v2/hd-keyring.mjs} +15 -13
- package/dist/v2/hd-keyring.mjs.map +1 -0
- package/dist/v2/index.cjs +6 -0
- package/dist/v2/index.cjs.map +1 -0
- package/dist/v2/index.d.cts +2 -0
- package/dist/v2/index.d.cts.map +1 -0
- package/dist/v2/index.d.mts +2 -0
- package/dist/v2/index.d.mts.map +1 -0
- package/dist/v2/index.mjs +2 -0
- package/dist/v2/index.mjs.map +1 -0
- package/package.json +35 -16
- package/dist/hd-keyring-v2.cjs.map +0 -1
- package/dist/hd-keyring-v2.d.cts.map +0 -1
- package/dist/hd-keyring-v2.d.mts.map +0 -1
- package/dist/hd-keyring-v2.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [14.0.0]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add `./v2` subpath export for keyring v2 implementation ([#513](https://github.com/MetaMask/accounts/pull/513))
|
|
15
|
+
- `HdKeyring` and `HdKeyringOptions` are now available from `@metamask/eth-hd-keyring/v2`.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **BREAKING:** Move and rename `HdKeyringV2` and `HdKeyringV2Options` to the new `./v2` subpath export ([#513](https://github.com/MetaMask/accounts/pull/513))
|
|
20
|
+
- `HdKeyringV2` is now `HdKeyring` from `@metamask/eth-hd-keyring/v2`.
|
|
21
|
+
- `HdKeyringV2Options` is now `HdKeyringOptions` from `@metamask/eth-hd-keyring/v2`.
|
|
22
|
+
- Bump `@metamask/utils` from `^11.10.0` to `^11.11.0` ([#483](https://github.com/MetaMask/accounts/pull/483))
|
|
23
|
+
- Bump `@metamask/account-api` from `^1.0.1` to `^1.0.2` ([#515](https://github.com/MetaMask/accounts/pull/515))
|
|
24
|
+
- Bump `@metamask/keyring-api` from `^22.0.0` to `^23.0.0` ([#515](https://github.com/MetaMask/accounts/pull/515))
|
|
25
|
+
- Bump `@metamask/keyring-sdk` from `^1.2.0` to `^2.0.0` ([#515](https://github.com/MetaMask/accounts/pull/515))
|
|
26
|
+
|
|
27
|
+
## [13.1.1]
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- Add new dependency `@metamask/keyring-sdk@1.2.0` ([#478](https://github.com/MetaMask/accounts/pull/478)), ([#482](https://github.com/MetaMask/accounts/pull/482)), ([#496](https://github.com/MetaMask/accounts/pull/496)), ([#509](https://github.com/MetaMask/accounts/pull/509))
|
|
32
|
+
- This package now contains the keyring v2 wrapper helpers (`EthKeyringWrapper`, `EthKeyringMethod`).
|
|
33
|
+
- The account ID (generated by `KeyringAccountRegistry`) are now deterministic for EVM addresses.
|
|
34
|
+
- Bump `@metamask/keyring-api` from `^21.6.0` to `^22.0.0` ([#482](https://github.com/MetaMask/accounts/pull/482))
|
|
35
|
+
- Bump `@metamask/account-api` from `^1.0.0` to `^1.0.1` ([#487](https://github.com/MetaMask/accounts/pull/487))
|
|
36
|
+
- Bump `@metamask/utils` from `^11.1.0` to `^11.10.0` ([#489](https://github.com/MetaMask/accounts/pull/489))
|
|
37
|
+
|
|
10
38
|
## [13.1.0]
|
|
11
39
|
|
|
12
40
|
### Added
|
|
@@ -235,7 +263,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
235
263
|
- Deserialize method (and `HdKeyring` constructor by extension) can no longer be passed an options object containing a value for `numberOfAccounts` if it is not also containing a value for `mnemonic`.
|
|
236
264
|
- Package name changed from `eth-hd-keyring` to `@metamask/eth-hd-keyring`.
|
|
237
265
|
|
|
238
|
-
[Unreleased]: https://github.com/MetaMask/accounts/compare/@metamask/eth-hd-keyring@
|
|
266
|
+
[Unreleased]: https://github.com/MetaMask/accounts/compare/@metamask/eth-hd-keyring@14.0.0...HEAD
|
|
267
|
+
[14.0.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-hd-keyring@13.1.1...@metamask/eth-hd-keyring@14.0.0
|
|
268
|
+
[13.1.1]: https://github.com/MetaMask/accounts/compare/@metamask/eth-hd-keyring@13.1.0...@metamask/eth-hd-keyring@13.1.1
|
|
239
269
|
[13.1.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-hd-keyring@13.0.0...@metamask/eth-hd-keyring@13.1.0
|
|
240
270
|
[13.0.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-hd-keyring@12.1.0...@metamask/eth-hd-keyring@13.0.0
|
|
241
271
|
[12.1.0]: https://github.com/MetaMask/accounts/compare/@metamask/eth-hd-keyring@12.0.0...@metamask/eth-hd-keyring@12.1.0
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.HdKeyring = void 0;
|
|
4
4
|
var hd_keyring_1 = require("./hd-keyring.cjs");
|
|
5
5
|
Object.defineProperty(exports, "HdKeyring", { enumerable: true, get: function () { return hd_keyring_1.HdKeyring; } });
|
|
6
|
-
var hd_keyring_v2_1 = require("./hd-keyring-v2.cjs");
|
|
7
|
-
Object.defineProperty(exports, "HdKeyringV2", { enumerable: true, get: function () { return hd_keyring_v2_1.HdKeyringV2; } });
|
|
8
6
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+CAAyC;AAAhC,uGAAA,SAAS,OAAA
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+CAAyC;AAAhC,uGAAA,SAAS,OAAA","sourcesContent":["export { HdKeyring } from './hd-keyring';\nexport type {\n SerializedHDKeyringState,\n DeserializableHDKeyringState,\n HDKeyringOptions,\n HDKeyringAccountSelectionOptions,\n} from './hd-keyring';\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { HdKeyring } from "./hd-keyring.cjs";
|
|
2
2
|
export type { SerializedHDKeyringState, DeserializableHDKeyringState, HDKeyringOptions, HDKeyringAccountSelectionOptions, } from "./hd-keyring.cjs";
|
|
3
|
-
export { HdKeyringV2, type HdKeyringV2Options } from "./hd-keyring-v2.cjs";
|
|
4
3
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,yBAAqB;AACzC,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,gCAAgC,GACjC,yBAAqB
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,yBAAqB;AACzC,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,gCAAgC,GACjC,yBAAqB"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
1
|
export { HdKeyring } from "./hd-keyring.mjs";
|
|
2
2
|
export type { SerializedHDKeyringState, DeserializableHDKeyringState, HDKeyringOptions, HDKeyringAccountSelectionOptions, } from "./hd-keyring.mjs";
|
|
3
|
-
export { HdKeyringV2, type HdKeyringV2Options } from "./hd-keyring-v2.mjs";
|
|
4
3
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,yBAAqB;AACzC,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,gCAAgC,GACjC,yBAAqB
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,yBAAqB;AACzC,YAAY,EACV,wBAAwB,EACxB,4BAA4B,EAC5B,gBAAgB,EAChB,gCAAgC,GACjC,yBAAqB"}
|
package/dist/index.mjs
CHANGED
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,yBAAqB
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,yBAAqB","sourcesContent":["export { HdKeyring } from './hd-keyring';\nexport type {\n SerializedHDKeyringState,\n DeserializableHDKeyringState,\n HDKeyringOptions,\n HDKeyringAccountSelectionOptions,\n} from './hd-keyring';\n"]}
|
|
@@ -4,10 +4,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
4
4
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
5
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
6
|
};
|
|
7
|
-
var
|
|
7
|
+
var _HdKeyring_instances, _HdKeyring_isLastAccount, _HdKeyring_createKeyringAccount;
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.
|
|
9
|
+
exports.HdKeyring = void 0;
|
|
10
10
|
const keyring_api_1 = require("@metamask/keyring-api");
|
|
11
|
+
const v2_1 = require("@metamask/keyring-api/v2");
|
|
12
|
+
const v2_2 = require("@metamask/keyring-sdk/v2");
|
|
11
13
|
const utils_1 = require("@metamask/utils");
|
|
12
14
|
/**
|
|
13
15
|
* Methods supported by HD keyring EOA accounts.
|
|
@@ -20,28 +22,28 @@ const HD_KEYRING_METHODS = [
|
|
|
20
22
|
keyring_api_1.EthMethod.SignTypedDataV1,
|
|
21
23
|
keyring_api_1.EthMethod.SignTypedDataV3,
|
|
22
24
|
keyring_api_1.EthMethod.SignTypedDataV4,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
v2_2.EthKeyringMethod.Decrypt,
|
|
26
|
+
v2_2.EthKeyringMethod.GetEncryptionPublicKey,
|
|
27
|
+
v2_2.EthKeyringMethod.GetAppKeyAddress,
|
|
28
|
+
v2_2.EthKeyringMethod.SignEip7702Authorization,
|
|
27
29
|
];
|
|
28
|
-
const
|
|
30
|
+
const hdKeyringCapabilities = {
|
|
29
31
|
scopes: [keyring_api_1.EthScope.Eoa],
|
|
30
32
|
bip44: {
|
|
31
33
|
deriveIndex: true,
|
|
32
34
|
},
|
|
33
35
|
privateKey: {
|
|
34
|
-
exportFormats: [{ encoding:
|
|
36
|
+
exportFormats: [{ encoding: v2_1.PrivateKeyEncoding.Hexadecimal }],
|
|
35
37
|
},
|
|
36
38
|
};
|
|
37
|
-
class
|
|
39
|
+
class HdKeyring extends v2_2.EthKeyringWrapper {
|
|
38
40
|
constructor(options) {
|
|
39
41
|
super({
|
|
40
|
-
type:
|
|
42
|
+
type: v2_1.KeyringType.Hd,
|
|
41
43
|
inner: options.legacyKeyring,
|
|
42
|
-
capabilities:
|
|
44
|
+
capabilities: hdKeyringCapabilities,
|
|
43
45
|
});
|
|
44
|
-
|
|
46
|
+
_HdKeyring_instances.add(this);
|
|
45
47
|
this.entropySource = options.entropySource;
|
|
46
48
|
}
|
|
47
49
|
async getAccounts() {
|
|
@@ -56,7 +58,7 @@ class HdKeyringV2 extends keyring_api_1.EthKeyringWrapper {
|
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
60
|
// Create and register the account if not already cached
|
|
59
|
-
return __classPrivateFieldGet(this,
|
|
61
|
+
return __classPrivateFieldGet(this, _HdKeyring_instances, "m", _HdKeyring_createKeyringAccount).call(this, address, addressIndex);
|
|
60
62
|
});
|
|
61
63
|
}
|
|
62
64
|
async createAccounts(options) {
|
|
@@ -90,7 +92,7 @@ class HdKeyringV2 extends keyring_api_1.EthKeyringWrapper {
|
|
|
90
92
|
if (!newAddress) {
|
|
91
93
|
throw new Error('Failed to create new account');
|
|
92
94
|
}
|
|
93
|
-
const newAccount = __classPrivateFieldGet(this,
|
|
95
|
+
const newAccount = __classPrivateFieldGet(this, _HdKeyring_instances, "m", _HdKeyring_createKeyringAccount).call(this, newAddress, targetIndex);
|
|
94
96
|
return [newAccount];
|
|
95
97
|
});
|
|
96
98
|
}
|
|
@@ -108,7 +110,7 @@ class HdKeyringV2 extends keyring_api_1.EthKeyringWrapper {
|
|
|
108
110
|
const hexAddress = this.toHexAddress(address);
|
|
109
111
|
// Assert that the account to delete is the last one in the inner keyring
|
|
110
112
|
// We check against the inner keyring directly to avoid stale registry issues
|
|
111
|
-
if (!(await __classPrivateFieldGet(this,
|
|
113
|
+
if (!(await __classPrivateFieldGet(this, _HdKeyring_instances, "m", _HdKeyring_isLastAccount).call(this, address))) {
|
|
112
114
|
throw new Error('Can only delete the last account in the HD keyring due to derivation index constraints.');
|
|
113
115
|
}
|
|
114
116
|
// Remove from the legacy keyring
|
|
@@ -127,9 +129,9 @@ class HdKeyringV2 extends keyring_api_1.EthKeyringWrapper {
|
|
|
127
129
|
async exportAccount(accountId, options) {
|
|
128
130
|
const account = await this.getAccount(accountId);
|
|
129
131
|
// Validate encoding - we only support hexadecimal for Ethereum keys
|
|
130
|
-
const requestedEncoding = options?.encoding ??
|
|
131
|
-
if (requestedEncoding !==
|
|
132
|
-
throw new Error(`Unsupported encoding for Ethereum HD keyring: ${requestedEncoding}. Only '${
|
|
132
|
+
const requestedEncoding = options?.encoding ?? v2_1.PrivateKeyEncoding.Hexadecimal;
|
|
133
|
+
if (requestedEncoding !== v2_1.PrivateKeyEncoding.Hexadecimal) {
|
|
134
|
+
throw new Error(`Unsupported encoding for Ethereum HD keyring: ${requestedEncoding}. Only '${v2_1.PrivateKeyEncoding.Hexadecimal}' is supported.`);
|
|
133
135
|
}
|
|
134
136
|
// The legacy HdKeyring returns a hex string without 0x prefix.
|
|
135
137
|
const privateKeyWithout0x = await this.inner.exportAccount(this.toHexAddress(account.address));
|
|
@@ -137,12 +139,12 @@ class HdKeyringV2 extends keyring_api_1.EthKeyringWrapper {
|
|
|
137
139
|
return {
|
|
138
140
|
type: 'private-key',
|
|
139
141
|
privateKey,
|
|
140
|
-
encoding:
|
|
142
|
+
encoding: v2_1.PrivateKeyEncoding.Hexadecimal,
|
|
141
143
|
};
|
|
142
144
|
}
|
|
143
145
|
}
|
|
144
|
-
exports.
|
|
145
|
-
|
|
146
|
+
exports.HdKeyring = HdKeyring;
|
|
147
|
+
_HdKeyring_instances = new WeakSet(), _HdKeyring_isLastAccount =
|
|
146
148
|
/**
|
|
147
149
|
* Checks if the given address is the last account in the inner keyring.
|
|
148
150
|
* This compares against the actual inner keyring state, not the registry,
|
|
@@ -151,11 +153,11 @@ _HdKeyringV2_instances = new WeakSet(), _HdKeyringV2_isLastAccount =
|
|
|
151
153
|
* @param address - The address to check.
|
|
152
154
|
* @returns True if this is the last account in the inner keyring.
|
|
153
155
|
*/
|
|
154
|
-
async function
|
|
156
|
+
async function _HdKeyring_isLastAccount(address) {
|
|
155
157
|
const innerAddresses = await this.inner.getAccounts();
|
|
156
158
|
const lastAddress = innerAddresses[innerAddresses.length - 1];
|
|
157
159
|
return address === lastAddress;
|
|
158
|
-
},
|
|
160
|
+
}, _HdKeyring_createKeyringAccount = function _HdKeyring_createKeyringAccount(address, addressIndex) {
|
|
159
161
|
const id = this.registry.register(address);
|
|
160
162
|
const account = {
|
|
161
163
|
id,
|
|
@@ -177,4 +179,4 @@ async function _HdKeyringV2_isLastAccount(address) {
|
|
|
177
179
|
this.registry.set(account);
|
|
178
180
|
return account;
|
|
179
181
|
};
|
|
180
|
-
//# sourceMappingURL=hd-keyring
|
|
182
|
+
//# sourceMappingURL=hd-keyring.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hd-keyring.cjs","sourceRoot":"","sources":["../../src/v2/hd-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport {\n EthAccountType,\n EthMethod,\n EthScope,\n type KeyringAccount,\n KeyringAccountEntropyTypeOption,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport {\n type CreateAccountOptions,\n type ExportAccountOptions,\n type ExportedAccount,\n type KeyringCapabilities,\n type Keyring,\n KeyringType,\n PrivateKeyEncoding,\n} from '@metamask/keyring-api/v2';\nimport { EthKeyringMethod, EthKeyringWrapper } from '@metamask/keyring-sdk/v2';\nimport type { AccountId } from '@metamask/keyring-utils';\nimport { add0x, type Hex } from '@metamask/utils';\n\nimport type { HdKeyring as LegacyHdKeyring } from '../hd-keyring';\n\n/**\n * Methods supported by HD keyring EOA accounts.\n * HD keyrings support all standard signing methods plus encryption and app keys.\n */\nconst HD_KEYRING_METHODS = [\n EthMethod.SignTransaction,\n EthMethod.Sign,\n EthMethod.PersonalSign,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n EthKeyringMethod.Decrypt,\n EthKeyringMethod.GetEncryptionPublicKey,\n EthKeyringMethod.GetAppKeyAddress,\n EthKeyringMethod.SignEip7702Authorization,\n];\n\nconst hdKeyringCapabilities: KeyringCapabilities = {\n scopes: [EthScope.Eoa],\n bip44: {\n deriveIndex: true,\n },\n privateKey: {\n exportFormats: [{ encoding: PrivateKeyEncoding.Hexadecimal }],\n },\n};\n\n/**\n * Concrete {@link Keyring} adapter for {@link HdKeyring}.\n *\n * This wrapper exposes the accounts and signing capabilities of the legacy\n * HD keyring via the unified V2 interface.\n */\nexport type HdKeyringOptions = {\n legacyKeyring: LegacyHdKeyring;\n entropySource: EntropySourceId;\n};\n\nexport class HdKeyring\n extends EthKeyringWrapper<LegacyHdKeyring, Bip44Account<KeyringAccount>>\n implements Keyring\n{\n protected readonly entropySource: EntropySourceId;\n\n constructor(options: HdKeyringOptions) {\n super({\n type: KeyringType.Hd,\n inner: options.legacyKeyring,\n capabilities: hdKeyringCapabilities,\n });\n this.entropySource = options.entropySource;\n }\n\n /**\n * Checks if the given address is the last account in the inner keyring.\n * This compares against the actual inner keyring state, not the registry,\n * to avoid issues with stale registry entries.\n *\n * @param address - The address to check.\n * @returns True if this is the last account in the inner keyring.\n */\n async #isLastAccount(address: string): Promise<boolean> {\n const innerAddresses = await this.inner.getAccounts();\n const lastAddress = innerAddresses[innerAddresses.length - 1];\n return address === lastAddress;\n }\n\n /**\n * Creates a KeyringAccount object for the given address and index.\n *\n * @param address - The account address.\n * @param addressIndex - The account index in the HD path.\n * @returns The created KeyringAccount.\n */\n #createKeyringAccount(\n address: Hex,\n addressIndex: number,\n ): Bip44Account<KeyringAccount> {\n const id = this.registry.register(address);\n\n const account: Bip44Account<KeyringAccount> = {\n id,\n type: EthAccountType.Eoa,\n address,\n scopes: [...this.capabilities.scopes],\n methods: [...HD_KEYRING_METHODS],\n options: {\n entropy: {\n type: KeyringAccountEntropyTypeOption.Mnemonic,\n id: this.entropySource,\n groupIndex: addressIndex,\n derivationPath: `${this.inner.hdPath}/${addressIndex}`,\n },\n exportable: true,\n },\n };\n\n // Add the account to the registry\n this.registry.set(account);\n\n return account;\n }\n\n async getAccounts(): Promise<Bip44Account<KeyringAccount>[]> {\n const addresses = await this.inner.getAccounts();\n\n return addresses.map((address, addressIndex) => {\n // Check if we already have this account in the registry\n const existingId = this.registry.getAccountId(address);\n if (existingId) {\n const cached = this.registry.get(existingId);\n if (cached) {\n return cached;\n }\n }\n\n // Create and register the account if not already cached\n return this.#createKeyringAccount(address, addressIndex);\n });\n }\n\n async createAccounts(\n options: CreateAccountOptions,\n ): Promise<Bip44Account<KeyringAccount>[]> {\n return this.withLock(async () => {\n // For HD keyring, we only support BIP-44 derive index\n if (options.type !== 'bip44:derive-index') {\n throw new Error(\n `Unsupported account creation type for HdKeyring: ${options.type}`,\n );\n }\n\n // Validate that the entropy source matches this keyring's entropy source\n if (options.entropySource !== this.entropySource) {\n throw new Error(\n `Entropy source mismatch: expected '${this.entropySource}', got '${options.entropySource}'`,\n );\n }\n\n // Sync with the inner keyring state in case it was modified externally\n // This ensures our cache is up-to-date before we make changes\n const currentAccounts = await this.getAccounts();\n const currentCount = currentAccounts.length;\n const targetIndex = options.groupIndex;\n\n // Check if an account at this index already exists\n // Since only the last account can be deleted, array position always equals groupIndex\n const existingAccount = currentAccounts[targetIndex];\n if (existingAccount) {\n return [existingAccount];\n }\n\n // Only allow derivation of the next account in sequence\n if (targetIndex !== currentCount) {\n throw new Error(\n `Can only create the next account in sequence. ` +\n `Expected groupIndex ${currentCount}, got ${targetIndex}.`,\n );\n }\n\n // Add the next account\n const [newAddress] = await this.inner.addAccounts(1);\n\n if (!newAddress) {\n throw new Error('Failed to create new account');\n }\n\n const newAccount = this.#createKeyringAccount(newAddress, targetIndex);\n\n return [newAccount];\n });\n }\n\n /**\n * Delete an account from the keyring.\n *\n * ⚠️ Warning: Only deleting the last account is possible.\n *\n * @param accountId - The account ID to delete.\n */\n async deleteAccount(accountId: AccountId): Promise<void> {\n await this.withLock(async () => {\n // Get the account first, before any registry operations\n const { address } = await this.getAccount(accountId);\n const hexAddress = this.toHexAddress(address);\n\n // Assert that the account to delete is the last one in the inner keyring\n // We check against the inner keyring directly to avoid stale registry issues\n if (!(await this.#isLastAccount(address))) {\n throw new Error(\n 'Can only delete the last account in the HD keyring due to derivation index constraints.',\n );\n }\n\n // Remove from the legacy keyring\n this.inner.removeAccount(hexAddress);\n\n // Remove from the registry\n this.registry.delete(accountId);\n });\n }\n\n /**\n * Export the private key for an account in hexadecimal format.\n *\n * @param accountId - The ID of the account to export.\n * @param options - Export options (only hexadecimal encoding is supported).\n * @returns The exported account with private key.\n */\n async exportAccount(\n accountId: AccountId,\n options?: ExportAccountOptions,\n ): Promise<ExportedAccount> {\n const account = await this.getAccount(accountId);\n\n // Validate encoding - we only support hexadecimal for Ethereum keys\n const requestedEncoding =\n options?.encoding ?? PrivateKeyEncoding.Hexadecimal;\n\n if (requestedEncoding !== PrivateKeyEncoding.Hexadecimal) {\n throw new Error(\n `Unsupported encoding for Ethereum HD keyring: ${requestedEncoding}. Only '${PrivateKeyEncoding.Hexadecimal}' is supported.`,\n );\n }\n\n // The legacy HdKeyring returns a hex string without 0x prefix.\n const privateKeyWithout0x = await this.inner.exportAccount(\n this.toHexAddress(account.address),\n );\n const privateKey = add0x(privateKeyWithout0x);\n\n return {\n type: 'private-key',\n privateKey,\n encoding: PrivateKeyEncoding.Hexadecimal,\n };\n }\n}\n"]}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import type { Bip44Account } from "@metamask/account-api";
|
|
2
|
-
import { type
|
|
2
|
+
import { type KeyringAccount, type EntropySourceId } from "@metamask/keyring-api";
|
|
3
|
+
import { type CreateAccountOptions, type ExportAccountOptions, type ExportedAccount, type Keyring } from "@metamask/keyring-api/v2";
|
|
4
|
+
import { EthKeyringWrapper } from "@metamask/keyring-sdk/v2";
|
|
3
5
|
import type { AccountId } from "@metamask/keyring-utils";
|
|
4
|
-
import type { HdKeyring } from "
|
|
6
|
+
import type { HdKeyring as LegacyHdKeyring } from "../hd-keyring.cjs";
|
|
5
7
|
/**
|
|
6
|
-
* Concrete {@link
|
|
8
|
+
* Concrete {@link Keyring} adapter for {@link HdKeyring}.
|
|
7
9
|
*
|
|
8
10
|
* This wrapper exposes the accounts and signing capabilities of the legacy
|
|
9
11
|
* HD keyring via the unified V2 interface.
|
|
10
12
|
*/
|
|
11
|
-
export type
|
|
12
|
-
legacyKeyring:
|
|
13
|
+
export type HdKeyringOptions = {
|
|
14
|
+
legacyKeyring: LegacyHdKeyring;
|
|
13
15
|
entropySource: EntropySourceId;
|
|
14
16
|
};
|
|
15
|
-
export declare class
|
|
17
|
+
export declare class HdKeyring extends EthKeyringWrapper<LegacyHdKeyring, Bip44Account<KeyringAccount>> implements Keyring {
|
|
16
18
|
#private;
|
|
17
19
|
protected readonly entropySource: EntropySourceId;
|
|
18
|
-
constructor(options:
|
|
20
|
+
constructor(options: HdKeyringOptions);
|
|
19
21
|
getAccounts(): Promise<Bip44Account<KeyringAccount>[]>;
|
|
20
22
|
createAccounts(options: CreateAccountOptions): Promise<Bip44Account<KeyringAccount>[]>;
|
|
21
23
|
/**
|
|
@@ -35,4 +37,4 @@ export declare class HdKeyringV2 extends EthKeyringWrapper<HdKeyring, Bip44Accou
|
|
|
35
37
|
*/
|
|
36
38
|
exportAccount(accountId: AccountId, options?: ExportAccountOptions): Promise<ExportedAccount>;
|
|
37
39
|
}
|
|
38
|
-
//# sourceMappingURL=hd-keyring
|
|
40
|
+
//# sourceMappingURL=hd-keyring.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hd-keyring.d.cts","sourceRoot":"","sources":["../../src/v2/hd-keyring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,EAIL,KAAK,cAAc,EAEnB,KAAK,eAAe,EACrB,8BAA8B;AAC/B,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EAEpB,KAAK,OAAO,EAGb,iCAAiC;AAClC,OAAO,EAAoB,iBAAiB,EAAE,iCAAiC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,gCAAgC;AAGzD,OAAO,KAAK,EAAE,SAAS,IAAI,eAAe,EAAE,0BAAsB;AA6BlE;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE,eAAe,CAAC;IAC/B,aAAa,EAAE,eAAe,CAAC;CAChC,CAAC;AAEF,qBAAa,SACX,SAAQ,iBAAiB,CAAC,eAAe,EAAE,YAAY,CAAC,cAAc,CAAC,CACvE,YAAW,OAAO;;IAElB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;gBAEtC,OAAO,EAAE,gBAAgB;IA2D/B,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkBtD,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkD1C;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxD;;;;;;OAMG;IACG,aAAa,CACjB,SAAS,EAAE,SAAS,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;CAyB5B"}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import type { Bip44Account } from "@metamask/account-api";
|
|
2
|
-
import { type
|
|
2
|
+
import { type KeyringAccount, type EntropySourceId } from "@metamask/keyring-api";
|
|
3
|
+
import { type CreateAccountOptions, type ExportAccountOptions, type ExportedAccount, type Keyring } from "@metamask/keyring-api/v2";
|
|
4
|
+
import { EthKeyringWrapper } from "@metamask/keyring-sdk/v2";
|
|
3
5
|
import type { AccountId } from "@metamask/keyring-utils";
|
|
4
|
-
import type { HdKeyring } from "
|
|
6
|
+
import type { HdKeyring as LegacyHdKeyring } from "../hd-keyring.mjs";
|
|
5
7
|
/**
|
|
6
|
-
* Concrete {@link
|
|
8
|
+
* Concrete {@link Keyring} adapter for {@link HdKeyring}.
|
|
7
9
|
*
|
|
8
10
|
* This wrapper exposes the accounts and signing capabilities of the legacy
|
|
9
11
|
* HD keyring via the unified V2 interface.
|
|
10
12
|
*/
|
|
11
|
-
export type
|
|
12
|
-
legacyKeyring:
|
|
13
|
+
export type HdKeyringOptions = {
|
|
14
|
+
legacyKeyring: LegacyHdKeyring;
|
|
13
15
|
entropySource: EntropySourceId;
|
|
14
16
|
};
|
|
15
|
-
export declare class
|
|
17
|
+
export declare class HdKeyring extends EthKeyringWrapper<LegacyHdKeyring, Bip44Account<KeyringAccount>> implements Keyring {
|
|
16
18
|
#private;
|
|
17
19
|
protected readonly entropySource: EntropySourceId;
|
|
18
|
-
constructor(options:
|
|
20
|
+
constructor(options: HdKeyringOptions);
|
|
19
21
|
getAccounts(): Promise<Bip44Account<KeyringAccount>[]>;
|
|
20
22
|
createAccounts(options: CreateAccountOptions): Promise<Bip44Account<KeyringAccount>[]>;
|
|
21
23
|
/**
|
|
@@ -35,4 +37,4 @@ export declare class HdKeyringV2 extends EthKeyringWrapper<HdKeyring, Bip44Accou
|
|
|
35
37
|
*/
|
|
36
38
|
exportAccount(accountId: AccountId, options?: ExportAccountOptions): Promise<ExportedAccount>;
|
|
37
39
|
}
|
|
38
|
-
//# sourceMappingURL=hd-keyring
|
|
40
|
+
//# sourceMappingURL=hd-keyring.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hd-keyring.d.mts","sourceRoot":"","sources":["../../src/v2/hd-keyring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,EAIL,KAAK,cAAc,EAEnB,KAAK,eAAe,EACrB,8BAA8B;AAC/B,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EAEpB,KAAK,OAAO,EAGb,iCAAiC;AAClC,OAAO,EAAoB,iBAAiB,EAAE,iCAAiC;AAC/E,OAAO,KAAK,EAAE,SAAS,EAAE,gCAAgC;AAGzD,OAAO,KAAK,EAAE,SAAS,IAAI,eAAe,EAAE,0BAAsB;AA6BlE;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,aAAa,EAAE,eAAe,CAAC;IAC/B,aAAa,EAAE,eAAe,CAAC;CAChC,CAAC;AAEF,qBAAa,SACX,SAAQ,iBAAiB,CAAC,eAAe,EAAE,YAAY,CAAC,cAAc,CAAC,CACvE,YAAW,OAAO;;IAElB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;gBAEtC,OAAO,EAAE,gBAAgB;IA2D/B,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkBtD,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkD1C;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxD;;;;;;OAMG;IACG,aAAa,CACjB,SAAS,EAAE,SAAS,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;CAyB5B"}
|
|
@@ -3,8 +3,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var
|
|
7
|
-
import { EthAccountType,
|
|
6
|
+
var _HdKeyring_instances, _HdKeyring_isLastAccount, _HdKeyring_createKeyringAccount;
|
|
7
|
+
import { EthAccountType, EthMethod, EthScope, KeyringAccountEntropyTypeOption } from "@metamask/keyring-api";
|
|
8
|
+
import { KeyringType, PrivateKeyEncoding } from "@metamask/keyring-api/v2";
|
|
9
|
+
import { EthKeyringMethod, EthKeyringWrapper } from "@metamask/keyring-sdk/v2";
|
|
8
10
|
import { add0x } from "@metamask/utils";
|
|
9
11
|
/**
|
|
10
12
|
* Methods supported by HD keyring EOA accounts.
|
|
@@ -22,7 +24,7 @@ const HD_KEYRING_METHODS = [
|
|
|
22
24
|
EthKeyringMethod.GetAppKeyAddress,
|
|
23
25
|
EthKeyringMethod.SignEip7702Authorization,
|
|
24
26
|
];
|
|
25
|
-
const
|
|
27
|
+
const hdKeyringCapabilities = {
|
|
26
28
|
scopes: [EthScope.Eoa],
|
|
27
29
|
bip44: {
|
|
28
30
|
deriveIndex: true,
|
|
@@ -31,14 +33,14 @@ const hdKeyringV2Capabilities = {
|
|
|
31
33
|
exportFormats: [{ encoding: PrivateKeyEncoding.Hexadecimal }],
|
|
32
34
|
},
|
|
33
35
|
};
|
|
34
|
-
export class
|
|
36
|
+
export class HdKeyring extends EthKeyringWrapper {
|
|
35
37
|
constructor(options) {
|
|
36
38
|
super({
|
|
37
39
|
type: KeyringType.Hd,
|
|
38
40
|
inner: options.legacyKeyring,
|
|
39
|
-
capabilities:
|
|
41
|
+
capabilities: hdKeyringCapabilities,
|
|
40
42
|
});
|
|
41
|
-
|
|
43
|
+
_HdKeyring_instances.add(this);
|
|
42
44
|
this.entropySource = options.entropySource;
|
|
43
45
|
}
|
|
44
46
|
async getAccounts() {
|
|
@@ -53,7 +55,7 @@ export class HdKeyringV2 extends EthKeyringWrapper {
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
// Create and register the account if not already cached
|
|
56
|
-
return __classPrivateFieldGet(this,
|
|
58
|
+
return __classPrivateFieldGet(this, _HdKeyring_instances, "m", _HdKeyring_createKeyringAccount).call(this, address, addressIndex);
|
|
57
59
|
});
|
|
58
60
|
}
|
|
59
61
|
async createAccounts(options) {
|
|
@@ -87,7 +89,7 @@ export class HdKeyringV2 extends EthKeyringWrapper {
|
|
|
87
89
|
if (!newAddress) {
|
|
88
90
|
throw new Error('Failed to create new account');
|
|
89
91
|
}
|
|
90
|
-
const newAccount = __classPrivateFieldGet(this,
|
|
92
|
+
const newAccount = __classPrivateFieldGet(this, _HdKeyring_instances, "m", _HdKeyring_createKeyringAccount).call(this, newAddress, targetIndex);
|
|
91
93
|
return [newAccount];
|
|
92
94
|
});
|
|
93
95
|
}
|
|
@@ -105,7 +107,7 @@ export class HdKeyringV2 extends EthKeyringWrapper {
|
|
|
105
107
|
const hexAddress = this.toHexAddress(address);
|
|
106
108
|
// Assert that the account to delete is the last one in the inner keyring
|
|
107
109
|
// We check against the inner keyring directly to avoid stale registry issues
|
|
108
|
-
if (!(await __classPrivateFieldGet(this,
|
|
110
|
+
if (!(await __classPrivateFieldGet(this, _HdKeyring_instances, "m", _HdKeyring_isLastAccount).call(this, address))) {
|
|
109
111
|
throw new Error('Can only delete the last account in the HD keyring due to derivation index constraints.');
|
|
110
112
|
}
|
|
111
113
|
// Remove from the legacy keyring
|
|
@@ -138,7 +140,7 @@ export class HdKeyringV2 extends EthKeyringWrapper {
|
|
|
138
140
|
};
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
|
-
|
|
143
|
+
_HdKeyring_instances = new WeakSet(), _HdKeyring_isLastAccount =
|
|
142
144
|
/**
|
|
143
145
|
* Checks if the given address is the last account in the inner keyring.
|
|
144
146
|
* This compares against the actual inner keyring state, not the registry,
|
|
@@ -147,11 +149,11 @@ _HdKeyringV2_instances = new WeakSet(), _HdKeyringV2_isLastAccount =
|
|
|
147
149
|
* @param address - The address to check.
|
|
148
150
|
* @returns True if this is the last account in the inner keyring.
|
|
149
151
|
*/
|
|
150
|
-
async function
|
|
152
|
+
async function _HdKeyring_isLastAccount(address) {
|
|
151
153
|
const innerAddresses = await this.inner.getAccounts();
|
|
152
154
|
const lastAddress = innerAddresses[innerAddresses.length - 1];
|
|
153
155
|
return address === lastAddress;
|
|
154
|
-
},
|
|
156
|
+
}, _HdKeyring_createKeyringAccount = function _HdKeyring_createKeyringAccount(address, addressIndex) {
|
|
155
157
|
const id = this.registry.register(address);
|
|
156
158
|
const account = {
|
|
157
159
|
id,
|
|
@@ -173,4 +175,4 @@ async function _HdKeyringV2_isLastAccount(address) {
|
|
|
173
175
|
this.registry.set(account);
|
|
174
176
|
return account;
|
|
175
177
|
};
|
|
176
|
-
//# sourceMappingURL=hd-keyring
|
|
178
|
+
//# sourceMappingURL=hd-keyring.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hd-keyring.mjs","sourceRoot":"","sources":["../../src/v2/hd-keyring.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport {\n EthAccountType,\n EthMethod,\n EthScope,\n type KeyringAccount,\n KeyringAccountEntropyTypeOption,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport {\n type CreateAccountOptions,\n type ExportAccountOptions,\n type ExportedAccount,\n type KeyringCapabilities,\n type Keyring,\n KeyringType,\n PrivateKeyEncoding,\n} from '@metamask/keyring-api/v2';\nimport { EthKeyringMethod, EthKeyringWrapper } from '@metamask/keyring-sdk/v2';\nimport type { AccountId } from '@metamask/keyring-utils';\nimport { add0x, type Hex } from '@metamask/utils';\n\nimport type { HdKeyring as LegacyHdKeyring } from '../hd-keyring';\n\n/**\n * Methods supported by HD keyring EOA accounts.\n * HD keyrings support all standard signing methods plus encryption and app keys.\n */\nconst HD_KEYRING_METHODS = [\n EthMethod.SignTransaction,\n EthMethod.Sign,\n EthMethod.PersonalSign,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n EthKeyringMethod.Decrypt,\n EthKeyringMethod.GetEncryptionPublicKey,\n EthKeyringMethod.GetAppKeyAddress,\n EthKeyringMethod.SignEip7702Authorization,\n];\n\nconst hdKeyringCapabilities: KeyringCapabilities = {\n scopes: [EthScope.Eoa],\n bip44: {\n deriveIndex: true,\n },\n privateKey: {\n exportFormats: [{ encoding: PrivateKeyEncoding.Hexadecimal }],\n },\n};\n\n/**\n * Concrete {@link Keyring} adapter for {@link HdKeyring}.\n *\n * This wrapper exposes the accounts and signing capabilities of the legacy\n * HD keyring via the unified V2 interface.\n */\nexport type HdKeyringOptions = {\n legacyKeyring: LegacyHdKeyring;\n entropySource: EntropySourceId;\n};\n\nexport class HdKeyring\n extends EthKeyringWrapper<LegacyHdKeyring, Bip44Account<KeyringAccount>>\n implements Keyring\n{\n protected readonly entropySource: EntropySourceId;\n\n constructor(options: HdKeyringOptions) {\n super({\n type: KeyringType.Hd,\n inner: options.legacyKeyring,\n capabilities: hdKeyringCapabilities,\n });\n this.entropySource = options.entropySource;\n }\n\n /**\n * Checks if the given address is the last account in the inner keyring.\n * This compares against the actual inner keyring state, not the registry,\n * to avoid issues with stale registry entries.\n *\n * @param address - The address to check.\n * @returns True if this is the last account in the inner keyring.\n */\n async #isLastAccount(address: string): Promise<boolean> {\n const innerAddresses = await this.inner.getAccounts();\n const lastAddress = innerAddresses[innerAddresses.length - 1];\n return address === lastAddress;\n }\n\n /**\n * Creates a KeyringAccount object for the given address and index.\n *\n * @param address - The account address.\n * @param addressIndex - The account index in the HD path.\n * @returns The created KeyringAccount.\n */\n #createKeyringAccount(\n address: Hex,\n addressIndex: number,\n ): Bip44Account<KeyringAccount> {\n const id = this.registry.register(address);\n\n const account: Bip44Account<KeyringAccount> = {\n id,\n type: EthAccountType.Eoa,\n address,\n scopes: [...this.capabilities.scopes],\n methods: [...HD_KEYRING_METHODS],\n options: {\n entropy: {\n type: KeyringAccountEntropyTypeOption.Mnemonic,\n id: this.entropySource,\n groupIndex: addressIndex,\n derivationPath: `${this.inner.hdPath}/${addressIndex}`,\n },\n exportable: true,\n },\n };\n\n // Add the account to the registry\n this.registry.set(account);\n\n return account;\n }\n\n async getAccounts(): Promise<Bip44Account<KeyringAccount>[]> {\n const addresses = await this.inner.getAccounts();\n\n return addresses.map((address, addressIndex) => {\n // Check if we already have this account in the registry\n const existingId = this.registry.getAccountId(address);\n if (existingId) {\n const cached = this.registry.get(existingId);\n if (cached) {\n return cached;\n }\n }\n\n // Create and register the account if not already cached\n return this.#createKeyringAccount(address, addressIndex);\n });\n }\n\n async createAccounts(\n options: CreateAccountOptions,\n ): Promise<Bip44Account<KeyringAccount>[]> {\n return this.withLock(async () => {\n // For HD keyring, we only support BIP-44 derive index\n if (options.type !== 'bip44:derive-index') {\n throw new Error(\n `Unsupported account creation type for HdKeyring: ${options.type}`,\n );\n }\n\n // Validate that the entropy source matches this keyring's entropy source\n if (options.entropySource !== this.entropySource) {\n throw new Error(\n `Entropy source mismatch: expected '${this.entropySource}', got '${options.entropySource}'`,\n );\n }\n\n // Sync with the inner keyring state in case it was modified externally\n // This ensures our cache is up-to-date before we make changes\n const currentAccounts = await this.getAccounts();\n const currentCount = currentAccounts.length;\n const targetIndex = options.groupIndex;\n\n // Check if an account at this index already exists\n // Since only the last account can be deleted, array position always equals groupIndex\n const existingAccount = currentAccounts[targetIndex];\n if (existingAccount) {\n return [existingAccount];\n }\n\n // Only allow derivation of the next account in sequence\n if (targetIndex !== currentCount) {\n throw new Error(\n `Can only create the next account in sequence. ` +\n `Expected groupIndex ${currentCount}, got ${targetIndex}.`,\n );\n }\n\n // Add the next account\n const [newAddress] = await this.inner.addAccounts(1);\n\n if (!newAddress) {\n throw new Error('Failed to create new account');\n }\n\n const newAccount = this.#createKeyringAccount(newAddress, targetIndex);\n\n return [newAccount];\n });\n }\n\n /**\n * Delete an account from the keyring.\n *\n * ⚠️ Warning: Only deleting the last account is possible.\n *\n * @param accountId - The account ID to delete.\n */\n async deleteAccount(accountId: AccountId): Promise<void> {\n await this.withLock(async () => {\n // Get the account first, before any registry operations\n const { address } = await this.getAccount(accountId);\n const hexAddress = this.toHexAddress(address);\n\n // Assert that the account to delete is the last one in the inner keyring\n // We check against the inner keyring directly to avoid stale registry issues\n if (!(await this.#isLastAccount(address))) {\n throw new Error(\n 'Can only delete the last account in the HD keyring due to derivation index constraints.',\n );\n }\n\n // Remove from the legacy keyring\n this.inner.removeAccount(hexAddress);\n\n // Remove from the registry\n this.registry.delete(accountId);\n });\n }\n\n /**\n * Export the private key for an account in hexadecimal format.\n *\n * @param accountId - The ID of the account to export.\n * @param options - Export options (only hexadecimal encoding is supported).\n * @returns The exported account with private key.\n */\n async exportAccount(\n accountId: AccountId,\n options?: ExportAccountOptions,\n ): Promise<ExportedAccount> {\n const account = await this.getAccount(accountId);\n\n // Validate encoding - we only support hexadecimal for Ethereum keys\n const requestedEncoding =\n options?.encoding ?? PrivateKeyEncoding.Hexadecimal;\n\n if (requestedEncoding !== PrivateKeyEncoding.Hexadecimal) {\n throw new Error(\n `Unsupported encoding for Ethereum HD keyring: ${requestedEncoding}. Only '${PrivateKeyEncoding.Hexadecimal}' is supported.`,\n );\n }\n\n // The legacy HdKeyring returns a hex string without 0x prefix.\n const privateKeyWithout0x = await this.inner.exportAccount(\n this.toHexAddress(account.address),\n );\n const privateKey = add0x(privateKeyWithout0x);\n\n return {\n type: 'private-key',\n privateKey,\n encoding: PrivateKeyEncoding.Hexadecimal,\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HdKeyring = void 0;
|
|
4
|
+
var hd_keyring_1 = require("./hd-keyring.cjs");
|
|
5
|
+
Object.defineProperty(exports, "HdKeyring", { enumerable: true, get: function () { return hd_keyring_1.HdKeyring; } });
|
|
6
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sourceRoot":"","sources":["../../src/v2/index.ts"],"names":[],"mappings":";;;AAAA,+CAAgE;AAAvD,uGAAA,SAAS,OAAA","sourcesContent":["export { HdKeyring, type HdKeyringOptions } from './hd-keyring';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/v2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,yBAAqB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../../src/v2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,yBAAqB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sourceRoot":"","sources":["../../src/v2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,yBAAqB","sourcesContent":["export { HdKeyring, type HdKeyringOptions } from './hd-keyring';\n"]}
|
package/package.json
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metamask/eth-hd-keyring",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "A simple standard interface for a seed phrase generated set of Ethereum accounts
|
|
3
|
+
"version": "14.0.0",
|
|
4
|
+
"description": "A simple standard interface for a seed phrase generated set of Ethereum accounts",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ethereum",
|
|
7
7
|
"keyring"
|
|
8
8
|
],
|
|
9
|
-
"homepage": "https://github.com/MetaMask/eth-hd
|
|
9
|
+
"homepage": "https://github.com/MetaMask/accounts/tree/main/packages/keyring-eth-hd#readme",
|
|
10
10
|
"bugs": {
|
|
11
|
-
"url": "https://github.com/MetaMask/
|
|
11
|
+
"url": "https://github.com/MetaMask/accounts/issues"
|
|
12
12
|
},
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/MetaMask/
|
|
15
|
+
"url": "https://github.com/MetaMask/accounts.git"
|
|
16
16
|
},
|
|
17
17
|
"license": "ISC",
|
|
18
|
+
"sideEffects": false,
|
|
18
19
|
"exports": {
|
|
19
20
|
".": {
|
|
20
21
|
"import": {
|
|
@@ -25,7 +26,18 @@
|
|
|
25
26
|
"types": "./dist/index.d.cts",
|
|
26
27
|
"default": "./dist/index.cjs"
|
|
27
28
|
}
|
|
28
|
-
}
|
|
29
|
+
},
|
|
30
|
+
"./v2": {
|
|
31
|
+
"import": {
|
|
32
|
+
"types": "./dist/v2/index.d.mts",
|
|
33
|
+
"default": "./dist/v2/index.mjs"
|
|
34
|
+
},
|
|
35
|
+
"require": {
|
|
36
|
+
"types": "./dist/v2/index.d.cts",
|
|
37
|
+
"default": "./dist/v2/index.cjs"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"./package.json": "./package.json"
|
|
29
41
|
},
|
|
30
42
|
"main": "./dist/index.cjs",
|
|
31
43
|
"types": "./dist/index.d.cts",
|
|
@@ -33,38 +45,45 @@
|
|
|
33
45
|
"dist/"
|
|
34
46
|
],
|
|
35
47
|
"scripts": {
|
|
36
|
-
"build": "ts-bridge --project tsconfig.build.json --no-references",
|
|
48
|
+
"build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
|
|
49
|
+
"build:all": "ts-bridge --project tsconfig.build.json --verbose --clean",
|
|
37
50
|
"build:clean": "yarn build --clean",
|
|
38
51
|
"build:docs": "typedoc",
|
|
39
52
|
"changelog:update": "../../scripts/update-changelog.sh @metamask/eth-hd-keyring",
|
|
40
53
|
"changelog:validate": "../../scripts/validate-changelog.sh @metamask/eth-hd-keyring",
|
|
41
54
|
"publish:preview": "yarn npm publish --tag preview",
|
|
42
|
-
"
|
|
43
|
-
"test
|
|
55
|
+
"since-latest-release": "../../scripts/since-latest-release.sh",
|
|
56
|
+
"test": "yarn test:source && yarn test:types",
|
|
57
|
+
"test:clean": "NODE_OPTIONS=--experimental-vm-modules jest --clearCache",
|
|
58
|
+
"test:source": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=jest-silent-reporter",
|
|
59
|
+
"test:types": "../../scripts/tsd-test.sh ./src",
|
|
60
|
+
"test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
|
|
61
|
+
"test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
|
|
44
62
|
},
|
|
45
63
|
"dependencies": {
|
|
46
64
|
"@ethereumjs/tx": "^5.4.0",
|
|
47
65
|
"@ethereumjs/util": "^9.1.0",
|
|
48
66
|
"@metamask/eth-sig-util": "^8.2.0",
|
|
49
67
|
"@metamask/key-tree": "^10.0.2",
|
|
50
|
-
"@metamask/keyring-api": "^
|
|
51
|
-
"@metamask/keyring-
|
|
68
|
+
"@metamask/keyring-api": "^23.0.0",
|
|
69
|
+
"@metamask/keyring-sdk": "^2.0.0",
|
|
70
|
+
"@metamask/keyring-utils": "^3.2.0",
|
|
52
71
|
"@metamask/scure-bip39": "^2.1.1",
|
|
53
72
|
"@metamask/superstruct": "^3.1.0",
|
|
54
|
-
"@metamask/utils": "^11.
|
|
55
|
-
"ethereum-cryptography": "^2.1
|
|
73
|
+
"@metamask/utils": "^11.11.0",
|
|
74
|
+
"ethereum-cryptography": "^2.2.1"
|
|
56
75
|
},
|
|
57
76
|
"devDependencies": {
|
|
58
77
|
"@lavamoat/allow-scripts": "^3.2.1",
|
|
59
78
|
"@lavamoat/preinstall-always-fail": "^2.1.0",
|
|
60
|
-
"@metamask/account-api": "^0.
|
|
79
|
+
"@metamask/account-api": "^1.0.2",
|
|
61
80
|
"@metamask/auto-changelog": "^3.4.4",
|
|
62
81
|
"@metamask/bip39": "^4.0.0",
|
|
82
|
+
"@metamask/old-hd-keyring": "npm:@metamask/eth-hd-keyring@^4.0.1",
|
|
63
83
|
"@ts-bridge/cli": "^0.6.3",
|
|
64
84
|
"@types/jest": "^29.5.12",
|
|
65
85
|
"deepmerge": "^4.2.2",
|
|
66
|
-
"jest": "^29.5.0"
|
|
67
|
-
"old-hd-keyring": "npm:@metamask/eth-hd-keyring@^4.0.1"
|
|
86
|
+
"jest": "^29.5.0"
|
|
68
87
|
},
|
|
69
88
|
"engines": {
|
|
70
89
|
"node": "^18.18 || >=20"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hd-keyring-v2.cjs","sourceRoot":"","sources":["../src/hd-keyring-v2.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport {\n type CreateAccountOptions,\n EthAccountType,\n EthKeyringMethod,\n EthKeyringWrapper,\n EthMethod,\n EthScope,\n type ExportAccountOptions,\n type ExportedAccount,\n type KeyringAccount,\n KeyringAccountEntropyTypeOption,\n type KeyringCapabilities,\n type KeyringV2,\n KeyringType,\n PrivateKeyEncoding,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport type { AccountId } from '@metamask/keyring-utils';\nimport { add0x, type Hex } from '@metamask/utils';\n\nimport type { HdKeyring } from './hd-keyring';\n\n/**\n * Methods supported by HD keyring EOA accounts.\n * HD keyrings support all standard signing methods plus encryption and app keys.\n */\nconst HD_KEYRING_METHODS = [\n EthMethod.SignTransaction,\n EthMethod.Sign,\n EthMethod.PersonalSign,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n EthKeyringMethod.Decrypt,\n EthKeyringMethod.GetEncryptionPublicKey,\n EthKeyringMethod.GetAppKeyAddress,\n EthKeyringMethod.SignEip7702Authorization,\n];\n\nconst hdKeyringV2Capabilities: KeyringCapabilities = {\n scopes: [EthScope.Eoa],\n bip44: {\n deriveIndex: true,\n },\n privateKey: {\n exportFormats: [{ encoding: PrivateKeyEncoding.Hexadecimal }],\n },\n};\n\n/**\n * Concrete {@link KeyringV2} adapter for {@link HdKeyring}.\n *\n * This wrapper exposes the accounts and signing capabilities of the legacy\n * HD keyring via the unified V2 interface.\n */\nexport type HdKeyringV2Options = {\n legacyKeyring: HdKeyring;\n entropySource: EntropySourceId;\n};\n\nexport class HdKeyringV2\n extends EthKeyringWrapper<HdKeyring, Bip44Account<KeyringAccount>>\n implements KeyringV2\n{\n protected readonly entropySource: EntropySourceId;\n\n constructor(options: HdKeyringV2Options) {\n super({\n type: KeyringType.Hd,\n inner: options.legacyKeyring,\n capabilities: hdKeyringV2Capabilities,\n });\n this.entropySource = options.entropySource;\n }\n\n /**\n * Checks if the given address is the last account in the inner keyring.\n * This compares against the actual inner keyring state, not the registry,\n * to avoid issues with stale registry entries.\n *\n * @param address - The address to check.\n * @returns True if this is the last account in the inner keyring.\n */\n async #isLastAccount(address: string): Promise<boolean> {\n const innerAddresses = await this.inner.getAccounts();\n const lastAddress = innerAddresses[innerAddresses.length - 1];\n return address === lastAddress;\n }\n\n /**\n * Creates a KeyringAccount object for the given address and index.\n *\n * @param address - The account address.\n * @param addressIndex - The account index in the HD path.\n * @returns The created KeyringAccount.\n */\n #createKeyringAccount(\n address: Hex,\n addressIndex: number,\n ): Bip44Account<KeyringAccount> {\n const id = this.registry.register(address);\n\n const account: Bip44Account<KeyringAccount> = {\n id,\n type: EthAccountType.Eoa,\n address,\n scopes: [...this.capabilities.scopes],\n methods: [...HD_KEYRING_METHODS],\n options: {\n entropy: {\n type: KeyringAccountEntropyTypeOption.Mnemonic,\n id: this.entropySource,\n groupIndex: addressIndex,\n derivationPath: `${this.inner.hdPath}/${addressIndex}`,\n },\n exportable: true,\n },\n };\n\n // Add the account to the registry\n this.registry.set(account);\n\n return account;\n }\n\n async getAccounts(): Promise<Bip44Account<KeyringAccount>[]> {\n const addresses = await this.inner.getAccounts();\n\n return addresses.map((address, addressIndex) => {\n // Check if we already have this account in the registry\n const existingId = this.registry.getAccountId(address);\n if (existingId) {\n const cached = this.registry.get(existingId);\n if (cached) {\n return cached;\n }\n }\n\n // Create and register the account if not already cached\n return this.#createKeyringAccount(address, addressIndex);\n });\n }\n\n async createAccounts(\n options: CreateAccountOptions,\n ): Promise<Bip44Account<KeyringAccount>[]> {\n return this.withLock(async () => {\n // For HD keyring, we only support BIP-44 derive index\n if (options.type !== 'bip44:derive-index') {\n throw new Error(\n `Unsupported account creation type for HdKeyring: ${options.type}`,\n );\n }\n\n // Validate that the entropy source matches this keyring's entropy source\n if (options.entropySource !== this.entropySource) {\n throw new Error(\n `Entropy source mismatch: expected '${this.entropySource}', got '${options.entropySource}'`,\n );\n }\n\n // Sync with the inner keyring state in case it was modified externally\n // This ensures our cache is up-to-date before we make changes\n const currentAccounts = await this.getAccounts();\n const currentCount = currentAccounts.length;\n const targetIndex = options.groupIndex;\n\n // Check if an account at this index already exists\n // Since only the last account can be deleted, array position always equals groupIndex\n const existingAccount = currentAccounts[targetIndex];\n if (existingAccount) {\n return [existingAccount];\n }\n\n // Only allow derivation of the next account in sequence\n if (targetIndex !== currentCount) {\n throw new Error(\n `Can only create the next account in sequence. ` +\n `Expected groupIndex ${currentCount}, got ${targetIndex}.`,\n );\n }\n\n // Add the next account\n const [newAddress] = await this.inner.addAccounts(1);\n\n if (!newAddress) {\n throw new Error('Failed to create new account');\n }\n\n const newAccount = this.#createKeyringAccount(newAddress, targetIndex);\n\n return [newAccount];\n });\n }\n\n /**\n * Delete an account from the keyring.\n *\n * ⚠️ Warning: Only deleting the last account is possible.\n *\n * @param accountId - The account ID to delete.\n */\n async deleteAccount(accountId: AccountId): Promise<void> {\n await this.withLock(async () => {\n // Get the account first, before any registry operations\n const { address } = await this.getAccount(accountId);\n const hexAddress = this.toHexAddress(address);\n\n // Assert that the account to delete is the last one in the inner keyring\n // We check against the inner keyring directly to avoid stale registry issues\n if (!(await this.#isLastAccount(address))) {\n throw new Error(\n 'Can only delete the last account in the HD keyring due to derivation index constraints.',\n );\n }\n\n // Remove from the legacy keyring\n this.inner.removeAccount(hexAddress);\n\n // Remove from the registry\n this.registry.delete(accountId);\n });\n }\n\n /**\n * Export the private key for an account in hexadecimal format.\n *\n * @param accountId - The ID of the account to export.\n * @param options - Export options (only hexadecimal encoding is supported).\n * @returns The exported account with private key.\n */\n async exportAccount(\n accountId: AccountId,\n options?: ExportAccountOptions,\n ): Promise<ExportedAccount> {\n const account = await this.getAccount(accountId);\n\n // Validate encoding - we only support hexadecimal for Ethereum keys\n const requestedEncoding =\n options?.encoding ?? PrivateKeyEncoding.Hexadecimal;\n\n if (requestedEncoding !== PrivateKeyEncoding.Hexadecimal) {\n throw new Error(\n `Unsupported encoding for Ethereum HD keyring: ${requestedEncoding}. Only '${PrivateKeyEncoding.Hexadecimal}' is supported.`,\n );\n }\n\n // The legacy HdKeyring returns a hex string without 0x prefix.\n const privateKeyWithout0x = await this.inner.exportAccount(\n this.toHexAddress(account.address),\n );\n const privateKey = add0x(privateKeyWithout0x);\n\n return {\n type: 'private-key',\n privateKey,\n encoding: PrivateKeyEncoding.Hexadecimal,\n };\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hd-keyring-v2.d.cts","sourceRoot":"","sources":["../src/hd-keyring-v2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,EACL,KAAK,oBAAoB,EAGzB,iBAAiB,EAGjB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,cAAc,EAGnB,KAAK,SAAS,EAGd,KAAK,eAAe,EACrB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,gCAAgC;AAGzD,OAAO,KAAK,EAAE,SAAS,EAAE,yBAAqB;AA6B9C;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,SAAS,CAAC;IACzB,aAAa,EAAE,eAAe,CAAC;CAChC,CAAC;AAEF,qBAAa,WACX,SAAQ,iBAAiB,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,CACjE,YAAW,SAAS;;IAEpB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;gBAEtC,OAAO,EAAE,kBAAkB;IA2DjC,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkBtD,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkD1C;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxD;;;;;;OAMG;IACG,aAAa,CACjB,SAAS,EAAE,SAAS,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;CAyB5B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hd-keyring-v2.d.mts","sourceRoot":"","sources":["../src/hd-keyring-v2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,8BAA8B;AAC1D,OAAO,EACL,KAAK,oBAAoB,EAGzB,iBAAiB,EAGjB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,cAAc,EAGnB,KAAK,SAAS,EAGd,KAAK,eAAe,EACrB,8BAA8B;AAC/B,OAAO,KAAK,EAAE,SAAS,EAAE,gCAAgC;AAGzD,OAAO,KAAK,EAAE,SAAS,EAAE,yBAAqB;AA6B9C;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,SAAS,CAAC;IACzB,aAAa,EAAE,eAAe,CAAC;CAChC,CAAC;AAEF,qBAAa,WACX,SAAQ,iBAAiB,CAAC,SAAS,EAAE,YAAY,CAAC,cAAc,CAAC,CACjE,YAAW,SAAS;;IAEpB,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;gBAEtC,OAAO,EAAE,kBAAkB;IA2DjC,WAAW,IAAI,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkBtD,cAAc,CAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;IAkD1C;;;;;;OAMG;IACG,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBxD;;;;;;OAMG;IACG,aAAa,CACjB,SAAS,EAAE,SAAS,EACpB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,eAAe,CAAC;CAyB5B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hd-keyring-v2.mjs","sourceRoot":"","sources":["../src/hd-keyring-v2.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Bip44Account } from '@metamask/account-api';\nimport {\n type CreateAccountOptions,\n EthAccountType,\n EthKeyringMethod,\n EthKeyringWrapper,\n EthMethod,\n EthScope,\n type ExportAccountOptions,\n type ExportedAccount,\n type KeyringAccount,\n KeyringAccountEntropyTypeOption,\n type KeyringCapabilities,\n type KeyringV2,\n KeyringType,\n PrivateKeyEncoding,\n type EntropySourceId,\n} from '@metamask/keyring-api';\nimport type { AccountId } from '@metamask/keyring-utils';\nimport { add0x, type Hex } from '@metamask/utils';\n\nimport type { HdKeyring } from './hd-keyring';\n\n/**\n * Methods supported by HD keyring EOA accounts.\n * HD keyrings support all standard signing methods plus encryption and app keys.\n */\nconst HD_KEYRING_METHODS = [\n EthMethod.SignTransaction,\n EthMethod.Sign,\n EthMethod.PersonalSign,\n EthMethod.SignTypedDataV1,\n EthMethod.SignTypedDataV3,\n EthMethod.SignTypedDataV4,\n EthKeyringMethod.Decrypt,\n EthKeyringMethod.GetEncryptionPublicKey,\n EthKeyringMethod.GetAppKeyAddress,\n EthKeyringMethod.SignEip7702Authorization,\n];\n\nconst hdKeyringV2Capabilities: KeyringCapabilities = {\n scopes: [EthScope.Eoa],\n bip44: {\n deriveIndex: true,\n },\n privateKey: {\n exportFormats: [{ encoding: PrivateKeyEncoding.Hexadecimal }],\n },\n};\n\n/**\n * Concrete {@link KeyringV2} adapter for {@link HdKeyring}.\n *\n * This wrapper exposes the accounts and signing capabilities of the legacy\n * HD keyring via the unified V2 interface.\n */\nexport type HdKeyringV2Options = {\n legacyKeyring: HdKeyring;\n entropySource: EntropySourceId;\n};\n\nexport class HdKeyringV2\n extends EthKeyringWrapper<HdKeyring, Bip44Account<KeyringAccount>>\n implements KeyringV2\n{\n protected readonly entropySource: EntropySourceId;\n\n constructor(options: HdKeyringV2Options) {\n super({\n type: KeyringType.Hd,\n inner: options.legacyKeyring,\n capabilities: hdKeyringV2Capabilities,\n });\n this.entropySource = options.entropySource;\n }\n\n /**\n * Checks if the given address is the last account in the inner keyring.\n * This compares against the actual inner keyring state, not the registry,\n * to avoid issues with stale registry entries.\n *\n * @param address - The address to check.\n * @returns True if this is the last account in the inner keyring.\n */\n async #isLastAccount(address: string): Promise<boolean> {\n const innerAddresses = await this.inner.getAccounts();\n const lastAddress = innerAddresses[innerAddresses.length - 1];\n return address === lastAddress;\n }\n\n /**\n * Creates a KeyringAccount object for the given address and index.\n *\n * @param address - The account address.\n * @param addressIndex - The account index in the HD path.\n * @returns The created KeyringAccount.\n */\n #createKeyringAccount(\n address: Hex,\n addressIndex: number,\n ): Bip44Account<KeyringAccount> {\n const id = this.registry.register(address);\n\n const account: Bip44Account<KeyringAccount> = {\n id,\n type: EthAccountType.Eoa,\n address,\n scopes: [...this.capabilities.scopes],\n methods: [...HD_KEYRING_METHODS],\n options: {\n entropy: {\n type: KeyringAccountEntropyTypeOption.Mnemonic,\n id: this.entropySource,\n groupIndex: addressIndex,\n derivationPath: `${this.inner.hdPath}/${addressIndex}`,\n },\n exportable: true,\n },\n };\n\n // Add the account to the registry\n this.registry.set(account);\n\n return account;\n }\n\n async getAccounts(): Promise<Bip44Account<KeyringAccount>[]> {\n const addresses = await this.inner.getAccounts();\n\n return addresses.map((address, addressIndex) => {\n // Check if we already have this account in the registry\n const existingId = this.registry.getAccountId(address);\n if (existingId) {\n const cached = this.registry.get(existingId);\n if (cached) {\n return cached;\n }\n }\n\n // Create and register the account if not already cached\n return this.#createKeyringAccount(address, addressIndex);\n });\n }\n\n async createAccounts(\n options: CreateAccountOptions,\n ): Promise<Bip44Account<KeyringAccount>[]> {\n return this.withLock(async () => {\n // For HD keyring, we only support BIP-44 derive index\n if (options.type !== 'bip44:derive-index') {\n throw new Error(\n `Unsupported account creation type for HdKeyring: ${options.type}`,\n );\n }\n\n // Validate that the entropy source matches this keyring's entropy source\n if (options.entropySource !== this.entropySource) {\n throw new Error(\n `Entropy source mismatch: expected '${this.entropySource}', got '${options.entropySource}'`,\n );\n }\n\n // Sync with the inner keyring state in case it was modified externally\n // This ensures our cache is up-to-date before we make changes\n const currentAccounts = await this.getAccounts();\n const currentCount = currentAccounts.length;\n const targetIndex = options.groupIndex;\n\n // Check if an account at this index already exists\n // Since only the last account can be deleted, array position always equals groupIndex\n const existingAccount = currentAccounts[targetIndex];\n if (existingAccount) {\n return [existingAccount];\n }\n\n // Only allow derivation of the next account in sequence\n if (targetIndex !== currentCount) {\n throw new Error(\n `Can only create the next account in sequence. ` +\n `Expected groupIndex ${currentCount}, got ${targetIndex}.`,\n );\n }\n\n // Add the next account\n const [newAddress] = await this.inner.addAccounts(1);\n\n if (!newAddress) {\n throw new Error('Failed to create new account');\n }\n\n const newAccount = this.#createKeyringAccount(newAddress, targetIndex);\n\n return [newAccount];\n });\n }\n\n /**\n * Delete an account from the keyring.\n *\n * ⚠️ Warning: Only deleting the last account is possible.\n *\n * @param accountId - The account ID to delete.\n */\n async deleteAccount(accountId: AccountId): Promise<void> {\n await this.withLock(async () => {\n // Get the account first, before any registry operations\n const { address } = await this.getAccount(accountId);\n const hexAddress = this.toHexAddress(address);\n\n // Assert that the account to delete is the last one in the inner keyring\n // We check against the inner keyring directly to avoid stale registry issues\n if (!(await this.#isLastAccount(address))) {\n throw new Error(\n 'Can only delete the last account in the HD keyring due to derivation index constraints.',\n );\n }\n\n // Remove from the legacy keyring\n this.inner.removeAccount(hexAddress);\n\n // Remove from the registry\n this.registry.delete(accountId);\n });\n }\n\n /**\n * Export the private key for an account in hexadecimal format.\n *\n * @param accountId - The ID of the account to export.\n * @param options - Export options (only hexadecimal encoding is supported).\n * @returns The exported account with private key.\n */\n async exportAccount(\n accountId: AccountId,\n options?: ExportAccountOptions,\n ): Promise<ExportedAccount> {\n const account = await this.getAccount(accountId);\n\n // Validate encoding - we only support hexadecimal for Ethereum keys\n const requestedEncoding =\n options?.encoding ?? PrivateKeyEncoding.Hexadecimal;\n\n if (requestedEncoding !== PrivateKeyEncoding.Hexadecimal) {\n throw new Error(\n `Unsupported encoding for Ethereum HD keyring: ${requestedEncoding}. Only '${PrivateKeyEncoding.Hexadecimal}' is supported.`,\n );\n }\n\n // The legacy HdKeyring returns a hex string without 0x prefix.\n const privateKeyWithout0x = await this.inner.exportAccount(\n this.toHexAddress(account.address),\n );\n const privateKey = add0x(privateKeyWithout0x);\n\n return {\n type: 'private-key',\n privateKey,\n encoding: PrivateKeyEncoding.Hexadecimal,\n };\n }\n}\n"]}
|