@pioneer-platform/pioneer-sdk 8.15.33 → 8.15.38

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,
@@ -4793,14 +4837,17 @@ class SDK {
4793
4837
  this.getUnifiedPortfolio = async function() {
4794
4838
  const tag6 = `${TAG12} | getUnifiedPortfolio | `;
4795
4839
  try {
4840
+ console.log(tag6, " checkpoint 4.0 - getUnifiedPortfolio start");
4796
4841
  const startTime = performance.now();
4797
4842
  try {
4798
4843
  const baseUrl = this.keepkeyEndpoint?.baseUrl || "kkapi://";
4799
4844
  const portfolioUrl = `${baseUrl}/api/portfolio`;
4845
+ console.log(tag6, " checkpoint 4.1 - Fetching portfolio from:", portfolioUrl);
4800
4846
  const portfolioResponse = await fetch(portfolioUrl, {
4801
4847
  method: "GET",
4802
4848
  signal: AbortSignal.timeout(2000)
4803
4849
  });
4850
+ console.log(tag6, " checkpoint 4.2 - Portfolio fetch returned, status:", portfolioResponse.status);
4804
4851
  if (!portfolioResponse.ok) {
4805
4852
  console.warn(tag6, "Portfolio endpoint returned", portfolioResponse.status);
4806
4853
  return null;
@@ -4913,7 +4960,9 @@ class SDK {
4913
4960
  };
4914
4961
  console.log("\uD83D\uDD11 [INIT] Initializing KeepKey SDK...");
4915
4962
  const keepKeySdk = await import_keepkey_sdk.KeepKeySdk.create(configKeepKey);
4963
+ console.log(tag6, " checkpoint 1.1 - KeepKeySdk created");
4916
4964
  const features = await keepKeySdk.system.info.getFeatures();
4965
+ console.log(tag6, " checkpoint 1.2 - features retrieved:", features);
4917
4966
  this.keepkeyApiKey = configKeepKey.apiKey;
4918
4967
  this.keepKeySdk = keepKeySdk;
4919
4968
  this.context = "keepkey:" + features.label + ".json";
@@ -4927,14 +4976,18 @@ class SDK {
4927
4976
  console.log("\uD83D\uDC41️ [VIEW-ONLY] Skipping vault endpoint detection");
4928
4977
  this.keepkeyEndpoint = null;
4929
4978
  }
4979
+ console.log(tag6, " checkpoint 2 - Starting WebSocket initialization");
4930
4980
  let configWss = {
4931
4981
  username: this.username,
4932
4982
  queryKey: this.queryKey,
4933
4983
  wss: this.wss
4934
4984
  };
4935
4985
  let clientEvents = new import_pioneer_events.Events(configWss);
4986
+ console.log(tag6, " checkpoint 2.1 - Events created, calling init()");
4936
4987
  await clientEvents.init();
4988
+ console.log(tag6, " checkpoint 2.2 - Events init complete, setting username");
4937
4989
  await clientEvents.setUsername(this.username);
4990
+ console.log(tag6, " checkpoint 2.3 - Username set, WebSocket ready");
4938
4991
  clientEvents.events.on("message", (request) => {
4939
4992
  this.events.emit("message", request);
4940
4993
  });
@@ -5000,11 +5053,14 @@ class SDK {
5000
5053
  }
5001
5054
  });
5002
5055
  this.events.emit("SET_STATUS", "init");
5056
+ console.log(tag6, " checkpoint 3 - Starting fast portfolio check");
5003
5057
  if (this.keepKeySdk && !skipSync) {
5004
5058
  console.log("⚡ [FAST PORTFOLIO] Attempting fast load...");
5059
+ console.log(tag6, " checkpoint 3.1 - Calling getUnifiedPortfolio()");
5005
5060
  const fastStart = performance.now();
5006
5061
  try {
5007
5062
  const unifiedResult = await this.getUnifiedPortfolio();
5063
+ console.log(tag6, " checkpoint 3.2 - getUnifiedPortfolio() returned");
5008
5064
  console.log("unifiedResult: ", unifiedResult);
5009
5065
  if (unifiedResult && unifiedResult.cached && unifiedResult.totalValueUsd > 0) {
5010
5066
  console.log(`✅ [FAST PORTFOLIO] Loaded in ${(performance.now() - fastStart).toFixed(0)}ms`);
@@ -5935,7 +5991,16 @@ class SDK {
5935
5991
  const networkId2 = import_pioneer_caip8.caipToNetworkId(asset.caip || asset.networkId);
5936
5992
  const currentContextValid = this.pubkeyContext?.networks?.includes(networkId2);
5937
5993
  if (!this.pubkeyContext || !currentContextValid) {
5938
- this.pubkeyContext = assetPubkeys[0];
5994
+ let preferredPubkey = assetPubkeys[0];
5995
+ const isBitcoin = networkId2?.includes("bip122:000000000019d6689c085ae165831e93") || asset.symbol === "BTC" || asset.name?.toLowerCase().includes("bitcoin");
5996
+ if (isBitcoin) {
5997
+ const nativeSegwitPubkey = assetPubkeys.find((pk) => pk.script_type === "p2wpkh" || pk.scriptType === "p2wpkh" || pk.note?.toLowerCase().includes("native") && pk.note?.toLowerCase().includes("segwit") || pk.pathMaster?.includes("84'"));
5998
+ if (nativeSegwitPubkey) {
5999
+ preferredPubkey = nativeSegwitPubkey;
6000
+ console.log(tag6, "Preferring Native Segwit (Bech32) for Bitcoin");
6001
+ }
6002
+ }
6003
+ this.pubkeyContext = preferredPubkey;
5939
6004
  console.log(tag6, "Auto-set pubkey context for network:", this.pubkeyContext.address || this.pubkeyContext.pubkey);
5940
6005
  } else {
5941
6006
  console.log(tag6, "Preserving existing pubkey context for network:", this.pubkeyContext.address || this.pubkeyContext.pubkey, `(addressNList: [${(this.pubkeyContext.addressNList || this.pubkeyContext.addressNListMaster).join(", ")}])`);
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,
@@ -4977,14 +5021,17 @@ class SDK {
4977
5021
  this.getUnifiedPortfolio = async function() {
4978
5022
  const tag6 = `${TAG12} | getUnifiedPortfolio | `;
4979
5023
  try {
5024
+ console.log(tag6, " checkpoint 4.0 - getUnifiedPortfolio start");
4980
5025
  const startTime = performance.now();
4981
5026
  try {
4982
5027
  const baseUrl = this.keepkeyEndpoint?.baseUrl || "kkapi://";
4983
5028
  const portfolioUrl = `${baseUrl}/api/portfolio`;
5029
+ console.log(tag6, " checkpoint 4.1 - Fetching portfolio from:", portfolioUrl);
4984
5030
  const portfolioResponse = await fetch(portfolioUrl, {
4985
5031
  method: "GET",
4986
5032
  signal: AbortSignal.timeout(2000)
4987
5033
  });
5034
+ console.log(tag6, " checkpoint 4.2 - Portfolio fetch returned, status:", portfolioResponse.status);
4988
5035
  if (!portfolioResponse.ok) {
4989
5036
  console.warn(tag6, "Portfolio endpoint returned", portfolioResponse.status);
4990
5037
  return null;
@@ -5097,7 +5144,9 @@ class SDK {
5097
5144
  };
5098
5145
  console.log("\uD83D\uDD11 [INIT] Initializing KeepKey SDK...");
5099
5146
  const keepKeySdk = await KeepKeySdk.create(configKeepKey);
5147
+ console.log(tag6, " checkpoint 1.1 - KeepKeySdk created");
5100
5148
  const features = await keepKeySdk.system.info.getFeatures();
5149
+ console.log(tag6, " checkpoint 1.2 - features retrieved:", features);
5101
5150
  this.keepkeyApiKey = configKeepKey.apiKey;
5102
5151
  this.keepKeySdk = keepKeySdk;
5103
5152
  this.context = "keepkey:" + features.label + ".json";
@@ -5111,14 +5160,18 @@ class SDK {
5111
5160
  console.log("\uD83D\uDC41️ [VIEW-ONLY] Skipping vault endpoint detection");
5112
5161
  this.keepkeyEndpoint = null;
5113
5162
  }
5163
+ console.log(tag6, " checkpoint 2 - Starting WebSocket initialization");
5114
5164
  let configWss = {
5115
5165
  username: this.username,
5116
5166
  queryKey: this.queryKey,
5117
5167
  wss: this.wss
5118
5168
  };
5119
5169
  let clientEvents = new Events(configWss);
5170
+ console.log(tag6, " checkpoint 2.1 - Events created, calling init()");
5120
5171
  await clientEvents.init();
5172
+ console.log(tag6, " checkpoint 2.2 - Events init complete, setting username");
5121
5173
  await clientEvents.setUsername(this.username);
5174
+ console.log(tag6, " checkpoint 2.3 - Username set, WebSocket ready");
5122
5175
  clientEvents.events.on("message", (request) => {
5123
5176
  this.events.emit("message", request);
5124
5177
  });
@@ -5184,11 +5237,14 @@ class SDK {
5184
5237
  }
5185
5238
  });
5186
5239
  this.events.emit("SET_STATUS", "init");
5240
+ console.log(tag6, " checkpoint 3 - Starting fast portfolio check");
5187
5241
  if (this.keepKeySdk && !skipSync) {
5188
5242
  console.log("⚡ [FAST PORTFOLIO] Attempting fast load...");
5243
+ console.log(tag6, " checkpoint 3.1 - Calling getUnifiedPortfolio()");
5189
5244
  const fastStart = performance.now();
5190
5245
  try {
5191
5246
  const unifiedResult = await this.getUnifiedPortfolio();
5247
+ console.log(tag6, " checkpoint 3.2 - getUnifiedPortfolio() returned");
5192
5248
  console.log("unifiedResult: ", unifiedResult);
5193
5249
  if (unifiedResult && unifiedResult.cached && unifiedResult.totalValueUsd > 0) {
5194
5250
  console.log(`✅ [FAST PORTFOLIO] Loaded in ${(performance.now() - fastStart).toFixed(0)}ms`);
@@ -6119,7 +6175,16 @@ class SDK {
6119
6175
  const networkId2 = caipToNetworkId7(asset.caip || asset.networkId);
6120
6176
  const currentContextValid = this.pubkeyContext?.networks?.includes(networkId2);
6121
6177
  if (!this.pubkeyContext || !currentContextValid) {
6122
- this.pubkeyContext = assetPubkeys[0];
6178
+ let preferredPubkey = assetPubkeys[0];
6179
+ const isBitcoin = networkId2?.includes("bip122:000000000019d6689c085ae165831e93") || asset.symbol === "BTC" || asset.name?.toLowerCase().includes("bitcoin");
6180
+ if (isBitcoin) {
6181
+ const nativeSegwitPubkey = assetPubkeys.find((pk) => pk.script_type === "p2wpkh" || pk.scriptType === "p2wpkh" || pk.note?.toLowerCase().includes("native") && pk.note?.toLowerCase().includes("segwit") || pk.pathMaster?.includes("84'"));
6182
+ if (nativeSegwitPubkey) {
6183
+ preferredPubkey = nativeSegwitPubkey;
6184
+ console.log(tag6, "Preferring Native Segwit (Bech32) for Bitcoin");
6185
+ }
6186
+ }
6187
+ this.pubkeyContext = preferredPubkey;
6123
6188
  console.log(tag6, "Auto-set pubkey context for network:", this.pubkeyContext.address || this.pubkeyContext.pubkey);
6124
6189
  } else {
6125
6190
  console.log(tag6, "Preserving existing pubkey context for network:", this.pubkeyContext.address || this.pubkeyContext.pubkey, `(addressNList: [${(this.pubkeyContext.addressNList || this.pubkeyContext.addressNListMaster).join(", ")}])`);
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,
@@ -4977,14 +5021,17 @@ class SDK {
4977
5021
  this.getUnifiedPortfolio = async function() {
4978
5022
  const tag6 = `${TAG12} | getUnifiedPortfolio | `;
4979
5023
  try {
5024
+ console.log(tag6, " checkpoint 4.0 - getUnifiedPortfolio start");
4980
5025
  const startTime = performance.now();
4981
5026
  try {
4982
5027
  const baseUrl = this.keepkeyEndpoint?.baseUrl || "kkapi://";
4983
5028
  const portfolioUrl = `${baseUrl}/api/portfolio`;
5029
+ console.log(tag6, " checkpoint 4.1 - Fetching portfolio from:", portfolioUrl);
4984
5030
  const portfolioResponse = await fetch(portfolioUrl, {
4985
5031
  method: "GET",
4986
5032
  signal: AbortSignal.timeout(2000)
4987
5033
  });
5034
+ console.log(tag6, " checkpoint 4.2 - Portfolio fetch returned, status:", portfolioResponse.status);
4988
5035
  if (!portfolioResponse.ok) {
4989
5036
  console.warn(tag6, "Portfolio endpoint returned", portfolioResponse.status);
4990
5037
  return null;
@@ -5097,7 +5144,9 @@ class SDK {
5097
5144
  };
5098
5145
  console.log("\uD83D\uDD11 [INIT] Initializing KeepKey SDK...");
5099
5146
  const keepKeySdk = await KeepKeySdk.create(configKeepKey);
5147
+ console.log(tag6, " checkpoint 1.1 - KeepKeySdk created");
5100
5148
  const features = await keepKeySdk.system.info.getFeatures();
5149
+ console.log(tag6, " checkpoint 1.2 - features retrieved:", features);
5101
5150
  this.keepkeyApiKey = configKeepKey.apiKey;
5102
5151
  this.keepKeySdk = keepKeySdk;
5103
5152
  this.context = "keepkey:" + features.label + ".json";
@@ -5111,14 +5160,18 @@ class SDK {
5111
5160
  console.log("\uD83D\uDC41️ [VIEW-ONLY] Skipping vault endpoint detection");
5112
5161
  this.keepkeyEndpoint = null;
5113
5162
  }
5163
+ console.log(tag6, " checkpoint 2 - Starting WebSocket initialization");
5114
5164
  let configWss = {
5115
5165
  username: this.username,
5116
5166
  queryKey: this.queryKey,
5117
5167
  wss: this.wss
5118
5168
  };
5119
5169
  let clientEvents = new Events(configWss);
5170
+ console.log(tag6, " checkpoint 2.1 - Events created, calling init()");
5120
5171
  await clientEvents.init();
5172
+ console.log(tag6, " checkpoint 2.2 - Events init complete, setting username");
5121
5173
  await clientEvents.setUsername(this.username);
5174
+ console.log(tag6, " checkpoint 2.3 - Username set, WebSocket ready");
5122
5175
  clientEvents.events.on("message", (request) => {
5123
5176
  this.events.emit("message", request);
5124
5177
  });
@@ -5184,11 +5237,14 @@ class SDK {
5184
5237
  }
5185
5238
  });
5186
5239
  this.events.emit("SET_STATUS", "init");
5240
+ console.log(tag6, " checkpoint 3 - Starting fast portfolio check");
5187
5241
  if (this.keepKeySdk && !skipSync) {
5188
5242
  console.log("⚡ [FAST PORTFOLIO] Attempting fast load...");
5243
+ console.log(tag6, " checkpoint 3.1 - Calling getUnifiedPortfolio()");
5189
5244
  const fastStart = performance.now();
5190
5245
  try {
5191
5246
  const unifiedResult = await this.getUnifiedPortfolio();
5247
+ console.log(tag6, " checkpoint 3.2 - getUnifiedPortfolio() returned");
5192
5248
  console.log("unifiedResult: ", unifiedResult);
5193
5249
  if (unifiedResult && unifiedResult.cached && unifiedResult.totalValueUsd > 0) {
5194
5250
  console.log(`✅ [FAST PORTFOLIO] Loaded in ${(performance.now() - fastStart).toFixed(0)}ms`);
@@ -6119,7 +6175,16 @@ class SDK {
6119
6175
  const networkId2 = caipToNetworkId7(asset.caip || asset.networkId);
6120
6176
  const currentContextValid = this.pubkeyContext?.networks?.includes(networkId2);
6121
6177
  if (!this.pubkeyContext || !currentContextValid) {
6122
- this.pubkeyContext = assetPubkeys[0];
6178
+ let preferredPubkey = assetPubkeys[0];
6179
+ const isBitcoin = networkId2?.includes("bip122:000000000019d6689c085ae165831e93") || asset.symbol === "BTC" || asset.name?.toLowerCase().includes("bitcoin");
6180
+ if (isBitcoin) {
6181
+ const nativeSegwitPubkey = assetPubkeys.find((pk) => pk.script_type === "p2wpkh" || pk.scriptType === "p2wpkh" || pk.note?.toLowerCase().includes("native") && pk.note?.toLowerCase().includes("segwit") || pk.pathMaster?.includes("84'"));
6182
+ if (nativeSegwitPubkey) {
6183
+ preferredPubkey = nativeSegwitPubkey;
6184
+ console.log(tag6, "Preferring Native Segwit (Bech32) for Bitcoin");
6185
+ }
6186
+ }
6187
+ this.pubkeyContext = preferredPubkey;
6123
6188
  console.log(tag6, "Auto-set pubkey context for network:", this.pubkeyContext.address || this.pubkeyContext.pubkey);
6124
6189
  } else {
6125
6190
  console.log(tag6, "Preserving existing pubkey context for network:", this.pubkeyContext.address || this.pubkeyContext.pubkey, `(addressNList: [${(this.pubkeyContext.addressNList || this.pubkeyContext.addressNListMaster).join(", ")}])`);
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.38",
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.15",
8
+ "@pioneer-platform/pioneer-client": "^9.10.21",
9
+ "@pioneer-platform/pioneer-coins": "^9.11.15",
10
+ "@pioneer-platform/pioneer-discovery": "^8.15.38",
11
+ "@pioneer-platform/pioneer-events": "^8.12.10",
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,
package/src/index.ts CHANGED
@@ -333,6 +333,7 @@ export class SDK {
333
333
  this.getUnifiedPortfolio = async function () {
334
334
  const tag = `${TAG} | getUnifiedPortfolio | `;
335
335
  try {
336
+ console.log(tag,' checkpoint 4.0 - getUnifiedPortfolio start')
336
337
  const startTime = performance.now();
337
338
 
338
339
  // Check if kkapi is available and use the detected endpoint
@@ -340,11 +341,13 @@ export class SDK {
340
341
  // Use the detected endpoint instead of hardcoded kkapi://
341
342
  const baseUrl = this.keepkeyEndpoint?.baseUrl || 'kkapi://';
342
343
  const portfolioUrl = `${baseUrl}/api/portfolio`;
344
+ console.log(tag,' checkpoint 4.1 - Fetching portfolio from:', portfolioUrl)
343
345
 
344
346
  const portfolioResponse = await fetch(portfolioUrl, {
345
347
  method: 'GET',
346
348
  signal: AbortSignal.timeout(2000), // 2 second timeout
347
349
  });
350
+ console.log(tag,' checkpoint 4.2 - Portfolio fetch returned, status:', portfolioResponse.status)
348
351
 
349
352
  if (!portfolioResponse.ok) {
350
353
  console.warn(tag, 'Portfolio endpoint returned', portfolioResponse.status);
@@ -495,8 +498,9 @@ export class SDK {
495
498
 
496
499
  console.log('🔑 [INIT] Initializing KeepKey SDK...');
497
500
  const keepKeySdk = await KeepKeySdk.create(configKeepKey);
501
+ console.log(tag,' checkpoint 1.1 - KeepKeySdk created')
498
502
  const features = await keepKeySdk.system.info.getFeatures();
499
-
503
+ console.log(tag,' checkpoint 1.2 - features retrieved:', features)
500
504
  this.keepkeyApiKey = configKeepKey.apiKey;
501
505
  this.keepKeySdk = keepKeySdk;
502
506
  this.context = 'keepkey:' + features.label + '.json';
@@ -512,6 +516,7 @@ export class SDK {
512
516
  }
513
517
 
514
518
  // Initialize WebSocket events
519
+ console.log(tag,' checkpoint 2 - Starting WebSocket initialization')
515
520
  let configWss = {
516
521
  username: this.username,
517
522
  queryKey: this.queryKey,
@@ -519,8 +524,11 @@ export class SDK {
519
524
  };
520
525
 
521
526
  let clientEvents = new Events(configWss);
527
+ console.log(tag,' checkpoint 2.1 - Events created, calling init()')
522
528
  await clientEvents.init();
529
+ console.log(tag,' checkpoint 2.2 - Events init complete, setting username')
523
530
  await clientEvents.setUsername(this.username);
531
+ console.log(tag,' checkpoint 2.3 - Username set, WebSocket ready')
524
532
 
525
533
  clientEvents.events.on('message', (request) => {
526
534
  this.events.emit('message', request);
@@ -620,12 +628,15 @@ export class SDK {
620
628
  this.events.emit('SET_STATUS', 'init');
621
629
 
622
630
  // Fast Portfolio Pattern: Try unified portfolio first, then sync if needed
631
+ console.log(tag,' checkpoint 3 - Starting fast portfolio check')
623
632
  if (this.keepKeySdk && !skipSync) {
624
633
  console.log('⚡ [FAST PORTFOLIO] Attempting fast load...');
634
+ console.log(tag,' checkpoint 3.1 - Calling getUnifiedPortfolio()')
625
635
  const fastStart = performance.now();
626
636
 
627
637
  try {
628
638
  const unifiedResult = await this.getUnifiedPortfolio();
639
+ console.log(tag,' checkpoint 3.2 - getUnifiedPortfolio() returned')
629
640
  console.log('unifiedResult: ', unifiedResult);
630
641
 
631
642
  if (unifiedResult && unifiedResult.cached && unifiedResult.totalValueUsd > 0) {
@@ -1976,8 +1987,30 @@ export class SDK {
1976
1987
  const currentContextValid = this.pubkeyContext?.networks?.includes(networkId);
1977
1988
 
1978
1989
  if (!this.pubkeyContext || !currentContextValid) {
1979
- // No context or wrong network - auto-set to first matching pubkey
1980
- this.pubkeyContext = assetPubkeys[0];
1990
+ // No context or wrong network - auto-set to preferred pubkey
1991
+ // For Bitcoin, prefer Native Segwit (Bech32) over legacy
1992
+ let preferredPubkey = assetPubkeys[0];
1993
+
1994
+ const isBitcoin = networkId?.includes('bip122:000000000019d6689c085ae165831e93') ||
1995
+ asset.symbol === 'BTC' ||
1996
+ asset.name?.toLowerCase().includes('bitcoin');
1997
+
1998
+ if (isBitcoin) {
1999
+ // Find Native Segwit pubkey (script_type: 'p2wpkh', path includes 84')
2000
+ const nativeSegwitPubkey = assetPubkeys.find((pk: any) =>
2001
+ pk.script_type === 'p2wpkh' ||
2002
+ pk.scriptType === 'p2wpkh' ||
2003
+ (pk.note?.toLowerCase().includes('native') && pk.note?.toLowerCase().includes('segwit')) ||
2004
+ pk.pathMaster?.includes("84'")
2005
+ );
2006
+
2007
+ if (nativeSegwitPubkey) {
2008
+ preferredPubkey = nativeSegwitPubkey;
2009
+ console.log(tag, 'Preferring Native Segwit (Bech32) for Bitcoin');
2010
+ }
2011
+ }
2012
+
2013
+ this.pubkeyContext = preferredPubkey;
1981
2014
  console.log(
1982
2015
  tag,
1983
2016
  'Auto-set pubkey context for network:',
@@ -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,