@avalabs/evm-module 0.0.21 → 0.0.22

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/manifest.json CHANGED
@@ -32,7 +32,16 @@
32
32
  "permissions": {
33
33
  "rpc": {
34
34
  "dapps": true,
35
- "methods": ["eth_sendTransaction", "eth_*", "personal_sign"]
35
+ "methods": [
36
+ "personal_sign",
37
+ "eth_sendTransaction",
38
+ "eth_*",
39
+ "web3_clientVersion",
40
+ "web3_sha3",
41
+ "net_version",
42
+ "net_peerCount",
43
+ "net_listening"
44
+ ]
36
45
  }
37
46
  },
38
47
  "manifestVersion": "0.0"
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@avalabs/evm-module",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "main": "dist/index.cjs",
5
5
  "module": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "dependencies": {
9
- "@avalabs/vm-module-types": "0.0.21",
9
+ "@avalabs/vm-module-types": "0.0.22",
10
10
  "@avalabs/coingecko-sdk": "v2.8.0-alpha.193",
11
11
  "@avalabs/utils-sdk": "2.8.0-alpha.193",
12
12
  "@avalabs/etherscan-sdk": "v2.8.0-alpha.193",
@@ -0,0 +1,90 @@
1
+ import { forwardToRpcNode } from './forward-to-rpc-node';
2
+ import { getProvider } from '../../utils/get-provider';
3
+ import { rpcErrors } from '@metamask/rpc-errors';
4
+ import { NetworkVMType, RpcMethod } from '@avalabs/vm-module-types';
5
+
6
+ jest.mock('../../utils/get-provider');
7
+ jest.mock('@metamask/rpc-errors', () => ({
8
+ rpcErrors: {
9
+ internal: jest.fn().mockImplementation((message) => ({ error: `mocked error: ${message}` })),
10
+ },
11
+ }));
12
+
13
+ const mockProvider = {
14
+ send: jest.fn(),
15
+ };
16
+
17
+ const network = {
18
+ chainId: 1,
19
+ chainName: 'mainnet',
20
+ rpcUrl: 'https://example.com',
21
+ networkToken: {
22
+ name: 'ethereum',
23
+ symbol: 'ETH',
24
+ decimals: 18,
25
+ },
26
+ vmName: NetworkVMType.EVM,
27
+ };
28
+
29
+ describe('forwardToRpcNode', () => {
30
+ beforeEach(() => {
31
+ jest.clearAllMocks();
32
+ (getProvider as jest.Mock).mockReturnValue(mockProvider);
33
+ });
34
+
35
+ it('should forward the request and return the result on success', async () => {
36
+ const request = {
37
+ method: 'eth_chainId' as RpcMethod,
38
+ params: [1, 2],
39
+ requestId: 'requestId',
40
+ sessionId: 'sessionId',
41
+ chainId: 'eip155:1',
42
+ dappInfo: {
43
+ name: 'some dapp',
44
+ url: 'some url',
45
+ icon: 'some icon',
46
+ },
47
+ };
48
+
49
+ const expectedResult = '0x1';
50
+
51
+ mockProvider.send.mockResolvedValue(expectedResult);
52
+
53
+ const result = await forwardToRpcNode(request, network);
54
+
55
+ expect(getProvider).toHaveBeenCalledWith({
56
+ chainId: network.chainId,
57
+ chainName: network.chainName,
58
+ rpcUrl: network.rpcUrl,
59
+ multiContractAddress: undefined,
60
+ pollingInterval: 1000,
61
+ });
62
+ expect(mockProvider.send).toHaveBeenCalledWith(request.method, request.params);
63
+ expect(result).toEqual({ result: expectedResult });
64
+ });
65
+
66
+ it('should handle errors and return a formatted error response', async () => {
67
+ const request = {
68
+ method: 'eth_accounts' as RpcMethod,
69
+ params: [],
70
+ requestId: 'requestId',
71
+ sessionId: 'sessionId',
72
+ chainId: 'eip155:1',
73
+ dappInfo: {
74
+ name: 'some dapp',
75
+ url: 'some url',
76
+ icon: 'some icon',
77
+ },
78
+ };
79
+
80
+ const error = new Error('Test error');
81
+
82
+ mockProvider.send.mockRejectedValue(error);
83
+
84
+ const result = await forwardToRpcNode(request, network);
85
+
86
+ expect(rpcErrors.internal).toHaveBeenCalledWith(error.message);
87
+ expect(result).toHaveProperty('error');
88
+ expect(result.error).toEqual({ error: `mocked error: ${error.message}` });
89
+ });
90
+ });
@@ -0,0 +1,23 @@
1
+ import type { Network, RpcRequest } from '@avalabs/vm-module-types';
2
+ import { rpcErrors } from '@metamask/rpc-errors';
3
+ import { getProvider } from '../../utils/get-provider';
4
+
5
+ export const forwardToRpcNode = async (request: RpcRequest, network: Network) => {
6
+ try {
7
+ const provider = getProvider({
8
+ chainId: network.chainId,
9
+ chainName: network.chainName,
10
+ rpcUrl: network.rpcUrl,
11
+ multiContractAddress: network.utilityAddresses?.multicall,
12
+ pollingInterval: 1000,
13
+ });
14
+
15
+ const response = await provider.send(request.method, request.params as unknown[]);
16
+ return { result: response };
17
+ } catch (error) {
18
+ // extracting the error message based on the error object structure from ethers lib
19
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
20
+ const message = (error as any).info?.error?.message || (error as any).error?.message || (error as Error).message;
21
+ return { error: rpcErrors.internal(message) };
22
+ }
23
+ };
package/src/module.ts CHANGED
@@ -21,6 +21,7 @@ import { getBalances } from './handlers/get-balances/get-balances';
21
21
  import { getEnv } from './env';
22
22
  import { EvmGlacierService } from './services/glacier-service/glacier-service';
23
23
  import { ethSign } from './handlers/eth-sign/eth-sign';
24
+ import { forwardToRpcNode } from './handlers/forward-to-rpc-node/forward-to-rpc-node';
24
25
 
25
26
  export class EvmModule implements Module {
26
27
  #glacierService: EvmGlacierService;
@@ -120,7 +121,18 @@ export class EvmModule implements Module {
120
121
  proxyApiUrl: this.#proxyApiUrl,
121
122
  });
122
123
  default:
124
+ if (shouldForwardToRpcNode(request.method)) {
125
+ return forwardToRpcNode(request, network);
126
+ }
127
+
123
128
  return { error: rpcErrors.methodNotSupported(`Method ${request.method} not supported`) };
124
129
  }
125
130
  }
126
131
  }
132
+
133
+ const shouldForwardToRpcNode = (method: RpcMethod) => {
134
+ return (
135
+ method.startsWith('eth_') ||
136
+ ['web3_clientVersion', 'web3_sha3', 'net_version', 'net_peerCount', 'net_listening'].includes(method)
137
+ );
138
+ };