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