@pioneer-platform/pioneer-sdk 8.15.14 → 8.15.16

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.js CHANGED
@@ -33,6 +33,117 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
33
33
  throw Error('Dynamic require of "' + x + '" is not supported');
34
34
  });
35
35
 
36
+ // ../../support/loggerdog/lib/index.js
37
+ var require_lib = __commonJS((exports, module) => {
38
+ var __spreadArray = exports && exports.__spreadArray || function(to, from, pack) {
39
+ if (pack || arguments.length === 2)
40
+ for (var i = 0, l = from.length, ar;i < l; i++) {
41
+ if (ar || !(i in from)) {
42
+ if (!ar)
43
+ ar = Array.prototype.slice.call(from, 0, i);
44
+ ar[i] = from[i];
45
+ }
46
+ }
47
+ return to.concat(ar || Array.prototype.slice.call(from));
48
+ };
49
+ var LOG_LEVELS = {
50
+ TEST: { val: 0, label: "TEST", color: "color: cyan" },
51
+ EMERG: { val: 0, label: "EMERG", color: "color: magenta" },
52
+ ALERT: { val: 1, label: "ALERT", color: "color: magenta" },
53
+ CRIT: { val: 2, label: "CRIT", color: "color: red" },
54
+ ERROR: { val: 3, label: "ERROR", color: "color: red" },
55
+ WARN: { val: 4, label: "WARN", color: "color: orange" },
56
+ NOTICE: { val: 5, label: "NOTICE", color: "color: yellow" },
57
+ VERBOSE: { val: 6, label: "VERBOSE", color: "color: cyan" },
58
+ INFO: { val: 6, label: "INFO", color: "color: cyan" },
59
+ DEBUG: { val: 7, label: "DEBUG", color: "color: green" },
60
+ DEBUGV: { val: 8, label: "DEBUG", color: "color: green" },
61
+ DEBUGVV: { val: 9, label: "DEBUG", color: "color: green" }
62
+ };
63
+ var DEFAULT_LOG_LEVEL = typeof process !== "undefined" ? process.env["DEFAULT_LOG_LEVEL"] || "INFO" : "INFO";
64
+ function _extractContext(stack, depth) {
65
+ try {
66
+ var arr = stack.split(`
67
+ `);
68
+ var chunks = arr[depth].split("/");
69
+ var business = chunks[chunks.length - 1];
70
+ var matches = business.match(/^([^:]+):(\d+):(\d+)/i) || "";
71
+ var filename = matches[1];
72
+ var line = matches[2];
73
+ var pos = matches[3];
74
+ return { filename, line, pos };
75
+ } catch (ex) {
76
+ return { filename: "unknown" };
77
+ }
78
+ }
79
+ function _getContextString() {
80
+ var stack = new Error().stack || "";
81
+ var _a = _extractContext(stack, 3), filename = _a.filename, line = _a.line, pos = _a.pos;
82
+ return "[".concat(filename, ":").concat(line, ":").concat(pos, "]");
83
+ }
84
+ var Logger = function() {
85
+ function Logger2() {
86
+ var stack = new Error().stack || "";
87
+ var ctx = _extractContext(stack, 3);
88
+ this._tag = ctx.filename || "";
89
+ for (var lvl in LOG_LEVELS) {
90
+ this[lvl.toLowerCase()] = this._log.bind(this, lvl);
91
+ }
92
+ this._setLogLevel();
93
+ }
94
+ Logger2.prototype._setLogLevel = function() {
95
+ var tag = this._tag.split(".")[0];
96
+ tag = tag.toUpperCase().replace("-", "_");
97
+ var level = typeof process !== "undefined" ? process.env["LOG_LEVEL_" + tag] || null : null;
98
+ if (level && LOG_LEVELS[level] !== undefined) {
99
+ this._level = LOG_LEVELS[level].val;
100
+ } else {
101
+ this._level = LOG_LEVELS[DEFAULT_LOG_LEVEL].val;
102
+ }
103
+ };
104
+ Logger2.prototype._log = function(level) {
105
+ var args = [];
106
+ for (var _i = 1;_i < arguments.length; _i++) {
107
+ args[_i - 1] = arguments[_i];
108
+ }
109
+ if (this._level >= LOG_LEVELS[level].val) {
110
+ var dt = new Date().toISOString().replace("T", " ");
111
+ var ctx = _getContextString();
112
+ var label = LOG_LEVELS[level].label;
113
+ var color = LOG_LEVELS[level].color;
114
+ var message = undefined;
115
+ if (typeof process !== "undefined" && process.env["STRUCTURED_LOGGING"]) {
116
+ message = {};
117
+ var tag = args[0];
118
+ var param = args[1];
119
+ var value = args[2];
120
+ if (typeof args === "object") {
121
+ message.loggerdog = true;
122
+ message.label = label;
123
+ message.param = param;
124
+ message.value = value;
125
+ message.ctx = ctx;
126
+ message.dt = dt;
127
+ message.tag = tag.toString();
128
+ message.raw = args.toString();
129
+ } else {
130
+ message.raw = args;
131
+ }
132
+ console.log("%c " + dt, color, label, ctx, message);
133
+ } else {
134
+ console.log.apply(console, __spreadArray(["%c " + dt, color, label, ctx], args, false));
135
+ }
136
+ }
137
+ };
138
+ return Logger2;
139
+ }();
140
+ var getLogger = function() {
141
+ return new Logger;
142
+ };
143
+ exports.default = getLogger;
144
+ module.exports = getLogger;
145
+ });
146
+
36
147
  // ../../../node_modules/coinselect/utils.js
37
148
  var require_utils = __commonJS((exports, module) => {
38
149
  var TX_EMPTY_SIZE = 4 + 1 + 1 + 4;
@@ -782,9 +893,9 @@ import { KeepKeySdk } from "@keepkey/keepkey-sdk";
782
893
  import { caipToNetworkId as caipToNetworkId7, networkIdToCaip as networkIdToCaip2 } from "@pioneer-platform/pioneer-caip";
783
894
 
784
895
  // ../pioneer-client/lib/index.js
896
+ var import_loggerdog = __toESM(require_lib(), 1);
785
897
  import SwaggerClient from "swagger-client";
786
- import loggerdog from "@pioneer-platform/loggerdog";
787
- var log = typeof window === "undefined" ? loggerdog() : {
898
+ var log = typeof window === "undefined" ? import_loggerdog.default() : {
788
899
  debug: (...args) => console.debug(...args),
789
900
  info: (...args) => console.info(...args),
790
901
  warn: (...args) => console.warn(...args),
@@ -929,7 +1040,7 @@ class Pioneer {
929
1040
  }
930
1041
 
931
1042
  // src/index.ts
932
- import { addressNListToBIP32 as addressNListToBIP322, getPaths } from "@pioneer-platform/pioneer-coins";
1043
+ import { getPaths as getPaths2 } from "@pioneer-platform/pioneer-coins";
933
1044
  import { assetData as assetData2 } from "@pioneer-platform/pioneer-discovery";
934
1045
  import { Events } from "@pioneer-platform/pioneer-events";
935
1046
 
@@ -1129,6 +1240,25 @@ function R(t) {
1129
1240
  var A = o;
1130
1241
  var P = o.prototype;
1131
1242
 
1243
+ // src/utils/logger.ts
1244
+ var DEBUG = process.env.DEBUG === "true" || typeof window !== "undefined" && window.DEBUG;
1245
+ var logger = {
1246
+ info: (tag, ...args) => {
1247
+ console.log(`[INFO] ${tag}`, ...args);
1248
+ },
1249
+ debug: (tag, ...args) => {
1250
+ if (DEBUG) {
1251
+ console.log(`[DEBUG] ${tag}`, ...args);
1252
+ }
1253
+ },
1254
+ warn: (tag, ...args) => {
1255
+ console.warn(`[WARN] ${tag}`, ...args);
1256
+ },
1257
+ error: (tag, ...args) => {
1258
+ console.error(`[ERROR] ${tag}`, ...args);
1259
+ }
1260
+ };
1261
+
1132
1262
  // src/getPubkey.ts
1133
1263
  import { NetworkIdToChain } from "@pioneer-platform/pioneer-caip";
1134
1264
  import {
@@ -4167,25 +4297,400 @@ async function syncMarket(balances, pioneer) {
4167
4297
  }
4168
4298
  }
4169
4299
 
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"
4300
+ // src/utils/pubkey-management.ts
4301
+ function getPubkeyKey(pubkey) {
4302
+ return `${pubkey.pubkey}_${pubkey.pathMaster}`;
4303
+ }
4304
+ function deduplicatePubkeys(pubkeys) {
4305
+ const seen = new Set;
4306
+ return pubkeys.filter((pubkey) => {
4307
+ const key = getPubkeyKey(pubkey);
4308
+ if (seen.has(key))
4309
+ return false;
4310
+ seen.add(key);
4311
+ return true;
4312
+ });
4313
+ }
4314
+ function validatePubkey(pubkey) {
4315
+ return !!(pubkey.pubkey && pubkey.pathMaster);
4316
+ }
4317
+ function findPubkeysForNetwork(pubkeys, networkId) {
4318
+ return pubkeys.filter((p) => {
4319
+ if (!p.networks || !Array.isArray(p.networks))
4320
+ return false;
4321
+ if (p.networks.includes(networkId))
4322
+ return true;
4323
+ if (networkId.startsWith("eip155:") && p.networks.includes("eip155:*")) {
4324
+ return true;
4325
+ }
4326
+ return false;
4327
+ });
4328
+ }
4329
+ function findPubkeyForNetwork(pubkeys, networkId) {
4330
+ return pubkeys.find((p) => {
4331
+ if (!p.networks || !Array.isArray(p.networks))
4332
+ return false;
4333
+ if (p.networks.includes(networkId))
4334
+ return true;
4335
+ if (networkId.startsWith("eip155:") && p.networks.includes("eip155:*"))
4336
+ return true;
4337
+ return false;
4338
+ });
4339
+ }
4340
+ function validatePubkeysForNetwork(pubkeys, networkId, caip) {
4341
+ if (!pubkeys || pubkeys.length === 0) {
4342
+ throw new Error(`Cannot set asset context for ${caip} - no pubkeys loaded. Please initialize wallet first.`);
4343
+ }
4344
+ const pubkeysForNetwork = findPubkeysForNetwork(pubkeys, networkId);
4345
+ if (pubkeysForNetwork.length === 0) {
4346
+ const availableNetworks = [...new Set(pubkeys.flatMap((p) => p.networks || []))];
4347
+ throw new Error(`Cannot set asset context for ${caip} - no address/xpub found for network ${networkId}. Available networks: ${availableNetworks.join(", ")}`);
4348
+ }
4349
+ const isUtxoChain = networkId.startsWith("bip122:");
4350
+ if (isUtxoChain) {
4351
+ const xpubFound = pubkeysForNetwork.some((p) => p.type === "xpub" && p.pubkey);
4352
+ if (!xpubFound) {
4353
+ throw new Error(`Cannot set asset context for UTXO chain ${caip} - xpub required but not found`);
4354
+ }
4355
+ }
4356
+ const hasValidAddress = pubkeysForNetwork.some((p) => p.address || p.master || p.pubkey);
4357
+ if (!hasValidAddress) {
4358
+ throw new Error(`Cannot set asset context for ${caip} - no valid address found in pubkeys`);
4359
+ }
4360
+ }
4361
+ function filterPubkeysForAsset(pubkeys, caip, caipToNetworkId7) {
4362
+ const networkId = caipToNetworkId7(caip);
4363
+ return pubkeys.filter((p) => {
4364
+ if (!p.networks || !Array.isArray(p.networks))
4365
+ return false;
4366
+ if (p.networks.includes(networkId))
4367
+ return true;
4368
+ if (networkId.includes("eip155") && p.networks.some((n) => n.startsWith("eip155"))) {
4369
+ return true;
4370
+ }
4371
+ return false;
4372
+ });
4373
+ }
4374
+
4375
+ // src/utils/portfolio-helpers.ts
4376
+ var TAG9 = " | portfolio-helpers | ";
4377
+ function isCacheDataValid(portfolioData) {
4378
+ if (!portfolioData.networks || !Array.isArray(portfolioData.networks)) {
4379
+ console.warn("[CACHE VALIDATION] Networks is not an array");
4380
+ return false;
4381
+ }
4382
+ if (portfolioData.networks.length > 50) {
4383
+ console.error(`[CACHE VALIDATION] CORRUPTED: ${portfolioData.networks.length} networks (should be < 50)`);
4384
+ return false;
4385
+ }
4386
+ const validNetworks = portfolioData.networks.filter((n) => n.networkId && n.totalValueUsd !== undefined && n.gasAssetSymbol);
4387
+ if (validNetworks.length === 0 && portfolioData.networks.length > 0) {
4388
+ console.error("[CACHE VALIDATION] CORRUPTED: No networks have required fields");
4389
+ return false;
4390
+ }
4391
+ console.log(`[CACHE VALIDATION] Found ${portfolioData.networks.length} networks, ${validNetworks.length} valid`);
4392
+ return true;
4393
+ }
4394
+ async function fetchMarketPrice(pioneer, caip) {
4395
+ const tag = TAG9 + " | fetchMarketPrice | ";
4396
+ try {
4397
+ if (!caip || typeof caip !== "string" || !caip.includes(":")) {
4398
+ logger.warn(tag, "Invalid or missing CAIP, skipping market price fetch:", caip);
4399
+ return 0;
4400
+ }
4401
+ logger.debug(tag, "Fetching fresh market price for:", caip);
4402
+ const marketData = await pioneer.GetMarketInfo([caip]);
4403
+ logger.debug(tag, "Market data response:", marketData);
4404
+ if (marketData && marketData.data && marketData.data.length > 0) {
4405
+ const price = marketData.data[0];
4406
+ logger.debug(tag, "✅ Fresh market price:", price);
4407
+ return price;
4408
+ } else {
4409
+ logger.warn(tag, "No market data returned for:", caip);
4410
+ return 0;
4411
+ }
4412
+ } catch (marketError) {
4413
+ logger.error(tag, "Error fetching market price:", marketError);
4414
+ return 0;
4415
+ }
4416
+ }
4417
+ function extractPriceFromBalances(balances) {
4418
+ const tag = TAG9 + " | extractPriceFromBalances | ";
4419
+ if (balances.length === 0)
4420
+ return 0;
4421
+ let priceValue = balances[0].priceUsd || balances[0].price;
4422
+ if ((!priceValue || priceValue === 0) && balances[0].valueUsd && balances[0].balance) {
4423
+ const balance = parseFloat(balances[0].balance);
4424
+ const valueUsd = parseFloat(balances[0].valueUsd);
4425
+ if (balance > 0 && valueUsd > 0) {
4426
+ priceValue = valueUsd / balance;
4427
+ logger.debug(tag, "Calculated priceUsd from valueUsd/balance:", priceValue);
4428
+ }
4429
+ }
4430
+ return priceValue || 0;
4431
+ }
4432
+ function aggregateBalances(balances, caip) {
4433
+ const tag = TAG9 + " | aggregateBalances | ";
4434
+ let totalBalance = 0;
4435
+ let totalValueUsd = 0;
4436
+ logger.debug(tag, `Aggregating ${balances.length} balance entries for ${caip}`);
4437
+ for (const balanceEntry of balances) {
4438
+ const balance = parseFloat(balanceEntry.balance) || 0;
4439
+ const valueUsd = parseFloat(balanceEntry.valueUsd) || 0;
4440
+ totalBalance += balance;
4441
+ totalValueUsd += valueUsd;
4442
+ logger.debug(tag, ` Balance entry: ${balance} (${valueUsd} USD)`);
4443
+ }
4444
+ logger.debug(tag, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
4445
+ return { totalBalance, totalValueUsd };
4446
+ }
4447
+ function updateBalancesWithPrice(balances, freshPriceUsd) {
4448
+ const tag = TAG9 + " | updateBalancesWithPrice | ";
4449
+ for (const balance of balances) {
4450
+ balance.price = freshPriceUsd;
4451
+ balance.priceUsd = freshPriceUsd;
4452
+ const balanceAmount = parseFloat(balance.balance || 0);
4453
+ balance.valueUsd = (balanceAmount * freshPriceUsd).toString();
4454
+ }
4455
+ logger.debug(tag, "Updated all balances with fresh price data");
4456
+ }
4457
+ function buildDashboardFromPortfolioData(portfolioData) {
4458
+ const cacheAge = portfolioData.lastUpdated ? Math.floor((Date.now() - portfolioData.lastUpdated) / 1000) : 0;
4459
+ return {
4460
+ totalValueUsd: portfolioData.totalValueUsd,
4461
+ pairedDevices: portfolioData.pairedDevices,
4462
+ devices: portfolioData.devices || [],
4463
+ networks: portfolioData.networks || [],
4464
+ assets: portfolioData.assets || [],
4465
+ statistics: portfolioData.statistics || {},
4466
+ cached: portfolioData.cached,
4467
+ lastUpdated: portfolioData.lastUpdated,
4468
+ cacheAge,
4469
+ networkPercentages: portfolioData.networks?.map((network) => ({
4470
+ networkId: network.network_id || network.networkId,
4471
+ percentage: network.percentage || 0
4472
+ })) || []
4473
+ };
4474
+ }
4475
+ function buildAssetQuery(pubkeys, caip) {
4476
+ return pubkeys.map((pubkey) => ({ caip, pubkey: pubkey.pubkey }));
4477
+ }
4478
+ function logQueryDiagnostics(assetQuery, tag = "") {
4479
+ const caipCounts = new Map;
4480
+ for (const query of assetQuery) {
4481
+ caipCounts.set(query.caip, (caipCounts.get(query.caip) || 0) + 1);
4482
+ }
4483
+ if (tag) {
4484
+ console.log(tag, "Built assetQuery with", assetQuery.length, "entries");
4485
+ console.log(tag, "Sample queries:", assetQuery.slice(0, 5));
4486
+ console.log(tag, "Queries by chain:");
4487
+ caipCounts.forEach((count, caip) => {
4488
+ console.log(` - ${caip}: ${count} queries`);
4489
+ });
4490
+ }
4491
+ }
4492
+ function enrichBalancesWithAssetInfo(balances, assetsMap, caipToNetworkId7) {
4493
+ const tag = TAG9 + " | enrichBalancesWithAssetInfo | ";
4494
+ for (const balance of balances) {
4495
+ const assetInfo = assetsMap.get(balance.caip.toLowerCase()) || assetsMap.get(balance.caip);
4496
+ if (!assetInfo) {
4497
+ throw new Error(`Missing AssetInfo for ${balance.caip}`);
4498
+ }
4499
+ Object.assign(balance, assetInfo, {
4500
+ type: balance.type || assetInfo.type,
4501
+ isNative: balance.isNative ?? assetInfo.isNative,
4502
+ networkId: caipToNetworkId7(balance.caip),
4503
+ icon: assetInfo.icon || "https://pioneers.dev/coins/etherum.png",
4504
+ identifier: `${balance.caip}:${balance.pubkey}`,
4505
+ updated: Date.now(),
4506
+ color: assetInfo.color
4507
+ });
4508
+ }
4509
+ return balances;
4510
+ }
4511
+
4512
+ // src/utils/sync-state.ts
4513
+ var TAG10 = " | sync-state | ";
4514
+ function resolveAssetInfo(assetsMap, assetData, asset) {
4515
+ const tag = TAG10 + " | resolveAssetInfo | ";
4516
+ let assetInfo = assetsMap.get(asset.caip.toLowerCase());
4517
+ logger.debug(tag, "assetInfo from assetsMap:", assetInfo);
4518
+ const assetInfoDiscovery = assetData[asset.caip];
4519
+ logger.debug(tag, "assetInfoDiscovery:", assetInfoDiscovery);
4520
+ if (assetInfoDiscovery) {
4521
+ assetInfo = assetInfoDiscovery;
4522
+ }
4523
+ if (!assetInfo) {
4524
+ logger.debug(tag, "Building placeholder asset for", asset.caip);
4525
+ assetInfo = {
4526
+ caip: asset.caip.toLowerCase(),
4527
+ networkId: asset.networkId,
4528
+ symbol: asset.symbol || "UNKNOWN",
4529
+ name: asset.name || "Unknown Asset",
4530
+ icon: asset.icon || "https://pioneers.dev/coins/ethereum.png"
4531
+ };
4532
+ }
4533
+ return assetInfo;
4534
+ }
4535
+ function createInitialSyncState(totalChains) {
4536
+ return {
4537
+ isSynced: false,
4538
+ isInitialSync: true,
4539
+ cacheAge: 0,
4540
+ syncProgress: 0,
4541
+ syncedChains: 0,
4542
+ totalChains,
4543
+ lastSyncTime: null,
4544
+ syncSource: "none"
4545
+ };
4546
+ }
4547
+ function createCacheSyncState(lastUpdated, totalChains) {
4548
+ const cacheAge = lastUpdated ? Math.floor((Date.now() - lastUpdated) / 1000) : 0;
4549
+ return {
4550
+ isSynced: true,
4551
+ isInitialSync: false,
4552
+ cacheAge,
4553
+ syncProgress: 100,
4554
+ syncedChains: totalChains,
4555
+ totalChains,
4556
+ lastSyncTime: lastUpdated || Date.now(),
4557
+ syncSource: "cache"
4558
+ };
4559
+ }
4560
+ function createFreshSyncState(totalChains) {
4561
+ return {
4562
+ isSynced: true,
4563
+ isInitialSync: false,
4564
+ cacheAge: 0,
4565
+ syncProgress: 100,
4566
+ syncedChains: totalChains,
4567
+ totalChains,
4568
+ lastSyncTime: Date.now(),
4569
+ syncSource: "fresh"
4570
+ };
4571
+ }
4572
+
4573
+ // src/utils/fee-reserves.ts
4574
+ var TAG11 = " | Pioneer-sdk | fee-reserves | ";
4575
+ var FEE_RESERVE_MAP = {
4576
+ "bip122:000000000019d6689c085ae165831e93/slip44:0": 0.00005,
4577
+ "eip155:1/slip44:60": 0.001,
4578
+ "cosmos:thorchain-mainnet-v1/slip44:931": 0.02,
4579
+ "bip122:00000000001a91e3dace36e2be3bf030/slip44:3": 1,
4580
+ "bip122:000007d91d1254d60e2dd1ae58038307/slip44:5": 0.001,
4581
+ "bip122:000000000000000000651ef99cb9fcbe/slip44:145": 0.0005,
4582
+ "bip122:12a765e31ffd4059bada1e25190f6e98/slip44:2": 0.001,
4583
+ "bip122:4da631f2ac1bed857bd968c67c913978/slip44:20": 0.1,
4584
+ "cosmos:cosmoshub-4/slip44:118": 0.005,
4585
+ "cosmos:osmosis-1/slip44:118": 0.035,
4586
+ "cosmos:mayachain-mainnet-v1/slip44:931": 0.5,
4587
+ "eip155:56/slip44:60": 0.001,
4588
+ "eip155:137/slip44:60": 0.01,
4589
+ "eip155:43114/slip44:60": 0.01,
4590
+ "eip155:10/slip44:60": 0.0001,
4591
+ "eip155:8453/slip44:60": 0.0001,
4592
+ "eip155:42161/slip44:60": 0.0001,
4593
+ "ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144": 0.00001
4188
4594
  };
4595
+ var DEFAULT_FEE_RESERVE = 0.001;
4596
+ function getFeeReserve(caip) {
4597
+ if (FEE_RESERVE_MAP[caip]) {
4598
+ return FEE_RESERVE_MAP[caip];
4599
+ }
4600
+ if (caip.startsWith("eip155:") && caip.includes("/slip44:60")) {
4601
+ return FEE_RESERVE_MAP["eip155:1/slip44:60"] || 0.001;
4602
+ }
4603
+ if (caip.startsWith("cosmos:")) {
4604
+ return 0.01;
4605
+ }
4606
+ if (caip.startsWith("bip122:")) {
4607
+ return 0.0001;
4608
+ }
4609
+ console.warn(TAG11, `No fee reserve defined for ${caip}, using default: ${DEFAULT_FEE_RESERVE}`);
4610
+ return DEFAULT_FEE_RESERVE;
4611
+ }
4612
+ function getMaxSendableAmount(balance, caip) {
4613
+ const reserve = getFeeReserve(caip);
4614
+ const maxAmount = Math.max(0, balance - reserve);
4615
+ console.log(TAG11, `Max sendable for ${caip}: ${maxAmount} (balance: ${balance}, reserve: ${reserve})`);
4616
+ return maxAmount;
4617
+ }
4618
+
4619
+ // src/utils/network-helpers.ts
4620
+ function matchesNetwork(item, networkId) {
4621
+ if (!item.networks || !Array.isArray(item.networks))
4622
+ return false;
4623
+ if (item.networks.includes(networkId))
4624
+ return true;
4625
+ if (networkId.startsWith("eip155:") && item.networks.includes("eip155:*"))
4626
+ return true;
4627
+ return false;
4628
+ }
4629
+ function normalizeNetworkId(networkId) {
4630
+ return networkId.includes("eip155:") ? "eip155:*" : networkId;
4631
+ }
4632
+ function validatePubkeysNetworks(pubkeys, tag = "") {
4633
+ const valid = pubkeys.filter((p) => p.networks && Array.isArray(p.networks));
4634
+ const invalid = pubkeys.filter((p) => !p.networks || !Array.isArray(p.networks));
4635
+ if (tag && invalid.length > 0) {
4636
+ console.warn(tag, `⚠️ ${invalid.length} pubkeys missing networks field`);
4637
+ invalid.forEach((pk) => {
4638
+ console.warn(tag, ` - ${pk.note || pk.pubkey.slice(0, 10)}: networks=${pk.networks}`);
4639
+ });
4640
+ }
4641
+ return { valid, invalid };
4642
+ }
4643
+
4644
+ // src/utils/path-discovery.ts
4645
+ import { getPaths } from "@pioneer-platform/pioneer-coins";
4646
+ async function ensurePathsForBlockchains(blockchains, currentPaths, tag) {
4647
+ let allPaths = [...currentPaths];
4648
+ for (const blockchain of blockchains) {
4649
+ const networkId = normalizeNetworkId(blockchain);
4650
+ const existingPaths = allPaths.filter((path) => matchesNetwork(path, networkId));
4651
+ if (existingPaths.length === 0) {
4652
+ logger.info(tag, `Discovering paths for ${networkId}...`);
4653
+ const newPaths = getPaths([networkId]);
4654
+ if (!newPaths || newPaths.length === 0) {
4655
+ throw new Error(`Path discovery failed for ${networkId}. ` + `Available blockchains: ${blockchains.join(", ")}`);
4656
+ }
4657
+ logger.debug(tag, `Added ${newPaths.length} paths for ${networkId}`);
4658
+ allPaths = allPaths.concat(newPaths);
4659
+ }
4660
+ }
4661
+ return allPaths;
4662
+ }
4663
+
4664
+ // src/utils/pubkey-sync.ts
4665
+ import { addressNListToBIP32 as addressNListToBIP322 } from "@pioneer-platform/pioneer-coins";
4666
+ async function syncPubkeysForBlockchains(blockchains, paths, existingPubkeys, keepKeySdk, context, getPubkeyFn, addPubkeyCallback, tag) {
4667
+ for (const blockchain of blockchains) {
4668
+ const networkId = normalizeNetworkId(blockchain);
4669
+ const pathsForChain = paths.filter((path) => matchesNetwork(path, networkId));
4670
+ if (pathsForChain.length === 0) {
4671
+ const availablePaths = paths.map((p) => p.note || p.path || "unnamed").join(", ");
4672
+ throw new Error(`No paths found for ${networkId}. ` + `Available paths: ${availablePaths || "none"}`);
4673
+ }
4674
+ logger.info(tag, `Syncing ${pathsForChain.length} pubkeys for ${networkId}...`);
4675
+ for (const path of pathsForChain) {
4676
+ const pathBip32 = addressNListToBIP322(path.addressNListMaster);
4677
+ const existingPubkey = existingPubkeys.find((p) => p.pathMaster === pathBip32);
4678
+ if (!existingPubkey) {
4679
+ logger.debug(tag, `Fetching pubkey for path ${pathBip32}...`);
4680
+ const newPubkey = await getPubkeyFn(blockchain, path, keepKeySdk, context);
4681
+ if (!newPubkey) {
4682
+ throw new Error(`Pubkey fetch failed for ${networkId} at path ${pathBip32}. ` + `Ensure hardware wallet is connected and unlocked.`);
4683
+ }
4684
+ addPubkeyCallback(newPubkey);
4685
+ logger.debug(tag, `✓ Added pubkey for ${pathBip32}`);
4686
+ }
4687
+ }
4688
+ }
4689
+ logger.info(tag, `✅ Pubkey sync complete. Total pubkeys: ${existingPubkeys.length}`);
4690
+ }
4691
+
4692
+ // src/index.ts
4693
+ var TAG12 = " | Pioneer-sdk | ";
4189
4694
 
4190
4695
  class SDK {
4191
4696
  status;
@@ -4243,7 +4748,6 @@ class SDK {
4243
4748
  init;
4244
4749
  getUnifiedPortfolio;
4245
4750
  offlineClient;
4246
- convertVaultPubkeysToPioneerFormat;
4247
4751
  app;
4248
4752
  addAsset;
4249
4753
  getAssets;
@@ -4316,23 +4820,14 @@ class SDK {
4316
4820
  this.utxoApiKey = config.utxoApiKey;
4317
4821
  this.walletConnectProjectId = config.walletConnectProjectId;
4318
4822
  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
- };
4823
+ this.syncState = createInitialSyncState(this.blockchains.length);
4329
4824
  this.offlineClient = config.offlineFirst ? new OfflineClient({
4330
4825
  vaultUrl: config.vaultUrl || "kkapi://",
4331
4826
  timeout: 1000,
4332
4827
  fallbackToRemote: true
4333
4828
  }) : null;
4334
4829
  this.pairWallet = async (options) => {
4335
- const tag6 = TAG9 + " | pairWallet | ";
4830
+ const tag6 = TAG12 + " | pairWallet | ";
4336
4831
  if (this.viewOnlyMode || this.skipDevicePairing) {
4337
4832
  console.log(tag6, "\uD83D\uDC41️ [VIEW-ONLY] Skipping device pairing");
4338
4833
  return {
@@ -4347,35 +4842,20 @@ class SDK {
4347
4842
  message: "Device pairing not yet implemented"
4348
4843
  });
4349
4844
  };
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
- };
4845
+ this.getPubkeyKey = getPubkeyKey;
4846
+ this.deduplicatePubkeys = deduplicatePubkeys;
4365
4847
  this.addPubkey = (pubkey) => {
4366
- if (!pubkey.pubkey || !pubkey.pathMaster) {
4848
+ if (!validatePubkey(pubkey))
4367
4849
  return false;
4368
- }
4369
- const key = this.getPubkeyKey(pubkey);
4370
- if (this.pubkeySet.has(key)) {
4850
+ const key = getPubkeyKey(pubkey);
4851
+ if (this.pubkeySet.has(key))
4371
4852
  return false;
4372
- }
4373
4853
  this.pubkeys.push(pubkey);
4374
4854
  this.pubkeySet.add(key);
4375
4855
  return true;
4376
4856
  };
4377
4857
  this.setPubkeys = (newPubkeys) => {
4378
- const tag6 = `${TAG9} | setPubkeys | `;
4858
+ const tag6 = `${TAG12} | setPubkeys | `;
4379
4859
  this.pubkeys = [];
4380
4860
  this.pubkeySet.clear();
4381
4861
  let added = 0;
@@ -4391,17 +4871,8 @@ class SDK {
4391
4871
  this.pubkeys = [];
4392
4872
  this.pubkeySet.clear();
4393
4873
  }
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
4874
  this.getUnifiedPortfolio = async function() {
4404
- const tag6 = `${TAG9} | getUnifiedPortfolio | `;
4875
+ const tag6 = `${TAG12} | getUnifiedPortfolio | `;
4405
4876
  try {
4406
4877
  const startTime = performance.now();
4407
4878
  try {
@@ -4433,8 +4904,7 @@ class SDK {
4433
4904
  this.events.emit("SET_BALANCES", this.balances);
4434
4905
  }
4435
4906
  if (portfolioData.pubkeys && portfolioData.pubkeys.length > 0) {
4436
- const convertedPubkeys = this.convertVaultPubkeysToPioneerFormat(portfolioData.pubkeys);
4437
- this.setPubkeys(convertedPubkeys);
4907
+ this.setPubkeys(portfolioData.pubkeys);
4438
4908
  this.events.emit("SET_PUBKEYS", this.pubkeys);
4439
4909
  }
4440
4910
  if (portfolioData.devices && portfolioData.devices.length > 0) {
@@ -4447,52 +4917,10 @@ class SDK {
4447
4917
  }));
4448
4918
  this.events.emit("SET_WALLETS", this.wallets);
4449
4919
  }
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
4920
  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;
4921
+ this.dashboard = buildDashboardFromPortfolioData(portfolioData);
4484
4922
  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
- };
4923
+ this.syncState = createCacheSyncState(portfolioData.lastUpdated, this.blockchains.length);
4496
4924
  this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4497
4925
  } else {
4498
4926
  console.warn("[CACHE VALIDATION] ❌ Cache data corrupted, building dashboard from cached balances");
@@ -4527,7 +4955,7 @@ class SDK {
4527
4955
  return this.syncState.isSynced;
4528
4956
  };
4529
4957
  this.init = async function(walletsVerbose, setup) {
4530
- const tag6 = `${TAG9} | init | `;
4958
+ const tag6 = `${TAG12} | init | `;
4531
4959
  try {
4532
4960
  if (!this.username)
4533
4961
  throw Error("username required!");
@@ -4548,7 +4976,7 @@ class SDK {
4548
4976
  this.pioneer = await PioneerClient.init();
4549
4977
  if (!this.pioneer)
4550
4978
  throw Error("Failed to init pioneer server!");
4551
- this.paths.concat(getPaths(this.blockchains));
4979
+ this.paths.concat(getPaths2(this.blockchains));
4552
4980
  await this.getGasAssets();
4553
4981
  if (!this.skipKeeperEndpoint) {
4554
4982
  this.keepkeyEndpoint = await detectKkApiAvailability(this.forceLocalhost);
@@ -4592,7 +5020,7 @@ class SDK {
4592
5020
  this.events.emit("message", request);
4593
5021
  });
4594
5022
  clientEvents.events.on("balance:update", (data) => {
4595
- const tag7 = TAG9 + " | balance:update | ";
5023
+ const tag7 = TAG12 + " | balance:update | ";
4596
5024
  try {
4597
5025
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4598
5026
  const balance = payload.balance;
@@ -4610,7 +5038,7 @@ class SDK {
4610
5038
  }
4611
5039
  });
4612
5040
  clientEvents.events.on("sync:progress", (data) => {
4613
- const tag7 = TAG9 + " | sync:progress | ";
5041
+ const tag7 = TAG12 + " | sync:progress | ";
4614
5042
  try {
4615
5043
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4616
5044
  console.log(tag7, `Sync progress: ${payload.percentage}%`);
@@ -4623,7 +5051,7 @@ class SDK {
4623
5051
  }
4624
5052
  });
4625
5053
  clientEvents.events.on("sync:complete", (data) => {
4626
- const tag7 = TAG9 + " | sync:complete | ";
5054
+ const tag7 = TAG12 + " | sync:complete | ";
4627
5055
  try {
4628
5056
  const payload = typeof data === "string" ? JSON.parse(data) : data;
4629
5057
  console.log(tag7, `Sync complete: ${payload.balances} balances in ${payload.duration}ms`);
@@ -4674,155 +5102,60 @@ class SDK {
4674
5102
  this.buildDashboardFromBalances = function() {
4675
5103
  return buildDashboardFromBalances(this.balances, this.blockchains, this.assetsMap);
4676
5104
  };
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
5105
  this.syncMarket = async function() {
4687
5106
  return syncMarket(this.balances, this.pioneer);
4688
5107
  };
4689
5108
  this.sync = async function() {
4690
- const tag6 = `${TAG9} | sync | `;
5109
+ const tag6 = `${TAG12} | sync | `;
5110
+ const log2 = logger;
4691
5111
  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;
5112
+ this.syncState = {
5113
+ ...createInitialSyncState(this.blockchains.length),
5114
+ syncProgress: 10
4700
5115
  };
5116
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5117
+ log2.info(tag6, "Fetching initial pubkeys...");
4701
5118
  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
- }
5119
+ this.syncState.syncProgress = 20;
5120
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5121
+ log2.info(tag6, "Discovering paths for blockchains...");
5122
+ this.paths = await ensurePathsForBlockchains(this.blockchains, this.paths, tag6);
5123
+ this.syncState.syncProgress = 30;
5124
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5125
+ log2.info(tag6, "Synchronizing pubkeys...");
5126
+ await syncPubkeysForBlockchains(this.blockchains, this.paths, this.pubkeys, this.keepKeySdk, this.context, getPubkey, (pubkey) => this.addPubkey(pubkey), tag6);
5127
+ this.syncState.syncProgress = 50;
5128
+ this.syncState.syncedChains = this.blockchains.length;
5129
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5130
+ log2.info(tag6, "Fetching balances...");
4733
5131
  await this.getBalances();
4734
- console.log(tag6, "Loading charts (tokens + portfolio)...");
5132
+ this.syncState.syncProgress = 70;
5133
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5134
+ log2.info(tag6, "Loading charts (tokens + portfolio)...");
4735
5135
  await this.getCharts();
4736
- console.log(tag6, `Charts loaded. Total balances: ${this.balances.length}`);
5136
+ log2.info(tag6, `Charts loaded. Total balances: ${this.balances.length}`);
5137
+ this.syncState.syncProgress = 85;
5138
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5139
+ log2.info(tag6, "Syncing market prices...");
4737
5140
  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
- };
5141
+ this.syncState.syncProgress = 95;
5142
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5143
+ log2.info(tag6, "Building dashboard...");
5144
+ this.dashboard = buildDashboardFromBalances(this.balances, [...new Set(this.blockchains)], this.assetsMap);
5145
+ this.syncState = createFreshSyncState(this.blockchains.length);
4821
5146
  this.events.emit("SYNC_STATE_CHANGED", this.syncState);
4822
5147
  this.events.emit("SYNC_COMPLETE", this.syncState);
5148
+ log2.info(tag6, "✅ Sync complete!");
4823
5149
  return true;
4824
5150
  } catch (e) {
4825
- console.error(tag6, "Error in sync:", e);
5151
+ log2.error(tag6, "Sync failed:", e);
5152
+ this.syncState = {
5153
+ ...this.syncState,
5154
+ isSynced: false,
5155
+ syncProgress: 0
5156
+ };
5157
+ this.events.emit("SYNC_STATE_CHANGED", this.syncState);
5158
+ this.events.emit("SYNC_ERROR", e);
4826
5159
  throw e;
4827
5160
  }
4828
5161
  };
@@ -4836,7 +5169,7 @@ class SDK {
4836
5169
  }
4837
5170
  };
4838
5171
  this.buildTx = async function(sendPayload) {
4839
- let tag6 = TAG9 + " | buildTx | ";
5172
+ let tag6 = TAG12 + " | buildTx | ";
4840
5173
  try {
4841
5174
  const transactionDependencies = {
4842
5175
  context: this.context,
@@ -4858,7 +5191,7 @@ class SDK {
4858
5191
  }
4859
5192
  };
4860
5193
  this.buildDelegateTx = async function(caip, params) {
4861
- let tag6 = TAG9 + " | buildDelegateTx | ";
5194
+ let tag6 = TAG12 + " | buildDelegateTx | ";
4862
5195
  try {
4863
5196
  const delegateParams = {
4864
5197
  ...params,
@@ -4873,7 +5206,7 @@ class SDK {
4873
5206
  }
4874
5207
  };
4875
5208
  this.buildUndelegateTx = async function(caip, params) {
4876
- let tag6 = TAG9 + " | buildUndelegateTx | ";
5209
+ let tag6 = TAG12 + " | buildUndelegateTx | ";
4877
5210
  try {
4878
5211
  const undelegateParams = {
4879
5212
  ...params,
@@ -4888,7 +5221,7 @@ class SDK {
4888
5221
  }
4889
5222
  };
4890
5223
  this.buildClaimRewardsTx = async function(caip, params) {
4891
- let tag6 = TAG9 + " | buildClaimRewardsTx | ";
5224
+ let tag6 = TAG12 + " | buildClaimRewardsTx | ";
4892
5225
  try {
4893
5226
  const claimParams = {
4894
5227
  ...params,
@@ -4903,7 +5236,7 @@ class SDK {
4903
5236
  }
4904
5237
  };
4905
5238
  this.buildClaimAllRewardsTx = async function(caip, params) {
4906
- let tag6 = TAG9 + " | buildClaimAllRewardsTx | ";
5239
+ let tag6 = TAG12 + " | buildClaimAllRewardsTx | ";
4907
5240
  try {
4908
5241
  const claimAllParams = {
4909
5242
  ...params,
@@ -4917,7 +5250,7 @@ class SDK {
4917
5250
  }
4918
5251
  };
4919
5252
  this.signTx = async function(caip, unsignedTx) {
4920
- let tag6 = TAG9 + " | signTx | ";
5253
+ let tag6 = TAG12 + " | signTx | ";
4921
5254
  try {
4922
5255
  const transactionDependencies = {
4923
5256
  context: this.context,
@@ -4938,7 +5271,7 @@ class SDK {
4938
5271
  }
4939
5272
  };
4940
5273
  this.broadcastTx = async function(caip, signedTx) {
4941
- let tag6 = TAG9 + " | broadcastTx | ";
5274
+ let tag6 = TAG12 + " | broadcastTx | ";
4942
5275
  try {
4943
5276
  const transactionDependencies = {
4944
5277
  context: this.context,
@@ -4962,7 +5295,7 @@ class SDK {
4962
5295
  }
4963
5296
  };
4964
5297
  this.swap = async function(swapPayload) {
4965
- let tag6 = `${TAG9} | swap | `;
5298
+ let tag6 = `${TAG12} | swap | `;
4966
5299
  try {
4967
5300
  if (!swapPayload)
4968
5301
  throw Error("swapPayload required!");
@@ -4980,15 +5313,6 @@ class SDK {
4980
5313
  throw Error("Invalid networkId for outboundAssetContext");
4981
5314
  if (!this.outboundAssetContext || !this.outboundAssetContext.address)
4982
5315
  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
5316
  const pubkeys = this.pubkeys.filter((e) => matchesNetwork(e, this.assetContext.networkId));
4993
5317
  let senderAddress = pubkeys[0]?.address || pubkeys[0]?.master || pubkeys[0]?.pubkey;
4994
5318
  if (!senderAddress)
@@ -5020,17 +5344,8 @@ class SDK {
5020
5344
  this.assetContext.balance = totalBalance.toString();
5021
5345
  this.assetContext.valueUsd = (totalBalance * parseFloat(this.assetContext.priceUsd || "0")).toFixed(2);
5022
5346
  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})`);
5347
+ inputAmount = getMaxSendableAmount(totalBalance, swapPayload.caipIn);
5348
+ console.log(tag6, `Using max amount for swap: ${inputAmount} (total balance: ${totalBalance})`);
5034
5349
  } else {
5035
5350
  inputAmount = typeof swapPayload.amount === "string" ? parseFloat(swapPayload.amount) : swapPayload.amount;
5036
5351
  if (isNaN(inputAmount) || inputAmount <= 0) {
@@ -5151,7 +5466,7 @@ class SDK {
5151
5466
  }
5152
5467
  };
5153
5468
  this.transfer = async function(sendPayload) {
5154
- let tag6 = `${TAG9} | transfer | `;
5469
+ let tag6 = `${TAG12} | transfer | `;
5155
5470
  try {
5156
5471
  if (!sendPayload)
5157
5472
  throw Error("sendPayload required!");
@@ -5246,7 +5561,7 @@ class SDK {
5246
5561
  }
5247
5562
  };
5248
5563
  this.setBlockchains = async function(blockchains) {
5249
- const tag6 = `${TAG9} | setBlockchains | `;
5564
+ const tag6 = `${TAG12} | setBlockchains | `;
5250
5565
  try {
5251
5566
  if (!blockchains)
5252
5567
  throw Error("blockchains required!");
@@ -5262,7 +5577,7 @@ class SDK {
5262
5577
  }
5263
5578
  };
5264
5579
  this.addAsset = async function(caip, data) {
5265
- let tag6 = TAG9 + " | addAsset | ";
5580
+ let tag6 = TAG12 + " | addAsset | ";
5266
5581
  try {
5267
5582
  let success = false;
5268
5583
  if (!caip)
@@ -5300,7 +5615,7 @@ class SDK {
5300
5615
  }
5301
5616
  };
5302
5617
  this.clearWalletState = async function() {
5303
- const tag6 = `${TAG9} | clearWalletState | `;
5618
+ const tag6 = `${TAG12} | clearWalletState | `;
5304
5619
  try {
5305
5620
  this.context = null;
5306
5621
  this.paths = [];
@@ -5315,7 +5630,7 @@ class SDK {
5315
5630
  }
5316
5631
  };
5317
5632
  this.addPath = async function(path) {
5318
- const tag6 = `${TAG9} | addPath | `;
5633
+ const tag6 = `${TAG12} | addPath | `;
5319
5634
  try {
5320
5635
  this.paths.push(path);
5321
5636
  const pubkey = await getPubkey(path.networks[0], path, this.keepKeySdk, this.context);
@@ -5329,7 +5644,7 @@ class SDK {
5329
5644
  }
5330
5645
  };
5331
5646
  this.addPaths = async function(paths) {
5332
- const tag6 = `${TAG9} | addPaths | `;
5647
+ const tag6 = `${TAG12} | addPaths | `;
5333
5648
  try {
5334
5649
  console.log(tag6, `Adding ${paths.length} paths in batch mode...`);
5335
5650
  this.paths.push(...paths);
@@ -5365,7 +5680,7 @@ class SDK {
5365
5680
  return this.getGasAssets();
5366
5681
  };
5367
5682
  this.getGasAssets = async function() {
5368
- const tag6 = `${TAG9} | getGasAssets | `;
5683
+ const tag6 = `${TAG12} | getGasAssets | `;
5369
5684
  try {
5370
5685
  for (let i = 0;i < this.blockchains.length; i++) {
5371
5686
  let networkId = this.blockchains[i];
@@ -5379,28 +5694,6 @@ class SDK {
5379
5694
  throw Error("GAS Asset MISSING from assetData " + caip);
5380
5695
  }
5381
5696
  }
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
5697
  return this.assetsMap;
5405
5698
  } catch (e) {
5406
5699
  console.error(e);
@@ -5408,7 +5701,7 @@ class SDK {
5408
5701
  }
5409
5702
  };
5410
5703
  this.getPubkeys = async function() {
5411
- const tag6 = `${TAG9} | getPubkeys | `;
5704
+ const tag6 = `${TAG12} | getPubkeys | `;
5412
5705
  try {
5413
5706
  if (this.paths.length === 0)
5414
5707
  throw new Error("No paths found!");
@@ -5453,134 +5746,57 @@ class SDK {
5453
5746
  }
5454
5747
  };
5455
5748
  this.getBalancesForNetworks = async function(networkIds, forceRefresh) {
5456
- const tag6 = `${TAG9} | getBalancesForNetworks | `;
5749
+ const tag6 = `${TAG12} | getBalancesForNetworks | `;
5457
5750
  try {
5458
5751
  if (!this.pioneer) {
5459
- console.error(tag6, "ERROR: Pioneer client not initialized! this.pioneer is:", this.pioneer);
5460
5752
  throw new Error("Pioneer client not initialized. Call init() first.");
5461
5753
  }
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
- }
5754
+ if (forceRefresh)
5755
+ console.log(tag6, "\uD83D\uDD04 Force refresh requested");
5756
+ console.log("\uD83D\uDD0D [DIAGNOSTIC] Networks:", networkIds.length, "Pubkeys:", this.pubkeys.length);
5757
+ const { valid, invalid } = validatePubkeysNetworks(this.pubkeys, "\uD83D\uDD0D [DIAGNOSTIC]");
5758
+ console.log("\uD83D\uDD0D [DIAGNOSTIC] Pubkeys:", { valid: valid.length, invalid: invalid.length });
5477
5759
  const assetQuery = [];
5478
5760
  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"}`);
5761
+ const pubkeys = findPubkeysForNetwork(this.pubkeys, networkId, this.paths, tag6);
5762
+ const caip = await networkIdToCaip2(networkId);
5763
+ assetQuery.push(...buildAssetQuery(pubkeys, caip));
5575
5764
  }
5765
+ logQueryDiagnostics(assetQuery, "\uD83D\uDD0D [DIAGNOSTIC]");
5766
+ console.log(`⏱️ [PERF] Starting GetPortfolioBalances...`);
5767
+ const apiStart = performance.now();
5768
+ console.time("GetPortfolioBalances Response");
5769
+ const marketInfo = await this.pioneer.GetPortfolioBalances({ pubkeys: assetQuery }, forceRefresh ? { forceRefresh: true } : undefined);
5770
+ console.timeEnd("GetPortfolioBalances Response");
5771
+ console.log(`⏱️ [PERF] API completed in ${(performance.now() - apiStart).toFixed(0)}ms`);
5772
+ const enrichStart = performance.now();
5773
+ console.log(`⏱️ [PERF] Enriching ${marketInfo.data?.length || 0} balances...`);
5774
+ const balances = enrichBalancesWithAssetInfo(marketInfo.data, this.assetsMap, caipToNetworkId7);
5775
+ console.log(`⏱️ [PERF] Enrichment completed in ${(performance.now() - enrichStart).toFixed(0)}ms`);
5776
+ this.balances = balances;
5777
+ this.events.emit("SET_BALANCES", this.balances);
5778
+ const dashStart = performance.now();
5779
+ this.dashboard = this.buildDashboardFromBalances();
5780
+ this.events.emit("SET_DASHBOARD", this.dashboard);
5781
+ console.log(`⏱️ [PERF] Dashboard built in ${(performance.now() - dashStart).toFixed(0)}ms`);
5782
+ console.log(`\uD83D\uDCCA Dashboard: ${this.dashboard?.networks?.length || 0} networks, $${this.dashboard?.totalValueUsd?.toFixed(2) || "0.00"}`);
5783
+ console.log(`⏱️ [PERF] Total: ${(performance.now() - apiStart).toFixed(0)}ms`);
5784
+ return this.balances;
5576
5785
  } catch (e) {
5577
- console.error(tag6, "Error: ", e);
5786
+ console.error(tag6, "Error:", e?.message || e);
5578
5787
  throw e;
5579
5788
  }
5580
5789
  };
5581
- this.getBalances = async function(forceRefresh) {
5582
- const tag6 = `${TAG9} | getBalances | `;
5790
+ this.getBalances = async function(forceRefresh, caip) {
5791
+ const tag6 = `${TAG12} | getBalances | `;
5583
5792
  try {
5793
+ if (caip) {
5794
+ console.log(tag6, `\uD83C\uDFAF Refreshing single asset: ${caip}`);
5795
+ const networkId = caip.split("/")[0];
5796
+ console.log(tag6, `\uD83D\uDCCD Target network: ${networkId}`);
5797
+ const results = await this.getBalancesForNetworks([networkId], forceRefresh);
5798
+ return results.filter((b2) => b2.caip === caip || b2.networkId === networkId);
5799
+ }
5584
5800
  return await this.getBalancesForNetworks(this.blockchains, forceRefresh);
5585
5801
  } catch (e) {
5586
5802
  console.error(tag6, "Error in getBalances: ", e);
@@ -5588,7 +5804,7 @@ class SDK {
5588
5804
  }
5589
5805
  };
5590
5806
  this.getBalance = async function(networkId) {
5591
- const tag6 = `${TAG9} | getBalance | `;
5807
+ const tag6 = `${TAG12} | getBalance | `;
5592
5808
  try {
5593
5809
  const results = await this.getBalancesForNetworks([networkId]);
5594
5810
  const filtered = results.filter(async (b2) => b2.networkId === await networkIdToCaip2(networkId));
@@ -5599,7 +5815,7 @@ class SDK {
5599
5815
  }
5600
5816
  };
5601
5817
  this.getFees = async function(networkId) {
5602
- const tag6 = `${TAG9} | getFees | `;
5818
+ const tag6 = `${TAG12} | getFees | `;
5603
5819
  try {
5604
5820
  if (!this.pioneer) {
5605
5821
  throw new Error("Pioneer client not initialized. Call init() first.");
@@ -5614,7 +5830,7 @@ class SDK {
5614
5830
  return estimateTransactionFee(feeRate, unit, networkType, txSize);
5615
5831
  };
5616
5832
  this.getCharts = async function() {
5617
- const tag6 = `${TAG9} | getCharts | `;
5833
+ const tag6 = `${TAG12} | getCharts | `;
5618
5834
  try {
5619
5835
  console.log(tag6, "Fetching charts (portfolio + tokens + staking)...");
5620
5836
  const { getCharts: getChartsModular } = await Promise.resolve().then(() => (init_charts(), exports_charts));
@@ -5639,7 +5855,7 @@ class SDK {
5639
5855
  }
5640
5856
  };
5641
5857
  this.setContext = async (context) => {
5642
- const tag6 = `${TAG9} | setContext | `;
5858
+ const tag6 = `${TAG12} | setContext | `;
5643
5859
  try {
5644
5860
  if (!context)
5645
5861
  throw Error("context required!");
@@ -5652,7 +5868,7 @@ class SDK {
5652
5868
  }
5653
5869
  };
5654
5870
  this.setContextType = async (contextType) => {
5655
- const tag6 = `${TAG9} | setContextType | `;
5871
+ const tag6 = `${TAG12} | setContextType | `;
5656
5872
  try {
5657
5873
  if (!contextType)
5658
5874
  throw Error("contextType required!");
@@ -5665,7 +5881,7 @@ class SDK {
5665
5881
  }
5666
5882
  };
5667
5883
  this.refresh = async (forceRefresh) => {
5668
- const tag6 = `${TAG9} | refresh | `;
5884
+ const tag6 = `${TAG12} | refresh | `;
5669
5885
  try {
5670
5886
  if (forceRefresh) {
5671
5887
  console.log(tag6, "\uD83D\uDD04 Force refresh - fetching fresh balances from blockchain");
@@ -5680,7 +5896,7 @@ class SDK {
5680
5896
  }
5681
5897
  };
5682
5898
  this.setAssetContext = async function(asset) {
5683
- const tag6 = `${TAG9} | setAssetContext | `;
5899
+ const tag6 = `${TAG12} | setAssetContext | `;
5684
5900
  try {
5685
5901
  if (!asset) {
5686
5902
  this.assetContext = null;
@@ -5690,114 +5906,28 @@ class SDK {
5690
5906
  throw Error("Invalid Asset! missing caip!");
5691
5907
  if (!asset.networkId)
5692
5908
  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
- }
5909
+ validatePubkeysForNetwork(this.pubkeys, asset.networkId, asset.caip);
5910
+ const pubkeysForNetwork = findPubkeysForNetwork(this.pubkeys, asset.networkId);
5731
5911
  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
- }
5912
+ const freshPriceUsd = await fetchMarketPrice(this.pioneer, asset.caip);
5913
+ let assetInfo = resolveAssetInfo(this.assetsMap, assetData2, asset);
5766
5914
  const matchingBalances = this.balances.filter((b2) => b2.caip === asset.caip);
5767
5915
  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) {
5916
+ const priceValue = extractPriceFromBalances(matchingBalances);
5917
+ if (priceValue > 0) {
5778
5918
  console.log(tag6, "detected priceUsd from balance:", priceValue);
5779
5919
  assetInfo.priceUsd = priceValue;
5780
5920
  }
5781
5921
  }
5782
- if (freshPriceUsd && freshPriceUsd > 0) {
5922
+ if (freshPriceUsd > 0) {
5783
5923
  assetInfo.priceUsd = freshPriceUsd;
5784
5924
  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
- }
5925
+ const { totalBalance, totalValueUsd } = aggregateBalances(matchingBalances, asset.caip);
5795
5926
  assetInfo.balance = totalBalance.toString();
5796
5927
  assetInfo.valueUsd = totalValueUsd.toFixed(2);
5797
- console.log(tag6, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
5798
5928
  }
5799
5929
  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")));
5930
+ const assetPubkeys = filterPubkeysForAsset(this.pubkeys, asset.caip, caipToNetworkId7);
5801
5931
  const finalAssetContext = {
5802
5932
  ...assetInfo,
5803
5933
  ...asset,
@@ -5807,45 +5937,12 @@ class SDK {
5807
5937
  if ((!asset.priceUsd || asset.priceUsd === 0) && assetInfo.priceUsd && assetInfo.priceUsd > 0) {
5808
5938
  finalAssetContext.priceUsd = assetInfo.priceUsd;
5809
5939
  }
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");
5940
+ if (freshPriceUsd > 0) {
5941
+ updateBalancesWithPrice(assetBalances, freshPriceUsd);
5818
5942
  }
5819
5943
  this.assetContext = finalAssetContext;
5820
5944
  if (asset.isToken || asset.type === "token" || assetInfo.isToken || assetInfo.type === "token") {
5821
5945
  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
5946
  this.assetContext.nativeSymbol = nativeSymbol;
5850
5947
  if (nativeCaip) {
5851
5948
  const nativeBalance = this.balances.find((b2) => b2.caip === nativeCaip);
@@ -5879,7 +5976,7 @@ class SDK {
5879
5976
  }
5880
5977
  };
5881
5978
  this.setPubkeyContext = async function(pubkey) {
5882
- let tag6 = `${TAG9} | setPubkeyContext | `;
5979
+ let tag6 = `${TAG12} | setPubkeyContext | `;
5883
5980
  try {
5884
5981
  if (!pubkey)
5885
5982
  throw Error("pubkey is required");
@@ -5898,97 +5995,40 @@ class SDK {
5898
5995
  }
5899
5996
  };
5900
5997
  this.setOutboundAssetContext = async function(asset) {
5901
- const tag6 = `${TAG9} | setOutputAssetContext | `;
5998
+ const tag6 = `${TAG12} | setOutputAssetContext | `;
5902
5999
  try {
5903
- console.log(tag6, "0. asset: ", asset);
6000
+ console.log(tag6, "asset:", asset);
5904
6001
  if (!asset) {
5905
6002
  this.outboundAssetContext = null;
5906
6003
  return;
5907
6004
  }
5908
- console.log(tag6, "1 asset: ", asset);
5909
6005
  if (!asset.caip)
5910
6006
  throw Error("Invalid Asset! missing caip!");
5911
6007
  if (!asset.networkId)
5912
6008
  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
- });
6009
+ console.log(tag6, "networkId:", asset.networkId);
6010
+ const pubkey = findPubkeyForNetwork(this.pubkeys, asset.networkId);
5924
6011
  if (!pubkey)
5925
6012
  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
- }
6013
+ const freshPriceUsd = await fetchMarketPrice(this.pioneer, asset.caip);
6014
+ let assetInfo = resolveAssetInfo(this.assetsMap, assetData2, asset);
5955
6015
  const matchingBalances = this.balances.filter((b2) => b2.caip === asset.caip);
5956
6016
  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) {
6017
+ const priceValue = extractPriceFromBalances(matchingBalances);
6018
+ if (priceValue > 0) {
5967
6019
  console.log(tag6, "detected priceUsd from balance:", priceValue);
5968
6020
  assetInfo.priceUsd = priceValue;
5969
6021
  }
5970
6022
  }
5971
- if (freshPriceUsd && freshPriceUsd > 0) {
6023
+ if (freshPriceUsd > 0) {
5972
6024
  assetInfo.priceUsd = freshPriceUsd;
5973
6025
  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
- }
6026
+ const { totalBalance, totalValueUsd } = aggregateBalances(matchingBalances, asset.caip);
5984
6027
  assetInfo.balance = totalBalance.toString();
5985
6028
  assetInfo.valueUsd = totalValueUsd.toFixed(2);
5986
- console.log(tag6, `Aggregated balance: ${totalBalance} (${totalValueUsd.toFixed(2)} USD)`);
5987
6029
  }
5988
- console.log(tag6, "CHECKPOINT 1");
5989
6030
  this.outboundAssetContext = { ...assetInfo, ...asset, ...pubkey };
5990
- console.log(tag6, "CHECKPOINT 3");
5991
- console.log(tag6, "outboundAssetContext: assetInfo: ", assetInfo);
6031
+ console.log(tag6, "outboundAssetContext set:", this.outboundAssetContext.caip);
5992
6032
  if (asset.caip) {
5993
6033
  this.outboundBlockchainContext = caipToNetworkId7(asset.caip);
5994
6034
  } else if (asset.networkId) {
@@ -6004,28 +6044,12 @@ class SDK {
6004
6044
  };
6005
6045
  }
6006
6046
  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
- }
6047
+ const result = await this.pioneer.GetTokenAllowance(params);
6048
+ return result.data;
6017
6049
  };
6018
6050
  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
- }
6051
+ const result = await this.pioneer.BuildApprovalTransaction(params);
6052
+ return result.data;
6029
6053
  };
6030
6054
  }
6031
6055
  var src_default = SDK;