@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.cjs
CHANGED
|
@@ -19,6 +19,7 @@ var IconSdkRaw = require('icon-sdk-js');
|
|
|
19
19
|
var sdkTs = require('@injectivelabs/sdk-ts');
|
|
20
20
|
var tx_js = require('cosmjs-types/cosmos/tx/v1beta1/tx.js');
|
|
21
21
|
var networks = require('@injectivelabs/networks');
|
|
22
|
+
var v4 = require('valibot');
|
|
22
23
|
var BigNumber5 = require('bignumber.js');
|
|
23
24
|
var swapSdkCore = require('@pancakeswap/swap-sdk-core');
|
|
24
25
|
var v3Sdk = require('@pancakeswap/v3-sdk');
|
|
@@ -47,6 +48,7 @@ var rlp__namespace = /*#__PURE__*/_interopNamespace(rlp);
|
|
|
47
48
|
var ecc__namespace = /*#__PURE__*/_interopNamespace(ecc);
|
|
48
49
|
var BN__default = /*#__PURE__*/_interopDefault(BN);
|
|
49
50
|
var IconSdkRaw__namespace = /*#__PURE__*/_interopNamespace(IconSdkRaw);
|
|
51
|
+
var v4__namespace = /*#__PURE__*/_interopNamespace(v4);
|
|
50
52
|
var BigNumber5__default = /*#__PURE__*/_interopDefault(BigNumber5);
|
|
51
53
|
|
|
52
54
|
// src/errors/SodaxError.ts
|
|
@@ -119,8 +121,8 @@ function serializeCause(cause, depth) {
|
|
|
119
121
|
}
|
|
120
122
|
function sanitizeContext(value, depth) {
|
|
121
123
|
const out = {};
|
|
122
|
-
for (const [key,
|
|
123
|
-
out[key] = sanitizeValue(
|
|
124
|
+
for (const [key, v6] of Object.entries(value)) {
|
|
125
|
+
out[key] = sanitizeValue(v6, depth + 1);
|
|
124
126
|
}
|
|
125
127
|
return out;
|
|
126
128
|
}
|
|
@@ -131,13 +133,13 @@ function sanitizeValue(value, depth) {
|
|
|
131
133
|
if (t === "bigint") return value.toString();
|
|
132
134
|
if (t === "string" || t === "number" || t === "boolean") return value;
|
|
133
135
|
if (t === "function" || t === "symbol") return safeString(value);
|
|
134
|
-
if (Array.isArray(value)) return value.map((
|
|
136
|
+
if (Array.isArray(value)) return value.map((v6) => sanitizeValue(v6, depth + 1));
|
|
135
137
|
if (value instanceof Date) return value.toISOString();
|
|
136
138
|
if (value instanceof Map) {
|
|
137
|
-
return Array.from(value.entries()).map(([k,
|
|
139
|
+
return Array.from(value.entries()).map(([k, v6]) => [sanitizeValue(k, depth + 1), sanitizeValue(v6, depth + 1)]);
|
|
138
140
|
}
|
|
139
141
|
if (value instanceof Set) {
|
|
140
|
-
return Array.from(value.values()).map((
|
|
142
|
+
return Array.from(value.values()).map((v6) => sanitizeValue(v6, depth + 1));
|
|
141
143
|
}
|
|
142
144
|
if (value instanceof Error) return { name: value.name, message: value.message };
|
|
143
145
|
if (t === "object") {
|
|
@@ -149,9 +151,9 @@ function sanitizeValue(value, depth) {
|
|
|
149
151
|
}
|
|
150
152
|
return safeString(value);
|
|
151
153
|
}
|
|
152
|
-
function safeString(
|
|
154
|
+
function safeString(v6) {
|
|
153
155
|
try {
|
|
154
|
-
return String(
|
|
156
|
+
return String(v6);
|
|
155
157
|
} catch {
|
|
156
158
|
return "[unserializable]";
|
|
157
159
|
}
|
|
@@ -199,6 +201,7 @@ var SODAX_FEATURES = [
|
|
|
199
201
|
"dex",
|
|
200
202
|
"partner",
|
|
201
203
|
"recovery",
|
|
204
|
+
"backend",
|
|
202
205
|
"leverageYield"
|
|
203
206
|
];
|
|
204
207
|
|
|
@@ -2640,7 +2643,7 @@ var RelayChainIdMap = {
|
|
|
2640
2643
|
[ChainKeys.STACKS_MAINNET]: 60n
|
|
2641
2644
|
};
|
|
2642
2645
|
var INTENT_CHAIN_IDS = Object.values(RelayChainIdMap);
|
|
2643
|
-
var IntentRelayChainIdToChainKey =
|
|
2646
|
+
var IntentRelayChainIdToChainKey = new Map(Object.entries(RelayChainIdMap).map(([chainKey, chainId]) => [chainId, chainKey]));
|
|
2644
2647
|
var CHAIN_LOGO_BASE_URL = "https://raw.githubusercontent.com/icon-project/sodax-sdks/main/packages/assets/chain";
|
|
2645
2648
|
var chainLogo = (key) => `${CHAIN_LOGO_BASE_URL}/${key}.png`;
|
|
2646
2649
|
var baseChainInfo = {
|
|
@@ -4246,7 +4249,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
|
|
|
4246
4249
|
}
|
|
4247
4250
|
|
|
4248
4251
|
// ../types/dist/index.js
|
|
4249
|
-
var CONFIG_VERSION =
|
|
4252
|
+
var CONFIG_VERSION = 217;
|
|
4250
4253
|
function isEvmSpokeChainConfig(value) {
|
|
4251
4254
|
return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
|
|
4252
4255
|
}
|
|
@@ -4336,26 +4339,6 @@ function isRawDestinationParams(value) {
|
|
|
4336
4339
|
if (typeof obj.dstAddress !== "string") return false;
|
|
4337
4340
|
return typeof obj.dstChainKey === "string" && spokeChainKeysSet.has(obj.dstChainKey);
|
|
4338
4341
|
}
|
|
4339
|
-
function isSubmitSwapTxResponse(value) {
|
|
4340
|
-
return typeof value === "object" && value !== null && typeof value.success === "boolean" && typeof value.message === "string";
|
|
4341
|
-
}
|
|
4342
|
-
function isSubmitSwapTxStatusResponse(value) {
|
|
4343
|
-
if (typeof value !== "object" || value === null) return false;
|
|
4344
|
-
const obj = value;
|
|
4345
|
-
if (typeof obj.success !== "boolean") return false;
|
|
4346
|
-
if (typeof obj.data !== "object" || obj.data === null) return false;
|
|
4347
|
-
const data = obj.data;
|
|
4348
|
-
if (typeof data.txHash !== "string") return false;
|
|
4349
|
-
if (typeof data.srcChainKey !== "string") return false;
|
|
4350
|
-
if (typeof data.status !== "string") return false;
|
|
4351
|
-
if (typeof data.failedAttempts !== "number") return false;
|
|
4352
|
-
if (data.result !== void 0) {
|
|
4353
|
-
if (typeof data.result !== "object" || data.result === null) return false;
|
|
4354
|
-
const result = data.result;
|
|
4355
|
-
if (typeof result.dstIntentTxHash !== "string") return false;
|
|
4356
|
-
}
|
|
4357
|
-
return true;
|
|
4358
|
-
}
|
|
4359
4342
|
function isBitcoinWalletProviderType(wp) {
|
|
4360
4343
|
return wp.chainType === "BITCOIN";
|
|
4361
4344
|
}
|
|
@@ -4393,11 +4376,11 @@ async function retry(action, retryCount = DEFAULT_MAX_RETRY, delayMs = DEFAULT_R
|
|
|
4393
4376
|
throw new Error(`Retry exceeded MAX_RETRY_DEFAULT=${DEFAULT_MAX_RETRY}`);
|
|
4394
4377
|
}
|
|
4395
4378
|
function getRandomBytes(length) {
|
|
4396
|
-
const
|
|
4379
|
+
const array3 = new Uint8Array(length);
|
|
4397
4380
|
for (let i = 0; i < length; i++) {
|
|
4398
|
-
|
|
4381
|
+
array3[i] = Math.floor(Math.random() * 256);
|
|
4399
4382
|
}
|
|
4400
|
-
return
|
|
4383
|
+
return array3;
|
|
4401
4384
|
}
|
|
4402
4385
|
function randomUint256() {
|
|
4403
4386
|
const bytes = getRandomBytes(32);
|
|
@@ -10649,6 +10632,144 @@ var ProtocolIntentsAbi = [
|
|
|
10649
10632
|
}
|
|
10650
10633
|
],
|
|
10651
10634
|
stateMutability: "view"
|
|
10635
|
+
},
|
|
10636
|
+
{
|
|
10637
|
+
type: "function",
|
|
10638
|
+
name: "cancelIntent",
|
|
10639
|
+
inputs: [
|
|
10640
|
+
{
|
|
10641
|
+
name: "fromToken",
|
|
10642
|
+
type: "address",
|
|
10643
|
+
internalType: "address"
|
|
10644
|
+
},
|
|
10645
|
+
{
|
|
10646
|
+
name: "toToken",
|
|
10647
|
+
type: "address",
|
|
10648
|
+
internalType: "address"
|
|
10649
|
+
}
|
|
10650
|
+
],
|
|
10651
|
+
outputs: [],
|
|
10652
|
+
stateMutability: "nonpayable"
|
|
10653
|
+
},
|
|
10654
|
+
{
|
|
10655
|
+
type: "function",
|
|
10656
|
+
name: "getUserIntent",
|
|
10657
|
+
inputs: [
|
|
10658
|
+
{
|
|
10659
|
+
name: "user",
|
|
10660
|
+
type: "address",
|
|
10661
|
+
internalType: "address"
|
|
10662
|
+
},
|
|
10663
|
+
{
|
|
10664
|
+
name: "fromToken",
|
|
10665
|
+
type: "address",
|
|
10666
|
+
internalType: "address"
|
|
10667
|
+
},
|
|
10668
|
+
{
|
|
10669
|
+
name: "toToken",
|
|
10670
|
+
type: "address",
|
|
10671
|
+
internalType: "address"
|
|
10672
|
+
}
|
|
10673
|
+
],
|
|
10674
|
+
outputs: [
|
|
10675
|
+
{
|
|
10676
|
+
name: "intentHash",
|
|
10677
|
+
type: "bytes32",
|
|
10678
|
+
internalType: "bytes32"
|
|
10679
|
+
}
|
|
10680
|
+
],
|
|
10681
|
+
stateMutability: "view"
|
|
10682
|
+
},
|
|
10683
|
+
{
|
|
10684
|
+
type: "function",
|
|
10685
|
+
name: "getIntentDetails",
|
|
10686
|
+
inputs: [
|
|
10687
|
+
{
|
|
10688
|
+
name: "intentHash",
|
|
10689
|
+
type: "bytes32",
|
|
10690
|
+
internalType: "bytes32"
|
|
10691
|
+
}
|
|
10692
|
+
],
|
|
10693
|
+
outputs: [
|
|
10694
|
+
{
|
|
10695
|
+
name: "intent",
|
|
10696
|
+
type: "tuple",
|
|
10697
|
+
internalType: "struct Intents.Intent",
|
|
10698
|
+
components: [
|
|
10699
|
+
{
|
|
10700
|
+
name: "intentId",
|
|
10701
|
+
type: "uint256",
|
|
10702
|
+
internalType: "uint256"
|
|
10703
|
+
},
|
|
10704
|
+
{
|
|
10705
|
+
name: "creator",
|
|
10706
|
+
type: "address",
|
|
10707
|
+
internalType: "address"
|
|
10708
|
+
},
|
|
10709
|
+
{
|
|
10710
|
+
name: "inputToken",
|
|
10711
|
+
type: "address",
|
|
10712
|
+
internalType: "address"
|
|
10713
|
+
},
|
|
10714
|
+
{
|
|
10715
|
+
name: "outputToken",
|
|
10716
|
+
type: "address",
|
|
10717
|
+
internalType: "address"
|
|
10718
|
+
},
|
|
10719
|
+
{
|
|
10720
|
+
name: "inputAmount",
|
|
10721
|
+
type: "uint256",
|
|
10722
|
+
internalType: "uint256"
|
|
10723
|
+
},
|
|
10724
|
+
{
|
|
10725
|
+
name: "minOutputAmount",
|
|
10726
|
+
type: "uint256",
|
|
10727
|
+
internalType: "uint256"
|
|
10728
|
+
},
|
|
10729
|
+
{
|
|
10730
|
+
name: "deadline",
|
|
10731
|
+
type: "uint256",
|
|
10732
|
+
internalType: "uint256"
|
|
10733
|
+
},
|
|
10734
|
+
{
|
|
10735
|
+
name: "allowPartialFill",
|
|
10736
|
+
type: "bool",
|
|
10737
|
+
internalType: "bool"
|
|
10738
|
+
},
|
|
10739
|
+
{
|
|
10740
|
+
name: "srcChain",
|
|
10741
|
+
type: "uint256",
|
|
10742
|
+
internalType: "uint256"
|
|
10743
|
+
},
|
|
10744
|
+
{
|
|
10745
|
+
name: "dstChain",
|
|
10746
|
+
type: "uint256",
|
|
10747
|
+
internalType: "uint256"
|
|
10748
|
+
},
|
|
10749
|
+
{
|
|
10750
|
+
name: "srcAddress",
|
|
10751
|
+
type: "bytes",
|
|
10752
|
+
internalType: "bytes"
|
|
10753
|
+
},
|
|
10754
|
+
{
|
|
10755
|
+
name: "dstAddress",
|
|
10756
|
+
type: "bytes",
|
|
10757
|
+
internalType: "bytes"
|
|
10758
|
+
},
|
|
10759
|
+
{
|
|
10760
|
+
name: "solver",
|
|
10761
|
+
type: "address",
|
|
10762
|
+
internalType: "address"
|
|
10763
|
+
},
|
|
10764
|
+
{
|
|
10765
|
+
name: "data",
|
|
10766
|
+
type: "bytes",
|
|
10767
|
+
internalType: "bytes"
|
|
10768
|
+
}
|
|
10769
|
+
]
|
|
10770
|
+
}
|
|
10771
|
+
],
|
|
10772
|
+
stateMutability: "view"
|
|
10652
10773
|
}
|
|
10653
10774
|
];
|
|
10654
10775
|
|
|
@@ -13506,29 +13627,6 @@ var universalRouterAbi = [
|
|
|
13506
13627
|
}
|
|
13507
13628
|
];
|
|
13508
13629
|
|
|
13509
|
-
// src/shared/utils/deepMerge.ts
|
|
13510
|
-
function deepMerge(target, source) {
|
|
13511
|
-
const result = { ...target };
|
|
13512
|
-
for (const key of Object.keys(source)) {
|
|
13513
|
-
const sourceVal = source[key];
|
|
13514
|
-
const targetVal = target[key];
|
|
13515
|
-
if (sourceVal !== void 0 && typeof sourceVal === "object" && sourceVal !== null && !Array.isArray(sourceVal) && typeof targetVal === "object" && targetVal !== null && !Array.isArray(targetVal)) {
|
|
13516
|
-
result[key] = deepMerge(
|
|
13517
|
-
targetVal,
|
|
13518
|
-
sourceVal
|
|
13519
|
-
);
|
|
13520
|
-
} else if (sourceVal !== void 0) {
|
|
13521
|
-
result[key] = sourceVal;
|
|
13522
|
-
}
|
|
13523
|
-
}
|
|
13524
|
-
return result;
|
|
13525
|
-
}
|
|
13526
|
-
|
|
13527
|
-
// src/shared/config/mergeSodaxConfig.ts
|
|
13528
|
-
function mergeSodaxConfig(base2, override) {
|
|
13529
|
-
return deepMerge(base2, override);
|
|
13530
|
-
}
|
|
13531
|
-
|
|
13532
13630
|
// src/shared/logger.ts
|
|
13533
13631
|
var consoleLogger = {
|
|
13534
13632
|
debug: (message, data) => data ? console.debug(message, data) : console.debug(message),
|
|
@@ -13556,16 +13654,85 @@ function resolveLogger(option) {
|
|
|
13556
13654
|
return option;
|
|
13557
13655
|
}
|
|
13558
13656
|
|
|
13657
|
+
// src/shared/analytics.ts
|
|
13658
|
+
var noopAnalytics = {
|
|
13659
|
+
isEnabled: () => false,
|
|
13660
|
+
emit: () => {
|
|
13661
|
+
},
|
|
13662
|
+
trackResult: (_feature, _action, run) => run()
|
|
13663
|
+
};
|
|
13664
|
+
var LEVEL_RANK = { basic: 0, detailed: 1 };
|
|
13665
|
+
function normalizeFeatures(features) {
|
|
13666
|
+
if (features === void 0) return null;
|
|
13667
|
+
const map = /* @__PURE__ */ new Map();
|
|
13668
|
+
if (Array.isArray(features)) {
|
|
13669
|
+
for (const feature of features) map.set(feature, true);
|
|
13670
|
+
} else {
|
|
13671
|
+
for (const [feature, scope] of Object.entries(features)) {
|
|
13672
|
+
if (scope === true) map.set(feature, true);
|
|
13673
|
+
else if (scope) map.set(feature, new Set(scope.actions));
|
|
13674
|
+
}
|
|
13675
|
+
}
|
|
13676
|
+
return map;
|
|
13677
|
+
}
|
|
13678
|
+
function resolveAnalytics(option) {
|
|
13679
|
+
if (!option) return noopAnalytics;
|
|
13680
|
+
const { tracker, level: configuredLevel = "basic", features } = option;
|
|
13681
|
+
const maxRank = LEVEL_RANK[configuredLevel];
|
|
13682
|
+
const allow = normalizeFeatures(features);
|
|
13683
|
+
const isEnabled = (feature, action, level = "basic") => {
|
|
13684
|
+
if (LEVEL_RANK[level] > maxRank) return false;
|
|
13685
|
+
if (allow === null) return true;
|
|
13686
|
+
const scope = allow.get(feature);
|
|
13687
|
+
if (scope === void 0) return false;
|
|
13688
|
+
if (scope === true) return true;
|
|
13689
|
+
if (action === void 0) return scope.size > 0;
|
|
13690
|
+
return scope.has(action);
|
|
13691
|
+
};
|
|
13692
|
+
const emit = (feature, action, phase, build, level = "basic") => {
|
|
13693
|
+
if (!isEnabled(feature, action, level)) return;
|
|
13694
|
+
try {
|
|
13695
|
+
tracker({ feature, action, phase, level, data: build?.() });
|
|
13696
|
+
} catch {
|
|
13697
|
+
}
|
|
13698
|
+
};
|
|
13699
|
+
const trackResult = async (feature, action, run, data) => {
|
|
13700
|
+
emit(feature, action, "start", data?.start);
|
|
13701
|
+
try {
|
|
13702
|
+
const result = await run();
|
|
13703
|
+
if (result.ok) {
|
|
13704
|
+
const build = data?.success;
|
|
13705
|
+
emit(feature, action, "success", build ? () => build(result.value) : void 0);
|
|
13706
|
+
} else {
|
|
13707
|
+
const build = data?.failure;
|
|
13708
|
+
emit(feature, action, "failure", build ? () => build(result.error) : void 0);
|
|
13709
|
+
}
|
|
13710
|
+
return result;
|
|
13711
|
+
} catch (error) {
|
|
13712
|
+
emit(feature, action, "failure", () => ({ error: error instanceof Error ? error.message : String(error) }));
|
|
13713
|
+
throw error;
|
|
13714
|
+
}
|
|
13715
|
+
};
|
|
13716
|
+
return { isEnabled, emit, trackResult };
|
|
13717
|
+
}
|
|
13718
|
+
|
|
13559
13719
|
// src/shared/config/ConfigService.ts
|
|
13560
13720
|
var ConfigService = class {
|
|
13561
13721
|
sodax;
|
|
13562
|
-
api
|
|
13563
|
-
|
|
13722
|
+
// TODO(config-v2): restore `api` / `userConfig` when initialize() dynamic fetch is re-enabled.
|
|
13723
|
+
// private readonly api: BackendApiService;
|
|
13724
|
+
// private readonly userConfig?: SodaxOptions;
|
|
13564
13725
|
/**
|
|
13565
13726
|
* SDK log sink. Resolved once at construction and kept independent of {@link sodax} so that
|
|
13566
13727
|
* {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.logger`.
|
|
13567
13728
|
*/
|
|
13568
13729
|
logger;
|
|
13730
|
+
/**
|
|
13731
|
+
* Analytics emitter. Resolved once at construction and kept independent of {@link sodax} so that
|
|
13732
|
+
* {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.analytics`;
|
|
13733
|
+
* disabled (no-op) unless the consumer passed an `analytics` config to `new Sodax(...)`.
|
|
13734
|
+
*/
|
|
13735
|
+
analytics;
|
|
13569
13736
|
/**
|
|
13570
13737
|
* Global partner fee. Resolved once at construction and kept independent of {@link sodax} so that
|
|
13571
13738
|
* {@link initialize}'s dynamic-config swap never clobbers it. The backend never supplies it — it is
|
|
@@ -13583,29 +13750,17 @@ var ConfigService = class {
|
|
|
13583
13750
|
stakedATokenAddressesSet;
|
|
13584
13751
|
chainToSupportedTokenAddressMap;
|
|
13585
13752
|
hubAssetToXTokenMap;
|
|
13586
|
-
|
|
13587
|
-
|
|
13753
|
+
// `api` / `userConfig` are accepted but unused while initialize()'s dynamic fetch is disabled
|
|
13754
|
+
// (see TODO(config-v2) below); restore their assignments when re-enabling.
|
|
13755
|
+
constructor({ api, config, userConfig, logger, analytics, fee }) {
|
|
13588
13756
|
this.sodax = config;
|
|
13589
|
-
this.userConfig = userConfig;
|
|
13590
13757
|
this.logger = logger ?? resolveLogger(void 0);
|
|
13758
|
+
this.analytics = analytics ?? noopAnalytics;
|
|
13591
13759
|
this.fee = fee;
|
|
13592
13760
|
this.loadSodaxConfigDataStructures(config);
|
|
13593
13761
|
}
|
|
13594
13762
|
async initialize() {
|
|
13595
13763
|
try {
|
|
13596
|
-
const result = await this.api.getAllConfig();
|
|
13597
|
-
if (!result.ok) return result;
|
|
13598
|
-
const response = result.value;
|
|
13599
|
-
if (!response.version || response.version < CONFIG_VERSION) {
|
|
13600
|
-
this.logger.warn(
|
|
13601
|
-
`Dynamic config version is less than the current version, resorting to the default one. Current version: ${CONFIG_VERSION}, response version: ${response.version}`
|
|
13602
|
-
);
|
|
13603
|
-
} else {
|
|
13604
|
-
const next = this.userConfig ? mergeSodaxConfig(response.config, this.userConfig) : response.config;
|
|
13605
|
-
this.loadSodaxConfigDataStructures(next);
|
|
13606
|
-
this.sodax = next;
|
|
13607
|
-
this.initialized = true;
|
|
13608
|
-
}
|
|
13609
13764
|
return { ok: true, value: void 0 };
|
|
13610
13765
|
} catch (error) {
|
|
13611
13766
|
return { ok: false, error };
|
|
@@ -13638,6 +13793,16 @@ var ConfigService = class {
|
|
|
13638
13793
|
getOriginalAssetAddress(chainId, hubAsset) {
|
|
13639
13794
|
return this.hubAssetToXTokenMap.get(hubAsset.toLowerCase())?.address;
|
|
13640
13795
|
}
|
|
13796
|
+
/**
|
|
13797
|
+
* Resolves the {@link XToken} descriptor (hub asset, vault, decimals) for a hub-asset address.
|
|
13798
|
+
*
|
|
13799
|
+
* Useful when a caller holds a hub asset directly on Sonic that has no spoke-token entry under
|
|
13800
|
+
* the hub chain — e.g. a partner BTC fee held as the BTC hub asset, which only exists as a spoke
|
|
13801
|
+
* token on Bitcoin. Returns `undefined` when the address is not a known hub asset.
|
|
13802
|
+
*/
|
|
13803
|
+
getXTokenFromHubAsset(hubAsset) {
|
|
13804
|
+
return this.hubAssetToXTokenMap.get(hubAsset.toLowerCase());
|
|
13805
|
+
}
|
|
13641
13806
|
getSpokeTokenFromOriginalAssetAddress(chainId, originalAssetAddress) {
|
|
13642
13807
|
return this.supportedTokensPerChain.get(chainId)?.find((token) => token.address.toLowerCase() === originalAssetAddress.toLowerCase());
|
|
13643
13808
|
}
|
|
@@ -13865,9 +14030,32 @@ function parseTokenArrayFromJson(input) {
|
|
|
13865
14030
|
}
|
|
13866
14031
|
return tokens;
|
|
13867
14032
|
}
|
|
14033
|
+
|
|
14034
|
+
// src/shared/utils/deepMerge.ts
|
|
14035
|
+
function deepMerge(target, source) {
|
|
14036
|
+
const result = { ...target };
|
|
14037
|
+
for (const key of Object.keys(source)) {
|
|
14038
|
+
const sourceVal = source[key];
|
|
14039
|
+
const targetVal = target[key];
|
|
14040
|
+
if (sourceVal !== void 0 && typeof sourceVal === "object" && sourceVal !== null && !Array.isArray(sourceVal) && typeof targetVal === "object" && targetVal !== null && !Array.isArray(targetVal)) {
|
|
14041
|
+
result[key] = deepMerge(
|
|
14042
|
+
targetVal,
|
|
14043
|
+
sourceVal
|
|
14044
|
+
);
|
|
14045
|
+
} else if (sourceVal !== void 0) {
|
|
14046
|
+
result[key] = sourceVal;
|
|
14047
|
+
}
|
|
14048
|
+
}
|
|
14049
|
+
return result;
|
|
14050
|
+
}
|
|
14051
|
+
|
|
14052
|
+
// src/shared/config/mergeSodaxConfig.ts
|
|
14053
|
+
function mergeSodaxConfig(base2, override) {
|
|
14054
|
+
return deepMerge(base2, override);
|
|
14055
|
+
}
|
|
13868
14056
|
function encodeContractCalls(calls) {
|
|
13869
14057
|
return viem.encodeAbiParameters(viem.parseAbiParameters("(address,uint256,bytes)[]"), [
|
|
13870
|
-
calls.map((
|
|
14058
|
+
calls.map((v6) => [v6.address, v6.value, v6.data])
|
|
13871
14059
|
]);
|
|
13872
14060
|
}
|
|
13873
14061
|
async function waitForTransactionReceipt(hash, provider) {
|
|
@@ -15548,6 +15736,32 @@ var BitcoinSpokeService = class {
|
|
|
15548
15736
|
throw error;
|
|
15549
15737
|
}
|
|
15550
15738
|
}
|
|
15739
|
+
/**
|
|
15740
|
+
* Sign and submit a TRADING-wallet raw transaction — the Bound-built *unsigned* PSBT returned by
|
|
15741
|
+
* `deposit({ raw: true })` / the Swaps API (`createIntent().tx.data`). Signs it with the wallet
|
|
15742
|
+
* provider's key, then sends it to Bound Exchange to co-sign with the second 2-of-2 key and
|
|
15743
|
+
* broadcast. Returns the broadcast tx id.
|
|
15744
|
+
*
|
|
15745
|
+
* This is the client-side completion of the TRADING deposit flow: the backend builds the PSBT
|
|
15746
|
+
* (it can't broadcast — the user's signature is missing), the client signs here, and Bound
|
|
15747
|
+
* co-signs + broadcasts. `relayData` ({ address, payload }) is the relay identity returned by
|
|
15748
|
+
* `createIntent()`; forwarding it lets Bound auto-resubmit a stuck relay. It is **not** recoverable
|
|
15749
|
+
* from `rawTx` (whose `to` is the asset manager, not the hub wallet), so callers must supply it.
|
|
15750
|
+
*
|
|
15751
|
+
* @throws if the chain is not in `TRADING` wallet mode (raw txs only exist in TRADING mode).
|
|
15752
|
+
*/
|
|
15753
|
+
async signAndSubmitRawTransaction(params) {
|
|
15754
|
+
if (this.walletMode !== "TRADING") {
|
|
15755
|
+
throw new Error("signAndSubmitRawTransaction requires TRADING wallet mode.");
|
|
15756
|
+
}
|
|
15757
|
+
const { rawTx, walletProvider, relayData, accessToken = this.radfi.accessToken } = params;
|
|
15758
|
+
if (!rawTx?.data || !rawTx?.from) {
|
|
15759
|
+
throw new Error("signAndSubmitRawTransaction: rawTx.data (PSBT) and rawTx.from are required.");
|
|
15760
|
+
}
|
|
15761
|
+
const signedTx = await walletProvider.signTransaction(rawTx.data, false);
|
|
15762
|
+
const signedBase64Tx = normalizePsbtToBase64(signedTx);
|
|
15763
|
+
return this.radfi.requestRadfiSignature({ userAddress: rawTx.from, signedBase64Tx, relayData }, accessToken);
|
|
15764
|
+
}
|
|
15551
15765
|
/**
|
|
15552
15766
|
* Build deposit PSBT with embedded cross-chain data
|
|
15553
15767
|
*/
|
|
@@ -15817,7 +16031,7 @@ function hexToBytes2(hex) {
|
|
|
15817
16031
|
const al = hl / 2;
|
|
15818
16032
|
if (hl % 2)
|
|
15819
16033
|
throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
15820
|
-
const
|
|
16034
|
+
const array3 = new Uint8Array(al);
|
|
15821
16035
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
15822
16036
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
15823
16037
|
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
@@ -15825,9 +16039,9 @@ function hexToBytes2(hex) {
|
|
|
15825
16039
|
const char = hex[hi] + hex[hi + 1];
|
|
15826
16040
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
15827
16041
|
}
|
|
15828
|
-
|
|
16042
|
+
array3[ai] = n1 * 16 + n2;
|
|
15829
16043
|
}
|
|
15830
|
-
return
|
|
16044
|
+
return array3;
|
|
15831
16045
|
}
|
|
15832
16046
|
function concatBytes(...arrays) {
|
|
15833
16047
|
let sum = 0;
|
|
@@ -16457,22 +16671,22 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
|
16457
16671
|
const byte0 = Uint8Array.of(0);
|
|
16458
16672
|
const byte1 = Uint8Array.of(1);
|
|
16459
16673
|
const _maxDrbgIters = 1e3;
|
|
16460
|
-
let
|
|
16674
|
+
let v6 = u8n(hashLen);
|
|
16461
16675
|
let k = u8n(hashLen);
|
|
16462
16676
|
let i = 0;
|
|
16463
16677
|
const reset = () => {
|
|
16464
|
-
|
|
16678
|
+
v6.fill(1);
|
|
16465
16679
|
k.fill(0);
|
|
16466
16680
|
i = 0;
|
|
16467
16681
|
};
|
|
16468
|
-
const h = (...msgs) => hmacFn(k, concatBytes(
|
|
16682
|
+
const h = (...msgs) => hmacFn(k, concatBytes(v6, ...msgs));
|
|
16469
16683
|
const reseed = (seed = NULL) => {
|
|
16470
16684
|
k = h(byte0, seed);
|
|
16471
|
-
|
|
16685
|
+
v6 = h();
|
|
16472
16686
|
if (seed.length === 0)
|
|
16473
16687
|
return;
|
|
16474
16688
|
k = h(byte1, seed);
|
|
16475
|
-
|
|
16689
|
+
v6 = h();
|
|
16476
16690
|
};
|
|
16477
16691
|
const gen = () => {
|
|
16478
16692
|
if (i++ >= _maxDrbgIters)
|
|
@@ -16480,10 +16694,10 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
|
16480
16694
|
let len = 0;
|
|
16481
16695
|
const out = [];
|
|
16482
16696
|
while (len < qByteLen) {
|
|
16483
|
-
|
|
16484
|
-
const sl =
|
|
16697
|
+
v6 = h();
|
|
16698
|
+
const sl = v6.slice();
|
|
16485
16699
|
out.push(sl);
|
|
16486
|
-
len +=
|
|
16700
|
+
len += v6.length;
|
|
16487
16701
|
}
|
|
16488
16702
|
return concatBytes(...out);
|
|
16489
16703
|
};
|
|
@@ -16498,18 +16712,18 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
|
16498
16712
|
};
|
|
16499
16713
|
return genUntil;
|
|
16500
16714
|
}
|
|
16501
|
-
function validateObject(
|
|
16502
|
-
if (!
|
|
16715
|
+
function validateObject(object4, fields = {}, optFields = {}) {
|
|
16716
|
+
if (!object4 || typeof object4 !== "object")
|
|
16503
16717
|
throw new Error("expected valid options object");
|
|
16504
16718
|
function checkField(fieldName, expectedType, isOpt) {
|
|
16505
|
-
const val =
|
|
16719
|
+
const val = object4[fieldName];
|
|
16506
16720
|
if (isOpt && val === void 0)
|
|
16507
16721
|
return;
|
|
16508
16722
|
const current = typeof val;
|
|
16509
16723
|
if (current !== expectedType || val === null)
|
|
16510
16724
|
throw new Error(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
16511
16725
|
}
|
|
16512
|
-
const iter = (f, isOpt) => Object.entries(f).forEach(([k,
|
|
16726
|
+
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v6]) => checkField(k, v6, isOpt));
|
|
16513
16727
|
iter(fields, false);
|
|
16514
16728
|
iter(optFields, true);
|
|
16515
16729
|
}
|
|
@@ -16548,12 +16762,12 @@ function pow2(x, power, modulo) {
|
|
|
16548
16762
|
}
|
|
16549
16763
|
return res;
|
|
16550
16764
|
}
|
|
16551
|
-
function invert(
|
|
16552
|
-
if (
|
|
16765
|
+
function invert(number4, modulo) {
|
|
16766
|
+
if (number4 === _0n2)
|
|
16553
16767
|
throw new Error("invert: expected non-zero number");
|
|
16554
16768
|
if (modulo <= _0n2)
|
|
16555
16769
|
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
16556
|
-
let a = mod(
|
|
16770
|
+
let a = mod(number4, modulo);
|
|
16557
16771
|
let b = modulo;
|
|
16558
16772
|
let x = _0n2, u = _1n2;
|
|
16559
16773
|
while (a !== _0n2) {
|
|
@@ -16580,9 +16794,9 @@ function sqrt3mod4(Fp, n) {
|
|
|
16580
16794
|
function sqrt5mod8(Fp, n) {
|
|
16581
16795
|
const p5div8 = (Fp.ORDER - _5n) / _8n;
|
|
16582
16796
|
const n2 = Fp.mul(n, _2n);
|
|
16583
|
-
const
|
|
16584
|
-
const nv = Fp.mul(n,
|
|
16585
|
-
const i = Fp.mul(Fp.mul(nv, _2n),
|
|
16797
|
+
const v6 = Fp.pow(n2, p5div8);
|
|
16798
|
+
const nv = Fp.mul(n, v6);
|
|
16799
|
+
const i = Fp.mul(Fp.mul(nv, _2n), v6);
|
|
16586
16800
|
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
|
16587
16801
|
assertIsSquare(Fp, root, n);
|
|
16588
16802
|
return root;
|
|
@@ -17057,27 +17271,27 @@ var wNAF = class {
|
|
|
17057
17271
|
assert0(n);
|
|
17058
17272
|
return acc;
|
|
17059
17273
|
}
|
|
17060
|
-
getPrecomputes(W, point,
|
|
17274
|
+
getPrecomputes(W, point, transform2) {
|
|
17061
17275
|
let comp = pointPrecomputes.get(point);
|
|
17062
17276
|
if (!comp) {
|
|
17063
17277
|
comp = this.precomputeWindow(point, W);
|
|
17064
17278
|
if (W !== 1) {
|
|
17065
|
-
if (typeof
|
|
17066
|
-
comp =
|
|
17279
|
+
if (typeof transform2 === "function")
|
|
17280
|
+
comp = transform2(comp);
|
|
17067
17281
|
pointPrecomputes.set(point, comp);
|
|
17068
17282
|
}
|
|
17069
17283
|
}
|
|
17070
17284
|
return comp;
|
|
17071
17285
|
}
|
|
17072
|
-
cached(point, scalar,
|
|
17286
|
+
cached(point, scalar, transform2) {
|
|
17073
17287
|
const W = getW(point);
|
|
17074
|
-
return this.wNAF(W, this.getPrecomputes(W, point,
|
|
17288
|
+
return this.wNAF(W, this.getPrecomputes(W, point, transform2), scalar);
|
|
17075
17289
|
}
|
|
17076
|
-
unsafe(point, scalar,
|
|
17290
|
+
unsafe(point, scalar, transform2, prev) {
|
|
17077
17291
|
const W = getW(point);
|
|
17078
17292
|
if (W === 1)
|
|
17079
17293
|
return this._unsafeLadder(point, scalar, prev);
|
|
17080
|
-
return this.wNAFUnsafe(W, this.getPrecomputes(W, point,
|
|
17294
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform2), scalar, prev);
|
|
17081
17295
|
}
|
|
17082
17296
|
// We calculate precomputes for elliptic curve point multiplication
|
|
17083
17297
|
// using windowed method. This specifies window size and
|
|
@@ -17164,9 +17378,9 @@ function edwards(params, extraOpts = {}) {
|
|
|
17164
17378
|
validateObject(extraOpts, {}, { uvRatio: "function" });
|
|
17165
17379
|
const MASK = _2n2 << BigInt(Fn.BYTES * 8) - _1n4;
|
|
17166
17380
|
const modP = (n) => Fp.create(n);
|
|
17167
|
-
const uvRatio2 = extraOpts.uvRatio || ((u,
|
|
17381
|
+
const uvRatio2 = extraOpts.uvRatio || ((u, v6) => {
|
|
17168
17382
|
try {
|
|
17169
|
-
return { isValid: true, value: Fp.sqrt(Fp.div(u,
|
|
17383
|
+
return { isValid: true, value: Fp.sqrt(Fp.div(u, v6)) };
|
|
17170
17384
|
} catch (e) {
|
|
17171
17385
|
return { isValid: false, value: _0n4 };
|
|
17172
17386
|
}
|
|
@@ -17262,8 +17476,8 @@ function edwards(params, extraOpts = {}) {
|
|
|
17262
17476
|
aInRange("point.y", y, _0n4, max);
|
|
17263
17477
|
const y2 = modP(y * y);
|
|
17264
17478
|
const u = modP(y2 - _1n4);
|
|
17265
|
-
const
|
|
17266
|
-
let { isValid, value: x } = uvRatio2(u,
|
|
17479
|
+
const v6 = modP(d * y2 - a);
|
|
17480
|
+
let { isValid, value: x } = uvRatio2(u, v6);
|
|
17267
17481
|
if (!isValid)
|
|
17268
17482
|
throw new Error("bad point: invalid y coordinate");
|
|
17269
17483
|
const isXOdd = (x & _1n4) === _1n4;
|
|
@@ -17603,13 +17817,13 @@ function adjustScalarBytes(bytes) {
|
|
|
17603
17817
|
return bytes;
|
|
17604
17818
|
}
|
|
17605
17819
|
var ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
|
|
17606
|
-
function uvRatio(u,
|
|
17820
|
+
function uvRatio(u, v6) {
|
|
17607
17821
|
const P = ed25519_CURVE_p;
|
|
17608
|
-
const
|
|
17609
|
-
const v7 = mod(
|
|
17822
|
+
const v32 = mod(v6 * v6 * v6, P);
|
|
17823
|
+
const v7 = mod(v32 * v32 * v6, P);
|
|
17610
17824
|
const pow = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
|
17611
|
-
let x = mod(u *
|
|
17612
|
-
const vx2 = mod(
|
|
17825
|
+
let x = mod(u * v32 * pow, P);
|
|
17826
|
+
const vx2 = mod(v6 * x * x, P);
|
|
17613
17827
|
const root1 = x;
|
|
17614
17828
|
const root2 = mod(x * ED25519_SQRT_M1, P);
|
|
17615
17829
|
const useRoot1 = vx2 === u;
|
|
@@ -17940,7 +18154,7 @@ function findSeatPrice(validators, maxNumberOfSeats, minimumStakeRatio, protocol
|
|
|
17940
18154
|
return findSeatPriceForProtocolAfter49(validators, maxNumberOfSeats, minimumStakeRatio);
|
|
17941
18155
|
}
|
|
17942
18156
|
function findSeatPriceForProtocolBefore49(validators, numSeats) {
|
|
17943
|
-
const stakes = validators.map((
|
|
18157
|
+
const stakes = validators.map((v6) => BigInt(v6.stake)).sort(sortBigIntAsc);
|
|
17944
18158
|
const num = BigInt(numSeats);
|
|
17945
18159
|
const stakesSum = stakes.reduce((a, b) => a + b);
|
|
17946
18160
|
if (stakesSum < num) {
|
|
@@ -17969,7 +18183,7 @@ function findSeatPriceForProtocolAfter49(validators, maxNumberOfSeats, minimumSt
|
|
|
17969
18183
|
if (minimumStakeRatio.length != 2) {
|
|
17970
18184
|
throw Error("minimumStakeRatio should have 2 elements");
|
|
17971
18185
|
}
|
|
17972
|
-
const stakes = validators.map((
|
|
18186
|
+
const stakes = validators.map((v6) => BigInt(v6.stake)).sort(sortBigIntAsc);
|
|
17973
18187
|
const stakesSum = stakes.reduce((a, b) => a + b);
|
|
17974
18188
|
if (validators.length < maxNumberOfSeats) {
|
|
17975
18189
|
return stakesSum * BigInt(minimumStakeRatio[0]) / BigInt(minimumStakeRatio[1]);
|
|
@@ -18141,10 +18355,10 @@ var DER = {
|
|
|
18141
18355
|
if (length < 128)
|
|
18142
18356
|
throw new E("tlv.decode(long): not minimal encoding");
|
|
18143
18357
|
}
|
|
18144
|
-
const
|
|
18145
|
-
if (
|
|
18358
|
+
const v6 = data.subarray(pos, pos + length);
|
|
18359
|
+
if (v6.length !== length)
|
|
18146
18360
|
throw new E("tlv.decode: wrong value length");
|
|
18147
|
-
return { v, l: data.subarray(pos + length) };
|
|
18361
|
+
return { v: v6, l: data.subarray(pos + length) };
|
|
18148
18362
|
}
|
|
18149
18363
|
},
|
|
18150
18364
|
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
|
@@ -18712,9 +18926,9 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
18712
18926
|
extraEntropy: false
|
|
18713
18927
|
};
|
|
18714
18928
|
const hasLargeCofactor = CURVE_ORDER * _2n4 < Fp.ORDER;
|
|
18715
|
-
function isBiggerThanHalfOrder(
|
|
18929
|
+
function isBiggerThanHalfOrder(number4) {
|
|
18716
18930
|
const HALF = CURVE_ORDER >> _1n6;
|
|
18717
|
-
return
|
|
18931
|
+
return number4 > HALF;
|
|
18718
18932
|
}
|
|
18719
18933
|
function validateRS(title, num) {
|
|
18720
18934
|
if (!Fn.isValidNot0(num))
|
|
@@ -18891,14 +19105,14 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
18891
19105
|
return false;
|
|
18892
19106
|
const { r, s } = sig;
|
|
18893
19107
|
const h = bits2int_modN(message);
|
|
18894
|
-
const
|
|
18895
|
-
const u1 = Fn.create(h *
|
|
18896
|
-
const u2 = Fn.create(r *
|
|
19108
|
+
const is2 = Fn.inv(s);
|
|
19109
|
+
const u1 = Fn.create(h * is2);
|
|
19110
|
+
const u2 = Fn.create(r * is2);
|
|
18897
19111
|
const R = Point.BASE.multiplyUnsafe(u1).add(P.multiplyUnsafe(u2));
|
|
18898
19112
|
if (R.is0())
|
|
18899
19113
|
return false;
|
|
18900
|
-
const
|
|
18901
|
-
return
|
|
19114
|
+
const v6 = Fn.create(R.x);
|
|
19115
|
+
return v6 === r;
|
|
18902
19116
|
} catch (e) {
|
|
18903
19117
|
return false;
|
|
18904
19118
|
}
|
|
@@ -26244,13 +26458,18 @@ var SwapService = class {
|
|
|
26244
26458
|
solver;
|
|
26245
26459
|
partnerFee;
|
|
26246
26460
|
relayerApiEndpoint;
|
|
26247
|
-
|
|
26461
|
+
// backend swaps-API client + opt-in 2-step submit-tx flag
|
|
26462
|
+
backendApi;
|
|
26463
|
+
useBackendSubmitTx;
|
|
26464
|
+
constructor({ config, hubProvider, spoke, backendApi, useBackendSubmitTx }) {
|
|
26248
26465
|
this.solver = config.solver;
|
|
26249
26466
|
this.partnerFee = config.swapPartnerFee;
|
|
26250
26467
|
this.relayerApiEndpoint = config.relay.relayerApiEndpoint;
|
|
26251
26468
|
this.config = config;
|
|
26252
26469
|
this.hubProvider = hubProvider;
|
|
26253
26470
|
this.spoke = spoke;
|
|
26471
|
+
this.backendApi = backendApi;
|
|
26472
|
+
this.useBackendSubmitTx = useBackendSubmitTx ?? false;
|
|
26254
26473
|
}
|
|
26255
26474
|
/**
|
|
26256
26475
|
* Estimates the gas cost for a raw (unsigned) transaction on a spoke chain.
|
|
@@ -26394,14 +26613,22 @@ var SwapService = class {
|
|
|
26394
26613
|
/**
|
|
26395
26614
|
* Executes a full end-to-end cross-chain swap.
|
|
26396
26615
|
*
|
|
26397
|
-
* Orchestrates the complete swap lifecycle
|
|
26398
|
-
*
|
|
26399
|
-
*
|
|
26400
|
-
*
|
|
26401
|
-
*
|
|
26402
|
-
*
|
|
26403
|
-
*
|
|
26404
|
-
*
|
|
26616
|
+
* Orchestrates the complete swap lifecycle. `createIntent` first submits the intent transaction on
|
|
26617
|
+
* the source spoke chain; completion then runs via one of two paths, both bounded by a single
|
|
26618
|
+
* shared `timeout` budget:
|
|
26619
|
+
*
|
|
26620
|
+
* - **Client-side (default), {@link fallbackSwapSteps}:** verifies the spoke tx landed on-chain,
|
|
26621
|
+
* relays it to the hub (Sonic) and waits for the packet — skipped when `srcChainKey` is the hub,
|
|
26622
|
+
* where the spoke tx already is the hub tx — then calls `postExecution` to notify the solver,
|
|
26623
|
+
* triggering it to fill the intent.
|
|
26624
|
+
* - **Backend 2-step (opt-in via `swapsOptions.useBackendSubmitTx`), {@link submitTx}:** hands the
|
|
26625
|
+
* broadcast tx to the swaps API, which verifies, relays and post-executes server-side, then polls
|
|
26626
|
+
* for completion. On ANY non-success it transparently falls back to the client-side path above —
|
|
26627
|
+
* safe because re-relaying / re-posting an already-processed swap is idempotent (no double-fill).
|
|
26628
|
+
*
|
|
26629
|
+
* @param _params - Swap action params including intent parameters, wallet provider, and an optional
|
|
26630
|
+
* `timeout` — the single shared budget for the whole completion flow (relay/poll plus any
|
|
26631
|
+
* fallback), so total wall-clock never exceeds it.
|
|
26405
26632
|
* @returns A `Result<SwapResponse, SwapError>`. On success:
|
|
26406
26633
|
* - `solverExecutionResponse` — solver acknowledgement (`{ answer: 'OK', intent_hash }`).
|
|
26407
26634
|
* - `intent` — the on-chain intent object that was created.
|
|
@@ -26425,63 +26652,179 @@ var SwapService = class {
|
|
|
26425
26652
|
const { params } = _params;
|
|
26426
26653
|
const srcChainKey = params.srcChainKey;
|
|
26427
26654
|
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey };
|
|
26428
|
-
|
|
26429
|
-
|
|
26430
|
-
|
|
26431
|
-
|
|
26432
|
-
|
|
26655
|
+
return this.config.analytics.trackResult(
|
|
26656
|
+
"swap",
|
|
26657
|
+
"swap",
|
|
26658
|
+
async () => {
|
|
26659
|
+
try {
|
|
26660
|
+
const createIntentResult = await this.createIntent(_params);
|
|
26661
|
+
if (!createIntentResult.ok) {
|
|
26662
|
+
return { ok: false, error: createIntentResult.error };
|
|
26663
|
+
}
|
|
26664
|
+
const created = createIntentResult.value;
|
|
26665
|
+
const deadline = Date.now() + (_params.timeout ?? DEFAULT_RELAY_TX_TIMEOUT);
|
|
26666
|
+
if (this.useBackendSubmitTx) {
|
|
26667
|
+
const submitted = await this.submitTx(_params, created, deadline);
|
|
26668
|
+
if (submitted.ok) return submitted;
|
|
26669
|
+
this.config.logger.warn(
|
|
26670
|
+
"[swap] backend submit-tx did not complete; falling back to the client-side relay",
|
|
26671
|
+
{
|
|
26672
|
+
error: submitted.error
|
|
26673
|
+
}
|
|
26674
|
+
);
|
|
26675
|
+
}
|
|
26676
|
+
return this.fallbackSwapSteps(_params, created, deadline);
|
|
26677
|
+
} catch (error) {
|
|
26678
|
+
if (isSwapError(error)) return { ok: false, error };
|
|
26679
|
+
return {
|
|
26680
|
+
ok: false,
|
|
26681
|
+
error: unknownFailed("swap", error, { ...baseCtx, action: "swap" })
|
|
26682
|
+
};
|
|
26683
|
+
}
|
|
26684
|
+
},
|
|
26685
|
+
{
|
|
26686
|
+
start: () => ({
|
|
26687
|
+
srcChainKey,
|
|
26688
|
+
dstChainKey: params.dstChainKey,
|
|
26689
|
+
srcAddress: params.srcAddress,
|
|
26690
|
+
dstAddress: params.dstAddress
|
|
26691
|
+
}),
|
|
26692
|
+
success: (value) => ({
|
|
26693
|
+
srcChainKey,
|
|
26694
|
+
dstChainKey: params.dstChainKey,
|
|
26695
|
+
srcTxHash: value.intentDeliveryInfo.srcTxHash,
|
|
26696
|
+
dstTxHash: value.intentDeliveryInfo.dstTxHash
|
|
26697
|
+
}),
|
|
26698
|
+
failure: (error) => ({ code: error.code })
|
|
26433
26699
|
}
|
|
26434
|
-
|
|
26435
|
-
|
|
26436
|
-
|
|
26437
|
-
|
|
26700
|
+
);
|
|
26701
|
+
}
|
|
26702
|
+
/**
|
|
26703
|
+
* Client-side swap completion (the default path): relay the broadcast intent tx to the hub — or
|
|
26704
|
+
* use it directly when the source IS the hub — then notify the solver via post-execution and
|
|
26705
|
+
* build the {@link SwapResponse}. Extracted verbatim from `swap()` so the opt-in backend 2-step
|
|
26706
|
+
* path ({@link submitTx}) can fall back to it on any non-success.
|
|
26707
|
+
*/
|
|
26708
|
+
async fallbackSwapSteps(_params, created, deadline) {
|
|
26709
|
+
const { params } = _params;
|
|
26710
|
+
const srcChainKey = params.srcChainKey;
|
|
26711
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey };
|
|
26712
|
+
const { tx: spokeTxHash, intent, relayData } = created;
|
|
26713
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
26714
|
+
txHash: created.tx,
|
|
26715
|
+
chainKey: srcChainKey
|
|
26716
|
+
});
|
|
26717
|
+
if (!verifyTxHashResult.ok) {
|
|
26718
|
+
return { ok: false, error: verifyFailed("swap", verifyTxHashResult.error, { ...baseCtx, action: "swap" }) };
|
|
26719
|
+
}
|
|
26720
|
+
let dstIntentTxHash;
|
|
26721
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
26722
|
+
dstIntentTxHash = spokeTxHash;
|
|
26723
|
+
} else {
|
|
26724
|
+
const packet = await relayTxAndWaitPacket({
|
|
26725
|
+
srcTxHash: spokeTxHash,
|
|
26726
|
+
data: relayData,
|
|
26727
|
+
chainKey: srcChainKey,
|
|
26728
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
26729
|
+
// Remaining shared budget: ≈ full `timeout` on the flag-off path (called immediately), or
|
|
26730
|
+
// the reserve `submitTx` left on the backend path. Floor keeps a stalled-backend fallback viable.
|
|
26731
|
+
timeout: Math.max(deadline - Date.now(), 5e3)
|
|
26438
26732
|
});
|
|
26439
|
-
if (!
|
|
26440
|
-
return { ok: false, error:
|
|
26733
|
+
if (!packet.ok) {
|
|
26734
|
+
return { ok: false, error: mapRelayFailure(packet.error, { feature: "swap", action: "swap", ...baseCtx }) };
|
|
26441
26735
|
}
|
|
26442
|
-
|
|
26443
|
-
|
|
26444
|
-
|
|
26445
|
-
|
|
26446
|
-
|
|
26736
|
+
dstIntentTxHash = packet.value.dst_tx_hash;
|
|
26737
|
+
}
|
|
26738
|
+
const postExecResult = await this.postExecution({
|
|
26739
|
+
intent_tx_hash: dstIntentTxHash
|
|
26740
|
+
});
|
|
26741
|
+
if (!postExecResult.ok) {
|
|
26742
|
+
return { ok: false, error: postExecResult.error };
|
|
26743
|
+
}
|
|
26744
|
+
return {
|
|
26745
|
+
ok: true,
|
|
26746
|
+
value: {
|
|
26747
|
+
solverExecutionResponse: postExecResult.value,
|
|
26748
|
+
intent,
|
|
26749
|
+
intentDeliveryInfo: {
|
|
26750
|
+
srcChainKey,
|
|
26447
26751
|
srcTxHash: spokeTxHash,
|
|
26448
|
-
|
|
26449
|
-
|
|
26450
|
-
|
|
26451
|
-
|
|
26452
|
-
});
|
|
26453
|
-
if (!packet.ok) {
|
|
26454
|
-
return { ok: false, error: mapRelayFailure(packet.error, { feature: "swap", action: "swap", ...baseCtx }) };
|
|
26752
|
+
srcAddress: params.srcAddress,
|
|
26753
|
+
dstChainKey: params.dstChainKey,
|
|
26754
|
+
dstTxHash: dstIntentTxHash,
|
|
26755
|
+
dstAddress: params.dstAddress
|
|
26455
26756
|
}
|
|
26456
|
-
dstIntentTxHash = packet.value.dst_tx_hash;
|
|
26457
26757
|
}
|
|
26458
|
-
|
|
26459
|
-
|
|
26758
|
+
};
|
|
26759
|
+
}
|
|
26760
|
+
/**
|
|
26761
|
+
* Backend 2-step swap path (opt-in via `swapsOptions.useBackendSubmitTx`): hand the broadcast
|
|
26762
|
+
* intent tx to the swaps API (`POST /swaps/submit-tx`); the backend relays + post-executes
|
|
26763
|
+
* server-side. Polls `getSubmitTxStatus` until `executed`, then reconstructs the same
|
|
26764
|
+
* {@link SwapResponse} the client-side path returns (`result.dstIntentTxHash` → delivery info,
|
|
26765
|
+
* `result.intent_hash` → solver response).
|
|
26766
|
+
*
|
|
26767
|
+
* Never throws — returns `{ ok: false }` on any non-success (submit `!ok`, terminal `failed` /
|
|
26768
|
+
* abandoned, or poll timeout) so `swap()` falls back to {@link fallbackSwapSteps}.
|
|
26769
|
+
*
|
|
26770
|
+
* Falling back is safe: re-relaying / re-posting an already-processed swap is idempotent — the
|
|
26771
|
+
* relay dedups and returns the existing `executed` packet, and the solver re-affirms the intent
|
|
26772
|
+
* (no double-fill). Verified live by `e2e-tests/e2e-relay.test.ts`. Polling stops at
|
|
26773
|
+
* `deadline - reserve` so the fallback keeps a guaranteed slice of the shared `swap` budget.
|
|
26774
|
+
*/
|
|
26775
|
+
async submitTx(_params, created, deadline) {
|
|
26776
|
+
const { params } = _params;
|
|
26777
|
+
const srcChainKey = params.srcChainKey;
|
|
26778
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey };
|
|
26779
|
+
const { tx: spokeTxHash, intent, relayData } = created;
|
|
26780
|
+
const submitTxFailed = (cause) => ({
|
|
26781
|
+
ok: false,
|
|
26782
|
+
error: executionFailed("swap", cause, { ...baseCtx, action: "swap" })
|
|
26783
|
+
});
|
|
26784
|
+
try {
|
|
26785
|
+
const submitted = await this.backendApi.swaps.submitTx({
|
|
26786
|
+
txHash: spokeTxHash,
|
|
26787
|
+
srcChainKey,
|
|
26788
|
+
walletAddress: params.srcAddress,
|
|
26789
|
+
intent,
|
|
26790
|
+
relayData: relayData.payload
|
|
26460
26791
|
});
|
|
26461
|
-
if (!
|
|
26462
|
-
|
|
26463
|
-
|
|
26464
|
-
|
|
26465
|
-
|
|
26466
|
-
|
|
26467
|
-
|
|
26468
|
-
|
|
26469
|
-
|
|
26470
|
-
|
|
26471
|
-
|
|
26472
|
-
|
|
26473
|
-
|
|
26474
|
-
|
|
26475
|
-
|
|
26792
|
+
if (!submitted.ok) return submitTxFailed(submitted.error);
|
|
26793
|
+
const reserveMs = Math.min(Math.ceil((deadline - Date.now()) / 3), 2e4);
|
|
26794
|
+
const pollDeadline = deadline - reserveMs;
|
|
26795
|
+
const pollIntervalMs = 1e3;
|
|
26796
|
+
while (Date.now() < pollDeadline) {
|
|
26797
|
+
const statusResult = await this.backendApi.swaps.getSubmitTxStatus({ txHash: spokeTxHash, srcChainKey });
|
|
26798
|
+
if (statusResult.ok) {
|
|
26799
|
+
const { status, result, failureReason, abandonedAt } = statusResult.value.data;
|
|
26800
|
+
if (status === "executed" && result?.dstIntentTxHash && result.intent_hash) {
|
|
26801
|
+
return {
|
|
26802
|
+
ok: true,
|
|
26803
|
+
value: {
|
|
26804
|
+
// Backend serializes the hex intent_hash as a plain string; brand it at the boundary.
|
|
26805
|
+
solverExecutionResponse: { answer: "OK", intent_hash: result.intent_hash },
|
|
26806
|
+
intent,
|
|
26807
|
+
intentDeliveryInfo: {
|
|
26808
|
+
srcChainKey,
|
|
26809
|
+
srcTxHash: spokeTxHash,
|
|
26810
|
+
srcAddress: params.srcAddress,
|
|
26811
|
+
dstChainKey: params.dstChainKey,
|
|
26812
|
+
dstTxHash: result.dstIntentTxHash,
|
|
26813
|
+
dstAddress: params.dstAddress
|
|
26814
|
+
}
|
|
26815
|
+
}
|
|
26816
|
+
};
|
|
26817
|
+
}
|
|
26818
|
+
if (status === "failed" || abandonedAt) {
|
|
26819
|
+
const reason = failureReason ? `: ${failureReason}` : "";
|
|
26820
|
+
return submitTxFailed(new Error(`backend submit-tx ${status}${reason}`));
|
|
26476
26821
|
}
|
|
26477
26822
|
}
|
|
26478
|
-
|
|
26823
|
+
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
26824
|
+
}
|
|
26825
|
+
return submitTxFailed(new Error("backend submit-tx polling timed out before reaching executed"));
|
|
26479
26826
|
} catch (error) {
|
|
26480
|
-
|
|
26481
|
-
return {
|
|
26482
|
-
ok: false,
|
|
26483
|
-
error: unknownFailed("swap", error, { ...baseCtx, action: "swap" })
|
|
26484
|
-
};
|
|
26827
|
+
return { ok: false, error: unknownFailed("swap", error, { ...baseCtx, action: "swap" }) };
|
|
26485
26828
|
}
|
|
26486
26829
|
}
|
|
26487
26830
|
/**
|
|
@@ -28528,72 +28871,94 @@ var MigrationService = class {
|
|
|
28528
28871
|
* }
|
|
28529
28872
|
*/
|
|
28530
28873
|
async migratebnUSD(_params) {
|
|
28531
|
-
|
|
28532
|
-
|
|
28533
|
-
|
|
28534
|
-
|
|
28535
|
-
|
|
28536
|
-
|
|
28537
|
-
|
|
28538
|
-
|
|
28539
|
-
|
|
28540
|
-
const { tx: spokeTxHash, relayData: extraData } = intentResult.value;
|
|
28541
|
-
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
28542
|
-
txHash: spokeTxHash,
|
|
28543
|
-
chainKey: params.srcChainKey
|
|
28544
|
-
});
|
|
28545
|
-
if (!verifyTxHashResult.ok) {
|
|
28546
|
-
return {
|
|
28547
|
-
ok: false,
|
|
28548
|
-
error: verifyFailed("migration", verifyTxHashResult.error, baseCtx)
|
|
28549
|
-
};
|
|
28550
|
-
}
|
|
28551
|
-
const packetResult = await relayTxAndWaitPacket({
|
|
28552
|
-
srcTxHash: spokeTxHash,
|
|
28553
|
-
data: extraData,
|
|
28554
|
-
chainKey: params.srcChainKey,
|
|
28555
|
-
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
28556
|
-
timeout
|
|
28557
|
-
});
|
|
28558
|
-
if (!packetResult.ok) {
|
|
28559
|
-
return {
|
|
28560
|
-
ok: false,
|
|
28561
|
-
error: mapRelayFailure(packetResult.error, {
|
|
28562
|
-
feature: "migration",
|
|
28563
|
-
action: baseCtx.action,
|
|
28564
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
28565
|
-
dstChainKey: baseCtx.dstChainKey
|
|
28566
|
-
})
|
|
28874
|
+
return this.config.analytics.trackResult(
|
|
28875
|
+
"migration",
|
|
28876
|
+
"migratebnUSD",
|
|
28877
|
+
async () => {
|
|
28878
|
+
const { params, timeout } = _params;
|
|
28879
|
+
const baseCtx = {
|
|
28880
|
+
srcChainKey: params.srcChainKey,
|
|
28881
|
+
dstChainKey: params.dstChainKey,
|
|
28882
|
+
action: "migratebnUSD"
|
|
28567
28883
|
};
|
|
28568
|
-
|
|
28569
|
-
|
|
28570
|
-
|
|
28571
|
-
|
|
28572
|
-
|
|
28573
|
-
|
|
28574
|
-
|
|
28575
|
-
|
|
28576
|
-
|
|
28884
|
+
try {
|
|
28885
|
+
const intentResult = await this.createMigratebnUSDIntent(_params);
|
|
28886
|
+
if (!intentResult.ok) return { ok: false, error: intentResult.error };
|
|
28887
|
+
const { tx: spokeTxHash, relayData: extraData } = intentResult.value;
|
|
28888
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
28889
|
+
txHash: spokeTxHash,
|
|
28890
|
+
chainKey: params.srcChainKey
|
|
28891
|
+
});
|
|
28892
|
+
if (!verifyTxHashResult.ok) {
|
|
28893
|
+
return {
|
|
28894
|
+
ok: false,
|
|
28895
|
+
error: verifyFailed("migration", verifyTxHashResult.error, baseCtx)
|
|
28896
|
+
};
|
|
28897
|
+
}
|
|
28898
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
28899
|
+
srcTxHash: spokeTxHash,
|
|
28900
|
+
data: extraData,
|
|
28901
|
+
chainKey: params.srcChainKey,
|
|
28902
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
28903
|
+
timeout
|
|
28904
|
+
});
|
|
28905
|
+
if (!packetResult.ok) {
|
|
28906
|
+
return {
|
|
28907
|
+
ok: false,
|
|
28908
|
+
error: mapRelayFailure(packetResult.error, {
|
|
28909
|
+
feature: "migration",
|
|
28910
|
+
action: baseCtx.action,
|
|
28911
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
28912
|
+
dstChainKey: baseCtx.dstChainKey
|
|
28913
|
+
})
|
|
28914
|
+
};
|
|
28915
|
+
}
|
|
28916
|
+
if (!(params.srcChainKey === ChainKeys.SONIC_MAINNET || params.dstChainKey === ChainKeys.SONIC_MAINNET)) {
|
|
28917
|
+
const execResult = await waitUntilIntentExecuted({
|
|
28918
|
+
intentRelayChainId: getIntentRelayChainId(ChainKeys.SONIC_MAINNET).toString(),
|
|
28919
|
+
srcTxHash: packetResult.value.dst_tx_hash,
|
|
28920
|
+
timeout,
|
|
28921
|
+
apiUrl: this.relayerApiEndpoint
|
|
28922
|
+
});
|
|
28923
|
+
if (!execResult.ok) {
|
|
28924
|
+
return {
|
|
28925
|
+
ok: false,
|
|
28926
|
+
error: mapRelayFailure(execResult.error, {
|
|
28927
|
+
feature: "migration",
|
|
28928
|
+
action: baseCtx.action,
|
|
28929
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
28930
|
+
dstChainKey: baseCtx.dstChainKey,
|
|
28931
|
+
phase: "destinationExecution"
|
|
28932
|
+
})
|
|
28933
|
+
};
|
|
28934
|
+
}
|
|
28935
|
+
}
|
|
28936
|
+
return { ok: true, value: { srcChainTxHash: spokeTxHash, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
28937
|
+
} catch (error) {
|
|
28938
|
+
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28577
28939
|
return {
|
|
28578
28940
|
ok: false,
|
|
28579
|
-
error:
|
|
28580
|
-
feature: "migration",
|
|
28581
|
-
action: baseCtx.action,
|
|
28582
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
28583
|
-
dstChainKey: baseCtx.dstChainKey,
|
|
28584
|
-
phase: "destinationExecution"
|
|
28585
|
-
})
|
|
28941
|
+
error: executionFailed("migration", error, baseCtx)
|
|
28586
28942
|
};
|
|
28587
28943
|
}
|
|
28944
|
+
},
|
|
28945
|
+
{
|
|
28946
|
+
start: () => ({
|
|
28947
|
+
srcChainKey: _params.params.srcChainKey,
|
|
28948
|
+
dstChainKey: _params.params.dstChainKey,
|
|
28949
|
+
srcAddress: _params.params.srcAddress,
|
|
28950
|
+
dstAddress: _params.params.dstAddress,
|
|
28951
|
+
srcbnUSD: _params.params.srcbnUSD,
|
|
28952
|
+
dstbnUSD: _params.params.dstbnUSD,
|
|
28953
|
+
amount: _params.params.amount
|
|
28954
|
+
}),
|
|
28955
|
+
success: (value) => ({
|
|
28956
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
28957
|
+
dstChainTxHash: value.dstChainTxHash
|
|
28958
|
+
}),
|
|
28959
|
+
failure: (error) => ({ code: error.code })
|
|
28588
28960
|
}
|
|
28589
|
-
|
|
28590
|
-
} catch (error) {
|
|
28591
|
-
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28592
|
-
return {
|
|
28593
|
-
ok: false,
|
|
28594
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28595
|
-
};
|
|
28596
|
-
}
|
|
28961
|
+
);
|
|
28597
28962
|
}
|
|
28598
28963
|
/**
|
|
28599
28964
|
* Migrates ICX or wICX tokens from ICON to SODA on the hub chain (Sonic), including relay.
|
|
@@ -28608,37 +28973,57 @@ var MigrationService = class {
|
|
|
28608
28973
|
* check fails, the deposit reverts, or the relay times out.
|
|
28609
28974
|
*/
|
|
28610
28975
|
async migrateIcxToSoda(_params) {
|
|
28611
|
-
|
|
28612
|
-
|
|
28613
|
-
|
|
28614
|
-
|
|
28615
|
-
|
|
28616
|
-
|
|
28617
|
-
|
|
28618
|
-
|
|
28619
|
-
|
|
28620
|
-
|
|
28621
|
-
|
|
28622
|
-
|
|
28623
|
-
|
|
28624
|
-
|
|
28625
|
-
|
|
28626
|
-
|
|
28627
|
-
|
|
28628
|
-
|
|
28629
|
-
|
|
28630
|
-
|
|
28631
|
-
|
|
28632
|
-
|
|
28976
|
+
return this.config.analytics.trackResult(
|
|
28977
|
+
"migration",
|
|
28978
|
+
"migrateIcxToSoda",
|
|
28979
|
+
async () => {
|
|
28980
|
+
const { timeout } = _params;
|
|
28981
|
+
const baseCtx = { srcChainKey: _params.params.srcChainKey, action: "migrateIcxToSoda" };
|
|
28982
|
+
try {
|
|
28983
|
+
const txResult = await this.createMigrateIcxToSodaIntent(_params);
|
|
28984
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
28985
|
+
const { tx, relayData } = txResult.value;
|
|
28986
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
28987
|
+
srcTxHash: tx,
|
|
28988
|
+
data: relayData,
|
|
28989
|
+
chainKey: _params.params.srcChainKey,
|
|
28990
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
28991
|
+
timeout
|
|
28992
|
+
});
|
|
28993
|
+
if (!packetResult.ok) {
|
|
28994
|
+
return {
|
|
28995
|
+
ok: false,
|
|
28996
|
+
error: mapRelayFailure(packetResult.error, {
|
|
28997
|
+
feature: "migration",
|
|
28998
|
+
action: baseCtx.action,
|
|
28999
|
+
srcChainKey: baseCtx.srcChainKey
|
|
29000
|
+
})
|
|
29001
|
+
};
|
|
29002
|
+
}
|
|
29003
|
+
return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
29004
|
+
} catch (error) {
|
|
29005
|
+
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
29006
|
+
return {
|
|
29007
|
+
ok: false,
|
|
29008
|
+
error: executionFailed("migration", error, baseCtx)
|
|
29009
|
+
};
|
|
29010
|
+
}
|
|
29011
|
+
},
|
|
29012
|
+
{
|
|
29013
|
+
start: () => ({
|
|
29014
|
+
srcChainKey: _params.params.srcChainKey,
|
|
29015
|
+
srcAddress: _params.params.srcAddress,
|
|
29016
|
+
dstAddress: _params.params.dstAddress,
|
|
29017
|
+
address: _params.params.address,
|
|
29018
|
+
amount: _params.params.amount
|
|
29019
|
+
}),
|
|
29020
|
+
success: (value) => ({
|
|
29021
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
29022
|
+
dstChainTxHash: value.dstChainTxHash
|
|
29023
|
+
}),
|
|
29024
|
+
failure: (error) => ({ code: error.code })
|
|
28633
29025
|
}
|
|
28634
|
-
|
|
28635
|
-
} catch (error) {
|
|
28636
|
-
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28637
|
-
return {
|
|
28638
|
-
ok: false,
|
|
28639
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28640
|
-
};
|
|
28641
|
-
}
|
|
29026
|
+
);
|
|
28642
29027
|
}
|
|
28643
29028
|
/**
|
|
28644
29029
|
* Reverts a previous ICX→SODA migration by swapping SODA back to wICX on the hub and
|
|
@@ -28656,37 +29041,56 @@ var MigrationService = class {
|
|
|
28656
29041
|
* Sonic deposit transaction and `dstChainTxHash` is the hub-side packet receipt.
|
|
28657
29042
|
*/
|
|
28658
29043
|
async revertMigrateSodaToIcx(_params) {
|
|
28659
|
-
|
|
28660
|
-
|
|
28661
|
-
|
|
28662
|
-
|
|
28663
|
-
|
|
28664
|
-
|
|
28665
|
-
|
|
28666
|
-
|
|
28667
|
-
|
|
28668
|
-
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
|
|
28678
|
-
|
|
28679
|
-
|
|
28680
|
-
|
|
29044
|
+
return this.config.analytics.trackResult(
|
|
29045
|
+
"migration",
|
|
29046
|
+
"revertMigrateSodaToIcx",
|
|
29047
|
+
async () => {
|
|
29048
|
+
const { timeout } = _params;
|
|
29049
|
+
const baseCtx = { srcChainKey: ChainKeys.SONIC_MAINNET, action: "revertMigrateSodaToIcx" };
|
|
29050
|
+
try {
|
|
29051
|
+
const txResult = await this.createRevertSodaToIcxMigrationIntent(_params);
|
|
29052
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
29053
|
+
const { tx, relayData } = txResult.value;
|
|
29054
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
29055
|
+
srcTxHash: tx,
|
|
29056
|
+
data: relayData,
|
|
29057
|
+
chainKey: ChainKeys.SONIC_MAINNET,
|
|
29058
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
29059
|
+
timeout
|
|
29060
|
+
});
|
|
29061
|
+
if (!packetResult.ok) {
|
|
29062
|
+
return {
|
|
29063
|
+
ok: false,
|
|
29064
|
+
error: mapRelayFailure(packetResult.error, {
|
|
29065
|
+
feature: "migration",
|
|
29066
|
+
action: baseCtx.action,
|
|
29067
|
+
srcChainKey: baseCtx.srcChainKey
|
|
29068
|
+
})
|
|
29069
|
+
};
|
|
29070
|
+
}
|
|
29071
|
+
return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
29072
|
+
} catch (error) {
|
|
29073
|
+
if (isRevertMigrationOrchestrationError(error)) return { ok: false, error };
|
|
29074
|
+
return {
|
|
29075
|
+
ok: false,
|
|
29076
|
+
error: executionFailed("migration", error, baseCtx)
|
|
29077
|
+
};
|
|
29078
|
+
}
|
|
29079
|
+
},
|
|
29080
|
+
{
|
|
29081
|
+
start: () => ({
|
|
29082
|
+
srcChainKey: _params.params.srcChainKey,
|
|
29083
|
+
srcAddress: _params.params.srcAddress,
|
|
29084
|
+
dstAddress: _params.params.dstAddress,
|
|
29085
|
+
amount: _params.params.amount
|
|
29086
|
+
}),
|
|
29087
|
+
success: (value) => ({
|
|
29088
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
29089
|
+
dstChainTxHash: value.dstChainTxHash
|
|
29090
|
+
}),
|
|
29091
|
+
failure: (error) => ({ code: error.code })
|
|
28681
29092
|
}
|
|
28682
|
-
|
|
28683
|
-
} catch (error) {
|
|
28684
|
-
if (isRevertMigrationOrchestrationError(error)) return { ok: false, error };
|
|
28685
|
-
return {
|
|
28686
|
-
ok: false,
|
|
28687
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28688
|
-
};
|
|
28689
|
-
}
|
|
29093
|
+
);
|
|
28690
29094
|
}
|
|
28691
29095
|
/**
|
|
28692
29096
|
* Migrates BALN tokens from ICON to SODA on the hub chain (Sonic), including relay.
|
|
@@ -28703,37 +29107,58 @@ var MigrationService = class {
|
|
|
28703
29107
|
* ICON deposit transaction and `dstChainTxHash` is the hub-side packet receipt.
|
|
28704
29108
|
*/
|
|
28705
29109
|
async migrateBaln(_params) {
|
|
28706
|
-
|
|
28707
|
-
|
|
28708
|
-
|
|
28709
|
-
|
|
28710
|
-
|
|
28711
|
-
|
|
28712
|
-
|
|
28713
|
-
|
|
28714
|
-
|
|
28715
|
-
|
|
28716
|
-
|
|
28717
|
-
|
|
28718
|
-
|
|
28719
|
-
|
|
28720
|
-
|
|
28721
|
-
|
|
28722
|
-
|
|
28723
|
-
|
|
28724
|
-
|
|
28725
|
-
|
|
28726
|
-
|
|
28727
|
-
|
|
29110
|
+
return this.config.analytics.trackResult(
|
|
29111
|
+
"migration",
|
|
29112
|
+
"migrateBaln",
|
|
29113
|
+
async () => {
|
|
29114
|
+
const { timeout } = _params;
|
|
29115
|
+
const baseCtx = { srcChainKey: ChainKeys.ICON_MAINNET, action: "migrateBaln" };
|
|
29116
|
+
try {
|
|
29117
|
+
const txResult = await this.createMigrateBalnIntent(_params);
|
|
29118
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
29119
|
+
const { tx, relayData } = txResult.value;
|
|
29120
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
29121
|
+
srcTxHash: tx,
|
|
29122
|
+
data: relayData,
|
|
29123
|
+
chainKey: ChainKeys.ICON_MAINNET,
|
|
29124
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
29125
|
+
timeout
|
|
29126
|
+
});
|
|
29127
|
+
if (!packetResult.ok) {
|
|
29128
|
+
return {
|
|
29129
|
+
ok: false,
|
|
29130
|
+
error: mapRelayFailure(packetResult.error, {
|
|
29131
|
+
feature: "migration",
|
|
29132
|
+
action: baseCtx.action,
|
|
29133
|
+
srcChainKey: baseCtx.srcChainKey
|
|
29134
|
+
})
|
|
29135
|
+
};
|
|
29136
|
+
}
|
|
29137
|
+
return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
|
|
29138
|
+
} catch (error) {
|
|
29139
|
+
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
29140
|
+
return {
|
|
29141
|
+
ok: false,
|
|
29142
|
+
error: executionFailed("migration", error, baseCtx)
|
|
29143
|
+
};
|
|
29144
|
+
}
|
|
29145
|
+
},
|
|
29146
|
+
{
|
|
29147
|
+
start: () => ({
|
|
29148
|
+
srcChainKey: _params.params.srcChainKey,
|
|
29149
|
+
srcAddress: _params.params.srcAddress,
|
|
29150
|
+
dstAddress: _params.params.dstAddress,
|
|
29151
|
+
amount: _params.params.amount,
|
|
29152
|
+
lockupPeriod: _params.params.lockupPeriod,
|
|
29153
|
+
stake: _params.params.stake
|
|
29154
|
+
}),
|
|
29155
|
+
success: (value) => ({
|
|
29156
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
29157
|
+
dstChainTxHash: value.dstChainTxHash
|
|
29158
|
+
}),
|
|
29159
|
+
failure: (error) => ({ code: error.code })
|
|
28728
29160
|
}
|
|
28729
|
-
|
|
28730
|
-
} catch (error) {
|
|
28731
|
-
if (isMigrateOrchestrationError(error)) return { ok: false, error };
|
|
28732
|
-
return {
|
|
28733
|
-
ok: false,
|
|
28734
|
-
error: executionFailed("migration", error, baseCtx)
|
|
28735
|
-
};
|
|
28736
|
-
}
|
|
29161
|
+
);
|
|
28737
29162
|
}
|
|
28738
29163
|
/**
|
|
28739
29164
|
* Builds and submits the spoke-side deposit for a BALN→SODA migration without relaying.
|
|
@@ -29124,71 +29549,883 @@ var MigrationService = class {
|
|
|
29124
29549
|
}
|
|
29125
29550
|
};
|
|
29126
29551
|
|
|
29127
|
-
// src/backendApi/
|
|
29128
|
-
var
|
|
29552
|
+
// src/backendApi/api-utils.ts
|
|
29553
|
+
var toJsonBody = (value) => JSON.stringify(value, (_key, val) => typeof val === "bigint" ? val.toString() : val);
|
|
29554
|
+
async function makeRequest(params) {
|
|
29555
|
+
const { endpoint, config, overrideConfig = {}, logger, serviceLabel } = params;
|
|
29556
|
+
const baseURL = overrideConfig.baseURL || config.baseURL || "";
|
|
29557
|
+
const url = `${baseURL}${endpoint}`;
|
|
29558
|
+
const headers = { ...config.headers, ...overrideConfig.headers };
|
|
29559
|
+
const controller = new AbortController();
|
|
29560
|
+
const timeout = overrideConfig.timeout ?? config.timeout ?? DEFAULT_BACKEND_API_TIMEOUT;
|
|
29561
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
29562
|
+
try {
|
|
29563
|
+
const response = await fetch(url, {
|
|
29564
|
+
method: config.method,
|
|
29565
|
+
headers,
|
|
29566
|
+
body: config.body,
|
|
29567
|
+
signal: controller.signal
|
|
29568
|
+
});
|
|
29569
|
+
clearTimeout(timeoutId);
|
|
29570
|
+
if (!response.ok) {
|
|
29571
|
+
const errorText = await response.text();
|
|
29572
|
+
throw new Error("HTTP_REQUEST_FAILED", { cause: new Error(`HTTP ${response.status}: ${errorText}`) });
|
|
29573
|
+
}
|
|
29574
|
+
const data = await response.json();
|
|
29575
|
+
return data;
|
|
29576
|
+
} catch (error) {
|
|
29577
|
+
clearTimeout(timeoutId);
|
|
29578
|
+
if (error instanceof Error) {
|
|
29579
|
+
if (error.name === "AbortError") {
|
|
29580
|
+
throw new Error("REQUEST_TIMEOUT", { cause: new Error(`Request timeout after ${timeout}ms`) });
|
|
29581
|
+
}
|
|
29582
|
+
logger.error(`[${serviceLabel}] Request error`, error);
|
|
29583
|
+
throw error;
|
|
29584
|
+
}
|
|
29585
|
+
logger.error(`[${serviceLabel}] Unknown error`, error);
|
|
29586
|
+
throw new Error("UNKNOWN_REQUEST_ERROR", { cause: error });
|
|
29587
|
+
}
|
|
29588
|
+
}
|
|
29589
|
+
var SwapTokenSchema = v4__namespace.object({
|
|
29590
|
+
symbol: v4__namespace.string(),
|
|
29591
|
+
name: v4__namespace.string(),
|
|
29592
|
+
decimals: v4__namespace.number(),
|
|
29593
|
+
address: v4__namespace.string(),
|
|
29594
|
+
chainKey: v4__namespace.string(),
|
|
29595
|
+
hubAsset: v4__namespace.string(),
|
|
29596
|
+
vault: v4__namespace.string()
|
|
29597
|
+
});
|
|
29598
|
+
var IntentResponseSchema = v4__namespace.object({
|
|
29599
|
+
intentId: v4__namespace.string(),
|
|
29600
|
+
creator: v4__namespace.string(),
|
|
29601
|
+
inputToken: v4__namespace.string(),
|
|
29602
|
+
outputToken: v4__namespace.string(),
|
|
29603
|
+
inputAmount: v4__namespace.string(),
|
|
29604
|
+
minOutputAmount: v4__namespace.string(),
|
|
29605
|
+
deadline: v4__namespace.string(),
|
|
29606
|
+
allowPartialFill: v4__namespace.boolean(),
|
|
29607
|
+
srcChain: v4__namespace.string(),
|
|
29608
|
+
dstChain: v4__namespace.string(),
|
|
29609
|
+
srcAddress: v4__namespace.string(),
|
|
29610
|
+
dstAddress: v4__namespace.string(),
|
|
29611
|
+
solver: v4__namespace.string(),
|
|
29612
|
+
data: v4__namespace.string()
|
|
29613
|
+
});
|
|
29614
|
+
var RelayExtraDataResponseSchema = v4__namespace.object({
|
|
29615
|
+
address: v4__namespace.string(),
|
|
29616
|
+
payload: v4__namespace.string()
|
|
29617
|
+
});
|
|
29618
|
+
var makeCreateIntentResponseSchema = (txSchema) => v4__namespace.object({
|
|
29619
|
+
tx: txSchema,
|
|
29620
|
+
intent: IntentResponseSchema,
|
|
29621
|
+
relayData: RelayExtraDataResponseSchema
|
|
29622
|
+
});
|
|
29623
|
+
var GetSwapTokensResponseSchema = v4__namespace.record(v4__namespace.string(), v4__namespace.array(SwapTokenSchema));
|
|
29624
|
+
var GetSwapTokensByChainResponseSchema = v4__namespace.array(SwapTokenSchema);
|
|
29625
|
+
var makeQuoteResponseSchema = (txSchema) => v4__namespace.object({
|
|
29626
|
+
quotedAmount: v4__namespace.string(),
|
|
29627
|
+
txData: v4__namespace.optional(makeCreateIntentResponseSchema(txSchema))
|
|
29628
|
+
});
|
|
29629
|
+
var DeadlineResponseSchema = v4__namespace.object({
|
|
29630
|
+
deadline: v4__namespace.string()
|
|
29631
|
+
});
|
|
29632
|
+
var AllowanceCheckResponseSchema = v4__namespace.object({
|
|
29633
|
+
valid: v4__namespace.boolean()
|
|
29634
|
+
});
|
|
29635
|
+
var makeApproveResponseSchema = (txSchema) => v4__namespace.object({ tx: txSchema });
|
|
29636
|
+
var SubmitIntentResponseSchema = v4__namespace.object({
|
|
29637
|
+
result: v4__namespace.unknown()
|
|
29638
|
+
});
|
|
29639
|
+
var StatusResponseSchema = v4__namespace.object({
|
|
29640
|
+
status: v4__namespace.picklist([-1, 1, 2, 3, 4]),
|
|
29641
|
+
fillTxHash: v4__namespace.optional(v4__namespace.string())
|
|
29642
|
+
});
|
|
29643
|
+
var makeCancelIntentResponseSchema = (txSchema) => v4__namespace.object({ tx: txSchema });
|
|
29644
|
+
var IntentHashResponseSchema = v4__namespace.object({
|
|
29645
|
+
hash: v4__namespace.string()
|
|
29646
|
+
});
|
|
29647
|
+
var IntentPacketResponseSchema = v4__namespace.object({
|
|
29648
|
+
srcChainId: v4__namespace.number(),
|
|
29649
|
+
srcTxHash: v4__namespace.string(),
|
|
29650
|
+
srcAddress: v4__namespace.string(),
|
|
29651
|
+
status: v4__namespace.string(),
|
|
29652
|
+
dstChainId: v4__namespace.number(),
|
|
29653
|
+
connSn: v4__namespace.number(),
|
|
29654
|
+
dstAddress: v4__namespace.string(),
|
|
29655
|
+
dstTxHash: v4__namespace.string(),
|
|
29656
|
+
signatures: v4__namespace.array(v4__namespace.string()),
|
|
29657
|
+
payload: v4__namespace.string()
|
|
29658
|
+
});
|
|
29659
|
+
var IntentStateResponseSchema = v4__namespace.object({
|
|
29660
|
+
exists: v4__namespace.boolean(),
|
|
29661
|
+
remainingInput: v4__namespace.string(),
|
|
29662
|
+
receivedOutput: v4__namespace.string(),
|
|
29663
|
+
pendingPayment: v4__namespace.boolean()
|
|
29664
|
+
});
|
|
29665
|
+
var GasEstimateResponseSchema = v4__namespace.object({
|
|
29666
|
+
gas: v4__namespace.unknown()
|
|
29667
|
+
});
|
|
29668
|
+
var FeeResponseSchema = v4__namespace.object({
|
|
29669
|
+
fee: v4__namespace.string()
|
|
29670
|
+
});
|
|
29671
|
+
var SubmitTxResponseSchema = v4__namespace.object({
|
|
29672
|
+
success: v4__namespace.boolean(),
|
|
29673
|
+
data: v4__namespace.object({
|
|
29674
|
+
status: v4__namespace.picklist(["inserted", "duplicate"]),
|
|
29675
|
+
message: v4__namespace.string()
|
|
29676
|
+
})
|
|
29677
|
+
});
|
|
29678
|
+
var SubmitSwapTxStatusSchema = v4__namespace.picklist([
|
|
29679
|
+
"pending",
|
|
29680
|
+
"relaying",
|
|
29681
|
+
"relayed",
|
|
29682
|
+
"posting_execution",
|
|
29683
|
+
"executed",
|
|
29684
|
+
"failed"
|
|
29685
|
+
]);
|
|
29686
|
+
var PacketDataSchema = v4__namespace.object({
|
|
29687
|
+
src_chain_id: v4__namespace.number(),
|
|
29688
|
+
src_tx_hash: v4__namespace.string(),
|
|
29689
|
+
src_address: v4__namespace.string(),
|
|
29690
|
+
status: v4__namespace.picklist(["pending", "validating", "executing", "executed"]),
|
|
29691
|
+
dst_chain_id: v4__namespace.number(),
|
|
29692
|
+
conn_sn: v4__namespace.number(),
|
|
29693
|
+
dst_address: v4__namespace.string(),
|
|
29694
|
+
dst_tx_hash: v4__namespace.string(),
|
|
29695
|
+
signatures: v4__namespace.array(v4__namespace.string()),
|
|
29696
|
+
payload: v4__namespace.string()
|
|
29697
|
+
});
|
|
29698
|
+
var SubmitTxStatusResultSchema = v4__namespace.object({
|
|
29699
|
+
dstIntentTxHash: v4__namespace.string(),
|
|
29700
|
+
packetData: v4__namespace.optional(PacketDataSchema),
|
|
29701
|
+
intent_hash: v4__namespace.optional(v4__namespace.string())
|
|
29702
|
+
});
|
|
29703
|
+
var SubmitTxStatusDataSchema = v4__namespace.object({
|
|
29704
|
+
txHash: v4__namespace.string(),
|
|
29705
|
+
srcChainKey: v4__namespace.string(),
|
|
29706
|
+
status: SubmitSwapTxStatusSchema,
|
|
29707
|
+
failedAtStep: v4__namespace.optional(SubmitSwapTxStatusSchema),
|
|
29708
|
+
failureReason: v4__namespace.optional(v4__namespace.string()),
|
|
29709
|
+
processingAttempts: v4__namespace.number(),
|
|
29710
|
+
abandonedAt: v4__namespace.optional(v4__namespace.string()),
|
|
29711
|
+
result: v4__namespace.optional(SubmitTxStatusResultSchema),
|
|
29712
|
+
userMessage: v4__namespace.optional(v4__namespace.string()),
|
|
29713
|
+
intentCancelled: v4__namespace.optional(v4__namespace.boolean())
|
|
29714
|
+
});
|
|
29715
|
+
var SubmitTxStatusResponseSchema = v4__namespace.object({
|
|
29716
|
+
success: v4__namespace.boolean(),
|
|
29717
|
+
data: SubmitTxStatusDataSchema
|
|
29718
|
+
});
|
|
29719
|
+
var AddressSchema = v4__namespace.custom((input) => typeof input === "string");
|
|
29720
|
+
var HexSchema = v4__namespace.custom((input) => typeof input === "string");
|
|
29721
|
+
var BigintFromString = v4__namespace.pipe(v4__namespace.string(), v4__namespace.toBigint());
|
|
29722
|
+
var BytesFromIndexRecord = v4__namespace.pipe(
|
|
29723
|
+
v4__namespace.record(v4__namespace.string(), v4__namespace.number()),
|
|
29724
|
+
v4__namespace.transform((indexed) => Uint8Array.from(Object.values(indexed)))
|
|
29725
|
+
);
|
|
29726
|
+
var EvmRawTxSchema = v4__namespace.object({
|
|
29727
|
+
from: AddressSchema,
|
|
29728
|
+
to: AddressSchema,
|
|
29729
|
+
value: BigintFromString,
|
|
29730
|
+
data: HexSchema
|
|
29731
|
+
});
|
|
29732
|
+
var SolanaRawTxSchema = v4__namespace.object({
|
|
29733
|
+
from: v4__namespace.string(),
|
|
29734
|
+
to: v4__namespace.string(),
|
|
29735
|
+
value: BigintFromString,
|
|
29736
|
+
data: v4__namespace.string()
|
|
29737
|
+
});
|
|
29738
|
+
var SuiRawTxSchema = v4__namespace.object({
|
|
29739
|
+
from: HexSchema,
|
|
29740
|
+
to: v4__namespace.string(),
|
|
29741
|
+
value: BigintFromString,
|
|
29742
|
+
data: v4__namespace.string()
|
|
29743
|
+
});
|
|
29744
|
+
var StellarRawTxSchema = v4__namespace.object({
|
|
29745
|
+
from: v4__namespace.string(),
|
|
29746
|
+
to: v4__namespace.string(),
|
|
29747
|
+
value: BigintFromString,
|
|
29748
|
+
data: v4__namespace.string()
|
|
29749
|
+
});
|
|
29750
|
+
var InjectiveRawTxSchema = v4__namespace.object({
|
|
29751
|
+
from: HexSchema,
|
|
29752
|
+
to: HexSchema,
|
|
29753
|
+
signedDoc: v4__namespace.object({
|
|
29754
|
+
bodyBytes: BytesFromIndexRecord,
|
|
29755
|
+
authInfoBytes: BytesFromIndexRecord,
|
|
29756
|
+
chainId: v4__namespace.string(),
|
|
29757
|
+
accountNumber: BigintFromString
|
|
29758
|
+
})
|
|
29759
|
+
});
|
|
29760
|
+
var NearRawTxSchema = v4__namespace.object({
|
|
29761
|
+
signerId: v4__namespace.string(),
|
|
29762
|
+
params: v4__namespace.object({
|
|
29763
|
+
contractId: v4__namespace.string(),
|
|
29764
|
+
method: v4__namespace.string(),
|
|
29765
|
+
args: v4__namespace.custom((input) => typeof input === "object" && input !== null),
|
|
29766
|
+
gas: v4__namespace.optional(BigintFromString),
|
|
29767
|
+
deposit: v4__namespace.optional(BigintFromString)
|
|
29768
|
+
})
|
|
29769
|
+
});
|
|
29770
|
+
var IconRawTxSchema = v4__namespace.record(
|
|
29771
|
+
v4__namespace.string(),
|
|
29772
|
+
v4__namespace.union([v4__namespace.string(), v4__namespace.custom((input) => typeof input === "object" && input !== null)])
|
|
29773
|
+
);
|
|
29774
|
+
var StacksRawTxSchema = v4__namespace.object({
|
|
29775
|
+
payload: v4__namespace.string(),
|
|
29776
|
+
estimatedLength: v4__namespace.optional(v4__namespace.number())
|
|
29777
|
+
});
|
|
29778
|
+
var AnyRawTxSchema = v4__namespace.custom((input) => typeof input === "object" && input !== null);
|
|
29779
|
+
function rawTxSchemaForChainKey(chainKey) {
|
|
29780
|
+
let chainType;
|
|
29781
|
+
try {
|
|
29782
|
+
chainType = getChainType(chainKey);
|
|
29783
|
+
} catch {
|
|
29784
|
+
chainType = void 0;
|
|
29785
|
+
}
|
|
29786
|
+
switch (chainType) {
|
|
29787
|
+
case "EVM":
|
|
29788
|
+
return EvmRawTxSchema;
|
|
29789
|
+
case "SOLANA":
|
|
29790
|
+
return SolanaRawTxSchema;
|
|
29791
|
+
case "SUI":
|
|
29792
|
+
return SuiRawTxSchema;
|
|
29793
|
+
case "STELLAR":
|
|
29794
|
+
return StellarRawTxSchema;
|
|
29795
|
+
case "INJECTIVE":
|
|
29796
|
+
return InjectiveRawTxSchema;
|
|
29797
|
+
case "ICON":
|
|
29798
|
+
return IconRawTxSchema;
|
|
29799
|
+
case "STACKS":
|
|
29800
|
+
return StacksRawTxSchema;
|
|
29801
|
+
case "NEAR":
|
|
29802
|
+
return NearRawTxSchema;
|
|
29803
|
+
default:
|
|
29804
|
+
return AnyRawTxSchema;
|
|
29805
|
+
}
|
|
29806
|
+
}
|
|
29807
|
+
|
|
29808
|
+
// src/backendApi/SwapsApiService.ts
|
|
29809
|
+
var SwapsApiService = class {
|
|
29810
|
+
// Fully-resolved swaps-API config supplied by the caller (BackendApiService resolves the
|
|
29811
|
+
// `ApiConfig` union via `resolveSwapsApiConfig`); this service does not resolve the union.
|
|
29812
|
+
config;
|
|
29813
|
+
headers;
|
|
29814
|
+
logger;
|
|
29129
29815
|
constructor(config, logger = consoleLogger) {
|
|
29130
29816
|
this.config = config;
|
|
29131
29817
|
this.headers = { ...config.headers };
|
|
29132
29818
|
this.logger = logger;
|
|
29133
29819
|
}
|
|
29134
|
-
headers;
|
|
29135
|
-
logger;
|
|
29136
29820
|
/**
|
|
29137
|
-
*
|
|
29138
|
-
*
|
|
29139
|
-
*
|
|
29140
|
-
*
|
|
29141
|
-
* request exceeds the timeout, so callers should use {@link request} instead of
|
|
29142
|
-
* calling this directly.
|
|
29143
|
-
*
|
|
29144
|
-
* @throws `Error('HTTP_REQUEST_FAILED')` on non-2xx responses.
|
|
29145
|
-
* @throws `Error('REQUEST_TIMEOUT')` when the request exceeds the timeout.
|
|
29146
|
-
* @throws `Error('UNKNOWN_REQUEST_ERROR')` for any other unexpected failure.
|
|
29821
|
+
* Issues a single HTTP request, validates the JSON body against `schema`, and
|
|
29822
|
+
* wraps the result in `Result<T>`. The service-level `baseURL`/`timeout`/
|
|
29823
|
+
* `headers` are merged with the optional per-call `overrideConfig` (which takes
|
|
29824
|
+
* precedence) inside {@link makeRequest}. Every public method delegates here.
|
|
29147
29825
|
*/
|
|
29148
|
-
async
|
|
29149
|
-
const url = config.baseURL ? `${config.baseURL}${endpoint}` : `${this.config.baseURL}${endpoint}`;
|
|
29150
|
-
const headers = { ...this.headers, ...config.headers };
|
|
29151
|
-
const controller = new AbortController();
|
|
29152
|
-
const timeout = config.timeout ?? this.config.timeout;
|
|
29153
|
-
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
29826
|
+
async request(endpoint, config, schema, overrideConfig) {
|
|
29154
29827
|
try {
|
|
29155
|
-
const
|
|
29156
|
-
|
|
29157
|
-
headers,
|
|
29158
|
-
|
|
29159
|
-
|
|
29828
|
+
const raw = await makeRequest({
|
|
29829
|
+
endpoint,
|
|
29830
|
+
config: { baseURL: this.config.baseURL, timeout: this.config.timeout, headers: this.headers, ...config },
|
|
29831
|
+
overrideConfig,
|
|
29832
|
+
logger: this.logger,
|
|
29833
|
+
serviceLabel: "SwapsApiService"
|
|
29160
29834
|
});
|
|
29161
|
-
|
|
29162
|
-
if (!
|
|
29163
|
-
|
|
29164
|
-
|
|
29835
|
+
const parsed = v4__namespace.safeParse(schema, raw);
|
|
29836
|
+
if (!parsed.success) {
|
|
29837
|
+
return {
|
|
29838
|
+
ok: false,
|
|
29839
|
+
error: new SodaxError("EXTERNAL_API_ERROR", `Invalid response shape from swaps API for ${endpoint}`, {
|
|
29840
|
+
feature: "backend",
|
|
29841
|
+
context: { api: "swaps", endpoint, reason: "invalid_response_shape", issues: v4__namespace.flatten(parsed.issues) }
|
|
29842
|
+
})
|
|
29843
|
+
};
|
|
29165
29844
|
}
|
|
29166
|
-
|
|
29167
|
-
return data;
|
|
29845
|
+
return { ok: true, value: parsed.output };
|
|
29168
29846
|
} catch (error) {
|
|
29169
|
-
|
|
29170
|
-
|
|
29171
|
-
|
|
29172
|
-
|
|
29173
|
-
|
|
29174
|
-
|
|
29175
|
-
|
|
29176
|
-
|
|
29177
|
-
|
|
29178
|
-
|
|
29847
|
+
return {
|
|
29848
|
+
ok: false,
|
|
29849
|
+
error: new SodaxError(
|
|
29850
|
+
"EXTERNAL_API_ERROR",
|
|
29851
|
+
error instanceof Error ? error.message : `Request to ${endpoint} failed`,
|
|
29852
|
+
{
|
|
29853
|
+
feature: "backend",
|
|
29854
|
+
cause: error,
|
|
29855
|
+
context: { api: "swaps", endpoint }
|
|
29856
|
+
}
|
|
29857
|
+
)
|
|
29858
|
+
};
|
|
29859
|
+
}
|
|
29860
|
+
}
|
|
29861
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29862
|
+
// Tokens
|
|
29863
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29864
|
+
/**
|
|
29865
|
+
* Fetch all supported swap tokens grouped by SpokeChainKey.
|
|
29866
|
+
*
|
|
29867
|
+
* @returns `Result<GetSwapTokensResponseV2>` — map of chain key → token list.
|
|
29868
|
+
*/
|
|
29869
|
+
async getTokens(config) {
|
|
29870
|
+
return this.request("/swaps/tokens", { method: "GET" }, GetSwapTokensResponseSchema, config);
|
|
29871
|
+
}
|
|
29872
|
+
/**
|
|
29873
|
+
* Fetch supported swap tokens for a single SpokeChainKey.
|
|
29874
|
+
*
|
|
29875
|
+
* @param chainKey - SODAX SpokeChainKey (e.g. `0xa4b1.arbitrum`, `solana`).
|
|
29876
|
+
* @returns `Result<GetSwapTokensByChainResponseV2>` — token list for the chain.
|
|
29877
|
+
*/
|
|
29878
|
+
async getTokensByChain(chainKey, config) {
|
|
29879
|
+
return this.request(
|
|
29880
|
+
`/swaps/tokens/${chainKey}`,
|
|
29881
|
+
{ method: "GET" },
|
|
29882
|
+
GetSwapTokensByChainResponseSchema,
|
|
29883
|
+
config
|
|
29884
|
+
);
|
|
29885
|
+
}
|
|
29886
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29887
|
+
// Quote · deadline
|
|
29888
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29889
|
+
/**
|
|
29890
|
+
* Get a solver quote for a cross-chain swap.
|
|
29891
|
+
*
|
|
29892
|
+
* Pass `query.includeTxData = true` to also build an unsigned create-intent
|
|
29893
|
+
* transaction (`txData`) using the quoted amount as `minOutputAmount`; in that
|
|
29894
|
+
* case `srcAddress`/`dstAddress` are required in the body.
|
|
29895
|
+
*
|
|
29896
|
+
* @returns `Result<QuoteResponseV2>` — `quotedAmount` (decimal string) and optional `txData`.
|
|
29897
|
+
*/
|
|
29898
|
+
async getQuote(body, query, config) {
|
|
29899
|
+
const endpoint = query?.includeTxData ? "/swaps/quote?includeTxData=true" : "/swaps/quote";
|
|
29900
|
+
const txSchema = rawTxSchemaForChainKey(body.tokenSrcChainKey);
|
|
29901
|
+
return this.request(
|
|
29902
|
+
endpoint,
|
|
29903
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29904
|
+
makeQuoteResponseSchema(txSchema),
|
|
29905
|
+
config
|
|
29906
|
+
);
|
|
29907
|
+
}
|
|
29908
|
+
/**
|
|
29909
|
+
* Compute a swap deadline (hub timestamp + `offsetSeconds`, default 300s).
|
|
29910
|
+
*
|
|
29911
|
+
* @returns `Result<DeadlineResponseV2>` — unix-seconds deadline (decimal string).
|
|
29912
|
+
*/
|
|
29913
|
+
async getDeadline(query, config) {
|
|
29914
|
+
const queryParams = new URLSearchParams();
|
|
29915
|
+
if (query?.offsetSeconds !== void 0) queryParams.append("offsetSeconds", String(query.offsetSeconds));
|
|
29916
|
+
const queryString = queryParams.toString();
|
|
29917
|
+
const endpoint = queryString.length > 0 ? `/swaps/deadline?${queryString}` : "/swaps/deadline";
|
|
29918
|
+
return this.request(endpoint, { method: "GET" }, DeadlineResponseSchema, config);
|
|
29919
|
+
}
|
|
29920
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29921
|
+
// Allowance · approve · create intent
|
|
29922
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29923
|
+
/**
|
|
29924
|
+
* Check whether the source token allowance is already sufficient for the intent.
|
|
29925
|
+
*
|
|
29926
|
+
* @returns `Result<AllowanceCheckResponseV2>` — `{ valid }`.
|
|
29927
|
+
*/
|
|
29928
|
+
async checkAllowance(body, config) {
|
|
29929
|
+
return this.request(
|
|
29930
|
+
"/swaps/allowance/check",
|
|
29931
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29932
|
+
AllowanceCheckResponseSchema,
|
|
29933
|
+
config
|
|
29934
|
+
);
|
|
29935
|
+
}
|
|
29936
|
+
/**
|
|
29937
|
+
* Build an unsigned token-approval transaction for the source token.
|
|
29938
|
+
*
|
|
29939
|
+
* @returns `Result<ApproveResponseV2>` — `{ tx }` (chain-specific unsigned tx).
|
|
29940
|
+
*/
|
|
29941
|
+
async approve(body, config) {
|
|
29942
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
29943
|
+
return this.request(
|
|
29944
|
+
"/swaps/approve",
|
|
29945
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29946
|
+
makeApproveResponseSchema(txSchema),
|
|
29947
|
+
config
|
|
29948
|
+
);
|
|
29949
|
+
}
|
|
29950
|
+
/**
|
|
29951
|
+
* Build an unsigned create-intent transaction.
|
|
29952
|
+
*
|
|
29953
|
+
* @returns `Result<CreateIntentResponseV2>` — `{ tx, intent, relayData }`.
|
|
29954
|
+
*/
|
|
29955
|
+
async createIntent(body, config) {
|
|
29956
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
29957
|
+
return this.request(
|
|
29958
|
+
"/swaps/intents",
|
|
29959
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29960
|
+
makeCreateIntentResponseSchema(txSchema),
|
|
29961
|
+
config
|
|
29962
|
+
);
|
|
29963
|
+
}
|
|
29964
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29965
|
+
// Intent lifecycle: submit · status · cancel · hash · packet · extra-data
|
|
29966
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
29967
|
+
/**
|
|
29968
|
+
* Submit the broadcast intent tx to the relay.
|
|
29969
|
+
*
|
|
29970
|
+
* @returns `Result<SubmitIntentResponseV2>` — `{ result }` (opaque relay response).
|
|
29971
|
+
*/
|
|
29972
|
+
async submitIntent(body, config) {
|
|
29973
|
+
return this.request(
|
|
29974
|
+
"/swaps/intents/submit",
|
|
29975
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29976
|
+
SubmitIntentResponseSchema,
|
|
29977
|
+
config
|
|
29978
|
+
);
|
|
29979
|
+
}
|
|
29980
|
+
/**
|
|
29981
|
+
* Poll the solver for intent execution status.
|
|
29982
|
+
*
|
|
29983
|
+
* @returns `Result<StatusResponseV2>` — `{ status, fillTxHash? }` (`fillTxHash` set when `status === 3`).
|
|
29984
|
+
*/
|
|
29985
|
+
async getStatus(body, config) {
|
|
29986
|
+
return this.request(
|
|
29987
|
+
"/swaps/intents/status",
|
|
29988
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
29989
|
+
StatusResponseSchema,
|
|
29990
|
+
config
|
|
29991
|
+
);
|
|
29992
|
+
}
|
|
29993
|
+
/**
|
|
29994
|
+
* Build an unsigned cancel-intent transaction. The `intent` field carries
|
|
29995
|
+
* `bigint` numerics — {@link toJsonBody} serializes them to decimal strings.
|
|
29996
|
+
*
|
|
29997
|
+
* @returns `Result<CancelIntentResponseV2>` — `{ tx }`.
|
|
29998
|
+
*/
|
|
29999
|
+
async cancelIntent(body, config) {
|
|
30000
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
30001
|
+
return this.request(
|
|
30002
|
+
"/swaps/intents/cancel",
|
|
30003
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30004
|
+
makeCancelIntentResponseSchema(txSchema),
|
|
30005
|
+
config
|
|
30006
|
+
);
|
|
30007
|
+
}
|
|
30008
|
+
/**
|
|
30009
|
+
* Compute the keccak256 hash of an Intent struct. The `intent` field carries
|
|
30010
|
+
* `bigint` numerics — {@link toJsonBody} serializes them to decimal strings.
|
|
30011
|
+
*
|
|
30012
|
+
* @returns `Result<IntentHashResponseV2>` — `{ hash }`.
|
|
30013
|
+
*/
|
|
30014
|
+
async getIntentHash(body, config) {
|
|
30015
|
+
return this.request(
|
|
30016
|
+
"/swaps/intents/hash",
|
|
30017
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30018
|
+
IntentHashResponseSchema,
|
|
30019
|
+
config
|
|
30020
|
+
);
|
|
30021
|
+
}
|
|
30022
|
+
/**
|
|
30023
|
+
* Long-poll the relayer until the fill packet lands on the destination chain.
|
|
30024
|
+
*
|
|
30025
|
+
* @returns `Result<IntentPacketResponseV2>` — delivered packet data.
|
|
30026
|
+
*/
|
|
30027
|
+
async getSolvedIntentPacket(body, config) {
|
|
30028
|
+
return this.request(
|
|
30029
|
+
"/swaps/intents/packet",
|
|
30030
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30031
|
+
IntentPacketResponseSchema,
|
|
30032
|
+
config
|
|
30033
|
+
);
|
|
30034
|
+
}
|
|
30035
|
+
/**
|
|
30036
|
+
* Recover the relay extra data needed by `/swaps/intents/submit`. Provide
|
|
30037
|
+
* EITHER `txHash` OR `intent` (whose `bigint` numerics {@link toJsonBody} serializes).
|
|
30038
|
+
*
|
|
30039
|
+
* @returns `Result<IntentExtraDataResponseV2>` — `{ address, payload }`.
|
|
30040
|
+
*/
|
|
30041
|
+
async getIntentSubmitTxExtraData(body, config) {
|
|
30042
|
+
return this.request(
|
|
30043
|
+
"/swaps/intents/extra-data",
|
|
30044
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30045
|
+
RelayExtraDataResponseSchema,
|
|
30046
|
+
config
|
|
30047
|
+
);
|
|
30048
|
+
}
|
|
30049
|
+
/**
|
|
30050
|
+
* Get the on-chain fill state for an intent by its hub-chain tx hash.
|
|
30051
|
+
*
|
|
30052
|
+
* @returns `Result<IntentStateV2>` — `{ exists, remainingInput, receivedOutput, pendingPayment }`.
|
|
30053
|
+
*/
|
|
30054
|
+
async getFilledIntent(txHash, config) {
|
|
30055
|
+
return this.request(`/swaps/intents/${txHash}/fill`, { method: "GET" }, IntentStateResponseSchema, config);
|
|
30056
|
+
}
|
|
30057
|
+
/**
|
|
30058
|
+
* Look up an Intent struct by its hub-chain creation tx hash.
|
|
30059
|
+
*
|
|
30060
|
+
* @returns `Result<GetIntentResponseV2>` — the decoded intent (bigint fields as decimal strings).
|
|
30061
|
+
*/
|
|
30062
|
+
async getIntent(txHash, config) {
|
|
30063
|
+
return this.request(`/swaps/intents/${txHash}`, { method: "GET" }, IntentResponseSchema, config);
|
|
30064
|
+
}
|
|
30065
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30066
|
+
// Limit orders · gas · fees
|
|
30067
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30068
|
+
/**
|
|
30069
|
+
* Build an unsigned create-limit-order-intent transaction (same as create-intent
|
|
30070
|
+
* but `deadline` is optional).
|
|
30071
|
+
*
|
|
30072
|
+
* @returns `Result<CreateLimitOrderResponseV2>` — `{ tx, intent, relayData }`.
|
|
30073
|
+
*/
|
|
30074
|
+
async createLimitOrderIntent(body, config) {
|
|
30075
|
+
const txSchema = rawTxSchemaForChainKey(body.srcChainKey);
|
|
30076
|
+
return this.request(
|
|
30077
|
+
"/swaps/limit-orders",
|
|
30078
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30079
|
+
makeCreateIntentResponseSchema(txSchema),
|
|
30080
|
+
config
|
|
30081
|
+
);
|
|
30082
|
+
}
|
|
30083
|
+
/**
|
|
30084
|
+
* Estimate gas for a raw transaction on a spoke chain.
|
|
30085
|
+
*
|
|
30086
|
+
* @returns `Result<GasEstimateResponseV2>` — `{ gas }` (chain-specific shape).
|
|
30087
|
+
*/
|
|
30088
|
+
async estimateGas(body, config) {
|
|
30089
|
+
return this.request(
|
|
30090
|
+
"/swaps/gas/estimate",
|
|
30091
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30092
|
+
GasEstimateResponseSchema,
|
|
30093
|
+
config
|
|
30094
|
+
);
|
|
30095
|
+
}
|
|
30096
|
+
/**
|
|
30097
|
+
* Compute the partner fee for a given input amount.
|
|
30098
|
+
*
|
|
30099
|
+
* @returns `Result<FeeResponseV2>` — `{ fee }` (decimal string).
|
|
30100
|
+
*/
|
|
30101
|
+
async getPartnerFee(query, config) {
|
|
30102
|
+
const queryParams = new URLSearchParams({ amount: query.amount });
|
|
30103
|
+
return this.request(
|
|
30104
|
+
`/swaps/fees/partner?${queryParams.toString()}`,
|
|
30105
|
+
{ method: "GET" },
|
|
30106
|
+
FeeResponseSchema,
|
|
30107
|
+
config
|
|
30108
|
+
);
|
|
30109
|
+
}
|
|
30110
|
+
/**
|
|
30111
|
+
* Compute the protocol (solver) fee for a given input amount.
|
|
30112
|
+
*
|
|
30113
|
+
* @returns `Result<FeeResponseV2>` — `{ fee }` (decimal string).
|
|
30114
|
+
*/
|
|
30115
|
+
async getSolverFee(query, config) {
|
|
30116
|
+
const queryParams = new URLSearchParams({ amount: query.amount });
|
|
30117
|
+
return this.request(
|
|
30118
|
+
`/swaps/fees/solver?${queryParams.toString()}`,
|
|
30119
|
+
{ method: "GET" },
|
|
30120
|
+
FeeResponseSchema,
|
|
30121
|
+
config
|
|
30122
|
+
);
|
|
30123
|
+
}
|
|
30124
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30125
|
+
// Submit-tx state machine
|
|
30126
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30127
|
+
/**
|
|
30128
|
+
* Submit a swap transaction to be processed (relay, post-execution, etc.). The
|
|
30129
|
+
* `intent` field carries `bigint` numerics — {@link toJsonBody} serializes them.
|
|
30130
|
+
* Idempotent on `(txHash, srcChainKey)`.
|
|
30131
|
+
*
|
|
30132
|
+
* @returns `Result<SubmitTxResponseV2>` — `{ success, data: { status, message } }`.
|
|
30133
|
+
*/
|
|
30134
|
+
async submitTx(body, config) {
|
|
30135
|
+
return this.request(
|
|
30136
|
+
"/swaps/submit-tx",
|
|
30137
|
+
{ method: "POST", body: toJsonBody(body) },
|
|
30138
|
+
SubmitTxResponseSchema,
|
|
30139
|
+
config
|
|
30140
|
+
);
|
|
30141
|
+
}
|
|
30142
|
+
/**
|
|
30143
|
+
* Get the processing status of a submitted swap transaction by `(txHash, srcChainKey)`.
|
|
30144
|
+
*
|
|
30145
|
+
* @returns `Result<SubmitTxStatusResponseV2>` — `{ success, data }` (processing state).
|
|
30146
|
+
*/
|
|
30147
|
+
async getSubmitTxStatus(query, config) {
|
|
30148
|
+
const queryParams = new URLSearchParams({ txHash: query.txHash, srcChainKey: query.srcChainKey });
|
|
30149
|
+
return this.request(
|
|
30150
|
+
`/swaps/submit-tx/status?${queryParams.toString()}`,
|
|
30151
|
+
{ method: "GET" },
|
|
30152
|
+
SubmitTxStatusResponseSchema,
|
|
30153
|
+
config
|
|
30154
|
+
);
|
|
30155
|
+
}
|
|
30156
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30157
|
+
// Utilities (parity with BackendApiService)
|
|
30158
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
30159
|
+
/**
|
|
30160
|
+
* Merge additional headers into the service's default header set. Existing
|
|
30161
|
+
* keys are overwritten; keys absent from `headers` are preserved.
|
|
30162
|
+
*/
|
|
30163
|
+
setHeaders(headers) {
|
|
30164
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
30165
|
+
this.headers[key] = value;
|
|
30166
|
+
});
|
|
30167
|
+
}
|
|
30168
|
+
/** Return the base URL the service is currently pointing at. */
|
|
30169
|
+
getBaseURL() {
|
|
30170
|
+
return this.config.baseURL;
|
|
30171
|
+
}
|
|
30172
|
+
};
|
|
30173
|
+
|
|
30174
|
+
// src/backendApi/apiConfig.ts
|
|
30175
|
+
function isCustomApiConfig(config) {
|
|
30176
|
+
return "baseApiConfig" in config || "swapsApiConfig" in config;
|
|
30177
|
+
}
|
|
30178
|
+
function layerConfigs(...slices) {
|
|
30179
|
+
return slices.reduce(
|
|
30180
|
+
(acc, slice) => slice ? {
|
|
30181
|
+
baseURL: slice.baseURL ?? acc.baseURL,
|
|
30182
|
+
timeout: slice.timeout ?? acc.timeout,
|
|
30183
|
+
headers: { ...acc.headers, ...slice.headers }
|
|
30184
|
+
} : acc,
|
|
30185
|
+
{
|
|
30186
|
+
baseURL: DEFAULT_BACKEND_API_ENDPOINT,
|
|
30187
|
+
timeout: DEFAULT_BACKEND_API_TIMEOUT,
|
|
30188
|
+
headers: { ...DEFAULT_BACKEND_API_HEADERS }
|
|
29179
30189
|
}
|
|
30190
|
+
);
|
|
30191
|
+
}
|
|
30192
|
+
function resolveBaseApiConfig(config) {
|
|
30193
|
+
if (isCustomApiConfig(config)) {
|
|
30194
|
+
return layerConfigs(config.baseApiConfig);
|
|
30195
|
+
}
|
|
30196
|
+
return layerConfigs(config);
|
|
30197
|
+
}
|
|
30198
|
+
function resolveSwapsApiConfig(config) {
|
|
30199
|
+
if (isCustomApiConfig(config)) {
|
|
30200
|
+
return layerConfigs(config.baseApiConfig, config.swapsApiConfig);
|
|
30201
|
+
}
|
|
30202
|
+
return layerConfigs(config);
|
|
30203
|
+
}
|
|
30204
|
+
var ChainKeySchema = v4__namespace.custom((input) => typeof input === "string");
|
|
30205
|
+
var SpokeChainKeySchema = v4__namespace.custom((input) => typeof input === "string");
|
|
30206
|
+
var AddressSchema2 = v4__namespace.custom((input) => typeof input === "string");
|
|
30207
|
+
var XTokenSchema = v4__namespace.object({
|
|
30208
|
+
symbol: v4__namespace.string(),
|
|
30209
|
+
name: v4__namespace.string(),
|
|
30210
|
+
decimals: v4__namespace.number(),
|
|
30211
|
+
address: v4__namespace.string(),
|
|
30212
|
+
chainKey: ChainKeySchema,
|
|
30213
|
+
hubAsset: AddressSchema2,
|
|
30214
|
+
vault: AddressSchema2,
|
|
30215
|
+
access: v4__namespace.optional(v4__namespace.picklist(["withdrawOnly", "depositOnly"]))
|
|
30216
|
+
});
|
|
30217
|
+
var IntentStructSchema = v4__namespace.object({
|
|
30218
|
+
intentId: v4__namespace.string(),
|
|
30219
|
+
creator: v4__namespace.string(),
|
|
30220
|
+
inputToken: v4__namespace.string(),
|
|
30221
|
+
outputToken: v4__namespace.string(),
|
|
30222
|
+
inputAmount: v4__namespace.string(),
|
|
30223
|
+
minOutputAmount: v4__namespace.string(),
|
|
30224
|
+
deadline: v4__namespace.string(),
|
|
30225
|
+
allowPartialFill: v4__namespace.boolean(),
|
|
30226
|
+
srcChain: v4__namespace.number(),
|
|
30227
|
+
dstChain: v4__namespace.number(),
|
|
30228
|
+
srcAddress: v4__namespace.string(),
|
|
30229
|
+
dstAddress: v4__namespace.string(),
|
|
30230
|
+
solver: v4__namespace.string(),
|
|
30231
|
+
data: v4__namespace.string()
|
|
30232
|
+
});
|
|
30233
|
+
var IntentResponseSchema2 = v4__namespace.object({
|
|
30234
|
+
intentHash: v4__namespace.string(),
|
|
30235
|
+
txHash: v4__namespace.string(),
|
|
30236
|
+
logIndex: v4__namespace.number(),
|
|
30237
|
+
chainId: v4__namespace.number(),
|
|
30238
|
+
blockNumber: v4__namespace.number(),
|
|
30239
|
+
open: v4__namespace.boolean(),
|
|
30240
|
+
intent: IntentStructSchema,
|
|
30241
|
+
events: v4__namespace.array(v4__namespace.unknown())
|
|
30242
|
+
});
|
|
30243
|
+
var UserIntentsResponseSchema = v4__namespace.object({
|
|
30244
|
+
total: v4__namespace.number(),
|
|
30245
|
+
offset: v4__namespace.number(),
|
|
30246
|
+
limit: v4__namespace.number(),
|
|
30247
|
+
items: v4__namespace.array(IntentResponseSchema2)
|
|
30248
|
+
});
|
|
30249
|
+
var OrderbookResponseSchema = v4__namespace.object({
|
|
30250
|
+
total: v4__namespace.number(),
|
|
30251
|
+
data: v4__namespace.array(
|
|
30252
|
+
v4__namespace.object({
|
|
30253
|
+
intentState: v4__namespace.object({
|
|
30254
|
+
exists: v4__namespace.boolean(),
|
|
30255
|
+
remainingInput: v4__namespace.string(),
|
|
30256
|
+
receivedOutput: v4__namespace.string(),
|
|
30257
|
+
pendingPayment: v4__namespace.boolean()
|
|
30258
|
+
}),
|
|
30259
|
+
intentData: v4__namespace.object({
|
|
30260
|
+
intentId: v4__namespace.string(),
|
|
30261
|
+
creator: v4__namespace.string(),
|
|
30262
|
+
inputToken: v4__namespace.string(),
|
|
30263
|
+
outputToken: v4__namespace.string(),
|
|
30264
|
+
inputAmount: v4__namespace.string(),
|
|
30265
|
+
minOutputAmount: v4__namespace.string(),
|
|
30266
|
+
deadline: v4__namespace.string(),
|
|
30267
|
+
allowPartialFill: v4__namespace.boolean(),
|
|
30268
|
+
srcChain: v4__namespace.number(),
|
|
30269
|
+
dstChain: v4__namespace.number(),
|
|
30270
|
+
srcAddress: v4__namespace.string(),
|
|
30271
|
+
dstAddress: v4__namespace.string(),
|
|
30272
|
+
solver: v4__namespace.string(),
|
|
30273
|
+
data: v4__namespace.string(),
|
|
30274
|
+
intentHash: v4__namespace.string(),
|
|
30275
|
+
txHash: v4__namespace.string(),
|
|
30276
|
+
blockNumber: v4__namespace.number()
|
|
30277
|
+
})
|
|
30278
|
+
})
|
|
30279
|
+
)
|
|
30280
|
+
});
|
|
30281
|
+
var MoneyMarketPositionSchema = v4__namespace.object({
|
|
30282
|
+
userAddress: v4__namespace.string(),
|
|
30283
|
+
positions: v4__namespace.array(
|
|
30284
|
+
v4__namespace.object({
|
|
30285
|
+
reserveAddress: v4__namespace.string(),
|
|
30286
|
+
aTokenAddress: v4__namespace.string(),
|
|
30287
|
+
variableDebtTokenAddress: v4__namespace.string(),
|
|
30288
|
+
aTokenBalance: v4__namespace.string(),
|
|
30289
|
+
variableDebtTokenBalance: v4__namespace.string(),
|
|
30290
|
+
blockNumber: v4__namespace.number()
|
|
30291
|
+
})
|
|
30292
|
+
)
|
|
30293
|
+
});
|
|
30294
|
+
var MoneyMarketAssetSchema = v4__namespace.object({
|
|
30295
|
+
reserveAddress: v4__namespace.string(),
|
|
30296
|
+
aTokenAddress: v4__namespace.string(),
|
|
30297
|
+
totalATokenBalance: v4__namespace.string(),
|
|
30298
|
+
variableDebtTokenAddress: v4__namespace.string(),
|
|
30299
|
+
totalVariableDebtTokenBalance: v4__namespace.string(),
|
|
30300
|
+
liquidityRate: v4__namespace.string(),
|
|
30301
|
+
symbol: v4__namespace.string(),
|
|
30302
|
+
totalSuppliers: v4__namespace.number(),
|
|
30303
|
+
totalBorrowers: v4__namespace.number(),
|
|
30304
|
+
variableBorrowRate: v4__namespace.string(),
|
|
30305
|
+
stableBorrowRate: v4__namespace.string(),
|
|
30306
|
+
liquidityIndex: v4__namespace.string(),
|
|
30307
|
+
variableBorrowIndex: v4__namespace.string(),
|
|
30308
|
+
blockNumber: v4__namespace.number()
|
|
30309
|
+
});
|
|
30310
|
+
var MoneyMarketAssetsSchema = v4__namespace.array(MoneyMarketAssetSchema);
|
|
30311
|
+
var MoneyMarketAssetBorrowersSchema = v4__namespace.object({
|
|
30312
|
+
borrowers: v4__namespace.array(v4__namespace.string()),
|
|
30313
|
+
total: v4__namespace.number(),
|
|
30314
|
+
offset: v4__namespace.number(),
|
|
30315
|
+
limit: v4__namespace.number()
|
|
30316
|
+
});
|
|
30317
|
+
var MoneyMarketAssetSuppliersSchema = v4__namespace.object({
|
|
30318
|
+
suppliers: v4__namespace.array(v4__namespace.string()),
|
|
30319
|
+
total: v4__namespace.number(),
|
|
30320
|
+
offset: v4__namespace.number(),
|
|
30321
|
+
limit: v4__namespace.number()
|
|
30322
|
+
});
|
|
30323
|
+
var MoneyMarketBorrowersSchema = v4__namespace.object({
|
|
30324
|
+
borrowers: v4__namespace.array(v4__namespace.string()),
|
|
30325
|
+
total: v4__namespace.number(),
|
|
30326
|
+
offset: v4__namespace.number(),
|
|
30327
|
+
limit: v4__namespace.number()
|
|
30328
|
+
});
|
|
30329
|
+
var GetChainsResponseSchema = v4__namespace.array(SpokeChainKeySchema);
|
|
30330
|
+
var TokensByChainMapSchema = v4__namespace.custom(
|
|
30331
|
+
(input) => typeof input === "object" && input !== null && Object.values(input).every((tokens) => Array.isArray(tokens) && tokens.every((t) => v4__namespace.is(XTokenSchema, t)))
|
|
30332
|
+
);
|
|
30333
|
+
var TokensListSchema = v4__namespace.array(XTokenSchema);
|
|
30334
|
+
var ReserveAssetsSchema = v4__namespace.array(AddressSchema2);
|
|
30335
|
+
|
|
30336
|
+
// src/backendApi/BackendApiService.ts
|
|
30337
|
+
var BackendApiService = class {
|
|
30338
|
+
// sub-services exposing domain-specific APIs
|
|
30339
|
+
swaps;
|
|
30340
|
+
// resolved base-API slice of the ApiConfig union (flat config, or its `baseApiConfig`)
|
|
30341
|
+
config;
|
|
30342
|
+
headers;
|
|
30343
|
+
logger;
|
|
30344
|
+
constructor(config, logger = consoleLogger) {
|
|
30345
|
+
this.config = resolveBaseApiConfig(config);
|
|
30346
|
+
this.headers = { ...this.config.headers };
|
|
30347
|
+
this.logger = logger;
|
|
30348
|
+
this.swaps = new SwapsApiService(resolveSwapsApiConfig(config), this.logger);
|
|
29180
30349
|
}
|
|
29181
30350
|
/**
|
|
29182
30351
|
* Wraps {@link makeRequest} in a `Result<T>` so all errors are captured rather
|
|
29183
30352
|
* than propagated as thrown exceptions. Every public endpoint method delegates
|
|
29184
30353
|
* here instead of calling `makeRequest` directly.
|
|
29185
30354
|
*/
|
|
29186
|
-
|
|
30355
|
+
/**
|
|
30356
|
+
* Fold any per-call override (carried on `config` alongside `method`/`body`) over the service
|
|
30357
|
+
* defaults: baseURL truthy-fallback (an empty-string override defers to the default), timeout
|
|
30358
|
+
* nullish-fallback, headers merged (override wins per key). Mirrors the original makeRequest merge.
|
|
30359
|
+
*/
|
|
30360
|
+
resolveRequestConfig(config) {
|
|
30361
|
+
const { baseURL, timeout, headers, ...rest } = config;
|
|
30362
|
+
return {
|
|
30363
|
+
...rest,
|
|
30364
|
+
baseURL: baseURL || this.config.baseURL,
|
|
30365
|
+
timeout: timeout ?? this.config.timeout,
|
|
30366
|
+
headers: { ...this.headers, ...headers }
|
|
30367
|
+
};
|
|
30368
|
+
}
|
|
30369
|
+
/**
|
|
30370
|
+
* Wrap a thrown transport failure (HTTP_REQUEST_FAILED / REQUEST_TIMEOUT / network error) as the
|
|
30371
|
+
* canonical backend `SodaxError` — identical shape to SwapsApiService; the underlying failure is
|
|
30372
|
+
* preserved on `error.cause`.
|
|
30373
|
+
*/
|
|
30374
|
+
toExternalApiError(endpoint, error) {
|
|
30375
|
+
return new SodaxError(
|
|
30376
|
+
"EXTERNAL_API_ERROR",
|
|
30377
|
+
error instanceof Error ? error.message : `Backend API request to ${endpoint} failed`,
|
|
30378
|
+
{ feature: "backend", cause: error, context: { api: "backend", endpoint } }
|
|
30379
|
+
);
|
|
30380
|
+
}
|
|
30381
|
+
/**
|
|
30382
|
+
* Issue a request and validate the JSON body against `schema`, wrapping the result in `Result<T>`.
|
|
30383
|
+
* Mirrors {@link SwapsApiService}: a 2xx body that fails the schema is surfaced as
|
|
30384
|
+
* `EXTERNAL_API_ERROR` (`context.reason: 'invalid_response_shape'`) rather than returned untyped.
|
|
30385
|
+
* Every data/token/money-market method delegates here; the config/relay reads use
|
|
30386
|
+
* {@link requestUnvalidated} instead.
|
|
30387
|
+
*/
|
|
30388
|
+
async request(endpoint, config, schema) {
|
|
30389
|
+
try {
|
|
30390
|
+
const raw = await makeRequest({
|
|
30391
|
+
endpoint,
|
|
30392
|
+
config: this.resolveRequestConfig(config),
|
|
30393
|
+
logger: this.logger,
|
|
30394
|
+
serviceLabel: "BackendApiService"
|
|
30395
|
+
});
|
|
30396
|
+
const parsed = v4__namespace.safeParse(schema, raw);
|
|
30397
|
+
if (!parsed.success) {
|
|
30398
|
+
return {
|
|
30399
|
+
ok: false,
|
|
30400
|
+
error: new SodaxError("EXTERNAL_API_ERROR", `Invalid response shape from backend API for ${endpoint}`, {
|
|
30401
|
+
feature: "backend",
|
|
30402
|
+
context: { api: "backend", endpoint, reason: "invalid_response_shape", issues: v4__namespace.flatten(parsed.issues) }
|
|
30403
|
+
})
|
|
30404
|
+
};
|
|
30405
|
+
}
|
|
30406
|
+
return { ok: true, value: parsed.output };
|
|
30407
|
+
} catch (error) {
|
|
30408
|
+
return { ok: false, error: this.toExternalApiError(endpoint, error) };
|
|
30409
|
+
}
|
|
30410
|
+
}
|
|
30411
|
+
/**
|
|
30412
|
+
* Issue a request WITHOUT response-shape validation (passthrough typing). Reserved for the
|
|
30413
|
+
* config/relay reads whose shapes are too large/brittle to schema-validate (`SodaxConfig` via
|
|
30414
|
+
* `getAllConfig`, `SpokeChainConfigMap` via `getSpokeChainConfig`) or carry `bigint` values that
|
|
30415
|
+
* cannot survive JSON validation (`getRelayChainIdMap`). `ConfigService` version-gates and falls
|
|
30416
|
+
* back to packaged defaults, so it relies on no response-shape guarantee from these endpoints.
|
|
30417
|
+
*/
|
|
30418
|
+
async requestUnvalidated(endpoint, config) {
|
|
29187
30419
|
try {
|
|
29188
|
-
const value = await
|
|
30420
|
+
const value = await makeRequest({
|
|
30421
|
+
endpoint,
|
|
30422
|
+
config: this.resolveRequestConfig(config),
|
|
30423
|
+
logger: this.logger,
|
|
30424
|
+
serviceLabel: "BackendApiService"
|
|
30425
|
+
});
|
|
29189
30426
|
return { ok: true, value };
|
|
29190
30427
|
} catch (error) {
|
|
29191
|
-
return { ok: false, error };
|
|
30428
|
+
return { ok: false, error: this.toExternalApiError(endpoint, error) };
|
|
29192
30429
|
}
|
|
29193
30430
|
}
|
|
29194
30431
|
// Intent endpoints
|
|
@@ -29203,7 +30440,7 @@ var BackendApiService = class {
|
|
|
29203
30440
|
* open/closed state, token amounts, and any fill events.
|
|
29204
30441
|
*/
|
|
29205
30442
|
async getIntentByTxHash(txHash, config) {
|
|
29206
|
-
return this.request(`/intent/tx/${txHash}`, { ...config, method: "GET" });
|
|
30443
|
+
return this.request(`/intent/tx/${txHash}`, { ...config, method: "GET" }, IntentResponseSchema2);
|
|
29207
30444
|
}
|
|
29208
30445
|
/**
|
|
29209
30446
|
* Fetch a swap intent by its canonical intent hash.
|
|
@@ -29212,58 +30449,7 @@ var BackendApiService = class {
|
|
|
29212
30449
|
* @returns `Result<IntentResponse>` — on success, the full intent details.
|
|
29213
30450
|
*/
|
|
29214
30451
|
async getIntentByHash(intentHash, config) {
|
|
29215
|
-
return this.request(`/intent/${intentHash}`, { ...config, method: "GET" });
|
|
29216
|
-
}
|
|
29217
|
-
// Swap submit-tx endpoints
|
|
29218
|
-
/**
|
|
29219
|
-
* Submit a signed spoke-chain swap transaction to the backend for processing.
|
|
29220
|
-
*
|
|
29221
|
-
* The backend relays the transaction to the hub chain, posts execution data
|
|
29222
|
-
* to the solver, and advances the intent through its lifecycle. The response
|
|
29223
|
-
* shape is validated at runtime via a type guard; an invalid shape is
|
|
29224
|
-
* returned as `{ ok: false }`.
|
|
29225
|
-
*
|
|
29226
|
-
* @param params - The signed transaction hash, source chain key, sender wallet
|
|
29227
|
-
* address, intent data, and relay data required to process the swap.
|
|
29228
|
-
* @returns `Result<SubmitSwapTxResponse>` — on success, a confirmation object
|
|
29229
|
-
* with `success: true` and a human-readable `message`.
|
|
29230
|
-
*/
|
|
29231
|
-
async submitSwapTx(params, config) {
|
|
29232
|
-
const result = await this.request("/swaps/submit-tx", {
|
|
29233
|
-
...config,
|
|
29234
|
-
method: "POST",
|
|
29235
|
-
body: JSON.stringify(params)
|
|
29236
|
-
});
|
|
29237
|
-
if (!result.ok) return result;
|
|
29238
|
-
if (!isSubmitSwapTxResponse(result.value)) {
|
|
29239
|
-
return { ok: false, error: new Error("Invalid submitSwapTx response: unexpected response shape") };
|
|
29240
|
-
}
|
|
29241
|
-
return { ok: true, value: result.value };
|
|
29242
|
-
}
|
|
29243
|
-
/**
|
|
29244
|
-
* Poll the backend relay pipeline for the current status of a previously
|
|
29245
|
-
* submitted swap transaction.
|
|
29246
|
-
*
|
|
29247
|
-
* Status progresses through: `pending` → `verifying` → `verified` →
|
|
29248
|
-
* `relaying` → `relayed` → `posting_execution` → `executed` (or `failed`).
|
|
29249
|
-
*
|
|
29250
|
-
* @param params - Object containing the source-chain transaction hash and,
|
|
29251
|
-
* optionally, the source chain key to disambiguate cross-chain hashes.
|
|
29252
|
-
* @returns `Result<SubmitSwapTxStatusResponse>` — on success, includes the
|
|
29253
|
-
* current `status`, any `failureReason`, and (once executed) the
|
|
29254
|
-
* `dstIntentTxHash` on the hub chain.
|
|
29255
|
-
*/
|
|
29256
|
-
async getSubmitSwapTxStatus(params, config) {
|
|
29257
|
-
const queryParams = new URLSearchParams();
|
|
29258
|
-
queryParams.append("txHash", params.txHash);
|
|
29259
|
-
if (params.srcChainKey) queryParams.append("srcChainKey", params.srcChainKey);
|
|
29260
|
-
const endpoint = `/swaps/submit-tx/status?${queryParams.toString()}`;
|
|
29261
|
-
const result = await this.request(endpoint, { ...config, method: "GET" });
|
|
29262
|
-
if (!result.ok) return result;
|
|
29263
|
-
if (!isSubmitSwapTxStatusResponse(result.value)) {
|
|
29264
|
-
return { ok: false, error: new Error("Invalid submitSwapTxStatus response: unexpected response shape") };
|
|
29265
|
-
}
|
|
29266
|
-
return { ok: true, value: result.value };
|
|
30452
|
+
return this.request(`/intent/${intentHash}`, { ...config, method: "GET" }, IntentResponseSchema2);
|
|
29267
30453
|
}
|
|
29268
30454
|
// Solver endpoints
|
|
29269
30455
|
/**
|
|
@@ -29280,7 +30466,7 @@ var BackendApiService = class {
|
|
|
29280
30466
|
queryParams.append("limit", params.limit);
|
|
29281
30467
|
const queryString = queryParams.toString();
|
|
29282
30468
|
const endpoint = `/solver/orderbook?${queryString}`;
|
|
29283
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30469
|
+
return this.request(endpoint, { ...config, method: "GET" }, OrderbookResponseSchema);
|
|
29284
30470
|
}
|
|
29285
30471
|
/**
|
|
29286
30472
|
* Fetch all swap intents created by a specific wallet address, with optional
|
|
@@ -29306,7 +30492,7 @@ var BackendApiService = class {
|
|
|
29306
30492
|
if (offset) queryParams.append("offset", offset);
|
|
29307
30493
|
const queryString = queryParams.toString();
|
|
29308
30494
|
const endpoint = queryString.length > 0 ? `/intent/user/${userAddress}?${queryString}` : `/intent/user/${userAddress}`;
|
|
29309
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30495
|
+
return this.request(endpoint, { ...config, method: "GET" }, UserIntentsResponseSchema);
|
|
29310
30496
|
}
|
|
29311
30497
|
// Money Market endpoints
|
|
29312
30498
|
/**
|
|
@@ -29321,7 +30507,11 @@ var BackendApiService = class {
|
|
|
29321
30507
|
* position across all active reserves.
|
|
29322
30508
|
*/
|
|
29323
30509
|
async getMoneyMarketPosition(userAddress, config) {
|
|
29324
|
-
return this.request(
|
|
30510
|
+
return this.request(
|
|
30511
|
+
`/moneymarket/position/${userAddress}`,
|
|
30512
|
+
{ ...config, method: "GET" },
|
|
30513
|
+
MoneyMarketPositionSchema
|
|
30514
|
+
);
|
|
29325
30515
|
}
|
|
29326
30516
|
/**
|
|
29327
30517
|
* Fetch the on-chain state for every active money market reserve asset.
|
|
@@ -29330,7 +30520,7 @@ var BackendApiService = class {
|
|
|
29330
30520
|
* snapshots including interest rates, liquidity indices, and participant counts.
|
|
29331
30521
|
*/
|
|
29332
30522
|
async getAllMoneyMarketAssets(config) {
|
|
29333
|
-
return this.request("/moneymarket/asset/all", { ...config, method: "GET" });
|
|
30523
|
+
return this.request("/moneymarket/asset/all", { ...config, method: "GET" }, MoneyMarketAssetsSchema);
|
|
29334
30524
|
}
|
|
29335
30525
|
/**
|
|
29336
30526
|
* Fetch the on-chain state for a single money market reserve asset.
|
|
@@ -29340,7 +30530,11 @@ var BackendApiService = class {
|
|
|
29340
30530
|
* including interest rates, total balances, and liquidity indices.
|
|
29341
30531
|
*/
|
|
29342
30532
|
async getMoneyMarketAsset(reserveAddress, config) {
|
|
29343
|
-
return this.request(
|
|
30533
|
+
return this.request(
|
|
30534
|
+
`/moneymarket/asset/${reserveAddress}`,
|
|
30535
|
+
{ ...config, method: "GET" },
|
|
30536
|
+
MoneyMarketAssetSchema
|
|
30537
|
+
);
|
|
29344
30538
|
}
|
|
29345
30539
|
/**
|
|
29346
30540
|
* Fetch a paginated list of wallets that currently have an outstanding borrow
|
|
@@ -29357,7 +30551,7 @@ var BackendApiService = class {
|
|
|
29357
30551
|
queryParams.append("limit", params.limit);
|
|
29358
30552
|
const queryString = queryParams.toString();
|
|
29359
30553
|
const endpoint = `/moneymarket/asset/${reserveAddress}/borrowers?${queryString}`;
|
|
29360
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30554
|
+
return this.request(endpoint, { ...config, method: "GET" }, MoneyMarketAssetBorrowersSchema);
|
|
29361
30555
|
}
|
|
29362
30556
|
/**
|
|
29363
30557
|
* Fetch a paginated list of wallets that currently have an active supply
|
|
@@ -29374,7 +30568,7 @@ var BackendApiService = class {
|
|
|
29374
30568
|
queryParams.append("limit", params.limit);
|
|
29375
30569
|
const queryString = queryParams.toString();
|
|
29376
30570
|
const endpoint = `/moneymarket/asset/${reserveAddress}/suppliers?${queryString}`;
|
|
29377
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30571
|
+
return this.request(endpoint, { ...config, method: "GET" }, MoneyMarketAssetSuppliersSchema);
|
|
29378
30572
|
}
|
|
29379
30573
|
/**
|
|
29380
30574
|
* Fetch a paginated list of all wallet addresses that hold an active borrow
|
|
@@ -29390,7 +30584,7 @@ var BackendApiService = class {
|
|
|
29390
30584
|
queryParams.append("limit", params.limit);
|
|
29391
30585
|
const queryString = queryParams.toString();
|
|
29392
30586
|
const endpoint = `/moneymarket/borrowers?${queryString}`;
|
|
29393
|
-
return this.request(endpoint, { ...config, method: "GET" });
|
|
30587
|
+
return this.request(endpoint, { ...config, method: "GET" }, MoneyMarketBorrowersSchema);
|
|
29394
30588
|
}
|
|
29395
30589
|
/**
|
|
29396
30590
|
* Fetch the complete SODAX runtime configuration in a single request.
|
|
@@ -29403,7 +30597,7 @@ var BackendApiService = class {
|
|
|
29403
30597
|
* `config` is the current `SodaxConfig` used by all SDK services.
|
|
29404
30598
|
*/
|
|
29405
30599
|
async getAllConfig(config) {
|
|
29406
|
-
return this.
|
|
30600
|
+
return this.requestUnvalidated("/config/all", { ...config, method: "GET" });
|
|
29407
30601
|
}
|
|
29408
30602
|
/**
|
|
29409
30603
|
* Fetch the list of spoke chain keys that are currently supported by the
|
|
@@ -29416,7 +30610,7 @@ var BackendApiService = class {
|
|
|
29416
30610
|
* `SpokeChainKey` strings (e.g. `["ethereum", "arbitrum", "solana", …]`).
|
|
29417
30611
|
*/
|
|
29418
30612
|
async getChains(config) {
|
|
29419
|
-
return this.request("/config/spoke/chains", { ...config, method: "GET" });
|
|
30613
|
+
return this.request("/config/spoke/chains", { ...config, method: "GET" }, GetChainsResponseSchema);
|
|
29420
30614
|
}
|
|
29421
30615
|
/**
|
|
29422
30616
|
* Fetch the full map of tokens available for swapping, keyed by spoke chain.
|
|
@@ -29428,7 +30622,7 @@ var BackendApiService = class {
|
|
|
29428
30622
|
* supported spoke chain key to its list of swappable `XToken` definitions.
|
|
29429
30623
|
*/
|
|
29430
30624
|
async getSwapTokens(config) {
|
|
29431
|
-
return this.request("/config/swap/tokens", { ...config, method: "GET" });
|
|
30625
|
+
return this.request("/config/swap/tokens", { ...config, method: "GET" }, TokensByChainMapSchema);
|
|
29432
30626
|
}
|
|
29433
30627
|
/**
|
|
29434
30628
|
* Fetch the list of tokens available for swapping on a specific spoke chain.
|
|
@@ -29440,10 +30634,7 @@ var BackendApiService = class {
|
|
|
29440
30634
|
* array of `XToken` definitions supported for swapping on that chain.
|
|
29441
30635
|
*/
|
|
29442
30636
|
async getSwapTokensByChainId(chainId, config) {
|
|
29443
|
-
return this.request(`/config/swap/${chainId}/tokens`, {
|
|
29444
|
-
...config,
|
|
29445
|
-
method: "GET"
|
|
29446
|
-
});
|
|
30637
|
+
return this.request(`/config/swap/${chainId}/tokens`, { ...config, method: "GET" }, TokensListSchema);
|
|
29447
30638
|
}
|
|
29448
30639
|
/**
|
|
29449
30640
|
* Fetch the full map of tokens available in the money market (lending/borrowing),
|
|
@@ -29455,10 +30646,7 @@ var BackendApiService = class {
|
|
|
29455
30646
|
* each supported spoke chain key to its list of money-market `XToken` definitions.
|
|
29456
30647
|
*/
|
|
29457
30648
|
async getMoneyMarketTokens(config) {
|
|
29458
|
-
return this.request("/config/money-market/tokens", {
|
|
29459
|
-
...config,
|
|
29460
|
-
method: "GET"
|
|
29461
|
-
});
|
|
30649
|
+
return this.request("/config/money-market/tokens", { ...config, method: "GET" }, TokensByChainMapSchema);
|
|
29462
30650
|
}
|
|
29463
30651
|
/**
|
|
29464
30652
|
* Fetch the list of hub-chain reserve asset addresses registered in the
|
|
@@ -29472,10 +30660,11 @@ var BackendApiService = class {
|
|
|
29472
30660
|
* readonly array of reserve `Address` strings.
|
|
29473
30661
|
*/
|
|
29474
30662
|
async getMoneyMarketReserveAssets(config) {
|
|
29475
|
-
return this.request(
|
|
29476
|
-
|
|
29477
|
-
method: "GET"
|
|
29478
|
-
|
|
30663
|
+
return this.request(
|
|
30664
|
+
"/config/money-market/reserve-assets",
|
|
30665
|
+
{ ...config, method: "GET" },
|
|
30666
|
+
ReserveAssetsSchema
|
|
30667
|
+
);
|
|
29479
30668
|
}
|
|
29480
30669
|
/**
|
|
29481
30670
|
* Fetch the list of tokens available for lending/borrowing on a specific
|
|
@@ -29488,10 +30677,11 @@ var BackendApiService = class {
|
|
|
29488
30677
|
* readonly array of `XToken` definitions supported in the money market on that chain.
|
|
29489
30678
|
*/
|
|
29490
30679
|
async getMoneyMarketTokensByChainId(chainId, config) {
|
|
29491
|
-
return this.request(
|
|
29492
|
-
|
|
29493
|
-
method: "GET"
|
|
29494
|
-
|
|
30680
|
+
return this.request(
|
|
30681
|
+
`/config/money-market/${chainId}/tokens`,
|
|
30682
|
+
{ ...config, method: "GET" },
|
|
30683
|
+
TokensListSchema
|
|
30684
|
+
);
|
|
29495
30685
|
}
|
|
29496
30686
|
/**
|
|
29497
30687
|
* Fetch the mapping from spoke chain keys to the numeric chain IDs used by
|
|
@@ -29505,7 +30695,7 @@ var BackendApiService = class {
|
|
|
29505
30695
|
* `IntentRelayChainIdMap` record mapping each spoke chain key to its relay chain ID.
|
|
29506
30696
|
*/
|
|
29507
30697
|
async getRelayChainIdMap(config) {
|
|
29508
|
-
return this.
|
|
30698
|
+
return this.requestUnvalidated("/config/relay/chain-id-map", {
|
|
29509
30699
|
...config,
|
|
29510
30700
|
method: "GET"
|
|
29511
30701
|
});
|
|
@@ -29522,7 +30712,7 @@ var BackendApiService = class {
|
|
|
29522
30712
|
* `SpokeChainConfigMap` for all currently enabled spoke chains.
|
|
29523
30713
|
*/
|
|
29524
30714
|
async getSpokeChainConfig(config) {
|
|
29525
|
-
return this.
|
|
30715
|
+
return this.requestUnvalidated("/config/spoke/all-chains-configs", {
|
|
29526
30716
|
...config,
|
|
29527
30717
|
method: "GET"
|
|
29528
30718
|
});
|
|
@@ -29534,12 +30724,17 @@ var BackendApiService = class {
|
|
|
29534
30724
|
* without constructing a new service instance. Existing header keys are
|
|
29535
30725
|
* overwritten; keys absent from `headers` are preserved.
|
|
29536
30726
|
*
|
|
30727
|
+
* The headers are also fanned out to the sub-services (`swaps`), which hold
|
|
30728
|
+
* their own header copies — so a token set here applies to every request made
|
|
30729
|
+
* through this client, including `swaps.*`.
|
|
30730
|
+
*
|
|
29537
30731
|
* @param headers - Key-value pairs to add or overwrite in the default headers.
|
|
29538
30732
|
*/
|
|
29539
30733
|
setHeaders(headers) {
|
|
29540
30734
|
Object.entries(headers).forEach(([key, value]) => {
|
|
29541
30735
|
this.headers[key] = value;
|
|
29542
30736
|
});
|
|
30737
|
+
this.swaps.setHeaders(headers);
|
|
29543
30738
|
}
|
|
29544
30739
|
/**
|
|
29545
30740
|
* Return the base URL the service is currently pointing at.
|
|
@@ -29787,49 +30982,71 @@ var BridgeService = class {
|
|
|
29787
30982
|
* }
|
|
29788
30983
|
*/
|
|
29789
30984
|
async bridge(_params) {
|
|
29790
|
-
|
|
29791
|
-
|
|
29792
|
-
|
|
29793
|
-
|
|
29794
|
-
|
|
29795
|
-
|
|
29796
|
-
|
|
29797
|
-
|
|
29798
|
-
|
|
29799
|
-
|
|
29800
|
-
|
|
29801
|
-
|
|
29802
|
-
|
|
29803
|
-
|
|
30985
|
+
return this.config.analytics.trackResult(
|
|
30986
|
+
"bridge",
|
|
30987
|
+
"bridge",
|
|
30988
|
+
async () => {
|
|
30989
|
+
const { params, timeout } = _params;
|
|
30990
|
+
const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
|
|
30991
|
+
try {
|
|
30992
|
+
const txResult = await this.createBridgeIntent(_params);
|
|
30993
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
30994
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
30995
|
+
txHash: txResult.value.tx,
|
|
30996
|
+
chainKey: params.srcChainKey
|
|
30997
|
+
});
|
|
30998
|
+
if (!verifyTxHashResult.ok) {
|
|
30999
|
+
return {
|
|
31000
|
+
ok: false,
|
|
31001
|
+
error: verifyFailed("bridge", verifyTxHashResult.error, baseCtx)
|
|
31002
|
+
};
|
|
31003
|
+
}
|
|
31004
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
31005
|
+
srcTxHash: txResult.value.tx,
|
|
31006
|
+
data: txResult.value.relayData,
|
|
31007
|
+
chainKey: params.srcChainKey,
|
|
31008
|
+
relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
|
|
31009
|
+
timeout
|
|
31010
|
+
});
|
|
31011
|
+
if (!packetResult.ok)
|
|
31012
|
+
return {
|
|
31013
|
+
ok: false,
|
|
31014
|
+
error: mapRelayFailure(packetResult.error, {
|
|
31015
|
+
feature: "bridge",
|
|
31016
|
+
action: "bridge",
|
|
31017
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
31018
|
+
dstChainKey: baseCtx.dstChainKey
|
|
31019
|
+
})
|
|
31020
|
+
};
|
|
31021
|
+
return {
|
|
31022
|
+
ok: true,
|
|
31023
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packetResult.value.dst_tx_hash }
|
|
31024
|
+
};
|
|
31025
|
+
} catch (error) {
|
|
31026
|
+
if (isBridgeOrchestrationError(error)) return { ok: false, error };
|
|
31027
|
+
return {
|
|
31028
|
+
ok: false,
|
|
31029
|
+
error: executionFailed("bridge", error, baseCtx)
|
|
31030
|
+
};
|
|
31031
|
+
}
|
|
31032
|
+
},
|
|
31033
|
+
{
|
|
31034
|
+
start: () => ({
|
|
31035
|
+
srcChainKey: _params.params.srcChainKey,
|
|
31036
|
+
dstChainKey: _params.params.dstChainKey,
|
|
31037
|
+
srcToken: _params.params.srcToken,
|
|
31038
|
+
dstToken: _params.params.dstToken,
|
|
31039
|
+
amount: _params.params.amount,
|
|
31040
|
+
srcAddress: _params.params.srcAddress,
|
|
31041
|
+
recipient: _params.params.recipient
|
|
31042
|
+
}),
|
|
31043
|
+
success: (value) => ({
|
|
31044
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
31045
|
+
dstChainTxHash: value.dstChainTxHash
|
|
31046
|
+
}),
|
|
31047
|
+
failure: (error) => ({ code: error.code })
|
|
29804
31048
|
}
|
|
29805
|
-
|
|
29806
|
-
srcTxHash: txResult.value.tx,
|
|
29807
|
-
data: txResult.value.relayData,
|
|
29808
|
-
chainKey: params.srcChainKey,
|
|
29809
|
-
relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
|
|
29810
|
-
timeout
|
|
29811
|
-
});
|
|
29812
|
-
if (!packetResult.ok)
|
|
29813
|
-
return {
|
|
29814
|
-
ok: false,
|
|
29815
|
-
error: mapRelayFailure(packetResult.error, {
|
|
29816
|
-
feature: "bridge",
|
|
29817
|
-
action: "bridge",
|
|
29818
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
29819
|
-
dstChainKey: baseCtx.dstChainKey
|
|
29820
|
-
})
|
|
29821
|
-
};
|
|
29822
|
-
return {
|
|
29823
|
-
ok: true,
|
|
29824
|
-
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packetResult.value.dst_tx_hash }
|
|
29825
|
-
};
|
|
29826
|
-
} catch (error) {
|
|
29827
|
-
if (isBridgeOrchestrationError(error)) return { ok: false, error };
|
|
29828
|
-
return {
|
|
29829
|
-
ok: false,
|
|
29830
|
-
error: executionFailed("bridge", error, baseCtx)
|
|
29831
|
-
};
|
|
29832
|
-
}
|
|
31049
|
+
);
|
|
29833
31050
|
}
|
|
29834
31051
|
/**
|
|
29835
31052
|
* Submits the spoke-side deposit transaction that initiates a bridge transfer,
|
|
@@ -29858,8 +31075,8 @@ var BridgeService = class {
|
|
|
29858
31075
|
const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
|
|
29859
31076
|
try {
|
|
29860
31077
|
bridgeInvariant(params.amount > 0n, "Amount must be greater than 0", { ...baseCtx, field: "amount" });
|
|
29861
|
-
const srcToken = this.
|
|
29862
|
-
const dstToken = this.
|
|
31078
|
+
const srcToken = this.resolveBridgeEndpointToken(params.srcChainKey, params.srcToken);
|
|
31079
|
+
const dstToken = this.resolveBridgeEndpointToken(params.dstChainKey, params.dstToken);
|
|
29863
31080
|
bridgeInvariant(srcToken, `Unsupported spoke chain (${params.srcChainKey}) token: ${params.srcToken}`, {
|
|
29864
31081
|
...baseCtx,
|
|
29865
31082
|
field: "srcToken"
|
|
@@ -29927,6 +31144,20 @@ var BridgeService = class {
|
|
|
29927
31144
|
};
|
|
29928
31145
|
}
|
|
29929
31146
|
}
|
|
31147
|
+
/**
|
|
31148
|
+
* Resolves a bridge endpoint's {@link XToken} descriptor from a chain key + token address.
|
|
31149
|
+
*
|
|
31150
|
+
* Spoke endpoints (and hub-native tokens such as USDC/WETH/S whose on-chain address equals their
|
|
31151
|
+
* hub asset) resolve by original asset address. On the hub a caller may instead hold a hub asset
|
|
31152
|
+
* that has no spoke-token entry under the hub chain — e.g. a partner BTC fee held as the BTC hub
|
|
31153
|
+
* asset, whose only spoke-token entry lives on Bitcoin. Resolve those by hub-asset address so the
|
|
31154
|
+
* Sonic-sourced "withdraw directly" bridge can find the matching vault/decimals.
|
|
31155
|
+
*/
|
|
31156
|
+
resolveBridgeEndpointToken(chainKey, token) {
|
|
31157
|
+
const spokeToken = this.config.getSpokeTokenFromOriginalAssetAddress(chainKey, token);
|
|
31158
|
+
if (spokeToken) return spokeToken;
|
|
31159
|
+
return isHubChainKeyType(chainKey) ? this.config.getXTokenFromHubAsset(token) : void 0;
|
|
31160
|
+
}
|
|
29930
31161
|
/**
|
|
29931
31162
|
* Encodes the hub-side execution payload for a bridge operation.
|
|
29932
31163
|
*
|
|
@@ -30809,52 +32040,71 @@ var StakingService = class {
|
|
|
30809
32040
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
30810
32041
|
*/
|
|
30811
32042
|
async stake(_params) {
|
|
30812
|
-
|
|
30813
|
-
|
|
30814
|
-
|
|
30815
|
-
|
|
30816
|
-
|
|
30817
|
-
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
|
|
30828
|
-
|
|
30829
|
-
|
|
30830
|
-
|
|
30831
|
-
|
|
30832
|
-
|
|
30833
|
-
|
|
30834
|
-
|
|
30835
|
-
|
|
30836
|
-
|
|
32043
|
+
return this.config.analytics.trackResult(
|
|
32044
|
+
"staking",
|
|
32045
|
+
"stake",
|
|
32046
|
+
async () => {
|
|
32047
|
+
const { params, timeout } = _params;
|
|
32048
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "stake" };
|
|
32049
|
+
try {
|
|
32050
|
+
const txResult = await this.createStakeIntent(_params);
|
|
32051
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32052
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
32053
|
+
txHash: txResult.value.tx,
|
|
32054
|
+
chainKey: params.srcChainKey
|
|
32055
|
+
});
|
|
32056
|
+
if (!verifyTxHashResult.ok) {
|
|
32057
|
+
return {
|
|
32058
|
+
ok: false,
|
|
32059
|
+
error: verifyFailed("staking", verifyTxHashResult.error, baseCtx)
|
|
32060
|
+
};
|
|
32061
|
+
}
|
|
32062
|
+
let hubTxHash;
|
|
32063
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32064
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32065
|
+
srcTxHash: txResult.value.tx,
|
|
32066
|
+
data: txResult.value.relayData,
|
|
32067
|
+
chainKey: params.srcChainKey,
|
|
32068
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32069
|
+
timeout
|
|
32070
|
+
});
|
|
32071
|
+
if (!packetResult.ok) {
|
|
32072
|
+
return {
|
|
32073
|
+
ok: false,
|
|
32074
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32075
|
+
feature: "staking",
|
|
32076
|
+
action: baseCtx.action,
|
|
32077
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32078
|
+
})
|
|
32079
|
+
};
|
|
32080
|
+
}
|
|
32081
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32082
|
+
} else {
|
|
32083
|
+
hubTxHash = txResult.value.tx;
|
|
32084
|
+
}
|
|
32085
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32086
|
+
} catch (error) {
|
|
32087
|
+
if (isStakeOrchestrationError(error)) return { ok: false, error };
|
|
30837
32088
|
return {
|
|
30838
32089
|
ok: false,
|
|
30839
|
-
error:
|
|
30840
|
-
feature: "staking",
|
|
30841
|
-
action: baseCtx.action,
|
|
30842
|
-
srcChainKey: baseCtx.srcChainKey
|
|
30843
|
-
})
|
|
32090
|
+
error: executionFailed("staking", error, baseCtx)
|
|
30844
32091
|
};
|
|
30845
32092
|
}
|
|
30846
|
-
|
|
30847
|
-
|
|
30848
|
-
|
|
32093
|
+
},
|
|
32094
|
+
{
|
|
32095
|
+
start: () => ({
|
|
32096
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32097
|
+
srcAddress: _params.params.srcAddress,
|
|
32098
|
+
amount: _params.params.amount,
|
|
32099
|
+
minReceive: _params.params.minReceive
|
|
32100
|
+
}),
|
|
32101
|
+
success: (value) => ({
|
|
32102
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32103
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32104
|
+
}),
|
|
32105
|
+
failure: (error) => ({ code: error.code })
|
|
30849
32106
|
}
|
|
30850
|
-
|
|
30851
|
-
} catch (error) {
|
|
30852
|
-
if (isStakeOrchestrationError(error)) return { ok: false, error };
|
|
30853
|
-
return {
|
|
30854
|
-
ok: false,
|
|
30855
|
-
error: executionFailed("staking", error, baseCtx)
|
|
30856
|
-
};
|
|
30857
|
-
}
|
|
32107
|
+
);
|
|
30858
32108
|
}
|
|
30859
32109
|
/**
|
|
30860
32110
|
* Submits the stake transaction on the spoke chain without relaying to the hub.
|
|
@@ -30959,42 +32209,60 @@ var StakingService = class {
|
|
|
30959
32209
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
30960
32210
|
*/
|
|
30961
32211
|
async unstake(_params) {
|
|
30962
|
-
|
|
30963
|
-
|
|
30964
|
-
|
|
30965
|
-
|
|
30966
|
-
|
|
30967
|
-
|
|
30968
|
-
|
|
30969
|
-
|
|
30970
|
-
|
|
30971
|
-
|
|
30972
|
-
|
|
30973
|
-
|
|
30974
|
-
|
|
30975
|
-
|
|
30976
|
-
|
|
32212
|
+
return this.config.analytics.trackResult(
|
|
32213
|
+
"staking",
|
|
32214
|
+
"unstake",
|
|
32215
|
+
async () => {
|
|
32216
|
+
const { params, timeout } = _params;
|
|
32217
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "unstake" };
|
|
32218
|
+
try {
|
|
32219
|
+
const txResult = await this.createUnstakeIntent(_params);
|
|
32220
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32221
|
+
let hubTxHash;
|
|
32222
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32223
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32224
|
+
srcTxHash: txResult.value.tx,
|
|
32225
|
+
data: txResult.value.relayData,
|
|
32226
|
+
chainKey: params.srcChainKey,
|
|
32227
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32228
|
+
timeout
|
|
32229
|
+
});
|
|
32230
|
+
if (!packetResult.ok) {
|
|
32231
|
+
return {
|
|
32232
|
+
ok: false,
|
|
32233
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32234
|
+
feature: "staking",
|
|
32235
|
+
action: baseCtx.action,
|
|
32236
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32237
|
+
})
|
|
32238
|
+
};
|
|
32239
|
+
}
|
|
32240
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32241
|
+
} else {
|
|
32242
|
+
hubTxHash = txResult.value.tx;
|
|
32243
|
+
}
|
|
32244
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32245
|
+
} catch (error) {
|
|
32246
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
30977
32247
|
return {
|
|
30978
32248
|
ok: false,
|
|
30979
|
-
error:
|
|
30980
|
-
feature: "staking",
|
|
30981
|
-
action: baseCtx.action,
|
|
30982
|
-
srcChainKey: baseCtx.srcChainKey
|
|
30983
|
-
})
|
|
32249
|
+
error: executionFailed("staking", error, baseCtx)
|
|
30984
32250
|
};
|
|
30985
32251
|
}
|
|
30986
|
-
|
|
30987
|
-
|
|
30988
|
-
|
|
32252
|
+
},
|
|
32253
|
+
{
|
|
32254
|
+
start: () => ({
|
|
32255
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32256
|
+
srcAddress: _params.params.srcAddress,
|
|
32257
|
+
amount: _params.params.amount
|
|
32258
|
+
}),
|
|
32259
|
+
success: (value) => ({
|
|
32260
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32261
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32262
|
+
}),
|
|
32263
|
+
failure: (error) => ({ code: error.code })
|
|
30989
32264
|
}
|
|
30990
|
-
|
|
30991
|
-
} catch (error) {
|
|
30992
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
30993
|
-
return {
|
|
30994
|
-
ok: false,
|
|
30995
|
-
error: executionFailed("staking", error, baseCtx)
|
|
30996
|
-
};
|
|
30997
|
-
}
|
|
32265
|
+
);
|
|
30998
32266
|
}
|
|
30999
32267
|
/**
|
|
31000
32268
|
* Submits the unstake transaction on the spoke chain without relaying to the hub.
|
|
@@ -31090,42 +32358,61 @@ var StakingService = class {
|
|
|
31090
32358
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
31091
32359
|
*/
|
|
31092
32360
|
async instantUnstake(_params) {
|
|
31093
|
-
|
|
31094
|
-
|
|
31095
|
-
|
|
31096
|
-
|
|
31097
|
-
|
|
31098
|
-
|
|
31099
|
-
|
|
31100
|
-
|
|
31101
|
-
|
|
31102
|
-
|
|
31103
|
-
|
|
31104
|
-
|
|
31105
|
-
|
|
31106
|
-
|
|
31107
|
-
|
|
32361
|
+
return this.config.analytics.trackResult(
|
|
32362
|
+
"staking",
|
|
32363
|
+
"instantUnstake",
|
|
32364
|
+
async () => {
|
|
32365
|
+
const { params, timeout } = _params;
|
|
32366
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "instantUnstake" };
|
|
32367
|
+
try {
|
|
32368
|
+
const txResult = await this.createInstantUnstakeIntent(_params);
|
|
32369
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32370
|
+
let hubTxHash;
|
|
32371
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32372
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32373
|
+
srcTxHash: txResult.value.tx,
|
|
32374
|
+
data: txResult.value.relayData,
|
|
32375
|
+
chainKey: params.srcChainKey,
|
|
32376
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32377
|
+
timeout
|
|
32378
|
+
});
|
|
32379
|
+
if (!packetResult.ok) {
|
|
32380
|
+
return {
|
|
32381
|
+
ok: false,
|
|
32382
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32383
|
+
feature: "staking",
|
|
32384
|
+
action: baseCtx.action,
|
|
32385
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32386
|
+
})
|
|
32387
|
+
};
|
|
32388
|
+
}
|
|
32389
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32390
|
+
} else {
|
|
32391
|
+
hubTxHash = txResult.value.tx;
|
|
32392
|
+
}
|
|
32393
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32394
|
+
} catch (error) {
|
|
32395
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31108
32396
|
return {
|
|
31109
32397
|
ok: false,
|
|
31110
|
-
error:
|
|
31111
|
-
feature: "staking",
|
|
31112
|
-
action: baseCtx.action,
|
|
31113
|
-
srcChainKey: baseCtx.srcChainKey
|
|
31114
|
-
})
|
|
32398
|
+
error: executionFailed("staking", error, baseCtx)
|
|
31115
32399
|
};
|
|
31116
32400
|
}
|
|
31117
|
-
|
|
31118
|
-
|
|
31119
|
-
|
|
32401
|
+
},
|
|
32402
|
+
{
|
|
32403
|
+
start: () => ({
|
|
32404
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32405
|
+
srcAddress: _params.params.srcAddress,
|
|
32406
|
+
amount: _params.params.amount,
|
|
32407
|
+
minAmount: _params.params.minAmount
|
|
32408
|
+
}),
|
|
32409
|
+
success: (value) => ({
|
|
32410
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32411
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32412
|
+
}),
|
|
32413
|
+
failure: (error) => ({ code: error.code })
|
|
31120
32414
|
}
|
|
31121
|
-
|
|
31122
|
-
} catch (error) {
|
|
31123
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31124
|
-
return {
|
|
31125
|
-
ok: false,
|
|
31126
|
-
error: executionFailed("staking", error, baseCtx)
|
|
31127
|
-
};
|
|
31128
|
-
}
|
|
32415
|
+
);
|
|
31129
32416
|
}
|
|
31130
32417
|
/**
|
|
31131
32418
|
* Submits the instant-unstake transaction on the spoke chain without relaying to the hub.
|
|
@@ -31233,42 +32520,61 @@ var StakingService = class {
|
|
|
31233
32520
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
31234
32521
|
*/
|
|
31235
32522
|
async claim(_params) {
|
|
31236
|
-
|
|
31237
|
-
|
|
31238
|
-
|
|
31239
|
-
|
|
31240
|
-
|
|
31241
|
-
|
|
31242
|
-
|
|
31243
|
-
|
|
31244
|
-
|
|
31245
|
-
|
|
31246
|
-
|
|
31247
|
-
|
|
31248
|
-
|
|
31249
|
-
|
|
31250
|
-
|
|
32523
|
+
return this.config.analytics.trackResult(
|
|
32524
|
+
"staking",
|
|
32525
|
+
"claim",
|
|
32526
|
+
async () => {
|
|
32527
|
+
const { params, timeout } = _params;
|
|
32528
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "claim" };
|
|
32529
|
+
try {
|
|
32530
|
+
const txResult = await this.createClaimIntent(_params);
|
|
32531
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32532
|
+
let hubTxHash;
|
|
32533
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32534
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32535
|
+
srcTxHash: txResult.value.tx,
|
|
32536
|
+
data: txResult.value.relayData,
|
|
32537
|
+
chainKey: params.srcChainKey,
|
|
32538
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32539
|
+
timeout
|
|
32540
|
+
});
|
|
32541
|
+
if (!packetResult.ok) {
|
|
32542
|
+
return {
|
|
32543
|
+
ok: false,
|
|
32544
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32545
|
+
feature: "staking",
|
|
32546
|
+
action: baseCtx.action,
|
|
32547
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32548
|
+
})
|
|
32549
|
+
};
|
|
32550
|
+
}
|
|
32551
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32552
|
+
} else {
|
|
32553
|
+
hubTxHash = txResult.value.tx;
|
|
32554
|
+
}
|
|
32555
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32556
|
+
} catch (error) {
|
|
32557
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31251
32558
|
return {
|
|
31252
32559
|
ok: false,
|
|
31253
|
-
error:
|
|
31254
|
-
feature: "staking",
|
|
31255
|
-
action: baseCtx.action,
|
|
31256
|
-
srcChainKey: baseCtx.srcChainKey
|
|
31257
|
-
})
|
|
32560
|
+
error: executionFailed("staking", error, baseCtx)
|
|
31258
32561
|
};
|
|
31259
32562
|
}
|
|
31260
|
-
|
|
31261
|
-
|
|
31262
|
-
|
|
32563
|
+
},
|
|
32564
|
+
{
|
|
32565
|
+
start: () => ({
|
|
32566
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32567
|
+
srcAddress: _params.params.srcAddress,
|
|
32568
|
+
requestId: _params.params.requestId,
|
|
32569
|
+
amount: _params.params.amount
|
|
32570
|
+
}),
|
|
32571
|
+
success: (value) => ({
|
|
32572
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32573
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32574
|
+
}),
|
|
32575
|
+
failure: (error) => ({ code: error.code })
|
|
31263
32576
|
}
|
|
31264
|
-
|
|
31265
|
-
} catch (error) {
|
|
31266
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31267
|
-
return {
|
|
31268
|
-
ok: false,
|
|
31269
|
-
error: executionFailed("staking", error, baseCtx)
|
|
31270
|
-
};
|
|
31271
|
-
}
|
|
32577
|
+
);
|
|
31272
32578
|
}
|
|
31273
32579
|
/**
|
|
31274
32580
|
* Submits the claim transaction on the spoke chain without relaying to the hub.
|
|
@@ -31382,42 +32688,60 @@ var StakingService = class {
|
|
|
31382
32688
|
* @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
|
|
31383
32689
|
*/
|
|
31384
32690
|
async cancelUnstake(_params) {
|
|
31385
|
-
|
|
31386
|
-
|
|
31387
|
-
|
|
31388
|
-
|
|
31389
|
-
|
|
31390
|
-
|
|
31391
|
-
|
|
31392
|
-
|
|
31393
|
-
|
|
31394
|
-
|
|
31395
|
-
|
|
31396
|
-
|
|
31397
|
-
|
|
31398
|
-
|
|
31399
|
-
|
|
32691
|
+
return this.config.analytics.trackResult(
|
|
32692
|
+
"staking",
|
|
32693
|
+
"cancelUnstake",
|
|
32694
|
+
async () => {
|
|
32695
|
+
const { params, timeout } = _params;
|
|
32696
|
+
const baseCtx = { srcChainKey: params.srcChainKey, action: "cancelUnstake" };
|
|
32697
|
+
try {
|
|
32698
|
+
const txResult = await this.createCancelUnstakeIntent(_params);
|
|
32699
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
32700
|
+
let hubTxHash;
|
|
32701
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
32702
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
32703
|
+
srcTxHash: txResult.value.tx,
|
|
32704
|
+
data: txResult.value.relayData,
|
|
32705
|
+
chainKey: params.srcChainKey,
|
|
32706
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
32707
|
+
timeout
|
|
32708
|
+
});
|
|
32709
|
+
if (!packetResult.ok) {
|
|
32710
|
+
return {
|
|
32711
|
+
ok: false,
|
|
32712
|
+
error: mapRelayFailure(packetResult.error, {
|
|
32713
|
+
feature: "staking",
|
|
32714
|
+
action: baseCtx.action,
|
|
32715
|
+
srcChainKey: baseCtx.srcChainKey
|
|
32716
|
+
})
|
|
32717
|
+
};
|
|
32718
|
+
}
|
|
32719
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
32720
|
+
} else {
|
|
32721
|
+
hubTxHash = txResult.value.tx;
|
|
32722
|
+
}
|
|
32723
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
32724
|
+
} catch (error) {
|
|
32725
|
+
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31400
32726
|
return {
|
|
31401
32727
|
ok: false,
|
|
31402
|
-
error:
|
|
31403
|
-
feature: "staking",
|
|
31404
|
-
action: baseCtx.action,
|
|
31405
|
-
srcChainKey: baseCtx.srcChainKey
|
|
31406
|
-
})
|
|
32728
|
+
error: executionFailed("staking", error, baseCtx)
|
|
31407
32729
|
};
|
|
31408
32730
|
}
|
|
31409
|
-
|
|
31410
|
-
|
|
31411
|
-
|
|
32731
|
+
},
|
|
32732
|
+
{
|
|
32733
|
+
start: () => ({
|
|
32734
|
+
srcChainKey: _params.params.srcChainKey,
|
|
32735
|
+
srcAddress: _params.params.srcAddress,
|
|
32736
|
+
requestId: _params.params.requestId
|
|
32737
|
+
}),
|
|
32738
|
+
success: (value) => ({
|
|
32739
|
+
srcChainTxHash: value.srcChainTxHash,
|
|
32740
|
+
dstChainTxHash: value.dstChainTxHash
|
|
32741
|
+
}),
|
|
32742
|
+
failure: (error) => ({ code: error.code })
|
|
31412
32743
|
}
|
|
31413
|
-
|
|
31414
|
-
} catch (error) {
|
|
31415
|
-
if (isStakingOrchestrationError(error)) return { ok: false, error };
|
|
31416
|
-
return {
|
|
31417
|
-
ok: false,
|
|
31418
|
-
error: executionFailed("staking", error, baseCtx)
|
|
31419
|
-
};
|
|
31420
|
-
}
|
|
32744
|
+
);
|
|
31421
32745
|
}
|
|
31422
32746
|
/**
|
|
31423
32747
|
* Submits the cancel-unstake transaction on the spoke chain without relaying to the hub.
|
|
@@ -32791,34 +34115,56 @@ var ClService = class _ClService {
|
|
|
32791
34115
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
32792
34116
|
*/
|
|
32793
34117
|
async supplyLiquidity(_params) {
|
|
32794
|
-
|
|
32795
|
-
|
|
32796
|
-
|
|
32797
|
-
|
|
32798
|
-
|
|
32799
|
-
|
|
32800
|
-
|
|
32801
|
-
|
|
32802
|
-
|
|
32803
|
-
|
|
32804
|
-
|
|
32805
|
-
|
|
32806
|
-
|
|
32807
|
-
|
|
32808
|
-
|
|
32809
|
-
|
|
32810
|
-
|
|
32811
|
-
|
|
32812
|
-
|
|
34118
|
+
return this.config.analytics.trackResult(
|
|
34119
|
+
"dex",
|
|
34120
|
+
"supplyLiquidity",
|
|
34121
|
+
async () => {
|
|
34122
|
+
const { params, timeout } = _params;
|
|
34123
|
+
try {
|
|
34124
|
+
const txResult = await this.executeSupplyLiquidity(_params);
|
|
34125
|
+
if (!txResult.ok) {
|
|
34126
|
+
return txResult;
|
|
34127
|
+
}
|
|
34128
|
+
let hubTxHash;
|
|
34129
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34130
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34131
|
+
srcTxHash: txResult.value.tx,
|
|
34132
|
+
data: txResult.value.relayData,
|
|
34133
|
+
chainKey: params.srcChainKey,
|
|
34134
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34135
|
+
timeout
|
|
34136
|
+
});
|
|
34137
|
+
if (!packetResult.ok) return packetResult;
|
|
34138
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34139
|
+
} else {
|
|
34140
|
+
hubTxHash = txResult.value.tx;
|
|
34141
|
+
}
|
|
34142
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34143
|
+
} catch (error) {
|
|
34144
|
+
this.config.logger.error("supplyLiquidity error", error);
|
|
34145
|
+
return {
|
|
34146
|
+
ok: false,
|
|
34147
|
+
error
|
|
34148
|
+
};
|
|
34149
|
+
}
|
|
34150
|
+
},
|
|
34151
|
+
{
|
|
34152
|
+
start: () => ({
|
|
34153
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34154
|
+
srcAddress: _params.params.srcAddress,
|
|
34155
|
+
currency0: _params.params.poolKey.currency0,
|
|
34156
|
+
currency1: _params.params.poolKey.currency1,
|
|
34157
|
+
fee: _params.params.poolKey.fee,
|
|
34158
|
+
tickLower: _params.params.tickLower,
|
|
34159
|
+
tickUpper: _params.params.tickUpper,
|
|
34160
|
+
liquidity: _params.params.liquidity,
|
|
34161
|
+
amount0Max: _params.params.amount0Max,
|
|
34162
|
+
amount1Max: _params.params.amount1Max
|
|
34163
|
+
}),
|
|
34164
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34165
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
32813
34166
|
}
|
|
32814
|
-
|
|
32815
|
-
} catch (error) {
|
|
32816
|
-
this.config.logger.error("supplyLiquidity error", error);
|
|
32817
|
-
return {
|
|
32818
|
-
ok: false,
|
|
32819
|
-
error
|
|
32820
|
-
};
|
|
32821
|
-
}
|
|
34167
|
+
);
|
|
32822
34168
|
}
|
|
32823
34169
|
/**
|
|
32824
34170
|
* Add liquidity to an existing position and wait for the cross-chain relay to complete.
|
|
@@ -32833,33 +34179,56 @@ var ClService = class _ClService {
|
|
|
32833
34179
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
32834
34180
|
*/
|
|
32835
34181
|
async increaseLiquidity(_params) {
|
|
32836
|
-
|
|
32837
|
-
|
|
32838
|
-
|
|
32839
|
-
|
|
32840
|
-
|
|
32841
|
-
|
|
32842
|
-
|
|
32843
|
-
|
|
32844
|
-
|
|
32845
|
-
|
|
32846
|
-
|
|
32847
|
-
|
|
32848
|
-
|
|
32849
|
-
|
|
32850
|
-
|
|
32851
|
-
|
|
32852
|
-
|
|
32853
|
-
|
|
32854
|
-
|
|
34182
|
+
return this.config.analytics.trackResult(
|
|
34183
|
+
"dex",
|
|
34184
|
+
"increaseLiquidity",
|
|
34185
|
+
async () => {
|
|
34186
|
+
const { params, timeout } = _params;
|
|
34187
|
+
try {
|
|
34188
|
+
const txResult = await this.executeIncreaseLiquidity(_params);
|
|
34189
|
+
if (!txResult.ok) {
|
|
34190
|
+
return txResult;
|
|
34191
|
+
}
|
|
34192
|
+
let hubTxHash;
|
|
34193
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34194
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34195
|
+
srcTxHash: txResult.value.tx,
|
|
34196
|
+
data: txResult.value.relayData,
|
|
34197
|
+
chainKey: params.srcChainKey,
|
|
34198
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34199
|
+
timeout
|
|
34200
|
+
});
|
|
34201
|
+
if (!packetResult.ok) return packetResult;
|
|
34202
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34203
|
+
} else {
|
|
34204
|
+
hubTxHash = txResult.value.tx;
|
|
34205
|
+
}
|
|
34206
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34207
|
+
} catch (error) {
|
|
34208
|
+
return {
|
|
34209
|
+
ok: false,
|
|
34210
|
+
error
|
|
34211
|
+
};
|
|
34212
|
+
}
|
|
34213
|
+
},
|
|
34214
|
+
{
|
|
34215
|
+
start: () => ({
|
|
34216
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34217
|
+
srcAddress: _params.params.srcAddress,
|
|
34218
|
+
currency0: _params.params.poolKey.currency0,
|
|
34219
|
+
currency1: _params.params.poolKey.currency1,
|
|
34220
|
+
fee: _params.params.poolKey.fee,
|
|
34221
|
+
tokenId: _params.params.tokenId,
|
|
34222
|
+
tickLower: _params.params.tickLower,
|
|
34223
|
+
tickUpper: _params.params.tickUpper,
|
|
34224
|
+
liquidity: _params.params.liquidity,
|
|
34225
|
+
amount0Max: _params.params.amount0Max,
|
|
34226
|
+
amount1Max: _params.params.amount1Max
|
|
34227
|
+
}),
|
|
34228
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34229
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
32855
34230
|
}
|
|
32856
|
-
|
|
32857
|
-
} catch (error) {
|
|
32858
|
-
return {
|
|
32859
|
-
ok: false,
|
|
32860
|
-
error
|
|
32861
|
-
};
|
|
32862
|
-
}
|
|
34231
|
+
);
|
|
32863
34232
|
}
|
|
32864
34233
|
/**
|
|
32865
34234
|
* Remove liquidity from an existing position and wait for the cross-chain relay to complete.
|
|
@@ -32874,33 +34243,54 @@ var ClService = class _ClService {
|
|
|
32874
34243
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
32875
34244
|
*/
|
|
32876
34245
|
async decreaseLiquidity(_params) {
|
|
32877
|
-
|
|
32878
|
-
|
|
32879
|
-
|
|
32880
|
-
|
|
32881
|
-
|
|
32882
|
-
|
|
32883
|
-
|
|
32884
|
-
|
|
32885
|
-
|
|
32886
|
-
|
|
32887
|
-
|
|
32888
|
-
|
|
32889
|
-
|
|
32890
|
-
|
|
32891
|
-
|
|
32892
|
-
|
|
32893
|
-
|
|
32894
|
-
|
|
32895
|
-
|
|
34246
|
+
return this.config.analytics.trackResult(
|
|
34247
|
+
"dex",
|
|
34248
|
+
"decreaseLiquidity",
|
|
34249
|
+
async () => {
|
|
34250
|
+
const { params, timeout } = _params;
|
|
34251
|
+
try {
|
|
34252
|
+
const txResult = await this.executeDecreaseLiquidity(_params);
|
|
34253
|
+
if (!txResult.ok) {
|
|
34254
|
+
return txResult;
|
|
34255
|
+
}
|
|
34256
|
+
let hubTxHash;
|
|
34257
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34258
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34259
|
+
srcTxHash: txResult.value.tx,
|
|
34260
|
+
data: txResult.value.relayData,
|
|
34261
|
+
chainKey: params.srcChainKey,
|
|
34262
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34263
|
+
timeout
|
|
34264
|
+
});
|
|
34265
|
+
if (!packetResult.ok) return packetResult;
|
|
34266
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34267
|
+
} else {
|
|
34268
|
+
hubTxHash = txResult.value.tx;
|
|
34269
|
+
}
|
|
34270
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34271
|
+
} catch (error) {
|
|
34272
|
+
return {
|
|
34273
|
+
ok: false,
|
|
34274
|
+
error
|
|
34275
|
+
};
|
|
34276
|
+
}
|
|
34277
|
+
},
|
|
34278
|
+
{
|
|
34279
|
+
start: () => ({
|
|
34280
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34281
|
+
srcAddress: _params.params.srcAddress,
|
|
34282
|
+
currency0: _params.params.poolKey.currency0,
|
|
34283
|
+
currency1: _params.params.poolKey.currency1,
|
|
34284
|
+
fee: _params.params.poolKey.fee,
|
|
34285
|
+
tokenId: _params.params.tokenId,
|
|
34286
|
+
liquidity: _params.params.liquidity,
|
|
34287
|
+
amount0Min: _params.params.amount0Min,
|
|
34288
|
+
amount1Min: _params.params.amount1Min
|
|
34289
|
+
}),
|
|
34290
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34291
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
32896
34292
|
}
|
|
32897
|
-
|
|
32898
|
-
} catch (error) {
|
|
32899
|
-
return {
|
|
32900
|
-
ok: false,
|
|
32901
|
-
error
|
|
32902
|
-
};
|
|
32903
|
-
}
|
|
34293
|
+
);
|
|
32904
34294
|
}
|
|
32905
34295
|
/**
|
|
32906
34296
|
* Fetch the reward configuration stored in the pool's hook contract.
|
|
@@ -33052,34 +34442,54 @@ var ClService = class _ClService {
|
|
|
33052
34442
|
* `dstChainTxHash` (hub) once the packet has been confirmed.
|
|
33053
34443
|
*/
|
|
33054
34444
|
async claimRewards(_params) {
|
|
33055
|
-
|
|
33056
|
-
|
|
33057
|
-
|
|
33058
|
-
|
|
33059
|
-
|
|
33060
|
-
|
|
33061
|
-
|
|
33062
|
-
|
|
33063
|
-
|
|
33064
|
-
|
|
33065
|
-
|
|
33066
|
-
|
|
33067
|
-
|
|
33068
|
-
|
|
33069
|
-
|
|
33070
|
-
|
|
33071
|
-
|
|
33072
|
-
|
|
33073
|
-
|
|
34445
|
+
return this.config.analytics.trackResult(
|
|
34446
|
+
"dex",
|
|
34447
|
+
"claimRewards",
|
|
34448
|
+
async () => {
|
|
34449
|
+
const { params, timeout } = _params;
|
|
34450
|
+
try {
|
|
34451
|
+
const txResult = await this.executeClaimRewards(_params);
|
|
34452
|
+
if (!txResult.ok) {
|
|
34453
|
+
return txResult;
|
|
34454
|
+
}
|
|
34455
|
+
let hubTxHash;
|
|
34456
|
+
if (!isHubChainKeyType(params.srcChainKey)) {
|
|
34457
|
+
const packetResult = await relayTxAndWaitPacket({
|
|
34458
|
+
srcTxHash: txResult.value.tx,
|
|
34459
|
+
data: txResult.value.relayData,
|
|
34460
|
+
chainKey: params.srcChainKey,
|
|
34461
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
34462
|
+
timeout
|
|
34463
|
+
});
|
|
34464
|
+
if (!packetResult.ok) return packetResult;
|
|
34465
|
+
hubTxHash = packetResult.value.dst_tx_hash;
|
|
34466
|
+
} else {
|
|
34467
|
+
hubTxHash = txResult.value.tx;
|
|
34468
|
+
}
|
|
34469
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
|
|
34470
|
+
} catch (error) {
|
|
34471
|
+
this.config.logger.error("claimRewards error", error);
|
|
34472
|
+
return {
|
|
34473
|
+
ok: false,
|
|
34474
|
+
error
|
|
34475
|
+
};
|
|
34476
|
+
}
|
|
34477
|
+
},
|
|
34478
|
+
{
|
|
34479
|
+
start: () => ({
|
|
34480
|
+
srcChainKey: _params.params.srcChainKey,
|
|
34481
|
+
srcAddress: _params.params.srcAddress,
|
|
34482
|
+
currency0: _params.params.poolKey.currency0,
|
|
34483
|
+
currency1: _params.params.poolKey.currency1,
|
|
34484
|
+
fee: _params.params.poolKey.fee,
|
|
34485
|
+
tokenId: _params.params.tokenId,
|
|
34486
|
+
tickLower: _params.params.tickLower,
|
|
34487
|
+
tickUpper: _params.params.tickUpper
|
|
34488
|
+
}),
|
|
34489
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
34490
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
33074
34491
|
}
|
|
33075
|
-
|
|
33076
|
-
} catch (error) {
|
|
33077
|
-
this.config.logger.error("claimRewards error", error);
|
|
33078
|
-
return {
|
|
33079
|
-
ok: false,
|
|
33080
|
-
error
|
|
33081
|
-
};
|
|
33082
|
-
}
|
|
34492
|
+
);
|
|
33083
34493
|
}
|
|
33084
34494
|
/**
|
|
33085
34495
|
* Return the list of configured concentrated-liquidity pool keys for the SODAX DEX.
|
|
@@ -36002,50 +37412,68 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
36002
37412
|
* @returns A pair of transaction hashes — `srcChainTxHash` (spoke) and `dstChainTxHash` (hub).
|
|
36003
37413
|
*/
|
|
36004
37414
|
async supply(_params) {
|
|
36005
|
-
|
|
36006
|
-
|
|
36007
|
-
|
|
36008
|
-
|
|
36009
|
-
|
|
36010
|
-
|
|
36011
|
-
|
|
36012
|
-
|
|
36013
|
-
|
|
36014
|
-
ok: false,
|
|
36015
|
-
|
|
36016
|
-
|
|
36017
|
-
|
|
36018
|
-
|
|
36019
|
-
|
|
36020
|
-
|
|
36021
|
-
|
|
36022
|
-
|
|
37415
|
+
return this.config.analytics.trackResult(
|
|
37416
|
+
"moneyMarket",
|
|
37417
|
+
"supply",
|
|
37418
|
+
async () => {
|
|
37419
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37420
|
+
const srcChainKey = params.srcChainKey;
|
|
37421
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "supply" };
|
|
37422
|
+
try {
|
|
37423
|
+
const txResult = await this.createSupplyIntent(_params);
|
|
37424
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37425
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37426
|
+
if (!verify.ok) {
|
|
37427
|
+
return {
|
|
37428
|
+
ok: false,
|
|
37429
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37430
|
+
};
|
|
37431
|
+
}
|
|
37432
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
37433
|
+
return {
|
|
37434
|
+
ok: true,
|
|
37435
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37436
|
+
};
|
|
37437
|
+
}
|
|
37438
|
+
const packet = await relayTxAndWaitPacket({
|
|
37439
|
+
srcTxHash: txResult.value.tx,
|
|
37440
|
+
data: txResult.value.relayData,
|
|
37441
|
+
chainKey: srcChainKey,
|
|
37442
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37443
|
+
timeout
|
|
37444
|
+
});
|
|
37445
|
+
if (!packet.ok)
|
|
37446
|
+
return {
|
|
37447
|
+
ok: false,
|
|
37448
|
+
error: mapRelayFailure(packet.error, {
|
|
37449
|
+
feature: "moneyMarket",
|
|
37450
|
+
action: baseCtx.action,
|
|
37451
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37452
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37453
|
+
})
|
|
37454
|
+
};
|
|
37455
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
37456
|
+
} catch (error) {
|
|
37457
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37458
|
+
return {
|
|
37459
|
+
ok: false,
|
|
37460
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37461
|
+
};
|
|
37462
|
+
}
|
|
37463
|
+
},
|
|
37464
|
+
{
|
|
37465
|
+
start: () => ({
|
|
37466
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37467
|
+
srcAddress: _params.params.srcAddress,
|
|
37468
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37469
|
+
dstAddress: _params.params.dstAddress,
|
|
37470
|
+
token: _params.params.token,
|
|
37471
|
+
amount: _params.params.amount
|
|
37472
|
+
}),
|
|
37473
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37474
|
+
failure: (error) => ({ code: error.code })
|
|
36023
37475
|
}
|
|
36024
|
-
|
|
36025
|
-
srcTxHash: txResult.value.tx,
|
|
36026
|
-
data: txResult.value.relayData,
|
|
36027
|
-
chainKey: srcChainKey,
|
|
36028
|
-
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
36029
|
-
timeout
|
|
36030
|
-
});
|
|
36031
|
-
if (!packet.ok)
|
|
36032
|
-
return {
|
|
36033
|
-
ok: false,
|
|
36034
|
-
error: mapRelayFailure(packet.error, {
|
|
36035
|
-
feature: "moneyMarket",
|
|
36036
|
-
action: baseCtx.action,
|
|
36037
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
36038
|
-
dstChainKey: baseCtx.dstChainKey
|
|
36039
|
-
})
|
|
36040
|
-
};
|
|
36041
|
-
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
36042
|
-
} catch (error) {
|
|
36043
|
-
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
36044
|
-
return {
|
|
36045
|
-
ok: false,
|
|
36046
|
-
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
36047
|
-
};
|
|
36048
|
-
}
|
|
37476
|
+
);
|
|
36049
37477
|
}
|
|
36050
37478
|
/**
|
|
36051
37479
|
* Build and optionally broadcast the spoke-side supply transaction without waiting for the
|
|
@@ -36162,58 +37590,76 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
36162
37590
|
* `dstChainTxHash` (hub delivery or relay destination).
|
|
36163
37591
|
*/
|
|
36164
37592
|
async borrow(_params) {
|
|
36165
|
-
|
|
36166
|
-
|
|
36167
|
-
|
|
36168
|
-
|
|
36169
|
-
|
|
36170
|
-
|
|
36171
|
-
|
|
36172
|
-
|
|
36173
|
-
|
|
36174
|
-
|
|
36175
|
-
ok: false,
|
|
36176
|
-
|
|
36177
|
-
|
|
36178
|
-
|
|
36179
|
-
|
|
36180
|
-
|
|
36181
|
-
|
|
36182
|
-
|
|
36183
|
-
|
|
36184
|
-
|
|
36185
|
-
|
|
36186
|
-
|
|
36187
|
-
|
|
36188
|
-
|
|
36189
|
-
|
|
36190
|
-
|
|
36191
|
-
|
|
36192
|
-
|
|
36193
|
-
|
|
36194
|
-
|
|
36195
|
-
|
|
36196
|
-
|
|
36197
|
-
|
|
36198
|
-
|
|
36199
|
-
|
|
36200
|
-
|
|
36201
|
-
|
|
36202
|
-
|
|
36203
|
-
|
|
36204
|
-
|
|
36205
|
-
|
|
36206
|
-
|
|
36207
|
-
|
|
37593
|
+
return this.config.analytics.trackResult(
|
|
37594
|
+
"moneyMarket",
|
|
37595
|
+
"borrow",
|
|
37596
|
+
async () => {
|
|
37597
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37598
|
+
const srcChainKey = params.srcChainKey;
|
|
37599
|
+
const hubChainId = this.hubProvider.chainConfig.chain.key;
|
|
37600
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "borrow" };
|
|
37601
|
+
try {
|
|
37602
|
+
const txResult = await this.createBorrowIntent(_params);
|
|
37603
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37604
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37605
|
+
if (!verify.ok) {
|
|
37606
|
+
return {
|
|
37607
|
+
ok: false,
|
|
37608
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37609
|
+
};
|
|
37610
|
+
}
|
|
37611
|
+
const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId;
|
|
37612
|
+
if (!needsRelay) {
|
|
37613
|
+
return {
|
|
37614
|
+
ok: true,
|
|
37615
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37616
|
+
};
|
|
37617
|
+
}
|
|
37618
|
+
const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
|
|
37619
|
+
const packet = await relayTxAndWaitPacket({
|
|
37620
|
+
...relayIdentity,
|
|
37621
|
+
chainKey: srcChainKey,
|
|
37622
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37623
|
+
timeout
|
|
37624
|
+
});
|
|
37625
|
+
if (!packet.ok)
|
|
37626
|
+
return {
|
|
37627
|
+
ok: false,
|
|
37628
|
+
error: mapRelayFailure(packet.error, {
|
|
37629
|
+
feature: "moneyMarket",
|
|
37630
|
+
action: baseCtx.action,
|
|
37631
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37632
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37633
|
+
})
|
|
37634
|
+
};
|
|
37635
|
+
return {
|
|
37636
|
+
ok: true,
|
|
37637
|
+
value: {
|
|
37638
|
+
srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
|
|
37639
|
+
dstChainTxHash: packet.value.dst_tx_hash
|
|
37640
|
+
}
|
|
37641
|
+
};
|
|
37642
|
+
} catch (error) {
|
|
37643
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37644
|
+
return {
|
|
37645
|
+
ok: false,
|
|
37646
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37647
|
+
};
|
|
36208
37648
|
}
|
|
36209
|
-
}
|
|
36210
|
-
|
|
36211
|
-
|
|
36212
|
-
|
|
36213
|
-
|
|
36214
|
-
|
|
36215
|
-
|
|
36216
|
-
|
|
37649
|
+
},
|
|
37650
|
+
{
|
|
37651
|
+
start: () => ({
|
|
37652
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37653
|
+
srcAddress: _params.params.srcAddress,
|
|
37654
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37655
|
+
dstAddress: _params.params.dstAddress,
|
|
37656
|
+
token: _params.params.token,
|
|
37657
|
+
amount: _params.params.amount
|
|
37658
|
+
}),
|
|
37659
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37660
|
+
failure: (error) => ({ code: error.code })
|
|
37661
|
+
}
|
|
37662
|
+
);
|
|
36217
37663
|
}
|
|
36218
37664
|
/**
|
|
36219
37665
|
* Build and optionally broadcast the spoke-side borrow message without waiting for the
|
|
@@ -36311,59 +37757,77 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
36311
37757
|
* `dstChainTxHash` (hub or relay destination).
|
|
36312
37758
|
*/
|
|
36313
37759
|
async withdraw(_params) {
|
|
36314
|
-
|
|
36315
|
-
|
|
36316
|
-
|
|
36317
|
-
|
|
36318
|
-
|
|
36319
|
-
|
|
36320
|
-
|
|
36321
|
-
|
|
36322
|
-
|
|
36323
|
-
|
|
36324
|
-
|
|
36325
|
-
ok: false,
|
|
36326
|
-
|
|
36327
|
-
|
|
36328
|
-
|
|
36329
|
-
|
|
36330
|
-
|
|
36331
|
-
|
|
36332
|
-
|
|
36333
|
-
|
|
36334
|
-
|
|
36335
|
-
|
|
36336
|
-
|
|
36337
|
-
|
|
36338
|
-
|
|
36339
|
-
|
|
36340
|
-
|
|
36341
|
-
|
|
36342
|
-
|
|
36343
|
-
|
|
36344
|
-
|
|
36345
|
-
|
|
36346
|
-
|
|
36347
|
-
|
|
36348
|
-
|
|
36349
|
-
|
|
36350
|
-
|
|
36351
|
-
|
|
36352
|
-
|
|
36353
|
-
|
|
36354
|
-
|
|
36355
|
-
|
|
36356
|
-
|
|
36357
|
-
|
|
37760
|
+
return this.config.analytics.trackResult(
|
|
37761
|
+
"moneyMarket",
|
|
37762
|
+
"withdraw",
|
|
37763
|
+
async () => {
|
|
37764
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37765
|
+
const srcChainKey = params.srcChainKey;
|
|
37766
|
+
const hubChainId = this.hubProvider.chainConfig.chain.key;
|
|
37767
|
+
const walletRouter = this.hubProvider.chainConfig.addresses.walletRouter;
|
|
37768
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "withdraw" };
|
|
37769
|
+
try {
|
|
37770
|
+
const txResult = await this.createWithdrawIntent(_params);
|
|
37771
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37772
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37773
|
+
if (!verify.ok) {
|
|
37774
|
+
return {
|
|
37775
|
+
ok: false,
|
|
37776
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37777
|
+
};
|
|
37778
|
+
}
|
|
37779
|
+
const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId && params.dstAddress !== walletRouter;
|
|
37780
|
+
if (!needsRelay) {
|
|
37781
|
+
return {
|
|
37782
|
+
ok: true,
|
|
37783
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37784
|
+
};
|
|
37785
|
+
}
|
|
37786
|
+
const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
|
|
37787
|
+
const packet = await relayTxAndWaitPacket({
|
|
37788
|
+
...relayIdentity,
|
|
37789
|
+
chainKey: srcChainKey,
|
|
37790
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37791
|
+
timeout
|
|
37792
|
+
});
|
|
37793
|
+
if (!packet.ok)
|
|
37794
|
+
return {
|
|
37795
|
+
ok: false,
|
|
37796
|
+
error: mapRelayFailure(packet.error, {
|
|
37797
|
+
feature: "moneyMarket",
|
|
37798
|
+
action: baseCtx.action,
|
|
37799
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37800
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37801
|
+
})
|
|
37802
|
+
};
|
|
37803
|
+
return {
|
|
37804
|
+
ok: true,
|
|
37805
|
+
value: {
|
|
37806
|
+
srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
|
|
37807
|
+
dstChainTxHash: packet.value.dst_tx_hash
|
|
37808
|
+
}
|
|
37809
|
+
};
|
|
37810
|
+
} catch (error) {
|
|
37811
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37812
|
+
return {
|
|
37813
|
+
ok: false,
|
|
37814
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37815
|
+
};
|
|
36358
37816
|
}
|
|
36359
|
-
}
|
|
36360
|
-
|
|
36361
|
-
|
|
36362
|
-
|
|
36363
|
-
|
|
36364
|
-
|
|
36365
|
-
|
|
36366
|
-
|
|
37817
|
+
},
|
|
37818
|
+
{
|
|
37819
|
+
start: () => ({
|
|
37820
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37821
|
+
srcAddress: _params.params.srcAddress,
|
|
37822
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37823
|
+
dstAddress: _params.params.dstAddress,
|
|
37824
|
+
token: _params.params.token,
|
|
37825
|
+
amount: _params.params.amount
|
|
37826
|
+
}),
|
|
37827
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37828
|
+
failure: (error) => ({ code: error.code })
|
|
37829
|
+
}
|
|
37830
|
+
);
|
|
36367
37831
|
}
|
|
36368
37832
|
/**
|
|
36369
37833
|
* Build and optionally broadcast the spoke-side withdraw message without waiting for the
|
|
@@ -36459,50 +37923,68 @@ var MoneyMarketService = class _MoneyMarketService {
|
|
|
36459
37923
|
* @returns A pair of transaction hashes — `srcChainTxHash` (spoke) and `dstChainTxHash` (hub).
|
|
36460
37924
|
*/
|
|
36461
37925
|
async repay(_params) {
|
|
36462
|
-
|
|
36463
|
-
|
|
36464
|
-
|
|
36465
|
-
|
|
36466
|
-
|
|
36467
|
-
|
|
36468
|
-
|
|
36469
|
-
|
|
36470
|
-
|
|
36471
|
-
ok: false,
|
|
36472
|
-
|
|
36473
|
-
|
|
36474
|
-
|
|
36475
|
-
|
|
36476
|
-
|
|
36477
|
-
|
|
36478
|
-
|
|
36479
|
-
|
|
37926
|
+
return this.config.analytics.trackResult(
|
|
37927
|
+
"moneyMarket",
|
|
37928
|
+
"repay",
|
|
37929
|
+
async () => {
|
|
37930
|
+
const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
|
|
37931
|
+
const srcChainKey = params.srcChainKey;
|
|
37932
|
+
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "repay" };
|
|
37933
|
+
try {
|
|
37934
|
+
const txResult = await this.createRepayIntent(_params);
|
|
37935
|
+
if (!txResult.ok) return { ok: false, error: txResult.error };
|
|
37936
|
+
const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
|
|
37937
|
+
if (!verify.ok) {
|
|
37938
|
+
return {
|
|
37939
|
+
ok: false,
|
|
37940
|
+
error: verifyFailed("moneyMarket", verify.error, baseCtx)
|
|
37941
|
+
};
|
|
37942
|
+
}
|
|
37943
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
37944
|
+
return {
|
|
37945
|
+
ok: true,
|
|
37946
|
+
value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
|
|
37947
|
+
};
|
|
37948
|
+
}
|
|
37949
|
+
const packet = await relayTxAndWaitPacket({
|
|
37950
|
+
srcTxHash: txResult.value.tx,
|
|
37951
|
+
data: txResult.value.relayData,
|
|
37952
|
+
chainKey: srcChainKey,
|
|
37953
|
+
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
37954
|
+
timeout
|
|
37955
|
+
});
|
|
37956
|
+
if (!packet.ok)
|
|
37957
|
+
return {
|
|
37958
|
+
ok: false,
|
|
37959
|
+
error: mapRelayFailure(packet.error, {
|
|
37960
|
+
feature: "moneyMarket",
|
|
37961
|
+
action: baseCtx.action,
|
|
37962
|
+
srcChainKey: baseCtx.srcChainKey,
|
|
37963
|
+
dstChainKey: baseCtx.dstChainKey
|
|
37964
|
+
})
|
|
37965
|
+
};
|
|
37966
|
+
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
37967
|
+
} catch (error) {
|
|
37968
|
+
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
37969
|
+
return {
|
|
37970
|
+
ok: false,
|
|
37971
|
+
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
37972
|
+
};
|
|
37973
|
+
}
|
|
37974
|
+
},
|
|
37975
|
+
{
|
|
37976
|
+
start: () => ({
|
|
37977
|
+
srcChainKey: _params.params.srcChainKey,
|
|
37978
|
+
srcAddress: _params.params.srcAddress,
|
|
37979
|
+
dstChainKey: _params.params.dstChainKey,
|
|
37980
|
+
dstAddress: _params.params.dstAddress,
|
|
37981
|
+
token: _params.params.token,
|
|
37982
|
+
amount: _params.params.amount
|
|
37983
|
+
}),
|
|
37984
|
+
success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
|
|
37985
|
+
failure: (error) => ({ code: error.code })
|
|
36480
37986
|
}
|
|
36481
|
-
|
|
36482
|
-
srcTxHash: txResult.value.tx,
|
|
36483
|
-
data: txResult.value.relayData,
|
|
36484
|
-
chainKey: srcChainKey,
|
|
36485
|
-
relayerApiEndpoint: this.relayerApiEndpoint,
|
|
36486
|
-
timeout
|
|
36487
|
-
});
|
|
36488
|
-
if (!packet.ok)
|
|
36489
|
-
return {
|
|
36490
|
-
ok: false,
|
|
36491
|
-
error: mapRelayFailure(packet.error, {
|
|
36492
|
-
feature: "moneyMarket",
|
|
36493
|
-
action: baseCtx.action,
|
|
36494
|
-
srcChainKey: baseCtx.srcChainKey,
|
|
36495
|
-
dstChainKey: baseCtx.dstChainKey
|
|
36496
|
-
})
|
|
36497
|
-
};
|
|
36498
|
-
return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
|
|
36499
|
-
} catch (error) {
|
|
36500
|
-
if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
|
|
36501
|
-
return {
|
|
36502
|
-
ok: false,
|
|
36503
|
-
error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
|
|
36504
|
-
};
|
|
36505
|
-
}
|
|
37987
|
+
);
|
|
36506
37988
|
}
|
|
36507
37989
|
/**
|
|
36508
37990
|
* Build and optionally broadcast the spoke-side repay transaction without waiting for the
|
|
@@ -37203,50 +38685,67 @@ var PartnerFeeClaimService = class {
|
|
|
37203
38685
|
* unsigned raw transaction (`raw: true`). Returns an error on failure.
|
|
37204
38686
|
*/
|
|
37205
38687
|
async setSwapPreference(_params) {
|
|
37206
|
-
|
|
37207
|
-
|
|
37208
|
-
|
|
37209
|
-
|
|
37210
|
-
|
|
37211
|
-
|
|
37212
|
-
|
|
37213
|
-
|
|
37214
|
-
|
|
37215
|
-
|
|
37216
|
-
from: params.srcAddress,
|
|
37217
|
-
to: this.protocolIntentsContract,
|
|
37218
|
-
value: 0n,
|
|
37219
|
-
data: viem.encodeFunctionData({
|
|
37220
|
-
abi: ProtocolIntentsAbi,
|
|
37221
|
-
functionName: "setAutoSwapPreferences",
|
|
37222
|
-
args: [
|
|
38688
|
+
return this.config.analytics.trackResult(
|
|
38689
|
+
"partner",
|
|
38690
|
+
"setSwapPreference",
|
|
38691
|
+
async () => {
|
|
38692
|
+
const { params, walletProvider, raw } = _params;
|
|
38693
|
+
try {
|
|
38694
|
+
invariant(isHubChainKeyType(params.srcChainKey), "PartnerFeeClaimService only supports Sonic spoke provider");
|
|
38695
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
38696
|
+
const outputToken = params.dstChainKey !== this.hubProvider.chainConfig.chain.key ? this.hubProvider.config.getSpokeTokenFromOriginalAssetAddress(params.dstChainKey, params.outputToken)?.hubAsset : params.outputToken;
|
|
38697
|
+
invariant(
|
|
37223
38698
|
outputToken,
|
|
37224
|
-
|
|
37225
|
-
|
|
37226
|
-
|
|
37227
|
-
|
|
37228
|
-
|
|
37229
|
-
|
|
37230
|
-
|
|
37231
|
-
|
|
37232
|
-
|
|
37233
|
-
|
|
38699
|
+
`hub asset not found for spoke chain token (params.outputToken): ${params.outputToken} with chain key: ${params.dstChainKey}`
|
|
38700
|
+
);
|
|
38701
|
+
const rawTx = {
|
|
38702
|
+
from: params.srcAddress,
|
|
38703
|
+
to: this.protocolIntentsContract,
|
|
38704
|
+
value: 0n,
|
|
38705
|
+
data: viem.encodeFunctionData({
|
|
38706
|
+
abi: ProtocolIntentsAbi,
|
|
38707
|
+
functionName: "setAutoSwapPreferences",
|
|
38708
|
+
args: [
|
|
38709
|
+
outputToken,
|
|
38710
|
+
BigInt(getIntentRelayChainId(params.dstChainKey)),
|
|
38711
|
+
encodeAddress(params.dstChainKey, params.dstAddress)
|
|
38712
|
+
]
|
|
38713
|
+
})
|
|
38714
|
+
};
|
|
38715
|
+
if (raw) {
|
|
38716
|
+
return {
|
|
38717
|
+
ok: true,
|
|
38718
|
+
value: rawTx
|
|
38719
|
+
};
|
|
38720
|
+
}
|
|
38721
|
+
invariant(
|
|
38722
|
+
isEvmWalletProviderType(walletProvider),
|
|
38723
|
+
"PartnerFeeClaimService only supports Evm (sonic) wallet provider"
|
|
38724
|
+
);
|
|
38725
|
+
const txHash = await walletProvider.sendTransaction(rawTx);
|
|
38726
|
+
return {
|
|
38727
|
+
ok: true,
|
|
38728
|
+
value: txHash
|
|
38729
|
+
};
|
|
38730
|
+
} catch (error) {
|
|
38731
|
+
return {
|
|
38732
|
+
ok: false,
|
|
38733
|
+
error
|
|
38734
|
+
};
|
|
38735
|
+
}
|
|
38736
|
+
},
|
|
38737
|
+
{
|
|
38738
|
+
start: () => ({
|
|
38739
|
+
srcChainKey: _params.params.srcChainKey,
|
|
38740
|
+
srcAddress: _params.params.srcAddress,
|
|
38741
|
+
outputToken: _params.params.outputToken,
|
|
38742
|
+
dstChainKey: _params.params.dstChainKey,
|
|
38743
|
+
dstAddress: _params.params.dstAddress
|
|
38744
|
+
}),
|
|
38745
|
+
success: (value) => ({ txHash: value }),
|
|
38746
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
37234
38747
|
}
|
|
37235
|
-
|
|
37236
|
-
isEvmWalletProviderType(walletProvider),
|
|
37237
|
-
"PartnerFeeClaimService only supports Evm (sonic) wallet provider"
|
|
37238
|
-
);
|
|
37239
|
-
const txHash = await walletProvider.sendTransaction(rawTx);
|
|
37240
|
-
return {
|
|
37241
|
-
ok: true,
|
|
37242
|
-
value: txHash
|
|
37243
|
-
};
|
|
37244
|
-
} catch (error) {
|
|
37245
|
-
return {
|
|
37246
|
-
ok: false,
|
|
37247
|
-
error
|
|
37248
|
-
};
|
|
37249
|
-
}
|
|
38748
|
+
);
|
|
37250
38749
|
}
|
|
37251
38750
|
/**
|
|
37252
38751
|
* Checks whether a hub-chain ERC-20 token is already approved for the ProtocolIntents contract.
|
|
@@ -37358,6 +38857,11 @@ var PartnerFeeClaimService = class {
|
|
|
37358
38857
|
* This is the low-level building block. Use `swap` for the full flow that also waits for
|
|
37359
38858
|
* the solver to execute the intent.
|
|
37360
38859
|
*
|
|
38860
|
+
* Guards against same-token intents: if the configured output token equals `fromToken` the solver
|
|
38861
|
+
* cannot fill the swap, so the call is rejected with `VALIDATION_FAILED` before any transaction is
|
|
38862
|
+
* built. The guard fails closed — if the preference lookup fails the call returns that error rather
|
|
38863
|
+
* than submitting an intent that may become unfillable.
|
|
38864
|
+
*
|
|
37361
38865
|
* @param _params - Action descriptor containing:
|
|
37362
38866
|
* - `params.srcChainKey` — must be the hub chain key (Sonic).
|
|
37363
38867
|
* - `params.srcAddress` — partner's EVM address; also used as the intent creator.
|
|
@@ -37381,6 +38885,25 @@ var PartnerFeeClaimService = class {
|
|
|
37381
38885
|
this.config.solver.protocolIntentsContract,
|
|
37382
38886
|
"protocolIntentsContract is not configured in solver config"
|
|
37383
38887
|
);
|
|
38888
|
+
const prefs = await this.getAutoSwapPreferences(params.srcAddress);
|
|
38889
|
+
if (!prefs.ok) return prefs;
|
|
38890
|
+
if (prefs.value.outputToken.toLowerCase() === params.fromToken.toLowerCase()) {
|
|
38891
|
+
return {
|
|
38892
|
+
ok: false,
|
|
38893
|
+
error: new SodaxError(
|
|
38894
|
+
"VALIDATION_FAILED",
|
|
38895
|
+
"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.",
|
|
38896
|
+
{
|
|
38897
|
+
feature: "partner",
|
|
38898
|
+
context: {
|
|
38899
|
+
action: "createIntentAutoSwap",
|
|
38900
|
+
fromToken: params.fromToken,
|
|
38901
|
+
outputToken: prefs.value.outputToken
|
|
38902
|
+
}
|
|
38903
|
+
}
|
|
38904
|
+
)
|
|
38905
|
+
};
|
|
38906
|
+
}
|
|
37384
38907
|
const minOutputAmount = 0n;
|
|
37385
38908
|
const rawTx = {
|
|
37386
38909
|
from: params.srcAddress,
|
|
@@ -37428,47 +38951,218 @@ var PartnerFeeClaimService = class {
|
|
|
37428
38951
|
*
|
|
37429
38952
|
* On failure the `error` is tagged:
|
|
37430
38953
|
* - `WAIT_INTENT_AUTO_SWAP_FAILED` — transaction was submitted but receipt polling failed.
|
|
37431
|
-
* - Error from `createIntentAutoSwap` — if the initial submission failed
|
|
38954
|
+
* - Error from `createIntentAutoSwap` — if the initial submission failed, including
|
|
38955
|
+
* `VALIDATION_FAILED` when the output token equals the fee token (same-token guard) or the
|
|
38956
|
+
* preference lookup that backs the guard fails.
|
|
37432
38957
|
* - Error from `SolverApiService.postExecution` — if the solver notification failed.
|
|
37433
38958
|
*/
|
|
37434
38959
|
async swap(_params) {
|
|
37435
|
-
|
|
37436
|
-
|
|
37437
|
-
|
|
37438
|
-
|
|
38960
|
+
return this.config.analytics.trackResult(
|
|
38961
|
+
"partner",
|
|
38962
|
+
"swap",
|
|
38963
|
+
async () => {
|
|
38964
|
+
try {
|
|
38965
|
+
const txHash = await this.createIntentAutoSwap(_params);
|
|
38966
|
+
if (!txHash.ok) {
|
|
38967
|
+
return txHash;
|
|
38968
|
+
}
|
|
38969
|
+
let intentTxHash;
|
|
38970
|
+
try {
|
|
38971
|
+
const receipt = await this.hubProvider.publicClient.waitForTransactionReceipt({ hash: txHash.value });
|
|
38972
|
+
intentTxHash = receipt.transactionHash;
|
|
38973
|
+
} catch (error) {
|
|
38974
|
+
return {
|
|
38975
|
+
ok: false,
|
|
38976
|
+
error: new SodaxError(
|
|
38977
|
+
"EXECUTION_FAILED",
|
|
38978
|
+
error instanceof Error ? error.message : "waitIntentAutoSwap failed",
|
|
38979
|
+
{ feature: "partner", cause: error, context: { action: "waitAutoSwap", phase: "execution" } }
|
|
38980
|
+
)
|
|
38981
|
+
};
|
|
38982
|
+
}
|
|
38983
|
+
const solverExecutionResponse = await SolverApiService.postExecution(
|
|
38984
|
+
{ intent_tx_hash: intentTxHash },
|
|
38985
|
+
this.config.solver,
|
|
38986
|
+
this.config.logger
|
|
38987
|
+
);
|
|
38988
|
+
if (!solverExecutionResponse.ok) {
|
|
38989
|
+
return solverExecutionResponse;
|
|
38990
|
+
}
|
|
38991
|
+
return {
|
|
38992
|
+
ok: true,
|
|
38993
|
+
value: {
|
|
38994
|
+
srcTxHash: txHash.value,
|
|
38995
|
+
solverExecutionResponse: solverExecutionResponse.value,
|
|
38996
|
+
intentTxHash
|
|
38997
|
+
}
|
|
38998
|
+
};
|
|
38999
|
+
} catch (error) {
|
|
39000
|
+
return { ok: false, error };
|
|
39001
|
+
}
|
|
39002
|
+
},
|
|
39003
|
+
{
|
|
39004
|
+
start: () => ({
|
|
39005
|
+
srcChainKey: _params.params.srcChainKey,
|
|
39006
|
+
srcAddress: _params.params.srcAddress,
|
|
39007
|
+
fromToken: _params.params.fromToken,
|
|
39008
|
+
amount: _params.params.amount
|
|
39009
|
+
}),
|
|
39010
|
+
success: (value) => ({
|
|
39011
|
+
srcTxHash: value.srcTxHash,
|
|
39012
|
+
intentTxHash: value.intentTxHash
|
|
39013
|
+
}),
|
|
39014
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
37439
39015
|
}
|
|
37440
|
-
|
|
37441
|
-
|
|
37442
|
-
|
|
37443
|
-
|
|
37444
|
-
|
|
39016
|
+
);
|
|
39017
|
+
}
|
|
39018
|
+
/**
|
|
39019
|
+
* Cancels a partner fee-claim auto-swap intent and refunds the input token to the partner.
|
|
39020
|
+
*
|
|
39021
|
+
* This targets the ProtocolIntents contract's own `cancelIntent(fromToken, toToken)`, which is
|
|
39022
|
+
* the only authorized cancel path for partner auto-swap intents: the intent's `creator` is the
|
|
39023
|
+
* ProtocolIntents contract (not the partner), so the generic `SwapService.cancelIntent` reverts
|
|
39024
|
+
* with `Unauthorized()`. ProtocolIntents looks up the caller's intent for the token pair, cancels
|
|
39025
|
+
* it in the main intents contract (as the creator), and transfers the locked `inputAmount` back
|
|
39026
|
+
* to the partner (`msg.sender`).
|
|
39027
|
+
*
|
|
39028
|
+
* Use this to recover funds stuck in an unfillable intent — most commonly a same-token claim
|
|
39029
|
+
* (`fromToken === toToken`) the solver refused to fill (see the guard in {@link swap}).
|
|
39030
|
+
*
|
|
39031
|
+
* @param _params - Action descriptor containing:
|
|
39032
|
+
* - `params.srcChainKey` — must be the hub chain key (Sonic).
|
|
39033
|
+
* - `params.srcAddress` — the partner's EVM address; must match the intent's owner.
|
|
39034
|
+
* - `params.fromToken` — the stuck intent's input (fee) token, hub-chain address.
|
|
39035
|
+
* - `params.toToken` — the stuck intent's output token, hub-chain address.
|
|
39036
|
+
* - `raw` — when `true`, returns the unsigned transaction object instead of submitting it.
|
|
39037
|
+
* - `walletProvider` — required when `raw` is `false`; must be an EVM wallet provider.
|
|
39038
|
+
* @returns A `Result` containing the submitted transaction hash (`raw: false`) or the unsigned
|
|
39039
|
+
* raw transaction (`raw: true`).
|
|
39040
|
+
*/
|
|
39041
|
+
async cancelIntent(_params) {
|
|
39042
|
+
return this.config.analytics.trackResult(
|
|
39043
|
+
"partner",
|
|
39044
|
+
"cancelIntent",
|
|
39045
|
+
async () => {
|
|
39046
|
+
const { params } = _params;
|
|
39047
|
+
try {
|
|
39048
|
+
invariant(isHubChainKeyType(params.srcChainKey), "PartnerFeeClaimService only supports Hub srcChainKey");
|
|
39049
|
+
invariant(
|
|
39050
|
+
isOptionalEvmWalletProviderType(_params.walletProvider),
|
|
39051
|
+
"PartnerFeeClaimService only supports Evm wallet provider"
|
|
39052
|
+
);
|
|
39053
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
39054
|
+
const rawTx = {
|
|
39055
|
+
from: params.srcAddress,
|
|
39056
|
+
to: this.protocolIntentsContract,
|
|
39057
|
+
value: 0n,
|
|
39058
|
+
data: viem.encodeFunctionData({
|
|
39059
|
+
abi: ProtocolIntentsAbi,
|
|
39060
|
+
functionName: "cancelIntent",
|
|
39061
|
+
args: [params.fromToken, params.toToken]
|
|
39062
|
+
})
|
|
39063
|
+
};
|
|
39064
|
+
if (_params.raw) {
|
|
39065
|
+
return {
|
|
39066
|
+
ok: true,
|
|
39067
|
+
value: rawTx
|
|
39068
|
+
};
|
|
39069
|
+
}
|
|
39070
|
+
const txHash = await _params.walletProvider.sendTransaction(rawTx);
|
|
39071
|
+
return {
|
|
39072
|
+
ok: true,
|
|
39073
|
+
value: txHash
|
|
39074
|
+
};
|
|
39075
|
+
} catch (error) {
|
|
39076
|
+
return { ok: false, error };
|
|
39077
|
+
}
|
|
39078
|
+
},
|
|
39079
|
+
{
|
|
39080
|
+
start: () => ({
|
|
39081
|
+
srcChainKey: _params.params.srcChainKey,
|
|
39082
|
+
srcAddress: _params.params.srcAddress,
|
|
39083
|
+
fromToken: _params.params.fromToken,
|
|
39084
|
+
toToken: _params.params.toToken
|
|
39085
|
+
}),
|
|
39086
|
+
success: (value) => ({ txHash: value }),
|
|
39087
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
39088
|
+
}
|
|
39089
|
+
);
|
|
39090
|
+
}
|
|
39091
|
+
/**
|
|
39092
|
+
* Returns the stored intent hash for a partner's `(user, fromToken, toToken)` token pair.
|
|
39093
|
+
*
|
|
39094
|
+
* A non-zero hash means an auto-swap intent currently exists for that pair (e.g. an unfilled
|
|
39095
|
+
* same-token claim) and can be cancelled via {@link cancelIntent}. A zero hash
|
|
39096
|
+
* (`0x000…0`) means there is no open intent for the pair.
|
|
39097
|
+
*
|
|
39098
|
+
* @param params.user - The partner's EVM address on Sonic.
|
|
39099
|
+
* @param params.fromToken - Input (fee) token, hub-chain address.
|
|
39100
|
+
* @param params.toToken - Output token, hub-chain address.
|
|
39101
|
+
* @returns A `Result` containing the intent hash, or an `Error` tagged `LOOKUP_FAILED`.
|
|
39102
|
+
*/
|
|
39103
|
+
async getUserIntent({ user, fromToken, toToken }) {
|
|
39104
|
+
try {
|
|
39105
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
39106
|
+
const intentHash = await this.hubProvider.publicClient.readContract({
|
|
39107
|
+
address: this.protocolIntentsContract,
|
|
39108
|
+
abi: ProtocolIntentsAbi,
|
|
39109
|
+
functionName: "getUserIntent",
|
|
39110
|
+
args: [user, fromToken, toToken]
|
|
39111
|
+
});
|
|
39112
|
+
return { ok: true, value: intentHash };
|
|
39113
|
+
} catch (error) {
|
|
39114
|
+
return { ok: false, error: lookupFailed("partner", "getUserIntent", error) };
|
|
39115
|
+
}
|
|
39116
|
+
}
|
|
39117
|
+
/**
|
|
39118
|
+
* Reads the full {@link Intent} details for a stored intent hash from the ProtocolIntents contract.
|
|
39119
|
+
*
|
|
39120
|
+
* Useful for displaying a stuck intent before cancelling it — e.g. the locked `inputAmount` and
|
|
39121
|
+
* `inputToken`. Pair with {@link getUserIntent} to resolve the hash from a token pair.
|
|
39122
|
+
*
|
|
39123
|
+
* @param intentHash - The intent hash (from {@link getUserIntent}).
|
|
39124
|
+
* @returns A `Result` containing the `Intent`, or an `Error` tagged `LOOKUP_FAILED`.
|
|
39125
|
+
*/
|
|
39126
|
+
async getIntentDetails(intentHash) {
|
|
39127
|
+
try {
|
|
39128
|
+
invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
|
|
39129
|
+
const intent = await this.hubProvider.publicClient.readContract({
|
|
39130
|
+
address: this.protocolIntentsContract,
|
|
39131
|
+
abi: ProtocolIntentsAbi,
|
|
39132
|
+
functionName: "getIntentDetails",
|
|
39133
|
+
args: [intentHash]
|
|
39134
|
+
});
|
|
39135
|
+
if (!this.config.isValidIntentRelayChainId(intent.srcChain) || !this.config.isValidIntentRelayChainId(intent.dstChain)) {
|
|
37445
39136
|
return {
|
|
37446
39137
|
ok: false,
|
|
37447
|
-
error:
|
|
37448
|
-
"
|
|
37449
|
-
|
|
37450
|
-
|
|
39138
|
+
error: lookupFailed(
|
|
39139
|
+
"partner",
|
|
39140
|
+
"getIntentDetails",
|
|
39141
|
+
new Error(`Invalid intent relay chain id: ${intent.srcChain} or ${intent.dstChain}`)
|
|
37451
39142
|
)
|
|
37452
39143
|
};
|
|
37453
39144
|
}
|
|
37454
|
-
const solverExecutionResponse = await SolverApiService.postExecution(
|
|
37455
|
-
{ intent_tx_hash: intentTxHash },
|
|
37456
|
-
this.config.solver,
|
|
37457
|
-
this.config.logger
|
|
37458
|
-
);
|
|
37459
|
-
if (!solverExecutionResponse.ok) {
|
|
37460
|
-
return solverExecutionResponse;
|
|
37461
|
-
}
|
|
37462
39145
|
return {
|
|
37463
39146
|
ok: true,
|
|
37464
39147
|
value: {
|
|
37465
|
-
|
|
37466
|
-
|
|
37467
|
-
|
|
39148
|
+
intentId: intent.intentId,
|
|
39149
|
+
creator: intent.creator,
|
|
39150
|
+
inputToken: intent.inputToken,
|
|
39151
|
+
outputToken: intent.outputToken,
|
|
39152
|
+
inputAmount: intent.inputAmount,
|
|
39153
|
+
minOutputAmount: intent.minOutputAmount,
|
|
39154
|
+
deadline: intent.deadline,
|
|
39155
|
+
allowPartialFill: intent.allowPartialFill,
|
|
39156
|
+
srcChain: intent.srcChain,
|
|
39157
|
+
dstChain: intent.dstChain,
|
|
39158
|
+
srcAddress: intent.srcAddress,
|
|
39159
|
+
dstAddress: intent.dstAddress,
|
|
39160
|
+
solver: intent.solver,
|
|
39161
|
+
data: intent.data
|
|
37468
39162
|
}
|
|
37469
39163
|
};
|
|
37470
39164
|
} catch (error) {
|
|
37471
|
-
return { ok: false, error };
|
|
39165
|
+
return { ok: false, error: lookupFailed("partner", "getIntentDetails", error) };
|
|
37472
39166
|
}
|
|
37473
39167
|
}
|
|
37474
39168
|
};
|
|
@@ -37603,42 +39297,62 @@ var RecoveryService = class {
|
|
|
37603
39297
|
* transaction object when `raw: true`, or the broadcast transaction hash when `raw: false`.
|
|
37604
39298
|
*/
|
|
37605
39299
|
async withdrawHubAsset(_params) {
|
|
37606
|
-
|
|
37607
|
-
|
|
37608
|
-
|
|
37609
|
-
|
|
37610
|
-
{
|
|
37611
|
-
|
|
37612
|
-
|
|
37613
|
-
|
|
37614
|
-
|
|
37615
|
-
|
|
37616
|
-
|
|
37617
|
-
|
|
37618
|
-
|
|
37619
|
-
|
|
37620
|
-
|
|
37621
|
-
|
|
37622
|
-
|
|
37623
|
-
|
|
37624
|
-
|
|
37625
|
-
|
|
37626
|
-
|
|
37627
|
-
|
|
37628
|
-
|
|
37629
|
-
|
|
37630
|
-
|
|
37631
|
-
|
|
37632
|
-
|
|
37633
|
-
|
|
37634
|
-
|
|
37635
|
-
|
|
37636
|
-
|
|
37637
|
-
|
|
37638
|
-
|
|
37639
|
-
|
|
37640
|
-
|
|
37641
|
-
|
|
39300
|
+
return this.config.analytics.trackResult(
|
|
39301
|
+
"recovery",
|
|
39302
|
+
"withdrawHubAsset",
|
|
39303
|
+
async () => {
|
|
39304
|
+
const { params } = _params;
|
|
39305
|
+
try {
|
|
39306
|
+
const hubWallet = await this.hubProvider.getUserHubWalletAddress(params.srcAddress, params.srcChainKey);
|
|
39307
|
+
const payload = EvmAssetManagerService.withdrawAssetData(
|
|
39308
|
+
{
|
|
39309
|
+
token: params.token,
|
|
39310
|
+
to: encodeAddress(params.srcChainKey, params.srcAddress),
|
|
39311
|
+
amount: params.amount
|
|
39312
|
+
},
|
|
39313
|
+
this.hubProvider,
|
|
39314
|
+
params.srcChainKey
|
|
39315
|
+
);
|
|
39316
|
+
const coreParams = {
|
|
39317
|
+
srcChainKey: params.srcChainKey,
|
|
39318
|
+
srcAddress: params.srcAddress,
|
|
39319
|
+
dstChainKey: this.hubProvider.chainConfig.chain.key,
|
|
39320
|
+
dstAddress: hubWallet,
|
|
39321
|
+
payload
|
|
39322
|
+
};
|
|
39323
|
+
const sendMessageParams = _params.raw ? { ...coreParams, raw: true } : {
|
|
39324
|
+
...coreParams,
|
|
39325
|
+
raw: false,
|
|
39326
|
+
walletProvider: _params.walletProvider
|
|
39327
|
+
};
|
|
39328
|
+
const txResult = await this.spoke.sendMessage(sendMessageParams);
|
|
39329
|
+
if (!txResult.ok) return txResult;
|
|
39330
|
+
return {
|
|
39331
|
+
ok: true,
|
|
39332
|
+
value: txResult.value
|
|
39333
|
+
};
|
|
39334
|
+
} catch (error) {
|
|
39335
|
+
return {
|
|
39336
|
+
ok: false,
|
|
39337
|
+
error: new SodaxError(
|
|
39338
|
+
"EXECUTION_FAILED",
|
|
39339
|
+
error instanceof Error ? error.message : "withdrawHubAsset failed",
|
|
39340
|
+
{ feature: "recovery", cause: error, context: { action: "withdrawHubAsset", phase: "execution" } }
|
|
39341
|
+
)
|
|
39342
|
+
};
|
|
39343
|
+
}
|
|
39344
|
+
},
|
|
39345
|
+
{
|
|
39346
|
+
start: () => ({
|
|
39347
|
+
srcChainKey: _params.params.srcChainKey,
|
|
39348
|
+
srcAddress: _params.params.srcAddress,
|
|
39349
|
+
token: _params.params.token,
|
|
39350
|
+
amount: _params.params.amount
|
|
39351
|
+
}),
|
|
39352
|
+
success: (value) => ({ txHash: typeof value === "string" ? value : void 0 }),
|
|
39353
|
+
failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
|
|
39354
|
+
}
|
|
39355
|
+
);
|
|
37642
39356
|
}
|
|
37643
39357
|
};
|
|
37644
39358
|
|
|
@@ -37740,7 +39454,7 @@ var LeverageYieldService = class {
|
|
|
37740
39454
|
}
|
|
37741
39455
|
/** Looks up a vault by its `name` field. Returns `undefined` when not registered. */
|
|
37742
39456
|
getVault(name) {
|
|
37743
|
-
return this.listVaults().find((
|
|
39457
|
+
return this.listVaults().find((v6) => v6.name === name);
|
|
37744
39458
|
}
|
|
37745
39459
|
/**
|
|
37746
39460
|
* Looks up a registered vault by its on-chain proxy address (case-insensitive).
|
|
@@ -37748,7 +39462,7 @@ var LeverageYieldService = class {
|
|
|
37748
39462
|
*/
|
|
37749
39463
|
getVaultByAddress(address) {
|
|
37750
39464
|
const normalized = address.toLowerCase();
|
|
37751
|
-
return this.listVaults().find((
|
|
39465
|
+
return this.listVaults().find((v6) => v6.vault.toLowerCase() === normalized);
|
|
37752
39466
|
}
|
|
37753
39467
|
/**
|
|
37754
39468
|
* Resolves the intent `deadline`: returns the caller-supplied value verbatim, otherwise
|
|
@@ -38098,70 +39812,93 @@ var LeverageYieldService = class {
|
|
|
38098
39812
|
const { params } = _params;
|
|
38099
39813
|
const srcChainKey = params.srcChainKey;
|
|
38100
39814
|
const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "vaultSwap" };
|
|
38101
|
-
|
|
38102
|
-
|
|
38103
|
-
|
|
38104
|
-
|
|
38105
|
-
|
|
38106
|
-
|
|
38107
|
-
|
|
38108
|
-
|
|
38109
|
-
|
|
38110
|
-
|
|
38111
|
-
|
|
38112
|
-
|
|
38113
|
-
|
|
38114
|
-
|
|
38115
|
-
|
|
38116
|
-
|
|
38117
|
-
|
|
38118
|
-
|
|
38119
|
-
|
|
38120
|
-
|
|
38121
|
-
|
|
38122
|
-
|
|
38123
|
-
|
|
38124
|
-
|
|
38125
|
-
|
|
38126
|
-
|
|
38127
|
-
|
|
38128
|
-
|
|
38129
|
-
|
|
39815
|
+
return this.config.analytics.trackResult(
|
|
39816
|
+
"leverageYield",
|
|
39817
|
+
"vaultSwap",
|
|
39818
|
+
async () => {
|
|
39819
|
+
try {
|
|
39820
|
+
const timeout = _params.timeout;
|
|
39821
|
+
const createIntentResult = await this.createVaultIntent(_params);
|
|
39822
|
+
if (!createIntentResult.ok) {
|
|
39823
|
+
return { ok: false, error: createIntentResult.error };
|
|
39824
|
+
}
|
|
39825
|
+
const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
|
|
39826
|
+
const verifyTxHashResult = await this.spoke.verifyTxHash({
|
|
39827
|
+
txHash: spokeTxHash,
|
|
39828
|
+
chainKey: srcChainKey
|
|
39829
|
+
});
|
|
39830
|
+
if (!verifyTxHashResult.ok) {
|
|
39831
|
+
return {
|
|
39832
|
+
ok: false,
|
|
39833
|
+
error: verifyFailed("leverageYield", verifyTxHashResult.error, baseCtx)
|
|
39834
|
+
};
|
|
39835
|
+
}
|
|
39836
|
+
let dstIntentTxHash;
|
|
39837
|
+
if (isHubChainKeyType(srcChainKey)) {
|
|
39838
|
+
dstIntentTxHash = spokeTxHash;
|
|
39839
|
+
} else {
|
|
39840
|
+
const packet = await relayTxAndWaitPacket({
|
|
39841
|
+
srcTxHash: spokeTxHash,
|
|
39842
|
+
data: relayData,
|
|
39843
|
+
chainKey: srcChainKey,
|
|
39844
|
+
relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
|
|
39845
|
+
timeout
|
|
39846
|
+
});
|
|
39847
|
+
if (!packet.ok) {
|
|
39848
|
+
return {
|
|
39849
|
+
ok: false,
|
|
39850
|
+
error: mapRelayFailure(packet.error, { feature: "leverageYield", ...baseCtx })
|
|
39851
|
+
};
|
|
39852
|
+
}
|
|
39853
|
+
dstIntentTxHash = packet.value.dst_tx_hash;
|
|
39854
|
+
}
|
|
39855
|
+
const postExecResult = await this.notifySolver({
|
|
39856
|
+
intent_tx_hash: dstIntentTxHash
|
|
39857
|
+
});
|
|
39858
|
+
if (!postExecResult.ok) {
|
|
39859
|
+
return { ok: false, error: postExecResult.error };
|
|
39860
|
+
}
|
|
39861
|
+
return {
|
|
39862
|
+
ok: true,
|
|
39863
|
+
value: {
|
|
39864
|
+
solverExecutionResponse: postExecResult.value,
|
|
39865
|
+
intent,
|
|
39866
|
+
intentDeliveryInfo: {
|
|
39867
|
+
srcChainKey,
|
|
39868
|
+
srcTxHash: spokeTxHash,
|
|
39869
|
+
srcAddress: params.srcAddress,
|
|
39870
|
+
dstChainKey: params.dstChainKey,
|
|
39871
|
+
dstTxHash: dstIntentTxHash,
|
|
39872
|
+
dstAddress: params.dstAddress
|
|
39873
|
+
}
|
|
39874
|
+
}
|
|
39875
|
+
};
|
|
39876
|
+
} catch (error) {
|
|
39877
|
+
if (isLeverageYieldSwapError(error)) return { ok: false, error };
|
|
38130
39878
|
return {
|
|
38131
39879
|
ok: false,
|
|
38132
|
-
error:
|
|
39880
|
+
error: unknownFailed("leverageYield", error, baseCtx)
|
|
38133
39881
|
};
|
|
38134
39882
|
}
|
|
38135
|
-
|
|
38136
|
-
|
|
38137
|
-
|
|
38138
|
-
|
|
38139
|
-
|
|
38140
|
-
|
|
38141
|
-
|
|
39883
|
+
},
|
|
39884
|
+
{
|
|
39885
|
+
start: () => ({
|
|
39886
|
+
srcChainKey: _params.params.srcChainKey,
|
|
39887
|
+
dstChainKey: _params.params.dstChainKey,
|
|
39888
|
+
srcAddress: _params.params.srcAddress,
|
|
39889
|
+
dstAddress: _params.params.dstAddress,
|
|
39890
|
+
inputToken: _params.params.inputToken,
|
|
39891
|
+
outputToken: _params.params.outputToken,
|
|
39892
|
+
inputAmount: _params.params.inputAmount
|
|
39893
|
+
}),
|
|
39894
|
+
success: (value) => ({
|
|
39895
|
+
intentId: value.intent.intentId,
|
|
39896
|
+
srcTxHash: value.intentDeliveryInfo.srcTxHash,
|
|
39897
|
+
dstTxHash: value.intentDeliveryInfo.dstTxHash
|
|
39898
|
+
}),
|
|
39899
|
+
failure: (error) => ({ code: error.code })
|
|
38142
39900
|
}
|
|
38143
|
-
|
|
38144
|
-
ok: true,
|
|
38145
|
-
value: {
|
|
38146
|
-
solverExecutionResponse: postExecResult.value,
|
|
38147
|
-
intent,
|
|
38148
|
-
intentDeliveryInfo: {
|
|
38149
|
-
srcChainKey,
|
|
38150
|
-
srcTxHash: spokeTxHash,
|
|
38151
|
-
srcAddress: params.srcAddress,
|
|
38152
|
-
dstChainKey: params.dstChainKey,
|
|
38153
|
-
dstTxHash: dstIntentTxHash,
|
|
38154
|
-
dstAddress: params.dstAddress
|
|
38155
|
-
}
|
|
38156
|
-
}
|
|
38157
|
-
};
|
|
38158
|
-
} catch (error) {
|
|
38159
|
-
if (isLeverageYieldSwapError(error)) return { ok: false, error };
|
|
38160
|
-
return {
|
|
38161
|
-
ok: false,
|
|
38162
|
-
error: unknownFailed("leverageYield", error, baseCtx)
|
|
38163
|
-
};
|
|
38164
|
-
}
|
|
39901
|
+
);
|
|
38165
39902
|
}
|
|
38166
39903
|
/**
|
|
38167
39904
|
* Notifies the solver that the vault intent landed on the hub, triggering it to fill.
|
|
@@ -38518,6 +40255,8 @@ var Sodax = class {
|
|
|
38518
40255
|
// ICX migration service enabling ICX migration to SODA
|
|
38519
40256
|
backendApi;
|
|
38520
40257
|
// backend API service enabling backend API endpoints
|
|
40258
|
+
api;
|
|
40259
|
+
// syntactic sugar for backend API service
|
|
38521
40260
|
bridge;
|
|
38522
40261
|
// Bridge service enabling cross-chain transfers
|
|
38523
40262
|
staking;
|
|
@@ -38538,14 +40277,18 @@ var Sodax = class {
|
|
|
38538
40277
|
// spoke service enabling spoke chain operations
|
|
38539
40278
|
constructor(options) {
|
|
38540
40279
|
const logger = resolveLogger(options?.logger);
|
|
40280
|
+
const analytics = resolveAnalytics(options?.analytics);
|
|
38541
40281
|
const fee = options?.fee;
|
|
40282
|
+
const useBackendSubmitTx = options?.swapsOptions?.useBackendSubmitTx ?? false;
|
|
38542
40283
|
this.instanceConfig = options ? mergeSodaxConfig(sodaxConfig, options) : sodaxConfig;
|
|
38543
40284
|
this.backendApi = new BackendApiService(this.instanceConfig.api, logger);
|
|
40285
|
+
this.api = this.backendApi;
|
|
38544
40286
|
this.config = new ConfigService({
|
|
38545
40287
|
api: this.backendApi,
|
|
38546
40288
|
config: this.instanceConfig,
|
|
38547
40289
|
userConfig: options,
|
|
38548
40290
|
logger,
|
|
40291
|
+
analytics,
|
|
38549
40292
|
fee
|
|
38550
40293
|
});
|
|
38551
40294
|
this.hubProvider = new EvmHubProvider({ config: this.config });
|
|
@@ -38553,7 +40296,9 @@ var Sodax = class {
|
|
|
38553
40296
|
this.swaps = new SwapService({
|
|
38554
40297
|
config: this.config,
|
|
38555
40298
|
hubProvider: this.hubProvider,
|
|
38556
|
-
spoke: this.spoke
|
|
40299
|
+
spoke: this.spoke,
|
|
40300
|
+
backendApi: this.backendApi,
|
|
40301
|
+
useBackendSubmitTx
|
|
38557
40302
|
});
|
|
38558
40303
|
this.moneyMarket = new MoneyMarketService({
|
|
38559
40304
|
config: this.config,
|
|
@@ -38753,6 +40498,7 @@ exports.StellarSpokeService = StellarSpokeService;
|
|
|
38753
40498
|
exports.SuiSpokeService = SuiSpokeService;
|
|
38754
40499
|
exports.SupportedMigrationTokens = SupportedMigrationTokens;
|
|
38755
40500
|
exports.SwapService = SwapService;
|
|
40501
|
+
exports.SwapsApiService = SwapsApiService;
|
|
38756
40502
|
exports.USD_DECIMALS = USD_DECIMALS;
|
|
38757
40503
|
exports.UiPoolDataProviderService = UiPoolDataProviderService;
|
|
38758
40504
|
exports.VAULT_TOKEN_DECIMALS = VAULT_TOKEN_DECIMALS;
|
|
@@ -38953,8 +40699,6 @@ exports.isStakingOrchestrationError = isStakingOrchestrationError;
|
|
|
38953
40699
|
exports.isStellarChainKey = isStellarChainKey;
|
|
38954
40700
|
exports.isStellarChainKeyType = isStellarChainKeyType;
|
|
38955
40701
|
exports.isStellarWalletProviderType = isStellarWalletProviderType;
|
|
38956
|
-
exports.isSubmitSwapTxResponse = isSubmitSwapTxResponse;
|
|
38957
|
-
exports.isSubmitSwapTxStatusResponse = isSubmitSwapTxStatusResponse;
|
|
38958
40702
|
exports.isSuiChainKey = isSuiChainKey;
|
|
38959
40703
|
exports.isSuiChainKeyType = isSuiChainKeyType;
|
|
38960
40704
|
exports.isSupportedBitcoinAddressType = isSupportedBitcoinAddressType;
|
|
@@ -38983,6 +40727,7 @@ exports.moneyMarketSupportedTokens = moneyMarketSupportedTokens;
|
|
|
38983
40727
|
exports.nativeToUSD = nativeToUSD;
|
|
38984
40728
|
exports.nearSupportedTokens = nearSupportedTokens;
|
|
38985
40729
|
exports.newbnUSDSpokeChainIds = newbnUSDSpokeChainIds;
|
|
40730
|
+
exports.noopAnalytics = noopAnalytics;
|
|
38986
40731
|
exports.normalize = normalize;
|
|
38987
40732
|
exports.normalizeBN = normalizeBN;
|
|
38988
40733
|
exports.normalizePsbtToBase64 = normalizePsbtToBase64;
|
|
@@ -39011,6 +40756,7 @@ exports.relayTxAndWaitPacket = relayTxAndWaitPacket;
|
|
|
39011
40756
|
exports.requestAddress = requestAddress;
|
|
39012
40757
|
exports.requestJsonRpc = requestJsonRpc;
|
|
39013
40758
|
exports.requestSigning = requestSigning;
|
|
40759
|
+
exports.resolveAnalytics = resolveAnalytics;
|
|
39014
40760
|
exports.resolveLogger = resolveLogger;
|
|
39015
40761
|
exports.retry = retry;
|
|
39016
40762
|
exports.reverseEncodeAddress = reverseEncodeAddress;
|