@sodax/sdk 1.3.1-beta-rc1 → 1.3.1-beta-rc3
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 +1038 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +382 -28
- package/dist/index.d.ts +382 -28
- package/dist/index.mjs +1024 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -5
package/dist/index.cjs
CHANGED
|
@@ -17,6 +17,8 @@ var coreProtoTs = require('@injectivelabs/core-proto-ts');
|
|
|
17
17
|
var rlp = require('rlp');
|
|
18
18
|
var anchor = require('@coral-xyz/anchor');
|
|
19
19
|
var BN = require('bn.js');
|
|
20
|
+
var bitcoin = require('bitcoinjs-lib');
|
|
21
|
+
var ecc = require('@bitcoinerlab/secp256k1');
|
|
20
22
|
|
|
21
23
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
24
|
|
|
@@ -44,6 +46,8 @@ var BigNumber4__default = /*#__PURE__*/_interopDefault(BigNumber4);
|
|
|
44
46
|
var rlp__namespace = /*#__PURE__*/_interopNamespace(rlp);
|
|
45
47
|
var anchor__namespace = /*#__PURE__*/_interopNamespace(anchor);
|
|
46
48
|
var BN__default = /*#__PURE__*/_interopDefault(BN);
|
|
49
|
+
var bitcoin__namespace = /*#__PURE__*/_interopNamespace(bitcoin);
|
|
50
|
+
var ecc__namespace = /*#__PURE__*/_interopNamespace(ecc);
|
|
47
51
|
|
|
48
52
|
// src/shared/abis/asset-manager.abi.ts
|
|
49
53
|
var assetManagerAbi = [
|
|
@@ -6855,7 +6859,7 @@ var stakingRouterAbi = [
|
|
|
6855
6859
|
];
|
|
6856
6860
|
|
|
6857
6861
|
// ../types/dist/constants/index.js
|
|
6858
|
-
var CONFIG_VERSION =
|
|
6862
|
+
var CONFIG_VERSION = 28;
|
|
6859
6863
|
var AVALANCHE_MAINNET_CHAIN_ID = "0xa86a.avax";
|
|
6860
6864
|
var ARBITRUM_MAINNET_CHAIN_ID = "0xa4b1.arbitrum";
|
|
6861
6865
|
var BASE_MAINNET_CHAIN_ID = "0x2105.base";
|
|
@@ -6872,6 +6876,7 @@ var HYPEREVM_MAINNET_CHAIN_ID = "hyper";
|
|
|
6872
6876
|
var LIGHTLINK_MAINNET_CHAIN_ID = "lightlink";
|
|
6873
6877
|
var NEAR_MAINNET_CHAIN_ID = "near";
|
|
6874
6878
|
var ETHEREUM_MAINNET_CHAIN_ID = "ethereum";
|
|
6879
|
+
var BITCOIN_MAINNET_CHAIN_ID = "bitcoin";
|
|
6875
6880
|
var REDBELLY_MAINNET_CHAIN_ID = "redbelly";
|
|
6876
6881
|
var KAIA_MAINNET_CHAIN_ID = "0x2019.kaia";
|
|
6877
6882
|
var HUB_CHAIN_IDS = [SONIC_MAINNET_CHAIN_ID];
|
|
@@ -6892,6 +6897,7 @@ var CHAIN_IDS = [
|
|
|
6892
6897
|
LIGHTLINK_MAINNET_CHAIN_ID,
|
|
6893
6898
|
NEAR_MAINNET_CHAIN_ID,
|
|
6894
6899
|
ETHEREUM_MAINNET_CHAIN_ID,
|
|
6900
|
+
BITCOIN_MAINNET_CHAIN_ID,
|
|
6895
6901
|
REDBELLY_MAINNET_CHAIN_ID,
|
|
6896
6902
|
KAIA_MAINNET_CHAIN_ID
|
|
6897
6903
|
];
|
|
@@ -7006,6 +7012,12 @@ var baseChainInfo = {
|
|
|
7006
7012
|
type: "EVM",
|
|
7007
7013
|
chainId: 1
|
|
7008
7014
|
},
|
|
7015
|
+
[BITCOIN_MAINNET_CHAIN_ID]: {
|
|
7016
|
+
name: "Bitcoin",
|
|
7017
|
+
id: BITCOIN_MAINNET_CHAIN_ID,
|
|
7018
|
+
type: "BITCOIN",
|
|
7019
|
+
chainId: "bitcoin"
|
|
7020
|
+
},
|
|
7009
7021
|
[REDBELLY_MAINNET_CHAIN_ID]: {
|
|
7010
7022
|
name: "Redbelly",
|
|
7011
7023
|
id: REDBELLY_MAINNET_CHAIN_ID,
|
|
@@ -7036,6 +7048,7 @@ var ChainIdToIntentRelayChainId = {
|
|
|
7036
7048
|
[LIGHTLINK_MAINNET_CHAIN_ID]: 27756n,
|
|
7037
7049
|
[NEAR_MAINNET_CHAIN_ID]: 15n,
|
|
7038
7050
|
[ETHEREUM_MAINNET_CHAIN_ID]: 2n,
|
|
7051
|
+
[BITCOIN_MAINNET_CHAIN_ID]: 627463n,
|
|
7039
7052
|
[REDBELLY_MAINNET_CHAIN_ID]: 726564n,
|
|
7040
7053
|
[KAIA_MAINNET_CHAIN_ID]: 27489n
|
|
7041
7054
|
};
|
|
@@ -7948,6 +7961,42 @@ var spokeChainConfig = {
|
|
|
7948
7961
|
rpcUrl: "https://injective-rpc.publicnode.com:443",
|
|
7949
7962
|
walletAddress: ""
|
|
7950
7963
|
},
|
|
7964
|
+
[BITCOIN_MAINNET_CHAIN_ID]: {
|
|
7965
|
+
addresses: {
|
|
7966
|
+
assetManager: "bc1pxguu2r4p9jcxp3gj7dh4r4jd9qzccwpyap3nj5nlapy28s76lhrqw522fz"
|
|
7967
|
+
},
|
|
7968
|
+
chain: baseChainInfo[BITCOIN_MAINNET_CHAIN_ID],
|
|
7969
|
+
bnUSD: "no",
|
|
7970
|
+
nativeToken: "BTC",
|
|
7971
|
+
supportedTokens: {
|
|
7972
|
+
BTC: {
|
|
7973
|
+
symbol: "BTC",
|
|
7974
|
+
name: "Bitcoin",
|
|
7975
|
+
decimals: 8,
|
|
7976
|
+
address: "0:0",
|
|
7977
|
+
xChainId: BITCOIN_MAINNET_CHAIN_ID
|
|
7978
|
+
},
|
|
7979
|
+
bnUSD: {
|
|
7980
|
+
symbol: "bnUSD",
|
|
7981
|
+
name: "bnUSD",
|
|
7982
|
+
decimals: 18,
|
|
7983
|
+
address: "0:0",
|
|
7984
|
+
xChainId: BITCOIN_MAINNET_CHAIN_ID
|
|
7985
|
+
},
|
|
7986
|
+
BUSD: {
|
|
7987
|
+
symbol: "BUSD",
|
|
7988
|
+
name: "BUSDSTABLECOIN",
|
|
7989
|
+
decimals: 6,
|
|
7990
|
+
address: "897442:43",
|
|
7991
|
+
xChainId: BITCOIN_MAINNET_CHAIN_ID
|
|
7992
|
+
}
|
|
7993
|
+
},
|
|
7994
|
+
radfiApiUrl: "https://api.canary.radfi.co/api",
|
|
7995
|
+
radfiApiKey: "",
|
|
7996
|
+
radfiUmsUrl: "https://ums.radfi.co/api",
|
|
7997
|
+
network: "MAINNET",
|
|
7998
|
+
rpcUrl: "https://mempool.space/api"
|
|
7999
|
+
},
|
|
7951
8000
|
[STELLAR_MAINNET_CHAIN_ID]: {
|
|
7952
8001
|
addresses: {
|
|
7953
8002
|
connection: "CDFQDDPUPAM3XPGORHDOEFRNLMKOH3N3X6XTXNLSXJQXIU3RVCM3OPEP",
|
|
@@ -9444,6 +9493,22 @@ var hubAssets = {
|
|
|
9444
9493
|
name: "RedBelly POL",
|
|
9445
9494
|
vault: SodaTokens.sodaPOL.address
|
|
9446
9495
|
}
|
|
9496
|
+
},
|
|
9497
|
+
[BITCOIN_MAINNET_CHAIN_ID]: {
|
|
9498
|
+
[spokeChainConfig[BITCOIN_MAINNET_CHAIN_ID].supportedTokens.BTC.address]: {
|
|
9499
|
+
asset: "0xeb0393893b5bf98a50073d6740738b08e575058b",
|
|
9500
|
+
decimal: 8,
|
|
9501
|
+
symbol: "BTC",
|
|
9502
|
+
name: "Bitcoin",
|
|
9503
|
+
vault: "0x7A1A5555842Ad2D0eD274d09b5c4406a95799D5d"
|
|
9504
|
+
},
|
|
9505
|
+
[spokeChainConfig[BITCOIN_MAINNET_CHAIN_ID].supportedTokens.BUSD.address]: {
|
|
9506
|
+
asset: "0xdb41c7d09406026d4582bc2fc6d6319c323fe1bb",
|
|
9507
|
+
decimal: 6,
|
|
9508
|
+
symbol: "BUSD",
|
|
9509
|
+
name: "BUSD.BUSD.BUSD",
|
|
9510
|
+
vault: "0xE801CA34E19aBCbFeA12025378D19c4FBE250131"
|
|
9511
|
+
}
|
|
9447
9512
|
}
|
|
9448
9513
|
};
|
|
9449
9514
|
var solverConfig = {
|
|
@@ -9584,6 +9649,10 @@ var swapSupportedTokens = {
|
|
|
9584
9649
|
spokeChainConfig[NEAR_MAINNET_CHAIN_ID].supportedTokens.USDC,
|
|
9585
9650
|
spokeChainConfig[NEAR_MAINNET_CHAIN_ID].supportedTokens.USDT
|
|
9586
9651
|
],
|
|
9652
|
+
[BITCOIN_MAINNET_CHAIN_ID]: [
|
|
9653
|
+
spokeChainConfig[BITCOIN_MAINNET_CHAIN_ID].supportedTokens.BTC
|
|
9654
|
+
// spokeChainConfig[BITCOIN_MAINNET_CHAIN_ID].supportedTokens.BUSD, // TODO: re-enable when trading wallet balance is ready
|
|
9655
|
+
],
|
|
9587
9656
|
[ETHEREUM_MAINNET_CHAIN_ID]: [
|
|
9588
9657
|
spokeChainConfig[ETHEREUM_MAINNET_CHAIN_ID].supportedTokens.ETH,
|
|
9589
9658
|
spokeChainConfig[ETHEREUM_MAINNET_CHAIN_ID].supportedTokens.bnUSD,
|
|
@@ -9785,6 +9854,9 @@ var moneyMarketSupportedTokens = {
|
|
|
9785
9854
|
spokeChainConfig[KAIA_MAINNET_CHAIN_ID].supportedTokens.bnUSD,
|
|
9786
9855
|
spokeChainConfig[KAIA_MAINNET_CHAIN_ID].supportedTokens.USDT,
|
|
9787
9856
|
spokeChainConfig[KAIA_MAINNET_CHAIN_ID].supportedTokens.SODA
|
|
9857
|
+
],
|
|
9858
|
+
[BITCOIN_MAINNET_CHAIN_ID]: [
|
|
9859
|
+
spokeChainConfig[BITCOIN_MAINNET_CHAIN_ID].supportedTokens.BTC
|
|
9788
9860
|
]
|
|
9789
9861
|
};
|
|
9790
9862
|
var moneyMarketReserveAssets = [
|
|
@@ -9809,7 +9881,7 @@ var defaultSharedConfig = {
|
|
|
9809
9881
|
};
|
|
9810
9882
|
|
|
9811
9883
|
// ../types/dist/common/index.js
|
|
9812
|
-
var ChainTypeArr = ["ICON", "EVM", "INJECTIVE", "SUI", "STELLAR", "SOLANA", "NEAR"];
|
|
9884
|
+
var ChainTypeArr = ["ICON", "EVM", "INJECTIVE", "SUI", "STELLAR", "SOLANA", "NEAR", "BITCOIN"];
|
|
9813
9885
|
|
|
9814
9886
|
// ../types/dist/injective/index.js
|
|
9815
9887
|
var InjectiveExecuteResponse = class _InjectiveExecuteResponse {
|
|
@@ -9828,6 +9900,17 @@ var InjectiveExecuteResponse = class _InjectiveExecuteResponse {
|
|
|
9828
9900
|
return response;
|
|
9829
9901
|
}
|
|
9830
9902
|
};
|
|
9903
|
+
|
|
9904
|
+
// ../types/dist/btc/index.js
|
|
9905
|
+
function detectBitcoinAddressType(address) {
|
|
9906
|
+
if (address.startsWith("bc1p") || address.startsWith("tb1p"))
|
|
9907
|
+
return "P2TR";
|
|
9908
|
+
if (address.startsWith("bc1") || address.startsWith("tb1"))
|
|
9909
|
+
return "P2WPKH";
|
|
9910
|
+
if (address.startsWith("1") || address.startsWith("m") || address.startsWith("n"))
|
|
9911
|
+
return "P2PKH";
|
|
9912
|
+
throw new Error(`Unknown Bitcoin address type: ${address}`);
|
|
9913
|
+
}
|
|
9831
9914
|
var DEFAULT_MAX_RETRY = 3;
|
|
9832
9915
|
var DEFAULT_RELAY_TX_TIMEOUT = 12e4;
|
|
9833
9916
|
var DEFAULT_RETRY_DELAY_MS = 2e3;
|
|
@@ -21206,6 +21289,714 @@ var SolanaSpokeService = class _SolanaSpokeService {
|
|
|
21206
21289
|
}
|
|
21207
21290
|
}
|
|
21208
21291
|
};
|
|
21292
|
+
|
|
21293
|
+
// src/shared/entities/btc/RadfiProvider.ts
|
|
21294
|
+
var RadfiProvider = class {
|
|
21295
|
+
constructor(config) {
|
|
21296
|
+
this.config = config;
|
|
21297
|
+
}
|
|
21298
|
+
async authenticate(params) {
|
|
21299
|
+
const res = await this.request("/auth/authenticate", {
|
|
21300
|
+
method: "POST",
|
|
21301
|
+
body: JSON.stringify(params)
|
|
21302
|
+
});
|
|
21303
|
+
if (!res.ok) {
|
|
21304
|
+
const err = await res.json();
|
|
21305
|
+
throw new Error(err.message || "Radfi authentication failed");
|
|
21306
|
+
}
|
|
21307
|
+
return res.json().then((r) => ({
|
|
21308
|
+
accessToken: r.data?.accessToken ?? "",
|
|
21309
|
+
refreshToken: r.data?.refreshToken ?? "",
|
|
21310
|
+
tradingAddress: r.data?.tradingAddress ?? r.data?.wallet?.tradingAddress ?? ""
|
|
21311
|
+
}));
|
|
21312
|
+
}
|
|
21313
|
+
async refreshAccessToken(refreshToken) {
|
|
21314
|
+
const res = await this.request("/auth/refresh-token", {
|
|
21315
|
+
method: "POST",
|
|
21316
|
+
body: JSON.stringify({ refreshToken })
|
|
21317
|
+
});
|
|
21318
|
+
if (!res.ok) {
|
|
21319
|
+
const err = await res.json();
|
|
21320
|
+
throw new Error(err.message || "Token refresh failed");
|
|
21321
|
+
}
|
|
21322
|
+
return res.json().then((r) => ({
|
|
21323
|
+
accessToken: r.data?.accessToken ?? "",
|
|
21324
|
+
refreshToken: r.data?.refreshToken ?? refreshToken
|
|
21325
|
+
}));
|
|
21326
|
+
}
|
|
21327
|
+
async createTradingWallet(params, accessToken) {
|
|
21328
|
+
const res = await this.request("/wallets", {
|
|
21329
|
+
method: "POST",
|
|
21330
|
+
headers: {
|
|
21331
|
+
Authorization: `Bearer ${accessToken || this.config.apiKey}`
|
|
21332
|
+
},
|
|
21333
|
+
body: JSON.stringify(params)
|
|
21334
|
+
});
|
|
21335
|
+
if (!res.ok) {
|
|
21336
|
+
const err = await res.json();
|
|
21337
|
+
throw new Error(err.message || "Failed to create trading wallet");
|
|
21338
|
+
}
|
|
21339
|
+
return res.json().then((r) => r.data);
|
|
21340
|
+
}
|
|
21341
|
+
async getTradingWallet(userAddress, accessToken) {
|
|
21342
|
+
const res = await this.request(`/wallets/details/${userAddress}`, {
|
|
21343
|
+
method: "GET",
|
|
21344
|
+
headers: accessToken ? { Authorization: `Bearer ${accessToken}` } : {}
|
|
21345
|
+
});
|
|
21346
|
+
if (!res.ok) {
|
|
21347
|
+
throw new Error("Trading wallet not found");
|
|
21348
|
+
}
|
|
21349
|
+
const data = await res.json().then((r) => r.data);
|
|
21350
|
+
if (!data) throw new Error("Trading wallet not found");
|
|
21351
|
+
return data;
|
|
21352
|
+
}
|
|
21353
|
+
async getBalance(address) {
|
|
21354
|
+
if (!this.config.umsUrl) {
|
|
21355
|
+
throw new Error("RadfiConfig.umsUrl is required for getBalance");
|
|
21356
|
+
}
|
|
21357
|
+
const umsUrl = this.config.umsUrl;
|
|
21358
|
+
const res = await fetch(`${umsUrl}/wallets/balance?address=${address}`, {
|
|
21359
|
+
method: "GET",
|
|
21360
|
+
headers: { "Content-Type": "application/json" }
|
|
21361
|
+
});
|
|
21362
|
+
if (!res.ok) {
|
|
21363
|
+
throw new Error("Failed to fetch wallet balance");
|
|
21364
|
+
}
|
|
21365
|
+
const { data } = await res.json();
|
|
21366
|
+
return {
|
|
21367
|
+
btcSatoshi: BigInt(data.btcSatoshi ?? "0"),
|
|
21368
|
+
pendingSatoshi: BigInt(data.pendingSatoshi ?? "0"),
|
|
21369
|
+
externalPendingSatoshi: BigInt(data.externalPendingSatoshi ?? "0"),
|
|
21370
|
+
totalUtxos: Number(data.totalUtxos ?? 0)
|
|
21371
|
+
};
|
|
21372
|
+
}
|
|
21373
|
+
async checkIfTradingWalletExists(userAddress) {
|
|
21374
|
+
try {
|
|
21375
|
+
await this.getTradingWallet(userAddress);
|
|
21376
|
+
return true;
|
|
21377
|
+
} catch (error) {
|
|
21378
|
+
return false;
|
|
21379
|
+
}
|
|
21380
|
+
}
|
|
21381
|
+
async createWithdrawTransaction(params, accessToken) {
|
|
21382
|
+
const res = await this.request("/sodax/transaction", {
|
|
21383
|
+
method: "POST",
|
|
21384
|
+
headers: {
|
|
21385
|
+
Authorization: `Bearer ${accessToken ?? this.config.apiKey}`
|
|
21386
|
+
},
|
|
21387
|
+
body: JSON.stringify({
|
|
21388
|
+
type: "sodax-withdraw",
|
|
21389
|
+
params: {
|
|
21390
|
+
amount: params.amount.toString(),
|
|
21391
|
+
tokenId: params.token,
|
|
21392
|
+
sodaxData: params.data
|
|
21393
|
+
}
|
|
21394
|
+
})
|
|
21395
|
+
});
|
|
21396
|
+
if (!res.ok) {
|
|
21397
|
+
const err = await res.json();
|
|
21398
|
+
throw new Error(err.message || "Radfi transaction request failed");
|
|
21399
|
+
}
|
|
21400
|
+
return res.json().then((r) => r.data);
|
|
21401
|
+
}
|
|
21402
|
+
async requestRadfiSignature(params, accessToken) {
|
|
21403
|
+
const res = await this.request("/sodax/transaction/sign", {
|
|
21404
|
+
method: "POST",
|
|
21405
|
+
headers: {
|
|
21406
|
+
Authorization: `Bearer ${accessToken ?? this.config.apiKey}`
|
|
21407
|
+
},
|
|
21408
|
+
body: JSON.stringify({
|
|
21409
|
+
type: "sodax-withdraw",
|
|
21410
|
+
params
|
|
21411
|
+
})
|
|
21412
|
+
});
|
|
21413
|
+
if (!res.ok) {
|
|
21414
|
+
const err = await res.json();
|
|
21415
|
+
throw new Error(err.message || "Radfi signature request failed");
|
|
21416
|
+
}
|
|
21417
|
+
return res.json().then((r) => r.data.txId);
|
|
21418
|
+
}
|
|
21419
|
+
/**
|
|
21420
|
+
* Fetch expired (or near-expiry) UTXOs for a trading wallet address from UMS API.
|
|
21421
|
+
*/
|
|
21422
|
+
async getExpiredUtxos(tradingAddress, params) {
|
|
21423
|
+
if (!this.config.umsUrl) {
|
|
21424
|
+
throw new Error("RadfiConfig.umsUrl is required for getExpiredUtxos");
|
|
21425
|
+
}
|
|
21426
|
+
const page = params?.page ?? 1;
|
|
21427
|
+
const pageSize = params?.pageSize ?? 100;
|
|
21428
|
+
const url = `${this.config.umsUrl}/utxos?address_eq=${tradingAddress}&isSpent_eq=false&isExpired_eq=true&page=${page}&pageSize=${pageSize}`;
|
|
21429
|
+
const res = await fetch(url, {
|
|
21430
|
+
method: "GET",
|
|
21431
|
+
headers: { "Content-Type": "application/json" }
|
|
21432
|
+
});
|
|
21433
|
+
if (!res.ok) {
|
|
21434
|
+
throw new Error("Failed to fetch expired UTXOs");
|
|
21435
|
+
}
|
|
21436
|
+
return res.json();
|
|
21437
|
+
}
|
|
21438
|
+
/**
|
|
21439
|
+
* Build a renew-utxo transaction via the Radfi API.
|
|
21440
|
+
* Returns a PSBT that needs to be signed by the user.
|
|
21441
|
+
*/
|
|
21442
|
+
async buildRenewUtxoTransaction(params, accessToken) {
|
|
21443
|
+
const res = await this.request("/transactions", {
|
|
21444
|
+
method: "POST",
|
|
21445
|
+
headers: {
|
|
21446
|
+
Authorization: `Bearer ${accessToken}`
|
|
21447
|
+
},
|
|
21448
|
+
body: JSON.stringify({
|
|
21449
|
+
type: "renew-utxo",
|
|
21450
|
+
params: {
|
|
21451
|
+
userAddress: params.userAddress,
|
|
21452
|
+
txIdVouts: params.txIdVouts
|
|
21453
|
+
}
|
|
21454
|
+
})
|
|
21455
|
+
});
|
|
21456
|
+
if (!res.ok) {
|
|
21457
|
+
const err = await res.json();
|
|
21458
|
+
throw new Error(err.message || "Failed to build renew-utxo transaction");
|
|
21459
|
+
}
|
|
21460
|
+
return res.json().then((r) => r.data);
|
|
21461
|
+
}
|
|
21462
|
+
/**
|
|
21463
|
+
* Sign and broadcast a renew-utxo transaction via the Radfi API.
|
|
21464
|
+
* The user signs the PSBT first, then Radfi co-signs and broadcasts.
|
|
21465
|
+
*/
|
|
21466
|
+
async signAndBroadcastRenewUtxo(params, accessToken) {
|
|
21467
|
+
const res = await this.request("/transactions/sign", {
|
|
21468
|
+
method: "POST",
|
|
21469
|
+
headers: {
|
|
21470
|
+
Authorization: `Bearer ${accessToken}`
|
|
21471
|
+
},
|
|
21472
|
+
body: JSON.stringify({
|
|
21473
|
+
type: "renew-utxo",
|
|
21474
|
+
params
|
|
21475
|
+
})
|
|
21476
|
+
});
|
|
21477
|
+
if (!res.ok) {
|
|
21478
|
+
const err = await res.json();
|
|
21479
|
+
throw new Error(err.message || "Failed to sign and broadcast renew-utxo transaction");
|
|
21480
|
+
}
|
|
21481
|
+
return res.json().then((r) => r.data.txId);
|
|
21482
|
+
}
|
|
21483
|
+
async request(endpoint, options) {
|
|
21484
|
+
return fetch(`${this.config.url}${endpoint}`, {
|
|
21485
|
+
...options,
|
|
21486
|
+
headers: {
|
|
21487
|
+
"Content-Type": "application/json",
|
|
21488
|
+
...options?.headers || {}
|
|
21489
|
+
}
|
|
21490
|
+
});
|
|
21491
|
+
}
|
|
21492
|
+
};
|
|
21493
|
+
bitcoin__namespace.initEccLib(ecc__namespace);
|
|
21494
|
+
var BITCOIN_DEFAULT_FEE_RATE = 3;
|
|
21495
|
+
var DUST_THRESHOLD = 546;
|
|
21496
|
+
function normalizePsbtToBase64(signedPsbt) {
|
|
21497
|
+
const isHex = /^[0-9a-fA-F]+$/.test(signedPsbt);
|
|
21498
|
+
return isHex ? Buffer.from(signedPsbt, "hex").toString("base64") : signedPsbt;
|
|
21499
|
+
}
|
|
21500
|
+
var BitcoinBaseSpokeProvider = class _BitcoinBaseSpokeProvider {
|
|
21501
|
+
rpcUrl;
|
|
21502
|
+
network;
|
|
21503
|
+
chainConfig;
|
|
21504
|
+
radfi;
|
|
21505
|
+
walletMode;
|
|
21506
|
+
radfiAccessToken = "";
|
|
21507
|
+
constructor(config, radfiConfig, walletMode = "USER", rpcURL) {
|
|
21508
|
+
this.chainConfig = config;
|
|
21509
|
+
this.rpcUrl = rpcURL ?? config.rpcUrl;
|
|
21510
|
+
this.network = config.network === "TESTNET" ? bitcoin__namespace.networks.testnet : bitcoin__namespace.networks.bitcoin;
|
|
21511
|
+
this.radfi = new RadfiProvider(radfiConfig);
|
|
21512
|
+
this.walletMode = walletMode;
|
|
21513
|
+
}
|
|
21514
|
+
setRadfiAccessToken(token) {
|
|
21515
|
+
this.radfiAccessToken = token;
|
|
21516
|
+
}
|
|
21517
|
+
/**
|
|
21518
|
+
* Get current fee estimates
|
|
21519
|
+
*/
|
|
21520
|
+
async getFeeEstimate(targetBlocks = 6) {
|
|
21521
|
+
try {
|
|
21522
|
+
const response = await fetch(`${this.rpcUrl}/fee-estimates`);
|
|
21523
|
+
if (!response.ok) {
|
|
21524
|
+
return BITCOIN_DEFAULT_FEE_RATE;
|
|
21525
|
+
}
|
|
21526
|
+
const feeEstimates = await response.json();
|
|
21527
|
+
return feeEstimates[targetBlocks] ?? BITCOIN_DEFAULT_FEE_RATE;
|
|
21528
|
+
} catch {
|
|
21529
|
+
return BITCOIN_DEFAULT_FEE_RATE;
|
|
21530
|
+
}
|
|
21531
|
+
}
|
|
21532
|
+
static async getBalance(tokenAddress, provider) {
|
|
21533
|
+
const walletAddress = await provider.walletProvider.getWalletAddress();
|
|
21534
|
+
if (!tokenAddress || tokenAddress === "0x" || tokenAddress === "BTC") {
|
|
21535
|
+
const utxos = await provider.fetchUTXOs(walletAddress);
|
|
21536
|
+
const totalBalance = utxos.reduce((sum, utxo) => sum + utxo.value, 0);
|
|
21537
|
+
return BigInt(totalBalance);
|
|
21538
|
+
}
|
|
21539
|
+
throw new Error("Token balance queries not yet implemented for non-BTC assets");
|
|
21540
|
+
}
|
|
21541
|
+
async fetchScriptPubKey(utxo, provider) {
|
|
21542
|
+
const txHex = await provider.fetchRawTransaction(utxo.txid);
|
|
21543
|
+
const tx = bitcoin__namespace.Transaction.fromHex(txHex);
|
|
21544
|
+
const out = tx.outs[utxo.vout];
|
|
21545
|
+
if (!out) {
|
|
21546
|
+
throw new Error(`UTXO not found: ${utxo.txid}:${utxo.vout}`);
|
|
21547
|
+
}
|
|
21548
|
+
return out.script.toString("hex");
|
|
21549
|
+
}
|
|
21550
|
+
/**
|
|
21551
|
+
* Build a priority Bitcoin transaction with proper fee calculation
|
|
21552
|
+
*/
|
|
21553
|
+
static async buildBitcoinTransaction(utxos, outputs, changeAddress, provider, feeRate) {
|
|
21554
|
+
const psbt = new bitcoin__namespace.Psbt({ network: provider.network });
|
|
21555
|
+
const effectiveFeeRate = feeRate ?? await provider.getFeeEstimate();
|
|
21556
|
+
let inputSum = 0;
|
|
21557
|
+
const outputSum = outputs.reduce((sum, o) => sum + o.value, 0);
|
|
21558
|
+
for (const utxo of utxos) {
|
|
21559
|
+
if (!utxo.status.confirmed) continue;
|
|
21560
|
+
const scriptPubKey = await provider.fetchScriptPubKey(utxo, provider);
|
|
21561
|
+
const isTaproot = scriptPubKey.startsWith("51");
|
|
21562
|
+
const isSegwitV0 = scriptPubKey.startsWith("00");
|
|
21563
|
+
if (isTaproot) {
|
|
21564
|
+
if (!provider.walletProvider.getPublicKey) {
|
|
21565
|
+
throw new Error("Missing public key for P2TR input");
|
|
21566
|
+
}
|
|
21567
|
+
const tapInternalKey = await provider.walletProvider.getPublicKey();
|
|
21568
|
+
psbt.addInput({
|
|
21569
|
+
hash: utxo.txid,
|
|
21570
|
+
index: utxo.vout,
|
|
21571
|
+
witnessUtxo: {
|
|
21572
|
+
script: Buffer.from(scriptPubKey, "hex"),
|
|
21573
|
+
value: utxo.value
|
|
21574
|
+
},
|
|
21575
|
+
tapInternalKey: Buffer.from(tapInternalKey, "hex")
|
|
21576
|
+
});
|
|
21577
|
+
} else if (isSegwitV0) {
|
|
21578
|
+
psbt.addInput({
|
|
21579
|
+
hash: utxo.txid,
|
|
21580
|
+
index: utxo.vout,
|
|
21581
|
+
witnessUtxo: {
|
|
21582
|
+
script: Buffer.from(scriptPubKey, "hex"),
|
|
21583
|
+
value: utxo.value
|
|
21584
|
+
}
|
|
21585
|
+
});
|
|
21586
|
+
} else {
|
|
21587
|
+
const txHex = await provider.fetchRawTransaction(utxo.txid);
|
|
21588
|
+
psbt.addInput({
|
|
21589
|
+
hash: utxo.txid,
|
|
21590
|
+
index: utxo.vout,
|
|
21591
|
+
nonWitnessUtxo: Buffer.from(txHex, "hex")
|
|
21592
|
+
});
|
|
21593
|
+
}
|
|
21594
|
+
inputSum += utxo.value;
|
|
21595
|
+
const estimatedSize = provider.estimateTxSize(psbt.inputCount, outputs.length);
|
|
21596
|
+
const estimatedFee = Math.ceil(effectiveFeeRate * estimatedSize);
|
|
21597
|
+
if (inputSum >= outputSum + estimatedFee + DUST_THRESHOLD) {
|
|
21598
|
+
break;
|
|
21599
|
+
}
|
|
21600
|
+
}
|
|
21601
|
+
for (const output of outputs) {
|
|
21602
|
+
psbt.addOutput({
|
|
21603
|
+
address: output.address,
|
|
21604
|
+
value: output.value
|
|
21605
|
+
});
|
|
21606
|
+
}
|
|
21607
|
+
const sizeWithChange = provider.estimateTxSize(psbt.inputCount, outputs.length + 1);
|
|
21608
|
+
const sizeWithoutChange = provider.estimateTxSize(psbt.inputCount, outputs.length);
|
|
21609
|
+
const feeWithChange = Math.ceil(effectiveFeeRate * sizeWithChange);
|
|
21610
|
+
const feeWithoutChange = Math.ceil(effectiveFeeRate * sizeWithoutChange);
|
|
21611
|
+
let change = inputSum - outputSum - feeWithChange;
|
|
21612
|
+
if (change < 0) {
|
|
21613
|
+
const confirmedCount = utxos.filter((u) => u.status.confirmed).length;
|
|
21614
|
+
const unconfirmedCount = utxos.length - confirmedCount;
|
|
21615
|
+
const hint = unconfirmedCount > 0 ? ` (${unconfirmedCount} unconfirmed UTXO(s) skipped \u2014 wait for confirmation)` : "";
|
|
21616
|
+
throw new Error(`Insufficient funds. Need ${outputSum + feeWithChange} satoshis, have ${inputSum}${hint}`);
|
|
21617
|
+
}
|
|
21618
|
+
if (change > DUST_THRESHOLD) {
|
|
21619
|
+
psbt.addOutput({
|
|
21620
|
+
address: changeAddress,
|
|
21621
|
+
value: change
|
|
21622
|
+
});
|
|
21623
|
+
} else {
|
|
21624
|
+
const finalFee = feeWithoutChange;
|
|
21625
|
+
change = inputSum - outputSum - finalFee;
|
|
21626
|
+
if (change < 0) {
|
|
21627
|
+
throw new Error(`Insufficient funds after dust handling. Need ${outputSum + finalFee}`);
|
|
21628
|
+
}
|
|
21629
|
+
}
|
|
21630
|
+
return psbt;
|
|
21631
|
+
}
|
|
21632
|
+
/**
|
|
21633
|
+
* Deposit operation - transfer BTC to the asset manager
|
|
21634
|
+
*/
|
|
21635
|
+
static async deposit(token, amount, data, provider, raw, accessToken = "") {
|
|
21636
|
+
try {
|
|
21637
|
+
const walletAddress = await provider.walletProvider.getWalletAddress();
|
|
21638
|
+
const returnRawTx = (psbtBase64) => ({
|
|
21639
|
+
from: walletAddress,
|
|
21640
|
+
to: provider.chainConfig.addresses.assetManager,
|
|
21641
|
+
value: amount,
|
|
21642
|
+
data: psbtBase64
|
|
21643
|
+
});
|
|
21644
|
+
if (provider.walletMode === "TRADING") {
|
|
21645
|
+
const tokenId = Object.values(provider.chainConfig.supportedTokens).find((t) => t.address === token)?.address;
|
|
21646
|
+
if (!tokenId) {
|
|
21647
|
+
throw new Error(`Unsupported token: ${token}`);
|
|
21648
|
+
}
|
|
21649
|
+
data = data.startsWith("0x") ? data.slice(2) : data;
|
|
21650
|
+
data = data.length === 64 ? data : viem.keccak256(`0x${data}`).slice(2);
|
|
21651
|
+
accessToken = accessToken || provider.radfiAccessToken;
|
|
21652
|
+
const withdrawTx = await provider.radfi.createWithdrawTransaction(
|
|
21653
|
+
{
|
|
21654
|
+
token: tokenId,
|
|
21655
|
+
amount,
|
|
21656
|
+
recipient: provider.chainConfig.addresses.assetManager,
|
|
21657
|
+
userAddress: walletAddress,
|
|
21658
|
+
data
|
|
21659
|
+
},
|
|
21660
|
+
accessToken
|
|
21661
|
+
);
|
|
21662
|
+
if (raw || isBitcoinRawSpokeProvider(provider)) {
|
|
21663
|
+
return returnRawTx(withdrawTx.base64Psbt);
|
|
21664
|
+
}
|
|
21665
|
+
const signedTx = await provider.walletProvider.signTransaction(withdrawTx.base64Psbt, false);
|
|
21666
|
+
const signedBase64Tx = normalizePsbtToBase64(signedTx);
|
|
21667
|
+
return await provider.radfi.requestRadfiSignature(
|
|
21668
|
+
{
|
|
21669
|
+
userAddress: walletAddress,
|
|
21670
|
+
signedBase64Tx
|
|
21671
|
+
},
|
|
21672
|
+
accessToken
|
|
21673
|
+
);
|
|
21674
|
+
}
|
|
21675
|
+
const utxos = await provider.fetchUTXOs(walletAddress);
|
|
21676
|
+
if (!utxos?.length) {
|
|
21677
|
+
throw new Error("No UTXOs available for deposit");
|
|
21678
|
+
}
|
|
21679
|
+
const depositPsbt = await _BitcoinBaseSpokeProvider.buildDepositPsbt(
|
|
21680
|
+
walletAddress,
|
|
21681
|
+
token,
|
|
21682
|
+
amount,
|
|
21683
|
+
data,
|
|
21684
|
+
utxos,
|
|
21685
|
+
provider
|
|
21686
|
+
);
|
|
21687
|
+
if (raw || isBitcoinRawSpokeProvider(provider)) {
|
|
21688
|
+
return returnRawTx(depositPsbt.toBase64());
|
|
21689
|
+
}
|
|
21690
|
+
return await provider.signAndBroadcastTransaction(depositPsbt);
|
|
21691
|
+
} catch (error) {
|
|
21692
|
+
console.error("Error during deposit:", error);
|
|
21693
|
+
throw error;
|
|
21694
|
+
}
|
|
21695
|
+
}
|
|
21696
|
+
/**
|
|
21697
|
+
* Build deposit PSBT with embedded cross-chain data
|
|
21698
|
+
*/
|
|
21699
|
+
static async buildDepositPsbt(walletAddress, token, amount, data, utxos, provider) {
|
|
21700
|
+
const assetManagerAddress = provider.chainConfig.addresses.assetManager;
|
|
21701
|
+
if (token.toLocaleLowerCase() === "btc") {
|
|
21702
|
+
const outputs = [
|
|
21703
|
+
{
|
|
21704
|
+
address: assetManagerAddress,
|
|
21705
|
+
value: Number(amount)
|
|
21706
|
+
}
|
|
21707
|
+
];
|
|
21708
|
+
const psbt = await _BitcoinBaseSpokeProvider.buildBitcoinTransaction(utxos, outputs, walletAddress, provider);
|
|
21709
|
+
const OP_RADFI_SODAX_DATA = 49;
|
|
21710
|
+
const payload = Buffer.concat([Buffer.from([OP_RADFI_SODAX_DATA]), Buffer.from(data.slice(2), "hex")]);
|
|
21711
|
+
const OP_RETURN = bitcoin__namespace.opcodes.OP_RETURN;
|
|
21712
|
+
const OP_12 = bitcoin__namespace.opcodes.OP_12;
|
|
21713
|
+
if (OP_RETURN === void 0 || OP_12 === void 0) {
|
|
21714
|
+
throw new Error("bitcoinjs-lib opcodes OP_RETURN or OP_12 are undefined");
|
|
21715
|
+
}
|
|
21716
|
+
const script2 = bitcoin__namespace.script.compile([OP_RETURN, OP_12, payload]);
|
|
21717
|
+
psbt.addOutput({
|
|
21718
|
+
script: script2,
|
|
21719
|
+
value: 0
|
|
21720
|
+
});
|
|
21721
|
+
return psbt;
|
|
21722
|
+
}
|
|
21723
|
+
throw new Error(`Non-BTC token deposits not yet implemented (token: ${token})`);
|
|
21724
|
+
}
|
|
21725
|
+
/**
|
|
21726
|
+
* Fetch UTXOs for an address
|
|
21727
|
+
*/
|
|
21728
|
+
async fetchUTXOs(address) {
|
|
21729
|
+
const response = await fetch(`${this.rpcUrl}/address/${address}/utxo`);
|
|
21730
|
+
if (!response.ok) {
|
|
21731
|
+
throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
|
|
21732
|
+
}
|
|
21733
|
+
return await response.json();
|
|
21734
|
+
}
|
|
21735
|
+
/**
|
|
21736
|
+
* Fetch raw transaction hex
|
|
21737
|
+
*/
|
|
21738
|
+
async fetchRawTransaction(txid) {
|
|
21739
|
+
const response = await fetch(`${this.rpcUrl}/tx/${txid}/hex`);
|
|
21740
|
+
if (!response.ok) {
|
|
21741
|
+
throw new Error(`Failed to fetch transaction: ${response.statusText}`);
|
|
21742
|
+
}
|
|
21743
|
+
return await response.text();
|
|
21744
|
+
}
|
|
21745
|
+
/**
|
|
21746
|
+
* Estimate transaction size in vbytes
|
|
21747
|
+
*/
|
|
21748
|
+
estimateTxSize(inputCount, outputCount) {
|
|
21749
|
+
return Math.ceil(10.5 + 44 + inputCount * 68 + outputCount * 31);
|
|
21750
|
+
}
|
|
21751
|
+
getAddressType(address) {
|
|
21752
|
+
return detectBitcoinAddressType(address);
|
|
21753
|
+
}
|
|
21754
|
+
encodePayloadToBytes(payload) {
|
|
21755
|
+
const ordered = {
|
|
21756
|
+
src_address: payload.src_address.toLowerCase(),
|
|
21757
|
+
data: payload.data.toLowerCase(),
|
|
21758
|
+
src_chain_id: payload.src_chain_id,
|
|
21759
|
+
dst_chain_id: payload.dst_chain_id,
|
|
21760
|
+
wallet_used: payload.wallet_used,
|
|
21761
|
+
timestamp: payload.timestamp,
|
|
21762
|
+
address_type: payload.address_type
|
|
21763
|
+
};
|
|
21764
|
+
const json = JSON.stringify(ordered);
|
|
21765
|
+
return json;
|
|
21766
|
+
}
|
|
21767
|
+
static async encodeWithdrawalData(dstChainId, data, provider, raw) {
|
|
21768
|
+
let srcAddress = await provider.walletProvider.getWalletAddress();
|
|
21769
|
+
const addressType = provider.getAddressType(srcAddress);
|
|
21770
|
+
if (provider.walletMode === "TRADING") {
|
|
21771
|
+
srcAddress = await provider.radfi.getTradingWallet(srcAddress).then((res) => res.tradingAddress).catch(() => srcAddress);
|
|
21772
|
+
}
|
|
21773
|
+
const payload = {
|
|
21774
|
+
src_address: srcAddress,
|
|
21775
|
+
data,
|
|
21776
|
+
src_chain_id: Number(getIntentRelayChainId(provider.chainConfig.chain.id)),
|
|
21777
|
+
dst_chain_id: Number(getIntentRelayChainId(dstChainId)),
|
|
21778
|
+
wallet_used: provider.walletMode,
|
|
21779
|
+
timestamp: Date.now(),
|
|
21780
|
+
address_type: addressType
|
|
21781
|
+
};
|
|
21782
|
+
const orderedPayload = provider.encodePayloadToBytes(payload);
|
|
21783
|
+
const onDemandWithdraw = {
|
|
21784
|
+
payload_hex: Buffer.from(orderedPayload).toString("hex"),
|
|
21785
|
+
signature: void 0
|
|
21786
|
+
};
|
|
21787
|
+
if (raw || isBitcoinRawSpokeProvider(provider)) {
|
|
21788
|
+
return JSON.stringify(onDemandWithdraw);
|
|
21789
|
+
}
|
|
21790
|
+
const signature = await provider.walletProvider.signEcdsaMessage(orderedPayload);
|
|
21791
|
+
onDemandWithdraw.signature = signature;
|
|
21792
|
+
return JSON.stringify(onDemandWithdraw);
|
|
21793
|
+
}
|
|
21794
|
+
};
|
|
21795
|
+
var BitcoinRawSpokeProvider = class extends BitcoinBaseSpokeProvider {
|
|
21796
|
+
walletProvider;
|
|
21797
|
+
raw = true;
|
|
21798
|
+
constructor(walletAddress, publicKey, chainConfig, radfiConfig, walletMode = "USER", rpcUrl) {
|
|
21799
|
+
super(chainConfig, radfiConfig, walletMode, rpcUrl);
|
|
21800
|
+
this.walletProvider = {
|
|
21801
|
+
getWalletAddress: async () => walletAddress,
|
|
21802
|
+
getPublicKey: async () => publicKey
|
|
21803
|
+
};
|
|
21804
|
+
}
|
|
21805
|
+
};
|
|
21806
|
+
var BitcoinSpokeProvider = class extends BitcoinBaseSpokeProvider {
|
|
21807
|
+
walletProvider;
|
|
21808
|
+
constructor(walletProvider, chainConfig, radfiConfig, walletMode = "USER", rpcUrl) {
|
|
21809
|
+
super(chainConfig, radfiConfig, walletMode, rpcUrl);
|
|
21810
|
+
this.walletProvider = walletProvider;
|
|
21811
|
+
}
|
|
21812
|
+
/**
|
|
21813
|
+
* Authenticate with Radfi: BIP322-sign a login message, then call the Radfi API.
|
|
21814
|
+
* Returns accessToken, refreshToken, and tradingAddress.
|
|
21815
|
+
*/
|
|
21816
|
+
async authenticateWithWallet(cachedPublicKey) {
|
|
21817
|
+
const address = await this.walletProvider.getWalletAddress();
|
|
21818
|
+
let publicKey = cachedPublicKey;
|
|
21819
|
+
if (!publicKey) {
|
|
21820
|
+
if (!this.walletProvider.getPublicKey) {
|
|
21821
|
+
throw new Error("Wallet provider does not support getPublicKey");
|
|
21822
|
+
}
|
|
21823
|
+
publicKey = await this.walletProvider.getPublicKey();
|
|
21824
|
+
}
|
|
21825
|
+
if (!publicKey) {
|
|
21826
|
+
throw new Error("Failed to retrieve public key from wallet. Please unlock your wallet and try again.");
|
|
21827
|
+
}
|
|
21828
|
+
const message = `Login to Radfi via Sodax: ${Date.now()}`;
|
|
21829
|
+
const signature = await this.walletProvider.signBip322Message(message);
|
|
21830
|
+
const result = await this.radfi.authenticate({ message, signature, address, publicKey });
|
|
21831
|
+
this.setRadfiAccessToken(result.accessToken);
|
|
21832
|
+
return { ...result, publicKey };
|
|
21833
|
+
}
|
|
21834
|
+
/**
|
|
21835
|
+
* Ensure a valid Radfi access token is set on this provider.
|
|
21836
|
+
* No-op if a token is already present.
|
|
21837
|
+
*/
|
|
21838
|
+
async ensureRadfiAccessToken() {
|
|
21839
|
+
if (this.radfiAccessToken) return;
|
|
21840
|
+
await this.authenticateWithWallet();
|
|
21841
|
+
}
|
|
21842
|
+
/**
|
|
21843
|
+
* Sign and broadcast a Bitcoin transaction
|
|
21844
|
+
*/
|
|
21845
|
+
async signAndBroadcastTransaction(psbt) {
|
|
21846
|
+
const psbtBase64 = typeof psbt === "string" ? psbt : psbt.toBase64();
|
|
21847
|
+
const signedPsbtHex = await this.walletProvider.signTransaction(psbtBase64);
|
|
21848
|
+
const txHash = await this.broadcastTransaction(signedPsbtHex);
|
|
21849
|
+
return txHash;
|
|
21850
|
+
}
|
|
21851
|
+
/**
|
|
21852
|
+
* Broadcast a signed transaction
|
|
21853
|
+
*/
|
|
21854
|
+
async broadcastTransaction(txHex) {
|
|
21855
|
+
const response = await fetch(`${this.rpcUrl}/tx`, {
|
|
21856
|
+
method: "POST",
|
|
21857
|
+
body: txHex
|
|
21858
|
+
});
|
|
21859
|
+
if (!response.ok) {
|
|
21860
|
+
const errorText = await response.text();
|
|
21861
|
+
throw new Error(`Failed to broadcast transaction: ${errorText}`);
|
|
21862
|
+
}
|
|
21863
|
+
return await response.text();
|
|
21864
|
+
}
|
|
21865
|
+
};
|
|
21866
|
+
|
|
21867
|
+
// src/shared/services/spoke/BitcoinSpokeService.ts
|
|
21868
|
+
var BitcoinSpokeService = class _BitcoinSpokeService {
|
|
21869
|
+
constructor() {
|
|
21870
|
+
}
|
|
21871
|
+
/**
|
|
21872
|
+
* Estimate transaction fee for a Bitcoin transaction
|
|
21873
|
+
*
|
|
21874
|
+
* @param {Hex} rawTx - The raw transaction parameters
|
|
21875
|
+
* @param {BitcoinSpokeProviderType} spokeProvider - The Bitcoin spoke provider
|
|
21876
|
+
* @returns {Promise<bigint>} Estimated fee in satoshis
|
|
21877
|
+
*/
|
|
21878
|
+
static async estimateGas(rawTx, spokeProvider) {
|
|
21879
|
+
const txBytes = Buffer.from(rawTx, "hex");
|
|
21880
|
+
const vsize = Math.ceil(txBytes.length);
|
|
21881
|
+
const feeRate = await spokeProvider.getFeeEstimate();
|
|
21882
|
+
const feeRateBigInt = typeof feeRate === "bigint" ? feeRate : BigInt(Math.ceil(feeRate));
|
|
21883
|
+
return BigInt(vsize) * feeRateBigInt;
|
|
21884
|
+
}
|
|
21885
|
+
/**
|
|
21886
|
+
* Deposit tokens to the spoke chain and bridge to hub
|
|
21887
|
+
*
|
|
21888
|
+
* @param {BitcoinSpokeDepositParams} params - Deposit parameters
|
|
21889
|
+
* @param {BitcoinSpokeProviderType} spokeProvider - The Bitcoin spoke provider
|
|
21890
|
+
* @param {EvmHubProvider} EvmHubProvider - The hub chain provider
|
|
21891
|
+
* @param {boolean} raw - Whether to return raw PSBT or transaction hash
|
|
21892
|
+
* @returns {Promise<TxReturnType<BitcoinSpokeProviderType, R>>} Transaction hash or raw PSBT
|
|
21893
|
+
*/
|
|
21894
|
+
static async deposit(params, spokeProvider, raw) {
|
|
21895
|
+
return _BitcoinSpokeService.transfer(
|
|
21896
|
+
{
|
|
21897
|
+
token: params.token,
|
|
21898
|
+
amount: params.amount,
|
|
21899
|
+
data: params.data ?? "0x",
|
|
21900
|
+
accessToken: params.accessToken
|
|
21901
|
+
},
|
|
21902
|
+
spokeProvider,
|
|
21903
|
+
raw
|
|
21904
|
+
);
|
|
21905
|
+
}
|
|
21906
|
+
/**
|
|
21907
|
+
* Get the balance of deposited tokens in the asset manager
|
|
21908
|
+
*
|
|
21909
|
+
* @param {string} token - Token identifier ('BTC' for native Bitcoin)
|
|
21910
|
+
* @param {BitcoinSpokeProviderType} spokeProvider - The Bitcoin spoke provider
|
|
21911
|
+
* @returns {Promise<bigint>} Balance in satoshis
|
|
21912
|
+
*/
|
|
21913
|
+
static async getDeposit(token, spokeProvider) {
|
|
21914
|
+
const assetManagerAddress = spokeProvider.chainConfig.addresses.assetManager;
|
|
21915
|
+
const utxos = await spokeProvider.fetchUTXOs(assetManagerAddress);
|
|
21916
|
+
const totalBalance = utxos.reduce((sum, utxo) => sum + utxo.value, 0);
|
|
21917
|
+
return BigInt(totalBalance);
|
|
21918
|
+
}
|
|
21919
|
+
/**
|
|
21920
|
+
* Generate simulation parameters for deposit
|
|
21921
|
+
*
|
|
21922
|
+
* @param {BitcoinSpokeDepositParams} params - Deposit parameters
|
|
21923
|
+
* @param {BitcoinSpokeProviderType} spokeProvider - The Bitcoin spoke provider
|
|
21924
|
+
* @param {EvmHubProvider} EvmHubProvider - The hub chain provider
|
|
21925
|
+
* @returns {Promise<DepositSimulationParams>} Simulation parameters
|
|
21926
|
+
*/
|
|
21927
|
+
static async getSimulateDepositParams(params, spokeProvider, EvmHubProvider2) {
|
|
21928
|
+
const to = params.to ?? await EvmWalletAbstraction.getUserHubWalletAddress(
|
|
21929
|
+
spokeProvider.chainConfig.chain.id,
|
|
21930
|
+
encodeAddress(spokeProvider.chainConfig.chain.id, params.from),
|
|
21931
|
+
EvmHubProvider2
|
|
21932
|
+
);
|
|
21933
|
+
const tokenEntry = Object.values(spokeProvider.chainConfig.supportedTokens).find((t) => t.address === params.token);
|
|
21934
|
+
const token = tokenEntry?.address ?? params.token;
|
|
21935
|
+
return {
|
|
21936
|
+
spokeChainID: spokeProvider.chainConfig.chain.id,
|
|
21937
|
+
token: encodeAddress(spokeProvider.chainConfig.chain.id, token),
|
|
21938
|
+
from: encodeAddress(spokeProvider.chainConfig.chain.id, params.from),
|
|
21939
|
+
to,
|
|
21940
|
+
amount: params.amount,
|
|
21941
|
+
data: params.data,
|
|
21942
|
+
srcAddress: encodeAddress(spokeProvider.chainConfig.chain.id, spokeProvider.chainConfig.addresses.assetManager)
|
|
21943
|
+
};
|
|
21944
|
+
}
|
|
21945
|
+
/**
|
|
21946
|
+
* Fund the Radfi trading wallet by sending BTC from the user's personal wallet
|
|
21947
|
+
*
|
|
21948
|
+
* @param {bigint} amount - Amount in satoshis to send
|
|
21949
|
+
* @param {BitcoinSpokeProvider} spokeProvider - The Bitcoin spoke provider (must have signing capability)
|
|
21950
|
+
* @returns {Promise<string>} Transaction ID of the funding transaction
|
|
21951
|
+
*/
|
|
21952
|
+
static async fundTradingWallet(amount, spokeProvider) {
|
|
21953
|
+
const walletAddress = await spokeProvider.walletProvider.getWalletAddress();
|
|
21954
|
+
const { tradingAddress } = await spokeProvider.radfi.getTradingWallet(walletAddress);
|
|
21955
|
+
return spokeProvider.walletProvider.sendBitcoin(tradingAddress, amount);
|
|
21956
|
+
}
|
|
21957
|
+
/**
|
|
21958
|
+
* Call a contract on the hub chain from Bitcoin spoke
|
|
21959
|
+
*
|
|
21960
|
+
* @param {HubAddress} from - The hub wallet address
|
|
21961
|
+
* @param {Hex} payload - The payload to send
|
|
21962
|
+
* @param {BitcoinSpokeProviderType} spokeProvider - The Bitcoin spoke provider
|
|
21963
|
+
* @param {EvmHubProvider} EvmHubProvider - The hub chain provider
|
|
21964
|
+
* @param {boolean} raw - Whether to return raw PSBT or transaction hash
|
|
21965
|
+
* @returns {Promise<TxReturnType<BitcoinSpokeProviderType, R>>} Stringified JSON for payload and signature
|
|
21966
|
+
*/
|
|
21967
|
+
static async callWallet(from, payload, spokeProvider, EvmHubProvider2, raw) {
|
|
21968
|
+
return _BitcoinSpokeService.call(EvmHubProvider2.chainConfig.chain.id, from, payload, spokeProvider, raw);
|
|
21969
|
+
}
|
|
21970
|
+
/**
|
|
21971
|
+
* Transfer tokens to the hub chain
|
|
21972
|
+
*
|
|
21973
|
+
* @param {BitcoinTransferToHubParams} params - Transfer parameters
|
|
21974
|
+
* @param {BitcoinSpokeProviderType} spokeProvider - The Bitcoin spoke provider
|
|
21975
|
+
* @param {boolean} raw - Whether to return raw PSBT or transaction hash
|
|
21976
|
+
* @returns {Promise<TxReturnType<BitcoinSpokeProviderType, R>>} Transaction hash or raw PSBT
|
|
21977
|
+
*/
|
|
21978
|
+
static async transfer({ token, amount, data = "0x", accessToken }, spokeProvider, raw) {
|
|
21979
|
+
return await BitcoinBaseSpokeProvider.deposit(token, amount, data, spokeProvider, raw, accessToken);
|
|
21980
|
+
}
|
|
21981
|
+
/**
|
|
21982
|
+
* Send a message to the hub chain
|
|
21983
|
+
*
|
|
21984
|
+
* @param {HubChainId} dstChainId - Destination chain ID
|
|
21985
|
+
* @param {HubAddress} dstAddress - Destination address on hub
|
|
21986
|
+
* @param {Hex} payload - Message payload
|
|
21987
|
+
* @param {BitcoinSpokeProviderType} spokeProvider - The Bitcoin spoke provider
|
|
21988
|
+
* @param {boolean} raw - Whether to return raw PSBT or transaction hash
|
|
21989
|
+
* @returns {Promise<TxReturnType<BitcoinSpokeProviderType, R>>} Transaction hash or raw PSBT
|
|
21990
|
+
*/
|
|
21991
|
+
static async call(dstChainId, dstAddress, payload, spokeProvider, raw) {
|
|
21992
|
+
return await BitcoinBaseSpokeProvider.encodeWithdrawalData(
|
|
21993
|
+
dstChainId,
|
|
21994
|
+
payload,
|
|
21995
|
+
spokeProvider,
|
|
21996
|
+
raw
|
|
21997
|
+
);
|
|
21998
|
+
}
|
|
21999
|
+
};
|
|
21209
22000
|
var NearSpokeService = class _NearSpokeService {
|
|
21210
22001
|
constructor() {
|
|
21211
22002
|
}
|
|
@@ -21564,6 +22355,14 @@ var SpokeService = class _SpokeService {
|
|
|
21564
22355
|
raw
|
|
21565
22356
|
);
|
|
21566
22357
|
}
|
|
22358
|
+
if (isBitcoinSpokeProviderType(spokeProvider)) {
|
|
22359
|
+
await _SpokeService.verifyDepositSimulation(params, spokeProvider, hubProvider, skipSimulation);
|
|
22360
|
+
return BitcoinSpokeService.deposit(
|
|
22361
|
+
params,
|
|
22362
|
+
spokeProvider,
|
|
22363
|
+
raw
|
|
22364
|
+
);
|
|
22365
|
+
}
|
|
21567
22366
|
if (isNearSpokeProviderType(spokeProvider)) {
|
|
21568
22367
|
await _SpokeService.verifyDepositSimulation(params, spokeProvider, hubProvider, skipSimulation);
|
|
21569
22368
|
return NearSpokeService.deposit(
|
|
@@ -21618,6 +22417,13 @@ var SpokeService = class _SpokeService {
|
|
|
21618
22417
|
hubProvider
|
|
21619
22418
|
);
|
|
21620
22419
|
}
|
|
22420
|
+
if (isBitcoinSpokeProviderType(spokeProvider)) {
|
|
22421
|
+
return BitcoinSpokeService.getSimulateDepositParams(
|
|
22422
|
+
params,
|
|
22423
|
+
spokeProvider,
|
|
22424
|
+
hubProvider
|
|
22425
|
+
);
|
|
22426
|
+
}
|
|
21621
22427
|
if (isNearSpokeProviderType(spokeProvider)) {
|
|
21622
22428
|
return NearSpokeService.getSimulateDepositParams(
|
|
21623
22429
|
params,
|
|
@@ -21664,6 +22470,9 @@ var SpokeService = class _SpokeService {
|
|
|
21664
22470
|
if (isSonicSpokeProviderType(spokeProvider)) {
|
|
21665
22471
|
return SonicSpokeService.getDeposit(token, spokeProvider);
|
|
21666
22472
|
}
|
|
22473
|
+
if (isBitcoinSpokeProviderType(spokeProvider)) {
|
|
22474
|
+
return BitcoinSpokeService.getDeposit(token, spokeProvider);
|
|
22475
|
+
}
|
|
21667
22476
|
if (isNearSpokeProviderType(spokeProvider)) {
|
|
21668
22477
|
return NearSpokeService.getDeposit(token, spokeProvider);
|
|
21669
22478
|
}
|
|
@@ -21681,15 +22490,24 @@ var SpokeService = class _SpokeService {
|
|
|
21681
22490
|
if (isSonicSpokeProviderType(spokeProvider)) {
|
|
21682
22491
|
return await SonicSpokeService.callWallet(payload, spokeProvider, raw);
|
|
21683
22492
|
}
|
|
22493
|
+
let srcAddress = encodeAddress(
|
|
22494
|
+
spokeProvider.chainConfig.chain.id,
|
|
22495
|
+
await spokeProvider.walletProvider.getWalletAddress()
|
|
22496
|
+
);
|
|
22497
|
+
if (isBitcoinSpokeProvider(spokeProvider)) {
|
|
22498
|
+
if (spokeProvider.walletMode === "TRADING") {
|
|
22499
|
+
const tradingWalletAddress = await spokeProvider.radfi.getTradingWallet(
|
|
22500
|
+
await spokeProvider.walletProvider.getWalletAddress()
|
|
22501
|
+
);
|
|
22502
|
+
srcAddress = encodeAddress(spokeProvider.chainConfig.chain.id, tradingWalletAddress.tradingAddress);
|
|
22503
|
+
}
|
|
22504
|
+
}
|
|
21684
22505
|
if (!skipSimulation) {
|
|
21685
22506
|
const result = await _SpokeService.simulateRecvMessage(
|
|
21686
22507
|
{
|
|
21687
22508
|
target: from,
|
|
21688
22509
|
srcChainId: getIntentRelayChainId(spokeProvider.chainConfig.chain.id),
|
|
21689
|
-
srcAddress
|
|
21690
|
-
spokeProvider.chainConfig.chain.id,
|
|
21691
|
-
await spokeProvider.walletProvider.getWalletAddress()
|
|
21692
|
-
),
|
|
22510
|
+
srcAddress,
|
|
21693
22511
|
payload
|
|
21694
22512
|
},
|
|
21695
22513
|
hubProvider
|
|
@@ -21740,6 +22558,16 @@ var SpokeService = class _SpokeService {
|
|
|
21740
22558
|
raw
|
|
21741
22559
|
);
|
|
21742
22560
|
}
|
|
22561
|
+
if (isBitcoinSpokeProviderType(spokeProvider)) {
|
|
22562
|
+
await _SpokeService.verifySimulation(from, payload, spokeProvider, hubProvider, skipSimulation);
|
|
22563
|
+
return await BitcoinSpokeService.callWallet(
|
|
22564
|
+
from,
|
|
22565
|
+
payload,
|
|
22566
|
+
spokeProvider,
|
|
22567
|
+
hubProvider,
|
|
22568
|
+
raw
|
|
22569
|
+
);
|
|
22570
|
+
}
|
|
21743
22571
|
if (isNearSpokeProviderType(spokeProvider)) {
|
|
21744
22572
|
await _SpokeService.verifySimulation(from, payload, spokeProvider, hubProvider, skipSimulation);
|
|
21745
22573
|
return await NearSpokeService.callWallet(from, payload, spokeProvider, hubProvider, raw);
|
|
@@ -21748,14 +22576,26 @@ var SpokeService = class _SpokeService {
|
|
|
21748
22576
|
}
|
|
21749
22577
|
static async verifySimulation(from, payload, spokeProvider, hubProvider, skipSimulation) {
|
|
21750
22578
|
if (!skipSimulation) {
|
|
22579
|
+
let srcAddress = encodeAddress(
|
|
22580
|
+
spokeProvider.chainConfig.chain.id,
|
|
22581
|
+
await spokeProvider.walletProvider.getWalletAddress()
|
|
22582
|
+
);
|
|
22583
|
+
if (isBitcoinSpokeProvider(spokeProvider)) {
|
|
22584
|
+
if (spokeProvider.walletMode === "TRADING") {
|
|
22585
|
+
const tradingWalletAddress = await spokeProvider.radfi.getTradingWallet(
|
|
22586
|
+
await spokeProvider.walletProvider.getWalletAddress()
|
|
22587
|
+
);
|
|
22588
|
+
srcAddress = encodeAddress(
|
|
22589
|
+
spokeProvider.chainConfig.chain.id,
|
|
22590
|
+
tradingWalletAddress.tradingAddress
|
|
22591
|
+
);
|
|
22592
|
+
}
|
|
22593
|
+
}
|
|
21751
22594
|
const result = await _SpokeService.simulateRecvMessage(
|
|
21752
22595
|
{
|
|
21753
22596
|
target: from,
|
|
21754
22597
|
srcChainId: getIntentRelayChainId(spokeProvider.chainConfig.chain.id),
|
|
21755
|
-
srcAddress
|
|
21756
|
-
spokeProvider.chainConfig.chain.id,
|
|
21757
|
-
await spokeProvider.walletProvider.getWalletAddress()
|
|
21758
|
-
),
|
|
22598
|
+
srcAddress,
|
|
21759
22599
|
payload
|
|
21760
22600
|
},
|
|
21761
22601
|
hubProvider
|
|
@@ -22189,7 +23029,7 @@ var SwapService = class {
|
|
|
22189
23029
|
let dstIntentTxHash;
|
|
22190
23030
|
if (spokeProvider.chainConfig.chain.id !== this.hubProvider.chainConfig.chain.id) {
|
|
22191
23031
|
const intentRelayChainId = getIntentRelayChainId(params.srcChain).toString();
|
|
22192
|
-
const submitPayload = params.srcChain === SOLANA_MAINNET_CHAIN_ID && data ? {
|
|
23032
|
+
const submitPayload = (params.srcChain === SOLANA_MAINNET_CHAIN_ID || params.srcChain === BITCOIN_MAINNET_CHAIN_ID) && data ? {
|
|
22193
23033
|
action: "submit",
|
|
22194
23034
|
params: {
|
|
22195
23035
|
chain_id: intentRelayChainId,
|
|
@@ -22514,17 +23354,51 @@ var SwapService = class {
|
|
|
22514
23354
|
this.configService.isValidSpokeChainId(params.dstChain),
|
|
22515
23355
|
`Invalid spoke chain (params.dstChain): ${params.dstChain}`
|
|
22516
23356
|
);
|
|
23357
|
+
if (params.dstChain === BITCOIN_MAINNET_CHAIN_ID && params.outputToken === "BTC") {
|
|
23358
|
+
invariant6__default.default(
|
|
23359
|
+
params.minOutputAmount >= 546n,
|
|
23360
|
+
`Invalid minOutputAmount (params.minOutputAmount): ${params.minOutputAmount}`
|
|
23361
|
+
);
|
|
23362
|
+
}
|
|
22517
23363
|
try {
|
|
22518
|
-
|
|
23364
|
+
console.log("[SwapService.createIntent] start", {
|
|
23365
|
+
srcChain: params.srcChain,
|
|
23366
|
+
dstChain: params.dstChain,
|
|
23367
|
+
inputToken: params.inputToken,
|
|
23368
|
+
inputAmount: params.inputAmount.toString()
|
|
23369
|
+
});
|
|
23370
|
+
let walletAddress = await spokeProvider.walletProvider.getWalletAddress();
|
|
23371
|
+
console.log("[SwapService.createIntent] walletAddress", walletAddress, "srcAddress", params.srcAddress);
|
|
22519
23372
|
invariant6__default.default(
|
|
22520
23373
|
params.srcAddress.toLowerCase() === walletAddress.toLowerCase(),
|
|
22521
23374
|
"srcAddress must be the same as wallet address"
|
|
22522
23375
|
);
|
|
23376
|
+
if (isBitcoinSpokeProvider(spokeProvider)) {
|
|
23377
|
+
console.log(
|
|
23378
|
+
"[SwapService.createIntent] Bitcoin detected, walletMode:",
|
|
23379
|
+
spokeProvider.walletMode,
|
|
23380
|
+
"hasToken:",
|
|
23381
|
+
!!spokeProvider.radfiAccessToken
|
|
23382
|
+
);
|
|
23383
|
+
await spokeProvider.ensureRadfiAccessToken();
|
|
23384
|
+
console.log(
|
|
23385
|
+
"[SwapService.createIntent] ensureRadfiAccessToken done, hasToken:",
|
|
23386
|
+
!!spokeProvider.radfiAccessToken
|
|
23387
|
+
);
|
|
23388
|
+
if (spokeProvider.walletMode === "TRADING") {
|
|
23389
|
+
const tradingWalletAddress = await spokeProvider.radfi.getTradingWallet(
|
|
23390
|
+
await spokeProvider.walletProvider.getWalletAddress()
|
|
23391
|
+
);
|
|
23392
|
+
console.log("[SwapService.createIntent] tradingWalletAddress", tradingWalletAddress);
|
|
23393
|
+
walletAddress = tradingWalletAddress.tradingAddress;
|
|
23394
|
+
}
|
|
23395
|
+
}
|
|
22523
23396
|
const creatorHubWalletAddress = await deriveUserWalletAddress(
|
|
22524
23397
|
this.hubProvider,
|
|
22525
23398
|
spokeProvider.chainConfig.chain.id,
|
|
22526
23399
|
walletAddress
|
|
22527
23400
|
);
|
|
23401
|
+
console.log("[SwapService.createIntent] creatorHubWalletAddress", creatorHubWalletAddress);
|
|
22528
23402
|
if (spokeProvider.chainConfig.chain.id === this.hubProvider.chainConfig.chain.id && isSonicSpokeProviderType(spokeProvider)) {
|
|
22529
23403
|
const [txResult, intent, feeAmount, data] = await SonicSpokeService.createSwapIntent(
|
|
22530
23404
|
params,
|
|
@@ -22555,6 +23429,11 @@ var SwapService = class {
|
|
|
22555
23429
|
this.configService,
|
|
22556
23430
|
fee
|
|
22557
23431
|
);
|
|
23432
|
+
console.log("[SwapService.createIntent] intent data constructed", {
|
|
23433
|
+
data,
|
|
23434
|
+
intentId: intent.intentId?.toString()
|
|
23435
|
+
});
|
|
23436
|
+
console.log("[SwapService.createIntent] calling SpokeService.deposit...");
|
|
22558
23437
|
const txResult = await SpokeService.deposit(
|
|
22559
23438
|
{
|
|
22560
23439
|
from: walletAddress,
|
|
@@ -22568,12 +23447,14 @@ var SwapService = class {
|
|
|
22568
23447
|
raw,
|
|
22569
23448
|
skipSimulation
|
|
22570
23449
|
);
|
|
23450
|
+
console.log("[SwapService.createIntent] SpokeService.deposit done, txResult:", txResult);
|
|
22571
23451
|
return {
|
|
22572
23452
|
ok: true,
|
|
22573
23453
|
value: [txResult, { ...intent, feeAmount }, data]
|
|
22574
23454
|
};
|
|
22575
23455
|
}
|
|
22576
23456
|
} catch (error) {
|
|
23457
|
+
console.error("[SwapService.createIntent] FAILED", error);
|
|
22577
23458
|
return {
|
|
22578
23459
|
ok: false,
|
|
22579
23460
|
error: {
|
|
@@ -25632,9 +26513,15 @@ function isNearSpokeProvider(value) {
|
|
|
25632
26513
|
function isStellarSpokeProviderType(value) {
|
|
25633
26514
|
return typeof value === "object" && value !== null && (isStellarSpokeProvider(value) || isStellarRawSpokeProvider(value));
|
|
25634
26515
|
}
|
|
26516
|
+
function isBitcoinSpokeProviderType(value) {
|
|
26517
|
+
return typeof value === "object" && value !== null && (isBitcoinSpokeProvider(value) || isBitcoinRawSpokeProvider(value));
|
|
26518
|
+
}
|
|
25635
26519
|
function isStellarSpokeProvider(value) {
|
|
25636
26520
|
return typeof value === "object" && value !== null && value instanceof StellarSpokeProvider && !("raw" in value) && value.chainConfig.chain.type === "STELLAR";
|
|
25637
26521
|
}
|
|
26522
|
+
function isBitcoinSpokeProvider(value) {
|
|
26523
|
+
return typeof value === "object" && value !== null && value instanceof BitcoinSpokeProvider && !("raw" in value) && value.chainConfig.chain.type === "BITCOIN";
|
|
26524
|
+
}
|
|
25638
26525
|
function isNearSpokeProviderType(value) {
|
|
25639
26526
|
return typeof value === "object" && value !== null && (isNearSpokeProvider(value) || isNearRawSpokeProvider(value));
|
|
25640
26527
|
}
|
|
@@ -25731,6 +26618,9 @@ function isSolanaRawSpokeProvider(value) {
|
|
|
25731
26618
|
function isStellarRawSpokeProvider(value) {
|
|
25732
26619
|
return isRawSpokeProvider(value) && value.chainConfig.chain.type === "STELLAR";
|
|
25733
26620
|
}
|
|
26621
|
+
function isBitcoinRawSpokeProvider(value) {
|
|
26622
|
+
return isRawSpokeProvider(value) && value.chainConfig.chain.type === "BITCOIN";
|
|
26623
|
+
}
|
|
25734
26624
|
function isIconRawSpokeProvider(value) {
|
|
25735
26625
|
return isRawSpokeProvider(value) && value.chainConfig.chain.type === "ICON";
|
|
25736
26626
|
}
|
|
@@ -25764,6 +26654,26 @@ function isSolanaRawSpokeProviderConfig(value) {
|
|
|
25764
26654
|
function isNearRawSpokeProviderConfig(value) {
|
|
25765
26655
|
return typeof value === "object" && value !== null && "walletAddress" in value && "chainConfig" in value && value.chainConfig.chain.type === "NEAR";
|
|
25766
26656
|
}
|
|
26657
|
+
function isSubmitSwapTxResponse(value) {
|
|
26658
|
+
return typeof value === "object" && value !== null && typeof value.success === "boolean" && typeof value.message === "string";
|
|
26659
|
+
}
|
|
26660
|
+
function isSubmitSwapTxStatusResponse(value) {
|
|
26661
|
+
if (typeof value !== "object" || value === null) return false;
|
|
26662
|
+
const obj = value;
|
|
26663
|
+
if (typeof obj.success !== "boolean") return false;
|
|
26664
|
+
if (typeof obj.data !== "object" || obj.data === null) return false;
|
|
26665
|
+
const data = obj.data;
|
|
26666
|
+
if (typeof data.txHash !== "string") return false;
|
|
26667
|
+
if (typeof data.srcChainId !== "string") return false;
|
|
26668
|
+
if (typeof data.status !== "string") return false;
|
|
26669
|
+
if (typeof data.failedAttempts !== "number") return false;
|
|
26670
|
+
if (data.result !== void 0) {
|
|
26671
|
+
if (typeof data.result !== "object" || data.result === null) return false;
|
|
26672
|
+
const result = data.result;
|
|
26673
|
+
if (typeof result.dstIntentTxHash !== "string") return false;
|
|
26674
|
+
}
|
|
26675
|
+
return true;
|
|
26676
|
+
}
|
|
25767
26677
|
async function retry(action, retryCount = DEFAULT_MAX_RETRY, delayMs = DEFAULT_RETRY_DELAY_MS) {
|
|
25768
26678
|
do {
|
|
25769
26679
|
try {
|
|
@@ -25839,8 +26749,6 @@ function encodeAddress(spokeChainId, address) {
|
|
|
25839
26749
|
case "0xa4b1.arbitrum":
|
|
25840
26750
|
case "sonic":
|
|
25841
26751
|
return address;
|
|
25842
|
-
case "injective-1":
|
|
25843
|
-
return viem.toHex(Buffer.from(address, "utf-8"));
|
|
25844
26752
|
case "0x1.icon":
|
|
25845
26753
|
return viem.toHex(Buffer.from(address.replace("cx", "01").replace("hx", "00") ?? "f8", "hex"));
|
|
25846
26754
|
case "sui":
|
|
@@ -25849,7 +26757,9 @@ function encodeAddress(spokeChainId, address) {
|
|
|
25849
26757
|
return viem.toHex(Buffer.from(new web3_js.PublicKey(address).toBytes()));
|
|
25850
26758
|
case "stellar":
|
|
25851
26759
|
return `0x${stellarSdk.Address.fromString(address).toScVal().toXDR("hex")}`;
|
|
26760
|
+
case "bitcoin":
|
|
25852
26761
|
case "near":
|
|
26762
|
+
case "injective-1":
|
|
25853
26763
|
return viem.toHex(Buffer.from(address, "utf-8"));
|
|
25854
26764
|
default:
|
|
25855
26765
|
return address;
|
|
@@ -25975,10 +26885,11 @@ var BackendApiService = class {
|
|
|
25975
26885
|
* @returns Promise<T>
|
|
25976
26886
|
*/
|
|
25977
26887
|
async makeRequest(endpoint, config) {
|
|
25978
|
-
const url = `${this.baseURL}${endpoint}`;
|
|
26888
|
+
const url = config.baseURL ? `${config.baseURL}${endpoint}` : `${this.baseURL}${endpoint}`;
|
|
25979
26889
|
const headers = { ...this.defaultHeaders, ...config.headers };
|
|
25980
26890
|
const controller = new AbortController();
|
|
25981
|
-
const
|
|
26891
|
+
const timeout = config.timeout ?? this.timeout;
|
|
26892
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
25982
26893
|
try {
|
|
25983
26894
|
const response = await fetch(url, {
|
|
25984
26895
|
method: config.method,
|
|
@@ -25997,7 +26908,7 @@ var BackendApiService = class {
|
|
|
25997
26908
|
clearTimeout(timeoutId);
|
|
25998
26909
|
if (error instanceof Error) {
|
|
25999
26910
|
if (error.name === "AbortError") {
|
|
26000
|
-
throw new Error(`Request timeout after ${
|
|
26911
|
+
throw new Error(`Request timeout after ${timeout}ms`);
|
|
26001
26912
|
}
|
|
26002
26913
|
console.error("[BackendApiService] Request error:", error.message);
|
|
26003
26914
|
throw error;
|
|
@@ -26013,16 +26924,50 @@ var BackendApiService = class {
|
|
|
26013
26924
|
* @param txHash - The intent created transaction hash from the hub chain
|
|
26014
26925
|
* @returns Promise<IntentResponse>
|
|
26015
26926
|
*/
|
|
26016
|
-
async getIntentByTxHash(txHash) {
|
|
26017
|
-
return this.makeRequest(`/intent/tx/${txHash}`, { method: "GET" });
|
|
26927
|
+
async getIntentByTxHash(txHash, config) {
|
|
26928
|
+
return this.makeRequest(`/intent/tx/${txHash}`, { ...config, method: "GET" });
|
|
26018
26929
|
}
|
|
26019
26930
|
/**
|
|
26020
26931
|
* Get intent details by intent hash
|
|
26021
26932
|
* @param intentHash - Intent hash
|
|
26022
26933
|
* @returns Promise<IntentResponse>
|
|
26023
26934
|
*/
|
|
26024
|
-
async getIntentByHash(intentHash) {
|
|
26025
|
-
return this.makeRequest(`/intent/${intentHash}`, { method: "GET" });
|
|
26935
|
+
async getIntentByHash(intentHash, config) {
|
|
26936
|
+
return this.makeRequest(`/intent/${intentHash}`, { ...config, method: "GET" });
|
|
26937
|
+
}
|
|
26938
|
+
// Swap submit-tx endpoints
|
|
26939
|
+
/**
|
|
26940
|
+
* Submit a swap transaction to be processed (relay, post execution to solver, etc.)
|
|
26941
|
+
* @param params - Swap transaction submission data
|
|
26942
|
+
* @returns Promise<SubmitSwapTxResponse>
|
|
26943
|
+
*/
|
|
26944
|
+
async submitSwapTx(params, config) {
|
|
26945
|
+
const data = await this.makeRequest("/swaps/submit-tx", {
|
|
26946
|
+
...config,
|
|
26947
|
+
method: "POST",
|
|
26948
|
+
body: JSON.stringify(params)
|
|
26949
|
+
});
|
|
26950
|
+
if (!isSubmitSwapTxResponse(data)) {
|
|
26951
|
+
throw new Error("Invalid submitSwapTx response: unexpected response shape");
|
|
26952
|
+
}
|
|
26953
|
+
return data;
|
|
26954
|
+
}
|
|
26955
|
+
/**
|
|
26956
|
+
* Get the processing status of a submitted swap transaction
|
|
26957
|
+
* @param params - Query parameters containing txHash and optional srcChainId
|
|
26958
|
+
* @returns Promise<SubmitSwapTxStatusResponse>
|
|
26959
|
+
*/
|
|
26960
|
+
async getSubmitSwapTxStatus(params, config) {
|
|
26961
|
+
const queryParams = new URLSearchParams();
|
|
26962
|
+
queryParams.append("txHash", params.txHash);
|
|
26963
|
+
if (params.srcChainId) queryParams.append("srcChainId", params.srcChainId);
|
|
26964
|
+
const queryString = queryParams.toString();
|
|
26965
|
+
const endpoint = `/swaps/submit-tx/status?${queryString}`;
|
|
26966
|
+
const data = await this.makeRequest(endpoint, { ...config, method: "GET" });
|
|
26967
|
+
if (!isSubmitSwapTxStatusResponse(data)) {
|
|
26968
|
+
throw new Error("Invalid submitSwapTxStatus response: unexpected response shape");
|
|
26969
|
+
}
|
|
26970
|
+
return data;
|
|
26026
26971
|
}
|
|
26027
26972
|
// Solver endpoints
|
|
26028
26973
|
/**
|
|
@@ -26030,13 +26975,13 @@ var BackendApiService = class {
|
|
|
26030
26975
|
* @param params - Object containing offset and limit parameters for pagination
|
|
26031
26976
|
* @returns Promise<OrderbookResponse>
|
|
26032
26977
|
*/
|
|
26033
|
-
async getOrderbook(params) {
|
|
26978
|
+
async getOrderbook(params, config) {
|
|
26034
26979
|
const queryParams = new URLSearchParams();
|
|
26035
26980
|
queryParams.append("offset", params.offset);
|
|
26036
26981
|
queryParams.append("limit", params.limit);
|
|
26037
26982
|
const queryString = queryParams.toString();
|
|
26038
26983
|
const endpoint = `/solver/orderbook?${queryString}`;
|
|
26039
|
-
return this.makeRequest(endpoint, { method: "GET" });
|
|
26984
|
+
return this.makeRequest(endpoint, { ...config, method: "GET" });
|
|
26040
26985
|
}
|
|
26041
26986
|
/**
|
|
26042
26987
|
* Get all intents created by a specific user address with optional filters.
|
|
@@ -26050,7 +26995,7 @@ var BackendApiService = class {
|
|
|
26050
26995
|
*
|
|
26051
26996
|
* @returns {Promise<UserIntentsResponse>} Promise resolving to an array of intent responses for the user.
|
|
26052
26997
|
*/
|
|
26053
|
-
async getUserIntents(params) {
|
|
26998
|
+
async getUserIntents(params, config) {
|
|
26054
26999
|
const { userAddress, startDate, endDate, limit, offset } = params;
|
|
26055
27000
|
const queryParams = new URLSearchParams();
|
|
26056
27001
|
if (startDate) queryParams.append("startDate", new Date(startDate).toISOString());
|
|
@@ -26059,7 +27004,7 @@ var BackendApiService = class {
|
|
|
26059
27004
|
if (offset) queryParams.append("offset", offset);
|
|
26060
27005
|
const queryString = queryParams.toString();
|
|
26061
27006
|
const endpoint = queryString.length > 0 ? `/intent/user/${userAddress}?${queryString}` : `/intent/user/${userAddress}`;
|
|
26062
|
-
return this.makeRequest(endpoint, { method: "GET" });
|
|
27007
|
+
return this.makeRequest(endpoint, { ...config, method: "GET" });
|
|
26063
27008
|
}
|
|
26064
27009
|
// Money Market endpoints
|
|
26065
27010
|
/**
|
|
@@ -26067,23 +27012,23 @@ var BackendApiService = class {
|
|
|
26067
27012
|
* @param userAddress - User's wallet address
|
|
26068
27013
|
* @returns Promise<MoneyMarketPosition>
|
|
26069
27014
|
*/
|
|
26070
|
-
async getMoneyMarketPosition(userAddress) {
|
|
26071
|
-
return this.makeRequest(`/moneymarket/position/${userAddress}`, { method: "GET" });
|
|
27015
|
+
async getMoneyMarketPosition(userAddress, config) {
|
|
27016
|
+
return this.makeRequest(`/moneymarket/position/${userAddress}`, { ...config, method: "GET" });
|
|
26072
27017
|
}
|
|
26073
27018
|
/**
|
|
26074
27019
|
* Get all money market assets
|
|
26075
27020
|
* @returns Promise<MoneyMarketAsset[]>
|
|
26076
27021
|
*/
|
|
26077
|
-
async getAllMoneyMarketAssets() {
|
|
26078
|
-
return this.makeRequest("/moneymarket/asset/all", { method: "GET" });
|
|
27022
|
+
async getAllMoneyMarketAssets(config) {
|
|
27023
|
+
return this.makeRequest("/moneymarket/asset/all", { ...config, method: "GET" });
|
|
26079
27024
|
}
|
|
26080
27025
|
/**
|
|
26081
27026
|
* Get specific money market asset details
|
|
26082
27027
|
* @param reserveAddress - Reserve contract address
|
|
26083
27028
|
* @returns Promise<MoneyMarketAsset>
|
|
26084
27029
|
*/
|
|
26085
|
-
async getMoneyMarketAsset(reserveAddress) {
|
|
26086
|
-
return this.makeRequest(`/moneymarket/asset/${reserveAddress}`, { method: "GET" });
|
|
27030
|
+
async getMoneyMarketAsset(reserveAddress, config) {
|
|
27031
|
+
return this.makeRequest(`/moneymarket/asset/${reserveAddress}`, { ...config, method: "GET" });
|
|
26087
27032
|
}
|
|
26088
27033
|
/**
|
|
26089
27034
|
* Get borrowers for a specific money market asset
|
|
@@ -26091,13 +27036,13 @@ var BackendApiService = class {
|
|
|
26091
27036
|
* @param params - Object containing offset and limit parameters for pagination
|
|
26092
27037
|
* @returns Promise<MoneyMarketAssetBorrowers>
|
|
26093
27038
|
*/
|
|
26094
|
-
async getMoneyMarketAssetBorrowers(reserveAddress, params) {
|
|
27039
|
+
async getMoneyMarketAssetBorrowers(reserveAddress, params, config) {
|
|
26095
27040
|
const queryParams = new URLSearchParams();
|
|
26096
27041
|
queryParams.append("offset", params.offset);
|
|
26097
27042
|
queryParams.append("limit", params.limit);
|
|
26098
27043
|
const queryString = queryParams.toString();
|
|
26099
27044
|
const endpoint = `/moneymarket/asset/${reserveAddress}/borrowers?${queryString}`;
|
|
26100
|
-
return this.makeRequest(endpoint, { method: "GET" });
|
|
27045
|
+
return this.makeRequest(endpoint, { ...config, method: "GET" });
|
|
26101
27046
|
}
|
|
26102
27047
|
/**
|
|
26103
27048
|
* Get suppliers for a specific money market asset
|
|
@@ -26105,69 +27050,76 @@ var BackendApiService = class {
|
|
|
26105
27050
|
* @param params - Object containing offset and limit parameters for pagination
|
|
26106
27051
|
* @returns Promise<MoneyMarketAssetSuppliers>
|
|
26107
27052
|
*/
|
|
26108
|
-
async getMoneyMarketAssetSuppliers(reserveAddress, params) {
|
|
27053
|
+
async getMoneyMarketAssetSuppliers(reserveAddress, params, config) {
|
|
26109
27054
|
const queryParams = new URLSearchParams();
|
|
26110
27055
|
queryParams.append("offset", params.offset);
|
|
26111
27056
|
queryParams.append("limit", params.limit);
|
|
26112
27057
|
const queryString = queryParams.toString();
|
|
26113
27058
|
const endpoint = `/moneymarket/asset/${reserveAddress}/suppliers?${queryString}`;
|
|
26114
|
-
return this.makeRequest(endpoint, { method: "GET" });
|
|
27059
|
+
return this.makeRequest(endpoint, { ...config, method: "GET" });
|
|
26115
27060
|
}
|
|
26116
27061
|
/**
|
|
26117
27062
|
* Get all money market borrowers
|
|
26118
27063
|
* @param params - Object containing offset and limit parameters for pagination
|
|
26119
27064
|
* @returns Promise<MoneyMarketBorrowers>
|
|
26120
27065
|
*/
|
|
26121
|
-
async getAllMoneyMarketBorrowers(params) {
|
|
27066
|
+
async getAllMoneyMarketBorrowers(params, config) {
|
|
26122
27067
|
const queryParams = new URLSearchParams();
|
|
26123
27068
|
queryParams.append("offset", params.offset);
|
|
26124
27069
|
queryParams.append("limit", params.limit);
|
|
26125
27070
|
const queryString = queryParams.toString();
|
|
26126
27071
|
const endpoint = `/moneymarket/borrowers?${queryString}`;
|
|
26127
|
-
return this.makeRequest(endpoint, { method: "GET" });
|
|
27072
|
+
return this.makeRequest(endpoint, { ...config, method: "GET" });
|
|
26128
27073
|
}
|
|
26129
27074
|
/**
|
|
26130
27075
|
* Get all supported config
|
|
26131
27076
|
* @returns Promise<GetAllConfigApiResponse>
|
|
26132
27077
|
*/
|
|
26133
|
-
async getAllConfig() {
|
|
26134
|
-
return this.makeRequest("/config/all", { method: "GET" });
|
|
27078
|
+
async getAllConfig(config) {
|
|
27079
|
+
return this.makeRequest("/config/all", { ...config, method: "GET" });
|
|
26135
27080
|
}
|
|
26136
27081
|
/**
|
|
26137
27082
|
* Get all supported spoke chains
|
|
26138
27083
|
* @returns Promise<GetChainsApiResponse>
|
|
26139
27084
|
*/
|
|
26140
|
-
async getChains() {
|
|
26141
|
-
return this.makeRequest("/config/spoke/chains", { method: "GET" });
|
|
27085
|
+
async getChains(config) {
|
|
27086
|
+
return this.makeRequest("/config/spoke/chains", { ...config, method: "GET" });
|
|
26142
27087
|
}
|
|
26143
27088
|
/**
|
|
26144
27089
|
* Get all supported swap tokens
|
|
26145
27090
|
* @returns Promise<GetSwapTokensApiResponse>
|
|
26146
27091
|
*/
|
|
26147
|
-
async getSwapTokens() {
|
|
26148
|
-
return this.makeRequest("/config/swap/tokens", { method: "GET" });
|
|
27092
|
+
async getSwapTokens(config) {
|
|
27093
|
+
return this.makeRequest("/config/swap/tokens", { ...config, method: "GET" });
|
|
26149
27094
|
}
|
|
26150
27095
|
/**
|
|
26151
27096
|
* Get supported swap tokens for a specific spoke chain
|
|
26152
27097
|
* @param chainId - Spoke chain id
|
|
26153
27098
|
* @returns Promise<GetSwapTokensByChainIdApiResponse>
|
|
26154
27099
|
*/
|
|
26155
|
-
async getSwapTokensByChainId(chainId) {
|
|
26156
|
-
return this.makeRequest(`/config/swap/${chainId}/tokens`, {
|
|
27100
|
+
async getSwapTokensByChainId(chainId, config) {
|
|
27101
|
+
return this.makeRequest(`/config/swap/${chainId}/tokens`, {
|
|
27102
|
+
...config,
|
|
27103
|
+
method: "GET"
|
|
27104
|
+
});
|
|
26157
27105
|
}
|
|
26158
27106
|
/**
|
|
26159
27107
|
* Get all supported money market tokens
|
|
26160
27108
|
* @returns Promise<GetMoneyMarketTokensApiResponse>
|
|
26161
27109
|
*/
|
|
26162
|
-
async getMoneyMarketTokens() {
|
|
26163
|
-
return this.makeRequest("/config/money-market/tokens", {
|
|
27110
|
+
async getMoneyMarketTokens(config) {
|
|
27111
|
+
return this.makeRequest("/config/money-market/tokens", {
|
|
27112
|
+
...config,
|
|
27113
|
+
method: "GET"
|
|
27114
|
+
});
|
|
26164
27115
|
}
|
|
26165
27116
|
/**
|
|
26166
27117
|
* Get all supported money market tokens
|
|
26167
27118
|
* @returns Promise<GetMoneyMarketTokensApiResponse>
|
|
26168
27119
|
*/
|
|
26169
|
-
async getMoneyMarketReserveAssets() {
|
|
27120
|
+
async getMoneyMarketReserveAssets(config) {
|
|
26170
27121
|
return this.makeRequest("/config/money-market/reserve-assets", {
|
|
27122
|
+
...config,
|
|
26171
27123
|
method: "GET"
|
|
26172
27124
|
});
|
|
26173
27125
|
}
|
|
@@ -26176,8 +27128,9 @@ var BackendApiService = class {
|
|
|
26176
27128
|
* @param chainId - Spoke chain id
|
|
26177
27129
|
* @returns Promise<GetMoneyMarketTokensByChainIdApiResponse>
|
|
26178
27130
|
*/
|
|
26179
|
-
async getMoneyMarketTokensByChainId(chainId) {
|
|
27131
|
+
async getMoneyMarketTokensByChainId(chainId, config) {
|
|
26180
27132
|
return this.makeRequest(`/config/money-market/${chainId}/tokens`, {
|
|
27133
|
+
...config,
|
|
26181
27134
|
method: "GET"
|
|
26182
27135
|
});
|
|
26183
27136
|
}
|
|
@@ -26185,30 +27138,39 @@ var BackendApiService = class {
|
|
|
26185
27138
|
* Get all supported hub assets (assets representing spoke token deposit)
|
|
26186
27139
|
* @returns Promise<GetHubAssetsApiResponse>
|
|
26187
27140
|
*/
|
|
26188
|
-
async getHubAssets() {
|
|
26189
|
-
return this.makeRequest("/config/hub/assets", { method: "GET" });
|
|
27141
|
+
async getHubAssets(config) {
|
|
27142
|
+
return this.makeRequest("/config/hub/assets", { ...config, method: "GET" });
|
|
26190
27143
|
}
|
|
26191
27144
|
/**
|
|
26192
27145
|
* Get supported hub assets (assets representing spoke token deposit) for a specific spoke chain
|
|
26193
27146
|
* @param chainId - Spoke chain id
|
|
26194
27147
|
* @returns Promise<GetHubAssetsByChainIdApiResponse>
|
|
26195
27148
|
*/
|
|
26196
|
-
async getHubAssetsByChainId(chainId) {
|
|
26197
|
-
return this.makeRequest(`/config/hub/${chainId}/assets`, {
|
|
27149
|
+
async getHubAssetsByChainId(chainId, config) {
|
|
27150
|
+
return this.makeRequest(`/config/hub/${chainId}/assets`, {
|
|
27151
|
+
...config,
|
|
27152
|
+
method: "GET"
|
|
27153
|
+
});
|
|
26198
27154
|
}
|
|
26199
27155
|
/**
|
|
26200
27156
|
* Get the intent relay chain id map
|
|
26201
27157
|
* @returns Promise<GetRelayChainIdMapApiResponse>
|
|
26202
27158
|
*/
|
|
26203
|
-
async getRelayChainIdMap() {
|
|
26204
|
-
return this.makeRequest("/config/relay/chain-id-map", {
|
|
27159
|
+
async getRelayChainIdMap(config) {
|
|
27160
|
+
return this.makeRequest("/config/relay/chain-id-map", {
|
|
27161
|
+
...config,
|
|
27162
|
+
method: "GET"
|
|
27163
|
+
});
|
|
26205
27164
|
}
|
|
26206
27165
|
/**
|
|
26207
27166
|
* Get the spoke chain config
|
|
26208
27167
|
* @returns Promise<GetSpokeChainConfigApiResponse>
|
|
26209
27168
|
*/
|
|
26210
|
-
async getSpokeChainConfig() {
|
|
26211
|
-
return this.makeRequest("/config/spoke/all-chains-configs", {
|
|
27169
|
+
async getSpokeChainConfig(config) {
|
|
27170
|
+
return this.makeRequest("/config/spoke/all-chains-configs", {
|
|
27171
|
+
...config,
|
|
27172
|
+
method: "GET"
|
|
27173
|
+
});
|
|
26212
27174
|
}
|
|
26213
27175
|
/**
|
|
26214
27176
|
* Set custom headers for API requests
|
|
@@ -26473,7 +27435,7 @@ var BridgeService = class {
|
|
|
26473
27435
|
}
|
|
26474
27436
|
const packetResult = await relayTxAndWaitPacket(
|
|
26475
27437
|
txResult.value,
|
|
26476
|
-
spokeProvider instanceof SolanaSpokeProvider ? txResult.data : void 0,
|
|
27438
|
+
spokeProvider instanceof SolanaSpokeProvider || spokeProvider instanceof BitcoinSpokeProvider ? txResult.data : void 0,
|
|
26477
27439
|
spokeProvider,
|
|
26478
27440
|
this.relayerApiEndpoint,
|
|
26479
27441
|
timeout
|
|
@@ -26546,7 +27508,11 @@ var BridgeService = class {
|
|
|
26546
27508
|
const dstAssetInfo = this.configService.getHubAssetInfo(params.dstChainId, params.dstAsset);
|
|
26547
27509
|
invariant6__default.default(srcAssetInfo, `Unsupported spoke chain (${params.srcChainId}) token: ${params.srcAsset}`);
|
|
26548
27510
|
invariant6__default.default(dstAssetInfo, `Unsupported spoke chain (${params.dstChainId}) token: ${params.dstAsset}`);
|
|
26549
|
-
|
|
27511
|
+
let walletAddress = await spokeProvider.walletProvider.getWalletAddress();
|
|
27512
|
+
if (spokeProvider instanceof BitcoinSpokeProvider && spokeProvider.walletMode === "TRADING") {
|
|
27513
|
+
const tradingWallet = await spokeProvider.radfi.getTradingWallet(walletAddress);
|
|
27514
|
+
walletAddress = tradingWallet.tradingAddress;
|
|
27515
|
+
}
|
|
26550
27516
|
const hubWallet = await WalletAbstractionService.getUserAbstractedWalletAddress(
|
|
26551
27517
|
walletAddress,
|
|
26552
27518
|
spokeProvider,
|
|
@@ -30080,11 +31046,16 @@ var BalnSwapService = class {
|
|
|
30080
31046
|
exports.ARBITRUM_MAINNET_CHAIN_ID = ARBITRUM_MAINNET_CHAIN_ID;
|
|
30081
31047
|
exports.AVALANCHE_MAINNET_CHAIN_ID = AVALANCHE_MAINNET_CHAIN_ID;
|
|
30082
31048
|
exports.BASE_MAINNET_CHAIN_ID = BASE_MAINNET_CHAIN_ID;
|
|
31049
|
+
exports.BITCOIN_MAINNET_CHAIN_ID = BITCOIN_MAINNET_CHAIN_ID;
|
|
30083
31050
|
exports.BSC_MAINNET_CHAIN_ID = BSC_MAINNET_CHAIN_ID;
|
|
30084
31051
|
exports.BackendApiService = BackendApiService;
|
|
30085
31052
|
exports.BalnSwapService = BalnSwapService;
|
|
30086
31053
|
exports.BigIntToHex = BigIntToHex;
|
|
30087
31054
|
exports.BigNumberZeroDecimal = BigNumberZeroDecimal;
|
|
31055
|
+
exports.BitcoinBaseSpokeProvider = BitcoinBaseSpokeProvider;
|
|
31056
|
+
exports.BitcoinRawSpokeProvider = BitcoinRawSpokeProvider;
|
|
31057
|
+
exports.BitcoinSpokeProvider = BitcoinSpokeProvider;
|
|
31058
|
+
exports.BitcoinSpokeService = BitcoinSpokeService;
|
|
30088
31059
|
exports.BnUSDMigrationService = BnUSDMigrationService;
|
|
30089
31060
|
exports.BridgeService = BridgeService;
|
|
30090
31061
|
exports.CHAIN_IDS = CHAIN_IDS;
|
|
@@ -30161,6 +31132,7 @@ exports.ProtocolIntentsAbi = ProtocolIntentsAbi;
|
|
|
30161
31132
|
exports.RAY = RAY;
|
|
30162
31133
|
exports.RAY_DECIMALS = RAY_DECIMALS;
|
|
30163
31134
|
exports.REDBELLY_MAINNET_CHAIN_ID = REDBELLY_MAINNET_CHAIN_ID;
|
|
31135
|
+
exports.RadfiProvider = RadfiProvider;
|
|
30164
31136
|
exports.SECONDS_PER_YEAR = SECONDS_PER_YEAR;
|
|
30165
31137
|
exports.SOLANA_MAINNET_CHAIN_ID = SOLANA_MAINNET_CHAIN_ID;
|
|
30166
31138
|
exports.SONIC_MAINNET_CHAIN_ID = SONIC_MAINNET_CHAIN_ID;
|
|
@@ -30226,6 +31198,7 @@ exports.convertTransactionInstructionToRaw = convertTransactionInstructionToRaw;
|
|
|
30226
31198
|
exports.defaultSharedConfig = defaultSharedConfig;
|
|
30227
31199
|
exports.defaultSodaxConfig = defaultSodaxConfig;
|
|
30228
31200
|
exports.deriveUserWalletAddress = deriveUserWalletAddress;
|
|
31201
|
+
exports.detectBitcoinAddressType = detectBitcoinAddressType;
|
|
30229
31202
|
exports.encodeAddress = encodeAddress;
|
|
30230
31203
|
exports.encodeContractCalls = encodeContractCalls;
|
|
30231
31204
|
exports.erc20Abi = erc20Abi;
|
|
@@ -30264,6 +31237,9 @@ exports.hubChainConfig = hubChainConfig;
|
|
|
30264
31237
|
exports.hyper = hyper;
|
|
30265
31238
|
exports.isAddressString = isAddressString;
|
|
30266
31239
|
exports.isBalnMigrateParams = isBalnMigrateParams;
|
|
31240
|
+
exports.isBitcoinRawSpokeProvider = isBitcoinRawSpokeProvider;
|
|
31241
|
+
exports.isBitcoinSpokeProvider = isBitcoinSpokeProvider;
|
|
31242
|
+
exports.isBitcoinSpokeProviderType = isBitcoinSpokeProviderType;
|
|
30267
31243
|
exports.isConfiguredMoneyMarketConfig = isConfiguredMoneyMarketConfig;
|
|
30268
31244
|
exports.isConfiguredSolverConfig = isConfiguredSolverConfig;
|
|
30269
31245
|
exports.isCreateIntentAutoSwapError = isCreateIntentAutoSwapError;
|
|
@@ -30331,6 +31307,8 @@ exports.isStellarRawSpokeProvider = isStellarRawSpokeProvider;
|
|
|
30331
31307
|
exports.isStellarRawSpokeProviderConfig = isStellarRawSpokeProviderConfig;
|
|
30332
31308
|
exports.isStellarSpokeProvider = isStellarSpokeProvider;
|
|
30333
31309
|
exports.isStellarSpokeProviderType = isStellarSpokeProviderType;
|
|
31310
|
+
exports.isSubmitSwapTxResponse = isSubmitSwapTxResponse;
|
|
31311
|
+
exports.isSubmitSwapTxStatusResponse = isSubmitSwapTxStatusResponse;
|
|
30334
31312
|
exports.isSuiRawSpokeProvider = isSuiRawSpokeProvider;
|
|
30335
31313
|
exports.isSuiSpokeProvider = isSuiSpokeProvider;
|
|
30336
31314
|
exports.isSuiSpokeProviderType = isSuiSpokeProviderType;
|
|
@@ -30345,6 +31323,7 @@ exports.nativeToUSD = nativeToUSD;
|
|
|
30345
31323
|
exports.newbnUSDSpokeChainIds = newbnUSDSpokeChainIds;
|
|
30346
31324
|
exports.normalize = normalize;
|
|
30347
31325
|
exports.normalizeBN = normalizeBN;
|
|
31326
|
+
exports.normalizePsbtToBase64 = normalizePsbtToBase64;
|
|
30348
31327
|
exports.normalizedToUsd = normalizedToUsd;
|
|
30349
31328
|
exports.parseToStroops = parseToStroops;
|
|
30350
31329
|
exports.parseTokenArrayFromJson = parseTokenArrayFromJson;
|