@metamask/keyring-sdk
Advanced tools
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.createMigrations = exports.isVersionedState = exports.VersionedStateStruct = void 0; | ||
| const superstruct_1 = require("@metamask/superstruct"); | ||
| const utils_1 = require("@metamask/utils"); | ||
| /** | ||
| * Superstruct schema for the versioned state envelope. | ||
| */ | ||
| exports.VersionedStateStruct = (0, superstruct_1.object)({ | ||
| version: (0, superstruct_1.integer)(), | ||
| data: utils_1.JsonStruct, | ||
| }); | ||
| /** | ||
| * Type guard to check if a value is a {@link VersionedState} envelope. | ||
| * | ||
| * @param state - The value to check. | ||
| * @returns `true` if the value is a versioned state envelope. | ||
| */ | ||
| function isVersionedState(state) { | ||
| return (0, superstruct_1.is)(state, exports.VersionedStateStruct); | ||
| } | ||
| exports.isVersionedState = isVersionedState; | ||
| /** | ||
| * Get the version and data from state, treating unversioned state as version 0. | ||
| * | ||
| * @param state - The state to check. | ||
| * @returns The version and data. | ||
| */ | ||
| function getVersionAndData(state) { | ||
| return isVersionedState(state) | ||
| ? { version: state.version, data: state.data } | ||
| : { version: 0, data: state }; | ||
| } | ||
| /** | ||
| * Apply the pending steps of a chain to `state`. | ||
| * | ||
| * Implements {@link MigrationChain.apply} for the chain built from `steps`. | ||
| * | ||
| * @param steps - All steps of the chain. | ||
| * @param state - The serialized keyring state. | ||
| * @returns The migrated state wrapped in a versioned envelope, plus a `migrated` flag. | ||
| */ | ||
| async function applySteps(steps, state) { | ||
| const latestVersion = steps.length; | ||
| const { version, data: initialData } = getVersionAndData(state); | ||
| if (version < 0) { | ||
| throw new Error(`State version ${version} is invalid; it cannot be negative`); | ||
| } | ||
| if (version > latestVersion) { | ||
| throw new Error(`State version ${version} is newer than the latest migration version ${latestVersion}`); | ||
| } | ||
| const pendingSteps = steps.slice(version); | ||
| let data = initialData; | ||
| for (const step of pendingSteps) { | ||
| (0, superstruct_1.assert)(data, step.inputSchema ?? utils_1.JsonStruct); | ||
| data = await step.migrate(data); | ||
| (0, superstruct_1.assert)(data, step.outputSchema ?? utils_1.JsonStruct); | ||
| } | ||
| return { | ||
| version: latestVersion, | ||
| data, | ||
| migrated: pendingSteps.length > 0, | ||
| }; | ||
| } | ||
| /** | ||
| * Build a {@link MigrationChain} wrapping the given internal steps. | ||
| * | ||
| * @param steps - The steps accumulated so far. | ||
| * @returns A chain exposing `add`, `version`, and `apply`. | ||
| */ | ||
| function buildChain(steps) { | ||
| return { | ||
| version: steps.length, | ||
| add: (step) => buildChain([...steps, step]), | ||
| apply: async (state) => applySteps(steps, state), | ||
| }; | ||
| } | ||
| /** | ||
| * Start a new, empty migration chain. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const migrations = createMigrations() | ||
| * .add({ migrate: (data) => ({ count: data.numberOfItems }) }) | ||
| * .add({ migrate: (data) => ({ ...data, createdAt: Date.now() }) }); // data typed as the first step's output, no cast | ||
| * | ||
| * const { data } = await migrations.apply(state); | ||
| * ``` | ||
| * @returns An empty chain, typed to accept `Json` as its first step's input. | ||
| */ | ||
| function createMigrations() { | ||
| return buildChain([]); | ||
| } | ||
| exports.createMigrations = createMigrations; | ||
| //# sourceMappingURL=migration.cjs.map |
| {"version":3,"file":"migration.cjs","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":";;;AACA,uDAAoE;AACpE,2CAA6C;AAG7C;;GAEG;AACU,QAAA,oBAAoB,GAAG,IAAA,oBAAM,EAAC;IACzC,OAAO,EAAE,IAAA,qBAAO,GAAE;IAClB,IAAI,EAAE,kBAAU;CACjB,CAAC,CAAC;AA4BH;;;;;GAKG;AACH,SAAgB,gBAAgB,CAC9B,KAAoC;IAEpC,OAAO,IAAA,gBAAE,EAAC,KAAK,EAAE,4BAAoB,CAAC,CAAC;AACzC,CAAC;AAJD,4CAIC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CACxB,KAAoC;IAEpC,OAAO,gBAAgB,CAAC,KAAK,CAAC;QAC5B,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;QAC9C,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAClC,CAAC;AA8ED;;;;;;;;GAQG;AACH,KAAK,UAAU,UAAU,CACvB,KAA+B,EAC/B,KAAW;IAEX,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAEhE,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,iBAAiB,OAAO,oCAAoC,CAC7D,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,iBAAiB,OAAO,+CAA+C,aAAa,EAAE,CACvF,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,IAAI,GAAG,WAAW,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,IAAA,oBAAM,EAAC,IAAI,EAAE,IAAI,CAAC,WAAW,IAAI,kBAAU,CAAC,CAAC;QAC7C,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,IAAA,oBAAM,EAAC,IAAI,EAAE,IAAI,CAAC,YAAY,IAAI,kBAAU,CAAC,CAAC;IAChD,CAAC;IAED,OAAO;QACL,OAAO,EAAE,aAAa;QACtB,IAAI;QACJ,QAAQ,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;KACT,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CACjB,KAA+B;IAE/B,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,MAAM;QACrB,GAAG,EAAE,CACH,IAAkC,EAClC,EAAE,CAAC,UAAU,CAAS,CAAC,GAAG,KAAK,EAAE,IAAgC,CAAC,CAAC;QACrE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAO,KAAK,EAAE,KAAK,CAAC;KACvD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,gBAAgB;IAC9B,OAAO,UAAU,CAAO,EAAE,CAAC,CAAC;AAC9B,CAAC;AAFD,4CAEC","sourcesContent":["import type { Infer, Struct } from '@metamask/superstruct';\nimport { assert, integer, is, object } from '@metamask/superstruct';\nimport { JsonStruct } from '@metamask/utils';\nimport type { Json } from '@metamask/utils';\n\n/**\n * Superstruct schema for the versioned state envelope.\n */\nexport const VersionedStateStruct = object({\n version: integer(),\n data: JsonStruct,\n});\n\n/**\n * Versioned state envelope wrapping the actual keyring data.\n *\n * After migrations are applied, state is always wrapped in this format. `serialize()`\n * should produce this envelope so that subsequent `deserialize()` calls can detect the\n * version.\n */\nexport type VersionedState<Data extends Json = Json> = Omit<\n Infer<typeof VersionedStateStruct>,\n 'data'\n> & {\n data: Data;\n};\n\n/**\n * Return value of {@link MigrationChain.apply}.\n *\n * Extends {@link VersionedState} with a `migrated` flag that is `true` when at least\n * one step was applied during the call. Callers can use this to detect that the\n * in-memory state has been upgraded and schedule a persist so the new version is\n * written to storage, even when no other state change happens in the session.\n */\nexport type MigrationResult<Data extends Json = Json> = VersionedState<Data> & {\n migrated: boolean;\n};\n\n/**\n * Type guard to check if a value is a {@link VersionedState} envelope.\n *\n * @param state - The value to check.\n * @returns `true` if the value is a versioned state envelope.\n */\nexport function isVersionedState<State extends Json = Json>(\n state: State | VersionedState<State>,\n): state is VersionedState<State> {\n return is(state, VersionedStateStruct);\n}\n\n/**\n * Get the version and data from state, treating unversioned state as version 0.\n *\n * @param state - The state to check.\n * @returns The version and data.\n */\nfunction getVersionAndData<State extends Json = Json>(\n state: State | VersionedState<State>,\n): VersionedState<State> {\n return isVersionedState(state)\n ? { version: state.version, data: state.data }\n : { version: 0, data: state };\n}\n\n/**\n * A single migration step, added to a {@link MigrationChain} via `.add()`.\n *\n * `Input` is bound automatically to the chain's current data type when the step is\n * passed to `.add()`, so `migrate` receives a correctly typed argument with no manual\n * cast.\n */\nexport type MigrationStep<\n Input extends Json = Json,\n Output extends Json = Json,\n> = {\n /**\n * Transform state from the previous step's output to this step's output.\n *\n * Receives the raw inner data (not the versioned envelope). May be sync or async to\n * support complex operations like re-deriving data from secrets.\n *\n * @param data - The state data from the previous step.\n * @returns The migrated data.\n */\n migrate(data: Input): Output | Promise<Output>;\n /**\n * Optional schema validating this step's input before `migrate` is called. Defaults\n * to a generic JSON-shape check when omitted.\n */\n inputSchema?: Struct<Input>;\n /**\n * Optional schema validating this step's output at runtime.\n */\n outputSchema?: Struct<Output>;\n};\n\n/**\n * A chain of migration steps for evolving keyring serialized state across versions.\n *\n * Steps are versioned by position: the first `.add()` call produces version 1, the\n * second version 2, and so on. Create one with {@link createMigrations}.\n */\nexport type MigrationChain<Data extends Json = Json> = {\n /**\n * The number of steps added so far. Since steps are versioned by position starting at\n * 1, this also doubles as \"the latest version\" (use it in `serialize()`).\n */\n readonly version: number;\n /**\n * Append a step to the chain.\n *\n * Returns a new chain typed to `Output`. It does not mutate the chain it's called on,\n * so branching from a shared base chain is safe.\n *\n * `Input` defaults to the chain's current `Data` type. Providing `inputSchema` lets\n * TypeScript infer a narrower `Input` (bounded to extend `Data`), so `migrate`\n * receives a schema-typed argument when narrowing raw state into a specific shape,\n * typically on a chain's first step, where `Data` is `Json`.\n *\n * @param step - The migration step to append.\n * @returns A new chain whose data type is the step's `Output`.\n */\n add<Input extends Data = Data, Output extends Json = Json>(\n step: MigrationStep<Input, Output>,\n ): MigrationChain<Output>;\n /**\n * Apply all pending steps to `state`.\n *\n * Handles both versioned state (wrapped in `{ version, data }` envelope) and\n * unversioned legacy state (treated as version 0).\n *\n * @param state - The serialized keyring state (from vault or previous serialize).\n * @returns The migrated state wrapped in a versioned envelope, plus a `migrated`\n * flag.\n * @throws If `state`'s version is newer than this chain's latest version, or if a\n * step's `inputSchema`/`outputSchema` validation fails.\n */\n apply(state: Json): Promise<MigrationResult<Data>>;\n};\n\n/**\n * Apply the pending steps of a chain to `state`.\n *\n * Implements {@link MigrationChain.apply} for the chain built from `steps`.\n *\n * @param steps - All steps of the chain.\n * @param state - The serialized keyring state.\n * @returns The migrated state wrapped in a versioned envelope, plus a `migrated` flag.\n */\nasync function applySteps<Data extends Json>(\n steps: readonly MigrationStep[],\n state: Json,\n): Promise<MigrationResult<Data>> {\n const latestVersion = steps.length;\n const { version, data: initialData } = getVersionAndData(state);\n\n if (version < 0) {\n throw new Error(\n `State version ${version} is invalid; it cannot be negative`,\n );\n }\n\n if (version > latestVersion) {\n throw new Error(\n `State version ${version} is newer than the latest migration version ${latestVersion}`,\n );\n }\n\n const pendingSteps = steps.slice(version);\n let data = initialData;\n\n for (const step of pendingSteps) {\n assert(data, step.inputSchema ?? JsonStruct);\n data = await step.migrate(data);\n assert(data, step.outputSchema ?? JsonStruct);\n }\n\n return {\n version: latestVersion,\n data,\n migrated: pendingSteps.length > 0,\n } as MigrationResult<Data>;\n}\n\n/**\n * Build a {@link MigrationChain} wrapping the given internal steps.\n *\n * @param steps - The steps accumulated so far.\n * @returns A chain exposing `add`, `version`, and `apply`.\n */\nfunction buildChain<Data extends Json>(\n steps: readonly MigrationStep[],\n): MigrationChain<Data> {\n return {\n version: steps.length,\n add: <Input extends Data, Output extends Json>(\n step: MigrationStep<Input, Output>,\n ) => buildChain<Output>([...steps, step as unknown as MigrationStep]),\n apply: async (state) => applySteps<Data>(steps, state),\n };\n}\n\n/**\n * Start a new, empty migration chain.\n *\n * @example\n * ```typescript\n * const migrations = createMigrations()\n * .add({ migrate: (data) => ({ count: data.numberOfItems }) })\n * .add({ migrate: (data) => ({ ...data, createdAt: Date.now() }) }); // data typed as the first step's output, no cast\n *\n * const { data } = await migrations.apply(state);\n * ```\n * @returns An empty chain, typed to accept `Json` as its first step's input.\n */\nexport function createMigrations(): MigrationChain<Json> {\n return buildChain<Json>([]);\n}\n"]} |
| import type { Infer, Struct } from "@metamask/superstruct"; | ||
| import type { Json } from "@metamask/utils"; | ||
| /** | ||
| * Superstruct schema for the versioned state envelope. | ||
| */ | ||
| export declare const VersionedStateStruct: Struct<{ | ||
| data: Json; | ||
| version: number; | ||
| }, { | ||
| version: Struct<number, null>; | ||
| data: Struct<Json, unknown>; | ||
| }>; | ||
| /** | ||
| * Versioned state envelope wrapping the actual keyring data. | ||
| * | ||
| * After migrations are applied, state is always wrapped in this format. `serialize()` | ||
| * should produce this envelope so that subsequent `deserialize()` calls can detect the | ||
| * version. | ||
| */ | ||
| export type VersionedState<Data extends Json = Json> = Omit<Infer<typeof VersionedStateStruct>, 'data'> & { | ||
| data: Data; | ||
| }; | ||
| /** | ||
| * Return value of {@link MigrationChain.apply}. | ||
| * | ||
| * Extends {@link VersionedState} with a `migrated` flag that is `true` when at least | ||
| * one step was applied during the call. Callers can use this to detect that the | ||
| * in-memory state has been upgraded and schedule a persist so the new version is | ||
| * written to storage, even when no other state change happens in the session. | ||
| */ | ||
| export type MigrationResult<Data extends Json = Json> = VersionedState<Data> & { | ||
| migrated: boolean; | ||
| }; | ||
| /** | ||
| * Type guard to check if a value is a {@link VersionedState} envelope. | ||
| * | ||
| * @param state - The value to check. | ||
| * @returns `true` if the value is a versioned state envelope. | ||
| */ | ||
| export declare function isVersionedState<State extends Json = Json>(state: State | VersionedState<State>): state is VersionedState<State>; | ||
| /** | ||
| * A single migration step, added to a {@link MigrationChain} via `.add()`. | ||
| * | ||
| * `Input` is bound automatically to the chain's current data type when the step is | ||
| * passed to `.add()`, so `migrate` receives a correctly typed argument with no manual | ||
| * cast. | ||
| */ | ||
| export type MigrationStep<Input extends Json = Json, Output extends Json = Json> = { | ||
| /** | ||
| * Transform state from the previous step's output to this step's output. | ||
| * | ||
| * Receives the raw inner data (not the versioned envelope). May be sync or async to | ||
| * support complex operations like re-deriving data from secrets. | ||
| * | ||
| * @param data - The state data from the previous step. | ||
| * @returns The migrated data. | ||
| */ | ||
| migrate(data: Input): Output | Promise<Output>; | ||
| /** | ||
| * Optional schema validating this step's input before `migrate` is called. Defaults | ||
| * to a generic JSON-shape check when omitted. | ||
| */ | ||
| inputSchema?: Struct<Input>; | ||
| /** | ||
| * Optional schema validating this step's output at runtime. | ||
| */ | ||
| outputSchema?: Struct<Output>; | ||
| }; | ||
| /** | ||
| * A chain of migration steps for evolving keyring serialized state across versions. | ||
| * | ||
| * Steps are versioned by position: the first `.add()` call produces version 1, the | ||
| * second version 2, and so on. Create one with {@link createMigrations}. | ||
| */ | ||
| export type MigrationChain<Data extends Json = Json> = { | ||
| /** | ||
| * The number of steps added so far. Since steps are versioned by position starting at | ||
| * 1, this also doubles as "the latest version" (use it in `serialize()`). | ||
| */ | ||
| readonly version: number; | ||
| /** | ||
| * Append a step to the chain. | ||
| * | ||
| * Returns a new chain typed to `Output`. It does not mutate the chain it's called on, | ||
| * so branching from a shared base chain is safe. | ||
| * | ||
| * `Input` defaults to the chain's current `Data` type. Providing `inputSchema` lets | ||
| * TypeScript infer a narrower `Input` (bounded to extend `Data`), so `migrate` | ||
| * receives a schema-typed argument when narrowing raw state into a specific shape, | ||
| * typically on a chain's first step, where `Data` is `Json`. | ||
| * | ||
| * @param step - The migration step to append. | ||
| * @returns A new chain whose data type is the step's `Output`. | ||
| */ | ||
| add<Input extends Data = Data, Output extends Json = Json>(step: MigrationStep<Input, Output>): MigrationChain<Output>; | ||
| /** | ||
| * Apply all pending steps to `state`. | ||
| * | ||
| * Handles both versioned state (wrapped in `{ version, data }` envelope) and | ||
| * unversioned legacy state (treated as version 0). | ||
| * | ||
| * @param state - The serialized keyring state (from vault or previous serialize). | ||
| * @returns The migrated state wrapped in a versioned envelope, plus a `migrated` | ||
| * flag. | ||
| * @throws If `state`'s version is newer than this chain's latest version, or if a | ||
| * step's `inputSchema`/`outputSchema` validation fails. | ||
| */ | ||
| apply(state: Json): Promise<MigrationResult<Data>>; | ||
| }; | ||
| /** | ||
| * Start a new, empty migration chain. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const migrations = createMigrations() | ||
| * .add({ migrate: (data) => ({ count: data.numberOfItems }) }) | ||
| * .add({ migrate: (data) => ({ ...data, createdAt: Date.now() }) }); // data typed as the first step's output, no cast | ||
| * | ||
| * const { data } = await migrations.apply(state); | ||
| * ``` | ||
| * @returns An empty chain, typed to accept `Json` as its first step's input. | ||
| */ | ||
| export declare function createMigrations(): MigrationChain<Json>; | ||
| //# sourceMappingURL=migration.d.cts.map |
| {"version":3,"file":"migration.d.cts","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B;AAG3D,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;EAG/B,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,IAAI,CACzD,KAAK,CAAC,OAAO,oBAAoB,CAAC,EAClC,MAAM,CACP,GAAG;IACF,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG;IAC7E,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EACxD,KAAK,EAAE,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,GACnC,KAAK,IAAI,cAAc,CAAC,KAAK,CAAC,CAEhC;AAgBD;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,CACvB,KAAK,SAAS,IAAI,GAAG,IAAI,EACzB,MAAM,SAAS,IAAI,GAAG,IAAI,IACxB;IACF;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI;IACrD;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;;OAaG;IACH,GAAG,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,MAAM,SAAS,IAAI,GAAG,IAAI,EACvD,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,GACjC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;CACpD,CAAC;AAgEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAAC,IAAI,CAAC,CAEvD"} |
| import type { Infer, Struct } from "@metamask/superstruct"; | ||
| import type { Json } from "@metamask/utils"; | ||
| /** | ||
| * Superstruct schema for the versioned state envelope. | ||
| */ | ||
| export declare const VersionedStateStruct: Struct<{ | ||
| data: Json; | ||
| version: number; | ||
| }, { | ||
| version: Struct<number, null>; | ||
| data: Struct<Json, unknown>; | ||
| }>; | ||
| /** | ||
| * Versioned state envelope wrapping the actual keyring data. | ||
| * | ||
| * After migrations are applied, state is always wrapped in this format. `serialize()` | ||
| * should produce this envelope so that subsequent `deserialize()` calls can detect the | ||
| * version. | ||
| */ | ||
| export type VersionedState<Data extends Json = Json> = Omit<Infer<typeof VersionedStateStruct>, 'data'> & { | ||
| data: Data; | ||
| }; | ||
| /** | ||
| * Return value of {@link MigrationChain.apply}. | ||
| * | ||
| * Extends {@link VersionedState} with a `migrated` flag that is `true` when at least | ||
| * one step was applied during the call. Callers can use this to detect that the | ||
| * in-memory state has been upgraded and schedule a persist so the new version is | ||
| * written to storage, even when no other state change happens in the session. | ||
| */ | ||
| export type MigrationResult<Data extends Json = Json> = VersionedState<Data> & { | ||
| migrated: boolean; | ||
| }; | ||
| /** | ||
| * Type guard to check if a value is a {@link VersionedState} envelope. | ||
| * | ||
| * @param state - The value to check. | ||
| * @returns `true` if the value is a versioned state envelope. | ||
| */ | ||
| export declare function isVersionedState<State extends Json = Json>(state: State | VersionedState<State>): state is VersionedState<State>; | ||
| /** | ||
| * A single migration step, added to a {@link MigrationChain} via `.add()`. | ||
| * | ||
| * `Input` is bound automatically to the chain's current data type when the step is | ||
| * passed to `.add()`, so `migrate` receives a correctly typed argument with no manual | ||
| * cast. | ||
| */ | ||
| export type MigrationStep<Input extends Json = Json, Output extends Json = Json> = { | ||
| /** | ||
| * Transform state from the previous step's output to this step's output. | ||
| * | ||
| * Receives the raw inner data (not the versioned envelope). May be sync or async to | ||
| * support complex operations like re-deriving data from secrets. | ||
| * | ||
| * @param data - The state data from the previous step. | ||
| * @returns The migrated data. | ||
| */ | ||
| migrate(data: Input): Output | Promise<Output>; | ||
| /** | ||
| * Optional schema validating this step's input before `migrate` is called. Defaults | ||
| * to a generic JSON-shape check when omitted. | ||
| */ | ||
| inputSchema?: Struct<Input>; | ||
| /** | ||
| * Optional schema validating this step's output at runtime. | ||
| */ | ||
| outputSchema?: Struct<Output>; | ||
| }; | ||
| /** | ||
| * A chain of migration steps for evolving keyring serialized state across versions. | ||
| * | ||
| * Steps are versioned by position: the first `.add()` call produces version 1, the | ||
| * second version 2, and so on. Create one with {@link createMigrations}. | ||
| */ | ||
| export type MigrationChain<Data extends Json = Json> = { | ||
| /** | ||
| * The number of steps added so far. Since steps are versioned by position starting at | ||
| * 1, this also doubles as "the latest version" (use it in `serialize()`). | ||
| */ | ||
| readonly version: number; | ||
| /** | ||
| * Append a step to the chain. | ||
| * | ||
| * Returns a new chain typed to `Output`. It does not mutate the chain it's called on, | ||
| * so branching from a shared base chain is safe. | ||
| * | ||
| * `Input` defaults to the chain's current `Data` type. Providing `inputSchema` lets | ||
| * TypeScript infer a narrower `Input` (bounded to extend `Data`), so `migrate` | ||
| * receives a schema-typed argument when narrowing raw state into a specific shape, | ||
| * typically on a chain's first step, where `Data` is `Json`. | ||
| * | ||
| * @param step - The migration step to append. | ||
| * @returns A new chain whose data type is the step's `Output`. | ||
| */ | ||
| add<Input extends Data = Data, Output extends Json = Json>(step: MigrationStep<Input, Output>): MigrationChain<Output>; | ||
| /** | ||
| * Apply all pending steps to `state`. | ||
| * | ||
| * Handles both versioned state (wrapped in `{ version, data }` envelope) and | ||
| * unversioned legacy state (treated as version 0). | ||
| * | ||
| * @param state - The serialized keyring state (from vault or previous serialize). | ||
| * @returns The migrated state wrapped in a versioned envelope, plus a `migrated` | ||
| * flag. | ||
| * @throws If `state`'s version is newer than this chain's latest version, or if a | ||
| * step's `inputSchema`/`outputSchema` validation fails. | ||
| */ | ||
| apply(state: Json): Promise<MigrationResult<Data>>; | ||
| }; | ||
| /** | ||
| * Start a new, empty migration chain. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const migrations = createMigrations() | ||
| * .add({ migrate: (data) => ({ count: data.numberOfItems }) }) | ||
| * .add({ migrate: (data) => ({ ...data, createdAt: Date.now() }) }); // data typed as the first step's output, no cast | ||
| * | ||
| * const { data } = await migrations.apply(state); | ||
| * ``` | ||
| * @returns An empty chain, typed to accept `Json` as its first step's input. | ||
| */ | ||
| export declare function createMigrations(): MigrationChain<Json>; | ||
| //# sourceMappingURL=migration.d.mts.map |
| {"version":3,"file":"migration.d.mts","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B;AAG3D,OAAO,KAAK,EAAE,IAAI,EAAE,wBAAwB;AAE5C;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;EAG/B,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,IAAI,CACzD,KAAK,CAAC,OAAO,oBAAoB,CAAC,EAClC,MAAM,CACP,GAAG;IACF,IAAI,EAAE,IAAI,CAAC;CACZ,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,eAAe,CAAC,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG;IAC7E,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EACxD,KAAK,EAAE,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,GACnC,KAAK,IAAI,cAAc,CAAC,KAAK,CAAC,CAEhC;AAgBD;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,CACvB,KAAK,SAAS,IAAI,GAAG,IAAI,EACzB,MAAM,SAAS,IAAI,GAAG,IAAI,IACxB;IACF;;;;;;;;OAQG;IACH,OAAO,CAAC,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;CAC/B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,cAAc,CAAC,IAAI,SAAS,IAAI,GAAG,IAAI,IAAI;IACrD;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;;;;OAaG;IACH,GAAG,CAAC,KAAK,SAAS,IAAI,GAAG,IAAI,EAAE,MAAM,SAAS,IAAI,GAAG,IAAI,EACvD,IAAI,EAAE,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,GACjC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;CACpD,CAAC;AAgEF;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAAC,IAAI,CAAC,CAEvD"} |
| import { assert, integer, is, object } from "@metamask/superstruct"; | ||
| import { JsonStruct } from "@metamask/utils"; | ||
| /** | ||
| * Superstruct schema for the versioned state envelope. | ||
| */ | ||
| export const VersionedStateStruct = object({ | ||
| version: integer(), | ||
| data: JsonStruct, | ||
| }); | ||
| /** | ||
| * Type guard to check if a value is a {@link VersionedState} envelope. | ||
| * | ||
| * @param state - The value to check. | ||
| * @returns `true` if the value is a versioned state envelope. | ||
| */ | ||
| export function isVersionedState(state) { | ||
| return is(state, VersionedStateStruct); | ||
| } | ||
| /** | ||
| * Get the version and data from state, treating unversioned state as version 0. | ||
| * | ||
| * @param state - The state to check. | ||
| * @returns The version and data. | ||
| */ | ||
| function getVersionAndData(state) { | ||
| return isVersionedState(state) | ||
| ? { version: state.version, data: state.data } | ||
| : { version: 0, data: state }; | ||
| } | ||
| /** | ||
| * Apply the pending steps of a chain to `state`. | ||
| * | ||
| * Implements {@link MigrationChain.apply} for the chain built from `steps`. | ||
| * | ||
| * @param steps - All steps of the chain. | ||
| * @param state - The serialized keyring state. | ||
| * @returns The migrated state wrapped in a versioned envelope, plus a `migrated` flag. | ||
| */ | ||
| async function applySteps(steps, state) { | ||
| const latestVersion = steps.length; | ||
| const { version, data: initialData } = getVersionAndData(state); | ||
| if (version < 0) { | ||
| throw new Error(`State version ${version} is invalid; it cannot be negative`); | ||
| } | ||
| if (version > latestVersion) { | ||
| throw new Error(`State version ${version} is newer than the latest migration version ${latestVersion}`); | ||
| } | ||
| const pendingSteps = steps.slice(version); | ||
| let data = initialData; | ||
| for (const step of pendingSteps) { | ||
| assert(data, step.inputSchema ?? JsonStruct); | ||
| data = await step.migrate(data); | ||
| assert(data, step.outputSchema ?? JsonStruct); | ||
| } | ||
| return { | ||
| version: latestVersion, | ||
| data, | ||
| migrated: pendingSteps.length > 0, | ||
| }; | ||
| } | ||
| /** | ||
| * Build a {@link MigrationChain} wrapping the given internal steps. | ||
| * | ||
| * @param steps - The steps accumulated so far. | ||
| * @returns A chain exposing `add`, `version`, and `apply`. | ||
| */ | ||
| function buildChain(steps) { | ||
| return { | ||
| version: steps.length, | ||
| add: (step) => buildChain([...steps, step]), | ||
| apply: async (state) => applySteps(steps, state), | ||
| }; | ||
| } | ||
| /** | ||
| * Start a new, empty migration chain. | ||
| * | ||
| * @example | ||
| * ```typescript | ||
| * const migrations = createMigrations() | ||
| * .add({ migrate: (data) => ({ count: data.numberOfItems }) }) | ||
| * .add({ migrate: (data) => ({ ...data, createdAt: Date.now() }) }); // data typed as the first step's output, no cast | ||
| * | ||
| * const { data } = await migrations.apply(state); | ||
| * ``` | ||
| * @returns An empty chain, typed to accept `Json` as its first step's input. | ||
| */ | ||
| export function createMigrations() { | ||
| return buildChain([]); | ||
| } | ||
| //# sourceMappingURL=migration.mjs.map |
| {"version":3,"file":"migration.mjs","sourceRoot":"","sources":["../src/migration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,8BAA8B;AACpE,OAAO,EAAE,UAAU,EAAE,wBAAwB;AAG7C;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC;IACzC,OAAO,EAAE,OAAO,EAAE;IAClB,IAAI,EAAE,UAAU;CACjB,CAAC,CAAC;AA4BH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAoC;IAEpC,OAAO,EAAE,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;AACzC,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CACxB,KAAoC;IAEpC,OAAO,gBAAgB,CAAC,KAAK,CAAC;QAC5B,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;QAC9C,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAClC,CAAC;AA8ED;;;;;;;;GAQG;AACH,KAAK,UAAU,UAAU,CACvB,KAA+B,EAC/B,KAAW;IAEX,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAAC;IACnC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IAEhE,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,iBAAiB,OAAO,oCAAoC,CAC7D,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,iBAAiB,OAAO,+CAA+C,aAAa,EAAE,CACvF,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,IAAI,GAAG,WAAW,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,IAAI,UAAU,CAAC,CAAC;QAC7C,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC;IAChD,CAAC;IAED,OAAO;QACL,OAAO,EAAE,aAAa;QACtB,IAAI;QACJ,QAAQ,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC;KACT,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CACjB,KAA+B;IAE/B,OAAO;QACL,OAAO,EAAE,KAAK,CAAC,MAAM;QACrB,GAAG,EAAE,CACH,IAAkC,EAClC,EAAE,CAAC,UAAU,CAAS,CAAC,GAAG,KAAK,EAAE,IAAgC,CAAC,CAAC;QACrE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,CAAO,KAAK,EAAE,KAAK,CAAC;KACvD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,UAAU,CAAO,EAAE,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["import type { Infer, Struct } from '@metamask/superstruct';\nimport { assert, integer, is, object } from '@metamask/superstruct';\nimport { JsonStruct } from '@metamask/utils';\nimport type { Json } from '@metamask/utils';\n\n/**\n * Superstruct schema for the versioned state envelope.\n */\nexport const VersionedStateStruct = object({\n version: integer(),\n data: JsonStruct,\n});\n\n/**\n * Versioned state envelope wrapping the actual keyring data.\n *\n * After migrations are applied, state is always wrapped in this format. `serialize()`\n * should produce this envelope so that subsequent `deserialize()` calls can detect the\n * version.\n */\nexport type VersionedState<Data extends Json = Json> = Omit<\n Infer<typeof VersionedStateStruct>,\n 'data'\n> & {\n data: Data;\n};\n\n/**\n * Return value of {@link MigrationChain.apply}.\n *\n * Extends {@link VersionedState} with a `migrated` flag that is `true` when at least\n * one step was applied during the call. Callers can use this to detect that the\n * in-memory state has been upgraded and schedule a persist so the new version is\n * written to storage, even when no other state change happens in the session.\n */\nexport type MigrationResult<Data extends Json = Json> = VersionedState<Data> & {\n migrated: boolean;\n};\n\n/**\n * Type guard to check if a value is a {@link VersionedState} envelope.\n *\n * @param state - The value to check.\n * @returns `true` if the value is a versioned state envelope.\n */\nexport function isVersionedState<State extends Json = Json>(\n state: State | VersionedState<State>,\n): state is VersionedState<State> {\n return is(state, VersionedStateStruct);\n}\n\n/**\n * Get the version and data from state, treating unversioned state as version 0.\n *\n * @param state - The state to check.\n * @returns The version and data.\n */\nfunction getVersionAndData<State extends Json = Json>(\n state: State | VersionedState<State>,\n): VersionedState<State> {\n return isVersionedState(state)\n ? { version: state.version, data: state.data }\n : { version: 0, data: state };\n}\n\n/**\n * A single migration step, added to a {@link MigrationChain} via `.add()`.\n *\n * `Input` is bound automatically to the chain's current data type when the step is\n * passed to `.add()`, so `migrate` receives a correctly typed argument with no manual\n * cast.\n */\nexport type MigrationStep<\n Input extends Json = Json,\n Output extends Json = Json,\n> = {\n /**\n * Transform state from the previous step's output to this step's output.\n *\n * Receives the raw inner data (not the versioned envelope). May be sync or async to\n * support complex operations like re-deriving data from secrets.\n *\n * @param data - The state data from the previous step.\n * @returns The migrated data.\n */\n migrate(data: Input): Output | Promise<Output>;\n /**\n * Optional schema validating this step's input before `migrate` is called. Defaults\n * to a generic JSON-shape check when omitted.\n */\n inputSchema?: Struct<Input>;\n /**\n * Optional schema validating this step's output at runtime.\n */\n outputSchema?: Struct<Output>;\n};\n\n/**\n * A chain of migration steps for evolving keyring serialized state across versions.\n *\n * Steps are versioned by position: the first `.add()` call produces version 1, the\n * second version 2, and so on. Create one with {@link createMigrations}.\n */\nexport type MigrationChain<Data extends Json = Json> = {\n /**\n * The number of steps added so far. Since steps are versioned by position starting at\n * 1, this also doubles as \"the latest version\" (use it in `serialize()`).\n */\n readonly version: number;\n /**\n * Append a step to the chain.\n *\n * Returns a new chain typed to `Output`. It does not mutate the chain it's called on,\n * so branching from a shared base chain is safe.\n *\n * `Input` defaults to the chain's current `Data` type. Providing `inputSchema` lets\n * TypeScript infer a narrower `Input` (bounded to extend `Data`), so `migrate`\n * receives a schema-typed argument when narrowing raw state into a specific shape,\n * typically on a chain's first step, where `Data` is `Json`.\n *\n * @param step - The migration step to append.\n * @returns A new chain whose data type is the step's `Output`.\n */\n add<Input extends Data = Data, Output extends Json = Json>(\n step: MigrationStep<Input, Output>,\n ): MigrationChain<Output>;\n /**\n * Apply all pending steps to `state`.\n *\n * Handles both versioned state (wrapped in `{ version, data }` envelope) and\n * unversioned legacy state (treated as version 0).\n *\n * @param state - The serialized keyring state (from vault or previous serialize).\n * @returns The migrated state wrapped in a versioned envelope, plus a `migrated`\n * flag.\n * @throws If `state`'s version is newer than this chain's latest version, or if a\n * step's `inputSchema`/`outputSchema` validation fails.\n */\n apply(state: Json): Promise<MigrationResult<Data>>;\n};\n\n/**\n * Apply the pending steps of a chain to `state`.\n *\n * Implements {@link MigrationChain.apply} for the chain built from `steps`.\n *\n * @param steps - All steps of the chain.\n * @param state - The serialized keyring state.\n * @returns The migrated state wrapped in a versioned envelope, plus a `migrated` flag.\n */\nasync function applySteps<Data extends Json>(\n steps: readonly MigrationStep[],\n state: Json,\n): Promise<MigrationResult<Data>> {\n const latestVersion = steps.length;\n const { version, data: initialData } = getVersionAndData(state);\n\n if (version < 0) {\n throw new Error(\n `State version ${version} is invalid; it cannot be negative`,\n );\n }\n\n if (version > latestVersion) {\n throw new Error(\n `State version ${version} is newer than the latest migration version ${latestVersion}`,\n );\n }\n\n const pendingSteps = steps.slice(version);\n let data = initialData;\n\n for (const step of pendingSteps) {\n assert(data, step.inputSchema ?? JsonStruct);\n data = await step.migrate(data);\n assert(data, step.outputSchema ?? JsonStruct);\n }\n\n return {\n version: latestVersion,\n data,\n migrated: pendingSteps.length > 0,\n } as MigrationResult<Data>;\n}\n\n/**\n * Build a {@link MigrationChain} wrapping the given internal steps.\n *\n * @param steps - The steps accumulated so far.\n * @returns A chain exposing `add`, `version`, and `apply`.\n */\nfunction buildChain<Data extends Json>(\n steps: readonly MigrationStep[],\n): MigrationChain<Data> {\n return {\n version: steps.length,\n add: <Input extends Data, Output extends Json>(\n step: MigrationStep<Input, Output>,\n ) => buildChain<Output>([...steps, step as unknown as MigrationStep]),\n apply: async (state) => applySteps<Data>(steps, state),\n };\n}\n\n/**\n * Start a new, empty migration chain.\n *\n * @example\n * ```typescript\n * const migrations = createMigrations()\n * .add({ migrate: (data) => ({ count: data.numberOfItems }) })\n * .add({ migrate: (data) => ({ ...data, createdAt: Date.now() }) }); // data typed as the first step's output, no cast\n *\n * const { data } = await migrations.apply(state);\n * ```\n * @returns An empty chain, typed to accept `Json` as its first step's input.\n */\nexport function createMigrations(): MigrationChain<Json> {\n return buildChain<Json>([]);\n}\n"]} |
+15
-1
@@ -10,2 +10,15 @@ # Changelog | ||
| ## [2.3.0] | ||
| ### Added | ||
| - Add keyring state migration framework ([#505](https://github.com/MetaMask/accounts/pull/505)) | ||
| - Use `createMigrations().add(...)` to build a chain of versioned migration steps, and `.apply(state)` to migrate the internal state of keyrings | ||
| ### Changed | ||
| - Bump `@metamask/keyring-api` from `^23.2.0` to `^23.6.0` ([#569](https://github.com/MetaMask/accounts/pull/569), [#583](https://github.com/MetaMask/accounts/pull/583), [#587](https://github.com/MetaMask/accounts/pull/587), [#600](https://github.com/MetaMask/accounts/pull/600)) | ||
| - Bump `@metamask/superstruct` from `^3.1.0` to `^3.4.1` ([#580](https://github.com/MetaMask/accounts/pull/580)), ([#577](https://github.com/MetaMask/accounts/pull/577)) | ||
| - Bump `@metamask/keyring-utils` from `^3.3.1` to `^4.0.0` ([#600](https://github.com/MetaMask/accounts/pull/600)) | ||
| ## [2.2.0] | ||
@@ -92,3 +105,4 @@ | ||
| [Unreleased]: https://github.com/MetaMask/accounts/compare/@metamask/keyring-sdk@2.2.0...HEAD | ||
| [Unreleased]: https://github.com/MetaMask/accounts/compare/@metamask/keyring-sdk@2.3.0...HEAD | ||
| [2.3.0]: https://github.com/MetaMask/accounts/compare/@metamask/keyring-sdk@2.2.0...@metamask/keyring-sdk@2.3.0 | ||
| [2.2.0]: https://github.com/MetaMask/accounts/compare/@metamask/keyring-sdk@2.1.1...@metamask/keyring-sdk@2.2.0 | ||
@@ -95,0 +109,0 @@ [2.1.1]: https://github.com/MetaMask/accounts/compare/@metamask/keyring-sdk@2.1.0...@metamask/keyring-sdk@2.1.1 |
+1
-0
@@ -18,4 +18,5 @@ "use strict"; | ||
| __exportStar(require("./keyring-account-registry.cjs"), exports); | ||
| __exportStar(require("./migration.cjs"), exports); | ||
| __exportStar(require("./mnemonic.cjs"), exports); | ||
| __exportStar(require("./eth/index.cjs"), exports); | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA2C;AAC3C,iDAA2B;AAC3B,kDAAsB","sourcesContent":["export * from './keyring-account-registry';\nexport * from './mnemonic';\nexport * from './eth';\n"]} | ||
| {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA2C;AAC3C,kDAA4B;AAC5B,iDAA2B;AAC3B,kDAAsB","sourcesContent":["export * from './keyring-account-registry';\nexport * from './migration';\nexport * from './mnemonic';\nexport * from './eth';\n"]} |
+1
-0
| export * from "./keyring-account-registry.cjs"; | ||
| export * from "./migration.cjs"; | ||
| export * from "./mnemonic.cjs"; | ||
| export * from "./eth/index.cjs"; | ||
| //# sourceMappingURL=index.d.cts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+CAA2C;AAC3C,+BAA2B;AAC3B,gCAAsB"} | ||
| {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+CAA2C;AAC3C,gCAA4B;AAC5B,+BAA2B;AAC3B,gCAAsB"} |
+1
-0
| export * from "./keyring-account-registry.mjs"; | ||
| export * from "./migration.mjs"; | ||
| export * from "./mnemonic.mjs"; | ||
| export * from "./eth/index.mjs"; | ||
| //# sourceMappingURL=index.d.mts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+CAA2C;AAC3C,+BAA2B;AAC3B,gCAAsB"} | ||
| {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+CAA2C;AAC3C,gCAA4B;AAC5B,+BAA2B;AAC3B,gCAAsB"} |
+1
-0
| export * from "./keyring-account-registry.mjs"; | ||
| export * from "./migration.mjs"; | ||
| export * from "./mnemonic.mjs"; | ||
| export * from "./eth/index.mjs"; | ||
| //# sourceMappingURL=index.mjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+CAA2C;AAC3C,+BAA2B;AAC3B,gCAAsB","sourcesContent":["export * from './keyring-account-registry';\nexport * from './mnemonic';\nexport * from './eth';\n"]} | ||
| {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+CAA2C;AAC3C,gCAA4B;AAC5B,+BAA2B;AAC3B,gCAAsB","sourcesContent":["export * from './keyring-account-registry';\nexport * from './migration';\nexport * from './mnemonic';\nexport * from './eth';\n"]} |
+4
-4
| { | ||
| "name": "@metamask/keyring-sdk", | ||
| "version": "2.2.0", | ||
| "version": "2.3.0", | ||
| "description": "MetaMask Keyring SDK", | ||
@@ -71,6 +71,6 @@ "keywords": [ | ||
| "@metamask/eth-sig-util": "^8.2.0", | ||
| "@metamask/keyring-api": "^23.2.0", | ||
| "@metamask/keyring-utils": "^3.3.1", | ||
| "@metamask/keyring-api": "^23.6.0", | ||
| "@metamask/keyring-utils": "^4.0.0", | ||
| "@metamask/scure-bip39": "^2.1.1", | ||
| "@metamask/superstruct": "^3.1.0", | ||
| "@metamask/superstruct": "^3.4.1", | ||
| "@metamask/utils": "^11.11.0", | ||
@@ -77,0 +77,0 @@ "async-mutex": "^0.5.0", |
335129
13.24%109
7.92%2039
9.98%- Removed
Updated