@pioneer-platform/pioneer-sdk 4.20.3 → 4.20.5

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/src/index.ts CHANGED
@@ -15,73 +15,13 @@ import { TransactionManager } from './TransactionManager.js';
15
15
  import { createUnsignedTendermintTx } from './txbuilder/createUnsignedTendermintTx.js';
16
16
  import { createUnsignedStakingTx, type StakingTxParams } from './txbuilder/createUnsignedStakingTx.js';
17
17
  import { getFees, estimateTransactionFee, type NormalizedFeeRates, type FeeEstimate } from './fees/index.js';
18
+ // Utils
19
+ import { detectKkApiAvailability } from './utils/kkapi-detection.js';
20
+ import { formatTime } from './utils/format-time.js';
21
+ import { buildDashboardFromBalances } from './utils/build-dashboard.js';
18
22
 
19
23
  const TAG = ' | Pioneer-sdk | ';
20
24
 
21
- // Utility function to detect if kkapi is available with smart environment detection
22
- async function detectKkApiAvailability(forceLocalhost?: boolean): Promise<{
23
- isAvailable: boolean;
24
- baseUrl: string;
25
- basePath: string;
26
- }> {
27
- const tag = `${TAG} | detectKkApiAvailability | `;
28
-
29
- try {
30
- // Smart detection: Check environment (Tauri, browser, or Node.js)
31
- const isTauri = typeof window !== 'undefined' && '__TAURI__' in window;
32
- const isBrowser = typeof window !== 'undefined';
33
- const isNodeJS = typeof process !== 'undefined' && process.versions && process.versions.node;
34
- const isLocalhost = isBrowser && window.location.hostname === 'localhost';
35
-
36
- // If in Tauri, use kkapi:// (will be proxied by Tauri)
37
- if (isTauri) {
38
- return {
39
- isAvailable: true,
40
- baseUrl: 'kkapi://',
41
- basePath: 'kkapi://spec/swagger.json',
42
- };
43
- }
44
-
45
- // In Node.js test environment or localhost browser, test if localhost:1646 is available
46
- // Force localhost if flag is set
47
- const shouldTestLocalhost = forceLocalhost || isLocalhost || isNodeJS;
48
-
49
- if (shouldTestLocalhost) {
50
- const testEnv = isNodeJS ? 'Node.js test environment' : 'development browser';
51
- try {
52
- const httpResponse = await fetch('http://localhost:1646/api/v1/health', {
53
- method: 'GET',
54
- signal: AbortSignal.timeout(1000), // 1 second timeout for localhost
55
- });
56
-
57
- if (httpResponse.ok) {
58
- return {
59
- isAvailable: true,
60
- baseUrl: 'http://localhost:1646',
61
- basePath: 'http://localhost:1646/spec/swagger.json',
62
- };
63
- }
64
- } catch (httpError: any) {
65
- console.error('❌ [KKAPI DETECTION] HTTP localhost:1646 not available:', httpError.message);
66
- }
67
- }
68
-
69
- // Fallback for production non-Tauri or when vault server is not running
70
- console.warn('⚠️ [KKAPI DETECTION] Using fallback config (vault may not be available)');
71
- return {
72
- isAvailable: false,
73
- baseUrl: 'http://localhost:1646',
74
- basePath: 'http://localhost:1646/spec/swagger.json',
75
- };
76
- } catch (error) {
77
- console.error('❌ [KKAPI DETECTION] Error during detection:', error);
78
- return {
79
- isAvailable: false,
80
- baseUrl: 'http://localhost:1646',
81
- basePath: 'http://localhost:1646/spec/swagger.json',
82
- };
83
- }
84
- }
85
25
 
86
26
  export interface PioneerSDKConfig {
87
27
  appName: string;
@@ -105,18 +45,6 @@ export interface PioneerSDKConfig {
105
45
  forceLocalhost?: boolean;
106
46
  }
107
47
 
108
- // Helper function to format time differences
109
- function formatTime(durationMs) {
110
- let seconds = Math.floor((durationMs / 1000) % 60);
111
- let minutes = Math.floor((durationMs / (1000 * 60)) % 60);
112
- let hours = Math.floor((durationMs / (1000 * 60 * 60)) % 24);
113
-
114
- let formatted = '';
115
- if (hours > 0) formatted += `${hours}h `;
116
- if (minutes > 0 || hours > 0) formatted += `${minutes}m `;
117
- formatted += `${seconds}s`;
118
- return formatted.trim();
119
- }
120
48
 
121
49
  export class SDK {
122
50
  public status: string;
@@ -642,181 +570,7 @@ export class SDK {
642
570
  };
643
571
  // Build dashboard from cached balances (no Pioneer API calls)
644
572
  this.buildDashboardFromBalances = function () {
645
- const tag = `${TAG} | buildDashboardFromBalances | `;
646
- console.log(tag, '[DASHBOARD] Building dashboard from cached balances...');
647
-
648
- const dashboardData: {
649
- networks: {
650
- networkId: string;
651
- totalValueUsd: number;
652
- gasAssetCaip: string | null;
653
- gasAssetSymbol: string | null;
654
- icon: string | null;
655
- color: string | null;
656
- totalNativeBalance: string;
657
- }[];
658
- totalValueUsd: number;
659
- networkPercentages: { networkId: string; percentage: number }[];
660
- } = {
661
- networks: [],
662
- totalValueUsd: 0,
663
- networkPercentages: [],
664
- };
665
-
666
- let totalPortfolioValue = 0;
667
- const networksTemp: {
668
- networkId: string;
669
- totalValueUsd: number;
670
- gasAssetCaip: string | null;
671
- gasAssetSymbol: string | null;
672
- icon: string | null;
673
- color: string | null;
674
- totalNativeBalance: string;
675
- }[] = [];
676
-
677
- console.log(tag, 'this.balances: ', this.balances);
678
-
679
- // Calculate totals for each blockchain
680
- for (const blockchain of this.blockchains) {
681
- const filteredBalances = this.balances.filter((b) => {
682
- const networkId = caipToNetworkId(b.caip);
683
- return (
684
- networkId === blockchain ||
685
- (blockchain === 'eip155:*' && networkId.startsWith('eip155:'))
686
- );
687
- });
688
-
689
- // Deduplicate balances based on caip + pubkey combination
690
- const balanceMap = new Map();
691
-
692
- // Special handling for Bitcoin to work around API bug
693
- const isBitcoin = blockchain.includes('bip122:000000000019d6689c085ae165831e93');
694
- if (isBitcoin) {
695
- console.log(tag, 'Bitcoin network detected - checking for duplicate balances');
696
- // Group Bitcoin balances by value to detect duplicates
697
- const bitcoinByValue = new Map();
698
- filteredBalances.forEach((balance) => {
699
- const valueKey = `${balance.balance}_${balance.valueUsd}`;
700
- if (!bitcoinByValue.has(valueKey)) {
701
- bitcoinByValue.set(valueKey, []);
702
- }
703
- bitcoinByValue.get(valueKey).push(balance);
704
- });
705
-
706
- // Check if all three address types have the same non-zero balance (API bug)
707
- for (const [valueKey, balances] of bitcoinByValue.entries()) {
708
- if (balances.length === 3 && parseFloat(balances[0].valueUsd || '0') > 0) {
709
- console.log(
710
- tag,
711
- 'BITCOIN API BUG DETECTED: All 3 address types have same balance, keeping only xpub',
712
- );
713
- // Keep only the xpub (or first one if no xpub)
714
- const xpubBalance = balances.find((b) => b.pubkey?.startsWith('xpub')) || balances[0];
715
- const key = `${xpubBalance.caip}_${xpubBalance.pubkey || 'default'}`;
716
- balanceMap.set(key, xpubBalance);
717
- } else {
718
- // Add all balances normally
719
- balances.forEach((balance) => {
720
- const key = `${balance.caip}_${balance.pubkey || 'default'}`;
721
- balanceMap.set(key, balance);
722
- });
723
- }
724
- }
725
- } else {
726
- // Standard deduplication for non-Bitcoin networks
727
- filteredBalances.forEach((balance) => {
728
- const key = `${balance.caip}_${balance.pubkey || 'default'}`;
729
- // Only keep the first occurrence or the one with higher value
730
- if (
731
- !balanceMap.has(key) ||
732
- parseFloat(balance.valueUsd || '0') > parseFloat(balanceMap.get(key).valueUsd || '0')
733
- ) {
734
- balanceMap.set(key, balance);
735
- }
736
- });
737
- }
738
-
739
- const networkBalances = Array.from(balanceMap.values());
740
-
741
- // Ensure we're working with numbers for calculations
742
- const networkTotal = networkBalances.reduce((sum, balance, idx) => {
743
- const valueUsd =
744
- typeof balance.valueUsd === 'string'
745
- ? parseFloat(balance.valueUsd)
746
- : balance.valueUsd || 0;
747
-
748
- if (blockchain.includes('bip122:000000000019d6689c085ae165831e93')) {
749
- console.log(
750
- tag,
751
- `[BITCOIN DEBUG ${idx}] pubkey:`,
752
- balance.pubkey?.substring(0, 10) + '...',
753
- '| balance:',
754
- balance.balance,
755
- '| valueUsd:',
756
- balance.valueUsd,
757
- '→ parsed:',
758
- valueUsd,
759
- '| running sum:',
760
- sum + valueUsd,
761
- );
762
- }
763
-
764
- return sum + valueUsd;
765
- }, 0);
766
-
767
- // Get native asset for this blockchain
768
- const nativeAssetCaip = networkIdToCaip(blockchain);
769
- const gasAsset = networkBalances.find((b) => b.caip === nativeAssetCaip);
770
-
771
- // Calculate total native balance (sum of all balances for the native asset)
772
- const totalNativeBalance = networkBalances
773
- .filter((b) => b.caip === nativeAssetCaip)
774
- .reduce((sum, balance) => {
775
- const balanceNum =
776
- typeof balance.balance === 'string'
777
- ? parseFloat(balance.balance)
778
- : balance.balance || 0;
779
- return sum + balanceNum;
780
- }, 0)
781
- .toString();
782
-
783
- // Get colors from assetMap since balances don't have them
784
- const assetInfo = nativeAssetCaip ? this.assetsMap.get(nativeAssetCaip) : null;
785
-
786
- networksTemp.push({
787
- networkId: blockchain,
788
- totalValueUsd: networkTotal,
789
- gasAssetCaip: nativeAssetCaip || null,
790
- gasAssetSymbol: gasAsset?.ticker || gasAsset?.symbol || assetInfo?.symbol || null,
791
- icon: gasAsset?.icon || assetInfo?.icon || null,
792
- color: gasAsset?.color || assetInfo?.color || null,
793
- totalNativeBalance,
794
- });
795
-
796
- totalPortfolioValue += networkTotal;
797
- }
798
-
799
- // Sort networks by USD value and assign to dashboard
800
- dashboardData.networks = networksTemp.sort((a, b) => b.totalValueUsd - a.totalValueUsd);
801
- dashboardData.totalValueUsd = totalPortfolioValue;
802
-
803
- // Calculate network percentages for pie chart
804
- dashboardData.networkPercentages = dashboardData.networks
805
- .map((network) => ({
806
- networkId: network.networkId,
807
- percentage:
808
- totalPortfolioValue > 0
809
- ? Number(((network.totalValueUsd / totalPortfolioValue) * 100).toFixed(2))
810
- : 0,
811
- }))
812
- .filter((entry) => entry.percentage > 0); // Remove zero percentages
813
-
814
- console.log(
815
- `[FAST DASHBOARD] ✅ Built dashboard: ${
816
- dashboardData.networks.length
817
- } networks, $${totalPortfolioValue.toFixed(2)} total`,
818
- );
819
- return dashboardData;
573
+ return buildDashboardFromBalances(this.balances, this.blockchains, this.assetsMap);
820
574
  };
821
575
 
822
576
  this.syncMarket = async function () {