@pioneer-platform/pioneer-sdk 8.19.0 → 8.21.0
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 +159 -2
- package/dist/index.es.js +159 -2
- package/dist/index.js +159 -2
- package/package.json +5 -5
- package/src/TransactionManager.ts +87 -0
- package/src/fees/index.ts +69 -2
- package/src/index.ts +22 -0
- package/src/supportedCaips.ts +2 -1
package/dist/index.cjs
CHANGED
|
@@ -59468,6 +59468,7 @@ var CAIP_TO_COIN_MAP = {
|
|
|
59468
59468
|
var OTHER_SUPPORT = [
|
|
59469
59469
|
"ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144",
|
|
59470
59470
|
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp/solana:so11111111111111111111111111111111111111112",
|
|
59471
|
+
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp",
|
|
59471
59472
|
"tron:0x2b6653dc/slip44:195",
|
|
59472
59473
|
"ton:-239/slip44:607"
|
|
59473
59474
|
];
|
|
@@ -61292,6 +61293,85 @@ class TransactionManager {
|
|
|
61292
61293
|
throw e;
|
|
61293
61294
|
}
|
|
61294
61295
|
}
|
|
61296
|
+
async signMessage({ caip, message, addressNList }) {
|
|
61297
|
+
let tag = TAG7 + " | signMessage | ";
|
|
61298
|
+
try {
|
|
61299
|
+
if (!this.pioneer)
|
|
61300
|
+
throw Error("Failed to init! pioneer");
|
|
61301
|
+
if (!caip)
|
|
61302
|
+
throw Error("Missing required param! caip");
|
|
61303
|
+
if (!message)
|
|
61304
|
+
throw Error("Missing required param! message");
|
|
61305
|
+
if (!addressNList)
|
|
61306
|
+
throw Error("Missing required param! addressNList");
|
|
61307
|
+
const type = await this.classifyCaip(caip);
|
|
61308
|
+
let signedMessage;
|
|
61309
|
+
switch (type) {
|
|
61310
|
+
case "OTHER": {
|
|
61311
|
+
if (caip.startsWith("solana:")) {
|
|
61312
|
+
const signRequest = {
|
|
61313
|
+
addressNList,
|
|
61314
|
+
message,
|
|
61315
|
+
showDisplay: true
|
|
61316
|
+
};
|
|
61317
|
+
try {
|
|
61318
|
+
const controller = new AbortController;
|
|
61319
|
+
const timeoutId = setTimeout(() => controller.abort(), 120000);
|
|
61320
|
+
try {
|
|
61321
|
+
const response = await fetch("http://localhost:1646/solana/sign-message", {
|
|
61322
|
+
method: "POST",
|
|
61323
|
+
headers: {
|
|
61324
|
+
"Content-Type": "application/json"
|
|
61325
|
+
},
|
|
61326
|
+
body: JSON.stringify(signRequest),
|
|
61327
|
+
signal: controller.signal
|
|
61328
|
+
});
|
|
61329
|
+
clearTimeout(timeoutId);
|
|
61330
|
+
if (!response.ok) {
|
|
61331
|
+
const errorData = await response.json();
|
|
61332
|
+
throw new Error(`Solana message signing failed: ${errorData.error || response.statusText}`);
|
|
61333
|
+
}
|
|
61334
|
+
const responseSign = await response.json();
|
|
61335
|
+
if (responseSign?.signature) {
|
|
61336
|
+
signedMessage = {
|
|
61337
|
+
signature: responseSign.signature,
|
|
61338
|
+
publicKey: responseSign.publicKey
|
|
61339
|
+
};
|
|
61340
|
+
} else {
|
|
61341
|
+
throw new Error("Solana message signing failed - no signature in response");
|
|
61342
|
+
}
|
|
61343
|
+
} catch (fetchError) {
|
|
61344
|
+
clearTimeout(timeoutId);
|
|
61345
|
+
if (fetchError.name === "AbortError") {
|
|
61346
|
+
throw new Error("Solana message signing timed out after 2 minutes");
|
|
61347
|
+
}
|
|
61348
|
+
throw fetchError;
|
|
61349
|
+
}
|
|
61350
|
+
} catch (e) {
|
|
61351
|
+
console.error(tag, "Solana message signing error:", e);
|
|
61352
|
+
throw new Error(`Solana message signing failed: ${e.message}`);
|
|
61353
|
+
}
|
|
61354
|
+
} else {
|
|
61355
|
+
throw new Error(`Message signing not supported for CAIP: ${caip}`);
|
|
61356
|
+
}
|
|
61357
|
+
break;
|
|
61358
|
+
}
|
|
61359
|
+
default: {
|
|
61360
|
+
throw new Error(`Message signing not supported for CAIP type: ${type}`);
|
|
61361
|
+
}
|
|
61362
|
+
}
|
|
61363
|
+
if (!signedMessage) {
|
|
61364
|
+
console.error(tag, "CRITICAL ERROR: signedMessage is missing after signing process");
|
|
61365
|
+
console.error(tag, "CAIP:", caip);
|
|
61366
|
+
console.error(tag, "Type:", type);
|
|
61367
|
+
throw Error("Failed to sign message! missing signedMessage");
|
|
61368
|
+
}
|
|
61369
|
+
return signedMessage;
|
|
61370
|
+
} catch (e) {
|
|
61371
|
+
console.error(tag, e);
|
|
61372
|
+
throw e;
|
|
61373
|
+
}
|
|
61374
|
+
}
|
|
61295
61375
|
async broadcast({ networkId, serialized }) {
|
|
61296
61376
|
let tag = TAG7 + " | broadcast | ";
|
|
61297
61377
|
try {
|
|
@@ -61571,6 +61651,8 @@ function getNetworkType(networkId) {
|
|
|
61571
61651
|
return "COSMOS";
|
|
61572
61652
|
if (networkId.startsWith("ripple:"))
|
|
61573
61653
|
return "RIPPLE";
|
|
61654
|
+
if (networkId.startsWith("solana:"))
|
|
61655
|
+
return "SOLANA";
|
|
61574
61656
|
return "OTHER";
|
|
61575
61657
|
}
|
|
61576
61658
|
function getNetworkName(networkId) {
|
|
@@ -61592,7 +61674,8 @@ function getNetworkName(networkId) {
|
|
|
61592
61674
|
"cosmos:osmosis-1": "Osmosis",
|
|
61593
61675
|
"cosmos:thorchain-mainnet-v1": "THORChain",
|
|
61594
61676
|
"cosmos:mayachain-mainnet-v1": "Maya",
|
|
61595
|
-
"ripple:4109c6f2045fc7eff4cde8f9905d19c2": "Ripple"
|
|
61677
|
+
"ripple:4109c6f2045fc7eff4cde8f9905d19c2": "Ripple",
|
|
61678
|
+
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp": "Solana"
|
|
61596
61679
|
};
|
|
61597
61680
|
return networkNames[networkId] || networkId;
|
|
61598
61681
|
}
|
|
@@ -61615,6 +61698,10 @@ async function getFees(pioneer, networkId) {
|
|
|
61615
61698
|
console.log(tag, "Using hardcoded fees for Ripple: 0.00001 XRP");
|
|
61616
61699
|
return getRippleFees(networkId);
|
|
61617
61700
|
}
|
|
61701
|
+
if (networkId === "solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp") {
|
|
61702
|
+
console.log(tag, "Using hardcoded fees for Solana: 0.000005 SOL (5000 lamports)");
|
|
61703
|
+
return getSolanaFees(networkId);
|
|
61704
|
+
}
|
|
61618
61705
|
if (networkId === "bip122:00000000001a91e3dace36e2be3bf030") {
|
|
61619
61706
|
console.log(tag, "Using hardcoded fees for Dogecoin: 10 sat/byte");
|
|
61620
61707
|
return {
|
|
@@ -61889,6 +61976,8 @@ function getDefaultUnit(networkType) {
|
|
|
61889
61976
|
return "uatom";
|
|
61890
61977
|
case "RIPPLE":
|
|
61891
61978
|
return "XRP";
|
|
61979
|
+
case "SOLANA":
|
|
61980
|
+
return "SOL";
|
|
61892
61981
|
default:
|
|
61893
61982
|
return "units";
|
|
61894
61983
|
}
|
|
@@ -61903,6 +61992,8 @@ function getDefaultDescription(networkType, networkName) {
|
|
|
61903
61992
|
return `Transaction fee for ${networkName}`;
|
|
61904
61993
|
case "RIPPLE":
|
|
61905
61994
|
return `Fixed transaction fee for ${networkName}`;
|
|
61995
|
+
case "SOLANA":
|
|
61996
|
+
return `Fixed transaction fee for ${networkName}`;
|
|
61906
61997
|
default:
|
|
61907
61998
|
return `Transaction fee for ${networkName}`;
|
|
61908
61999
|
}
|
|
@@ -61928,6 +62019,11 @@ function getEstimatedTime(networkType, priority) {
|
|
|
61928
62019
|
low: "~4 seconds",
|
|
61929
62020
|
medium: "~4 seconds",
|
|
61930
62021
|
high: "~4 seconds"
|
|
62022
|
+
},
|
|
62023
|
+
SOLANA: {
|
|
62024
|
+
low: "~1 second",
|
|
62025
|
+
medium: "~1 second",
|
|
62026
|
+
high: "~1 second"
|
|
61931
62027
|
}
|
|
61932
62028
|
};
|
|
61933
62029
|
return times[networkType]?.[priority] || "~varies";
|
|
@@ -62007,6 +62103,39 @@ function getRippleFees(networkId) {
|
|
|
62007
62103
|
raw: { hardcoded: true, fee: standardFee, unit: "XRP" }
|
|
62008
62104
|
};
|
|
62009
62105
|
}
|
|
62106
|
+
function getSolanaFees(networkId) {
|
|
62107
|
+
const networkName = getNetworkName(networkId);
|
|
62108
|
+
const standardFee = "0.000005";
|
|
62109
|
+
return {
|
|
62110
|
+
slow: {
|
|
62111
|
+
label: "Standard",
|
|
62112
|
+
value: standardFee,
|
|
62113
|
+
unit: "SOL",
|
|
62114
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
62115
|
+
estimatedTime: "~1 second",
|
|
62116
|
+
priority: "low"
|
|
62117
|
+
},
|
|
62118
|
+
average: {
|
|
62119
|
+
label: "Standard",
|
|
62120
|
+
value: standardFee,
|
|
62121
|
+
unit: "SOL",
|
|
62122
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
62123
|
+
estimatedTime: "~1 second",
|
|
62124
|
+
priority: "medium"
|
|
62125
|
+
},
|
|
62126
|
+
fastest: {
|
|
62127
|
+
label: "Standard",
|
|
62128
|
+
value: standardFee,
|
|
62129
|
+
unit: "SOL",
|
|
62130
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
62131
|
+
estimatedTime: "~1 second",
|
|
62132
|
+
priority: "high"
|
|
62133
|
+
},
|
|
62134
|
+
networkId,
|
|
62135
|
+
networkType: "SOLANA",
|
|
62136
|
+
raw: { hardcoded: true, fee: standardFee, unit: "SOL", lamports: 5000 }
|
|
62137
|
+
};
|
|
62138
|
+
}
|
|
62010
62139
|
function getFallbackFees(networkId) {
|
|
62011
62140
|
const networkType = getNetworkType(networkId);
|
|
62012
62141
|
const networkName = getNetworkName(networkId);
|
|
@@ -62016,7 +62145,8 @@ function getFallbackFees(networkId) {
|
|
|
62016
62145
|
const fallbacks = {
|
|
62017
62146
|
UTXO: { slow: "1", average: "2", fastest: "3", unit: "sat/vB" },
|
|
62018
62147
|
EVM: { slow: "1", average: "1.5", fastest: "2", unit: "gwei" },
|
|
62019
|
-
RIPPLE: { slow: "0.00001", average: "0.00001", fastest: "0.00001", unit: "XRP" }
|
|
62148
|
+
RIPPLE: { slow: "0.00001", average: "0.00001", fastest: "0.00001", unit: "XRP" },
|
|
62149
|
+
SOLANA: { slow: "0.000005", average: "0.000005", fastest: "0.000005", unit: "SOL" }
|
|
62020
62150
|
};
|
|
62021
62151
|
const fallback = fallbacks[networkType] || fallbacks.UTXO;
|
|
62022
62152
|
return {
|
|
@@ -62072,6 +62202,11 @@ function estimateTransactionFee(feeRate, unit, networkType, txSize) {
|
|
|
62072
62202
|
amount: feeRate,
|
|
62073
62203
|
unit: "XRP"
|
|
62074
62204
|
};
|
|
62205
|
+
case "SOLANA":
|
|
62206
|
+
return {
|
|
62207
|
+
amount: feeRate,
|
|
62208
|
+
unit: "SOL"
|
|
62209
|
+
};
|
|
62075
62210
|
default:
|
|
62076
62211
|
return {
|
|
62077
62212
|
amount: feeRate,
|
|
@@ -62909,6 +63044,7 @@ class SDK {
|
|
|
62909
63044
|
followTransaction;
|
|
62910
63045
|
broadcastTx;
|
|
62911
63046
|
signTx;
|
|
63047
|
+
signMessage;
|
|
62912
63048
|
buildTx;
|
|
62913
63049
|
buildDelegateTx;
|
|
62914
63050
|
buildUndelegateTx;
|
|
@@ -63472,6 +63608,27 @@ class SDK {
|
|
|
63472
63608
|
throw e;
|
|
63473
63609
|
}
|
|
63474
63610
|
};
|
|
63611
|
+
this.signMessage = async function(caip, message, addressNList) {
|
|
63612
|
+
let tag6 = TAG14 + " | signMessage | ";
|
|
63613
|
+
try {
|
|
63614
|
+
const transactionDependencies = {
|
|
63615
|
+
context: this.context,
|
|
63616
|
+
assetContext: this.assetContext,
|
|
63617
|
+
balances: this.balances,
|
|
63618
|
+
pioneer: this.pioneer,
|
|
63619
|
+
pubkeys: this.pubkeys,
|
|
63620
|
+
pubkeyContext: this.pubkeyContext,
|
|
63621
|
+
nodes: this.nodes,
|
|
63622
|
+
keepKeySdk: this.keepKeySdk
|
|
63623
|
+
};
|
|
63624
|
+
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
63625
|
+
let signedMessage = await txManager.signMessage({ caip, message, addressNList });
|
|
63626
|
+
return signedMessage;
|
|
63627
|
+
} catch (e) {
|
|
63628
|
+
console.error(e);
|
|
63629
|
+
throw e;
|
|
63630
|
+
}
|
|
63631
|
+
};
|
|
63475
63632
|
this.broadcastTx = async function(caip, signedTx) {
|
|
63476
63633
|
let tag6 = TAG14 + " | broadcastTx | ";
|
|
63477
63634
|
try {
|
package/dist/index.es.js
CHANGED
|
@@ -34788,6 +34788,7 @@ var CAIP_TO_COIN_MAP = {
|
|
|
34788
34788
|
var OTHER_SUPPORT = [
|
|
34789
34789
|
"ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144",
|
|
34790
34790
|
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp/solana:so11111111111111111111111111111111111111112",
|
|
34791
|
+
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp",
|
|
34791
34792
|
"tron:0x2b6653dc/slip44:195",
|
|
34792
34793
|
"ton:-239/slip44:607"
|
|
34793
34794
|
];
|
|
@@ -47648,6 +47649,85 @@ class TransactionManager {
|
|
|
47648
47649
|
throw e;
|
|
47649
47650
|
}
|
|
47650
47651
|
}
|
|
47652
|
+
async signMessage({ caip, message, addressNList }) {
|
|
47653
|
+
let tag = TAG7 + " | signMessage | ";
|
|
47654
|
+
try {
|
|
47655
|
+
if (!this.pioneer)
|
|
47656
|
+
throw Error("Failed to init! pioneer");
|
|
47657
|
+
if (!caip)
|
|
47658
|
+
throw Error("Missing required param! caip");
|
|
47659
|
+
if (!message)
|
|
47660
|
+
throw Error("Missing required param! message");
|
|
47661
|
+
if (!addressNList)
|
|
47662
|
+
throw Error("Missing required param! addressNList");
|
|
47663
|
+
const type2 = await this.classifyCaip(caip);
|
|
47664
|
+
let signedMessage;
|
|
47665
|
+
switch (type2) {
|
|
47666
|
+
case "OTHER": {
|
|
47667
|
+
if (caip.startsWith("solana:")) {
|
|
47668
|
+
const signRequest = {
|
|
47669
|
+
addressNList,
|
|
47670
|
+
message,
|
|
47671
|
+
showDisplay: true
|
|
47672
|
+
};
|
|
47673
|
+
try {
|
|
47674
|
+
const controller = new AbortController;
|
|
47675
|
+
const timeoutId = setTimeout(() => controller.abort(), 120000);
|
|
47676
|
+
try {
|
|
47677
|
+
const response = await fetch("http://localhost:1646/solana/sign-message", {
|
|
47678
|
+
method: "POST",
|
|
47679
|
+
headers: {
|
|
47680
|
+
"Content-Type": "application/json"
|
|
47681
|
+
},
|
|
47682
|
+
body: JSON.stringify(signRequest),
|
|
47683
|
+
signal: controller.signal
|
|
47684
|
+
});
|
|
47685
|
+
clearTimeout(timeoutId);
|
|
47686
|
+
if (!response.ok) {
|
|
47687
|
+
const errorData = await response.json();
|
|
47688
|
+
throw new Error(`Solana message signing failed: ${errorData.error || response.statusText}`);
|
|
47689
|
+
}
|
|
47690
|
+
const responseSign = await response.json();
|
|
47691
|
+
if (responseSign?.signature) {
|
|
47692
|
+
signedMessage = {
|
|
47693
|
+
signature: responseSign.signature,
|
|
47694
|
+
publicKey: responseSign.publicKey
|
|
47695
|
+
};
|
|
47696
|
+
} else {
|
|
47697
|
+
throw new Error("Solana message signing failed - no signature in response");
|
|
47698
|
+
}
|
|
47699
|
+
} catch (fetchError) {
|
|
47700
|
+
clearTimeout(timeoutId);
|
|
47701
|
+
if (fetchError.name === "AbortError") {
|
|
47702
|
+
throw new Error("Solana message signing timed out after 2 minutes");
|
|
47703
|
+
}
|
|
47704
|
+
throw fetchError;
|
|
47705
|
+
}
|
|
47706
|
+
} catch (e) {
|
|
47707
|
+
console.error(tag, "Solana message signing error:", e);
|
|
47708
|
+
throw new Error(`Solana message signing failed: ${e.message}`);
|
|
47709
|
+
}
|
|
47710
|
+
} else {
|
|
47711
|
+
throw new Error(`Message signing not supported for CAIP: ${caip}`);
|
|
47712
|
+
}
|
|
47713
|
+
break;
|
|
47714
|
+
}
|
|
47715
|
+
default: {
|
|
47716
|
+
throw new Error(`Message signing not supported for CAIP type: ${type2}`);
|
|
47717
|
+
}
|
|
47718
|
+
}
|
|
47719
|
+
if (!signedMessage) {
|
|
47720
|
+
console.error(tag, "CRITICAL ERROR: signedMessage is missing after signing process");
|
|
47721
|
+
console.error(tag, "CAIP:", caip);
|
|
47722
|
+
console.error(tag, "Type:", type2);
|
|
47723
|
+
throw Error("Failed to sign message! missing signedMessage");
|
|
47724
|
+
}
|
|
47725
|
+
return signedMessage;
|
|
47726
|
+
} catch (e) {
|
|
47727
|
+
console.error(tag, e);
|
|
47728
|
+
throw e;
|
|
47729
|
+
}
|
|
47730
|
+
}
|
|
47651
47731
|
async broadcast({ networkId, serialized }) {
|
|
47652
47732
|
let tag = TAG7 + " | broadcast | ";
|
|
47653
47733
|
try {
|
|
@@ -47927,6 +48007,8 @@ function getNetworkType(networkId) {
|
|
|
47927
48007
|
return "COSMOS";
|
|
47928
48008
|
if (networkId.startsWith("ripple:"))
|
|
47929
48009
|
return "RIPPLE";
|
|
48010
|
+
if (networkId.startsWith("solana:"))
|
|
48011
|
+
return "SOLANA";
|
|
47930
48012
|
return "OTHER";
|
|
47931
48013
|
}
|
|
47932
48014
|
function getNetworkName(networkId) {
|
|
@@ -47948,7 +48030,8 @@ function getNetworkName(networkId) {
|
|
|
47948
48030
|
"cosmos:osmosis-1": "Osmosis",
|
|
47949
48031
|
"cosmos:thorchain-mainnet-v1": "THORChain",
|
|
47950
48032
|
"cosmos:mayachain-mainnet-v1": "Maya",
|
|
47951
|
-
"ripple:4109c6f2045fc7eff4cde8f9905d19c2": "Ripple"
|
|
48033
|
+
"ripple:4109c6f2045fc7eff4cde8f9905d19c2": "Ripple",
|
|
48034
|
+
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp": "Solana"
|
|
47952
48035
|
};
|
|
47953
48036
|
return networkNames[networkId] || networkId;
|
|
47954
48037
|
}
|
|
@@ -47971,6 +48054,10 @@ async function getFees(pioneer, networkId) {
|
|
|
47971
48054
|
console.log(tag, "Using hardcoded fees for Ripple: 0.00001 XRP");
|
|
47972
48055
|
return getRippleFees(networkId);
|
|
47973
48056
|
}
|
|
48057
|
+
if (networkId === "solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp") {
|
|
48058
|
+
console.log(tag, "Using hardcoded fees for Solana: 0.000005 SOL (5000 lamports)");
|
|
48059
|
+
return getSolanaFees(networkId);
|
|
48060
|
+
}
|
|
47974
48061
|
if (networkId === "bip122:00000000001a91e3dace36e2be3bf030") {
|
|
47975
48062
|
console.log(tag, "Using hardcoded fees for Dogecoin: 10 sat/byte");
|
|
47976
48063
|
return {
|
|
@@ -48245,6 +48332,8 @@ function getDefaultUnit(networkType) {
|
|
|
48245
48332
|
return "uatom";
|
|
48246
48333
|
case "RIPPLE":
|
|
48247
48334
|
return "XRP";
|
|
48335
|
+
case "SOLANA":
|
|
48336
|
+
return "SOL";
|
|
48248
48337
|
default:
|
|
48249
48338
|
return "units";
|
|
48250
48339
|
}
|
|
@@ -48259,6 +48348,8 @@ function getDefaultDescription(networkType, networkName) {
|
|
|
48259
48348
|
return `Transaction fee for ${networkName}`;
|
|
48260
48349
|
case "RIPPLE":
|
|
48261
48350
|
return `Fixed transaction fee for ${networkName}`;
|
|
48351
|
+
case "SOLANA":
|
|
48352
|
+
return `Fixed transaction fee for ${networkName}`;
|
|
48262
48353
|
default:
|
|
48263
48354
|
return `Transaction fee for ${networkName}`;
|
|
48264
48355
|
}
|
|
@@ -48284,6 +48375,11 @@ function getEstimatedTime(networkType, priority) {
|
|
|
48284
48375
|
low: "~4 seconds",
|
|
48285
48376
|
medium: "~4 seconds",
|
|
48286
48377
|
high: "~4 seconds"
|
|
48378
|
+
},
|
|
48379
|
+
SOLANA: {
|
|
48380
|
+
low: "~1 second",
|
|
48381
|
+
medium: "~1 second",
|
|
48382
|
+
high: "~1 second"
|
|
48287
48383
|
}
|
|
48288
48384
|
};
|
|
48289
48385
|
return times[networkType]?.[priority] || "~varies";
|
|
@@ -48363,6 +48459,39 @@ function getRippleFees(networkId) {
|
|
|
48363
48459
|
raw: { hardcoded: true, fee: standardFee, unit: "XRP" }
|
|
48364
48460
|
};
|
|
48365
48461
|
}
|
|
48462
|
+
function getSolanaFees(networkId) {
|
|
48463
|
+
const networkName = getNetworkName(networkId);
|
|
48464
|
+
const standardFee = "0.000005";
|
|
48465
|
+
return {
|
|
48466
|
+
slow: {
|
|
48467
|
+
label: "Standard",
|
|
48468
|
+
value: standardFee,
|
|
48469
|
+
unit: "SOL",
|
|
48470
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
48471
|
+
estimatedTime: "~1 second",
|
|
48472
|
+
priority: "low"
|
|
48473
|
+
},
|
|
48474
|
+
average: {
|
|
48475
|
+
label: "Standard",
|
|
48476
|
+
value: standardFee,
|
|
48477
|
+
unit: "SOL",
|
|
48478
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
48479
|
+
estimatedTime: "~1 second",
|
|
48480
|
+
priority: "medium"
|
|
48481
|
+
},
|
|
48482
|
+
fastest: {
|
|
48483
|
+
label: "Standard",
|
|
48484
|
+
value: standardFee,
|
|
48485
|
+
unit: "SOL",
|
|
48486
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
48487
|
+
estimatedTime: "~1 second",
|
|
48488
|
+
priority: "high"
|
|
48489
|
+
},
|
|
48490
|
+
networkId,
|
|
48491
|
+
networkType: "SOLANA",
|
|
48492
|
+
raw: { hardcoded: true, fee: standardFee, unit: "SOL", lamports: 5000 }
|
|
48493
|
+
};
|
|
48494
|
+
}
|
|
48366
48495
|
function getFallbackFees(networkId) {
|
|
48367
48496
|
const networkType = getNetworkType(networkId);
|
|
48368
48497
|
const networkName = getNetworkName(networkId);
|
|
@@ -48372,7 +48501,8 @@ function getFallbackFees(networkId) {
|
|
|
48372
48501
|
const fallbacks = {
|
|
48373
48502
|
UTXO: { slow: "1", average: "2", fastest: "3", unit: "sat/vB" },
|
|
48374
48503
|
EVM: { slow: "1", average: "1.5", fastest: "2", unit: "gwei" },
|
|
48375
|
-
RIPPLE: { slow: "0.00001", average: "0.00001", fastest: "0.00001", unit: "XRP" }
|
|
48504
|
+
RIPPLE: { slow: "0.00001", average: "0.00001", fastest: "0.00001", unit: "XRP" },
|
|
48505
|
+
SOLANA: { slow: "0.000005", average: "0.000005", fastest: "0.000005", unit: "SOL" }
|
|
48376
48506
|
};
|
|
48377
48507
|
const fallback = fallbacks[networkType] || fallbacks.UTXO;
|
|
48378
48508
|
return {
|
|
@@ -48428,6 +48558,11 @@ function estimateTransactionFee(feeRate, unit, networkType, txSize) {
|
|
|
48428
48558
|
amount: feeRate,
|
|
48429
48559
|
unit: "XRP"
|
|
48430
48560
|
};
|
|
48561
|
+
case "SOLANA":
|
|
48562
|
+
return {
|
|
48563
|
+
amount: feeRate,
|
|
48564
|
+
unit: "SOL"
|
|
48565
|
+
};
|
|
48431
48566
|
default:
|
|
48432
48567
|
return {
|
|
48433
48568
|
amount: feeRate,
|
|
@@ -49265,6 +49400,7 @@ class SDK {
|
|
|
49265
49400
|
followTransaction;
|
|
49266
49401
|
broadcastTx;
|
|
49267
49402
|
signTx;
|
|
49403
|
+
signMessage;
|
|
49268
49404
|
buildTx;
|
|
49269
49405
|
buildDelegateTx;
|
|
49270
49406
|
buildUndelegateTx;
|
|
@@ -49828,6 +49964,27 @@ class SDK {
|
|
|
49828
49964
|
throw e;
|
|
49829
49965
|
}
|
|
49830
49966
|
};
|
|
49967
|
+
this.signMessage = async function(caip, message, addressNList) {
|
|
49968
|
+
let tag6 = TAG14 + " | signMessage | ";
|
|
49969
|
+
try {
|
|
49970
|
+
const transactionDependencies = {
|
|
49971
|
+
context: this.context,
|
|
49972
|
+
assetContext: this.assetContext,
|
|
49973
|
+
balances: this.balances,
|
|
49974
|
+
pioneer: this.pioneer,
|
|
49975
|
+
pubkeys: this.pubkeys,
|
|
49976
|
+
pubkeyContext: this.pubkeyContext,
|
|
49977
|
+
nodes: this.nodes,
|
|
49978
|
+
keepKeySdk: this.keepKeySdk
|
|
49979
|
+
};
|
|
49980
|
+
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
49981
|
+
let signedMessage = await txManager.signMessage({ caip, message, addressNList });
|
|
49982
|
+
return signedMessage;
|
|
49983
|
+
} catch (e) {
|
|
49984
|
+
console.error(e);
|
|
49985
|
+
throw e;
|
|
49986
|
+
}
|
|
49987
|
+
};
|
|
49831
49988
|
this.broadcastTx = async function(caip, signedTx) {
|
|
49832
49989
|
let tag6 = TAG14 + " | broadcastTx | ";
|
|
49833
49990
|
try {
|
package/dist/index.js
CHANGED
|
@@ -34788,6 +34788,7 @@ var CAIP_TO_COIN_MAP = {
|
|
|
34788
34788
|
var OTHER_SUPPORT = [
|
|
34789
34789
|
"ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144",
|
|
34790
34790
|
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp/solana:so11111111111111111111111111111111111111112",
|
|
34791
|
+
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp",
|
|
34791
34792
|
"tron:0x2b6653dc/slip44:195",
|
|
34792
34793
|
"ton:-239/slip44:607"
|
|
34793
34794
|
];
|
|
@@ -47648,6 +47649,85 @@ class TransactionManager {
|
|
|
47648
47649
|
throw e;
|
|
47649
47650
|
}
|
|
47650
47651
|
}
|
|
47652
|
+
async signMessage({ caip, message, addressNList }) {
|
|
47653
|
+
let tag = TAG7 + " | signMessage | ";
|
|
47654
|
+
try {
|
|
47655
|
+
if (!this.pioneer)
|
|
47656
|
+
throw Error("Failed to init! pioneer");
|
|
47657
|
+
if (!caip)
|
|
47658
|
+
throw Error("Missing required param! caip");
|
|
47659
|
+
if (!message)
|
|
47660
|
+
throw Error("Missing required param! message");
|
|
47661
|
+
if (!addressNList)
|
|
47662
|
+
throw Error("Missing required param! addressNList");
|
|
47663
|
+
const type2 = await this.classifyCaip(caip);
|
|
47664
|
+
let signedMessage;
|
|
47665
|
+
switch (type2) {
|
|
47666
|
+
case "OTHER": {
|
|
47667
|
+
if (caip.startsWith("solana:")) {
|
|
47668
|
+
const signRequest = {
|
|
47669
|
+
addressNList,
|
|
47670
|
+
message,
|
|
47671
|
+
showDisplay: true
|
|
47672
|
+
};
|
|
47673
|
+
try {
|
|
47674
|
+
const controller = new AbortController;
|
|
47675
|
+
const timeoutId = setTimeout(() => controller.abort(), 120000);
|
|
47676
|
+
try {
|
|
47677
|
+
const response = await fetch("http://localhost:1646/solana/sign-message", {
|
|
47678
|
+
method: "POST",
|
|
47679
|
+
headers: {
|
|
47680
|
+
"Content-Type": "application/json"
|
|
47681
|
+
},
|
|
47682
|
+
body: JSON.stringify(signRequest),
|
|
47683
|
+
signal: controller.signal
|
|
47684
|
+
});
|
|
47685
|
+
clearTimeout(timeoutId);
|
|
47686
|
+
if (!response.ok) {
|
|
47687
|
+
const errorData = await response.json();
|
|
47688
|
+
throw new Error(`Solana message signing failed: ${errorData.error || response.statusText}`);
|
|
47689
|
+
}
|
|
47690
|
+
const responseSign = await response.json();
|
|
47691
|
+
if (responseSign?.signature) {
|
|
47692
|
+
signedMessage = {
|
|
47693
|
+
signature: responseSign.signature,
|
|
47694
|
+
publicKey: responseSign.publicKey
|
|
47695
|
+
};
|
|
47696
|
+
} else {
|
|
47697
|
+
throw new Error("Solana message signing failed - no signature in response");
|
|
47698
|
+
}
|
|
47699
|
+
} catch (fetchError) {
|
|
47700
|
+
clearTimeout(timeoutId);
|
|
47701
|
+
if (fetchError.name === "AbortError") {
|
|
47702
|
+
throw new Error("Solana message signing timed out after 2 minutes");
|
|
47703
|
+
}
|
|
47704
|
+
throw fetchError;
|
|
47705
|
+
}
|
|
47706
|
+
} catch (e) {
|
|
47707
|
+
console.error(tag, "Solana message signing error:", e);
|
|
47708
|
+
throw new Error(`Solana message signing failed: ${e.message}`);
|
|
47709
|
+
}
|
|
47710
|
+
} else {
|
|
47711
|
+
throw new Error(`Message signing not supported for CAIP: ${caip}`);
|
|
47712
|
+
}
|
|
47713
|
+
break;
|
|
47714
|
+
}
|
|
47715
|
+
default: {
|
|
47716
|
+
throw new Error(`Message signing not supported for CAIP type: ${type2}`);
|
|
47717
|
+
}
|
|
47718
|
+
}
|
|
47719
|
+
if (!signedMessage) {
|
|
47720
|
+
console.error(tag, "CRITICAL ERROR: signedMessage is missing after signing process");
|
|
47721
|
+
console.error(tag, "CAIP:", caip);
|
|
47722
|
+
console.error(tag, "Type:", type2);
|
|
47723
|
+
throw Error("Failed to sign message! missing signedMessage");
|
|
47724
|
+
}
|
|
47725
|
+
return signedMessage;
|
|
47726
|
+
} catch (e) {
|
|
47727
|
+
console.error(tag, e);
|
|
47728
|
+
throw e;
|
|
47729
|
+
}
|
|
47730
|
+
}
|
|
47651
47731
|
async broadcast({ networkId, serialized }) {
|
|
47652
47732
|
let tag = TAG7 + " | broadcast | ";
|
|
47653
47733
|
try {
|
|
@@ -47927,6 +48007,8 @@ function getNetworkType(networkId) {
|
|
|
47927
48007
|
return "COSMOS";
|
|
47928
48008
|
if (networkId.startsWith("ripple:"))
|
|
47929
48009
|
return "RIPPLE";
|
|
48010
|
+
if (networkId.startsWith("solana:"))
|
|
48011
|
+
return "SOLANA";
|
|
47930
48012
|
return "OTHER";
|
|
47931
48013
|
}
|
|
47932
48014
|
function getNetworkName(networkId) {
|
|
@@ -47948,7 +48030,8 @@ function getNetworkName(networkId) {
|
|
|
47948
48030
|
"cosmos:osmosis-1": "Osmosis",
|
|
47949
48031
|
"cosmos:thorchain-mainnet-v1": "THORChain",
|
|
47950
48032
|
"cosmos:mayachain-mainnet-v1": "Maya",
|
|
47951
|
-
"ripple:4109c6f2045fc7eff4cde8f9905d19c2": "Ripple"
|
|
48033
|
+
"ripple:4109c6f2045fc7eff4cde8f9905d19c2": "Ripple",
|
|
48034
|
+
"solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp": "Solana"
|
|
47952
48035
|
};
|
|
47953
48036
|
return networkNames[networkId] || networkId;
|
|
47954
48037
|
}
|
|
@@ -47971,6 +48054,10 @@ async function getFees(pioneer, networkId) {
|
|
|
47971
48054
|
console.log(tag, "Using hardcoded fees for Ripple: 0.00001 XRP");
|
|
47972
48055
|
return getRippleFees(networkId);
|
|
47973
48056
|
}
|
|
48057
|
+
if (networkId === "solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp") {
|
|
48058
|
+
console.log(tag, "Using hardcoded fees for Solana: 0.000005 SOL (5000 lamports)");
|
|
48059
|
+
return getSolanaFees(networkId);
|
|
48060
|
+
}
|
|
47974
48061
|
if (networkId === "bip122:00000000001a91e3dace36e2be3bf030") {
|
|
47975
48062
|
console.log(tag, "Using hardcoded fees for Dogecoin: 10 sat/byte");
|
|
47976
48063
|
return {
|
|
@@ -48245,6 +48332,8 @@ function getDefaultUnit(networkType) {
|
|
|
48245
48332
|
return "uatom";
|
|
48246
48333
|
case "RIPPLE":
|
|
48247
48334
|
return "XRP";
|
|
48335
|
+
case "SOLANA":
|
|
48336
|
+
return "SOL";
|
|
48248
48337
|
default:
|
|
48249
48338
|
return "units";
|
|
48250
48339
|
}
|
|
@@ -48259,6 +48348,8 @@ function getDefaultDescription(networkType, networkName) {
|
|
|
48259
48348
|
return `Transaction fee for ${networkName}`;
|
|
48260
48349
|
case "RIPPLE":
|
|
48261
48350
|
return `Fixed transaction fee for ${networkName}`;
|
|
48351
|
+
case "SOLANA":
|
|
48352
|
+
return `Fixed transaction fee for ${networkName}`;
|
|
48262
48353
|
default:
|
|
48263
48354
|
return `Transaction fee for ${networkName}`;
|
|
48264
48355
|
}
|
|
@@ -48284,6 +48375,11 @@ function getEstimatedTime(networkType, priority) {
|
|
|
48284
48375
|
low: "~4 seconds",
|
|
48285
48376
|
medium: "~4 seconds",
|
|
48286
48377
|
high: "~4 seconds"
|
|
48378
|
+
},
|
|
48379
|
+
SOLANA: {
|
|
48380
|
+
low: "~1 second",
|
|
48381
|
+
medium: "~1 second",
|
|
48382
|
+
high: "~1 second"
|
|
48287
48383
|
}
|
|
48288
48384
|
};
|
|
48289
48385
|
return times[networkType]?.[priority] || "~varies";
|
|
@@ -48363,6 +48459,39 @@ function getRippleFees(networkId) {
|
|
|
48363
48459
|
raw: { hardcoded: true, fee: standardFee, unit: "XRP" }
|
|
48364
48460
|
};
|
|
48365
48461
|
}
|
|
48462
|
+
function getSolanaFees(networkId) {
|
|
48463
|
+
const networkName = getNetworkName(networkId);
|
|
48464
|
+
const standardFee = "0.000005";
|
|
48465
|
+
return {
|
|
48466
|
+
slow: {
|
|
48467
|
+
label: "Standard",
|
|
48468
|
+
value: standardFee,
|
|
48469
|
+
unit: "SOL",
|
|
48470
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
48471
|
+
estimatedTime: "~1 second",
|
|
48472
|
+
priority: "low"
|
|
48473
|
+
},
|
|
48474
|
+
average: {
|
|
48475
|
+
label: "Standard",
|
|
48476
|
+
value: standardFee,
|
|
48477
|
+
unit: "SOL",
|
|
48478
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
48479
|
+
estimatedTime: "~1 second",
|
|
48480
|
+
priority: "medium"
|
|
48481
|
+
},
|
|
48482
|
+
fastest: {
|
|
48483
|
+
label: "Standard",
|
|
48484
|
+
value: standardFee,
|
|
48485
|
+
unit: "SOL",
|
|
48486
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
48487
|
+
estimatedTime: "~1 second",
|
|
48488
|
+
priority: "high"
|
|
48489
|
+
},
|
|
48490
|
+
networkId,
|
|
48491
|
+
networkType: "SOLANA",
|
|
48492
|
+
raw: { hardcoded: true, fee: standardFee, unit: "SOL", lamports: 5000 }
|
|
48493
|
+
};
|
|
48494
|
+
}
|
|
48366
48495
|
function getFallbackFees(networkId) {
|
|
48367
48496
|
const networkType = getNetworkType(networkId);
|
|
48368
48497
|
const networkName = getNetworkName(networkId);
|
|
@@ -48372,7 +48501,8 @@ function getFallbackFees(networkId) {
|
|
|
48372
48501
|
const fallbacks = {
|
|
48373
48502
|
UTXO: { slow: "1", average: "2", fastest: "3", unit: "sat/vB" },
|
|
48374
48503
|
EVM: { slow: "1", average: "1.5", fastest: "2", unit: "gwei" },
|
|
48375
|
-
RIPPLE: { slow: "0.00001", average: "0.00001", fastest: "0.00001", unit: "XRP" }
|
|
48504
|
+
RIPPLE: { slow: "0.00001", average: "0.00001", fastest: "0.00001", unit: "XRP" },
|
|
48505
|
+
SOLANA: { slow: "0.000005", average: "0.000005", fastest: "0.000005", unit: "SOL" }
|
|
48376
48506
|
};
|
|
48377
48507
|
const fallback = fallbacks[networkType] || fallbacks.UTXO;
|
|
48378
48508
|
return {
|
|
@@ -48428,6 +48558,11 @@ function estimateTransactionFee(feeRate, unit, networkType, txSize) {
|
|
|
48428
48558
|
amount: feeRate,
|
|
48429
48559
|
unit: "XRP"
|
|
48430
48560
|
};
|
|
48561
|
+
case "SOLANA":
|
|
48562
|
+
return {
|
|
48563
|
+
amount: feeRate,
|
|
48564
|
+
unit: "SOL"
|
|
48565
|
+
};
|
|
48431
48566
|
default:
|
|
48432
48567
|
return {
|
|
48433
48568
|
amount: feeRate,
|
|
@@ -49265,6 +49400,7 @@ class SDK {
|
|
|
49265
49400
|
followTransaction;
|
|
49266
49401
|
broadcastTx;
|
|
49267
49402
|
signTx;
|
|
49403
|
+
signMessage;
|
|
49268
49404
|
buildTx;
|
|
49269
49405
|
buildDelegateTx;
|
|
49270
49406
|
buildUndelegateTx;
|
|
@@ -49828,6 +49964,27 @@ class SDK {
|
|
|
49828
49964
|
throw e;
|
|
49829
49965
|
}
|
|
49830
49966
|
};
|
|
49967
|
+
this.signMessage = async function(caip, message, addressNList) {
|
|
49968
|
+
let tag6 = TAG14 + " | signMessage | ";
|
|
49969
|
+
try {
|
|
49970
|
+
const transactionDependencies = {
|
|
49971
|
+
context: this.context,
|
|
49972
|
+
assetContext: this.assetContext,
|
|
49973
|
+
balances: this.balances,
|
|
49974
|
+
pioneer: this.pioneer,
|
|
49975
|
+
pubkeys: this.pubkeys,
|
|
49976
|
+
pubkeyContext: this.pubkeyContext,
|
|
49977
|
+
nodes: this.nodes,
|
|
49978
|
+
keepKeySdk: this.keepKeySdk
|
|
49979
|
+
};
|
|
49980
|
+
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
49981
|
+
let signedMessage = await txManager.signMessage({ caip, message, addressNList });
|
|
49982
|
+
return signedMessage;
|
|
49983
|
+
} catch (e) {
|
|
49984
|
+
console.error(e);
|
|
49985
|
+
throw e;
|
|
49986
|
+
}
|
|
49987
|
+
};
|
|
49831
49988
|
this.broadcastTx = async function(caip, signedTx) {
|
|
49832
49989
|
let tag6 = TAG14 + " | broadcastTx | ";
|
|
49833
49990
|
try {
|
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.21.0",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"keepkey-vault-sdk": "^1.0.2",
|
|
7
|
-
"@pioneer-platform/pioneer-caip": "^9.
|
|
7
|
+
"@pioneer-platform/pioneer-caip": "^9.16.0",
|
|
8
8
|
"@pioneer-platform/pioneer-client": "^9.10.24",
|
|
9
|
-
"@pioneer-platform/pioneer-coins": "^9.
|
|
10
|
-
"@pioneer-platform/pioneer-discovery": "^8.
|
|
11
|
-
"@pioneer-platform/pioneer-events": "^8.
|
|
9
|
+
"@pioneer-platform/pioneer-coins": "^9.17.0",
|
|
10
|
+
"@pioneer-platform/pioneer-discovery": "^8.21.0",
|
|
11
|
+
"@pioneer-platform/pioneer-events": "^8.17.0",
|
|
12
12
|
"coinselect": "^3.1.13",
|
|
13
13
|
"eventemitter3": "^5.0.1",
|
|
14
14
|
"neotraverse": "^0.6.8",
|
|
@@ -456,6 +456,93 @@ export class TransactionManager {
|
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
+
async signMessage({ caip, message, addressNList }: any): Promise<any> {
|
|
460
|
+
let tag = TAG + ' | signMessage | ';
|
|
461
|
+
try {
|
|
462
|
+
if (!this.pioneer) throw Error('Failed to init! pioneer');
|
|
463
|
+
if (!caip) throw Error('Missing required param! caip');
|
|
464
|
+
if (!message) throw Error('Missing required param! message');
|
|
465
|
+
if (!addressNList) throw Error('Missing required param! addressNList');
|
|
466
|
+
|
|
467
|
+
const type = await this.classifyCaip(caip);
|
|
468
|
+
|
|
469
|
+
let signedMessage: any;
|
|
470
|
+
|
|
471
|
+
switch (type) {
|
|
472
|
+
case 'OTHER': {
|
|
473
|
+
if (caip.startsWith('solana:')) {
|
|
474
|
+
// Solana message signing via keepkey-server REST API
|
|
475
|
+
const signRequest = {
|
|
476
|
+
addressNList,
|
|
477
|
+
message, // Already base64 encoded
|
|
478
|
+
showDisplay: true
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
try {
|
|
482
|
+
// Create AbortController with 2-minute timeout for manual device confirmation
|
|
483
|
+
const controller = new AbortController();
|
|
484
|
+
const timeoutId = setTimeout(() => controller.abort(), 120000); // 2 minutes
|
|
485
|
+
|
|
486
|
+
try {
|
|
487
|
+
const response = await fetch('http://localhost:1646/solana/sign-message', {
|
|
488
|
+
method: 'POST',
|
|
489
|
+
headers: {
|
|
490
|
+
'Content-Type': 'application/json',
|
|
491
|
+
},
|
|
492
|
+
body: JSON.stringify(signRequest),
|
|
493
|
+
signal: controller.signal
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
clearTimeout(timeoutId);
|
|
497
|
+
|
|
498
|
+
if (!response.ok) {
|
|
499
|
+
const errorData = await response.json();
|
|
500
|
+
throw new Error(`Solana message signing failed: ${errorData.error || response.statusText}`);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const responseSign = await response.json();
|
|
504
|
+
if (responseSign?.signature) {
|
|
505
|
+
signedMessage = {
|
|
506
|
+
signature: responseSign.signature,
|
|
507
|
+
publicKey: responseSign.publicKey
|
|
508
|
+
};
|
|
509
|
+
} else {
|
|
510
|
+
throw new Error('Solana message signing failed - no signature in response');
|
|
511
|
+
}
|
|
512
|
+
} catch (fetchError: any) {
|
|
513
|
+
clearTimeout(timeoutId);
|
|
514
|
+
if (fetchError.name === 'AbortError') {
|
|
515
|
+
throw new Error('Solana message signing timed out after 2 minutes');
|
|
516
|
+
}
|
|
517
|
+
throw fetchError;
|
|
518
|
+
}
|
|
519
|
+
} catch (e: any) {
|
|
520
|
+
console.error(tag, 'Solana message signing error:', e);
|
|
521
|
+
throw new Error(`Solana message signing failed: ${e.message}`);
|
|
522
|
+
}
|
|
523
|
+
} else {
|
|
524
|
+
throw new Error(`Message signing not supported for CAIP: ${caip}`);
|
|
525
|
+
}
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
default: {
|
|
529
|
+
throw new Error(`Message signing not supported for CAIP type: ${type}`);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (!signedMessage) {
|
|
534
|
+
console.error(tag, 'CRITICAL ERROR: signedMessage is missing after signing process');
|
|
535
|
+
console.error(tag, 'CAIP:', caip);
|
|
536
|
+
console.error(tag, 'Type:', type);
|
|
537
|
+
throw Error('Failed to sign message! missing signedMessage');
|
|
538
|
+
}
|
|
539
|
+
return signedMessage;
|
|
540
|
+
} catch (e: any) {
|
|
541
|
+
console.error(tag, e);
|
|
542
|
+
throw e;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
459
546
|
async broadcast({ networkId, serialized }: any): Promise<any> {
|
|
460
547
|
let tag = TAG + ' | broadcast | ';
|
|
461
548
|
try {
|
package/src/fees/index.ts
CHANGED
|
@@ -21,7 +21,7 @@ export interface NormalizedFeeRates {
|
|
|
21
21
|
average: FeeLevel;
|
|
22
22
|
fastest: FeeLevel;
|
|
23
23
|
networkId: string;
|
|
24
|
-
networkType: 'UTXO' | 'EVM' | 'COSMOS' | 'RIPPLE' | 'OTHER';
|
|
24
|
+
networkType: 'UTXO' | 'EVM' | 'COSMOS' | 'RIPPLE' | 'SOLANA' | 'OTHER';
|
|
25
25
|
raw: any; // Original API response for debugging
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -32,11 +32,12 @@ export interface FeeEstimate {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// Network type detection
|
|
35
|
-
function getNetworkType(networkId: string): 'UTXO' | 'EVM' | 'COSMOS' | 'RIPPLE' | 'OTHER' {
|
|
35
|
+
function getNetworkType(networkId: string): 'UTXO' | 'EVM' | 'COSMOS' | 'RIPPLE' | 'SOLANA' | 'OTHER' {
|
|
36
36
|
if (networkId.startsWith('bip122:')) return 'UTXO';
|
|
37
37
|
if (networkId.startsWith('eip155:')) return 'EVM';
|
|
38
38
|
if (networkId.startsWith('cosmos:')) return 'COSMOS';
|
|
39
39
|
if (networkId.startsWith('ripple:')) return 'RIPPLE';
|
|
40
|
+
if (networkId.startsWith('solana:')) return 'SOLANA';
|
|
40
41
|
return 'OTHER';
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -61,6 +62,7 @@ function getNetworkName(networkId: string): string {
|
|
|
61
62
|
'cosmos:thorchain-mainnet-v1': 'THORChain',
|
|
62
63
|
'cosmos:mayachain-mainnet-v1': 'Maya',
|
|
63
64
|
'ripple:4109c6f2045fc7eff4cde8f9905d19c2': 'Ripple',
|
|
65
|
+
'solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp': 'Solana',
|
|
64
66
|
};
|
|
65
67
|
return networkNames[networkId] || networkId;
|
|
66
68
|
}
|
|
@@ -104,6 +106,12 @@ export async function getFees(
|
|
|
104
106
|
return getRippleFees(networkId);
|
|
105
107
|
}
|
|
106
108
|
|
|
109
|
+
// Hardcode Solana fees (fixed fee model)
|
|
110
|
+
if (networkId === 'solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp') {
|
|
111
|
+
console.log(tag, 'Using hardcoded fees for Solana: 0.000005 SOL (5000 lamports)');
|
|
112
|
+
return getSolanaFees(networkId);
|
|
113
|
+
}
|
|
114
|
+
|
|
107
115
|
// Hardcode DOGE fees at 10 sat/byte (API and Blockbook often unreliable for DOGE)
|
|
108
116
|
if (networkId === 'bip122:00000000001a91e3dace36e2be3bf030') {
|
|
109
117
|
console.log(tag, 'Using hardcoded fees for Dogecoin: 10 sat/byte');
|
|
@@ -473,6 +481,8 @@ function getDefaultUnit(networkType: string): string {
|
|
|
473
481
|
return 'uatom';
|
|
474
482
|
case 'RIPPLE':
|
|
475
483
|
return 'XRP';
|
|
484
|
+
case 'SOLANA':
|
|
485
|
+
return 'SOL';
|
|
476
486
|
default:
|
|
477
487
|
return 'units';
|
|
478
488
|
}
|
|
@@ -491,6 +501,8 @@ function getDefaultDescription(networkType: string, networkName: string): string
|
|
|
491
501
|
return `Transaction fee for ${networkName}`;
|
|
492
502
|
case 'RIPPLE':
|
|
493
503
|
return `Fixed transaction fee for ${networkName}`;
|
|
504
|
+
case 'SOLANA':
|
|
505
|
+
return `Fixed transaction fee for ${networkName}`;
|
|
494
506
|
default:
|
|
495
507
|
return `Transaction fee for ${networkName}`;
|
|
496
508
|
}
|
|
@@ -521,6 +533,11 @@ function getEstimatedTime(networkType: string, priority: string): string {
|
|
|
521
533
|
medium: '~4 seconds',
|
|
522
534
|
high: '~4 seconds',
|
|
523
535
|
},
|
|
536
|
+
SOLANA: {
|
|
537
|
+
low: '~1 second',
|
|
538
|
+
medium: '~1 second',
|
|
539
|
+
high: '~1 second',
|
|
540
|
+
},
|
|
524
541
|
};
|
|
525
542
|
|
|
526
543
|
return times[networkType]?.[priority] || '~varies';
|
|
@@ -620,6 +637,48 @@ function getRippleFees(networkId: string): NormalizedFeeRates {
|
|
|
620
637
|
};
|
|
621
638
|
}
|
|
622
639
|
|
|
640
|
+
/**
|
|
641
|
+
* Get hardcoded Solana fees
|
|
642
|
+
* Solana uses a fixed fee model with very low transaction costs (5000 lamports)
|
|
643
|
+
*/
|
|
644
|
+
function getSolanaFees(networkId: string): NormalizedFeeRates {
|
|
645
|
+
const networkName = getNetworkName(networkId);
|
|
646
|
+
|
|
647
|
+
// Solana standard fee is 5000 lamports = 0.000005 SOL
|
|
648
|
+
// This is the typical fee for a simple transfer (1 signature)
|
|
649
|
+
const standardFee = '0.000005';
|
|
650
|
+
|
|
651
|
+
return {
|
|
652
|
+
slow: {
|
|
653
|
+
label: 'Standard',
|
|
654
|
+
value: standardFee,
|
|
655
|
+
unit: 'SOL',
|
|
656
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
657
|
+
estimatedTime: '~1 second',
|
|
658
|
+
priority: 'low',
|
|
659
|
+
},
|
|
660
|
+
average: {
|
|
661
|
+
label: 'Standard',
|
|
662
|
+
value: standardFee,
|
|
663
|
+
unit: 'SOL',
|
|
664
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
665
|
+
estimatedTime: '~1 second',
|
|
666
|
+
priority: 'medium',
|
|
667
|
+
},
|
|
668
|
+
fastest: {
|
|
669
|
+
label: 'Standard',
|
|
670
|
+
value: standardFee,
|
|
671
|
+
unit: 'SOL',
|
|
672
|
+
description: `Fixed fee for ${networkName}. Solana uses a deterministic fee model.`,
|
|
673
|
+
estimatedTime: '~1 second',
|
|
674
|
+
priority: 'high',
|
|
675
|
+
},
|
|
676
|
+
networkId,
|
|
677
|
+
networkType: 'SOLANA',
|
|
678
|
+
raw: { hardcoded: true, fee: standardFee, unit: 'SOL', lamports: 5000 },
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
|
|
623
682
|
/**
|
|
624
683
|
* Get fallback fees when API fails
|
|
625
684
|
*/
|
|
@@ -637,6 +696,7 @@ function getFallbackFees(networkId: string): NormalizedFeeRates {
|
|
|
637
696
|
UTXO: { slow: '1', average: '2', fastest: '3', unit: 'sat/vB' },
|
|
638
697
|
EVM: { slow: '1', average: '1.5', fastest: '2', unit: 'gwei' },
|
|
639
698
|
RIPPLE: { slow: '0.00001', average: '0.00001', fastest: '0.00001', unit: 'XRP' },
|
|
699
|
+
SOLANA: { slow: '0.000005', average: '0.000005', fastest: '0.000005', unit: 'SOL' },
|
|
640
700
|
};
|
|
641
701
|
|
|
642
702
|
const fallback = fallbacks[networkType] || fallbacks.UTXO;
|
|
@@ -709,6 +769,13 @@ export function estimateTransactionFee(
|
|
|
709
769
|
unit: 'XRP',
|
|
710
770
|
};
|
|
711
771
|
|
|
772
|
+
case 'SOLANA':
|
|
773
|
+
// Solana has fixed fees (5000 lamports)
|
|
774
|
+
return {
|
|
775
|
+
amount: feeRate,
|
|
776
|
+
unit: 'SOL',
|
|
777
|
+
};
|
|
778
|
+
|
|
712
779
|
default:
|
|
713
780
|
return {
|
|
714
781
|
amount: feeRate,
|
package/src/index.ts
CHANGED
|
@@ -192,6 +192,7 @@ export class SDK {
|
|
|
192
192
|
}>;
|
|
193
193
|
public broadcastTx: (caip: string, signedTx: any) => Promise<any>;
|
|
194
194
|
public signTx: (caip: string, unsignedTx: any) => Promise<any>;
|
|
195
|
+
public signMessage: (caip: string, message: string, addressNList: number[]) => Promise<any>;
|
|
195
196
|
public buildTx: (sendPayload: any) => Promise<any>;
|
|
196
197
|
public buildDelegateTx: (caip: string, params: StakingTxParams) => Promise<any>;
|
|
197
198
|
public buildUndelegateTx: (caip: string, params: StakingTxParams) => Promise<any>;
|
|
@@ -978,6 +979,27 @@ export class SDK {
|
|
|
978
979
|
throw e;
|
|
979
980
|
}
|
|
980
981
|
};
|
|
982
|
+
this.signMessage = async function (caip: string, message: string, addressNList: number[]) {
|
|
983
|
+
let tag = TAG + ' | signMessage | ';
|
|
984
|
+
try {
|
|
985
|
+
const transactionDependencies = {
|
|
986
|
+
context: this.context,
|
|
987
|
+
assetContext: this.assetContext,
|
|
988
|
+
balances: this.balances,
|
|
989
|
+
pioneer: this.pioneer,
|
|
990
|
+
pubkeys: this.pubkeys,
|
|
991
|
+
pubkeyContext: this.pubkeyContext,
|
|
992
|
+
nodes: this.nodes,
|
|
993
|
+
keepKeySdk: this.keepKeySdk,
|
|
994
|
+
};
|
|
995
|
+
let txManager = new TransactionManager(transactionDependencies, this.events);
|
|
996
|
+
let signedMessage = await txManager.signMessage({ caip, message, addressNList });
|
|
997
|
+
return signedMessage;
|
|
998
|
+
} catch (e) {
|
|
999
|
+
console.error(e);
|
|
1000
|
+
throw e;
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
981
1003
|
this.broadcastTx = async function (caip: string, signedTx: any) {
|
|
982
1004
|
let tag = TAG + ' | broadcastTx | ';
|
|
983
1005
|
try {
|
package/src/supportedCaips.ts
CHANGED
|
@@ -32,7 +32,8 @@ export const CAIP_TO_COIN_MAP: { [key: string]: string } = {
|
|
|
32
32
|
|
|
33
33
|
export const OTHER_SUPPORT = [
|
|
34
34
|
'ripple:4109c6f2045fc7eff4cde8f9905d19c2/slip44:144', // XRP
|
|
35
|
-
'solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp/solana:so11111111111111111111111111111111111111112', // SOL
|
|
35
|
+
'solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp/solana:so11111111111111111111111111111111111111112', // SOL (native asset)
|
|
36
|
+
'solana:5eykt4usfv8p8njdtrepy1vzqkqzkvdp', // SOL (chain-only for message signing)
|
|
36
37
|
'tron:0x2b6653dc/slip44:195', // TRX
|
|
37
38
|
'ton:-239/slip44:607', // TON
|
|
38
39
|
];
|