Skip to content

Commit 204cc79

Browse files
authored
feat(keyring-api): add bip44:derive-index-range (#451)
Add new `bip44:derive-index-range` constructor. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Public API/types are extended and `KeyringCapabilities.bip44` now requires a new `deriveIndexRange` boolean, which may force downstream keyring implementations to update their declared capabilities. > > **Overview** > Adds support for a new account-creation mode `bip44:derive-index-range` by introducing `AccountCreationType.Bip44DeriveIndexRange` plus `CreateAccountBip44DeriveIndexRangeOptions`/superstruct validation, and wiring it into the `CreateAccountOptionsStruct` selective union. > > Extends `KeyringCapabilities.bip44` with a required `deriveIndexRange` boolean and updates type tests and Ethereum keyring wrappers (HD/Ledger/QR/Trezor) to explicitly report `deriveIndexRange: false`, along with changelog entries across affected packages. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 714aa5c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent b1cb8e5 commit 204cc79

18 files changed

Lines changed: 76 additions & 5 deletions

File tree

packages/keyring-api/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- Add support for account derivations using range of indices in `KeyringV2` ([#451](https://github.com/MetaMask/accounts/pull/451))
13+
- Add `bip44:derive-index-range` capability to `KeyringCapabilities`.
14+
- Add `AccountCreationType.Bip44DeriveIndexRange` and `CreateAccountBip44DeriveIndexRangeOptions`.
1215
- Add support for custom capabilities and entropy types in `KeyringV2` ([#415](https://github.com/MetaMask/accounts/pull/415))
1316
- Add `custom` capability to `KeyringCapabilities` for keyrings with non-standard `createAccounts` method.
1417
- Add `KeyringAccountEntropyTypeOption.Custom` for custom/opaque entropy sources.

packages/keyring-api/src/api/v2/create-account/bip44.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,43 @@ export const CreateAccountBip44DiscoverOptionsStruct = object({
8888
export type CreateAccountBip44DiscoverOptions = Infer<
8989
typeof CreateAccountBip44DiscoverOptionsStruct
9090
>;
91+
92+
/**
93+
* Struct for {@link CreateAccountBip44DeriveIndexRangeOptions}.
94+
*/
95+
export const CreateAccountBip44DeriveIndexRangeOptionsStruct = object({
96+
/**
97+
* The type of the options.
98+
*/
99+
type: literal('bip44:derive-index-range'),
100+
/**
101+
* ID of the entropy source to be used to derive the accounts.
102+
*/
103+
entropySource: string(),
104+
/**
105+
* The range of account group indices to derive (inclusive on both ends).
106+
*/
107+
range: object({
108+
/**
109+
* The starting index of the account group range (inclusive).
110+
*/
111+
from: number(),
112+
/**
113+
* The ending index of the account group range (inclusive).
114+
*/
115+
to: number(),
116+
}),
117+
});
118+
119+
/**
120+
* Options for creating accounts by deriving a range of BIP-44 account indices.
121+
*
122+
* The range is inclusive on both ends, meaning range.from=0 and range.to=5
123+
* will create accounts for group indices 0, 1, 2, 3, 4, and 5.
124+
*
125+
* Note that the keyring can support non-standard BIP-44 paths for
126+
* compatibility with other wallets.
127+
*/
128+
export type CreateAccountBip44DeriveIndexRangeOptions = Infer<
129+
typeof CreateAccountBip44DeriveIndexRangeOptionsStruct
130+
>;

packages/keyring-api/src/api/v2/create-account/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { type Infer } from '@metamask/superstruct';
44
import {
55
CreateAccountBip44DiscoverOptionsStruct,
66
CreateAccountBip44DeriveIndexOptionsStruct,
7+
CreateAccountBip44DeriveIndexRangeOptionsStruct,
78
CreateAccountBip44DerivePathOptionsStruct,
89
} from './bip44';
910
import { CreateAccountCustomOptionsStruct } from './custom';
@@ -31,6 +32,15 @@ export enum AccountCreationType {
3132
*/
3233
Bip44DeriveIndex = 'bip44:derive-index',
3334

35+
/**
36+
* Represents accounts created by deriving a range of BIP-44 account indices.
37+
*
38+
* More than one account can be created per index, for example, the keyring
39+
* can create multiple account types (e.g., P2PKH, P2TR, P2WPKH) for each
40+
* account index in the range.
41+
*/
42+
Bip44DeriveIndexRange = 'bip44:derive-index-range',
43+
3444
/**
3545
* Represents accounts created through BIP-44 account discovery.
3646
*
@@ -64,6 +74,8 @@ export const CreateAccountOptionsStruct = selectiveUnion((value: any) => {
6474
return CreateAccountBip44DerivePathOptionsStruct;
6575
case AccountCreationType.Bip44DeriveIndex:
6676
return CreateAccountBip44DeriveIndexOptionsStruct;
77+
case AccountCreationType.Bip44DeriveIndexRange:
78+
return CreateAccountBip44DeriveIndexRangeOptionsStruct;
6779
case AccountCreationType.Bip44Discover:
6880
return CreateAccountBip44DiscoverOptionsStruct;
6981
case AccountCreationType.PrivateKeyImport:

packages/keyring-api/src/api/v2/keyring-capabilities.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ export const KeyringCapabilitiesStruct = object({
3535
* Whether the keyring supports deriving accounts from a BIP-44 account index.
3636
*/
3737
deriveIndex: boolean(),
38+
/**
39+
* Whether the keyring supports deriving accounts from a range of BIP-44 account indices.
40+
*/
41+
deriveIndexRange: boolean(),
3842
/**
3943
* Whether the keyring supports BIP-44 account discovery.
4044
*/
@@ -82,6 +86,7 @@ export const KeyringCapabilitiesStruct = object({
8286
* bip44: {
8387
* derivePath: true,
8488
* deriveIndex: true,
89+
* deriveIndexRange: true,
8590
* discover: true,
8691
* },
8792
* privateKey: {

packages/keyring-api/src/api/v2/keyring.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ expectAssignable<KeyringCapabilities>({
6363
bip44: {
6464
derivePath: true,
6565
deriveIndex: true,
66+
deriveIndexRange: true,
6667
discover: false,
6768
},
6869
});

packages/keyring-eth-hd/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12-
- Add `HdKeyringV2` class implementing `KeyringV2` interface ([#398](https://github.com/MetaMask/accounts/pull/398)), ([#404](https://github.com/MetaMask/accounts/pull/404)), ([#410](https://github.com/MetaMask/accounts/pull/410)), ([#413](https://github.com/MetaMask/accounts/pull/413))
12+
- Add `HdKeyringV2` class implementing `KeyringV2` interface ([#398](https://github.com/MetaMask/accounts/pull/398)), ([#404](https://github.com/MetaMask/accounts/pull/404)), ([#410](https://github.com/MetaMask/accounts/pull/410)), ([#413](https://github.com/MetaMask/accounts/pull/413)), ([#451](https://github.com/MetaMask/accounts/pull/451))
1313
- Wraps legacy `HdKeyring` to expose accounts via the unified `KeyringV2` API and the `KeyringAccount` type.
1414
- Extends `EthKeyringWrapper` for common Ethereum logic.
1515

packages/keyring-eth-hd/src/hd-keyring-v2.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ describe('HdKeyringV2', () => {
6767
expect(wrapper.capabilities.scopes).toStrictEqual([EthScope.Eoa]);
6868
expect(wrapper.capabilities.bip44?.deriveIndex).toBe(true);
6969
expect(wrapper.capabilities.bip44?.derivePath).toBe(false);
70+
expect(wrapper.capabilities.bip44?.deriveIndexRange).toBe(false);
7071
expect(wrapper.capabilities.bip44?.discover).toBe(false);
7172
});
7273
});

packages/keyring-eth-hd/src/hd-keyring-v2.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const hdKeyringV2Capabilities: KeyringCapabilities = {
4343
bip44: {
4444
deriveIndex: true,
4545
derivePath: false,
46+
deriveIndexRange: false,
4647
discover: false,
4748
},
4849
privateKey: {

packages/keyring-eth-ledger-bridge/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12-
- Add `LedgerKeyringV2` class implementing `KeyringV2` interface ([#416](https://github.com/MetaMask/accounts/pull/416))
12+
- Add `LedgerKeyringV2` class implementing `KeyringV2` interface ([#416](https://github.com/MetaMask/accounts/pull/416)), ([#451](https://github.com/MetaMask/accounts/pull/451))
1313
- Wraps legacy `LedgerKeyring` to expose accounts via the unified `KeyringV2` API and the `KeyringAccount` type.
1414
- Extends `EthKeyringWrapper` for common Ethereum logic.
1515

packages/keyring-eth-ledger-bridge/src/ledger-keyring-v2.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ describe('LedgerKeyringV2', () => {
252252
bip44: {
253253
deriveIndex: true,
254254
derivePath: true,
255+
deriveIndexRange: false,
255256
discover: false,
256257
},
257258
});

0 commit comments

Comments
 (0)