@sodax/sdk 2.0.0-rc.11 → 2.0.0-rc.12
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 +388 -127
- package/dist/index.d.cts +215 -93
- package/dist/index.d.ts +215 -93
- package/dist/index.mjs +383 -129
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -3052,9 +3052,9 @@ var spokeChainConfig = {
|
|
|
3052
3052
|
supportedTokens: bitcoinSupportedTokens,
|
|
3053
3053
|
radfi: {
|
|
3054
3054
|
walletMode: "TRADING",
|
|
3055
|
-
apiUrl: "https://api.
|
|
3055
|
+
apiUrl: "https://api.bound.exchange/api",
|
|
3056
3056
|
apiKey: "",
|
|
3057
|
-
umsUrl: "https://ums.
|
|
3057
|
+
umsUrl: "https://api.ums.bound.exchange/api",
|
|
3058
3058
|
accessToken: "",
|
|
3059
3059
|
refreshToken: ""
|
|
3060
3060
|
},
|
|
@@ -3896,6 +3896,9 @@ function detectBitcoinAddressType(address) {
|
|
|
3896
3896
|
return "P2PKH";
|
|
3897
3897
|
throw new Error(`Unknown Bitcoin address type: ${address}`);
|
|
3898
3898
|
}
|
|
3899
|
+
function usesBip322MessageSigning(addressType) {
|
|
3900
|
+
return addressType === "P2WPKH" || addressType === "P2TR";
|
|
3901
|
+
}
|
|
3899
3902
|
var BTC_WALLET_ADDRESS_TYPES = ["taproot", "segwit"];
|
|
3900
3903
|
var BTC_ADDRESS_TYPES = ["P2PKH", "P2SH", "P2WPKH", "P2TR"];
|
|
3901
3904
|
|
|
@@ -4013,7 +4016,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
|
|
|
4013
4016
|
}
|
|
4014
4017
|
|
|
4015
4018
|
// ../types/dist/index.js
|
|
4016
|
-
var CONFIG_VERSION =
|
|
4019
|
+
var CONFIG_VERSION = 210;
|
|
4017
4020
|
function isEvmSpokeChainConfig(value) {
|
|
4018
4021
|
return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
|
|
4019
4022
|
}
|
|
@@ -4440,7 +4443,7 @@ async function waitUntilIntentExecuted(payload) {
|
|
|
4440
4443
|
}
|
|
4441
4444
|
async function relayTxAndWaitPacket(params) {
|
|
4442
4445
|
try {
|
|
4443
|
-
const { srcTxHash, data, chainKey, relayerApiEndpoint, timeout = DEFAULT_RELAY_TX_TIMEOUT } = params;
|
|
4446
|
+
const { srcTxHash, data, chainKey, relayerApiEndpoint, timeout = DEFAULT_RELAY_TX_TIMEOUT, pollTxHash } = params;
|
|
4444
4447
|
const intentRelayChainId = getIntentRelayChainId(chainKey).toString();
|
|
4445
4448
|
const isSplitTxChain = isSolanaChainKeyType(chainKey) || isBitcoinChainKeyType(chainKey);
|
|
4446
4449
|
invariant(!isSplitTxChain || data !== void 0, "Data is required for Solana and Bitcoin chain keys");
|
|
@@ -4459,7 +4462,9 @@ async function relayTxAndWaitPacket(params) {
|
|
|
4459
4462
|
if (!submitResult.ok) return submitResult;
|
|
4460
4463
|
return await waitUntilIntentExecuted({
|
|
4461
4464
|
intentRelayChainId,
|
|
4462
|
-
|
|
4465
|
+
// The relay may track the packet under a different id than the submit tx_hash (Bitcoin
|
|
4466
|
+
// on-demand: submit "withdraw", poll the derived `od:<hash>`). Defaults to the submit id.
|
|
4467
|
+
srcTxHash: pollTxHash ?? srcTxHash,
|
|
4463
4468
|
timeout,
|
|
4464
4469
|
apiUrl: relayerApiEndpoint
|
|
4465
4470
|
});
|
|
@@ -13298,11 +13303,43 @@ function mergeSodaxConfig(base2, override) {
|
|
|
13298
13303
|
return merged;
|
|
13299
13304
|
}
|
|
13300
13305
|
|
|
13306
|
+
// src/shared/logger.ts
|
|
13307
|
+
var consoleLogger = {
|
|
13308
|
+
debug: (message, data) => data ? console.debug(message, data) : console.debug(message),
|
|
13309
|
+
info: (message, data) => data ? console.info(message, data) : console.info(message),
|
|
13310
|
+
warn: (message, data) => data ? console.warn(message, data) : console.warn(message),
|
|
13311
|
+
error: (message, error, data) => {
|
|
13312
|
+
if (error !== void 0 && data !== void 0) console.error(message, error, data);
|
|
13313
|
+
else if (error !== void 0) console.error(message, error);
|
|
13314
|
+
else console.error(message);
|
|
13315
|
+
}
|
|
13316
|
+
};
|
|
13317
|
+
var silentLogger = {
|
|
13318
|
+
debug: () => {
|
|
13319
|
+
},
|
|
13320
|
+
info: () => {
|
|
13321
|
+
},
|
|
13322
|
+
warn: () => {
|
|
13323
|
+
},
|
|
13324
|
+
error: () => {
|
|
13325
|
+
}
|
|
13326
|
+
};
|
|
13327
|
+
function resolveLogger(option) {
|
|
13328
|
+
if (option === void 0 || option === "console") return consoleLogger;
|
|
13329
|
+
if (option === "silent") return silentLogger;
|
|
13330
|
+
return option;
|
|
13331
|
+
}
|
|
13332
|
+
|
|
13301
13333
|
// src/shared/config/ConfigService.ts
|
|
13302
13334
|
var ConfigService = class {
|
|
13303
13335
|
sodax;
|
|
13304
13336
|
api;
|
|
13305
13337
|
userConfig;
|
|
13338
|
+
/**
|
|
13339
|
+
* SDK log sink. Resolved once at construction and kept independent of {@link sodax} so that
|
|
13340
|
+
* {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.logger`.
|
|
13341
|
+
*/
|
|
13342
|
+
logger;
|
|
13306
13343
|
initialized = false;
|
|
13307
13344
|
// data structures for quick lookup
|
|
13308
13345
|
supportedHubAssetsSet;
|
|
@@ -13314,10 +13351,11 @@ var ConfigService = class {
|
|
|
13314
13351
|
stakedATokenAddressesSet;
|
|
13315
13352
|
chainToSupportedTokenAddressMap;
|
|
13316
13353
|
hubAssetToXTokenMap;
|
|
13317
|
-
constructor({ api, config, userConfig }) {
|
|
13354
|
+
constructor({ api, config, userConfig, logger }) {
|
|
13318
13355
|
this.api = api;
|
|
13319
13356
|
this.sodax = config;
|
|
13320
13357
|
this.userConfig = userConfig;
|
|
13358
|
+
this.logger = logger ?? resolveLogger(void 0);
|
|
13321
13359
|
this.loadSodaxConfigDataStructures(config);
|
|
13322
13360
|
}
|
|
13323
13361
|
async initialize() {
|
|
@@ -13326,7 +13364,7 @@ var ConfigService = class {
|
|
|
13326
13364
|
if (!result.ok) return result;
|
|
13327
13365
|
const response = result.value;
|
|
13328
13366
|
if (!response.version || response.version < CONFIG_VERSION) {
|
|
13329
|
-
|
|
13367
|
+
this.logger.warn(
|
|
13330
13368
|
`Dynamic config version is less than the current version, resorting to the default one. Current version: ${CONFIG_VERSION}, response version: ${response.version}`
|
|
13331
13369
|
);
|
|
13332
13370
|
} else {
|
|
@@ -14484,7 +14522,7 @@ var RadfiProvider = class {
|
|
|
14484
14522
|
}
|
|
14485
14523
|
}
|
|
14486
14524
|
/**
|
|
14487
|
-
* Authenticate with
|
|
14525
|
+
* Authenticate with Bound Exchange: BIP322-sign a login message, then call the Bound Exchange API.
|
|
14488
14526
|
* Returns accessToken, refreshToken, and tradingAddress.
|
|
14489
14527
|
*/
|
|
14490
14528
|
async authenticateWithWallet(walletProvider, cachedPublicKey) {
|
|
@@ -14500,15 +14538,14 @@ var RadfiProvider = class {
|
|
|
14500
14538
|
throw new Error("Failed to retrieve public key from wallet. Please unlock your wallet and try again.");
|
|
14501
14539
|
}
|
|
14502
14540
|
const message = `${Date.now()}`;
|
|
14503
|
-
const
|
|
14504
|
-
const signature = addressType === "P2WPKH" || addressType === "P2TR" ? await walletProvider.signBip322Message(message) : await walletProvider.signEcdsaMessage(message);
|
|
14541
|
+
const signature = usesBip322MessageSigning(detectBitcoinAddressType(address)) ? await walletProvider.signBip322Message(message) : await walletProvider.signEcdsaMessage(message);
|
|
14505
14542
|
const result = await this.authenticate({ message, signature, address, publicKey });
|
|
14506
14543
|
this.setRadfiAccessToken(result.accessToken, result.refreshToken);
|
|
14507
14544
|
return { ...result, publicKey };
|
|
14508
14545
|
}
|
|
14509
14546
|
/**
|
|
14510
|
-
* Ensure a valid
|
|
14511
|
-
* If a token exists, validates it via the
|
|
14547
|
+
* Ensure a valid Bound Exchange access token is set on this provider.
|
|
14548
|
+
* If a token exists, validates it via the Bound Exchange API.
|
|
14512
14549
|
* If invalid, tries refreshing with the refresh token first.
|
|
14513
14550
|
* If refresh also fails, falls back to full re-authentication (BIP322 sign).
|
|
14514
14551
|
*/
|
|
@@ -14541,7 +14578,7 @@ var RadfiProvider = class {
|
|
|
14541
14578
|
});
|
|
14542
14579
|
if (!res.ok) {
|
|
14543
14580
|
const err = await res.json();
|
|
14544
|
-
throw new RadfiApiError(res.status, err, "
|
|
14581
|
+
throw new RadfiApiError(res.status, err, "Bound Exchange authentication failed");
|
|
14545
14582
|
}
|
|
14546
14583
|
return res.json().then((r) => ({
|
|
14547
14584
|
accessToken: r.data?.accessToken ?? "",
|
|
@@ -14633,12 +14670,20 @@ var RadfiProvider = class {
|
|
|
14633
14670
|
}
|
|
14634
14671
|
})
|
|
14635
14672
|
});
|
|
14636
|
-
|
|
14637
|
-
|
|
14638
|
-
throw new RadfiApiError(res.status,
|
|
14673
|
+
const body = await res.json();
|
|
14674
|
+
if (!res.ok || !body?.data) {
|
|
14675
|
+
throw new RadfiApiError(res.status, body, "Bound Exchange transaction request failed");
|
|
14639
14676
|
}
|
|
14640
|
-
return
|
|
14677
|
+
return body.data;
|
|
14641
14678
|
}
|
|
14679
|
+
/**
|
|
14680
|
+
* Co-sign and broadcast a `sodax-withdraw` deposit via the Bound Exchange API.
|
|
14681
|
+
*
|
|
14682
|
+
* `relayData` ({ address, payload }) is the same `RelayExtraData` the SDK returns from
|
|
14683
|
+
* `createIntent()` / money-market supply etc. It is optional and non-breaking: when supplied,
|
|
14684
|
+
* the Bound Exchange backend persists it so it can auto-resubmit the intent relay if the relay
|
|
14685
|
+
* gets stuck (otherwise a stuck relay eventually refunds instead of completing the swap).
|
|
14686
|
+
*/
|
|
14642
14687
|
async requestRadfiSignature(params, accessToken) {
|
|
14643
14688
|
const res = await this.request("/sodax/transaction/sign", {
|
|
14644
14689
|
method: "POST",
|
|
@@ -14652,7 +14697,7 @@ var RadfiProvider = class {
|
|
|
14652
14697
|
});
|
|
14653
14698
|
if (!res.ok) {
|
|
14654
14699
|
const err = await res.json();
|
|
14655
|
-
throw new RadfiApiError(res.status, err, "
|
|
14700
|
+
throw new RadfiApiError(res.status, err, "Bound Exchange signature request failed");
|
|
14656
14701
|
}
|
|
14657
14702
|
return res.json().then((r) => r.data.txId);
|
|
14658
14703
|
}
|
|
@@ -14676,7 +14721,7 @@ var RadfiProvider = class {
|
|
|
14676
14721
|
return res.json();
|
|
14677
14722
|
}
|
|
14678
14723
|
/**
|
|
14679
|
-
* Build a renew-utxo transaction via the
|
|
14724
|
+
* Build a renew-utxo transaction via the Bound Exchange API.
|
|
14680
14725
|
* Returns a PSBT that needs to be signed by the user.
|
|
14681
14726
|
*/
|
|
14682
14727
|
async buildRenewUtxoTransaction(params, accessToken) {
|
|
@@ -14700,8 +14745,8 @@ var RadfiProvider = class {
|
|
|
14700
14745
|
return res.json().then((r) => r.data);
|
|
14701
14746
|
}
|
|
14702
14747
|
/**
|
|
14703
|
-
* Sign and broadcast a renew-utxo transaction via the
|
|
14704
|
-
* The user signs the PSBT first, then
|
|
14748
|
+
* Sign and broadcast a renew-utxo transaction via the Bound Exchange API.
|
|
14749
|
+
* The user signs the PSBT first, then Bound Exchange co-signs and broadcasts.
|
|
14705
14750
|
*/
|
|
14706
14751
|
async signAndBroadcastRenewUtxo(params, accessToken) {
|
|
14707
14752
|
const res = await this.request("/transactions/sign", {
|
|
@@ -14742,7 +14787,7 @@ var RadfiProvider = class {
|
|
|
14742
14787
|
return res.json().then((r) => r.data);
|
|
14743
14788
|
}
|
|
14744
14789
|
/**
|
|
14745
|
-
* Sign and broadcast a withdraw transaction via
|
|
14790
|
+
* Sign and broadcast a withdraw transaction via Bound Exchange.
|
|
14746
14791
|
*/
|
|
14747
14792
|
async signAndBroadcastWithdraw(params, accessToken) {
|
|
14748
14793
|
const res = await this.request("/transactions/sign", {
|
|
@@ -14796,7 +14841,20 @@ var RadfiProvider = class {
|
|
|
14796
14841
|
};
|
|
14797
14842
|
|
|
14798
14843
|
// src/shared/entities/btc/btc-utils.ts
|
|
14799
|
-
|
|
14844
|
+
var BITCOIN_FEE_SAFETY_VBYTES = 20;
|
|
14845
|
+
function calcOpReturnOutputVbytes(payloadByteLength) {
|
|
14846
|
+
let scriptSize;
|
|
14847
|
+
if (payloadByteLength <= 75) {
|
|
14848
|
+
scriptSize = 3 + payloadByteLength;
|
|
14849
|
+
} else if (payloadByteLength <= 255) {
|
|
14850
|
+
scriptSize = 4 + payloadByteLength;
|
|
14851
|
+
} else {
|
|
14852
|
+
scriptSize = 5 + payloadByteLength;
|
|
14853
|
+
}
|
|
14854
|
+
const scriptLenVarint = scriptSize <= 252 ? 1 : 3;
|
|
14855
|
+
return 8 + scriptLenVarint + scriptSize;
|
|
14856
|
+
}
|
|
14857
|
+
function estimateBitcoinTxSize(inputCount, outputCount, addressType, opReturnOutputVbytes = 44) {
|
|
14800
14858
|
let inputWeight;
|
|
14801
14859
|
switch (addressType) {
|
|
14802
14860
|
case "P2PKH":
|
|
@@ -14812,7 +14870,9 @@ function estimateBitcoinTxSize(inputCount, outputCount, addressType) {
|
|
|
14812
14870
|
inputWeight = 68;
|
|
14813
14871
|
break;
|
|
14814
14872
|
}
|
|
14815
|
-
return Math.ceil(
|
|
14873
|
+
return Math.ceil(
|
|
14874
|
+
10.5 + opReturnOutputVbytes + BITCOIN_FEE_SAFETY_VBYTES + inputCount * inputWeight + outputCount * 31
|
|
14875
|
+
);
|
|
14816
14876
|
}
|
|
14817
14877
|
function encodeBtcPayloadToBytes(payload) {
|
|
14818
14878
|
return JSON.stringify({
|
|
@@ -14829,6 +14889,10 @@ function normalizePsbtToBase64(signedPsbt) {
|
|
|
14829
14889
|
const isHex = /^[0-9a-fA-F]+$/.test(signedPsbt);
|
|
14830
14890
|
return isHex ? Buffer.from(signedPsbt, "hex").toString("base64") : signedPsbt;
|
|
14831
14891
|
}
|
|
14892
|
+
function normalizeSignatureToBase64(signature) {
|
|
14893
|
+
const isHex = /^[0-9a-fA-F]+$/.test(signature);
|
|
14894
|
+
return isHex ? Buffer.from(signature, "hex").toString("base64") : signature;
|
|
14895
|
+
}
|
|
14832
14896
|
|
|
14833
14897
|
// src/shared/services/spoke/BitcoinSpokeService.ts
|
|
14834
14898
|
bitcoinjsLib.initEccLib(ecc__namespace);
|
|
@@ -14937,7 +15001,7 @@ var BitcoinSpokeService = class {
|
|
|
14937
15001
|
return BigInt(totalBalance);
|
|
14938
15002
|
}
|
|
14939
15003
|
/**
|
|
14940
|
-
* Fund the
|
|
15004
|
+
* Fund the Bound Exchange trading wallet by sending BTC from the user's personal wallet
|
|
14941
15005
|
*
|
|
14942
15006
|
* @param {bigint} amount - Amount in satoshis to send
|
|
14943
15007
|
* @param {BitcoinSpokeProvider} spokeProvider - The Bitcoin spoke provider (must have signing capability)
|
|
@@ -14961,10 +15025,28 @@ var BitcoinSpokeService = class {
|
|
|
14961
15025
|
async sendMessage(params) {
|
|
14962
15026
|
return await this.encodeWithdrawalData(params);
|
|
14963
15027
|
}
|
|
15028
|
+
/**
|
|
15029
|
+
* Build the relay submit/poll identity for an on-demand action (borrow/withdraw).
|
|
15030
|
+
*
|
|
15031
|
+
* Bitcoin borrow/withdraw are on-demand: there is no broadcast transaction — the spoke result is
|
|
15032
|
+
* the signed payload JSON produced by {@link encodeWithdrawalData}/{@link sendMessage}. The relay
|
|
15033
|
+
* accepts the submit under the literal `withdraw` tx_hash with the signed payload (as a JSON object)
|
|
15034
|
+
* in `data`, then tracks the resulting packet under a derived id: `od:` + keccak256 of the ASCII
|
|
15035
|
+
* `payload_hex` string (hash the hex characters, not the decoded bytes). Polling must use that
|
|
15036
|
+
* derived id (`pollTxHash`), not `withdraw`.
|
|
15037
|
+
*
|
|
15038
|
+
* @param tx - The JSON-stringified signed payload returned by `sendMessage` / `encodeWithdrawalData`.
|
|
15039
|
+
*/
|
|
15040
|
+
getOnDemandRelayIdentity(tx) {
|
|
15041
|
+
const data = JSON.parse(tx);
|
|
15042
|
+
const payloadHex = data.payload_hex.startsWith("0x") ? data.payload_hex.slice(2) : data.payload_hex;
|
|
15043
|
+
const pollTxHash = `od:${viem.keccak256(viem.stringToBytes(payloadHex)).slice(2)}`;
|
|
15044
|
+
return { srcTxHash: "withdraw", data, pollTxHash };
|
|
15045
|
+
}
|
|
14964
15046
|
/**
|
|
14965
15047
|
* Build a priority Bitcoin transaction with proper fee calculation
|
|
14966
15048
|
*/
|
|
14967
|
-
async buildBitcoinTransaction(utxos, outputs, changeAddress, chainId, walletProvider, feeRate) {
|
|
15049
|
+
async buildBitcoinTransaction(utxos, outputs, changeAddress, chainId, walletProvider, feeRate, opReturnOutputVbytes) {
|
|
14968
15050
|
const psbt = new bitcoinjsLib.Psbt({ network: this.getBtcNetwork(chainId) });
|
|
14969
15051
|
const effectiveFeeRate = feeRate ?? await this.getFeeRateEstimate();
|
|
14970
15052
|
const walletAddress = await walletProvider.getWalletAddress();
|
|
@@ -15027,7 +15109,7 @@ var BitcoinSpokeService = class {
|
|
|
15027
15109
|
});
|
|
15028
15110
|
}
|
|
15029
15111
|
inputSum += utxo.value;
|
|
15030
|
-
const estimatedSize = estimateBitcoinTxSize(psbt.inputCount, outputs.length, addressType);
|
|
15112
|
+
const estimatedSize = estimateBitcoinTxSize(psbt.inputCount, outputs.length, addressType, opReturnOutputVbytes);
|
|
15031
15113
|
const estimatedFee = Math.ceil(effectiveFeeRate * estimatedSize);
|
|
15032
15114
|
if (inputSum >= outputSum + estimatedFee + DUST_THRESHOLD) {
|
|
15033
15115
|
break;
|
|
@@ -15039,8 +15121,13 @@ var BitcoinSpokeService = class {
|
|
|
15039
15121
|
value: output.value
|
|
15040
15122
|
});
|
|
15041
15123
|
}
|
|
15042
|
-
const sizeWithChange = estimateBitcoinTxSize(
|
|
15043
|
-
|
|
15124
|
+
const sizeWithChange = estimateBitcoinTxSize(
|
|
15125
|
+
psbt.inputCount,
|
|
15126
|
+
outputs.length + 1,
|
|
15127
|
+
addressType,
|
|
15128
|
+
opReturnOutputVbytes
|
|
15129
|
+
);
|
|
15130
|
+
const sizeWithoutChange = estimateBitcoinTxSize(psbt.inputCount, outputs.length, addressType, opReturnOutputVbytes);
|
|
15044
15131
|
const feeWithChange = Math.ceil(effectiveFeeRate * sizeWithChange);
|
|
15045
15132
|
const feeWithoutChange = Math.ceil(effectiveFeeRate * sizeWithoutChange);
|
|
15046
15133
|
let change = inputSum - outputSum - feeWithChange;
|
|
@@ -15109,7 +15196,12 @@ var BitcoinSpokeService = class {
|
|
|
15109
15196
|
return await this.radfi.requestRadfiSignature(
|
|
15110
15197
|
{
|
|
15111
15198
|
userAddress: from,
|
|
15112
|
-
signedBase64Tx
|
|
15199
|
+
signedBase64Tx,
|
|
15200
|
+
// Forward the relay identity ({ hub wallet address, full payload }) so the Bound Exchange
|
|
15201
|
+
// backend can auto-resubmit the intent relay if it gets stuck. `to` is the hub wallet
|
|
15202
|
+
// (relayData.address) and `data` is the full payload (relayData.payload) — the same pair
|
|
15203
|
+
// feature services return as `relayData` from createIntent()/supply().
|
|
15204
|
+
relayData: { address: params.to, payload: data }
|
|
15113
15205
|
},
|
|
15114
15206
|
accessToken
|
|
15115
15207
|
);
|
|
@@ -15119,7 +15211,11 @@ var BitcoinSpokeService = class {
|
|
|
15119
15211
|
"Raw mode is not supported for normal Bitcoin deposits. Use TRADING wallet mode for raw transactions."
|
|
15120
15212
|
);
|
|
15121
15213
|
}
|
|
15122
|
-
const
|
|
15214
|
+
const [allUtxos, mempoolSpent] = await Promise.all([
|
|
15215
|
+
this.fetchUTXOs(from),
|
|
15216
|
+
this.fetchMempoolSpentOutpoints(from)
|
|
15217
|
+
]);
|
|
15218
|
+
const utxos = allUtxos.filter((u) => !mempoolSpent.has(`${u.txid}:${u.vout}`));
|
|
15123
15219
|
if (!utxos?.length) {
|
|
15124
15220
|
throw new Error("No UTXOs available for deposit");
|
|
15125
15221
|
}
|
|
@@ -15134,7 +15230,7 @@ var BitcoinSpokeService = class {
|
|
|
15134
15230
|
);
|
|
15135
15231
|
return await this.signAndBroadcastTransaction(depositPsbt, params.walletProvider);
|
|
15136
15232
|
} catch (error) {
|
|
15137
|
-
|
|
15233
|
+
this.config.logger.error("Error during deposit", error);
|
|
15138
15234
|
throw error;
|
|
15139
15235
|
}
|
|
15140
15236
|
}
|
|
@@ -15142,22 +15238,37 @@ var BitcoinSpokeService = class {
|
|
|
15142
15238
|
* Build deposit PSBT with embedded cross-chain data
|
|
15143
15239
|
*/
|
|
15144
15240
|
async buildDepositPsbt(walletAddress, walletProvider, srcChainKey, token, amount, data, utxos) {
|
|
15145
|
-
const
|
|
15146
|
-
|
|
15241
|
+
const chainConfig = this.config.getChainConfig(srcChainKey);
|
|
15242
|
+
const assetManagerAddress = chainConfig.addresses.assetManager;
|
|
15243
|
+
const normalizedToken = token.toLocaleLowerCase();
|
|
15244
|
+
const nativeBtcTokens = new Set(
|
|
15245
|
+
["btc", chainConfig.nativeToken, chainConfig.supportedTokens.BTC?.address].filter((value) => !!value).map((value) => value.toLocaleLowerCase())
|
|
15246
|
+
);
|
|
15247
|
+
const isNativeBtc = nativeBtcTokens.has(normalizedToken);
|
|
15248
|
+
if (isNativeBtc) {
|
|
15249
|
+
const OP_RETURN = bitcoinjsLib.opcodes.OP_RETURN;
|
|
15250
|
+
const OP_12 = bitcoinjsLib.opcodes.OP_12;
|
|
15251
|
+
if (OP_RETURN === void 0 || OP_12 === void 0) {
|
|
15252
|
+
throw new Error("bitcoinjs-lib opcodes OP_RETURN or OP_12 are undefined");
|
|
15253
|
+
}
|
|
15254
|
+
const OP_RADFI_SODAX_DATA = 49;
|
|
15255
|
+
const payload = Buffer.concat([Buffer.from([OP_RADFI_SODAX_DATA]), Buffer.from(data.slice(2), "hex")]);
|
|
15256
|
+
const opReturnOutputVbytes = calcOpReturnOutputVbytes(payload.length);
|
|
15147
15257
|
const outputs = [
|
|
15148
15258
|
{
|
|
15149
15259
|
address: assetManagerAddress,
|
|
15150
15260
|
value: Number(amount)
|
|
15151
15261
|
}
|
|
15152
15262
|
];
|
|
15153
|
-
const psbt = await this.buildBitcoinTransaction(
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
-
|
|
15160
|
-
|
|
15263
|
+
const psbt = await this.buildBitcoinTransaction(
|
|
15264
|
+
utxos,
|
|
15265
|
+
outputs,
|
|
15266
|
+
walletAddress,
|
|
15267
|
+
srcChainKey,
|
|
15268
|
+
walletProvider,
|
|
15269
|
+
void 0,
|
|
15270
|
+
opReturnOutputVbytes
|
|
15271
|
+
);
|
|
15161
15272
|
const compiledScript = bitcoinjsLib.script.compile([OP_RETURN, OP_12, payload]);
|
|
15162
15273
|
psbt.addOutput({
|
|
15163
15274
|
script: compiledScript,
|
|
@@ -15177,6 +15288,27 @@ var BitcoinSpokeService = class {
|
|
|
15177
15288
|
}
|
|
15178
15289
|
return await response.json();
|
|
15179
15290
|
}
|
|
15291
|
+
/**
|
|
15292
|
+
* Returns the set of "txid:vout" outpoints currently being spent by
|
|
15293
|
+
* unconfirmed transactions in the mempool for the given address.
|
|
15294
|
+
* Used to prevent double-spend when building a new PSBT.
|
|
15295
|
+
*/
|
|
15296
|
+
async fetchMempoolSpentOutpoints(address) {
|
|
15297
|
+
try {
|
|
15298
|
+
const response = await fetch(`${this.rpcUrl}/address/${address}/txs/mempool`);
|
|
15299
|
+
if (!response.ok) return /* @__PURE__ */ new Set();
|
|
15300
|
+
const mempoolTxs = await response.json();
|
|
15301
|
+
const spent = /* @__PURE__ */ new Set();
|
|
15302
|
+
for (const tx of mempoolTxs) {
|
|
15303
|
+
for (const input of tx.vin) {
|
|
15304
|
+
spent.add(`${input.txid}:${input.vout}`);
|
|
15305
|
+
}
|
|
15306
|
+
}
|
|
15307
|
+
return spent;
|
|
15308
|
+
} catch {
|
|
15309
|
+
return /* @__PURE__ */ new Set();
|
|
15310
|
+
}
|
|
15311
|
+
}
|
|
15180
15312
|
/**
|
|
15181
15313
|
* Fetch raw transaction hex
|
|
15182
15314
|
*/
|
|
@@ -15192,7 +15324,7 @@ var BitcoinSpokeService = class {
|
|
|
15192
15324
|
let srcAddress = from;
|
|
15193
15325
|
const addressType = detectBitcoinAddressType(from);
|
|
15194
15326
|
if (walletMode === "TRADING") {
|
|
15195
|
-
srcAddress = await this.radfi.getTradingWallet(srcAddress)
|
|
15327
|
+
srcAddress = (await this.radfi.getTradingWallet(srcAddress)).tradingAddress;
|
|
15196
15328
|
}
|
|
15197
15329
|
const payload = {
|
|
15198
15330
|
src_address: srcAddress,
|
|
@@ -15211,8 +15343,12 @@ var BitcoinSpokeService = class {
|
|
|
15211
15343
|
if (params.raw === true) {
|
|
15212
15344
|
return JSON.stringify(onDemandWithdraw);
|
|
15213
15345
|
}
|
|
15214
|
-
|
|
15215
|
-
|
|
15346
|
+
if (!params.walletProvider.getPublicKey) {
|
|
15347
|
+
throw new Error("Wallet provider does not support getPublicKey");
|
|
15348
|
+
}
|
|
15349
|
+
const rawSignature = usesBip322MessageSigning(addressType) ? await params.walletProvider.signBip322Message(orderedPayload) : await params.walletProvider.signEcdsaMessage(orderedPayload);
|
|
15350
|
+
onDemandWithdraw.signature = normalizeSignatureToBase64(rawSignature);
|
|
15351
|
+
onDemandWithdraw.public_key = await params.walletProvider.getPublicKey();
|
|
15216
15352
|
return JSON.stringify(onDemandWithdraw);
|
|
15217
15353
|
}
|
|
15218
15354
|
/**
|
|
@@ -15220,8 +15356,14 @@ var BitcoinSpokeService = class {
|
|
|
15220
15356
|
*/
|
|
15221
15357
|
async signAndBroadcastTransaction(psbt, walletProvider) {
|
|
15222
15358
|
const psbtBase64 = typeof psbt === "string" ? psbt : psbt.toBase64();
|
|
15223
|
-
const
|
|
15224
|
-
const
|
|
15359
|
+
const signedRaw = await walletProvider.signTransaction(psbtBase64, false);
|
|
15360
|
+
const signedPsbt = bitcoinjsLib.Psbt.fromBase64(normalizePsbtToBase64(signedRaw));
|
|
15361
|
+
try {
|
|
15362
|
+
signedPsbt.finalizeAllInputs();
|
|
15363
|
+
} catch {
|
|
15364
|
+
}
|
|
15365
|
+
const txHex = signedPsbt.extractTransaction().toHex();
|
|
15366
|
+
const txHash = await this.broadcastTransaction(txHex);
|
|
15225
15367
|
return txHash;
|
|
15226
15368
|
}
|
|
15227
15369
|
/**
|
|
@@ -17460,7 +17602,7 @@ function base64Decode(str) {
|
|
|
17460
17602
|
}
|
|
17461
17603
|
var encoder = new TextEncoder();
|
|
17462
17604
|
var decoder = new TextDecoder();
|
|
17463
|
-
function
|
|
17605
|
+
function stringToBytes2(str) {
|
|
17464
17606
|
return encoder.encode(str);
|
|
17465
17607
|
}
|
|
17466
17608
|
function bytesToString(bytes) {
|
|
@@ -20857,7 +20999,7 @@ var JsonRpcProvider = class {
|
|
|
20857
20999
|
};
|
|
20858
21000
|
}
|
|
20859
21001
|
async viewContractState({ contractId, prefix: prefix2, blockQuery = { finality: DEFAULT_FINALITY } }) {
|
|
20860
|
-
const prefixBase64 = base64Encode(
|
|
21002
|
+
const prefixBase64 = base64Encode(stringToBytes2(prefix2 || ""));
|
|
20861
21003
|
let reference;
|
|
20862
21004
|
if ("blockId" in blockQuery) {
|
|
20863
21005
|
reference = { block_id: blockQuery.blockId };
|
|
@@ -20885,7 +21027,7 @@ var JsonRpcProvider = class {
|
|
|
20885
21027
|
}
|
|
20886
21028
|
}
|
|
20887
21029
|
async callFunctionRaw({ contractId, method, args, blockQuery = { finality: DEFAULT_FINALITY } }) {
|
|
20888
|
-
const argsBytes = args instanceof Uint8Array ? args :
|
|
21030
|
+
const argsBytes = args instanceof Uint8Array ? args : stringToBytes2(JSON.stringify(args));
|
|
20889
21031
|
const argsBase64 = base64Encode(argsBytes);
|
|
20890
21032
|
if ("blockId" in blockQuery) {
|
|
20891
21033
|
return this.query({
|
|
@@ -21151,6 +21293,7 @@ var JsonRpcProvider = class {
|
|
|
21151
21293
|
|
|
21152
21294
|
// src/shared/services/spoke/NearSpokeService.ts
|
|
21153
21295
|
var NEAR_DEFAULT_GAS = BigInt("300000000000000");
|
|
21296
|
+
var NEAR_STORAGE_DEPOSIT = BigInt("1250000000000000000000");
|
|
21154
21297
|
var NearSpokeService = class {
|
|
21155
21298
|
config;
|
|
21156
21299
|
rpcProvider;
|
|
@@ -21200,7 +21343,7 @@ var NearSpokeService = class {
|
|
|
21200
21343
|
token: Array.from(Buffer.from(fillData.token, "utf-8"))
|
|
21201
21344
|
};
|
|
21202
21345
|
}
|
|
21203
|
-
async fillIntent(fromInfo, fillData, deposit = BigInt("
|
|
21346
|
+
async fillIntent(fromInfo, fillData, deposit = BigInt("1"), gas = BigInt("300000000000000")) {
|
|
21204
21347
|
const intentFiller = this.config.getChainConfig(fromInfo.srcChainKey).addresses.intentFiller;
|
|
21205
21348
|
if (isNativeToken(fromInfo.srcChainKey, fillData.token)) {
|
|
21206
21349
|
deposit = BigInt(fillData.amount);
|
|
@@ -21274,7 +21417,8 @@ var NearSpokeService = class {
|
|
|
21274
21417
|
data: inputParams.data
|
|
21275
21418
|
})
|
|
21276
21419
|
},
|
|
21277
|
-
|
|
21420
|
+
// NEP-141 requires exactly 1 yoctoNEAR attached to ft_transfer_call.
|
|
21421
|
+
deposit: BigInt("1"),
|
|
21278
21422
|
gas: NEAR_DEFAULT_GAS
|
|
21279
21423
|
}
|
|
21280
21424
|
};
|
|
@@ -21305,6 +21449,52 @@ var NearSpokeService = class {
|
|
|
21305
21449
|
}
|
|
21306
21450
|
return BigInt(bal);
|
|
21307
21451
|
}
|
|
21452
|
+
/**
|
|
21453
|
+
* Whether `accountId` is storage-registered on a NEP-141 `token` contract. NEP-141 requires an
|
|
21454
|
+
* account to pay a one-time storage bond before it can receive (hold a balance of) the token, so
|
|
21455
|
+
* this gates any leg that delivers a token to a user on NEAR (swap output on NEAR, bridge into
|
|
21456
|
+
* NEAR, money-market borrow/withdraw to NEAR).
|
|
21457
|
+
*
|
|
21458
|
+
* Native NEAR is not a NEP-141 token and has no storage registration, so this returns `true` for
|
|
21459
|
+
* the native token. The view goes through {@link queryContract}, i.e. the configurable RPC from
|
|
21460
|
+
* chain config — a custom `rpcUrl` passed to the SDK is honoured.
|
|
21461
|
+
*/
|
|
21462
|
+
async isStorageRegistered(token, accountId) {
|
|
21463
|
+
if (isNativeToken(ChainKeys.NEAR_MAINNET, token)) {
|
|
21464
|
+
return true;
|
|
21465
|
+
}
|
|
21466
|
+
const balance = await this.queryContract(token, "storage_balance_of", { account_id: accountId });
|
|
21467
|
+
return balance != null;
|
|
21468
|
+
}
|
|
21469
|
+
/**
|
|
21470
|
+
* Build (and, unless `raw`, submit) a NEP-141 `storage_deposit` registration for `accountId` on
|
|
21471
|
+
* the `token` contract. Call this when {@link isStorageRegistered} is `false` before a token is
|
|
21472
|
+
* delivered to the account on NEAR.
|
|
21473
|
+
*
|
|
21474
|
+
* Native NEAR has no storage registration — passing the native token throws.
|
|
21475
|
+
*
|
|
21476
|
+
* @param params.deposit Storage bond to attach; defaults to {@link NEAR_STORAGE_DEPOSIT}
|
|
21477
|
+
* (0.00125 NEAR). Override per token if its `storage_balance_bounds.min` differs.
|
|
21478
|
+
*/
|
|
21479
|
+
async registerStorage(params) {
|
|
21480
|
+
if (isNativeToken(ChainKeys.NEAR_MAINNET, params.token)) {
|
|
21481
|
+
throw new Error("[NearSpokeService.registerStorage] Native NEAR has no NEP-141 storage registration.");
|
|
21482
|
+
}
|
|
21483
|
+
const tx = {
|
|
21484
|
+
signerId: params.accountId,
|
|
21485
|
+
params: {
|
|
21486
|
+
contractId: params.token,
|
|
21487
|
+
method: "storage_deposit",
|
|
21488
|
+
args: { account_id: params.accountId, registration_only: true },
|
|
21489
|
+
deposit: params.deposit ?? NEAR_STORAGE_DEPOSIT,
|
|
21490
|
+
gas: NEAR_DEFAULT_GAS
|
|
21491
|
+
}
|
|
21492
|
+
};
|
|
21493
|
+
if (params.raw === true) {
|
|
21494
|
+
return tx;
|
|
21495
|
+
}
|
|
21496
|
+
return params.walletProvider.signAndSubmitTxn(tx);
|
|
21497
|
+
}
|
|
21308
21498
|
/**
|
|
21309
21499
|
* Sends a message to the hub chain.
|
|
21310
21500
|
* @param {SendMessageParams} params - Includes dstChainKey, the chain key of the hub chain.
|
|
@@ -22512,13 +22702,13 @@ var StellarSpokeService = class {
|
|
|
22512
22702
|
);
|
|
22513
22703
|
return `${hash}`;
|
|
22514
22704
|
} catch (error) {
|
|
22515
|
-
|
|
22705
|
+
this.config.logger.error("Error during sendMessage", error);
|
|
22516
22706
|
throw error;
|
|
22517
22707
|
}
|
|
22518
22708
|
}
|
|
22519
22709
|
handleSendTransactionError(response) {
|
|
22520
22710
|
if (response.status === "ERROR") {
|
|
22521
|
-
|
|
22711
|
+
this.config.logger.error(JSON.stringify(response, null, 2));
|
|
22522
22712
|
throw new Error(JSON.stringify(response, null, 2));
|
|
22523
22713
|
}
|
|
22524
22714
|
return response;
|
|
@@ -22629,7 +22819,7 @@ var StellarSpokeService = class {
|
|
|
22629
22819
|
);
|
|
22630
22820
|
return `${hash}`;
|
|
22631
22821
|
} catch (error) {
|
|
22632
|
-
|
|
22822
|
+
this.config.logger.error("Error during deposit", error);
|
|
22633
22823
|
throw error;
|
|
22634
22824
|
}
|
|
22635
22825
|
}
|
|
@@ -22657,7 +22847,7 @@ var StellarSpokeService = class {
|
|
|
22657
22847
|
(balance2) => "limit" in balance2 && "balance" in balance2 && "asset_code" in balance2 && trustlineConfig.assetCode.toLowerCase() === balance2.asset_code?.toLowerCase() && "asset_issuer" in balance2 && trustlineConfig.assetIssuer.toLowerCase() === balance2.asset_issuer?.toLowerCase()
|
|
22658
22848
|
);
|
|
22659
22849
|
if (!tokenBalance) {
|
|
22660
|
-
|
|
22850
|
+
this.config.logger.error(`No token balances found for token: ${token}`);
|
|
22661
22851
|
return false;
|
|
22662
22852
|
}
|
|
22663
22853
|
const limit = parseToStroops(tokenBalance.limit);
|
|
@@ -22706,7 +22896,7 @@ var StellarSpokeService = class {
|
|
|
22706
22896
|
const hash = await this.signAndSendTransaction(walletProvider, transaction);
|
|
22707
22897
|
return `${hash}`;
|
|
22708
22898
|
} catch (error) {
|
|
22709
|
-
|
|
22899
|
+
this.config.logger.error("Error during requestTrustline", error);
|
|
22710
22900
|
throw error;
|
|
22711
22901
|
}
|
|
22712
22902
|
}
|
|
@@ -23565,7 +23755,7 @@ var SpokeService = class _SpokeService {
|
|
|
23565
23755
|
}
|
|
23566
23756
|
default: {
|
|
23567
23757
|
const exhaustiveCheck = chainType;
|
|
23568
|
-
|
|
23758
|
+
this.config.logger.debug("Unhandled exhaustive case", { value: exhaustiveCheck });
|
|
23569
23759
|
throw new Error(`[getSpokeService] Invalid chain type. Valid chain types: ${ChainTypeArr.join(", ")}`);
|
|
23570
23760
|
}
|
|
23571
23761
|
}
|
|
@@ -23738,7 +23928,7 @@ var SpokeService = class _SpokeService {
|
|
|
23738
23928
|
}
|
|
23739
23929
|
default: {
|
|
23740
23930
|
const exhaustiveCheck = chainType;
|
|
23741
|
-
|
|
23931
|
+
this.config.logger.debug("Unhandled exhaustive case", { value: exhaustiveCheck });
|
|
23742
23932
|
return {
|
|
23743
23933
|
ok: false,
|
|
23744
23934
|
error: new Error(`[estimateGas] Invalid chain type. Valid chain types: ${ChainTypeArr.join(", ")}`)
|
|
@@ -23845,17 +24035,17 @@ var SpokeService = class _SpokeService {
|
|
|
23845
24035
|
args: [params.srcChainId, params.srcAddress, params.payload]
|
|
23846
24036
|
})
|
|
23847
24037
|
});
|
|
23848
|
-
|
|
24038
|
+
this.config.logger.warn("simulateRecvMessage did not revert as expected", { result });
|
|
23849
24039
|
return {
|
|
23850
24040
|
ok: false,
|
|
23851
24041
|
error: new Error('Function should have reverted with "Simulation completed"')
|
|
23852
24042
|
};
|
|
23853
24043
|
} catch (error) {
|
|
23854
24044
|
if (error instanceof Error && error.message?.includes("Simulation completed")) {
|
|
23855
|
-
|
|
24045
|
+
this.config.logger.warn("simulateRecvMessage completed successfully with expected revert");
|
|
23856
24046
|
return { ok: true, value: true };
|
|
23857
24047
|
}
|
|
23858
|
-
|
|
24048
|
+
this.config.logger.error("simulateRecvMessage failed with unexpected error", error);
|
|
23859
24049
|
return { ok: false, error };
|
|
23860
24050
|
}
|
|
23861
24051
|
}
|
|
@@ -23940,7 +24130,7 @@ var SpokeService = class _SpokeService {
|
|
|
23940
24130
|
}
|
|
23941
24131
|
default: {
|
|
23942
24132
|
const exhaustiveCheck = chainType;
|
|
23943
|
-
|
|
24133
|
+
this.config.logger.debug("Unhandled exhaustive case", { value: exhaustiveCheck });
|
|
23944
24134
|
return {
|
|
23945
24135
|
ok: false,
|
|
23946
24136
|
error: new Error(`[deposit] Invalid chain type. Valid chain types: ${ChainTypeArr.join(", ")}`)
|
|
@@ -24017,7 +24207,7 @@ var SpokeService = class _SpokeService {
|
|
|
24017
24207
|
}
|
|
24018
24208
|
default: {
|
|
24019
24209
|
const exhaustiveCheck = chainType;
|
|
24020
|
-
|
|
24210
|
+
this.config.logger.debug("Unhandled exhaustive case", { value: exhaustiveCheck });
|
|
24021
24211
|
return {
|
|
24022
24212
|
ok: false,
|
|
24023
24213
|
error: new Error(`[getDeposit] Invalid chain type. Valid chain types: ${ChainTypeArr.join(", ")}`)
|
|
@@ -24126,7 +24316,7 @@ var SpokeService = class _SpokeService {
|
|
|
24126
24316
|
}
|
|
24127
24317
|
default: {
|
|
24128
24318
|
const exhaustiveCheck = chainType;
|
|
24129
|
-
|
|
24319
|
+
this.config.logger.debug("Unhandled exhaustive case", { value: exhaustiveCheck });
|
|
24130
24320
|
return {
|
|
24131
24321
|
ok: false,
|
|
24132
24322
|
error: new Error(`[sendMessage] Invalid chain type. Valid chain types: ${ChainTypeArr.join(", ")}`)
|
|
@@ -24205,10 +24395,10 @@ var SpokeService = class _SpokeService {
|
|
|
24205
24395
|
if (isSolanaChainKeyType(chainKey)) {
|
|
24206
24396
|
const result = await this.solana.waitForTransactionReceipt({ txHash, chainKey });
|
|
24207
24397
|
if (!result.ok || result.value.status !== "success") {
|
|
24208
|
-
|
|
24398
|
+
this.config.logger.warn(
|
|
24209
24399
|
`Solana verifyTxHash failed: ${!result.ok ? result.error : "error" in result.value ? result.value.error : "unknown"}`
|
|
24210
24400
|
);
|
|
24211
|
-
|
|
24401
|
+
this.config.logger.warn("Returning true to assume transaction exists on chain in future ");
|
|
24212
24402
|
return { ok: true, value: true };
|
|
24213
24403
|
}
|
|
24214
24404
|
return { ok: true, value: true };
|
|
@@ -24295,7 +24485,7 @@ var SpokeService = class _SpokeService {
|
|
|
24295
24485
|
}
|
|
24296
24486
|
default: {
|
|
24297
24487
|
const exhaustiveCheck = chainType;
|
|
24298
|
-
|
|
24488
|
+
this.config.logger.debug("Unhandled exhaustive case", { value: exhaustiveCheck });
|
|
24299
24489
|
return { ok: false, error: new Error(`waitForTransactionReceipt not supported for ${params.chainKey}`) };
|
|
24300
24490
|
}
|
|
24301
24491
|
}
|
|
@@ -25346,6 +25536,7 @@ var EvmHubProvider = class {
|
|
|
25346
25536
|
};
|
|
25347
25537
|
|
|
25348
25538
|
// src/swap/SolverApiService.ts
|
|
25539
|
+
var bigintReplacer = (_key, value) => typeof value === "bigint" ? value.toString() : value;
|
|
25349
25540
|
var SolverApiService = class {
|
|
25350
25541
|
constructor() {
|
|
25351
25542
|
}
|
|
@@ -25414,13 +25605,16 @@ var SolverApiService = class {
|
|
|
25414
25605
|
}
|
|
25415
25606
|
};
|
|
25416
25607
|
} catch (e) {
|
|
25417
|
-
|
|
25608
|
+
configService.logger.error(
|
|
25609
|
+
"[SolverApiService.getQuote] failed",
|
|
25610
|
+
e instanceof Error ? e : new Error(JSON.stringify(e, bigintReplacer))
|
|
25611
|
+
);
|
|
25418
25612
|
return {
|
|
25419
25613
|
ok: false,
|
|
25420
25614
|
error: {
|
|
25421
25615
|
detail: {
|
|
25422
25616
|
code: exports.SolverIntentErrorCode.UNKNOWN,
|
|
25423
|
-
message: e ? JSON.stringify(e) : "Unknown error"
|
|
25617
|
+
message: e ? JSON.stringify(e, bigintReplacer) : "Unknown error"
|
|
25424
25618
|
}
|
|
25425
25619
|
}
|
|
25426
25620
|
};
|
|
@@ -25437,7 +25631,7 @@ var SolverApiService = class {
|
|
|
25437
25631
|
* @param config - Solver endpoint configuration.
|
|
25438
25632
|
* @returns A `Result` containing `{ answer: 'OK', intent_hash: Hex }` on success.
|
|
25439
25633
|
*/
|
|
25440
|
-
static async postExecution(request, config) {
|
|
25634
|
+
static async postExecution(request, config, logger = silentLogger) {
|
|
25441
25635
|
try {
|
|
25442
25636
|
const response = await retry(
|
|
25443
25637
|
() => fetch(`${config.solverApiEndpoint}/execute`, {
|
|
@@ -25459,13 +25653,16 @@ var SolverApiService = class {
|
|
|
25459
25653
|
value: await response.json()
|
|
25460
25654
|
};
|
|
25461
25655
|
} catch (e) {
|
|
25462
|
-
|
|
25656
|
+
logger.error(
|
|
25657
|
+
"[SolverApiService.postExecution] failed",
|
|
25658
|
+
e instanceof Error ? e : new Error(JSON.stringify(e, bigintReplacer))
|
|
25659
|
+
);
|
|
25463
25660
|
return {
|
|
25464
25661
|
ok: false,
|
|
25465
25662
|
error: {
|
|
25466
25663
|
detail: {
|
|
25467
25664
|
code: exports.SolverIntentErrorCode.UNKNOWN,
|
|
25468
|
-
message: e ? JSON.stringify(e) : "Unknown error"
|
|
25665
|
+
message: e ? JSON.stringify(e, bigintReplacer) : "Unknown error"
|
|
25469
25666
|
}
|
|
25470
25667
|
}
|
|
25471
25668
|
};
|
|
@@ -25480,7 +25677,7 @@ var SolverApiService = class {
|
|
|
25480
25677
|
* `fill_tx_hash` is set only when `status === SolverIntentStatusCode.SOLVED (3)`.
|
|
25481
25678
|
* @throws Invariant error if `intent_tx_hash` is empty (thrown before the async request).
|
|
25482
25679
|
*/
|
|
25483
|
-
static async getStatus(request, config) {
|
|
25680
|
+
static async getStatus(request, config, logger = silentLogger) {
|
|
25484
25681
|
invariant(request.intent_tx_hash.length > 0, "Empty intent_tx_hash");
|
|
25485
25682
|
try {
|
|
25486
25683
|
const response = await fetch(`${config.solverApiEndpoint}/status`, {
|
|
@@ -25501,13 +25698,16 @@ var SolverApiService = class {
|
|
|
25501
25698
|
value: await response.json()
|
|
25502
25699
|
};
|
|
25503
25700
|
} catch (e) {
|
|
25504
|
-
|
|
25701
|
+
logger.error(
|
|
25702
|
+
"[SolverApiService.getStatus] failed",
|
|
25703
|
+
e instanceof Error ? e : new Error(JSON.stringify(e, bigintReplacer))
|
|
25704
|
+
);
|
|
25505
25705
|
return {
|
|
25506
25706
|
ok: false,
|
|
25507
25707
|
error: {
|
|
25508
25708
|
detail: {
|
|
25509
25709
|
code: exports.SolverIntentErrorCode.UNKNOWN,
|
|
25510
|
-
message: e ? JSON.stringify(e) : "Unknown error"
|
|
25710
|
+
message: e ? JSON.stringify(e, bigintReplacer) : "Unknown error"
|
|
25511
25711
|
}
|
|
25512
25712
|
}
|
|
25513
25713
|
};
|
|
@@ -25627,7 +25827,7 @@ var SwapService = class {
|
|
|
25627
25827
|
* `fill_tx_hash` is populated only when `status === SolverIntentStatusCode.SOLVED (3)`.
|
|
25628
25828
|
*/
|
|
25629
25829
|
async getStatus(request) {
|
|
25630
|
-
return SolverApiService.getStatus(request, this.solver);
|
|
25830
|
+
return SolverApiService.getStatus(request, this.solver, this.config.logger);
|
|
25631
25831
|
}
|
|
25632
25832
|
/**
|
|
25633
25833
|
* Notifies the solver API that an intent has been registered on the hub chain, triggering
|
|
@@ -25650,7 +25850,7 @@ var SwapService = class {
|
|
|
25650
25850
|
*/
|
|
25651
25851
|
async postExecution(request) {
|
|
25652
25852
|
try {
|
|
25653
|
-
const result = await SolverApiService.postExecution(request, this.solver);
|
|
25853
|
+
const result = await SolverApiService.postExecution(request, this.solver, this.config.logger);
|
|
25654
25854
|
if (result.ok) return result;
|
|
25655
25855
|
const detail = result.error?.detail ?? {
|
|
25656
25856
|
code: -999,
|
|
@@ -25923,7 +26123,7 @@ var SwapService = class {
|
|
|
25923
26123
|
* - `raw: false` — broadcasts the transaction; `walletProvider` is required and must match `K`.
|
|
25924
26124
|
*
|
|
25925
26125
|
* Validates tokens and chain keys against the active `ConfigService` before constructing the
|
|
25926
|
-
* intent. Bitcoin source chains require an additional
|
|
26126
|
+
* intent. Bitcoin source chains require an additional Bound Exchange access token step.
|
|
25927
26127
|
*
|
|
25928
26128
|
* @param _params - Intent parameters, source chain key, wallet provider (when `raw: false`),
|
|
25929
26129
|
* and optional `skipSimulation` flag.
|
|
@@ -28404,11 +28604,13 @@ var MigrationService = class {
|
|
|
28404
28604
|
|
|
28405
28605
|
// src/backendApi/BackendApiService.ts
|
|
28406
28606
|
var BackendApiService = class {
|
|
28407
|
-
constructor(config) {
|
|
28607
|
+
constructor(config, logger = consoleLogger) {
|
|
28408
28608
|
this.config = config;
|
|
28409
28609
|
this.headers = { ...config.headers };
|
|
28610
|
+
this.logger = logger;
|
|
28410
28611
|
}
|
|
28411
28612
|
headers;
|
|
28613
|
+
logger;
|
|
28412
28614
|
/**
|
|
28413
28615
|
* Execute a single HTTP request and return the parsed JSON body.
|
|
28414
28616
|
*
|
|
@@ -28447,10 +28649,10 @@ var BackendApiService = class {
|
|
|
28447
28649
|
if (error.name === "AbortError") {
|
|
28448
28650
|
throw new Error("REQUEST_TIMEOUT", { cause: new Error(`Request timeout after ${timeout}ms`) });
|
|
28449
28651
|
}
|
|
28450
|
-
|
|
28652
|
+
this.logger.error("[BackendApiService] Request error", error);
|
|
28451
28653
|
throw error;
|
|
28452
28654
|
}
|
|
28453
|
-
|
|
28655
|
+
this.logger.error("[BackendApiService] Unknown error", error);
|
|
28454
28656
|
throw new Error("UNKNOWN_REQUEST_ERROR", { cause: error });
|
|
28455
28657
|
}
|
|
28456
28658
|
}
|
|
@@ -29120,7 +29322,7 @@ var BridgeService = class {
|
|
|
29120
29322
|
* transaction simulation or batching). When `raw` is `false`, signs and submits the deposit
|
|
29121
29323
|
* transaction via the provided wallet provider.
|
|
29122
29324
|
*
|
|
29123
|
-
* Bitcoin is only supported with `raw: false` because it requires the
|
|
29325
|
+
* Bitcoin is only supported with `raw: false` because it requires the Bound Exchange trading wallet
|
|
29124
29326
|
* derivation flow.
|
|
29125
29327
|
*
|
|
29126
29328
|
* @param _params - Bridge parameters including source/destination chain keys, token addresses,
|
|
@@ -29153,9 +29355,12 @@ var BridgeService = class {
|
|
|
29153
29355
|
{ ...baseCtx, field: "walletProvider" }
|
|
29154
29356
|
);
|
|
29155
29357
|
walletAddress = await this.spoke.bitcoin.getEffectiveWalletAddress(personalAddress);
|
|
29156
|
-
|
|
29358
|
+
if (this.spoke.bitcoin.walletMode === "TRADING") {
|
|
29359
|
+
await this.spoke.bitcoin.radfi.ensureRadfiAccessToken(_params.walletProvider);
|
|
29360
|
+
}
|
|
29157
29361
|
}
|
|
29158
|
-
const hubWallet = await this.hubProvider.getUserHubWalletAddress(
|
|
29362
|
+
const hubWallet = await this.hubProvider.getUserHubWalletAddress(walletAddress, params.srcChainKey);
|
|
29363
|
+
const effectiveSkipSimulation = skipSimulation || isBitcoinChainKeyType(params.srcChainKey) && this.spoke.bitcoin.walletMode === "USER";
|
|
29159
29364
|
const data = this.buildBridgeData(params, srcToken, dstToken, this.config.bridge.partnerFee);
|
|
29160
29365
|
const coreParams = {
|
|
29161
29366
|
srcChainKey: params.srcChainKey,
|
|
@@ -29164,7 +29369,7 @@ var BridgeService = class {
|
|
|
29164
29369
|
token: params.srcToken,
|
|
29165
29370
|
amount: params.amount,
|
|
29166
29371
|
data,
|
|
29167
|
-
skipSimulation
|
|
29372
|
+
skipSimulation: effectiveSkipSimulation
|
|
29168
29373
|
};
|
|
29169
29374
|
const txResult = await this.spoke.deposit(
|
|
29170
29375
|
_params.raw ? {
|
|
@@ -29177,7 +29382,7 @@ var BridgeService = class {
|
|
|
29177
29382
|
}
|
|
29178
29383
|
);
|
|
29179
29384
|
if (!txResult.ok) {
|
|
29180
|
-
|
|
29385
|
+
this.config.logger.error("createBridgeIntent failed", txResult.error);
|
|
29181
29386
|
if (isBridgeCreateIntentError(txResult.error)) return { ok: false, error: txResult.error };
|
|
29182
29387
|
return {
|
|
29183
29388
|
ok: false,
|
|
@@ -29192,7 +29397,7 @@ var BridgeService = class {
|
|
|
29192
29397
|
}
|
|
29193
29398
|
};
|
|
29194
29399
|
} catch (error) {
|
|
29195
|
-
|
|
29400
|
+
this.config.logger.error("createBridgeIntent failed", error);
|
|
29196
29401
|
if (isBridgeCreateIntentError(error)) return { ok: false, error };
|
|
29197
29402
|
return {
|
|
29198
29403
|
ok: false,
|
|
@@ -29362,7 +29567,7 @@ var BridgeService = class {
|
|
|
29362
29567
|
value: availableDepositNormalised.isLessThan(assetManagerBalanceNormalised) ? { amount: availableDeposit, decimals: fromTokenInfo.decimals, type: "DEPOSIT_LIMIT" } : { amount: assetManagerBalance, decimals: toTokenInfo.decimals, type: "WITHDRAWAL_LIMIT" }
|
|
29363
29568
|
};
|
|
29364
29569
|
} catch (error) {
|
|
29365
|
-
|
|
29570
|
+
this.config.logger.error("getBridgeableAmount failed", error);
|
|
29366
29571
|
if (isBridgeLookupError(error)) return { ok: false, error };
|
|
29367
29572
|
return {
|
|
29368
29573
|
ok: false,
|
|
@@ -29409,7 +29614,7 @@ var BridgeService = class {
|
|
|
29409
29614
|
});
|
|
29410
29615
|
return srcToken.vault.toLowerCase() === dstToken.vault.toLowerCase();
|
|
29411
29616
|
} catch (error) {
|
|
29412
|
-
|
|
29617
|
+
this.config.logger.error("isBridgeable check failed", error);
|
|
29413
29618
|
return false;
|
|
29414
29619
|
}
|
|
29415
29620
|
}
|
|
@@ -31799,7 +32004,7 @@ var ClService = class _ClService {
|
|
|
31799
32004
|
};
|
|
31800
32005
|
const txResult = await this.spoke.sendMessage(sendMessageParams);
|
|
31801
32006
|
if (!txResult.ok) {
|
|
31802
|
-
|
|
32007
|
+
this.config.logger.error("executeSupplyLiquidity error", txResult.error);
|
|
31803
32008
|
return {
|
|
31804
32009
|
ok: false,
|
|
31805
32010
|
error: txResult.error
|
|
@@ -31813,7 +32018,7 @@ var ClService = class _ClService {
|
|
|
31813
32018
|
}
|
|
31814
32019
|
};
|
|
31815
32020
|
} catch (error) {
|
|
31816
|
-
|
|
32021
|
+
this.config.logger.error("executeSupplyLiquidity error", error);
|
|
31817
32022
|
return {
|
|
31818
32023
|
ok: false,
|
|
31819
32024
|
error
|
|
@@ -32086,7 +32291,7 @@ var ClService = class _ClService {
|
|
|
32086
32291
|
}
|
|
32087
32292
|
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32088
32293
|
} catch (error) {
|
|
32089
|
-
|
|
32294
|
+
this.config.logger.error("supplyLiquidity error", error);
|
|
32090
32295
|
return {
|
|
32091
32296
|
ok: false,
|
|
32092
32297
|
error
|
|
@@ -32230,7 +32435,7 @@ var ClService = class _ClService {
|
|
|
32230
32435
|
}
|
|
32231
32436
|
};
|
|
32232
32437
|
} catch (error) {
|
|
32233
|
-
|
|
32438
|
+
this.config.logger.error("getPoolRewardConfig error", error);
|
|
32234
32439
|
return {
|
|
32235
32440
|
ok: false,
|
|
32236
32441
|
error: lookupFailed("dex", "getPoolRewardConfig", error)
|
|
@@ -32291,7 +32496,7 @@ var ClService = class _ClService {
|
|
|
32291
32496
|
};
|
|
32292
32497
|
const txResult = await this.spoke.sendMessage(sendMessageParams);
|
|
32293
32498
|
if (!txResult.ok) {
|
|
32294
|
-
|
|
32499
|
+
this.config.logger.error("executeClaimRewards error", txResult.error);
|
|
32295
32500
|
return {
|
|
32296
32501
|
ok: false,
|
|
32297
32502
|
error: txResult.error
|
|
@@ -32305,7 +32510,7 @@ var ClService = class _ClService {
|
|
|
32305
32510
|
}
|
|
32306
32511
|
};
|
|
32307
32512
|
} catch (error) {
|
|
32308
|
-
|
|
32513
|
+
this.config.logger.error("executeClaimRewards error", error);
|
|
32309
32514
|
return {
|
|
32310
32515
|
ok: false,
|
|
32311
32516
|
error
|
|
@@ -32347,7 +32552,7 @@ var ClService = class _ClService {
|
|
|
32347
32552
|
}
|
|
32348
32553
|
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32349
32554
|
} catch (error) {
|
|
32350
|
-
|
|
32555
|
+
this.config.logger.error("claimRewards error", error);
|
|
32351
32556
|
return {
|
|
32352
32557
|
ok: false,
|
|
32353
32558
|
error
|
|
@@ -32395,7 +32600,7 @@ var ClService = class _ClService {
|
|
|
32395
32600
|
address: tokenAddress
|
|
32396
32601
|
};
|
|
32397
32602
|
} catch (error) {
|
|
32398
|
-
|
|
32603
|
+
this.config.logger.error(`Failed to fetch token info for ${tokenAddress}`, error);
|
|
32399
32604
|
return {
|
|
32400
32605
|
symbol: "UNKNOWN",
|
|
32401
32606
|
name: "Unknown Token",
|
|
@@ -32420,12 +32625,12 @@ var ClService = class _ClService {
|
|
|
32420
32625
|
const oneShare = BigInt(10 ** 18);
|
|
32421
32626
|
const result = await Erc4626Service.convertToAssets(statATokenAddress, oneShare, this.hubProvider.publicClient);
|
|
32422
32627
|
if (!result.ok) {
|
|
32423
|
-
|
|
32628
|
+
this.config.logger.error("[getStatATokenConversionRate] Failed to get conversion rate", result.error);
|
|
32424
32629
|
return oneShare;
|
|
32425
32630
|
}
|
|
32426
32631
|
return result.value;
|
|
32427
32632
|
} catch (error) {
|
|
32428
|
-
|
|
32633
|
+
this.config.logger.error("[getStatATokenConversionRate] Error", error);
|
|
32429
32634
|
return BigInt(10 ** 18);
|
|
32430
32635
|
}
|
|
32431
32636
|
}
|
|
@@ -32462,7 +32667,7 @@ var ClService = class _ClService {
|
|
|
32462
32667
|
underlyingToken
|
|
32463
32668
|
};
|
|
32464
32669
|
} catch (error) {
|
|
32465
|
-
|
|
32670
|
+
this.config.logger.error(`[getTokenEnrichmentData] Failed to enrich token ${token.address}`, error);
|
|
32466
32671
|
return {
|
|
32467
32672
|
token,
|
|
32468
32673
|
isStatAToken: true
|
|
@@ -32532,7 +32737,7 @@ var ClService = class _ClService {
|
|
|
32532
32737
|
rewardConfig = rewardConfigResult.value;
|
|
32533
32738
|
}
|
|
32534
32739
|
} catch (error) {
|
|
32535
|
-
|
|
32740
|
+
this.config.logger.warn("Failed to fetch reward config for pool", { error });
|
|
32536
32741
|
}
|
|
32537
32742
|
}
|
|
32538
32743
|
return {
|
|
@@ -32568,7 +32773,7 @@ var ClService = class _ClService {
|
|
|
32568
32773
|
}
|
|
32569
32774
|
};
|
|
32570
32775
|
} catch (error) {
|
|
32571
|
-
|
|
32776
|
+
this.config.logger.error("Failed to fetch pool data", error);
|
|
32572
32777
|
return {
|
|
32573
32778
|
ok: false,
|
|
32574
32779
|
error: lookupFailed("dex", "getPoolData", error)
|
|
@@ -35352,14 +35557,25 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35352
35557
|
);
|
|
35353
35558
|
const dstChainKey = params.dstChainKey ?? srcChainKey;
|
|
35354
35559
|
const dstAddress = params.dstAddress ?? params.srcAddress;
|
|
35355
|
-
const
|
|
35356
|
-
|
|
35357
|
-
|
|
35358
|
-
|
|
35560
|
+
const isBitcoinSrc = isBitcoinChainKeyType(srcChainKey);
|
|
35561
|
+
if (isBitcoinSrc && !_params.raw) {
|
|
35562
|
+
mmInvariant(
|
|
35563
|
+
walletProvider !== void 0 && isBitcoinWalletProviderType(walletProvider),
|
|
35564
|
+
`Invalid wallet provider for chain key: ${srcChainKey}. Expected bitcoin wallet provider.`,
|
|
35565
|
+
{ ...baseCtx, field: "walletProvider" }
|
|
35566
|
+
);
|
|
35567
|
+
await this.spoke.bitcoin.radfi.ensureRadfiAccessToken(walletProvider);
|
|
35568
|
+
}
|
|
35569
|
+
const srcEffectiveAddress = isBitcoinSrc ? await this.spoke.bitcoin.getEffectiveWalletAddress(params.srcAddress) : params.srcAddress;
|
|
35570
|
+
const fromHubWallet = await this.hubProvider.getUserHubWalletAddress(srcEffectiveAddress, srcChainKey);
|
|
35571
|
+
const toHubWallet = dstChainKey === srcChainKey && dstAddress === params.srcAddress ? fromHubWallet : await this.hubProvider.getUserHubWalletAddress(
|
|
35572
|
+
isBitcoinChainKeyType(dstChainKey) ? await this.spoke.bitcoin.getEffectiveWalletAddress(dstAddress) : dstAddress,
|
|
35573
|
+
dstChainKey
|
|
35574
|
+
);
|
|
35359
35575
|
const data = this.buildSupplyData(srcChainKey, params.token, params.amount, toHubWallet);
|
|
35360
35576
|
const coreParams = {
|
|
35361
35577
|
srcChainKey,
|
|
35362
|
-
srcAddress:
|
|
35578
|
+
srcAddress: srcEffectiveAddress,
|
|
35363
35579
|
to: fromHubWallet,
|
|
35364
35580
|
token: params.token,
|
|
35365
35581
|
amount: params.amount,
|
|
@@ -35399,6 +35615,17 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35399
35615
|
}
|
|
35400
35616
|
}
|
|
35401
35617
|
// ==== borrow ==========================================================================
|
|
35618
|
+
/**
|
|
35619
|
+
* Build the relay submit/poll identity for a money-market borrow/withdraw.
|
|
35620
|
+
*
|
|
35621
|
+
* Bitcoin borrow/withdraw are on-demand: the spoke result is a signed payload JSON that the relay
|
|
35622
|
+
* submits under the literal "withdraw" tx_hash and tracks under a derived `od:<hash>` poll id
|
|
35623
|
+
* (see {@link BitcoinSpokeService.getOnDemandRelayIdentity}). Every other chain relays and polls by
|
|
35624
|
+
* its real spoke tx hash, so `pollTxHash` is undefined and `srcChainTxHash` stays the spoke tx.
|
|
35625
|
+
*/
|
|
35626
|
+
buildRelayIdentity(srcChainKey, tx, relayData) {
|
|
35627
|
+
return isBitcoinChainKeyType(srcChainKey) ? this.spoke.bitcoin.getOnDemandRelayIdentity(tx) : { srcTxHash: tx, data: relayData, pollTxHash: void 0 };
|
|
35628
|
+
}
|
|
35402
35629
|
/**
|
|
35403
35630
|
* Borrow tokens from the money market lending pool and wait for the cross-chain relay to
|
|
35404
35631
|
* deliver the funds to the destination address.
|
|
@@ -35434,9 +35661,9 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35434
35661
|
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
35435
35662
|
};
|
|
35436
35663
|
}
|
|
35664
|
+
const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
|
|
35437
35665
|
const packet = await relayTxAndWaitPacket({
|
|
35438
|
-
|
|
35439
|
-
data: txResult.value.relayData,
|
|
35666
|
+
...relayIdentity,
|
|
35440
35667
|
chainKey: srcChainKey,
|
|
35441
35668
|
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
35442
35669
|
timeout
|
|
@@ -35451,7 +35678,13 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35451
35678
|
dstChainKey: baseCtx.dstChainKey
|
|
35452
35679
|
})
|
|
35453
35680
|
};
|
|
35454
|
-
return {
|
|
35681
|
+
return {
|
|
35682
|
+
ok: true,
|
|
35683
|
+
value: {
|
|
35684
|
+
srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
|
|
35685
|
+
dstChainTxHash: packet.value.dst_tx_hash
|
|
35686
|
+
}
|
|
35687
|
+
};
|
|
35455
35688
|
} catch (error) {
|
|
35456
35689
|
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
35457
35690
|
return {
|
|
@@ -35493,7 +35726,8 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35493
35726
|
field: "token"
|
|
35494
35727
|
});
|
|
35495
35728
|
const encodedDstAddress = encodeAddress(dstChainKey, dstAddress);
|
|
35496
|
-
const
|
|
35729
|
+
const srcEffectiveAddress = isBitcoinChainKeyType(srcChainKey) ? await this.spoke.bitcoin.getEffectiveWalletAddress(params.srcAddress) : params.srcAddress;
|
|
35730
|
+
const fromHubWallet = await this.hubProvider.getUserHubWalletAddress(srcEffectiveAddress, srcChainKey);
|
|
35497
35731
|
const payload = this.buildBorrowData(
|
|
35498
35732
|
fromHubWallet,
|
|
35499
35733
|
encodedDstAddress,
|
|
@@ -35577,9 +35811,9 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35577
35811
|
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
35578
35812
|
};
|
|
35579
35813
|
}
|
|
35814
|
+
const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
|
|
35580
35815
|
const packet = await relayTxAndWaitPacket({
|
|
35581
|
-
|
|
35582
|
-
data: txResult.value.relayData,
|
|
35816
|
+
...relayIdentity,
|
|
35583
35817
|
chainKey: srcChainKey,
|
|
35584
35818
|
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
35585
35819
|
timeout
|
|
@@ -35594,7 +35828,13 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35594
35828
|
dstChainKey: baseCtx.dstChainKey
|
|
35595
35829
|
})
|
|
35596
35830
|
};
|
|
35597
|
-
return {
|
|
35831
|
+
return {
|
|
35832
|
+
ok: true,
|
|
35833
|
+
value: {
|
|
35834
|
+
srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
|
|
35835
|
+
dstChainTxHash: packet.value.dst_tx_hash
|
|
35836
|
+
}
|
|
35837
|
+
};
|
|
35598
35838
|
} catch (error) {
|
|
35599
35839
|
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
35600
35840
|
return {
|
|
@@ -35636,7 +35876,8 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35636
35876
|
{ ...baseCtx, field: "token" }
|
|
35637
35877
|
);
|
|
35638
35878
|
const encodedDstAddress = encodeAddress(dstChainKey, dstAddress);
|
|
35639
|
-
const
|
|
35879
|
+
const srcEffectiveAddress = isBitcoinChainKeyType(srcChainKey) ? await this.spoke.bitcoin.getEffectiveWalletAddress(params.srcAddress) : params.srcAddress;
|
|
35880
|
+
const fromHubWallet = await this.hubProvider.getUserHubWalletAddress(srcEffectiveAddress, srcChainKey);
|
|
35640
35881
|
const payload = this.buildWithdrawData(
|
|
35641
35882
|
fromHubWallet,
|
|
35642
35883
|
encodedDstAddress,
|
|
@@ -35773,14 +36014,25 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35773
36014
|
);
|
|
35774
36015
|
const dstChainKey = params.dstChainKey ?? srcChainKey;
|
|
35775
36016
|
const dstAddress = params.dstAddress ?? params.srcAddress;
|
|
35776
|
-
const
|
|
35777
|
-
|
|
35778
|
-
|
|
35779
|
-
|
|
36017
|
+
const isBitcoinSrc = isBitcoinChainKeyType(srcChainKey);
|
|
36018
|
+
if (isBitcoinSrc && !_params.raw) {
|
|
36019
|
+
mmInvariant(
|
|
36020
|
+
walletProvider !== void 0 && isBitcoinWalletProviderType(walletProvider),
|
|
36021
|
+
`Invalid wallet provider for chain key: ${srcChainKey}. Expected bitcoin wallet provider.`,
|
|
36022
|
+
{ ...baseCtx, field: "walletProvider" }
|
|
36023
|
+
);
|
|
36024
|
+
await this.spoke.bitcoin.radfi.ensureRadfiAccessToken(walletProvider);
|
|
36025
|
+
}
|
|
36026
|
+
const srcEffectiveAddress = isBitcoinSrc ? await this.spoke.bitcoin.getEffectiveWalletAddress(params.srcAddress) : params.srcAddress;
|
|
36027
|
+
const fromHubWallet = await this.hubProvider.getUserHubWalletAddress(srcEffectiveAddress, srcChainKey);
|
|
36028
|
+
const toHubWallet = dstChainKey === srcChainKey && dstAddress === params.srcAddress ? fromHubWallet : await this.hubProvider.getUserHubWalletAddress(
|
|
36029
|
+
isBitcoinChainKeyType(dstChainKey) ? await this.spoke.bitcoin.getEffectiveWalletAddress(dstAddress) : dstAddress,
|
|
36030
|
+
dstChainKey
|
|
36031
|
+
);
|
|
35780
36032
|
const data = this.buildRepayData(srcChainKey, params.token, params.amount, toHubWallet);
|
|
35781
36033
|
const coreParams = {
|
|
35782
36034
|
srcChainKey,
|
|
35783
|
-
srcAddress:
|
|
36035
|
+
srcAddress: srcEffectiveAddress,
|
|
35784
36036
|
to: fromHubWallet,
|
|
35785
36037
|
token: params.token,
|
|
35786
36038
|
amount: params.amount,
|
|
@@ -36341,9 +36593,9 @@ var PartnerFeeClaimService = class {
|
|
|
36341
36593
|
if (typeof balanceResult === "bigint") {
|
|
36342
36594
|
balance = balanceResult;
|
|
36343
36595
|
} else {
|
|
36344
|
-
|
|
36345
|
-
`[PartnerFeeClaimService] Unexpected balance result format for ${entry.hubAsset.symbol} (${entry.assetAddress})
|
|
36346
|
-
balanceResult
|
|
36596
|
+
this.config.logger.warn(
|
|
36597
|
+
`[PartnerFeeClaimService] Unexpected balance result format for ${entry.hubAsset.symbol} (${entry.assetAddress})`,
|
|
36598
|
+
{ balanceResult }
|
|
36347
36599
|
);
|
|
36348
36600
|
balance = 0n;
|
|
36349
36601
|
}
|
|
@@ -36679,7 +36931,8 @@ var PartnerFeeClaimService = class {
|
|
|
36679
36931
|
}
|
|
36680
36932
|
const solverExecutionResponse = await SolverApiService.postExecution(
|
|
36681
36933
|
{ intent_tx_hash: intentTxHash },
|
|
36682
|
-
this.config.solver
|
|
36934
|
+
this.config.solver,
|
|
36935
|
+
this.config.logger
|
|
36683
36936
|
);
|
|
36684
36937
|
if (!solverExecutionResponse.ok) {
|
|
36685
36938
|
return solverExecutionResponse;
|
|
@@ -36890,9 +37143,10 @@ var Sodax = class {
|
|
|
36890
37143
|
spoke;
|
|
36891
37144
|
// spoke service enabling spoke chain operations
|
|
36892
37145
|
constructor(config) {
|
|
37146
|
+
const logger = resolveLogger(config?.logger);
|
|
36893
37147
|
this.instanceConfig = config ? mergeSodaxConfig(sodaxConfig, config) : sodaxConfig;
|
|
36894
|
-
this.backendApi = new BackendApiService(this.instanceConfig.api);
|
|
36895
|
-
this.config = new ConfigService({ api: this.backendApi, config: this.instanceConfig, userConfig: config });
|
|
37148
|
+
this.backendApi = new BackendApiService(this.instanceConfig.api, logger);
|
|
37149
|
+
this.config = new ConfigService({ api: this.backendApi, config: this.instanceConfig, userConfig: config, logger });
|
|
36896
37150
|
this.hubProvider = new EvmHubProvider({ config: this.config });
|
|
36897
37151
|
this.spoke = new SpokeService({ config: this.config, hubProvider: this.hubProvider });
|
|
36898
37152
|
this.swaps = new SwapService({
|
|
@@ -37045,6 +37299,7 @@ exports.MoneyMarketService = MoneyMarketService;
|
|
|
37045
37299
|
exports.NEAR_CHAIN_KEYS = NEAR_CHAIN_KEYS;
|
|
37046
37300
|
exports.NEAR_CHAIN_KEYS_SET = NEAR_CHAIN_KEYS_SET;
|
|
37047
37301
|
exports.NEAR_DEFAULT_GAS = NEAR_DEFAULT_GAS;
|
|
37302
|
+
exports.NEAR_STORAGE_DEPOSIT = NEAR_STORAGE_DEPOSIT;
|
|
37048
37303
|
exports.NearSpokeService = NearSpokeService;
|
|
37049
37304
|
exports.PartnerFeeClaimService = PartnerFeeClaimService;
|
|
37050
37305
|
exports.PartnerService = PartnerService;
|
|
@@ -37108,6 +37363,7 @@ exports.bnUSDLegacyTokens = bnUSDLegacyTokens;
|
|
|
37108
37363
|
exports.bridgeConfig = bridgeConfig;
|
|
37109
37364
|
exports.bridgeInvariant = bridgeInvariant;
|
|
37110
37365
|
exports.bscSupportedTokens = bscSupportedTokens;
|
|
37366
|
+
exports.calcOpReturnOutputVbytes = calcOpReturnOutputVbytes;
|
|
37111
37367
|
exports.calculateAllReserveIncentives = calculateAllReserveIncentives;
|
|
37112
37368
|
exports.calculateAllUserIncentives = calculateAllUserIncentives;
|
|
37113
37369
|
exports.calculateAvailableBorrowsMarketReferenceCurrency = calculateAvailableBorrowsMarketReferenceCurrency;
|
|
@@ -37126,6 +37382,7 @@ exports.clRouterAbi = clRouterAbi;
|
|
|
37126
37382
|
exports.clTickLensAbi = clTickLensAbi;
|
|
37127
37383
|
exports.concentratedLiquidityConfig = concentratedLiquidityConfig;
|
|
37128
37384
|
exports.connectionAbi = connectionAbi;
|
|
37385
|
+
exports.consoleLogger = consoleLogger;
|
|
37129
37386
|
exports.convertTransactionInstructionToRaw = convertTransactionInstructionToRaw;
|
|
37130
37387
|
exports.createInvariant = createInvariant;
|
|
37131
37388
|
exports.deepMerge = deepMerge;
|
|
@@ -37302,6 +37559,7 @@ exports.newbnUSDSpokeChainIds = newbnUSDSpokeChainIds;
|
|
|
37302
37559
|
exports.normalize = normalize;
|
|
37303
37560
|
exports.normalizeBN = normalizeBN;
|
|
37304
37561
|
exports.normalizePsbtToBase64 = normalizePsbtToBase64;
|
|
37562
|
+
exports.normalizeSignatureToBase64 = normalizeSignatureToBase64;
|
|
37305
37563
|
exports.normalizedToUsd = normalizedToUsd;
|
|
37306
37564
|
exports.optimismSupportedTokens = optimismSupportedTokens;
|
|
37307
37565
|
exports.pancakeSwapInfinityDefaultHookAbi = pancakeSwapInfinityDefaultHookAbi;
|
|
@@ -37326,9 +37584,11 @@ exports.relayTxAndWaitPacket = relayTxAndWaitPacket;
|
|
|
37326
37584
|
exports.requestAddress = requestAddress;
|
|
37327
37585
|
exports.requestJsonRpc = requestJsonRpc;
|
|
37328
37586
|
exports.requestSigning = requestSigning;
|
|
37587
|
+
exports.resolveLogger = resolveLogger;
|
|
37329
37588
|
exports.retry = retry;
|
|
37330
37589
|
exports.reverseEncodeAddress = reverseEncodeAddress;
|
|
37331
37590
|
exports.serializeAddressData = serializeAddressData;
|
|
37591
|
+
exports.silentLogger = silentLogger;
|
|
37332
37592
|
exports.sleep = sleep;
|
|
37333
37593
|
exports.sodaxConfig = sodaxConfig;
|
|
37334
37594
|
exports.sodaxInvariant = sodaxInvariant;
|
|
@@ -37356,6 +37616,7 @@ exports.swapsConfig = swapsConfig;
|
|
|
37356
37616
|
exports.uiPoolDataAbi = uiPoolDataAbi;
|
|
37357
37617
|
exports.universalRouterAbi = universalRouterAbi;
|
|
37358
37618
|
exports.unknownFailed = unknownFailed;
|
|
37619
|
+
exports.usesBip322MessageSigning = usesBip322MessageSigning;
|
|
37359
37620
|
exports.valueToBigNumber = valueToBigNumber;
|
|
37360
37621
|
exports.valueToZDBigNumber = valueToZDBigNumber;
|
|
37361
37622
|
exports.variableDebtTokenAbi = variableDebtTokenAbi;
|