@pioneer-platform/pioneer-sdk 4.20.4 → 4.20.6
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 +146 -138
- package/dist/index.es.js +146 -138
- package/dist/index.js +146 -138
- package/package.json +6 -6
- package/src/index.ts +1 -187
- package/src/utils/sync-portfolio.ts +100 -0
- package/src/index.ts.tmp +0 -2580
- package/src/index.ts.tmp2 +0 -2584
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "highlander",
|
|
3
3
|
"name": "@pioneer-platform/pioneer-sdk",
|
|
4
|
-
"version": "4.20.
|
|
4
|
+
"version": "4.20.6",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@keepkey/keepkey-sdk": "^0.2.62",
|
|
7
7
|
"@pioneer-platform/loggerdog": "^8.11.0",
|
|
8
8
|
"@pioneer-platform/pioneer-caip": "^9.10.0",
|
|
9
|
-
"@pioneer-platform/pioneer-client": "^9.10.
|
|
9
|
+
"@pioneer-platform/pioneer-client": "^9.10.2",
|
|
10
10
|
"@pioneer-platform/pioneer-coins": "^9.11.0",
|
|
11
11
|
"@pioneer-platform/pioneer-discovery": "^0.8.0",
|
|
12
12
|
"@pioneer-platform/pioneer-events": "^8.11.0",
|
|
@@ -48,6 +48,8 @@
|
|
|
48
48
|
},
|
|
49
49
|
"react-native": "./src/index.ts",
|
|
50
50
|
"repository": "https://github.com/thorswap/SwapKit.git",
|
|
51
|
+
"type": "module",
|
|
52
|
+
"types": "./dist/index.d.ts",
|
|
51
53
|
"scripts": {
|
|
52
54
|
"build": "bash scripts/build.sh",
|
|
53
55
|
"build:watch": "nodemon --watch src --exec 'bun run build'",
|
|
@@ -55,7 +57,5 @@
|
|
|
55
57
|
"lint": "eslint ./ --ext .ts,.tsx --fix; tsc --noEmit",
|
|
56
58
|
"test": "echo 'vitest --run'",
|
|
57
59
|
"test:coverage": "echo 'vitest run --coverage'"
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
"types": "./dist/index.d.ts"
|
|
61
|
-
}
|
|
60
|
+
}
|
|
61
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -45,18 +45,6 @@ export interface PioneerSDKConfig {
|
|
|
45
45
|
forceLocalhost?: boolean;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
// Helper function to format time differences
|
|
49
|
-
function formatTime(durationMs) {
|
|
50
|
-
let seconds = Math.floor((durationMs / 1000) % 60);
|
|
51
|
-
let minutes = Math.floor((durationMs / (1000 * 60)) % 60);
|
|
52
|
-
let hours = Math.floor((durationMs / (1000 * 60 * 60)) % 24);
|
|
53
|
-
|
|
54
|
-
let formatted = '';
|
|
55
|
-
if (hours > 0) formatted += `${hours}h `;
|
|
56
|
-
if (minutes > 0 || hours > 0) formatted += `${minutes}m `;
|
|
57
|
-
formatted += `${seconds}s`;
|
|
58
|
-
return formatted.trim();
|
|
59
|
-
}
|
|
60
48
|
|
|
61
49
|
export class SDK {
|
|
62
50
|
public status: string;
|
|
@@ -582,181 +570,7 @@ export class SDK {
|
|
|
582
570
|
};
|
|
583
571
|
// Build dashboard from cached balances (no Pioneer API calls)
|
|
584
572
|
this.buildDashboardFromBalances = function () {
|
|
585
|
-
|
|
586
|
-
console.log(tag, '[DASHBOARD] Building dashboard from cached balances...');
|
|
587
|
-
|
|
588
|
-
const dashboardData: {
|
|
589
|
-
networks: {
|
|
590
|
-
networkId: string;
|
|
591
|
-
totalValueUsd: number;
|
|
592
|
-
gasAssetCaip: string | null;
|
|
593
|
-
gasAssetSymbol: string | null;
|
|
594
|
-
icon: string | null;
|
|
595
|
-
color: string | null;
|
|
596
|
-
totalNativeBalance: string;
|
|
597
|
-
}[];
|
|
598
|
-
totalValueUsd: number;
|
|
599
|
-
networkPercentages: { networkId: string; percentage: number }[];
|
|
600
|
-
} = {
|
|
601
|
-
networks: [],
|
|
602
|
-
totalValueUsd: 0,
|
|
603
|
-
networkPercentages: [],
|
|
604
|
-
};
|
|
605
|
-
|
|
606
|
-
let totalPortfolioValue = 0;
|
|
607
|
-
const networksTemp: {
|
|
608
|
-
networkId: string;
|
|
609
|
-
totalValueUsd: number;
|
|
610
|
-
gasAssetCaip: string | null;
|
|
611
|
-
gasAssetSymbol: string | null;
|
|
612
|
-
icon: string | null;
|
|
613
|
-
color: string | null;
|
|
614
|
-
totalNativeBalance: string;
|
|
615
|
-
}[] = [];
|
|
616
|
-
|
|
617
|
-
console.log(tag, 'this.balances: ', this.balances);
|
|
618
|
-
|
|
619
|
-
// Calculate totals for each blockchain
|
|
620
|
-
for (const blockchain of this.blockchains) {
|
|
621
|
-
const filteredBalances = this.balances.filter((b) => {
|
|
622
|
-
const networkId = caipToNetworkId(b.caip);
|
|
623
|
-
return (
|
|
624
|
-
networkId === blockchain ||
|
|
625
|
-
(blockchain === 'eip155:*' && networkId.startsWith('eip155:'))
|
|
626
|
-
);
|
|
627
|
-
});
|
|
628
|
-
|
|
629
|
-
// Deduplicate balances based on caip + pubkey combination
|
|
630
|
-
const balanceMap = new Map();
|
|
631
|
-
|
|
632
|
-
// Special handling for Bitcoin to work around API bug
|
|
633
|
-
const isBitcoin = blockchain.includes('bip122:000000000019d6689c085ae165831e93');
|
|
634
|
-
if (isBitcoin) {
|
|
635
|
-
console.log(tag, 'Bitcoin network detected - checking for duplicate balances');
|
|
636
|
-
// Group Bitcoin balances by value to detect duplicates
|
|
637
|
-
const bitcoinByValue = new Map();
|
|
638
|
-
filteredBalances.forEach((balance) => {
|
|
639
|
-
const valueKey = `${balance.balance}_${balance.valueUsd}`;
|
|
640
|
-
if (!bitcoinByValue.has(valueKey)) {
|
|
641
|
-
bitcoinByValue.set(valueKey, []);
|
|
642
|
-
}
|
|
643
|
-
bitcoinByValue.get(valueKey).push(balance);
|
|
644
|
-
});
|
|
645
|
-
|
|
646
|
-
// Check if all three address types have the same non-zero balance (API bug)
|
|
647
|
-
for (const [valueKey, balances] of bitcoinByValue.entries()) {
|
|
648
|
-
if (balances.length === 3 && parseFloat(balances[0].valueUsd || '0') > 0) {
|
|
649
|
-
console.log(
|
|
650
|
-
tag,
|
|
651
|
-
'BITCOIN API BUG DETECTED: All 3 address types have same balance, keeping only xpub',
|
|
652
|
-
);
|
|
653
|
-
// Keep only the xpub (or first one if no xpub)
|
|
654
|
-
const xpubBalance = balances.find((b) => b.pubkey?.startsWith('xpub')) || balances[0];
|
|
655
|
-
const key = `${xpubBalance.caip}_${xpubBalance.pubkey || 'default'}`;
|
|
656
|
-
balanceMap.set(key, xpubBalance);
|
|
657
|
-
} else {
|
|
658
|
-
// Add all balances normally
|
|
659
|
-
balances.forEach((balance) => {
|
|
660
|
-
const key = `${balance.caip}_${balance.pubkey || 'default'}`;
|
|
661
|
-
balanceMap.set(key, balance);
|
|
662
|
-
});
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
} else {
|
|
666
|
-
// Standard deduplication for non-Bitcoin networks
|
|
667
|
-
filteredBalances.forEach((balance) => {
|
|
668
|
-
const key = `${balance.caip}_${balance.pubkey || 'default'}`;
|
|
669
|
-
// Only keep the first occurrence or the one with higher value
|
|
670
|
-
if (
|
|
671
|
-
!balanceMap.has(key) ||
|
|
672
|
-
parseFloat(balance.valueUsd || '0') > parseFloat(balanceMap.get(key).valueUsd || '0')
|
|
673
|
-
) {
|
|
674
|
-
balanceMap.set(key, balance);
|
|
675
|
-
}
|
|
676
|
-
});
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
const networkBalances = Array.from(balanceMap.values());
|
|
680
|
-
|
|
681
|
-
// Ensure we're working with numbers for calculations
|
|
682
|
-
const networkTotal = networkBalances.reduce((sum, balance, idx) => {
|
|
683
|
-
const valueUsd =
|
|
684
|
-
typeof balance.valueUsd === 'string'
|
|
685
|
-
? parseFloat(balance.valueUsd)
|
|
686
|
-
: balance.valueUsd || 0;
|
|
687
|
-
|
|
688
|
-
if (blockchain.includes('bip122:000000000019d6689c085ae165831e93')) {
|
|
689
|
-
console.log(
|
|
690
|
-
tag,
|
|
691
|
-
`[BITCOIN DEBUG ${idx}] pubkey:`,
|
|
692
|
-
balance.pubkey?.substring(0, 10) + '...',
|
|
693
|
-
'| balance:',
|
|
694
|
-
balance.balance,
|
|
695
|
-
'| valueUsd:',
|
|
696
|
-
balance.valueUsd,
|
|
697
|
-
'→ parsed:',
|
|
698
|
-
valueUsd,
|
|
699
|
-
'| running sum:',
|
|
700
|
-
sum + valueUsd,
|
|
701
|
-
);
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
return sum + valueUsd;
|
|
705
|
-
}, 0);
|
|
706
|
-
|
|
707
|
-
// Get native asset for this blockchain
|
|
708
|
-
const nativeAssetCaip = networkIdToCaip(blockchain);
|
|
709
|
-
const gasAsset = networkBalances.find((b) => b.caip === nativeAssetCaip);
|
|
710
|
-
|
|
711
|
-
// Calculate total native balance (sum of all balances for the native asset)
|
|
712
|
-
const totalNativeBalance = networkBalances
|
|
713
|
-
.filter((b) => b.caip === nativeAssetCaip)
|
|
714
|
-
.reduce((sum, balance) => {
|
|
715
|
-
const balanceNum =
|
|
716
|
-
typeof balance.balance === 'string'
|
|
717
|
-
? parseFloat(balance.balance)
|
|
718
|
-
: balance.balance || 0;
|
|
719
|
-
return sum + balanceNum;
|
|
720
|
-
}, 0)
|
|
721
|
-
.toString();
|
|
722
|
-
|
|
723
|
-
// Get colors from assetMap since balances don't have them
|
|
724
|
-
const assetInfo = nativeAssetCaip ? this.assetsMap.get(nativeAssetCaip) : null;
|
|
725
|
-
|
|
726
|
-
networksTemp.push({
|
|
727
|
-
networkId: blockchain,
|
|
728
|
-
totalValueUsd: networkTotal,
|
|
729
|
-
gasAssetCaip: nativeAssetCaip || null,
|
|
730
|
-
gasAssetSymbol: gasAsset?.ticker || gasAsset?.symbol || assetInfo?.symbol || null,
|
|
731
|
-
icon: gasAsset?.icon || assetInfo?.icon || null,
|
|
732
|
-
color: gasAsset?.color || assetInfo?.color || null,
|
|
733
|
-
totalNativeBalance,
|
|
734
|
-
});
|
|
735
|
-
|
|
736
|
-
totalPortfolioValue += networkTotal;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
// Sort networks by USD value and assign to dashboard
|
|
740
|
-
dashboardData.networks = networksTemp.sort((a, b) => b.totalValueUsd - a.totalValueUsd);
|
|
741
|
-
dashboardData.totalValueUsd = totalPortfolioValue;
|
|
742
|
-
|
|
743
|
-
// Calculate network percentages for pie chart
|
|
744
|
-
dashboardData.networkPercentages = dashboardData.networks
|
|
745
|
-
.map((network) => ({
|
|
746
|
-
networkId: network.networkId,
|
|
747
|
-
percentage:
|
|
748
|
-
totalPortfolioValue > 0
|
|
749
|
-
? Number(((network.totalValueUsd / totalPortfolioValue) * 100).toFixed(2))
|
|
750
|
-
: 0,
|
|
751
|
-
}))
|
|
752
|
-
.filter((entry) => entry.percentage > 0); // Remove zero percentages
|
|
753
|
-
|
|
754
|
-
console.log(
|
|
755
|
-
`[FAST DASHBOARD] ✅ Built dashboard: ${
|
|
756
|
-
dashboardData.networks.length
|
|
757
|
-
} networks, $${totalPortfolioValue.toFixed(2)} total`,
|
|
758
|
-
);
|
|
759
|
-
return dashboardData;
|
|
573
|
+
return buildDashboardFromBalances(this.balances, this.blockchains, this.assetsMap);
|
|
760
574
|
};
|
|
761
575
|
|
|
762
576
|
this.syncMarket = async function () {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Portfolio synchronization logic
|
|
2
|
+
import { getPaths } from '@pioneer-platform/pioneer-coins';
|
|
3
|
+
|
|
4
|
+
const TAG = ' | sync-portfolio | ';
|
|
5
|
+
|
|
6
|
+
export async function syncPortfolio(context: {
|
|
7
|
+
blockchains: string[];
|
|
8
|
+
paths: any[];
|
|
9
|
+
pubkeys: any[];
|
|
10
|
+
balances: any[];
|
|
11
|
+
pioneer: any;
|
|
12
|
+
getPubkeys: () => Promise<any[]>;
|
|
13
|
+
getBalances: () => Promise<any[]>;
|
|
14
|
+
events: any;
|
|
15
|
+
}) {
|
|
16
|
+
const tag = `${TAG} | syncPortfolio | `;
|
|
17
|
+
try {
|
|
18
|
+
// Helper to check network match with EVM wildcard support (works for both paths and pubkeys)
|
|
19
|
+
const matchesNetwork = (item: any, networkId: string) => {
|
|
20
|
+
if (!item.networks || !Array.isArray(item.networks)) return false;
|
|
21
|
+
if (item.networks.includes(networkId)) return true;
|
|
22
|
+
if (networkId.startsWith('eip155:') && item.networks.includes('eip155:*')) return true;
|
|
23
|
+
return false;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
//at least 1 path per chain
|
|
27
|
+
await context.getPubkeys();
|
|
28
|
+
for (let i = 0; i < context.blockchains.length; i++) {
|
|
29
|
+
let networkId = context.blockchains[i];
|
|
30
|
+
if (networkId.indexOf('eip155:') >= 0) networkId = 'eip155:*';
|
|
31
|
+
|
|
32
|
+
let paths = context.paths.filter((path) => matchesNetwork(path, networkId));
|
|
33
|
+
if (paths.length === 0) {
|
|
34
|
+
//get paths for chain
|
|
35
|
+
const pathsForChain = getPaths([networkId]);
|
|
36
|
+
console.log(tag, 'pathsForChain: ', pathsForChain);
|
|
37
|
+
for (let j = 0; j < pathsForChain.length; j++) {
|
|
38
|
+
const path = pathsForChain[j];
|
|
39
|
+
if (!context.paths.find((p) => p.note === path.note)) {
|
|
40
|
+
context.paths.push(path);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
//get balances for paths
|
|
47
|
+
await context.getPubkeys();
|
|
48
|
+
console.log(tag, 'context.pubkeys: ', context.pubkeys);
|
|
49
|
+
await context.getBalances();
|
|
50
|
+
|
|
51
|
+
// Get market data with cache support
|
|
52
|
+
let allCaips = context.balances
|
|
53
|
+
.filter((b) => b && b.caip && typeof b.caip === 'string' && b.caip.trim().length > 0)
|
|
54
|
+
.map((b) => b.caip);
|
|
55
|
+
|
|
56
|
+
// Remove duplicates
|
|
57
|
+
allCaips = [...new Set(allCaips)];
|
|
58
|
+
|
|
59
|
+
// CRITICAL: Double-check all elements are valid strings after Set deduplication
|
|
60
|
+
allCaips = allCaips.filter(
|
|
61
|
+
(caip) =>
|
|
62
|
+
caip &&
|
|
63
|
+
typeof caip === 'string' &&
|
|
64
|
+
caip.trim().length > 0 &&
|
|
65
|
+
caip.includes(':'), // CAIP format always has a colon
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
if (allCaips && allCaips.length > 0) {
|
|
69
|
+
try {
|
|
70
|
+
let allPrices = await context.pioneer.GetMarketInfo(allCaips);
|
|
71
|
+
|
|
72
|
+
// Create a map of CAIP to price for easier lookup
|
|
73
|
+
const priceMap = {};
|
|
74
|
+
if (allPrices && allPrices.data) {
|
|
75
|
+
for (let i = 0; i < allCaips.length && i < allPrices.data.length; i++) {
|
|
76
|
+
priceMap[allCaips[i]] = allPrices.data[i];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Update each balance with the corresponding price and value
|
|
81
|
+
for (let balance of context.balances) {
|
|
82
|
+
if (balance && balance.caip && priceMap[balance.caip] !== undefined) {
|
|
83
|
+
balance.price = priceMap[balance.caip];
|
|
84
|
+
balance.priceUsd = priceMap[balance.caip];
|
|
85
|
+
balance.valueUsd = balance.price * (balance.balance || 0);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
} catch (apiError) {
|
|
89
|
+
console.error(tag, 'API error fetching market info:', apiError);
|
|
90
|
+
console.warn(tag, 'Continuing without market prices');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
context.events.emit('BALANCES_UPDATED', context.balances);
|
|
95
|
+
return true;
|
|
96
|
+
} catch (e) {
|
|
97
|
+
console.error(tag, 'e: ', e);
|
|
98
|
+
throw e;
|
|
99
|
+
}
|
|
100
|
+
}
|