@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.cjs +673 -649
- package/dist/index.es.js +674 -650
- package/dist/index.js +674 -650
- package/package.json +2 -3
- package/src/index.ts +223 -915
- package/src/utils/fee-reserves.ts +162 -0
- package/src/utils/logger.ts +21 -0
- package/src/utils/network-helpers.ts +85 -0
- package/src/utils/path-discovery.ts +67 -0
- package/src/utils/portfolio-helpers.ts +209 -0
- package/src/utils/pubkey-management.ts +124 -0
- package/src/utils/pubkey-sync.ts +85 -0
- package/src/utils/sync-state.ts +93 -0
package/dist/index.es.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
|
-
|
|
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 {
|
|
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/
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4182
|
-
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
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 =
|
|
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 =
|
|
4351
|
-
|
|
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
|
|
4848
|
+
if (!validatePubkey(pubkey))
|
|
4367
4849
|
return false;
|
|
4368
|
-
|
|
4369
|
-
|
|
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 = `${
|
|
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 = `${
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 = `${
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 = `${
|
|
5109
|
+
const tag6 = `${TAG12} | sync | `;
|
|
5110
|
+
const log2 = logger;
|
|
4691
5111
|
try {
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
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
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 = `${
|
|
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
|
-
|
|
5024
|
-
|
|
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 = `${
|
|
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 = `${
|
|
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 =
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
console.log("\uD83D\uDD0D [DIAGNOSTIC]
|
|
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
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
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:
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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 = `${
|
|
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
|
-
|
|
5694
|
-
|
|
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
|
-
|
|
5733
|
-
|
|
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
|
-
|
|
5769
|
-
if (
|
|
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
|
|
5922
|
+
if (freshPriceUsd > 0) {
|
|
5783
5923
|
assetInfo.priceUsd = freshPriceUsd;
|
|
5784
5924
|
console.log(tag6, "✅ Using fresh market price:", freshPriceUsd);
|
|
5785
|
-
|
|
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
|
|
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
|
|
5811
|
-
|
|
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 = `${
|
|
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 = `${
|
|
5998
|
+
const tag6 = `${TAG12} | setOutputAssetContext | `;
|
|
5902
5999
|
try {
|
|
5903
|
-
console.log(tag6, "
|
|
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:
|
|
5914
|
-
|
|
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
|
-
|
|
5927
|
-
|
|
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
|
-
|
|
5958
|
-
if (
|
|
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
|
|
6023
|
+
if (freshPriceUsd > 0) {
|
|
5972
6024
|
assetInfo.priceUsd = freshPriceUsd;
|
|
5973
6025
|
console.log(tag6, "✅ Using fresh market price:", freshPriceUsd);
|
|
5974
|
-
|
|
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, "
|
|
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
|
|
6008
|
-
|
|
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
|
|
6020
|
-
|
|
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;
|