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