@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.cjs CHANGED
@@ -944,7 +944,7 @@ class Pioneer {
944
944
  }
945
945
 
946
946
  // src/index.ts
947
- var import_pioneer_coins4 = require("@pioneer-platform/pioneer-coins");
947
+ var import_pioneer_coins6 = require("@pioneer-platform/pioneer-coins");
948
948
  var import_pioneer_discovery2 = require("@pioneer-platform/pioneer-discovery");
949
949
  var import_pioneer_events = require("@pioneer-platform/pioneer-events");
950
950
  var import_events = __toESM(require("events"));
@@ -3983,25 +3983,404 @@ async function syncMarket(balances, pioneer) {
3983
3983
  }
3984
3984
  }
3985
3985
 
3986
- // src/index.ts
3987
- var TAG9 = " | Pioneer-sdk | ";
3988
- var ASSET_COLORS = {
3989
- "bip122:000000000019d6689c085ae165831e93/slip44:0": "#FF9800",
3990
- "eip155:1/slip44:60": "#627EEA",
3991
- "eip155:137/slip44:60": "#8247E5",
3992
- "eip155:8453/slip44:60": "#0052FF",
3993
- "eip155:56/slip44:60": "#F3BA2F",
3994
- "bip122:12a765e31ffd4059bada1e25190f6e98/slip44:2": "#BFBBBB",
3995
- "bip122:00000000001a91e3dace36e2be3bf030/slip44:3": "#C2A633",
3996
- "bip122:000000000000000000651ef99cb9fcbe/slip44:145": "#8DC351",
3997
- "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": "#008CE7",
3998
- "bip122:4da631f2ac1bed857bd968c67c913978/slip44:20": "#006AD2",
3999
- "cosmos:cosmoshub-4/slip44:118": "#2E3148",
4000
- "cosmos:osmosis-1/slip44:118": "#9B1FD7",
4001
- "ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144": "#23292F",
4002
- "cosmos:mayachain-mainnet-v1/slip44:931": "#00D4AA",
4003
- "cosmos:thorchain-mainnet-v1/slip44:931": "#00CCFF"
3986
+ // src/utils/pubkey-management.ts
3987
+ function getPubkeyKey(pubkey) {
3988
+ return `${pubkey.pubkey}_${pubkey.pathMaster}`;
3989
+ }
3990
+ function deduplicatePubkeys(pubkeys) {
3991
+ const seen = new Set;
3992
+ return pubkeys.filter((pubkey) => {
3993
+ const key = getPubkeyKey(pubkey);
3994
+ if (seen.has(key))
3995
+ return false;
3996
+ seen.add(key);
3997
+ return true;
3998
+ });
3999
+ }
4000
+ function validatePubkey(pubkey) {
4001
+ return !!(pubkey.pubkey && pubkey.pathMaster);
4002
+ }
4003
+ function findPubkeysForNetwork(pubkeys, networkId) {
4004
+ return pubkeys.filter((p) => {
4005
+ if (!p.networks || !Array.isArray(p.networks))
4006
+ return false;
4007
+ if (p.networks.includes(networkId))
4008
+ return true;
4009
+ if (networkId.startsWith("eip155:") && p.networks.includes("eip155:*")) {
4010
+ return true;
4011
+ }
4012
+ return false;
4013
+ });
4014
+ }
4015
+ function findPubkeyForNetwork(pubkeys, networkId) {
4016
+ return pubkeys.find((p) => {
4017
+ if (!p.networks || !Array.isArray(p.networks))
4018
+ return false;
4019
+ if (p.networks.includes(networkId))
4020
+ return true;
4021
+ if (networkId.startsWith("eip155:") && p.networks.includes("eip155:*"))
4022
+ return true;
4023
+ return false;
4024
+ });
4025
+ }
4026
+ function validatePubkeysForNetwork(pubkeys, networkId, caip) {
4027
+ if (!pubkeys || pubkeys.length === 0) {
4028
+ throw new Error(`Cannot set asset context for ${caip} - no pubkeys loaded. Please initialize wallet first.`);
4029
+ }
4030
+ const pubkeysForNetwork = findPubkeysForNetwork(pubkeys, networkId);
4031
+ if (pubkeysForNetwork.length === 0) {
4032
+ const availableNetworks = [...new Set(pubkeys.flatMap((p) => p.networks || []))];
4033
+ throw new Error(`Cannot set asset context for ${caip} - no address/xpub found for network ${networkId}. Available networks: ${availableNetworks.join(", ")}`);
4034
+ }
4035
+ const isUtxoChain = networkId.startsWith("bip122:");
4036
+ if (isUtxoChain) {
4037
+ const xpubFound = pubkeysForNetwork.some((p) => p.type === "xpub" && p.pubkey);
4038
+ if (!xpubFound) {
4039
+ throw new Error(`Cannot set asset context for UTXO chain ${caip} - xpub required but not found`);
4040
+ }
4041
+ }
4042
+ const hasValidAddress = pubkeysForNetwork.some((p) => p.address || p.master || p.pubkey);
4043
+ if (!hasValidAddress) {
4044
+ throw new Error(`Cannot set asset context for ${caip} - no valid address found in pubkeys`);
4045
+ }
4046
+ }
4047
+ function filterPubkeysForAsset(pubkeys, caip, caipToNetworkId7) {
4048
+ const networkId = caipToNetworkId7(caip);
4049
+ return pubkeys.filter((p) => {
4050
+ if (!p.networks || !Array.isArray(p.networks))
4051
+ return false;
4052
+ if (p.networks.includes(networkId))
4053
+ return true;
4054
+ if (networkId.includes("eip155") && p.networks.some((n) => n.startsWith("eip155"))) {
4055
+ return true;
4056
+ }
4057
+ return false;
4058
+ });
4059
+ }
4060
+
4061
+ // src/utils/portfolio-helpers.ts
4062
+ var log2 = require("@pioneer-platform/loggerdog")();
4063
+ var TAG9 = " | portfolio-helpers | ";
4064
+ function isCacheDataValid(portfolioData) {
4065
+ if (!portfolioData.networks || !Array.isArray(portfolioData.networks)) {
4066
+ console.warn("[CACHE VALIDATION] Networks is not an array");
4067
+ return false;
4068
+ }
4069
+ if (portfolioData.networks.length > 50) {
4070
+ console.error(`[CACHE VALIDATION] CORRUPTED: ${portfolioData.networks.length} networks (should be < 50)`);
4071
+ return false;
4072
+ }
4073
+ const validNetworks = portfolioData.networks.filter((n) => n.networkId && n.totalValueUsd !== undefined && n.gasAssetSymbol);
4074
+ if (validNetworks.length === 0 && portfolioData.networks.length > 0) {
4075
+ console.error("[CACHE VALIDATION] CORRUPTED: No networks have required fields");
4076
+ return false;
4077
+ }
4078
+ console.log(`[CACHE VALIDATION] Found ${portfolioData.networks.length} networks, ${validNetworks.length} valid`);
4079
+ return true;
4080
+ }
4081
+ async function fetchMarketPrice(pioneer, caip) {
4082
+ const tag = TAG9 + " | fetchMarketPrice | ";
4083
+ try {
4084
+ if (!caip || typeof caip !== "string" || !caip.includes(":")) {
4085
+ log2.warn(tag, "Invalid or missing CAIP, skipping market price fetch:", caip);
4086
+ return 0;
4087
+ }
4088
+ log2.debug(tag, "Fetching fresh market price for:", caip);
4089
+ const marketData = await pioneer.GetMarketInfo([caip]);
4090
+ log2.debug(tag, "Market data response:", marketData);
4091
+ if (marketData && marketData.data && marketData.data.length > 0) {
4092
+ const price = marketData.data[0];
4093
+ log2.debug(tag, "✅ Fresh market price:", price);
4094
+ return price;
4095
+ } else {
4096
+ log2.warn(tag, "No market data returned for:", caip);
4097
+ return 0;
4098
+ }
4099
+ } catch (marketError) {
4100
+ log2.error(tag, "Error fetching market price:", marketError);
4101
+ return 0;
4102
+ }
4103
+ }
4104
+ function extractPriceFromBalances(balances) {
4105
+ const tag = TAG9 + " | extractPriceFromBalances | ";
4106
+ if (balances.length === 0)
4107
+ return 0;
4108
+ let priceValue = balances[0].priceUsd || balances[0].price;
4109
+ if ((!priceValue || priceValue === 0) && balances[0].valueUsd && balances[0].balance) {
4110
+ const balance = parseFloat(balances[0].balance);
4111
+ const valueUsd = parseFloat(balances[0].valueUsd);
4112
+ if (balance > 0 && valueUsd > 0) {
4113
+ priceValue = valueUsd / balance;
4114
+ log2.debug(tag, "Calculated priceUsd from valueUsd/balance:", priceValue);
4115
+ }
4116
+ }
4117
+ return priceValue || 0;
4118
+ }
4119
+ function aggregateBalances(balances, caip) {
4120
+ const tag = TAG9 + " | aggregateBalances | ";
4121
+ let totalBalance = 0;
4122
+ let totalValueUsd = 0;
4123
+ log2.debug(tag, `Aggregating ${balances.length} balance entries for ${caip}`);
4124
+ for (const balanceEntry of balances) {
4125
+ const balance = parseFloat(balanceEntry.balance) || 0;
4126
+ const valueUsd = parseFloat(balanceEntry.valueUsd) || 0;
4127
+ totalBalance += balance;
4128
+ totalValueUsd += valueUsd;
4129
+ log2.debug(tag, ` Balance entry: ${balance} (${valueUsd} USD)`);
4130
+ }
4131
+ log2.debug(tag, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
4132
+ return { totalBalance, totalValueUsd };
4133
+ }
4134
+ function updateBalancesWithPrice(balances, freshPriceUsd) {
4135
+ const tag = TAG9 + " | updateBalancesWithPrice | ";
4136
+ for (const balance of balances) {
4137
+ balance.price = freshPriceUsd;
4138
+ balance.priceUsd = freshPriceUsd;
4139
+ const balanceAmount = parseFloat(balance.balance || 0);
4140
+ balance.valueUsd = (balanceAmount * freshPriceUsd).toString();
4141
+ }
4142
+ log2.debug(tag, "Updated all balances with fresh price data");
4143
+ }
4144
+ function buildDashboardFromPortfolioData(portfolioData) {
4145
+ const cacheAge = portfolioData.lastUpdated ? Math.floor((Date.now() - portfolioData.lastUpdated) / 1000) : 0;
4146
+ return {
4147
+ totalValueUsd: portfolioData.totalValueUsd,
4148
+ pairedDevices: portfolioData.pairedDevices,
4149
+ devices: portfolioData.devices || [],
4150
+ networks: portfolioData.networks || [],
4151
+ assets: portfolioData.assets || [],
4152
+ statistics: portfolioData.statistics || {},
4153
+ cached: portfolioData.cached,
4154
+ lastUpdated: portfolioData.lastUpdated,
4155
+ cacheAge,
4156
+ networkPercentages: portfolioData.networks?.map((network) => ({
4157
+ networkId: network.network_id || network.networkId,
4158
+ percentage: network.percentage || 0
4159
+ })) || []
4160
+ };
4161
+ }
4162
+ function buildAssetQuery(pubkeys, caip) {
4163
+ return pubkeys.map((pubkey) => ({ caip, pubkey: pubkey.pubkey }));
4164
+ }
4165
+ function logQueryDiagnostics(assetQuery, tag = "") {
4166
+ const caipCounts = new Map;
4167
+ for (const query of assetQuery) {
4168
+ caipCounts.set(query.caip, (caipCounts.get(query.caip) || 0) + 1);
4169
+ }
4170
+ if (tag) {
4171
+ console.log(tag, "Built assetQuery with", assetQuery.length, "entries");
4172
+ console.log(tag, "Sample queries:", assetQuery.slice(0, 5));
4173
+ console.log(tag, "Queries by chain:");
4174
+ caipCounts.forEach((count, caip) => {
4175
+ console.log(` - ${caip}: ${count} queries`);
4176
+ });
4177
+ }
4178
+ }
4179
+ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4180
+ const tag = TAG9 + " | enrichBalancesWithAssetInfo | ";
4181
+ for (const balance of balances) {
4182
+ const assetInfo = assetsMap.get(balance.caip.toLowerCase()) || assetsMap.get(balance.caip);
4183
+ if (!assetInfo) {
4184
+ throw new Error(`Missing AssetInfo for ${balance.caip}`);
4185
+ }
4186
+ Object.assign(balance, assetInfo, {
4187
+ type: balance.type || assetInfo.type,
4188
+ isNative: balance.isNative ?? assetInfo.isNative,
4189
+ networkId: caipToNetworkId7(balance.caip),
4190
+ icon: assetInfo.icon || "https://pioneers.dev/coins/etherum.png",
4191
+ identifier: `${balance.caip}:${balance.pubkey}`,
4192
+ updated: Date.now(),
4193
+ color: assetInfo.color
4194
+ });
4195
+ }
4196
+ return balances;
4197
+ }
4198
+
4199
+ // src/utils/sync-state.ts
4200
+ var log3 = require("@pioneer-platform/loggerdog")();
4201
+ var TAG10 = " | sync-state | ";
4202
+ function resolveAssetInfo(assetsMap, assetData, asset) {
4203
+ const tag = TAG10 + " | resolveAssetInfo | ";
4204
+ let assetInfo = assetsMap.get(asset.caip.toLowerCase());
4205
+ log3.debug(tag, "assetInfo from assetsMap:", assetInfo);
4206
+ const assetInfoDiscovery = assetData[asset.caip];
4207
+ log3.debug(tag, "assetInfoDiscovery:", assetInfoDiscovery);
4208
+ if (assetInfoDiscovery) {
4209
+ assetInfo = assetInfoDiscovery;
4210
+ }
4211
+ if (!assetInfo) {
4212
+ log3.debug(tag, "Building placeholder asset for", asset.caip);
4213
+ assetInfo = {
4214
+ caip: asset.caip.toLowerCase(),
4215
+ networkId: asset.networkId,
4216
+ symbol: asset.symbol || "UNKNOWN",
4217
+ name: asset.name || "Unknown Asset",
4218
+ icon: asset.icon || "https://pioneers.dev/coins/ethereum.png"
4219
+ };
4220
+ }
4221
+ return assetInfo;
4222
+ }
4223
+ function createInitialSyncState(totalChains) {
4224
+ return {
4225
+ isSynced: false,
4226
+ isInitialSync: true,
4227
+ cacheAge: 0,
4228
+ syncProgress: 0,
4229
+ syncedChains: 0,
4230
+ totalChains,
4231
+ lastSyncTime: null,
4232
+ syncSource: "none"
4233
+ };
4234
+ }
4235
+ function createCacheSyncState(lastUpdated, totalChains) {
4236
+ const cacheAge = lastUpdated ? Math.floor((Date.now() - lastUpdated) / 1000) : 0;
4237
+ return {
4238
+ isSynced: true,
4239
+ isInitialSync: false,
4240
+ cacheAge,
4241
+ syncProgress: 100,
4242
+ syncedChains: totalChains,
4243
+ totalChains,
4244
+ lastSyncTime: lastUpdated || Date.now(),
4245
+ syncSource: "cache"
4246
+ };
4247
+ }
4248
+ function createFreshSyncState(totalChains) {
4249
+ return {
4250
+ isSynced: true,
4251
+ isInitialSync: false,
4252
+ cacheAge: 0,
4253
+ syncProgress: 100,
4254
+ syncedChains: totalChains,
4255
+ totalChains,
4256
+ lastSyncTime: Date.now(),
4257
+ syncSource: "fresh"
4258
+ };
4259
+ }
4260
+
4261
+ // src/utils/fee-reserves.ts
4262
+ var TAG11 = " | Pioneer-sdk | fee-reserves | ";
4263
+ var FEE_RESERVE_MAP = {
4264
+ "bip122:000000000019d6689c085ae165831e93/slip44:0": 0.00005,
4265
+ "eip155:1/slip44:60": 0.001,
4266
+ "cosmos:thorchain-mainnet-v1/slip44:931": 0.02,
4267
+ "bip122:00000000001a91e3dace36e2be3bf030/slip44:3": 1,
4268
+ "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": 0.001,
4269
+ "bip122:000000000000000000651ef99cb9fcbe/slip44:145": 0.0005,
4270
+ "bip122:12a765e31ffd4059bada1e25190f6e98/slip44:2": 0.001,
4271
+ "bip122:4da631f2ac1bed857bd968c67c913978/slip44:20": 0.1,
4272
+ "cosmos:cosmoshub-4/slip44:118": 0.005,
4273
+ "cosmos:osmosis-1/slip44:118": 0.035,
4274
+ "cosmos:mayachain-mainnet-v1/slip44:931": 0.5,
4275
+ "eip155:56/slip44:60": 0.001,
4276
+ "eip155:137/slip44:60": 0.01,
4277
+ "eip155:43114/slip44:60": 0.01,
4278
+ "eip155:10/slip44:60": 0.0001,
4279
+ "eip155:8453/slip44:60": 0.0001,
4280
+ "eip155:42161/slip44:60": 0.0001,
4281
+ "ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144": 0.00001
4004
4282
  };
4283
+ var DEFAULT_FEE_RESERVE = 0.001;
4284
+ function getFeeReserve(caip) {
4285
+ if (FEE_RESERVE_MAP[caip]) {
4286
+ return FEE_RESERVE_MAP[caip];
4287
+ }
4288
+ if (caip.startsWith("eip155:") && caip.includes("/slip44:60")) {
4289
+ return FEE_RESERVE_MAP["eip155:1/slip44:60"] || 0.001;
4290
+ }
4291
+ if (caip.startsWith("cosmos:")) {
4292
+ return 0.01;
4293
+ }
4294
+ if (caip.startsWith("bip122:")) {
4295
+ return 0.0001;
4296
+ }
4297
+ console.warn(TAG11, `No fee reserve defined for ${caip}, using default: ${DEFAULT_FEE_RESERVE}`);
4298
+ return DEFAULT_FEE_RESERVE;
4299
+ }
4300
+ function getMaxSendableAmount(balance, caip) {
4301
+ const reserve = getFeeReserve(caip);
4302
+ const maxAmount = Math.max(0, balance - reserve);
4303
+ console.log(TAG11, `Max sendable for ${caip}: ${maxAmount} (balance: ${balance}, reserve: ${reserve})`);
4304
+ return maxAmount;
4305
+ }
4306
+
4307
+ // src/utils/network-helpers.ts
4308
+ function matchesNetwork(item, networkId) {
4309
+ if (!item.networks || !Array.isArray(item.networks))
4310
+ return false;
4311
+ if (item.networks.includes(networkId))
4312
+ return true;
4313
+ if (networkId.startsWith("eip155:") && item.networks.includes("eip155:*"))
4314
+ return true;
4315
+ return false;
4316
+ }
4317
+ function normalizeNetworkId(networkId) {
4318
+ return networkId.includes("eip155:") ? "eip155:*" : networkId;
4319
+ }
4320
+ function validatePubkeysNetworks(pubkeys, tag = "") {
4321
+ const valid = pubkeys.filter((p) => p.networks && Array.isArray(p.networks));
4322
+ const invalid = pubkeys.filter((p) => !p.networks || !Array.isArray(p.networks));
4323
+ if (tag && invalid.length > 0) {
4324
+ console.warn(tag, `⚠️ ${invalid.length} pubkeys missing networks field`);
4325
+ invalid.forEach((pk) => {
4326
+ console.warn(tag, ` - ${pk.note || pk.pubkey.slice(0, 10)}: networks=${pk.networks}`);
4327
+ });
4328
+ }
4329
+ return { valid, invalid };
4330
+ }
4331
+
4332
+ // src/utils/path-discovery.ts
4333
+ var import_pioneer_coins4 = require("@pioneer-platform/pioneer-coins");
4334
+ var log4 = require("@pioneer-platform/loggerdog")();
4335
+ async function ensurePathsForBlockchains(blockchains, currentPaths, tag) {
4336
+ let allPaths = [...currentPaths];
4337
+ for (const blockchain of blockchains) {
4338
+ const networkId = normalizeNetworkId(blockchain);
4339
+ const existingPaths = allPaths.filter((path) => matchesNetwork(path, networkId));
4340
+ if (existingPaths.length === 0) {
4341
+ log4.info(tag, `Discovering paths for ${networkId}...`);
4342
+ const newPaths = import_pioneer_coins4.getPaths([networkId]);
4343
+ if (!newPaths || newPaths.length === 0) {
4344
+ throw new Error(`Path discovery failed for ${networkId}. ` + `Available blockchains: ${blockchains.join(", ")}`);
4345
+ }
4346
+ log4.debug(tag, `Added ${newPaths.length} paths for ${networkId}`);
4347
+ allPaths = allPaths.concat(newPaths);
4348
+ }
4349
+ }
4350
+ return allPaths;
4351
+ }
4352
+
4353
+ // src/utils/pubkey-sync.ts
4354
+ var import_pioneer_coins5 = require("@pioneer-platform/pioneer-coins");
4355
+ var log5 = require("@pioneer-platform/loggerdog")();
4356
+ async function syncPubkeysForBlockchains(blockchains, paths, existingPubkeys, keepKeySdk, context, getPubkeyFn, addPubkeyCallback, tag) {
4357
+ for (const blockchain of blockchains) {
4358
+ const networkId = normalizeNetworkId(blockchain);
4359
+ const pathsForChain = paths.filter((path) => matchesNetwork(path, networkId));
4360
+ if (pathsForChain.length === 0) {
4361
+ const availablePaths = paths.map((p) => p.note || p.path || "unnamed").join(", ");
4362
+ throw new Error(`No paths found for ${networkId}. ` + `Available paths: ${availablePaths || "none"}`);
4363
+ }
4364
+ log5.info(tag, `Syncing ${pathsForChain.length} pubkeys for ${networkId}...`);
4365
+ for (const path of pathsForChain) {
4366
+ const pathBip32 = import_pioneer_coins5.addressNListToBIP32(path.addressNListMaster);
4367
+ const existingPubkey = existingPubkeys.find((p) => p.pathMaster === pathBip32);
4368
+ if (!existingPubkey) {
4369
+ log5.debug(tag, `Fetching pubkey for path ${pathBip32}...`);
4370
+ const newPubkey = await getPubkeyFn(blockchain, path, keepKeySdk, context);
4371
+ if (!newPubkey) {
4372
+ throw new Error(`Pubkey fetch failed for ${networkId} at path ${pathBip32}. ` + `Ensure hardware wallet is connected and unlocked.`);
4373
+ }
4374
+ addPubkeyCallback(newPubkey);
4375
+ log5.debug(tag, `✓ Added pubkey for ${pathBip32}`);
4376
+ }
4377
+ }
4378
+ }
4379
+ log5.info(tag, `✅ Pubkey sync complete. Total pubkeys: ${existingPubkeys.length}`);
4380
+ }
4381
+
4382
+ // src/index.ts
4383
+ var TAG12 = " | Pioneer-sdk | ";
4005
4384
 
4006
4385
  class SDK {
4007
4386
  status;
@@ -4059,7 +4438,6 @@ class SDK {
4059
4438
  init;
4060
4439
  getUnifiedPortfolio;
4061
4440
  offlineClient;
4062
- convertVaultPubkeysToPioneerFormat;
4063
4441
  app;
4064
4442
  addAsset;
4065
4443
  getAssets;
@@ -4132,23 +4510,14 @@ class SDK {
4132
4510
  this.utxoApiKey = config.utxoApiKey;
4133
4511
  this.walletConnectProjectId = config.walletConnectProjectId;
4134
4512
  this.contextType = "";
4135
- this.syncState = {
4136
- isSynced: false,
4137
- isInitialSync: true,
4138
- cacheAge: 0,
4139
- syncProgress: 0,
4140
- syncedChains: 0,
4141
- totalChains: this.blockchains.length,
4142
- lastSyncTime: null,
4143
- syncSource: "none"
4144
- };
4513
+ this.syncState = createInitialSyncState(this.blockchains.length);
4145
4514
  this.offlineClient = config.offlineFirst ? new OfflineClient({
4146
4515
  vaultUrl: config.vaultUrl || "kkapi://",
4147
4516
  timeout: 1000,
4148
4517
  fallbackToRemote: true
4149
4518
  }) : null;
4150
4519
  this.pairWallet = async (options) => {
4151
- const tag6 = TAG9 + " | pairWallet | ";
4520
+ const tag6 = TAG12 + " | pairWallet | ";
4152
4521
  if (this.viewOnlyMode || this.skipDevicePairing) {
4153
4522
  console.log(tag6, "\uD83D\uDC41️ [VIEW-ONLY] Skipping device pairing");
4154
4523
  return {
@@ -4163,35 +4532,20 @@ class SDK {
4163
4532
  message: "Device pairing not yet implemented"
4164
4533
  });
4165
4534
  };
4166
- this.getPubkeyKey = (pubkey) => {
4167
- return `${pubkey.pubkey}_${pubkey.pathMaster}`;
4168
- };
4169
- this.deduplicatePubkeys = (pubkeys) => {
4170
- const seen = new Set;
4171
- const deduped = pubkeys.filter((pubkey) => {
4172
- const key = this.getPubkeyKey(pubkey);
4173
- if (seen.has(key)) {
4174
- return false;
4175
- }
4176
- seen.add(key);
4177
- return true;
4178
- });
4179
- return deduped;
4180
- };
4535
+ this.getPubkeyKey = getPubkeyKey;
4536
+ this.deduplicatePubkeys = deduplicatePubkeys;
4181
4537
  this.addPubkey = (pubkey) => {
4182
- if (!pubkey.pubkey || !pubkey.pathMaster) {
4538
+ if (!validatePubkey(pubkey))
4183
4539
  return false;
4184
- }
4185
- const key = this.getPubkeyKey(pubkey);
4186
- if (this.pubkeySet.has(key)) {
4540
+ const key = getPubkeyKey(pubkey);
4541
+ if (this.pubkeySet.has(key))
4187
4542
  return false;
4188
- }
4189
4543
  this.pubkeys.push(pubkey);
4190
4544
  this.pubkeySet.add(key);
4191
4545
  return true;
4192
4546
  };
4193
4547
  this.setPubkeys = (newPubkeys) => {
4194
- const tag6 = `${TAG9} | setPubkeys | `;
4548
+ const tag6 = `${TAG12} | setPubkeys | `;
4195
4549
  this.pubkeys = [];
4196
4550
  this.pubkeySet.clear();
4197
4551
  let added = 0;
@@ -4207,17 +4561,8 @@ class SDK {
4207
4561
  this.pubkeys = [];
4208
4562
  this.pubkeySet.clear();
4209
4563
  }
4210
- this.isViewOnlyMode = () => {
4211
- return this.viewOnlyMode;
4212
- };
4213
- this.canSignTransactions = () => {
4214
- return !this.viewOnlyMode && !!this.keepKeySdk;
4215
- };
4216
- this.isVaultAvailable = () => {
4217
- return !!this.keepkeyEndpoint && this.keepkeyEndpoint.isAvailable;
4218
- };
4219
4564
  this.getUnifiedPortfolio = async function() {
4220
- const tag6 = `${TAG9} | getUnifiedPortfolio | `;
4565
+ const tag6 = `${TAG12} | getUnifiedPortfolio | `;
4221
4566
  try {
4222
4567
  const startTime = performance.now();
4223
4568
  try {
@@ -4249,8 +4594,7 @@ class SDK {
4249
4594
  this.events.emit("SET_BALANCES", this.balances);
4250
4595
  }
4251
4596
  if (portfolioData.pubkeys && portfolioData.pubkeys.length > 0) {
4252
- const convertedPubkeys = this.convertVaultPubkeysToPioneerFormat(portfolioData.pubkeys);
4253
- this.setPubkeys(convertedPubkeys);
4597
+ this.setPubkeys(portfolioData.pubkeys);
4254
4598
  this.events.emit("SET_PUBKEYS", this.pubkeys);
4255
4599
  }
4256
4600
  if (portfolioData.devices && portfolioData.devices.length > 0) {
@@ -4263,52 +4607,10 @@ class SDK {
4263
4607
  }));
4264
4608
  this.events.emit("SET_WALLETS", this.wallets);
4265
4609
  }
4266
- const isCacheDataValid = (portfolioData2) => {
4267
- if (!portfolioData2.networks || !Array.isArray(portfolioData2.networks)) {
4268
- console.warn("[CACHE VALIDATION] Networks is not an array");
4269
- return false;
4270
- }
4271
- if (portfolioData2.networks.length > 50) {
4272
- console.error(`[CACHE VALIDATION] CORRUPTED: ${portfolioData2.networks.length} networks (should be < 50)`);
4273
- return false;
4274
- }
4275
- const validNetworks = portfolioData2.networks.filter((n) => n.networkId && n.totalValueUsd !== undefined && n.gasAssetSymbol);
4276
- if (validNetworks.length === 0 && portfolioData2.networks.length > 0) {
4277
- console.error("[CACHE VALIDATION] CORRUPTED: No networks have required fields");
4278
- return false;
4279
- }
4280
- console.log(`[CACHE VALIDATION] Found ${portfolioData2.networks.length} networks, ${validNetworks.length} valid`);
4281
- return true;
4282
- };
4283
4610
  if (isCacheDataValid(portfolioData)) {
4284
- const dashboardData = {
4285
- totalValueUsd: portfolioData.totalValueUsd,
4286
- pairedDevices: portfolioData.pairedDevices,
4287
- devices: portfolioData.devices || [],
4288
- networks: portfolioData.networks || [],
4289
- assets: portfolioData.assets || [],
4290
- statistics: portfolioData.statistics || {},
4291
- cached: portfolioData.cached,
4292
- lastUpdated: portfolioData.lastUpdated,
4293
- cacheAge: portfolioData.lastUpdated ? Math.floor((Date.now() - portfolioData.lastUpdated) / 1000) : 0,
4294
- networkPercentages: portfolioData.networks?.map((network) => ({
4295
- networkId: network.network_id || network.networkId,
4296
- percentage: network.percentage || 0
4297
- })) || []
4298
- };
4299
- this.dashboard = dashboardData;
4611
+ this.dashboard = buildDashboardFromPortfolioData(portfolioData);
4300
4612
  this.events.emit("SET_DASHBOARD", this.dashboard);
4301
- const cacheAge = portfolioData.lastUpdated ? Math.floor((Date.now() - portfolioData.lastUpdated) / 1000) : 0;
4302
- this.syncState = {
4303
- isSynced: true,
4304
- isInitialSync: false,
4305
- cacheAge,
4306
- syncProgress: 100,
4307
- syncedChains: this.blockchains.length,
4308
- totalChains: this.blockchains.length,
4309
- lastSyncTime: portfolioData.lastUpdated || Date.now(),
4310
- syncSource: "cache"
4311
- };
4613
+ this.syncState = createCacheSyncState(portfolioData.lastUpdated, this.blockchains.length);
4312
4614
  this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4313
4615
  } else {
4314
4616
  console.warn("[CACHE VALIDATION] ❌ Cache data corrupted, building dashboard from cached balances");
@@ -4343,7 +4645,7 @@ class SDK {
4343
4645
  return this.syncState.isSynced;
4344
4646
  };
4345
4647
  this.init = async function(walletsVerbose, setup) {
4346
- const tag6 = `${TAG9} | init | `;
4648
+ const tag6 = `${TAG12} | init | `;
4347
4649
  try {
4348
4650
  if (!this.username)
4349
4651
  throw Error("username required!");
@@ -4364,7 +4666,7 @@ class SDK {
4364
4666
  this.pioneer = await PioneerClient.init();
4365
4667
  if (!this.pioneer)
4366
4668
  throw Error("Failed to init pioneer server!");
4367
- this.paths.concat(import_pioneer_coins4.getPaths(this.blockchains));
4669
+ this.paths.concat(import_pioneer_coins6.getPaths(this.blockchains));
4368
4670
  await this.getGasAssets();
4369
4671
  if (!this.skipKeeperEndpoint) {
4370
4672
  this.keepkeyEndpoint = await detectKkApiAvailability(this.forceLocalhost);
@@ -4408,7 +4710,7 @@ class SDK {
4408
4710
  this.events.emit("message", request);
4409
4711
  });
4410
4712
  clientEvents.events.on("balance:update", (data) => {
4411
- const tag7 = TAG9 + " | balance:update | ";
4713
+ const tag7 = TAG12 + " | balance:update | ";
4412
4714
  try {
4413
4715
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4414
4716
  const balance = payload.balance;
@@ -4426,7 +4728,7 @@ class SDK {
4426
4728
  }
4427
4729
  });
4428
4730
  clientEvents.events.on("sync:progress", (data) => {
4429
- const tag7 = TAG9 + " | sync:progress | ";
4731
+ const tag7 = TAG12 + " | sync:progress | ";
4430
4732
  try {
4431
4733
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4432
4734
  console.log(tag7, `Sync progress: ${payload.percentage}%`);
@@ -4439,7 +4741,7 @@ class SDK {
4439
4741
  }
4440
4742
  });
4441
4743
  clientEvents.events.on("sync:complete", (data) => {
4442
- const tag7 = TAG9 + " | sync:complete | ";
4744
+ const tag7 = TAG12 + " | sync:complete | ";
4443
4745
  try {
4444
4746
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4445
4747
  console.log(tag7, `Sync complete: ${payload.balances} balances in ${payload.duration}ms`);
@@ -4490,155 +4792,60 @@ class SDK {
4490
4792
  this.buildDashboardFromBalances = function() {
4491
4793
  return buildDashboardFromBalances(this.balances, this.blockchains, this.assetsMap);
4492
4794
  };
4493
- this.inferTypeFromCaip = function(caip) {
4494
- if (caip.includes("/slip44:"))
4495
- return "native";
4496
- if (caip.includes("/erc20:") || caip.includes("/bep20:") || caip.includes("/spl:"))
4497
- return "token";
4498
- if (caip.includes("/denom:"))
4499
- return "native";
4500
- return "unknown";
4501
- };
4502
4795
  this.syncMarket = async function() {
4503
4796
  return syncMarket(this.balances, this.pioneer);
4504
4797
  };
4505
4798
  this.sync = async function() {
4506
- const tag6 = `${TAG9} | sync | `;
4799
+ const tag6 = `${TAG12} | sync | `;
4800
+ const log6 = require("@pioneer-platform/loggerdog")();
4507
4801
  try {
4508
- const matchesNetwork = (item, networkId) => {
4509
- if (!item.networks || !Array.isArray(item.networks))
4510
- return false;
4511
- if (item.networks.includes(networkId))
4512
- return true;
4513
- if (networkId.startsWith("eip155:") && item.networks.includes("eip155:*"))
4514
- return true;
4515
- return false;
4802
+ this.syncState = {
4803
+ ...createInitialSyncState(this.blockchains.length),
4804
+ syncProgress: 10
4516
4805
  };
4806
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4807
+ log6.info(tag6, "Fetching initial pubkeys...");
4517
4808
  await this.getPubkeys();
4518
- for (let i = 0;i < this.blockchains.length; i++) {
4519
- let networkId = this.blockchains[i];
4520
- if (networkId.indexOf("eip155:") >= 0)
4521
- networkId = "eip155:*";
4522
- let paths = this.paths.filter((path) => matchesNetwork(path, networkId));
4523
- if (paths.length === 0) {
4524
- let paths2 = import_pioneer_coins4.getPaths([networkId]);
4525
- if (!paths2 || paths2.length === 0)
4526
- throw Error("Unable to find paths for: " + networkId);
4527
- this.paths = this.paths.concat(paths2);
4528
- }
4529
- }
4530
- for (let i = 0;i < this.blockchains.length; i++) {
4531
- let networkId = this.blockchains[i];
4532
- if (networkId.indexOf("eip155:") >= 0)
4533
- networkId = "eip155:*";
4534
- const pathsForChain = this.paths.filter((path) => matchesNetwork(path, networkId));
4535
- if (!pathsForChain || pathsForChain.length === 0)
4536
- throw Error("No paths found for blockchain: " + networkId);
4537
- for (let j = 0;j < pathsForChain.length; j++) {
4538
- const path = pathsForChain[j];
4539
- let pathBip32 = import_pioneer_coins4.addressNListToBIP32(path.addressNListMaster);
4540
- let pubkey = this.pubkeys.find((pubkey2) => pubkey2.pathMaster === pathBip32);
4541
- if (!pubkey) {
4542
- const pubkey2 = await getPubkey(this.blockchains[i], path, this.keepKeySdk, this.context);
4543
- if (!pubkey2)
4544
- throw Error("Unable to get pubkey for network+ " + networkId);
4545
- this.addPubkey(pubkey2);
4546
- }
4547
- }
4548
- }
4809
+ this.syncState.syncProgress = 20;
4810
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4811
+ log6.info(tag6, "Discovering paths for blockchains...");
4812
+ this.paths = await ensurePathsForBlockchains(this.blockchains, this.paths, tag6);
4813
+ this.syncState.syncProgress = 30;
4814
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4815
+ log6.info(tag6, "Synchronizing pubkeys...");
4816
+ await syncPubkeysForBlockchains(this.blockchains, this.paths, this.pubkeys, this.keepKeySdk, this.context, getPubkey, (pubkey) => this.addPubkey(pubkey), tag6);
4817
+ this.syncState.syncProgress = 50;
4818
+ this.syncState.syncedChains = this.blockchains.length;
4819
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4820
+ log6.info(tag6, "Fetching balances...");
4549
4821
  await this.getBalances();
4550
- console.log(tag6, "Loading charts (tokens + portfolio)...");
4822
+ this.syncState.syncProgress = 70;
4823
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4824
+ log6.info(tag6, "Loading charts (tokens + portfolio)...");
4551
4825
  await this.getCharts();
4552
- console.log(tag6, `Charts loaded. Total balances: ${this.balances.length}`);
4826
+ log6.info(tag6, `Charts loaded. Total balances: ${this.balances.length}`);
4827
+ this.syncState.syncProgress = 85;
4828
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4829
+ log6.info(tag6, "Syncing market prices...");
4553
4830
  await this.syncMarket();
4554
- const dashboardData = {
4555
- networks: [],
4556
- totalValueUsd: 0,
4557
- networkPercentages: []
4558
- };
4559
- let totalPortfolioValue = 0;
4560
- const networksTemp = [];
4561
- const uniqueBlockchains = [...new Set(this.blockchains)];
4562
- for (const blockchain of uniqueBlockchains) {
4563
- const filteredBalances = this.balances.filter((b) => {
4564
- const networkId = import_pioneer_caip8.caipToNetworkId(b.caip);
4565
- return networkId === blockchain || blockchain === "eip155:*" && networkId.startsWith("eip155:");
4566
- });
4567
- const balanceMap = new Map;
4568
- const isBitcoin = blockchain.includes("bip122:000000000019d6689c085ae165831e93");
4569
- if (isBitcoin) {
4570
- const bitcoinByValue = new Map;
4571
- filteredBalances.forEach((balance) => {
4572
- const valueKey = `${balance.balance}_${balance.valueUsd}`;
4573
- if (!bitcoinByValue.has(valueKey)) {
4574
- bitcoinByValue.set(valueKey, []);
4575
- }
4576
- bitcoinByValue.get(valueKey).push(balance);
4577
- });
4578
- for (const [valueKey, balances] of bitcoinByValue.entries()) {
4579
- if (balances.length === 3 && parseFloat(balances[0].valueUsd || "0") > 0) {
4580
- const xpubBalance = balances.find((b) => b.pubkey?.startsWith("xpub")) || balances[0];
4581
- const key = `${xpubBalance.caip}_${xpubBalance.pubkey || "default"}`;
4582
- balanceMap.set(key, xpubBalance);
4583
- } else {
4584
- balances.forEach((balance) => {
4585
- const key = `${balance.caip}_${balance.pubkey || "default"}`;
4586
- balanceMap.set(key, balance);
4587
- });
4588
- }
4589
- }
4590
- } else {
4591
- filteredBalances.forEach((balance) => {
4592
- const key = `${balance.caip}_${balance.pubkey || "default"}`;
4593
- if (!balanceMap.has(key) || parseFloat(balance.valueUsd || "0") > parseFloat(balanceMap.get(key).valueUsd || "0")) {
4594
- balanceMap.set(key, balance);
4595
- }
4596
- });
4597
- }
4598
- const networkBalances = Array.from(balanceMap.values());
4599
- const networkTotal = networkBalances.reduce((sum, balance, idx) => {
4600
- const valueUsd = typeof balance.valueUsd === "string" ? parseFloat(balance.valueUsd) : balance.valueUsd || 0;
4601
- return sum + valueUsd;
4602
- }, 0);
4603
- const nativeAssetCaip = import_pioneer_caip8.networkIdToCaip(blockchain);
4604
- const gasAsset = networkBalances.find((b) => b.caip === nativeAssetCaip);
4605
- const totalNativeBalance = networkBalances.filter((b) => b.caip === nativeAssetCaip).reduce((sum, balance) => {
4606
- const balanceNum = typeof balance.balance === "string" ? parseFloat(balance.balance) : balance.balance || 0;
4607
- return sum + balanceNum;
4608
- }, 0).toString();
4609
- networksTemp.push({
4610
- networkId: blockchain,
4611
- totalValueUsd: networkTotal,
4612
- gasAssetCaip: nativeAssetCaip || null,
4613
- gasAssetSymbol: gasAsset?.symbol || null,
4614
- icon: gasAsset?.icon || null,
4615
- color: gasAsset?.color || null,
4616
- totalNativeBalance
4617
- });
4618
- totalPortfolioValue += networkTotal;
4619
- }
4620
- dashboardData.networks = networksTemp.sort((a, b) => b.totalValueUsd - a.totalValueUsd);
4621
- dashboardData.totalValueUsd = totalPortfolioValue;
4622
- dashboardData.networkPercentages = dashboardData.networks.map((network) => ({
4623
- networkId: network.networkId,
4624
- percentage: totalPortfolioValue > 0 ? Number((network.totalValueUsd / totalPortfolioValue * 100).toFixed(2)) : 0
4625
- })).filter((entry) => entry.percentage > 0);
4626
- this.dashboard = dashboardData;
4627
- this.syncState = {
4628
- isSynced: true,
4629
- isInitialSync: false,
4630
- cacheAge: 0,
4631
- syncProgress: 100,
4632
- syncedChains: this.blockchains.length,
4633
- totalChains: this.blockchains.length,
4634
- lastSyncTime: Date.now(),
4635
- syncSource: "fresh"
4636
- };
4831
+ this.syncState.syncProgress = 95;
4832
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4833
+ log6.info(tag6, "Building dashboard...");
4834
+ this.dashboard = buildDashboardFromBalances(this.balances, [...new Set(this.blockchains)], this.assetsMap);
4835
+ this.syncState = createFreshSyncState(this.blockchains.length);
4637
4836
  this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4638
4837
  this.events.emit("SYNC_COMPLETE", this.syncState);
4838
+ log6.info(tag6, "✅ Sync complete!");
4639
4839
  return true;
4640
4840
  } catch (e) {
4641
- console.error(tag6, "Error in sync:", e);
4841
+ log6.error(tag6, "Sync failed:", e);
4842
+ this.syncState = {
4843
+ ...this.syncState,
4844
+ isSynced: false,
4845
+ syncProgress: 0
4846
+ };
4847
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4848
+ this.events.emit("SYNC_ERROR", e);
4642
4849
  throw e;
4643
4850
  }
4644
4851
  };
@@ -4652,7 +4859,7 @@ class SDK {
4652
4859
  }
4653
4860
  };
4654
4861
  this.buildTx = async function(sendPayload) {
4655
- let tag6 = TAG9 + " | buildTx | ";
4862
+ let tag6 = TAG12 + " | buildTx | ";
4656
4863
  try {
4657
4864
  const transactionDependencies = {
4658
4865
  context: this.context,
@@ -4674,7 +4881,7 @@ class SDK {
4674
4881
  }
4675
4882
  };
4676
4883
  this.buildDelegateTx = async function(caip, params) {
4677
- let tag6 = TAG9 + " | buildDelegateTx | ";
4884
+ let tag6 = TAG12 + " | buildDelegateTx | ";
4678
4885
  try {
4679
4886
  const delegateParams = {
4680
4887
  ...params,
@@ -4689,7 +4896,7 @@ class SDK {
4689
4896
  }
4690
4897
  };
4691
4898
  this.buildUndelegateTx = async function(caip, params) {
4692
- let tag6 = TAG9 + " | buildUndelegateTx | ";
4899
+ let tag6 = TAG12 + " | buildUndelegateTx | ";
4693
4900
  try {
4694
4901
  const undelegateParams = {
4695
4902
  ...params,
@@ -4704,7 +4911,7 @@ class SDK {
4704
4911
  }
4705
4912
  };
4706
4913
  this.buildClaimRewardsTx = async function(caip, params) {
4707
- let tag6 = TAG9 + " | buildClaimRewardsTx | ";
4914
+ let tag6 = TAG12 + " | buildClaimRewardsTx | ";
4708
4915
  try {
4709
4916
  const claimParams = {
4710
4917
  ...params,
@@ -4719,7 +4926,7 @@ class SDK {
4719
4926
  }
4720
4927
  };
4721
4928
  this.buildClaimAllRewardsTx = async function(caip, params) {
4722
- let tag6 = TAG9 + " | buildClaimAllRewardsTx | ";
4929
+ let tag6 = TAG12 + " | buildClaimAllRewardsTx | ";
4723
4930
  try {
4724
4931
  const claimAllParams = {
4725
4932
  ...params,
@@ -4733,7 +4940,7 @@ class SDK {
4733
4940
  }
4734
4941
  };
4735
4942
  this.signTx = async function(caip, unsignedTx) {
4736
- let tag6 = TAG9 + " | signTx | ";
4943
+ let tag6 = TAG12 + " | signTx | ";
4737
4944
  try {
4738
4945
  const transactionDependencies = {
4739
4946
  context: this.context,
@@ -4754,7 +4961,7 @@ class SDK {
4754
4961
  }
4755
4962
  };
4756
4963
  this.broadcastTx = async function(caip, signedTx) {
4757
- let tag6 = TAG9 + " | broadcastTx | ";
4964
+ let tag6 = TAG12 + " | broadcastTx | ";
4758
4965
  try {
4759
4966
  const transactionDependencies = {
4760
4967
  context: this.context,
@@ -4778,7 +4985,7 @@ class SDK {
4778
4985
  }
4779
4986
  };
4780
4987
  this.swap = async function(swapPayload) {
4781
- let tag6 = `${TAG9} | swap | `;
4988
+ let tag6 = `${TAG12} | swap | `;
4782
4989
  try {
4783
4990
  if (!swapPayload)
4784
4991
  throw Error("swapPayload required!");
@@ -4796,15 +5003,6 @@ class SDK {
4796
5003
  throw Error("Invalid networkId for outboundAssetContext");
4797
5004
  if (!this.outboundAssetContext || !this.outboundAssetContext.address)
4798
5005
  throw Error("Invalid outboundAssetContext missing address");
4799
- const matchesNetwork = (pubkey, networkId) => {
4800
- if (!pubkey.networks || !Array.isArray(pubkey.networks))
4801
- return false;
4802
- if (pubkey.networks.includes(networkId))
4803
- return true;
4804
- if (networkId.startsWith("eip155:") && pubkey.networks.includes("eip155:*"))
4805
- return true;
4806
- return false;
4807
- };
4808
5006
  const pubkeys = this.pubkeys.filter((e) => matchesNetwork(e, this.assetContext.networkId));
4809
5007
  let senderAddress = pubkeys[0]?.address || pubkeys[0]?.master || pubkeys[0]?.pubkey;
4810
5008
  if (!senderAddress)
@@ -4836,17 +5034,8 @@ class SDK {
4836
5034
  this.assetContext.balance = totalBalance.toString();
4837
5035
  this.assetContext.valueUsd = (totalBalance * parseFloat(this.assetContext.priceUsd || "0")).toFixed(2);
4838
5036
  console.log(tag6, `Updated assetContext balance to aggregated total: ${totalBalance}`);
4839
- const feeReserves = {
4840
- "bip122:000000000019d6689c085ae165831e93/slip44:0": 0.00005,
4841
- "eip155:1/slip44:60": 0.001,
4842
- "cosmos:thorchain-mainnet-v1/slip44:931": 0.02,
4843
- "bip122:00000000001a91e3dace36e2be3bf030/slip44:3": 1,
4844
- "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": 0.001,
4845
- "bip122:000000000000000000651ef99cb9fcbe/slip44:145": 0.0005
4846
- };
4847
- const reserve = feeReserves[swapPayload.caipIn] || 0.0001;
4848
- inputAmount = Math.max(0, totalBalance - reserve);
4849
- console.log(tag6, `Using max amount for swap: ${inputAmount} (total balance: ${totalBalance}, reserve: ${reserve})`);
5037
+ inputAmount = getMaxSendableAmount(totalBalance, swapPayload.caipIn);
5038
+ console.log(tag6, `Using max amount for swap: ${inputAmount} (total balance: ${totalBalance})`);
4850
5039
  } else {
4851
5040
  inputAmount = typeof swapPayload.amount === "string" ? parseFloat(swapPayload.amount) : swapPayload.amount;
4852
5041
  if (isNaN(inputAmount) || inputAmount <= 0) {
@@ -4967,7 +5156,7 @@ class SDK {
4967
5156
  }
4968
5157
  };
4969
5158
  this.transfer = async function(sendPayload) {
4970
- let tag6 = `${TAG9} | transfer | `;
5159
+ let tag6 = `${TAG12} | transfer | `;
4971
5160
  try {
4972
5161
  if (!sendPayload)
4973
5162
  throw Error("sendPayload required!");
@@ -5062,7 +5251,7 @@ class SDK {
5062
5251
  }
5063
5252
  };
5064
5253
  this.setBlockchains = async function(blockchains) {
5065
- const tag6 = `${TAG9} | setBlockchains | `;
5254
+ const tag6 = `${TAG12} | setBlockchains | `;
5066
5255
  try {
5067
5256
  if (!blockchains)
5068
5257
  throw Error("blockchains required!");
@@ -5078,7 +5267,7 @@ class SDK {
5078
5267
  }
5079
5268
  };
5080
5269
  this.addAsset = async function(caip, data) {
5081
- let tag6 = TAG9 + " | addAsset | ";
5270
+ let tag6 = TAG12 + " | addAsset | ";
5082
5271
  try {
5083
5272
  let success = false;
5084
5273
  if (!caip)
@@ -5116,7 +5305,7 @@ class SDK {
5116
5305
  }
5117
5306
  };
5118
5307
  this.clearWalletState = async function() {
5119
- const tag6 = `${TAG9} | clearWalletState | `;
5308
+ const tag6 = `${TAG12} | clearWalletState | `;
5120
5309
  try {
5121
5310
  this.context = null;
5122
5311
  this.paths = [];
@@ -5131,7 +5320,7 @@ class SDK {
5131
5320
  }
5132
5321
  };
5133
5322
  this.addPath = async function(path) {
5134
- const tag6 = `${TAG9} | addPath | `;
5323
+ const tag6 = `${TAG12} | addPath | `;
5135
5324
  try {
5136
5325
  this.paths.push(path);
5137
5326
  const pubkey = await getPubkey(path.networks[0], path, this.keepKeySdk, this.context);
@@ -5145,7 +5334,7 @@ class SDK {
5145
5334
  }
5146
5335
  };
5147
5336
  this.addPaths = async function(paths) {
5148
- const tag6 = `${TAG9} | addPaths | `;
5337
+ const tag6 = `${TAG12} | addPaths | `;
5149
5338
  try {
5150
5339
  console.log(tag6, `Adding ${paths.length} paths in batch mode...`);
5151
5340
  this.paths.push(...paths);
@@ -5181,7 +5370,7 @@ class SDK {
5181
5370
  return this.getGasAssets();
5182
5371
  };
5183
5372
  this.getGasAssets = async function() {
5184
- const tag6 = `${TAG9} | getGasAssets | `;
5373
+ const tag6 = `${TAG12} | getGasAssets | `;
5185
5374
  try {
5186
5375
  for (let i = 0;i < this.blockchains.length; i++) {
5187
5376
  let networkId = this.blockchains[i];
@@ -5195,28 +5384,6 @@ class SDK {
5195
5384
  throw Error("GAS Asset MISSING from assetData " + caip);
5196
5385
  }
5197
5386
  }
5198
- const mayaTokenCaip = "cosmos:mayachain-mainnet-v1/denom:maya";
5199
- if (!this.assetsMap.has(mayaTokenCaip)) {
5200
- const mayaToken = {
5201
- caip: mayaTokenCaip,
5202
- networkId: "cosmos:mayachain-mainnet-v1",
5203
- chainId: "mayachain-mainnet-v1",
5204
- symbol: "MAYA",
5205
- name: "Maya Token",
5206
- precision: 4,
5207
- decimals: 4,
5208
- color: "#00D4AA",
5209
- icon: "https://pioneers.dev/coins/maya.png",
5210
- explorer: "https://explorer.mayachain.info",
5211
- explorerAddressLink: "https://explorer.mayachain.info/address/{{address}}",
5212
- explorerTxLink: "https://explorer.mayachain.info/tx/{{txid}}",
5213
- type: "token",
5214
- isToken: true,
5215
- denom: "maya"
5216
- };
5217
- this.assetsMap.set(mayaTokenCaip, mayaToken);
5218
- console.log(tag6, "Added MAYA token to assetsMap");
5219
- }
5220
5387
  return this.assetsMap;
5221
5388
  } catch (e) {
5222
5389
  console.error(e);
@@ -5224,7 +5391,7 @@ class SDK {
5224
5391
  }
5225
5392
  };
5226
5393
  this.getPubkeys = async function() {
5227
- const tag6 = `${TAG9} | getPubkeys | `;
5394
+ const tag6 = `${TAG12} | getPubkeys | `;
5228
5395
  try {
5229
5396
  if (this.paths.length === 0)
5230
5397
  throw new Error("No paths found!");
@@ -5269,134 +5436,57 @@ class SDK {
5269
5436
  }
5270
5437
  };
5271
5438
  this.getBalancesForNetworks = async function(networkIds, forceRefresh) {
5272
- const tag6 = `${TAG9} | getBalancesForNetworks | `;
5439
+ const tag6 = `${TAG12} | getBalancesForNetworks | `;
5273
5440
  try {
5274
5441
  if (!this.pioneer) {
5275
- console.error(tag6, "ERROR: Pioneer client not initialized! this.pioneer is:", this.pioneer);
5276
5442
  throw new Error("Pioneer client not initialized. Call init() first.");
5277
5443
  }
5278
- if (forceRefresh) {
5279
- console.log(tag6, "\uD83D\uDD04 Force refresh requested - bypassing balance cache");
5280
- }
5281
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Input networks:", networkIds);
5282
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Total pubkeys:", this.pubkeys.length);
5283
- const pubkeysWithNetworks = this.pubkeys.filter((p) => p.networks && Array.isArray(p.networks));
5284
- const pubkeysWithoutNetworks = this.pubkeys.filter((p) => !p.networks || !Array.isArray(p.networks));
5285
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Pubkeys WITH networks:", pubkeysWithNetworks.length);
5286
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Pubkeys WITHOUT networks:", pubkeysWithoutNetworks.length);
5287
- if (pubkeysWithoutNetworks.length > 0) {
5288
- console.warn("⚠️ [WARNING] Some pubkeys missing networks field:");
5289
- pubkeysWithoutNetworks.forEach((pk) => {
5290
- console.warn(` - ${pk.note || pk.pubkey.slice(0, 10)}: networks=${pk.networks}`);
5291
- });
5292
- }
5444
+ if (forceRefresh)
5445
+ console.log(tag6, "\uD83D\uDD04 Force refresh requested");
5446
+ console.log("\uD83D\uDD0D [DIAGNOSTIC] Networks:", networkIds.length, "Pubkeys:", this.pubkeys.length);
5447
+ const { valid, invalid } = validatePubkeysNetworks(this.pubkeys, "\uD83D\uDD0D [DIAGNOSTIC]");
5448
+ console.log("\uD83D\uDD0D [DIAGNOSTIC] Pubkeys:", { valid: valid.length, invalid: invalid.length });
5293
5449
  const assetQuery = [];
5294
5450
  for (const networkId of networkIds) {
5295
- let adjustedNetworkId = networkId;
5296
- if (adjustedNetworkId.includes("eip155:")) {
5297
- adjustedNetworkId = "eip155:*";
5298
- }
5299
- const isEip155 = adjustedNetworkId.includes("eip155");
5300
- let pubkeys = this.pubkeys.filter((pubkey) => pubkey.networks && Array.isArray(pubkey.networks) && pubkey.networks.some((network) => {
5301
- if (isEip155)
5302
- return network.startsWith("eip155:");
5303
- return network === adjustedNetworkId;
5304
- }));
5305
- if (pubkeys.length === 0) {
5306
- console.warn(tag6, `⚠️ No pubkeys found for ${networkId} with networks field`);
5307
- console.warn(tag6, "Attempting fallback: finding pubkeys by path matching");
5308
- const pathsForNetwork = this.paths.filter((p) => p.networks?.includes(networkId) || networkId.startsWith("eip155:") && p.networks?.includes("eip155:*"));
5309
- for (const path of pathsForNetwork) {
5310
- const matchingPubkey = this.pubkeys.find((pk) => JSON.stringify(pk.addressNList) === JSON.stringify(path.addressNList));
5311
- if (matchingPubkey) {
5312
- console.warn(tag6, ` ✓ Found pubkey via path matching: ${matchingPubkey.note || matchingPubkey.pubkey.slice(0, 10)}`);
5313
- pubkeys.push(matchingPubkey);
5314
- }
5315
- }
5316
- if (pubkeys.length > 0) {
5317
- console.warn(tag6, ` ✅ Fallback successful: Found ${pubkeys.length} pubkeys for ${networkId}`);
5318
- } else {
5319
- console.error(tag6, ` ❌ Fallback failed: No pubkeys found for ${networkId}`);
5320
- }
5321
- }
5322
- const caipNative = await import_pioneer_caip8.networkIdToCaip(networkId);
5323
- for (const pubkey of pubkeys) {
5324
- assetQuery.push({ caip: caipNative, pubkey: pubkey.pubkey });
5325
- }
5326
- }
5327
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Built assetQuery with", assetQuery.length, "entries");
5328
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Sample queries:", assetQuery.slice(0, 5));
5329
- const caipCounts = new Map;
5330
- for (const query of assetQuery) {
5331
- caipCounts.set(query.caip, (caipCounts.get(query.caip) || 0) + 1);
5332
- }
5333
- console.log("\uD83D\uDD0D [DIAGNOSTIC] Queries by chain:");
5334
- caipCounts.forEach((count, caip) => {
5335
- console.log(` - ${caip}: ${count} queries`);
5336
- });
5337
- console.log(`⏱️ [PERF] Starting GetPortfolioBalances API call...`);
5338
- const apiCallStart = performance.now();
5339
- console.time("GetPortfolioBalances Response Time");
5340
- try {
5341
- let marketInfo = await this.pioneer.GetPortfolioBalances({ pubkeys: assetQuery }, forceRefresh ? { forceRefresh: true } : undefined);
5342
- const apiCallTime = performance.now() - apiCallStart;
5343
- console.timeEnd("GetPortfolioBalances Response Time");
5344
- console.log(`⏱️ [PERF] API call completed in ${apiCallTime.toFixed(0)}ms`);
5345
- const enrichStart = performance.now();
5346
- let balances = marketInfo.data;
5347
- console.log(`⏱️ [PERF] Received ${balances?.length || 0} balances from server`);
5348
- console.log(`⏱️ [PERF] Starting balance enrichment...`);
5349
- for (let balance of balances) {
5350
- const assetInfo = this.assetsMap.get(balance.caip.toLowerCase()) || this.assetsMap.get(balance.caip);
5351
- if (!assetInfo) {
5352
- console.warn(`⚠️ [ENRICHMENT] Asset metadata missing for ${balance.caip}, using fallback enrichment`);
5353
- const inferredType = this.inferTypeFromCaip(balance.caip);
5354
- Object.assign(balance, {
5355
- type: balance.type || inferredType,
5356
- isNative: balance.isNative ?? inferredType === "native",
5357
- networkId: import_pioneer_caip8.caipToNetworkId(balance.caip),
5358
- icon: "https://pioneers.dev/coins/unknown.png",
5359
- identifier: `${balance.caip}:${balance.pubkey}`,
5360
- updated: Date.now()
5361
- });
5362
- continue;
5363
- }
5364
- const color = ASSET_COLORS[balance.caip] || assetInfo.color;
5365
- Object.assign(balance, assetInfo, {
5366
- type: balance.type || assetInfo.type,
5367
- isNative: balance.isNative ?? assetInfo.isNative,
5368
- networkId: import_pioneer_caip8.caipToNetworkId(balance.caip),
5369
- icon: assetInfo.icon || "https://pioneers.dev/coins/etherum.png",
5370
- identifier: `${balance.caip}:${balance.pubkey}`,
5371
- updated: Date.now(),
5372
- color
5373
- });
5374
- }
5375
- const enrichTime = performance.now() - enrichStart;
5376
- console.log(`⏱️ [PERF] Enrichment completed in ${enrichTime.toFixed(0)}ms`);
5377
- this.balances = balances;
5378
- this.events.emit("SET_BALANCES", this.balances);
5379
- console.log(`⏱️ [PERF] Building dashboard from ${balances.length} balances...`);
5380
- const dashboardStart = performance.now();
5381
- const dashboardData = this.buildDashboardFromBalances();
5382
- this.dashboard = dashboardData;
5383
- this.events.emit("SET_DASHBOARD", this.dashboard);
5384
- console.log(`⏱️ [PERF] Dashboard built in ${(performance.now() - dashboardStart).toFixed(0)}ms`);
5385
- console.log(`\uD83D\uDCCA Dashboard created: ${this.dashboard?.networks?.length || 0} networks, $${this.dashboard?.totalValueUsd?.toFixed(2) || "0.00"} total`);
5386
- console.log(`⏱️ [PERF] Total getBalancesForNetworks: ${(performance.now() - apiCallStart).toFixed(0)}ms`);
5387
- return this.balances;
5388
- } catch (apiError) {
5389
- console.error(tag6, "GetPortfolioBalances API call failed:", apiError);
5390
- throw new Error(`GetPortfolioBalances API call failed: ${apiError?.message || "Unknown error"}`);
5451
+ const pubkeys = findPubkeysForNetwork(this.pubkeys, networkId, this.paths, tag6);
5452
+ const caip = await import_pioneer_caip8.networkIdToCaip(networkId);
5453
+ assetQuery.push(...buildAssetQuery(pubkeys, caip));
5391
5454
  }
5455
+ logQueryDiagnostics(assetQuery, "\uD83D\uDD0D [DIAGNOSTIC]");
5456
+ console.log(`⏱️ [PERF] Starting GetPortfolioBalances...`);
5457
+ const apiStart = performance.now();
5458
+ console.time("GetPortfolioBalances Response");
5459
+ const marketInfo = await this.pioneer.GetPortfolioBalances({ pubkeys: assetQuery }, forceRefresh ? { forceRefresh: true } : undefined);
5460
+ console.timeEnd("GetPortfolioBalances Response");
5461
+ console.log(`⏱️ [PERF] API completed in ${(performance.now() - apiStart).toFixed(0)}ms`);
5462
+ const enrichStart = performance.now();
5463
+ console.log(`⏱️ [PERF] Enriching ${marketInfo.data?.length || 0} balances...`);
5464
+ const balances = enrichBalancesWithAssetInfo(marketInfo.data, this.assetsMap, import_pioneer_caip8.caipToNetworkId);
5465
+ console.log(`⏱️ [PERF] Enrichment completed in ${(performance.now() - enrichStart).toFixed(0)}ms`);
5466
+ this.balances = balances;
5467
+ this.events.emit("SET_BALANCES", this.balances);
5468
+ const dashStart = performance.now();
5469
+ this.dashboard = this.buildDashboardFromBalances();
5470
+ this.events.emit("SET_DASHBOARD", this.dashboard);
5471
+ console.log(`⏱️ [PERF] Dashboard built in ${(performance.now() - dashStart).toFixed(0)}ms`);
5472
+ console.log(`\uD83D\uDCCA Dashboard: ${this.dashboard?.networks?.length || 0} networks, $${this.dashboard?.totalValueUsd?.toFixed(2) || "0.00"}`);
5473
+ console.log(`⏱️ [PERF] Total: ${(performance.now() - apiStart).toFixed(0)}ms`);
5474
+ return this.balances;
5392
5475
  } catch (e) {
5393
- console.error(tag6, "Error: ", e);
5476
+ console.error(tag6, "Error:", e?.message || e);
5394
5477
  throw e;
5395
5478
  }
5396
5479
  };
5397
- this.getBalances = async function(forceRefresh) {
5398
- const tag6 = `${TAG9} | getBalances | `;
5480
+ this.getBalances = async function(forceRefresh, caip) {
5481
+ const tag6 = `${TAG12} | getBalances | `;
5399
5482
  try {
5483
+ if (caip) {
5484
+ console.log(tag6, `\uD83C\uDFAF Refreshing single asset: ${caip}`);
5485
+ const networkId = caip.split("/")[0];
5486
+ console.log(tag6, `\uD83D\uDCCD Target network: ${networkId}`);
5487
+ const results = await this.getBalancesForNetworks([networkId], forceRefresh);
5488
+ return results.filter((b) => b.caip === caip || b.networkId === networkId);
5489
+ }
5400
5490
  return await this.getBalancesForNetworks(this.blockchains, forceRefresh);
5401
5491
  } catch (e) {
5402
5492
  console.error(tag6, "Error in getBalances: ", e);
@@ -5404,7 +5494,7 @@ class SDK {
5404
5494
  }
5405
5495
  };
5406
5496
  this.getBalance = async function(networkId) {
5407
- const tag6 = `${TAG9} | getBalance | `;
5497
+ const tag6 = `${TAG12} | getBalance | `;
5408
5498
  try {
5409
5499
  const results = await this.getBalancesForNetworks([networkId]);
5410
5500
  const filtered = results.filter(async (b) => b.networkId === await import_pioneer_caip8.networkIdToCaip(networkId));
@@ -5415,7 +5505,7 @@ class SDK {
5415
5505
  }
5416
5506
  };
5417
5507
  this.getFees = async function(networkId) {
5418
- const tag6 = `${TAG9} | getFees | `;
5508
+ const tag6 = `${TAG12} | getFees | `;
5419
5509
  try {
5420
5510
  if (!this.pioneer) {
5421
5511
  throw new Error("Pioneer client not initialized. Call init() first.");
@@ -5430,7 +5520,7 @@ class SDK {
5430
5520
  return estimateTransactionFee(feeRate, unit, networkType, txSize);
5431
5521
  };
5432
5522
  this.getCharts = async function() {
5433
- const tag6 = `${TAG9} | getCharts | `;
5523
+ const tag6 = `${TAG12} | getCharts | `;
5434
5524
  try {
5435
5525
  console.log(tag6, "Fetching charts (portfolio + tokens + staking)...");
5436
5526
  const { getCharts: getChartsModular } = await Promise.resolve().then(() => (init_charts(), exports_charts));
@@ -5455,7 +5545,7 @@ class SDK {
5455
5545
  }
5456
5546
  };
5457
5547
  this.setContext = async (context) => {
5458
- const tag6 = `${TAG9} | setContext | `;
5548
+ const tag6 = `${TAG12} | setContext | `;
5459
5549
  try {
5460
5550
  if (!context)
5461
5551
  throw Error("context required!");
@@ -5468,7 +5558,7 @@ class SDK {
5468
5558
  }
5469
5559
  };
5470
5560
  this.setContextType = async (contextType) => {
5471
- const tag6 = `${TAG9} | setContextType | `;
5561
+ const tag6 = `${TAG12} | setContextType | `;
5472
5562
  try {
5473
5563
  if (!contextType)
5474
5564
  throw Error("contextType required!");
@@ -5481,7 +5571,7 @@ class SDK {
5481
5571
  }
5482
5572
  };
5483
5573
  this.refresh = async (forceRefresh) => {
5484
- const tag6 = `${TAG9} | refresh | `;
5574
+ const tag6 = `${TAG12} | refresh | `;
5485
5575
  try {
5486
5576
  if (forceRefresh) {
5487
5577
  console.log(tag6, "\uD83D\uDD04 Force refresh - fetching fresh balances from blockchain");
@@ -5496,7 +5586,7 @@ class SDK {
5496
5586
  }
5497
5587
  };
5498
5588
  this.setAssetContext = async function(asset) {
5499
- const tag6 = `${TAG9} | setAssetContext | `;
5589
+ const tag6 = `${TAG12} | setAssetContext | `;
5500
5590
  try {
5501
5591
  if (!asset) {
5502
5592
  this.assetContext = null;
@@ -5506,114 +5596,28 @@ class SDK {
5506
5596
  throw Error("Invalid Asset! missing caip!");
5507
5597
  if (!asset.networkId)
5508
5598
  asset.networkId = import_pioneer_caip8.caipToNetworkId(asset.caip);
5509
- if (!this.pubkeys || this.pubkeys.length === 0) {
5510
- const errorMsg = `Cannot set asset context for ${asset.caip} - no pubkeys loaded. Please initialize wallet first.`;
5511
- console.error(tag6, errorMsg);
5512
- throw new Error(errorMsg);
5513
- }
5514
- const pubkeysForNetwork = this.pubkeys.filter((e) => {
5515
- if (!e.networks || !Array.isArray(e.networks))
5516
- return false;
5517
- if (e.networks.includes(asset.networkId))
5518
- return true;
5519
- if (asset.networkId.startsWith("eip155:") && e.networks.includes("eip155:*")) {
5520
- return true;
5521
- }
5522
- return false;
5523
- });
5524
- if (pubkeysForNetwork.length === 0) {
5525
- const errorMsg = `Cannot set asset context for ${asset.caip} - no address/xpub found for network ${asset.networkId}`;
5526
- console.error(tag6, errorMsg);
5527
- console.error(tag6, "Available networks in pubkeys:", [
5528
- ...new Set(this.pubkeys.flatMap((p) => p.networks || []))
5529
- ]);
5530
- throw new Error(errorMsg);
5531
- }
5532
- const isUtxoChain = asset.networkId.startsWith("bip122:");
5533
- if (isUtxoChain) {
5534
- const xpubFound = pubkeysForNetwork.some((p) => p.type === "xpub" && p.pubkey);
5535
- if (!xpubFound) {
5536
- const errorMsg = `Cannot set asset context for UTXO chain ${asset.caip} - xpub required but not found`;
5537
- console.error(tag6, errorMsg);
5538
- throw new Error(errorMsg);
5539
- }
5540
- }
5541
- const hasValidAddress = pubkeysForNetwork.some((p) => p.address || p.master || p.pubkey);
5542
- if (!hasValidAddress) {
5543
- const errorMsg = `Cannot set asset context for ${asset.caip} - no valid address found in pubkeys`;
5544
- console.error(tag6, errorMsg);
5545
- throw new Error(errorMsg);
5546
- }
5599
+ validatePubkeysForNetwork(this.pubkeys, asset.networkId, asset.caip);
5600
+ const pubkeysForNetwork = findPubkeysForNetwork(this.pubkeys, asset.networkId);
5547
5601
  console.log(tag6, `✅ Validated: Found ${pubkeysForNetwork.length} addresses for ${asset.networkId}`);
5548
- let freshPriceUsd = 0;
5549
- try {
5550
- if (!asset.caip || typeof asset.caip !== "string" || !asset.caip.includes(":")) {
5551
- console.warn(tag6, "Invalid or missing CAIP, skipping market price fetch:", asset.caip);
5552
- } else {
5553
- console.log(tag6, "Fetching fresh market price for:", asset.caip);
5554
- const marketData = await this.pioneer.GetMarketInfo([asset.caip]);
5555
- console.log(tag6, "Market data response:", marketData);
5556
- if (marketData && marketData.data && marketData.data.length > 0) {
5557
- freshPriceUsd = marketData.data[0];
5558
- console.log(tag6, "✅ Fresh market price:", freshPriceUsd);
5559
- } else {
5560
- console.warn(tag6, "No market data returned for:", asset.caip);
5561
- }
5562
- }
5563
- } catch (marketError) {
5564
- console.error(tag6, "Error fetching market price:", marketError);
5565
- }
5566
- let assetInfo = this.assetsMap.get(asset.caip.toLowerCase());
5567
- console.log(tag6, "assetInfo: ", assetInfo);
5568
- let assetInfoDiscovery = import_pioneer_discovery2.assetData[asset.caip];
5569
- console.log(tag6, "assetInfoDiscovery: ", assetInfoDiscovery);
5570
- if (assetInfoDiscovery)
5571
- assetInfo = assetInfoDiscovery;
5572
- if (!assetInfo) {
5573
- console.log(tag6, "Building placeholder asset!");
5574
- assetInfo = {
5575
- caip: asset.caip.toLowerCase(),
5576
- networkId: asset.networkId,
5577
- symbol: asset.symbol || "UNKNOWN",
5578
- name: asset.name || "Unknown Asset",
5579
- icon: asset.icon || "https://pioneers.dev/coins/ethereum.png"
5580
- };
5581
- }
5602
+ const freshPriceUsd = await fetchMarketPrice(this.pioneer, asset.caip);
5603
+ let assetInfo = resolveAssetInfo(this.assetsMap, import_pioneer_discovery2.assetData, asset);
5582
5604
  const matchingBalances = this.balances.filter((b) => b.caip === asset.caip);
5583
5605
  if (matchingBalances.length > 0) {
5584
- let priceValue = matchingBalances[0].priceUsd || matchingBalances[0].price;
5585
- if ((!priceValue || priceValue === 0) && matchingBalances[0].valueUsd && matchingBalances[0].balance) {
5586
- const balance = parseFloat(matchingBalances[0].balance);
5587
- const valueUsd = parseFloat(matchingBalances[0].valueUsd);
5588
- if (balance > 0 && valueUsd > 0) {
5589
- priceValue = valueUsd / balance;
5590
- console.log(tag6, "calculated priceUsd from valueUsd/balance:", priceValue);
5591
- }
5592
- }
5593
- if (priceValue && priceValue > 0) {
5606
+ const priceValue = extractPriceFromBalances(matchingBalances);
5607
+ if (priceValue > 0) {
5594
5608
  console.log(tag6, "detected priceUsd from balance:", priceValue);
5595
5609
  assetInfo.priceUsd = priceValue;
5596
5610
  }
5597
5611
  }
5598
- if (freshPriceUsd && freshPriceUsd > 0) {
5612
+ if (freshPriceUsd > 0) {
5599
5613
  assetInfo.priceUsd = freshPriceUsd;
5600
5614
  console.log(tag6, "✅ Using fresh market price:", freshPriceUsd);
5601
- let totalBalance = 0;
5602
- let totalValueUsd = 0;
5603
- console.log(tag6, `Found ${matchingBalances.length} balance entries for ${asset.caip}`);
5604
- for (const balanceEntry of matchingBalances) {
5605
- const balance = parseFloat(balanceEntry.balance) || 0;
5606
- const valueUsd = parseFloat(balanceEntry.valueUsd) || 0;
5607
- totalBalance += balance;
5608
- totalValueUsd += valueUsd;
5609
- console.log(tag6, ` Balance entry: ${balance} (${valueUsd} USD)`);
5610
- }
5615
+ const { totalBalance, totalValueUsd } = aggregateBalances(matchingBalances, asset.caip);
5611
5616
  assetInfo.balance = totalBalance.toString();
5612
5617
  assetInfo.valueUsd = totalValueUsd.toFixed(2);
5613
- console.log(tag6, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
5614
5618
  }
5615
5619
  const assetBalances = this.balances.filter((b) => b.caip === asset.caip);
5616
- const assetPubkeys = this.pubkeys.filter((p) => p.networks && Array.isArray(p.networks) && p.networks.includes(import_pioneer_caip8.caipToNetworkId(asset.caip)) || import_pioneer_caip8.caipToNetworkId(asset.caip).includes("eip155") && p.networks && Array.isArray(p.networks) && p.networks.some((n) => n.startsWith("eip155")));
5620
+ const assetPubkeys = filterPubkeysForAsset(this.pubkeys, asset.caip, import_pioneer_caip8.caipToNetworkId);
5617
5621
  const finalAssetContext = {
5618
5622
  ...assetInfo,
5619
5623
  ...asset,
@@ -5623,45 +5627,12 @@ class SDK {
5623
5627
  if ((!asset.priceUsd || asset.priceUsd === 0) && assetInfo.priceUsd && assetInfo.priceUsd > 0) {
5624
5628
  finalAssetContext.priceUsd = assetInfo.priceUsd;
5625
5629
  }
5626
- if (freshPriceUsd && freshPriceUsd > 0) {
5627
- for (const balance of assetBalances) {
5628
- balance.price = freshPriceUsd;
5629
- balance.priceUsd = freshPriceUsd;
5630
- const balanceAmount = parseFloat(balance.balance || 0);
5631
- balance.valueUsd = (balanceAmount * freshPriceUsd).toString();
5632
- }
5633
- console.log(tag6, "Updated all balances with fresh price data");
5630
+ if (freshPriceUsd > 0) {
5631
+ updateBalancesWithPrice(assetBalances, freshPriceUsd);
5634
5632
  }
5635
5633
  this.assetContext = finalAssetContext;
5636
5634
  if (asset.isToken || asset.type === "token" || assetInfo.isToken || assetInfo.type === "token") {
5637
5635
  const networkId = asset.networkId || assetInfo.networkId;
5638
- let nativeSymbol = "GAS";
5639
- let nativeCaip = "";
5640
- if (networkId.includes("mayachain")) {
5641
- nativeSymbol = "CACAO";
5642
- nativeCaip = "cosmos:mayachain-mainnet-v1/slip44:931";
5643
- } else if (networkId.includes("thorchain")) {
5644
- nativeSymbol = "RUNE";
5645
- nativeCaip = "cosmos:thorchain-mainnet-v1/slip44:931";
5646
- } else if (networkId.includes("cosmoshub")) {
5647
- nativeSymbol = "ATOM";
5648
- nativeCaip = "cosmos:cosmoshub-4/slip44:118";
5649
- } else if (networkId.includes("osmosis")) {
5650
- nativeSymbol = "OSMO";
5651
- nativeCaip = "cosmos:osmosis-1/slip44:118";
5652
- } else if (networkId.includes("eip155:1")) {
5653
- nativeSymbol = "ETH";
5654
- nativeCaip = "eip155:1/slip44:60";
5655
- } else if (networkId.includes("eip155:137")) {
5656
- nativeSymbol = "MATIC";
5657
- nativeCaip = "eip155:137/slip44:60";
5658
- } else if (networkId.includes("eip155:56")) {
5659
- nativeSymbol = "BNB";
5660
- nativeCaip = "eip155:56/slip44:60";
5661
- } else if (networkId.includes("eip155:43114")) {
5662
- nativeSymbol = "AVAX";
5663
- nativeCaip = "eip155:43114/slip44:60";
5664
- }
5665
5636
  this.assetContext.nativeSymbol = nativeSymbol;
5666
5637
  if (nativeCaip) {
5667
5638
  const nativeBalance = this.balances.find((b) => b.caip === nativeCaip);
@@ -5695,7 +5666,7 @@ class SDK {
5695
5666
  }
5696
5667
  };
5697
5668
  this.setPubkeyContext = async function(pubkey) {
5698
- let tag6 = `${TAG9} | setPubkeyContext | `;
5669
+ let tag6 = `${TAG12} | setPubkeyContext | `;
5699
5670
  try {
5700
5671
  if (!pubkey)
5701
5672
  throw Error("pubkey is required");
@@ -5714,97 +5685,40 @@ class SDK {
5714
5685
  }
5715
5686
  };
5716
5687
  this.setOutboundAssetContext = async function(asset) {
5717
- const tag6 = `${TAG9} | setOutputAssetContext | `;
5688
+ const tag6 = `${TAG12} | setOutputAssetContext | `;
5718
5689
  try {
5719
- console.log(tag6, "0. asset: ", asset);
5690
+ console.log(tag6, "asset:", asset);
5720
5691
  if (!asset) {
5721
5692
  this.outboundAssetContext = null;
5722
5693
  return;
5723
5694
  }
5724
- console.log(tag6, "1 asset: ", asset);
5725
5695
  if (!asset.caip)
5726
5696
  throw Error("Invalid Asset! missing caip!");
5727
5697
  if (!asset.networkId)
5728
5698
  asset.networkId = import_pioneer_caip8.caipToNetworkId(asset.caip);
5729
- console.log(tag6, "networkId: ", asset.networkId);
5730
- console.log(tag6, "this.pubkeys: ", this.pubkeys);
5731
- const pubkey = this.pubkeys.find((p) => {
5732
- if (!p.networks || !Array.isArray(p.networks))
5733
- return false;
5734
- if (p.networks.includes(asset.networkId))
5735
- return true;
5736
- if (asset.networkId.startsWith("eip155:") && p.networks.includes("eip155:*"))
5737
- return true;
5738
- return false;
5739
- });
5699
+ console.log(tag6, "networkId:", asset.networkId);
5700
+ const pubkey = findPubkeyForNetwork(this.pubkeys, asset.networkId);
5740
5701
  if (!pubkey)
5741
5702
  throw Error("Invalid network! missing pubkey for network! " + asset.networkId);
5742
- let freshPriceUsd = 0;
5743
- try {
5744
- if (!asset.caip || typeof asset.caip !== "string" || !asset.caip.includes(":")) {
5745
- console.warn(tag6, "Invalid or missing CAIP, skipping market price fetch:", asset.caip);
5746
- } else {
5747
- console.log(tag6, "Fetching fresh market price for:", asset.caip);
5748
- const marketData = await this.pioneer.GetMarketInfo([asset.caip]);
5749
- console.log(tag6, "Market data response:", marketData);
5750
- if (marketData && marketData.data && marketData.data.length > 0) {
5751
- freshPriceUsd = marketData.data[0];
5752
- console.log(tag6, "✅ Fresh market price:", freshPriceUsd);
5753
- } else {
5754
- console.warn(tag6, "No market data returned for:", asset.caip);
5755
- }
5756
- }
5757
- } catch (marketError) {
5758
- console.error(tag6, "Error fetching market price:", marketError);
5759
- }
5760
- let assetInfo = this.assetsMap.get(asset.caip.toLowerCase());
5761
- console.log(tag6, "assetInfo: ", assetInfo);
5762
- if (!assetInfo) {
5763
- assetInfo = {
5764
- caip: asset.caip.toLowerCase(),
5765
- networkId: asset.networkId,
5766
- symbol: asset.symbol || "UNKNOWN",
5767
- name: asset.name || "Unknown Asset",
5768
- icon: asset.icon || "https://pioneers.dev/coins/ethereum.png"
5769
- };
5770
- }
5703
+ const freshPriceUsd = await fetchMarketPrice(this.pioneer, asset.caip);
5704
+ let assetInfo = resolveAssetInfo(this.assetsMap, import_pioneer_discovery2.assetData, asset);
5771
5705
  const matchingBalances = this.balances.filter((b) => b.caip === asset.caip);
5772
5706
  if (matchingBalances.length > 0) {
5773
- let priceValue = matchingBalances[0].priceUsd || matchingBalances[0].price;
5774
- if ((!priceValue || priceValue === 0) && matchingBalances[0].valueUsd && matchingBalances[0].balance) {
5775
- const balance = parseFloat(matchingBalances[0].balance);
5776
- const valueUsd = parseFloat(matchingBalances[0].valueUsd);
5777
- if (balance > 0 && valueUsd > 0) {
5778
- priceValue = valueUsd / balance;
5779
- console.log(tag6, "calculated priceUsd from valueUsd/balance:", priceValue);
5780
- }
5781
- }
5782
- if (priceValue && priceValue > 0) {
5707
+ const priceValue = extractPriceFromBalances(matchingBalances);
5708
+ if (priceValue > 0) {
5783
5709
  console.log(tag6, "detected priceUsd from balance:", priceValue);
5784
5710
  assetInfo.priceUsd = priceValue;
5785
5711
  }
5786
5712
  }
5787
- if (freshPriceUsd && freshPriceUsd > 0) {
5713
+ if (freshPriceUsd > 0) {
5788
5714
  assetInfo.priceUsd = freshPriceUsd;
5789
5715
  console.log(tag6, "✅ Using fresh market price:", freshPriceUsd);
5790
- let totalBalance = 0;
5791
- let totalValueUsd = 0;
5792
- console.log(tag6, `Found ${matchingBalances.length} balance entries for ${asset.caip}`);
5793
- for (const balanceEntry of matchingBalances) {
5794
- const balance = parseFloat(balanceEntry.balance) || 0;
5795
- const valueUsd = parseFloat(balanceEntry.valueUsd) || 0;
5796
- totalBalance += balance;
5797
- totalValueUsd += valueUsd;
5798
- console.log(tag6, ` Balance entry: ${balance} (${valueUsd} USD)`);
5799
- }
5716
+ const { totalBalance, totalValueUsd } = aggregateBalances(matchingBalances, asset.caip);
5800
5717
  assetInfo.balance = totalBalance.toString();
5801
5718
  assetInfo.valueUsd = totalValueUsd.toFixed(2);
5802
- console.log(tag6, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
5803
5719
  }
5804
- console.log(tag6, "CHECKPOINT 1");
5805
5720
  this.outboundAssetContext = { ...assetInfo, ...asset, ...pubkey };
5806
- console.log(tag6, "CHECKPOINT 3");
5807
- console.log(tag6, "outboundAssetContext: assetInfo: ", assetInfo);
5721
+ console.log(tag6, "outboundAssetContext set:", this.outboundAssetContext.caip);
5808
5722
  if (asset.caip) {
5809
5723
  this.outboundBlockchainContext = import_pioneer_caip8.caipToNetworkId(asset.caip);
5810
5724
  } else if (asset.networkId) {
@@ -5820,28 +5734,12 @@ class SDK {
5820
5734
  };
5821
5735
  }
5822
5736
  CheckERC20Allowance = async (params) => {
5823
- const tag6 = TAG9 + " | CheckERC20Allowance | ";
5824
- try {
5825
- console.log(tag6, "Checking ERC20 allowance:", params);
5826
- const result = await this.pioneer.GetTokenAllowance(params);
5827
- console.log(tag6, "Allowance result:", result);
5828
- return result.data;
5829
- } catch (e) {
5830
- console.error(tag6, "Error checking ERC20 allowance:", e);
5831
- throw e;
5832
- }
5737
+ const result = await this.pioneer.GetTokenAllowance(params);
5738
+ return result.data;
5833
5739
  };
5834
5740
  BuildERC20ApprovalTx = async (params) => {
5835
- const tag6 = TAG9 + " | BuildERC20ApprovalTx | ";
5836
- try {
5837
- console.log(tag6, "Building ERC20 approval transaction:", params);
5838
- const result = await this.pioneer.BuildApprovalTransaction(params);
5839
- console.log(tag6, "Approval tx built:", result);
5840
- return result.data;
5841
- } catch (e) {
5842
- console.error(tag6, "Error building approval transaction:", e);
5843
- throw e;
5844
- }
5741
+ const result = await this.pioneer.BuildApprovalTransaction(params);
5742
+ return result.data;
5845
5743
  };
5846
5744
  }
5847
5745
  var src_default = SDK;