diff --git a/packages/keyring-internal-api/CHANGELOG.md b/packages/keyring-internal-api/CHANGELOG.md index 9adb0d738..5b26da765 100644 --- a/packages/keyring-internal-api/CHANGELOG.md +++ b/packages/keyring-internal-api/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Add `KeyringInternalFeature` and `KeyringInternalFeatures` support ([#423](https://github.com/MetaMask/accounts/pull/423)) + - They can be used to describe the internal feature supported by a keyring (for internal use). + +### Removed + +- **BREAKING:** Remove `KeyringVersion` support ([#423](https://github.com/MetaMask/accounts/pull/423)) + - Use `KeyringInternalFeature` and `KeyringInternalFeatures` instead. + ## [9.1.1] ### Changed diff --git a/packages/keyring-internal-api/src/compatibility/index.ts b/packages/keyring-internal-api/src/compatibility/index.ts index 5b98253d9..630b8e4eb 100644 --- a/packages/keyring-internal-api/src/compatibility/index.ts +++ b/packages/keyring-internal-api/src/compatibility/index.ts @@ -1 +1 @@ -export * from './v1'; +export * from './legacy'; diff --git a/packages/keyring-internal-api/src/compatibility/v1.test.ts b/packages/keyring-internal-api/src/compatibility/legacy.test.ts similarity index 73% rename from packages/keyring-internal-api/src/compatibility/v1.test.ts rename to packages/keyring-internal-api/src/compatibility/legacy.test.ts index b4d1fc4b9..000b22d1d 100644 --- a/packages/keyring-internal-api/src/compatibility/v1.test.ts +++ b/packages/keyring-internal-api/src/compatibility/legacy.test.ts @@ -1,9 +1,9 @@ import { EthMethod, EthScope } from '@metamask/keyring-api'; -import { toKeyringRequestV1 } from './v1'; +import { toLegacyKeyringRequest } from './legacy'; describe('v1', () => { - describe('toKeyringRequestV1', () => { + describe('toLegacyKeyringRequest', () => { const request = { id: 'mock-request-id', scope: EthScope.Mainnet, @@ -17,7 +17,7 @@ describe('v1', () => { const { origin, ...requestV1 } = request; it('converts a keyring request to a keyring request v1', () => { - expect(toKeyringRequestV1(request)).toStrictEqual(requestV1); + expect(toLegacyKeyringRequest(request)).toStrictEqual(requestV1); }); }); }); diff --git a/packages/keyring-internal-api/src/compatibility/v1.ts b/packages/keyring-internal-api/src/compatibility/legacy.ts similarity index 51% rename from packages/keyring-internal-api/src/compatibility/v1.ts rename to packages/keyring-internal-api/src/compatibility/legacy.ts index d51a09463..3a866926b 100644 --- a/packages/keyring-internal-api/src/compatibility/v1.ts +++ b/packages/keyring-internal-api/src/compatibility/legacy.ts @@ -8,18 +8,20 @@ import { omit, type Infer } from '@metamask/superstruct'; /** * Keyring request (v1). */ -export const KeyringRequestV1Struct = omit(KeyringRequestStruct, ['origin']); +export const LegacyKeyringRequestStruct = omit(KeyringRequestStruct, [ + 'origin', +]); -export type KeyringRequestV1 = Infer; +export type LegacyKeyringRequest = Infer; /** * Response to a call to `submitRequest` (v1). */ -export const KeyringResponseV1Struct = KeyringResponseStruct; +export const LegacyKeyringResponseStruct = KeyringResponseStruct; -export type KeyringResponseV1 = Infer; +export type LegacyKeyringResponse = Infer; -export const SubmitRequestResponseV1Struct = KeyringResponseV1Struct; +export const SubmitRequestResponseV1Struct = LegacyKeyringResponseStruct; /** * Converts a keyring request to a keyring request v1. @@ -27,7 +29,9 @@ export const SubmitRequestResponseV1Struct = KeyringResponseV1Struct; * @param request - A keyring request. * @returns A keyring request v1. */ -export function toKeyringRequestV1(request: KeyringRequest): KeyringRequestV1 { +export function toLegacyKeyringRequest( + request: KeyringRequest, +): LegacyKeyringRequest { const { origin, ...requestV1 } = request; return requestV1; diff --git a/packages/keyring-internal-api/src/versions.ts b/packages/keyring-internal-api/src/versions.ts index 4a42f19cd..02cb07cd7 100644 --- a/packages/keyring-internal-api/src/versions.ts +++ b/packages/keyring-internal-api/src/versions.ts @@ -1,12 +1,14 @@ -export enum KeyringVersion { - /** Default. */ - V1 = 'v1', - +export enum KeyringInternalFeature { /** * Introduction of `KeyringRequest.origin`. * * Snap will now receive the `origin` as part of a `KeyringRequest` when `submitRequest` is invoked. * We also expect Snaps to display this `origin` in their confirmation screens (if any). */ - V2 = 'v2', + UseOrigin = 'use-origin', } + +/** + * Type representing a set of keyring internal features. + */ +export type KeyringInternalFeatures = Set; diff --git a/packages/keyring-internal-snap-client/CHANGELOG.md b/packages/keyring-internal-snap-client/CHANGELOG.md index 91cef694e..1dcc1fc42 100644 --- a/packages/keyring-internal-snap-client/CHANGELOG.md +++ b/packages/keyring-internal-snap-client/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/snaps-sdk` from `^9.0.0` to `^10.3.0` ([#422](https://github.com/MetaMask/accounts/pull/422)) - Bump `@metamask/snaps-utils` from `^11.0.0` to `^11.7.0` ([#422](https://github.com/MetaMask/accounts/pull/422)) +### Removed + +- **BREAKING:** Rename `submitRequestV1` method to `submitLegacyRequest` ([#423](https://github.com/MetaMask/accounts/pull/423)) + ## [8.0.1] ### Changed diff --git a/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts b/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts index 525ec0f56..7a19e947e 100644 --- a/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts +++ b/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.test.ts @@ -3,7 +3,7 @@ import { EthScope, type KeyringAccount, } from '@metamask/keyring-api'; -import type { KeyringRequestV1 } from '@metamask/keyring-internal-api'; +import type { LegacyKeyringRequest } from '@metamask/keyring-internal-api'; import type { SnapId } from '@metamask/snaps-sdk'; import { @@ -87,8 +87,8 @@ describe('KeyringInternalSnapClient', () => { }); }); - describe('submitRequestV1', () => { - const keyringRequest: KeyringRequestV1 = { + describe('submitLegacyRequest', () => { + const keyringRequest: LegacyKeyringRequest = { id: 'mock-request-id', scope: EthScope.Mainnet, account: MOCK_ACCOUNT.id, @@ -109,7 +109,7 @@ describe('KeyringInternalSnapClient', () => { }, }; - it('calls the submitRequestV1 method', async () => { + it('calls the submitLegacyRequest method', async () => { const client = new KeyringInternalSnapClient({ messenger: messenger as unknown as KeyringInternalSnapClientMessenger, snapId, @@ -119,7 +119,7 @@ describe('KeyringInternalSnapClient', () => { pending: false, result: null, }); - await client.submitRequestV1(keyringRequest); + await client.submitLegacyRequest(keyringRequest); expect(messenger.call).toHaveBeenCalledWith( 'SnapController:handleRequest', request, diff --git a/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.ts b/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.ts index 49b2c7917..65586350b 100644 --- a/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.ts +++ b/packages/keyring-internal-snap-client/src/KeyringInternalSnapClient.ts @@ -1,7 +1,7 @@ import { KeyringRpcMethod } from '@metamask/keyring-api'; import type { - KeyringRequestV1, - KeyringResponseV1, + LegacyKeyringRequest, + LegacyKeyringResponse, } from '@metamask/keyring-internal-api'; import { SubmitRequestResponseV1Struct } from '@metamask/keyring-internal-api'; import { KeyringClient, type Sender } from '@metamask/keyring-snap-client'; @@ -131,7 +131,9 @@ export class KeyringInternalSnapClient extends KeyringClient { * @param request - Keyring request. * @returns Keyring request's response. */ - async submitRequestV1(request: KeyringRequestV1): Promise { + async submitLegacyRequest( + request: LegacyKeyringRequest, + ): Promise { return strictMask( await this.send({ method: KeyringRpcMethod.SubmitRequest, diff --git a/packages/keyring-snap-bridge/CHANGELOG.md b/packages/keyring-snap-bridge/CHANGELOG.md index 30baa95b1..08bf9903d 100644 --- a/packages/keyring-snap-bridge/CHANGELOG.md +++ b/packages/keyring-snap-bridge/CHANGELOG.md @@ -13,6 +13,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `@metamask/snaps-sdk` from `^9.0.0` to `^10.3.0` ([#422](https://github.com/MetaMask/accounts/pull/422)) - Bump `@metamask/snaps-utils` from `^11.0.0` to `^11.7.0` ([#422](https://github.com/MetaMask/accounts/pull/422)) +### Removed + +- **BREAKING:** Remove `KeyringVersion` support ([#423](https://github.com/MetaMask/accounts/pull/423)) + - Both `getKeyringVersionFromPlatform`, `PLATFORM_VERSION_TO_KEYRING_VERSION` got removed too. + - Use `KeyringInternalFeature` instead. +- **BREAKING:** Rename `submitRequestV1` method to `submitLegacyRequest` ([#423](https://github.com/MetaMask/accounts/pull/423)) + ## [18.0.2] ### Fixed diff --git a/packages/keyring-snap-bridge/src/SnapKeyring.ts b/packages/keyring-snap-bridge/src/SnapKeyring.ts index 5e20ef214..b0059b1aa 100644 --- a/packages/keyring-snap-bridge/src/SnapKeyring.ts +++ b/packages/keyring-snap-bridge/src/SnapKeyring.ts @@ -13,7 +13,6 @@ import type { ResolvedAccountAddress, CaipChainId, MetaMaskOptions, - KeyringRequest, KeyringResponse, } from '@metamask/keyring-api'; import { @@ -28,10 +27,13 @@ import { AccountTransactionsUpdatedEventStruct, AnyAccountType, } from '@metamask/keyring-api'; +import type { + KeyringInternalFeatures, + InternalAccount, +} from '@metamask/keyring-internal-api'; import { - KeyringVersion, - toKeyringRequestV1, - type InternalAccount, + KeyringInternalFeature, + toLegacyKeyringRequest, } from '@metamask/keyring-internal-api'; import { KeyringInternalSnapClient } from '@metamask/keyring-internal-snap-client'; import { @@ -84,7 +86,7 @@ import { toJson, unique, } from './util'; -import { getKeyringVersionFromPlatform } from './versions'; +import { getKeyringFeaturesFromPlatform } from './versions'; export const SNAP_KEYRING_TYPE = 'Snap Keyring'; @@ -248,13 +250,13 @@ export class SnapKeyring { } /** - * Gets keyring's version for a given Snap. + * Gets keyring's features for a given Snap. * * @param snapId - The Snap ID. - * @returns The Snap's keyring version. + * @returns The Snap's keyring features. */ - #getKeyringVersion(snapId: SnapId): KeyringVersion { - return getKeyringVersionFromPlatform((version: SemVerVersion) => { + #getKeyringFeatures(snapId: SnapId): KeyringInternalFeatures { + return getKeyringFeaturesFromPlatform((version: SemVerVersion) => { return this.#messenger.call( 'SnapController:isMinimumPlatformVersion', snapId, @@ -1012,34 +1014,6 @@ export class SnapKeyring { }); } - /** - * Submits a request to a Snap and fix-up the payload depending on the version currently supported. - * - * @param options - The options for the Snap request. - * @param options.version - The supported keyring version for the Snap. - * @param options.snapId - The Snap ID to submit the request to. - * @param options.request - The Snap request. - * @returns A promise that resolves to the keyring response from the Snap. - */ - async #submitSnapRequestForVersion({ - snapId, - version, - request, - }: { - snapId: SnapId; - version: KeyringVersion; - request: KeyringRequest; - }): Promise { - // Get specific client for that Snap. - const client = this.#snapClient.withSnapId(snapId); - - if (version === KeyringVersion.V1) { - return await client.submitRequestV1(toKeyringRequestV1(request)); - } - - return await client.submitRequest(request); - } - /** * Submits a request to a Snap. * @@ -1093,7 +1067,7 @@ export class SnapKeyring { ); try { - const version = this.#getKeyringVersion(snapId); + const features = this.#getKeyringFeatures(snapId); const request = { id: requestId, @@ -1108,11 +1082,18 @@ export class SnapKeyring { log('Submit Snap request: ', request); - const response = await this.#submitSnapRequestForVersion({ - version, - snapId, - request, - }); + // Get specific client for that Snap. + const client = this.#snapClient.withSnapId(snapId); + + let response: KeyringResponse; + if (features.has(KeyringInternalFeature.UseOrigin)) { + response = await client.submitRequest(request); + } else { + // LegacyV1 keyring request did not support the `origin` field. + response = await client.submitLegacyRequest( + toLegacyKeyringRequest(request), + ); + } // Some methods, like the ones used to prepare and patch user operations, // require the Snap to answer synchronously in order to work with the diff --git a/packages/keyring-snap-bridge/src/versions.test.ts b/packages/keyring-snap-bridge/src/versions.test.ts index 0c39b1579..fe039a752 100644 --- a/packages/keyring-snap-bridge/src/versions.test.ts +++ b/packages/keyring-snap-bridge/src/versions.test.ts @@ -1,35 +1,35 @@ -import { KeyringVersion } from '@metamask/keyring-internal-api'; +import { KeyringInternalFeature } from '@metamask/keyring-internal-api'; import { isValidSemVerVersion, type SemVerVersion } from '@metamask/utils'; import { - getKeyringVersionFromPlatform, - PLATFORM_VERSION_TO_KEYRING_VERSION, + getKeyringFeaturesFromPlatform, + PLATFORM_VERSION_TO_KEYRING_FEATURES, } from './versions'; -describe('getKeyringVersionFromPlatform', () => { - it('gets the keyring version v1 as default', () => { +describe('getKeyringFeaturesFromPlatform', () => { + it('gets an empty feature set as default', () => { const isSupportedVersion = (): boolean => false; - expect(getKeyringVersionFromPlatform(isSupportedVersion)).toBe( - KeyringVersion.V1, + expect(getKeyringFeaturesFromPlatform(isSupportedVersion)).toStrictEqual( + new Set(), ); }); - it('gets the keyring version v2 if the platform version is 7.0.0', () => { + it('gets the UseOrigin feature if the platform version is 7.0.0', () => { const isSupportedVersion = (version: SemVerVersion): boolean => { return version === '7.0.0'; }; - expect(getKeyringVersionFromPlatform(isSupportedVersion)).toBe( - KeyringVersion.V2, + expect(getKeyringFeaturesFromPlatform(isSupportedVersion)).toStrictEqual( + new Set([KeyringInternalFeature.UseOrigin]), ); }); }); -describe('PLATFORM_VERSION_TO_KEYRING_VERSION', () => { - it.each(PLATFORM_VERSION_TO_KEYRING_VERSION)( +describe('PLATFORM_VERSION_TO_KEYRING_FEATURES', () => { + it.each(PLATFORM_VERSION_TO_KEYRING_FEATURES)( 'is a valid semver version: %s', - // `PLATFORM_VERSION_TO_KEYRING_VERSION` items are flattened by `it.each`, no need + // `PLATFORM_VERSION_TO_KEYRING_FEATURES` items are flattened by `it.each`, no need // to destructure the tuple here. (version) => { expect(isValidSemVerVersion(version)).toBe(true); diff --git a/packages/keyring-snap-bridge/src/versions.ts b/packages/keyring-snap-bridge/src/versions.ts index b09c783e6..553127a54 100644 --- a/packages/keyring-snap-bridge/src/versions.ts +++ b/packages/keyring-snap-bridge/src/versions.ts @@ -1,36 +1,37 @@ -import { KeyringVersion } from '@metamask/keyring-internal-api'; +import type { KeyringInternalFeatures } from '@metamask/keyring-internal-api'; +import { KeyringInternalFeature } from '@metamask/keyring-internal-api'; import type { SemVerVersion } from '@metamask/utils'; /** - * Mapping of the Snap platform version to its `KeyringVersion` equivalent. + * Mapping of the Snap platform version to its `KeyringInternalFeatures` equivalent. * * NOTE: We use an array here to preserve ordering of each versions. */ -export const PLATFORM_VERSION_TO_KEYRING_VERSION = [ +export const PLATFORM_VERSION_TO_KEYRING_FEATURES = [ // ! NOTE: This versions needs to be sorted in a descending order (highest platform version first). // Introduction of `KeyringRequest.origin`. - ['7.0.0', KeyringVersion.V2], + ['7.0.0', new Set([KeyringInternalFeature.UseOrigin])], ] as const; /** - * Gets keyring's version for a given Snap. + * Gets keyring's features for a given Snap. * * @param isSupportedVersion - Predicate to check if the version is supported. - * @returns The Snap's keyring version. + * @returns The Snap's keyring features. */ -export function getKeyringVersionFromPlatform( +export function getKeyringFeaturesFromPlatform( isSupportedVersion: (version: SemVerVersion) => boolean, -): KeyringVersion { +): KeyringInternalFeatures { for (const [ platformVersion, - keyringVersion, - ] of PLATFORM_VERSION_TO_KEYRING_VERSION) { + keyringFeatures, + ] of PLATFORM_VERSION_TO_KEYRING_FEATURES) { // NOTE: We are type-casting, but we have a unit tests that make sure all // versions are following the semver spec. if (isSupportedVersion(platformVersion as SemVerVersion)) { - return keyringVersion; + return keyringFeatures; } } - return KeyringVersion.V1; + return new Set(); }