@deserialize/multi-vm-wallet 1.6.0 → 1.6.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.
@@ -17,6 +17,7 @@ export interface PocketBalance {
17
17
  balances: {
18
18
  token: string;
19
19
  balance: Balance;
20
+ balanceInUsd: number;
20
21
  }[];
21
22
  }
22
23
  export declare class MultiChainSavingsManager {
@@ -25,6 +26,9 @@ export declare class MultiChainSavingsManager {
25
26
  private evmManagers;
26
27
  private svmManagers;
27
28
  private chainConfigs;
29
+ private getTokenKey;
30
+ private normalizePriceMap;
31
+ private getPriceMap;
28
32
  constructor(mnemonic: string, chains: ChainConfig[], walletIndex?: number);
29
33
  addChain(chain: ChainConfig): void;
30
34
  removeChain(chainId: string): void;
@@ -3,12 +3,41 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MultiChainSavingsManager = void 0;
4
4
  const evm_savings_1 = require("./evm-savings");
5
5
  const svm_savings_1 = require("./svm-savings");
6
+ const price_1 = require("../price");
6
7
  class MultiChainSavingsManager {
7
8
  mnemonic;
8
9
  walletIndex;
9
10
  evmManagers = new Map();
10
11
  svmManagers = new Map();
11
12
  chainConfigs = new Map();
13
+ getTokenKey(tokenAddress, chainType) {
14
+ if (chainType === 'EVM') {
15
+ return tokenAddress.toLowerCase();
16
+ }
17
+ return tokenAddress;
18
+ }
19
+ normalizePriceMap(prices, chainType) {
20
+ const priceMap = new Map();
21
+ for (const item of prices) {
22
+ if (!item?.tokenAddress || typeof item.price !== 'number')
23
+ continue;
24
+ priceMap.set(this.getTokenKey(item.tokenAddress, chainType), item.price);
25
+ }
26
+ return priceMap;
27
+ }
28
+ async getPriceMap(chain, tokenAddresses) {
29
+ const chainWithId = chain.config;
30
+ if (typeof chainWithId.chainId !== 'number') {
31
+ return new Map();
32
+ }
33
+ const uniqueTokenAddresses = Array.from(new Set(tokenAddresses));
34
+ const priceResult = await (0, price_1.fetchPrices)({
35
+ vm: chain.type,
36
+ chainId: chainWithId.chainId,
37
+ tokenAddresses: uniqueTokenAddresses
38
+ });
39
+ return this.normalizePriceMap(priceResult.data?.prices ?? [], chain.type);
40
+ }
12
41
  constructor(mnemonic, chains, walletIndex = 0) {
13
42
  if (!mnemonic || typeof mnemonic !== 'string') {
14
43
  throw new Error('Mnemonic must be a non-empty string');
@@ -96,14 +125,21 @@ class MultiChainSavingsManager {
96
125
  const manager = this.evmManagers.get(chainId);
97
126
  const balances = await manager.getPocketBalance(pocketIndex, tokens);
98
127
  const pocket = manager.getPocket(pocketIndex);
128
+ const balanceRows = balances.map(b => ({
129
+ token: b.address === 'native' ? 'native' : b.address,
130
+ balance: b.balance
131
+ }));
132
+ const priceMap = await this.getPriceMap(chain, balanceRows.map(row => row.token));
99
133
  return {
100
134
  chainId,
101
135
  chainType: 'EVM',
102
136
  pocketIndex,
103
137
  address: pocket.address,
104
- balances: balances.map(b => ({
105
- token: b.address === 'native' ? 'native' : b.address,
106
- balance: b.balance
138
+ balances: balanceRows.map(row => ({
139
+ token: row.token,
140
+ balance: row.balance,
141
+ balanceInUsd: row.balance.formatted *
142
+ (priceMap.get(this.getTokenKey(row.token, 'EVM')) ?? 0)
107
143
  }))
108
144
  };
109
145
  }
@@ -111,14 +147,21 @@ class MultiChainSavingsManager {
111
147
  const manager = this.svmManagers.get(chainId);
112
148
  const balances = await manager.getPocketBalance(pocketIndex, tokens);
113
149
  const pocket = manager.getPocket(pocketIndex);
150
+ const balanceRows = balances.map(b => ({
151
+ token: b.address === 'native' ? 'native' : b.address.toBase58(),
152
+ balance: b.balance
153
+ }));
154
+ const priceMap = await this.getPriceMap(chain, balanceRows.map(row => row.token));
114
155
  return {
115
156
  chainId,
116
157
  chainType: 'SVM',
117
158
  pocketIndex,
118
159
  address: pocket.address.toBase58(),
119
- balances: balances.map(b => ({
120
- token: b.address === 'native' ? 'native' : b.address.toBase58(),
121
- balance: b.balance
160
+ balances: balanceRows.map(row => ({
161
+ token: row.token,
162
+ balance: row.balance,
163
+ balanceInUsd: row.balance.formatted *
164
+ (priceMap.get(this.getTokenKey(row.token, 'SVM')) ?? 0)
122
165
  }))
123
166
  };
124
167
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deserialize/multi-vm-wallet",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "devDependencies": {
5
5
  "@types/bn.js": "^5.2.0",
6
6
  "@types/crypto-js": "^4.2.2",
@@ -10,6 +10,7 @@ import { SVMSavingsManager } from "./svm-savings";
10
10
  import { ChainWalletConfig, Balance } from "../types";
11
11
  import { Hex } from "viem";
12
12
  import { PublicKey } from "@solana/web3.js";
13
+ import { fetchPrices } from "../price";
13
14
 
14
15
  /**
15
16
  * Chain type identifier
@@ -46,6 +47,8 @@ export interface PocketBalance {
46
47
  token: string;
47
48
  /** Balance information */
48
49
  balance: Balance;
50
+ /** Balance in USD (if unavailable, defaults to 0) */
51
+ balanceInUsd: number;
49
52
  }[];
50
53
  }
51
54
 
@@ -90,6 +93,44 @@ export class MultiChainSavingsManager {
90
93
  // Track chain configs
91
94
  private chainConfigs: Map<string, ChainConfig> = new Map();
92
95
 
96
+ private getTokenKey(tokenAddress: string, chainType: ChainType): string {
97
+ if (chainType === 'EVM') {
98
+ return tokenAddress.toLowerCase();
99
+ }
100
+ return tokenAddress;
101
+ }
102
+
103
+ private normalizePriceMap(
104
+ prices: Array<{ tokenAddress: string; price: number }>,
105
+ chainType: ChainType
106
+ ): Map<string, number> {
107
+ const priceMap = new Map<string, number>();
108
+ for (const item of prices) {
109
+ if (!item?.tokenAddress || typeof item.price !== 'number') continue;
110
+ priceMap.set(this.getTokenKey(item.tokenAddress, chainType), item.price);
111
+ }
112
+ return priceMap;
113
+ }
114
+
115
+ private async getPriceMap(
116
+ chain: ChainConfig,
117
+ tokenAddresses: string[]
118
+ ): Promise<Map<string, number>> {
119
+ const chainWithId = chain.config as Partial<ChainWalletConfig>;
120
+ if (typeof chainWithId.chainId !== 'number') {
121
+ return new Map();
122
+ }
123
+
124
+ const uniqueTokenAddresses = Array.from(new Set(tokenAddresses));
125
+ const priceResult = await fetchPrices({
126
+ vm: chain.type,
127
+ chainId: chainWithId.chainId,
128
+ tokenAddresses: uniqueTokenAddresses
129
+ });
130
+
131
+ return this.normalizePriceMap(priceResult.data?.prices ?? [], chain.type);
132
+ }
133
+
93
134
  /**
94
135
  * Create a new MultiChainSavingsManager
95
136
  *
@@ -253,30 +294,52 @@ export class MultiChainSavingsManager {
253
294
  const manager = this.evmManagers.get(chainId)!;
254
295
  const balances = await manager.getPocketBalance(pocketIndex, tokens);
255
296
  const pocket = manager.getPocket(pocketIndex);
297
+ const balanceRows = balances.map(b => ({
298
+ token: b.address === 'native' ? 'native' : b.address,
299
+ balance: b.balance
300
+ }));
301
+ const priceMap = await this.getPriceMap(
302
+ chain,
303
+ balanceRows.map(row => row.token)
304
+ );
256
305
 
257
306
  return {
258
307
  chainId,
259
308
  chainType: 'EVM',
260
309
  pocketIndex,
261
310
  address: pocket.address,
262
- balances: balances.map(b => ({
263
- token: b.address === 'native' ? 'native' : b.address,
264
- balance: b.balance
311
+ balances: balanceRows.map(row => ({
312
+ token: row.token,
313
+ balance: row.balance,
314
+ balanceInUsd:
315
+ row.balance.formatted *
316
+ (priceMap.get(this.getTokenKey(row.token, 'EVM')) ?? 0)
265
317
  }))
266
318
  };
267
319
  } else {
268
320
  const manager = this.svmManagers.get(chainId)!;
269
321
  const balances = await manager.getPocketBalance(pocketIndex, tokens);
270
322
  const pocket = manager.getPocket(pocketIndex);
323
+ const balanceRows = balances.map(b => ({
324
+ token: b.address === 'native' ? 'native' : b.address.toBase58(),
325
+ balance: b.balance
326
+ }));
327
+ const priceMap = await this.getPriceMap(
328
+ chain,
329
+ balanceRows.map(row => row.token)
330
+ );
271
331
 
272
332
  return {
273
333
  chainId,
274
334
  chainType: 'SVM',
275
335
  pocketIndex,
276
336
  address: pocket.address.toBase58(),
277
- balances: balances.map(b => ({
278
- token: b.address === 'native' ? 'native' : b.address.toBase58(),
279
- balance: b.balance
337
+ balances: balanceRows.map(row => ({
338
+ token: row.token,
339
+ balance: row.balance,
340
+ balanceInUsd:
341
+ row.balance.formatted *
342
+ (priceMap.get(this.getTokenKey(row.token, 'SVM')) ?? 0)
280
343
  }))
281
344
  };
282
345
  }