@pioneer-platform/pioneer-sdk 8.15.33 → 8.15.34

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/dist/index.cjs CHANGED
@@ -436,6 +436,17 @@ function processPortfolioBalance(balance, primaryAddress, context, blockchains)
436
436
  console.log(tag2, `Calculated price from value/balance: ${calculatedPrice} for ${balance.caip}`);
437
437
  }
438
438
  }
439
+ const decimals = assetInfo?.decimals ?? assetInfo?.decimal ?? balance.decimals ?? balance.decimal;
440
+ if (decimals === undefined || decimals === null) {
441
+ throw new Error(`CRITICAL: Asset ${balance.caip} (${assetInfo?.symbol || balance.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({
442
+ caip: balance.caip,
443
+ symbol: assetInfo?.symbol || balance.symbol,
444
+ hasAssetInfoDecimals: !!assetInfo?.decimals,
445
+ hasAssetInfoDecimal: !!assetInfo?.decimal,
446
+ hasBalanceDecimals: !!balance.decimals,
447
+ hasBalanceDecimal: !!balance.decimal
448
+ })}`);
449
+ }
439
450
  const chartBalance = {
440
451
  context,
441
452
  chart: "pioneer",
@@ -452,7 +463,9 @@ function processPortfolioBalance(balance, primaryAddress, context, blockchains)
452
463
  symbol: assetInfo?.symbol || balance.symbol || "UNK",
453
464
  type: balanceType,
454
465
  token: isToken,
455
- decimal: assetInfo?.decimal || balance.decimal,
466
+ decimal: decimals,
467
+ decimals,
468
+ precision: decimals,
456
469
  balance: balance.balance.toString(),
457
470
  price: calculatedPrice,
458
471
  priceUsd: calculatedPrice,
@@ -483,6 +496,17 @@ function processPortfolioToken(token, primaryAddress, context, blockchains) {
483
496
  }
484
497
  const tokenAssetInfo = hydrateAssetData(token.assetCaip);
485
498
  const tokenPubkey = token.pubkey || primaryAddress;
499
+ const tokenDecimals = tokenAssetInfo?.decimals ?? tokenAssetInfo?.decimal ?? token.token?.decimals ?? token.token?.decimal;
500
+ if (tokenDecimals === undefined || tokenDecimals === null) {
501
+ throw new Error(`CRITICAL: Token ${token.assetCaip} (${tokenAssetInfo?.symbol || token.token?.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Token data: ${JSON.stringify({
502
+ caip: token.assetCaip,
503
+ symbol: tokenAssetInfo?.symbol || token.token?.symbol,
504
+ hasAssetInfoDecimals: !!tokenAssetInfo?.decimals,
505
+ hasAssetInfoDecimal: !!tokenAssetInfo?.decimal,
506
+ hasTokenDecimals: !!token.token?.decimals,
507
+ hasTokenDecimal: !!token.token?.decimal
508
+ })}`);
509
+ }
486
510
  const chartBalance = {
487
511
  context,
488
512
  chart: "pioneer",
@@ -498,7 +522,9 @@ function processPortfolioToken(token, primaryAddress, context, blockchains) {
498
522
  symbol: tokenAssetInfo?.symbol || token.token?.symbol || "UNK",
499
523
  type: tokenAssetInfo?.type || "token",
500
524
  token: true,
501
- decimal: tokenAssetInfo?.decimal || token.token?.decimal,
525
+ decimal: tokenDecimals,
526
+ decimals: tokenDecimals,
527
+ precision: tokenDecimals,
502
528
  balance: token.token?.balance?.toString() || "0",
503
529
  priceUsd: token.token?.price || 0,
504
530
  valueUsd: token.token?.balanceUSD || 0,
@@ -605,6 +631,17 @@ async function getMayaCharts(params, existingBalances) {
605
631
  }
606
632
  const mayaAssetInfo = hydrateAssetData(mayaBalance.caip);
607
633
  const isToken = mayaBalance.caip.includes("/denom:") && !mayaBalance.caip.endsWith("/denom:cacao");
634
+ const decimals = mayaAssetInfo?.decimals ?? mayaAssetInfo?.decimal ?? mayaBalance.decimals ?? mayaBalance.decimal;
635
+ if (decimals === undefined || decimals === null) {
636
+ throw new Error(`CRITICAL: Asset ${mayaBalance.caip} (${mayaAssetInfo?.symbol || "MAYA"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({
637
+ caip: mayaBalance.caip,
638
+ symbol: mayaAssetInfo?.symbol,
639
+ hasAssetInfoDecimals: !!mayaAssetInfo?.decimals,
640
+ hasAssetInfoDecimal: !!mayaAssetInfo?.decimal,
641
+ hasBalanceDecimals: !!mayaBalance.decimals,
642
+ hasBalanceDecimal: !!mayaBalance.decimal
643
+ })}`);
644
+ }
608
645
  const mayaTokenBalance = {
609
646
  context,
610
647
  chart: "pioneer",
@@ -620,7 +657,9 @@ async function getMayaCharts(params, existingBalances) {
620
657
  symbol: mayaAssetInfo?.symbol || "MAYA",
621
658
  type: mayaAssetInfo?.type || "token",
622
659
  token: isToken,
623
- decimal: mayaAssetInfo?.decimal,
660
+ decimal: decimals,
661
+ decimals,
662
+ precision: decimals,
624
663
  balance: mayaBalance.balance?.toString() || "0",
625
664
  priceUsd: parseFloat(mayaBalance.priceUsd) || 0,
626
665
  valueUsd: parseFloat(mayaBalance.valueUsd) || 0,
@@ -4404,6 +4443,10 @@ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4404
4443
  const explorerUrls = EXPLORER_BASE_URLS[networkId];
4405
4444
  const explorerAddressLink = explorerUrls && balance.pubkey ? explorerUrls.address + balance.pubkey : undefined;
4406
4445
  const explorerTxLink = explorerUrls?.tx;
4446
+ const decimals = assetInfo.decimals ?? balance.decimals;
4447
+ if (decimals === undefined || decimals === null) {
4448
+ throw new Error(`CRITICAL: Asset ${balance.caip} (${assetInfo.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `AssetInfo is incomplete. This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({ caip: balance.caip, symbol: assetInfo.symbol, hasDecimals: !!assetInfo.decimals })}`);
4449
+ }
4407
4450
  Object.assign(balance, assetInfo, {
4408
4451
  type: balance.type || assetInfo.type,
4409
4452
  isNative: balance.isNative ?? assetInfo.isNative,
@@ -4412,7 +4455,8 @@ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4412
4455
  identifier: `${balance.caip}:${balance.pubkey}`,
4413
4456
  updated: Date.now(),
4414
4457
  color: assetInfo.color,
4415
- decimals: assetInfo.decimals || balance.decimals || 8,
4458
+ decimals,
4459
+ precision: decimals,
4416
4460
  explorerAddressLink,
4417
4461
  explorerTxLink,
4418
4462
  explorer: explorerUrls?.address,
package/dist/index.es.js CHANGED
@@ -427,6 +427,17 @@ function processPortfolioBalance(balance, primaryAddress, context, blockchains)
427
427
  console.log(tag2, `Calculated price from value/balance: ${calculatedPrice} for ${balance.caip}`);
428
428
  }
429
429
  }
430
+ const decimals = assetInfo?.decimals ?? assetInfo?.decimal ?? balance.decimals ?? balance.decimal;
431
+ if (decimals === undefined || decimals === null) {
432
+ throw new Error(`CRITICAL: Asset ${balance.caip} (${assetInfo?.symbol || balance.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({
433
+ caip: balance.caip,
434
+ symbol: assetInfo?.symbol || balance.symbol,
435
+ hasAssetInfoDecimals: !!assetInfo?.decimals,
436
+ hasAssetInfoDecimal: !!assetInfo?.decimal,
437
+ hasBalanceDecimals: !!balance.decimals,
438
+ hasBalanceDecimal: !!balance.decimal
439
+ })}`);
440
+ }
430
441
  const chartBalance = {
431
442
  context,
432
443
  chart: "pioneer",
@@ -443,7 +454,9 @@ function processPortfolioBalance(balance, primaryAddress, context, blockchains)
443
454
  symbol: assetInfo?.symbol || balance.symbol || "UNK",
444
455
  type: balanceType,
445
456
  token: isToken,
446
- decimal: assetInfo?.decimal || balance.decimal,
457
+ decimal: decimals,
458
+ decimals,
459
+ precision: decimals,
447
460
  balance: balance.balance.toString(),
448
461
  price: calculatedPrice,
449
462
  priceUsd: calculatedPrice,
@@ -474,6 +487,17 @@ function processPortfolioToken(token, primaryAddress, context, blockchains) {
474
487
  }
475
488
  const tokenAssetInfo = hydrateAssetData(token.assetCaip);
476
489
  const tokenPubkey = token.pubkey || primaryAddress;
490
+ const tokenDecimals = tokenAssetInfo?.decimals ?? tokenAssetInfo?.decimal ?? token.token?.decimals ?? token.token?.decimal;
491
+ if (tokenDecimals === undefined || tokenDecimals === null) {
492
+ throw new Error(`CRITICAL: Token ${token.assetCaip} (${tokenAssetInfo?.symbol || token.token?.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Token data: ${JSON.stringify({
493
+ caip: token.assetCaip,
494
+ symbol: tokenAssetInfo?.symbol || token.token?.symbol,
495
+ hasAssetInfoDecimals: !!tokenAssetInfo?.decimals,
496
+ hasAssetInfoDecimal: !!tokenAssetInfo?.decimal,
497
+ hasTokenDecimals: !!token.token?.decimals,
498
+ hasTokenDecimal: !!token.token?.decimal
499
+ })}`);
500
+ }
477
501
  const chartBalance = {
478
502
  context,
479
503
  chart: "pioneer",
@@ -489,7 +513,9 @@ function processPortfolioToken(token, primaryAddress, context, blockchains) {
489
513
  symbol: tokenAssetInfo?.symbol || token.token?.symbol || "UNK",
490
514
  type: tokenAssetInfo?.type || "token",
491
515
  token: true,
492
- decimal: tokenAssetInfo?.decimal || token.token?.decimal,
516
+ decimal: tokenDecimals,
517
+ decimals: tokenDecimals,
518
+ precision: tokenDecimals,
493
519
  balance: token.token?.balance?.toString() || "0",
494
520
  priceUsd: token.token?.price || 0,
495
521
  valueUsd: token.token?.balanceUSD || 0,
@@ -596,6 +622,17 @@ async function getMayaCharts(params, existingBalances) {
596
622
  }
597
623
  const mayaAssetInfo = hydrateAssetData(mayaBalance.caip);
598
624
  const isToken = mayaBalance.caip.includes("/denom:") && !mayaBalance.caip.endsWith("/denom:cacao");
625
+ const decimals = mayaAssetInfo?.decimals ?? mayaAssetInfo?.decimal ?? mayaBalance.decimals ?? mayaBalance.decimal;
626
+ if (decimals === undefined || decimals === null) {
627
+ throw new Error(`CRITICAL: Asset ${mayaBalance.caip} (${mayaAssetInfo?.symbol || "MAYA"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({
628
+ caip: mayaBalance.caip,
629
+ symbol: mayaAssetInfo?.symbol,
630
+ hasAssetInfoDecimals: !!mayaAssetInfo?.decimals,
631
+ hasAssetInfoDecimal: !!mayaAssetInfo?.decimal,
632
+ hasBalanceDecimals: !!mayaBalance.decimals,
633
+ hasBalanceDecimal: !!mayaBalance.decimal
634
+ })}`);
635
+ }
599
636
  const mayaTokenBalance = {
600
637
  context,
601
638
  chart: "pioneer",
@@ -611,7 +648,9 @@ async function getMayaCharts(params, existingBalances) {
611
648
  symbol: mayaAssetInfo?.symbol || "MAYA",
612
649
  type: mayaAssetInfo?.type || "token",
613
650
  token: isToken,
614
- decimal: mayaAssetInfo?.decimal,
651
+ decimal: decimals,
652
+ decimals,
653
+ precision: decimals,
615
654
  balance: mayaBalance.balance?.toString() || "0",
616
655
  priceUsd: parseFloat(mayaBalance.priceUsd) || 0,
617
656
  valueUsd: parseFloat(mayaBalance.valueUsd) || 0,
@@ -4588,6 +4627,10 @@ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4588
4627
  const explorerUrls = EXPLORER_BASE_URLS[networkId];
4589
4628
  const explorerAddressLink = explorerUrls && balance.pubkey ? explorerUrls.address + balance.pubkey : undefined;
4590
4629
  const explorerTxLink = explorerUrls?.tx;
4630
+ const decimals = assetInfo.decimals ?? balance.decimals;
4631
+ if (decimals === undefined || decimals === null) {
4632
+ throw new Error(`CRITICAL: Asset ${balance.caip} (${assetInfo.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `AssetInfo is incomplete. This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({ caip: balance.caip, symbol: assetInfo.symbol, hasDecimals: !!assetInfo.decimals })}`);
4633
+ }
4591
4634
  Object.assign(balance, assetInfo, {
4592
4635
  type: balance.type || assetInfo.type,
4593
4636
  isNative: balance.isNative ?? assetInfo.isNative,
@@ -4596,7 +4639,8 @@ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4596
4639
  identifier: `${balance.caip}:${balance.pubkey}`,
4597
4640
  updated: Date.now(),
4598
4641
  color: assetInfo.color,
4599
- decimals: assetInfo.decimals || balance.decimals || 8,
4642
+ decimals,
4643
+ precision: decimals,
4600
4644
  explorerAddressLink,
4601
4645
  explorerTxLink,
4602
4646
  explorer: explorerUrls?.address,
package/dist/index.js CHANGED
@@ -427,6 +427,17 @@ function processPortfolioBalance(balance, primaryAddress, context, blockchains)
427
427
  console.log(tag2, `Calculated price from value/balance: ${calculatedPrice} for ${balance.caip}`);
428
428
  }
429
429
  }
430
+ const decimals = assetInfo?.decimals ?? assetInfo?.decimal ?? balance.decimals ?? balance.decimal;
431
+ if (decimals === undefined || decimals === null) {
432
+ throw new Error(`CRITICAL: Asset ${balance.caip} (${assetInfo?.symbol || balance.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({
433
+ caip: balance.caip,
434
+ symbol: assetInfo?.symbol || balance.symbol,
435
+ hasAssetInfoDecimals: !!assetInfo?.decimals,
436
+ hasAssetInfoDecimal: !!assetInfo?.decimal,
437
+ hasBalanceDecimals: !!balance.decimals,
438
+ hasBalanceDecimal: !!balance.decimal
439
+ })}`);
440
+ }
430
441
  const chartBalance = {
431
442
  context,
432
443
  chart: "pioneer",
@@ -443,7 +454,9 @@ function processPortfolioBalance(balance, primaryAddress, context, blockchains)
443
454
  symbol: assetInfo?.symbol || balance.symbol || "UNK",
444
455
  type: balanceType,
445
456
  token: isToken,
446
- decimal: assetInfo?.decimal || balance.decimal,
457
+ decimal: decimals,
458
+ decimals,
459
+ precision: decimals,
447
460
  balance: balance.balance.toString(),
448
461
  price: calculatedPrice,
449
462
  priceUsd: calculatedPrice,
@@ -474,6 +487,17 @@ function processPortfolioToken(token, primaryAddress, context, blockchains) {
474
487
  }
475
488
  const tokenAssetInfo = hydrateAssetData(token.assetCaip);
476
489
  const tokenPubkey = token.pubkey || primaryAddress;
490
+ const tokenDecimals = tokenAssetInfo?.decimals ?? tokenAssetInfo?.decimal ?? token.token?.decimals ?? token.token?.decimal;
491
+ if (tokenDecimals === undefined || tokenDecimals === null) {
492
+ throw new Error(`CRITICAL: Token ${token.assetCaip} (${tokenAssetInfo?.symbol || token.token?.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Token data: ${JSON.stringify({
493
+ caip: token.assetCaip,
494
+ symbol: tokenAssetInfo?.symbol || token.token?.symbol,
495
+ hasAssetInfoDecimals: !!tokenAssetInfo?.decimals,
496
+ hasAssetInfoDecimal: !!tokenAssetInfo?.decimal,
497
+ hasTokenDecimals: !!token.token?.decimals,
498
+ hasTokenDecimal: !!token.token?.decimal
499
+ })}`);
500
+ }
477
501
  const chartBalance = {
478
502
  context,
479
503
  chart: "pioneer",
@@ -489,7 +513,9 @@ function processPortfolioToken(token, primaryAddress, context, blockchains) {
489
513
  symbol: tokenAssetInfo?.symbol || token.token?.symbol || "UNK",
490
514
  type: tokenAssetInfo?.type || "token",
491
515
  token: true,
492
- decimal: tokenAssetInfo?.decimal || token.token?.decimal,
516
+ decimal: tokenDecimals,
517
+ decimals: tokenDecimals,
518
+ precision: tokenDecimals,
493
519
  balance: token.token?.balance?.toString() || "0",
494
520
  priceUsd: token.token?.price || 0,
495
521
  valueUsd: token.token?.balanceUSD || 0,
@@ -596,6 +622,17 @@ async function getMayaCharts(params, existingBalances) {
596
622
  }
597
623
  const mayaAssetInfo = hydrateAssetData(mayaBalance.caip);
598
624
  const isToken = mayaBalance.caip.includes("/denom:") && !mayaBalance.caip.endsWith("/denom:cacao");
625
+ const decimals = mayaAssetInfo?.decimals ?? mayaAssetInfo?.decimal ?? mayaBalance.decimals ?? mayaBalance.decimal;
626
+ if (decimals === undefined || decimals === null) {
627
+ throw new Error(`CRITICAL: Asset ${mayaBalance.caip} (${mayaAssetInfo?.symbol || "MAYA"}) has NO decimals/precision! ` + `This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({
628
+ caip: mayaBalance.caip,
629
+ symbol: mayaAssetInfo?.symbol,
630
+ hasAssetInfoDecimals: !!mayaAssetInfo?.decimals,
631
+ hasAssetInfoDecimal: !!mayaAssetInfo?.decimal,
632
+ hasBalanceDecimals: !!mayaBalance.decimals,
633
+ hasBalanceDecimal: !!mayaBalance.decimal
634
+ })}`);
635
+ }
599
636
  const mayaTokenBalance = {
600
637
  context,
601
638
  chart: "pioneer",
@@ -611,7 +648,9 @@ async function getMayaCharts(params, existingBalances) {
611
648
  symbol: mayaAssetInfo?.symbol || "MAYA",
612
649
  type: mayaAssetInfo?.type || "token",
613
650
  token: isToken,
614
- decimal: mayaAssetInfo?.decimal,
651
+ decimal: decimals,
652
+ decimals,
653
+ precision: decimals,
615
654
  balance: mayaBalance.balance?.toString() || "0",
616
655
  priceUsd: parseFloat(mayaBalance.priceUsd) || 0,
617
656
  valueUsd: parseFloat(mayaBalance.valueUsd) || 0,
@@ -4588,6 +4627,10 @@ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4588
4627
  const explorerUrls = EXPLORER_BASE_URLS[networkId];
4589
4628
  const explorerAddressLink = explorerUrls && balance.pubkey ? explorerUrls.address + balance.pubkey : undefined;
4590
4629
  const explorerTxLink = explorerUrls?.tx;
4630
+ const decimals = assetInfo.decimals ?? balance.decimals;
4631
+ if (decimals === undefined || decimals === null) {
4632
+ throw new Error(`CRITICAL: Asset ${balance.caip} (${assetInfo.symbol || "UNKNOWN"}) has NO decimals/precision! ` + `AssetInfo is incomplete. This would cause incorrect balance calculations. ` + `Asset data: ${JSON.stringify({ caip: balance.caip, symbol: assetInfo.symbol, hasDecimals: !!assetInfo.decimals })}`);
4633
+ }
4591
4634
  Object.assign(balance, assetInfo, {
4592
4635
  type: balance.type || assetInfo.type,
4593
4636
  isNative: balance.isNative ?? assetInfo.isNative,
@@ -4596,7 +4639,8 @@ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4596
4639
  identifier: `${balance.caip}:${balance.pubkey}`,
4597
4640
  updated: Date.now(),
4598
4641
  color: assetInfo.color,
4599
- decimals: assetInfo.decimals || balance.decimals || 8,
4642
+ decimals,
4643
+ precision: decimals,
4600
4644
  explorerAddressLink,
4601
4645
  explorerTxLink,
4602
4646
  explorer: explorerUrls?.address,
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "author": "highlander",
3
3
  "name": "@pioneer-platform/pioneer-sdk",
4
- "version": "8.15.33",
4
+ "version": "8.15.34",
5
5
  "dependencies": {
6
6
  "@keepkey/keepkey-sdk": "^0.2.62",
7
- "@pioneer-platform/pioneer-caip": "^9.10.10",
8
- "@pioneer-platform/pioneer-client": "^9.10.16",
9
- "@pioneer-platform/pioneer-coins": "^9.11.10",
10
- "@pioneer-platform/pioneer-discovery": "^8.15.33",
11
- "@pioneer-platform/pioneer-events": "^8.12.5",
7
+ "@pioneer-platform/pioneer-caip": "^9.10.11",
8
+ "@pioneer-platform/pioneer-client": "^9.10.17",
9
+ "@pioneer-platform/pioneer-coins": "^9.11.11",
10
+ "@pioneer-platform/pioneer-discovery": "^8.15.34",
11
+ "@pioneer-platform/pioneer-events": "^8.12.6",
12
12
  "coinselect": "^3.1.13",
13
13
  "eventemitter3": "^5.0.1",
14
14
  "neotraverse": "^0.6.8",
package/src/charts/evm.ts CHANGED
@@ -178,6 +178,25 @@ function processPortfolioBalance(
178
178
  }
179
179
  }
180
180
 
181
+ // CRITICAL: FAIL FAST if decimals/precision is missing
182
+ // Extract decimals from multiple possible sources (assetInfo, balance API response)
183
+ const decimals = assetInfo?.decimals ?? assetInfo?.decimal ?? balance.decimals ?? balance.decimal;
184
+
185
+ if (decimals === undefined || decimals === null) {
186
+ throw new Error(
187
+ `CRITICAL: Asset ${balance.caip} (${assetInfo?.symbol || balance.symbol || 'UNKNOWN'}) has NO decimals/precision! ` +
188
+ `This would cause incorrect balance calculations. ` +
189
+ `Asset data: ${JSON.stringify({
190
+ caip: balance.caip,
191
+ symbol: assetInfo?.symbol || balance.symbol,
192
+ hasAssetInfoDecimals: !!assetInfo?.decimals,
193
+ hasAssetInfoDecimal: !!assetInfo?.decimal,
194
+ hasBalanceDecimals: !!balance.decimals,
195
+ hasBalanceDecimal: !!balance.decimal
196
+ })}`
197
+ );
198
+ }
199
+
181
200
  const chartBalance: ChartBalance = {
182
201
  context,
183
202
  chart: 'pioneer',
@@ -194,7 +213,10 @@ function processPortfolioBalance(
194
213
  symbol: assetInfo?.symbol || balance.symbol || 'UNK',
195
214
  type: balanceType,
196
215
  token: isToken,
197
- decimal: assetInfo?.decimal || balance.decimal,
216
+ // CRITICAL: Set BOTH decimal (legacy) and decimals/precision (new standard)
217
+ decimal: decimals,
218
+ decimals: decimals,
219
+ precision: decimals,
198
220
  balance: balance.balance.toString(),
199
221
  price: calculatedPrice,
200
222
  priceUsd: calculatedPrice,
@@ -244,10 +266,28 @@ function processPortfolioToken(
244
266
 
245
267
  // Hydrate token with assetData
246
268
  const tokenAssetInfo = hydrateAssetData(token.assetCaip);
247
-
269
+
248
270
  // CRITICAL FIX: Use consistent pubkey for tokens too
249
271
  const tokenPubkey = token.pubkey || primaryAddress;
250
272
 
273
+ // CRITICAL: FAIL FAST if decimals/precision is missing for tokens
274
+ const tokenDecimals = tokenAssetInfo?.decimals ?? tokenAssetInfo?.decimal ?? token.token?.decimals ?? token.token?.decimal;
275
+
276
+ if (tokenDecimals === undefined || tokenDecimals === null) {
277
+ throw new Error(
278
+ `CRITICAL: Token ${token.assetCaip} (${tokenAssetInfo?.symbol || token.token?.symbol || 'UNKNOWN'}) has NO decimals/precision! ` +
279
+ `This would cause incorrect balance calculations. ` +
280
+ `Token data: ${JSON.stringify({
281
+ caip: token.assetCaip,
282
+ symbol: tokenAssetInfo?.symbol || token.token?.symbol,
283
+ hasAssetInfoDecimals: !!tokenAssetInfo?.decimals,
284
+ hasAssetInfoDecimal: !!tokenAssetInfo?.decimal,
285
+ hasTokenDecimals: !!token.token?.decimals,
286
+ hasTokenDecimal: !!token.token?.decimal
287
+ })}`
288
+ );
289
+ }
290
+
251
291
  const chartBalance: ChartBalance = {
252
292
  context,
253
293
  chart: 'pioneer',
@@ -263,7 +303,10 @@ function processPortfolioToken(
263
303
  symbol: tokenAssetInfo?.symbol || token.token?.symbol || 'UNK',
264
304
  type: tokenAssetInfo?.type || 'token',
265
305
  token: true, // Tokens from portfolio.tokens are always tokens
266
- decimal: tokenAssetInfo?.decimal || token.token?.decimal,
306
+ // CRITICAL: Set ALL decimal fields for compatibility
307
+ decimal: tokenDecimals,
308
+ decimals: tokenDecimals,
309
+ precision: tokenDecimals,
267
310
  balance: token.token?.balance?.toString() || '0',
268
311
  priceUsd: token.token?.price || 0,
269
312
  valueUsd: token.token?.balanceUSD || 0,
@@ -79,7 +79,26 @@ export async function getMayaCharts(
79
79
 
80
80
  // CACAO is the native asset, MAYA is a token on the Maya chain
81
81
  const isToken = mayaBalance.caip.includes('/denom:') && !mayaBalance.caip.endsWith('/denom:cacao');
82
-
82
+
83
+ // CRITICAL: FAIL FAST if decimals/precision is missing
84
+ // Extract decimals from multiple possible sources (assetInfo, balance API response)
85
+ const decimals = mayaAssetInfo?.decimals ?? mayaAssetInfo?.decimal ?? mayaBalance.decimals ?? mayaBalance.decimal;
86
+
87
+ if (decimals === undefined || decimals === null) {
88
+ throw new Error(
89
+ `CRITICAL: Asset ${mayaBalance.caip} (${mayaAssetInfo?.symbol || 'MAYA'}) has NO decimals/precision! ` +
90
+ `This would cause incorrect balance calculations. ` +
91
+ `Asset data: ${JSON.stringify({
92
+ caip: mayaBalance.caip,
93
+ symbol: mayaAssetInfo?.symbol,
94
+ hasAssetInfoDecimals: !!mayaAssetInfo?.decimals,
95
+ hasAssetInfoDecimal: !!mayaAssetInfo?.decimal,
96
+ hasBalanceDecimals: !!mayaBalance.decimals,
97
+ hasBalanceDecimal: !!mayaBalance.decimal
98
+ })}`
99
+ );
100
+ }
101
+
83
102
  const mayaTokenBalance: ChartBalance = {
84
103
  context,
85
104
  chart: 'pioneer',
@@ -95,7 +114,10 @@ export async function getMayaCharts(
95
114
  symbol: mayaAssetInfo?.symbol || 'MAYA',
96
115
  type: mayaAssetInfo?.type || 'token',
97
116
  token: isToken, // MAYA is a token, CACAO is the native asset
98
- decimal: mayaAssetInfo?.decimal,
117
+ // CRITICAL: Set BOTH decimal (legacy) and decimals/precision (new standard)
118
+ decimal: decimals,
119
+ decimals: decimals,
120
+ precision: decimals,
99
121
  balance: mayaBalance.balance?.toString() || '0',
100
122
  priceUsd: parseFloat(mayaBalance.priceUsd) || 0,
101
123
  valueUsd: parseFloat(mayaBalance.valueUsd) || 0,
@@ -345,6 +345,17 @@ export function enrichBalancesWithAssetInfo(
345
345
 
346
346
  const explorerTxLink = explorerUrls?.tx; // Base URL for txs, actual txid added later
347
347
 
348
+ // CRITICAL: NEVER default decimals to 8 - this causes incorrect balance calculations
349
+ // If decimals is missing, the asset data is incomplete and we should FAIL FAST
350
+ const decimals = assetInfo.decimals ?? balance.decimals;
351
+ if (decimals === undefined || decimals === null) {
352
+ throw new Error(
353
+ `CRITICAL: Asset ${balance.caip} (${assetInfo.symbol || 'UNKNOWN'}) has NO decimals/precision! ` +
354
+ `AssetInfo is incomplete. This would cause incorrect balance calculations. ` +
355
+ `Asset data: ${JSON.stringify({ caip: balance.caip, symbol: assetInfo.symbol, hasDecimals: !!assetInfo.decimals })}`
356
+ );
357
+ }
358
+
348
359
  Object.assign(balance, assetInfo, {
349
360
  type: balance.type || assetInfo.type,
350
361
  isNative: balance.isNative ?? assetInfo.isNative,
@@ -353,8 +364,9 @@ export function enrichBalancesWithAssetInfo(
353
364
  identifier: `${balance.caip}:${balance.pubkey}`,
354
365
  updated: Date.now(),
355
366
  color: assetInfo.color,
356
- // CRITICAL: Always use decimals from assetInfo if available
357
- decimals: assetInfo.decimals || balance.decimals || 8,
367
+ // CRITICAL: Use validated decimals
368
+ decimals,
369
+ precision: decimals, // Also set precision for compatibility
358
370
  // Add explorer links
359
371
  explorerAddressLink,
360
372
  explorerTxLink,