@avalabs/evm-module 0.0.21 → 0.0.23

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 (31) hide show
  1. package/.turbo/turbo-build.log +10 -10
  2. package/.turbo/turbo-lint.log +1 -1
  3. package/.turbo/turbo-test.log +8 -5
  4. package/CHANGELOG.md +15 -0
  5. package/dist/index.cjs +19 -21
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +2 -2
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.js +18 -19
  10. package/dist/index.js.map +1 -1
  11. package/manifest.json +10 -1
  12. package/package.json +9 -8
  13. package/src/handlers/forward-to-rpc-node/forward-to-rpc-node.test.ts +90 -0
  14. package/src/handlers/forward-to-rpc-node/forward-to-rpc-node.ts +23 -0
  15. package/src/handlers/get-address/get-address.ts +26 -0
  16. package/src/handlers/get-balances/evm-balance-service/get-erc20-balances.test.ts +3 -4
  17. package/src/handlers/get-balances/evm-balance-service/get-erc20-balances.ts +13 -17
  18. package/src/handlers/get-balances/evm-balance-service/get-native-token-balances.test.ts +4 -5
  19. package/src/handlers/get-balances/evm-balance-service/get-native-token-balances.ts +7 -10
  20. package/src/handlers/get-balances/get-balances.test.ts +10 -11
  21. package/src/handlers/get-balances/get-balances.ts +5 -3
  22. package/src/handlers/get-balances/glacier-balance-service/get-erc20-balances.test.ts +1 -2
  23. package/src/handlers/get-balances/glacier-balance-service/get-erc20-balances.ts +10 -13
  24. package/src/handlers/get-balances/glacier-balance-service/get-native-token-balances.test.ts +2 -3
  25. package/src/handlers/get-balances/glacier-balance-service/get-native-token-balances.ts +10 -9
  26. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-erc20.test.ts +53 -0
  27. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-erc20.ts +3 -5
  28. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-normal.test.ts +57 -0
  29. package/src/handlers/get-transaction-history/converters/etherscan-transaction-converter/convert-transaction-normal.ts +3 -4
  30. package/src/handlers/get-transaction-history/converters/evm-transaction-converter/get-tokens.ts +5 -6
  31. package/src/module.ts +17 -2
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,23 +1,24 @@
1
1
  {
2
2
  "name": "@avalabs/evm-module",
3
- "version": "0.0.21",
3
+ "version": "0.0.23",
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",
10
- "@avalabs/coingecko-sdk": "v2.8.0-alpha.193",
11
- "@avalabs/utils-sdk": "2.8.0-alpha.193",
12
- "@avalabs/etherscan-sdk": "v2.8.0-alpha.193",
13
- "@avalabs/glacier-sdk": "v2.8.0-alpha.193",
14
- "@avalabs/wallets-sdk": "v2.8.0-alpha.193",
9
+ "@avalabs/vm-module-types": "0.0.23",
10
+ "@avalabs/coingecko-sdk": "v2.8.0-alpha.195",
11
+ "@avalabs/utils-sdk": "2.8.0-alpha.195",
12
+ "@avalabs/etherscan-sdk": "v2.8.0-alpha.195",
13
+ "@avalabs/glacier-sdk": "v2.8.0-alpha.195",
14
+ "@avalabs/wallets-sdk": "v2.8.0-alpha.195",
15
15
  "@blockaid/client": "0.11.0",
16
16
  "bn.js": "5.2.1",
17
17
  "lodash.startcase": "4.4.0",
18
18
  "@metamask/rpc-errors": "6.3.0",
19
19
  "zod": "3.23.8",
20
- "@zodios/core": "10.9.6"
20
+ "@zodios/core": "10.9.6",
21
+ "@avalabs/types": "2.8.0-alpha.193"
21
22
  },
22
23
  "devDependencies": {
23
24
  "typechain": "8.3.1",
@@ -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
+ };
@@ -0,0 +1,26 @@
1
+ import { NetworkVMType, WalletType, type GetAddressParams, type GetAddressResponse } from '@avalabs/vm-module-types';
2
+ import { getAddressFromXPub, getEvmAddressFromPubKey } from '@avalabs/wallets-sdk';
3
+ import { rpcErrors } from '@metamask/rpc-errors';
4
+
5
+ type GetAddress = Omit<GetAddressParams, 'isTestnet' | 'xpubXP'>;
6
+
7
+ export const getAddress = async ({ accountIndex, xpub, walletType }: GetAddress): Promise<GetAddressResponse> => {
8
+ switch (walletType) {
9
+ case WalletType.Mnemonic:
10
+ case WalletType.Ledger:
11
+ case WalletType.Keystone: {
12
+ return {
13
+ [NetworkVMType.EVM]: getAddressFromXPub(xpub, accountIndex),
14
+ };
15
+ }
16
+ case WalletType.LedgerLive:
17
+ case WalletType.Seedless: {
18
+ const pubKeyBuffer = Buffer.from(xpub, 'hex');
19
+ return {
20
+ [NetworkVMType.EVM]: getEvmAddressFromPubKey(pubKeyBuffer),
21
+ };
22
+ }
23
+ default:
24
+ throw rpcErrors.invalidParams(`Unsupported wallet type: ${walletType}`);
25
+ }
26
+ };
@@ -1,4 +1,3 @@
1
- import { BN } from 'bn.js';
2
1
  import { getErc20Balances } from './get-erc20-balances';
3
2
  import { ethers } from 'ethers';
4
3
  import { TokenType } from '@avalabs/vm-module-types';
@@ -7,7 +6,7 @@ describe('get-erc20-balances', () => {
7
6
  it('should return erc20 token balances', async () => {
8
7
  jest.spyOn(ethers, 'Contract').mockImplementation(() => {
9
8
  return {
10
- balanceOf: jest.fn().mockResolvedValue(new BN('1000000000000000000')),
9
+ balanceOf: jest.fn().mockResolvedValue(1000000000000000000n),
11
10
  } as never;
12
11
  });
13
12
 
@@ -23,7 +22,7 @@ describe('get-erc20-balances', () => {
23
22
  },
24
23
  ],
25
24
  provider: {
26
- getBalance: jest.fn().mockResolvedValue(new BN('1000000000000000000')),
25
+ getBalance: jest.fn().mockResolvedValue(1000000000000000000n),
27
26
  } as never,
28
27
  tokenService: {
29
28
  getPricesByAddresses: jest.fn().mockResolvedValue({
@@ -63,7 +62,7 @@ describe('get-erc20-balances', () => {
63
62
  symbol: 'ETH',
64
63
  decimals: 18,
65
64
  logoUri: 'https://example.com/logo.png',
66
- balance: new BN('1000000000000000000'),
65
+ balance: 1000000000000000000n,
67
66
  balanceCurrencyDisplayValue: '1000.00',
68
67
  balanceDisplayValue: '1',
69
68
  balanceInCurrency: 1000,
@@ -1,10 +1,9 @@
1
- import { numberToBN, bnToBig, balanceToDisplayValue } from '@avalabs/utils-sdk';
2
- import { TokenType, type ERC20Token, type Network, type TokenWithBalance } from '@avalabs/vm-module-types';
1
+ import { TokenUnit } from '@avalabs/utils-sdk';
2
+ import { type ERC20Token, type Network, TokenType, type TokenWithBalanceEVM } from '@avalabs/vm-module-types';
3
3
  import { ethers, type Provider } from 'ethers';
4
4
  import ERC20 from '@openzeppelin/contracts/build/contracts/ERC20.json';
5
5
  import type { TokenService } from '@internal/utils';
6
6
  import { VsCurrencyType } from '@avalabs/coingecko-sdk';
7
- import BN from 'bn.js';
8
7
 
9
8
  export const getErc20Balances = async ({
10
9
  provider,
@@ -20,7 +19,7 @@ export const getErc20Balances = async ({
20
19
  currency: string;
21
20
  tokens: ERC20Token[];
22
21
  network: Network;
23
- }): Promise<Record<string, TokenWithBalance>> => {
22
+ }): Promise<Record<string, TokenWithBalanceEVM>> => {
24
23
  const coingeckoPlatformId = network.pricingProviders?.coingecko.assetPlatformId;
25
24
  const coingeckoTokenId = network.pricingProviders?.coingecko.nativeTokenId;
26
25
  const tokenAddresses = tokens.map((token) => token.address);
@@ -28,19 +27,17 @@ export const getErc20Balances = async ({
28
27
  const tokensBalances = await Promise.allSettled(
29
28
  tokens.map(async (token) => {
30
29
  const contract = new ethers.Contract(token.address, ERC20.abi, provider);
31
- const balanceBig = await contract.balanceOf?.(userAddress);
32
- const balance = new BN(balanceBig) || numberToBN(0, token.decimals);
30
+ const balanceBig: bigint = await contract.balanceOf?.(userAddress);
31
+ const balance = balanceBig || 0n;
33
32
 
34
- const tokenWithBalance = {
33
+ return {
35
34
  ...token,
36
35
  balance,
37
36
  };
38
-
39
- return tokenWithBalance;
40
37
  }),
41
38
  ).then((res) => {
42
- return res.reduce<(ERC20Token & { balance: BN })[]>((acc, result) => {
43
- return result.status === 'fulfilled' && !result.value.balance.isZero() ? [...acc, result.value] : acc;
39
+ return res.reduce<(ERC20Token & { balance: bigint })[]>((acc, result) => {
40
+ return result.status === 'fulfilled' && result.value.balance !== 0n ? [...acc, result.value] : acc;
44
41
  }, []);
45
42
  });
46
43
 
@@ -58,11 +55,10 @@ export const getErc20Balances = async ({
58
55
  const vol24 = simplePriceResponse?.[coingeckoTokenId ?? '']?.[currency]?.vol24 ?? undefined;
59
56
  const change24 = simplePriceResponse?.[coingeckoTokenId ?? '']?.[currency]?.change24 ?? undefined;
60
57
 
61
- const balanceInCurrency = priceInCurrency
62
- ? bnToBig(token.balance, token.decimals).mul(priceInCurrency).toNumber()
63
- : undefined;
64
- const balanceDisplayValue = balanceToDisplayValue(token.balance, token.decimals);
65
- const balanceCurrencyDisplayValue = balanceInCurrency?.toFixed(2);
58
+ const balance = new TokenUnit(token.balance, token.decimals, token.symbol);
59
+ const balanceCurrencyDisplayValue = priceInCurrency ? balance.mul(priceInCurrency).toDisplay(2) : undefined;
60
+ const balanceInCurrency = balanceCurrencyDisplayValue ? Number(balanceCurrencyDisplayValue) : undefined;
61
+ const balanceDisplayValue = balance.toDisplay();
66
62
 
67
63
  return {
68
64
  ...acc,
@@ -80,6 +76,6 @@ export const getErc20Balances = async ({
80
76
  },
81
77
  };
82
78
  },
83
- {} as Record<string, TokenWithBalance>,
79
+ {} as Record<string, TokenWithBalanceEVM>,
84
80
  );
85
81
  };
@@ -1,11 +1,10 @@
1
- import { BN } from 'bn.js';
2
1
  import { getNativeTokenBalances } from './get-native-token-balances';
3
2
 
4
3
  describe('get-native-token-balances', () => {
5
4
  it('should return native token balances', async () => {
6
5
  const balance = getNativeTokenBalances({
7
6
  provider: {
8
- getBalance: jest.fn().mockResolvedValue(new BN('1000000000000000000')),
7
+ getBalance: jest.fn().mockResolvedValue(1000000000000000000n),
9
8
  } as never,
10
9
  tokenService: {
11
10
  getSimplePrice: jest.fn().mockResolvedValue({
@@ -43,7 +42,7 @@ describe('get-native-token-balances', () => {
43
42
  symbol: 'ETH',
44
43
  decimals: 18,
45
44
  logoUri: 'https://example.com/logo.png',
46
- balance: new BN('1000000000000000000'),
45
+ balance: 1000000000000000000n,
47
46
  balanceCurrencyDisplayValue: '1000.00',
48
47
  balanceDisplayValue: '1',
49
48
  balanceInCurrency: 1000,
@@ -59,7 +58,7 @@ describe('get-native-token-balances', () => {
59
58
  it('should return native token object without balance data', async () => {
60
59
  const balance = getNativeTokenBalances({
61
60
  provider: {
62
- getBalance: jest.fn().mockResolvedValue(new BN('0')),
61
+ getBalance: jest.fn().mockResolvedValue(0n),
63
62
  } as never,
64
63
  tokenService: {
65
64
  getSimplePrice: jest.fn().mockResolvedValue({}),
@@ -87,7 +86,7 @@ describe('get-native-token-balances', () => {
87
86
  symbol: 'ETH',
88
87
  decimals: 18,
89
88
  logoUri: 'https://example.com/logo.png',
90
- balance: new BN('0'),
89
+ balance: 0n,
91
90
  balanceCurrencyDisplayValue: undefined,
92
91
  balanceDisplayValue: '0',
93
92
  coingeckoId: '123',
@@ -1,5 +1,5 @@
1
- import { balanceToDisplayValue, bigToBN, bigintToBig, bnToBig } from '@avalabs/utils-sdk';
2
- import { TokenType, type Network, type NetworkTokenWithBalance } from '@avalabs/vm-module-types';
1
+ import { TokenUnit } from '@avalabs/utils-sdk';
2
+ import { type Network, type NetworkTokenWithBalance, TokenType } from '@avalabs/vm-module-types';
3
3
  import type { VsCurrencyType } from '@avalabs/coingecko-sdk';
4
4
  import { TokenService } from '@internal/utils';
5
5
  import type { Provider } from 'ethers';
@@ -31,14 +31,11 @@ export const getNativeTokenBalances = async ({
31
31
  const vol24 = simplePriceResponse?.[coingeckoTokenId ?? '']?.[currency]?.vol24 ?? undefined;
32
32
  const change24 = simplePriceResponse?.[coingeckoTokenId ?? '']?.[currency]?.change24 ?? undefined;
33
33
 
34
- const balanceBigint = await provider.getBalance(address);
35
- const balaceBig = bigintToBig(balanceBigint, networkToken.decimals);
36
- const balance = bigToBN(balaceBig, networkToken.decimals);
37
- const balanceDisplayValue = balanceToDisplayValue(balance, networkToken.decimals);
38
- const balanceInCurrency = priceInCurrency
39
- ? bnToBig(balance, networkToken.decimals).mul(priceInCurrency).toNumber()
40
- : undefined;
41
- const balanceCurrencyDisplayValue = balanceInCurrency?.toFixed(2);
34
+ const balance = await provider.getBalance(address);
35
+ const balanceUnit = new TokenUnit(balance, networkToken.decimals, networkToken.symbol);
36
+ const balanceDisplayValue = balanceUnit.toDisplay();
37
+ const balanceCurrencyDisplayValue = priceInCurrency ? balanceUnit.mul(priceInCurrency).toDisplay(2) : undefined;
38
+ const balanceInCurrency = balanceCurrencyDisplayValue ? Number(balanceCurrencyDisplayValue) : undefined;
42
39
 
43
40
  return {
44
41
  ...networkToken,
@@ -1,7 +1,6 @@
1
1
  import { NetworkVMType, TokenType } from '@avalabs/vm-module-types';
2
2
  import { getBalances } from './get-balances';
3
3
  import * as GlacierNativeToken from './glacier-balance-service/get-native-token-balances';
4
- import { BN } from 'bn.js';
5
4
  import * as GlacierERC20Token from './glacier-balance-service/get-erc20-balances';
6
5
  import * as EvmNativeToken from './evm-balance-service/get-native-token-balances';
7
6
  import * as EvmERC20Token from './evm-balance-service/get-erc20-balances';
@@ -22,7 +21,7 @@ describe('get-balances', () => {
22
21
  type: TokenType.NATIVE,
23
22
  logoUri:
24
23
  'https://images.ctfassets.net/gcj8jwzm6086/6l56QLVZmvacuBfjHBTThP/791d743dd2c526692562780c2325fedf/eth-circle__1_.svg',
25
- balance: new BN(1),
24
+ balance: 1n,
26
25
  balanceDisplayValue: '1',
27
26
  balanceInCurrency: 1,
28
27
  balanceCurrencyDisplayValue: '1',
@@ -43,7 +42,7 @@ describe('get-balances', () => {
43
42
  symbol: 'DAI',
44
43
  decimals: 18,
45
44
  logoUri: 'https://s3.us-east-2.amazonaws.com/nomics-api/static/images/currencies/dai.svg',
46
- balance: new BN(1),
45
+ balance: 1n,
47
46
  balanceCurrencyDisplayValue: '1',
48
47
  balanceDisplayValue: '1',
49
48
  balanceInCurrency: 1,
@@ -67,7 +66,7 @@ describe('get-balances', () => {
67
66
  decimals: 18,
68
67
  symbol: 'ETH',
69
68
  description:
70
- 'Ether is used to pay for transaction fees and computational services on Etherum. Users can send Ether to other users, and developers can write smart contracts that receive, hold, and send Ether.',
69
+ 'Ether is used to pay for transaction fees and computational services on Ethereum. Users can send Ether to other users, and developers can write smart contracts that receive, hold, and send Ether.',
71
70
  logoUri:
72
71
  'https://images.ctfassets.net/gcj8jwzm6086/6l56QLVZmvacuBfjHBTThP/791d743dd2c526692562780c2325fedf/eth-circle__1_.svg',
73
72
  },
@@ -83,7 +82,7 @@ describe('get-balances', () => {
83
82
  '0x123': {
84
83
  '0x123': {
85
84
  address: '0x123',
86
- balance: new BN(1),
85
+ balance: 1n,
87
86
  balanceCurrencyDisplayValue: '1',
88
87
  balanceDisplayValue: '1',
89
88
  balanceInCurrency: 1,
@@ -99,7 +98,7 @@ describe('get-balances', () => {
99
98
  vol24: 0,
100
99
  },
101
100
  ETH: {
102
- balance: new BN(1),
101
+ balance: 1n,
103
102
  balanceCurrencyDisplayValue: '1',
104
103
  balanceDisplayValue: '1',
105
104
  balanceInCurrency: 1,
@@ -150,7 +149,7 @@ describe('get-balances', () => {
150
149
  type: TokenType.NATIVE,
151
150
  logoUri:
152
151
  'https://images.ctfassets.net/gcj8jwzm6086/6l56QLVZmvacuBfjHBTThP/791d743dd2c526692562780c2325fedf/eth-circle__1_.svg',
153
- balance: new BN(1),
152
+ balance: 1n,
154
153
  balanceDisplayValue: '1',
155
154
  balanceInCurrency: 1,
156
155
  balanceCurrencyDisplayValue: '1',
@@ -171,7 +170,7 @@ describe('get-balances', () => {
171
170
  symbol: 'DAI2',
172
171
  decimals: 18,
173
172
  logoUri: 'https://s3.us-east-2.amazonaws.com/nomics-api/static/images/currencies/dai.svg',
174
- balance: new BN(1),
173
+ balance: 1n,
175
174
  balanceCurrencyDisplayValue: '1',
176
175
  balanceDisplayValue: '1',
177
176
  balanceInCurrency: 1,
@@ -195,7 +194,7 @@ describe('get-balances', () => {
195
194
  decimals: 18,
196
195
  symbol: 'ETH2',
197
196
  description:
198
- 'Ether is used to pay for transaction fees and computational services on Etherum. Users can send Ether to other users, and developers can write smart contracts that receive, hold, and send Ether.',
197
+ 'Ether is used to pay for transaction fees and computational services on Ethereum. Users can send Ether to other users, and developers can write smart contracts that receive, hold, and send Ether.',
199
198
  logoUri:
200
199
  'https://images.ctfassets.net/gcj8jwzm6086/6l56QLVZmvacuBfjHBTThP/791d743dd2c526692562780c2325fedf/eth-circle__1_.svg',
201
200
  },
@@ -211,7 +210,7 @@ describe('get-balances', () => {
211
210
  '0x456': {
212
211
  '0x456': {
213
212
  address: '0x456',
214
- balance: new BN(1),
213
+ balance: 1n,
215
214
  balanceCurrencyDisplayValue: '1',
216
215
  balanceDisplayValue: '1',
217
216
  balanceInCurrency: 1,
@@ -227,7 +226,7 @@ describe('get-balances', () => {
227
226
  vol24: 0,
228
227
  },
229
228
  ETH2: {
230
- balance: new BN(1),
229
+ balance: 1n,
231
230
  balanceCurrencyDisplayValue: '1',
232
231
  balanceDisplayValue: '1',
233
232
  balanceInCurrency: 1,
@@ -1,10 +1,10 @@
1
1
  import {
2
- type GetBalancesResponse,
3
2
  type GetBalancesParams,
4
3
  type Storage,
5
4
  TokenType,
6
5
  type NetworkContractToken,
7
6
  type ERC20Token,
7
+ type TokenWithBalanceEVM,
8
8
  } from '@avalabs/vm-module-types';
9
9
  import { getErc20Balances } from './evm-balance-service/get-erc20-balances';
10
10
  import { TokenService } from '@internal/utils';
@@ -15,6 +15,8 @@ import { getNativeTokenBalances as getNativeTokenBalancesFromGlacier } from './g
15
15
  import { getErc20Balances as getErc20BalancesFromGlacier } from './glacier-balance-service/get-erc20-balances';
16
16
  import type { EvmGlacierService } from '../../services/glacier-service/glacier-service';
17
17
 
18
+ type GetEvmBalancesResponse = Record<string, Record<string, TokenWithBalanceEVM>>;
19
+
18
20
  export const getBalances = async ({
19
21
  addresses,
20
22
  currency,
@@ -27,7 +29,7 @@ export const getBalances = async ({
27
29
  proxyApiUrl: string;
28
30
  glacierService: EvmGlacierService;
29
31
  storage?: Storage;
30
- }): Promise<GetBalancesResponse> => {
32
+ }): Promise<GetEvmBalancesResponse> => {
31
33
  const chainId = network.chainId;
32
34
  const isNetworkSupported = await glacierService.isNetworkSupported(network.chainId);
33
35
  const isHealthy = glacierService.isHealthy();
@@ -111,7 +113,7 @@ export const getBalances = async ({
111
113
  ...acc,
112
114
  [result.value.address]: result.value.balances,
113
115
  };
114
- }, {} as GetBalancesResponse);
116
+ }, {} as GetEvmBalancesResponse);
115
117
 
116
118
  return filterBalances;
117
119
  };
@@ -1,4 +1,3 @@
1
- import { BN } from 'bn.js';
2
1
  import { getErc20Balances } from './get-erc20-balances';
3
2
  import type { EvmGlacierService } from '../../../services/glacier-service/glacier-service';
4
3
 
@@ -45,7 +44,7 @@ describe('get-erc20-balances', () => {
45
44
  symbol: 'ETH',
46
45
  decimals: 18,
47
46
  logoUri: 'https://example.com/logo.png',
48
- balance: new BN('1000000000000000000'),
47
+ balance: 1000000000000000000n,
49
48
  balanceCurrencyDisplayValue: '1000',
50
49
  balanceDisplayValue: '1',
51
50
  balanceInCurrency: 1000,
@@ -1,12 +1,11 @@
1
- import { balanceToDisplayValue, bnToBig } from '@avalabs/utils-sdk';
1
+ import { TokenUnit } from '@avalabs/utils-sdk';
2
2
  import {
3
+ type ERC20Token,
3
4
  TokenType,
5
+ type TokenWithBalanceEVM,
4
6
  type TokenWithBalanceERC20,
5
- type TokenWithBalance,
6
- type ERC20Token,
7
7
  } from '@avalabs/vm-module-types';
8
8
  import { CurrencyCode, Erc20TokenBalance } from '@avalabs/glacier-sdk';
9
- import BN from 'bn.js';
10
9
  import type { EvmGlacierService } from '../../../services/glacier-service/glacier-service';
11
10
  import { DEFAULT_DECIMALS } from '../../../constants';
12
11
 
@@ -22,7 +21,7 @@ export const getErc20Balances = async ({
22
21
  currency: string;
23
22
  chainId: number;
24
23
  customTokens: ERC20Token[];
25
- }): Promise<Record<string, TokenWithBalance>> => {
24
+ }): Promise<Record<string, TokenWithBalanceEVM>> => {
26
25
  const tokensWithBalance: TokenWithBalanceERC20[] = [];
27
26
  /**
28
27
  * Load all pages to make sure we have all the tokens with balances
@@ -56,7 +55,7 @@ export const getErc20Balances = async ({
56
55
  (acc, token) => {
57
56
  return { ...acc, [token.address.toLowerCase()]: token };
58
57
  },
59
- {} as Record<string, TokenWithBalance>,
58
+ {} as Record<string, TokenWithBalanceEVM>,
60
59
  );
61
60
  };
62
61
 
@@ -66,7 +65,7 @@ const convertErc20TokenToTokenWithBalance = (tokens: ERC20Token[]): TokenWithBal
66
65
  ...token,
67
66
  decimals: token.decimals ?? DEFAULT_DECIMALS,
68
67
  type: TokenType.ERC20,
69
- balance: new BN(0),
68
+ balance: 0n,
70
69
  balanceInCurrency: 0,
71
70
  balanceDisplayValue: '0',
72
71
  balanceCurrencyDisplayValue: '0',
@@ -83,13 +82,11 @@ const convertErc20TokenWithBalanceToTokenWithBalance = (
83
82
  chainId: number,
84
83
  ): TokenWithBalanceERC20[] => {
85
84
  return tokenBalances.map((token: Erc20TokenBalance): TokenWithBalanceERC20 => {
86
- const balance = new BN(token.balance);
87
- const balanceDisplayValue = balanceToDisplayValue(balance, token.decimals);
85
+ const balance = new TokenUnit(token.balance, token.decimals, token.symbol);
86
+ const balanceDisplayValue = balance.toDisplay();
88
87
  const balanceCurrencyDisplayValue = token.balanceValue?.value.toString();
89
88
  const priceInCurrency = token.price?.value;
90
- const balanceInCurrency = priceInCurrency
91
- ? bnToBig(balance, token.decimals).mul(priceInCurrency).toNumber()
92
- : undefined;
89
+ const balanceInCurrency = priceInCurrency ? Number(balance.mul(priceInCurrency).toDisplay(2)) : undefined;
93
90
 
94
91
  return {
95
92
  chainId,
@@ -98,7 +95,7 @@ const convertErc20TokenWithBalanceToTokenWithBalance = (
98
95
  symbol: token.symbol,
99
96
  decimals: token.decimals,
100
97
  logoUri: token.logoUri,
101
- balance,
98
+ balance: balance.toSubUnit(),
102
99
  balanceCurrencyDisplayValue,
103
100
  balanceDisplayValue,
104
101
  balanceInCurrency,
@@ -1,4 +1,3 @@
1
- import { BN } from 'bn.js';
2
1
  import { getNativeTokenBalances } from './get-native-token-balances';
3
2
  import type { EvmGlacierService } from '../../../services/glacier-service/glacier-service';
4
3
 
@@ -8,7 +7,7 @@ describe('get-native-token-balances', () => {
8
7
  ...expect.any(Object),
9
8
  getNativeBalance: jest.fn().mockResolvedValue({
10
9
  nativeTokenBalance: {
11
- balance: new BN('1000000000000000000'),
10
+ balance: 1000000000000000000n,
12
11
  decimals: 18,
13
12
  name: 'Ethereum',
14
13
  symbol: 'ETH',
@@ -34,7 +33,7 @@ describe('get-native-token-balances', () => {
34
33
  decimals: 18,
35
34
  type: 'NATIVE',
36
35
  logoUri: 'https://example.com/logo.png',
37
- balance: new BN('1000000000000000000'),
36
+ balance: 1000000000000000000n,
38
37
  balanceDisplayValue: '1',
39
38
  balanceInCurrency: 1000,
40
39
  balanceCurrencyDisplayValue: '1000.00',
@@ -1,7 +1,6 @@
1
1
  import type { CurrencyCode } from '@avalabs/glacier-sdk';
2
2
  import { TokenType, type NetworkTokenWithBalance } from '@avalabs/vm-module-types';
3
- import { balanceToDisplayValue, bnToBig } from '@avalabs/utils-sdk';
4
- import { BN } from 'bn.js';
3
+ import { TokenUnit } from '@avalabs/utils-sdk';
5
4
  import type { EvmGlacierService } from '../../../services/glacier-service/glacier-service';
6
5
 
7
6
  export const getNativeTokenBalances = async ({
@@ -23,13 +22,15 @@ export const getNativeTokenBalances = async ({
23
22
  currency: currency.toLocaleLowerCase() as CurrencyCode,
24
23
  });
25
24
  const nativeTokenBalance = nativeBalance.nativeTokenBalance;
26
- const balance = new BN(nativeTokenBalance.balance);
27
- const balanceDisplayValue = balanceToDisplayValue(balance, nativeTokenBalance.decimals);
25
+ const balanceTokenUnit = new TokenUnit(
26
+ nativeTokenBalance.balance,
27
+ nativeTokenBalance.decimals,
28
+ nativeTokenBalance.symbol,
29
+ );
30
+ const balanceDisplayValue = balanceTokenUnit.toDisplay();
28
31
  const priceInCurrency = nativeTokenBalance.price?.value;
29
- const balanceInCurrency = priceInCurrency
30
- ? bnToBig(balance, nativeTokenBalance.decimals).mul(priceInCurrency).toNumber()
31
- : undefined;
32
- const balanceCurrencyDisplayValue = balanceInCurrency?.toFixed(2);
32
+ const balanceCurrencyDisplayValue = priceInCurrency ? balanceTokenUnit.mul(priceInCurrency).toDisplay(2) : undefined;
33
+ const balanceInCurrency = balanceCurrencyDisplayValue ? Number(balanceCurrencyDisplayValue) : undefined;
33
34
 
34
35
  return {
35
36
  name: nativeTokenBalance.name,
@@ -37,7 +38,7 @@ export const getNativeTokenBalances = async ({
37
38
  decimals: nativeTokenBalance.decimals,
38
39
  type: TokenType.NATIVE,
39
40
  logoUri: nativeTokenBalance.logoUri,
40
- balance,
41
+ balance: balanceTokenUnit.toSubUnit(),
41
42
  balanceDisplayValue,
42
43
  balanceInCurrency,
43
44
  balanceCurrencyDisplayValue,