@avalabs/evm-module 0.0.0-workspaces-20240716185307 → 0.0.2

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.
Files changed (67) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +3 -49
  4. package/CHANGELOG.md +0 -98
  5. package/dist/index.cjs +2 -25
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +3 -39
  8. package/dist/index.d.ts +3 -39
  9. package/dist/index.js +2 -17
  10. package/dist/index.js.map +1 -1
  11. package/package.json +6 -30
  12. package/src/index.ts +22 -2
  13. package/{manifest.json → src/manifest.json} +1 -1
  14. package/tsconfig.json +1 -2
  15. package/src/contracts/openzeppelin/ERC1155.ts +0 -440
  16. package/src/contracts/openzeppelin/ERC20.ts +0 -330
  17. package/src/contracts/openzeppelin/ERC721.ts +0 -420
  18. package/src/contracts/openzeppelin/common.ts +0 -131
  19. package/src/contracts/openzeppelin/factories/ERC1155__factory.ts +0 -388
  20. package/src/contracts/openzeppelin/factories/ERC20__factory.ts +0 -353
  21. package/src/contracts/openzeppelin/factories/ERC721__factory.ts +0 -413
  22. package/src/contracts/openzeppelin/factories/index.ts +0 -6
  23. package/src/contracts/openzeppelin/index.ts +0 -10
  24. package/src/handlers/eth-send-transaction/eth-send-transaction.test.ts +0 -350
  25. package/src/handlers/eth-send-transaction/eth-send-transaction.ts +0 -183
  26. package/src/handlers/eth-send-transaction/schema.test.ts +0 -240
  27. package/src/handlers/eth-send-transaction/schema.ts +0 -20
  28. package/src/handlers/get-balances/evm-balance-service/get-erc20-balances.test.ts +0 -78
  29. package/src/handlers/get-balances/evm-balance-service/get-erc20-balances.ts +0 -87
  30. package/src/handlers/get-balances/evm-balance-service/get-native-token-balances.test.ts +0 -102
  31. package/src/handlers/get-balances/evm-balance-service/get-native-token-balances.ts +0 -54
  32. package/src/handlers/get-balances/get-balances.test.ts +0 -250
  33. package/src/handlers/get-balances/get-balances.ts +0 -107
  34. package/src/handlers/get-balances/glacier-balance-service/get-erc20-balances.test.ts +0 -76
  35. package/src/handlers/get-balances/glacier-balance-service/get-erc20-balances.ts +0 -110
  36. package/src/handlers/get-balances/glacier-balance-service/get-native-token-balances.test.ts +0 -61
  37. package/src/handlers/get-balances/glacier-balance-service/get-native-token-balances.ts +0 -46
  38. package/src/handlers/get-network-fee/get-network-fee.test.ts +0 -43
  39. package/src/handlers/get-network-fee/get-network-fee.ts +0 -59
  40. package/src/handlers/get-tokens/get-tokens.test.ts +0 -100
  41. package/src/handlers/get-tokens/get-tokens.ts +0 -18
  42. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-erc20.ts +0 -51
  43. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-normal.ts +0 -58
  44. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.test.ts +0 -116
  45. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/get-transaction-from-etherscan.ts +0 -73
  46. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/convert-transaction.ts +0 -47
  47. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-nft-metadata.ts +0 -35
  48. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-sender-info.ts +0 -38
  49. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tokens.ts +0 -107
  50. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transaction-from-glacier.test.ts +0 -191
  51. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-transactions-from-glacier.ts +0 -62
  52. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tx-type.ts +0 -52
  53. package/src/handlers/get-transaction-history/get-transaction-history.test.ts +0 -53
  54. package/src/handlers/get-transaction-history/get-transaction-history.ts +0 -46
  55. package/src/handlers/get-transaction-history/utils/get-explorer-address-by-network.ts +0 -7
  56. package/src/handlers/get-transaction-history/utils/get-small-image-for-nft.ts +0 -16
  57. package/src/handlers/get-transaction-history/utils/ipfs-resolver-with-fallback.ts +0 -18
  58. package/src/handlers/get-transaction-history/utils/is-ethereum-chain-id.ts +0 -15
  59. package/src/handlers/get-transaction-history/utils/resolve.ts +0 -7
  60. package/src/module.ts +0 -105
  61. package/src/types.ts +0 -16
  62. package/src/utils/estimate-gas-limit.ts +0 -27
  63. package/src/utils/get-chain-id.ts +0 -12
  64. package/src/utils/get-nonce.ts +0 -11
  65. package/src/utils/get-provider.ts +0 -46
  66. package/src/utils/parse-erc20-transaction-type.ts +0 -21
  67. package/src/utils/transaction-simulation.ts +0 -227
@@ -1,350 +0,0 @@
1
- import { ethSendTransaction } from './eth-send-transaction';
2
- import { parseRequestParams } from './schema';
3
- import { estimateGasLimit } from '../../utils/estimate-gas-limit';
4
- import { getNonce } from '../../utils/get-nonce';
5
- import { rpcErrors } from '@metamask/rpc-errors';
6
- import { RpcMethod, type ApprovalController, type Network } from '@avalabs/vm-module-types';
7
- import { ZodError } from 'zod';
8
- import { getProvider } from '../../utils/get-provider';
9
-
10
- const mockGetProvider = getProvider as jest.MockedFunction<typeof getProvider>;
11
-
12
- const PROXY_API_URL = 'https://proxy-api.avax.network';
13
-
14
- jest.mock('./schema');
15
- jest.mock('../../utils/estimate-gas-limit');
16
- jest.mock('../../utils/get-nonce');
17
- jest.mock('../../utils/get-provider');
18
- jest.mock('@blockaid/client', () => {
19
- return jest.fn().mockImplementation(() => {
20
- return {
21
- evm: {
22
- transaction: {
23
- scan: jest.fn().mockResolvedValue({ validation: { result_type: 'Success' } }),
24
- },
25
- jsonRpc: {
26
- scan: jest.fn(),
27
- },
28
- },
29
- };
30
- });
31
- });
32
-
33
- const mockOnTransactionConfirmed = jest.fn();
34
- const mockOnTransactionReverted = jest.fn();
35
- const mockApprovalController: jest.Mocked<ApprovalController> = {
36
- requestApproval: jest.fn(),
37
- onTransactionConfirmed: mockOnTransactionConfirmed,
38
- onTransactionReverted: mockOnTransactionReverted,
39
- };
40
-
41
- const mockParseRequestParams = parseRequestParams as jest.MockedFunction<typeof parseRequestParams>;
42
- const mockEstimateGasLimit = estimateGasLimit as jest.MockedFunction<typeof estimateGasLimit>;
43
- const mockGetNonce = getNonce as jest.MockedFunction<typeof getNonce>;
44
- const mockSend = jest.fn();
45
- const mockWaitForTransaction = jest.fn();
46
-
47
- const mockProvider = {
48
- send: mockSend,
49
- waitForTransaction: mockWaitForTransaction,
50
- };
51
-
52
- // @ts-expect-error missing properties
53
- mockGetProvider.mockReturnValue(mockProvider);
54
- const testNetwork: Network = {
55
- isTestnet: false,
56
- chainId: 1,
57
- chainName: 'chainName',
58
- rpcUrl: 'rpcUrl',
59
- logoUri: 'logoUri',
60
- utilityAddresses: { multicall: 'multiContractAddress' },
61
- networkToken: {
62
- name: 'Ethereum',
63
- symbol: 'ETH',
64
- decimals: 9,
65
- description: 'Ethereum Token',
66
- logoUri: 'some logo uri',
67
- },
68
- };
69
-
70
- const testParams = { from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue', nonce: '12', gas: '0x5208' };
71
-
72
- const testRequestParams = () => ({
73
- request: {
74
- requestId: '1',
75
- sessionId: '2',
76
- method: RpcMethod.ETH_SEND_TRANSACTION,
77
- chainId: 'eip155:1',
78
- dappInfo: { url: 'https://example.com', name: 'dapp', icon: 'icon' },
79
- params: [testParams],
80
- },
81
- network: testNetwork,
82
- approvalController: mockApprovalController,
83
- proxyApiUrl: PROXY_API_URL,
84
- });
85
-
86
- const displayData = {
87
- title: 'Approve Transaction',
88
- network: {
89
- chainId: testNetwork.chainId,
90
- name: testNetwork.chainName,
91
- logoUri: testNetwork.logoUri,
92
- },
93
- transactionDetails: {
94
- website: 'example.com',
95
- from: '0xfrom',
96
- to: '0xto',
97
- data: '0xdata',
98
- },
99
- networkFeeSelector: true,
100
- };
101
-
102
- const signingData = {
103
- type: 'evm_transaction',
104
- account: '0xfrom',
105
- chainId: 1,
106
- data: {
107
- type: 2,
108
- nonce: 12,
109
- gasLimit: 21000,
110
- to: '0xto',
111
- from: '0xfrom',
112
- data: '0xdata',
113
- value: '0xvalue',
114
- },
115
- };
116
-
117
- const testTxHash = '0xtxhash';
118
-
119
- describe('eth_sendTransaction handler', () => {
120
- beforeEach(() => {
121
- jest.clearAllMocks();
122
-
123
- mockParseRequestParams.mockReturnValue({
124
- success: true,
125
- data: [testParams],
126
- });
127
-
128
- mockApprovalController.requestApproval.mockResolvedValue({ result: testTxHash });
129
- });
130
-
131
- it('should return error if request params are invalid', async () => {
132
- mockParseRequestParams.mockReturnValue({
133
- success: false,
134
- error: new Error('Invalid params') as ZodError,
135
- });
136
-
137
- const response = await ethSendTransaction(testRequestParams());
138
-
139
- expect(response).toEqual({
140
- error: rpcErrors.invalidParams('Transaction params are invalid'),
141
- });
142
- });
143
-
144
- it('should calculate gas limit if not provided', async () => {
145
- mockParseRequestParams.mockReturnValue({
146
- success: true,
147
- data: [{ from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue', nonce: '12' }],
148
- });
149
- mockEstimateGasLimit.mockResolvedValue(21000);
150
-
151
- const requestParams = testRequestParams();
152
-
153
- await ethSendTransaction(requestParams);
154
-
155
- expect(mockGetProvider).toHaveBeenCalledWith({
156
- chainId: 1,
157
- chainName: 'chainName',
158
- rpcUrl: 'rpcUrl',
159
- multiContractAddress: 'multiContractAddress',
160
- pollingInterval: 1000,
161
- });
162
-
163
- expect(mockEstimateGasLimit).toHaveBeenCalledWith({
164
- provider: mockProvider,
165
- transactionParams: { from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue' },
166
- });
167
-
168
- expect(mockApprovalController.requestApproval).toHaveBeenCalledWith({
169
- request: requestParams.request,
170
- displayData,
171
- signingData,
172
- });
173
- });
174
-
175
- it('should calculate nonce if not provided', async () => {
176
- mockParseRequestParams.mockReturnValue({
177
- success: true,
178
- data: [{ from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue', gas: '0x5208' }],
179
- });
180
- mockGetNonce.mockResolvedValue(12);
181
-
182
- const requestParams = testRequestParams();
183
- await ethSendTransaction(requestParams);
184
-
185
- expect(mockGetProvider).toHaveBeenCalledWith({
186
- chainId: 1,
187
- chainName: 'chainName',
188
- rpcUrl: 'rpcUrl',
189
- multiContractAddress: 'multiContractAddress',
190
- pollingInterval: 1000,
191
- });
192
-
193
- expect(mockGetNonce).toHaveBeenCalledWith({
194
- provider: mockProvider,
195
- from: '0xfrom',
196
- });
197
-
198
- expect(mockApprovalController.requestApproval).toHaveBeenCalledWith({
199
- request: requestParams.request,
200
- displayData,
201
- signingData,
202
- });
203
- });
204
-
205
- it('should calculate both gas and nonce if not provided', async () => {
206
- mockParseRequestParams.mockReturnValue({
207
- success: true,
208
- data: [{ from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue' }],
209
- });
210
- mockGetNonce.mockResolvedValue(12);
211
- mockEstimateGasLimit.mockResolvedValue(21000);
212
-
213
- const requestParams = testRequestParams();
214
- await ethSendTransaction(requestParams);
215
-
216
- expect(mockGetProvider).toHaveBeenCalledWith({
217
- chainId: 1,
218
- chainName: 'chainName',
219
- rpcUrl: 'rpcUrl',
220
- multiContractAddress: 'multiContractAddress',
221
- pollingInterval: 1000,
222
- });
223
-
224
- expect(mockGetNonce).toHaveBeenCalledWith({
225
- provider: mockProvider,
226
- from: '0xfrom',
227
- });
228
-
229
- expect(mockEstimateGasLimit).toHaveBeenCalledWith({
230
- provider: mockProvider,
231
- transactionParams: { from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue' },
232
- });
233
-
234
- expect(mockApprovalController.requestApproval).toHaveBeenCalledWith({
235
- request: requestParams.request,
236
- displayData,
237
- signingData,
238
- });
239
- });
240
-
241
- it('should return error if gas limit calculation fails', async () => {
242
- mockParseRequestParams.mockReturnValue({
243
- success: true,
244
- data: [{ from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue', nonce: '12' }],
245
- });
246
-
247
- mockEstimateGasLimit.mockRejectedValue(new Error('gas calculation error'));
248
-
249
- const requestParams = testRequestParams();
250
- const response = await ethSendTransaction(requestParams);
251
-
252
- expect(response).toEqual({
253
- error: rpcErrors.internal('Unable to calculate gas limit'),
254
- });
255
- });
256
-
257
- it('should return error if nonce calculation fails', async () => {
258
- mockParseRequestParams.mockReturnValue({
259
- success: true,
260
- data: [{ from: '0xfrom', to: '0xto', data: '0xdata', value: '0xvalue', gas: '0x5208' }],
261
- });
262
- mockGetNonce.mockRejectedValue(new Error('Nonce calculation error'));
263
-
264
- const requestParams = testRequestParams();
265
- const response = await ethSendTransaction(requestParams);
266
-
267
- expect(response).toEqual({
268
- error: rpcErrors.internal('Unable to calculate nonce'),
269
- });
270
- });
271
-
272
- describe('approval succeeds', () => {
273
- beforeEach(() => {
274
- jest.clearAllMocks();
275
-
276
- mockApprovalController.requestApproval.mockResolvedValue({ result: testTxHash });
277
- mockSend.mockResolvedValue(testTxHash);
278
- });
279
-
280
- it('should broadcast the signed transaction and return transaction hash', async () => {
281
- const requestParams = testRequestParams();
282
- const response = await ethSendTransaction(requestParams);
283
-
284
- expect(mockGetProvider).toHaveBeenCalledWith({
285
- chainId: 1,
286
- chainName: 'chainName',
287
- rpcUrl: 'rpcUrl',
288
- multiContractAddress: 'multiContractAddress',
289
- pollingInterval: 1000,
290
- });
291
-
292
- expect(mockSend).toHaveBeenCalledWith('eth_sendRawTransaction', [testTxHash]);
293
-
294
- expect(response).toStrictEqual({ result: testTxHash });
295
- });
296
-
297
- it('should notify when transaction is confirmed', async () => {
298
- mockWaitForTransaction.mockResolvedValue({ status: 1 });
299
-
300
- const requestParams = testRequestParams();
301
- const response = await ethSendTransaction(requestParams);
302
-
303
- expect(mockGetProvider).toHaveBeenCalledWith({
304
- chainId: 1,
305
- chainName: 'chainName',
306
- rpcUrl: 'rpcUrl',
307
- multiContractAddress: 'multiContractAddress',
308
- pollingInterval: 1000,
309
- });
310
-
311
- expect(response).toStrictEqual({ result: testTxHash });
312
-
313
- expect(mockWaitForTransaction).toHaveBeenCalledWith(testTxHash);
314
-
315
- expect(mockOnTransactionConfirmed).toHaveBeenCalledWith(testTxHash);
316
- });
317
-
318
- it('should notify when transaction is reverted', async () => {
319
- mockWaitForTransaction.mockResolvedValue({ status: 0 });
320
-
321
- const requestParams = testRequestParams();
322
- const response = await ethSendTransaction(requestParams);
323
-
324
- expect(mockGetProvider).toHaveBeenCalledWith({
325
- chainId: 1,
326
- chainName: 'chainName',
327
- rpcUrl: 'rpcUrl',
328
- multiContractAddress: 'multiContractAddress',
329
- pollingInterval: 1000,
330
- });
331
-
332
- expect(response).toStrictEqual({ result: testTxHash });
333
-
334
- expect(mockWaitForTransaction).toHaveBeenCalledWith(testTxHash);
335
-
336
- expect(mockOnTransactionReverted).toHaveBeenCalledWith(testTxHash);
337
- });
338
- });
339
-
340
- describe('approval fails', () => {
341
- it('should return error', async () => {
342
- mockApprovalController.requestApproval.mockResolvedValue({ error: rpcErrors.internal('something went wrong') });
343
-
344
- const requestParams = testRequestParams();
345
- const response = await ethSendTransaction(requestParams);
346
-
347
- expect(response).toStrictEqual({ error: rpcErrors.internal('something went wrong') });
348
- });
349
- });
350
- });
@@ -1,183 +0,0 @@
1
- import {
2
- type Network,
3
- type Hex,
4
- type RpcRequest,
5
- type ApprovalController,
6
- type DisplayData,
7
- type SigningData,
8
- SigningDataType,
9
- } from '@avalabs/vm-module-types';
10
- import { parseRequestParams } from './schema';
11
- import { estimateGasLimit } from '../../utils/estimate-gas-limit';
12
- import { getNonce } from '../../utils/get-nonce';
13
- import { rpcErrors } from '@metamask/rpc-errors';
14
- import { getProvider } from '../../utils/get-provider';
15
- import type { JsonRpcBatchInternal } from '@avalabs/wallets-sdk';
16
- import { simulateTransaction } from '../../utils/transaction-simulation';
17
- import { parseERC20TransactionType } from '../../utils/parse-erc20-transaction-type';
18
-
19
- export const ethSendTransaction = 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 { dappInfo, params } = request;
31
-
32
- // validate params
33
- const result = parseRequestParams(params);
34
-
35
- if (!result.success) {
36
- console.error(result.error);
37
- return {
38
- error: rpcErrors.invalidParams('Transaction params are invalid'),
39
- };
40
- }
41
-
42
- const transaction = result.data[0];
43
-
44
- if (!transaction) {
45
- return {
46
- error: rpcErrors.invalidParams('Transaction params are invalid'),
47
- };
48
- }
49
-
50
- const provider = getProvider({
51
- chainId: network.chainId,
52
- chainName: network.chainName,
53
- rpcUrl: network.rpcUrl,
54
- multiContractAddress: network.utilityAddresses?.multicall,
55
- pollingInterval: 1000,
56
- });
57
-
58
- // calculate gas limit if not provided/invalid
59
- if (!transaction.gas || Number(transaction.gas) < 0) {
60
- try {
61
- const gasLimit = await estimateGasLimit({
62
- transactionParams: {
63
- from: transaction.from,
64
- to: transaction.to,
65
- data: transaction.data,
66
- value: transaction.value,
67
- },
68
- provider,
69
- });
70
-
71
- transaction.gas = '0x' + gasLimit.toString(16);
72
- } catch (error) {
73
- return {
74
- error: rpcErrors.internal('Unable to calculate gas limit'),
75
- };
76
- }
77
- }
78
-
79
- // calculate nonce if not provided
80
- if (!transaction.nonce) {
81
- try {
82
- const nonce = await getNonce({
83
- from: transaction.from,
84
- provider,
85
- });
86
- transaction.nonce = String(nonce);
87
- } catch (error) {
88
- return {
89
- error: rpcErrors.internal('Unable to calculate nonce'),
90
- };
91
- }
92
- }
93
-
94
- const transactionType = parseERC20TransactionType(transaction);
95
-
96
- const { transactionValidation, transactionSimulation } = await simulateTransaction({
97
- proxyApiUrl,
98
- chainId: network.chainId,
99
- params: transaction,
100
- dAppUrl: request.dappInfo.url,
101
- });
102
-
103
- // generate display and signing data
104
- // TODO adjust title for different transaction types
105
- // https://ava-labs.atlassian.net/browse/CP-8870
106
- const displayData: DisplayData = {
107
- title: 'Approve Transaction',
108
- network: {
109
- chainId: network.chainId,
110
- name: network.chainName,
111
- logoUri: network.logoUri,
112
- },
113
- transactionDetails: {
114
- website: new URL(dappInfo.url).hostname,
115
- from: transaction.from,
116
- to: transaction.to,
117
- data: transaction.data,
118
- type: transactionType,
119
- },
120
- networkFeeSelector: true,
121
- transactionValidation,
122
- transactionSimulation,
123
- };
124
-
125
- const signingData: SigningData = {
126
- type: SigningDataType.EVM_TRANSACTION,
127
- account: transaction.from,
128
- chainId: network.chainId,
129
- data: {
130
- type: 2, // hardcoding to 2 for now as we only support EIP-1559
131
- nonce: Number(transaction.nonce),
132
- gasLimit: Number(transaction.gas),
133
- to: transaction.to,
134
- from: transaction.from,
135
- data: transaction.data,
136
- value: transaction.value,
137
- chainId: transaction.chainId,
138
- },
139
- };
140
-
141
- // prompt user for approval
142
- const response = await approvalController.requestApproval({ request, displayData, signingData });
143
-
144
- if ('error' in response) {
145
- return {
146
- error: response.error,
147
- };
148
- }
149
-
150
- // broadcast the signed transaction
151
- const txHash = await provider.send('eth_sendRawTransaction', [response.result]);
152
-
153
- waitForTransactionReceipt({
154
- provider,
155
- txHash,
156
- onTransactionConfirmed: approvalController.onTransactionConfirmed,
157
- onTransactionReverted: approvalController.onTransactionReverted,
158
- });
159
-
160
- return { result: txHash };
161
- };
162
-
163
- const waitForTransactionReceipt = async ({
164
- provider,
165
- txHash,
166
- onTransactionConfirmed,
167
- onTransactionReverted,
168
- }: {
169
- provider: JsonRpcBatchInternal;
170
- txHash: Hex;
171
- onTransactionConfirmed: (txHash: Hex) => void;
172
- onTransactionReverted: (txHash: Hex) => void;
173
- }) => {
174
- const receipt = await provider.waitForTransaction(txHash);
175
-
176
- const success = receipt?.status === 1; // 1 indicates success, 0 indicates revert
177
-
178
- if (success) {
179
- onTransactionConfirmed(txHash);
180
- } else {
181
- onTransactionReverted(txHash);
182
- }
183
- };