@sodax/sdk 2.0.0-rc.17 → 2.0.0-rc.19
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 +2873 -1127
- package/dist/index.d.cts +564 -74
- package/dist/index.d.ts +564 -74
- package/dist/index.mjs +2870 -1126
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import * as IconSdkRaw from 'icon-sdk-js';
|
|
|
17
17
|
import { ChainGrpcWasmApi, TxGrpcApi, toBase64, fromBase64, MsgExecuteContract, ChainRestAuthApi, BaseAccount, createTransaction } from '@injectivelabs/sdk-ts';
|
|
18
18
|
import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx.js';
|
|
19
19
|
import { getNetworkEndpoints, Network } from '@injectivelabs/networks';
|
|
20
|
+
import * as v4 from 'valibot';
|
|
20
21
|
import BigNumber5, { BigNumber } from 'bignumber.js';
|
|
21
22
|
import { Token, Price } from '@pancakeswap/swap-sdk-core';
|
|
22
23
|
import { sqrtRatioX96ToPrice, PositionMath, tickToPrice, TickMath, maxLiquidityForAmount0Precise, maxLiquidityForAmount1, maxLiquidityForAmounts } from '@pancakeswap/v3-sdk';
|
|
@@ -91,8 +92,8 @@ function serializeCause(cause, depth) {
|
|
|
91
92
|
}
|
|
92
93
|
function sanitizeContext(value, depth) {
|
|
93
94
|
const out = {};
|
|
94
|
-
for (const [key,
|
|
95
|
-
out[key] = sanitizeValue(
|
|
95
|
+
for (const [key, v6] of Object.entries(value)) {
|
|
96
|
+
out[key] = sanitizeValue(v6, depth + 1);
|
|
96
97
|
}
|
|
97
98
|
return out;
|
|
98
99
|
}
|
|
@@ -103,13 +104,13 @@ function sanitizeValue(value, depth) {
|
|
|
103
104
|
if (t === "bigint") return value.toString();
|
|
104
105
|
if (t === "string" || t === "number" || t === "boolean") return value;
|
|
105
106
|
if (t === "function" || t === "symbol") return safeString(value);
|
|
106
|
-
if (Array.isArray(value)) return value.map((
|
|
107
|
+
if (Array.isArray(value)) return value.map((v6) => sanitizeValue(v6, depth + 1));
|
|
107
108
|
if (value instanceof Date) return value.toISOString();
|
|
108
109
|
if (value instanceof Map) {
|
|
109
|
-
return Array.from(value.entries()).map(([k,
|
|
110
|
+
return Array.from(value.entries()).map(([k, v6]) => [sanitizeValue(k, depth + 1), sanitizeValue(v6, depth + 1)]);
|
|
110
111
|
}
|
|
111
112
|
if (value instanceof Set) {
|
|
112
|
-
return Array.from(value.values()).map((
|
|
113
|
+
return Array.from(value.values()).map((v6) => sanitizeValue(v6, depth + 1));
|
|
113
114
|
}
|
|
114
115
|
if (value instanceof Error) return { name: value.name, message: value.message };
|
|
115
116
|
if (t === "object") {
|
|
@@ -121,9 +122,9 @@ function sanitizeValue(value, depth) {
|
|
|
121
122
|
}
|
|
122
123
|
return safeString(value);
|
|
123
124
|
}
|
|
124
|
-
function safeString(
|
|
125
|
+
function safeString(v6) {
|
|
125
126
|
try {
|
|
126
|
-
return String(
|
|
127
|
+
return String(v6);
|
|
127
128
|
} catch {
|
|
128
129
|
return "[unserializable]";
|
|
129
130
|
}
|
|
@@ -171,6 +172,7 @@ var SODAX_FEATURES = [
|
|
|
171
172
|
"dex",
|
|
172
173
|
"partner",
|
|
173
174
|
"recovery",
|
|
175
|
+
"backend",
|
|
174
176
|
"leverageYield"
|
|
175
177
|
];
|
|
176
178
|
|
|
@@ -2612,7 +2614,7 @@ var RelayChainIdMap = {
|
|
|
2612
2614
|
[ChainKeys.STACKS_MAINNET]: 60n
|
|
2613
2615
|
};
|
|
2614
2616
|
var INTENT_CHAIN_IDS = Object.values(RelayChainIdMap);
|
|
2615
|
-
var IntentRelayChainIdToChainKey =
|
|
2617
|
+
var IntentRelayChainIdToChainKey = new Map(Object.entries(RelayChainIdMap).map(([chainKey, chainId]) => [chainId, chainKey]));
|
|
2616
2618
|
var CHAIN_LOGO_BASE_URL = "https://raw.githubusercontent.com/icon-project/sodax-sdks/main/packages/assets/chain";
|
|
2617
2619
|
var chainLogo = (key) => `${CHAIN_LOGO_BASE_URL}/${key}.png`;
|
|
2618
2620
|
var baseChainInfo = {
|
|
@@ -4218,7 +4220,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
|
|
|
4218
4220
|
}
|
|
4219
4221
|
|
|
4220
4222
|
// ../types/dist/index.js
|
|
4221
|
-
var CONFIG_VERSION =
|
|
4223
|
+
var CONFIG_VERSION = 217;
|
|
4222
4224
|
function isEvmSpokeChainConfig(value) {
|
|
4223
4225
|
return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
|
|
4224
4226
|
}
|
|
@@ -4308,26 +4310,6 @@ function isRawDestinationParams(value) {
|
|
|
4308
4310
|
if (typeof obj.dstAddress !== "string") return false;
|
|
4309
4311
|
return typeof obj.dstChainKey === "string" && spokeChainKeysSet.has(obj.dstChainKey);
|
|
4310
4312
|
}
|
|
4311
|
-
function isSubmitSwapTxResponse(value) {
|
|
4312
|
-
return typeof value === "object" && value !== null && typeof value.success === "boolean" && typeof value.message === "string";
|
|
4313
|
-
}
|
|
4314
|
-
function isSubmitSwapTxStatusResponse(value) {
|
|
4315
|
-
if (typeof value !== "object" || value === null) return false;
|
|
4316
|
-
const obj = value;
|
|
4317
|
-
if (typeof obj.success !== "boolean") return false;
|
|
4318
|
-
if (typeof obj.data !== "object" || obj.data === null) return false;
|
|
4319
|
-
const data = obj.data;
|
|
4320
|
-
if (typeof data.txHash !== "string") return false;
|
|
4321
|
-
if (typeof data.srcChainKey !== "string") return false;
|
|
4322
|
-
if (typeof data.status !== "string") return false;
|
|
4323
|
-
if (typeof data.failedAttempts !== "number") return false;
|
|
4324
|
-
if (data.result !== void 0) {
|
|
4325
|
-
if (typeof data.result !== "object" || data.result === null) return false;
|
|
4326
|
-
const result = data.result;
|
|
4327
|
-
if (typeof result.dstIntentTxHash !== "string") return false;
|
|
4328
|
-
}
|
|
4329
|
-
return true;
|
|
4330
|
-
}
|
|
4331
4313
|
function isBitcoinWalletProviderType(wp) {
|
|
4332
4314
|
return wp.chainType === "BITCOIN";
|
|
4333
4315
|
}
|
|
@@ -4365,11 +4347,11 @@ async function retry(action, retryCount = DEFAULT_MAX_RETRY, delayMs = DEFAULT_R
|
|
|
4365
4347
|
throw new Error(`Retry exceeded MAX_RETRY_DEFAULT=${DEFAULT_MAX_RETRY}`);
|
|
4366
4348
|
}
|
|
4367
4349
|
function getRandomBytes(length) {
|
|
4368
|
-
const
|
|
4350
|
+
const array3 = new Uint8Array(length);
|
|
4369
4351
|
for (let i = 0; i < length; i++) {
|
|
4370
|
-
|
|
4352
|
+
array3[i] = Math.floor(Math.random() * 256);
|
|
4371
4353
|
}
|
|
4372
|
-
return
|
|
4354
|
+
return array3;
|
|
4373
4355
|
}
|
|
4374
4356
|
function randomUint256() {
|
|
4375
4357
|
const bytes = getRandomBytes(32);
|
|
@@ -10621,6 +10603,144 @@ var ProtocolIntentsAbi = [
|
|
|
10621
10603
|
}
|
|
10622
10604
|
],
|
|
10623
10605
|
stateMutability: "view"
|
|
10606
|
+
},
|
|
10607
|
+
{
|
|
10608
|
+
type: "function",
|
|
10609
|
+
name: "cancelIntent",
|
|
10610
|
+
inputs: [
|
|
10611
|
+
{
|
|
10612
|
+
name: "fromToken",
|
|
10613
|
+
type: "address",
|
|
10614
|
+
internalType: "address"
|
|
10615
|
+
},
|
|
10616
|
+
{
|
|
10617
|
+
name: "toToken",
|
|
10618
|
+
type: "address",
|
|
10619
|
+
internalType: "address"
|
|
10620
|
+
}
|
|
10621
|
+
],
|
|
10622
|
+
outputs: [],
|
|
10623
|
+
stateMutability: "nonpayable"
|
|
10624
|
+
},
|
|
10625
|
+
{
|
|
10626
|
+
type: "function",
|
|
10627
|
+
name: "getUserIntent",
|
|
10628
|
+
inputs: [
|
|
10629
|
+
{
|
|
10630
|
+
name: "user",
|
|
10631
|
+
type: "address",
|
|
10632
|
+
internalType: "address"
|
|
10633
|
+
},
|
|
10634
|
+
{
|
|
10635
|
+
name: "fromToken",
|
|
10636
|
+
type: "address",
|
|
10637
|
+
internalType: "address"
|
|
10638
|
+
},
|
|
10639
|
+
{
|
|
10640
|
+
name: "toToken",
|
|
10641
|
+
type: "address",
|
|
10642
|
+
internalType: "address"
|
|
10643
|
+
}
|
|
10644
|
+
],
|
|
10645
|
+
outputs: [
|
|
10646
|
+
{
|
|
10647
|
+
name: "intentHash",
|
|
10648
|
+
type: "bytes32",
|
|
10649
|
+
internalType: "bytes32"
|
|
10650
|
+
}
|
|
10651
|
+
],
|
|
10652
|
+
stateMutability: "view"
|
|
10653
|
+
},
|
|
10654
|
+
{
|
|
10655
|
+
type: "function",
|
|
10656
|
+
name: "getIntentDetails",
|
|
10657
|
+
inputs: [
|
|
10658
|
+
{
|
|
10659
|
+
name: "intentHash",
|
|
10660
|
+
type: "bytes32",
|
|
10661
|
+
internalType: "bytes32"
|
|
10662
|
+
}
|
|
10663
|
+
],
|
|
10664
|
+
outputs: [
|
|
10665
|
+
{
|
|
10666
|
+
name: "intent",
|
|
10667
|
+
type: "tuple",
|
|
10668
|
+
internalType: "struct Intents.Intent",
|
|
10669
|
+
components: [
|
|
10670
|
+
{
|
|
10671
|
+
name: "intentId",
|
|
10672
|
+
type: "uint256",
|
|
10673
|
+
internalType: "uint256"
|
|
10674
|
+
},
|
|
10675
|
+
{
|
|
10676
|
+
name: "creator",
|
|
10677
|
+
type: "address",
|
|
10678
|
+
internalType: "address"
|
|
10679
|
+
},
|
|
10680
|
+
{
|
|
10681
|
+
name: "inputToken",
|
|
10682
|
+
type: "address",
|
|
10683
|
+
internalType: "address"
|
|
10684
|
+
},
|
|
10685
|
+
{
|
|
10686
|
+
name: "outputToken",
|
|
10687
|
+
type: "address",
|
|
10688
|
+
internalType: "address"
|
|
10689
|
+
},
|
|
10690
|
+
{
|
|
10691
|
+
name: "inputAmount",
|
|
10692
|
+
type: "uint256",
|
|
10693
|
+
internalType: "uint256"
|
|
10694
|
+
},
|
|
10695
|
+
{
|
|
10696
|
+
name: "minOutputAmount",
|
|
10697
|
+
type: "uint256",
|
|
10698
|
+
internalType: "uint256"
|
|
10699
|
+
},
|
|
10700
|
+
{
|
|
10701
|
+
name: "deadline",
|
|
10702
|
+
type: "uint256",
|
|
10703
|
+
internalType: "uint256"
|
|
10704
|
+
},
|
|
10705
|
+
{
|
|
10706
|
+
name: "allowPartialFill",
|
|
10707
|
+
type: "bool",
|
|
10708
|
+
internalType: "bool"
|
|
10709
|
+
},
|
|
10710
|
+
{
|
|
10711
|
+
name: "srcChain",
|
|
10712
|
+
type: "uint256",
|
|
10713
|
+
internalType: "uint256"
|
|
10714
|
+
},
|
|
10715
|
+
{
|
|
10716
|
+
name: "dstChain",
|
|
10717
|
+
type: "uint256",
|
|
10718
|
+
internalType: "uint256"
|
|
10719
|
+
},
|
|
10720
|
+
{
|
|
10721
|
+
name: "srcAddress",
|
|
10722
|
+
type: "bytes",
|
|
10723
|
+
internalType: "bytes"
|
|
10724
|
+
},
|
|
10725
|
+
{
|
|
10726
|
+
name: "dstAddress",
|
|
10727
|
+
type: "bytes",
|
|
10728
|
+
internalType: "bytes"
|
|
10729
|
+
},
|
|
10730
|
+
{
|
|
10731
|
+
name: "solver",
|
|
10732
|
+
type: "address",
|
|
10733
|
+
internalType: "address"
|
|
10734
|
+
},
|
|
10735
|
+
{
|
|
10736
|
+
name: "data",
|
|
10737
|
+
type: "bytes",
|
|
10738
|
+
internalType: "bytes"
|
|
10739
|
+
}
|
|
10740
|
+
]
|
|
10741
|
+
}
|
|
10742
|
+
],
|
|
10743
|
+
stateMutability: "view"
|
|
10624
10744
|
}
|
|
10625
10745
|
];
|
|
10626
10746
|
|
|
@@ -13478,29 +13598,6 @@ var universalRouterAbi = [
|
|
|
13478
13598
|
}
|
|
13479
13599
|
];
|
|
13480
13600
|
|
|
13481
|
-
// src/shared/utils/deepMerge.ts
|
|
13482
|
-
function deepMerge(target, source) {
|
|
13483
|
-
const result = { ...target };
|
|
13484
|
-
for (const key of Object.keys(source)) {
|
|
13485
|
-
const sourceVal = source[key];
|
|
13486
|
-
const targetVal = target[key];
|
|
13487
|
-
if (sourceVal !== void 0 && typeof sourceVal === "object" && sourceVal !== null && !Array.isArray(sourceVal) && typeof targetVal === "object" && targetVal !== null && !Array.isArray(targetVal)) {
|
|
13488
|
-
result[key] = deepMerge(
|
|
13489
|
-
targetVal,
|
|
13490
|
-
sourceVal
|
|
13491
|
-
);
|
|
13492
|
-
} else if (sourceVal !== void 0) {
|
|
13493
|
-
result[key] = sourceVal;
|
|
13494
|
-
}
|
|
13495
|
-
}
|
|
13496
|
-
return result;
|
|
13497
|
-
}
|
|
13498
|
-
|
|
13499
|
-
// src/shared/config/mergeSodaxConfig.ts
|
|
13500
|
-
function mergeSodaxConfig(base2, override) {
|
|
13501
|
-
return deepMerge(base2, override);
|
|
13502
|
-
}
|
|
13503
|
-
|
|
13504
13601
|
// src/shared/logger.ts
|
|
13505
13602
|
var consoleLogger = {
|
|
13506
13603
|
debug: (message, data) => data ? console.debug(message, data) : console.debug(message),
|
|
@@ -13528,16 +13625,85 @@ function resolveLogger(option) {
|
|
|
13528
13625
|
return option;
|
|
13529
13626
|
}
|
|
13530
13627
|
|
|
13628
|
+
// src/shared/analytics.ts
|
|
13629
|
+
var noopAnalytics = {
|
|
13630
|
+
isEnabled: () => false,
|
|
13631
|
+
emit: () => {
|
|
13632
|
+
},
|
|
13633
|
+
trackResult: (_feature, _action, run) => run()
|
|
13634
|
+
};
|
|
13635
|
+
var LEVEL_RANK = { basic: 0, detailed: 1 };
|
|
13636
|
+
function normalizeFeatures(features) {
|
|
13637
|
+
if (features === void 0) return null;
|
|
13638
|
+
const map = /* @__PURE__ */ new Map();
|
|
13639
|
+
if (Array.isArray(features)) {
|
|
13640
|
+
for (const feature of features) map.set(feature, true);
|
|
13641
|
+
} else {
|
|
13642
|
+
for (const [feature, scope] of Object.entries(features)) {
|
|
13643
|
+
if (scope === true) map.set(feature, true);
|
|
13644
|
+
else if (scope) map.set(feature, new Set(scope.actions));
|
|
13645
|
+
}
|
|
13646
|
+
}
|
|
13647
|
+
return map;
|
|
13648
|
+
}
|
|
13649
|
+
function resolveAnalytics(option) {
|
|
13650
|
+
if (!option) return noopAnalytics;
|
|
13651
|
+
const { tracker, level: configuredLevel = "basic", features } = option;
|
|
13652
|
+
const maxRank = LEVEL_RANK[configuredLevel];
|
|
13653
|
+
const allow = normalizeFeatures(features);
|
|
13654
|
+
const isEnabled = (feature, action, level = "basic") => {
|
|
13655
|
+
if (LEVEL_RANK[level] > maxRank) return false;
|
|
13656
|
+
if (allow === null) return true;
|
|
13657
|
+
const scope = allow.get(feature);
|
|
13658
|
+
if (scope === void 0) return false;
|
|
13659
|
+
if (scope === true) return true;
|
|
13660
|
+
if (action === void 0) return scope.size > 0;
|
|
13661
|
+
return scope.has(action);
|
|
13662
|
+
};
|
|
13663
|
+
const emit = (feature, action, phase, build, level = "basic") => {
|
|
13664
|
+
if (!isEnabled(feature, action, level)) return;
|
|
13665
|
+
try {
|
|
13666
|
+
tracker({ feature, action, phase, level, data: build?.() });
|
|
13667
|
+
} catch {
|
|
13668
|
+
}
|
|
13669
|
+
};
|
|
13670
|
+
const trackResult = async (feature, action, run, data) => {
|
|
13671
|
+
emit(feature, action, "start", data?.start);
|
|
13672
|
+
try {
|
|
13673
|
+
const result = await run();
|
|
13674
|
+
if (result.ok) {
|
|
13675
|
+
const build = data?.success;
|
|
13676
|
+
emit(feature, action, "success", build ? () => build(result.value) : void 0);
|
|
13677
|
+
} else {
|
|
13678
|
+
const build = data?.failure;
|
|
13679
|
+
emit(feature, action, "failure", build ? () => build(result.error) : void 0);
|
|
13680
|
+
}
|
|
13681
|
+
return result;
|
|
13682
|
+
} catch (error) {
|
|
13683
|
+
emit(feature, action, "failure", () => ({ error: error instanceof Error ? error.message : String(error) }));
|
|
13684
|
+
throw error;
|
|
13685
|
+
}
|
|
13686
|
+
};
|
|
13687
|
+
return { isEnabled, emit, trackResult };
|
|
13688
|
+
}
|
|
13689
|
+
|
|
13531
13690
|
// src/shared/config/ConfigService.ts
|
|
13532
13691
|
var ConfigService = class {
|
|
13533
13692
|
sodax;
|
|
13534
|
-
api
|
|
13535
|
-
|
|
13693
|
+
// TODO(config-v2): restore `api` / `userConfig` when initialize() dynamic fetch is re-enabled.
|
|
13694
|
+
// private readonly api: BackendApiService;
|
|
13695
|
+
// private readonly userConfig?: SodaxOptions;
|
|
13536
13696
|
/**
|
|
13537
13697
|
* SDK log sink. Resolved once at construction and kept independent of {@link sodax} so that
|
|
13538
13698
|
* {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.logger`.
|
|
13539
13699
|
*/
|
|
13540
13700
|
logger;
|
|
13701
|
+
/**
|
|
13702
|
+
* Analytics emitter. Resolved once at construction and kept independent of {@link sodax} so that
|
|
13703
|
+
* {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.analytics`;
|
|
13704
|
+
* disabled (no-op) unless the consumer passed an `analytics` config to `new Sodax(...)`.
|
|
13705
|
+
*/
|
|
13706
|
+
analytics;
|
|
13541
13707
|
/**
|
|
13542
13708
|
* Global partner fee. Resolved once at construction and kept independent of {@link sodax} so that
|
|
13543
13709
|
* {@link initialize}'s dynamic-config swap never clobbers it. The backend never supplies it — it is
|
|
@@ -13555,29 +13721,17 @@ var ConfigService = class {
|
|
|
13555
13721
|
stakedATokenAddressesSet;
|
|
13556
13722
|
chainToSupportedTokenAddressMap;
|
|
13557
13723
|
hubAssetToXTokenMap;
|
|
13558
|
-
|
|
13559
|
-
|
|
13724
|
+
// `api` / `userConfig` are accepted but unused while initialize()'s dynamic fetch is disabled
|
|
13725
|
+
// (see TODO(config-v2) below); restore their assignments when re-enabling.
|
|
13726
|
+
constructor({ api, config, userConfig, logger, analytics, fee }) {
|
|
13560
13727
|
this.sodax = config;
|
|
13561
|
-
this.userConfig = userConfig;
|
|
13562
13728
|
this.logger = logger ?? resolveLogger(void 0);
|
|
13729
|
+
this.analytics = analytics ?? noopAnalytics;
|
|
13563
13730
|
this.fee = fee;
|
|
13564
13731
|
this.loadSodaxConfigDataStructures(config);
|
|
13565
13732
|
}
|
|
13566
13733
|
async initialize() {
|
|
13567
13734
|
try {
|
|
13568
|
-
const result = await this.api.getAllConfig();
|
|
13569
|
-
if (!result.ok) return result;
|
|
13570
|
-
const response = result.value;
|
|
13571
|
-
if (!response.version || response.version < CONFIG_VERSION) {
|
|
13572
|
-
this.logger.warn(
|
|
13573
|
-
`Dynamic config version is less than the current version, resorting to the default one. Current version: ${CONFIG_VERSION}, response version: ${response.version}`
|
|
13574
|
-
);
|
|
13575
|
-
} else {
|
|
13576
|
-
const next = this.userConfig ? mergeSodaxConfig(response.config, this.userConfig) : response.config;
|
|
13577
|
-
this.loadSodaxConfigDataStructures(next);
|
|
13578
|
-
this.sodax = next;
|
|
13579
|
-
this.initialized = true;
|
|
13580
|
-
}
|
|
13581
13735
|
return { ok: true, value: void 0 };
|
|
13582
13736
|
} catch (error) {
|
|
13583
13737
|
return { ok: false, error };
|
|
@@ -13610,6 +13764,16 @@ var ConfigService = class {
|
|
|
13610
13764
|
getOriginalAssetAddress(chainId, hubAsset) {
|
|
13611
13765
|
return this.hubAssetToXTokenMap.get(hubAsset.toLowerCase())?.address;
|
|
13612
13766
|
}
|
|
13767
|
+
/**
|
|
13768
|
+
* Resolves the {@link XToken} descriptor (hub asset, vault, decimals) for a hub-asset address.
|
|
13769
|
+
*
|
|
13770
|
+
* Useful when a caller holds a hub asset directly on Sonic that has no spoke-token entry under
|
|
13771
|
+
* the hub chain — e.g. a partner BTC fee held as the BTC hub asset, which only exists as a spoke
|
|
13772
|
+
* token on Bitcoin. Returns `undefined` when the address is not a known hub asset.
|
|
13773
|
+
*/
|
|
13774
|
+
getXTokenFromHubAsset(hubAsset) {
|
|
13775
|
+
return this.hubAssetToXTokenMap.get(hubAsset.toLowerCase());
|
|
13776
|
+
}
|
|
13613
13777
|
getSpokeTokenFromOriginalAssetAddress(chainId, originalAssetAddress) {
|
|
13614
13778
|
return this.supportedTokensPerChain.get(chainId)?.find((token) => token.address.toLowerCase() === originalAssetAddress.toLowerCase());
|
|
13615
13779
|
}
|
|
@@ -13837,9 +14001,32 @@ function parseTokenArrayFromJson(input) {
|
|
|
13837
14001
|
}
|
|
13838
14002
|
return tokens;
|
|
13839
14003
|
}
|
|
14004
|
+
|
|
14005
|
+
// src/shared/utils/deepMerge.ts
|
|
14006
|
+
function deepMerge(target, source) {
|
|
14007
|
+
const result = { ...target };
|
|
14008
|
+
for (const key of Object.keys(source)) {
|
|
14009
|
+
const sourceVal = source[key];
|
|
14010
|
+
const targetVal = target[key];
|
|
14011
|
+
if (sourceVal !== void 0 && typeof sourceVal === "object" && sourceVal !== null && !Array.isArray(sourceVal) && typeof targetVal === "object" && targetVal !== null && !Array.isArray(targetVal)) {
|
|
14012
|
+
result[key] = deepMerge(
|
|
14013
|
+
targetVal,
|
|
14014
|
+
sourceVal
|
|
14015
|
+
);
|
|
14016
|
+
} else if (sourceVal !== void 0) {
|
|
14017
|
+
result[key] = sourceVal;
|
|
14018
|
+
}
|
|
14019
|
+
}
|
|
14020
|
+
return result;
|
|
14021
|
+
}
|
|
14022
|
+
|
|
14023
|
+
// src/shared/config/mergeSodaxConfig.ts
|
|
14024
|
+
function mergeSodaxConfig(base2, override) {
|
|
14025
|
+
return deepMerge(base2, override);
|
|
14026
|
+
}
|
|
13840
14027
|
function encodeContractCalls(calls) {
|
|
13841
14028
|
return encodeAbiParameters(parseAbiParameters("(address,uint256,bytes)[]"), [
|
|
13842
|
-
calls.map((
|
|
14029
|
+
calls.map((v6) => [v6.address, v6.value, v6.data])
|
|
13843
14030
|
]);
|
|
13844
14031
|
}
|
|
13845
14032
|
async function waitForTransactionReceipt(hash, provider) {
|
|
@@ -15520,6 +15707,32 @@ var BitcoinSpokeService = class {
|
|
|
15520
15707
|
throw error;
|
|
15521
15708
|
}
|
|
15522
15709
|
}
|
|
15710
|
+
/**
|
|
15711
|
+
* Sign and submit a TRADING-wallet raw transaction — the Bound-built *unsigned* PSBT returned by
|
|
15712
|
+
* `deposit({ raw: true })` / the Swaps API (`createIntent().tx.data`). Signs it with the wallet
|
|
15713
|
+
* provider's key, then sends it to Bound Exchange to co-sign with the second 2-of-2 key and
|
|
15714
|
+
* broadcast. Returns the broadcast tx id.
|
|
15715
|
+
*
|
|
15716
|
+
* This is the client-side completion of the TRADING deposit flow: the backend builds the PSBT
|
|
15717
|
+
* (it can't broadcast — the user's signature is missing), the client signs here, and Bound
|
|
15718
|
+
* co-signs + broadcasts. `relayData` ({ address, payload }) is the relay identity returned by
|
|
15719
|
+
* `createIntent()`; forwarding it lets Bound auto-resubmit a stuck relay. It is **not** recoverable
|
|
15720
|
+
* from `rawTx` (whose `to` is the asset manager, not the hub wallet), so callers must supply it.
|
|
15721
|
+
*
|
|
15722
|
+
* @throws if the chain is not in `TRADING` wallet mode (raw txs only exist in TRADING mode).
|
|
15723
|
+
*/
|
|
15724
|
+
async signAndSubmitRawTransaction(params) {
|
|
15725
|
+
if (this.walletMode !== "TRADING") {
|
|
15726
|
+
throw new Error("signAndSubmitRawTransaction requires TRADING wallet mode.");
|
|
15727
|
+
}
|
|
15728
|
+
const { rawTx, walletProvider, relayData, accessToken = this.radfi.accessToken } = params;
|
|
15729
|
+
if (!rawTx?.data || !rawTx?.from) {
|
|
15730
|
+
throw new Error("signAndSubmitRawTransaction: rawTx.data (PSBT) and rawTx.from are required.");
|
|
15731
|
+
}
|
|
15732
|
+
const signedTx = await walletProvider.signTransaction(rawTx.data, false);
|
|
15733
|
+
const signedBase64Tx = normalizePsbtToBase64(signedTx);
|
|
15734
|
+
return this.radfi.requestRadfiSignature({ userAddress: rawTx.from, signedBase64Tx, relayData }, accessToken);
|
|
15735
|
+
}
|
|
15523
15736
|
/**
|
|
15524
15737
|
* Build deposit PSBT with embedded cross-chain data
|
|
15525
15738
|
*/
|
|
@@ -15789,7 +16002,7 @@ function hexToBytes2(hex) {
|
|
|
15789
16002
|
const al = hl / 2;
|
|
15790
16003
|
if (hl % 2)
|
|
15791
16004
|
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
15792
|
-
const
|
|
16005
|
+
const array3 = new Uint8Array(al);
|
|
15793
16006
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
15794
16007
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
15795
16008
|
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
@@ -15797,9 +16010,9 @@ function hexToBytes2(hex) {
|
|
|
15797
16010
|
const char = hex[hi] + hex[hi + 1];
|
|
15798
16011
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
15799
16012
|
}
|
|
15800
|
-
|
|
16013
|
+
array3[ai] = n1 * 16 + n2;
|
|
15801
16014
|
}
|
|
15802
|
-
return
|
|
16015
|
+
return array3;
|
|
15803
16016
|
}
|
|
15804
16017
|
function concatBytes(...arrays) {
|
|
15805
16018
|
let sum = 0;
|
|
@@ -16429,22 +16642,22 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
|
16429
16642
|
const byte0 = Uint8Array.of(0);
|
|
16430
16643
|
const byte1 = Uint8Array.of(1);
|
|
16431
16644
|
const _maxDrbgIters = 1e3;
|
|
16432
|
-
let
|
|
16645
|
+
let v6 = u8n(hashLen);
|
|
16433
16646
|
let k = u8n(hashLen);
|
|
16434
16647
|
let i = 0;
|
|
16435
16648
|
const reset = () => {
|
|
16436
|
-
|
|
16649
|
+
v6.fill(1);
|
|
16437
16650
|
k.fill(0);
|
|
16438
16651
|
i = 0;
|
|
16439
16652
|
};
|
|
16440
|
-
const h = (...msgs) => hmacFn(k, concatBytes(
|
|
16653
|
+
const h = (...msgs) => hmacFn(k, concatBytes(v6, ...msgs));
|
|
16441
16654
|
const reseed = (seed = NULL) => {
|
|
16442
16655
|
k = h(byte0, seed);
|
|
16443
|
-
|
|
16656
|
+
v6 = h();
|
|
16444
16657
|
if (seed.length === 0)
|
|
16445
16658
|
return;
|
|
16446
16659
|
k = h(byte1, seed);
|
|
16447
|
-
|
|
16660
|
+
v6 = h();
|
|
16448
16661
|
};
|
|
16449
16662
|
const gen = () => {
|
|
16450
16663
|
if (i++ >= _maxDrbgIters)
|
|
@@ -16452,10 +16665,10 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
|
16452
16665
|
let len = 0;
|
|
16453
16666
|
const out = [];
|
|
16454
16667
|
while (len < qByteLen) {
|
|
16455
|
-
|
|
16456
|
-
const sl =
|
|
16668
|
+
v6 = h();
|
|
16669
|
+
const sl = v6.slice();
|
|
16457
16670
|
out.push(sl);
|
|
16458
|
-
len +=
|
|
16671
|
+
len += v6.length;
|
|
16459
16672
|
}
|
|
16460
16673
|
return concatBytes(...out);
|
|
16461
16674
|
};
|
|
@@ -16470,18 +16683,18 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
|
16470
16683
|
};
|
|
16471
16684
|
return genUntil;
|
|
16472
16685
|
}
|
|
16473
|
-
function validateObject(
|
|
16474
|
-
if (!
|
|
16686
|
+
function validateObject(object4, fields = {}, optFields = {}) {
|
|
16687
|
+
if (!object4 || typeof object4 !== "object")
|
|
16475
16688
|
throw new Error("expected valid options object");
|
|
16476
16689
|
function checkField(fieldName, expectedType, isOpt) {
|
|
16477
|
-
const val =
|
|
16690
|
+
const val = object4[fieldName];
|
|
16478
16691
|
if (isOpt && val === void 0)
|
|
16479
16692
|
return;
|
|
16480
16693
|
const current = typeof val;
|
|
16481
16694
|
if (current !== expectedType || val === null)
|
|
16482
16695
|
throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
16483
16696
|
}
|
|
16484
|
-
const iter = (f, isOpt) => Object.entries(f).forEach(([k,
|
|
16697
|
+
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v6]) => checkField(k, v6, isOpt));
|
|
16485
16698
|
iter(fields, false);
|
|
16486
16699
|
iter(optFields, true);
|
|
16487
16700
|
}
|
|
@@ -16520,12 +16733,12 @@ function pow2(x, power, modulo) {
|
|
|
16520
16733
|
}
|
|
16521
16734
|
return res;
|
|
16522
16735
|
}
|
|
16523
|
-
function invert(
|
|
16524
|
-
if (
|
|
16736
|
+
function invert(number4, modulo) {
|
|
16737
|
+
if (number4 === _0n2)
|
|
16525
16738
|
throw new Error("invert: expected non-zero number");
|
|
16526
16739
|
if (modulo <= _0n2)
|
|
16527
16740
|
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
16528
|
-
let a = mod(
|
|
16741
|
+
let a = mod(number4, modulo);
|
|
16529
16742
|
let b = modulo;
|
|
16530
16743
|
let x = _0n2, u = _1n2;
|
|
16531
16744
|
while (a !== _0n2) {
|
|
@@ -16552,9 +16765,9 @@ function sqrt3mod4(Fp, n) {
|
|
|
16552
16765
|
function sqrt5mod8(Fp, n) {
|
|
16553
16766
|
const p5div8 = (Fp.ORDER - _5n) / _8n;
|
|
16554
16767
|
const n2 = Fp.mul(n, _2n);
|
|
16555
|
-
const
|
|
16556
|
-
const nv = Fp.mul(n,
|
|
16557
|
-
const i = Fp.mul(Fp.mul(nv, _2n),
|
|
16768
|
+
const v6 = Fp.pow(n2, p5div8);
|
|
16769
|
+
const nv = Fp.mul(n, v6);
|
|
16770
|
+
const i = Fp.mul(Fp.mul(nv, _2n), v6);
|
|
16558
16771
|
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
|
16559
16772
|
assertIsSquare(Fp, root, n);
|
|
16560
16773
|
return root;
|
|
@@ -17029,27 +17242,27 @@ var wNAF = class {
|
|
|
17029
17242
|
assert0(n);
|
|
17030
17243
|
return acc;
|
|
17031
17244
|
}
|
|
17032
|
-
getPrecomputes(W, point,
|
|
17245
|
+
getPrecomputes(W, point, transform2) {
|
|
17033
17246
|
let comp = pointPrecomputes.get(point);
|
|
17034
17247
|
if (!comp) {
|
|
17035
17248
|
comp = this.precomputeWindow(point, W);
|
|
17036
17249
|
if (W !== 1) {
|
|
17037
|
-
if (typeof
|
|
17038
|
-
comp =
|
|
17250
|
+
if (typeof transform2 === "function")
|
|
17251
|
+
comp = transform2(comp);
|
|
17039
17252
|
pointPrecomputes.set(point, comp);
|
|
17040
17253
|
}
|
|
17041
17254
|
}
|
|
17042
17255
|
return comp;
|
|
17043
17256
|
}
|
|
17044
|
-
cached(point, scalar,
|
|
17257
|
+
cached(point, scalar, transform2) {
|
|
17045
17258
|
const W = getW(point);
|
|
17046
|
-
return this.wNAF(W, this.getPrecomputes(W, point,
|
|
17259
|
+
return this.wNAF(W, this.getPrecomputes(W, point, transform2), scalar);
|
|
17047
17260
|
}
|
|
17048
|
-
unsafe(point, scalar,
|
|
17261
|
+
unsafe(point, scalar, transform2, prev) {
|
|
17049
17262
|
const W = getW(point);
|
|
17050
17263
|
if (W === 1)
|
|
17051
17264
|
return this._unsafeLadder(point, scalar, prev);
|
|
17052
|
-
return this.wNAFUnsafe(W, this.getPrecomputes(W, point,
|
|
17265
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform2), scalar, prev);
|
|
17053
17266
|
}
|
|
17054
17267
|
// We calculate precomputes for elliptic curve point multiplication
|
|
17055
17268
|
// using windowed method. This specifies window size and
|
|
@@ -17136,9 +17349,9 @@ function edwards(params, extraOpts = {}) {
|
|
|
17136
17349
|
validateObject(extraOpts, {}, { uvRatio: "function" });
|
|
17137
17350
|
const MASK = _2n2 << BigInt(Fn.BYTES * 8) - _1n4;
|
|
17138
17351
|
const modP = (n) => Fp.create(n);
|
|
17139
|
-
const uvRatio2 = extraOpts.uvRatio || ((u,
|
|
17352
|
+
const uvRatio2 = extraOpts.uvRatio || ((u, v6) => {
|
|
17140
17353
|
try {
|
|
17141
|
-
return { isValid: true, value: Fp.sqrt(Fp.div(u,
|
|
17354
|
+
return { isValid: true, value: Fp.sqrt(Fp.div(u, v6)) };
|
|
17142
17355
|
} catch (e) {
|
|
17143
17356
|
return { isValid: false, value: _0n4 };
|
|
17144
17357
|
}
|
|
@@ -17234,8 +17447,8 @@ function edwards(params, extraOpts = {}) {
|
|
|
17234
17447
|
aInRange("point.y", y, _0n4, max);
|
|
17235
17448
|
const y2 = modP(y * y);
|
|
17236
17449
|
const u = modP(y2 - _1n4);
|
|
17237
|
-
const
|
|
17238
|
-
let { isValid, value: x } = uvRatio2(u,
|
|
17450
|
+
const v6 = modP(d * y2 - a);
|
|
17451
|
+
let { isValid, value: x } = uvRatio2(u, v6);
|
|
17239
17452
|
if (!isValid)
|
|
17240
17453
|
throw new Error("bad point: invalid y coordinate");
|
|
17241
17454
|
const isXOdd = (x & _1n4) === _1n4;
|
|
@@ -17575,13 +17788,13 @@ function adjustScalarBytes(bytes) {
|
|
|
17575
17788
|
return bytes;
|
|
17576
17789
|
}
|
|
17577
17790
|
var ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
|
|
17578
|
-
function uvRatio(u,
|
|
17791
|
+
function uvRatio(u, v6) {
|
|
17579
17792
|
const P = ed25519_CURVE_p;
|
|
17580
|
-
const
|
|
17581
|
-
const v7 = mod(
|
|
17793
|
+
const v32 = mod(v6 * v6 * v6, P);
|
|
17794
|
+
const v7 = mod(v32 * v32 * v6, P);
|
|
17582
17795
|
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
|
17583
|
-
let x = mod(u *
|
|
17584
|
-
const vx2 = mod(
|
|
17796
|
+
let x = mod(u * v32 * pow, P);
|
|
17797
|
+
const vx2 = mod(v6 * x * x, P);
|
|
17585
17798
|
const root1 = x;
|
|
17586
17799
|
const root2 = mod(x * ED25519_SQRT_M1, P);
|
|
17587
17800
|
const useRoot1 = vx2 === u;
|
|
@@ -17912,7 +18125,7 @@ function findSeatPrice(validators, maxNumberOfSeats, minimumStakeRatio, protocol
|
|
|
17912
18125
|
return findSeatPriceForProtocolAfter49(validators, maxNumberOfSeats, minimumStakeRatio);
|
|
17913
18126
|
}
|
|
17914
18127
|
function findSeatPriceForProtocolBefore49(validators, numSeats) {
|
|
17915
|
-
const stakes = validators.map((
|
|
18128
|
+
const stakes = validators.map((v6) => BigInt(v6.stake)).sort(sortBigIntAsc);
|
|
17916
18129
|
const num = BigInt(numSeats);
|
|
17917
18130
|
const stakesSum = stakes.reduce((a, b) => a + b);
|
|
17918
18131
|
if (stakesSum < num) {
|
|
@@ -17941,7 +18154,7 @@ function findSeatPriceForProtocolAfter49(validators, maxNumberOfSeats, minimumSt
|
|
|
17941
18154
|
if (minimumStakeRatio.length != 2) {
|
|
17942
18155
|
throw Error("minimumStakeRatio should have 2 elements");
|
|
17943
18156
|
}
|
|
17944
|
-
const stakes = validators.map((
|
|
18157
|
+
const stakes = validators.map((v6) => BigInt(v6.stake)).sort(sortBigIntAsc);
|
|
17945
18158
|
const stakesSum = stakes.reduce((a, b) => a + b);
|
|
17946
18159
|
if (validators.length < maxNumberOfSeats) {
|
|
17947
18160
|
return stakesSum * BigInt(minimumStakeRatio[0]) / BigInt(minimumStakeRatio[1]);
|
|
@@ -18113,10 +18326,10 @@ var DER = {
|
|
|
18113
18326
|
if (length < 128)
|
|
18114
18327
|
throw new E("tlv.decode(long): not minimal encoding");
|
|
18115
18328
|
}
|
|
18116
|
-
const
|
|
18117
|
-
if (
|
|
18329
|
+
const v6 = data.subarray(pos, pos + length);
|
|
18330
|
+
if (v6.length !== length)
|
|
18118
18331
|
throw new E("tlv.decode: wrong value length");
|
|
18119
|
-
return { v, l: data.subarray(pos + length) };
|
|
18332
|
+
return { v: v6, l: data.subarray(pos + length) };
|
|
18120
18333
|
}
|
|
18121
18334
|
},
|
|
18122
18335
|
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
|
@@ -18684,9 +18897,9 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
18684
18897
|
extraEntropy: false
|
|
18685
18898
|
};
|
|
18686
18899
|
const hasLargeCofactor = CURVE_ORDER * _2n4 < Fp.ORDER;
|
|
18687
|
-
function isBiggerThanHalfOrder(
|
|
18900
|
+
function isBiggerThanHalfOrder(number4) {
|
|
18688
18901
|
const HALF = CURVE_ORDER >> _1n6;
|
|
18689
|
-
return
|
|
18902
|
+
return number4 > HALF;
|
|
18690
18903
|
}
|
|
18691
18904
|
function validateRS(title, num) {
|
|
18692
18905
|
if (!Fn.isValidNot0(num))
|
|
@@ -18863,14 +19076,14 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
18863
19076
|
return false;
|
|
18864
19077
|
const { r, s } = sig;
|
|
18865
19078
|
const h = bits2int_modN(message);
|
|
18866
|
-
const
|
|
18867
|
-
const u1 = Fn.create(h *
|
|
18868
|
-
const u2 = Fn.create(r *
|
|
19079
|
+
const is2 = Fn.inv(s);
|
|
19080
|
+
const u1 = Fn.create(h * is2);
|
|
19081
|
+
const u2 = Fn.create(r * is2);
|
|
18869
19082
|
const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2));
|
|
18870
19083
|
if (R.is0())
|
|
18871
19084
|
return false;
|
|
18872
|
-
const
|
|
18873
|
-
return
|
|
19085
|
+
const v6 = Fn.create(R.x);
|
|
19086
|
+
return v6 === r;
|
|
18874
19087
|
} catch (e) {
|
|
18875
19088
|
return false;
|
|
18876
19089
|
}
|
|
@@ -26216,13 +26429,18 @@ var SwapService = class {
|
|
|
26216
26429
|
solver;
|
|
26217
26430
|
partnerFee;
|
|
26218
26431
|
relayerApiEndpoint;
|
|
26219
|
-
|
|
26432
|
+
// backend swaps-API client + opt-in 2-step submit-tx flag
|
|
26433
|
+
backendApi;
|
|
26434
|
+
useBackendSubmitTx;
|
|
26435
|
+
constructor({ config, hubProvider, spoke, backendApi, useBackendSubmitTx }) {
|
|
26220
26436
|
this.solver = config.solver;
|
|
26221
26437
|
this.partnerFee = config.swapPartnerFee;
|
|
26222
26438
|
this.relayerApiEndpoint = config.relay.relayerApiEndpoint;
|
|
26223
26439
|
this.config = config;
|
|
26224
26440
|
this.hubProvider = hubProvider;
|
|
26225
26441
|
this.spoke = spoke;
|
|
26442
|
+
this.backendApi = backendApi;
|
|
26443
|
+
this.useBackendSubmitTx = useBackendSubmitTx ?? false;
|
|
26226
26444
|
}
|
|
26227
26445
|
/**
|
|
26228
26446
|
* Estimates the gas cost for a raw (unsigned) transaction on a spoke chain.
|
|
@@ -26366,14 +26584,22 @@ var SwapService = class {
|
|
|
26366
26584
|
/**
|
|
26367
26585
|
* Executes a full end-to-end cross-chain swap.
|
|
26368
26586
|
*
|
|
26369
|
-
* Orchestrates the complete swap lifecycle
|
|
26370
|
-
*
|
|
26371
|
-
*
|
|
26372
|
-
*
|
|
26373
|
-
*
|
|
26374
|
-
*
|
|
26375
|
-
*
|
|
26376
|
-
*
|
|
26587
|
+
* Orchestrates the complete swap lifecycle. `createIntent` first submits the intent transaction on
|
|
26588
|
+
* the source spoke chain; completion then runs via one of two paths, both bounded by a single
|
|
26589
|
+
* shared `timeout` budget:
|
|
26590
|
+
*
|
|
26591
|
+
* - **Client-side (default), {@link fallbackSwapSteps}:** verifies the spoke tx landed on-chain,
|
|
26592
|
+
* relays it to the hub (Sonic) and waits for the packet — skipped when `srcChainKey` is the hub,
|
|
26593
|
+
* where the spoke tx already is the hub tx — then calls `postExecution` to notify the solver,
|
|
26594
|
+
* triggering it to fill the intent.
|
|
26595
|
+
* - **Backend 2-step (opt-in via `swapsOptions.useBackendSubmitTx`), {@link submitTx}:** hands the
|
|
26596
|
+
* broadcast tx to the swaps API, which verifies, relays and post-executes server-side, then polls
|
|
26597
|
+
* for completion. On ANY non-success it transparently falls back to the client-side path above —
|
|
26598
|
+
* safe because re-relaying / re-posting an already-processed swap is idempotent (no double-fill).
|
|
26599
|
+
*
|
|
26600
|
+
* @param _params - Swap action params including intent parameters, wallet provider, and an optional
|
|
26601
|
+
* `timeout` — the single shared budget for the whole completion flow (relay/poll plus any
|
|
26602
|
+
* fallback), so total wall-clock never exceeds it.
|
|
26377
26603
|
* @returns A `Result<SwapResponse, SwapError>`. On success:
|
|
26378
26604
|
* - `solverExecutionResponse` — solver acknowledgement (`{ answer: 'OK', intent_hash }`).
|
|
26379
26605
|
* - `intent` — the on-chain intent object that was created.
|
|
@@ -26397,63 +26623,179 @@ var SwapService = class {
|
|
|
26397
26623
|
const { params } = _params;
|
|
26398
26624
|
const srcChainKey = params.srcChainKey;
|
|
26399
26625
|
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey };
|
|
26400
|
-
|
|
26401
|
-
|
|
26402
|
-
|
|
26403
|
-
|
|
26404
|
-
|
|
26626
|
+
return this.config.analytics.trackResult(
|
|
26627
|
+
"swap",
|
|
26628
|
+
"swap",
|
|
26629
|
+
async () => {
|
|
26630
|
+
try {
|
|
26631
|
+
const createIntentResult = await this.createIntent(_params);
|
|
26632
|
+
if (!createIntentResult.ok) {
|
|
26633
|
+
return { ok: false, error: createIntentResult.error };
|
|
26634
|
+
}
|
|
26635
|
+
const created = createIntentResult.value;
|
|
26636
|
+
const deadline = Date.now() + (_params.timeout ?? DEFAULT_RELAY_TX_TIMEOUT);
|
|
26637
|
+
if (this.useBackendSubmitTx) {
|
|
26638
|
+
const submitted = await this.submitTx(_params, created, deadline);
|
|
26639
|
+
if (submitted.ok) return submitted;
|
|
26640
|
+
this.config.logger.warn(
|
|
26641
|
+
"[swap] backend submit-tx did not complete; falling back to the client-side relay",
|
|
26642
|
+
{
|
|
26643
|
+
error: submitted.error
|
|
26644
|
+
}
|
|
26645
|
+
);
|
|
26646
|
+
}
|
|
26647
|
+
return this.fallbackSwapSteps(_params, created, deadline);
|
|
26648
|
+
} catch (error) {
|
|
26649
|
+
if (isSwapError(error)) return { ok: false, error };
|
|
26650
|
+
return {
|
|
26651
|
+
ok: false,
|
|
26652
|
+
error: unknownFailed("swap", error, { ...baseCtx, action: "swap" })
|
|
26653
|
+
};
|
|
26654
|
+
}
|
|
26655
|
+
},
|
|
26656
|
+
{
|
|
26657
|
+
start: () => ({
|
|
26658
|
+
srcChainKey,
|
|
26659
|
+
dstChainKey: params.dstChainKey,
|
|
26660
|
+
srcAddress: params.srcAddress,
|
|
26661
|
+
dstAddress: params.dstAddress
|
|
26662
|
+
}),
|
|
26663
|
+
success: (value) => ({
|
|
26664
|
+
srcChainKey,
|
|
26665
|
+
dstChainKey: params.dstChainKey,
|
|
26666
|
+
srcTxHash: value.intentDeliveryInfo.srcTxHash,
|
|
26667
|
+
dstTxHash: value.intentDeliveryInfo.dstTxHash
|
|
26668
|
+
}),
|
|
26669
|
+
failure: (error) => ({ code: error.code })
|
|
26405
26670
|
}
|
|
26406
|
-
|
|
26407
|
-
|
|
26408
|
-
|
|
26409
|
-
|
|
26671
|
+
);
|
|
26672
|
+
}
|
|
26673
|
+
/**
|
|
26674
|
+
* Client-side swap completion (the default path): relay the broadcast intent tx to the hub — or
|
|
26675
|
+
* use it directly when the source IS the hub — then notify the solver via post-execution and
|
|
26676
|
+
* build the {@link SwapResponse}. Extracted verbatim from `swap()` so the opt-in backend 2-step
|
|
26677
|
+
* path ({@link submitTx}) can fall back to it on any non-success.
|
|
26678
|
+
*/
|
|
26679
|
+
async fallbackSwapSteps(_params, created, deadline) {
|
|
26680
|
+
const { params } = _params;
|
|
26681
|
+
const srcChainKey = params.srcChainKey;
|
|
26682
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey };
|
|
26683
|
+
const { tx: spokeTxHash, intent, relayData } = created;
|
|
26684
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
26685
|
+
txHash: created.tx,
|
|
26686
|
+
chainKey: srcChainKey
|
|
26687
|
+
});
|
|
26688
|
+
if (!verifyTxHashResult.ok) {
|
|
26689
|
+
return { ok: false, error: verifyFailed("swap", verifyTxHashResult.error, { ...baseCtx, action: "swap" }) };
|
|
26690
|
+
}
|
|
26691
|
+
let dstIntentTxHash;
|
|
26692
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
26693
|
+
dstIntentTxHash = spokeTxHash;
|
|
26694
|
+
} else {
|
|
26695
|
+
const packet = await relayTxAndWaitPacket({
|
|
26696
|
+
srcTxHash: spokeTxHash,
|
|
26697
|
+
data: relayData,
|
|
26698
|
+
chainKey: srcChainKey,
|
|
26699
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
26700
|
+
// Remaining shared budget: ≈ full `timeout` on the flag-off path (called immediately), or
|
|
26701
|
+
// the reserve `submitTx` left on the backend path. Floor keeps a stalled-backend fallback viable.
|
|
26702
|
+
timeout: Math.max(deadline - Date.now(), 5e3)
|
|
26410
26703
|
});
|
|
26411
|
-
if (!
|
|
26412
|
-
return { ok: false, error:
|
|
26704
|
+
if (!packet.ok) {
|
|
26705
|
+
return { ok: false, error: mapRelayFailure(packet.error, { feature: "swap", action: "swap", ...baseCtx }) };
|
|
26413
26706
|
}
|
|
26414
|
-
|
|
26415
|
-
|
|
26416
|
-
|
|
26417
|
-
|
|
26418
|
-
|
|
26707
|
+
dstIntentTxHash = packet.value.dst_tx_hash;
|
|
26708
|
+
}
|
|
26709
|
+
const postExecResult = await this.postExecution({
|
|
26710
|
+
intent_tx_hash: dstIntentTxHash
|
|
26711
|
+
});
|
|
26712
|
+
if (!postExecResult.ok) {
|
|
26713
|
+
return { ok: false, error: postExecResult.error };
|
|
26714
|
+
}
|
|
26715
|
+
return {
|
|
26716
|
+
ok: true,
|
|
26717
|
+
value: {
|
|
26718
|
+
solverExecutionResponse: postExecResult.value,
|
|
26719
|
+
intent,
|
|
26720
|
+
intentDeliveryInfo: {
|
|
26721
|
+
srcChainKey,
|
|
26419
26722
|
srcTxHash: spokeTxHash,
|
|
26420
|
-
|
|
26421
|
-
|
|
26422
|
-
|
|
26423
|
-
|
|
26424
|
-
});
|
|
26425
|
-
if (!packet.ok) {
|
|
26426
|
-
return { ok: false, error: mapRelayFailure(packet.error, { feature: "swap", action: "swap", ...baseCtx }) };
|
|
26723
|
+
srcAddress: params.srcAddress,
|
|
26724
|
+
dstChainKey: params.dstChainKey,
|
|
26725
|
+
dstTxHash: dstIntentTxHash,
|
|
26726
|
+
dstAddress: params.dstAddress
|
|
26427
26727
|
}
|
|
26428
|
-
dstIntentTxHash = packet.value.dst_tx_hash;
|
|
26429
26728
|
}
|
|
26430
|
-
|
|
26431
|
-
|
|
26729
|
+
};
|
|
26730
|
+
}
|
|
26731
|
+
/**
|
|
26732
|
+
* Backend 2-step swap path (opt-in via `swapsOptions.useBackendSubmitTx`): hand the broadcast
|
|
26733
|
+
* intent tx to the swaps API (`POST /swaps/submit-tx`); the backend relays + post-executes
|
|
26734
|
+
* server-side. Polls `getSubmitTxStatus` until `executed`, then reconstructs the same
|
|
26735
|
+
* {@link SwapResponse} the client-side path returns (`result.dstIntentTxHash` → delivery info,
|
|
26736
|
+
* `result.intent_hash` → solver response).
|
|
26737
|
+
*
|
|
26738
|
+
* Never throws — returns `{ ok: false }` on any non-success (submit `!ok`, terminal `failed` /
|
|
26739
|
+
* abandoned, or poll timeout) so `swap()` falls back to {@link fallbackSwapSteps}.
|
|
26740
|
+
*
|
|
26741
|
+
* Falling back is safe: re-relaying / re-posting an already-processed swap is idempotent — the
|
|
26742
|
+
* relay dedups and returns the existing `executed` packet, and the solver re-affirms the intent
|
|
26743
|
+
* (no double-fill). Verified live by `e2e-tests/e2e-relay.test.ts`. Polling stops at
|
|
26744
|
+
* `deadline - reserve` so the fallback keeps a guaranteed slice of the shared `swap` budget.
|
|
26745
|
+
*/
|
|
26746
|
+
async submitTx(_params, created, deadline) {
|
|
26747
|
+
const { params } = _params;
|
|
26748
|
+
const srcChainKey = params.srcChainKey;
|
|
26749
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey };
|
|
26750
|
+
const { tx: spokeTxHash, intent, relayData } = created;
|
|
26751
|
+
const submitTxFailed = (cause) => ({
|
|
26752
|
+
ok: false,
|
|
26753
|
+
error: executionFailed("swap", cause, { ...baseCtx, action: "swap" })
|
|
26754
|
+
});
|
|
26755
|
+
try {
|
|
26756
|
+
const submitted = await this.backendApi.swaps.submitTx({
|
|
26757
|
+
txHash: spokeTxHash,
|
|
26758
|
+
srcChainKey,
|
|
26759
|
+
walletAddress: params.srcAddress,
|
|
26760
|
+
intent,
|
|
26761
|
+
relayData: relayData.payload
|
|
26432
26762
|
});
|
|
26433
|
-
if (!
|
|
26434
|
-
|
|
26435
|
-
|
|
26436
|
-
|
|
26437
|
-
|
|
26438
|
-
|
|
26439
|
-
|
|
26440
|
-
|
|
26441
|
-
|
|
26442
|
-
|
|
26443
|
-
|
|
26444
|
-
|
|
26445
|
-
|
|
26446
|
-
|
|
26447
|
-
|
|
26763
|
+
if (!submitted.ok) return submitTxFailed(submitted.error);
|
|
26764
|
+
const reserveMs = Math.min(Math.ceil((deadline - Date.now()) / 3), 2e4);
|
|
26765
|
+
const pollDeadline = deadline - reserveMs;
|
|
26766
|
+
const pollIntervalMs = 1e3;
|
|
26767
|
+
while (Date.now() < pollDeadline) {
|
|
26768
|
+
const statusResult = await this.backendApi.swaps.getSubmitTxStatus({ txHash: spokeTxHash, srcChainKey });
|
|
26769
|
+
if (statusResult.ok) {
|
|
26770
|
+
const { status, result, failureReason, abandonedAt } = statusResult.value.data;
|
|
26771
|
+
if (status === "executed" && result?.dstIntentTxHash && result.intent_hash) {
|
|
26772
|
+
return {
|
|
26773
|
+
ok: true,
|
|
26774
|
+
value: {
|
|
26775
|
+
// Backend serializes the hex intent_hash as a plain string; brand it at the boundary.
|
|
26776
|
+
solverExecutionResponse: { answer: "OK", intent_hash: result.intent_hash },
|
|
26777
|
+
intent,
|
|
26778
|
+
intentDeliveryInfo: {
|
|
26779
|
+
srcChainKey,
|
|
26780
|
+
srcTxHash: spokeTxHash,
|
|
26781
|
+
srcAddress: params.srcAddress,
|
|
26782
|
+
dstChainKey: params.dstChainKey,
|
|
26783
|
+
dstTxHash: result.dstIntentTxHash,
|
|
26784
|
+
dstAddress: params.dstAddress
|
|
26785
|
+
}
|
|
26786
|
+
}
|
|
26787
|
+
};
|
|
26788
|
+
}
|
|
26789
|
+
if (status === "failed" || abandonedAt) {
|
|
26790
|
+
const reason = failureReason ? `: ${failureReason}` : "";
|
|
26791
|
+
return submitTxFailed(new Error(`backend submit-tx ${status}${reason}`));
|
|
26448
26792
|
}
|
|
26449
26793
|
}
|
|
26450
|
-
|
|
26794
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
26795
|
+
}
|
|
26796
|
+
return submitTxFailed(new Error("backend submit-tx polling timed out before reaching executed"));
|
|
26451
26797
|
} catch (error) {
|
|
26452
|
-
|
|
26453
|
-
return {
|
|
26454
|
-
ok: false,
|
|
26455
|
-
error: unknownFailed("swap", error, { ...baseCtx, action: "swap" })
|
|
26456
|
-
};
|
|
26798
|
+
return { ok: false, error: unknownFailed("swap", error, { ...baseCtx, action: "swap" }) };
|
|
26457
26799
|
}
|
|
26458
26800
|
}
|
|
26459
26801
|
/**
|
|
@@ -28500,72 +28842,94 @@ var MigrationService = class {
|
|
|
28500
28842
|
* }
|
|
28501
28843
|
*/
|
|
28502
28844
|
async migratebnUSD(_params) {
|
|
28503
|
-
|
|
28504
|
-
|
|
28505
|
-
|
|
28506
|
-
|
|
28507
|
-
|
|
28508
|
-
|
|
28509
|
-
|
|
28510
|
-
|
|
28511
|
-
|
|
28512
|
-
const { tx: spokeTxHash, relayData: extraData } = intentResult.value;
|
|
28513
|
-
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
28514
|
-
txHash: spokeTxHash,
|
|
28515
|
-
chainKey: params.srcChainKey
|
|
28516
|
-
});
|
|
28517
|
-
if (!verifyTxHashResult.ok) {
|
|
28518
|
-
return {
|
|
28519
|
-
ok: false,
|
|
28520
|
-
error: verifyFailed("migration", verifyTxHashResult.error, baseCtx)
|
|
28521
|
-
};
|
|
28522
|
-
}
|
|
28523
|
-
const packetResult = await relayTxAndWaitPacket({
|
|
28524
|
-
srcTxHash: spokeTxHash,
|
|
28525
|
-
data: extraData,
|
|
28526
|
-
chainKey: params.srcChainKey,
|
|
28527
|
-
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
28528
|
-
timeout
|
|
28529
|
-
});
|
|
28530
|
-
if (!packetResult.ok) {
|
|
28531
|
-
return {
|
|
28532
|
-
ok: false,
|
|
28533
|
-
error: mapRelayFailure(packetResult.error, {
|
|
28534
|
-
feature: "migration",
|
|
28535
|
-
action: baseCtx.action,
|
|
28536
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
28537
|
-
dstChainKey: baseCtx.dstChainKey
|
|
28538
|
-
})
|
|
28845
|
+
return this.config.analytics.trackResult(
|
|
28846
|
+
"migration",
|
|
28847
|
+
"migratebnUSD",
|
|
28848
|
+
async () => {
|
|
28849
|
+
const { params, timeout } = _params;
|
|
28850
|
+
const baseCtx = {
|
|
28851
|
+
srcChainKey: params.srcChainKey,
|
|
28852
|
+
dstChainKey: params.dstChainKey,
|
|
28853
|
+
action: "migratebnUSD"
|
|
28539
28854
|
};
|
|
28540
|
-
|
|
28541
|
-
|
|
28542
|
-
|
|
28543
|
-
|
|
28544
|
-
|
|
28545
|
-
|
|
28546
|
-
|
|
28547
|
-
|
|
28548
|
-
|
|
28855
|
+
try {
|
|
28856
|
+
const intentResult = await this.createMigratebnUSDIntent(_params);
|
|
28857
|
+
if (!intentResult.ok) return { ok: false, error: intentResult.error };
|
|
28858
|
+
const { tx: spokeTxHash, relayData: extraData } = intentResult.value;
|
|
28859
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
28860
|
+
txHash: spokeTxHash,
|
|
28861
|
+
chainKey: params.srcChainKey
|
|
28862
|
+
});
|
|
28863
|
+
if (!verifyTxHashResult.ok) {
|
|
28864
|
+
return {
|
|
28865
|
+
ok: false,
|
|
28866
|
+
error: verifyFailed("migration", verifyTxHashResult.error, baseCtx)
|
|
28867
|
+
};
|
|
28868
|
+
}
|
|
28869
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
28870
|
+
srcTxHash: spokeTxHash,
|
|
28871
|
+
data: extraData,
|
|
28872
|
+
chainKey: params.srcChainKey,
|
|
28873
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
28874
|
+
timeout
|
|
28875
|
+
});
|
|
28876
|
+
if (!packetResult.ok) {
|
|
28877
|
+
return {
|
|
28878
|
+
ok: false,
|
|
28879
|
+
error: mapRelayFailure(packetResult.error, {
|
|
28880
|
+
feature: "migration",
|
|
28881
|
+
action: baseCtx.action,
|
|
28882
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
28883
|
+
dstChainKey: baseCtx.dstChainKey
|
|
28884
|
+
})
|
|
28885
|
+
};
|
|
28886
|
+
}
|
|
28887
|
+
if (!(params.srcChainKey === ChainKeys.SONIC_MAINNET || params.dstChainKey === ChainKeys.SONIC_MAINNET)) {
|
|
28888
|
+
const execResult = await waitUntilIntentExecuted({
|
|
28889
|
+
intentRelayChainId: getIntentRelayChainId(ChainKeys.SONIC_MAINNET).toString(),
|
|
28890
|
+
srcTxHash: packetResult.value.dst_tx_hash,
|
|
28891
|
+
timeout,
|
|
28892
|
+
apiUrl: this.relayerApiEndpoint
|
|
28893
|
+
});
|
|
28894
|
+
if (!execResult.ok) {
|
|
28895
|
+
return {
|
|
28896
|
+
ok: false,
|
|
28897
|
+
error: mapRelayFailure(execResult.error, {
|
|
28898
|
+
feature: "migration",
|
|
28899
|
+
action: baseCtx.action,
|
|
28900
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
28901
|
+
dstChainKey: baseCtx.dstChainKey,
|
|
28902
|
+
phase: "destinationExecution"
|
|
28903
|
+
})
|
|
28904
|
+
};
|
|
28905
|
+
}
|
|
28906
|
+
}
|
|
28907
|
+
return { ok: true, value: { srcChainTxHash: spokeTxHash, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
28908
|
+
} catch (error) {
|
|
28909
|
+
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28549
28910
|
return {
|
|
28550
28911
|
ok: false,
|
|
28551
|
-
error:
|
|
28552
|
-
feature: "migration",
|
|
28553
|
-
action: baseCtx.action,
|
|
28554
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
28555
|
-
dstChainKey: baseCtx.dstChainKey,
|
|
28556
|
-
phase: "destinationExecution"
|
|
28557
|
-
})
|
|
28912
|
+
error: executionFailed("migration", error, baseCtx)
|
|
28558
28913
|
};
|
|
28559
28914
|
}
|
|
28915
|
+
},
|
|
28916
|
+
{
|
|
28917
|
+
start: () => ({
|
|
28918
|
+
srcChainKey: _params.params.srcChainKey,
|
|
28919
|
+
dstChainKey: _params.params.dstChainKey,
|
|
28920
|
+
srcAddress: _params.params.srcAddress,
|
|
28921
|
+
dstAddress: _params.params.dstAddress,
|
|
28922
|
+
srcbnUSD: _params.params.srcbnUSD,
|
|
28923
|
+
dstbnUSD: _params.params.dstbnUSD,
|
|
28924
|
+
amount: _params.params.amount
|
|
28925
|
+
}),
|
|
28926
|
+
success: (value) => ({
|
|
28927
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
28928
|
+
dstChainTxHash: value.dstChainTxHash
|
|
28929
|
+
}),
|
|
28930
|
+
failure: (error) => ({ code: error.code })
|
|
28560
28931
|
}
|
|
28561
|
-
|
|
28562
|
-
} catch (error) {
|
|
28563
|
-
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28564
|
-
return {
|
|
28565
|
-
ok: false,
|
|
28566
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28567
|
-
};
|
|
28568
|
-
}
|
|
28932
|
+
);
|
|
28569
28933
|
}
|
|
28570
28934
|
/**
|
|
28571
28935
|
* Migrates ICX or wICX tokens from ICON to SODA on the hub chain (Sonic), including relay.
|
|
@@ -28580,37 +28944,57 @@ var MigrationService = class {
|
|
|
28580
28944
|
* check fails, the deposit reverts, or the relay times out.
|
|
28581
28945
|
*/
|
|
28582
28946
|
async migrateIcxToSoda(_params) {
|
|
28583
|
-
|
|
28584
|
-
|
|
28585
|
-
|
|
28586
|
-
|
|
28587
|
-
|
|
28588
|
-
|
|
28589
|
-
|
|
28590
|
-
|
|
28591
|
-
|
|
28592
|
-
|
|
28593
|
-
|
|
28594
|
-
|
|
28595
|
-
|
|
28596
|
-
|
|
28597
|
-
|
|
28598
|
-
|
|
28599
|
-
|
|
28600
|
-
|
|
28601
|
-
|
|
28602
|
-
|
|
28603
|
-
|
|
28604
|
-
|
|
28947
|
+
return this.config.analytics.trackResult(
|
|
28948
|
+
"migration",
|
|
28949
|
+
"migrateIcxToSoda",
|
|
28950
|
+
async () => {
|
|
28951
|
+
const { timeout } = _params;
|
|
28952
|
+
const baseCtx = { srcChainKey: _params.params.srcChainKey, action: "migrateIcxToSoda" };
|
|
28953
|
+
try {
|
|
28954
|
+
const txResult = await this.createMigrateIcxToSodaIntent(_params);
|
|
28955
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
28956
|
+
const { tx, relayData } = txResult.value;
|
|
28957
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
28958
|
+
srcTxHash: tx,
|
|
28959
|
+
data: relayData,
|
|
28960
|
+
chainKey: _params.params.srcChainKey,
|
|
28961
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
28962
|
+
timeout
|
|
28963
|
+
});
|
|
28964
|
+
if (!packetResult.ok) {
|
|
28965
|
+
return {
|
|
28966
|
+
ok: false,
|
|
28967
|
+
error: mapRelayFailure(packetResult.error, {
|
|
28968
|
+
feature: "migration",
|
|
28969
|
+
action: baseCtx.action,
|
|
28970
|
+
srcChainKey: baseCtx.srcChainKey
|
|
28971
|
+
})
|
|
28972
|
+
};
|
|
28973
|
+
}
|
|
28974
|
+
return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
28975
|
+
} catch (error) {
|
|
28976
|
+
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28977
|
+
return {
|
|
28978
|
+
ok: false,
|
|
28979
|
+
error: executionFailed("migration", error, baseCtx)
|
|
28980
|
+
};
|
|
28981
|
+
}
|
|
28982
|
+
},
|
|
28983
|
+
{
|
|
28984
|
+
start: () => ({
|
|
28985
|
+
srcChainKey: _params.params.srcChainKey,
|
|
28986
|
+
srcAddress: _params.params.srcAddress,
|
|
28987
|
+
dstAddress: _params.params.dstAddress,
|
|
28988
|
+
address: _params.params.address,
|
|
28989
|
+
amount: _params.params.amount
|
|
28990
|
+
}),
|
|
28991
|
+
success: (value) => ({
|
|
28992
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
28993
|
+
dstChainTxHash: value.dstChainTxHash
|
|
28994
|
+
}),
|
|
28995
|
+
failure: (error) => ({ code: error.code })
|
|
28605
28996
|
}
|
|
28606
|
-
|
|
28607
|
-
} catch (error) {
|
|
28608
|
-
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28609
|
-
return {
|
|
28610
|
-
ok: false,
|
|
28611
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28612
|
-
};
|
|
28613
|
-
}
|
|
28997
|
+
);
|
|
28614
28998
|
}
|
|
28615
28999
|
/**
|
|
28616
29000
|
* Reverts a previous ICX→SODA migration by swapping SODA back to wICX on the hub and
|
|
@@ -28628,37 +29012,56 @@ var MigrationService = class {
|
|
|
28628
29012
|
* Sonic deposit transaction and `dstChainTxHash` is the hub-side packet receipt.
|
|
28629
29013
|
*/
|
|
28630
29014
|
async revertMigrateSodaToIcx(_params) {
|
|
28631
|
-
|
|
28632
|
-
|
|
28633
|
-
|
|
28634
|
-
|
|
28635
|
-
|
|
28636
|
-
|
|
28637
|
-
|
|
28638
|
-
|
|
28639
|
-
|
|
28640
|
-
|
|
28641
|
-
|
|
28642
|
-
|
|
28643
|
-
|
|
28644
|
-
|
|
28645
|
-
|
|
28646
|
-
|
|
28647
|
-
|
|
28648
|
-
|
|
28649
|
-
|
|
28650
|
-
|
|
28651
|
-
|
|
28652
|
-
|
|
29015
|
+
return this.config.analytics.trackResult(
|
|
29016
|
+
"migration",
|
|
29017
|
+
"revertMigrateSodaToIcx",
|
|
29018
|
+
async () => {
|
|
29019
|
+
const { timeout } = _params;
|
|
29020
|
+
const baseCtx = { srcChainKey: ChainKeys.SONIC_MAINNET, action: "revertMigrateSodaToIcx" };
|
|
29021
|
+
try {
|
|
29022
|
+
const txResult = await this.createRevertSodaToIcxMigrationIntent(_params);
|
|
29023
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
29024
|
+
const { tx, relayData } = txResult.value;
|
|
29025
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
29026
|
+
srcTxHash: tx,
|
|
29027
|
+
data: relayData,
|
|
29028
|
+
chainKey: ChainKeys.SONIC_MAINNET,
|
|
29029
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
29030
|
+
timeout
|
|
29031
|
+
});
|
|
29032
|
+
if (!packetResult.ok) {
|
|
29033
|
+
return {
|
|
29034
|
+
ok: false,
|
|
29035
|
+
error: mapRelayFailure(packetResult.error, {
|
|
29036
|
+
feature: "migration",
|
|
29037
|
+
action: baseCtx.action,
|
|
29038
|
+
srcChainKey: baseCtx.srcChainKey
|
|
29039
|
+
})
|
|
29040
|
+
};
|
|
29041
|
+
}
|
|
29042
|
+
return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
29043
|
+
} catch (error) {
|
|
29044
|
+
if (isRevertMigrationOrchestrationError(error)) return { ok: false, error };
|
|
29045
|
+
return {
|
|
29046
|
+
ok: false,
|
|
29047
|
+
error: executionFailed("migration", error, baseCtx)
|
|
29048
|
+
};
|
|
29049
|
+
}
|
|
29050
|
+
},
|
|
29051
|
+
{
|
|
29052
|
+
start: () => ({
|
|
29053
|
+
srcChainKey: _params.params.srcChainKey,
|
|
29054
|
+
srcAddress: _params.params.srcAddress,
|
|
29055
|
+
dstAddress: _params.params.dstAddress,
|
|
29056
|
+
amount: _params.params.amount
|
|
29057
|
+
}),
|
|
29058
|
+
success: (value) => ({
|
|
29059
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
29060
|
+
dstChainTxHash: value.dstChainTxHash
|
|
29061
|
+
}),
|
|
29062
|
+
failure: (error) => ({ code: error.code })
|
|
28653
29063
|
}
|
|
28654
|
-
|
|
28655
|
-
} catch (error) {
|
|
28656
|
-
if (isRevertMigrationOrchestrationError(error)) return { ok: false, error };
|
|
28657
|
-
return {
|
|
28658
|
-
ok: false,
|
|
28659
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28660
|
-
};
|
|
28661
|
-
}
|
|
29064
|
+
);
|
|
28662
29065
|
}
|
|
28663
29066
|
/**
|
|
28664
29067
|
* Migrates BALN tokens from ICON to SODA on the hub chain (Sonic), including relay.
|
|
@@ -28675,37 +29078,58 @@ var MigrationService = class {
|
|
|
28675
29078
|
* ICON deposit transaction and `dstChainTxHash` is the hub-side packet receipt.
|
|
28676
29079
|
*/
|
|
28677
29080
|
async migrateBaln(_params) {
|
|
28678
|
-
|
|
28679
|
-
|
|
28680
|
-
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
28695
|
-
|
|
28696
|
-
|
|
28697
|
-
|
|
28698
|
-
|
|
28699
|
-
|
|
29081
|
+
return this.config.analytics.trackResult(
|
|
29082
|
+
"migration",
|
|
29083
|
+
"migrateBaln",
|
|
29084
|
+
async () => {
|
|
29085
|
+
const { timeout } = _params;
|
|
29086
|
+
const baseCtx = { srcChainKey: ChainKeys.ICON_MAINNET, action: "migrateBaln" };
|
|
29087
|
+
try {
|
|
29088
|
+
const txResult = await this.createMigrateBalnIntent(_params);
|
|
29089
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
29090
|
+
const { tx, relayData } = txResult.value;
|
|
29091
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
29092
|
+
srcTxHash: tx,
|
|
29093
|
+
data: relayData,
|
|
29094
|
+
chainKey: ChainKeys.ICON_MAINNET,
|
|
29095
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
29096
|
+
timeout
|
|
29097
|
+
});
|
|
29098
|
+
if (!packetResult.ok) {
|
|
29099
|
+
return {
|
|
29100
|
+
ok: false,
|
|
29101
|
+
error: mapRelayFailure(packetResult.error, {
|
|
29102
|
+
feature: "migration",
|
|
29103
|
+
action: baseCtx.action,
|
|
29104
|
+
srcChainKey: baseCtx.srcChainKey
|
|
29105
|
+
})
|
|
29106
|
+
};
|
|
29107
|
+
}
|
|
29108
|
+
return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
29109
|
+
} catch (error) {
|
|
29110
|
+
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
29111
|
+
return {
|
|
29112
|
+
ok: false,
|
|
29113
|
+
error: executionFailed("migration", error, baseCtx)
|
|
29114
|
+
};
|
|
29115
|
+
}
|
|
29116
|
+
},
|
|
29117
|
+
{
|
|
29118
|
+
start: () => ({
|
|
29119
|
+
srcChainKey: _params.params.srcChainKey,
|
|
29120
|
+
srcAddress: _params.params.srcAddress,
|
|
29121
|
+
dstAddress: _params.params.dstAddress,
|
|
29122
|
+
amount: _params.params.amount,
|
|
29123
|
+
lockupPeriod: _params.params.lockupPeriod,
|
|
29124
|
+
stake: _params.params.stake
|
|
29125
|
+
}),
|
|
29126
|
+
success: (value) => ({
|
|
29127
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
29128
|
+
dstChainTxHash: value.dstChainTxHash
|
|
29129
|
+
}),
|
|
29130
|
+
failure: (error) => ({ code: error.code })
|
|
28700
29131
|
}
|
|
28701
|
-
|
|
28702
|
-
} catch (error) {
|
|
28703
|
-
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28704
|
-
return {
|
|
28705
|
-
ok: false,
|
|
28706
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28707
|
-
};
|
|
28708
|
-
}
|
|
29132
|
+
);
|
|
28709
29133
|
}
|
|
28710
29134
|
/**
|
|
28711
29135
|
* Builds and submits the spoke-side deposit for a BALN→SODA migration without relaying.
|
|
@@ -29096,71 +29520,883 @@ var MigrationService = class {
|
|
|
29096
29520
|
}
|
|
29097
29521
|
};
|
|
29098
29522
|
|
|
29099
|
-
// src/backendApi/
|
|
29100
|
-
var
|
|
29523
|
+
// src/backendApi/api-utils.ts
|
|
29524
|
+
var toJsonBody = (value) => JSON.stringify(value, (_key, val) => typeof val === "bigint" ? val.toString() : val);
|
|
29525
|
+
async function makeRequest(params) {
|
|
29526
|
+
const { endpoint, config, overrideConfig = {}, logger, serviceLabel } = params;
|
|
29527
|
+
const baseURL = overrideConfig.baseURL || config.baseURL || "";
|
|
29528
|
+
const url = `${baseURL}${endpoint}`;
|
|
29529
|
+
const headers = { ...config.headers, ...overrideConfig.headers };
|
|
29530
|
+
const controller = new AbortController();
|
|
29531
|
+
const timeout = overrideConfig.timeout ?? config.timeout ?? DEFAULT_BACKEND_API_TIMEOUT;
|
|
29532
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
29533
|
+
try {
|
|
29534
|
+
const response = await fetch(url, {
|
|
29535
|
+
method: config.method,
|
|
29536
|
+
headers,
|
|
29537
|
+
body: config.body,
|
|
29538
|
+
signal: controller.signal
|
|
29539
|
+
});
|
|
29540
|
+
clearTimeout(timeoutId);
|
|
29541
|
+
if (!response.ok) {
|
|
29542
|
+
const errorText = await response.text();
|
|
29543
|
+
throw new Error("HTTP_REQUEST_FAILED", { cause: new Error(`HTTP ${response.status}: ${errorText}`) });
|
|
29544
|
+
}
|
|
29545
|
+
const data = await response.json();
|
|
29546
|
+
return data;
|
|
29547
|
+
} catch (error) {
|
|
29548
|
+
clearTimeout(timeoutId);
|
|
29549
|
+
if (error instanceof Error) {
|
|
29550
|
+
if (error.name === "AbortError") {
|
|
29551
|
+
throw new Error("REQUEST_TIMEOUT", { cause: new Error(`Request timeout after ${timeout}ms`) });
|
|
29552
|
+
}
|
|
29553
|
+
logger.error(`[${serviceLabel}] Request error`, error);
|
|
29554
|
+
throw error;
|
|
29555
|
+
}
|
|
29556
|
+
logger.error(`[${serviceLabel}] Unknown error`, error);
|
|
29557
|
+
throw new Error("UNKNOWN_REQUEST_ERROR", { cause: error });
|
|
29558
|
+
}
|
|
29559
|
+
}
|
|
29560
|
+
var SwapTokenSchema = v4.object({
|
|
29561
|
+
symbol: v4.string(),
|
|
29562
|
+
name: v4.string(),
|
|
29563
|
+
decimals: v4.number(),
|
|
29564
|
+
address: v4.string(),
|
|
29565
|
+
chainKey: v4.string(),
|
|
29566
|
+
hubAsset: v4.string(),
|
|
29567
|
+
vault: v4.string()
|
|
29568
|
+
});
|
|
29569
|
+
var IntentResponseSchema = v4.object({
|
|
29570
|
+
intentId: v4.string(),
|
|
29571
|
+
creator: v4.string(),
|
|
29572
|
+
inputToken: v4.string(),
|
|
29573
|
+
outputToken: v4.string(),
|
|
29574
|
+
inputAmount: v4.string(),
|
|
29575
|
+
minOutputAmount: v4.string(),
|
|
29576
|
+
deadline: v4.string(),
|
|
29577
|
+
allowPartialFill: v4.boolean(),
|
|
29578
|
+
srcChain: v4.string(),
|
|
29579
|
+
dstChain: v4.string(),
|
|
29580
|
+
srcAddress: v4.string(),
|
|
29581
|
+
dstAddress: v4.string(),
|
|
29582
|
+
solver: v4.string(),
|
|
29583
|
+
data: v4.string()
|
|
29584
|
+
});
|
|
29585
|
+
var RelayExtraDataResponseSchema = v4.object({
|
|
29586
|
+
address: v4.string(),
|
|
29587
|
+
payload: v4.string()
|
|
29588
|
+
});
|
|
29589
|
+
var makeCreateIntentResponseSchema = (txSchema) => v4.object({
|
|
29590
|
+
tx: txSchema,
|
|
29591
|
+
intent: IntentResponseSchema,
|
|
29592
|
+
relayData: RelayExtraDataResponseSchema
|
|
29593
|
+
});
|
|
29594
|
+
var GetSwapTokensResponseSchema = v4.record(v4.string(), v4.array(SwapTokenSchema));
|
|
29595
|
+
var GetSwapTokensByChainResponseSchema = v4.array(SwapTokenSchema);
|
|
29596
|
+
var makeQuoteResponseSchema = (txSchema) => v4.object({
|
|
29597
|
+
quotedAmount: v4.string(),
|
|
29598
|
+
txData: v4.optional(makeCreateIntentResponseSchema(txSchema))
|
|
29599
|
+
});
|
|
29600
|
+
var DeadlineResponseSchema = v4.object({
|
|
29601
|
+
deadline: v4.string()
|
|
29602
|
+
});
|
|
29603
|
+
var AllowanceCheckResponseSchema = v4.object({
|
|
29604
|
+
valid: v4.boolean()
|
|
29605
|
+
});
|
|
29606
|
+
var makeApproveResponseSchema = (txSchema) => v4.object({ tx: txSchema });
|
|
29607
|
+
var SubmitIntentResponseSchema = v4.object({
|
|
29608
|
+
result: v4.unknown()
|
|
29609
|
+
});
|
|
29610
|
+
var StatusResponseSchema = v4.object({
|
|
29611
|
+
status: v4.picklist([-1, 1, 2, 3, 4]),
|
|
29612
|
+
fillTxHash: v4.optional(v4.string())
|
|
29613
|
+
});
|
|
29614
|
+
var makeCancelIntentResponseSchema = (txSchema) => v4.object({ tx: txSchema });
|
|
29615
|
+
var IntentHashResponseSchema = v4.object({
|
|
29616
|
+
hash: v4.string()
|
|
29617
|
+
});
|
|
29618
|
+
var IntentPacketResponseSchema = v4.object({
|
|
29619
|
+
srcChainId: v4.number(),
|
|
29620
|
+
srcTxHash: v4.string(),
|
|
29621
|
+
srcAddress: v4.string(),
|
|
29622
|
+
status: v4.string(),
|
|
29623
|
+
dstChainId: v4.number(),
|
|
29624
|
+
connSn: v4.number(),
|
|
29625
|
+
dstAddress: v4.string(),
|
|
29626
|
+
dstTxHash: v4.string(),
|
|
29627
|
+
signatures: v4.array(v4.string()),
|
|
29628
|
+
payload: v4.string()
|
|
29629
|
+
});
|
|
29630
|
+
var IntentStateResponseSchema = v4.object({
|
|
29631
|
+
exists: v4.boolean(),
|
|
29632
|
+
remainingInput: v4.string(),
|
|
29633
|
+
receivedOutput: v4.string(),
|
|
29634
|
+
pendingPayment: v4.boolean()
|
|
29635
|
+
});
|
|
29636
|
+
var GasEstimateResponseSchema = v4.object({
|
|
29637
|
+
gas: v4.unknown()
|
|
29638
|
+
});
|
|
29639
|
+
var FeeResponseSchema = v4.object({
|
|
29640
|
+
fee: v4.string()
|
|
29641
|
+
});
|
|
29642
|
+
var SubmitTxResponseSchema = v4.object({
|
|
29643
|
+
success: v4.boolean(),
|
|
29644
|
+
data: v4.object({
|
|
29645
|
+
status: v4.picklist(["inserted", "duplicate"]),
|
|
29646
|
+
message: v4.string()
|
|
29647
|
+
})
|
|
29648
|
+
});
|
|
29649
|
+
var SubmitSwapTxStatusSchema = v4.picklist([
|
|
29650
|
+
"pending",
|
|
29651
|
+
"relaying",
|
|
29652
|
+
"relayed",
|
|
29653
|
+
"posting_execution",
|
|
29654
|
+
"executed",
|
|
29655
|
+
"failed"
|
|
29656
|
+
]);
|
|
29657
|
+
var PacketDataSchema = v4.object({
|
|
29658
|
+
src_chain_id: v4.number(),
|
|
29659
|
+
src_tx_hash: v4.string(),
|
|
29660
|
+
src_address: v4.string(),
|
|
29661
|
+
status: v4.picklist(["pending", "validating", "executing", "executed"]),
|
|
29662
|
+
dst_chain_id: v4.number(),
|
|
29663
|
+
conn_sn: v4.number(),
|
|
29664
|
+
dst_address: v4.string(),
|
|
29665
|
+
dst_tx_hash: v4.string(),
|
|
29666
|
+
signatures: v4.array(v4.string()),
|
|
29667
|
+
payload: v4.string()
|
|
29668
|
+
});
|
|
29669
|
+
var SubmitTxStatusResultSchema = v4.object({
|
|
29670
|
+
dstIntentTxHash: v4.string(),
|
|
29671
|
+
packetData: v4.optional(PacketDataSchema),
|
|
29672
|
+
intent_hash: v4.optional(v4.string())
|
|
29673
|
+
});
|
|
29674
|
+
var SubmitTxStatusDataSchema = v4.object({
|
|
29675
|
+
txHash: v4.string(),
|
|
29676
|
+
srcChainKey: v4.string(),
|
|
29677
|
+
status: SubmitSwapTxStatusSchema,
|
|
29678
|
+
failedAtStep: v4.optional(SubmitSwapTxStatusSchema),
|
|
29679
|
+
failureReason: v4.optional(v4.string()),
|
|
29680
|
+
processingAttempts: v4.number(),
|
|
29681
|
+
abandonedAt: v4.optional(v4.string()),
|
|
29682
|
+
result: v4.optional(SubmitTxStatusResultSchema),
|
|
29683
|
+
userMessage: v4.optional(v4.string()),
|
|
29684
|
+
intentCancelled: v4.optional(v4.boolean())
|
|
29685
|
+
});
|
|
29686
|
+
var SubmitTxStatusResponseSchema = v4.object({
|
|
29687
|
+
success: v4.boolean(),
|
|
29688
|
+
data: SubmitTxStatusDataSchema
|
|
29689
|
+
});
|
|
29690
|
+
var AddressSchema = v4.custom((input) => typeof input === "string");
|
|
29691
|
+
var HexSchema = v4.custom((input) => typeof input === "string");
|
|
29692
|
+
var BigintFromString = v4.pipe(v4.string(), v4.toBigint());
|
|
29693
|
+
var BytesFromIndexRecord = v4.pipe(
|
|
29694
|
+
v4.record(v4.string(), v4.number()),
|
|
29695
|
+
v4.transform((indexed) => Uint8Array.from(Object.values(indexed)))
|
|
29696
|
+
);
|
|
29697
|
+
var EvmRawTxSchema = v4.object({
|
|
29698
|
+
from: AddressSchema,
|
|
29699
|
+
to: AddressSchema,
|
|
29700
|
+
value: BigintFromString,
|
|
29701
|
+
data: HexSchema
|
|
29702
|
+
});
|
|
29703
|
+
var SolanaRawTxSchema = v4.object({
|
|
29704
|
+
from: v4.string(),
|
|
29705
|
+
to: v4.string(),
|
|
29706
|
+
value: BigintFromString,
|
|
29707
|
+
data: v4.string()
|
|
29708
|
+
});
|
|
29709
|
+
var SuiRawTxSchema = v4.object({
|
|
29710
|
+
from: HexSchema,
|
|
29711
|
+
to: v4.string(),
|
|
29712
|
+
value: BigintFromString,
|
|
29713
|
+
data: v4.string()
|
|
29714
|
+
});
|
|
29715
|
+
var StellarRawTxSchema = v4.object({
|
|
29716
|
+
from: v4.string(),
|
|
29717
|
+
to: v4.string(),
|
|
29718
|
+
value: BigintFromString,
|
|
29719
|
+
data: v4.string()
|
|
29720
|
+
});
|
|
29721
|
+
var InjectiveRawTxSchema = v4.object({
|
|
29722
|
+
from: HexSchema,
|
|
29723
|
+
to: HexSchema,
|
|
29724
|
+
signedDoc: v4.object({
|
|
29725
|
+
bodyBytes: BytesFromIndexRecord,
|
|
29726
|
+
authInfoBytes: BytesFromIndexRecord,
|
|
29727
|
+
chainId: v4.string(),
|
|
29728
|
+
accountNumber: BigintFromString
|
|
29729
|
+
})
|
|
29730
|
+
});
|
|
29731
|
+
var NearRawTxSchema = v4.object({
|
|
29732
|
+
signerId: v4.string(),
|
|
29733
|
+
params: v4.object({
|
|
29734
|
+
contractId: v4.string(),
|
|
29735
|
+
method: v4.string(),
|
|
29736
|
+
args: v4.custom((input) => typeof input === "object" && input !== null),
|
|
29737
|
+
gas: v4.optional(BigintFromString),
|
|
29738
|
+
deposit: v4.optional(BigintFromString)
|
|
29739
|
+
})
|
|
29740
|
+
});
|
|
29741
|
+
var IconRawTxSchema = v4.record(
|
|
29742
|
+
v4.string(),
|
|
29743
|
+
v4.union([v4.string(), v4.custom((input) => typeof input === "object" && input !== null)])
|
|
29744
|
+
);
|
|
29745
|
+
var StacksRawTxSchema = v4.object({
|
|
29746
|
+
payload: v4.string(),
|
|
29747
|
+
estimatedLength: v4.optional(v4.number())
|
|
29748
|
+
});
|
|
29749
|
+
var AnyRawTxSchema = v4.custom((input) => typeof input === "object" && input !== null);
|
|
29750
|
+
function rawTxSchemaForChainKey(chainKey) {
|
|
29751
|
+
let chainType;
|
|
29752
|
+
try {
|
|
29753
|
+
chainType = getChainType(chainKey);
|
|
29754
|
+
} catch {
|
|
29755
|
+
chainType = void 0;
|
|
29756
|
+
}
|
|
29757
|
+
switch (chainType) {
|
|
29758
|
+
case "EVM":
|
|
29759
|
+
return EvmRawTxSchema;
|
|
29760
|
+
case "SOLANA":
|
|
29761
|
+
return SolanaRawTxSchema;
|
|
29762
|
+
case "SUI":
|
|
29763
|
+
return SuiRawTxSchema;
|
|
29764
|
+
case "STELLAR":
|
|
29765
|
+
return StellarRawTxSchema;
|
|
29766
|
+
case "INJECTIVE":
|
|
29767
|
+
return InjectiveRawTxSchema;
|
|
29768
|
+
case "ICON":
|
|
29769
|
+
return IconRawTxSchema;
|
|
29770
|
+
case "STACKS":
|
|
29771
|
+
return StacksRawTxSchema;
|
|
29772
|
+
case "NEAR":
|
|
29773
|
+
return NearRawTxSchema;
|
|
29774
|
+
default:
|
|
29775
|
+
return AnyRawTxSchema;
|
|
29776
|
+
}
|
|
29777
|
+
}
|
|
29778
|
+
|
|
29779
|
+
// src/backendApi/SwapsApiService.ts
|
|
29780
|
+
var SwapsApiService = class {
|
|
29781
|
+
// Fully-resolved swaps-API config supplied by the caller (BackendApiService resolves the
|
|
29782
|
+
// `ApiConfig` union via `resolveSwapsApiConfig`); this service does not resolve the union.
|
|
29783
|
+
config;
|
|
29784
|
+
headers;
|
|
29785
|
+
logger;
|
|
29101
29786
|
constructor(config, logger = consoleLogger) {
|
|
29102
29787
|
this.config = config;
|
|
29103
29788
|
this.headers = { ...config.headers };
|
|
29104
29789
|
this.logger = logger;
|
|
29105
29790
|
}
|
|
29106
|
-
headers;
|
|
29107
|
-
logger;
|
|
29108
29791
|
/**
|
|
29109
|
-
*
|
|
29110
|
-
*
|
|
29111
|
-
*
|
|
29112
|
-
*
|
|
29113
|
-
* request exceeds the timeout, so callers should use {@link request} instead of
|
|
29114
|
-
* calling this directly.
|
|
29115
|
-
*
|
|
29116
|
-
* @throws `Error('HTTP_REQUEST_FAILED')` on non-2xx responses.
|
|
29117
|
-
* @throws `Error('REQUEST_TIMEOUT')` when the request exceeds the timeout.
|
|
29118
|
-
* @throws `Error('UNKNOWN_REQUEST_ERROR')` for any other unexpected failure.
|
|
29792
|
+
* Issues a single HTTP request, validates the JSON body against `schema`, and
|
|
29793
|
+
* wraps the result in `Result<T>`. The service-level `baseURL`/`timeout`/
|
|
29794
|
+
* `headers` are merged with the optional per-call `overrideConfig` (which takes
|
|
29795
|
+
* precedence) inside {@link makeRequest}. Every public method delegates here.
|
|
29119
29796
|
*/
|
|
29120
|
-
async
|
|
29121
|
-
const url = config.baseURL ? `${config.baseURL}${endpoint}` : `${this.config.baseURL}${endpoint}`;
|
|
29122
|
-
const headers = { ...this.headers, ...config.headers };
|
|
29123
|
-
const controller = new AbortController();
|
|
29124
|
-
const timeout = config.timeout ?? this.config.timeout;
|
|
29125
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
29797
|
+
async request(endpoint, config, schema, overrideConfig) {
|
|
29126
29798
|
try {
|
|
29127
|
-
const
|
|
29128
|
-
|
|
29129
|
-
headers,
|
|
29130
|
-
|
|
29131
|
-
|
|
29799
|
+
const raw = await makeRequest({
|
|
29800
|
+
endpoint,
|
|
29801
|
+
config: { baseURL: this.config.baseURL, timeout: this.config.timeout, headers: this.headers, ...config },
|
|
29802
|
+
overrideConfig,
|
|
29803
|
+
logger: this.logger,
|
|
29804
|
+
serviceLabel: "SwapsApiService"
|
|
29132
29805
|
});
|
|
29133
|
-
|
|
29134
|
-
if (!
|
|
29135
|
-
|
|
29136
|
-
|
|
29806
|
+
const parsed = v4.safeParse(schema, raw);
|
|
29807
|
+
if (!parsed.success) {
|
|
29808
|
+
return {
|
|
29809
|
+
ok: false,
|
|
29810
|
+
error: new SodaxError("EXTERNAL_API_ERROR", `Invalid response shape from swaps API for ${endpoint}`, {
|
|
29811
|
+
feature: "backend",
|
|
29812
|
+
context: { api: "swaps", endpoint, reason: "invalid_response_shape", issues: v4.flatten(parsed.issues) }
|
|
29813
|
+
})
|
|
29814
|
+
};
|
|
29137
29815
|
}
|
|
29138
|
-
|
|
29139
|
-
return data;
|
|
29816
|
+
return { ok: true, value: parsed.output };
|
|
29140
29817
|
} catch (error) {
|
|
29141
|
-
|
|
29142
|
-
|
|
29143
|
-
|
|
29144
|
-
|
|
29145
|
-
|
|
29146
|
-
|
|
29147
|
-
|
|
29148
|
-
|
|
29149
|
-
|
|
29150
|
-
|
|
29818
|
+
return {
|
|
29819
|
+
ok: false,
|
|
29820
|
+
error: new SodaxError(
|
|
29821
|
+
"EXTERNAL_API_ERROR",
|
|
29822
|
+
error instanceof Error ? error.message : `Request to ${endpoint} failed`,
|
|
29823
|
+
{
|
|
29824
|
+
feature: "backend",
|
|
29825
|
+
cause: error,
|
|
29826
|
+
context: { api: "swaps", endpoint }
|
|
29827
|
+
}
|
|
29828
|
+
)
|
|
29829
|
+
};
|
|
29830
|
+
}
|
|
29831
|
+
}
|
|
29832
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29833
|
+
// Tokens
|
|
29834
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29835
|
+
/**
|
|
29836
|
+
* Fetch all supported swap tokens grouped by SpokeChainKey.
|
|
29837
|
+
*
|
|
29838
|
+
* @returns `Result<GetSwapTokensResponseV2>` — map of chain key → token list.
|
|
29839
|
+
*/
|
|
29840
|
+
async getTokens(config) {
|
|
29841
|
+
return this.request("/swaps/tokens", { method: "GET" }, GetSwapTokensResponseSchema, config);
|
|
29842
|
+
}
|
|
29843
|
+
/**
|
|
29844
|
+
* Fetch supported swap tokens for a single SpokeChainKey.
|
|
29845
|
+
*
|
|
29846
|
+
* @param chainKey - SODAX SpokeChainKey (e.g. `0xa4b1.arbitrum`, `solana`).
|
|
29847
|
+
* @returns `Result<GetSwapTokensByChainResponseV2>` — token list for the chain.
|
|
29848
|
+
*/
|
|
29849
|
+
async getTokensByChain(chainKey, config) {
|
|
29850
|
+
return this.request(
|
|
29851
|
+
`/swaps/tokens/${chainKey}`,
|
|
29852
|
+
{ method: "GET" },
|
|
29853
|
+
GetSwapTokensByChainResponseSchema,
|
|
29854
|
+
config
|
|
29855
|
+
);
|
|
29856
|
+
}
|
|
29857
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29858
|
+
// Quote · deadline
|
|
29859
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29860
|
+
/**
|
|
29861
|
+
* Get a solver quote for a cross-chain swap.
|
|
29862
|
+
*
|
|
29863
|
+
* Pass `query.includeTxData = true` to also build an unsigned create-intent
|
|
29864
|
+
* transaction (`txData`) using the quoted amount as `minOutputAmount`; in that
|
|
29865
|
+
* case `srcAddress`/`dstAddress` are required in the body.
|
|
29866
|
+
*
|
|
29867
|
+
* @returns `Result<QuoteResponseV2>` — `quotedAmount` (decimal string) and optional `txData`.
|
|
29868
|
+
*/
|
|
29869
|
+
async getQuote(body, query, config) {
|
|
29870
|
+
const endpoint = query?.includeTxData ? "/swaps/quote?includeTxData=true" : "/swaps/quote";
|
|
29871
|
+
const txSchema = rawTxSchemaForChainKey(body.tokenSrcChainKey);
|
|
29872
|
+
return this.request(
|
|
29873
|
+
endpoint,
|
|
29874
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29875
|
+
makeQuoteResponseSchema(txSchema),
|
|
29876
|
+
config
|
|
29877
|
+
);
|
|
29878
|
+
}
|
|
29879
|
+
/**
|
|
29880
|
+
* Compute a swap deadline (hub timestamp + `offsetSeconds`, default 300s).
|
|
29881
|
+
*
|
|
29882
|
+
* @returns `Result<DeadlineResponseV2>` — unix-seconds deadline (decimal string).
|
|
29883
|
+
*/
|
|
29884
|
+
async getDeadline(query, config) {
|
|
29885
|
+
const queryParams = new URLSearchParams();
|
|
29886
|
+
if (query?.offsetSeconds !== void 0) queryParams.append("offsetSeconds", String(query.offsetSeconds));
|
|
29887
|
+
const queryString = queryParams.toString();
|
|
29888
|
+
const endpoint = queryString.length > 0 ? `/swaps/deadline?${queryString}` : "/swaps/deadline";
|
|
29889
|
+
return this.request(endpoint, { method: "GET" }, DeadlineResponseSchema, config);
|
|
29890
|
+
}
|
|
29891
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29892
|
+
// Allowance · approve · create intent
|
|
29893
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29894
|
+
/**
|
|
29895
|
+
* Check whether the source token allowance is already sufficient for the intent.
|
|
29896
|
+
*
|
|
29897
|
+
* @returns `Result<AllowanceCheckResponseV2>` — `{ valid }`.
|
|
29898
|
+
*/
|
|
29899
|
+
async checkAllowance(body, config) {
|
|
29900
|
+
return this.request(
|
|
29901
|
+
"/swaps/allowance/check",
|
|
29902
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29903
|
+
AllowanceCheckResponseSchema,
|
|
29904
|
+
config
|
|
29905
|
+
);
|
|
29906
|
+
}
|
|
29907
|
+
/**
|
|
29908
|
+
* Build an unsigned token-approval transaction for the source token.
|
|
29909
|
+
*
|
|
29910
|
+
* @returns `Result<ApproveResponseV2>` — `{ tx }` (chain-specific unsigned tx).
|
|
29911
|
+
*/
|
|
29912
|
+
async approve(body, config) {
|
|
29913
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
29914
|
+
return this.request(
|
|
29915
|
+
"/swaps/approve",
|
|
29916
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29917
|
+
makeApproveResponseSchema(txSchema),
|
|
29918
|
+
config
|
|
29919
|
+
);
|
|
29920
|
+
}
|
|
29921
|
+
/**
|
|
29922
|
+
* Build an unsigned create-intent transaction.
|
|
29923
|
+
*
|
|
29924
|
+
* @returns `Result<CreateIntentResponseV2>` — `{ tx, intent, relayData }`.
|
|
29925
|
+
*/
|
|
29926
|
+
async createIntent(body, config) {
|
|
29927
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
29928
|
+
return this.request(
|
|
29929
|
+
"/swaps/intents",
|
|
29930
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29931
|
+
makeCreateIntentResponseSchema(txSchema),
|
|
29932
|
+
config
|
|
29933
|
+
);
|
|
29934
|
+
}
|
|
29935
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29936
|
+
// Intent lifecycle: submit · status · cancel · hash · packet · extra-data
|
|
29937
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29938
|
+
/**
|
|
29939
|
+
* Submit the broadcast intent tx to the relay.
|
|
29940
|
+
*
|
|
29941
|
+
* @returns `Result<SubmitIntentResponseV2>` — `{ result }` (opaque relay response).
|
|
29942
|
+
*/
|
|
29943
|
+
async submitIntent(body, config) {
|
|
29944
|
+
return this.request(
|
|
29945
|
+
"/swaps/intents/submit",
|
|
29946
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29947
|
+
SubmitIntentResponseSchema,
|
|
29948
|
+
config
|
|
29949
|
+
);
|
|
29950
|
+
}
|
|
29951
|
+
/**
|
|
29952
|
+
* Poll the solver for intent execution status.
|
|
29953
|
+
*
|
|
29954
|
+
* @returns `Result<StatusResponseV2>` — `{ status, fillTxHash? }` (`fillTxHash` set when `status === 3`).
|
|
29955
|
+
*/
|
|
29956
|
+
async getStatus(body, config) {
|
|
29957
|
+
return this.request(
|
|
29958
|
+
"/swaps/intents/status",
|
|
29959
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29960
|
+
StatusResponseSchema,
|
|
29961
|
+
config
|
|
29962
|
+
);
|
|
29963
|
+
}
|
|
29964
|
+
/**
|
|
29965
|
+
* Build an unsigned cancel-intent transaction. The `intent` field carries
|
|
29966
|
+
* `bigint` numerics — {@link toJsonBody} serializes them to decimal strings.
|
|
29967
|
+
*
|
|
29968
|
+
* @returns `Result<CancelIntentResponseV2>` — `{ tx }`.
|
|
29969
|
+
*/
|
|
29970
|
+
async cancelIntent(body, config) {
|
|
29971
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
29972
|
+
return this.request(
|
|
29973
|
+
"/swaps/intents/cancel",
|
|
29974
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29975
|
+
makeCancelIntentResponseSchema(txSchema),
|
|
29976
|
+
config
|
|
29977
|
+
);
|
|
29978
|
+
}
|
|
29979
|
+
/**
|
|
29980
|
+
* Compute the keccak256 hash of an Intent struct. The `intent` field carries
|
|
29981
|
+
* `bigint` numerics — {@link toJsonBody} serializes them to decimal strings.
|
|
29982
|
+
*
|
|
29983
|
+
* @returns `Result<IntentHashResponseV2>` — `{ hash }`.
|
|
29984
|
+
*/
|
|
29985
|
+
async getIntentHash(body, config) {
|
|
29986
|
+
return this.request(
|
|
29987
|
+
"/swaps/intents/hash",
|
|
29988
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29989
|
+
IntentHashResponseSchema,
|
|
29990
|
+
config
|
|
29991
|
+
);
|
|
29992
|
+
}
|
|
29993
|
+
/**
|
|
29994
|
+
* Long-poll the relayer until the fill packet lands on the destination chain.
|
|
29995
|
+
*
|
|
29996
|
+
* @returns `Result<IntentPacketResponseV2>` — delivered packet data.
|
|
29997
|
+
*/
|
|
29998
|
+
async getSolvedIntentPacket(body, config) {
|
|
29999
|
+
return this.request(
|
|
30000
|
+
"/swaps/intents/packet",
|
|
30001
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30002
|
+
IntentPacketResponseSchema,
|
|
30003
|
+
config
|
|
30004
|
+
);
|
|
30005
|
+
}
|
|
30006
|
+
/**
|
|
30007
|
+
* Recover the relay extra data needed by `/swaps/intents/submit`. Provide
|
|
30008
|
+
* EITHER `txHash` OR `intent` (whose `bigint` numerics {@link toJsonBody} serializes).
|
|
30009
|
+
*
|
|
30010
|
+
* @returns `Result<IntentExtraDataResponseV2>` — `{ address, payload }`.
|
|
30011
|
+
*/
|
|
30012
|
+
async getIntentSubmitTxExtraData(body, config) {
|
|
30013
|
+
return this.request(
|
|
30014
|
+
"/swaps/intents/extra-data",
|
|
30015
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30016
|
+
RelayExtraDataResponseSchema,
|
|
30017
|
+
config
|
|
30018
|
+
);
|
|
30019
|
+
}
|
|
30020
|
+
/**
|
|
30021
|
+
* Get the on-chain fill state for an intent by its hub-chain tx hash.
|
|
30022
|
+
*
|
|
30023
|
+
* @returns `Result<IntentStateV2>` — `{ exists, remainingInput, receivedOutput, pendingPayment }`.
|
|
30024
|
+
*/
|
|
30025
|
+
async getFilledIntent(txHash, config) {
|
|
30026
|
+
return this.request(`/swaps/intents/${txHash}/fill`, { method: "GET" }, IntentStateResponseSchema, config);
|
|
30027
|
+
}
|
|
30028
|
+
/**
|
|
30029
|
+
* Look up an Intent struct by its hub-chain creation tx hash.
|
|
30030
|
+
*
|
|
30031
|
+
* @returns `Result<GetIntentResponseV2>` — the decoded intent (bigint fields as decimal strings).
|
|
30032
|
+
*/
|
|
30033
|
+
async getIntent(txHash, config) {
|
|
30034
|
+
return this.request(`/swaps/intents/${txHash}`, { method: "GET" }, IntentResponseSchema, config);
|
|
30035
|
+
}
|
|
30036
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30037
|
+
// Limit orders · gas · fees
|
|
30038
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30039
|
+
/**
|
|
30040
|
+
* Build an unsigned create-limit-order-intent transaction (same as create-intent
|
|
30041
|
+
* but `deadline` is optional).
|
|
30042
|
+
*
|
|
30043
|
+
* @returns `Result<CreateLimitOrderResponseV2>` — `{ tx, intent, relayData }`.
|
|
30044
|
+
*/
|
|
30045
|
+
async createLimitOrderIntent(body, config) {
|
|
30046
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
30047
|
+
return this.request(
|
|
30048
|
+
"/swaps/limit-orders",
|
|
30049
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30050
|
+
makeCreateIntentResponseSchema(txSchema),
|
|
30051
|
+
config
|
|
30052
|
+
);
|
|
30053
|
+
}
|
|
30054
|
+
/**
|
|
30055
|
+
* Estimate gas for a raw transaction on a spoke chain.
|
|
30056
|
+
*
|
|
30057
|
+
* @returns `Result<GasEstimateResponseV2>` — `{ gas }` (chain-specific shape).
|
|
30058
|
+
*/
|
|
30059
|
+
async estimateGas(body, config) {
|
|
30060
|
+
return this.request(
|
|
30061
|
+
"/swaps/gas/estimate",
|
|
30062
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30063
|
+
GasEstimateResponseSchema,
|
|
30064
|
+
config
|
|
30065
|
+
);
|
|
30066
|
+
}
|
|
30067
|
+
/**
|
|
30068
|
+
* Compute the partner fee for a given input amount.
|
|
30069
|
+
*
|
|
30070
|
+
* @returns `Result<FeeResponseV2>` — `{ fee }` (decimal string).
|
|
30071
|
+
*/
|
|
30072
|
+
async getPartnerFee(query, config) {
|
|
30073
|
+
const queryParams = new URLSearchParams({ amount: query.amount });
|
|
30074
|
+
return this.request(
|
|
30075
|
+
`/swaps/fees/partner?${queryParams.toString()}`,
|
|
30076
|
+
{ method: "GET" },
|
|
30077
|
+
FeeResponseSchema,
|
|
30078
|
+
config
|
|
30079
|
+
);
|
|
30080
|
+
}
|
|
30081
|
+
/**
|
|
30082
|
+
* Compute the protocol (solver) fee for a given input amount.
|
|
30083
|
+
*
|
|
30084
|
+
* @returns `Result<FeeResponseV2>` — `{ fee }` (decimal string).
|
|
30085
|
+
*/
|
|
30086
|
+
async getSolverFee(query, config) {
|
|
30087
|
+
const queryParams = new URLSearchParams({ amount: query.amount });
|
|
30088
|
+
return this.request(
|
|
30089
|
+
`/swaps/fees/solver?${queryParams.toString()}`,
|
|
30090
|
+
{ method: "GET" },
|
|
30091
|
+
FeeResponseSchema,
|
|
30092
|
+
config
|
|
30093
|
+
);
|
|
30094
|
+
}
|
|
30095
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30096
|
+
// Submit-tx state machine
|
|
30097
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30098
|
+
/**
|
|
30099
|
+
* Submit a swap transaction to be processed (relay, post-execution, etc.). The
|
|
30100
|
+
* `intent` field carries `bigint` numerics — {@link toJsonBody} serializes them.
|
|
30101
|
+
* Idempotent on `(txHash, srcChainKey)`.
|
|
30102
|
+
*
|
|
30103
|
+
* @returns `Result<SubmitTxResponseV2>` — `{ success, data: { status, message } }`.
|
|
30104
|
+
*/
|
|
30105
|
+
async submitTx(body, config) {
|
|
30106
|
+
return this.request(
|
|
30107
|
+
"/swaps/submit-tx",
|
|
30108
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30109
|
+
SubmitTxResponseSchema,
|
|
30110
|
+
config
|
|
30111
|
+
);
|
|
30112
|
+
}
|
|
30113
|
+
/**
|
|
30114
|
+
* Get the processing status of a submitted swap transaction by `(txHash, srcChainKey)`.
|
|
30115
|
+
*
|
|
30116
|
+
* @returns `Result<SubmitTxStatusResponseV2>` — `{ success, data }` (processing state).
|
|
30117
|
+
*/
|
|
30118
|
+
async getSubmitTxStatus(query, config) {
|
|
30119
|
+
const queryParams = new URLSearchParams({ txHash: query.txHash, srcChainKey: query.srcChainKey });
|
|
30120
|
+
return this.request(
|
|
30121
|
+
`/swaps/submit-tx/status?${queryParams.toString()}`,
|
|
30122
|
+
{ method: "GET" },
|
|
30123
|
+
SubmitTxStatusResponseSchema,
|
|
30124
|
+
config
|
|
30125
|
+
);
|
|
30126
|
+
}
|
|
30127
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30128
|
+
// Utilities (parity with BackendApiService)
|
|
30129
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30130
|
+
/**
|
|
30131
|
+
* Merge additional headers into the service's default header set. Existing
|
|
30132
|
+
* keys are overwritten; keys absent from `headers` are preserved.
|
|
30133
|
+
*/
|
|
30134
|
+
setHeaders(headers) {
|
|
30135
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
30136
|
+
this.headers[key] = value;
|
|
30137
|
+
});
|
|
30138
|
+
}
|
|
30139
|
+
/** Return the base URL the service is currently pointing at. */
|
|
30140
|
+
getBaseURL() {
|
|
30141
|
+
return this.config.baseURL;
|
|
30142
|
+
}
|
|
30143
|
+
};
|
|
30144
|
+
|
|
30145
|
+
// src/backendApi/apiConfig.ts
|
|
30146
|
+
function isCustomApiConfig(config) {
|
|
30147
|
+
return "baseApiConfig" in config || "swapsApiConfig" in config;
|
|
30148
|
+
}
|
|
30149
|
+
function layerConfigs(...slices) {
|
|
30150
|
+
return slices.reduce(
|
|
30151
|
+
(acc, slice) => slice ? {
|
|
30152
|
+
baseURL: slice.baseURL ?? acc.baseURL,
|
|
30153
|
+
timeout: slice.timeout ?? acc.timeout,
|
|
30154
|
+
headers: { ...acc.headers, ...slice.headers }
|
|
30155
|
+
} : acc,
|
|
30156
|
+
{
|
|
30157
|
+
baseURL: DEFAULT_BACKEND_API_ENDPOINT,
|
|
30158
|
+
timeout: DEFAULT_BACKEND_API_TIMEOUT,
|
|
30159
|
+
headers: { ...DEFAULT_BACKEND_API_HEADERS }
|
|
29151
30160
|
}
|
|
30161
|
+
);
|
|
30162
|
+
}
|
|
30163
|
+
function resolveBaseApiConfig(config) {
|
|
30164
|
+
if (isCustomApiConfig(config)) {
|
|
30165
|
+
return layerConfigs(config.baseApiConfig);
|
|
30166
|
+
}
|
|
30167
|
+
return layerConfigs(config);
|
|
30168
|
+
}
|
|
30169
|
+
function resolveSwapsApiConfig(config) {
|
|
30170
|
+
if (isCustomApiConfig(config)) {
|
|
30171
|
+
return layerConfigs(config.baseApiConfig, config.swapsApiConfig);
|
|
30172
|
+
}
|
|
30173
|
+
return layerConfigs(config);
|
|
30174
|
+
}
|
|
30175
|
+
var ChainKeySchema = v4.custom((input) => typeof input === "string");
|
|
30176
|
+
var SpokeChainKeySchema = v4.custom((input) => typeof input === "string");
|
|
30177
|
+
var AddressSchema2 = v4.custom((input) => typeof input === "string");
|
|
30178
|
+
var XTokenSchema = v4.object({
|
|
30179
|
+
symbol: v4.string(),
|
|
30180
|
+
name: v4.string(),
|
|
30181
|
+
decimals: v4.number(),
|
|
30182
|
+
address: v4.string(),
|
|
30183
|
+
chainKey: ChainKeySchema,
|
|
30184
|
+
hubAsset: AddressSchema2,
|
|
30185
|
+
vault: AddressSchema2,
|
|
30186
|
+
access: v4.optional(v4.picklist(["withdrawOnly", "depositOnly"]))
|
|
30187
|
+
});
|
|
30188
|
+
var IntentStructSchema = v4.object({
|
|
30189
|
+
intentId: v4.string(),
|
|
30190
|
+
creator: v4.string(),
|
|
30191
|
+
inputToken: v4.string(),
|
|
30192
|
+
outputToken: v4.string(),
|
|
30193
|
+
inputAmount: v4.string(),
|
|
30194
|
+
minOutputAmount: v4.string(),
|
|
30195
|
+
deadline: v4.string(),
|
|
30196
|
+
allowPartialFill: v4.boolean(),
|
|
30197
|
+
srcChain: v4.number(),
|
|
30198
|
+
dstChain: v4.number(),
|
|
30199
|
+
srcAddress: v4.string(),
|
|
30200
|
+
dstAddress: v4.string(),
|
|
30201
|
+
solver: v4.string(),
|
|
30202
|
+
data: v4.string()
|
|
30203
|
+
});
|
|
30204
|
+
var IntentResponseSchema2 = v4.object({
|
|
30205
|
+
intentHash: v4.string(),
|
|
30206
|
+
txHash: v4.string(),
|
|
30207
|
+
logIndex: v4.number(),
|
|
30208
|
+
chainId: v4.number(),
|
|
30209
|
+
blockNumber: v4.number(),
|
|
30210
|
+
open: v4.boolean(),
|
|
30211
|
+
intent: IntentStructSchema,
|
|
30212
|
+
events: v4.array(v4.unknown())
|
|
30213
|
+
});
|
|
30214
|
+
var UserIntentsResponseSchema = v4.object({
|
|
30215
|
+
total: v4.number(),
|
|
30216
|
+
offset: v4.number(),
|
|
30217
|
+
limit: v4.number(),
|
|
30218
|
+
items: v4.array(IntentResponseSchema2)
|
|
30219
|
+
});
|
|
30220
|
+
var OrderbookResponseSchema = v4.object({
|
|
30221
|
+
total: v4.number(),
|
|
30222
|
+
data: v4.array(
|
|
30223
|
+
v4.object({
|
|
30224
|
+
intentState: v4.object({
|
|
30225
|
+
exists: v4.boolean(),
|
|
30226
|
+
remainingInput: v4.string(),
|
|
30227
|
+
receivedOutput: v4.string(),
|
|
30228
|
+
pendingPayment: v4.boolean()
|
|
30229
|
+
}),
|
|
30230
|
+
intentData: v4.object({
|
|
30231
|
+
intentId: v4.string(),
|
|
30232
|
+
creator: v4.string(),
|
|
30233
|
+
inputToken: v4.string(),
|
|
30234
|
+
outputToken: v4.string(),
|
|
30235
|
+
inputAmount: v4.string(),
|
|
30236
|
+
minOutputAmount: v4.string(),
|
|
30237
|
+
deadline: v4.string(),
|
|
30238
|
+
allowPartialFill: v4.boolean(),
|
|
30239
|
+
srcChain: v4.number(),
|
|
30240
|
+
dstChain: v4.number(),
|
|
30241
|
+
srcAddress: v4.string(),
|
|
30242
|
+
dstAddress: v4.string(),
|
|
30243
|
+
solver: v4.string(),
|
|
30244
|
+
data: v4.string(),
|
|
30245
|
+
intentHash: v4.string(),
|
|
30246
|
+
txHash: v4.string(),
|
|
30247
|
+
blockNumber: v4.number()
|
|
30248
|
+
})
|
|
30249
|
+
})
|
|
30250
|
+
)
|
|
30251
|
+
});
|
|
30252
|
+
var MoneyMarketPositionSchema = v4.object({
|
|
30253
|
+
userAddress: v4.string(),
|
|
30254
|
+
positions: v4.array(
|
|
30255
|
+
v4.object({
|
|
30256
|
+
reserveAddress: v4.string(),
|
|
30257
|
+
aTokenAddress: v4.string(),
|
|
30258
|
+
variableDebtTokenAddress: v4.string(),
|
|
30259
|
+
aTokenBalance: v4.string(),
|
|
30260
|
+
variableDebtTokenBalance: v4.string(),
|
|
30261
|
+
blockNumber: v4.number()
|
|
30262
|
+
})
|
|
30263
|
+
)
|
|
30264
|
+
});
|
|
30265
|
+
var MoneyMarketAssetSchema = v4.object({
|
|
30266
|
+
reserveAddress: v4.string(),
|
|
30267
|
+
aTokenAddress: v4.string(),
|
|
30268
|
+
totalATokenBalance: v4.string(),
|
|
30269
|
+
variableDebtTokenAddress: v4.string(),
|
|
30270
|
+
totalVariableDebtTokenBalance: v4.string(),
|
|
30271
|
+
liquidityRate: v4.string(),
|
|
30272
|
+
symbol: v4.string(),
|
|
30273
|
+
totalSuppliers: v4.number(),
|
|
30274
|
+
totalBorrowers: v4.number(),
|
|
30275
|
+
variableBorrowRate: v4.string(),
|
|
30276
|
+
stableBorrowRate: v4.string(),
|
|
30277
|
+
liquidityIndex: v4.string(),
|
|
30278
|
+
variableBorrowIndex: v4.string(),
|
|
30279
|
+
blockNumber: v4.number()
|
|
30280
|
+
});
|
|
30281
|
+
var MoneyMarketAssetsSchema = v4.array(MoneyMarketAssetSchema);
|
|
30282
|
+
var MoneyMarketAssetBorrowersSchema = v4.object({
|
|
30283
|
+
borrowers: v4.array(v4.string()),
|
|
30284
|
+
total: v4.number(),
|
|
30285
|
+
offset: v4.number(),
|
|
30286
|
+
limit: v4.number()
|
|
30287
|
+
});
|
|
30288
|
+
var MoneyMarketAssetSuppliersSchema = v4.object({
|
|
30289
|
+
suppliers: v4.array(v4.string()),
|
|
30290
|
+
total: v4.number(),
|
|
30291
|
+
offset: v4.number(),
|
|
30292
|
+
limit: v4.number()
|
|
30293
|
+
});
|
|
30294
|
+
var MoneyMarketBorrowersSchema = v4.object({
|
|
30295
|
+
borrowers: v4.array(v4.string()),
|
|
30296
|
+
total: v4.number(),
|
|
30297
|
+
offset: v4.number(),
|
|
30298
|
+
limit: v4.number()
|
|
30299
|
+
});
|
|
30300
|
+
var GetChainsResponseSchema = v4.array(SpokeChainKeySchema);
|
|
30301
|
+
var TokensByChainMapSchema = v4.custom(
|
|
30302
|
+
(input) => typeof input === "object" && input !== null && Object.values(input).every((tokens) => Array.isArray(tokens) && tokens.every((t) => v4.is(XTokenSchema, t)))
|
|
30303
|
+
);
|
|
30304
|
+
var TokensListSchema = v4.array(XTokenSchema);
|
|
30305
|
+
var ReserveAssetsSchema = v4.array(AddressSchema2);
|
|
30306
|
+
|
|
30307
|
+
// src/backendApi/BackendApiService.ts
|
|
30308
|
+
var BackendApiService = class {
|
|
30309
|
+
// sub-services exposing domain-specific APIs
|
|
30310
|
+
swaps;
|
|
30311
|
+
// resolved base-API slice of the ApiConfig union (flat config, or its `baseApiConfig`)
|
|
30312
|
+
config;
|
|
30313
|
+
headers;
|
|
30314
|
+
logger;
|
|
30315
|
+
constructor(config, logger = consoleLogger) {
|
|
30316
|
+
this.config = resolveBaseApiConfig(config);
|
|
30317
|
+
this.headers = { ...this.config.headers };
|
|
30318
|
+
this.logger = logger;
|
|
30319
|
+
this.swaps = new SwapsApiService(resolveSwapsApiConfig(config), this.logger);
|
|
29152
30320
|
}
|
|
29153
30321
|
/**
|
|
29154
30322
|
* Wraps {@link makeRequest} in a `Result<T>` so all errors are captured rather
|
|
29155
30323
|
* than propagated as thrown exceptions. Every public endpoint method delegates
|
|
29156
30324
|
* here instead of calling `makeRequest` directly.
|
|
29157
30325
|
*/
|
|
29158
|
-
|
|
30326
|
+
/**
|
|
30327
|
+
* Fold any per-call override (carried on `config` alongside `method`/`body`) over the service
|
|
30328
|
+
* defaults: baseURL truthy-fallback (an empty-string override defers to the default), timeout
|
|
30329
|
+
* nullish-fallback, headers merged (override wins per key). Mirrors the original makeRequest merge.
|
|
30330
|
+
*/
|
|
30331
|
+
resolveRequestConfig(config) {
|
|
30332
|
+
const { baseURL, timeout, headers, ...rest } = config;
|
|
30333
|
+
return {
|
|
30334
|
+
...rest,
|
|
30335
|
+
baseURL: baseURL || this.config.baseURL,
|
|
30336
|
+
timeout: timeout ?? this.config.timeout,
|
|
30337
|
+
headers: { ...this.headers, ...headers }
|
|
30338
|
+
};
|
|
30339
|
+
}
|
|
30340
|
+
/**
|
|
30341
|
+
* Wrap a thrown transport failure (HTTP_REQUEST_FAILED / REQUEST_TIMEOUT / network error) as the
|
|
30342
|
+
* canonical backend `SodaxError` — identical shape to SwapsApiService; the underlying failure is
|
|
30343
|
+
* preserved on `error.cause`.
|
|
30344
|
+
*/
|
|
30345
|
+
toExternalApiError(endpoint, error) {
|
|
30346
|
+
return new SodaxError(
|
|
30347
|
+
"EXTERNAL_API_ERROR",
|
|
30348
|
+
error instanceof Error ? error.message : `Backend API request to ${endpoint} failed`,
|
|
30349
|
+
{ feature: "backend", cause: error, context: { api: "backend", endpoint } }
|
|
30350
|
+
);
|
|
30351
|
+
}
|
|
30352
|
+
/**
|
|
30353
|
+
* Issue a request and validate the JSON body against `schema`, wrapping the result in `Result<T>`.
|
|
30354
|
+
* Mirrors {@link SwapsApiService}: a 2xx body that fails the schema is surfaced as
|
|
30355
|
+
* `EXTERNAL_API_ERROR` (`context.reason: 'invalid_response_shape'`) rather than returned untyped.
|
|
30356
|
+
* Every data/token/money-market method delegates here; the config/relay reads use
|
|
30357
|
+
* {@link requestUnvalidated} instead.
|
|
30358
|
+
*/
|
|
30359
|
+
async request(endpoint, config, schema) {
|
|
30360
|
+
try {
|
|
30361
|
+
const raw = await makeRequest({
|
|
30362
|
+
endpoint,
|
|
30363
|
+
config: this.resolveRequestConfig(config),
|
|
30364
|
+
logger: this.logger,
|
|
30365
|
+
serviceLabel: "BackendApiService"
|
|
30366
|
+
});
|
|
30367
|
+
const parsed = v4.safeParse(schema, raw);
|
|
30368
|
+
if (!parsed.success) {
|
|
30369
|
+
return {
|
|
30370
|
+
ok: false,
|
|
30371
|
+
error: new SodaxError("EXTERNAL_API_ERROR", `Invalid response shape from backend API for ${endpoint}`, {
|
|
30372
|
+
feature: "backend",
|
|
30373
|
+
context: { api: "backend", endpoint, reason: "invalid_response_shape", issues: v4.flatten(parsed.issues) }
|
|
30374
|
+
})
|
|
30375
|
+
};
|
|
30376
|
+
}
|
|
30377
|
+
return { ok: true, value: parsed.output };
|
|
30378
|
+
} catch (error) {
|
|
30379
|
+
return { ok: false, error: this.toExternalApiError(endpoint, error) };
|
|
30380
|
+
}
|
|
30381
|
+
}
|
|
30382
|
+
/**
|
|
30383
|
+
* Issue a request WITHOUT response-shape validation (passthrough typing). Reserved for the
|
|
30384
|
+
* config/relay reads whose shapes are too large/brittle to schema-validate (`SodaxConfig` via
|
|
30385
|
+
* `getAllConfig`, `SpokeChainConfigMap` via `getSpokeChainConfig`) or carry `bigint` values that
|
|
30386
|
+
* cannot survive JSON validation (`getRelayChainIdMap`). `ConfigService` version-gates and falls
|
|
30387
|
+
* back to packaged defaults, so it relies on no response-shape guarantee from these endpoints.
|
|
30388
|
+
*/
|
|
30389
|
+
async requestUnvalidated(endpoint, config) {
|
|
29159
30390
|
try {
|
|
29160
|
-
const value = await
|
|
30391
|
+
const value = await makeRequest({
|
|
30392
|
+
endpoint,
|
|
30393
|
+
config: this.resolveRequestConfig(config),
|
|
30394
|
+
logger: this.logger,
|
|
30395
|
+
serviceLabel: "BackendApiService"
|
|
30396
|
+
});
|
|
29161
30397
|
return { ok: true, value };
|
|
29162
30398
|
} catch (error) {
|
|
29163
|
-
return { ok: false, error };
|
|
30399
|
+
return { ok: false, error: this.toExternalApiError(endpoint, error) };
|
|
29164
30400
|
}
|
|
29165
30401
|
}
|
|
29166
30402
|
// Intent endpoints
|
|
@@ -29175,7 +30411,7 @@ var BackendApiService = class {
|
|
|
29175
30411
|
* open/closed state, token amounts, and any fill events.
|
|
29176
30412
|
*/
|
|
29177
30413
|
async getIntentByTxHash(txHash, config) {
|
|
29178
|
-
return this.request(`/intent/tx/${txHash}`, { ...config, method: "GET" });
|
|
30414
|
+
return this.request(`/intent/tx/${txHash}`, { ...config, method: "GET" }, IntentResponseSchema2);
|
|
29179
30415
|
}
|
|
29180
30416
|
/**
|
|
29181
30417
|
* Fetch a swap intent by its canonical intent hash.
|
|
@@ -29184,58 +30420,7 @@ var BackendApiService = class {
|
|
|
29184
30420
|
* @returns `Result<IntentResponse>` — on success, the full intent details.
|
|
29185
30421
|
*/
|
|
29186
30422
|
async getIntentByHash(intentHash, config) {
|
|
29187
|
-
return this.request(`/intent/${intentHash}`, { ...config, method: "GET" });
|
|
29188
|
-
}
|
|
29189
|
-
// Swap submit-tx endpoints
|
|
29190
|
-
/**
|
|
29191
|
-
* Submit a signed spoke-chain swap transaction to the backend for processing.
|
|
29192
|
-
*
|
|
29193
|
-
* The backend relays the transaction to the hub chain, posts execution data
|
|
29194
|
-
* to the solver, and advances the intent through its lifecycle. The response
|
|
29195
|
-
* shape is validated at runtime via a type guard; an invalid shape is
|
|
29196
|
-
* returned as `{ ok: false }`.
|
|
29197
|
-
*
|
|
29198
|
-
* @param params - The signed transaction hash, source chain key, sender wallet
|
|
29199
|
-
* address, intent data, and relay data required to process the swap.
|
|
29200
|
-
* @returns `Result<SubmitSwapTxResponse>` — on success, a confirmation object
|
|
29201
|
-
* with `success: true` and a human-readable `message`.
|
|
29202
|
-
*/
|
|
29203
|
-
async submitSwapTx(params, config) {
|
|
29204
|
-
const result = await this.request("/swaps/submit-tx", {
|
|
29205
|
-
...config,
|
|
29206
|
-
method: "POST",
|
|
29207
|
-
body: JSON.stringify(params)
|
|
29208
|
-
});
|
|
29209
|
-
if (!result.ok) return result;
|
|
29210
|
-
if (!isSubmitSwapTxResponse(result.value)) {
|
|
29211
|
-
return { ok: false, error: new Error("Invalid submitSwapTx response: unexpected response shape") };
|
|
29212
|
-
}
|
|
29213
|
-
return { ok: true, value: result.value };
|
|
29214
|
-
}
|
|
29215
|
-
/**
|
|
29216
|
-
* Poll the backend relay pipeline for the current status of a previously
|
|
29217
|
-
* submitted swap transaction.
|
|
29218
|
-
*
|
|
29219
|
-
* Status progresses through: `pending` → `verifying` → `verified` →
|
|
29220
|
-
* `relaying` → `relayed` → `posting_execution` → `executed` (or `failed`).
|
|
29221
|
-
*
|
|
29222
|
-
* @param params - Object containing the source-chain transaction hash and,
|
|
29223
|
-
* optionally, the source chain key to disambiguate cross-chain hashes.
|
|
29224
|
-
* @returns `Result<SubmitSwapTxStatusResponse>` — on success, includes the
|
|
29225
|
-
* current `status`, any `failureReason`, and (once executed) the
|
|
29226
|
-
* `dstIntentTxHash` on the hub chain.
|
|
29227
|
-
*/
|
|
29228
|
-
async getSubmitSwapTxStatus(params, config) {
|
|
29229
|
-
const queryParams = new URLSearchParams();
|
|
29230
|
-
queryParams.append("txHash", params.txHash);
|
|
29231
|
-
if (params.srcChainKey) queryParams.append("srcChainKey", params.srcChainKey);
|
|
29232
|
-
const endpoint = `/swaps/submit-tx/status?${queryParams.toString()}`;
|
|
29233
|
-
const result = await this.request(endpoint, { ...config, method: "GET" });
|
|
29234
|
-
if (!result.ok) return result;
|
|
29235
|
-
if (!isSubmitSwapTxStatusResponse(result.value)) {
|
|
29236
|
-
return { ok: false, error: new Error("Invalid submitSwapTxStatus response: unexpected response shape") };
|
|
29237
|
-
}
|
|
29238
|
-
return { ok: true, value: result.value };
|
|
30423
|
+
return this.request(`/intent/${intentHash}`, { ...config, method: "GET" }, IntentResponseSchema2);
|
|
29239
30424
|
}
|
|
29240
30425
|
// Solver endpoints
|
|
29241
30426
|
/**
|
|
@@ -29252,7 +30437,7 @@ var BackendApiService = class {
|
|
|
29252
30437
|
queryParams.append("limit", params.limit);
|
|
29253
30438
|
const queryString = queryParams.toString();
|
|
29254
30439
|
const endpoint = `/solver/orderbook?${queryString}`;
|
|
29255
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30440
|
+
return this.request(endpoint, { ...config, method: "GET" }, OrderbookResponseSchema);
|
|
29256
30441
|
}
|
|
29257
30442
|
/**
|
|
29258
30443
|
* Fetch all swap intents created by a specific wallet address, with optional
|
|
@@ -29278,7 +30463,7 @@ var BackendApiService = class {
|
|
|
29278
30463
|
if (offset) queryParams.append("offset", offset);
|
|
29279
30464
|
const queryString = queryParams.toString();
|
|
29280
30465
|
const endpoint = queryString.length > 0 ? `/intent/user/${userAddress}?${queryString}` : `/intent/user/${userAddress}`;
|
|
29281
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30466
|
+
return this.request(endpoint, { ...config, method: "GET" }, UserIntentsResponseSchema);
|
|
29282
30467
|
}
|
|
29283
30468
|
// Money Market endpoints
|
|
29284
30469
|
/**
|
|
@@ -29293,7 +30478,11 @@ var BackendApiService = class {
|
|
|
29293
30478
|
* position across all active reserves.
|
|
29294
30479
|
*/
|
|
29295
30480
|
async getMoneyMarketPosition(userAddress, config) {
|
|
29296
|
-
return this.request(
|
|
30481
|
+
return this.request(
|
|
30482
|
+
`/moneymarket/position/${userAddress}`,
|
|
30483
|
+
{ ...config, method: "GET" },
|
|
30484
|
+
MoneyMarketPositionSchema
|
|
30485
|
+
);
|
|
29297
30486
|
}
|
|
29298
30487
|
/**
|
|
29299
30488
|
* Fetch the on-chain state for every active money market reserve asset.
|
|
@@ -29302,7 +30491,7 @@ var BackendApiService = class {
|
|
|
29302
30491
|
* snapshots including interest rates, liquidity indices, and participant counts.
|
|
29303
30492
|
*/
|
|
29304
30493
|
async getAllMoneyMarketAssets(config) {
|
|
29305
|
-
return this.request("/moneymarket/asset/all", { ...config, method: "GET" });
|
|
30494
|
+
return this.request("/moneymarket/asset/all", { ...config, method: "GET" }, MoneyMarketAssetsSchema);
|
|
29306
30495
|
}
|
|
29307
30496
|
/**
|
|
29308
30497
|
* Fetch the on-chain state for a single money market reserve asset.
|
|
@@ -29312,7 +30501,11 @@ var BackendApiService = class {
|
|
|
29312
30501
|
* including interest rates, total balances, and liquidity indices.
|
|
29313
30502
|
*/
|
|
29314
30503
|
async getMoneyMarketAsset(reserveAddress, config) {
|
|
29315
|
-
return this.request(
|
|
30504
|
+
return this.request(
|
|
30505
|
+
`/moneymarket/asset/${reserveAddress}`,
|
|
30506
|
+
{ ...config, method: "GET" },
|
|
30507
|
+
MoneyMarketAssetSchema
|
|
30508
|
+
);
|
|
29316
30509
|
}
|
|
29317
30510
|
/**
|
|
29318
30511
|
* Fetch a paginated list of wallets that currently have an outstanding borrow
|
|
@@ -29329,7 +30522,7 @@ var BackendApiService = class {
|
|
|
29329
30522
|
queryParams.append("limit", params.limit);
|
|
29330
30523
|
const queryString = queryParams.toString();
|
|
29331
30524
|
const endpoint = `/moneymarket/asset/${reserveAddress}/borrowers?${queryString}`;
|
|
29332
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30525
|
+
return this.request(endpoint, { ...config, method: "GET" }, MoneyMarketAssetBorrowersSchema);
|
|
29333
30526
|
}
|
|
29334
30527
|
/**
|
|
29335
30528
|
* Fetch a paginated list of wallets that currently have an active supply
|
|
@@ -29346,7 +30539,7 @@ var BackendApiService = class {
|
|
|
29346
30539
|
queryParams.append("limit", params.limit);
|
|
29347
30540
|
const queryString = queryParams.toString();
|
|
29348
30541
|
const endpoint = `/moneymarket/asset/${reserveAddress}/suppliers?${queryString}`;
|
|
29349
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30542
|
+
return this.request(endpoint, { ...config, method: "GET" }, MoneyMarketAssetSuppliersSchema);
|
|
29350
30543
|
}
|
|
29351
30544
|
/**
|
|
29352
30545
|
* Fetch a paginated list of all wallet addresses that hold an active borrow
|
|
@@ -29362,7 +30555,7 @@ var BackendApiService = class {
|
|
|
29362
30555
|
queryParams.append("limit", params.limit);
|
|
29363
30556
|
const queryString = queryParams.toString();
|
|
29364
30557
|
const endpoint = `/moneymarket/borrowers?${queryString}`;
|
|
29365
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30558
|
+
return this.request(endpoint, { ...config, method: "GET" }, MoneyMarketBorrowersSchema);
|
|
29366
30559
|
}
|
|
29367
30560
|
/**
|
|
29368
30561
|
* Fetch the complete SODAX runtime configuration in a single request.
|
|
@@ -29375,7 +30568,7 @@ var BackendApiService = class {
|
|
|
29375
30568
|
* `config` is the current `SodaxConfig` used by all SDK services.
|
|
29376
30569
|
*/
|
|
29377
30570
|
async getAllConfig(config) {
|
|
29378
|
-
return this.
|
|
30571
|
+
return this.requestUnvalidated("/config/all", { ...config, method: "GET" });
|
|
29379
30572
|
}
|
|
29380
30573
|
/**
|
|
29381
30574
|
* Fetch the list of spoke chain keys that are currently supported by the
|
|
@@ -29388,7 +30581,7 @@ var BackendApiService = class {
|
|
|
29388
30581
|
* `SpokeChainKey` strings (e.g. `["ethereum", "arbitrum", "solana", …]`).
|
|
29389
30582
|
*/
|
|
29390
30583
|
async getChains(config) {
|
|
29391
|
-
return this.request("/config/spoke/chains", { ...config, method: "GET" });
|
|
30584
|
+
return this.request("/config/spoke/chains", { ...config, method: "GET" }, GetChainsResponseSchema);
|
|
29392
30585
|
}
|
|
29393
30586
|
/**
|
|
29394
30587
|
* Fetch the full map of tokens available for swapping, keyed by spoke chain.
|
|
@@ -29400,7 +30593,7 @@ var BackendApiService = class {
|
|
|
29400
30593
|
* supported spoke chain key to its list of swappable `XToken` definitions.
|
|
29401
30594
|
*/
|
|
29402
30595
|
async getSwapTokens(config) {
|
|
29403
|
-
return this.request("/config/swap/tokens", { ...config, method: "GET" });
|
|
30596
|
+
return this.request("/config/swap/tokens", { ...config, method: "GET" }, TokensByChainMapSchema);
|
|
29404
30597
|
}
|
|
29405
30598
|
/**
|
|
29406
30599
|
* Fetch the list of tokens available for swapping on a specific spoke chain.
|
|
@@ -29412,10 +30605,7 @@ var BackendApiService = class {
|
|
|
29412
30605
|
* array of `XToken` definitions supported for swapping on that chain.
|
|
29413
30606
|
*/
|
|
29414
30607
|
async getSwapTokensByChainId(chainId, config) {
|
|
29415
|
-
return this.request(`/config/swap/${chainId}/tokens`, {
|
|
29416
|
-
...config,
|
|
29417
|
-
method: "GET"
|
|
29418
|
-
});
|
|
30608
|
+
return this.request(`/config/swap/${chainId}/tokens`, { ...config, method: "GET" }, TokensListSchema);
|
|
29419
30609
|
}
|
|
29420
30610
|
/**
|
|
29421
30611
|
* Fetch the full map of tokens available in the money market (lending/borrowing),
|
|
@@ -29427,10 +30617,7 @@ var BackendApiService = class {
|
|
|
29427
30617
|
* each supported spoke chain key to its list of money-market `XToken` definitions.
|
|
29428
30618
|
*/
|
|
29429
30619
|
async getMoneyMarketTokens(config) {
|
|
29430
|
-
return this.request("/config/money-market/tokens", {
|
|
29431
|
-
...config,
|
|
29432
|
-
method: "GET"
|
|
29433
|
-
});
|
|
30620
|
+
return this.request("/config/money-market/tokens", { ...config, method: "GET" }, TokensByChainMapSchema);
|
|
29434
30621
|
}
|
|
29435
30622
|
/**
|
|
29436
30623
|
* Fetch the list of hub-chain reserve asset addresses registered in the
|
|
@@ -29444,10 +30631,11 @@ var BackendApiService = class {
|
|
|
29444
30631
|
* readonly array of reserve `Address` strings.
|
|
29445
30632
|
*/
|
|
29446
30633
|
async getMoneyMarketReserveAssets(config) {
|
|
29447
|
-
return this.request(
|
|
29448
|
-
|
|
29449
|
-
method: "GET"
|
|
29450
|
-
|
|
30634
|
+
return this.request(
|
|
30635
|
+
"/config/money-market/reserve-assets",
|
|
30636
|
+
{ ...config, method: "GET" },
|
|
30637
|
+
ReserveAssetsSchema
|
|
30638
|
+
);
|
|
29451
30639
|
}
|
|
29452
30640
|
/**
|
|
29453
30641
|
* Fetch the list of tokens available for lending/borrowing on a specific
|
|
@@ -29460,10 +30648,11 @@ var BackendApiService = class {
|
|
|
29460
30648
|
* readonly array of `XToken` definitions supported in the money market on that chain.
|
|
29461
30649
|
*/
|
|
29462
30650
|
async getMoneyMarketTokensByChainId(chainId, config) {
|
|
29463
|
-
return this.request(
|
|
29464
|
-
|
|
29465
|
-
method: "GET"
|
|
29466
|
-
|
|
30651
|
+
return this.request(
|
|
30652
|
+
`/config/money-market/${chainId}/tokens`,
|
|
30653
|
+
{ ...config, method: "GET" },
|
|
30654
|
+
TokensListSchema
|
|
30655
|
+
);
|
|
29467
30656
|
}
|
|
29468
30657
|
/**
|
|
29469
30658
|
* Fetch the mapping from spoke chain keys to the numeric chain IDs used by
|
|
@@ -29477,7 +30666,7 @@ var BackendApiService = class {
|
|
|
29477
30666
|
* `IntentRelayChainIdMap` record mapping each spoke chain key to its relay chain ID.
|
|
29478
30667
|
*/
|
|
29479
30668
|
async getRelayChainIdMap(config) {
|
|
29480
|
-
return this.
|
|
30669
|
+
return this.requestUnvalidated("/config/relay/chain-id-map", {
|
|
29481
30670
|
...config,
|
|
29482
30671
|
method: "GET"
|
|
29483
30672
|
});
|
|
@@ -29494,7 +30683,7 @@ var BackendApiService = class {
|
|
|
29494
30683
|
* `SpokeChainConfigMap` for all currently enabled spoke chains.
|
|
29495
30684
|
*/
|
|
29496
30685
|
async getSpokeChainConfig(config) {
|
|
29497
|
-
return this.
|
|
30686
|
+
return this.requestUnvalidated("/config/spoke/all-chains-configs", {
|
|
29498
30687
|
...config,
|
|
29499
30688
|
method: "GET"
|
|
29500
30689
|
});
|
|
@@ -29506,12 +30695,17 @@ var BackendApiService = class {
|
|
|
29506
30695
|
* without constructing a new service instance. Existing header keys are
|
|
29507
30696
|
* overwritten; keys absent from `headers` are preserved.
|
|
29508
30697
|
*
|
|
30698
|
+
* The headers are also fanned out to the sub-services (`swaps`), which hold
|
|
30699
|
+
* their own header copies — so a token set here applies to every request made
|
|
30700
|
+
* through this client, including `swaps.*`.
|
|
30701
|
+
*
|
|
29509
30702
|
* @param headers - Key-value pairs to add or overwrite in the default headers.
|
|
29510
30703
|
*/
|
|
29511
30704
|
setHeaders(headers) {
|
|
29512
30705
|
Object.entries(headers).forEach(([key, value]) => {
|
|
29513
30706
|
this.headers[key] = value;
|
|
29514
30707
|
});
|
|
30708
|
+
this.swaps.setHeaders(headers);
|
|
29515
30709
|
}
|
|
29516
30710
|
/**
|
|
29517
30711
|
* Return the base URL the service is currently pointing at.
|
|
@@ -29759,49 +30953,71 @@ var BridgeService = class {
|
|
|
29759
30953
|
* }
|
|
29760
30954
|
*/
|
|
29761
30955
|
async bridge(_params) {
|
|
29762
|
-
|
|
29763
|
-
|
|
29764
|
-
|
|
29765
|
-
|
|
29766
|
-
|
|
29767
|
-
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
|
|
29773
|
-
|
|
29774
|
-
|
|
29775
|
-
|
|
30956
|
+
return this.config.analytics.trackResult(
|
|
30957
|
+
"bridge",
|
|
30958
|
+
"bridge",
|
|
30959
|
+
async () => {
|
|
30960
|
+
const { params, timeout } = _params;
|
|
30961
|
+
const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
|
|
30962
|
+
try {
|
|
30963
|
+
const txResult = await this.createBridgeIntent(_params);
|
|
30964
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
30965
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
30966
|
+
txHash: txResult.value.tx,
|
|
30967
|
+
chainKey: params.srcChainKey
|
|
30968
|
+
});
|
|
30969
|
+
if (!verifyTxHashResult.ok) {
|
|
30970
|
+
return {
|
|
30971
|
+
ok: false,
|
|
30972
|
+
error: verifyFailed("bridge", verifyTxHashResult.error, baseCtx)
|
|
30973
|
+
};
|
|
30974
|
+
}
|
|
30975
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
30976
|
+
srcTxHash: txResult.value.tx,
|
|
30977
|
+
data: txResult.value.relayData,
|
|
30978
|
+
chainKey: params.srcChainKey,
|
|
30979
|
+
relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
|
|
30980
|
+
timeout
|
|
30981
|
+
});
|
|
30982
|
+
if (!packetResult.ok)
|
|
30983
|
+
return {
|
|
30984
|
+
ok: false,
|
|
30985
|
+
error: mapRelayFailure(packetResult.error, {
|
|
30986
|
+
feature: "bridge",
|
|
30987
|
+
action: "bridge",
|
|
30988
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
30989
|
+
dstChainKey: baseCtx.dstChainKey
|
|
30990
|
+
})
|
|
30991
|
+
};
|
|
30992
|
+
return {
|
|
30993
|
+
ok: true,
|
|
30994
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packetResult.value.dst_tx_hash }
|
|
30995
|
+
};
|
|
30996
|
+
} catch (error) {
|
|
30997
|
+
if (isBridgeOrchestrationError(error)) return { ok: false, error };
|
|
30998
|
+
return {
|
|
30999
|
+
ok: false,
|
|
31000
|
+
error: executionFailed("bridge", error, baseCtx)
|
|
31001
|
+
};
|
|
31002
|
+
}
|
|
31003
|
+
},
|
|
31004
|
+
{
|
|
31005
|
+
start: () => ({
|
|
31006
|
+
srcChainKey: _params.params.srcChainKey,
|
|
31007
|
+
dstChainKey: _params.params.dstChainKey,
|
|
31008
|
+
srcToken: _params.params.srcToken,
|
|
31009
|
+
dstToken: _params.params.dstToken,
|
|
31010
|
+
amount: _params.params.amount,
|
|
31011
|
+
srcAddress: _params.params.srcAddress,
|
|
31012
|
+
recipient: _params.params.recipient
|
|
31013
|
+
}),
|
|
31014
|
+
success: (value) => ({
|
|
31015
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
31016
|
+
dstChainTxHash: value.dstChainTxHash
|
|
31017
|
+
}),
|
|
31018
|
+
failure: (error) => ({ code: error.code })
|
|
29776
31019
|
}
|
|
29777
|
-
|
|
29778
|
-
srcTxHash: txResult.value.tx,
|
|
29779
|
-
data: txResult.value.relayData,
|
|
29780
|
-
chainKey: params.srcChainKey,
|
|
29781
|
-
relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
|
|
29782
|
-
timeout
|
|
29783
|
-
});
|
|
29784
|
-
if (!packetResult.ok)
|
|
29785
|
-
return {
|
|
29786
|
-
ok: false,
|
|
29787
|
-
error: mapRelayFailure(packetResult.error, {
|
|
29788
|
-
feature: "bridge",
|
|
29789
|
-
action: "bridge",
|
|
29790
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
29791
|
-
dstChainKey: baseCtx.dstChainKey
|
|
29792
|
-
})
|
|
29793
|
-
};
|
|
29794
|
-
return {
|
|
29795
|
-
ok: true,
|
|
29796
|
-
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packetResult.value.dst_tx_hash }
|
|
29797
|
-
};
|
|
29798
|
-
} catch (error) {
|
|
29799
|
-
if (isBridgeOrchestrationError(error)) return { ok: false, error };
|
|
29800
|
-
return {
|
|
29801
|
-
ok: false,
|
|
29802
|
-
error: executionFailed("bridge", error, baseCtx)
|
|
29803
|
-
};
|
|
29804
|
-
}
|
|
31020
|
+
);
|
|
29805
31021
|
}
|
|
29806
31022
|
/**
|
|
29807
31023
|
* Submits the spoke-side deposit transaction that initiates a bridge transfer,
|
|
@@ -29830,8 +31046,8 @@ var BridgeService = class {
|
|
|
29830
31046
|
const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
|
|
29831
31047
|
try {
|
|
29832
31048
|
bridgeInvariant(params.amount > 0n, "Amount must be greater than 0", { ...baseCtx, field: "amount" });
|
|
29833
|
-
const srcToken = this.
|
|
29834
|
-
const dstToken = this.
|
|
31049
|
+
const srcToken = this.resolveBridgeEndpointToken(params.srcChainKey, params.srcToken);
|
|
31050
|
+
const dstToken = this.resolveBridgeEndpointToken(params.dstChainKey, params.dstToken);
|
|
29835
31051
|
bridgeInvariant(srcToken, `Unsupported spoke chain (${params.srcChainKey}) token: ${params.srcToken}`, {
|
|
29836
31052
|
...baseCtx,
|
|
29837
31053
|
field: "srcToken"
|
|
@@ -29899,6 +31115,20 @@ var BridgeService = class {
|
|
|
29899
31115
|
};
|
|
29900
31116
|
}
|
|
29901
31117
|
}
|
|
31118
|
+
/**
|
|
31119
|
+
* Resolves a bridge endpoint's {@link XToken} descriptor from a chain key + token address.
|
|
31120
|
+
*
|
|
31121
|
+
* Spoke endpoints (and hub-native tokens such as USDC/WETH/S whose on-chain address equals their
|
|
31122
|
+
* hub asset) resolve by original asset address. On the hub a caller may instead hold a hub asset
|
|
31123
|
+
* that has no spoke-token entry under the hub chain — e.g. a partner BTC fee held as the BTC hub
|
|
31124
|
+
* asset, whose only spoke-token entry lives on Bitcoin. Resolve those by hub-asset address so the
|
|
31125
|
+
* Sonic-sourced "withdraw directly" bridge can find the matching vault/decimals.
|
|
31126
|
+
*/
|
|
31127
|
+
resolveBridgeEndpointToken(chainKey, token) {
|
|
31128
|
+
const spokeToken = this.config.getSpokeTokenFromOriginalAssetAddress(chainKey, token);
|
|
31129
|
+
if (spokeToken) return spokeToken;
|
|
31130
|
+
return isHubChainKeyType(chainKey) ? this.config.getXTokenFromHubAsset(token) : void 0;
|
|
31131
|
+
}
|
|
29902
31132
|
/**
|
|
29903
31133
|
* Encodes the hub-side execution payload for a bridge operation.
|
|
29904
31134
|
*
|
|
@@ -30781,52 +32011,71 @@ var StakingService = class {
|
|
|
30781
32011
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
30782
32012
|
*/
|
|
30783
32013
|
async stake(_params) {
|
|
30784
|
-
|
|
30785
|
-
|
|
30786
|
-
|
|
30787
|
-
|
|
30788
|
-
|
|
30789
|
-
|
|
30790
|
-
|
|
30791
|
-
|
|
30792
|
-
|
|
30793
|
-
|
|
30794
|
-
|
|
30795
|
-
|
|
30796
|
-
|
|
30797
|
-
|
|
30798
|
-
|
|
30799
|
-
|
|
30800
|
-
|
|
30801
|
-
|
|
30802
|
-
|
|
30803
|
-
|
|
30804
|
-
|
|
30805
|
-
|
|
30806
|
-
|
|
30807
|
-
|
|
30808
|
-
|
|
32014
|
+
return this.config.analytics.trackResult(
|
|
32015
|
+
"staking",
|
|
32016
|
+
"stake",
|
|
32017
|
+
async () => {
|
|
32018
|
+
const { params, timeout } = _params;
|
|
32019
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "stake" };
|
|
32020
|
+
try {
|
|
32021
|
+
const txResult = await this.createStakeIntent(_params);
|
|
32022
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32023
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
32024
|
+
txHash: txResult.value.tx,
|
|
32025
|
+
chainKey: params.srcChainKey
|
|
32026
|
+
});
|
|
32027
|
+
if (!verifyTxHashResult.ok) {
|
|
32028
|
+
return {
|
|
32029
|
+
ok: false,
|
|
32030
|
+
error: verifyFailed("staking", verifyTxHashResult.error, baseCtx)
|
|
32031
|
+
};
|
|
32032
|
+
}
|
|
32033
|
+
let hubTxHash;
|
|
32034
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32035
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32036
|
+
srcTxHash: txResult.value.tx,
|
|
32037
|
+
data: txResult.value.relayData,
|
|
32038
|
+
chainKey: params.srcChainKey,
|
|
32039
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32040
|
+
timeout
|
|
32041
|
+
});
|
|
32042
|
+
if (!packetResult.ok) {
|
|
32043
|
+
return {
|
|
32044
|
+
ok: false,
|
|
32045
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32046
|
+
feature: "staking",
|
|
32047
|
+
action: baseCtx.action,
|
|
32048
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32049
|
+
})
|
|
32050
|
+
};
|
|
32051
|
+
}
|
|
32052
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32053
|
+
} else {
|
|
32054
|
+
hubTxHash = txResult.value.tx;
|
|
32055
|
+
}
|
|
32056
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32057
|
+
} catch (error) {
|
|
32058
|
+
if (isStakeOrchestrationError(error)) return { ok: false, error };
|
|
30809
32059
|
return {
|
|
30810
32060
|
ok: false,
|
|
30811
|
-
error:
|
|
30812
|
-
feature: "staking",
|
|
30813
|
-
action: baseCtx.action,
|
|
30814
|
-
srcChainKey: baseCtx.srcChainKey
|
|
30815
|
-
})
|
|
32061
|
+
error: executionFailed("staking", error, baseCtx)
|
|
30816
32062
|
};
|
|
30817
32063
|
}
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
|
|
32064
|
+
},
|
|
32065
|
+
{
|
|
32066
|
+
start: () => ({
|
|
32067
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32068
|
+
srcAddress: _params.params.srcAddress,
|
|
32069
|
+
amount: _params.params.amount,
|
|
32070
|
+
minReceive: _params.params.minReceive
|
|
32071
|
+
}),
|
|
32072
|
+
success: (value) => ({
|
|
32073
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32074
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32075
|
+
}),
|
|
32076
|
+
failure: (error) => ({ code: error.code })
|
|
30821
32077
|
}
|
|
30822
|
-
|
|
30823
|
-
} catch (error) {
|
|
30824
|
-
if (isStakeOrchestrationError(error)) return { ok: false, error };
|
|
30825
|
-
return {
|
|
30826
|
-
ok: false,
|
|
30827
|
-
error: executionFailed("staking", error, baseCtx)
|
|
30828
|
-
};
|
|
30829
|
-
}
|
|
32078
|
+
);
|
|
30830
32079
|
}
|
|
30831
32080
|
/**
|
|
30832
32081
|
* Submits the stake transaction on the spoke chain without relaying to the hub.
|
|
@@ -30931,42 +32180,60 @@ var StakingService = class {
|
|
|
30931
32180
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
30932
32181
|
*/
|
|
30933
32182
|
async unstake(_params) {
|
|
30934
|
-
|
|
30935
|
-
|
|
30936
|
-
|
|
30937
|
-
|
|
30938
|
-
|
|
30939
|
-
|
|
30940
|
-
|
|
30941
|
-
|
|
30942
|
-
|
|
30943
|
-
|
|
30944
|
-
|
|
30945
|
-
|
|
30946
|
-
|
|
30947
|
-
|
|
30948
|
-
|
|
32183
|
+
return this.config.analytics.trackResult(
|
|
32184
|
+
"staking",
|
|
32185
|
+
"unstake",
|
|
32186
|
+
async () => {
|
|
32187
|
+
const { params, timeout } = _params;
|
|
32188
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "unstake" };
|
|
32189
|
+
try {
|
|
32190
|
+
const txResult = await this.createUnstakeIntent(_params);
|
|
32191
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32192
|
+
let hubTxHash;
|
|
32193
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32194
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32195
|
+
srcTxHash: txResult.value.tx,
|
|
32196
|
+
data: txResult.value.relayData,
|
|
32197
|
+
chainKey: params.srcChainKey,
|
|
32198
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32199
|
+
timeout
|
|
32200
|
+
});
|
|
32201
|
+
if (!packetResult.ok) {
|
|
32202
|
+
return {
|
|
32203
|
+
ok: false,
|
|
32204
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32205
|
+
feature: "staking",
|
|
32206
|
+
action: baseCtx.action,
|
|
32207
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32208
|
+
})
|
|
32209
|
+
};
|
|
32210
|
+
}
|
|
32211
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32212
|
+
} else {
|
|
32213
|
+
hubTxHash = txResult.value.tx;
|
|
32214
|
+
}
|
|
32215
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32216
|
+
} catch (error) {
|
|
32217
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
30949
32218
|
return {
|
|
30950
32219
|
ok: false,
|
|
30951
|
-
error:
|
|
30952
|
-
feature: "staking",
|
|
30953
|
-
action: baseCtx.action,
|
|
30954
|
-
srcChainKey: baseCtx.srcChainKey
|
|
30955
|
-
})
|
|
32220
|
+
error: executionFailed("staking", error, baseCtx)
|
|
30956
32221
|
};
|
|
30957
32222
|
}
|
|
30958
|
-
|
|
30959
|
-
|
|
30960
|
-
|
|
32223
|
+
},
|
|
32224
|
+
{
|
|
32225
|
+
start: () => ({
|
|
32226
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32227
|
+
srcAddress: _params.params.srcAddress,
|
|
32228
|
+
amount: _params.params.amount
|
|
32229
|
+
}),
|
|
32230
|
+
success: (value) => ({
|
|
32231
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32232
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32233
|
+
}),
|
|
32234
|
+
failure: (error) => ({ code: error.code })
|
|
30961
32235
|
}
|
|
30962
|
-
|
|
30963
|
-
} catch (error) {
|
|
30964
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
30965
|
-
return {
|
|
30966
|
-
ok: false,
|
|
30967
|
-
error: executionFailed("staking", error, baseCtx)
|
|
30968
|
-
};
|
|
30969
|
-
}
|
|
32236
|
+
);
|
|
30970
32237
|
}
|
|
30971
32238
|
/**
|
|
30972
32239
|
* Submits the unstake transaction on the spoke chain without relaying to the hub.
|
|
@@ -31062,42 +32329,61 @@ var StakingService = class {
|
|
|
31062
32329
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
31063
32330
|
*/
|
|
31064
32331
|
async instantUnstake(_params) {
|
|
31065
|
-
|
|
31066
|
-
|
|
31067
|
-
|
|
31068
|
-
|
|
31069
|
-
|
|
31070
|
-
|
|
31071
|
-
|
|
31072
|
-
|
|
31073
|
-
|
|
31074
|
-
|
|
31075
|
-
|
|
31076
|
-
|
|
31077
|
-
|
|
31078
|
-
|
|
31079
|
-
|
|
32332
|
+
return this.config.analytics.trackResult(
|
|
32333
|
+
"staking",
|
|
32334
|
+
"instantUnstake",
|
|
32335
|
+
async () => {
|
|
32336
|
+
const { params, timeout } = _params;
|
|
32337
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "instantUnstake" };
|
|
32338
|
+
try {
|
|
32339
|
+
const txResult = await this.createInstantUnstakeIntent(_params);
|
|
32340
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32341
|
+
let hubTxHash;
|
|
32342
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32343
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32344
|
+
srcTxHash: txResult.value.tx,
|
|
32345
|
+
data: txResult.value.relayData,
|
|
32346
|
+
chainKey: params.srcChainKey,
|
|
32347
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32348
|
+
timeout
|
|
32349
|
+
});
|
|
32350
|
+
if (!packetResult.ok) {
|
|
32351
|
+
return {
|
|
32352
|
+
ok: false,
|
|
32353
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32354
|
+
feature: "staking",
|
|
32355
|
+
action: baseCtx.action,
|
|
32356
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32357
|
+
})
|
|
32358
|
+
};
|
|
32359
|
+
}
|
|
32360
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32361
|
+
} else {
|
|
32362
|
+
hubTxHash = txResult.value.tx;
|
|
32363
|
+
}
|
|
32364
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32365
|
+
} catch (error) {
|
|
32366
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31080
32367
|
return {
|
|
31081
32368
|
ok: false,
|
|
31082
|
-
error:
|
|
31083
|
-
feature: "staking",
|
|
31084
|
-
action: baseCtx.action,
|
|
31085
|
-
srcChainKey: baseCtx.srcChainKey
|
|
31086
|
-
})
|
|
32369
|
+
error: executionFailed("staking", error, baseCtx)
|
|
31087
32370
|
};
|
|
31088
32371
|
}
|
|
31089
|
-
|
|
31090
|
-
|
|
31091
|
-
|
|
32372
|
+
},
|
|
32373
|
+
{
|
|
32374
|
+
start: () => ({
|
|
32375
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32376
|
+
srcAddress: _params.params.srcAddress,
|
|
32377
|
+
amount: _params.params.amount,
|
|
32378
|
+
minAmount: _params.params.minAmount
|
|
32379
|
+
}),
|
|
32380
|
+
success: (value) => ({
|
|
32381
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32382
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32383
|
+
}),
|
|
32384
|
+
failure: (error) => ({ code: error.code })
|
|
31092
32385
|
}
|
|
31093
|
-
|
|
31094
|
-
} catch (error) {
|
|
31095
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31096
|
-
return {
|
|
31097
|
-
ok: false,
|
|
31098
|
-
error: executionFailed("staking", error, baseCtx)
|
|
31099
|
-
};
|
|
31100
|
-
}
|
|
32386
|
+
);
|
|
31101
32387
|
}
|
|
31102
32388
|
/**
|
|
31103
32389
|
* Submits the instant-unstake transaction on the spoke chain without relaying to the hub.
|
|
@@ -31205,42 +32491,61 @@ var StakingService = class {
|
|
|
31205
32491
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
31206
32492
|
*/
|
|
31207
32493
|
async claim(_params) {
|
|
31208
|
-
|
|
31209
|
-
|
|
31210
|
-
|
|
31211
|
-
|
|
31212
|
-
|
|
31213
|
-
|
|
31214
|
-
|
|
31215
|
-
|
|
31216
|
-
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
|
|
31222
|
-
|
|
32494
|
+
return this.config.analytics.trackResult(
|
|
32495
|
+
"staking",
|
|
32496
|
+
"claim",
|
|
32497
|
+
async () => {
|
|
32498
|
+
const { params, timeout } = _params;
|
|
32499
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "claim" };
|
|
32500
|
+
try {
|
|
32501
|
+
const txResult = await this.createClaimIntent(_params);
|
|
32502
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32503
|
+
let hubTxHash;
|
|
32504
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32505
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32506
|
+
srcTxHash: txResult.value.tx,
|
|
32507
|
+
data: txResult.value.relayData,
|
|
32508
|
+
chainKey: params.srcChainKey,
|
|
32509
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32510
|
+
timeout
|
|
32511
|
+
});
|
|
32512
|
+
if (!packetResult.ok) {
|
|
32513
|
+
return {
|
|
32514
|
+
ok: false,
|
|
32515
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32516
|
+
feature: "staking",
|
|
32517
|
+
action: baseCtx.action,
|
|
32518
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32519
|
+
})
|
|
32520
|
+
};
|
|
32521
|
+
}
|
|
32522
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32523
|
+
} else {
|
|
32524
|
+
hubTxHash = txResult.value.tx;
|
|
32525
|
+
}
|
|
32526
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32527
|
+
} catch (error) {
|
|
32528
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31223
32529
|
return {
|
|
31224
32530
|
ok: false,
|
|
31225
|
-
error:
|
|
31226
|
-
feature: "staking",
|
|
31227
|
-
action: baseCtx.action,
|
|
31228
|
-
srcChainKey: baseCtx.srcChainKey
|
|
31229
|
-
})
|
|
32531
|
+
error: executionFailed("staking", error, baseCtx)
|
|
31230
32532
|
};
|
|
31231
32533
|
}
|
|
31232
|
-
|
|
31233
|
-
|
|
31234
|
-
|
|
32534
|
+
},
|
|
32535
|
+
{
|
|
32536
|
+
start: () => ({
|
|
32537
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32538
|
+
srcAddress: _params.params.srcAddress,
|
|
32539
|
+
requestId: _params.params.requestId,
|
|
32540
|
+
amount: _params.params.amount
|
|
32541
|
+
}),
|
|
32542
|
+
success: (value) => ({
|
|
32543
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32544
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32545
|
+
}),
|
|
32546
|
+
failure: (error) => ({ code: error.code })
|
|
31235
32547
|
}
|
|
31236
|
-
|
|
31237
|
-
} catch (error) {
|
|
31238
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31239
|
-
return {
|
|
31240
|
-
ok: false,
|
|
31241
|
-
error: executionFailed("staking", error, baseCtx)
|
|
31242
|
-
};
|
|
31243
|
-
}
|
|
32548
|
+
);
|
|
31244
32549
|
}
|
|
31245
32550
|
/**
|
|
31246
32551
|
* Submits the claim transaction on the spoke chain without relaying to the hub.
|
|
@@ -31354,42 +32659,60 @@ var StakingService = class {
|
|
|
31354
32659
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
31355
32660
|
*/
|
|
31356
32661
|
async cancelUnstake(_params) {
|
|
31357
|
-
|
|
31358
|
-
|
|
31359
|
-
|
|
31360
|
-
|
|
31361
|
-
|
|
31362
|
-
|
|
31363
|
-
|
|
31364
|
-
|
|
31365
|
-
|
|
31366
|
-
|
|
31367
|
-
|
|
31368
|
-
|
|
31369
|
-
|
|
31370
|
-
|
|
31371
|
-
|
|
32662
|
+
return this.config.analytics.trackResult(
|
|
32663
|
+
"staking",
|
|
32664
|
+
"cancelUnstake",
|
|
32665
|
+
async () => {
|
|
32666
|
+
const { params, timeout } = _params;
|
|
32667
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "cancelUnstake" };
|
|
32668
|
+
try {
|
|
32669
|
+
const txResult = await this.createCancelUnstakeIntent(_params);
|
|
32670
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32671
|
+
let hubTxHash;
|
|
32672
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32673
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32674
|
+
srcTxHash: txResult.value.tx,
|
|
32675
|
+
data: txResult.value.relayData,
|
|
32676
|
+
chainKey: params.srcChainKey,
|
|
32677
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32678
|
+
timeout
|
|
32679
|
+
});
|
|
32680
|
+
if (!packetResult.ok) {
|
|
32681
|
+
return {
|
|
32682
|
+
ok: false,
|
|
32683
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32684
|
+
feature: "staking",
|
|
32685
|
+
action: baseCtx.action,
|
|
32686
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32687
|
+
})
|
|
32688
|
+
};
|
|
32689
|
+
}
|
|
32690
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32691
|
+
} else {
|
|
32692
|
+
hubTxHash = txResult.value.tx;
|
|
32693
|
+
}
|
|
32694
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32695
|
+
} catch (error) {
|
|
32696
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31372
32697
|
return {
|
|
31373
32698
|
ok: false,
|
|
31374
|
-
error:
|
|
31375
|
-
feature: "staking",
|
|
31376
|
-
action: baseCtx.action,
|
|
31377
|
-
srcChainKey: baseCtx.srcChainKey
|
|
31378
|
-
})
|
|
32699
|
+
error: executionFailed("staking", error, baseCtx)
|
|
31379
32700
|
};
|
|
31380
32701
|
}
|
|
31381
|
-
|
|
31382
|
-
|
|
31383
|
-
|
|
32702
|
+
},
|
|
32703
|
+
{
|
|
32704
|
+
start: () => ({
|
|
32705
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32706
|
+
srcAddress: _params.params.srcAddress,
|
|
32707
|
+
requestId: _params.params.requestId
|
|
32708
|
+
}),
|
|
32709
|
+
success: (value) => ({
|
|
32710
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32711
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32712
|
+
}),
|
|
32713
|
+
failure: (error) => ({ code: error.code })
|
|
31384
32714
|
}
|
|
31385
|
-
|
|
31386
|
-
} catch (error) {
|
|
31387
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31388
|
-
return {
|
|
31389
|
-
ok: false,
|
|
31390
|
-
error: executionFailed("staking", error, baseCtx)
|
|
31391
|
-
};
|
|
31392
|
-
}
|
|
32715
|
+
);
|
|
31393
32716
|
}
|
|
31394
32717
|
/**
|
|
31395
32718
|
* Submits the cancel-unstake transaction on the spoke chain without relaying to the hub.
|
|
@@ -32763,34 +34086,56 @@ var ClService = class _ClService {
|
|
|
32763
34086
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
32764
34087
|
*/
|
|
32765
34088
|
async supplyLiquidity(_params) {
|
|
32766
|
-
|
|
32767
|
-
|
|
32768
|
-
|
|
32769
|
-
|
|
32770
|
-
|
|
32771
|
-
|
|
32772
|
-
|
|
32773
|
-
|
|
32774
|
-
|
|
32775
|
-
|
|
32776
|
-
|
|
32777
|
-
|
|
32778
|
-
|
|
32779
|
-
|
|
32780
|
-
|
|
32781
|
-
|
|
32782
|
-
|
|
32783
|
-
|
|
32784
|
-
|
|
34089
|
+
return this.config.analytics.trackResult(
|
|
34090
|
+
"dex",
|
|
34091
|
+
"supplyLiquidity",
|
|
34092
|
+
async () => {
|
|
34093
|
+
const { params, timeout } = _params;
|
|
34094
|
+
try {
|
|
34095
|
+
const txResult = await this.executeSupplyLiquidity(_params);
|
|
34096
|
+
if (!txResult.ok) {
|
|
34097
|
+
return txResult;
|
|
34098
|
+
}
|
|
34099
|
+
let hubTxHash;
|
|
34100
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34101
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34102
|
+
srcTxHash: txResult.value.tx,
|
|
34103
|
+
data: txResult.value.relayData,
|
|
34104
|
+
chainKey: params.srcChainKey,
|
|
34105
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34106
|
+
timeout
|
|
34107
|
+
});
|
|
34108
|
+
if (!packetResult.ok) return packetResult;
|
|
34109
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34110
|
+
} else {
|
|
34111
|
+
hubTxHash = txResult.value.tx;
|
|
34112
|
+
}
|
|
34113
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34114
|
+
} catch (error) {
|
|
34115
|
+
this.config.logger.error("supplyLiquidity error", error);
|
|
34116
|
+
return {
|
|
34117
|
+
ok: false,
|
|
34118
|
+
error
|
|
34119
|
+
};
|
|
34120
|
+
}
|
|
34121
|
+
},
|
|
34122
|
+
{
|
|
34123
|
+
start: () => ({
|
|
34124
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34125
|
+
srcAddress: _params.params.srcAddress,
|
|
34126
|
+
currency0: _params.params.poolKey.currency0,
|
|
34127
|
+
currency1: _params.params.poolKey.currency1,
|
|
34128
|
+
fee: _params.params.poolKey.fee,
|
|
34129
|
+
tickLower: _params.params.tickLower,
|
|
34130
|
+
tickUpper: _params.params.tickUpper,
|
|
34131
|
+
liquidity: _params.params.liquidity,
|
|
34132
|
+
amount0Max: _params.params.amount0Max,
|
|
34133
|
+
amount1Max: _params.params.amount1Max
|
|
34134
|
+
}),
|
|
34135
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34136
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
32785
34137
|
}
|
|
32786
|
-
|
|
32787
|
-
} catch (error) {
|
|
32788
|
-
this.config.logger.error("supplyLiquidity error", error);
|
|
32789
|
-
return {
|
|
32790
|
-
ok: false,
|
|
32791
|
-
error
|
|
32792
|
-
};
|
|
32793
|
-
}
|
|
34138
|
+
);
|
|
32794
34139
|
}
|
|
32795
34140
|
/**
|
|
32796
34141
|
* Add liquidity to an existing position and wait for the cross-chain relay to complete.
|
|
@@ -32805,33 +34150,56 @@ var ClService = class _ClService {
|
|
|
32805
34150
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
32806
34151
|
*/
|
|
32807
34152
|
async increaseLiquidity(_params) {
|
|
32808
|
-
|
|
32809
|
-
|
|
32810
|
-
|
|
32811
|
-
|
|
32812
|
-
|
|
32813
|
-
|
|
32814
|
-
|
|
32815
|
-
|
|
32816
|
-
|
|
32817
|
-
|
|
32818
|
-
|
|
32819
|
-
|
|
32820
|
-
|
|
32821
|
-
|
|
32822
|
-
|
|
32823
|
-
|
|
32824
|
-
|
|
32825
|
-
|
|
32826
|
-
|
|
34153
|
+
return this.config.analytics.trackResult(
|
|
34154
|
+
"dex",
|
|
34155
|
+
"increaseLiquidity",
|
|
34156
|
+
async () => {
|
|
34157
|
+
const { params, timeout } = _params;
|
|
34158
|
+
try {
|
|
34159
|
+
const txResult = await this.executeIncreaseLiquidity(_params);
|
|
34160
|
+
if (!txResult.ok) {
|
|
34161
|
+
return txResult;
|
|
34162
|
+
}
|
|
34163
|
+
let hubTxHash;
|
|
34164
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34165
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34166
|
+
srcTxHash: txResult.value.tx,
|
|
34167
|
+
data: txResult.value.relayData,
|
|
34168
|
+
chainKey: params.srcChainKey,
|
|
34169
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34170
|
+
timeout
|
|
34171
|
+
});
|
|
34172
|
+
if (!packetResult.ok) return packetResult;
|
|
34173
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34174
|
+
} else {
|
|
34175
|
+
hubTxHash = txResult.value.tx;
|
|
34176
|
+
}
|
|
34177
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34178
|
+
} catch (error) {
|
|
34179
|
+
return {
|
|
34180
|
+
ok: false,
|
|
34181
|
+
error
|
|
34182
|
+
};
|
|
34183
|
+
}
|
|
34184
|
+
},
|
|
34185
|
+
{
|
|
34186
|
+
start: () => ({
|
|
34187
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34188
|
+
srcAddress: _params.params.srcAddress,
|
|
34189
|
+
currency0: _params.params.poolKey.currency0,
|
|
34190
|
+
currency1: _params.params.poolKey.currency1,
|
|
34191
|
+
fee: _params.params.poolKey.fee,
|
|
34192
|
+
tokenId: _params.params.tokenId,
|
|
34193
|
+
tickLower: _params.params.tickLower,
|
|
34194
|
+
tickUpper: _params.params.tickUpper,
|
|
34195
|
+
liquidity: _params.params.liquidity,
|
|
34196
|
+
amount0Max: _params.params.amount0Max,
|
|
34197
|
+
amount1Max: _params.params.amount1Max
|
|
34198
|
+
}),
|
|
34199
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34200
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
32827
34201
|
}
|
|
32828
|
-
|
|
32829
|
-
} catch (error) {
|
|
32830
|
-
return {
|
|
32831
|
-
ok: false,
|
|
32832
|
-
error
|
|
32833
|
-
};
|
|
32834
|
-
}
|
|
34202
|
+
);
|
|
32835
34203
|
}
|
|
32836
34204
|
/**
|
|
32837
34205
|
* Remove liquidity from an existing position and wait for the cross-chain relay to complete.
|
|
@@ -32846,33 +34214,54 @@ var ClService = class _ClService {
|
|
|
32846
34214
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
32847
34215
|
*/
|
|
32848
34216
|
async decreaseLiquidity(_params) {
|
|
32849
|
-
|
|
32850
|
-
|
|
32851
|
-
|
|
32852
|
-
|
|
32853
|
-
|
|
32854
|
-
|
|
32855
|
-
|
|
32856
|
-
|
|
32857
|
-
|
|
32858
|
-
|
|
32859
|
-
|
|
32860
|
-
|
|
32861
|
-
|
|
32862
|
-
|
|
32863
|
-
|
|
32864
|
-
|
|
32865
|
-
|
|
32866
|
-
|
|
32867
|
-
|
|
34217
|
+
return this.config.analytics.trackResult(
|
|
34218
|
+
"dex",
|
|
34219
|
+
"decreaseLiquidity",
|
|
34220
|
+
async () => {
|
|
34221
|
+
const { params, timeout } = _params;
|
|
34222
|
+
try {
|
|
34223
|
+
const txResult = await this.executeDecreaseLiquidity(_params);
|
|
34224
|
+
if (!txResult.ok) {
|
|
34225
|
+
return txResult;
|
|
34226
|
+
}
|
|
34227
|
+
let hubTxHash;
|
|
34228
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34229
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34230
|
+
srcTxHash: txResult.value.tx,
|
|
34231
|
+
data: txResult.value.relayData,
|
|
34232
|
+
chainKey: params.srcChainKey,
|
|
34233
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34234
|
+
timeout
|
|
34235
|
+
});
|
|
34236
|
+
if (!packetResult.ok) return packetResult;
|
|
34237
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34238
|
+
} else {
|
|
34239
|
+
hubTxHash = txResult.value.tx;
|
|
34240
|
+
}
|
|
34241
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34242
|
+
} catch (error) {
|
|
34243
|
+
return {
|
|
34244
|
+
ok: false,
|
|
34245
|
+
error
|
|
34246
|
+
};
|
|
34247
|
+
}
|
|
34248
|
+
},
|
|
34249
|
+
{
|
|
34250
|
+
start: () => ({
|
|
34251
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34252
|
+
srcAddress: _params.params.srcAddress,
|
|
34253
|
+
currency0: _params.params.poolKey.currency0,
|
|
34254
|
+
currency1: _params.params.poolKey.currency1,
|
|
34255
|
+
fee: _params.params.poolKey.fee,
|
|
34256
|
+
tokenId: _params.params.tokenId,
|
|
34257
|
+
liquidity: _params.params.liquidity,
|
|
34258
|
+
amount0Min: _params.params.amount0Min,
|
|
34259
|
+
amount1Min: _params.params.amount1Min
|
|
34260
|
+
}),
|
|
34261
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34262
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
32868
34263
|
}
|
|
32869
|
-
|
|
32870
|
-
} catch (error) {
|
|
32871
|
-
return {
|
|
32872
|
-
ok: false,
|
|
32873
|
-
error
|
|
32874
|
-
};
|
|
32875
|
-
}
|
|
34264
|
+
);
|
|
32876
34265
|
}
|
|
32877
34266
|
/**
|
|
32878
34267
|
* Fetch the reward configuration stored in the pool's hook contract.
|
|
@@ -33024,34 +34413,54 @@ var ClService = class _ClService {
|
|
|
33024
34413
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
33025
34414
|
*/
|
|
33026
34415
|
async claimRewards(_params) {
|
|
33027
|
-
|
|
33028
|
-
|
|
33029
|
-
|
|
33030
|
-
|
|
33031
|
-
|
|
33032
|
-
|
|
33033
|
-
|
|
33034
|
-
|
|
33035
|
-
|
|
33036
|
-
|
|
33037
|
-
|
|
33038
|
-
|
|
33039
|
-
|
|
33040
|
-
|
|
33041
|
-
|
|
33042
|
-
|
|
33043
|
-
|
|
33044
|
-
|
|
33045
|
-
|
|
34416
|
+
return this.config.analytics.trackResult(
|
|
34417
|
+
"dex",
|
|
34418
|
+
"claimRewards",
|
|
34419
|
+
async () => {
|
|
34420
|
+
const { params, timeout } = _params;
|
|
34421
|
+
try {
|
|
34422
|
+
const txResult = await this.executeClaimRewards(_params);
|
|
34423
|
+
if (!txResult.ok) {
|
|
34424
|
+
return txResult;
|
|
34425
|
+
}
|
|
34426
|
+
let hubTxHash;
|
|
34427
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34428
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34429
|
+
srcTxHash: txResult.value.tx,
|
|
34430
|
+
data: txResult.value.relayData,
|
|
34431
|
+
chainKey: params.srcChainKey,
|
|
34432
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34433
|
+
timeout
|
|
34434
|
+
});
|
|
34435
|
+
if (!packetResult.ok) return packetResult;
|
|
34436
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34437
|
+
} else {
|
|
34438
|
+
hubTxHash = txResult.value.tx;
|
|
34439
|
+
}
|
|
34440
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34441
|
+
} catch (error) {
|
|
34442
|
+
this.config.logger.error("claimRewards error", error);
|
|
34443
|
+
return {
|
|
34444
|
+
ok: false,
|
|
34445
|
+
error
|
|
34446
|
+
};
|
|
34447
|
+
}
|
|
34448
|
+
},
|
|
34449
|
+
{
|
|
34450
|
+
start: () => ({
|
|
34451
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34452
|
+
srcAddress: _params.params.srcAddress,
|
|
34453
|
+
currency0: _params.params.poolKey.currency0,
|
|
34454
|
+
currency1: _params.params.poolKey.currency1,
|
|
34455
|
+
fee: _params.params.poolKey.fee,
|
|
34456
|
+
tokenId: _params.params.tokenId,
|
|
34457
|
+
tickLower: _params.params.tickLower,
|
|
34458
|
+
tickUpper: _params.params.tickUpper
|
|
34459
|
+
}),
|
|
34460
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34461
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
33046
34462
|
}
|
|
33047
|
-
|
|
33048
|
-
} catch (error) {
|
|
33049
|
-
this.config.logger.error("claimRewards error", error);
|
|
33050
|
-
return {
|
|
33051
|
-
ok: false,
|
|
33052
|
-
error
|
|
33053
|
-
};
|
|
33054
|
-
}
|
|
34463
|
+
);
|
|
33055
34464
|
}
|
|
33056
34465
|
/**
|
|
33057
34466
|
* Return the list of configured concentrated-liquidity pool keys for the SODAX DEX.
|
|
@@ -35974,50 +37383,68 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
35974
37383
|
* @returns A pair of transaction hashes — `srcChainTxHash` (spoke) and `dstChainTxHash` (hub).
|
|
35975
37384
|
*/
|
|
35976
37385
|
async supply(_params) {
|
|
35977
|
-
|
|
35978
|
-
|
|
35979
|
-
|
|
35980
|
-
|
|
35981
|
-
|
|
35982
|
-
|
|
35983
|
-
|
|
35984
|
-
|
|
35985
|
-
|
|
35986
|
-
ok: false,
|
|
35987
|
-
|
|
35988
|
-
|
|
35989
|
-
|
|
35990
|
-
|
|
35991
|
-
|
|
35992
|
-
|
|
35993
|
-
|
|
35994
|
-
|
|
37386
|
+
return this.config.analytics.trackResult(
|
|
37387
|
+
"moneyMarket",
|
|
37388
|
+
"supply",
|
|
37389
|
+
async () => {
|
|
37390
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37391
|
+
const srcChainKey = params.srcChainKey;
|
|
37392
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "supply" };
|
|
37393
|
+
try {
|
|
37394
|
+
const txResult = await this.createSupplyIntent(_params);
|
|
37395
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37396
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37397
|
+
if (!verify.ok) {
|
|
37398
|
+
return {
|
|
37399
|
+
ok: false,
|
|
37400
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37401
|
+
};
|
|
37402
|
+
}
|
|
37403
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
37404
|
+
return {
|
|
37405
|
+
ok: true,
|
|
37406
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37407
|
+
};
|
|
37408
|
+
}
|
|
37409
|
+
const packet = await relayTxAndWaitPacket({
|
|
37410
|
+
srcTxHash: txResult.value.tx,
|
|
37411
|
+
data: txResult.value.relayData,
|
|
37412
|
+
chainKey: srcChainKey,
|
|
37413
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37414
|
+
timeout
|
|
37415
|
+
});
|
|
37416
|
+
if (!packet.ok)
|
|
37417
|
+
return {
|
|
37418
|
+
ok: false,
|
|
37419
|
+
error: mapRelayFailure(packet.error, {
|
|
37420
|
+
feature: "moneyMarket",
|
|
37421
|
+
action: baseCtx.action,
|
|
37422
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37423
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37424
|
+
})
|
|
37425
|
+
};
|
|
37426
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
37427
|
+
} catch (error) {
|
|
37428
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37429
|
+
return {
|
|
37430
|
+
ok: false,
|
|
37431
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37432
|
+
};
|
|
37433
|
+
}
|
|
37434
|
+
},
|
|
37435
|
+
{
|
|
37436
|
+
start: () => ({
|
|
37437
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37438
|
+
srcAddress: _params.params.srcAddress,
|
|
37439
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37440
|
+
dstAddress: _params.params.dstAddress,
|
|
37441
|
+
token: _params.params.token,
|
|
37442
|
+
amount: _params.params.amount
|
|
37443
|
+
}),
|
|
37444
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37445
|
+
failure: (error) => ({ code: error.code })
|
|
35995
37446
|
}
|
|
35996
|
-
|
|
35997
|
-
srcTxHash: txResult.value.tx,
|
|
35998
|
-
data: txResult.value.relayData,
|
|
35999
|
-
chainKey: srcChainKey,
|
|
36000
|
-
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
36001
|
-
timeout
|
|
36002
|
-
});
|
|
36003
|
-
if (!packet.ok)
|
|
36004
|
-
return {
|
|
36005
|
-
ok: false,
|
|
36006
|
-
error: mapRelayFailure(packet.error, {
|
|
36007
|
-
feature: "moneyMarket",
|
|
36008
|
-
action: baseCtx.action,
|
|
36009
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
36010
|
-
dstChainKey: baseCtx.dstChainKey
|
|
36011
|
-
})
|
|
36012
|
-
};
|
|
36013
|
-
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
36014
|
-
} catch (error) {
|
|
36015
|
-
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
36016
|
-
return {
|
|
36017
|
-
ok: false,
|
|
36018
|
-
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
36019
|
-
};
|
|
36020
|
-
}
|
|
37447
|
+
);
|
|
36021
37448
|
}
|
|
36022
37449
|
/**
|
|
36023
37450
|
* Build and optionally broadcast the spoke-side supply transaction without waiting for the
|
|
@@ -36134,58 +37561,76 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
36134
37561
|
* `dstChainTxHash` (hub delivery or relay destination).
|
|
36135
37562
|
*/
|
|
36136
37563
|
async borrow(_params) {
|
|
36137
|
-
|
|
36138
|
-
|
|
36139
|
-
|
|
36140
|
-
|
|
36141
|
-
|
|
36142
|
-
|
|
36143
|
-
|
|
36144
|
-
|
|
36145
|
-
|
|
36146
|
-
|
|
36147
|
-
ok: false,
|
|
36148
|
-
|
|
36149
|
-
|
|
36150
|
-
|
|
36151
|
-
|
|
36152
|
-
|
|
36153
|
-
|
|
36154
|
-
|
|
36155
|
-
|
|
36156
|
-
|
|
36157
|
-
|
|
36158
|
-
|
|
36159
|
-
|
|
36160
|
-
|
|
36161
|
-
|
|
36162
|
-
|
|
36163
|
-
|
|
36164
|
-
|
|
36165
|
-
|
|
36166
|
-
|
|
36167
|
-
|
|
36168
|
-
|
|
36169
|
-
|
|
36170
|
-
|
|
36171
|
-
|
|
36172
|
-
|
|
36173
|
-
|
|
36174
|
-
|
|
36175
|
-
|
|
36176
|
-
|
|
36177
|
-
|
|
36178
|
-
|
|
36179
|
-
|
|
37564
|
+
return this.config.analytics.trackResult(
|
|
37565
|
+
"moneyMarket",
|
|
37566
|
+
"borrow",
|
|
37567
|
+
async () => {
|
|
37568
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37569
|
+
const srcChainKey = params.srcChainKey;
|
|
37570
|
+
const hubChainId = this.hubProvider.chainConfig.chain.key;
|
|
37571
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "borrow" };
|
|
37572
|
+
try {
|
|
37573
|
+
const txResult = await this.createBorrowIntent(_params);
|
|
37574
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37575
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37576
|
+
if (!verify.ok) {
|
|
37577
|
+
return {
|
|
37578
|
+
ok: false,
|
|
37579
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37580
|
+
};
|
|
37581
|
+
}
|
|
37582
|
+
const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId;
|
|
37583
|
+
if (!needsRelay) {
|
|
37584
|
+
return {
|
|
37585
|
+
ok: true,
|
|
37586
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37587
|
+
};
|
|
37588
|
+
}
|
|
37589
|
+
const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
|
|
37590
|
+
const packet = await relayTxAndWaitPacket({
|
|
37591
|
+
...relayIdentity,
|
|
37592
|
+
chainKey: srcChainKey,
|
|
37593
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37594
|
+
timeout
|
|
37595
|
+
});
|
|
37596
|
+
if (!packet.ok)
|
|
37597
|
+
return {
|
|
37598
|
+
ok: false,
|
|
37599
|
+
error: mapRelayFailure(packet.error, {
|
|
37600
|
+
feature: "moneyMarket",
|
|
37601
|
+
action: baseCtx.action,
|
|
37602
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37603
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37604
|
+
})
|
|
37605
|
+
};
|
|
37606
|
+
return {
|
|
37607
|
+
ok: true,
|
|
37608
|
+
value: {
|
|
37609
|
+
srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
|
|
37610
|
+
dstChainTxHash: packet.value.dst_tx_hash
|
|
37611
|
+
}
|
|
37612
|
+
};
|
|
37613
|
+
} catch (error) {
|
|
37614
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37615
|
+
return {
|
|
37616
|
+
ok: false,
|
|
37617
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37618
|
+
};
|
|
36180
37619
|
}
|
|
36181
|
-
}
|
|
36182
|
-
|
|
36183
|
-
|
|
36184
|
-
|
|
36185
|
-
|
|
36186
|
-
|
|
36187
|
-
|
|
36188
|
-
|
|
37620
|
+
},
|
|
37621
|
+
{
|
|
37622
|
+
start: () => ({
|
|
37623
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37624
|
+
srcAddress: _params.params.srcAddress,
|
|
37625
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37626
|
+
dstAddress: _params.params.dstAddress,
|
|
37627
|
+
token: _params.params.token,
|
|
37628
|
+
amount: _params.params.amount
|
|
37629
|
+
}),
|
|
37630
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37631
|
+
failure: (error) => ({ code: error.code })
|
|
37632
|
+
}
|
|
37633
|
+
);
|
|
36189
37634
|
}
|
|
36190
37635
|
/**
|
|
36191
37636
|
* Build and optionally broadcast the spoke-side borrow message without waiting for the
|
|
@@ -36283,59 +37728,77 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
36283
37728
|
* `dstChainTxHash` (hub or relay destination).
|
|
36284
37729
|
*/
|
|
36285
37730
|
async withdraw(_params) {
|
|
36286
|
-
|
|
36287
|
-
|
|
36288
|
-
|
|
36289
|
-
|
|
36290
|
-
|
|
36291
|
-
|
|
36292
|
-
|
|
36293
|
-
|
|
36294
|
-
|
|
36295
|
-
|
|
36296
|
-
|
|
36297
|
-
ok: false,
|
|
36298
|
-
|
|
36299
|
-
|
|
36300
|
-
|
|
36301
|
-
|
|
36302
|
-
|
|
36303
|
-
|
|
36304
|
-
|
|
36305
|
-
|
|
36306
|
-
|
|
36307
|
-
|
|
36308
|
-
|
|
36309
|
-
|
|
36310
|
-
|
|
36311
|
-
|
|
36312
|
-
|
|
36313
|
-
|
|
36314
|
-
|
|
36315
|
-
|
|
36316
|
-
|
|
36317
|
-
|
|
36318
|
-
|
|
36319
|
-
|
|
36320
|
-
|
|
36321
|
-
|
|
36322
|
-
|
|
36323
|
-
|
|
36324
|
-
|
|
36325
|
-
|
|
36326
|
-
|
|
36327
|
-
|
|
36328
|
-
|
|
36329
|
-
|
|
37731
|
+
return this.config.analytics.trackResult(
|
|
37732
|
+
"moneyMarket",
|
|
37733
|
+
"withdraw",
|
|
37734
|
+
async () => {
|
|
37735
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37736
|
+
const srcChainKey = params.srcChainKey;
|
|
37737
|
+
const hubChainId = this.hubProvider.chainConfig.chain.key;
|
|
37738
|
+
const walletRouter = this.hubProvider.chainConfig.addresses.walletRouter;
|
|
37739
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "withdraw" };
|
|
37740
|
+
try {
|
|
37741
|
+
const txResult = await this.createWithdrawIntent(_params);
|
|
37742
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37743
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37744
|
+
if (!verify.ok) {
|
|
37745
|
+
return {
|
|
37746
|
+
ok: false,
|
|
37747
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37748
|
+
};
|
|
37749
|
+
}
|
|
37750
|
+
const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId && params.dstAddress !== walletRouter;
|
|
37751
|
+
if (!needsRelay) {
|
|
37752
|
+
return {
|
|
37753
|
+
ok: true,
|
|
37754
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37755
|
+
};
|
|
37756
|
+
}
|
|
37757
|
+
const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
|
|
37758
|
+
const packet = await relayTxAndWaitPacket({
|
|
37759
|
+
...relayIdentity,
|
|
37760
|
+
chainKey: srcChainKey,
|
|
37761
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37762
|
+
timeout
|
|
37763
|
+
});
|
|
37764
|
+
if (!packet.ok)
|
|
37765
|
+
return {
|
|
37766
|
+
ok: false,
|
|
37767
|
+
error: mapRelayFailure(packet.error, {
|
|
37768
|
+
feature: "moneyMarket",
|
|
37769
|
+
action: baseCtx.action,
|
|
37770
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37771
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37772
|
+
})
|
|
37773
|
+
};
|
|
37774
|
+
return {
|
|
37775
|
+
ok: true,
|
|
37776
|
+
value: {
|
|
37777
|
+
srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
|
|
37778
|
+
dstChainTxHash: packet.value.dst_tx_hash
|
|
37779
|
+
}
|
|
37780
|
+
};
|
|
37781
|
+
} catch (error) {
|
|
37782
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37783
|
+
return {
|
|
37784
|
+
ok: false,
|
|
37785
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37786
|
+
};
|
|
36330
37787
|
}
|
|
36331
|
-
}
|
|
36332
|
-
|
|
36333
|
-
|
|
36334
|
-
|
|
36335
|
-
|
|
36336
|
-
|
|
36337
|
-
|
|
36338
|
-
|
|
37788
|
+
},
|
|
37789
|
+
{
|
|
37790
|
+
start: () => ({
|
|
37791
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37792
|
+
srcAddress: _params.params.srcAddress,
|
|
37793
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37794
|
+
dstAddress: _params.params.dstAddress,
|
|
37795
|
+
token: _params.params.token,
|
|
37796
|
+
amount: _params.params.amount
|
|
37797
|
+
}),
|
|
37798
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37799
|
+
failure: (error) => ({ code: error.code })
|
|
37800
|
+
}
|
|
37801
|
+
);
|
|
36339
37802
|
}
|
|
36340
37803
|
/**
|
|
36341
37804
|
* Build and optionally broadcast the spoke-side withdraw message without waiting for the
|
|
@@ -36431,50 +37894,68 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
36431
37894
|
* @returns A pair of transaction hashes — `srcChainTxHash` (spoke) and `dstChainTxHash` (hub).
|
|
36432
37895
|
*/
|
|
36433
37896
|
async repay(_params) {
|
|
36434
|
-
|
|
36435
|
-
|
|
36436
|
-
|
|
36437
|
-
|
|
36438
|
-
|
|
36439
|
-
|
|
36440
|
-
|
|
36441
|
-
|
|
36442
|
-
|
|
36443
|
-
ok: false,
|
|
36444
|
-
|
|
36445
|
-
|
|
36446
|
-
|
|
36447
|
-
|
|
36448
|
-
|
|
36449
|
-
|
|
36450
|
-
|
|
36451
|
-
|
|
37897
|
+
return this.config.analytics.trackResult(
|
|
37898
|
+
"moneyMarket",
|
|
37899
|
+
"repay",
|
|
37900
|
+
async () => {
|
|
37901
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37902
|
+
const srcChainKey = params.srcChainKey;
|
|
37903
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "repay" };
|
|
37904
|
+
try {
|
|
37905
|
+
const txResult = await this.createRepayIntent(_params);
|
|
37906
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37907
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37908
|
+
if (!verify.ok) {
|
|
37909
|
+
return {
|
|
37910
|
+
ok: false,
|
|
37911
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37912
|
+
};
|
|
37913
|
+
}
|
|
37914
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
37915
|
+
return {
|
|
37916
|
+
ok: true,
|
|
37917
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37918
|
+
};
|
|
37919
|
+
}
|
|
37920
|
+
const packet = await relayTxAndWaitPacket({
|
|
37921
|
+
srcTxHash: txResult.value.tx,
|
|
37922
|
+
data: txResult.value.relayData,
|
|
37923
|
+
chainKey: srcChainKey,
|
|
37924
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37925
|
+
timeout
|
|
37926
|
+
});
|
|
37927
|
+
if (!packet.ok)
|
|
37928
|
+
return {
|
|
37929
|
+
ok: false,
|
|
37930
|
+
error: mapRelayFailure(packet.error, {
|
|
37931
|
+
feature: "moneyMarket",
|
|
37932
|
+
action: baseCtx.action,
|
|
37933
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37934
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37935
|
+
})
|
|
37936
|
+
};
|
|
37937
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
37938
|
+
} catch (error) {
|
|
37939
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37940
|
+
return {
|
|
37941
|
+
ok: false,
|
|
37942
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37943
|
+
};
|
|
37944
|
+
}
|
|
37945
|
+
},
|
|
37946
|
+
{
|
|
37947
|
+
start: () => ({
|
|
37948
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37949
|
+
srcAddress: _params.params.srcAddress,
|
|
37950
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37951
|
+
dstAddress: _params.params.dstAddress,
|
|
37952
|
+
token: _params.params.token,
|
|
37953
|
+
amount: _params.params.amount
|
|
37954
|
+
}),
|
|
37955
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37956
|
+
failure: (error) => ({ code: error.code })
|
|
36452
37957
|
}
|
|
36453
|
-
|
|
36454
|
-
srcTxHash: txResult.value.tx,
|
|
36455
|
-
data: txResult.value.relayData,
|
|
36456
|
-
chainKey: srcChainKey,
|
|
36457
|
-
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
36458
|
-
timeout
|
|
36459
|
-
});
|
|
36460
|
-
if (!packet.ok)
|
|
36461
|
-
return {
|
|
36462
|
-
ok: false,
|
|
36463
|
-
error: mapRelayFailure(packet.error, {
|
|
36464
|
-
feature: "moneyMarket",
|
|
36465
|
-
action: baseCtx.action,
|
|
36466
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
36467
|
-
dstChainKey: baseCtx.dstChainKey
|
|
36468
|
-
})
|
|
36469
|
-
};
|
|
36470
|
-
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
36471
|
-
} catch (error) {
|
|
36472
|
-
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
36473
|
-
return {
|
|
36474
|
-
ok: false,
|
|
36475
|
-
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
36476
|
-
};
|
|
36477
|
-
}
|
|
37958
|
+
);
|
|
36478
37959
|
}
|
|
36479
37960
|
/**
|
|
36480
37961
|
* Build and optionally broadcast the spoke-side repay transaction without waiting for the
|
|
@@ -37175,50 +38656,67 @@ var PartnerFeeClaimService = class {
|
|
|
37175
38656
|
* unsigned raw transaction (`raw: true`). Returns an error on failure.
|
|
37176
38657
|
*/
|
|
37177
38658
|
async setSwapPreference(_params) {
|
|
37178
|
-
|
|
37179
|
-
|
|
37180
|
-
|
|
37181
|
-
|
|
37182
|
-
|
|
37183
|
-
|
|
37184
|
-
|
|
37185
|
-
|
|
37186
|
-
|
|
37187
|
-
|
|
37188
|
-
from: params.srcAddress,
|
|
37189
|
-
to: this.protocolIntentsContract,
|
|
37190
|
-
value: 0n,
|
|
37191
|
-
data: encodeFunctionData({
|
|
37192
|
-
abi: ProtocolIntentsAbi,
|
|
37193
|
-
functionName: "setAutoSwapPreferences",
|
|
37194
|
-
args: [
|
|
38659
|
+
return this.config.analytics.trackResult(
|
|
38660
|
+
"partner",
|
|
38661
|
+
"setSwapPreference",
|
|
38662
|
+
async () => {
|
|
38663
|
+
const { params, walletProvider, raw } = _params;
|
|
38664
|
+
try {
|
|
38665
|
+
invariant(isHubChainKeyType(params.srcChainKey), "PartnerFeeClaimService only supports Sonic spoke provider");
|
|
38666
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
38667
|
+
const outputToken = params.dstChainKey !== this.hubProvider.chainConfig.chain.key ? this.hubProvider.config.getSpokeTokenFromOriginalAssetAddress(params.dstChainKey, params.outputToken)?.hubAsset : params.outputToken;
|
|
38668
|
+
invariant(
|
|
37195
38669
|
outputToken,
|
|
37196
|
-
|
|
37197
|
-
|
|
37198
|
-
|
|
37199
|
-
|
|
37200
|
-
|
|
37201
|
-
|
|
37202
|
-
|
|
37203
|
-
|
|
37204
|
-
|
|
37205
|
-
|
|
38670
|
+
`hub asset not found for spoke chain token (params.outputToken): ${params.outputToken} with chain key: ${params.dstChainKey}`
|
|
38671
|
+
);
|
|
38672
|
+
const rawTx = {
|
|
38673
|
+
from: params.srcAddress,
|
|
38674
|
+
to: this.protocolIntentsContract,
|
|
38675
|
+
value: 0n,
|
|
38676
|
+
data: encodeFunctionData({
|
|
38677
|
+
abi: ProtocolIntentsAbi,
|
|
38678
|
+
functionName: "setAutoSwapPreferences",
|
|
38679
|
+
args: [
|
|
38680
|
+
outputToken,
|
|
38681
|
+
BigInt(getIntentRelayChainId(params.dstChainKey)),
|
|
38682
|
+
encodeAddress(params.dstChainKey, params.dstAddress)
|
|
38683
|
+
]
|
|
38684
|
+
})
|
|
38685
|
+
};
|
|
38686
|
+
if (raw) {
|
|
38687
|
+
return {
|
|
38688
|
+
ok: true,
|
|
38689
|
+
value: rawTx
|
|
38690
|
+
};
|
|
38691
|
+
}
|
|
38692
|
+
invariant(
|
|
38693
|
+
isEvmWalletProviderType(walletProvider),
|
|
38694
|
+
"PartnerFeeClaimService only supports Evm (sonic) wallet provider"
|
|
38695
|
+
);
|
|
38696
|
+
const txHash = await walletProvider.sendTransaction(rawTx);
|
|
38697
|
+
return {
|
|
38698
|
+
ok: true,
|
|
38699
|
+
value: txHash
|
|
38700
|
+
};
|
|
38701
|
+
} catch (error) {
|
|
38702
|
+
return {
|
|
38703
|
+
ok: false,
|
|
38704
|
+
error
|
|
38705
|
+
};
|
|
38706
|
+
}
|
|
38707
|
+
},
|
|
38708
|
+
{
|
|
38709
|
+
start: () => ({
|
|
38710
|
+
srcChainKey: _params.params.srcChainKey,
|
|
38711
|
+
srcAddress: _params.params.srcAddress,
|
|
38712
|
+
outputToken: _params.params.outputToken,
|
|
38713
|
+
dstChainKey: _params.params.dstChainKey,
|
|
38714
|
+
dstAddress: _params.params.dstAddress
|
|
38715
|
+
}),
|
|
38716
|
+
success: (value) => ({ txHash: value }),
|
|
38717
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
37206
38718
|
}
|
|
37207
|
-
|
|
37208
|
-
isEvmWalletProviderType(walletProvider),
|
|
37209
|
-
"PartnerFeeClaimService only supports Evm (sonic) wallet provider"
|
|
37210
|
-
);
|
|
37211
|
-
const txHash = await walletProvider.sendTransaction(rawTx);
|
|
37212
|
-
return {
|
|
37213
|
-
ok: true,
|
|
37214
|
-
value: txHash
|
|
37215
|
-
};
|
|
37216
|
-
} catch (error) {
|
|
37217
|
-
return {
|
|
37218
|
-
ok: false,
|
|
37219
|
-
error
|
|
37220
|
-
};
|
|
37221
|
-
}
|
|
38719
|
+
);
|
|
37222
38720
|
}
|
|
37223
38721
|
/**
|
|
37224
38722
|
* Checks whether a hub-chain ERC-20 token is already approved for the ProtocolIntents contract.
|
|
@@ -37330,6 +38828,11 @@ var PartnerFeeClaimService = class {
|
|
|
37330
38828
|
* This is the low-level building block. Use `swap` for the full flow that also waits for
|
|
37331
38829
|
* the solver to execute the intent.
|
|
37332
38830
|
*
|
|
38831
|
+
* Guards against same-token intents: if the configured output token equals `fromToken` the solver
|
|
38832
|
+
* cannot fill the swap, so the call is rejected with `VALIDATION_FAILED` before any transaction is
|
|
38833
|
+
* built. The guard fails closed — if the preference lookup fails the call returns that error rather
|
|
38834
|
+
* than submitting an intent that may become unfillable.
|
|
38835
|
+
*
|
|
37333
38836
|
* @param _params - Action descriptor containing:
|
|
37334
38837
|
* - `params.srcChainKey` — must be the hub chain key (Sonic).
|
|
37335
38838
|
* - `params.srcAddress` — partner's EVM address; also used as the intent creator.
|
|
@@ -37353,6 +38856,25 @@ var PartnerFeeClaimService = class {
|
|
|
37353
38856
|
this.config.solver.protocolIntentsContract,
|
|
37354
38857
|
"protocolIntentsContract is not configured in solver config"
|
|
37355
38858
|
);
|
|
38859
|
+
const prefs = await this.getAutoSwapPreferences(params.srcAddress);
|
|
38860
|
+
if (!prefs.ok) return prefs;
|
|
38861
|
+
if (prefs.value.outputToken.toLowerCase() === params.fromToken.toLowerCase()) {
|
|
38862
|
+
return {
|
|
38863
|
+
ok: false,
|
|
38864
|
+
error: new SodaxError(
|
|
38865
|
+
"VALIDATION_FAILED",
|
|
38866
|
+
"Auto-swap output token equals the fee token; the solver cannot swap a token into itself. Withdraw the fee token directly (bridge/transfer) or change the swap preference before claiming.",
|
|
38867
|
+
{
|
|
38868
|
+
feature: "partner",
|
|
38869
|
+
context: {
|
|
38870
|
+
action: "createIntentAutoSwap",
|
|
38871
|
+
fromToken: params.fromToken,
|
|
38872
|
+
outputToken: prefs.value.outputToken
|
|
38873
|
+
}
|
|
38874
|
+
}
|
|
38875
|
+
)
|
|
38876
|
+
};
|
|
38877
|
+
}
|
|
37356
38878
|
const minOutputAmount = 0n;
|
|
37357
38879
|
const rawTx = {
|
|
37358
38880
|
from: params.srcAddress,
|
|
@@ -37400,47 +38922,218 @@ var PartnerFeeClaimService = class {
|
|
|
37400
38922
|
*
|
|
37401
38923
|
* On failure the `error` is tagged:
|
|
37402
38924
|
* - `WAIT_INTENT_AUTO_SWAP_FAILED` — transaction was submitted but receipt polling failed.
|
|
37403
|
-
* - Error from `createIntentAutoSwap` — if the initial submission failed
|
|
38925
|
+
* - Error from `createIntentAutoSwap` — if the initial submission failed, including
|
|
38926
|
+
* `VALIDATION_FAILED` when the output token equals the fee token (same-token guard) or the
|
|
38927
|
+
* preference lookup that backs the guard fails.
|
|
37404
38928
|
* - Error from `SolverApiService.postExecution` — if the solver notification failed.
|
|
37405
38929
|
*/
|
|
37406
38930
|
async swap(_params) {
|
|
37407
|
-
|
|
37408
|
-
|
|
37409
|
-
|
|
37410
|
-
|
|
38931
|
+
return this.config.analytics.trackResult(
|
|
38932
|
+
"partner",
|
|
38933
|
+
"swap",
|
|
38934
|
+
async () => {
|
|
38935
|
+
try {
|
|
38936
|
+
const txHash = await this.createIntentAutoSwap(_params);
|
|
38937
|
+
if (!txHash.ok) {
|
|
38938
|
+
return txHash;
|
|
38939
|
+
}
|
|
38940
|
+
let intentTxHash;
|
|
38941
|
+
try {
|
|
38942
|
+
const receipt = await this.hubProvider.publicClient.waitForTransactionReceipt({ hash: txHash.value });
|
|
38943
|
+
intentTxHash = receipt.transactionHash;
|
|
38944
|
+
} catch (error) {
|
|
38945
|
+
return {
|
|
38946
|
+
ok: false,
|
|
38947
|
+
error: new SodaxError(
|
|
38948
|
+
"EXECUTION_FAILED",
|
|
38949
|
+
error instanceof Error ? error.message : "waitIntentAutoSwap failed",
|
|
38950
|
+
{ feature: "partner", cause: error, context: { action: "waitAutoSwap", phase: "execution" } }
|
|
38951
|
+
)
|
|
38952
|
+
};
|
|
38953
|
+
}
|
|
38954
|
+
const solverExecutionResponse = await SolverApiService.postExecution(
|
|
38955
|
+
{ intent_tx_hash: intentTxHash },
|
|
38956
|
+
this.config.solver,
|
|
38957
|
+
this.config.logger
|
|
38958
|
+
);
|
|
38959
|
+
if (!solverExecutionResponse.ok) {
|
|
38960
|
+
return solverExecutionResponse;
|
|
38961
|
+
}
|
|
38962
|
+
return {
|
|
38963
|
+
ok: true,
|
|
38964
|
+
value: {
|
|
38965
|
+
srcTxHash: txHash.value,
|
|
38966
|
+
solverExecutionResponse: solverExecutionResponse.value,
|
|
38967
|
+
intentTxHash
|
|
38968
|
+
}
|
|
38969
|
+
};
|
|
38970
|
+
} catch (error) {
|
|
38971
|
+
return { ok: false, error };
|
|
38972
|
+
}
|
|
38973
|
+
},
|
|
38974
|
+
{
|
|
38975
|
+
start: () => ({
|
|
38976
|
+
srcChainKey: _params.params.srcChainKey,
|
|
38977
|
+
srcAddress: _params.params.srcAddress,
|
|
38978
|
+
fromToken: _params.params.fromToken,
|
|
38979
|
+
amount: _params.params.amount
|
|
38980
|
+
}),
|
|
38981
|
+
success: (value) => ({
|
|
38982
|
+
srcTxHash: value.srcTxHash,
|
|
38983
|
+
intentTxHash: value.intentTxHash
|
|
38984
|
+
}),
|
|
38985
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
37411
38986
|
}
|
|
37412
|
-
|
|
37413
|
-
|
|
37414
|
-
|
|
37415
|
-
|
|
37416
|
-
|
|
38987
|
+
);
|
|
38988
|
+
}
|
|
38989
|
+
/**
|
|
38990
|
+
* Cancels a partner fee-claim auto-swap intent and refunds the input token to the partner.
|
|
38991
|
+
*
|
|
38992
|
+
* This targets the ProtocolIntents contract's own `cancelIntent(fromToken, toToken)`, which is
|
|
38993
|
+
* the only authorized cancel path for partner auto-swap intents: the intent's `creator` is the
|
|
38994
|
+
* ProtocolIntents contract (not the partner), so the generic `SwapService.cancelIntent` reverts
|
|
38995
|
+
* with `Unauthorized()`. ProtocolIntents looks up the caller's intent for the token pair, cancels
|
|
38996
|
+
* it in the main intents contract (as the creator), and transfers the locked `inputAmount` back
|
|
38997
|
+
* to the partner (`msg.sender`).
|
|
38998
|
+
*
|
|
38999
|
+
* Use this to recover funds stuck in an unfillable intent — most commonly a same-token claim
|
|
39000
|
+
* (`fromToken === toToken`) the solver refused to fill (see the guard in {@link swap}).
|
|
39001
|
+
*
|
|
39002
|
+
* @param _params - Action descriptor containing:
|
|
39003
|
+
* - `params.srcChainKey` — must be the hub chain key (Sonic).
|
|
39004
|
+
* - `params.srcAddress` — the partner's EVM address; must match the intent's owner.
|
|
39005
|
+
* - `params.fromToken` — the stuck intent's input (fee) token, hub-chain address.
|
|
39006
|
+
* - `params.toToken` — the stuck intent's output token, hub-chain address.
|
|
39007
|
+
* - `raw` — when `true`, returns the unsigned transaction object instead of submitting it.
|
|
39008
|
+
* - `walletProvider` — required when `raw` is `false`; must be an EVM wallet provider.
|
|
39009
|
+
* @returns A `Result` containing the submitted transaction hash (`raw: false`) or the unsigned
|
|
39010
|
+
* raw transaction (`raw: true`).
|
|
39011
|
+
*/
|
|
39012
|
+
async cancelIntent(_params) {
|
|
39013
|
+
return this.config.analytics.trackResult(
|
|
39014
|
+
"partner",
|
|
39015
|
+
"cancelIntent",
|
|
39016
|
+
async () => {
|
|
39017
|
+
const { params } = _params;
|
|
39018
|
+
try {
|
|
39019
|
+
invariant(isHubChainKeyType(params.srcChainKey), "PartnerFeeClaimService only supports Hub srcChainKey");
|
|
39020
|
+
invariant(
|
|
39021
|
+
isOptionalEvmWalletProviderType(_params.walletProvider),
|
|
39022
|
+
"PartnerFeeClaimService only supports Evm wallet provider"
|
|
39023
|
+
);
|
|
39024
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
39025
|
+
const rawTx = {
|
|
39026
|
+
from: params.srcAddress,
|
|
39027
|
+
to: this.protocolIntentsContract,
|
|
39028
|
+
value: 0n,
|
|
39029
|
+
data: encodeFunctionData({
|
|
39030
|
+
abi: ProtocolIntentsAbi,
|
|
39031
|
+
functionName: "cancelIntent",
|
|
39032
|
+
args: [params.fromToken, params.toToken]
|
|
39033
|
+
})
|
|
39034
|
+
};
|
|
39035
|
+
if (_params.raw) {
|
|
39036
|
+
return {
|
|
39037
|
+
ok: true,
|
|
39038
|
+
value: rawTx
|
|
39039
|
+
};
|
|
39040
|
+
}
|
|
39041
|
+
const txHash = await _params.walletProvider.sendTransaction(rawTx);
|
|
39042
|
+
return {
|
|
39043
|
+
ok: true,
|
|
39044
|
+
value: txHash
|
|
39045
|
+
};
|
|
39046
|
+
} catch (error) {
|
|
39047
|
+
return { ok: false, error };
|
|
39048
|
+
}
|
|
39049
|
+
},
|
|
39050
|
+
{
|
|
39051
|
+
start: () => ({
|
|
39052
|
+
srcChainKey: _params.params.srcChainKey,
|
|
39053
|
+
srcAddress: _params.params.srcAddress,
|
|
39054
|
+
fromToken: _params.params.fromToken,
|
|
39055
|
+
toToken: _params.params.toToken
|
|
39056
|
+
}),
|
|
39057
|
+
success: (value) => ({ txHash: value }),
|
|
39058
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
39059
|
+
}
|
|
39060
|
+
);
|
|
39061
|
+
}
|
|
39062
|
+
/**
|
|
39063
|
+
* Returns the stored intent hash for a partner's `(user, fromToken, toToken)` token pair.
|
|
39064
|
+
*
|
|
39065
|
+
* A non-zero hash means an auto-swap intent currently exists for that pair (e.g. an unfilled
|
|
39066
|
+
* same-token claim) and can be cancelled via {@link cancelIntent}. A zero hash
|
|
39067
|
+
* (`0x000…0`) means there is no open intent for the pair.
|
|
39068
|
+
*
|
|
39069
|
+
* @param params.user - The partner's EVM address on Sonic.
|
|
39070
|
+
* @param params.fromToken - Input (fee) token, hub-chain address.
|
|
39071
|
+
* @param params.toToken - Output token, hub-chain address.
|
|
39072
|
+
* @returns A `Result` containing the intent hash, or an `Error` tagged `LOOKUP_FAILED`.
|
|
39073
|
+
*/
|
|
39074
|
+
async getUserIntent({ user, fromToken, toToken }) {
|
|
39075
|
+
try {
|
|
39076
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
39077
|
+
const intentHash = await this.hubProvider.publicClient.readContract({
|
|
39078
|
+
address: this.protocolIntentsContract,
|
|
39079
|
+
abi: ProtocolIntentsAbi,
|
|
39080
|
+
functionName: "getUserIntent",
|
|
39081
|
+
args: [user, fromToken, toToken]
|
|
39082
|
+
});
|
|
39083
|
+
return { ok: true, value: intentHash };
|
|
39084
|
+
} catch (error) {
|
|
39085
|
+
return { ok: false, error: lookupFailed("partner", "getUserIntent", error) };
|
|
39086
|
+
}
|
|
39087
|
+
}
|
|
39088
|
+
/**
|
|
39089
|
+
* Reads the full {@link Intent} details for a stored intent hash from the ProtocolIntents contract.
|
|
39090
|
+
*
|
|
39091
|
+
* Useful for displaying a stuck intent before cancelling it — e.g. the locked `inputAmount` and
|
|
39092
|
+
* `inputToken`. Pair with {@link getUserIntent} to resolve the hash from a token pair.
|
|
39093
|
+
*
|
|
39094
|
+
* @param intentHash - The intent hash (from {@link getUserIntent}).
|
|
39095
|
+
* @returns A `Result` containing the `Intent`, or an `Error` tagged `LOOKUP_FAILED`.
|
|
39096
|
+
*/
|
|
39097
|
+
async getIntentDetails(intentHash) {
|
|
39098
|
+
try {
|
|
39099
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
39100
|
+
const intent = await this.hubProvider.publicClient.readContract({
|
|
39101
|
+
address: this.protocolIntentsContract,
|
|
39102
|
+
abi: ProtocolIntentsAbi,
|
|
39103
|
+
functionName: "getIntentDetails",
|
|
39104
|
+
args: [intentHash]
|
|
39105
|
+
});
|
|
39106
|
+
if (!this.config.isValidIntentRelayChainId(intent.srcChain) || !this.config.isValidIntentRelayChainId(intent.dstChain)) {
|
|
37417
39107
|
return {
|
|
37418
39108
|
ok: false,
|
|
37419
|
-
error:
|
|
37420
|
-
"
|
|
37421
|
-
|
|
37422
|
-
|
|
39109
|
+
error: lookupFailed(
|
|
39110
|
+
"partner",
|
|
39111
|
+
"getIntentDetails",
|
|
39112
|
+
new Error(`Invalid intent relay chain id: ${intent.srcChain} or ${intent.dstChain}`)
|
|
37423
39113
|
)
|
|
37424
39114
|
};
|
|
37425
39115
|
}
|
|
37426
|
-
const solverExecutionResponse = await SolverApiService.postExecution(
|
|
37427
|
-
{ intent_tx_hash: intentTxHash },
|
|
37428
|
-
this.config.solver,
|
|
37429
|
-
this.config.logger
|
|
37430
|
-
);
|
|
37431
|
-
if (!solverExecutionResponse.ok) {
|
|
37432
|
-
return solverExecutionResponse;
|
|
37433
|
-
}
|
|
37434
39116
|
return {
|
|
37435
39117
|
ok: true,
|
|
37436
39118
|
value: {
|
|
37437
|
-
|
|
37438
|
-
|
|
37439
|
-
|
|
39119
|
+
intentId: intent.intentId,
|
|
39120
|
+
creator: intent.creator,
|
|
39121
|
+
inputToken: intent.inputToken,
|
|
39122
|
+
outputToken: intent.outputToken,
|
|
39123
|
+
inputAmount: intent.inputAmount,
|
|
39124
|
+
minOutputAmount: intent.minOutputAmount,
|
|
39125
|
+
deadline: intent.deadline,
|
|
39126
|
+
allowPartialFill: intent.allowPartialFill,
|
|
39127
|
+
srcChain: intent.srcChain,
|
|
39128
|
+
dstChain: intent.dstChain,
|
|
39129
|
+
srcAddress: intent.srcAddress,
|
|
39130
|
+
dstAddress: intent.dstAddress,
|
|
39131
|
+
solver: intent.solver,
|
|
39132
|
+
data: intent.data
|
|
37440
39133
|
}
|
|
37441
39134
|
};
|
|
37442
39135
|
} catch (error) {
|
|
37443
|
-
return { ok: false, error };
|
|
39136
|
+
return { ok: false, error: lookupFailed("partner", "getIntentDetails", error) };
|
|
37444
39137
|
}
|
|
37445
39138
|
}
|
|
37446
39139
|
};
|
|
@@ -37575,42 +39268,62 @@ var RecoveryService = class {
|
|
|
37575
39268
|
* transaction object when `raw: true`, or the broadcast transaction hash when `raw: false`.
|
|
37576
39269
|
*/
|
|
37577
39270
|
async withdrawHubAsset(_params) {
|
|
37578
|
-
|
|
37579
|
-
|
|
37580
|
-
|
|
37581
|
-
|
|
37582
|
-
{
|
|
37583
|
-
|
|
37584
|
-
|
|
37585
|
-
|
|
37586
|
-
|
|
37587
|
-
|
|
37588
|
-
|
|
37589
|
-
|
|
37590
|
-
|
|
37591
|
-
|
|
37592
|
-
|
|
37593
|
-
|
|
37594
|
-
|
|
37595
|
-
|
|
37596
|
-
|
|
37597
|
-
|
|
37598
|
-
|
|
37599
|
-
|
|
37600
|
-
|
|
37601
|
-
|
|
37602
|
-
|
|
37603
|
-
|
|
37604
|
-
|
|
37605
|
-
|
|
37606
|
-
|
|
37607
|
-
|
|
37608
|
-
|
|
37609
|
-
|
|
37610
|
-
|
|
37611
|
-
|
|
37612
|
-
|
|
37613
|
-
|
|
39271
|
+
return this.config.analytics.trackResult(
|
|
39272
|
+
"recovery",
|
|
39273
|
+
"withdrawHubAsset",
|
|
39274
|
+
async () => {
|
|
39275
|
+
const { params } = _params;
|
|
39276
|
+
try {
|
|
39277
|
+
const hubWallet = await this.hubProvider.getUserHubWalletAddress(params.srcAddress, params.srcChainKey);
|
|
39278
|
+
const payload = EvmAssetManagerService.withdrawAssetData(
|
|
39279
|
+
{
|
|
39280
|
+
token: params.token,
|
|
39281
|
+
to: encodeAddress(params.srcChainKey, params.srcAddress),
|
|
39282
|
+
amount: params.amount
|
|
39283
|
+
},
|
|
39284
|
+
this.hubProvider,
|
|
39285
|
+
params.srcChainKey
|
|
39286
|
+
);
|
|
39287
|
+
const coreParams = {
|
|
39288
|
+
srcChainKey: params.srcChainKey,
|
|
39289
|
+
srcAddress: params.srcAddress,
|
|
39290
|
+
dstChainKey: this.hubProvider.chainConfig.chain.key,
|
|
39291
|
+
dstAddress: hubWallet,
|
|
39292
|
+
payload
|
|
39293
|
+
};
|
|
39294
|
+
const sendMessageParams = _params.raw ? { ...coreParams, raw: true } : {
|
|
39295
|
+
...coreParams,
|
|
39296
|
+
raw: false,
|
|
39297
|
+
walletProvider: _params.walletProvider
|
|
39298
|
+
};
|
|
39299
|
+
const txResult = await this.spoke.sendMessage(sendMessageParams);
|
|
39300
|
+
if (!txResult.ok) return txResult;
|
|
39301
|
+
return {
|
|
39302
|
+
ok: true,
|
|
39303
|
+
value: txResult.value
|
|
39304
|
+
};
|
|
39305
|
+
} catch (error) {
|
|
39306
|
+
return {
|
|
39307
|
+
ok: false,
|
|
39308
|
+
error: new SodaxError(
|
|
39309
|
+
"EXECUTION_FAILED",
|
|
39310
|
+
error instanceof Error ? error.message : "withdrawHubAsset failed",
|
|
39311
|
+
{ feature: "recovery", cause: error, context: { action: "withdrawHubAsset", phase: "execution" } }
|
|
39312
|
+
)
|
|
39313
|
+
};
|
|
39314
|
+
}
|
|
39315
|
+
},
|
|
39316
|
+
{
|
|
39317
|
+
start: () => ({
|
|
39318
|
+
srcChainKey: _params.params.srcChainKey,
|
|
39319
|
+
srcAddress: _params.params.srcAddress,
|
|
39320
|
+
token: _params.params.token,
|
|
39321
|
+
amount: _params.params.amount
|
|
39322
|
+
}),
|
|
39323
|
+
success: (value) => ({ txHash: typeof value === "string" ? value : void 0 }),
|
|
39324
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
39325
|
+
}
|
|
39326
|
+
);
|
|
37614
39327
|
}
|
|
37615
39328
|
};
|
|
37616
39329
|
|
|
@@ -37712,7 +39425,7 @@ var LeverageYieldService = class {
|
|
|
37712
39425
|
}
|
|
37713
39426
|
/** Looks up a vault by its `name` field. Returns `undefined` when not registered. */
|
|
37714
39427
|
getVault(name) {
|
|
37715
|
-
return this.listVaults().find((
|
|
39428
|
+
return this.listVaults().find((v6) => v6.name === name);
|
|
37716
39429
|
}
|
|
37717
39430
|
/**
|
|
37718
39431
|
* Looks up a registered vault by its on-chain proxy address (case-insensitive).
|
|
@@ -37720,7 +39433,7 @@ var LeverageYieldService = class {
|
|
|
37720
39433
|
*/
|
|
37721
39434
|
getVaultByAddress(address) {
|
|
37722
39435
|
const normalized = address.toLowerCase();
|
|
37723
|
-
return this.listVaults().find((
|
|
39436
|
+
return this.listVaults().find((v6) => v6.vault.toLowerCase() === normalized);
|
|
37724
39437
|
}
|
|
37725
39438
|
/**
|
|
37726
39439
|
* Resolves the intent `deadline`: returns the caller-supplied value verbatim, otherwise
|
|
@@ -38070,70 +39783,93 @@ var LeverageYieldService = class {
|
|
|
38070
39783
|
const { params } = _params;
|
|
38071
39784
|
const srcChainKey = params.srcChainKey;
|
|
38072
39785
|
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "vaultSwap" };
|
|
38073
|
-
|
|
38074
|
-
|
|
38075
|
-
|
|
38076
|
-
|
|
38077
|
-
|
|
38078
|
-
|
|
38079
|
-
|
|
38080
|
-
|
|
38081
|
-
|
|
38082
|
-
|
|
38083
|
-
|
|
38084
|
-
|
|
38085
|
-
|
|
38086
|
-
|
|
38087
|
-
|
|
38088
|
-
|
|
38089
|
-
|
|
38090
|
-
|
|
38091
|
-
|
|
38092
|
-
|
|
38093
|
-
|
|
38094
|
-
|
|
38095
|
-
|
|
38096
|
-
|
|
38097
|
-
|
|
38098
|
-
|
|
38099
|
-
|
|
38100
|
-
|
|
38101
|
-
|
|
39786
|
+
return this.config.analytics.trackResult(
|
|
39787
|
+
"leverageYield",
|
|
39788
|
+
"vaultSwap",
|
|
39789
|
+
async () => {
|
|
39790
|
+
try {
|
|
39791
|
+
const timeout = _params.timeout;
|
|
39792
|
+
const createIntentResult = await this.createVaultIntent(_params);
|
|
39793
|
+
if (!createIntentResult.ok) {
|
|
39794
|
+
return { ok: false, error: createIntentResult.error };
|
|
39795
|
+
}
|
|
39796
|
+
const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
|
|
39797
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
39798
|
+
txHash: spokeTxHash,
|
|
39799
|
+
chainKey: srcChainKey
|
|
39800
|
+
});
|
|
39801
|
+
if (!verifyTxHashResult.ok) {
|
|
39802
|
+
return {
|
|
39803
|
+
ok: false,
|
|
39804
|
+
error: verifyFailed("leverageYield", verifyTxHashResult.error, baseCtx)
|
|
39805
|
+
};
|
|
39806
|
+
}
|
|
39807
|
+
let dstIntentTxHash;
|
|
39808
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
39809
|
+
dstIntentTxHash = spokeTxHash;
|
|
39810
|
+
} else {
|
|
39811
|
+
const packet = await relayTxAndWaitPacket({
|
|
39812
|
+
srcTxHash: spokeTxHash,
|
|
39813
|
+
data: relayData,
|
|
39814
|
+
chainKey: srcChainKey,
|
|
39815
|
+
relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
|
|
39816
|
+
timeout
|
|
39817
|
+
});
|
|
39818
|
+
if (!packet.ok) {
|
|
39819
|
+
return {
|
|
39820
|
+
ok: false,
|
|
39821
|
+
error: mapRelayFailure(packet.error, { feature: "leverageYield", ...baseCtx })
|
|
39822
|
+
};
|
|
39823
|
+
}
|
|
39824
|
+
dstIntentTxHash = packet.value.dst_tx_hash;
|
|
39825
|
+
}
|
|
39826
|
+
const postExecResult = await this.notifySolver({
|
|
39827
|
+
intent_tx_hash: dstIntentTxHash
|
|
39828
|
+
});
|
|
39829
|
+
if (!postExecResult.ok) {
|
|
39830
|
+
return { ok: false, error: postExecResult.error };
|
|
39831
|
+
}
|
|
39832
|
+
return {
|
|
39833
|
+
ok: true,
|
|
39834
|
+
value: {
|
|
39835
|
+
solverExecutionResponse: postExecResult.value,
|
|
39836
|
+
intent,
|
|
39837
|
+
intentDeliveryInfo: {
|
|
39838
|
+
srcChainKey,
|
|
39839
|
+
srcTxHash: spokeTxHash,
|
|
39840
|
+
srcAddress: params.srcAddress,
|
|
39841
|
+
dstChainKey: params.dstChainKey,
|
|
39842
|
+
dstTxHash: dstIntentTxHash,
|
|
39843
|
+
dstAddress: params.dstAddress
|
|
39844
|
+
}
|
|
39845
|
+
}
|
|
39846
|
+
};
|
|
39847
|
+
} catch (error) {
|
|
39848
|
+
if (isLeverageYieldSwapError(error)) return { ok: false, error };
|
|
38102
39849
|
return {
|
|
38103
39850
|
ok: false,
|
|
38104
|
-
error:
|
|
39851
|
+
error: unknownFailed("leverageYield", error, baseCtx)
|
|
38105
39852
|
};
|
|
38106
39853
|
}
|
|
38107
|
-
|
|
38108
|
-
|
|
38109
|
-
|
|
38110
|
-
|
|
38111
|
-
|
|
38112
|
-
|
|
38113
|
-
|
|
39854
|
+
},
|
|
39855
|
+
{
|
|
39856
|
+
start: () => ({
|
|
39857
|
+
srcChainKey: _params.params.srcChainKey,
|
|
39858
|
+
dstChainKey: _params.params.dstChainKey,
|
|
39859
|
+
srcAddress: _params.params.srcAddress,
|
|
39860
|
+
dstAddress: _params.params.dstAddress,
|
|
39861
|
+
inputToken: _params.params.inputToken,
|
|
39862
|
+
outputToken: _params.params.outputToken,
|
|
39863
|
+
inputAmount: _params.params.inputAmount
|
|
39864
|
+
}),
|
|
39865
|
+
success: (value) => ({
|
|
39866
|
+
intentId: value.intent.intentId,
|
|
39867
|
+
srcTxHash: value.intentDeliveryInfo.srcTxHash,
|
|
39868
|
+
dstTxHash: value.intentDeliveryInfo.dstTxHash
|
|
39869
|
+
}),
|
|
39870
|
+
failure: (error) => ({ code: error.code })
|
|
38114
39871
|
}
|
|
38115
|
-
|
|
38116
|
-
ok: true,
|
|
38117
|
-
value: {
|
|
38118
|
-
solverExecutionResponse: postExecResult.value,
|
|
38119
|
-
intent,
|
|
38120
|
-
intentDeliveryInfo: {
|
|
38121
|
-
srcChainKey,
|
|
38122
|
-
srcTxHash: spokeTxHash,
|
|
38123
|
-
srcAddress: params.srcAddress,
|
|
38124
|
-
dstChainKey: params.dstChainKey,
|
|
38125
|
-
dstTxHash: dstIntentTxHash,
|
|
38126
|
-
dstAddress: params.dstAddress
|
|
38127
|
-
}
|
|
38128
|
-
}
|
|
38129
|
-
};
|
|
38130
|
-
} catch (error) {
|
|
38131
|
-
if (isLeverageYieldSwapError(error)) return { ok: false, error };
|
|
38132
|
-
return {
|
|
38133
|
-
ok: false,
|
|
38134
|
-
error: unknownFailed("leverageYield", error, baseCtx)
|
|
38135
|
-
};
|
|
38136
|
-
}
|
|
39872
|
+
);
|
|
38137
39873
|
}
|
|
38138
39874
|
/**
|
|
38139
39875
|
* Notifies the solver that the vault intent landed on the hub, triggering it to fill.
|
|
@@ -38490,6 +40226,8 @@ var Sodax = class {
|
|
|
38490
40226
|
// ICX migration service enabling ICX migration to SODA
|
|
38491
40227
|
backendApi;
|
|
38492
40228
|
// backend API service enabling backend API endpoints
|
|
40229
|
+
api;
|
|
40230
|
+
// syntactic sugar for backend API service
|
|
38493
40231
|
bridge;
|
|
38494
40232
|
// Bridge service enabling cross-chain transfers
|
|
38495
40233
|
staking;
|
|
@@ -38510,14 +40248,18 @@ var Sodax = class {
|
|
|
38510
40248
|
// spoke service enabling spoke chain operations
|
|
38511
40249
|
constructor(options) {
|
|
38512
40250
|
const logger = resolveLogger(options?.logger);
|
|
40251
|
+
const analytics = resolveAnalytics(options?.analytics);
|
|
38513
40252
|
const fee = options?.fee;
|
|
40253
|
+
const useBackendSubmitTx = options?.swapsOptions?.useBackendSubmitTx ?? false;
|
|
38514
40254
|
this.instanceConfig = options ? mergeSodaxConfig(sodaxConfig, options) : sodaxConfig;
|
|
38515
40255
|
this.backendApi = new BackendApiService(this.instanceConfig.api, logger);
|
|
40256
|
+
this.api = this.backendApi;
|
|
38516
40257
|
this.config = new ConfigService({
|
|
38517
40258
|
api: this.backendApi,
|
|
38518
40259
|
config: this.instanceConfig,
|
|
38519
40260
|
userConfig: options,
|
|
38520
40261
|
logger,
|
|
40262
|
+
analytics,
|
|
38521
40263
|
fee
|
|
38522
40264
|
});
|
|
38523
40265
|
this.hubProvider = new EvmHubProvider({ config: this.config });
|
|
@@ -38525,7 +40267,9 @@ var Sodax = class {
|
|
|
38525
40267
|
this.swaps = new SwapService({
|
|
38526
40268
|
config: this.config,
|
|
38527
40269
|
hubProvider: this.hubProvider,
|
|
38528
|
-
spoke: this.spoke
|
|
40270
|
+
spoke: this.spoke,
|
|
40271
|
+
backendApi: this.backendApi,
|
|
40272
|
+
useBackendSubmitTx
|
|
38529
40273
|
});
|
|
38530
40274
|
this.moneyMarket = new MoneyMarketService({
|
|
38531
40275
|
config: this.config,
|
|
@@ -38599,4 +40343,4 @@ var isPartnerError = isCodeMember(PARTNER_CODES);
|
|
|
38599
40343
|
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
38600
40344
|
*/
|
|
38601
40345
|
|
|
38602
|
-
export { ALLOWANCE_CHECK_CODES, APPROVE_CODES, AssetService, BITCOIN_CHAIN_KEYS, BITCOIN_CHAIN_KEYS_SET, BTC_WALLET_ADDRESS_TYPES, BackendApiService, BalnSwapService, BigIntToHex, BigNumberZeroDecimal, BitcoinSpokeService, BnUSDMigrationService, BridgeService, CHAIN_KEYS, CHAIN_LOGO_BASE_URL, CONFIG_VERSION, CREATE_INTENT_CODES, ChainKeys, ChainTypeArr, ClService, ConfigService, CustomSorobanServer, CustomStellarAccount, DEFAULT_BACKEND_API_ENDPOINT, DEFAULT_BACKEND_API_HEADERS, DEFAULT_BACKEND_API_TIMEOUT, DEFAULT_DEADLINE_OFFSET, DEFAULT_MAX_RETRY, DEFAULT_RELAYER_API_ENDPOINT, DEFAULT_RELAY_TX_TIMEOUT, DEFAULT_RETRY_DELAY_MS, DexService, EVM_CHAIN_ID_TO_KEY, EVM_CHAIN_KEYS, EVM_CHAIN_KEYS_SET, EVM_SPOKE_ONLY_CHAIN_KEYS, EVM_SPOKE_ONLY_CHAIN_KEYS_SET, Erc20Service, Erc4626Service, EvmAssetManagerService, EvmHubProvider, EvmSolverService, EvmSpokeService, EvmVaultTokenService, FEE_PERCENTAGE_SCALE, GAS_ESTIMATION_CODES, HALF_RAY, HALF_WAD, HUB_CHAIN_KEY, HookKind, HookService, HttpRelayError, HubVaultSymbols, ICON_CHAIN_KEYS, ICON_CHAIN_KEYS_SET, ICON_TX_RESULT_WAIT_MAX_RETRY, INJECTIVE_CHAIN_KEYS, INJECTIVE_CHAIN_KEYS_SET, INTENT_CHAIN_IDS, IconSpokeService, IcxMigrationService, Injective20Token, InjectiveSpokeService, IntentCreatedEventAbi, IntentDataService, IntentDataType, IntentFilledEventAbi, IntentRelayChainIdToChainKey, IntentsAbi, LOOKUP_CODES, LTV_PRECISION, LendingPoolService, LeverageYieldService, LockupMultiplier, LockupPeriod, LsodaSymbols, LsodaTokens, MAX_UINT256, MigrationService, MintPositionEventAbi, MoneyMarketDataService, MoneyMarketService, NEAR_CHAIN_KEYS, NEAR_CHAIN_KEYS_SET, NEAR_DEFAULT_GAS, NEAR_STORAGE_DEPOSIT, NearSpokeService, PartnerFeeClaimService, PartnerService, Permit2Service, ProtocolIntentsAbi, RAY, RAY_DECIMALS, RELAY_ERROR_CODES, RadfiApiError, RadfiProvider, RecoveryService, RelayChainIdMap, SECONDS_PER_YEAR, SODAX_ERROR_CODES, SODAX_FEATURES, SOLANA_CHAIN_KEYS, SOLANA_CHAIN_KEYS_SET, SONIC_CHAIN_KEYS, SONIC_CHAIN_KEYS_SET, STACKS_CHAIN_KEYS, STACKS_CHAIN_KEYS_SET, STELLAR_CHAIN_KEYS, STELLAR_CHAIN_KEYS_SET, SUI_CHAIN_KEYS, SUI_CHAIN_KEYS_SET, SodaTokens, Sodax, SodaxError, SolanaSpokeService, SolverApiService, SolverIntentErrorCode, SolverIntentStatusCode, SonicSpokeService, SpokeService, StacksSpokeService, StakingLogic, StakingService, StatATokenAddresses, StellarSpokeService, SuiSpokeService, SupportedMigrationTokens, SwapService, USD_DECIMALS, UiPoolDataProviderService, VAULT_TOKEN_DECIMALS, WAD, WAD_RAY_RATIO, WEI_DECIMALS, adjustAmountByFee, allowanceCheckFailed, apiConfig, approveFailed, arbitrumSupportedTokens, assetManagerAbi, avalancheSupportedTokens, balnSwapAbi, baseChainInfo, baseSupportedTokens, binomialApproximatedRayPow, bitcoinSupportedTokens, bnUSDLegacySpokeChainIds, bnUSDLegacyTokens, bridgeConfig, bridgeInvariant, bscSupportedTokens, calcOpReturnOutputVbytes, calculateAllReserveIncentives, calculateAllUserIncentives, calculateAvailableBorrowsMarketReferenceCurrency, calculateCompoundedInterest, calculateCompoundedRate, calculateFeeAmount, calculateHealthFactorFromBalances, calculateHealthFactorFromBalancesBigUnits, calculateLinearInterest, calculatePercentageFeeAmount, clPoolAbi, clPoolManagerAbi, clPositionManagerAbi, clQuoterAbi, clRouterAbi, clTickLensAbi, concentratedLiquidityConfig, connectionAbi, consoleLogger, convertTransactionInstructionToRaw, createInvariant, deepMerge, defaultHookAbi, detectBitcoinAddressType, dexConfig, dexInvariant, dexPools, encodeAddress, encodeBtcPayloadToBytes, encodeContractCalls, erc20Abi, erc4626Abi, estimateBitcoinTxSize, ethereumSupportedTokens, executionFailed, formatBasisPoints, formatEModeCategory, formatEModes, formatPercentage, formatReserve, formatReserveUSD, formatReserves, formatReservesAndIncentives, formatUserSummary, formatUserSummaryAndIncentives, gasEstimationFailed, getAllLegacybnUSDTokens, getAndFormatReserveEModes, getAssetManagerIdl, getAssetManagerProgram, getChainKeyFromRelayChainId, getChainType, getCompoundedBalance, getConcentratedLiquidityConfig, getConnectionIdl, getConnectionProgram, getEvmChainKeyByChainId, getEvmViemChain, getIconAddressBytes, getIntentRelayChainId, getLinearBalance, getMarketReferenceCurrencyAndUsdBalance, getPacket, getProvider, getRandomBytes, getReserveNormalizedIncome, getReservesEModes, getSolanaAddressBytes, getSolverConfig, getSpokeHook, getSpokeHooks, getStagingSolverTokens, getSupportedSolverTokens, getTransactionPackets, getbnUSDToken, hexToBigInt, hexToSolanaAddress, hubConfig, hyper, hyperevmSupportedTokens, iconSupportedTokens, injectiveSupportedTokens, intentCreationFailed, isBalnMigrateParams, isBitcoinChainKey, isBitcoinChainKeyType, isBitcoinWalletProviderType, isBridgeAllowanceCheckError, isBridgeApproveError, isBridgeCreateIntentError, isBridgeError, isBridgeLookupError, isBridgeOrchestrationError, isCodeMember, isDexError, isEvmChainKey, isEvmChainKeyType, isEvmSpokeChainConfig, isEvmSpokeOnlyChainKey, isEvmSpokeOnlyChainKeyType, isEvmWalletProviderType, isFeatureError, isHookSupportedToken, isHubChainKey, isHubChainKeyType, isIconAddress, isIconChainKey, isIconChainKeyType, isIcxCreateRevertMigrationParams, isIcxMigrateParams, isInjectiveChainKey, isInjectiveChainKeyType, isJsonRpcPayloadResponse, isLegacybnUSDChainId, isLegacybnUSDToken, isLeverageYieldAllowanceCheckError, isLeverageYieldApproveError, isLeverageYieldCreateIntentError, isLeverageYieldError, isLeverageYieldLookupError, isLeverageYieldPostExecutionError, isLeverageYieldSwapError, isMigrateOrchestrationError, isMigrationAllowanceCheckError, isMigrationApproveError, isMigrationCreateIntentError, isMigrationError, isMigrationLookupError, isMoneyMarketAllowanceCheckError, isMoneyMarketApproveError, isMoneyMarketCreateIntentError, isMoneyMarketError, isMoneyMarketGasEstimationError, isMoneyMarketOrchestrationError, isNativeToken, isNearChainKey, isNearChainKeyType, isNewbnUSDChainId, isNewbnUSDToken, isOptionalBitcoinWalletProviderType, isOptionalEvmWalletProviderType, isOptionalStellarWalletProviderType, isPartnerError, isPartnerFeeAmount, isPartnerFeePercentage, isPostExecutionError, isRawDestinationParams, isRecoveryError, isResponseAddressType, isResponseSigningType, isRevertMigrationOrchestrationError, isSodaxError, isSolanaChainKey, isSolanaChainKeyType, isSolanaNativeToken, isSonicChainKey, isSonicChainKeyType, isSpokeApproveParamsEvmSpoke, isSpokeApproveParamsHub, isSpokeApproveParamsStellar, isSpokeChainKey, isSpokeIsAllowanceValidParamsEvmSpoke, isSpokeIsAllowanceValidParamsHub, isSpokeIsAllowanceValidParamsStellar, isStacksChainKey, isStacksChainKeyType, isStakeOrchestrationError, isStakingAllowanceCheckError, isStakingApproveError, isStakingCreateIntentError, isStakingError, isStakingInfoFetchError, isStakingOrchestrationError, isStellarChainKey, isStellarChainKeyType, isStellarWalletProviderType,
|
|
40346
|
+
export { ALLOWANCE_CHECK_CODES, APPROVE_CODES, AssetService, BITCOIN_CHAIN_KEYS, BITCOIN_CHAIN_KEYS_SET, BTC_WALLET_ADDRESS_TYPES, BackendApiService, BalnSwapService, BigIntToHex, BigNumberZeroDecimal, BitcoinSpokeService, BnUSDMigrationService, BridgeService, CHAIN_KEYS, CHAIN_LOGO_BASE_URL, CONFIG_VERSION, CREATE_INTENT_CODES, ChainKeys, ChainTypeArr, ClService, ConfigService, CustomSorobanServer, CustomStellarAccount, DEFAULT_BACKEND_API_ENDPOINT, DEFAULT_BACKEND_API_HEADERS, DEFAULT_BACKEND_API_TIMEOUT, DEFAULT_DEADLINE_OFFSET, DEFAULT_MAX_RETRY, DEFAULT_RELAYER_API_ENDPOINT, DEFAULT_RELAY_TX_TIMEOUT, DEFAULT_RETRY_DELAY_MS, DexService, EVM_CHAIN_ID_TO_KEY, EVM_CHAIN_KEYS, EVM_CHAIN_KEYS_SET, EVM_SPOKE_ONLY_CHAIN_KEYS, EVM_SPOKE_ONLY_CHAIN_KEYS_SET, Erc20Service, Erc4626Service, EvmAssetManagerService, EvmHubProvider, EvmSolverService, EvmSpokeService, EvmVaultTokenService, FEE_PERCENTAGE_SCALE, GAS_ESTIMATION_CODES, HALF_RAY, HALF_WAD, HUB_CHAIN_KEY, HookKind, HookService, HttpRelayError, HubVaultSymbols, ICON_CHAIN_KEYS, ICON_CHAIN_KEYS_SET, ICON_TX_RESULT_WAIT_MAX_RETRY, INJECTIVE_CHAIN_KEYS, INJECTIVE_CHAIN_KEYS_SET, INTENT_CHAIN_IDS, IconSpokeService, IcxMigrationService, Injective20Token, InjectiveSpokeService, IntentCreatedEventAbi, IntentDataService, IntentDataType, IntentFilledEventAbi, IntentRelayChainIdToChainKey, IntentsAbi, LOOKUP_CODES, LTV_PRECISION, LendingPoolService, LeverageYieldService, LockupMultiplier, LockupPeriod, LsodaSymbols, LsodaTokens, MAX_UINT256, MigrationService, MintPositionEventAbi, MoneyMarketDataService, MoneyMarketService, NEAR_CHAIN_KEYS, NEAR_CHAIN_KEYS_SET, NEAR_DEFAULT_GAS, NEAR_STORAGE_DEPOSIT, NearSpokeService, PartnerFeeClaimService, PartnerService, Permit2Service, ProtocolIntentsAbi, RAY, RAY_DECIMALS, RELAY_ERROR_CODES, RadfiApiError, RadfiProvider, RecoveryService, RelayChainIdMap, SECONDS_PER_YEAR, SODAX_ERROR_CODES, SODAX_FEATURES, SOLANA_CHAIN_KEYS, SOLANA_CHAIN_KEYS_SET, SONIC_CHAIN_KEYS, SONIC_CHAIN_KEYS_SET, STACKS_CHAIN_KEYS, STACKS_CHAIN_KEYS_SET, STELLAR_CHAIN_KEYS, STELLAR_CHAIN_KEYS_SET, SUI_CHAIN_KEYS, SUI_CHAIN_KEYS_SET, SodaTokens, Sodax, SodaxError, SolanaSpokeService, SolverApiService, SolverIntentErrorCode, SolverIntentStatusCode, SonicSpokeService, SpokeService, StacksSpokeService, StakingLogic, StakingService, StatATokenAddresses, StellarSpokeService, SuiSpokeService, SupportedMigrationTokens, SwapService, SwapsApiService, USD_DECIMALS, UiPoolDataProviderService, VAULT_TOKEN_DECIMALS, WAD, WAD_RAY_RATIO, WEI_DECIMALS, adjustAmountByFee, allowanceCheckFailed, apiConfig, approveFailed, arbitrumSupportedTokens, assetManagerAbi, avalancheSupportedTokens, balnSwapAbi, baseChainInfo, baseSupportedTokens, binomialApproximatedRayPow, bitcoinSupportedTokens, bnUSDLegacySpokeChainIds, bnUSDLegacyTokens, bridgeConfig, bridgeInvariant, bscSupportedTokens, calcOpReturnOutputVbytes, calculateAllReserveIncentives, calculateAllUserIncentives, calculateAvailableBorrowsMarketReferenceCurrency, calculateCompoundedInterest, calculateCompoundedRate, calculateFeeAmount, calculateHealthFactorFromBalances, calculateHealthFactorFromBalancesBigUnits, calculateLinearInterest, calculatePercentageFeeAmount, clPoolAbi, clPoolManagerAbi, clPositionManagerAbi, clQuoterAbi, clRouterAbi, clTickLensAbi, concentratedLiquidityConfig, connectionAbi, consoleLogger, convertTransactionInstructionToRaw, createInvariant, deepMerge, defaultHookAbi, detectBitcoinAddressType, dexConfig, dexInvariant, dexPools, encodeAddress, encodeBtcPayloadToBytes, encodeContractCalls, erc20Abi, erc4626Abi, estimateBitcoinTxSize, ethereumSupportedTokens, executionFailed, formatBasisPoints, formatEModeCategory, formatEModes, formatPercentage, formatReserve, formatReserveUSD, formatReserves, formatReservesAndIncentives, formatUserSummary, formatUserSummaryAndIncentives, gasEstimationFailed, getAllLegacybnUSDTokens, getAndFormatReserveEModes, getAssetManagerIdl, getAssetManagerProgram, getChainKeyFromRelayChainId, getChainType, getCompoundedBalance, getConcentratedLiquidityConfig, getConnectionIdl, getConnectionProgram, getEvmChainKeyByChainId, getEvmViemChain, getIconAddressBytes, getIntentRelayChainId, getLinearBalance, getMarketReferenceCurrencyAndUsdBalance, getPacket, getProvider, getRandomBytes, getReserveNormalizedIncome, getReservesEModes, getSolanaAddressBytes, getSolverConfig, getSpokeHook, getSpokeHooks, getStagingSolverTokens, getSupportedSolverTokens, getTransactionPackets, getbnUSDToken, hexToBigInt, hexToSolanaAddress, hubConfig, hyper, hyperevmSupportedTokens, iconSupportedTokens, injectiveSupportedTokens, intentCreationFailed, isBalnMigrateParams, isBitcoinChainKey, isBitcoinChainKeyType, isBitcoinWalletProviderType, isBridgeAllowanceCheckError, isBridgeApproveError, isBridgeCreateIntentError, isBridgeError, isBridgeLookupError, isBridgeOrchestrationError, isCodeMember, isDexError, isEvmChainKey, isEvmChainKeyType, isEvmSpokeChainConfig, isEvmSpokeOnlyChainKey, isEvmSpokeOnlyChainKeyType, isEvmWalletProviderType, isFeatureError, isHookSupportedToken, isHubChainKey, isHubChainKeyType, isIconAddress, isIconChainKey, isIconChainKeyType, isIcxCreateRevertMigrationParams, isIcxMigrateParams, isInjectiveChainKey, isInjectiveChainKeyType, isJsonRpcPayloadResponse, isLegacybnUSDChainId, isLegacybnUSDToken, isLeverageYieldAllowanceCheckError, isLeverageYieldApproveError, isLeverageYieldCreateIntentError, isLeverageYieldError, isLeverageYieldLookupError, isLeverageYieldPostExecutionError, isLeverageYieldSwapError, isMigrateOrchestrationError, isMigrationAllowanceCheckError, isMigrationApproveError, isMigrationCreateIntentError, isMigrationError, isMigrationLookupError, isMoneyMarketAllowanceCheckError, isMoneyMarketApproveError, isMoneyMarketCreateIntentError, isMoneyMarketError, isMoneyMarketGasEstimationError, isMoneyMarketOrchestrationError, isNativeToken, isNearChainKey, isNearChainKeyType, isNewbnUSDChainId, isNewbnUSDToken, isOptionalBitcoinWalletProviderType, isOptionalEvmWalletProviderType, isOptionalStellarWalletProviderType, isPartnerError, isPartnerFeeAmount, isPartnerFeePercentage, isPostExecutionError, isRawDestinationParams, isRecoveryError, isResponseAddressType, isResponseSigningType, isRevertMigrationOrchestrationError, isSodaxError, isSolanaChainKey, isSolanaChainKeyType, isSolanaNativeToken, isSonicChainKey, isSonicChainKeyType, isSpokeApproveParamsEvmSpoke, isSpokeApproveParamsHub, isSpokeApproveParamsStellar, isSpokeChainKey, isSpokeIsAllowanceValidParamsEvmSpoke, isSpokeIsAllowanceValidParamsHub, isSpokeIsAllowanceValidParamsStellar, isStacksChainKey, isStacksChainKeyType, isStakeOrchestrationError, isStakingAllowanceCheckError, isStakingApproveError, isStakingCreateIntentError, isStakingError, isStakingInfoFetchError, isStakingOrchestrationError, isStellarChainKey, isStellarChainKeyType, isStellarWalletProviderType, isSuiChainKey, isSuiChainKeyType, isSupportedBitcoinAddressType, isSwapCreateIntentError, isSwapError, isSwapSupportedToken, isUndefinedOrValidWalletProviderForChainKey, isUnifiedBnUSDMigrateParams, isValidWalletProviderForChainKey, kaiaSupportedTokens, leverageYieldConfig, leverageYieldInvariant, leverageYieldVaults, lightlinkSupportedTokens, lookupFailed, mapRelayFailure, mergeSodaxConfig, messageOf, migrationInvariant, mintPositionParamsAbi, mmInvariant, modifyLiquidityParamsAbi, moneyMarketConfig, moneyMarketReserveAssets, moneyMarketSupportedTokens, nativeToUSD, nearSupportedTokens, newbnUSDSpokeChainIds, noopAnalytics, normalize, normalizeBN, normalizePsbtToBase64, normalizeSignatureToBase64, normalizedToUsd, optimismSupportedTokens, pancakeSwapInfinityDefaultHookAbi, pancakeSwapInfinityPoolManagerAbi, pancakeSwapInfinityPositionManagerAbi, parseToStroops, parseTokenArrayFromJson, partnerInvariant, permit2Abi, polygonSupportedTokens, poolAbi, poolKeyAbi, randomUint256, rayDiv, rayMul, rayPow, rayToWad, recoveryInvariant, redbellySupportedTokens, relayConfig, relayTxAndWaitPacket, requestAddress, requestJsonRpc, requestSigning, resolveAnalytics, resolveLogger, retry, reverseEncodeAddress, serializeAddressData, silentLogger, sleep, sodaxConfig, sodaxInvariant, solanaSupportedTokens, solverConfig, sonicSupportedTokens, sonicWalletFactoryAbi, spokeAssetManagerAbi, spokeChainConfig, spokeChainKeysSet, spokeHooks, stacksSupportedTokens, stagingSwapSupportedTokens, stakedSodaAbi, stakingInvariant, stakingRouterAbi, stataTokenFactoryAbi, stellarSupportedTokens, submitTransaction, suiSupportedTokens, supportedSpokeChains, supportedTokensByChain, swapExactInSingleParamsAbi, swapInvariant, swapSupportedTokens, swapsConfig, uiPoolDataAbi, universalRouterAbi, unknownFailed, usesBip322MessageSigning, valueToBigNumber, valueToZDBigNumber, variableDebtTokenAbi, vaultTokenAbi, verifyFailed, wadToRay, waitForStacksTransaction, waitForTransactionReceipt, waitUntilIntentExecuted, walletFactoryAbi, wrappedSonicAbi };
|