diff --git a/packages/snap-networks-utils/CHANGELOG.md b/packages/snap-networks-utils/CHANGELOG.md index 1ad15de4..d5c96340 100644 --- a/packages/snap-networks-utils/CHANGELOG.md +++ b/packages/snap-networks-utils/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Add `ExtendedKeyringAccount`, `KeyringAccountExtension`, and `asStrictKeyringAccount` for snap keyring accounts that persist `entropySource`, `derivationPath`, and `index`. ([#300](https://github.com/MetaMask/internal-snaps/pull/300)) - Add shared snap state helpers `IStateManager`, `State`, and `InMemoryState` (Tron-style write mutex plus blob/path locking). ([#288](https://github.com/MetaMask/internal-snaps/pull/288)) - Add shared caching utilities for network snaps ([#287](https://github.com/MetaMask/internal-snaps/pull/287)) - `ICache`, `CacheEntry`, and `TimestampMilliseconds` for describing a generic cache diff --git a/packages/snap-networks-utils/package.json b/packages/snap-networks-utils/package.json index 7a70b479..cf57573d 100644 --- a/packages/snap-networks-utils/package.json +++ b/packages/snap-networks-utils/package.json @@ -72,6 +72,7 @@ }, "dependencies": { "@metamask/assets-controller": "^13.0.0", + "@metamask/keyring-api": "^24.1.0", "@metamask/remote-feature-flag-controller": "^5.0.0", "@metamask/snaps-sdk": "^12.0.1", "@metamask/superstruct": "^3.4.1", diff --git a/packages/snap-networks-utils/src/index.ts b/packages/snap-networks-utils/src/index.ts index e90003ea..574b8f11 100644 --- a/packages/snap-networks-utils/src/index.ts +++ b/packages/snap-networks-utils/src/index.ts @@ -17,6 +17,11 @@ export { } from './utils/sanitize/sanitize'; export { UrlStruct } from './utils/urlStruct/urlStruct'; export { UuidStruct } from './utils/uuidStruct/uuidStruct'; +export { asStrictKeyringAccount } from './utils/keyringAccount/keyringAccount'; +export type { + ExtendedKeyringAccount, + KeyringAccountExtension, +} from './utils/keyringAccount/keyringAccount'; export { batchesAll, batchesAllSettled, diff --git a/packages/snap-networks-utils/src/utils/keyringAccount/keyringAccount.test.ts b/packages/snap-networks-utils/src/utils/keyringAccount/keyringAccount.test.ts new file mode 100644 index 00000000..375ea0ee --- /dev/null +++ b/packages/snap-networks-utils/src/utils/keyringAccount/keyringAccount.test.ts @@ -0,0 +1,34 @@ +import { asStrictKeyringAccount } from './keyringAccount'; +import type { ExtendedKeyringAccount } from './keyringAccount'; + +describe('asStrictKeyringAccount', () => { + const account: ExtendedKeyringAccount = { + type: 'eip155:eoa', + id: '4b445722-6766-4f99-ade5-c2c9295f21d0', + address: 'TAddress0', + options: { + entropy: { + type: 'mnemonic', + id: 'entropy-source', + derivationPath: "m/44'/195'/0'/0/0", + groupIndex: 0, + }, + }, + methods: ['personal_sign'], + scopes: ['tron:mainnet'], + entropySource: 'entropy-source', + derivationPath: "m/44'/195'/0'/0/0", + index: 0, + }; + + it('returns only KeyringAccount fields', () => { + expect(asStrictKeyringAccount(account)).toStrictEqual({ + type: account.type, + id: account.id, + address: account.address, + options: account.options, + methods: account.methods, + scopes: account.scopes, + }); + }); +}); diff --git a/packages/snap-networks-utils/src/utils/keyringAccount/keyringAccount.ts b/packages/snap-networks-utils/src/utils/keyringAccount/keyringAccount.ts new file mode 100644 index 00000000..6f1770e5 --- /dev/null +++ b/packages/snap-networks-utils/src/utils/keyringAccount/keyringAccount.ts @@ -0,0 +1,43 @@ +import type { EntropySourceId, KeyringAccount } from '@metamask/keyring-api'; + +/** + * Keyring account fields snaps persist in addition to `@metamask/keyring-api`'s + * `KeyringAccount`. `index` is stored so an account can be restored at a + * previously used derivation index. + */ +export type KeyringAccountExtension = { + entropySource: EntropySourceId; + derivationPath: `m/${string}`; + index: number; +}; + +/** + * A `KeyringAccount` plus the derivation fields used by Solana, Tron, and Stellar. + * + * A snap may narrow `derivationPath` (for example Stellar's BIP-44 coin type). + */ +export type ExtendedKeyringAccount = KeyringAccount & KeyringAccountExtension; + +/** + * Converts an extended snap account to the Keyring API shape. + * + * Snaps persist `entropySource`, `derivationPath`, and `index` on the account + * object. The Keyring API must not receive those fields, so this copies only + * the six `KeyringAccount` properties. + * + * @param account - A snap keyring account with derivation fields. + * @returns A `KeyringAccount` with no extra properties. + */ +export function asStrictKeyringAccount( + account: ExtendedKeyringAccount, +): KeyringAccount { + const { id, address, type, options, methods, scopes } = account; + return { + id, + address, + type, + options, + methods, + scopes, + }; +} diff --git a/yarn.lock b/yarn.lock index 9f340362..6687e9f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3327,6 +3327,7 @@ __metadata: dependencies: "@metamask/assets-controller": "npm:^13.0.0" "@metamask/auto-changelog": "npm:^6.1.1" + "@metamask/keyring-api": "npm:^24.1.0" "@metamask/messenger": "npm:^2.0.0" "@metamask/remote-feature-flag-controller": "npm:^5.0.0" "@metamask/snaps-sdk": "npm:^12.0.1"