Skip to content

Commit 2afa37b

Browse files
authored
feat(keyring-eth-hd): add keyring v2 getters (#529)
Re-expose the same getters than the v1 (inner) keyring, so we can use v2 keyrings to replace their current usage. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Adds new public accessors that expose sensitive key material (mnemonic/seed/HD keys) through the v2 wrapper; while pass-through, it can broaden where secrets are accessed and relied upon. > > **Overview** > Re-exposes legacy HD keyring state on the v2 `HdKeyring` wrapper by adding passthrough getters for `mnemonic`, `seed`, `root`, `hdWallet`, and `hdPath` (returning `undefined` pre-deserialization) to maintain compatibility with v1 consumers. > > Adds unit tests asserting the getters mirror the inner keyring values and updates the changelog to document the new API surface. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit c56bb3b. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent aa1a3e9 commit 2afa37b

3 files changed

Lines changed: 80 additions & 0 deletions

File tree

packages/keyring-eth-hd/CHANGELOG.md

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

88
## [Unreleased]
99

10+
### Added
11+
12+
- Expose same getters in `HdKeyring` (v2 keyring wrapper from `/v2`) ([#529](https://github.com/MetaMask/accounts/pull/529))
13+
- We need this as some consumers were already using those getters when using the v1 keyring.
14+
1015
## [14.0.1]
1116

1217
### Changed

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,46 @@ describe('HdKeyring (v2 wrapper)', () => {
6666
});
6767
});
6868

69+
describe('getters', () => {
70+
it('exposes mnemonic from the inner keyring', () => {
71+
expect(wrapper.mnemonic).toStrictEqual(inner.mnemonic);
72+
expect(wrapper.mnemonic).toBeInstanceOf(Uint8Array);
73+
});
74+
75+
it('exposes seed from the inner keyring', () => {
76+
expect(wrapper.seed).toStrictEqual(inner.seed);
77+
expect(wrapper.seed).toBeInstanceOf(Uint8Array);
78+
});
79+
80+
it('exposes root from the inner keyring', () => {
81+
expect(wrapper.root).toStrictEqual(inner.root);
82+
expect(wrapper.root).not.toBeNull();
83+
});
84+
85+
it('exposes hdWallet from the inner keyring', () => {
86+
expect(wrapper.hdWallet).toStrictEqual(inner.hdWallet);
87+
expect(wrapper.hdWallet).toBeDefined();
88+
});
89+
90+
it('exposes hdPath from the inner keyring', () => {
91+
expect(wrapper.hdPath).toBe(inner.hdPath);
92+
expect(wrapper.hdPath).toBe("m/44'/60'/0'/0");
93+
});
94+
95+
it('returns null for mnemonic/seed/root before deserialization', () => {
96+
const emptyInner = new LegacyHdKeyring();
97+
const emptyWrapper = new HdKeyring({
98+
legacyKeyring: emptyInner,
99+
entropySource: TEST_ENTROPY_SOURCE_ID,
100+
});
101+
102+
expect(emptyWrapper.mnemonic).toBeUndefined();
103+
expect(emptyWrapper.seed).toBeUndefined();
104+
expect(emptyWrapper.root).toBeUndefined();
105+
expect(emptyWrapper.hdWallet).toBeUndefined();
106+
});
107+
});
108+
69109
describe('getAccounts', () => {
70110
beforeEach(async () => {
71111
await inner.addAccounts(2);

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,41 @@ export class HdKeyring
7474
this.entropySource = options.entropySource;
7575
}
7676

77+
/**
78+
* @returns The mnemonic seed phrase as a `Uint8Array`, or `null`/`undefined` before initialization.
79+
*/
80+
get mnemonic(): LegacyHdKeyring['mnemonic'] {
81+
return this.inner.mnemonic;
82+
}
83+
84+
/**
85+
* @returns The seed derived from the mnemonic, or `null`/`undefined` before initialization.
86+
*/
87+
get seed(): LegacyHdKeyring['seed'] {
88+
return this.inner.seed;
89+
}
90+
91+
/**
92+
* @returns The root HD key derived from the seed at `hdPath`, or `null`/`undefined` before initialization.
93+
*/
94+
get root(): LegacyHdKeyring['root'] {
95+
return this.inner.root;
96+
}
97+
98+
/**
99+
* @returns The master HD wallet key derived from the seed, or `undefined` before initialization.
100+
*/
101+
get hdWallet(): LegacyHdKeyring['hdWallet'] {
102+
return this.inner.hdWallet;
103+
}
104+
105+
/**
106+
* @returns The BIP-44 derivation path used to derive accounts (default: `m/44'/60'/0'/0`).
107+
*/
108+
get hdPath(): LegacyHdKeyring['hdPath'] {
109+
return this.inner.hdPath;
110+
}
111+
77112
/**
78113
* Checks if the given address is the last account in the inner keyring.
79114
* This compares against the actual inner keyring state, not the registry,

0 commit comments

Comments
 (0)