@avalabs/evm-module 0.0.23 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +1 -1
- package/dist/index.cjs +6 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/package.json +13 -8
- package/.turbo/turbo-build.log +0 -22
- package/.turbo/turbo-lint.log +0 -4
- package/.turbo/turbo-test.log +0 -119
- package/CHANGELOG.md +0 -174
- package/jest.config.js +0 -9
- package/src/constants.ts +0 -1
- package/src/contracts/openzeppelin/ERC1155.ts +0 -440
- package/src/contracts/openzeppelin/ERC20.ts +0 -330
- package/src/contracts/openzeppelin/ERC721.ts +0 -420
- package/src/contracts/openzeppelin/common.ts +0 -131
- package/src/contracts/openzeppelin/factories/ERC1155__factory.ts +0 -388
- package/src/contracts/openzeppelin/factories/ERC20__factory.ts +0 -353
- package/src/contracts/openzeppelin/factories/ERC721__factory.ts +0 -413
- package/src/contracts/openzeppelin/factories/index.ts +0 -6
- package/src/contracts/openzeppelin/index.ts +0 -10
- package/src/env.ts +0 -25
- package/src/handlers/eth-send-transaction/eth-send-transaction.test.ts +0 -572
- package/src/handlers/eth-send-transaction/eth-send-transaction.ts +0 -189
- package/src/handlers/eth-send-transaction/schema.test.ts +0 -240
- package/src/handlers/eth-send-transaction/schema.ts +0 -20
- package/src/handlers/eth-sign/eth-sign.test.ts +0 -359
- package/src/handlers/eth-sign/eth-sign.ts +0 -158
- package/src/handlers/eth-sign/schemas/eth-sign-typed-data.ts +0 -65
- package/src/handlers/eth-sign/schemas/eth-sign.ts +0 -9
- package/src/handlers/eth-sign/schemas/parse-request-params/fixture.ts +0 -47
- package/src/handlers/eth-sign/schemas/parse-request-params/parse-request-params.test.ts +0 -284
- package/src/handlers/eth-sign/schemas/parse-request-params/parse-request-params.ts +0 -94
- package/src/handlers/eth-sign/schemas/personal-sign.ts +0 -12
- package/src/handlers/eth-sign/schemas/shared.ts +0 -5
- package/src/handlers/eth-sign/utils/beautify-message/beautify-message.test.ts +0 -29
- package/src/handlers/eth-sign/utils/beautify-message/beautify-message.ts +0 -134
- package/src/handlers/eth-sign/utils/is-typed-data-valid.ts +0 -26
- package/src/handlers/eth-sign/utils/typeguards.ts +0 -10
- package/src/handlers/forward-to-rpc-node/forward-to-rpc-node.test.ts +0 -90
- package/src/handlers/forward-to-rpc-node/forward-to-rpc-node.ts +0 -23
- package/src/handlers/get-address/get-address.ts +0 -26
- package/src/handlers/get-balances/evm-balance-service/get-erc20-balances.test.ts +0 -77
- package/src/handlers/get-balances/evm-balance-service/get-erc20-balances.ts +0 -81
- package/src/handlers/get-balances/evm-balance-service/get-native-token-balances.test.ts +0 -96
- package/src/handlers/get-balances/evm-balance-service/get-native-token-balances.ts +0 -53
- package/src/handlers/get-balances/get-balances.test.ts +0 -248
- package/src/handlers/get-balances/get-balances.ts +0 -123
- package/src/handlers/get-balances/glacier-balance-service/get-erc20-balances.test.ts +0 -71
- package/src/handlers/get-balances/glacier-balance-service/get-erc20-balances.ts +0 -106
- package/src/handlers/get-balances/glacier-balance-service/get-native-token-balances.test.ts +0 -59
- package/src/handlers/get-balances/glacier-balance-service/get-native-token-balances.ts +0 -48
- package/src/handlers/get-network-fee/get-network-fee.test.ts +0 -43
- package/src/handlers/get-network-fee/get-network-fee.ts +0 -59
- package/src/handlers/get-tokens/get-tokens.test.ts +0 -100
- package/src/handlers/get-tokens/get-tokens.ts +0 -18
- package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-erc20.test.ts +0 -53
- package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-erc20.ts +0 -49
- package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-normal.test.ts +0 -57
- package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-normal.ts +0 -57
- package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.test.ts +0 -116
- package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.ts +0 -73
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/convert-transaction.ts +0 -47
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-nft-metadata.ts +0 -35
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-sender-info.ts +0 -38
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tokens.ts +0 -106
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transaction-from-glacier.test.ts +0 -222
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transactions-from-glacier.ts +0 -62
- package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tx-type.ts +0 -52
- package/src/handlers/get-transaction-history/get-transaction-history.test.ts +0 -57
- package/src/handlers/get-transaction-history/get-transaction-history.ts +0 -55
- package/src/handlers/get-transaction-history/utils/get-explorer-address-by-network.ts +0 -7
- package/src/handlers/get-transaction-history/utils/get-small-image-for-nft.ts +0 -16
- package/src/handlers/get-transaction-history/utils/ipfs-resolver-with-fallback.ts +0 -18
- package/src/handlers/get-transaction-history/utils/is-ethereum-chain-id.ts +0 -15
- package/src/handlers/get-transaction-history/utils/resolve.ts +0 -7
- package/src/index.ts +0 -3
- package/src/module.ts +0 -141
- package/src/services/glacier-service/glacier-service.ts +0 -238
- package/src/types.ts +0 -25
- package/src/utils/estimate-gas-limit.ts +0 -27
- package/src/utils/get-chain-id.ts +0 -12
- package/src/utils/get-nonce.ts +0 -11
- package/src/utils/get-provider.ts +0 -46
- package/src/utils/parse-erc20-transaction-type.ts +0 -35
- package/src/utils/process-transaction-simulation.test.ts +0 -105
- package/src/utils/process-transaction-simulation.ts +0 -293
- package/src/utils/scan-transaction.ts +0 -63
- package/tsconfig.jest.json +0 -7
- package/tsconfig.json +0 -14
- package/tsup.config.ts +0 -4
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
import { ethSign } from './eth-sign';
|
|
2
|
-
import { AlertType, NetworkVMType, RpcMethod } from '@avalabs/vm-module-types';
|
|
3
|
-
import { rpcErrors } from '@metamask/rpc-errors';
|
|
4
|
-
import Blockaid from '@blockaid/client';
|
|
5
|
-
|
|
6
|
-
const PROXY_API_URL = 'https://proxy-api.avax.network';
|
|
7
|
-
|
|
8
|
-
jest.mock('@blockaid/client', () => {
|
|
9
|
-
return jest.fn().mockImplementation(() => {
|
|
10
|
-
return {
|
|
11
|
-
evm: {
|
|
12
|
-
transaction: {
|
|
13
|
-
scan: jest.fn().mockResolvedValue({ validation: { result_type: 'Benign' } }),
|
|
14
|
-
},
|
|
15
|
-
jsonRpc: {
|
|
16
|
-
scan: jest.fn().mockResolvedValue({ validation: { result_type: 'Benign' } }),
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
jest.mock('./schemas/parse-request-params/parse-request-params', () => ({
|
|
24
|
-
parseRequestParams: jest.fn(),
|
|
25
|
-
}));
|
|
26
|
-
|
|
27
|
-
jest.mock('./utils/is-typed-data-valid', () => ({
|
|
28
|
-
isTypedDataValid: jest.fn(),
|
|
29
|
-
}));
|
|
30
|
-
|
|
31
|
-
jest.mock('ethers', () => ({
|
|
32
|
-
toUtf8String: jest.fn(),
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
|
-
jest.mock('./utils/beautify-message/beautify-message', () => ({
|
|
36
|
-
beautifySimpleMessage: jest.fn(),
|
|
37
|
-
beautifyComplexMessage: jest.fn(),
|
|
38
|
-
}));
|
|
39
|
-
|
|
40
|
-
jest.mock('./utils/typeguards', () => ({
|
|
41
|
-
isTypedDataV1: jest.fn(),
|
|
42
|
-
isTypedData: jest.fn(),
|
|
43
|
-
}));
|
|
44
|
-
|
|
45
|
-
const mockParseRequestParams = require('./schemas/parse-request-params/parse-request-params').parseRequestParams;
|
|
46
|
-
const mockIsTypedDataValid = require('./utils/is-typed-data-valid').isTypedDataValid;
|
|
47
|
-
const mockToUtf8 = require('ethers').toUtf8String;
|
|
48
|
-
const mockBeautifySimpleMessage = require('./utils/beautify-message/beautify-message').beautifySimpleMessage;
|
|
49
|
-
const mockBeautifyComplexMessage = require('./utils/beautify-message/beautify-message').beautifyComplexMessage;
|
|
50
|
-
const mockIsTypedDataV1 = require('./utils/typeguards').isTypedDataV1;
|
|
51
|
-
|
|
52
|
-
const mockRequest = {
|
|
53
|
-
method: RpcMethod.ETH_SIGN,
|
|
54
|
-
params: ['0x123'],
|
|
55
|
-
dappInfo: {
|
|
56
|
-
name: 'Test DApp',
|
|
57
|
-
url: 'test-url',
|
|
58
|
-
icon: 'test-icon-uri',
|
|
59
|
-
},
|
|
60
|
-
requestId: 'requestId',
|
|
61
|
-
sessionId: 'sessionId',
|
|
62
|
-
chainId: 'eip155:1',
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const mockNetwork = {
|
|
66
|
-
chainId: 1,
|
|
67
|
-
chainName: 'Ethereum',
|
|
68
|
-
logoUri: 'test-logo-uri',
|
|
69
|
-
rpcUrl: 'rpcUrl',
|
|
70
|
-
networkToken: {
|
|
71
|
-
name: 'ethereum',
|
|
72
|
-
symbol: 'ETH',
|
|
73
|
-
decimals: 18,
|
|
74
|
-
},
|
|
75
|
-
vmName: NetworkVMType.EVM,
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const mockApprovalController = {
|
|
79
|
-
requestApproval: jest.fn(),
|
|
80
|
-
onTransactionConfirmed: jest.fn(),
|
|
81
|
-
onTransactionReverted: jest.fn(),
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
describe('ethSign', () => {
|
|
85
|
-
beforeEach(() => {
|
|
86
|
-
mockApprovalController.requestApproval.mockResolvedValue({ result: '0x1234' });
|
|
87
|
-
mockBeautifySimpleMessage.mockReturnValue('beautified simple message');
|
|
88
|
-
mockBeautifyComplexMessage.mockReturnValue('beautified complex message');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should return error when params are invalid', async () => {
|
|
92
|
-
mockParseRequestParams.mockReturnValueOnce({ success: false, error: 'Invalid params' });
|
|
93
|
-
|
|
94
|
-
const result = await ethSign({
|
|
95
|
-
request: mockRequest,
|
|
96
|
-
network: mockNetwork,
|
|
97
|
-
approvalController: mockApprovalController,
|
|
98
|
-
proxyApiUrl: PROXY_API_URL,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
expect(result).toEqual({
|
|
102
|
-
success: false,
|
|
103
|
-
error: rpcErrors.invalidParams('Params are invalid'),
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it.each([RpcMethod.SIGN_TYPED_DATA_V3, RpcMethod.SIGN_TYPED_DATA_V4])(
|
|
108
|
-
'should generate a warning banner for typed data validation failure for %s',
|
|
109
|
-
async (method) => {
|
|
110
|
-
mockParseRequestParams.mockReturnValueOnce({
|
|
111
|
-
success: true,
|
|
112
|
-
data: { method, data: {}, address: '0xabc' },
|
|
113
|
-
});
|
|
114
|
-
mockIsTypedDataValid.mockReturnValueOnce({ isValid: false, error: 'Invalid typed data' });
|
|
115
|
-
|
|
116
|
-
await ethSign({
|
|
117
|
-
request: { ...mockRequest, method },
|
|
118
|
-
network: mockNetwork,
|
|
119
|
-
approvalController: mockApprovalController,
|
|
120
|
-
proxyApiUrl: PROXY_API_URL,
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
expect(mockApprovalController.requestApproval).toHaveBeenCalledWith(
|
|
124
|
-
expect.objectContaining({
|
|
125
|
-
displayData: expect.objectContaining({
|
|
126
|
-
alert: {
|
|
127
|
-
type: AlertType.INFO,
|
|
128
|
-
details: {
|
|
129
|
-
title: 'Warning: Verify Message Content',
|
|
130
|
-
description: 'This message contains non-standard elements.',
|
|
131
|
-
detailedDescription: 'Invalid typed data',
|
|
132
|
-
},
|
|
133
|
-
},
|
|
134
|
-
}),
|
|
135
|
-
}),
|
|
136
|
-
);
|
|
137
|
-
},
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
it.each([
|
|
141
|
-
[
|
|
142
|
-
RpcMethod.ETH_SIGN,
|
|
143
|
-
'data',
|
|
144
|
-
'data',
|
|
145
|
-
"Signing this message can be dangerous. This signature could potentially perform any operation on your account's behalf, including granting complete control of your account and all of its assets to the requesting site. Only sign this message if you know what you're doing or completely trust the requesting site",
|
|
146
|
-
],
|
|
147
|
-
[RpcMethod.PERSONAL_SIGN, 'data', 'data in utf8', undefined],
|
|
148
|
-
[RpcMethod.SIGN_TYPED_DATA, 'data', 'beautified simple message', undefined],
|
|
149
|
-
[RpcMethod.SIGN_TYPED_DATA_V1, 'data', 'beautified simple message', undefined],
|
|
150
|
-
[
|
|
151
|
-
RpcMethod.SIGN_TYPED_DATA_V3,
|
|
152
|
-
{ types: {}, primaryType: '', message: 'test' },
|
|
153
|
-
'beautified complex message',
|
|
154
|
-
undefined,
|
|
155
|
-
],
|
|
156
|
-
[
|
|
157
|
-
RpcMethod.SIGN_TYPED_DATA_V4,
|
|
158
|
-
{ types: {}, primaryType: '', message: 'test' },
|
|
159
|
-
'beautified complex message',
|
|
160
|
-
undefined,
|
|
161
|
-
],
|
|
162
|
-
])(
|
|
163
|
-
'should generate signingData and displayData for %s',
|
|
164
|
-
async (method, inputData, expectedMessageDetails, expectedDisclaimer) => {
|
|
165
|
-
if (method === RpcMethod.SIGN_TYPED_DATA || method === RpcMethod.SIGN_TYPED_DATA_V1) {
|
|
166
|
-
mockIsTypedDataV1.mockReturnValueOnce(true);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
mockParseRequestParams.mockReturnValueOnce({
|
|
170
|
-
success: true,
|
|
171
|
-
data: { method, data: inputData, address: '0xabc' },
|
|
172
|
-
});
|
|
173
|
-
mockIsTypedDataValid.mockReturnValueOnce({ isValid: true });
|
|
174
|
-
mockToUtf8.mockReturnValue('data in utf8');
|
|
175
|
-
|
|
176
|
-
await ethSign({
|
|
177
|
-
request: { ...mockRequest, method },
|
|
178
|
-
network: mockNetwork,
|
|
179
|
-
approvalController: mockApprovalController,
|
|
180
|
-
proxyApiUrl: PROXY_API_URL,
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
expect(mockApprovalController.requestApproval).toHaveBeenCalledWith({
|
|
184
|
-
displayData: {
|
|
185
|
-
title: 'Sign Message',
|
|
186
|
-
messageDetails: expectedMessageDetails,
|
|
187
|
-
account: '0xabc',
|
|
188
|
-
banner: undefined,
|
|
189
|
-
dAppInfo: {
|
|
190
|
-
action: 'Test DApp requests you to sign the following message',
|
|
191
|
-
logoUri: 'test-icon-uri',
|
|
192
|
-
name: 'Test DApp',
|
|
193
|
-
},
|
|
194
|
-
disclaimer: expectedDisclaimer,
|
|
195
|
-
network: {
|
|
196
|
-
chainId: 1,
|
|
197
|
-
logoUri: 'test-logo-uri',
|
|
198
|
-
name: 'Ethereum',
|
|
199
|
-
},
|
|
200
|
-
alert: undefined,
|
|
201
|
-
balanceChange: undefined,
|
|
202
|
-
tokenApprovals: undefined,
|
|
203
|
-
},
|
|
204
|
-
request: { ...mockRequest, method },
|
|
205
|
-
signingData: {
|
|
206
|
-
account: '0xabc',
|
|
207
|
-
chainId: 1,
|
|
208
|
-
data: inputData,
|
|
209
|
-
type: method,
|
|
210
|
-
},
|
|
211
|
-
});
|
|
212
|
-
},
|
|
213
|
-
);
|
|
214
|
-
|
|
215
|
-
it('should add alert object with Warning type to displayData when validation result is Warning', async () => {
|
|
216
|
-
testWithValidationResultType('Warning');
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it('should add alert object with Warning type to displayData when validation result is Error', async () => {
|
|
220
|
-
testWithValidationResultType('Error');
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
it('should add alert object with Danger type to displayData when validation result is Malicious', async () => {
|
|
224
|
-
testWithValidationResultType('Malicious');
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
it('should add alert object with Warning type to displayData when schema validation error occurs in jsonRpc scan', async () => {
|
|
228
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
229
|
-
(Blockaid as any).mockImplementation(() => ({
|
|
230
|
-
evm: {
|
|
231
|
-
jsonRpc: {
|
|
232
|
-
scan: jest.fn().mockRejectedValue({ message: 'schema validation error' }),
|
|
233
|
-
},
|
|
234
|
-
},
|
|
235
|
-
}));
|
|
236
|
-
|
|
237
|
-
mockParseRequestParams.mockReturnValueOnce({
|
|
238
|
-
success: true,
|
|
239
|
-
data: { method: RpcMethod.ETH_SIGN, data: 'data', address: '0xabc' },
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
const result = await ethSign({
|
|
243
|
-
request: mockRequest,
|
|
244
|
-
network: mockNetwork,
|
|
245
|
-
approvalController: mockApprovalController,
|
|
246
|
-
proxyApiUrl: PROXY_API_URL,
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
expect(result).toEqual({ result: '0x1234' });
|
|
250
|
-
expect(mockApprovalController.requestApproval).toHaveBeenCalledWith(
|
|
251
|
-
expect.objectContaining({
|
|
252
|
-
displayData: expect.objectContaining({
|
|
253
|
-
alert: {
|
|
254
|
-
type: AlertType.WARNING,
|
|
255
|
-
details: {
|
|
256
|
-
title: 'Suspicious Transaction',
|
|
257
|
-
description: 'Use caution, this transaction may be malicious.',
|
|
258
|
-
},
|
|
259
|
-
},
|
|
260
|
-
}),
|
|
261
|
-
}),
|
|
262
|
-
);
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
it('should handle success case for approvalController.requestApproval', async () => {
|
|
266
|
-
mockParseRequestParams.mockReturnValueOnce({
|
|
267
|
-
success: true,
|
|
268
|
-
data: { method: RpcMethod.ETH_SIGN, data: 'data', address: '0xabc' },
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
const result = await ethSign({
|
|
272
|
-
request: mockRequest,
|
|
273
|
-
network: mockNetwork,
|
|
274
|
-
approvalController: mockApprovalController,
|
|
275
|
-
proxyApiUrl: PROXY_API_URL,
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
expect(result).toEqual({ result: '0x1234' });
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
it('should handle error case for approvalController.requestApproval', async () => {
|
|
282
|
-
mockParseRequestParams.mockReturnValueOnce({
|
|
283
|
-
success: true,
|
|
284
|
-
data: { method: RpcMethod.ETH_SIGN, data: 'data', address: '0xabc' },
|
|
285
|
-
});
|
|
286
|
-
mockApprovalController.requestApproval.mockResolvedValueOnce({ error: 'User denied message signature' });
|
|
287
|
-
|
|
288
|
-
const result = await ethSign({
|
|
289
|
-
request: mockRequest,
|
|
290
|
-
network: mockNetwork,
|
|
291
|
-
approvalController: mockApprovalController,
|
|
292
|
-
proxyApiUrl: PROXY_API_URL,
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
expect(result).toEqual({ error: 'User denied message signature' });
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
const testWithValidationResultType = async (resultType: 'Warning' | 'Error' | 'Malicious') => {
|
|
300
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
301
|
-
(Blockaid as any).mockImplementation(() => ({
|
|
302
|
-
evm: {
|
|
303
|
-
jsonRpc: {
|
|
304
|
-
scan: jest.fn().mockResolvedValue({
|
|
305
|
-
validation: { result_type: resultType },
|
|
306
|
-
simulation: { status: 'Success', account_summary: { exposures: [], assets_diffs: [] } },
|
|
307
|
-
}),
|
|
308
|
-
},
|
|
309
|
-
},
|
|
310
|
-
}));
|
|
311
|
-
|
|
312
|
-
mockParseRequestParams.mockReturnValueOnce({
|
|
313
|
-
success: true,
|
|
314
|
-
data: { method: RpcMethod.ETH_SIGN, data: 'data', address: '0xabc' },
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
const result = await ethSign({
|
|
318
|
-
request: mockRequest,
|
|
319
|
-
network: mockNetwork,
|
|
320
|
-
approvalController: mockApprovalController,
|
|
321
|
-
proxyApiUrl: PROXY_API_URL,
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
expect(result).toEqual({ result: '0x1234' });
|
|
325
|
-
|
|
326
|
-
if (resultType === 'Malicious') {
|
|
327
|
-
expect(mockApprovalController.requestApproval).toHaveBeenCalledWith(
|
|
328
|
-
expect.objectContaining({
|
|
329
|
-
displayData: expect.objectContaining({
|
|
330
|
-
alert: {
|
|
331
|
-
type: AlertType.DANGER,
|
|
332
|
-
details: {
|
|
333
|
-
title: 'Scam Transaction',
|
|
334
|
-
description: 'This transaction is malicious, do not proceed.',
|
|
335
|
-
actionTitles: {
|
|
336
|
-
reject: 'Reject Transaction',
|
|
337
|
-
proceed: 'Proceed Anyway',
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
},
|
|
341
|
-
}),
|
|
342
|
-
}),
|
|
343
|
-
);
|
|
344
|
-
} else {
|
|
345
|
-
expect(mockApprovalController.requestApproval).toHaveBeenCalledWith(
|
|
346
|
-
expect.objectContaining({
|
|
347
|
-
displayData: expect.objectContaining({
|
|
348
|
-
alert: {
|
|
349
|
-
type: AlertType.WARNING,
|
|
350
|
-
details: {
|
|
351
|
-
title: 'Suspicious Transaction',
|
|
352
|
-
description: 'Use caution, this transaction may be malicious.',
|
|
353
|
-
},
|
|
354
|
-
},
|
|
355
|
-
}),
|
|
356
|
-
}),
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
};
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type SigningData,
|
|
3
|
-
type Network,
|
|
4
|
-
type ApprovalController,
|
|
5
|
-
type DisplayData,
|
|
6
|
-
type RpcRequest,
|
|
7
|
-
RpcMethod,
|
|
8
|
-
type Alert,
|
|
9
|
-
AlertType,
|
|
10
|
-
} from '@avalabs/vm-module-types';
|
|
11
|
-
import { rpcErrors } from '@metamask/rpc-errors';
|
|
12
|
-
import { toUtf8String } from 'ethers';
|
|
13
|
-
import { beautifySimpleMessage, beautifyComplexMessage } from './utils/beautify-message/beautify-message';
|
|
14
|
-
import { parseRequestParams } from './schemas/parse-request-params/parse-request-params';
|
|
15
|
-
import { isTypedDataV1 } from './utils/typeguards';
|
|
16
|
-
import { isTypedDataValid } from './utils/is-typed-data-valid';
|
|
17
|
-
import { processJsonRpcSimulation } from '../../utils/process-transaction-simulation';
|
|
18
|
-
|
|
19
|
-
export const ethSign = async ({
|
|
20
|
-
request,
|
|
21
|
-
network,
|
|
22
|
-
approvalController,
|
|
23
|
-
proxyApiUrl,
|
|
24
|
-
}: {
|
|
25
|
-
request: RpcRequest;
|
|
26
|
-
network: Network;
|
|
27
|
-
approvalController: ApprovalController;
|
|
28
|
-
proxyApiUrl: string;
|
|
29
|
-
}) => {
|
|
30
|
-
const result = parseRequestParams({ method: request.method, params: request.params });
|
|
31
|
-
|
|
32
|
-
if (!result.success) {
|
|
33
|
-
console.error('invalid params', result.error);
|
|
34
|
-
|
|
35
|
-
return {
|
|
36
|
-
success: false,
|
|
37
|
-
error: rpcErrors.invalidParams('Params are invalid'),
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
const { method, data, address } = result.data;
|
|
41
|
-
|
|
42
|
-
// validate typed data
|
|
43
|
-
let typedDataValidationResult: ReturnType<typeof isTypedDataValid> | undefined;
|
|
44
|
-
|
|
45
|
-
if (method === RpcMethod.SIGN_TYPED_DATA_V3 || method === RpcMethod.SIGN_TYPED_DATA_V4) {
|
|
46
|
-
typedDataValidationResult = isTypedDataValid(data);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// generate display data and signing data
|
|
50
|
-
let signingData: SigningData | undefined;
|
|
51
|
-
let messageDetails: string | undefined;
|
|
52
|
-
let disclaimer: string | undefined;
|
|
53
|
-
let alert: Alert | undefined;
|
|
54
|
-
|
|
55
|
-
if (typedDataValidationResult && !typedDataValidationResult.isValid) {
|
|
56
|
-
alert = {
|
|
57
|
-
type: AlertType.INFO,
|
|
58
|
-
details: {
|
|
59
|
-
title: 'Warning: Verify Message Content',
|
|
60
|
-
description: 'This message contains non-standard elements.',
|
|
61
|
-
detailedDescription: (typedDataValidationResult.error as Error).toString(),
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (method === RpcMethod.ETH_SIGN) {
|
|
67
|
-
signingData = {
|
|
68
|
-
type: method,
|
|
69
|
-
account: address,
|
|
70
|
-
chainId: network.chainId,
|
|
71
|
-
data: data,
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
messageDetails = data;
|
|
75
|
-
|
|
76
|
-
disclaimer =
|
|
77
|
-
"Signing this message can be dangerous. This signature could potentially perform any operation on your account's behalf, including granting complete control of your account and all of its assets to the requesting site. Only sign this message if you know what you're doing or completely trust the requesting site";
|
|
78
|
-
} else if (method === RpcMethod.PERSONAL_SIGN) {
|
|
79
|
-
signingData = {
|
|
80
|
-
type: method,
|
|
81
|
-
account: address,
|
|
82
|
-
chainId: network.chainId,
|
|
83
|
-
data: data,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
messageDetails = toUtf8String(data);
|
|
87
|
-
} else if (method === RpcMethod.SIGN_TYPED_DATA || method === RpcMethod.SIGN_TYPED_DATA_V1) {
|
|
88
|
-
signingData = {
|
|
89
|
-
type: method,
|
|
90
|
-
account: address,
|
|
91
|
-
chainId: network.chainId,
|
|
92
|
-
data: data,
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
messageDetails = isTypedDataV1(data) ? beautifySimpleMessage(data) : beautifyComplexMessage(data);
|
|
96
|
-
} else if (method === RpcMethod.SIGN_TYPED_DATA_V3 || method === RpcMethod.SIGN_TYPED_DATA_V4) {
|
|
97
|
-
signingData = {
|
|
98
|
-
type: method,
|
|
99
|
-
account: address,
|
|
100
|
-
chainId: network.chainId,
|
|
101
|
-
data: data,
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const { types, primaryType, ...messageToDisplay } = data;
|
|
105
|
-
messageDetails = beautifyComplexMessage(messageToDisplay);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (!signingData) {
|
|
109
|
-
return {
|
|
110
|
-
success: false,
|
|
111
|
-
error: rpcErrors.internal('Unable to generate signing data'),
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const {
|
|
116
|
-
alert: prioritizedAlert,
|
|
117
|
-
balanceChange,
|
|
118
|
-
tokenApprovals,
|
|
119
|
-
} = await processJsonRpcSimulation({
|
|
120
|
-
request,
|
|
121
|
-
proxyApiUrl,
|
|
122
|
-
accountAddress: address,
|
|
123
|
-
chainId: network.chainId,
|
|
124
|
-
data: { method, params: request.params },
|
|
125
|
-
dAppUrl: request.dappInfo.url,
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const displayData: DisplayData = {
|
|
129
|
-
title: 'Sign Message',
|
|
130
|
-
dAppInfo: {
|
|
131
|
-
name: request.dappInfo.name,
|
|
132
|
-
action: `${request.dappInfo.name} requests you to sign the following message`,
|
|
133
|
-
logoUri: request.dappInfo.icon,
|
|
134
|
-
},
|
|
135
|
-
network: {
|
|
136
|
-
chainId: network.chainId,
|
|
137
|
-
name: network.chainName,
|
|
138
|
-
logoUri: network.logoUri,
|
|
139
|
-
},
|
|
140
|
-
account: address,
|
|
141
|
-
messageDetails,
|
|
142
|
-
disclaimer,
|
|
143
|
-
alert: prioritizedAlert ?? alert,
|
|
144
|
-
balanceChange,
|
|
145
|
-
tokenApprovals,
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
// prompt user for approval
|
|
149
|
-
const response = await approvalController.requestApproval({ request, displayData, signingData });
|
|
150
|
-
|
|
151
|
-
if ('error' in response) {
|
|
152
|
-
return {
|
|
153
|
-
error: response.error,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return { result: response.result };
|
|
158
|
-
};
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { addressSchema } from './shared';
|
|
3
|
-
import { RpcMethod } from '@avalabs/vm-module-types';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* For the different eth_signTypedData methods, the payload differs based on the version.
|
|
7
|
-
*
|
|
8
|
-
* V1 is based upon [an early version of EIP-712](https://github.com/ethereum/EIPs/pull/712/commits/21abe254fe0452d8583d5b132b1d7be87c0439ca)
|
|
9
|
-
* that lacked some later security improvements, and should generally be neglected in favor of
|
|
10
|
-
* later versions.
|
|
11
|
-
*
|
|
12
|
-
* V3 is based on [EIP-712](https://eips.ethereum.org/EIPS/eip-712), except that arrays and
|
|
13
|
-
* recursive data structures are not supported.
|
|
14
|
-
*
|
|
15
|
-
* V4 is based on [EIP-712](https://eips.ethereum.org/EIPS/eip-712), and includes full support of
|
|
16
|
-
* arrays and recursive data structures.
|
|
17
|
-
*
|
|
18
|
-
* References:
|
|
19
|
-
* - https://eips.ethereum.org/EIPS/eip-712#specification-of-the-eth_signtypeddata-json-rpc
|
|
20
|
-
* - https://docs.metamask.io/guide/signing-data.html#signtypeddata-v4
|
|
21
|
-
*/
|
|
22
|
-
const messageTypeSchema = z.object({ name: z.string(), type: z.string() });
|
|
23
|
-
|
|
24
|
-
export const typedDataSchema = z.object({
|
|
25
|
-
types: z.object({ EIP712Domain: z.array(messageTypeSchema) }).catchall(z.array(messageTypeSchema)),
|
|
26
|
-
primaryType: z.string(),
|
|
27
|
-
domain: z.record(z.any()),
|
|
28
|
-
message: z.record(z.any()),
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
export const typedDataV1Schema = z
|
|
32
|
-
.array(
|
|
33
|
-
z.object({
|
|
34
|
-
type: z.string(),
|
|
35
|
-
name: z.string(),
|
|
36
|
-
value: z.union([z.string(), z.number(), z.boolean(), z.object({}).passthrough(), z.array(z.unknown()), z.null()]),
|
|
37
|
-
}),
|
|
38
|
-
)
|
|
39
|
-
.nonempty();
|
|
40
|
-
|
|
41
|
-
export const combinedTypedDataSchema = typedDataSchema.or(typedDataV1Schema);
|
|
42
|
-
|
|
43
|
-
const dataSchema = z.union([z.string().describe('data string'), typedDataSchema]);
|
|
44
|
-
|
|
45
|
-
export const combinedDataSchema = z.union([z.string().describe('data string'), combinedTypedDataSchema]);
|
|
46
|
-
|
|
47
|
-
export const ethSignTypedDataSchema = z.object({
|
|
48
|
-
method: z.literal(RpcMethod.SIGN_TYPED_DATA),
|
|
49
|
-
params: z.tuple([addressSchema, combinedDataSchema]),
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
export const ethSignTypedDataV1Schema = z.object({
|
|
53
|
-
method: z.literal(RpcMethod.SIGN_TYPED_DATA_V1),
|
|
54
|
-
params: z.tuple([addressSchema, combinedDataSchema]),
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
export const ethSignTypedDataV3Schema = z.object({
|
|
58
|
-
method: z.literal(RpcMethod.SIGN_TYPED_DATA_V3),
|
|
59
|
-
params: z.tuple([addressSchema, dataSchema]),
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
export const ethSignTypedDataV4Schema = z.object({
|
|
63
|
-
method: z.literal(RpcMethod.SIGN_TYPED_DATA_V4),
|
|
64
|
-
params: z.tuple([addressSchema, dataSchema]),
|
|
65
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { addressSchema, messageSchema } from './shared';
|
|
3
|
-
import { RpcMethod } from '@avalabs/vm-module-types';
|
|
4
|
-
|
|
5
|
-
// https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign
|
|
6
|
-
export const ethSignSchema = z.object({
|
|
7
|
-
method: z.literal(RpcMethod.ETH_SIGN),
|
|
8
|
-
params: z.tuple([addressSchema, messageSchema]),
|
|
9
|
-
});
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
export const typedData = {
|
|
2
|
-
types: {
|
|
3
|
-
EIP712Domain: [
|
|
4
|
-
{ name: 'name', type: 'string' },
|
|
5
|
-
{ name: 'version', type: 'string' },
|
|
6
|
-
{ name: 'chainId', type: 'uint256' },
|
|
7
|
-
{ name: 'verifyingContract', type: 'address' },
|
|
8
|
-
],
|
|
9
|
-
Group: [
|
|
10
|
-
{ name: 'name', type: 'string' },
|
|
11
|
-
{ name: 'members', type: 'Person[]' },
|
|
12
|
-
],
|
|
13
|
-
Mail: [
|
|
14
|
-
{ name: 'from', type: 'Person' },
|
|
15
|
-
{ name: 'to', type: 'Person[]' },
|
|
16
|
-
{ name: 'contents', type: 'string' },
|
|
17
|
-
],
|
|
18
|
-
Person: [
|
|
19
|
-
{ name: 'name', type: 'string' },
|
|
20
|
-
{ name: 'wallets', type: 'address[]' },
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
primaryType: 'Mail',
|
|
24
|
-
domain: {
|
|
25
|
-
chainId: 43113,
|
|
26
|
-
name: 'Ether Mail',
|
|
27
|
-
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
|
|
28
|
-
version: '1',
|
|
29
|
-
},
|
|
30
|
-
message: {
|
|
31
|
-
contents: 'Hello, Bob!',
|
|
32
|
-
from: {
|
|
33
|
-
name: 'Cow',
|
|
34
|
-
wallets: ['0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF'],
|
|
35
|
-
},
|
|
36
|
-
to: [
|
|
37
|
-
{
|
|
38
|
-
name: 'Bob',
|
|
39
|
-
wallets: [
|
|
40
|
-
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
|
41
|
-
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
|
42
|
-
'0xB0B0b0b0b0b0B000000000000000000000000000',
|
|
43
|
-
],
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
},
|
|
47
|
-
};
|