-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathConfirmationHandler.ts
More file actions
177 lines (164 loc) · 5.42 KB
/
Copy pathConfirmationHandler.ts
File metadata and controls
177 lines (164 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import { SolMethod } from '@metamask/keyring-api';
import { assert, union } from '@metamask/superstruct';
import type { SolanaKeyringAccount } from '../../../entities';
import { render as renderConfirmSignIn } from '../../../features/confirmation/views/ConfirmSignIn/render';
import { render as renderConfirmSignMessage } from '../../../features/confirmation/views/ConfirmSignMessage/render';
import {
DEFAULT_CONFIRMATION_CONTEXT,
render as renderConfirmTransactionRequest,
} from '../../../features/confirmation/views/ConfirmTransactionRequest/render';
import { ScheduleBackgroundEventMethod } from '../../handlers/onCronjob/backgroundEvents/ScheduleBackgroundEventMethod';
import type { SolanaKeyringRequest } from '../../handlers/onKeyringRequest/structs';
import {
SolanaSignAndSendTransactionRequestStruct,
SolanaSignTransactionRequestStruct,
} from '../wallet/structs';
/**
* Wraps the confirmation logic for the keyring API.
*
* It is responsible for rendering the confirmation UI and handling the side effects that need to happen when the transaction is shown in confirmation UI.
*/
export class ConfirmationHandler {
/**
* Handles the confirmation of a request, based on the method of the request.
* Renders the appropriate confirmation UI for the request, and returns whether the request was confirmed.
*
* @param request - The request to confirm.
* @param account - The account that the request is for.
* @returns Whether the request was confirmed.
*/
async handleKeyringRequest(
request: SolanaKeyringRequest,
account: SolanaKeyringAccount,
): Promise<boolean> {
const {
request: { method },
} = request;
switch (method) {
case SolMethod.SignAndSendTransaction:
return this.#handleConfirmTransactionRequest(request, account);
case SolMethod.SignTransaction:
return this.#handleConfirmTransactionRequest(request, account);
case SolMethod.SignMessage:
return this.#handleConfirmSignMessage(request, account);
case SolMethod.SignIn:
return this.#handleConfirmSignIn(request, account);
default:
throw new Error(`Unsupported method: ${method}`);
}
}
/**
* Handles the confirmation whenever a transaction needs to be signed:
* - Sign and send transaction request.
* - Sign transaction request.
*
* @param request - The request to confirm.
* @param account - The account that the request is for.
* @returns Whether the request was confirmed.
*/
async #handleConfirmTransactionRequest(
request: SolanaKeyringRequest,
account: SolanaKeyringAccount,
): Promise<boolean> {
assert(
request.request,
union([
SolanaSignAndSendTransactionRequestStruct,
SolanaSignTransactionRequestStruct,
]),
);
const {
request: {
method,
params: { transaction: base64EncodedTransaction },
},
scope,
account: accountId,
} = request;
// Trigger the side effects that need to happen when the transaction is shown in confirmation UI
await snap.request({
method: 'snap_scheduleBackgroundEvent',
params: {
duration: 'PT1S',
request: {
method: ScheduleBackgroundEventMethod.OnTransactionAdded,
params: {
accountId,
base64EncodedTransaction,
scope,
},
},
},
});
const isConfirmed = await renderConfirmTransactionRequest({
...DEFAULT_CONFIRMATION_CONTEXT,
scope,
method,
origin: request.origin,
transaction: base64EncodedTransaction,
account,
});
if (isConfirmed) {
// Trigger the side effects that need to happen when the transaction is approved
await snap.request({
method: 'snap_scheduleBackgroundEvent',
params: {
duration: 'PT1S',
request: {
method: ScheduleBackgroundEventMethod.OnTransactionApproved,
params: {
accountId,
base64EncodedTransaction,
scope,
},
},
},
});
return true;
}
// Trigger the side effects that need to happen when the transaction is rejected
await snap.request({
method: 'snap_scheduleBackgroundEvent',
params: {
duration: 'PT1S',
request: {
method: ScheduleBackgroundEventMethod.OnTransactionRejected,
params: {
accountId,
base64EncodedTransaction,
scope,
},
},
},
});
return false;
}
/**
* Handles the confirmation of a sign message request.
*
* @param request - The request to confirm.
* @param account - The account that the request is for.
* @returns Whether the request was confirmed.
*/
async #handleConfirmSignMessage(
request: SolanaKeyringRequest,
account: SolanaKeyringAccount,
): Promise<boolean> {
const isConfirmed = await renderConfirmSignMessage(request, account);
return Boolean(isConfirmed);
}
/**
* Handles the confirmation of a sign in request.
*
* @param request - The request to confirm.
* @param account - The account that the request is for.
* @returns Whether the request was confirmed.
*/
async #handleConfirmSignIn(
request: SolanaKeyringRequest,
account: SolanaKeyringAccount,
): Promise<boolean> {
const isConfirmed = await renderConfirmSignIn(request, account);
return Boolean(isConfirmed);
}
}