@metamask/snaps-simulation
Version:
A simulation framework for MetaMask Snaps, enabling headless testing of Snaps in a controlled environment
255 lines • 10.7 kB
text/typescript
import type { ActionConstraint, EventConstraint } from "@metamask/base-controller";
import { Messenger } from "@metamask/base-controller";
import type { CryptographicFunctions } from "@metamask/key-tree";
import type { AbstractExecutionService } from "@metamask/snaps-controllers";
import type { TrackEventParams, AuxiliaryFileEncoding, Component, InterfaceState, InterfaceContext, SnapId, EntropySource, TraceRequest, EndTraceRequest, TraceContext } from "@metamask/snaps-sdk";
import type { FetchedSnapFiles, Snap } from "@metamask/snaps-utils";
import type { Json } from "@metamask/utils";
import type { RootControllerMessenger } from "./controllers.mjs";
import type { SnapHelpers } from "./helpers.mjs";
import type { SimulationOptions, SimulationUserOptions } from "./options.mjs";
import type { RunSagaFunction, Store } from "./store/index.mjs";
/**
* Options for the execution service, without the options that are shared
* between all execution services.
*
* @template Service - The type of the execution service, i.e., the class that
* creates the execution service.
*/
export type ExecutionServiceOptions<Service extends new (...args: any[]) => any> = Omit<ConstructorParameters<Service>[0], keyof ConstructorParameters<typeof AbstractExecutionService<unknown>>[0]>;
/**
* The options for running a Snap in a simulated environment.
*
* @property executionService - The execution service to use.
* @property executionServiceOptions - The options to use when creating the
* execution service, if any. This should only include options specific to the
* provided execution service.
* @property options - The simulation options.
* @template Service - The type of the execution service.
*/
export type InstallSnapOptions<Service extends new (...args: any[]) => InstanceType<typeof AbstractExecutionService<unknown>>> = ExecutionServiceOptions<Service> extends Record<string, never> ? {
executionService: Service;
executionServiceOptions?: ExecutionServiceOptions<Service>;
options?: SimulationUserOptions;
} : {
executionService: Service;
executionServiceOptions: ExecutionServiceOptions<Service>;
options?: SimulationUserOptions;
};
export type InstalledSnap = {
snapId: SnapId;
store: Store;
executionService: InstanceType<typeof AbstractExecutionService>;
controllerMessenger: Messenger<ActionConstraint, EventConstraint>;
runSaga: RunSagaFunction;
};
export type RestrictedMiddlewareHooks = {
/**
* A hook that returns the user's secret recovery phrase.
*
* @param source - The entropy source to get the mnemonic from.
* @returns The user's secret recovery phrase.
*/
getMnemonic: (source?: string | undefined) => Promise<Uint8Array>;
/**
* A hook that returns the seed derived from the user's secret recovery phrase.
*
* @param source - The entropy source to get the seed from.
* @returns The seed.
*/
getMnemonicSeed: (source?: string | undefined) => Promise<Uint8Array>;
/**
* A hook that returns whether the client is locked or not.
*
* @returns A boolean flag signaling whether the client is locked.
*/
getIsLocked: () => boolean;
/**
* Get the cryptographic functions to use for the client. This may return an
* empty object to fall back to the default cryptographic functions.
*
* @returns The cryptographic functions to use for the client.
*/
getClientCryptography: () => CryptographicFunctions;
};
export type PermittedMiddlewareHooks = {
/**
* A hook that gets whether the requesting origin has a given permission.
*
* @param permissionName - The name of the permission to check.
* @returns Whether the origin has the permission.
*/
hasPermission: (permissionName: string) => boolean;
/**
* A hook that returns the entropy sources available to the Snap.
*
* @returns The entropy sources available to the Snap.
*/
getEntropySources: () => EntropySource[];
/**
* A hook that returns a promise that resolves once the extension is unlocked.
*
* @param shouldShowUnlockRequest - Whether to show the unlock request.
* @returns A promise that resolves once the extension is unlocked.
*/
getUnlockPromise: (shouldShowUnlockRequest: boolean) => Promise<void>;
/**
* A hook that returns whether the client is locked or not.
*
* @returns A boolean flag signaling whether the client is locked.
*/
getIsLocked: () => boolean;
/**
* A hook that returns whether the client is active or not.
*
* @returns A boolean flag signaling whether the client is opened.
*/
getIsActive: () => boolean;
/**
* A hook that returns the Snap's auxiliary file for the given path. This hook
* is bound to the Snap ID.
*
* @param path - The path of the auxiliary file to get.
* @param encoding - The encoding to use when returning the file.
* @returns The Snap's auxiliary file for the given path.
*/
getSnapFile: (path: string, encoding: AuxiliaryFileEncoding) => Promise<string | null>;
/**
* A hook that gets the state of the Snap. This hook is bound to the Snap ID.
*
* @param encrypted - Whether to get the encrypted or unencrypted state.
* @returns The current state of the Snap.
*/
getSnapState: (encrypted: boolean) => Promise<Record<string, Json>>;
/**
* A hook that updates the state of the Snap. This hook is bound to the Snap
* ID.
*
* @param newState - The new state.
* @param encrypted - Whether to update the encrypted or unencrypted state.
*/
updateSnapState: (newState: Record<string, Json>, encrypted: boolean) => Promise<void>;
/**
* A hook that clears the state of the Snap. This hook is bound to the Snap
* ID.
*
* @param encrypted - Whether to clear the encrypted or unencrypted state.
*/
clearSnapState: (encrypted: boolean) => Promise<void>;
/**
* A hook that creates an interface for the Snap. This hook is bound to the
* Snap ID.
*
* @param content - The content of the interface.
* @param context - The context of the interface.
* @returns The ID of the created interface.
*/
createInterface: (content: Component, context?: InterfaceContext) => Promise<string>;
/**
* A hook that updates an interface for the Snap. This hook is bound to the
* Snap ID.
*
* @param id - The ID of the interface to update.
* @param content - The content of the interface.
*/
updateInterface: (id: string, content: Component) => Promise<void>;
/**
* A hook that gets the state of an interface for the Snap. This hook is bound
* to the Snap ID.
*
* @param id - The ID of the interface to get.
* @returns The state of the interface.
*/
getInterfaceState: (id: string) => InterfaceState;
/**
* A hook that gets the context of an interface for the Snap. This hook is
* bound to the Snap ID.
*
* @param id - The ID of the interface to get.
* @returns The context of the interface.
*/
getInterfaceContext: (id: string) => InterfaceContext | null;
/**
* A hook that resolves an interface for the Snap. This hook is bound to the
* Snap ID.
*
* @param id - The ID of the interface to resolve.
* @param value - The value to resolve the interface with.
*/
resolveInterface: (id: string, value: Json) => Promise<void>;
/**
* A hook that gets the Snap's metadata.
*
* @param snapId - The ID of the Snap to get.
* @returns The Snap's metadata.
*/
getSnap(snapId: string): Snap;
/**
* A hook that tracks an error.
*
* @param error - The error object containing error details and properties.
*/
trackError(error: Error): void;
/**
* A hook that tracks an event.
*
* @param event - The event object containing event details and properties.
*/
trackEvent(event: TrackEventParams['event']): void;
/**
* A hook that starts a performance trace.
*
* @param request - The trace request object containing trace details.
*/
startTrace(request: TraceRequest): TraceContext;
/**
* A hook that ends a performance trace.
*
* @param request - The trace request object containing trace details.
* @returns The trace data.
*/
endTrace(request: EndTraceRequest): void;
};
/**
* Install a Snap in a simulated environment. This will fetch the Snap files,
* create a Redux store, set up the controllers and JSON-RPC stack, register the
* Snap, and run the Snap code in the execution service.
*
* @param snapId - The ID of the Snap to install.
* @param options - The options to use when installing the Snap.
* @param options.executionService - The execution service to use.
* @param options.executionServiceOptions - The options to use when creating the
* execution service, if any. This should only include options specific to the
* provided execution service.
* @param options.options - The simulation options.
* @returns The installed Snap object.
* @template Service - The type of the execution service.
*/
export declare function installSnap<Service extends new (...args: any[]) => InstanceType<typeof AbstractExecutionService>>(snapId: SnapId, { executionService, executionServiceOptions, options: rawOptions, }?: Partial<InstallSnapOptions<Service>>): Promise<InstalledSnap & SnapHelpers>;
/**
* Get the hooks for the simulation.
*
* @param options - The simulation options.
* @returns The hooks for the simulation.
*/
export declare function getRestrictedHooks(options: SimulationOptions): RestrictedMiddlewareHooks;
/**
* Get the permitted hooks for the simulation.
*
* @param snapId - The ID of the Snap.
* @param snapFiles - The fetched Snap files.
* @param controllerMessenger - The controller messenger.
* @param runSaga - The run saga function.
* @returns The permitted hooks for the simulation.
*/
export declare function getPermittedHooks(snapId: SnapId, snapFiles: FetchedSnapFiles, controllerMessenger: RootControllerMessenger, runSaga: RunSagaFunction): PermittedMiddlewareHooks;
/**
* Register mocked action handlers.
*
* @param controllerMessenger - The controller messenger.
* @param runSaga - The run saga function.
* @param options - The simulation options.
* @param snapId - The ID of the Snap.
*/
export declare function registerActions(controllerMessenger: RootControllerMessenger, runSaga: RunSagaFunction, options: SimulationOptions, snapId: SnapId): void;
//# sourceMappingURL=simulation.d.mts.map