Skip to content

Commit 45be45e

Browse files
refactor: clean arch
1 parent 115d4c4 commit 45be45e

13 files changed

Lines changed: 75 additions & 68 deletions

File tree

packages/snap/openrpc.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"openrpc": "1.0.0",
2+
"openrpc": "1.2.4",
33
"info": {
4-
"title": "MetaMask Solana Wallet Snap JSON-RPC API",
4+
"title": "MetaMask Solana Wallet Snap",
55
"description": "JSON-RPC API of the MetaMask Solana Wallet Snap. This snap brings official Solana support to MetaMask. Create accounts, check balances, and use Solana dApps right from your MetaMask wallet. Simple, secure, and seamless.",
66
"version": "1.0.0",
77
"contact": {
@@ -21,7 +21,7 @@
2121
{
2222
"name": "client_signAndSendTransactionWithIntent",
2323
"summary": "Sign and send a transaction with verified intent",
24-
"description": "Allows the client (MetaMask) to request the snap to sign and send a transaction with verified intent.\n\n**Process:**\n\n1. **Verify Backend Signature** - Ensures the payload `{ intent, signature }` was signed by the trusted Swaps API\n2. **Match Transaction to Intent** - Verifies the transaction performs exactly what the intent describes\n3. **Sign Transaction** - If all validation pass, signs the transaction with the user's account specified in the intent\n4. **Send Transaction** - Sends the transaction to the Solana network",
24+
"description": "Allows the client (MetaMask) to request the snap to sign and send a transaction with verified intent.\n\n**Process:**\n\n1. **Verify Backend Signature** - Ensures that the payload **{ intent, signature }** was signed by the trusted Swaps API\n2. **Match Transaction to Intent** - Verifies that the transaction performs exactly what the intent describes\n3. **Sign Transaction** - If all validation pass, signs the transaction with the user's account specified in the intent\n4. **Send Transaction** - Sends the transaction to the Solana network",
2525
"params": [
2626
{
2727
"name": "intent",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type { Infer } from '@metamask/superstruct';
2+
import { object, string } from '@metamask/superstruct';
3+
import { CaipAssetTypeStruct } from '@metamask/utils';
4+
5+
import { UuidStruct } from '../validation/structs';
6+
7+
export const AssetAmountStruct = object({
8+
assetType: CaipAssetTypeStruct,
9+
amount: string(),
10+
});
11+
12+
export const IntentStruct = object({
13+
id: UuidStruct,
14+
timestamp: string(),
15+
accountId: string(),
16+
from: AssetAmountStruct,
17+
to: AssetAmountStruct,
18+
});
19+
20+
export type Intent = Infer<typeof IntentStruct>;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Intent';

packages/snap/src/core/handlers/onClientRequest/ClientRequestHandler.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ import { type Json, type JsonRpcRequest } from '@metamask/snaps-sdk';
22
import type { Struct } from '@metamask/superstruct';
33
import { assert, enums } from '@metamask/superstruct';
44

5+
import type {
6+
SignAndSendTransactionWithIntentUseCase,
7+
UseCase,
8+
} from '../../use-cases';
59
import type { ILogger } from '../../utils/logger';
6-
import type { SignAndSendTransactionWithIntentUseCase } from './SignAndSendTransactionWithIntentUseCase';
7-
import type { ClientRequestUseCase } from './types';
8-
import {
9-
ClientRequestMethod,
10-
SignAndSendTransactionWithIntentParamsStruct,
11-
} from './types';
10+
import { ClientRequestMethod } from './types';
11+
import { SignAndSendTransactionWithIntentParamsStruct } from './validation';
1212

1313
export class ClientRequestHandler {
14-
readonly #methodToUseCase: Record<ClientRequestMethod, ClientRequestUseCase>;
14+
readonly #methodToUseCase: Record<ClientRequestMethod, UseCase>;
1515

1616
readonly #methodToParamsStruct: Record<ClientRequestMethod, Struct<any, any>>;
1717

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
11
export * from './ClientRequestHandler';
2-
export * from './SignAndSendTransactionWithIntentUseCase';
32
export * from './types';
Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,3 @@
1-
import type { Infer } from '@metamask/superstruct';
2-
import { object, string } from '@metamask/superstruct';
3-
import type { Json } from '@metamask/utils';
4-
import { CaipAssetTypeStruct } from '@metamask/utils';
5-
6-
import { Base64Struct, UuidStruct } from '../../validation/structs';
7-
81
export enum ClientRequestMethod {
92
SignAndSendTransactionWithIntent = 'client_signAndSendTransactionWithIntent',
103
}
11-
12-
export const AssetAmountStruct = object({
13-
assetType: CaipAssetTypeStruct,
14-
amount: string(),
15-
});
16-
17-
export const IntentStruct = object({
18-
id: UuidStruct,
19-
timestamp: string(),
20-
accountId: string(),
21-
from: AssetAmountStruct,
22-
to: AssetAmountStruct,
23-
});
24-
25-
export const SignAndSendTransactionWithIntentParamsStruct = object({
26-
intent: IntentStruct,
27-
transaction: Base64Struct,
28-
signature: string(),
29-
});
30-
31-
export type AssetAmount = Infer<typeof AssetAmountStruct>;
32-
33-
export type Intent = Infer<typeof IntentStruct>;
34-
35-
export type SignAndSendTransactionWithIntentParams = Infer<
36-
typeof SignAndSendTransactionWithIntentParamsStruct
37-
>;
38-
39-
export type ClientRequestUseCase<TParams = any> = {
40-
execute: (params: TParams) => Promise<Json>;
41-
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { string, tuple } from '@metamask/superstruct';
2+
3+
import { IntentStruct } from '../../domain/Intent';
4+
import { Base64Struct } from '../../validation/structs';
5+
6+
export const SignAndSendTransactionWithIntentParamsStruct = tuple([
7+
IntentStruct, // params[0] = intent
8+
Base64Struct, // params[1] = transaction
9+
string(), // params[2] = signature
10+
]);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { SignAndSendTransactionWithIntentUseCase } from './SignAndSendTransactionWithIntentUseCase';
2+
3+
describe('SignAndSendTransactionWithIntentUseCase', () => {
4+
it('should be defined', () => {
5+
expect(SignAndSendTransactionWithIntentUseCase).toBeDefined();
6+
});
7+
});

packages/snap/src/core/handlers/onClientRequest/SignAndSendTransactionWithIntentUseCase.ts renamed to packages/snap/src/core/use-cases/SignAndSendTransactionWithIntent/SignAndSendTransactionWithIntentUseCase.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
import { SolMethod } from '@metamask/keyring-api';
22
import { parseCaipAssetType, type Json } from '@metamask/utils';
33

4+
import type { Intent } from '../../domain';
5+
import type { SolanaKeyring } from '../../handlers/onKeyringRequest/Keyring';
46
import type { WalletService } from '../../services/wallet/WalletService';
57
import type { ILogger } from '../../utils/logger';
6-
import type { SolanaKeyring } from '../onKeyringRequest/Keyring';
7-
import type {
8-
ClientRequestUseCase,
9-
Intent,
10-
SignAndSendTransactionWithIntentParams,
11-
} from './types';
12-
13-
export class SignAndSendTransactionWithIntentUseCase
14-
implements ClientRequestUseCase<SignAndSendTransactionWithIntentParams>
15-
{
8+
import type { UseCase } from '../UseCase';
9+
10+
export class SignAndSendTransactionWithIntentUseCase implements UseCase {
1611
#keyring: SolanaKeyring;
1712

1813
#walletService: WalletService;
@@ -34,16 +29,23 @@ export class SignAndSendTransactionWithIntentUseCase
3429
* This allows transactions to be executed without user confirmation
3530
* when they match a verified intent from the backend.
3631
*
37-
* @param params - The validated parameters containing intent, transaction, and signature.
32+
* @param intent - The validated intent.
33+
* @param transaction - The validated transaction.
34+
* @param signature - The validated signature.
3835
* @returns The transaction signature if successful.
3936
*/
40-
async execute(params: SignAndSendTransactionWithIntentParams): Promise<Json> {
37+
async execute(
38+
intent: Intent,
39+
transaction: string,
40+
signature: string,
41+
): Promise<Json> {
4142
this.#logger.log(
4243
'[SignAndSendTransactionWithIntentUseCase] execute',
43-
params,
44+
intent,
45+
transaction,
46+
signature,
4447
);
4548

46-
const { intent, transaction, signature } = params;
4749
const { accountId, from } = intent;
4850

4951
// Verify that the backend signed the payload { intent, transaction }
@@ -113,7 +115,7 @@ export class SignAndSendTransactionWithIntentUseCase
113115
* @returns True if the signature is valid.
114116
*/
115117
async #verifyBackendSignature(
116-
intent: any,
118+
intent: Intent,
117119
transaction: string,
118120
signature: string,
119121
): Promise<boolean> {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './SignAndSendTransactionWithIntentUseCase';

0 commit comments

Comments
 (0)