@pioneer-platform/pioneer-sdk 8.14.0 → 8.15.2
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 +802 -222
- package/dist/index.es.js +810 -222
- package/dist/index.js +810 -222
- package/package.json +2 -2
- package/src/fees/index.ts +49 -1
- package/src/index.ts +67 -60
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "highlander",
|
|
3
3
|
"name": "@pioneer-platform/pioneer-sdk",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.15.2",
|
|
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
9
|
"@pioneer-platform/pioneer-client": "^9.10.10",
|
|
10
10
|
"@pioneer-platform/pioneer-coins": "^9.11.0",
|
|
11
|
-
"@pioneer-platform/pioneer-discovery": "^8.
|
|
11
|
+
"@pioneer-platform/pioneer-discovery": "^8.14.1",
|
|
12
12
|
"@pioneer-platform/pioneer-events": "^8.12.0",
|
|
13
13
|
"coinselect": "^3.1.13",
|
|
14
14
|
"eventemitter3": "^5.0.1",
|
package/src/fees/index.ts
CHANGED
|
@@ -89,13 +89,19 @@ export async function getFees(
|
|
|
89
89
|
try {
|
|
90
90
|
console.log(tag, `Fetching fees for network: ${networkId}`);
|
|
91
91
|
|
|
92
|
-
// For Cosmos chains, always use hardcoded fees
|
|
92
|
+
// For Cosmos chains, always use hardcoded fees (multiple Cosmos chains)
|
|
93
93
|
const networkType = getNetworkType(networkId);
|
|
94
94
|
if (networkType === 'COSMOS') {
|
|
95
95
|
console.log(tag, 'Using hardcoded fees for Cosmos network:', networkId);
|
|
96
96
|
return getCosmosFees(networkId);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
// Hardcode XRP fees (fixed fee model)
|
|
100
|
+
if (networkId === 'ripple:4109c6f2045fc7eff4cde8f9905d19c2') {
|
|
101
|
+
console.log(tag, 'Using hardcoded fees for Ripple: 0.00001 XRP');
|
|
102
|
+
return getRippleFees(networkId);
|
|
103
|
+
}
|
|
104
|
+
|
|
99
105
|
// Hardcode DOGE fees at 10 sat/byte (API and Blockbook often unreliable for DOGE)
|
|
100
106
|
if (networkId === 'bip122:00000000001a91e3dace36e2be3bf030') {
|
|
101
107
|
console.log(tag, 'Using hardcoded fees for Dogecoin: 10 sat/byte');
|
|
@@ -535,6 +541,48 @@ function getCosmosFees(networkId: string): NormalizedFeeRates {
|
|
|
535
541
|
};
|
|
536
542
|
}
|
|
537
543
|
|
|
544
|
+
/**
|
|
545
|
+
* Get hardcoded Ripple fees
|
|
546
|
+
* XRP uses a fixed fee model with very low transaction costs
|
|
547
|
+
*/
|
|
548
|
+
function getRippleFees(networkId: string): NormalizedFeeRates {
|
|
549
|
+
const networkName = getNetworkName(networkId);
|
|
550
|
+
|
|
551
|
+
// XRP standard fee is 0.00001 XRP (10 drops)
|
|
552
|
+
// This is sufficient for most transactions and is the network minimum
|
|
553
|
+
const standardFee = '0.00001';
|
|
554
|
+
|
|
555
|
+
return {
|
|
556
|
+
slow: {
|
|
557
|
+
label: 'Standard',
|
|
558
|
+
value: standardFee,
|
|
559
|
+
unit: 'XRP',
|
|
560
|
+
description: `Fixed fee for ${networkName}. XRP uses a deterministic fee model.`,
|
|
561
|
+
estimatedTime: '~4 seconds',
|
|
562
|
+
priority: 'low',
|
|
563
|
+
},
|
|
564
|
+
average: {
|
|
565
|
+
label: 'Standard',
|
|
566
|
+
value: standardFee,
|
|
567
|
+
unit: 'XRP',
|
|
568
|
+
description: `Fixed fee for ${networkName}. XRP uses a deterministic fee model.`,
|
|
569
|
+
estimatedTime: '~4 seconds',
|
|
570
|
+
priority: 'medium',
|
|
571
|
+
},
|
|
572
|
+
fastest: {
|
|
573
|
+
label: 'Standard',
|
|
574
|
+
value: standardFee,
|
|
575
|
+
unit: 'XRP',
|
|
576
|
+
description: `Fixed fee for ${networkName}. XRP uses a deterministic fee model.`,
|
|
577
|
+
estimatedTime: '~4 seconds',
|
|
578
|
+
priority: 'high',
|
|
579
|
+
},
|
|
580
|
+
networkId,
|
|
581
|
+
networkType: 'RIPPLE',
|
|
582
|
+
raw: { hardcoded: true, fee: standardFee, unit: 'XRP' },
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
538
586
|
/**
|
|
539
587
|
* Get fallback fees when API fails
|
|
540
588
|
*/
|
package/src/index.ts
CHANGED
|
@@ -782,6 +782,13 @@ export class SDK {
|
|
|
782
782
|
this.buildDashboardFromBalances = function () {
|
|
783
783
|
return buildDashboardFromBalances(this.balances, this.blockchains, this.assetsMap);
|
|
784
784
|
};
|
|
785
|
+
// ✅ PHASE 3: Infer asset type from CAIP structure (fallback helper)
|
|
786
|
+
this.inferTypeFromCaip = function (caip: string): string {
|
|
787
|
+
if (caip.includes('/slip44:')) return 'native';
|
|
788
|
+
if (caip.includes('/erc20:') || caip.includes('/bep20:') || caip.includes('/spl:')) return 'token';
|
|
789
|
+
if (caip.includes('/denom:')) return 'native'; // Cosmos denoms
|
|
790
|
+
return 'unknown';
|
|
791
|
+
};
|
|
785
792
|
this.syncMarket = async function () {
|
|
786
793
|
return syncMarket(this.balances, this.pioneer);
|
|
787
794
|
};
|
|
@@ -1880,7 +1887,7 @@ export class SDK {
|
|
|
1880
1887
|
throw error;
|
|
1881
1888
|
}
|
|
1882
1889
|
};
|
|
1883
|
-
this.getBalancesForNetworks = async function (networkIds: string[]) {
|
|
1890
|
+
this.getBalancesForNetworks = async function (networkIds: string[], forceRefresh?: boolean) {
|
|
1884
1891
|
const tag = `${TAG} | getBalancesForNetworks | `;
|
|
1885
1892
|
try {
|
|
1886
1893
|
// Add defensive check for pioneer initialization
|
|
@@ -1893,6 +1900,11 @@ export class SDK {
|
|
|
1893
1900
|
throw new Error('Pioneer client not initialized. Call init() first.');
|
|
1894
1901
|
}
|
|
1895
1902
|
|
|
1903
|
+
// Log force refresh request
|
|
1904
|
+
if (forceRefresh) {
|
|
1905
|
+
console.log(tag, '🔄 Force refresh requested - bypassing balance cache');
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1896
1908
|
// DIAGNOSTIC: Log input
|
|
1897
1909
|
console.log('🔍 [DIAGNOSTIC] Input networks:', networkIds);
|
|
1898
1910
|
console.log('🔍 [DIAGNOSTIC] Total pubkeys:', this.pubkeys.length);
|
|
@@ -1987,7 +1999,11 @@ export class SDK {
|
|
|
1987
1999
|
|
|
1988
2000
|
try {
|
|
1989
2001
|
// Wrap assetQuery in object with pubkeys field (API expects { pubkeys: [...] })
|
|
1990
|
-
|
|
2002
|
+
// Pass forceRefresh as query parameter if provided
|
|
2003
|
+
let marketInfo = await this.pioneer.GetPortfolioBalances(
|
|
2004
|
+
{ pubkeys: assetQuery },
|
|
2005
|
+
forceRefresh ? { forceRefresh: true } : undefined
|
|
2006
|
+
);
|
|
1991
2007
|
const apiCallTime = performance.now() - apiCallStart;
|
|
1992
2008
|
console.timeEnd('GetPortfolioBalances Response Time');
|
|
1993
2009
|
console.log(`⏱️ [PERF] API call completed in ${apiCallTime.toFixed(0)}ms`);
|
|
@@ -2000,12 +2016,30 @@ export class SDK {
|
|
|
2000
2016
|
console.log(`⏱️ [PERF] Starting balance enrichment...`);
|
|
2001
2017
|
for (let balance of balances) {
|
|
2002
2018
|
const assetInfo = this.assetsMap.get(balance.caip.toLowerCase()) || this.assetsMap.get(balance.caip);
|
|
2003
|
-
|
|
2019
|
+
|
|
2020
|
+
// ✅ PHASE 3: Add fallback for missing asset metadata
|
|
2021
|
+
if (!assetInfo) {
|
|
2022
|
+
console.warn(`⚠️ [ENRICHMENT] Asset metadata missing for ${balance.caip}, using fallback enrichment`);
|
|
2023
|
+
|
|
2024
|
+
// Fallback: Use API-provided values or infer from CAIP
|
|
2025
|
+
const inferredType = this.inferTypeFromCaip(balance.caip);
|
|
2026
|
+
Object.assign(balance, {
|
|
2027
|
+
type: balance.type || inferredType,
|
|
2028
|
+
isNative: balance.isNative ?? (inferredType === 'native'),
|
|
2029
|
+
networkId: caipToNetworkId(balance.caip),
|
|
2030
|
+
icon: 'https://pioneers.dev/coins/unknown.png',
|
|
2031
|
+
identifier: `${balance.caip}:${balance.pubkey}`,
|
|
2032
|
+
updated: Date.now(),
|
|
2033
|
+
});
|
|
2034
|
+
continue;
|
|
2035
|
+
}
|
|
2004
2036
|
|
|
2005
2037
|
// Get color from mapping (fallback to assetInfo.color if it exists)
|
|
2006
2038
|
const color = ASSET_COLORS[balance.caip] || assetInfo.color;
|
|
2007
2039
|
|
|
2008
2040
|
Object.assign(balance, assetInfo, {
|
|
2041
|
+
type: balance.type || assetInfo.type, // ✅ PHASE 3: Prefer API type, fallback to assetInfo
|
|
2042
|
+
isNative: balance.isNative ?? assetInfo.isNative, // ✅ PHASE 3: Prefer API isNative
|
|
2009
2043
|
networkId: caipToNetworkId(balance.caip),
|
|
2010
2044
|
icon: assetInfo.icon || 'https://pioneers.dev/coins/etherum.png',
|
|
2011
2045
|
identifier: `${balance.caip}:${balance.pubkey}`,
|
|
@@ -2041,11 +2075,11 @@ export class SDK {
|
|
|
2041
2075
|
throw e;
|
|
2042
2076
|
}
|
|
2043
2077
|
};
|
|
2044
|
-
this.getBalances = async function () {
|
|
2078
|
+
this.getBalances = async function (forceRefresh?: boolean) {
|
|
2045
2079
|
const tag = `${TAG} | getBalances | `;
|
|
2046
2080
|
try {
|
|
2047
2081
|
// Simply call the shared function with all blockchains
|
|
2048
|
-
return await this.getBalancesForNetworks(this.blockchains);
|
|
2082
|
+
return await this.getBalancesForNetworks(this.blockchains, forceRefresh);
|
|
2049
2083
|
} catch (e) {
|
|
2050
2084
|
console.error(tag, 'Error in getBalances: ', e);
|
|
2051
2085
|
throw e;
|
|
@@ -2110,57 +2144,21 @@ export class SDK {
|
|
|
2110
2144
|
this.getCharts = async function () {
|
|
2111
2145
|
const tag = `${TAG} | getCharts | `;
|
|
2112
2146
|
try {
|
|
2113
|
-
console.log(tag, 'Fetching charts
|
|
2114
|
-
|
|
2115
|
-
//
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
const supportsNetwork = supportedNetworks.some((net: string) =>
|
|
2129
|
-
net === blockchain ||
|
|
2130
|
-
(net.endsWith(':*') && blockchain.startsWith(net.replace(':*', ':')))
|
|
2131
|
-
);
|
|
2132
|
-
|
|
2133
|
-
if (supportsNetwork) {
|
|
2134
|
-
// Build the CAIP for this combination
|
|
2135
|
-
let caip: string;
|
|
2136
|
-
if (blockchain.startsWith('eip155:')) {
|
|
2137
|
-
caip = `${blockchain}/slip44:60`;
|
|
2138
|
-
} else {
|
|
2139
|
-
caip = `${blockchain}/slip44:0`; // Fallback for non-EVM
|
|
2140
|
-
}
|
|
2141
|
-
|
|
2142
|
-
pubkeysForBatch.push({
|
|
2143
|
-
pubkey: address,
|
|
2144
|
-
caip: caip
|
|
2145
|
-
});
|
|
2146
|
-
}
|
|
2147
|
-
}
|
|
2148
|
-
}
|
|
2149
|
-
|
|
2150
|
-
console.log(tag, `Calling batch GetCharts with ${pubkeysForBatch.length} pubkeys`);
|
|
2151
|
-
|
|
2152
|
-
// Single batch call to get ALL charts data
|
|
2153
|
-
let newBalances = [];
|
|
2154
|
-
try {
|
|
2155
|
-
const chartsResponse = await this.pioneer.GetCharts({
|
|
2156
|
-
pubkeys: pubkeysForBatch
|
|
2157
|
-
});
|
|
2158
|
-
newBalances = chartsResponse?.data?.balances || [];
|
|
2159
|
-
console.log(tag, `Received ${newBalances.length} balances from batch endpoint`);
|
|
2160
|
-
} catch (chartsError: any) {
|
|
2161
|
-
// GetCharts API may not be available - gracefully continue without charts data
|
|
2162
|
-
console.warn(tag, `GetCharts API not available (${chartsError.message}), continuing without charts data`);
|
|
2163
|
-
}
|
|
2147
|
+
console.log(tag, 'Fetching charts (portfolio + tokens + staking)...');
|
|
2148
|
+
|
|
2149
|
+
// Use the NEW modular chart implementation
|
|
2150
|
+
// This calls /charts/portfolio (BLOCKING) which fetches tokens from Zapper/Unchained
|
|
2151
|
+
const { getCharts: getChartsModular } = await import('./charts');
|
|
2152
|
+
|
|
2153
|
+
// Call new implementation with all required parameters
|
|
2154
|
+
const newBalances = await getChartsModular(
|
|
2155
|
+
this.blockchains,
|
|
2156
|
+
this.pioneer,
|
|
2157
|
+
this.pubkeys,
|
|
2158
|
+
this.context
|
|
2159
|
+
);
|
|
2160
|
+
|
|
2161
|
+
console.log(tag, `Modular charts returned ${newBalances.length} balances (native + tokens + staking)`);
|
|
2164
2162
|
|
|
2165
2163
|
// Deduplicate balances using a Map with `identifier` as the key
|
|
2166
2164
|
const uniqueBalances = new Map(
|
|
@@ -2172,11 +2170,15 @@ export class SDK {
|
|
|
2172
2170
|
},
|
|
2173
2171
|
]),
|
|
2174
2172
|
);
|
|
2175
|
-
console.log(tag, '
|
|
2173
|
+
console.log(tag, 'Deduplicated to:', uniqueBalances.size, 'unique balances');
|
|
2176
2174
|
|
|
2177
2175
|
// Convert Map back to array and set this.balances
|
|
2178
2176
|
this.balances = Array.from(uniqueBalances.values());
|
|
2179
|
-
|
|
2177
|
+
|
|
2178
|
+
// Log breakdown of balance types
|
|
2179
|
+
const tokens = this.balances.filter((b: any) => b.token === true);
|
|
2180
|
+
const native = this.balances.filter((b: any) => b.token !== true);
|
|
2181
|
+
console.log(tag, `Balance breakdown: ${native.length} native + ${tokens.length} tokens = ${this.balances.length} total`);
|
|
2180
2182
|
|
|
2181
2183
|
return this.balances;
|
|
2182
2184
|
} catch (e) {
|
|
@@ -2208,10 +2210,15 @@ export class SDK {
|
|
|
2208
2210
|
return { success: false };
|
|
2209
2211
|
}
|
|
2210
2212
|
};
|
|
2211
|
-
this.refresh = async (): Promise<any> => {
|
|
2213
|
+
this.refresh = async (forceRefresh?: boolean): Promise<any> => {
|
|
2212
2214
|
const tag = `${TAG} | refresh | `;
|
|
2213
2215
|
try {
|
|
2214
|
-
|
|
2216
|
+
if (forceRefresh) {
|
|
2217
|
+
console.log(tag, '🔄 Force refresh - fetching fresh balances from blockchain');
|
|
2218
|
+
await this.getBalances(true);
|
|
2219
|
+
} else {
|
|
2220
|
+
await this.sync();
|
|
2221
|
+
}
|
|
2215
2222
|
return this.balances;
|
|
2216
2223
|
} catch (e) {
|
|
2217
2224
|
console.error(tag, 'e: ', e);
|