From 8f60351d532f77539bf3905bdf3ba489337d0d4a Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Mon, 27 Jan 2025 09:59:27 +0100 Subject: [PATCH 1/6] feat: add `chianIds` to `InternalAccountMetadata` --- packages/keyring-internal-api/src/types.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/keyring-internal-api/src/types.ts b/packages/keyring-internal-api/src/types.ts index a6fa4e9d8..904990daf 100644 --- a/packages/keyring-internal-api/src/types.ts +++ b/packages/keyring-internal-api/src/types.ts @@ -15,7 +15,8 @@ import { } from '@metamask/keyring-api'; import { exactOptional, object } from '@metamask/keyring-utils'; import type { Infer, Struct } from '@metamask/superstruct'; -import { boolean, string, number } from '@metamask/superstruct'; +import { boolean, string, number, array } from '@metamask/superstruct'; +import { CaipChainIdStruct } from '@metamask/utils'; export type InternalAccountType = | EthAccountType @@ -38,6 +39,25 @@ export const InternalAccountMetadataStruct = object({ keyring: object({ type: string(), }), + + /** + * List of chain IDs that the account is compatible with. + * + * This differs from the `scopes` field. The `scopes` field can include + * namespaces, which are used to indicate that the account is compatible + * with all chains within a given namespace. + * + * Namespaces are useful because it might not be possible to list every + * individual chain at the time of account creation. This is due to the + * dynamic nature of chain availability (new chains may be added in the + * future) and because the account creator may not know which specific + * networks are supported by the client. + * + * The `chainIds` field provides a precise list of supported chains and is + * dynamically updated by the client to reflect the networks currently + * compatible with the account. + */ + chainIds: array(CaipChainIdStruct), }), }); From 157d1f5d3f95af97f518e975e96405a8b60889a9 Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Tue, 28 Jan 2025 12:51:13 +0100 Subject: [PATCH 2/6] refactor!: enforce that `scopes` are chain IDs --- packages/keyring-api/src/api/account.ts | 17 ++------ packages/keyring-api/src/btc/constants.ts | 3 +- packages/keyring-api/src/eth/constants.ts | 4 +- packages/keyring-api/src/eth/types.ts | 4 +- packages/keyring-api/src/events.test.ts | 10 ++--- packages/keyring-api/src/sol/constants.ts | 3 +- .../keyring-internal-api/src/types.test.ts | 14 +++--- packages/keyring-internal-api/src/types.ts | 22 +--------- .../src/KeyringInternalSnapClient.test.ts | 2 +- .../src/SnapKeyring.test.ts | 43 +++++++++++++------ .../keyring-snap-bridge/src/migrations/v1.ts | 19 +++++--- .../src/KeyringClient.test.ts | 8 ++-- .../src/KeyringSnapRpcClient.test.ts | 2 +- .../keyring-snap-sdk/src/rpc-handler.test.ts | 4 +- 14 files changed, 73 insertions(+), 82 deletions(-) diff --git a/packages/keyring-api/src/api/account.ts b/packages/keyring-api/src/api/account.ts index 0a09a66a2..4ae5957a6 100644 --- a/packages/keyring-api/src/api/account.ts +++ b/packages/keyring-api/src/api/account.ts @@ -1,18 +1,7 @@ import { AccountIdStruct, object } from '@metamask/keyring-utils'; import type { Infer } from '@metamask/superstruct'; -import { - nonempty, - array, - enums, - record, - string, - union, -} from '@metamask/superstruct'; -import { - CaipChainIdStruct, - CaipNamespaceStruct, - JsonStruct, -} from '@metamask/utils'; +import { nonempty, array, enums, record, string } from '@metamask/superstruct'; +import { CaipChainIdStruct, JsonStruct } from '@metamask/utils'; /** * Supported Ethereum account types. @@ -76,7 +65,7 @@ export const KeyringAccountStruct = object({ /** * Account supported scopes (CAIP-2 chain IDs or CAIP-2 namespaces). */ - scopes: nonempty(array(union([CaipNamespaceStruct, CaipChainIdStruct]))), + scopes: nonempty(array(CaipChainIdStruct)), /** * Account options. diff --git a/packages/keyring-api/src/btc/constants.ts b/packages/keyring-api/src/btc/constants.ts index 658611f6c..ea0068f58 100644 --- a/packages/keyring-api/src/btc/constants.ts +++ b/packages/keyring-api/src/btc/constants.ts @@ -3,8 +3,7 @@ /** * Scopes for Bitcoin account type. See {@link KeyringAccount.scopes}. */ -export enum BtcScope { - Namespace = 'bip122', +export enum BtcScopes { Mainnet = 'bip122:000000000019d6689c085ae165831e93', Testnet = 'bip122:000000000933ea01ad0ee984209779ba', Testnet4 = 'bip122:00000000da84f2bafbbc53dee25a72ae', diff --git a/packages/keyring-api/src/eth/constants.ts b/packages/keyring-api/src/eth/constants.ts index 65c120f6a..e4111902a 100644 --- a/packages/keyring-api/src/eth/constants.ts +++ b/packages/keyring-api/src/eth/constants.ts @@ -3,8 +3,8 @@ /** * Scopes for EVM account type. See {@link KeyringAccount.scopes}. */ -export enum EthScope { - Namespace = 'eip155', +export enum EthScopes { + Eoa = 'eip155:0', Mainnet = 'eip155:1', Testnet = 'eip155:11155111', } diff --git a/packages/keyring-api/src/eth/types.ts b/packages/keyring-api/src/eth/types.ts index f08b0240a..3aa2aae37 100644 --- a/packages/keyring-api/src/eth/types.ts +++ b/packages/keyring-api/src/eth/types.ts @@ -49,9 +49,9 @@ export const EthEoaAccountStruct = object({ type: literal(`${EthAccountType.Eoa}`), /** - * Account scopes (must be ['eip155']). + * Account scopes (must be ['eip155:0']). */ - scopes: nonempty(array(literal(EthScope.Namespace))), + scopes: nonempty(array(literal(EthScopes.Eoa))), /** * Account supported methods. diff --git a/packages/keyring-api/src/events.test.ts b/packages/keyring-api/src/events.test.ts index 11d62f479..70dd9572e 100644 --- a/packages/keyring-api/src/events.test.ts +++ b/packages/keyring-api/src/events.test.ts @@ -22,7 +22,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }, }, @@ -40,7 +40,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }, }, @@ -58,7 +58,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }, displayConfirmation: true, @@ -79,7 +79,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }, }, @@ -97,7 +97,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }, }, diff --git a/packages/keyring-api/src/sol/constants.ts b/packages/keyring-api/src/sol/constants.ts index 5bfc0536e..33ce9370a 100644 --- a/packages/keyring-api/src/sol/constants.ts +++ b/packages/keyring-api/src/sol/constants.ts @@ -3,8 +3,7 @@ /** * Scopes for Solana account type. See {@link KeyringAccount.scopes}. */ -export enum SolScope { - Namespace = 'solana', +export enum SolScopes { Devnet = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', Mainnet = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', Testnet = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z', diff --git a/packages/keyring-internal-api/src/types.test.ts b/packages/keyring-internal-api/src/types.test.ts index 505697c04..08c3d4410 100644 --- a/packages/keyring-internal-api/src/types.test.ts +++ b/packages/keyring-internal-api/src/types.test.ts @@ -5,7 +5,7 @@ import { InternalAccountStruct } from '.'; describe('InternalAccount', () => { it.each([ - { type: 'eip155:eoa', address: '0x000', scopes: ['eip155'] }, + { type: 'eip155:eoa', address: '0x000', scopes: ['eip155:0'] }, { type: 'bip122:p2wpkh', address: 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4', @@ -37,7 +37,7 @@ describe('InternalAccount', () => { address: '0x000', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', metadata: { keyring: {}, @@ -57,7 +57,7 @@ describe('InternalAccount', () => { address: '0x000', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', metadata: { name: 'Account 1', @@ -76,7 +76,7 @@ describe('InternalAccount', () => { address: '0x000', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }; @@ -105,7 +105,7 @@ describe('InternalAccount', () => { address: '0x000', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', metadata: { keyring: { @@ -129,7 +129,7 @@ describe('InternalAccount', () => { options: {}, methods: [], type: 'eip155:eoa', - scopes: ['eip155'], + scopes: ['eip155:0'], metadata: { keyring: { type: 'Test Keyring', @@ -155,7 +155,7 @@ describe('InternalAccount', () => { address: '0x000', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', metadata: { keyring: { diff --git a/packages/keyring-internal-api/src/types.ts b/packages/keyring-internal-api/src/types.ts index 904990daf..a6fa4e9d8 100644 --- a/packages/keyring-internal-api/src/types.ts +++ b/packages/keyring-internal-api/src/types.ts @@ -15,8 +15,7 @@ import { } from '@metamask/keyring-api'; import { exactOptional, object } from '@metamask/keyring-utils'; import type { Infer, Struct } from '@metamask/superstruct'; -import { boolean, string, number, array } from '@metamask/superstruct'; -import { CaipChainIdStruct } from '@metamask/utils'; +import { boolean, string, number } from '@metamask/superstruct'; export type InternalAccountType = | EthAccountType @@ -39,25 +38,6 @@ export const InternalAccountMetadataStruct = object({ keyring: object({ type: string(), }), - - /** - * List of chain IDs that the account is compatible with. - * - * This differs from the `scopes` field. The `scopes` field can include - * namespaces, which are used to indicate that the account is compatible - * with all chains within a given namespace. - * - * Namespaces are useful because it might not be possible to list every - * individual chain at the time of account creation. This is due to the - * dynamic nature of chain availability (new chains may be added in the - * future) and because the account creator may not know which specific - * networks are supported by the client. - * - * The `chainIds` field provides a precise list of supported chains and is - * dynamically updated by the client to reflect the networks currently - * compatible with the account. - */ - chainIds: array(CaipChainIdStruct), }), }); diff --git a/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts b/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts index 891ed4fae..982850ac9 100644 --- a/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts +++ b/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts @@ -15,7 +15,7 @@ describe('KeyringInternalSnapClient', () => { address: '0xE9A74AACd7df8112911ca93260fC5a046f8a64Ae', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }, ]; diff --git a/packages/keyring-snap-bridge/src/SnapKeyring.test.ts b/packages/keyring-snap-bridge/src/SnapKeyring.test.ts index c76b42221..06eab518c 100644 --- a/packages/keyring-snap-bridge/src/SnapKeyring.test.ts +++ b/packages/keyring-snap-bridge/src/SnapKeyring.test.ts @@ -24,7 +24,7 @@ import { SolScope, } from '@metamask/keyring-api'; import type { SnapId } from '@metamask/snaps-sdk'; -import { toCaipChainId } from '@metamask/utils'; +import { KnownCaipNamespace, toCaipChainId } from '@metamask/utils'; import type { KeyringState } from '.'; import { SnapKeyring } from '.'; @@ -104,7 +104,7 @@ describe('SnapKeyring', () => { address: '0xC728514Df8A7F9271f4B7a4dd2Aa6d2D723d3eE3'.toLowerCase(), options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }; const ethEoaAccount2 = { @@ -112,7 +112,7 @@ describe('SnapKeyring', () => { address: '0x34b13912eAc00152bE0Cb409A301Ab8E55739e63'.toLowerCase(), options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }; const ethEoaAccount3 = { @@ -120,7 +120,7 @@ describe('SnapKeyring', () => { address: '0xf7bDe8609231033c69E502C08f85153f8A1548F2'.toLowerCase(), options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, }; const ethErc4337Account = { @@ -162,7 +162,7 @@ describe('SnapKeyring', () => { methods: [], // For unknown accounts, we consider them as EVM EOA for now, so just re-use the // same scopes. - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], // This should not be really possible to create such account, but since we potentially // migrate data upon the Snap keyring initialization, we want to cover edge-cases // like this one to avoid crashing and blocking everything... @@ -237,7 +237,7 @@ describe('SnapKeyring', () => { id: 'b05d918a-b37c-497a-bb28-3d15c0d56b7a', options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], type: EthAccountType.Eoa, // Even checksummed address will be lower-cased by the bridge. address: '0x6431726EEE67570BF6f0Cf892aE0a3988F03903F', @@ -429,7 +429,7 @@ describe('SnapKeyring', () => { metadata: expect.any(Object), // By default, new EVM accounts will have this scopes if it not provided // during the account creation flow. - scopes: [EthScope.Namespace], + scopes: [EthScopes.Eoa], }); }); @@ -707,7 +707,7 @@ describe('SnapKeyring', () => { const keyringAccounts = keyring.listAccounts(); expect(keyringAccounts.length).toBeGreaterThan(0); - expect(keyringAccounts[0]?.scopes).toStrictEqual([EthScope.Namespace]); + expect(keyringAccounts[0]?.scopes).toStrictEqual([EthScopes.Eoa]); }); it('updates a ERC4337 account with the no scope will throw an error', async () => { @@ -1044,7 +1044,7 @@ describe('SnapKeyring', () => { it('unknown v1 accounts scopes defaults to EOA scopes', () => { expect(getScopesForAccountV1(unknownAccount)).toStrictEqual([ - EthScope.Namespace, + EthScopes.Eoa, ]); }); }); @@ -1472,7 +1472,10 @@ describe('SnapKeyring', () => { method: 'keyring_submitRequest', params: { id: expect.any(String), - scope: toCaipChainId(EthScope.Namespace, executionContext.chainId), + scope: toCaipChainId( + KnownCaipNamespace.Eip155, + executionContext.chainId, + ), account: ethErc4337Account.id, request: { method: 'eth_prepareUserOperation', @@ -1525,7 +1528,10 @@ describe('SnapKeyring', () => { method: 'keyring_submitRequest', params: { id: expect.any(String), - scope: toCaipChainId(EthScope.Namespace, executionContext.chainId), + scope: toCaipChainId( + KnownCaipNamespace.Eip155, + executionContext.chainId, + ), account: ethErc4337Account.id, request: { method: 'eth_patchUserOperation', @@ -1574,7 +1580,10 @@ describe('SnapKeyring', () => { method: 'keyring_submitRequest', params: { id: expect.any(String), - scope: toCaipChainId(EthScope.Namespace, executionContext.chainId), + scope: toCaipChainId( + KnownCaipNamespace.Eip155, + executionContext.chainId, + ), account: ethErc4337Account.id, request: { method: 'eth_signUserOperation', @@ -1799,7 +1808,10 @@ describe('SnapKeyring', () => { method: 'keyring_submitRequest', params: { id: expect.any(String), - scope: toCaipChainId(EthScope.Namespace, executionContext.chainId), + scope: toCaipChainId( + KnownCaipNamespace.Eip155, + executionContext.chainId, + ), account: ethErc4337Account.id, request: { method: 'eth_prepareUserOperation', @@ -1866,7 +1878,10 @@ describe('SnapKeyring', () => { method: 'keyring_submitRequest', params: { id: expect.any(String), - scope: toCaipChainId(EthScope.Namespace, executionContext.chainId), + scope: toCaipChainId( + KnownCaipNamespace.Eip155, + executionContext.chainId, + ), account: ethErc4337Account.id, request: { method: 'eth_patchUserOperation', diff --git a/packages/keyring-snap-bridge/src/migrations/v1.ts b/packages/keyring-snap-bridge/src/migrations/v1.ts index 56dc9c024..7265ed938 100644 --- a/packages/keyring-snap-bridge/src/migrations/v1.ts +++ b/packages/keyring-snap-bridge/src/migrations/v1.ts @@ -9,6 +9,7 @@ import { } from '@metamask/keyring-api'; import { isBtcMainnetAddress } from '@metamask/keyring-utils'; import { is } from '@metamask/superstruct'; +import type { CaipChainId } from '@metamask/utils'; import { assertKeyringAccount, @@ -35,12 +36,16 @@ export function isAccountV1( * @param accountV1 - A v1 account. * @returns The list of scopes for that accounts. */ -export function getScopesForAccountV1(accountV1: KeyringAccountV1): string[] { +export function getScopesForAccountV1( + accountV1: KeyringAccountV1, +): CaipChainId[] { switch (accountV1.type) { case EthAccountType.Eoa: { - // EVM EOA account are compatible with any EVM networks, and we use CAIP-2 - // namespaces when the scope relates to ALL chains (from that namespace). - return [EthScope.Namespace]; + // EVM EOA account are compatible with any EVM networks, we use the + // 'eip155:0' scope as defined in the EVM CAIP-10 namespaces. + // + // See: https://namespaces.chainagnostic.org/eip155/caip10 + return [EthScopes.Eoa]; } case EthAccountType.Erc4337: { // EVM Erc4337 account @@ -64,7 +69,7 @@ export function getScopesForAccountV1(accountV1: KeyringAccountV1): string[] { } default: // We re-use EOA scopes if we don't know what to do for now. - return [EthScope.Namespace]; + return [EthScopes.Eoa]; } } @@ -87,6 +92,10 @@ export function transformAccountV1( // So we can automatically inject a valid `scopes` for this, but not for // other kind of accounts. if (type === EthAccountType.Eoa) { + // EVM EOA accounts are compatible with any EVM networks, we use the + // 'eip155:0' scope as defined in the EVM CAIP-10 namespaces. + // + // See: https://namespaces.chainagnostic.org/eip155/caip10 return { ...accountV1, scopes: getScopesForAccountV1(accountV1), diff --git a/packages/keyring-snap-client/src/KeyringClient.test.ts b/packages/keyring-snap-client/src/KeyringClient.test.ts index f94eedd38..ba3295f1d 100644 --- a/packages/keyring-snap-client/src/KeyringClient.test.ts +++ b/packages/keyring-snap-client/src/KeyringClient.test.ts @@ -28,7 +28,7 @@ describe('KeyringClient', () => { address: '0xE9A74AACd7df8112911ca93260fC5a046f8a64Ae', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }, ]; @@ -52,7 +52,7 @@ describe('KeyringClient', () => { address: '0xE9A74AACd7df8112911ca93260fC5a046f8a64Ae', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }; @@ -75,7 +75,7 @@ describe('KeyringClient', () => { address: '0xE9A74AACd7df8112911ca93260fC5a046f8a64Ae', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }; @@ -438,7 +438,7 @@ describe('KeyringClient', () => { address: '0xE9A74AACd7df8112911ca93260fC5a046f8a64Ae', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }; diff --git a/packages/keyring-snap-client/src/KeyringSnapRpcClient.test.ts b/packages/keyring-snap-client/src/KeyringSnapRpcClient.test.ts index 736274c43..cd927c302 100644 --- a/packages/keyring-snap-client/src/KeyringSnapRpcClient.test.ts +++ b/packages/keyring-snap-client/src/KeyringSnapRpcClient.test.ts @@ -12,7 +12,7 @@ describe('KeyringSnapRpcClient', () => { address: '0xE9A74AACd7df8112911ca93260fC5a046f8a64Ae', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }, ]; diff --git a/packages/keyring-snap-sdk/src/rpc-handler.test.ts b/packages/keyring-snap-sdk/src/rpc-handler.test.ts index d2f0d1ee1..c8108881d 100644 --- a/packages/keyring-snap-sdk/src/rpc-handler.test.ts +++ b/packages/keyring-snap-sdk/src/rpc-handler.test.ts @@ -226,7 +226,7 @@ describe('handleKeyringRequest', () => { address: '0x0', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }, }, @@ -240,7 +240,7 @@ describe('handleKeyringRequest', () => { address: '0x0', options: {}, methods: [], - scopes: ['eip155'], + scopes: ['eip155:0'], type: 'eip155:eoa', }); expect(result).toBe('UpdateAccount result'); From 2f85f78f38190ca041dfb713332aa96404697690 Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:01:35 +0100 Subject: [PATCH 3/6] refactor!: rename enums `*Scopes` to `*Scope` --- packages/keyring-api/src/btc/constants.ts | 2 +- packages/keyring-api/src/eth/constants.ts | 2 +- packages/keyring-api/src/eth/types.ts | 2 +- packages/keyring-api/src/events.test.ts | 10 +++++----- packages/keyring-api/src/sol/constants.ts | 2 +- .../keyring-snap-bridge/src/SnapKeyring.test.ts | 16 ++++++++-------- .../keyring-snap-bridge/src/migrations/v1.ts | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/keyring-api/src/btc/constants.ts b/packages/keyring-api/src/btc/constants.ts index ea0068f58..1347794ca 100644 --- a/packages/keyring-api/src/btc/constants.ts +++ b/packages/keyring-api/src/btc/constants.ts @@ -3,7 +3,7 @@ /** * Scopes for Bitcoin account type. See {@link KeyringAccount.scopes}. */ -export enum BtcScopes { +export enum BtcScope { Mainnet = 'bip122:000000000019d6689c085ae165831e93', Testnet = 'bip122:000000000933ea01ad0ee984209779ba', Testnet4 = 'bip122:00000000da84f2bafbbc53dee25a72ae', diff --git a/packages/keyring-api/src/eth/constants.ts b/packages/keyring-api/src/eth/constants.ts index e4111902a..e9b883ee0 100644 --- a/packages/keyring-api/src/eth/constants.ts +++ b/packages/keyring-api/src/eth/constants.ts @@ -3,7 +3,7 @@ /** * Scopes for EVM account type. See {@link KeyringAccount.scopes}. */ -export enum EthScopes { +export enum EthScope { Eoa = 'eip155:0', Mainnet = 'eip155:1', Testnet = 'eip155:11155111', diff --git a/packages/keyring-api/src/eth/types.ts b/packages/keyring-api/src/eth/types.ts index 3aa2aae37..90f895fe3 100644 --- a/packages/keyring-api/src/eth/types.ts +++ b/packages/keyring-api/src/eth/types.ts @@ -51,7 +51,7 @@ export const EthEoaAccountStruct = object({ /** * Account scopes (must be ['eip155:0']). */ - scopes: nonempty(array(literal(EthScopes.Eoa))), + scopes: nonempty(array(literal(EthScope.Eoa))), /** * Account supported methods. diff --git a/packages/keyring-api/src/events.test.ts b/packages/keyring-api/src/events.test.ts index 70dd9572e..05bae0601 100644 --- a/packages/keyring-api/src/events.test.ts +++ b/packages/keyring-api/src/events.test.ts @@ -22,7 +22,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }, }, @@ -40,7 +40,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }, }, @@ -58,7 +58,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }, displayConfirmation: true, @@ -79,7 +79,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }, }, @@ -97,7 +97,7 @@ describe('events', () => { address: '0x0123', methods: [], options: {}, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }, }, diff --git a/packages/keyring-api/src/sol/constants.ts b/packages/keyring-api/src/sol/constants.ts index 33ce9370a..c23b38280 100644 --- a/packages/keyring-api/src/sol/constants.ts +++ b/packages/keyring-api/src/sol/constants.ts @@ -3,7 +3,7 @@ /** * Scopes for Solana account type. See {@link KeyringAccount.scopes}. */ -export enum SolScopes { +export enum SolScope { Devnet = 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', Mainnet = 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp', Testnet = 'solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z', diff --git a/packages/keyring-snap-bridge/src/SnapKeyring.test.ts b/packages/keyring-snap-bridge/src/SnapKeyring.test.ts index 06eab518c..5db8d9d6f 100644 --- a/packages/keyring-snap-bridge/src/SnapKeyring.test.ts +++ b/packages/keyring-snap-bridge/src/SnapKeyring.test.ts @@ -104,7 +104,7 @@ describe('SnapKeyring', () => { address: '0xC728514Df8A7F9271f4B7a4dd2Aa6d2D723d3eE3'.toLowerCase(), options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }; const ethEoaAccount2 = { @@ -112,7 +112,7 @@ describe('SnapKeyring', () => { address: '0x34b13912eAc00152bE0Cb409A301Ab8E55739e63'.toLowerCase(), options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }; const ethEoaAccount3 = { @@ -120,7 +120,7 @@ describe('SnapKeyring', () => { address: '0xf7bDe8609231033c69E502C08f85153f8A1548F2'.toLowerCase(), options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, }; const ethErc4337Account = { @@ -162,7 +162,7 @@ describe('SnapKeyring', () => { methods: [], // For unknown accounts, we consider them as EVM EOA for now, so just re-use the // same scopes. - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], // This should not be really possible to create such account, but since we potentially // migrate data upon the Snap keyring initialization, we want to cover edge-cases // like this one to avoid crashing and blocking everything... @@ -237,7 +237,7 @@ describe('SnapKeyring', () => { id: 'b05d918a-b37c-497a-bb28-3d15c0d56b7a', options: {}, methods: ETH_EOA_METHODS, - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], type: EthAccountType.Eoa, // Even checksummed address will be lower-cased by the bridge. address: '0x6431726EEE67570BF6f0Cf892aE0a3988F03903F', @@ -429,7 +429,7 @@ describe('SnapKeyring', () => { metadata: expect.any(Object), // By default, new EVM accounts will have this scopes if it not provided // during the account creation flow. - scopes: [EthScopes.Eoa], + scopes: [EthScope.Eoa], }); }); @@ -707,7 +707,7 @@ describe('SnapKeyring', () => { const keyringAccounts = keyring.listAccounts(); expect(keyringAccounts.length).toBeGreaterThan(0); - expect(keyringAccounts[0]?.scopes).toStrictEqual([EthScopes.Eoa]); + expect(keyringAccounts[0]?.scopes).toStrictEqual([EthScope.Eoa]); }); it('updates a ERC4337 account with the no scope will throw an error', async () => { @@ -1044,7 +1044,7 @@ describe('SnapKeyring', () => { it('unknown v1 accounts scopes defaults to EOA scopes', () => { expect(getScopesForAccountV1(unknownAccount)).toStrictEqual([ - EthScopes.Eoa, + EthScope.Eoa, ]); }); }); diff --git a/packages/keyring-snap-bridge/src/migrations/v1.ts b/packages/keyring-snap-bridge/src/migrations/v1.ts index 7265ed938..eb8295e99 100644 --- a/packages/keyring-snap-bridge/src/migrations/v1.ts +++ b/packages/keyring-snap-bridge/src/migrations/v1.ts @@ -45,7 +45,7 @@ export function getScopesForAccountV1( // 'eip155:0' scope as defined in the EVM CAIP-10 namespaces. // // See: https://namespaces.chainagnostic.org/eip155/caip10 - return [EthScopes.Eoa]; + return [EthScope.Eoa]; } case EthAccountType.Erc4337: { // EVM Erc4337 account @@ -69,7 +69,7 @@ export function getScopesForAccountV1( } default: // We re-use EOA scopes if we don't know what to do for now. - return [EthScopes.Eoa]; + return [EthScope.Eoa]; } } From eb05c91a199b90cc63db876ce175261a38ec1498 Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Tue, 28 Jan 2025 13:05:47 +0100 Subject: [PATCH 4/6] chore: update error message --- packages/keyring-api/src/api/account.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/keyring-api/src/api/account.test.ts b/packages/keyring-api/src/api/account.test.ts index cb07e8d71..b59f7305e 100644 --- a/packages/keyring-api/src/api/account.test.ts +++ b/packages/keyring-api/src/api/account.test.ts @@ -52,7 +52,7 @@ describe('api', () => { scopes: [scope], }; expect(() => assert(account, KeyringAccountStruct)).toThrow( - `At path: scopes.0 -- Expected the value to satisfy a union of \`string | string\`, but received: "${scope}"`, + `At path: scopes.0 -- Expected a string matching \`/^(?[-a-z0-9]{3,8}):(?[-_a-zA-Z0-9]{1,32})$/\` but received "${scope}"`, ); }); }); From 30e933c6a6d76528f264db179c52d71c0ceb5631 Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Tue, 28 Jan 2025 14:28:41 +0100 Subject: [PATCH 5/6] chore: remove outdated comment --- packages/keyring-snap-bridge/src/migrations/v1.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/keyring-snap-bridge/src/migrations/v1.ts b/packages/keyring-snap-bridge/src/migrations/v1.ts index eb8295e99..180d2df2e 100644 --- a/packages/keyring-snap-bridge/src/migrations/v1.ts +++ b/packages/keyring-snap-bridge/src/migrations/v1.ts @@ -92,10 +92,6 @@ export function transformAccountV1( // So we can automatically inject a valid `scopes` for this, but not for // other kind of accounts. if (type === EthAccountType.Eoa) { - // EVM EOA accounts are compatible with any EVM networks, we use the - // 'eip155:0' scope as defined in the EVM CAIP-10 namespaces. - // - // See: https://namespaces.chainagnostic.org/eip155/caip10 return { ...accountV1, scopes: getScopesForAccountV1(accountV1), From 46d5a76323d6395ae04a71588c158a26fcae747e Mon Sep 17 00:00:00 2001 From: Daniel Rocha <68558152+danroc@users.noreply.github.com> Date: Tue, 28 Jan 2025 18:12:39 +0100 Subject: [PATCH 6/6] chore: update comment --- packages/keyring-api/src/api/account.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/keyring-api/src/api/account.ts b/packages/keyring-api/src/api/account.ts index 4ae5957a6..2e2c2010d 100644 --- a/packages/keyring-api/src/api/account.ts +++ b/packages/keyring-api/src/api/account.ts @@ -63,7 +63,7 @@ export const KeyringAccountStruct = object({ address: string(), /** - * Account supported scopes (CAIP-2 chain IDs or CAIP-2 namespaces). + * Account supported scopes (CAIP-2 chain IDs). */ scopes: nonempty(array(CaipChainIdStruct)),