@pioneer-platform/pioneer-sdk 8.15.41 → 8.15.44
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 +137 -4
- package/dist/index.es.js +137 -4
- package/dist/index.js +137 -4
- package/package.json +4 -4
- package/src/index.ts +212 -3
- package/src/utils/portfolio-helpers.ts +2 -2
package/dist/index.cjs
CHANGED
|
@@ -4264,8 +4264,8 @@ var EXPLORER_BASE_URLS = {
|
|
|
4264
4264
|
tx: "https://blockchair.com/bitcoin-cash/transaction/"
|
|
4265
4265
|
},
|
|
4266
4266
|
"bip122:000007d91d1254d60e2dd1ae58038307": {
|
|
4267
|
-
address: "https://
|
|
4268
|
-
tx: "https://
|
|
4267
|
+
address: "https://explorer.dash.org/insight/address/",
|
|
4268
|
+
tx: "https://explorer.dash.org/insight/tx/"
|
|
4269
4269
|
},
|
|
4270
4270
|
"bip122:4da631f2ac1bed857bd968c67c913978": {
|
|
4271
4271
|
address: "https://digiexplorer.info/address/",
|
|
@@ -4702,6 +4702,7 @@ class SDK {
|
|
|
4702
4702
|
assetsMap;
|
|
4703
4703
|
dashboard;
|
|
4704
4704
|
nfts;
|
|
4705
|
+
pendingTransactions;
|
|
4705
4706
|
events;
|
|
4706
4707
|
pairWallet;
|
|
4707
4708
|
setContext;
|
|
@@ -4781,6 +4782,7 @@ class SDK {
|
|
|
4781
4782
|
this.nodes = config.nodes || [];
|
|
4782
4783
|
this.charts = ["covalent", "zapper"];
|
|
4783
4784
|
this.nfts = [];
|
|
4785
|
+
this.pendingTransactions = [];
|
|
4784
4786
|
this.isPioneer = null;
|
|
4785
4787
|
this.pioneer = null;
|
|
4786
4788
|
this.context = "";
|
|
@@ -5188,6 +5190,29 @@ class SDK {
|
|
|
5188
5190
|
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
5189
5191
|
let unsignedTx = await txManager.transfer(sendPayload);
|
|
5190
5192
|
console.log(tag6, "unsignedTx: ", unsignedTx);
|
|
5193
|
+
if (this.assetContext && sendPayload) {
|
|
5194
|
+
this.assetContext.sendAmount = sendPayload.amount;
|
|
5195
|
+
this.assetContext.sendTo = sendPayload.to;
|
|
5196
|
+
this.assetContext.sendMemo = sendPayload.memo;
|
|
5197
|
+
let estimatedFee = "0";
|
|
5198
|
+
if (unsignedTx) {
|
|
5199
|
+
if (unsignedTx.fee) {
|
|
5200
|
+
estimatedFee = typeof unsignedTx.fee === "string" ? unsignedTx.fee : unsignedTx.fee.toString();
|
|
5201
|
+
} else if (unsignedTx.gasPrice && unsignedTx.gasLimit) {
|
|
5202
|
+
const gasPrice = parseFloat(unsignedTx.gasPrice);
|
|
5203
|
+
const gasLimit = parseFloat(unsignedTx.gasLimit);
|
|
5204
|
+
estimatedFee = (gasPrice * gasLimit / 1e9).toFixed(8);
|
|
5205
|
+
} else if (unsignedTx.fee && unsignedTx.fee.amount && Array.isArray(unsignedTx.fee.amount)) {
|
|
5206
|
+
estimatedFee = unsignedTx.fee.amount[0]?.amount || "0";
|
|
5207
|
+
}
|
|
5208
|
+
}
|
|
5209
|
+
this.assetContext.sendFee = estimatedFee;
|
|
5210
|
+
console.log(tag6, "\uD83D\uDCBE Stored transaction details for optimistic update:", {
|
|
5211
|
+
amount: this.assetContext.sendAmount,
|
|
5212
|
+
fee: this.assetContext.sendFee,
|
|
5213
|
+
to: this.assetContext.sendTo
|
|
5214
|
+
});
|
|
5215
|
+
}
|
|
5191
5216
|
return unsignedTx;
|
|
5192
5217
|
} catch (e) {
|
|
5193
5218
|
console.error(e);
|
|
@@ -5292,12 +5317,101 @@ class SDK {
|
|
|
5292
5317
|
serialized: signedTx
|
|
5293
5318
|
};
|
|
5294
5319
|
let txid = await txManager.broadcast(payload);
|
|
5320
|
+
if (txid && !txid.error) {
|
|
5321
|
+
const amount = this.assetContext?.sendAmount || "0";
|
|
5322
|
+
const fee = this.assetContext?.sendFee || "0";
|
|
5323
|
+
const to = this.assetContext?.sendTo || "";
|
|
5324
|
+
const from = this.pubkeyContext?.address || this.pubkeyContext?.master || "";
|
|
5325
|
+
if (amount !== "0" && parseFloat(amount) > 0) {
|
|
5326
|
+
console.log(tag6, "\uD83D\uDCB0 Performing optimistic balance update:", {
|
|
5327
|
+
caip,
|
|
5328
|
+
amount,
|
|
5329
|
+
fee,
|
|
5330
|
+
from,
|
|
5331
|
+
to
|
|
5332
|
+
});
|
|
5333
|
+
this.debitBalance(caip, amount, fee);
|
|
5334
|
+
this.addPendingTransaction({
|
|
5335
|
+
txid,
|
|
5336
|
+
caip,
|
|
5337
|
+
amount,
|
|
5338
|
+
to,
|
|
5339
|
+
from,
|
|
5340
|
+
fee,
|
|
5341
|
+
broadcastTime: Date.now(),
|
|
5342
|
+
status: "pending"
|
|
5343
|
+
});
|
|
5344
|
+
}
|
|
5345
|
+
}
|
|
5295
5346
|
return txid;
|
|
5296
5347
|
} catch (e) {
|
|
5297
5348
|
console.error(e);
|
|
5298
5349
|
throw e;
|
|
5299
5350
|
}
|
|
5300
5351
|
};
|
|
5352
|
+
this.addPendingTransaction = function(txData) {
|
|
5353
|
+
const tag6 = TAG12 + " | addPendingTransaction | ";
|
|
5354
|
+
console.log(tag6, "Adding pending transaction:", txData);
|
|
5355
|
+
this.pendingTransactions.unshift({
|
|
5356
|
+
...txData,
|
|
5357
|
+
status: txData.status || "pending",
|
|
5358
|
+
addedAt: Date.now()
|
|
5359
|
+
});
|
|
5360
|
+
if (this.pendingTransactions.length > 50) {
|
|
5361
|
+
this.pendingTransactions = this.pendingTransactions.slice(0, 50);
|
|
5362
|
+
}
|
|
5363
|
+
this.events.emit("PENDING_TX_ADDED", txData);
|
|
5364
|
+
this.events.emit("PENDING_TXS_UPDATED", this.pendingTransactions);
|
|
5365
|
+
console.log(tag6, `Pending transactions count: ${this.pendingTransactions.length}`);
|
|
5366
|
+
return txData;
|
|
5367
|
+
};
|
|
5368
|
+
this.debitBalance = function(caip, amount, fee = "0") {
|
|
5369
|
+
const tag6 = TAG12 + " | debitBalance | ";
|
|
5370
|
+
console.log(tag6, "Debiting balance:", { caip, amount, fee });
|
|
5371
|
+
const balanceIndex = this.balances.findIndex((b) => b.caip === caip);
|
|
5372
|
+
if (balanceIndex === -1) {
|
|
5373
|
+
console.warn(tag6, "Balance not found for CAIP:", caip);
|
|
5374
|
+
return null;
|
|
5375
|
+
}
|
|
5376
|
+
const currentBalance = this.balances[balanceIndex];
|
|
5377
|
+
const currentBalanceNum = parseFloat(currentBalance.balance || "0");
|
|
5378
|
+
const amountNum = parseFloat(amount);
|
|
5379
|
+
const feeNum = parseFloat(fee);
|
|
5380
|
+
const totalDebit = amountNum + feeNum;
|
|
5381
|
+
const newBalanceNum = currentBalanceNum - totalDebit;
|
|
5382
|
+
if (newBalanceNum < 0) {
|
|
5383
|
+
console.warn(tag6, "Cannot debit - would result in negative balance:", {
|
|
5384
|
+
current: currentBalanceNum,
|
|
5385
|
+
debit: totalDebit,
|
|
5386
|
+
result: newBalanceNum
|
|
5387
|
+
});
|
|
5388
|
+
return null;
|
|
5389
|
+
}
|
|
5390
|
+
const updatedBalance = {
|
|
5391
|
+
...currentBalance,
|
|
5392
|
+
balance: newBalanceNum.toFixed(8),
|
|
5393
|
+
valueUsd: newBalanceNum * (parseFloat(currentBalance.priceUsd) || 0),
|
|
5394
|
+
updated: Date.now(),
|
|
5395
|
+
optimistic: true,
|
|
5396
|
+
previousBalance: currentBalanceNum
|
|
5397
|
+
};
|
|
5398
|
+
this.balances[balanceIndex] = updatedBalance;
|
|
5399
|
+
console.log(tag6, "✅ Balance updated:", {
|
|
5400
|
+
previous: currentBalanceNum.toFixed(8),
|
|
5401
|
+
new: newBalanceNum.toFixed(8),
|
|
5402
|
+
deducted: totalDebit.toFixed(8)
|
|
5403
|
+
});
|
|
5404
|
+
this.events.emit("BALANCES_UPDATED", this.balances);
|
|
5405
|
+
this.events.emit("SET_BALANCES", this.balances);
|
|
5406
|
+
try {
|
|
5407
|
+
this.dashboard = this.buildDashboardFromBalances();
|
|
5408
|
+
this.events.emit("SET_DASHBOARD", this.dashboard);
|
|
5409
|
+
console.log(tag6, "✅ Dashboard rebuilt with updated balance");
|
|
5410
|
+
} catch (dashboardError) {
|
|
5411
|
+
console.error(tag6, "Error rebuilding dashboard:", dashboardError);
|
|
5412
|
+
}
|
|
5413
|
+
return updatedBalance;
|
|
5414
|
+
};
|
|
5301
5415
|
this.swap = async function(swapPayload) {
|
|
5302
5416
|
let tag6 = `${TAG12} | swap | `;
|
|
5303
5417
|
try {
|
|
@@ -5763,6 +5877,14 @@ class SDK {
|
|
|
5763
5877
|
const assetQuery = [];
|
|
5764
5878
|
for (const networkId of networkIds) {
|
|
5765
5879
|
const pubkeys = findPubkeysForNetwork(this.pubkeys, networkId, this.paths, tag6);
|
|
5880
|
+
console.log(`\uD83D\uDD0D [DIAGNOSTIC] ${networkId}: Found ${pubkeys.length} pubkeys`);
|
|
5881
|
+
if (networkId.startsWith("bip122:000000000019")) {
|
|
5882
|
+
console.log("\uD83D\uDD0D [BITCOIN DIAGNOSTIC] Bitcoin pubkeys:", pubkeys.map((p) => ({
|
|
5883
|
+
pubkey: p.pubkey?.substring(0, 20) + "...",
|
|
5884
|
+
networks: p.networks,
|
|
5885
|
+
symbol: p.symbol
|
|
5886
|
+
})));
|
|
5887
|
+
}
|
|
5766
5888
|
const caip = await import_pioneer_caip8.networkIdToCaip(networkId);
|
|
5767
5889
|
assetQuery.push(...buildAssetQuery(pubkeys, caip));
|
|
5768
5890
|
}
|
|
@@ -5777,7 +5899,18 @@ class SDK {
|
|
|
5777
5899
|
console.log(`⏱️ [PERF] Enriching ${marketInfo.data?.length || 0} balances...`);
|
|
5778
5900
|
const balances = enrichBalancesWithAssetInfo(marketInfo.data, this.assetsMap, import_pioneer_caip8.caipToNetworkId);
|
|
5779
5901
|
console.log(`⏱️ [PERF] Enrichment completed in ${(performance.now() - enrichStart).toFixed(0)}ms`);
|
|
5780
|
-
|
|
5902
|
+
console.log(tag6, `⚙️ Merging balances: ${balances.length} new + ${this.balances.length} existing`);
|
|
5903
|
+
const uniqueBalances = new Map([...this.balances, ...balances].map((balance) => [
|
|
5904
|
+
balance.identifier || `${balance.caip}:${balance.pubkey}`,
|
|
5905
|
+
balance
|
|
5906
|
+
]));
|
|
5907
|
+
const beforeCount = [...this.balances, ...balances].length;
|
|
5908
|
+
this.balances = Array.from(uniqueBalances.values());
|
|
5909
|
+
const duplicatesRemoved = beforeCount - this.balances.length;
|
|
5910
|
+
if (duplicatesRemoved > 0) {
|
|
5911
|
+
console.log(tag6, `\uD83D\uDD27 Removed ${duplicatesRemoved} duplicate balances`);
|
|
5912
|
+
}
|
|
5913
|
+
console.log(tag6, `✅ Final balance count: ${this.balances.length} unique balances`);
|
|
5781
5914
|
this.events.emit("SET_BALANCES", this.balances);
|
|
5782
5915
|
const dashStart = performance.now();
|
|
5783
5916
|
this.dashboard = this.buildDashboardFromBalances();
|
|
@@ -5954,7 +6087,7 @@ class SDK {
|
|
|
5954
6087
|
"bip122:12a765e31ffd4059bada1e25190f6e98": { address: "https://blockchair.com/litecoin/address/", tx: "https://blockchair.com/litecoin/transaction/" },
|
|
5955
6088
|
"bip122:00000000001a91e3dace36e2be3bf030": { address: "https://dogechain.info/address/", tx: "https://dogechain.info/tx/" },
|
|
5956
6089
|
"bip122:000000000000000000651ef99cb9fcbe": { address: "https://blockchair.com/bitcoin-cash/address/", tx: "https://blockchair.com/bitcoin-cash/transaction/" },
|
|
5957
|
-
"bip122:000007d91d1254d60e2dd1ae58038307": { address: "https://
|
|
6090
|
+
"bip122:000007d91d1254d60e2dd1ae58038307": { address: "https://explorer.dash.org/insight/address/", tx: "https://explorer.dash.org/insight/tx/" },
|
|
5958
6091
|
"bip122:4da631f2ac1bed857bd968c67c913978": { address: "https://digiexplorer.info/address/", tx: "https://digiexplorer.info/tx/" },
|
|
5959
6092
|
"bip122:00040fe8ec8471911baa1db1266ea15d": { address: "https://explorer.zcha.in/accounts/", tx: "https://explorer.zcha.in/transactions/" },
|
|
5960
6093
|
"cosmos:cosmoshub-4": { address: "https://www.mintscan.io/cosmos/address/", tx: "https://www.mintscan.io/cosmos/tx/" },
|
package/dist/index.es.js
CHANGED
|
@@ -4448,8 +4448,8 @@ var EXPLORER_BASE_URLS = {
|
|
|
4448
4448
|
tx: "https://blockchair.com/bitcoin-cash/transaction/"
|
|
4449
4449
|
},
|
|
4450
4450
|
"bip122:000007d91d1254d60e2dd1ae58038307": {
|
|
4451
|
-
address: "https://
|
|
4452
|
-
tx: "https://
|
|
4451
|
+
address: "https://explorer.dash.org/insight/address/",
|
|
4452
|
+
tx: "https://explorer.dash.org/insight/tx/"
|
|
4453
4453
|
},
|
|
4454
4454
|
"bip122:4da631f2ac1bed857bd968c67c913978": {
|
|
4455
4455
|
address: "https://digiexplorer.info/address/",
|
|
@@ -4886,6 +4886,7 @@ class SDK {
|
|
|
4886
4886
|
assetsMap;
|
|
4887
4887
|
dashboard;
|
|
4888
4888
|
nfts;
|
|
4889
|
+
pendingTransactions;
|
|
4889
4890
|
events;
|
|
4890
4891
|
pairWallet;
|
|
4891
4892
|
setContext;
|
|
@@ -4965,6 +4966,7 @@ class SDK {
|
|
|
4965
4966
|
this.nodes = config.nodes || [];
|
|
4966
4967
|
this.charts = ["covalent", "zapper"];
|
|
4967
4968
|
this.nfts = [];
|
|
4969
|
+
this.pendingTransactions = [];
|
|
4968
4970
|
this.isPioneer = null;
|
|
4969
4971
|
this.pioneer = null;
|
|
4970
4972
|
this.context = "";
|
|
@@ -5372,6 +5374,29 @@ class SDK {
|
|
|
5372
5374
|
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
5373
5375
|
let unsignedTx = await txManager.transfer(sendPayload);
|
|
5374
5376
|
console.log(tag6, "unsignedTx: ", unsignedTx);
|
|
5377
|
+
if (this.assetContext && sendPayload) {
|
|
5378
|
+
this.assetContext.sendAmount = sendPayload.amount;
|
|
5379
|
+
this.assetContext.sendTo = sendPayload.to;
|
|
5380
|
+
this.assetContext.sendMemo = sendPayload.memo;
|
|
5381
|
+
let estimatedFee = "0";
|
|
5382
|
+
if (unsignedTx) {
|
|
5383
|
+
if (unsignedTx.fee) {
|
|
5384
|
+
estimatedFee = typeof unsignedTx.fee === "string" ? unsignedTx.fee : unsignedTx.fee.toString();
|
|
5385
|
+
} else if (unsignedTx.gasPrice && unsignedTx.gasLimit) {
|
|
5386
|
+
const gasPrice = parseFloat(unsignedTx.gasPrice);
|
|
5387
|
+
const gasLimit = parseFloat(unsignedTx.gasLimit);
|
|
5388
|
+
estimatedFee = (gasPrice * gasLimit / 1e9).toFixed(8);
|
|
5389
|
+
} else if (unsignedTx.fee && unsignedTx.fee.amount && Array.isArray(unsignedTx.fee.amount)) {
|
|
5390
|
+
estimatedFee = unsignedTx.fee.amount[0]?.amount || "0";
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
this.assetContext.sendFee = estimatedFee;
|
|
5394
|
+
console.log(tag6, "\uD83D\uDCBE Stored transaction details for optimistic update:", {
|
|
5395
|
+
amount: this.assetContext.sendAmount,
|
|
5396
|
+
fee: this.assetContext.sendFee,
|
|
5397
|
+
to: this.assetContext.sendTo
|
|
5398
|
+
});
|
|
5399
|
+
}
|
|
5375
5400
|
return unsignedTx;
|
|
5376
5401
|
} catch (e) {
|
|
5377
5402
|
console.error(e);
|
|
@@ -5476,12 +5501,101 @@ class SDK {
|
|
|
5476
5501
|
serialized: signedTx
|
|
5477
5502
|
};
|
|
5478
5503
|
let txid = await txManager.broadcast(payload);
|
|
5504
|
+
if (txid && !txid.error) {
|
|
5505
|
+
const amount = this.assetContext?.sendAmount || "0";
|
|
5506
|
+
const fee = this.assetContext?.sendFee || "0";
|
|
5507
|
+
const to = this.assetContext?.sendTo || "";
|
|
5508
|
+
const from = this.pubkeyContext?.address || this.pubkeyContext?.master || "";
|
|
5509
|
+
if (amount !== "0" && parseFloat(amount) > 0) {
|
|
5510
|
+
console.log(tag6, "\uD83D\uDCB0 Performing optimistic balance update:", {
|
|
5511
|
+
caip,
|
|
5512
|
+
amount,
|
|
5513
|
+
fee,
|
|
5514
|
+
from,
|
|
5515
|
+
to
|
|
5516
|
+
});
|
|
5517
|
+
this.debitBalance(caip, amount, fee);
|
|
5518
|
+
this.addPendingTransaction({
|
|
5519
|
+
txid,
|
|
5520
|
+
caip,
|
|
5521
|
+
amount,
|
|
5522
|
+
to,
|
|
5523
|
+
from,
|
|
5524
|
+
fee,
|
|
5525
|
+
broadcastTime: Date.now(),
|
|
5526
|
+
status: "pending"
|
|
5527
|
+
});
|
|
5528
|
+
}
|
|
5529
|
+
}
|
|
5479
5530
|
return txid;
|
|
5480
5531
|
} catch (e) {
|
|
5481
5532
|
console.error(e);
|
|
5482
5533
|
throw e;
|
|
5483
5534
|
}
|
|
5484
5535
|
};
|
|
5536
|
+
this.addPendingTransaction = function(txData) {
|
|
5537
|
+
const tag6 = TAG12 + " | addPendingTransaction | ";
|
|
5538
|
+
console.log(tag6, "Adding pending transaction:", txData);
|
|
5539
|
+
this.pendingTransactions.unshift({
|
|
5540
|
+
...txData,
|
|
5541
|
+
status: txData.status || "pending",
|
|
5542
|
+
addedAt: Date.now()
|
|
5543
|
+
});
|
|
5544
|
+
if (this.pendingTransactions.length > 50) {
|
|
5545
|
+
this.pendingTransactions = this.pendingTransactions.slice(0, 50);
|
|
5546
|
+
}
|
|
5547
|
+
this.events.emit("PENDING_TX_ADDED", txData);
|
|
5548
|
+
this.events.emit("PENDING_TXS_UPDATED", this.pendingTransactions);
|
|
5549
|
+
console.log(tag6, `Pending transactions count: ${this.pendingTransactions.length}`);
|
|
5550
|
+
return txData;
|
|
5551
|
+
};
|
|
5552
|
+
this.debitBalance = function(caip, amount, fee = "0") {
|
|
5553
|
+
const tag6 = TAG12 + " | debitBalance | ";
|
|
5554
|
+
console.log(tag6, "Debiting balance:", { caip, amount, fee });
|
|
5555
|
+
const balanceIndex = this.balances.findIndex((b2) => b2.caip === caip);
|
|
5556
|
+
if (balanceIndex === -1) {
|
|
5557
|
+
console.warn(tag6, "Balance not found for CAIP:", caip);
|
|
5558
|
+
return null;
|
|
5559
|
+
}
|
|
5560
|
+
const currentBalance = this.balances[balanceIndex];
|
|
5561
|
+
const currentBalanceNum = parseFloat(currentBalance.balance || "0");
|
|
5562
|
+
const amountNum = parseFloat(amount);
|
|
5563
|
+
const feeNum = parseFloat(fee);
|
|
5564
|
+
const totalDebit = amountNum + feeNum;
|
|
5565
|
+
const newBalanceNum = currentBalanceNum - totalDebit;
|
|
5566
|
+
if (newBalanceNum < 0) {
|
|
5567
|
+
console.warn(tag6, "Cannot debit - would result in negative balance:", {
|
|
5568
|
+
current: currentBalanceNum,
|
|
5569
|
+
debit: totalDebit,
|
|
5570
|
+
result: newBalanceNum
|
|
5571
|
+
});
|
|
5572
|
+
return null;
|
|
5573
|
+
}
|
|
5574
|
+
const updatedBalance = {
|
|
5575
|
+
...currentBalance,
|
|
5576
|
+
balance: newBalanceNum.toFixed(8),
|
|
5577
|
+
valueUsd: newBalanceNum * (parseFloat(currentBalance.priceUsd) || 0),
|
|
5578
|
+
updated: Date.now(),
|
|
5579
|
+
optimistic: true,
|
|
5580
|
+
previousBalance: currentBalanceNum
|
|
5581
|
+
};
|
|
5582
|
+
this.balances[balanceIndex] = updatedBalance;
|
|
5583
|
+
console.log(tag6, "✅ Balance updated:", {
|
|
5584
|
+
previous: currentBalanceNum.toFixed(8),
|
|
5585
|
+
new: newBalanceNum.toFixed(8),
|
|
5586
|
+
deducted: totalDebit.toFixed(8)
|
|
5587
|
+
});
|
|
5588
|
+
this.events.emit("BALANCES_UPDATED", this.balances);
|
|
5589
|
+
this.events.emit("SET_BALANCES", this.balances);
|
|
5590
|
+
try {
|
|
5591
|
+
this.dashboard = this.buildDashboardFromBalances();
|
|
5592
|
+
this.events.emit("SET_DASHBOARD", this.dashboard);
|
|
5593
|
+
console.log(tag6, "✅ Dashboard rebuilt with updated balance");
|
|
5594
|
+
} catch (dashboardError) {
|
|
5595
|
+
console.error(tag6, "Error rebuilding dashboard:", dashboardError);
|
|
5596
|
+
}
|
|
5597
|
+
return updatedBalance;
|
|
5598
|
+
};
|
|
5485
5599
|
this.swap = async function(swapPayload) {
|
|
5486
5600
|
let tag6 = `${TAG12} | swap | `;
|
|
5487
5601
|
try {
|
|
@@ -5947,6 +6061,14 @@ class SDK {
|
|
|
5947
6061
|
const assetQuery = [];
|
|
5948
6062
|
for (const networkId of networkIds) {
|
|
5949
6063
|
const pubkeys = findPubkeysForNetwork(this.pubkeys, networkId, this.paths, tag6);
|
|
6064
|
+
console.log(`\uD83D\uDD0D [DIAGNOSTIC] ${networkId}: Found ${pubkeys.length} pubkeys`);
|
|
6065
|
+
if (networkId.startsWith("bip122:000000000019")) {
|
|
6066
|
+
console.log("\uD83D\uDD0D [BITCOIN DIAGNOSTIC] Bitcoin pubkeys:", pubkeys.map((p) => ({
|
|
6067
|
+
pubkey: p.pubkey?.substring(0, 20) + "...",
|
|
6068
|
+
networks: p.networks,
|
|
6069
|
+
symbol: p.symbol
|
|
6070
|
+
})));
|
|
6071
|
+
}
|
|
5950
6072
|
const caip = await networkIdToCaip2(networkId);
|
|
5951
6073
|
assetQuery.push(...buildAssetQuery(pubkeys, caip));
|
|
5952
6074
|
}
|
|
@@ -5961,7 +6083,18 @@ class SDK {
|
|
|
5961
6083
|
console.log(`⏱️ [PERF] Enriching ${marketInfo.data?.length || 0} balances...`);
|
|
5962
6084
|
const balances = enrichBalancesWithAssetInfo(marketInfo.data, this.assetsMap, caipToNetworkId7);
|
|
5963
6085
|
console.log(`⏱️ [PERF] Enrichment completed in ${(performance.now() - enrichStart).toFixed(0)}ms`);
|
|
5964
|
-
|
|
6086
|
+
console.log(tag6, `⚙️ Merging balances: ${balances.length} new + ${this.balances.length} existing`);
|
|
6087
|
+
const uniqueBalances = new Map([...this.balances, ...balances].map((balance) => [
|
|
6088
|
+
balance.identifier || `${balance.caip}:${balance.pubkey}`,
|
|
6089
|
+
balance
|
|
6090
|
+
]));
|
|
6091
|
+
const beforeCount = [...this.balances, ...balances].length;
|
|
6092
|
+
this.balances = Array.from(uniqueBalances.values());
|
|
6093
|
+
const duplicatesRemoved = beforeCount - this.balances.length;
|
|
6094
|
+
if (duplicatesRemoved > 0) {
|
|
6095
|
+
console.log(tag6, `\uD83D\uDD27 Removed ${duplicatesRemoved} duplicate balances`);
|
|
6096
|
+
}
|
|
6097
|
+
console.log(tag6, `✅ Final balance count: ${this.balances.length} unique balances`);
|
|
5965
6098
|
this.events.emit("SET_BALANCES", this.balances);
|
|
5966
6099
|
const dashStart = performance.now();
|
|
5967
6100
|
this.dashboard = this.buildDashboardFromBalances();
|
|
@@ -6138,7 +6271,7 @@ class SDK {
|
|
|
6138
6271
|
"bip122:12a765e31ffd4059bada1e25190f6e98": { address: "https://blockchair.com/litecoin/address/", tx: "https://blockchair.com/litecoin/transaction/" },
|
|
6139
6272
|
"bip122:00000000001a91e3dace36e2be3bf030": { address: "https://dogechain.info/address/", tx: "https://dogechain.info/tx/" },
|
|
6140
6273
|
"bip122:000000000000000000651ef99cb9fcbe": { address: "https://blockchair.com/bitcoin-cash/address/", tx: "https://blockchair.com/bitcoin-cash/transaction/" },
|
|
6141
|
-
"bip122:000007d91d1254d60e2dd1ae58038307": { address: "https://
|
|
6274
|
+
"bip122:000007d91d1254d60e2dd1ae58038307": { address: "https://explorer.dash.org/insight/address/", tx: "https://explorer.dash.org/insight/tx/" },
|
|
6142
6275
|
"bip122:4da631f2ac1bed857bd968c67c913978": { address: "https://digiexplorer.info/address/", tx: "https://digiexplorer.info/tx/" },
|
|
6143
6276
|
"bip122:00040fe8ec8471911baa1db1266ea15d": { address: "https://explorer.zcha.in/accounts/", tx: "https://explorer.zcha.in/transactions/" },
|
|
6144
6277
|
"cosmos:cosmoshub-4": { address: "https://www.mintscan.io/cosmos/address/", tx: "https://www.mintscan.io/cosmos/tx/" },
|
package/dist/index.js
CHANGED
|
@@ -4448,8 +4448,8 @@ var EXPLORER_BASE_URLS = {
|
|
|
4448
4448
|
tx: "https://blockchair.com/bitcoin-cash/transaction/"
|
|
4449
4449
|
},
|
|
4450
4450
|
"bip122:000007d91d1254d60e2dd1ae58038307": {
|
|
4451
|
-
address: "https://
|
|
4452
|
-
tx: "https://
|
|
4451
|
+
address: "https://explorer.dash.org/insight/address/",
|
|
4452
|
+
tx: "https://explorer.dash.org/insight/tx/"
|
|
4453
4453
|
},
|
|
4454
4454
|
"bip122:4da631f2ac1bed857bd968c67c913978": {
|
|
4455
4455
|
address: "https://digiexplorer.info/address/",
|
|
@@ -4886,6 +4886,7 @@ class SDK {
|
|
|
4886
4886
|
assetsMap;
|
|
4887
4887
|
dashboard;
|
|
4888
4888
|
nfts;
|
|
4889
|
+
pendingTransactions;
|
|
4889
4890
|
events;
|
|
4890
4891
|
pairWallet;
|
|
4891
4892
|
setContext;
|
|
@@ -4965,6 +4966,7 @@ class SDK {
|
|
|
4965
4966
|
this.nodes = config.nodes || [];
|
|
4966
4967
|
this.charts = ["covalent", "zapper"];
|
|
4967
4968
|
this.nfts = [];
|
|
4969
|
+
this.pendingTransactions = [];
|
|
4968
4970
|
this.isPioneer = null;
|
|
4969
4971
|
this.pioneer = null;
|
|
4970
4972
|
this.context = "";
|
|
@@ -5372,6 +5374,29 @@ class SDK {
|
|
|
5372
5374
|
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
5373
5375
|
let unsignedTx = await txManager.transfer(sendPayload);
|
|
5374
5376
|
console.log(tag6, "unsignedTx: ", unsignedTx);
|
|
5377
|
+
if (this.assetContext && sendPayload) {
|
|
5378
|
+
this.assetContext.sendAmount = sendPayload.amount;
|
|
5379
|
+
this.assetContext.sendTo = sendPayload.to;
|
|
5380
|
+
this.assetContext.sendMemo = sendPayload.memo;
|
|
5381
|
+
let estimatedFee = "0";
|
|
5382
|
+
if (unsignedTx) {
|
|
5383
|
+
if (unsignedTx.fee) {
|
|
5384
|
+
estimatedFee = typeof unsignedTx.fee === "string" ? unsignedTx.fee : unsignedTx.fee.toString();
|
|
5385
|
+
} else if (unsignedTx.gasPrice && unsignedTx.gasLimit) {
|
|
5386
|
+
const gasPrice = parseFloat(unsignedTx.gasPrice);
|
|
5387
|
+
const gasLimit = parseFloat(unsignedTx.gasLimit);
|
|
5388
|
+
estimatedFee = (gasPrice * gasLimit / 1e9).toFixed(8);
|
|
5389
|
+
} else if (unsignedTx.fee && unsignedTx.fee.amount && Array.isArray(unsignedTx.fee.amount)) {
|
|
5390
|
+
estimatedFee = unsignedTx.fee.amount[0]?.amount || "0";
|
|
5391
|
+
}
|
|
5392
|
+
}
|
|
5393
|
+
this.assetContext.sendFee = estimatedFee;
|
|
5394
|
+
console.log(tag6, "\uD83D\uDCBE Stored transaction details for optimistic update:", {
|
|
5395
|
+
amount: this.assetContext.sendAmount,
|
|
5396
|
+
fee: this.assetContext.sendFee,
|
|
5397
|
+
to: this.assetContext.sendTo
|
|
5398
|
+
});
|
|
5399
|
+
}
|
|
5375
5400
|
return unsignedTx;
|
|
5376
5401
|
} catch (e) {
|
|
5377
5402
|
console.error(e);
|
|
@@ -5476,12 +5501,101 @@ class SDK {
|
|
|
5476
5501
|
serialized: signedTx
|
|
5477
5502
|
};
|
|
5478
5503
|
let txid = await txManager.broadcast(payload);
|
|
5504
|
+
if (txid && !txid.error) {
|
|
5505
|
+
const amount = this.assetContext?.sendAmount || "0";
|
|
5506
|
+
const fee = this.assetContext?.sendFee || "0";
|
|
5507
|
+
const to = this.assetContext?.sendTo || "";
|
|
5508
|
+
const from = this.pubkeyContext?.address || this.pubkeyContext?.master || "";
|
|
5509
|
+
if (amount !== "0" && parseFloat(amount) > 0) {
|
|
5510
|
+
console.log(tag6, "\uD83D\uDCB0 Performing optimistic balance update:", {
|
|
5511
|
+
caip,
|
|
5512
|
+
amount,
|
|
5513
|
+
fee,
|
|
5514
|
+
from,
|
|
5515
|
+
to
|
|
5516
|
+
});
|
|
5517
|
+
this.debitBalance(caip, amount, fee);
|
|
5518
|
+
this.addPendingTransaction({
|
|
5519
|
+
txid,
|
|
5520
|
+
caip,
|
|
5521
|
+
amount,
|
|
5522
|
+
to,
|
|
5523
|
+
from,
|
|
5524
|
+
fee,
|
|
5525
|
+
broadcastTime: Date.now(),
|
|
5526
|
+
status: "pending"
|
|
5527
|
+
});
|
|
5528
|
+
}
|
|
5529
|
+
}
|
|
5479
5530
|
return txid;
|
|
5480
5531
|
} catch (e) {
|
|
5481
5532
|
console.error(e);
|
|
5482
5533
|
throw e;
|
|
5483
5534
|
}
|
|
5484
5535
|
};
|
|
5536
|
+
this.addPendingTransaction = function(txData) {
|
|
5537
|
+
const tag6 = TAG12 + " | addPendingTransaction | ";
|
|
5538
|
+
console.log(tag6, "Adding pending transaction:", txData);
|
|
5539
|
+
this.pendingTransactions.unshift({
|
|
5540
|
+
...txData,
|
|
5541
|
+
status: txData.status || "pending",
|
|
5542
|
+
addedAt: Date.now()
|
|
5543
|
+
});
|
|
5544
|
+
if (this.pendingTransactions.length > 50) {
|
|
5545
|
+
this.pendingTransactions = this.pendingTransactions.slice(0, 50);
|
|
5546
|
+
}
|
|
5547
|
+
this.events.emit("PENDING_TX_ADDED", txData);
|
|
5548
|
+
this.events.emit("PENDING_TXS_UPDATED", this.pendingTransactions);
|
|
5549
|
+
console.log(tag6, `Pending transactions count: ${this.pendingTransactions.length}`);
|
|
5550
|
+
return txData;
|
|
5551
|
+
};
|
|
5552
|
+
this.debitBalance = function(caip, amount, fee = "0") {
|
|
5553
|
+
const tag6 = TAG12 + " | debitBalance | ";
|
|
5554
|
+
console.log(tag6, "Debiting balance:", { caip, amount, fee });
|
|
5555
|
+
const balanceIndex = this.balances.findIndex((b2) => b2.caip === caip);
|
|
5556
|
+
if (balanceIndex === -1) {
|
|
5557
|
+
console.warn(tag6, "Balance not found for CAIP:", caip);
|
|
5558
|
+
return null;
|
|
5559
|
+
}
|
|
5560
|
+
const currentBalance = this.balances[balanceIndex];
|
|
5561
|
+
const currentBalanceNum = parseFloat(currentBalance.balance || "0");
|
|
5562
|
+
const amountNum = parseFloat(amount);
|
|
5563
|
+
const feeNum = parseFloat(fee);
|
|
5564
|
+
const totalDebit = amountNum + feeNum;
|
|
5565
|
+
const newBalanceNum = currentBalanceNum - totalDebit;
|
|
5566
|
+
if (newBalanceNum < 0) {
|
|
5567
|
+
console.warn(tag6, "Cannot debit - would result in negative balance:", {
|
|
5568
|
+
current: currentBalanceNum,
|
|
5569
|
+
debit: totalDebit,
|
|
5570
|
+
result: newBalanceNum
|
|
5571
|
+
});
|
|
5572
|
+
return null;
|
|
5573
|
+
}
|
|
5574
|
+
const updatedBalance = {
|
|
5575
|
+
...currentBalance,
|
|
5576
|
+
balance: newBalanceNum.toFixed(8),
|
|
5577
|
+
valueUsd: newBalanceNum * (parseFloat(currentBalance.priceUsd) || 0),
|
|
5578
|
+
updated: Date.now(),
|
|
5579
|
+
optimistic: true,
|
|
5580
|
+
previousBalance: currentBalanceNum
|
|
5581
|
+
};
|
|
5582
|
+
this.balances[balanceIndex] = updatedBalance;
|
|
5583
|
+
console.log(tag6, "✅ Balance updated:", {
|
|
5584
|
+
previous: currentBalanceNum.toFixed(8),
|
|
5585
|
+
new: newBalanceNum.toFixed(8),
|
|
5586
|
+
deducted: totalDebit.toFixed(8)
|
|
5587
|
+
});
|
|
5588
|
+
this.events.emit("BALANCES_UPDATED", this.balances);
|
|
5589
|
+
this.events.emit("SET_BALANCES", this.balances);
|
|
5590
|
+
try {
|
|
5591
|
+
this.dashboard = this.buildDashboardFromBalances();
|
|
5592
|
+
this.events.emit("SET_DASHBOARD", this.dashboard);
|
|
5593
|
+
console.log(tag6, "✅ Dashboard rebuilt with updated balance");
|
|
5594
|
+
} catch (dashboardError) {
|
|
5595
|
+
console.error(tag6, "Error rebuilding dashboard:", dashboardError);
|
|
5596
|
+
}
|
|
5597
|
+
return updatedBalance;
|
|
5598
|
+
};
|
|
5485
5599
|
this.swap = async function(swapPayload) {
|
|
5486
5600
|
let tag6 = `${TAG12} | swap | `;
|
|
5487
5601
|
try {
|
|
@@ -5947,6 +6061,14 @@ class SDK {
|
|
|
5947
6061
|
const assetQuery = [];
|
|
5948
6062
|
for (const networkId of networkIds) {
|
|
5949
6063
|
const pubkeys = findPubkeysForNetwork(this.pubkeys, networkId, this.paths, tag6);
|
|
6064
|
+
console.log(`\uD83D\uDD0D [DIAGNOSTIC] ${networkId}: Found ${pubkeys.length} pubkeys`);
|
|
6065
|
+
if (networkId.startsWith("bip122:000000000019")) {
|
|
6066
|
+
console.log("\uD83D\uDD0D [BITCOIN DIAGNOSTIC] Bitcoin pubkeys:", pubkeys.map((p) => ({
|
|
6067
|
+
pubkey: p.pubkey?.substring(0, 20) + "...",
|
|
6068
|
+
networks: p.networks,
|
|
6069
|
+
symbol: p.symbol
|
|
6070
|
+
})));
|
|
6071
|
+
}
|
|
5950
6072
|
const caip = await networkIdToCaip2(networkId);
|
|
5951
6073
|
assetQuery.push(...buildAssetQuery(pubkeys, caip));
|
|
5952
6074
|
}
|
|
@@ -5961,7 +6083,18 @@ class SDK {
|
|
|
5961
6083
|
console.log(`⏱️ [PERF] Enriching ${marketInfo.data?.length || 0} balances...`);
|
|
5962
6084
|
const balances = enrichBalancesWithAssetInfo(marketInfo.data, this.assetsMap, caipToNetworkId7);
|
|
5963
6085
|
console.log(`⏱️ [PERF] Enrichment completed in ${(performance.now() - enrichStart).toFixed(0)}ms`);
|
|
5964
|
-
|
|
6086
|
+
console.log(tag6, `⚙️ Merging balances: ${balances.length} new + ${this.balances.length} existing`);
|
|
6087
|
+
const uniqueBalances = new Map([...this.balances, ...balances].map((balance) => [
|
|
6088
|
+
balance.identifier || `${balance.caip}:${balance.pubkey}`,
|
|
6089
|
+
balance
|
|
6090
|
+
]));
|
|
6091
|
+
const beforeCount = [...this.balances, ...balances].length;
|
|
6092
|
+
this.balances = Array.from(uniqueBalances.values());
|
|
6093
|
+
const duplicatesRemoved = beforeCount - this.balances.length;
|
|
6094
|
+
if (duplicatesRemoved > 0) {
|
|
6095
|
+
console.log(tag6, `\uD83D\uDD27 Removed ${duplicatesRemoved} duplicate balances`);
|
|
6096
|
+
}
|
|
6097
|
+
console.log(tag6, `✅ Final balance count: ${this.balances.length} unique balances`);
|
|
5965
6098
|
this.events.emit("SET_BALANCES", this.balances);
|
|
5966
6099
|
const dashStart = performance.now();
|
|
5967
6100
|
this.dashboard = this.buildDashboardFromBalances();
|
|
@@ -6138,7 +6271,7 @@ class SDK {
|
|
|
6138
6271
|
"bip122:12a765e31ffd4059bada1e25190f6e98": { address: "https://blockchair.com/litecoin/address/", tx: "https://blockchair.com/litecoin/transaction/" },
|
|
6139
6272
|
"bip122:00000000001a91e3dace36e2be3bf030": { address: "https://dogechain.info/address/", tx: "https://dogechain.info/tx/" },
|
|
6140
6273
|
"bip122:000000000000000000651ef99cb9fcbe": { address: "https://blockchair.com/bitcoin-cash/address/", tx: "https://blockchair.com/bitcoin-cash/transaction/" },
|
|
6141
|
-
"bip122:000007d91d1254d60e2dd1ae58038307": { address: "https://
|
|
6274
|
+
"bip122:000007d91d1254d60e2dd1ae58038307": { address: "https://explorer.dash.org/insight/address/", tx: "https://explorer.dash.org/insight/tx/" },
|
|
6142
6275
|
"bip122:4da631f2ac1bed857bd968c67c913978": { address: "https://digiexplorer.info/address/", tx: "https://digiexplorer.info/tx/" },
|
|
6143
6276
|
"bip122:00040fe8ec8471911baa1db1266ea15d": { address: "https://explorer.zcha.in/accounts/", tx: "https://explorer.zcha.in/transactions/" },
|
|
6144
6277
|
"cosmos:cosmoshub-4": { address: "https://www.mintscan.io/cosmos/address/", tx: "https://www.mintscan.io/cosmos/tx/" },
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "highlander",
|
|
3
3
|
"name": "@pioneer-platform/pioneer-sdk",
|
|
4
|
-
"version": "8.15.
|
|
4
|
+
"version": "8.15.44",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@keepkey/keepkey-sdk": "^0.2.62",
|
|
7
|
-
"@pioneer-platform/pioneer-caip": "^9.10.
|
|
7
|
+
"@pioneer-platform/pioneer-caip": "^9.10.21",
|
|
8
8
|
"@pioneer-platform/pioneer-client": "^9.10.24",
|
|
9
|
-
"@pioneer-platform/pioneer-coins": "^9.11.
|
|
10
|
-
"@pioneer-platform/pioneer-discovery": "^8.15.
|
|
9
|
+
"@pioneer-platform/pioneer-coins": "^9.11.21",
|
|
10
|
+
"@pioneer-platform/pioneer-discovery": "^8.15.44",
|
|
11
11
|
"@pioneer-platform/pioneer-events": "^8.12.13",
|
|
12
12
|
"coinselect": "^3.1.13",
|
|
13
13
|
"eventemitter3": "^5.0.1",
|
package/src/index.ts
CHANGED
|
@@ -128,6 +128,7 @@ export class SDK {
|
|
|
128
128
|
public assetsMap: any;
|
|
129
129
|
public dashboard: any;
|
|
130
130
|
public nfts: any[];
|
|
131
|
+
public pendingTransactions: any[]; // Track recent/pending transactions
|
|
131
132
|
public events: any;
|
|
132
133
|
public pairWallet: (options: any) => Promise<any>;
|
|
133
134
|
public setContext: (context: string) => Promise<{ success: boolean }>;
|
|
@@ -236,6 +237,7 @@ export class SDK {
|
|
|
236
237
|
this.nodes = config.nodes || [];
|
|
237
238
|
this.charts = ['covalent', 'zapper'];
|
|
238
239
|
this.nfts = [];
|
|
240
|
+
this.pendingTransactions = []; // Initialize empty pending transactions array
|
|
239
241
|
this.isPioneer = null;
|
|
240
242
|
this.pioneer = null;
|
|
241
243
|
this.context = '';
|
|
@@ -814,6 +816,46 @@ export class SDK {
|
|
|
814
816
|
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
815
817
|
let unsignedTx = await txManager.transfer(sendPayload);
|
|
816
818
|
console.log(tag, 'unsignedTx: ', unsignedTx);
|
|
819
|
+
|
|
820
|
+
// CRITICAL: Store transaction details in assetContext for optimistic balance update
|
|
821
|
+
// These will be used by broadcastTx to debit the balance immediately
|
|
822
|
+
if (this.assetContext && sendPayload) {
|
|
823
|
+
this.assetContext.sendAmount = sendPayload.amount;
|
|
824
|
+
this.assetContext.sendTo = sendPayload.to;
|
|
825
|
+
this.assetContext.sendMemo = sendPayload.memo;
|
|
826
|
+
|
|
827
|
+
// Extract fee from unsignedTx if available
|
|
828
|
+
// Different chains have different fee structures
|
|
829
|
+
let estimatedFee = '0';
|
|
830
|
+
if (unsignedTx) {
|
|
831
|
+
// UTXO chains
|
|
832
|
+
if (unsignedTx.fee) {
|
|
833
|
+
estimatedFee = typeof unsignedTx.fee === 'string'
|
|
834
|
+
? unsignedTx.fee
|
|
835
|
+
: unsignedTx.fee.toString();
|
|
836
|
+
}
|
|
837
|
+
// EVM chains
|
|
838
|
+
else if (unsignedTx.gasPrice && unsignedTx.gasLimit) {
|
|
839
|
+
const gasPrice = parseFloat(unsignedTx.gasPrice);
|
|
840
|
+
const gasLimit = parseFloat(unsignedTx.gasLimit);
|
|
841
|
+
// Convert from gwei to native token (rough estimate)
|
|
842
|
+
estimatedFee = ((gasPrice * gasLimit) / 1000000000).toFixed(8);
|
|
843
|
+
}
|
|
844
|
+
// Tendermint chains
|
|
845
|
+
else if (unsignedTx.fee && unsignedTx.fee.amount && Array.isArray(unsignedTx.fee.amount)) {
|
|
846
|
+
estimatedFee = unsignedTx.fee.amount[0]?.amount || '0';
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
this.assetContext.sendFee = estimatedFee;
|
|
851
|
+
|
|
852
|
+
console.log(tag, '💾 Stored transaction details for optimistic update:', {
|
|
853
|
+
amount: this.assetContext.sendAmount,
|
|
854
|
+
fee: this.assetContext.sendFee,
|
|
855
|
+
to: this.assetContext.sendTo
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
|
|
817
859
|
return unsignedTx;
|
|
818
860
|
} catch (e) {
|
|
819
861
|
console.error(e);
|
|
@@ -943,12 +985,149 @@ export class SDK {
|
|
|
943
985
|
serialized: signedTx,
|
|
944
986
|
};
|
|
945
987
|
let txid = await txManager.broadcast(payload);
|
|
988
|
+
|
|
989
|
+
// OPTIMISTIC UPDATE: Debit balance immediately after successful broadcast
|
|
990
|
+
if (txid && !txid.error) {
|
|
991
|
+
// Extract transaction details from assetContext (set during buildTx)
|
|
992
|
+
const amount = this.assetContext?.sendAmount || '0';
|
|
993
|
+
const fee = this.assetContext?.sendFee || '0';
|
|
994
|
+
const to = this.assetContext?.sendTo || '';
|
|
995
|
+
const from = this.pubkeyContext?.address || this.pubkeyContext?.master || '';
|
|
996
|
+
|
|
997
|
+
// Only perform optimistic update if we have valid transaction details
|
|
998
|
+
if (amount !== '0' && parseFloat(amount) > 0) {
|
|
999
|
+
console.log(tag, '💰 Performing optimistic balance update:', {
|
|
1000
|
+
caip,
|
|
1001
|
+
amount,
|
|
1002
|
+
fee,
|
|
1003
|
+
from,
|
|
1004
|
+
to
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
// Debit the balance optimistically
|
|
1008
|
+
this.debitBalance(caip, amount, fee);
|
|
1009
|
+
|
|
1010
|
+
// Track pending transaction
|
|
1011
|
+
this.addPendingTransaction({
|
|
1012
|
+
txid,
|
|
1013
|
+
caip,
|
|
1014
|
+
amount,
|
|
1015
|
+
to,
|
|
1016
|
+
from,
|
|
1017
|
+
fee,
|
|
1018
|
+
broadcastTime: Date.now(),
|
|
1019
|
+
status: 'pending'
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
|
|
946
1024
|
return txid;
|
|
947
1025
|
} catch (e) {
|
|
948
1026
|
console.error(e);
|
|
949
1027
|
throw e;
|
|
950
1028
|
}
|
|
951
1029
|
};
|
|
1030
|
+
|
|
1031
|
+
// Add pending transaction to tracking array
|
|
1032
|
+
this.addPendingTransaction = function (txData: {
|
|
1033
|
+
txid: string;
|
|
1034
|
+
caip: string;
|
|
1035
|
+
amount: string;
|
|
1036
|
+
to: string;
|
|
1037
|
+
from: string;
|
|
1038
|
+
fee: string;
|
|
1039
|
+
broadcastTime: number;
|
|
1040
|
+
status: 'pending' | 'confirmed' | 'failed';
|
|
1041
|
+
}) {
|
|
1042
|
+
const tag = TAG + ' | addPendingTransaction | ';
|
|
1043
|
+
console.log(tag, 'Adding pending transaction:', txData);
|
|
1044
|
+
|
|
1045
|
+
// Add to pending transactions array (most recent first)
|
|
1046
|
+
this.pendingTransactions.unshift({
|
|
1047
|
+
...txData,
|
|
1048
|
+
status: txData.status || 'pending',
|
|
1049
|
+
addedAt: Date.now()
|
|
1050
|
+
});
|
|
1051
|
+
|
|
1052
|
+
// Keep only last 50 pending transactions to avoid memory bloat
|
|
1053
|
+
if (this.pendingTransactions.length > 50) {
|
|
1054
|
+
this.pendingTransactions = this.pendingTransactions.slice(0, 50);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
// Emit events for UI updates
|
|
1058
|
+
this.events.emit('PENDING_TX_ADDED', txData);
|
|
1059
|
+
this.events.emit('PENDING_TXS_UPDATED', this.pendingTransactions);
|
|
1060
|
+
|
|
1061
|
+
console.log(tag, `Pending transactions count: ${this.pendingTransactions.length}`);
|
|
1062
|
+
|
|
1063
|
+
return txData;
|
|
1064
|
+
};
|
|
1065
|
+
|
|
1066
|
+
// Optimistically debit balance after broadcast (before confirmation)
|
|
1067
|
+
this.debitBalance = function (caip: string, amount: string, fee: string = '0') {
|
|
1068
|
+
const tag = TAG + ' | debitBalance | ';
|
|
1069
|
+
console.log(tag, 'Debiting balance:', { caip, amount, fee });
|
|
1070
|
+
|
|
1071
|
+
// Find the balance entry for this asset
|
|
1072
|
+
const balanceIndex = this.balances.findIndex((b: any) => b.caip === caip);
|
|
1073
|
+
|
|
1074
|
+
if (balanceIndex === -1) {
|
|
1075
|
+
console.warn(tag, 'Balance not found for CAIP:', caip);
|
|
1076
|
+
return null;
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
const currentBalance = this.balances[balanceIndex];
|
|
1080
|
+
const currentBalanceNum = parseFloat(currentBalance.balance || '0');
|
|
1081
|
+
const amountNum = parseFloat(amount);
|
|
1082
|
+
const feeNum = parseFloat(fee);
|
|
1083
|
+
const totalDebit = amountNum + feeNum;
|
|
1084
|
+
|
|
1085
|
+
// Calculate new balance
|
|
1086
|
+
const newBalanceNum = currentBalanceNum - totalDebit;
|
|
1087
|
+
|
|
1088
|
+
// Safety check: don't allow negative balance
|
|
1089
|
+
if (newBalanceNum < 0) {
|
|
1090
|
+
console.warn(tag, 'Cannot debit - would result in negative balance:', {
|
|
1091
|
+
current: currentBalanceNum,
|
|
1092
|
+
debit: totalDebit,
|
|
1093
|
+
result: newBalanceNum
|
|
1094
|
+
});
|
|
1095
|
+
return null;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
// Update the balance with optimistic flag
|
|
1099
|
+
const updatedBalance = {
|
|
1100
|
+
...currentBalance,
|
|
1101
|
+
balance: newBalanceNum.toFixed(8),
|
|
1102
|
+
valueUsd: newBalanceNum * (parseFloat(currentBalance.priceUsd) || 0),
|
|
1103
|
+
updated: Date.now(),
|
|
1104
|
+
optimistic: true, // Mark as optimistic update (will be replaced by real data on next sync)
|
|
1105
|
+
previousBalance: currentBalanceNum // Store previous balance for rollback if needed
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
this.balances[balanceIndex] = updatedBalance;
|
|
1109
|
+
|
|
1110
|
+
console.log(tag, '✅ Balance updated:', {
|
|
1111
|
+
previous: currentBalanceNum.toFixed(8),
|
|
1112
|
+
new: newBalanceNum.toFixed(8),
|
|
1113
|
+
deducted: totalDebit.toFixed(8)
|
|
1114
|
+
});
|
|
1115
|
+
|
|
1116
|
+
// Emit balance update events
|
|
1117
|
+
this.events.emit('BALANCES_UPDATED', this.balances);
|
|
1118
|
+
this.events.emit('SET_BALANCES', this.balances);
|
|
1119
|
+
|
|
1120
|
+
// Rebuild dashboard with updated balances
|
|
1121
|
+
try {
|
|
1122
|
+
this.dashboard = this.buildDashboardFromBalances();
|
|
1123
|
+
this.events.emit('SET_DASHBOARD', this.dashboard);
|
|
1124
|
+
console.log(tag, '✅ Dashboard rebuilt with updated balance');
|
|
1125
|
+
} catch (dashboardError) {
|
|
1126
|
+
console.error(tag, 'Error rebuilding dashboard:', dashboardError);
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
return updatedBalance;
|
|
1130
|
+
};
|
|
952
1131
|
this.swap = async function (swapPayload) {
|
|
953
1132
|
let tag = `${TAG} | swap | `;
|
|
954
1133
|
try {
|
|
@@ -1622,6 +1801,14 @@ export class SDK {
|
|
|
1622
1801
|
const assetQuery: { caip: string; pubkey: string }[] = [];
|
|
1623
1802
|
for (const networkId of networkIds) {
|
|
1624
1803
|
const pubkeys = findPubkeysForNetwork(this.pubkeys, networkId, this.paths, tag);
|
|
1804
|
+
console.log(`🔍 [DIAGNOSTIC] ${networkId}: Found ${pubkeys.length} pubkeys`);
|
|
1805
|
+
if (networkId.startsWith('bip122:000000000019')) {
|
|
1806
|
+
console.log('🔍 [BITCOIN DIAGNOSTIC] Bitcoin pubkeys:', pubkeys.map((p: any) => ({
|
|
1807
|
+
pubkey: p.pubkey?.substring(0, 20) + '...',
|
|
1808
|
+
networks: p.networks,
|
|
1809
|
+
symbol: p.symbol
|
|
1810
|
+
})));
|
|
1811
|
+
}
|
|
1625
1812
|
const caip = await networkIdToCaip(networkId);
|
|
1626
1813
|
assetQuery.push(...buildAssetQuery(pubkeys, caip));
|
|
1627
1814
|
}
|
|
@@ -1653,8 +1840,30 @@ export class SDK {
|
|
|
1653
1840
|
|
|
1654
1841
|
console.log(`⏱️ [PERF] Enrichment completed in ${(performance.now() - enrichStart).toFixed(0)}ms`);
|
|
1655
1842
|
|
|
1656
|
-
//
|
|
1657
|
-
|
|
1843
|
+
// CRITICAL: Deduplicate balances BEFORE setting
|
|
1844
|
+
// Merge new balances with existing balances, deduplicating by identifier (caip:pubkey)
|
|
1845
|
+
console.log(tag, `⚙️ Merging balances: ${balances.length} new + ${this.balances.length} existing`);
|
|
1846
|
+
|
|
1847
|
+
// Create a Map with identifier as key to deduplicate
|
|
1848
|
+
// Put NEW balances LAST so they override stale cached data
|
|
1849
|
+
const uniqueBalances = new Map(
|
|
1850
|
+
[...this.balances, ...balances].map((balance: any) => [
|
|
1851
|
+
balance.identifier || `${balance.caip}:${balance.pubkey}`,
|
|
1852
|
+
balance
|
|
1853
|
+
])
|
|
1854
|
+
);
|
|
1855
|
+
|
|
1856
|
+
const beforeCount = [...this.balances, ...balances].length;
|
|
1857
|
+
this.balances = Array.from(uniqueBalances.values());
|
|
1858
|
+
const duplicatesRemoved = beforeCount - this.balances.length;
|
|
1859
|
+
|
|
1860
|
+
if (duplicatesRemoved > 0) {
|
|
1861
|
+
console.log(tag, `🔧 Removed ${duplicatesRemoved} duplicate balances`);
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
console.log(tag, `✅ Final balance count: ${this.balances.length} unique balances`);
|
|
1865
|
+
|
|
1866
|
+
// Emit events
|
|
1658
1867
|
this.events.emit('SET_BALANCES', this.balances);
|
|
1659
1868
|
|
|
1660
1869
|
// Build and emit dashboard
|
|
@@ -1902,7 +2111,7 @@ export class SDK {
|
|
|
1902
2111
|
'bip122:12a765e31ffd4059bada1e25190f6e98': { address: 'https://blockchair.com/litecoin/address/', tx: 'https://blockchair.com/litecoin/transaction/' },
|
|
1903
2112
|
'bip122:00000000001a91e3dace36e2be3bf030': { address: 'https://dogechain.info/address/', tx: 'https://dogechain.info/tx/' },
|
|
1904
2113
|
'bip122:000000000000000000651ef99cb9fcbe': { address: 'https://blockchair.com/bitcoin-cash/address/', tx: 'https://blockchair.com/bitcoin-cash/transaction/' },
|
|
1905
|
-
'bip122:000007d91d1254d60e2dd1ae58038307': { address: 'https://
|
|
2114
|
+
'bip122:000007d91d1254d60e2dd1ae58038307': { address: 'https://explorer.dash.org/insight/address/', tx: 'https://explorer.dash.org/insight/tx/' },
|
|
1906
2115
|
'bip122:4da631f2ac1bed857bd968c67c913978': { address: 'https://digiexplorer.info/address/', tx: 'https://digiexplorer.info/tx/' },
|
|
1907
2116
|
'bip122:00040fe8ec8471911baa1db1266ea15d': { address: 'https://explorer.zcha.in/accounts/', tx: 'https://explorer.zcha.in/transactions/' },
|
|
1908
2117
|
'cosmos:cosmoshub-4': { address: 'https://www.mintscan.io/cosmos/address/', tx: 'https://www.mintscan.io/cosmos/tx/' },
|
|
@@ -57,8 +57,8 @@ const EXPLORER_BASE_URLS: Record<string, { address: string; tx: string }> = {
|
|
|
57
57
|
},
|
|
58
58
|
// Dash
|
|
59
59
|
'bip122:000007d91d1254d60e2dd1ae58038307': {
|
|
60
|
-
address: 'https://
|
|
61
|
-
tx: 'https://
|
|
60
|
+
address: 'https://explorer.dash.org/insight/address/',
|
|
61
|
+
tx: 'https://explorer.dash.org/insight/tx/'
|
|
62
62
|
},
|
|
63
63
|
// DigiByte
|
|
64
64
|
'bip122:4da631f2ac1bed857bd968c67c913978': {
|