@pioneer-platform/pioneer-sdk 8.15.14 → 8.15.15

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.es.js CHANGED
@@ -929,7 +929,7 @@ class Pioneer {
929
929
  }
930
930
 
931
931
  // src/index.ts
932
- import { addressNListToBIP32 as addressNListToBIP322, getPaths } from "@pioneer-platform/pioneer-coins";
932
+ import { getPaths as getPaths2 } from "@pioneer-platform/pioneer-coins";
933
933
  import { assetData as assetData2 } from "@pioneer-platform/pioneer-discovery";
934
934
  import { Events } from "@pioneer-platform/pioneer-events";
935
935
 
@@ -4167,25 +4167,404 @@ async function syncMarket(balances, pioneer) {
4167
4167
  }
4168
4168
  }
4169
4169
 
4170
- // src/index.ts
4171
- var TAG9 = " | Pioneer-sdk | ";
4172
- var ASSET_COLORS = {
4173
- "bip122:000000000019d6689c085ae165831e93/slip44:0": "#FF9800",
4174
- "eip155:1/slip44:60": "#627EEA",
4175
- "eip155:137/slip44:60": "#8247E5",
4176
- "eip155:8453/slip44:60": "#0052FF",
4177
- "eip155:56/slip44:60": "#F3BA2F",
4178
- "bip122:12a765e31ffd4059bada1e25190f6e98/slip44:2": "#BFBBBB",
4179
- "bip122:00000000001a91e3dace36e2be3bf030/slip44:3": "#C2A633",
4180
- "bip122:000000000000000000651ef99cb9fcbe/slip44:145": "#8DC351",
4181
- "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": "#008CE7",
4182
- "bip122:4da631f2ac1bed857bd968c67c913978/slip44:20": "#006AD2",
4183
- "cosmos:cosmoshub-4/slip44:118": "#2E3148",
4184
- "cosmos:osmosis-1/slip44:118": "#9B1FD7",
4185
- "ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144": "#23292F",
4186
- "cosmos:mayachain-mainnet-v1/slip44:931": "#00D4AA",
4187
- "cosmos:thorchain-mainnet-v1/slip44:931": "#00CCFF"
4170
+ // src/utils/pubkey-management.ts
4171
+ function getPubkeyKey(pubkey) {
4172
+ return `${pubkey.pubkey}_${pubkey.pathMaster}`;
4173
+ }
4174
+ function deduplicatePubkeys(pubkeys) {
4175
+ const seen = new Set;
4176
+ return pubkeys.filter((pubkey) => {
4177
+ const key = getPubkeyKey(pubkey);
4178
+ if (seen.has(key))
4179
+ return false;
4180
+ seen.add(key);
4181
+ return true;
4182
+ });
4183
+ }
4184
+ function validatePubkey(pubkey) {
4185
+ return !!(pubkey.pubkey && pubkey.pathMaster);
4186
+ }
4187
+ function findPubkeysForNetwork(pubkeys, networkId) {
4188
+ return pubkeys.filter((p) => {
4189
+ if (!p.networks || !Array.isArray(p.networks))
4190
+ return false;
4191
+ if (p.networks.includes(networkId))
4192
+ return true;
4193
+ if (networkId.startsWith("eip155:") && p.networks.includes("eip155:*")) {
4194
+ return true;
4195
+ }
4196
+ return false;
4197
+ });
4198
+ }
4199
+ function findPubkeyForNetwork(pubkeys, networkId) {
4200
+ return pubkeys.find((p) => {
4201
+ if (!p.networks || !Array.isArray(p.networks))
4202
+ return false;
4203
+ if (p.networks.includes(networkId))
4204
+ return true;
4205
+ if (networkId.startsWith("eip155:") && p.networks.includes("eip155:*"))
4206
+ return true;
4207
+ return false;
4208
+ });
4209
+ }
4210
+ function validatePubkeysForNetwork(pubkeys, networkId, caip) {
4211
+ if (!pubkeys || pubkeys.length === 0) {
4212
+ throw new Error(`Cannot set asset context for ${caip} - no pubkeys loaded. Please initialize wallet first.`);
4213
+ }
4214
+ const pubkeysForNetwork = findPubkeysForNetwork(pubkeys, networkId);
4215
+ if (pubkeysForNetwork.length === 0) {
4216
+ const availableNetworks = [...new Set(pubkeys.flatMap((p) => p.networks || []))];
4217
+ throw new Error(`Cannot set asset context for ${caip} - no address/xpub found for network ${networkId}. Available networks: ${availableNetworks.join(", ")}`);
4218
+ }
4219
+ const isUtxoChain = networkId.startsWith("bip122:");
4220
+ if (isUtxoChain) {
4221
+ const xpubFound = pubkeysForNetwork.some((p) => p.type === "xpub" && p.pubkey);
4222
+ if (!xpubFound) {
4223
+ throw new Error(`Cannot set asset context for UTXO chain ${caip} - xpub required but not found`);
4224
+ }
4225
+ }
4226
+ const hasValidAddress = pubkeysForNetwork.some((p) => p.address || p.master || p.pubkey);
4227
+ if (!hasValidAddress) {
4228
+ throw new Error(`Cannot set asset context for ${caip} - no valid address found in pubkeys`);
4229
+ }
4230
+ }
4231
+ function filterPubkeysForAsset(pubkeys, caip, caipToNetworkId7) {
4232
+ const networkId = caipToNetworkId7(caip);
4233
+ return pubkeys.filter((p) => {
4234
+ if (!p.networks || !Array.isArray(p.networks))
4235
+ return false;
4236
+ if (p.networks.includes(networkId))
4237
+ return true;
4238
+ if (networkId.includes("eip155") && p.networks.some((n) => n.startsWith("eip155"))) {
4239
+ return true;
4240
+ }
4241
+ return false;
4242
+ });
4243
+ }
4244
+
4245
+ // src/utils/portfolio-helpers.ts
4246
+ var log2 = __require("@pioneer-platform/loggerdog")();
4247
+ var TAG9 = " | portfolio-helpers | ";
4248
+ function isCacheDataValid(portfolioData) {
4249
+ if (!portfolioData.networks || !Array.isArray(portfolioData.networks)) {
4250
+ console.warn("[CACHE VALIDATION] Networks is not an array");
4251
+ return false;
4252
+ }
4253
+ if (portfolioData.networks.length > 50) {
4254
+ console.error(`[CACHE VALIDATION] CORRUPTED: ${portfolioData.networks.length} networks (should be < 50)`);
4255
+ return false;
4256
+ }
4257
+ const validNetworks = portfolioData.networks.filter((n) => n.networkId && n.totalValueUsd !== undefined && n.gasAssetSymbol);
4258
+ if (validNetworks.length === 0 && portfolioData.networks.length > 0) {
4259
+ console.error("[CACHE VALIDATION] CORRUPTED: No networks have required fields");
4260
+ return false;
4261
+ }
4262
+ console.log(`[CACHE VALIDATION] Found ${portfolioData.networks.length} networks, ${validNetworks.length} valid`);
4263
+ return true;
4264
+ }
4265
+ async function fetchMarketPrice(pioneer, caip) {
4266
+ const tag = TAG9 + " | fetchMarketPrice | ";
4267
+ try {
4268
+ if (!caip || typeof caip !== "string" || !caip.includes(":")) {
4269
+ log2.warn(tag, "Invalid or missing CAIP, skipping market price fetch:", caip);
4270
+ return 0;
4271
+ }
4272
+ log2.debug(tag, "Fetching fresh market price for:", caip);
4273
+ const marketData = await pioneer.GetMarketInfo([caip]);
4274
+ log2.debug(tag, "Market data response:", marketData);
4275
+ if (marketData && marketData.data && marketData.data.length > 0) {
4276
+ const price = marketData.data[0];
4277
+ log2.debug(tag, "✅ Fresh market price:", price);
4278
+ return price;
4279
+ } else {
4280
+ log2.warn(tag, "No market data returned for:", caip);
4281
+ return 0;
4282
+ }
4283
+ } catch (marketError) {
4284
+ log2.error(tag, "Error fetching market price:", marketError);
4285
+ return 0;
4286
+ }
4287
+ }
4288
+ function extractPriceFromBalances(balances) {
4289
+ const tag = TAG9 + " | extractPriceFromBalances | ";
4290
+ if (balances.length === 0)
4291
+ return 0;
4292
+ let priceValue = balances[0].priceUsd || balances[0].price;
4293
+ if ((!priceValue || priceValue === 0) && balances[0].valueUsd && balances[0].balance) {
4294
+ const balance = parseFloat(balances[0].balance);
4295
+ const valueUsd = parseFloat(balances[0].valueUsd);
4296
+ if (balance > 0 && valueUsd > 0) {
4297
+ priceValue = valueUsd / balance;
4298
+ log2.debug(tag, "Calculated priceUsd from valueUsd/balance:", priceValue);
4299
+ }
4300
+ }
4301
+ return priceValue || 0;
4302
+ }
4303
+ function aggregateBalances(balances, caip) {
4304
+ const tag = TAG9 + " | aggregateBalances | ";
4305
+ let totalBalance = 0;
4306
+ let totalValueUsd = 0;
4307
+ log2.debug(tag, `Aggregating ${balances.length} balance entries for ${caip}`);
4308
+ for (const balanceEntry of balances) {
4309
+ const balance = parseFloat(balanceEntry.balance) || 0;
4310
+ const valueUsd = parseFloat(balanceEntry.valueUsd) || 0;
4311
+ totalBalance += balance;
4312
+ totalValueUsd += valueUsd;
4313
+ log2.debug(tag, ` Balance entry: ${balance} (${valueUsd} USD)`);
4314
+ }
4315
+ log2.debug(tag, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
4316
+ return { totalBalance, totalValueUsd };
4317
+ }
4318
+ function updateBalancesWithPrice(balances, freshPriceUsd) {
4319
+ const tag = TAG9 + " | updateBalancesWithPrice | ";
4320
+ for (const balance of balances) {
4321
+ balance.price = freshPriceUsd;
4322
+ balance.priceUsd = freshPriceUsd;
4323
+ const balanceAmount = parseFloat(balance.balance || 0);
4324
+ balance.valueUsd = (balanceAmount * freshPriceUsd).toString();
4325
+ }
4326
+ log2.debug(tag, "Updated all balances with fresh price data");
4327
+ }
4328
+ function buildDashboardFromPortfolioData(portfolioData) {
4329
+ const cacheAge = portfolioData.lastUpdated ? Math.floor((Date.now() - portfolioData.lastUpdated) / 1000) : 0;
4330
+ return {
4331
+ totalValueUsd: portfolioData.totalValueUsd,
4332
+ pairedDevices: portfolioData.pairedDevices,
4333
+ devices: portfolioData.devices || [],
4334
+ networks: portfolioData.networks || [],
4335
+ assets: portfolioData.assets || [],
4336
+ statistics: portfolioData.statistics || {},
4337
+ cached: portfolioData.cached,
4338
+ lastUpdated: portfolioData.lastUpdated,
4339
+ cacheAge,
4340
+ networkPercentages: portfolioData.networks?.map((network) => ({
4341
+ networkId: network.network_id || network.networkId,
4342
+ percentage: network.percentage || 0
4343
+ })) || []
4344
+ };
4345
+ }
4346
+ function buildAssetQuery(pubkeys, caip) {
4347
+ return pubkeys.map((pubkey) => ({ caip, pubkey: pubkey.pubkey }));
4348
+ }
4349
+ function logQueryDiagnostics(assetQuery, tag = "") {
4350
+ const caipCounts = new Map;
4351
+ for (const query of assetQuery) {
4352
+ caipCounts.set(query.caip, (caipCounts.get(query.caip) || 0) + 1);
4353
+ }
4354
+ if (tag) {
4355
+ console.log(tag, "Built assetQuery with", assetQuery.length, "entries");
4356
+ console.log(tag, "Sample queries:", assetQuery.slice(0, 5));
4357
+ console.log(tag, "Queries by chain:");
4358
+ caipCounts.forEach((count, caip) => {
4359
+ console.log(` - ${caip}: ${count} queries`);
4360
+ });
4361
+ }
4362
+ }
4363
+ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4364
+ const tag = TAG9 + " | enrichBalancesWithAssetInfo | ";
4365
+ for (const balance of balances) {
4366
+ const assetInfo = assetsMap.get(balance.caip.toLowerCase()) || assetsMap.get(balance.caip);
4367
+ if (!assetInfo) {
4368
+ throw new Error(`Missing AssetInfo for ${balance.caip}`);
4369
+ }
4370
+ Object.assign(balance, assetInfo, {
4371
+ type: balance.type || assetInfo.type,
4372
+ isNative: balance.isNative ?? assetInfo.isNative,
4373
+ networkId: caipToNetworkId7(balance.caip),
4374
+ icon: assetInfo.icon || "https://pioneers.dev/coins/etherum.png",
4375
+ identifier: `${balance.caip}:${balance.pubkey}`,
4376
+ updated: Date.now(),
4377
+ color: assetInfo.color
4378
+ });
4379
+ }
4380
+ return balances;
4381
+ }
4382
+
4383
+ // src/utils/sync-state.ts
4384
+ var log3 = __require("@pioneer-platform/loggerdog")();
4385
+ var TAG10 = " | sync-state | ";
4386
+ function resolveAssetInfo(assetsMap, assetData, asset) {
4387
+ const tag = TAG10 + " | resolveAssetInfo | ";
4388
+ let assetInfo = assetsMap.get(asset.caip.toLowerCase());
4389
+ log3.debug(tag, "assetInfo from assetsMap:", assetInfo);
4390
+ const assetInfoDiscovery = assetData[asset.caip];
4391
+ log3.debug(tag, "assetInfoDiscovery:", assetInfoDiscovery);
4392
+ if (assetInfoDiscovery) {
4393
+ assetInfo = assetInfoDiscovery;
4394
+ }
4395
+ if (!assetInfo) {
4396
+ log3.debug(tag, "Building placeholder asset for", asset.caip);
4397
+ assetInfo = {
4398
+ caip: asset.caip.toLowerCase(),
4399
+ networkId: asset.networkId,
4400
+ symbol: asset.symbol || "UNKNOWN",
4401
+ name: asset.name || "Unknown Asset",
4402
+ icon: asset.icon || "https://pioneers.dev/coins/ethereum.png"
4403
+ };
4404
+ }
4405
+ return assetInfo;
4406
+ }
4407
+ function createInitialSyncState(totalChains) {
4408
+ return {
4409
+ isSynced: false,
4410
+ isInitialSync: true,
4411
+ cacheAge: 0,
4412
+ syncProgress: 0,
4413
+ syncedChains: 0,
4414
+ totalChains,
4415
+ lastSyncTime: null,
4416
+ syncSource: "none"
4417
+ };
4418
+ }
4419
+ function createCacheSyncState(lastUpdated, totalChains) {
4420
+ const cacheAge = lastUpdated ? Math.floor((Date.now() - lastUpdated) / 1000) : 0;
4421
+ return {
4422
+ isSynced: true,
4423
+ isInitialSync: false,
4424
+ cacheAge,
4425
+ syncProgress: 100,
4426
+ syncedChains: totalChains,
4427
+ totalChains,
4428
+ lastSyncTime: lastUpdated || Date.now(),
4429
+ syncSource: "cache"
4430
+ };
4431
+ }
4432
+ function createFreshSyncState(totalChains) {
4433
+ return {
4434
+ isSynced: true,
4435
+ isInitialSync: false,
4436
+ cacheAge: 0,
4437
+ syncProgress: 100,
4438
+ syncedChains: totalChains,
4439
+ totalChains,
4440
+ lastSyncTime: Date.now(),
4441
+ syncSource: "fresh"
4442
+ };
4443
+ }
4444
+
4445
+ // src/utils/fee-reserves.ts
4446
+ var TAG11 = " | Pioneer-sdk | fee-reserves | ";
4447
+ var FEE_RESERVE_MAP = {
4448
+ "bip122:000000000019d6689c085ae165831e93/slip44:0": 0.00005,
4449
+ "eip155:1/slip44:60": 0.001,
4450
+ "cosmos:thorchain-mainnet-v1/slip44:931": 0.02,
4451
+ "bip122:00000000001a91e3dace36e2be3bf030/slip44:3": 1,
4452
+ "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": 0.001,
4453
+ "bip122:000000000000000000651ef99cb9fcbe/slip44:145": 0.0005,
4454
+ "bip122:12a765e31ffd4059bada1e25190f6e98/slip44:2": 0.001,
4455
+ "bip122:4da631f2ac1bed857bd968c67c913978/slip44:20": 0.1,
4456
+ "cosmos:cosmoshub-4/slip44:118": 0.005,
4457
+ "cosmos:osmosis-1/slip44:118": 0.035,
4458
+ "cosmos:mayachain-mainnet-v1/slip44:931": 0.5,
4459
+ "eip155:56/slip44:60": 0.001,
4460
+ "eip155:137/slip44:60": 0.01,
4461
+ "eip155:43114/slip44:60": 0.01,
4462
+ "eip155:10/slip44:60": 0.0001,
4463
+ "eip155:8453/slip44:60": 0.0001,
4464
+ "eip155:42161/slip44:60": 0.0001,
4465
+ "ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144": 0.00001
4188
4466
  };
4467
+ var DEFAULT_FEE_RESERVE = 0.001;
4468
+ function getFeeReserve(caip) {
4469
+ if (FEE_RESERVE_MAP[caip]) {
4470
+ return FEE_RESERVE_MAP[caip];
4471
+ }
4472
+ if (caip.startsWith("eip155:") && caip.includes("/slip44:60")) {
4473
+ return FEE_RESERVE_MAP["eip155:1/slip44:60"] || 0.001;
4474
+ }
4475
+ if (caip.startsWith("cosmos:")) {
4476
+ return 0.01;
4477
+ }
4478
+ if (caip.startsWith("bip122:")) {
4479
+ return 0.0001;
4480
+ }
4481
+ console.warn(TAG11, `No fee reserve defined for ${caip}, using default: ${DEFAULT_FEE_RESERVE}`);
4482
+ return DEFAULT_FEE_RESERVE;
4483
+ }
4484
+ function getMaxSendableAmount(balance, caip) {
4485
+ const reserve = getFeeReserve(caip);
4486
+ const maxAmount = Math.max(0, balance - reserve);
4487
+ console.log(TAG11, `Max sendable for ${caip}: ${maxAmount} (balance: ${balance}, reserve: ${reserve})`);
4488
+ return maxAmount;
4489
+ }
4490
+
4491
+ // src/utils/network-helpers.ts
4492
+ function matchesNetwork(item, networkId) {
4493
+ if (!item.networks || !Array.isArray(item.networks))
4494
+ return false;
4495
+ if (item.networks.includes(networkId))
4496
+ return true;
4497
+ if (networkId.startsWith("eip155:") && item.networks.includes("eip155:*"))
4498
+ return true;
4499
+ return false;
4500
+ }
4501
+ function normalizeNetworkId(networkId) {
4502
+ return networkId.includes("eip155:") ? "eip155:*" : networkId;
4503
+ }
4504
+ function validatePubkeysNetworks(pubkeys, tag = "") {
4505
+ const valid = pubkeys.filter((p) => p.networks && Array.isArray(p.networks));
4506
+ const invalid = pubkeys.filter((p) => !p.networks || !Array.isArray(p.networks));
4507
+ if (tag && invalid.length > 0) {
4508
+ console.warn(tag, `⚠️ ${invalid.length} pubkeys missing networks field`);
4509
+ invalid.forEach((pk) => {
4510
+ console.warn(tag, ` - ${pk.note || pk.pubkey.slice(0, 10)}: networks=${pk.networks}`);
4511
+ });
4512
+ }
4513
+ return { valid, invalid };
4514
+ }
4515
+
4516
+ // src/utils/path-discovery.ts
4517
+ import { getPaths } from "@pioneer-platform/pioneer-coins";
4518
+ var log4 = __require("@pioneer-platform/loggerdog")();
4519
+ async function ensurePathsForBlockchains(blockchains, currentPaths, tag) {
4520
+ let allPaths = [...currentPaths];
4521
+ for (const blockchain of blockchains) {
4522
+ const networkId = normalizeNetworkId(blockchain);
4523
+ const existingPaths = allPaths.filter((path) => matchesNetwork(path, networkId));
4524
+ if (existingPaths.length === 0) {
4525
+ log4.info(tag, `Discovering paths for ${networkId}...`);
4526
+ const newPaths = getPaths([networkId]);
4527
+ if (!newPaths || newPaths.length === 0) {
4528
+ throw new Error(`Path discovery failed for ${networkId}. ` + `Available blockchains: ${blockchains.join(", ")}`);
4529
+ }
4530
+ log4.debug(tag, `Added ${newPaths.length} paths for ${networkId}`);
4531
+ allPaths = allPaths.concat(newPaths);
4532
+ }
4533
+ }
4534
+ return allPaths;
4535
+ }
4536
+
4537
+ // src/utils/pubkey-sync.ts
4538
+ import { addressNListToBIP32 as addressNListToBIP322 } from "@pioneer-platform/pioneer-coins";
4539
+ var log5 = __require("@pioneer-platform/loggerdog")();
4540
+ async function syncPubkeysForBlockchains(blockchains, paths, existingPubkeys, keepKeySdk, context, getPubkeyFn, addPubkeyCallback, tag) {
4541
+ for (const blockchain of blockchains) {
4542
+ const networkId = normalizeNetworkId(blockchain);
4543
+ const pathsForChain = paths.filter((path) => matchesNetwork(path, networkId));
4544
+ if (pathsForChain.length === 0) {
4545
+ const availablePaths = paths.map((p) => p.note || p.path || "unnamed").join(", ");
4546
+ throw new Error(`No paths found for ${networkId}. ` + `Available paths: ${availablePaths || "none"}`);
4547
+ }
4548
+ log5.info(tag, `Syncing ${pathsForChain.length} pubkeys for ${networkId}...`);
4549
+ for (const path of pathsForChain) {
4550
+ const pathBip32 = addressNListToBIP322(path.addressNListMaster);
4551
+ const existingPubkey = existingPubkeys.find((p) => p.pathMaster === pathBip32);
4552
+ if (!existingPubkey) {
4553
+ log5.debug(tag, `Fetching pubkey for path ${pathBip32}...`);
4554
+ const newPubkey = await getPubkeyFn(blockchain, path, keepKeySdk, context);
4555
+ if (!newPubkey) {
4556
+ throw new Error(`Pubkey fetch failed for ${networkId} at path ${pathBip32}. ` + `Ensure hardware wallet is connected and unlocked.`);
4557
+ }
4558
+ addPubkeyCallback(newPubkey);
4559
+ log5.debug(tag, `✓ Added pubkey for ${pathBip32}`);
4560
+ }
4561
+ }
4562
+ }
4563
+ log5.info(tag, `✅ Pubkey sync complete. Total pubkeys: ${existingPubkeys.length}`);
4564
+ }
4565
+
4566
+ // src/index.ts
4567
+ var TAG12 = " | Pioneer-sdk | ";
4189
4568
 
4190
4569
  class SDK {
4191
4570
  status;
@@ -4243,7 +4622,6 @@ class SDK {
4243
4622
  init;
4244
4623
  getUnifiedPortfolio;
4245
4624
  offlineClient;
4246
- convertVaultPubkeysToPioneerFormat;
4247
4625
  app;
4248
4626
  addAsset;
4249
4627
  getAssets;
@@ -4316,23 +4694,14 @@ class SDK {
4316
4694
  this.utxoApiKey = config.utxoApiKey;
4317
4695
  this.walletConnectProjectId = config.walletConnectProjectId;
4318
4696
  this.contextType = "";
4319
- this.syncState = {
4320
- isSynced: false,
4321
- isInitialSync: true,
4322
- cacheAge: 0,
4323
- syncProgress: 0,
4324
- syncedChains: 0,
4325
- totalChains: this.blockchains.length,
4326
- lastSyncTime: null,
4327
- syncSource: "none"
4328
- };
4697
+ this.syncState = createInitialSyncState(this.blockchains.length);
4329
4698
  this.offlineClient = config.offlineFirst ? new OfflineClient({
4330
4699
  vaultUrl: config.vaultUrl || "kkapi://",
4331
4700
  timeout: 1000,
4332
4701
  fallbackToRemote: true
4333
4702
  }) : null;
4334
4703
  this.pairWallet = async (options) => {
4335
- const tag6 = TAG9 + " | pairWallet | ";
4704
+ const tag6 = TAG12 + " | pairWallet | ";
4336
4705
  if (this.viewOnlyMode || this.skipDevicePairing) {
4337
4706
  console.log(tag6, "\uD83D\uDC41️ [VIEW-ONLY] Skipping device pairing");
4338
4707
  return {
@@ -4347,35 +4716,20 @@ class SDK {
4347
4716
  message: "Device pairing not yet implemented"
4348
4717
  });
4349
4718
  };
4350
- this.getPubkeyKey = (pubkey) => {
4351
- return `${pubkey.pubkey}_${pubkey.pathMaster}`;
4352
- };
4353
- this.deduplicatePubkeys = (pubkeys) => {
4354
- const seen = new Set;
4355
- const deduped = pubkeys.filter((pubkey) => {
4356
- const key = this.getPubkeyKey(pubkey);
4357
- if (seen.has(key)) {
4358
- return false;
4359
- }
4360
- seen.add(key);
4361
- return true;
4362
- });
4363
- return deduped;
4364
- };
4719
+ this.getPubkeyKey = getPubkeyKey;
4720
+ this.deduplicatePubkeys = deduplicatePubkeys;
4365
4721
  this.addPubkey = (pubkey) => {
4366
- if (!pubkey.pubkey || !pubkey.pathMaster) {
4722
+ if (!validatePubkey(pubkey))
4367
4723
  return false;
4368
- }
4369
- const key = this.getPubkeyKey(pubkey);
4370
- if (this.pubkeySet.has(key)) {
4724
+ const key = getPubkeyKey(pubkey);
4725
+ if (this.pubkeySet.has(key))
4371
4726
  return false;
4372
- }
4373
4727
  this.pubkeys.push(pubkey);
4374
4728
  this.pubkeySet.add(key);
4375
4729
  return true;
4376
4730
  };
4377
4731
  this.setPubkeys = (newPubkeys) => {
4378
- const tag6 = `${TAG9} | setPubkeys | `;
4732
+ const tag6 = `${TAG12} | setPubkeys | `;
4379
4733
  this.pubkeys = [];
4380
4734
  this.pubkeySet.clear();
4381
4735
  let added = 0;
@@ -4391,17 +4745,8 @@ class SDK {
4391
4745
  this.pubkeys = [];
4392
4746
  this.pubkeySet.clear();
4393
4747
  }
4394
- this.isViewOnlyMode = () => {
4395
- return this.viewOnlyMode;
4396
- };
4397
- this.canSignTransactions = () => {
4398
- return !this.viewOnlyMode && !!this.keepKeySdk;
4399
- };
4400
- this.isVaultAvailable = () => {
4401
- return !!this.keepkeyEndpoint && this.keepkeyEndpoint.isAvailable;
4402
- };
4403
4748
  this.getUnifiedPortfolio = async function() {
4404
- const tag6 = `${TAG9} | getUnifiedPortfolio | `;
4749
+ const tag6 = `${TAG12} | getUnifiedPortfolio | `;
4405
4750
  try {
4406
4751
  const startTime = performance.now();
4407
4752
  try {
@@ -4433,8 +4778,7 @@ class SDK {
4433
4778
  this.events.emit("SET_BALANCES", this.balances);
4434
4779
  }
4435
4780
  if (portfolioData.pubkeys && portfolioData.pubkeys.length > 0) {
4436
- const convertedPubkeys = this.convertVaultPubkeysToPioneerFormat(portfolioData.pubkeys);
4437
- this.setPubkeys(convertedPubkeys);
4781
+ this.setPubkeys(portfolioData.pubkeys);
4438
4782
  this.events.emit("SET_PUBKEYS", this.pubkeys);
4439
4783
  }
4440
4784
  if (portfolioData.devices && portfolioData.devices.length > 0) {
@@ -4447,52 +4791,10 @@ class SDK {
4447
4791
  }));
4448
4792
  this.events.emit("SET_WALLETS", this.wallets);
4449
4793
  }
4450
- const isCacheDataValid = (portfolioData2) => {
4451
- if (!portfolioData2.networks || !Array.isArray(portfolioData2.networks)) {
4452
- console.warn("[CACHE VALIDATION] Networks is not an array");
4453
- return false;
4454
- }
4455
- if (portfolioData2.networks.length > 50) {
4456
- console.error(`[CACHE VALIDATION] CORRUPTED: ${portfolioData2.networks.length} networks (should be < 50)`);
4457
- return false;
4458
- }
4459
- const validNetworks = portfolioData2.networks.filter((n) => n.networkId && n.totalValueUsd !== undefined && n.gasAssetSymbol);
4460
- if (validNetworks.length === 0 && portfolioData2.networks.length > 0) {
4461
- console.error("[CACHE VALIDATION] CORRUPTED: No networks have required fields");
4462
- return false;
4463
- }
4464
- console.log(`[CACHE VALIDATION] Found ${portfolioData2.networks.length} networks, ${validNetworks.length} valid`);
4465
- return true;
4466
- };
4467
4794
  if (isCacheDataValid(portfolioData)) {
4468
- const dashboardData = {
4469
- totalValueUsd: portfolioData.totalValueUsd,
4470
- pairedDevices: portfolioData.pairedDevices,
4471
- devices: portfolioData.devices || [],
4472
- networks: portfolioData.networks || [],
4473
- assets: portfolioData.assets || [],
4474
- statistics: portfolioData.statistics || {},
4475
- cached: portfolioData.cached,
4476
- lastUpdated: portfolioData.lastUpdated,
4477
- cacheAge: portfolioData.lastUpdated ? Math.floor((Date.now() - portfolioData.lastUpdated) / 1000) : 0,
4478
- networkPercentages: portfolioData.networks?.map((network) => ({
4479
- networkId: network.network_id || network.networkId,
4480
- percentage: network.percentage || 0
4481
- })) || []
4482
- };
4483
- this.dashboard = dashboardData;
4795
+ this.dashboard = buildDashboardFromPortfolioData(portfolioData);
4484
4796
  this.events.emit("SET_DASHBOARD", this.dashboard);
4485
- const cacheAge = portfolioData.lastUpdated ? Math.floor((Date.now() - portfolioData.lastUpdated) / 1000) : 0;
4486
- this.syncState = {
4487
- isSynced: true,
4488
- isInitialSync: false,
4489
- cacheAge,
4490
- syncProgress: 100,
4491
- syncedChains: this.blockchains.length,
4492
- totalChains: this.blockchains.length,
4493
- lastSyncTime: portfolioData.lastUpdated || Date.now(),
4494
- syncSource: "cache"
4495
- };
4797
+ this.syncState = createCacheSyncState(portfolioData.lastUpdated, this.blockchains.length);
4496
4798
  this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4497
4799
  } else {
4498
4800
  console.warn("[CACHE VALIDATION] ❌ Cache data corrupted, building dashboard from cached balances");
@@ -4527,7 +4829,7 @@ class SDK {
4527
4829
  return this.syncState.isSynced;
4528
4830
  };
4529
4831
  this.init = async function(walletsVerbose, setup) {
4530
- const tag6 = `${TAG9} | init | `;
4832
+ const tag6 = `${TAG12} | init | `;
4531
4833
  try {
4532
4834
  if (!this.username)
4533
4835
  throw Error("username required!");
@@ -4548,7 +4850,7 @@ class SDK {
4548
4850
  this.pioneer = await PioneerClient.init();
4549
4851
  if (!this.pioneer)
4550
4852
  throw Error("Failed to init pioneer server!");
4551
- this.paths.concat(getPaths(this.blockchains));
4853
+ this.paths.concat(getPaths2(this.blockchains));
4552
4854
  await this.getGasAssets();
4553
4855
  if (!this.skipKeeperEndpoint) {
4554
4856
  this.keepkeyEndpoint = await detectKkApiAvailability(this.forceLocalhost);
@@ -4592,7 +4894,7 @@ class SDK {
4592
4894
  this.events.emit("message", request);
4593
4895
  });
4594
4896
  clientEvents.events.on("balance:update", (data) => {
4595
- const tag7 = TAG9 + " | balance:update | ";
4897
+ const tag7 = TAG12 + " | balance:update | ";
4596
4898
  try {
4597
4899
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4598
4900
  const balance = payload.balance;
@@ -4610,7 +4912,7 @@ class SDK {
4610
4912
  }
4611
4913
  });
4612
4914
  clientEvents.events.on("sync:progress", (data) => {
4613
- const tag7 = TAG9 + " | sync:progress | ";
4915
+ const tag7 = TAG12 + " | sync:progress | ";
4614
4916
  try {
4615
4917
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4616
4918
  console.log(tag7, `Sync progress: ${payload.percentage}%`);
@@ -4623,7 +4925,7 @@ class SDK {
4623
4925
  }
4624
4926
  });
4625
4927
  clientEvents.events.on("sync:complete", (data) => {
4626
- const tag7 = TAG9 + " | sync:complete | ";
4928
+ const tag7 = TAG12 + " | sync:complete | ";
4627
4929
  try {
4628
4930
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4629
4931
  console.log(tag7, `Sync complete: ${payload.balances} balances in ${payload.duration}ms`);
@@ -4674,155 +4976,60 @@ class SDK {
4674
4976
  this.buildDashboardFromBalances = function() {
4675
4977
  return buildDashboardFromBalances(this.balances, this.blockchains, this.assetsMap);
4676
4978
  };
4677
- this.inferTypeFromCaip = function(caip) {
4678
- if (caip.includes("/slip44:"))
4679
- return "native";
4680
- if (caip.includes("/erc20:") || caip.includes("/bep20:") || caip.includes("/spl:"))
4681
- return "token";
4682
- if (caip.includes("/denom:"))
4683
- return "native";
4684
- return "unknown";
4685
- };
4686
4979
  this.syncMarket = async function() {
4687
4980
  return syncMarket(this.balances, this.pioneer);
4688
4981
  };
4689
4982
  this.sync = async function() {
4690
- const tag6 = `${TAG9} | sync | `;
4983
+ const tag6 = `${TAG12} | sync | `;
4984
+ const log6 = __require("@pioneer-platform/loggerdog")();
4691
4985
  try {
4692
- const matchesNetwork = (item, networkId) => {
4693
- if (!item.networks || !Array.isArray(item.networks))
4694
- return false;
4695
- if (item.networks.includes(networkId))
4696
- return true;
4697
- if (networkId.startsWith("eip155:") && item.networks.includes("eip155:*"))
4698
- return true;
4699
- return false;
4986
+ this.syncState = {
4987
+ ...createInitialSyncState(this.blockchains.length),
4988
+ syncProgress: 10
4700
4989
  };
4990
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4991
+ log6.info(tag6, "Fetching initial pubkeys...");
4701
4992
  await this.getPubkeys();
4702
- for (let i = 0;i < this.blockchains.length; i++) {
4703
- let networkId = this.blockchains[i];
4704
- if (networkId.indexOf("eip155:") >= 0)
4705
- networkId = "eip155:*";
4706
- let paths = this.paths.filter((path) => matchesNetwork(path, networkId));
4707
- if (paths.length === 0) {
4708
- let paths2 = getPaths([networkId]);
4709
- if (!paths2 || paths2.length === 0)
4710
- throw Error("Unable to find paths for: " + networkId);
4711
- this.paths = this.paths.concat(paths2);
4712
- }
4713
- }
4714
- for (let i = 0;i < this.blockchains.length; i++) {
4715
- let networkId = this.blockchains[i];
4716
- if (networkId.indexOf("eip155:") >= 0)
4717
- networkId = "eip155:*";
4718
- const pathsForChain = this.paths.filter((path) => matchesNetwork(path, networkId));
4719
- if (!pathsForChain || pathsForChain.length === 0)
4720
- throw Error("No paths found for blockchain: " + networkId);
4721
- for (let j2 = 0;j2 < pathsForChain.length; j2++) {
4722
- const path = pathsForChain[j2];
4723
- let pathBip32 = addressNListToBIP322(path.addressNListMaster);
4724
- let pubkey = this.pubkeys.find((pubkey2) => pubkey2.pathMaster === pathBip32);
4725
- if (!pubkey) {
4726
- const pubkey2 = await getPubkey(this.blockchains[i], path, this.keepKeySdk, this.context);
4727
- if (!pubkey2)
4728
- throw Error("Unable to get pubkey for network+ " + networkId);
4729
- this.addPubkey(pubkey2);
4730
- }
4731
- }
4732
- }
4993
+ this.syncState.syncProgress = 20;
4994
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4995
+ log6.info(tag6, "Discovering paths for blockchains...");
4996
+ this.paths = await ensurePathsForBlockchains(this.blockchains, this.paths, tag6);
4997
+ this.syncState.syncProgress = 30;
4998
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4999
+ log6.info(tag6, "Synchronizing pubkeys...");
5000
+ await syncPubkeysForBlockchains(this.blockchains, this.paths, this.pubkeys, this.keepKeySdk, this.context, getPubkey, (pubkey) => this.addPubkey(pubkey), tag6);
5001
+ this.syncState.syncProgress = 50;
5002
+ this.syncState.syncedChains = this.blockchains.length;
5003
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5004
+ log6.info(tag6, "Fetching balances...");
4733
5005
  await this.getBalances();
4734
- console.log(tag6, "Loading charts (tokens + portfolio)...");
5006
+ this.syncState.syncProgress = 70;
5007
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5008
+ log6.info(tag6, "Loading charts (tokens + portfolio)...");
4735
5009
  await this.getCharts();
4736
- console.log(tag6, `Charts loaded. Total balances: ${this.balances.length}`);
5010
+ log6.info(tag6, `Charts loaded. Total balances: ${this.balances.length}`);
5011
+ this.syncState.syncProgress = 85;
5012
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5013
+ log6.info(tag6, "Syncing market prices...");
4737
5014
  await this.syncMarket();
4738
- const dashboardData = {
4739
- networks: [],
4740
- totalValueUsd: 0,
4741
- networkPercentages: []
4742
- };
4743
- let totalPortfolioValue = 0;
4744
- const networksTemp = [];
4745
- const uniqueBlockchains = [...new Set(this.blockchains)];
4746
- for (const blockchain of uniqueBlockchains) {
4747
- const filteredBalances = this.balances.filter((b2) => {
4748
- const networkId = caipToNetworkId7(b2.caip);
4749
- return networkId === blockchain || blockchain === "eip155:*" && networkId.startsWith("eip155:");
4750
- });
4751
- const balanceMap = new Map;
4752
- const isBitcoin = blockchain.includes("bip122:000000000019d6689c085ae165831e93");
4753
- if (isBitcoin) {
4754
- const bitcoinByValue = new Map;
4755
- filteredBalances.forEach((balance) => {
4756
- const valueKey = `${balance.balance}_${balance.valueUsd}`;
4757
- if (!bitcoinByValue.has(valueKey)) {
4758
- bitcoinByValue.set(valueKey, []);
4759
- }
4760
- bitcoinByValue.get(valueKey).push(balance);
4761
- });
4762
- for (const [valueKey, balances] of bitcoinByValue.entries()) {
4763
- if (balances.length === 3 && parseFloat(balances[0].valueUsd || "0") > 0) {
4764
- const xpubBalance = balances.find((b2) => b2.pubkey?.startsWith("xpub")) || balances[0];
4765
- const key = `${xpubBalance.caip}_${xpubBalance.pubkey || "default"}`;
4766
- balanceMap.set(key, xpubBalance);
4767
- } else {
4768
- balances.forEach((balance) => {
4769
- const key = `${balance.caip}_${balance.pubkey || "default"}`;
4770
- balanceMap.set(key, balance);
4771
- });
4772
- }
4773
- }
4774
- } else {
4775
- filteredBalances.forEach((balance) => {
4776
- const key = `${balance.caip}_${balance.pubkey || "default"}`;
4777
- if (!balanceMap.has(key) || parseFloat(balance.valueUsd || "0") > parseFloat(balanceMap.get(key).valueUsd || "0")) {
4778
- balanceMap.set(key, balance);
4779
- }
4780
- });
4781
- }
4782
- const networkBalances = Array.from(balanceMap.values());
4783
- const networkTotal = networkBalances.reduce((sum, balance, idx) => {
4784
- const valueUsd = typeof balance.valueUsd === "string" ? parseFloat(balance.valueUsd) : balance.valueUsd || 0;
4785
- return sum + valueUsd;
4786
- }, 0);
4787
- const nativeAssetCaip = networkIdToCaip2(blockchain);
4788
- const gasAsset = networkBalances.find((b2) => b2.caip === nativeAssetCaip);
4789
- const totalNativeBalance = networkBalances.filter((b2) => b2.caip === nativeAssetCaip).reduce((sum, balance) => {
4790
- const balanceNum = typeof balance.balance === "string" ? parseFloat(balance.balance) : balance.balance || 0;
4791
- return sum + balanceNum;
4792
- }, 0).toString();
4793
- networksTemp.push({
4794
- networkId: blockchain,
4795
- totalValueUsd: networkTotal,
4796
- gasAssetCaip: nativeAssetCaip || null,
4797
- gasAssetSymbol: gasAsset?.symbol || null,
4798
- icon: gasAsset?.icon || null,
4799
- color: gasAsset?.color || null,
4800
- totalNativeBalance
4801
- });
4802
- totalPortfolioValue += networkTotal;
4803
- }
4804
- dashboardData.networks = networksTemp.sort((a2, b2) => b2.totalValueUsd - a2.totalValueUsd);
4805
- dashboardData.totalValueUsd = totalPortfolioValue;
4806
- dashboardData.networkPercentages = dashboardData.networks.map((network) => ({
4807
- networkId: network.networkId,
4808
- percentage: totalPortfolioValue > 0 ? Number((network.totalValueUsd / totalPortfolioValue * 100).toFixed(2)) : 0
4809
- })).filter((entry) => entry.percentage > 0);
4810
- this.dashboard = dashboardData;
4811
- this.syncState = {
4812
- isSynced: true,
4813
- isInitialSync: false,
4814
- cacheAge: 0,
4815
- syncProgress: 100,
4816
- syncedChains: this.blockchains.length,
4817
- totalChains: this.blockchains.length,
4818
- lastSyncTime: Date.now(),
4819
- syncSource: "fresh"
4820
- };
5015
+ this.syncState.syncProgress = 95;
5016
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5017
+ log6.info(tag6, "Building dashboard...");
5018
+ this.dashboard = buildDashboardFromBalances(this.balances, [...new Set(this.blockchains)], this.assetsMap);
5019
+ this.syncState = createFreshSyncState(this.blockchains.length);
4821
5020
  this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4822
5021
  this.events.emit("SYNC_COMPLETE", this.syncState);
5022
+ log6.info(tag6, "✅ Sync complete!");
4823
5023
  return true;
4824
5024
  } catch (e) {
4825
- console.error(tag6, "Error in sync:", e);
5025
+ log6.error(tag6, "Sync failed:", e);
5026
+ this.syncState = {
5027
+ ...this.syncState,
5028
+ isSynced: false,
5029
+ syncProgress: 0
5030
+ };
5031
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5032
+ this.events.emit("SYNC_ERROR", e);
4826
5033
  throw e;
4827
5034
  }
4828
5035
  };
@@ -4836,7 +5043,7 @@ class SDK {
4836
5043
  }
4837
5044
  };
4838
5045
  this.buildTx = async function(sendPayload) {
4839
- let tag6 = TAG9 + " | buildTx | ";
5046
+ let tag6 = TAG12 + " | buildTx | ";
4840
5047
  try {
4841
5048
  const transactionDependencies = {
4842
5049
  context: this.context,
@@ -4858,7 +5065,7 @@ class SDK {
4858
5065
  }
4859
5066
  };
4860
5067
  this.buildDelegateTx = async function(caip, params) {
4861
- let tag6 = TAG9 + " | buildDelegateTx | ";
5068
+ let tag6 = TAG12 + " | buildDelegateTx | ";
4862
5069
  try {
4863
5070
  const delegateParams = {
4864
5071
  ...params,
@@ -4873,7 +5080,7 @@ class SDK {
4873
5080
  }
4874
5081
  };
4875
5082
  this.buildUndelegateTx = async function(caip, params) {
4876
- let tag6 = TAG9 + " | buildUndelegateTx | ";
5083
+ let tag6 = TAG12 + " | buildUndelegateTx | ";
4877
5084
  try {
4878
5085
  const undelegateParams = {
4879
5086
  ...params,
@@ -4888,7 +5095,7 @@ class SDK {
4888
5095
  }
4889
5096
  };
4890
5097
  this.buildClaimRewardsTx = async function(caip, params) {
4891
- let tag6 = TAG9 + " | buildClaimRewardsTx | ";
5098
+ let tag6 = TAG12 + " | buildClaimRewardsTx | ";
4892
5099
  try {
4893
5100
  const claimParams = {
4894
5101
  ...params,
@@ -4903,7 +5110,7 @@ class SDK {
4903
5110
  }
4904
5111
  };
4905
5112
  this.buildClaimAllRewardsTx = async function(caip, params) {
4906
- let tag6 = TAG9 + " | buildClaimAllRewardsTx | ";
5113
+ let tag6 = TAG12 + " | buildClaimAllRewardsTx | ";
4907
5114
  try {
4908
5115
  const claimAllParams = {
4909
5116
  ...params,
@@ -4917,7 +5124,7 @@ class SDK {
4917
5124
  }
4918
5125
  };
4919
5126
  this.signTx = async function(caip, unsignedTx) {
4920
- let tag6 = TAG9 + " | signTx | ";
5127
+ let tag6 = TAG12 + " | signTx | ";
4921
5128
  try {
4922
5129
  const transactionDependencies = {
4923
5130
  context: this.context,
@@ -4938,7 +5145,7 @@ class SDK {
4938
5145
  }
4939
5146
  };
4940
5147
  this.broadcastTx = async function(caip, signedTx) {
4941
- let tag6 = TAG9 + " | broadcastTx | ";
5148
+ let tag6 = TAG12 + " | broadcastTx | ";
4942
5149
  try {
4943
5150
  const transactionDependencies = {
4944
5151
  context: this.context,
@@ -4962,7 +5169,7 @@ class SDK {
4962
5169
  }
4963
5170
  };
4964
5171
  this.swap = async function(swapPayload) {
4965
- let tag6 = `${TAG9} | swap | `;
5172
+ let tag6 = `${TAG12} | swap | `;
4966
5173
  try {
4967
5174
  if (!swapPayload)
4968
5175
  throw Error("swapPayload required!");
@@ -4980,15 +5187,6 @@ class SDK {
4980
5187
  throw Error("Invalid networkId for outboundAssetContext");
4981
5188
  if (!this.outboundAssetContext || !this.outboundAssetContext.address)
4982
5189
  throw Error("Invalid outboundAssetContext missing address");
4983
- const matchesNetwork = (pubkey, networkId) => {
4984
- if (!pubkey.networks || !Array.isArray(pubkey.networks))
4985
- return false;
4986
- if (pubkey.networks.includes(networkId))
4987
- return true;
4988
- if (networkId.startsWith("eip155:") && pubkey.networks.includes("eip155:*"))
4989
- return true;
4990
- return false;
4991
- };
4992
5190
  const pubkeys = this.pubkeys.filter((e) => matchesNetwork(e, this.assetContext.networkId));
4993
5191
  let senderAddress = pubkeys[0]?.address || pubkeys[0]?.master || pubkeys[0]?.pubkey;
4994
5192
  if (!senderAddress)
@@ -5020,17 +5218,8 @@ class SDK {
5020
5218
  this.assetContext.balance = totalBalance.toString();
5021
5219
  this.assetContext.valueUsd = (totalBalance * parseFloat(this.assetContext.priceUsd || "0")).toFixed(2);
5022
5220
  console.log(tag6, `Updated assetContext balance to aggregated total: ${totalBalance}`);
5023
- const feeReserves = {
5024
- "bip122:000000000019d6689c085ae165831e93/slip44:0": 0.00005,
5025
- "eip155:1/slip44:60": 0.001,
5026
- "cosmos:thorchain-mainnet-v1/slip44:931": 0.02,
5027
- "bip122:00000000001a91e3dace36e2be3bf030/slip44:3": 1,
5028
- "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": 0.001,
5029
- "bip122:000000000000000000651ef99cb9fcbe/slip44:145": 0.0005
5030
- };
5031
- const reserve = feeReserves[swapPayload.caipIn] || 0.0001;
5032
- inputAmount = Math.max(0, totalBalance - reserve);
5033
- console.log(tag6, `Using max amount for swap: ${inputAmount} (total balance: ${totalBalance}, reserve: ${reserve})`);
5221
+ inputAmount = getMaxSendableAmount(totalBalance, swapPayload.caipIn);
5222
+ console.log(tag6, `Using max amount for swap: ${inputAmount} (total balance: ${totalBalance})`);
5034
5223
  } else {
5035
5224
  inputAmount = typeof swapPayload.amount === "string" ? parseFloat(swapPayload.amount) : swapPayload.amount;
5036
5225
  if (isNaN(inputAmount) || inputAmount <= 0) {
@@ -5151,7 +5340,7 @@ class SDK {
5151
5340
  }
5152
5341
  };
5153
5342
  this.transfer = async function(sendPayload) {
5154
- let tag6 = `${TAG9} | transfer | `;
5343
+ let tag6 = `${TAG12} | transfer | `;
5155
5344
  try {
5156
5345
  if (!sendPayload)
5157
5346
  throw Error("sendPayload required!");
@@ -5246,7 +5435,7 @@ class SDK {
5246
5435
  }
5247
5436
  };
5248
5437
  this.setBlockchains = async function(blockchains) {
5249
- const tag6 = `${TAG9} | setBlockchains | `;
5438
+ const tag6 = `${TAG12} | setBlockchains | `;
5250
5439
  try {
5251
5440
  if (!blockchains)
5252
5441
  throw Error("blockchains required!");
@@ -5262,7 +5451,7 @@ class SDK {
5262
5451
  }
5263
5452
  };
5264
5453
  this.addAsset = async function(caip, data) {
5265
- let tag6 = TAG9 + " | addAsset | ";
5454
+ let tag6 = TAG12 + " | addAsset | ";
5266
5455
  try {
5267
5456
  let success = false;
5268
5457
  if (!caip)
@@ -5300,7 +5489,7 @@ class SDK {
5300
5489
  }
5301
5490
  };
5302
5491
  this.clearWalletState = async function() {
5303
- const tag6 = `${TAG9} | clearWalletState | `;
5492
+ const tag6 = `${TAG12} | clearWalletState | `;
5304
5493
  try {
5305
5494
  this.context = null;
5306
5495
  this.paths = [];
@@ -5315,7 +5504,7 @@ class SDK {
5315
5504
  }
5316
5505
  };
5317
5506
  this.addPath = async function(path) {
5318
- const tag6 = `${TAG9} | addPath | `;
5507
+ const tag6 = `${TAG12} | addPath | `;
5319
5508
  try {
5320
5509
  this.paths.push(path);
5321
5510
  const pubkey = await getPubkey(path.networks[0], path, this.keepKeySdk, this.context);
@@ -5329,7 +5518,7 @@ class SDK {
5329
5518
  }
5330
5519
  };
5331
5520
  this.addPaths = async function(paths) {
5332
- const tag6 = `${TAG9} | addPaths | `;
5521
+ const tag6 = `${TAG12} | addPaths | `;
5333
5522
  try {
5334
5523
  console.log(tag6, `Adding ${paths.length} paths in batch mode...`);
5335
5524
  this.paths.push(...paths);
@@ -5365,7 +5554,7 @@ class SDK {
5365
5554
  return this.getGasAssets();
5366
5555
  };
5367
5556
  this.getGasAssets = async function() {
5368
- const tag6 = `${TAG9} | getGasAssets | `;
5557
+ const tag6 = `${TAG12} | getGasAssets | `;
5369
5558
  try {
5370
5559
  for (let i = 0;i < this.blockchains.length; i++) {
5371
5560
  let networkId = this.blockchains[i];
@@ -5379,28 +5568,6 @@ class SDK {
5379
5568
  throw Error("GAS Asset MISSING from assetData " + caip);
5380
5569
  }
5381
5570
  }
5382
- const mayaTokenCaip = "cosmos:mayachain-mainnet-v1/denom:maya";
5383
- if (!this.assetsMap.has(mayaTokenCaip)) {
5384
- const mayaToken = {
5385
- caip: mayaTokenCaip,
5386
- networkId: "cosmos:mayachain-mainnet-v1",
5387
- chainId: "mayachain-mainnet-v1",
5388
- symbol: "MAYA",
5389
- name: "Maya Token",
5390
- precision: 4,
5391
- decimals: 4,
5392
- color: "#00D4AA",
5393
- icon: "https://pioneers.dev/coins/maya.png",
5394
- explorer: "https://explorer.mayachain.info",
5395
- explorerAddressLink: "https://explorer.mayachain.info/address/{{address}}",
5396
- explorerTxLink: "https://explorer.mayachain.info/tx/{{txid}}",
5397
- type: "token",
5398
- isToken: true,
5399
- denom: "maya"
5400
- };
5401
- this.assetsMap.set(mayaTokenCaip, mayaToken);
5402
- console.log(tag6, "Added MAYA token to assetsMap");
5403
- }
5404
5571
  return this.assetsMap;
5405
5572
  } catch (e) {
5406
5573
  console.error(e);
@@ -5408,7 +5575,7 @@ class SDK {
5408
5575
  }
5409
5576
  };
5410
5577
  this.getPubkeys = async function() {
5411
- const tag6 = `${TAG9} | getPubkeys | `;
5578
+ const tag6 = `${TAG12} | getPubkeys | `;
5412
5579
  try {
5413
5580
  if (this.paths.length === 0)
5414
5581
  throw new Error("No paths found!");
@@ -5453,134 +5620,57 @@ class SDK {
5453
5620
  }
5454
5621
  };
5455
5622
  this.getBalancesForNetworks = async function(networkIds, forceRefresh) {
5456
- const tag6 = `${TAG9} | getBalancesForNetworks | `;
5623
+ const tag6 = `${TAG12} | getBalancesForNetworks | `;
5457
5624
  try {
5458
5625
  if (!this.pioneer) {
5459
- console.error(tag6, "ERROR: Pioneer client not initialized! this.pioneer is:", this.pioneer);
5460
5626
  throw new Error("Pioneer client not initialized. Call init() first.");
5461
5627
  }
5462
- if (forceRefresh) {
5463
- console.log(tag6, "\uD83D\uDD04 Force refresh requested - bypassing balance cache");
5464
- }
5465
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Input networks:", networkIds);
5466
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Total pubkeys:", this.pubkeys.length);
5467
- const pubkeysWithNetworks = this.pubkeys.filter((p) => p.networks && Array.isArray(p.networks));
5468
- const pubkeysWithoutNetworks = this.pubkeys.filter((p) => !p.networks || !Array.isArray(p.networks));
5469
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Pubkeys WITH networks:", pubkeysWithNetworks.length);
5470
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Pubkeys WITHOUT networks:", pubkeysWithoutNetworks.length);
5471
- if (pubkeysWithoutNetworks.length > 0) {
5472
- console.warn("⚠️ [WARNING] Some pubkeys missing networks field:");
5473
- pubkeysWithoutNetworks.forEach((pk) => {
5474
- console.warn(` - ${pk.note || pk.pubkey.slice(0, 10)}: networks=${pk.networks}`);
5475
- });
5476
- }
5628
+ if (forceRefresh)
5629
+ console.log(tag6, "\uD83D\uDD04 Force refresh requested");
5630
+ console.log("\uD83D\uDD0D [DIAGNOSTIC] Networks:", networkIds.length, "Pubkeys:", this.pubkeys.length);
5631
+ const { valid, invalid } = validatePubkeysNetworks(this.pubkeys, "\uD83D\uDD0D [DIAGNOSTIC]");
5632
+ console.log("\uD83D\uDD0D [DIAGNOSTIC] Pubkeys:", { valid: valid.length, invalid: invalid.length });
5477
5633
  const assetQuery = [];
5478
5634
  for (const networkId of networkIds) {
5479
- let adjustedNetworkId = networkId;
5480
- if (adjustedNetworkId.includes("eip155:")) {
5481
- adjustedNetworkId = "eip155:*";
5482
- }
5483
- const isEip155 = adjustedNetworkId.includes("eip155");
5484
- let pubkeys = this.pubkeys.filter((pubkey) => pubkey.networks && Array.isArray(pubkey.networks) && pubkey.networks.some((network) => {
5485
- if (isEip155)
5486
- return network.startsWith("eip155:");
5487
- return network === adjustedNetworkId;
5488
- }));
5489
- if (pubkeys.length === 0) {
5490
- console.warn(tag6, `⚠️ No pubkeys found for ${networkId} with networks field`);
5491
- console.warn(tag6, "Attempting fallback: finding pubkeys by path matching");
5492
- const pathsForNetwork = this.paths.filter((p) => p.networks?.includes(networkId) || networkId.startsWith("eip155:") && p.networks?.includes("eip155:*"));
5493
- for (const path of pathsForNetwork) {
5494
- const matchingPubkey = this.pubkeys.find((pk) => JSON.stringify(pk.addressNList) === JSON.stringify(path.addressNList));
5495
- if (matchingPubkey) {
5496
- console.warn(tag6, ` ✓ Found pubkey via path matching: ${matchingPubkey.note || matchingPubkey.pubkey.slice(0, 10)}`);
5497
- pubkeys.push(matchingPubkey);
5498
- }
5499
- }
5500
- if (pubkeys.length > 0) {
5501
- console.warn(tag6, ` ✅ Fallback successful: Found ${pubkeys.length} pubkeys for ${networkId}`);
5502
- } else {
5503
- console.error(tag6, ` ❌ Fallback failed: No pubkeys found for ${networkId}`);
5504
- }
5505
- }
5506
- const caipNative = await networkIdToCaip2(networkId);
5507
- for (const pubkey of pubkeys) {
5508
- assetQuery.push({ caip: caipNative, pubkey: pubkey.pubkey });
5509
- }
5510
- }
5511
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Built assetQuery with", assetQuery.length, "entries");
5512
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Sample queries:", assetQuery.slice(0, 5));
5513
- const caipCounts = new Map;
5514
- for (const query of assetQuery) {
5515
- caipCounts.set(query.caip, (caipCounts.get(query.caip) || 0) + 1);
5516
- }
5517
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Queries by chain:");
5518
- caipCounts.forEach((count, caip) => {
5519
- console.log(` - ${caip}: ${count} queries`);
5520
- });
5521
- console.log(`⏱️ [PERF] Starting GetPortfolioBalances API call...`);
5522
- const apiCallStart = performance.now();
5523
- console.time("GetPortfolioBalances Response Time");
5524
- try {
5525
- let marketInfo = await this.pioneer.GetPortfolioBalances({ pubkeys: assetQuery }, forceRefresh ? { forceRefresh: true } : undefined);
5526
- const apiCallTime = performance.now() - apiCallStart;
5527
- console.timeEnd("GetPortfolioBalances Response Time");
5528
- console.log(`⏱️ [PERF] API call completed in ${apiCallTime.toFixed(0)}ms`);
5529
- const enrichStart = performance.now();
5530
- let balances = marketInfo.data;
5531
- console.log(`⏱️ [PERF] Received ${balances?.length || 0} balances from server`);
5532
- console.log(`⏱️ [PERF] Starting balance enrichment...`);
5533
- for (let balance of balances) {
5534
- const assetInfo = this.assetsMap.get(balance.caip.toLowerCase()) || this.assetsMap.get(balance.caip);
5535
- if (!assetInfo) {
5536
- console.warn(`⚠️ [ENRICHMENT] Asset metadata missing for ${balance.caip}, using fallback enrichment`);
5537
- const inferredType = this.inferTypeFromCaip(balance.caip);
5538
- Object.assign(balance, {
5539
- type: balance.type || inferredType,
5540
- isNative: balance.isNative ?? inferredType === "native",
5541
- networkId: caipToNetworkId7(balance.caip),
5542
- icon: "https://pioneers.dev/coins/unknown.png",
5543
- identifier: `${balance.caip}:${balance.pubkey}`,
5544
- updated: Date.now()
5545
- });
5546
- continue;
5547
- }
5548
- const color = ASSET_COLORS[balance.caip] || assetInfo.color;
5549
- Object.assign(balance, assetInfo, {
5550
- type: balance.type || assetInfo.type,
5551
- isNative: balance.isNative ?? assetInfo.isNative,
5552
- networkId: caipToNetworkId7(balance.caip),
5553
- icon: assetInfo.icon || "https://pioneers.dev/coins/etherum.png",
5554
- identifier: `${balance.caip}:${balance.pubkey}`,
5555
- updated: Date.now(),
5556
- color
5557
- });
5558
- }
5559
- const enrichTime = performance.now() - enrichStart;
5560
- console.log(`⏱️ [PERF] Enrichment completed in ${enrichTime.toFixed(0)}ms`);
5561
- this.balances = balances;
5562
- this.events.emit("SET_BALANCES", this.balances);
5563
- console.log(`⏱️ [PERF] Building dashboard from ${balances.length} balances...`);
5564
- const dashboardStart = performance.now();
5565
- const dashboardData = this.buildDashboardFromBalances();
5566
- this.dashboard = dashboardData;
5567
- this.events.emit("SET_DASHBOARD", this.dashboard);
5568
- console.log(`⏱️ [PERF] Dashboard built in ${(performance.now() - dashboardStart).toFixed(0)}ms`);
5569
- console.log(`\uD83D\uDCCA Dashboard created: ${this.dashboard?.networks?.length || 0} networks, $${this.dashboard?.totalValueUsd?.toFixed(2) || "0.00"} total`);
5570
- console.log(`⏱️ [PERF] Total getBalancesForNetworks: ${(performance.now() - apiCallStart).toFixed(0)}ms`);
5571
- return this.balances;
5572
- } catch (apiError) {
5573
- console.error(tag6, "GetPortfolioBalances API call failed:", apiError);
5574
- throw new Error(`GetPortfolioBalances API call failed: ${apiError?.message || "Unknown error"}`);
5635
+ const pubkeys = findPubkeysForNetwork(this.pubkeys, networkId, this.paths, tag6);
5636
+ const caip = await networkIdToCaip2(networkId);
5637
+ assetQuery.push(...buildAssetQuery(pubkeys, caip));
5575
5638
  }
5639
+ logQueryDiagnostics(assetQuery, "\uD83D\uDD0D [DIAGNOSTIC]");
5640
+ console.log(`⏱️ [PERF] Starting GetPortfolioBalances...`);
5641
+ const apiStart = performance.now();
5642
+ console.time("GetPortfolioBalances Response");
5643
+ const marketInfo = await this.pioneer.GetPortfolioBalances({ pubkeys: assetQuery }, forceRefresh ? { forceRefresh: true } : undefined);
5644
+ console.timeEnd("GetPortfolioBalances Response");
5645
+ console.log(`⏱️ [PERF] API completed in ${(performance.now() - apiStart).toFixed(0)}ms`);
5646
+ const enrichStart = performance.now();
5647
+ console.log(`⏱️ [PERF] Enriching ${marketInfo.data?.length || 0} balances...`);
5648
+ const balances = enrichBalancesWithAssetInfo(marketInfo.data, this.assetsMap, caipToNetworkId7);
5649
+ console.log(`⏱️ [PERF] Enrichment completed in ${(performance.now() - enrichStart).toFixed(0)}ms`);
5650
+ this.balances = balances;
5651
+ this.events.emit("SET_BALANCES", this.balances);
5652
+ const dashStart = performance.now();
5653
+ this.dashboard = this.buildDashboardFromBalances();
5654
+ this.events.emit("SET_DASHBOARD", this.dashboard);
5655
+ console.log(`⏱️ [PERF] Dashboard built in ${(performance.now() - dashStart).toFixed(0)}ms`);
5656
+ console.log(`\uD83D\uDCCA Dashboard: ${this.dashboard?.networks?.length || 0} networks, $${this.dashboard?.totalValueUsd?.toFixed(2) || "0.00"}`);
5657
+ console.log(`⏱️ [PERF] Total: ${(performance.now() - apiStart).toFixed(0)}ms`);
5658
+ return this.balances;
5576
5659
  } catch (e) {
5577
- console.error(tag6, "Error: ", e);
5660
+ console.error(tag6, "Error:", e?.message || e);
5578
5661
  throw e;
5579
5662
  }
5580
5663
  };
5581
- this.getBalances = async function(forceRefresh) {
5582
- const tag6 = `${TAG9} | getBalances | `;
5664
+ this.getBalances = async function(forceRefresh, caip) {
5665
+ const tag6 = `${TAG12} | getBalances | `;
5583
5666
  try {
5667
+ if (caip) {
5668
+ console.log(tag6, `\uD83C\uDFAF Refreshing single asset: ${caip}`);
5669
+ const networkId = caip.split("/")[0];
5670
+ console.log(tag6, `\uD83D\uDCCD Target network: ${networkId}`);
5671
+ const results = await this.getBalancesForNetworks([networkId], forceRefresh);
5672
+ return results.filter((b2) => b2.caip === caip || b2.networkId === networkId);
5673
+ }
5584
5674
  return await this.getBalancesForNetworks(this.blockchains, forceRefresh);
5585
5675
  } catch (e) {
5586
5676
  console.error(tag6, "Error in getBalances: ", e);
@@ -5588,7 +5678,7 @@ class SDK {
5588
5678
  }
5589
5679
  };
5590
5680
  this.getBalance = async function(networkId) {
5591
- const tag6 = `${TAG9} | getBalance | `;
5681
+ const tag6 = `${TAG12} | getBalance | `;
5592
5682
  try {
5593
5683
  const results = await this.getBalancesForNetworks([networkId]);
5594
5684
  const filtered = results.filter(async (b2) => b2.networkId === await networkIdToCaip2(networkId));
@@ -5599,7 +5689,7 @@ class SDK {
5599
5689
  }
5600
5690
  };
5601
5691
  this.getFees = async function(networkId) {
5602
- const tag6 = `${TAG9} | getFees | `;
5692
+ const tag6 = `${TAG12} | getFees | `;
5603
5693
  try {
5604
5694
  if (!this.pioneer) {
5605
5695
  throw new Error("Pioneer client not initialized. Call init() first.");
@@ -5614,7 +5704,7 @@ class SDK {
5614
5704
  return estimateTransactionFee(feeRate, unit, networkType, txSize);
5615
5705
  };
5616
5706
  this.getCharts = async function() {
5617
- const tag6 = `${TAG9} | getCharts | `;
5707
+ const tag6 = `${TAG12} | getCharts | `;
5618
5708
  try {
5619
5709
  console.log(tag6, "Fetching charts (portfolio + tokens + staking)...");
5620
5710
  const { getCharts: getChartsModular } = await Promise.resolve().then(() => (init_charts(), exports_charts));
@@ -5639,7 +5729,7 @@ class SDK {
5639
5729
  }
5640
5730
  };
5641
5731
  this.setContext = async (context) => {
5642
- const tag6 = `${TAG9} | setContext | `;
5732
+ const tag6 = `${TAG12} | setContext | `;
5643
5733
  try {
5644
5734
  if (!context)
5645
5735
  throw Error("context required!");
@@ -5652,7 +5742,7 @@ class SDK {
5652
5742
  }
5653
5743
  };
5654
5744
  this.setContextType = async (contextType) => {
5655
- const tag6 = `${TAG9} | setContextType | `;
5745
+ const tag6 = `${TAG12} | setContextType | `;
5656
5746
  try {
5657
5747
  if (!contextType)
5658
5748
  throw Error("contextType required!");
@@ -5665,7 +5755,7 @@ class SDK {
5665
5755
  }
5666
5756
  };
5667
5757
  this.refresh = async (forceRefresh) => {
5668
- const tag6 = `${TAG9} | refresh | `;
5758
+ const tag6 = `${TAG12} | refresh | `;
5669
5759
  try {
5670
5760
  if (forceRefresh) {
5671
5761
  console.log(tag6, "\uD83D\uDD04 Force refresh - fetching fresh balances from blockchain");
@@ -5680,7 +5770,7 @@ class SDK {
5680
5770
  }
5681
5771
  };
5682
5772
  this.setAssetContext = async function(asset) {
5683
- const tag6 = `${TAG9} | setAssetContext | `;
5773
+ const tag6 = `${TAG12} | setAssetContext | `;
5684
5774
  try {
5685
5775
  if (!asset) {
5686
5776
  this.assetContext = null;
@@ -5690,114 +5780,28 @@ class SDK {
5690
5780
  throw Error("Invalid Asset! missing caip!");
5691
5781
  if (!asset.networkId)
5692
5782
  asset.networkId = caipToNetworkId7(asset.caip);
5693
- if (!this.pubkeys || this.pubkeys.length === 0) {
5694
- const errorMsg = `Cannot set asset context for ${asset.caip} - no pubkeys loaded. Please initialize wallet first.`;
5695
- console.error(tag6, errorMsg);
5696
- throw new Error(errorMsg);
5697
- }
5698
- const pubkeysForNetwork = this.pubkeys.filter((e) => {
5699
- if (!e.networks || !Array.isArray(e.networks))
5700
- return false;
5701
- if (e.networks.includes(asset.networkId))
5702
- return true;
5703
- if (asset.networkId.startsWith("eip155:") && e.networks.includes("eip155:*")) {
5704
- return true;
5705
- }
5706
- return false;
5707
- });
5708
- if (pubkeysForNetwork.length === 0) {
5709
- const errorMsg = `Cannot set asset context for ${asset.caip} - no address/xpub found for network ${asset.networkId}`;
5710
- console.error(tag6, errorMsg);
5711
- console.error(tag6, "Available networks in pubkeys:", [
5712
- ...new Set(this.pubkeys.flatMap((p) => p.networks || []))
5713
- ]);
5714
- throw new Error(errorMsg);
5715
- }
5716
- const isUtxoChain = asset.networkId.startsWith("bip122:");
5717
- if (isUtxoChain) {
5718
- const xpubFound = pubkeysForNetwork.some((p) => p.type === "xpub" && p.pubkey);
5719
- if (!xpubFound) {
5720
- const errorMsg = `Cannot set asset context for UTXO chain ${asset.caip} - xpub required but not found`;
5721
- console.error(tag6, errorMsg);
5722
- throw new Error(errorMsg);
5723
- }
5724
- }
5725
- const hasValidAddress = pubkeysForNetwork.some((p) => p.address || p.master || p.pubkey);
5726
- if (!hasValidAddress) {
5727
- const errorMsg = `Cannot set asset context for ${asset.caip} - no valid address found in pubkeys`;
5728
- console.error(tag6, errorMsg);
5729
- throw new Error(errorMsg);
5730
- }
5783
+ validatePubkeysForNetwork(this.pubkeys, asset.networkId, asset.caip);
5784
+ const pubkeysForNetwork = findPubkeysForNetwork(this.pubkeys, asset.networkId);
5731
5785
  console.log(tag6, `✅ Validated: Found ${pubkeysForNetwork.length} addresses for ${asset.networkId}`);
5732
- let freshPriceUsd = 0;
5733
- try {
5734
- if (!asset.caip || typeof asset.caip !== "string" || !asset.caip.includes(":")) {
5735
- console.warn(tag6, "Invalid or missing CAIP, skipping market price fetch:", asset.caip);
5736
- } else {
5737
- console.log(tag6, "Fetching fresh market price for:", asset.caip);
5738
- const marketData = await this.pioneer.GetMarketInfo([asset.caip]);
5739
- console.log(tag6, "Market data response:", marketData);
5740
- if (marketData && marketData.data && marketData.data.length > 0) {
5741
- freshPriceUsd = marketData.data[0];
5742
- console.log(tag6, "✅ Fresh market price:", freshPriceUsd);
5743
- } else {
5744
- console.warn(tag6, "No market data returned for:", asset.caip);
5745
- }
5746
- }
5747
- } catch (marketError) {
5748
- console.error(tag6, "Error fetching market price:", marketError);
5749
- }
5750
- let assetInfo = this.assetsMap.get(asset.caip.toLowerCase());
5751
- console.log(tag6, "assetInfo: ", assetInfo);
5752
- let assetInfoDiscovery = assetData2[asset.caip];
5753
- console.log(tag6, "assetInfoDiscovery: ", assetInfoDiscovery);
5754
- if (assetInfoDiscovery)
5755
- assetInfo = assetInfoDiscovery;
5756
- if (!assetInfo) {
5757
- console.log(tag6, "Building placeholder asset!");
5758
- assetInfo = {
5759
- caip: asset.caip.toLowerCase(),
5760
- networkId: asset.networkId,
5761
- symbol: asset.symbol || "UNKNOWN",
5762
- name: asset.name || "Unknown Asset",
5763
- icon: asset.icon || "https://pioneers.dev/coins/ethereum.png"
5764
- };
5765
- }
5786
+ const freshPriceUsd = await fetchMarketPrice(this.pioneer, asset.caip);
5787
+ let assetInfo = resolveAssetInfo(this.assetsMap, assetData2, asset);
5766
5788
  const matchingBalances = this.balances.filter((b2) => b2.caip === asset.caip);
5767
5789
  if (matchingBalances.length > 0) {
5768
- let priceValue = matchingBalances[0].priceUsd || matchingBalances[0].price;
5769
- if ((!priceValue || priceValue === 0) && matchingBalances[0].valueUsd && matchingBalances[0].balance) {
5770
- const balance = parseFloat(matchingBalances[0].balance);
5771
- const valueUsd = parseFloat(matchingBalances[0].valueUsd);
5772
- if (balance > 0 && valueUsd > 0) {
5773
- priceValue = valueUsd / balance;
5774
- console.log(tag6, "calculated priceUsd from valueUsd/balance:", priceValue);
5775
- }
5776
- }
5777
- if (priceValue && priceValue > 0) {
5790
+ const priceValue = extractPriceFromBalances(matchingBalances);
5791
+ if (priceValue > 0) {
5778
5792
  console.log(tag6, "detected priceUsd from balance:", priceValue);
5779
5793
  assetInfo.priceUsd = priceValue;
5780
5794
  }
5781
5795
  }
5782
- if (freshPriceUsd && freshPriceUsd > 0) {
5796
+ if (freshPriceUsd > 0) {
5783
5797
  assetInfo.priceUsd = freshPriceUsd;
5784
5798
  console.log(tag6, "✅ Using fresh market price:", freshPriceUsd);
5785
- let totalBalance = 0;
5786
- let totalValueUsd = 0;
5787
- console.log(tag6, `Found ${matchingBalances.length} balance entries for ${asset.caip}`);
5788
- for (const balanceEntry of matchingBalances) {
5789
- const balance = parseFloat(balanceEntry.balance) || 0;
5790
- const valueUsd = parseFloat(balanceEntry.valueUsd) || 0;
5791
- totalBalance += balance;
5792
- totalValueUsd += valueUsd;
5793
- console.log(tag6, ` Balance entry: ${balance} (${valueUsd} USD)`);
5794
- }
5799
+ const { totalBalance, totalValueUsd } = aggregateBalances(matchingBalances, asset.caip);
5795
5800
  assetInfo.balance = totalBalance.toString();
5796
5801
  assetInfo.valueUsd = totalValueUsd.toFixed(2);
5797
- console.log(tag6, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
5798
5802
  }
5799
5803
  const assetBalances = this.balances.filter((b2) => b2.caip === asset.caip);
5800
- const assetPubkeys = this.pubkeys.filter((p) => p.networks && Array.isArray(p.networks) && p.networks.includes(caipToNetworkId7(asset.caip)) || caipToNetworkId7(asset.caip).includes("eip155") && p.networks && Array.isArray(p.networks) && p.networks.some((n) => n.startsWith("eip155")));
5804
+ const assetPubkeys = filterPubkeysForAsset(this.pubkeys, asset.caip, caipToNetworkId7);
5801
5805
  const finalAssetContext = {
5802
5806
  ...assetInfo,
5803
5807
  ...asset,
@@ -5807,45 +5811,12 @@ class SDK {
5807
5811
  if ((!asset.priceUsd || asset.priceUsd === 0) && assetInfo.priceUsd && assetInfo.priceUsd > 0) {
5808
5812
  finalAssetContext.priceUsd = assetInfo.priceUsd;
5809
5813
  }
5810
- if (freshPriceUsd && freshPriceUsd > 0) {
5811
- for (const balance of assetBalances) {
5812
- balance.price = freshPriceUsd;
5813
- balance.priceUsd = freshPriceUsd;
5814
- const balanceAmount = parseFloat(balance.balance || 0);
5815
- balance.valueUsd = (balanceAmount * freshPriceUsd).toString();
5816
- }
5817
- console.log(tag6, "Updated all balances with fresh price data");
5814
+ if (freshPriceUsd > 0) {
5815
+ updateBalancesWithPrice(assetBalances, freshPriceUsd);
5818
5816
  }
5819
5817
  this.assetContext = finalAssetContext;
5820
5818
  if (asset.isToken || asset.type === "token" || assetInfo.isToken || assetInfo.type === "token") {
5821
5819
  const networkId = asset.networkId || assetInfo.networkId;
5822
- let nativeSymbol = "GAS";
5823
- let nativeCaip = "";
5824
- if (networkId.includes("mayachain")) {
5825
- nativeSymbol = "CACAO";
5826
- nativeCaip = "cosmos:mayachain-mainnet-v1/slip44:931";
5827
- } else if (networkId.includes("thorchain")) {
5828
- nativeSymbol = "RUNE";
5829
- nativeCaip = "cosmos:thorchain-mainnet-v1/slip44:931";
5830
- } else if (networkId.includes("cosmoshub")) {
5831
- nativeSymbol = "ATOM";
5832
- nativeCaip = "cosmos:cosmoshub-4/slip44:118";
5833
- } else if (networkId.includes("osmosis")) {
5834
- nativeSymbol = "OSMO";
5835
- nativeCaip = "cosmos:osmosis-1/slip44:118";
5836
- } else if (networkId.includes("eip155:1")) {
5837
- nativeSymbol = "ETH";
5838
- nativeCaip = "eip155:1/slip44:60";
5839
- } else if (networkId.includes("eip155:137")) {
5840
- nativeSymbol = "MATIC";
5841
- nativeCaip = "eip155:137/slip44:60";
5842
- } else if (networkId.includes("eip155:56")) {
5843
- nativeSymbol = "BNB";
5844
- nativeCaip = "eip155:56/slip44:60";
5845
- } else if (networkId.includes("eip155:43114")) {
5846
- nativeSymbol = "AVAX";
5847
- nativeCaip = "eip155:43114/slip44:60";
5848
- }
5849
5820
  this.assetContext.nativeSymbol = nativeSymbol;
5850
5821
  if (nativeCaip) {
5851
5822
  const nativeBalance = this.balances.find((b2) => b2.caip === nativeCaip);
@@ -5879,7 +5850,7 @@ class SDK {
5879
5850
  }
5880
5851
  };
5881
5852
  this.setPubkeyContext = async function(pubkey) {
5882
- let tag6 = `${TAG9} | setPubkeyContext | `;
5853
+ let tag6 = `${TAG12} | setPubkeyContext | `;
5883
5854
  try {
5884
5855
  if (!pubkey)
5885
5856
  throw Error("pubkey is required");
@@ -5898,97 +5869,40 @@ class SDK {
5898
5869
  }
5899
5870
  };
5900
5871
  this.setOutboundAssetContext = async function(asset) {
5901
- const tag6 = `${TAG9} | setOutputAssetContext | `;
5872
+ const tag6 = `${TAG12} | setOutputAssetContext | `;
5902
5873
  try {
5903
- console.log(tag6, "0. asset: ", asset);
5874
+ console.log(tag6, "asset:", asset);
5904
5875
  if (!asset) {
5905
5876
  this.outboundAssetContext = null;
5906
5877
  return;
5907
5878
  }
5908
- console.log(tag6, "1 asset: ", asset);
5909
5879
  if (!asset.caip)
5910
5880
  throw Error("Invalid Asset! missing caip!");
5911
5881
  if (!asset.networkId)
5912
5882
  asset.networkId = caipToNetworkId7(asset.caip);
5913
- console.log(tag6, "networkId: ", asset.networkId);
5914
- console.log(tag6, "this.pubkeys: ", this.pubkeys);
5915
- const pubkey = this.pubkeys.find((p) => {
5916
- if (!p.networks || !Array.isArray(p.networks))
5917
- return false;
5918
- if (p.networks.includes(asset.networkId))
5919
- return true;
5920
- if (asset.networkId.startsWith("eip155:") && p.networks.includes("eip155:*"))
5921
- return true;
5922
- return false;
5923
- });
5883
+ console.log(tag6, "networkId:", asset.networkId);
5884
+ const pubkey = findPubkeyForNetwork(this.pubkeys, asset.networkId);
5924
5885
  if (!pubkey)
5925
5886
  throw Error("Invalid network! missing pubkey for network! " + asset.networkId);
5926
- let freshPriceUsd = 0;
5927
- try {
5928
- if (!asset.caip || typeof asset.caip !== "string" || !asset.caip.includes(":")) {
5929
- console.warn(tag6, "Invalid or missing CAIP, skipping market price fetch:", asset.caip);
5930
- } else {
5931
- console.log(tag6, "Fetching fresh market price for:", asset.caip);
5932
- const marketData = await this.pioneer.GetMarketInfo([asset.caip]);
5933
- console.log(tag6, "Market data response:", marketData);
5934
- if (marketData && marketData.data && marketData.data.length > 0) {
5935
- freshPriceUsd = marketData.data[0];
5936
- console.log(tag6, "✅ Fresh market price:", freshPriceUsd);
5937
- } else {
5938
- console.warn(tag6, "No market data returned for:", asset.caip);
5939
- }
5940
- }
5941
- } catch (marketError) {
5942
- console.error(tag6, "Error fetching market price:", marketError);
5943
- }
5944
- let assetInfo = this.assetsMap.get(asset.caip.toLowerCase());
5945
- console.log(tag6, "assetInfo: ", assetInfo);
5946
- if (!assetInfo) {
5947
- assetInfo = {
5948
- caip: asset.caip.toLowerCase(),
5949
- networkId: asset.networkId,
5950
- symbol: asset.symbol || "UNKNOWN",
5951
- name: asset.name || "Unknown Asset",
5952
- icon: asset.icon || "https://pioneers.dev/coins/ethereum.png"
5953
- };
5954
- }
5887
+ const freshPriceUsd = await fetchMarketPrice(this.pioneer, asset.caip);
5888
+ let assetInfo = resolveAssetInfo(this.assetsMap, assetData2, asset);
5955
5889
  const matchingBalances = this.balances.filter((b2) => b2.caip === asset.caip);
5956
5890
  if (matchingBalances.length > 0) {
5957
- let priceValue = matchingBalances[0].priceUsd || matchingBalances[0].price;
5958
- if ((!priceValue || priceValue === 0) && matchingBalances[0].valueUsd && matchingBalances[0].balance) {
5959
- const balance = parseFloat(matchingBalances[0].balance);
5960
- const valueUsd = parseFloat(matchingBalances[0].valueUsd);
5961
- if (balance > 0 && valueUsd > 0) {
5962
- priceValue = valueUsd / balance;
5963
- console.log(tag6, "calculated priceUsd from valueUsd/balance:", priceValue);
5964
- }
5965
- }
5966
- if (priceValue && priceValue > 0) {
5891
+ const priceValue = extractPriceFromBalances(matchingBalances);
5892
+ if (priceValue > 0) {
5967
5893
  console.log(tag6, "detected priceUsd from balance:", priceValue);
5968
5894
  assetInfo.priceUsd = priceValue;
5969
5895
  }
5970
5896
  }
5971
- if (freshPriceUsd && freshPriceUsd > 0) {
5897
+ if (freshPriceUsd > 0) {
5972
5898
  assetInfo.priceUsd = freshPriceUsd;
5973
5899
  console.log(tag6, "✅ Using fresh market price:", freshPriceUsd);
5974
- let totalBalance = 0;
5975
- let totalValueUsd = 0;
5976
- console.log(tag6, `Found ${matchingBalances.length} balance entries for ${asset.caip}`);
5977
- for (const balanceEntry of matchingBalances) {
5978
- const balance = parseFloat(balanceEntry.balance) || 0;
5979
- const valueUsd = parseFloat(balanceEntry.valueUsd) || 0;
5980
- totalBalance += balance;
5981
- totalValueUsd += valueUsd;
5982
- console.log(tag6, ` Balance entry: ${balance} (${valueUsd} USD)`);
5983
- }
5900
+ const { totalBalance, totalValueUsd } = aggregateBalances(matchingBalances, asset.caip);
5984
5901
  assetInfo.balance = totalBalance.toString();
5985
5902
  assetInfo.valueUsd = totalValueUsd.toFixed(2);
5986
- console.log(tag6, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
5987
5903
  }
5988
- console.log(tag6, "CHECKPOINT 1");
5989
5904
  this.outboundAssetContext = { ...assetInfo, ...asset, ...pubkey };
5990
- console.log(tag6, "CHECKPOINT 3");
5991
- console.log(tag6, "outboundAssetContext: assetInfo: ", assetInfo);
5905
+ console.log(tag6, "outboundAssetContext set:", this.outboundAssetContext.caip);
5992
5906
  if (asset.caip) {
5993
5907
  this.outboundBlockchainContext = caipToNetworkId7(asset.caip);
5994
5908
  } else if (asset.networkId) {
@@ -6004,28 +5918,12 @@ class SDK {
6004
5918
  };
6005
5919
  }
6006
5920
  CheckERC20Allowance = async (params) => {
6007
- const tag6 = TAG9 + " | CheckERC20Allowance | ";
6008
- try {
6009
- console.log(tag6, "Checking ERC20 allowance:", params);
6010
- const result = await this.pioneer.GetTokenAllowance(params);
6011
- console.log(tag6, "Allowance result:", result);
6012
- return result.data;
6013
- } catch (e) {
6014
- console.error(tag6, "Error checking ERC20 allowance:", e);
6015
- throw e;
6016
- }
5921
+ const result = await this.pioneer.GetTokenAllowance(params);
5922
+ return result.data;
6017
5923
  };
6018
5924
  BuildERC20ApprovalTx = async (params) => {
6019
- const tag6 = TAG9 + " | BuildERC20ApprovalTx | ";
6020
- try {
6021
- console.log(tag6, "Building ERC20 approval transaction:", params);
6022
- const result = await this.pioneer.BuildApprovalTransaction(params);
6023
- console.log(tag6, "Approval tx built:", result);
6024
- return result.data;
6025
- } catch (e) {
6026
- console.error(tag6, "Error building approval transaction:", e);
6027
- throw e;
6028
- }
5925
+ const result = await this.pioneer.BuildApprovalTransaction(params);
5926
+ return result.data;
6029
5927
  };
6030
5928
  }
6031
5929
  var src_default = SDK;