Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/snaps-utils/coverage.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"branches": 99.75,
"functions": 98.94,
"lines": 99.62,
"statements": 96.99
"lines": 98.55,
"statements": 97.03
}
4 changes: 2 additions & 2 deletions packages/snaps-utils/src/eval-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import 'ses/lockdown';

import { readFileSync } from 'fs';

import type { HandlerType } from './handler-types';
import { SNAP_EXPORT_NAMES } from './handler-types';
import type { HandlerType } from './handlers';
import { SNAP_EXPORT_NAMES } from './handlers';
import { generateMockEndowments } from './mock';

declare let lockdown: any, Compartment: any;
Expand Down
13 changes: 0 additions & 13 deletions packages/snaps-utils/src/handlers.test.ts

This file was deleted.

34 changes: 34 additions & 0 deletions packages/snaps-utils/src/handlers/exports.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { SNAP_EXPORT_NAMES, SNAP_EXPORTS } from './exports';

describe('SNAP_EXPORTS', () => {
describe('validator', () => {
it.each(Object.values(SNAP_EXPORTS))(
'validates that the snap export is a function',
({ validator }) => {
expect(validator(() => undefined)).toBe(true);
expect(validator('')).toBe(false);
},
);
});
});

describe('SNAP_EXPORT_NAMES', () => {
it('is an array of all handler types', () => {
expect(SNAP_EXPORT_NAMES).toStrictEqual([
'onRpcRequest',
'onSignature',
'onTransaction',
'onCronjob',
'onInstall',
'onUpdate',
'onNameLookup',
'onKeyringRequest',
'onHomePage',
'onSettingsPage',
'onUserInput',
'onAssetsLookup',
'onAssetsConversion',
'onProtocolRequest',
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,8 @@ import type {
OnUpdateHandler,
OnUserInputHandler,
} from '@metamask/snaps-sdk';
import { ComponentOrElementStruct, SeverityLevel } from '@metamask/snaps-sdk';
import {
assign,
literal,
nullable,
object,
optional,
string,
array,
size,
union,
} from '@metamask/superstruct';

import type { SnapHandler } from './handler-types';
import { HandlerType } from './handler-types';

export type SnapRpcHookArgs = {
origin: string;
handler: HandlerType;
request: Record<string, unknown>;
};
import { HandlerType } from './types';

export const SNAP_EXPORTS = {
[HandlerType.OnRpcRequest]: {
Expand Down Expand Up @@ -141,89 +122,4 @@ export const SNAP_EXPORTS = {
},
} as const;

export const OnTransactionSeverityResponseStruct = object({
severity: optional(literal(SeverityLevel.Critical)),
});

export const OnTransactionResponseWithIdStruct = assign(
OnTransactionSeverityResponseStruct,
object({
id: string(),
}),
);

export const OnTransactionResponseWithContentStruct = assign(
OnTransactionSeverityResponseStruct,
object({
content: ComponentOrElementStruct,
}),
);

export const OnTransactionResponseStruct = nullable(
union([
OnTransactionResponseWithContentStruct,
OnTransactionResponseWithIdStruct,
]),
);

export const OnSignatureResponseStruct = OnTransactionResponseStruct;

export const OnHomePageResponseWithContentStruct = object({
content: ComponentOrElementStruct,
});

export const OnHomePageResponseWithIdStruct = object({
id: string(),
});

export const OnHomePageResponseStruct = union([
OnHomePageResponseWithContentStruct,
OnHomePageResponseWithIdStruct,
]);

export const OnSettingsPageResponseStruct = OnHomePageResponseStruct;

export const AddressResolutionStruct = object({
protocol: string(),
resolvedDomain: string(),
});

export const DomainResolutionStruct = object({
protocol: string(),
resolvedAddress: string(),
domainName: string(),
});

export const AddressResolutionResponseStruct = object({
resolvedDomains: size(array(AddressResolutionStruct), 1, Infinity),
});

export const DomainResolutionResponseStruct = object({
resolvedAddresses: size(array(DomainResolutionStruct), 1, Infinity),
});

export const OnNameLookupResponseStruct = nullable(
union([AddressResolutionResponseStruct, DomainResolutionResponseStruct]),
);

/**
* Utility type for getting the handler function type from a handler type.
*/
export type HandlerFunction<Type extends SnapHandler> =
Type['validator'] extends (snapExport: unknown) => snapExport is infer Handler
? Handler
: never;

/**
* All the function-based handlers that a snap can implement.
*/
export type SnapFunctionExports = {
[Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<
(typeof SNAP_EXPORTS)[Key]
>;
};

/**
* All handlers that a snap can implement.
*/
export type SnapExports = SnapFunctionExports;
export const SNAP_EXPORT_NAMES = Object.values(HandlerType);
15 changes: 15 additions & 0 deletions packages/snaps-utils/src/handlers/home-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ComponentOrElementStruct } from '@metamask/snaps-sdk';
import { object, string, union } from '@metamask/superstruct';

export const OnHomePageResponseWithContentStruct = object({
content: ComponentOrElementStruct,
});

export const OnHomePageResponseWithIdStruct = object({
id: string(),
});

export const OnHomePageResponseStruct = union([
OnHomePageResponseWithContentStruct,
OnHomePageResponseWithIdStruct,
]);
2 changes: 2 additions & 0 deletions packages/snaps-utils/src/handlers/index.executionenv.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { HandlerType, type SnapHandler } from './types';
export { SNAP_EXPORT_NAMES } from './exports';
7 changes: 7 additions & 0 deletions packages/snaps-utils/src/handlers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from './exports';
export * from './home-page';
export * from './name-lookup';
export * from './settings-page';
export * from './signature';
export * from './transaction';
export * from './types';
31 changes: 31 additions & 0 deletions packages/snaps-utils/src/handlers/name-lookup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {
array,
nullable,
object,
size,
string,
union,
} from '@metamask/superstruct';

export const AddressResolutionStruct = object({
protocol: string(),
resolvedDomain: string(),
});

export const DomainResolutionStruct = object({
protocol: string(),
resolvedAddress: string(),
domainName: string(),
});

export const AddressResolutionResponseStruct = object({
resolvedDomains: size(array(AddressResolutionStruct), 1, Infinity),
});

export const DomainResolutionResponseStruct = object({
resolvedAddresses: size(array(DomainResolutionStruct), 1, Infinity),
});

export const OnNameLookupResponseStruct = nullable(
union([AddressResolutionResponseStruct, DomainResolutionResponseStruct]),
);
3 changes: 3 additions & 0 deletions packages/snaps-utils/src/handlers/settings-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { OnHomePageResponseStruct } from './home-page';

export const OnSettingsPageResponseStruct = OnHomePageResponseStruct;
3 changes: 3 additions & 0 deletions packages/snaps-utils/src/handlers/signature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { OnTransactionResponseStruct } from './transaction';

export const OnSignatureResponseStruct = OnTransactionResponseStruct;
35 changes: 35 additions & 0 deletions packages/snaps-utils/src/handlers/transaction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ComponentOrElementStruct, SeverityLevel } from '@metamask/snaps-sdk';
import {
literal,
object,
optional,
string,
assign,
nullable,
union,
} from '@metamask/superstruct';

export const OnTransactionSeverityResponseStruct = object({
severity: optional(literal(SeverityLevel.Critical)),
});

export const OnTransactionResponseWithIdStruct = assign(
OnTransactionSeverityResponseStruct,
object({
id: string(),
}),
);

export const OnTransactionResponseWithContentStruct = assign(
OnTransactionSeverityResponseStruct,
object({
content: ComponentOrElementStruct,
}),
);

export const OnTransactionResponseStruct = nullable(
union([
OnTransactionResponseWithContentStruct,
OnTransactionResponseWithIdStruct,
]),
);
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
import type { SNAP_EXPORTS } from './exports';

export type SnapRpcHookArgs = {
origin: string;
handler: HandlerType;
request: Record<string, unknown>;
};

/**
* Utility type for getting the handler function type from a handler type.
*/
export type HandlerFunction<Type extends SnapHandler> =
Type['validator'] extends (snapExport: unknown) => snapExport is infer Handler
? Handler
: never;

/**
* All the function-based handlers that a snap can implement.
*/
export type SnapFunctionExports = {
[Key in keyof typeof SNAP_EXPORTS]?: HandlerFunction<
(typeof SNAP_EXPORTS)[Key]
>;
};

/**
* All handlers that a snap can implement.
*/
export type SnapExports = SnapFunctionExports;

export enum HandlerType {
OnRpcRequest = 'onRpcRequest',
OnSignature = 'onSignature',
Expand Down Expand Up @@ -38,5 +68,3 @@ export type SnapHandler = {
*/
validator: (snapExport: unknown) => boolean;
};

export const SNAP_EXPORT_NAMES = Object.values(HandlerType);
1 change: 0 additions & 1 deletion packages/snaps-utils/src/index.executionenv.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Special entrypoint for execution environments for bundle sizing reasons
export * from './errors';
export * from './handlers';
export * from './handler-types';
export * from './iframe';
export * from './logging';
export * from './types';
1 change: 0 additions & 1 deletion packages/snaps-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export * from './derivation-paths';
export * from './entropy';
export * from './errors';
export * from './handlers';
export * from './handler-types';
export * from './iframe';
export * from './json';
export * from './json-rpc';
Expand Down
Loading