@sodax/sdk 2.0.0-rc.16 → 2.0.0-rc.18

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.mjs CHANGED
@@ -2613,6 +2613,8 @@ var RelayChainIdMap = {
2613
2613
  };
2614
2614
  var INTENT_CHAIN_IDS = Object.values(RelayChainIdMap);
2615
2615
  var IntentRelayChainIdToChainKey = Object.fromEntries(Object.entries(RelayChainIdMap).map(([chainKey, chainId]) => [chainId, chainKey]));
2616
+ var CHAIN_LOGO_BASE_URL = "https://raw.githubusercontent.com/icon-project/sodax-sdks/main/packages/assets/chain";
2617
+ var chainLogo = (key) => `${CHAIN_LOGO_BASE_URL}/${key}.png`;
2616
2618
  var baseChainInfo = {
2617
2619
  [ChainKeys.SONIC_MAINNET]: {
2618
2620
  name: "Sonic",
@@ -2620,6 +2622,7 @@ var baseChainInfo = {
2620
2622
  type: "EVM",
2621
2623
  chainId: 146,
2622
2624
  mainnet: true,
2625
+ logo: chainLogo(ChainKeys.SONIC_MAINNET),
2623
2626
  explorer: {
2624
2627
  baseUrl: "https://sonicscan.org/",
2625
2628
  txUrl: "https://sonicscan.org/tx/",
@@ -2633,6 +2636,7 @@ var baseChainInfo = {
2633
2636
  type: "SOLANA",
2634
2637
  chainId: "solana",
2635
2638
  mainnet: true,
2639
+ logo: chainLogo(ChainKeys.SOLANA_MAINNET),
2636
2640
  explorer: {
2637
2641
  baseUrl: "https://solscan.io/",
2638
2642
  txUrl: "https://solscan.io/tx/",
@@ -2646,6 +2650,7 @@ var baseChainInfo = {
2646
2650
  type: "EVM",
2647
2651
  chainId: 43114,
2648
2652
  mainnet: true,
2653
+ logo: chainLogo(ChainKeys.AVALANCHE_MAINNET),
2649
2654
  explorer: {
2650
2655
  baseUrl: "https://snowtrace.io/",
2651
2656
  txUrl: "https://snowtrace.io/tx/",
@@ -2659,6 +2664,7 @@ var baseChainInfo = {
2659
2664
  type: "EVM",
2660
2665
  chainId: 42161,
2661
2666
  mainnet: true,
2667
+ logo: chainLogo(ChainKeys.ARBITRUM_MAINNET),
2662
2668
  explorer: {
2663
2669
  baseUrl: "https://arbiscan.io/",
2664
2670
  txUrl: "https://arbiscan.io/tx/",
@@ -2672,6 +2678,7 @@ var baseChainInfo = {
2672
2678
  type: "EVM",
2673
2679
  chainId: 8453,
2674
2680
  mainnet: true,
2681
+ logo: chainLogo(ChainKeys.BASE_MAINNET),
2675
2682
  explorer: {
2676
2683
  baseUrl: "https://basescan.org/",
2677
2684
  txUrl: "https://basescan.org/tx/",
@@ -2685,6 +2692,7 @@ var baseChainInfo = {
2685
2692
  type: "EVM",
2686
2693
  chainId: 10,
2687
2694
  mainnet: true,
2695
+ logo: chainLogo(ChainKeys.OPTIMISM_MAINNET),
2688
2696
  explorer: {
2689
2697
  baseUrl: "https://optimistic.etherscan.io/",
2690
2698
  txUrl: "https://optimistic.etherscan.io/tx/",
@@ -2698,6 +2706,7 @@ var baseChainInfo = {
2698
2706
  type: "EVM",
2699
2707
  chainId: 56,
2700
2708
  mainnet: true,
2709
+ logo: chainLogo(ChainKeys.BSC_MAINNET),
2701
2710
  explorer: {
2702
2711
  baseUrl: "https://bscscan.com/",
2703
2712
  txUrl: "https://bscscan.com/tx/",
@@ -2711,6 +2720,7 @@ var baseChainInfo = {
2711
2720
  type: "EVM",
2712
2721
  chainId: 137,
2713
2722
  mainnet: true,
2723
+ logo: chainLogo(ChainKeys.POLYGON_MAINNET),
2714
2724
  explorer: {
2715
2725
  baseUrl: "https://polygonscan.com/",
2716
2726
  txUrl: "https://polygonscan.com/tx/",
@@ -2724,6 +2734,7 @@ var baseChainInfo = {
2724
2734
  type: "EVM",
2725
2735
  chainId: 999,
2726
2736
  mainnet: true,
2737
+ logo: chainLogo(ChainKeys.HYPEREVM_MAINNET),
2727
2738
  explorer: {
2728
2739
  baseUrl: "https://hyperevmscan.io/",
2729
2740
  txUrl: "https://hyperevmscan.io/tx/",
@@ -2737,6 +2748,7 @@ var baseChainInfo = {
2737
2748
  type: "EVM",
2738
2749
  chainId: 1890,
2739
2750
  mainnet: true,
2751
+ logo: chainLogo(ChainKeys.LIGHTLINK_MAINNET),
2740
2752
  explorer: {
2741
2753
  baseUrl: "https://phoenix.lightlink.io/",
2742
2754
  txUrl: "https://phoenix.lightlink.io/tx/",
@@ -2750,6 +2762,7 @@ var baseChainInfo = {
2750
2762
  type: "INJECTIVE",
2751
2763
  chainId: "injective-1",
2752
2764
  mainnet: true,
2765
+ logo: chainLogo(ChainKeys.INJECTIVE_MAINNET),
2753
2766
  explorer: {
2754
2767
  baseUrl: "https://www.mintscan.io/injective/",
2755
2768
  txUrl: "https://www.mintscan.io/injective/tx/",
@@ -2763,6 +2776,7 @@ var baseChainInfo = {
2763
2776
  type: "STELLAR",
2764
2777
  chainId: "stellar",
2765
2778
  mainnet: true,
2779
+ logo: chainLogo(ChainKeys.STELLAR_MAINNET),
2766
2780
  explorer: {
2767
2781
  baseUrl: "https://stellar.expert/explorer/public/",
2768
2782
  txUrl: "https://stellar.expert/explorer/public/tx/",
@@ -2776,6 +2790,7 @@ var baseChainInfo = {
2776
2790
  type: "SUI",
2777
2791
  chainId: "sui",
2778
2792
  mainnet: true,
2793
+ logo: chainLogo(ChainKeys.SUI_MAINNET),
2779
2794
  explorer: {
2780
2795
  baseUrl: "https://suivision.xyz/",
2781
2796
  txUrl: "https://suivision.xyz/txblock/",
@@ -2789,6 +2804,7 @@ var baseChainInfo = {
2789
2804
  type: "ICON",
2790
2805
  chainId: "0x1.icon",
2791
2806
  mainnet: true,
2807
+ logo: chainLogo(ChainKeys.ICON_MAINNET),
2792
2808
  explorer: {
2793
2809
  baseUrl: "https://tracker.icon.community/",
2794
2810
  txUrl: "https://tracker.icon.community/transaction/",
@@ -2802,6 +2818,7 @@ var baseChainInfo = {
2802
2818
  type: "NEAR",
2803
2819
  chainId: "near",
2804
2820
  mainnet: true,
2821
+ logo: chainLogo(ChainKeys.NEAR_MAINNET),
2805
2822
  explorer: {
2806
2823
  baseUrl: "https://nearblocks.io/",
2807
2824
  txUrl: "https://nearblocks.io/txns/",
@@ -2815,6 +2832,7 @@ var baseChainInfo = {
2815
2832
  type: "EVM",
2816
2833
  chainId: 1,
2817
2834
  mainnet: true,
2835
+ logo: chainLogo(ChainKeys.ETHEREUM_MAINNET),
2818
2836
  explorer: {
2819
2837
  baseUrl: "https://etherscan.io/",
2820
2838
  txUrl: "https://etherscan.io/tx/",
@@ -2828,6 +2846,7 @@ var baseChainInfo = {
2828
2846
  type: "BITCOIN",
2829
2847
  chainId: "bitcoin",
2830
2848
  mainnet: true,
2849
+ logo: chainLogo(ChainKeys.BITCOIN_MAINNET),
2831
2850
  explorer: {
2832
2851
  baseUrl: "https://mempool.space/",
2833
2852
  txUrl: "https://mempool.space/tx/",
@@ -2841,6 +2860,7 @@ var baseChainInfo = {
2841
2860
  type: "EVM",
2842
2861
  chainId: 151,
2843
2862
  mainnet: true,
2863
+ logo: chainLogo(ChainKeys.REDBELLY_MAINNET),
2844
2864
  explorer: {
2845
2865
  baseUrl: "https://redbelly.routescan.io/",
2846
2866
  txUrl: "https://redbelly.routescan.io/tx/",
@@ -2854,6 +2874,7 @@ var baseChainInfo = {
2854
2874
  type: "EVM",
2855
2875
  chainId: 8217,
2856
2876
  mainnet: true,
2877
+ logo: chainLogo(ChainKeys.KAIA_MAINNET),
2857
2878
  explorer: {
2858
2879
  baseUrl: "https://klaytnfinder.io/",
2859
2880
  txUrl: "https://klaytnfinder.io/tx/",
@@ -2867,6 +2888,7 @@ var baseChainInfo = {
2867
2888
  type: "STACKS",
2868
2889
  chainId: "stacks",
2869
2890
  mainnet: true,
2891
+ logo: chainLogo(ChainKeys.STACKS_MAINNET),
2870
2892
  explorer: {
2871
2893
  baseUrl: "https://explorer.hiro.so/",
2872
2894
  txUrl: "https://explorer.hiro.so/txid/",
@@ -3858,8 +3880,11 @@ var swapSupportedTokens = {
3858
3880
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.WAL,
3859
3881
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.NAVX
3860
3882
  ],
3861
- // Injective is currently staging-only — see stagingSwapSupportedTokens
3862
- [ChainKeys.INJECTIVE_MAINNET]: [],
3883
+ [ChainKeys.INJECTIVE_MAINNET]: [
3884
+ spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.INJ,
3885
+ spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.bnUSD,
3886
+ spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.USDC
3887
+ ],
3863
3888
  [ChainKeys.NEAR_MAINNET]: [
3864
3889
  spokeChainConfig[ChainKeys.NEAR_MAINNET].supportedTokens.NEAR,
3865
3890
  spokeChainConfig[ChainKeys.NEAR_MAINNET].supportedTokens.bnUSD,
@@ -3948,12 +3973,7 @@ var stagingSwapSupportedTokens = {
3948
3973
  [ChainKeys.ICON_MAINNET]: [],
3949
3974
  [ChainKeys.STELLAR_MAINNET]: [],
3950
3975
  [ChainKeys.SUI_MAINNET]: [spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.USDT],
3951
- [ChainKeys.INJECTIVE_MAINNET]: [
3952
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.INJ,
3953
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.bnUSD,
3954
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.USDC
3955
- // spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.SODA, // NOTE: not in solver wiki
3956
- ],
3976
+ [ChainKeys.INJECTIVE_MAINNET]: [],
3957
3977
  [ChainKeys.NEAR_MAINNET]: [],
3958
3978
  [ChainKeys.BITCOIN_MAINNET]: [],
3959
3979
  [ChainKeys.ETHEREUM_MAINNET]: [
@@ -4059,6 +4079,31 @@ function usesBip322MessageSigning(addressType) {
4059
4079
  var BTC_WALLET_ADDRESS_TYPES = ["taproot", "segwit"];
4060
4080
  var BTC_ADDRESS_TYPES = ["P2PKH", "P2SH", "P2WPKH", "P2TR"];
4061
4081
 
4082
+ // ../types/dist/hooks/hooks.js
4083
+ var HookKind = {
4084
+ /** Deposits delivered USDC into the recipient's HyperCore perps account (HyperEVM). */
4085
+ HYPERCORE_DEPOSIT: "hyperCoreDeposit"
4086
+ };
4087
+ var spokeHooks = {
4088
+ [ChainKeys.HYPEREVM_MAINNET]: [
4089
+ {
4090
+ kind: HookKind.HYPERCORE_DEPOSIT,
4091
+ address: "0xc79224a4DEE653C9a26572B941149d95a88432c4",
4092
+ supportedTokens: [spokeChainConfig[ChainKeys.HYPEREVM_MAINNET].supportedTokens.USDC.address]
4093
+ // USDC on HyperEVM
4094
+ }
4095
+ ]
4096
+ };
4097
+ var getSpokeHook = (chainKey, kind) => spokeHooks[chainKey]?.find((h) => h.kind === kind);
4098
+ var getSpokeHooks = (chainKey) => spokeHooks[chainKey] ?? [];
4099
+ var isHookSupportedToken = (chainKey, kind, token) => {
4100
+ const hook = getSpokeHook(chainKey, kind);
4101
+ if (!hook) {
4102
+ return false;
4103
+ }
4104
+ return !hook.supportedTokens || hook.supportedTokens.some((t) => t.toLowerCase() === token.toLowerCase());
4105
+ };
4106
+
4062
4107
  // ../types/dist/utils/utils.js
4063
4108
  function isHubChainKey(chainId) {
4064
4109
  return chainId === HUB_CHAIN_KEY;
@@ -4173,7 +4218,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
4173
4218
  }
4174
4219
 
4175
4220
  // ../types/dist/index.js
4176
- var CONFIG_VERSION = 214;
4221
+ var CONFIG_VERSION = 216;
4177
4222
  function isEvmSpokeChainConfig(value) {
4178
4223
  return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
4179
4224
  }
@@ -10576,6 +10621,144 @@ var ProtocolIntentsAbi = [
10576
10621
  }
10577
10622
  ],
10578
10623
  stateMutability: "view"
10624
+ },
10625
+ {
10626
+ type: "function",
10627
+ name: "cancelIntent",
10628
+ inputs: [
10629
+ {
10630
+ name: "fromToken",
10631
+ type: "address",
10632
+ internalType: "address"
10633
+ },
10634
+ {
10635
+ name: "toToken",
10636
+ type: "address",
10637
+ internalType: "address"
10638
+ }
10639
+ ],
10640
+ outputs: [],
10641
+ stateMutability: "nonpayable"
10642
+ },
10643
+ {
10644
+ type: "function",
10645
+ name: "getUserIntent",
10646
+ inputs: [
10647
+ {
10648
+ name: "user",
10649
+ type: "address",
10650
+ internalType: "address"
10651
+ },
10652
+ {
10653
+ name: "fromToken",
10654
+ type: "address",
10655
+ internalType: "address"
10656
+ },
10657
+ {
10658
+ name: "toToken",
10659
+ type: "address",
10660
+ internalType: "address"
10661
+ }
10662
+ ],
10663
+ outputs: [
10664
+ {
10665
+ name: "intentHash",
10666
+ type: "bytes32",
10667
+ internalType: "bytes32"
10668
+ }
10669
+ ],
10670
+ stateMutability: "view"
10671
+ },
10672
+ {
10673
+ type: "function",
10674
+ name: "getIntentDetails",
10675
+ inputs: [
10676
+ {
10677
+ name: "intentHash",
10678
+ type: "bytes32",
10679
+ internalType: "bytes32"
10680
+ }
10681
+ ],
10682
+ outputs: [
10683
+ {
10684
+ name: "intent",
10685
+ type: "tuple",
10686
+ internalType: "struct Intents.Intent",
10687
+ components: [
10688
+ {
10689
+ name: "intentId",
10690
+ type: "uint256",
10691
+ internalType: "uint256"
10692
+ },
10693
+ {
10694
+ name: "creator",
10695
+ type: "address",
10696
+ internalType: "address"
10697
+ },
10698
+ {
10699
+ name: "inputToken",
10700
+ type: "address",
10701
+ internalType: "address"
10702
+ },
10703
+ {
10704
+ name: "outputToken",
10705
+ type: "address",
10706
+ internalType: "address"
10707
+ },
10708
+ {
10709
+ name: "inputAmount",
10710
+ type: "uint256",
10711
+ internalType: "uint256"
10712
+ },
10713
+ {
10714
+ name: "minOutputAmount",
10715
+ type: "uint256",
10716
+ internalType: "uint256"
10717
+ },
10718
+ {
10719
+ name: "deadline",
10720
+ type: "uint256",
10721
+ internalType: "uint256"
10722
+ },
10723
+ {
10724
+ name: "allowPartialFill",
10725
+ type: "bool",
10726
+ internalType: "bool"
10727
+ },
10728
+ {
10729
+ name: "srcChain",
10730
+ type: "uint256",
10731
+ internalType: "uint256"
10732
+ },
10733
+ {
10734
+ name: "dstChain",
10735
+ type: "uint256",
10736
+ internalType: "uint256"
10737
+ },
10738
+ {
10739
+ name: "srcAddress",
10740
+ type: "bytes",
10741
+ internalType: "bytes"
10742
+ },
10743
+ {
10744
+ name: "dstAddress",
10745
+ type: "bytes",
10746
+ internalType: "bytes"
10747
+ },
10748
+ {
10749
+ name: "solver",
10750
+ type: "address",
10751
+ internalType: "address"
10752
+ },
10753
+ {
10754
+ name: "data",
10755
+ type: "bytes",
10756
+ internalType: "bytes"
10757
+ }
10758
+ ]
10759
+ }
10760
+ ],
10761
+ stateMutability: "view"
10579
10762
  }
10580
10763
  ];
10581
10764
 
@@ -13483,6 +13666,68 @@ function resolveLogger(option) {
13483
13666
  return option;
13484
13667
  }
13485
13668
 
13669
+ // src/shared/analytics.ts
13670
+ var noopAnalytics = {
13671
+ isEnabled: () => false,
13672
+ emit: () => {
13673
+ },
13674
+ trackResult: (_feature, _action, run) => run()
13675
+ };
13676
+ var LEVEL_RANK = { basic: 0, detailed: 1 };
13677
+ function normalizeFeatures(features) {
13678
+ if (features === void 0) return null;
13679
+ const map = /* @__PURE__ */ new Map();
13680
+ if (Array.isArray(features)) {
13681
+ for (const feature of features) map.set(feature, true);
13682
+ } else {
13683
+ for (const [feature, scope] of Object.entries(features)) {
13684
+ if (scope === true) map.set(feature, true);
13685
+ else if (scope) map.set(feature, new Set(scope.actions));
13686
+ }
13687
+ }
13688
+ return map;
13689
+ }
13690
+ function resolveAnalytics(option) {
13691
+ if (!option) return noopAnalytics;
13692
+ const { tracker, level: configuredLevel = "basic", features } = option;
13693
+ const maxRank = LEVEL_RANK[configuredLevel];
13694
+ const allow = normalizeFeatures(features);
13695
+ const isEnabled = (feature, action, level = "basic") => {
13696
+ if (LEVEL_RANK[level] > maxRank) return false;
13697
+ if (allow === null) return true;
13698
+ const scope = allow.get(feature);
13699
+ if (scope === void 0) return false;
13700
+ if (scope === true) return true;
13701
+ if (action === void 0) return scope.size > 0;
13702
+ return scope.has(action);
13703
+ };
13704
+ const emit = (feature, action, phase, build, level = "basic") => {
13705
+ if (!isEnabled(feature, action, level)) return;
13706
+ try {
13707
+ tracker({ feature, action, phase, level, data: build?.() });
13708
+ } catch {
13709
+ }
13710
+ };
13711
+ const trackResult = async (feature, action, run, data) => {
13712
+ emit(feature, action, "start", data?.start);
13713
+ try {
13714
+ const result = await run();
13715
+ if (result.ok) {
13716
+ const build = data?.success;
13717
+ emit(feature, action, "success", build ? () => build(result.value) : void 0);
13718
+ } else {
13719
+ const build = data?.failure;
13720
+ emit(feature, action, "failure", build ? () => build(result.error) : void 0);
13721
+ }
13722
+ return result;
13723
+ } catch (error) {
13724
+ emit(feature, action, "failure", () => ({ error: error instanceof Error ? error.message : String(error) }));
13725
+ throw error;
13726
+ }
13727
+ };
13728
+ return { isEnabled, emit, trackResult };
13729
+ }
13730
+
13486
13731
  // src/shared/config/ConfigService.ts
13487
13732
  var ConfigService = class {
13488
13733
  sodax;
@@ -13493,6 +13738,12 @@ var ConfigService = class {
13493
13738
  * {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.logger`.
13494
13739
  */
13495
13740
  logger;
13741
+ /**
13742
+ * Analytics emitter. Resolved once at construction and kept independent of {@link sodax} so that
13743
+ * {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.analytics`;
13744
+ * disabled (no-op) unless the consumer passed an `analytics` config to `new Sodax(...)`.
13745
+ */
13746
+ analytics;
13496
13747
  /**
13497
13748
  * Global partner fee. Resolved once at construction and kept independent of {@link sodax} so that
13498
13749
  * {@link initialize}'s dynamic-config swap never clobbers it. The backend never supplies it — it is
@@ -13510,11 +13761,12 @@ var ConfigService = class {
13510
13761
  stakedATokenAddressesSet;
13511
13762
  chainToSupportedTokenAddressMap;
13512
13763
  hubAssetToXTokenMap;
13513
- constructor({ api, config, userConfig, logger, fee }) {
13764
+ constructor({ api, config, userConfig, logger, analytics, fee }) {
13514
13765
  this.api = api;
13515
13766
  this.sodax = config;
13516
13767
  this.userConfig = userConfig;
13517
13768
  this.logger = logger ?? resolveLogger(void 0);
13769
+ this.analytics = analytics ?? noopAnalytics;
13518
13770
  this.fee = fee;
13519
13771
  this.loadSodaxConfigDataStructures(config);
13520
13772
  }
@@ -13565,6 +13817,16 @@ var ConfigService = class {
13565
13817
  getOriginalAssetAddress(chainId, hubAsset) {
13566
13818
  return this.hubAssetToXTokenMap.get(hubAsset.toLowerCase())?.address;
13567
13819
  }
13820
+ /**
13821
+ * Resolves the {@link XToken} descriptor (hub asset, vault, decimals) for a hub-asset address.
13822
+ *
13823
+ * Useful when a caller holds a hub asset directly on Sonic that has no spoke-token entry under
13824
+ * the hub chain — e.g. a partner BTC fee held as the BTC hub asset, which only exists as a spoke
13825
+ * token on Bitcoin. Returns `undefined` when the address is not a known hub asset.
13826
+ */
13827
+ getXTokenFromHubAsset(hubAsset) {
13828
+ return this.hubAssetToXTokenMap.get(hubAsset.toLowerCase());
13829
+ }
13568
13830
  getSpokeTokenFromOriginalAssetAddress(chainId, originalAssetAddress) {
13569
13831
  return this.supportedTokensPerChain.get(chainId)?.find((token) => token.address.toLowerCase() === originalAssetAddress.toLowerCase());
13570
13832
  }
@@ -21824,9 +22086,147 @@ var NearSpokeService = class {
21824
22086
 
21825
22087
  // src/shared/types/intent-types.ts
21826
22088
  var IntentDataType = /* @__PURE__ */ ((IntentDataType2) => {
22089
+ IntentDataType2[IntentDataType2["ARRAY"] = 0] = "ARRAY";
21827
22090
  IntentDataType2[IntentDataType2["FEE"] = 1] = "FEE";
22091
+ IntentDataType2[IntentDataType2["HOOK"] = 2] = "HOOK";
22092
+ IntentDataType2[IntentDataType2["DELIVERY"] = 3] = "DELIVERY";
21828
22093
  return IntentDataType2;
21829
22094
  })(IntentDataType || {});
22095
+ var HOOK_DELIVERY_ABI = {
22096
+ // HyperCoreDepositHook expects `abi.encode(address)` — the HyperCore account to credit.
22097
+ [HookKind.HYPERCORE_DEPOSIT]: [{ name: "recipient", type: "address" }]
22098
+ };
22099
+ var HookService = class _HookService {
22100
+ constructor() {
22101
+ }
22102
+ /**
22103
+ * Encodes a hook's `deliveryData` payload. One common entry point for all hooks — the encoding is
22104
+ * selected by {@link HookRequest.kind} and uses that hook's schema from {@link HOOK_DELIVERY_ABI}.
22105
+ *
22106
+ * @param request - The hook selection (and any hook-specific params).
22107
+ * @param recipient - The end recipient the hook should credit (the intent's `dstAddress`).
22108
+ */
22109
+ static encodeDeliveryData(request, recipient) {
22110
+ switch (request.kind) {
22111
+ case HookKind.HYPERCORE_DEPOSIT:
22112
+ return encodeAbiParameters(HOOK_DELIVERY_ABI[HookKind.HYPERCORE_DEPOSIT], [recipient]);
22113
+ }
22114
+ throw new Error(
22115
+ `[HookService.encodeDeliveryData] Unsupported delivery hook kind: ${request.kind}`
22116
+ );
22117
+ }
22118
+ /**
22119
+ * Resolves a high-level {@link HookRequest} to the on-chain delivery pair: the deployed hook address
22120
+ * (becomes the intent's `dstAddress`) and the encoded payload the hook expects (`deliveryData`).
22121
+ * Bundling lookup + codec here guarantees the address and its payload schema can never drift.
22122
+ *
22123
+ * @param chainKey - Destination spoke chain (must have the requested hook deployed).
22124
+ * @param request - The hook selection (and any hook-specific params).
22125
+ * @param recipient - The end recipient the hook should credit (the intent's `dstAddress`).
22126
+ */
22127
+ static resolveDeliveryHook(chainKey, request, recipient) {
22128
+ const hook = getSpokeHook(chainKey, request.kind);
22129
+ invariant(hook, `No '${request.kind}' delivery hook is deployed on chain ${chainKey}`);
22130
+ return { dstAddress: hook.address, deliveryData: _HookService.encodeDeliveryData(request, recipient) };
22131
+ }
22132
+ /**
22133
+ * Resolves the effective delivery target for an intent. When {@link CreateIntentParams.hook} is set,
22134
+ * routes the output through that registered hook (overriding `dstAddress` and deriving `deliveryData`);
22135
+ * otherwise returns the caller's `dstAddress` and low-level `deliveryData` unchanged. Centralised so
22136
+ * both the hub and Sonic intent constructors apply hooks identically.
22137
+ *
22138
+ * @returns `{ dstAddress, deliveryData }` — the address to deliver to and the payload to forward.
22139
+ */
22140
+ static resolveDelivery(params) {
22141
+ if (!params.hook) {
22142
+ return { dstAddress: params.dstAddress, deliveryData: params.deliveryData };
22143
+ }
22144
+ return _HookService.resolveDeliveryHook(params.dstChainKey, params.hook, params.dstAddress);
22145
+ }
22146
+ };
22147
+ var ARRAY_DATA_ABI = [
22148
+ {
22149
+ type: "tuple",
22150
+ components: [
22151
+ {
22152
+ name: "data",
22153
+ type: "tuple[]",
22154
+ components: [
22155
+ { name: "dataType", type: "uint8" },
22156
+ { name: "data", type: "bytes" }
22157
+ ]
22158
+ }
22159
+ ]
22160
+ }
22161
+ ];
22162
+ var IntentDataService = class _IntentDataService {
22163
+ constructor() {
22164
+ }
22165
+ /**
22166
+ * Folds a partner-fee envelope and an optional delivery payload into the final `Intent.data`:
22167
+ * - Neither → `'0x'`.
22168
+ * - Exactly one → that single packed `[uint8 type, bytes payload]` envelope (byte-identical to a
22169
+ * bare fee envelope, so a fee-only intent's `data` is unchanged and stays decode-stable).
22170
+ * - Both → a `TYPE_ARRAY` envelope wrapping `[FEE, DELIVERY]` entries.
22171
+ *
22172
+ * @param feeEnvelope - The packed fee envelope from `EvmSolverService.createIntentFeeData` (`'0x'` if no fee).
22173
+ * @param deliveryData - Opaque delivery payload (e.g. from `HookService.encodeDeliveryData`), or `undefined`.
22174
+ */
22175
+ static composeIntentData(feeEnvelope, deliveryData) {
22176
+ const entries = [];
22177
+ if (feeEnvelope !== "0x") {
22178
+ entries.push({ type: 1 /* FEE */, data: `0x${feeEnvelope.slice(4)}` });
22179
+ }
22180
+ if (deliveryData && deliveryData !== "0x") {
22181
+ entries.push({ type: 3 /* DELIVERY */, data: deliveryData });
22182
+ }
22183
+ return _IntentDataService.encodeIntentData(entries);
22184
+ }
22185
+ /**
22186
+ * Encodes a list of typed `IntentData` entries into the `Intent.data` bytes the contract decodes.
22187
+ * Empty → `'0x'`; single → a packed `[uint8 type, bytes payload]` envelope; multiple → a `TYPE_ARRAY`
22188
+ * envelope wrapping the entries as `ArrayData { DataEntry[] }`.
22189
+ */
22190
+ static encodeIntentData(entries) {
22191
+ if (entries.length === 0) {
22192
+ return "0x";
22193
+ }
22194
+ const [first] = entries;
22195
+ if (first && entries.length === 1) {
22196
+ return encodePacked(["uint8", "bytes"], [first.type, first.data]);
22197
+ }
22198
+ const encodedArray = encodeAbiParameters(ARRAY_DATA_ABI, [
22199
+ { data: entries.map((e) => ({ dataType: e.type, data: e.data })) }
22200
+ ]);
22201
+ return encodePacked(["uint8", "bytes"], [0 /* ARRAY */, encodedArray]);
22202
+ }
22203
+ /**
22204
+ * Extracts the raw `FeeData` payload (`abi.encode(uint256 fee, address receiver)`) from an intent's
22205
+ * `data`, unwrapping whichever envelope shape it uses. Returns `undefined` when there is no fee:
22206
+ * empty `data`, a delivery-only envelope, or an unknown type byte (logged). Used by
22207
+ * `EvmSolverService.decodeIntentFeeAmount` to recover fees regardless of delivery data.
22208
+ */
22209
+ static extractFeePayload(data) {
22210
+ if (data === "0x" || data.length <= 2) {
22211
+ return void 0;
22212
+ }
22213
+ const typeByte = Number.parseInt(data.slice(2, 4), 16);
22214
+ if (typeByte === 1 /* FEE */) {
22215
+ return `0x${data.slice(4)}`;
22216
+ }
22217
+ if (typeByte === 0 /* ARRAY */) {
22218
+ const [arrayData] = decodeAbiParameters(ARRAY_DATA_ABI, `0x${data.slice(4)}`);
22219
+ return arrayData.data.find((e) => e.dataType === 1 /* FEE */)?.data;
22220
+ }
22221
+ if (typeByte === 3 /* DELIVERY */) {
22222
+ return void 0;
22223
+ }
22224
+ console.error(
22225
+ `[IntentDataService.extractFeePayload] Unknown IntentData type byte: ${typeByte}. Gracefully returning no fee.`
22226
+ );
22227
+ return void 0;
22228
+ }
22229
+ };
21830
22230
  var IntentCreatedEventAbi = getAbiItem({ abi: IntentsAbi, name: "IntentCreated" });
21831
22231
  var IntentFilledEventAbi = getAbiItem({ abi: IntentsAbi, name: "IntentFilled" });
21832
22232
  var MintPositionEventAbi = getAbiItem({ abi: CLPositionManagerAbi, name: "MintPosition" });
@@ -21865,7 +22265,9 @@ var EvmSolverService = class _EvmSolverService {
21865
22265
  outputToken,
21866
22266
  `hub asset not found for spoke chain token (intent.outputToken): ${createIntentParams.outputToken}`
21867
22267
  );
21868
- const [feeData, feeAmount] = _EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22268
+ const { dstAddress, deliveryData } = HookService.resolveDelivery(createIntentParams);
22269
+ const [feeEnvelope, feeAmount] = _EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22270
+ const intentData = IntentDataService.composeIntentData(feeEnvelope, deliveryData);
21869
22271
  const calls = [];
21870
22272
  const intentsContract = config.solver.intentsContract;
21871
22273
  const intent = {
@@ -21880,10 +22282,10 @@ var EvmSolverService = class _EvmSolverService {
21880
22282
  srcChain: getIntentRelayChainId(createIntentParams.srcChainKey),
21881
22283
  dstChain: getIntentRelayChainId(createIntentParams.dstChainKey),
21882
22284
  srcAddress: encodeAddress(createIntentParams.srcChainKey, createIntentParams.srcAddress),
21883
- dstAddress: encodeAddress(createIntentParams.dstChainKey, createIntentParams.dstAddress),
22285
+ dstAddress: encodeAddress(createIntentParams.dstChainKey, dstAddress),
21884
22286
  solver: createIntentParams.solver ?? "0x0000000000000000000000000000000000000000",
21885
- data: feeData
21886
- // fee amount will be deducted from the input amount
22287
+ data: intentData
22288
+ // fee amount will be deducted from the input amount; may also carry delivery data
21887
22289
  };
21888
22290
  calls.push(Erc20Service.encodeApprove(intent.inputToken, intentsContract, createIntentParams.inputAmount));
21889
22291
  calls.push(_EvmSolverService.encodeCreateIntent(intent, intentsContract));
@@ -21944,29 +22346,25 @@ var EvmSolverService = class _EvmSolverService {
21944
22346
  /**
21945
22347
  * Recovers the partner fee amount embedded in an intent's `data` field.
21946
22348
  *
21947
- * Exact inverse of {@link createIntentFeeData}: `'0x'` means no fee (`0n`); otherwise the first
21948
- * byte is the {@link IntentDataType} tag (from the `encodePacked(['uint8','bytes'], …)` envelope)
21949
- * and the remainder is the ABI-encoded `(uint256 fee, address receiver)` struct.
22349
+ * Inverse of {@link createIntentFeeData}: returns the encoded fee, regardless of whether the `data`
22350
+ * is a bare fee envelope or a multi-entry envelope that also carries delivery data. The envelope
22351
+ * parsing lives in {@link IntentDataService.extractFeePayload}; this method just decodes the fee struct.
21950
22352
  *
21951
22353
  * @param data - The intent's `data` field (`'0x'` when no fee was configured).
21952
- * @returns The fee amount in the input token's smallest unit (`0n` when no fee data is present, or
21953
- * when the leading type byte is not {@link IntentDataType.FEE} — in which case it logs and degrades to `0n`).
22354
+ * @returns The fee amount in the input token's smallest unit (`0n` when no fee is present).
21954
22355
  */
21955
22356
  static decodeIntentFeeAmount(data) {
21956
- if (data === "0x" || data.length <= 2) {
21957
- return 0n;
21958
- }
21959
- const typeByte = Number.parseInt(data.slice(2, 4), 16);
21960
- if (typeByte !== 1 /* FEE */) {
21961
- console.error(`[decodeIntentFeeAmount] Unknown IntentData type byte: ${typeByte}. Gracefully returning 0n.`);
21962
- return 0n;
21963
- }
22357
+ const feePayload = IntentDataService.extractFeePayload(data);
22358
+ return feePayload ? _EvmSolverService.decodeFeePayload(feePayload) : 0n;
22359
+ }
22360
+ /** Decodes a raw `FeeData` payload (`abi.encode(uint256 fee, address receiver)`) to its fee amount. */
22361
+ static decodeFeePayload(payload) {
21964
22362
  const [feeAmount] = decodeAbiParameters(
21965
22363
  [
21966
22364
  { name: "fee", type: "uint256" },
21967
22365
  { name: "receiver", type: "address" }
21968
22366
  ],
21969
- `0x${data.slice(4)}`
22367
+ payload
21970
22368
  );
21971
22369
  return feeAmount;
21972
22370
  }
@@ -22332,7 +22730,9 @@ var SonicSpokeService = class {
22332
22730
  outputToken,
22333
22731
  `hub asset not found for spoke chain token (intent.outputToken): ${createIntentParams.outputToken}`
22334
22732
  );
22335
- const [feeData, feeAmount] = EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22733
+ const { dstAddress, deliveryData } = HookService.resolveDelivery(createIntentParams);
22734
+ const [feeEnvelope, feeAmount] = EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22735
+ const intentData = IntentDataService.composeIntentData(feeEnvelope, deliveryData);
22336
22736
  const intentsContract = solverConfig2.intentsContract;
22337
22737
  const intent = {
22338
22738
  intentId: randomUint256(),
@@ -22346,10 +22746,10 @@ var SonicSpokeService = class {
22346
22746
  srcChain: getIntentRelayChainId(createIntentParams.srcChainKey),
22347
22747
  dstChain: getIntentRelayChainId(createIntentParams.dstChainKey),
22348
22748
  srcAddress: encodeAddress(createIntentParams.srcChainKey, createIntentParams.srcAddress),
22349
- dstAddress: encodeAddress(createIntentParams.dstChainKey, createIntentParams.dstAddress),
22749
+ dstAddress: encodeAddress(createIntentParams.dstChainKey, dstAddress),
22350
22750
  solver: createIntentParams.solver ?? "0x0000000000000000000000000000000000000000",
22351
- data: feeData
22352
- // fee amount will be deducted from the input amount
22751
+ data: intentData
22752
+ // fee amount will be deducted from the input amount; may also carry delivery data
22353
22753
  };
22354
22754
  const txData = EvmSolverService.encodeCreateIntent(intent, intentsContract);
22355
22755
  const rawTx = {
@@ -26214,64 +26614,88 @@ var SwapService = class {
26214
26614
  const { params } = _params;
26215
26615
  const srcChainKey = params.srcChainKey;
26216
26616
  const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey };
26217
- try {
26218
- const timeout = _params.timeout;
26219
- const createIntentResult = await this.createIntent(_params);
26220
- if (!createIntentResult.ok) {
26221
- return { ok: false, error: createIntentResult.error };
26222
- }
26223
- const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
26224
- const verifyTxHashResult = await this.spoke.verifyTxHash({
26225
- txHash: spokeTxHash,
26226
- chainKey: srcChainKey
26227
- });
26228
- if (!verifyTxHashResult.ok) {
26229
- return { ok: false, error: verifyFailed("swap", verifyTxHashResult.error, { ...baseCtx, action: "swap" }) };
26230
- }
26231
- let dstIntentTxHash;
26232
- if (isHubChainKeyType(srcChainKey)) {
26233
- dstIntentTxHash = spokeTxHash;
26234
- } else {
26235
- const packet = await relayTxAndWaitPacket({
26236
- srcTxHash: spokeTxHash,
26237
- data: relayData,
26238
- chainKey: srcChainKey,
26239
- relayerApiEndpoint: this.relayerApiEndpoint,
26240
- timeout
26241
- });
26242
- if (!packet.ok) {
26243
- return { ok: false, error: mapRelayFailure(packet.error, { feature: "swap", action: "swap", ...baseCtx }) };
26244
- }
26245
- dstIntentTxHash = packet.value.dst_tx_hash;
26246
- }
26247
- const postExecResult = await this.postExecution({
26248
- intent_tx_hash: dstIntentTxHash
26249
- });
26250
- if (!postExecResult.ok) {
26251
- return { ok: false, error: postExecResult.error };
26252
- }
26253
- return {
26254
- ok: true,
26255
- value: {
26256
- solverExecutionResponse: postExecResult.value,
26257
- intent,
26258
- intentDeliveryInfo: {
26259
- srcChainKey,
26260
- srcTxHash: spokeTxHash,
26261
- srcAddress: params.srcAddress,
26262
- dstChainKey: params.dstChainKey,
26263
- dstTxHash: dstIntentTxHash,
26264
- dstAddress: params.dstAddress
26617
+ return this.config.analytics.trackResult(
26618
+ "swap",
26619
+ "swap",
26620
+ async () => {
26621
+ try {
26622
+ const timeout = _params.timeout;
26623
+ const createIntentResult = await this.createIntent(_params);
26624
+ if (!createIntentResult.ok) {
26625
+ return { ok: false, error: createIntentResult.error };
26626
+ }
26627
+ const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
26628
+ const verifyTxHashResult = await this.spoke.verifyTxHash({
26629
+ txHash: spokeTxHash,
26630
+ chainKey: srcChainKey
26631
+ });
26632
+ if (!verifyTxHashResult.ok) {
26633
+ return { ok: false, error: verifyFailed("swap", verifyTxHashResult.error, { ...baseCtx, action: "swap" }) };
26634
+ }
26635
+ let dstIntentTxHash;
26636
+ if (isHubChainKeyType(srcChainKey)) {
26637
+ dstIntentTxHash = spokeTxHash;
26638
+ } else {
26639
+ const packet = await relayTxAndWaitPacket({
26640
+ srcTxHash: spokeTxHash,
26641
+ data: relayData,
26642
+ chainKey: srcChainKey,
26643
+ relayerApiEndpoint: this.relayerApiEndpoint,
26644
+ timeout
26645
+ });
26646
+ if (!packet.ok) {
26647
+ return {
26648
+ ok: false,
26649
+ error: mapRelayFailure(packet.error, { feature: "swap", action: "swap", ...baseCtx })
26650
+ };
26651
+ }
26652
+ dstIntentTxHash = packet.value.dst_tx_hash;
26265
26653
  }
26654
+ const postExecResult = await this.postExecution({
26655
+ intent_tx_hash: dstIntentTxHash
26656
+ });
26657
+ if (!postExecResult.ok) {
26658
+ return { ok: false, error: postExecResult.error };
26659
+ }
26660
+ return {
26661
+ ok: true,
26662
+ value: {
26663
+ solverExecutionResponse: postExecResult.value,
26664
+ intent,
26665
+ intentDeliveryInfo: {
26666
+ srcChainKey,
26667
+ srcTxHash: spokeTxHash,
26668
+ srcAddress: params.srcAddress,
26669
+ dstChainKey: params.dstChainKey,
26670
+ dstTxHash: dstIntentTxHash,
26671
+ dstAddress: params.dstAddress
26672
+ }
26673
+ }
26674
+ };
26675
+ } catch (error) {
26676
+ if (isSwapError(error)) return { ok: false, error };
26677
+ return {
26678
+ ok: false,
26679
+ error: unknownFailed("swap", error, { ...baseCtx, action: "swap" })
26680
+ };
26266
26681
  }
26267
- };
26268
- } catch (error) {
26269
- if (isSwapError(error)) return { ok: false, error };
26270
- return {
26271
- ok: false,
26272
- error: unknownFailed("swap", error, { ...baseCtx, action: "swap" })
26273
- };
26274
- }
26682
+ },
26683
+ {
26684
+ start: () => ({
26685
+ srcChainKey,
26686
+ dstChainKey: params.dstChainKey,
26687
+ srcAddress: params.srcAddress,
26688
+ dstAddress: params.dstAddress
26689
+ }),
26690
+ success: (value) => ({
26691
+ srcChainKey,
26692
+ dstChainKey: params.dstChainKey,
26693
+ srcTxHash: value.intentDeliveryInfo.srcTxHash,
26694
+ dstTxHash: value.intentDeliveryInfo.dstTxHash
26695
+ }),
26696
+ failure: (error) => ({ code: error.code })
26697
+ }
26698
+ );
26275
26699
  }
26276
26700
  /**
26277
26701
  * Checks whether the relevant spender contract is already approved to spend the input token amount.
@@ -28317,72 +28741,94 @@ var MigrationService = class {
28317
28741
  * }
28318
28742
  */
28319
28743
  async migratebnUSD(_params) {
28320
- const { params, timeout } = _params;
28321
- const baseCtx = {
28322
- srcChainKey: params.srcChainKey,
28323
- dstChainKey: params.dstChainKey,
28324
- action: "migratebnUSD"
28325
- };
28326
- try {
28327
- const intentResult = await this.createMigratebnUSDIntent(_params);
28328
- if (!intentResult.ok) return { ok: false, error: intentResult.error };
28329
- const { tx: spokeTxHash, relayData: extraData } = intentResult.value;
28330
- const verifyTxHashResult = await this.spoke.verifyTxHash({
28331
- txHash: spokeTxHash,
28332
- chainKey: params.srcChainKey
28333
- });
28334
- if (!verifyTxHashResult.ok) {
28335
- return {
28336
- ok: false,
28337
- error: verifyFailed("migration", verifyTxHashResult.error, baseCtx)
28338
- };
28339
- }
28340
- const packetResult = await relayTxAndWaitPacket({
28341
- srcTxHash: spokeTxHash,
28342
- data: extraData,
28343
- chainKey: params.srcChainKey,
28344
- relayerApiEndpoint: this.relayerApiEndpoint,
28345
- timeout
28346
- });
28347
- if (!packetResult.ok) {
28348
- return {
28349
- ok: false,
28350
- error: mapRelayFailure(packetResult.error, {
28351
- feature: "migration",
28352
- action: baseCtx.action,
28353
- srcChainKey: baseCtx.srcChainKey,
28354
- dstChainKey: baseCtx.dstChainKey
28355
- })
28744
+ return this.config.analytics.trackResult(
28745
+ "migration",
28746
+ "migratebnUSD",
28747
+ async () => {
28748
+ const { params, timeout } = _params;
28749
+ const baseCtx = {
28750
+ srcChainKey: params.srcChainKey,
28751
+ dstChainKey: params.dstChainKey,
28752
+ action: "migratebnUSD"
28356
28753
  };
28357
- }
28358
- if (!(params.srcChainKey === ChainKeys.SONIC_MAINNET || params.dstChainKey === ChainKeys.SONIC_MAINNET)) {
28359
- const execResult = await waitUntilIntentExecuted({
28360
- intentRelayChainId: getIntentRelayChainId(ChainKeys.SONIC_MAINNET).toString(),
28361
- srcTxHash: packetResult.value.dst_tx_hash,
28362
- timeout,
28363
- apiUrl: this.relayerApiEndpoint
28364
- });
28365
- if (!execResult.ok) {
28754
+ try {
28755
+ const intentResult = await this.createMigratebnUSDIntent(_params);
28756
+ if (!intentResult.ok) return { ok: false, error: intentResult.error };
28757
+ const { tx: spokeTxHash, relayData: extraData } = intentResult.value;
28758
+ const verifyTxHashResult = await this.spoke.verifyTxHash({
28759
+ txHash: spokeTxHash,
28760
+ chainKey: params.srcChainKey
28761
+ });
28762
+ if (!verifyTxHashResult.ok) {
28763
+ return {
28764
+ ok: false,
28765
+ error: verifyFailed("migration", verifyTxHashResult.error, baseCtx)
28766
+ };
28767
+ }
28768
+ const packetResult = await relayTxAndWaitPacket({
28769
+ srcTxHash: spokeTxHash,
28770
+ data: extraData,
28771
+ chainKey: params.srcChainKey,
28772
+ relayerApiEndpoint: this.relayerApiEndpoint,
28773
+ timeout
28774
+ });
28775
+ if (!packetResult.ok) {
28776
+ return {
28777
+ ok: false,
28778
+ error: mapRelayFailure(packetResult.error, {
28779
+ feature: "migration",
28780
+ action: baseCtx.action,
28781
+ srcChainKey: baseCtx.srcChainKey,
28782
+ dstChainKey: baseCtx.dstChainKey
28783
+ })
28784
+ };
28785
+ }
28786
+ if (!(params.srcChainKey === ChainKeys.SONIC_MAINNET || params.dstChainKey === ChainKeys.SONIC_MAINNET)) {
28787
+ const execResult = await waitUntilIntentExecuted({
28788
+ intentRelayChainId: getIntentRelayChainId(ChainKeys.SONIC_MAINNET).toString(),
28789
+ srcTxHash: packetResult.value.dst_tx_hash,
28790
+ timeout,
28791
+ apiUrl: this.relayerApiEndpoint
28792
+ });
28793
+ if (!execResult.ok) {
28794
+ return {
28795
+ ok: false,
28796
+ error: mapRelayFailure(execResult.error, {
28797
+ feature: "migration",
28798
+ action: baseCtx.action,
28799
+ srcChainKey: baseCtx.srcChainKey,
28800
+ dstChainKey: baseCtx.dstChainKey,
28801
+ phase: "destinationExecution"
28802
+ })
28803
+ };
28804
+ }
28805
+ }
28806
+ return { ok: true, value: { srcChainTxHash: spokeTxHash, dstChainTxHash: packetResult.value.dst_tx_hash } };
28807
+ } catch (error) {
28808
+ if (isMigrateOrchestrationError(error)) return { ok: false, error };
28366
28809
  return {
28367
28810
  ok: false,
28368
- error: mapRelayFailure(execResult.error, {
28369
- feature: "migration",
28370
- action: baseCtx.action,
28371
- srcChainKey: baseCtx.srcChainKey,
28372
- dstChainKey: baseCtx.dstChainKey,
28373
- phase: "destinationExecution"
28374
- })
28811
+ error: executionFailed("migration", error, baseCtx)
28375
28812
  };
28376
28813
  }
28814
+ },
28815
+ {
28816
+ start: () => ({
28817
+ srcChainKey: _params.params.srcChainKey,
28818
+ dstChainKey: _params.params.dstChainKey,
28819
+ srcAddress: _params.params.srcAddress,
28820
+ dstAddress: _params.params.dstAddress,
28821
+ srcbnUSD: _params.params.srcbnUSD,
28822
+ dstbnUSD: _params.params.dstbnUSD,
28823
+ amount: _params.params.amount
28824
+ }),
28825
+ success: (value) => ({
28826
+ srcChainTxHash: value.srcChainTxHash,
28827
+ dstChainTxHash: value.dstChainTxHash
28828
+ }),
28829
+ failure: (error) => ({ code: error.code })
28377
28830
  }
28378
- return { ok: true, value: { srcChainTxHash: spokeTxHash, dstChainTxHash: packetResult.value.dst_tx_hash } };
28379
- } catch (error) {
28380
- if (isMigrateOrchestrationError(error)) return { ok: false, error };
28381
- return {
28382
- ok: false,
28383
- error: executionFailed("migration", error, baseCtx)
28384
- };
28385
- }
28831
+ );
28386
28832
  }
28387
28833
  /**
28388
28834
  * Migrates ICX or wICX tokens from ICON to SODA on the hub chain (Sonic), including relay.
@@ -28397,37 +28843,57 @@ var MigrationService = class {
28397
28843
  * check fails, the deposit reverts, or the relay times out.
28398
28844
  */
28399
28845
  async migrateIcxToSoda(_params) {
28400
- const { timeout } = _params;
28401
- const baseCtx = { srcChainKey: _params.params.srcChainKey, action: "migrateIcxToSoda" };
28402
- try {
28403
- const txResult = await this.createMigrateIcxToSodaIntent(_params);
28404
- if (!txResult.ok) return { ok: false, error: txResult.error };
28405
- const { tx, relayData } = txResult.value;
28406
- const packetResult = await relayTxAndWaitPacket({
28407
- srcTxHash: tx,
28408
- data: relayData,
28409
- chainKey: _params.params.srcChainKey,
28410
- relayerApiEndpoint: this.relayerApiEndpoint,
28411
- timeout
28412
- });
28413
- if (!packetResult.ok) {
28414
- return {
28415
- ok: false,
28416
- error: mapRelayFailure(packetResult.error, {
28417
- feature: "migration",
28418
- action: baseCtx.action,
28419
- srcChainKey: baseCtx.srcChainKey
28420
- })
28421
- };
28846
+ return this.config.analytics.trackResult(
28847
+ "migration",
28848
+ "migrateIcxToSoda",
28849
+ async () => {
28850
+ const { timeout } = _params;
28851
+ const baseCtx = { srcChainKey: _params.params.srcChainKey, action: "migrateIcxToSoda" };
28852
+ try {
28853
+ const txResult = await this.createMigrateIcxToSodaIntent(_params);
28854
+ if (!txResult.ok) return { ok: false, error: txResult.error };
28855
+ const { tx, relayData } = txResult.value;
28856
+ const packetResult = await relayTxAndWaitPacket({
28857
+ srcTxHash: tx,
28858
+ data: relayData,
28859
+ chainKey: _params.params.srcChainKey,
28860
+ relayerApiEndpoint: this.relayerApiEndpoint,
28861
+ timeout
28862
+ });
28863
+ if (!packetResult.ok) {
28864
+ return {
28865
+ ok: false,
28866
+ error: mapRelayFailure(packetResult.error, {
28867
+ feature: "migration",
28868
+ action: baseCtx.action,
28869
+ srcChainKey: baseCtx.srcChainKey
28870
+ })
28871
+ };
28872
+ }
28873
+ return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
28874
+ } catch (error) {
28875
+ if (isMigrateOrchestrationError(error)) return { ok: false, error };
28876
+ return {
28877
+ ok: false,
28878
+ error: executionFailed("migration", error, baseCtx)
28879
+ };
28880
+ }
28881
+ },
28882
+ {
28883
+ start: () => ({
28884
+ srcChainKey: _params.params.srcChainKey,
28885
+ srcAddress: _params.params.srcAddress,
28886
+ dstAddress: _params.params.dstAddress,
28887
+ address: _params.params.address,
28888
+ amount: _params.params.amount
28889
+ }),
28890
+ success: (value) => ({
28891
+ srcChainTxHash: value.srcChainTxHash,
28892
+ dstChainTxHash: value.dstChainTxHash
28893
+ }),
28894
+ failure: (error) => ({ code: error.code })
28422
28895
  }
28423
- return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
28424
- } catch (error) {
28425
- if (isMigrateOrchestrationError(error)) return { ok: false, error };
28426
- return {
28427
- ok: false,
28428
- error: executionFailed("migration", error, baseCtx)
28429
- };
28430
- }
28896
+ );
28431
28897
  }
28432
28898
  /**
28433
28899
  * Reverts a previous ICX→SODA migration by swapping SODA back to wICX on the hub and
@@ -28445,37 +28911,56 @@ var MigrationService = class {
28445
28911
  * Sonic deposit transaction and `dstChainTxHash` is the hub-side packet receipt.
28446
28912
  */
28447
28913
  async revertMigrateSodaToIcx(_params) {
28448
- const { timeout } = _params;
28449
- const baseCtx = { srcChainKey: ChainKeys.SONIC_MAINNET, action: "revertMigrateSodaToIcx" };
28450
- try {
28451
- const txResult = await this.createRevertSodaToIcxMigrationIntent(_params);
28452
- if (!txResult.ok) return { ok: false, error: txResult.error };
28453
- const { tx, relayData } = txResult.value;
28454
- const packetResult = await relayTxAndWaitPacket({
28455
- srcTxHash: tx,
28456
- data: relayData,
28457
- chainKey: ChainKeys.SONIC_MAINNET,
28458
- relayerApiEndpoint: this.relayerApiEndpoint,
28459
- timeout
28460
- });
28461
- if (!packetResult.ok) {
28462
- return {
28463
- ok: false,
28464
- error: mapRelayFailure(packetResult.error, {
28465
- feature: "migration",
28466
- action: baseCtx.action,
28467
- srcChainKey: baseCtx.srcChainKey
28468
- })
28469
- };
28914
+ return this.config.analytics.trackResult(
28915
+ "migration",
28916
+ "revertMigrateSodaToIcx",
28917
+ async () => {
28918
+ const { timeout } = _params;
28919
+ const baseCtx = { srcChainKey: ChainKeys.SONIC_MAINNET, action: "revertMigrateSodaToIcx" };
28920
+ try {
28921
+ const txResult = await this.createRevertSodaToIcxMigrationIntent(_params);
28922
+ if (!txResult.ok) return { ok: false, error: txResult.error };
28923
+ const { tx, relayData } = txResult.value;
28924
+ const packetResult = await relayTxAndWaitPacket({
28925
+ srcTxHash: tx,
28926
+ data: relayData,
28927
+ chainKey: ChainKeys.SONIC_MAINNET,
28928
+ relayerApiEndpoint: this.relayerApiEndpoint,
28929
+ timeout
28930
+ });
28931
+ if (!packetResult.ok) {
28932
+ return {
28933
+ ok: false,
28934
+ error: mapRelayFailure(packetResult.error, {
28935
+ feature: "migration",
28936
+ action: baseCtx.action,
28937
+ srcChainKey: baseCtx.srcChainKey
28938
+ })
28939
+ };
28940
+ }
28941
+ return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
28942
+ } catch (error) {
28943
+ if (isRevertMigrationOrchestrationError(error)) return { ok: false, error };
28944
+ return {
28945
+ ok: false,
28946
+ error: executionFailed("migration", error, baseCtx)
28947
+ };
28948
+ }
28949
+ },
28950
+ {
28951
+ start: () => ({
28952
+ srcChainKey: _params.params.srcChainKey,
28953
+ srcAddress: _params.params.srcAddress,
28954
+ dstAddress: _params.params.dstAddress,
28955
+ amount: _params.params.amount
28956
+ }),
28957
+ success: (value) => ({
28958
+ srcChainTxHash: value.srcChainTxHash,
28959
+ dstChainTxHash: value.dstChainTxHash
28960
+ }),
28961
+ failure: (error) => ({ code: error.code })
28470
28962
  }
28471
- return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
28472
- } catch (error) {
28473
- if (isRevertMigrationOrchestrationError(error)) return { ok: false, error };
28474
- return {
28475
- ok: false,
28476
- error: executionFailed("migration", error, baseCtx)
28477
- };
28478
- }
28963
+ );
28479
28964
  }
28480
28965
  /**
28481
28966
  * Migrates BALN tokens from ICON to SODA on the hub chain (Sonic), including relay.
@@ -28492,37 +28977,58 @@ var MigrationService = class {
28492
28977
  * ICON deposit transaction and `dstChainTxHash` is the hub-side packet receipt.
28493
28978
  */
28494
28979
  async migrateBaln(_params) {
28495
- const { timeout } = _params;
28496
- const baseCtx = { srcChainKey: ChainKeys.ICON_MAINNET, action: "migrateBaln" };
28497
- try {
28498
- const txResult = await this.createMigrateBalnIntent(_params);
28499
- if (!txResult.ok) return { ok: false, error: txResult.error };
28500
- const { tx, relayData } = txResult.value;
28501
- const packetResult = await relayTxAndWaitPacket({
28502
- srcTxHash: tx,
28503
- data: relayData,
28504
- chainKey: ChainKeys.ICON_MAINNET,
28505
- relayerApiEndpoint: this.relayerApiEndpoint,
28506
- timeout
28507
- });
28508
- if (!packetResult.ok) {
28509
- return {
28510
- ok: false,
28511
- error: mapRelayFailure(packetResult.error, {
28512
- feature: "migration",
28513
- action: baseCtx.action,
28514
- srcChainKey: baseCtx.srcChainKey
28515
- })
28516
- };
28980
+ return this.config.analytics.trackResult(
28981
+ "migration",
28982
+ "migrateBaln",
28983
+ async () => {
28984
+ const { timeout } = _params;
28985
+ const baseCtx = { srcChainKey: ChainKeys.ICON_MAINNET, action: "migrateBaln" };
28986
+ try {
28987
+ const txResult = await this.createMigrateBalnIntent(_params);
28988
+ if (!txResult.ok) return { ok: false, error: txResult.error };
28989
+ const { tx, relayData } = txResult.value;
28990
+ const packetResult = await relayTxAndWaitPacket({
28991
+ srcTxHash: tx,
28992
+ data: relayData,
28993
+ chainKey: ChainKeys.ICON_MAINNET,
28994
+ relayerApiEndpoint: this.relayerApiEndpoint,
28995
+ timeout
28996
+ });
28997
+ if (!packetResult.ok) {
28998
+ return {
28999
+ ok: false,
29000
+ error: mapRelayFailure(packetResult.error, {
29001
+ feature: "migration",
29002
+ action: baseCtx.action,
29003
+ srcChainKey: baseCtx.srcChainKey
29004
+ })
29005
+ };
29006
+ }
29007
+ return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
29008
+ } catch (error) {
29009
+ if (isMigrateOrchestrationError(error)) return { ok: false, error };
29010
+ return {
29011
+ ok: false,
29012
+ error: executionFailed("migration", error, baseCtx)
29013
+ };
29014
+ }
29015
+ },
29016
+ {
29017
+ start: () => ({
29018
+ srcChainKey: _params.params.srcChainKey,
29019
+ srcAddress: _params.params.srcAddress,
29020
+ dstAddress: _params.params.dstAddress,
29021
+ amount: _params.params.amount,
29022
+ lockupPeriod: _params.params.lockupPeriod,
29023
+ stake: _params.params.stake
29024
+ }),
29025
+ success: (value) => ({
29026
+ srcChainTxHash: value.srcChainTxHash,
29027
+ dstChainTxHash: value.dstChainTxHash
29028
+ }),
29029
+ failure: (error) => ({ code: error.code })
28517
29030
  }
28518
- return { ok: true, value: { srcChainTxHash: tx, dstChainTxHash: packetResult.value.dst_tx_hash } };
28519
- } catch (error) {
28520
- if (isMigrateOrchestrationError(error)) return { ok: false, error };
28521
- return {
28522
- ok: false,
28523
- error: executionFailed("migration", error, baseCtx)
28524
- };
28525
- }
29031
+ );
28526
29032
  }
28527
29033
  /**
28528
29034
  * Builds and submits the spoke-side deposit for a BALN→SODA migration without relaying.
@@ -29576,49 +30082,71 @@ var BridgeService = class {
29576
30082
  * }
29577
30083
  */
29578
30084
  async bridge(_params) {
29579
- const { params, timeout } = _params;
29580
- const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
29581
- try {
29582
- const txResult = await this.createBridgeIntent(_params);
29583
- if (!txResult.ok) return { ok: false, error: txResult.error };
29584
- const verifyTxHashResult = await this.spoke.verifyTxHash({
29585
- txHash: txResult.value.tx,
29586
- chainKey: params.srcChainKey
29587
- });
29588
- if (!verifyTxHashResult.ok) {
29589
- return {
29590
- ok: false,
29591
- error: verifyFailed("bridge", verifyTxHashResult.error, baseCtx)
29592
- };
30085
+ return this.config.analytics.trackResult(
30086
+ "bridge",
30087
+ "bridge",
30088
+ async () => {
30089
+ const { params, timeout } = _params;
30090
+ const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
30091
+ try {
30092
+ const txResult = await this.createBridgeIntent(_params);
30093
+ if (!txResult.ok) return { ok: false, error: txResult.error };
30094
+ const verifyTxHashResult = await this.spoke.verifyTxHash({
30095
+ txHash: txResult.value.tx,
30096
+ chainKey: params.srcChainKey
30097
+ });
30098
+ if (!verifyTxHashResult.ok) {
30099
+ return {
30100
+ ok: false,
30101
+ error: verifyFailed("bridge", verifyTxHashResult.error, baseCtx)
30102
+ };
30103
+ }
30104
+ const packetResult = await relayTxAndWaitPacket({
30105
+ srcTxHash: txResult.value.tx,
30106
+ data: txResult.value.relayData,
30107
+ chainKey: params.srcChainKey,
30108
+ relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
30109
+ timeout
30110
+ });
30111
+ if (!packetResult.ok)
30112
+ return {
30113
+ ok: false,
30114
+ error: mapRelayFailure(packetResult.error, {
30115
+ feature: "bridge",
30116
+ action: "bridge",
30117
+ srcChainKey: baseCtx.srcChainKey,
30118
+ dstChainKey: baseCtx.dstChainKey
30119
+ })
30120
+ };
30121
+ return {
30122
+ ok: true,
30123
+ value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packetResult.value.dst_tx_hash }
30124
+ };
30125
+ } catch (error) {
30126
+ if (isBridgeOrchestrationError(error)) return { ok: false, error };
30127
+ return {
30128
+ ok: false,
30129
+ error: executionFailed("bridge", error, baseCtx)
30130
+ };
30131
+ }
30132
+ },
30133
+ {
30134
+ start: () => ({
30135
+ srcChainKey: _params.params.srcChainKey,
30136
+ dstChainKey: _params.params.dstChainKey,
30137
+ srcToken: _params.params.srcToken,
30138
+ dstToken: _params.params.dstToken,
30139
+ amount: _params.params.amount,
30140
+ srcAddress: _params.params.srcAddress,
30141
+ recipient: _params.params.recipient
30142
+ }),
30143
+ success: (value) => ({
30144
+ srcChainTxHash: value.srcChainTxHash,
30145
+ dstChainTxHash: value.dstChainTxHash
30146
+ }),
30147
+ failure: (error) => ({ code: error.code })
29593
30148
  }
29594
- const packetResult = await relayTxAndWaitPacket({
29595
- srcTxHash: txResult.value.tx,
29596
- data: txResult.value.relayData,
29597
- chainKey: params.srcChainKey,
29598
- relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
29599
- timeout
29600
- });
29601
- if (!packetResult.ok)
29602
- return {
29603
- ok: false,
29604
- error: mapRelayFailure(packetResult.error, {
29605
- feature: "bridge",
29606
- action: "bridge",
29607
- srcChainKey: baseCtx.srcChainKey,
29608
- dstChainKey: baseCtx.dstChainKey
29609
- })
29610
- };
29611
- return {
29612
- ok: true,
29613
- value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packetResult.value.dst_tx_hash }
29614
- };
29615
- } catch (error) {
29616
- if (isBridgeOrchestrationError(error)) return { ok: false, error };
29617
- return {
29618
- ok: false,
29619
- error: executionFailed("bridge", error, baseCtx)
29620
- };
29621
- }
30149
+ );
29622
30150
  }
29623
30151
  /**
29624
30152
  * Submits the spoke-side deposit transaction that initiates a bridge transfer,
@@ -29647,8 +30175,8 @@ var BridgeService = class {
29647
30175
  const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
29648
30176
  try {
29649
30177
  bridgeInvariant(params.amount > 0n, "Amount must be greater than 0", { ...baseCtx, field: "amount" });
29650
- const srcToken = this.config.getSpokeTokenFromOriginalAssetAddress(params.srcChainKey, params.srcToken);
29651
- const dstToken = this.config.getSpokeTokenFromOriginalAssetAddress(params.dstChainKey, params.dstToken);
30178
+ const srcToken = this.resolveBridgeEndpointToken(params.srcChainKey, params.srcToken);
30179
+ const dstToken = this.resolveBridgeEndpointToken(params.dstChainKey, params.dstToken);
29652
30180
  bridgeInvariant(srcToken, `Unsupported spoke chain (${params.srcChainKey}) token: ${params.srcToken}`, {
29653
30181
  ...baseCtx,
29654
30182
  field: "srcToken"
@@ -29716,6 +30244,20 @@ var BridgeService = class {
29716
30244
  };
29717
30245
  }
29718
30246
  }
30247
+ /**
30248
+ * Resolves a bridge endpoint's {@link XToken} descriptor from a chain key + token address.
30249
+ *
30250
+ * Spoke endpoints (and hub-native tokens such as USDC/WETH/S whose on-chain address equals their
30251
+ * hub asset) resolve by original asset address. On the hub a caller may instead hold a hub asset
30252
+ * that has no spoke-token entry under the hub chain — e.g. a partner BTC fee held as the BTC hub
30253
+ * asset, whose only spoke-token entry lives on Bitcoin. Resolve those by hub-asset address so the
30254
+ * Sonic-sourced "withdraw directly" bridge can find the matching vault/decimals.
30255
+ */
30256
+ resolveBridgeEndpointToken(chainKey, token) {
30257
+ const spokeToken = this.config.getSpokeTokenFromOriginalAssetAddress(chainKey, token);
30258
+ if (spokeToken) return spokeToken;
30259
+ return isHubChainKeyType(chainKey) ? this.config.getXTokenFromHubAsset(token) : void 0;
30260
+ }
29719
30261
  /**
29720
30262
  * Encodes the hub-side execution payload for a bridge operation.
29721
30263
  *
@@ -30598,52 +31140,71 @@ var StakingService = class {
30598
31140
  * @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
30599
31141
  */
30600
31142
  async stake(_params) {
30601
- const { params, timeout } = _params;
30602
- const baseCtx = { srcChainKey: params.srcChainKey, action: "stake" };
30603
- try {
30604
- const txResult = await this.createStakeIntent(_params);
30605
- if (!txResult.ok) return { ok: false, error: txResult.error };
30606
- const verifyTxHashResult = await this.spoke.verifyTxHash({
30607
- txHash: txResult.value.tx,
30608
- chainKey: params.srcChainKey
30609
- });
30610
- if (!verifyTxHashResult.ok) {
30611
- return {
30612
- ok: false,
30613
- error: verifyFailed("staking", verifyTxHashResult.error, baseCtx)
30614
- };
30615
- }
30616
- let hubTxHash;
30617
- if (!isHubChainKeyType(params.srcChainKey)) {
30618
- const packetResult = await relayTxAndWaitPacket({
30619
- srcTxHash: txResult.value.tx,
30620
- data: txResult.value.relayData,
30621
- chainKey: params.srcChainKey,
30622
- relayerApiEndpoint: this.relayerApiEndpoint,
30623
- timeout
30624
- });
30625
- if (!packetResult.ok) {
31143
+ return this.config.analytics.trackResult(
31144
+ "staking",
31145
+ "stake",
31146
+ async () => {
31147
+ const { params, timeout } = _params;
31148
+ const baseCtx = { srcChainKey: params.srcChainKey, action: "stake" };
31149
+ try {
31150
+ const txResult = await this.createStakeIntent(_params);
31151
+ if (!txResult.ok) return { ok: false, error: txResult.error };
31152
+ const verifyTxHashResult = await this.spoke.verifyTxHash({
31153
+ txHash: txResult.value.tx,
31154
+ chainKey: params.srcChainKey
31155
+ });
31156
+ if (!verifyTxHashResult.ok) {
31157
+ return {
31158
+ ok: false,
31159
+ error: verifyFailed("staking", verifyTxHashResult.error, baseCtx)
31160
+ };
31161
+ }
31162
+ let hubTxHash;
31163
+ if (!isHubChainKeyType(params.srcChainKey)) {
31164
+ const packetResult = await relayTxAndWaitPacket({
31165
+ srcTxHash: txResult.value.tx,
31166
+ data: txResult.value.relayData,
31167
+ chainKey: params.srcChainKey,
31168
+ relayerApiEndpoint: this.relayerApiEndpoint,
31169
+ timeout
31170
+ });
31171
+ if (!packetResult.ok) {
31172
+ return {
31173
+ ok: false,
31174
+ error: mapRelayFailure(packetResult.error, {
31175
+ feature: "staking",
31176
+ action: baseCtx.action,
31177
+ srcChainKey: baseCtx.srcChainKey
31178
+ })
31179
+ };
31180
+ }
31181
+ hubTxHash = packetResult.value.dst_tx_hash;
31182
+ } else {
31183
+ hubTxHash = txResult.value.tx;
31184
+ }
31185
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
31186
+ } catch (error) {
31187
+ if (isStakeOrchestrationError(error)) return { ok: false, error };
30626
31188
  return {
30627
31189
  ok: false,
30628
- error: mapRelayFailure(packetResult.error, {
30629
- feature: "staking",
30630
- action: baseCtx.action,
30631
- srcChainKey: baseCtx.srcChainKey
30632
- })
31190
+ error: executionFailed("staking", error, baseCtx)
30633
31191
  };
30634
31192
  }
30635
- hubTxHash = packetResult.value.dst_tx_hash;
30636
- } else {
30637
- hubTxHash = txResult.value.tx;
31193
+ },
31194
+ {
31195
+ start: () => ({
31196
+ srcChainKey: _params.params.srcChainKey,
31197
+ srcAddress: _params.params.srcAddress,
31198
+ amount: _params.params.amount,
31199
+ minReceive: _params.params.minReceive
31200
+ }),
31201
+ success: (value) => ({
31202
+ srcChainTxHash: value.srcChainTxHash,
31203
+ dstChainTxHash: value.dstChainTxHash
31204
+ }),
31205
+ failure: (error) => ({ code: error.code })
30638
31206
  }
30639
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
30640
- } catch (error) {
30641
- if (isStakeOrchestrationError(error)) return { ok: false, error };
30642
- return {
30643
- ok: false,
30644
- error: executionFailed("staking", error, baseCtx)
30645
- };
30646
- }
31207
+ );
30647
31208
  }
30648
31209
  /**
30649
31210
  * Submits the stake transaction on the spoke chain without relaying to the hub.
@@ -30748,42 +31309,60 @@ var StakingService = class {
30748
31309
  * @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
30749
31310
  */
30750
31311
  async unstake(_params) {
30751
- const { params, timeout } = _params;
30752
- const baseCtx = { srcChainKey: params.srcChainKey, action: "unstake" };
30753
- try {
30754
- const txResult = await this.createUnstakeIntent(_params);
30755
- if (!txResult.ok) return { ok: false, error: txResult.error };
30756
- let hubTxHash;
30757
- if (!isHubChainKeyType(params.srcChainKey)) {
30758
- const packetResult = await relayTxAndWaitPacket({
30759
- srcTxHash: txResult.value.tx,
30760
- data: txResult.value.relayData,
30761
- chainKey: params.srcChainKey,
30762
- relayerApiEndpoint: this.relayerApiEndpoint,
30763
- timeout
30764
- });
30765
- if (!packetResult.ok) {
31312
+ return this.config.analytics.trackResult(
31313
+ "staking",
31314
+ "unstake",
31315
+ async () => {
31316
+ const { params, timeout } = _params;
31317
+ const baseCtx = { srcChainKey: params.srcChainKey, action: "unstake" };
31318
+ try {
31319
+ const txResult = await this.createUnstakeIntent(_params);
31320
+ if (!txResult.ok) return { ok: false, error: txResult.error };
31321
+ let hubTxHash;
31322
+ if (!isHubChainKeyType(params.srcChainKey)) {
31323
+ const packetResult = await relayTxAndWaitPacket({
31324
+ srcTxHash: txResult.value.tx,
31325
+ data: txResult.value.relayData,
31326
+ chainKey: params.srcChainKey,
31327
+ relayerApiEndpoint: this.relayerApiEndpoint,
31328
+ timeout
31329
+ });
31330
+ if (!packetResult.ok) {
31331
+ return {
31332
+ ok: false,
31333
+ error: mapRelayFailure(packetResult.error, {
31334
+ feature: "staking",
31335
+ action: baseCtx.action,
31336
+ srcChainKey: baseCtx.srcChainKey
31337
+ })
31338
+ };
31339
+ }
31340
+ hubTxHash = packetResult.value.dst_tx_hash;
31341
+ } else {
31342
+ hubTxHash = txResult.value.tx;
31343
+ }
31344
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
31345
+ } catch (error) {
31346
+ if (isStakingOrchestrationError(error)) return { ok: false, error };
30766
31347
  return {
30767
31348
  ok: false,
30768
- error: mapRelayFailure(packetResult.error, {
30769
- feature: "staking",
30770
- action: baseCtx.action,
30771
- srcChainKey: baseCtx.srcChainKey
30772
- })
31349
+ error: executionFailed("staking", error, baseCtx)
30773
31350
  };
30774
31351
  }
30775
- hubTxHash = packetResult.value.dst_tx_hash;
30776
- } else {
30777
- hubTxHash = txResult.value.tx;
31352
+ },
31353
+ {
31354
+ start: () => ({
31355
+ srcChainKey: _params.params.srcChainKey,
31356
+ srcAddress: _params.params.srcAddress,
31357
+ amount: _params.params.amount
31358
+ }),
31359
+ success: (value) => ({
31360
+ srcChainTxHash: value.srcChainTxHash,
31361
+ dstChainTxHash: value.dstChainTxHash
31362
+ }),
31363
+ failure: (error) => ({ code: error.code })
30778
31364
  }
30779
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
30780
- } catch (error) {
30781
- if (isStakingOrchestrationError(error)) return { ok: false, error };
30782
- return {
30783
- ok: false,
30784
- error: executionFailed("staking", error, baseCtx)
30785
- };
30786
- }
31365
+ );
30787
31366
  }
30788
31367
  /**
30789
31368
  * Submits the unstake transaction on the spoke chain without relaying to the hub.
@@ -30879,42 +31458,61 @@ var StakingService = class {
30879
31458
  * @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
30880
31459
  */
30881
31460
  async instantUnstake(_params) {
30882
- const { params, timeout } = _params;
30883
- const baseCtx = { srcChainKey: params.srcChainKey, action: "instantUnstake" };
30884
- try {
30885
- const txResult = await this.createInstantUnstakeIntent(_params);
30886
- if (!txResult.ok) return { ok: false, error: txResult.error };
30887
- let hubTxHash;
30888
- if (!isHubChainKeyType(params.srcChainKey)) {
30889
- const packetResult = await relayTxAndWaitPacket({
30890
- srcTxHash: txResult.value.tx,
30891
- data: txResult.value.relayData,
30892
- chainKey: params.srcChainKey,
30893
- relayerApiEndpoint: this.relayerApiEndpoint,
30894
- timeout
30895
- });
30896
- if (!packetResult.ok) {
31461
+ return this.config.analytics.trackResult(
31462
+ "staking",
31463
+ "instantUnstake",
31464
+ async () => {
31465
+ const { params, timeout } = _params;
31466
+ const baseCtx = { srcChainKey: params.srcChainKey, action: "instantUnstake" };
31467
+ try {
31468
+ const txResult = await this.createInstantUnstakeIntent(_params);
31469
+ if (!txResult.ok) return { ok: false, error: txResult.error };
31470
+ let hubTxHash;
31471
+ if (!isHubChainKeyType(params.srcChainKey)) {
31472
+ const packetResult = await relayTxAndWaitPacket({
31473
+ srcTxHash: txResult.value.tx,
31474
+ data: txResult.value.relayData,
31475
+ chainKey: params.srcChainKey,
31476
+ relayerApiEndpoint: this.relayerApiEndpoint,
31477
+ timeout
31478
+ });
31479
+ if (!packetResult.ok) {
31480
+ return {
31481
+ ok: false,
31482
+ error: mapRelayFailure(packetResult.error, {
31483
+ feature: "staking",
31484
+ action: baseCtx.action,
31485
+ srcChainKey: baseCtx.srcChainKey
31486
+ })
31487
+ };
31488
+ }
31489
+ hubTxHash = packetResult.value.dst_tx_hash;
31490
+ } else {
31491
+ hubTxHash = txResult.value.tx;
31492
+ }
31493
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
31494
+ } catch (error) {
31495
+ if (isStakingOrchestrationError(error)) return { ok: false, error };
30897
31496
  return {
30898
31497
  ok: false,
30899
- error: mapRelayFailure(packetResult.error, {
30900
- feature: "staking",
30901
- action: baseCtx.action,
30902
- srcChainKey: baseCtx.srcChainKey
30903
- })
31498
+ error: executionFailed("staking", error, baseCtx)
30904
31499
  };
30905
31500
  }
30906
- hubTxHash = packetResult.value.dst_tx_hash;
30907
- } else {
30908
- hubTxHash = txResult.value.tx;
31501
+ },
31502
+ {
31503
+ start: () => ({
31504
+ srcChainKey: _params.params.srcChainKey,
31505
+ srcAddress: _params.params.srcAddress,
31506
+ amount: _params.params.amount,
31507
+ minAmount: _params.params.minAmount
31508
+ }),
31509
+ success: (value) => ({
31510
+ srcChainTxHash: value.srcChainTxHash,
31511
+ dstChainTxHash: value.dstChainTxHash
31512
+ }),
31513
+ failure: (error) => ({ code: error.code })
30909
31514
  }
30910
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
30911
- } catch (error) {
30912
- if (isStakingOrchestrationError(error)) return { ok: false, error };
30913
- return {
30914
- ok: false,
30915
- error: executionFailed("staking", error, baseCtx)
30916
- };
30917
- }
31515
+ );
30918
31516
  }
30919
31517
  /**
30920
31518
  * Submits the instant-unstake transaction on the spoke chain without relaying to the hub.
@@ -31022,42 +31620,61 @@ var StakingService = class {
31022
31620
  * @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
31023
31621
  */
31024
31622
  async claim(_params) {
31025
- const { params, timeout } = _params;
31026
- const baseCtx = { srcChainKey: params.srcChainKey, action: "claim" };
31027
- try {
31028
- const txResult = await this.createClaimIntent(_params);
31029
- if (!txResult.ok) return { ok: false, error: txResult.error };
31030
- let hubTxHash;
31031
- if (!isHubChainKeyType(params.srcChainKey)) {
31032
- const packetResult = await relayTxAndWaitPacket({
31033
- srcTxHash: txResult.value.tx,
31034
- data: txResult.value.relayData,
31035
- chainKey: params.srcChainKey,
31036
- relayerApiEndpoint: this.relayerApiEndpoint,
31037
- timeout
31038
- });
31039
- if (!packetResult.ok) {
31623
+ return this.config.analytics.trackResult(
31624
+ "staking",
31625
+ "claim",
31626
+ async () => {
31627
+ const { params, timeout } = _params;
31628
+ const baseCtx = { srcChainKey: params.srcChainKey, action: "claim" };
31629
+ try {
31630
+ const txResult = await this.createClaimIntent(_params);
31631
+ if (!txResult.ok) return { ok: false, error: txResult.error };
31632
+ let hubTxHash;
31633
+ if (!isHubChainKeyType(params.srcChainKey)) {
31634
+ const packetResult = await relayTxAndWaitPacket({
31635
+ srcTxHash: txResult.value.tx,
31636
+ data: txResult.value.relayData,
31637
+ chainKey: params.srcChainKey,
31638
+ relayerApiEndpoint: this.relayerApiEndpoint,
31639
+ timeout
31640
+ });
31641
+ if (!packetResult.ok) {
31642
+ return {
31643
+ ok: false,
31644
+ error: mapRelayFailure(packetResult.error, {
31645
+ feature: "staking",
31646
+ action: baseCtx.action,
31647
+ srcChainKey: baseCtx.srcChainKey
31648
+ })
31649
+ };
31650
+ }
31651
+ hubTxHash = packetResult.value.dst_tx_hash;
31652
+ } else {
31653
+ hubTxHash = txResult.value.tx;
31654
+ }
31655
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
31656
+ } catch (error) {
31657
+ if (isStakingOrchestrationError(error)) return { ok: false, error };
31040
31658
  return {
31041
31659
  ok: false,
31042
- error: mapRelayFailure(packetResult.error, {
31043
- feature: "staking",
31044
- action: baseCtx.action,
31045
- srcChainKey: baseCtx.srcChainKey
31046
- })
31660
+ error: executionFailed("staking", error, baseCtx)
31047
31661
  };
31048
31662
  }
31049
- hubTxHash = packetResult.value.dst_tx_hash;
31050
- } else {
31051
- hubTxHash = txResult.value.tx;
31663
+ },
31664
+ {
31665
+ start: () => ({
31666
+ srcChainKey: _params.params.srcChainKey,
31667
+ srcAddress: _params.params.srcAddress,
31668
+ requestId: _params.params.requestId,
31669
+ amount: _params.params.amount
31670
+ }),
31671
+ success: (value) => ({
31672
+ srcChainTxHash: value.srcChainTxHash,
31673
+ dstChainTxHash: value.dstChainTxHash
31674
+ }),
31675
+ failure: (error) => ({ code: error.code })
31052
31676
  }
31053
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
31054
- } catch (error) {
31055
- if (isStakingOrchestrationError(error)) return { ok: false, error };
31056
- return {
31057
- ok: false,
31058
- error: executionFailed("staking", error, baseCtx)
31059
- };
31060
- }
31677
+ );
31061
31678
  }
31062
31679
  /**
31063
31680
  * Submits the claim transaction on the spoke chain without relaying to the hub.
@@ -31171,42 +31788,60 @@ var StakingService = class {
31171
31788
  * @returns `{ ok: true, value: { srcChainTxHash, dstChainTxHash } }` on success.
31172
31789
  */
31173
31790
  async cancelUnstake(_params) {
31174
- const { params, timeout } = _params;
31175
- const baseCtx = { srcChainKey: params.srcChainKey, action: "cancelUnstake" };
31176
- try {
31177
- const txResult = await this.createCancelUnstakeIntent(_params);
31178
- if (!txResult.ok) return { ok: false, error: txResult.error };
31179
- let hubTxHash;
31180
- if (!isHubChainKeyType(params.srcChainKey)) {
31181
- const packetResult = await relayTxAndWaitPacket({
31182
- srcTxHash: txResult.value.tx,
31183
- data: txResult.value.relayData,
31184
- chainKey: params.srcChainKey,
31185
- relayerApiEndpoint: this.relayerApiEndpoint,
31186
- timeout
31187
- });
31188
- if (!packetResult.ok) {
31791
+ return this.config.analytics.trackResult(
31792
+ "staking",
31793
+ "cancelUnstake",
31794
+ async () => {
31795
+ const { params, timeout } = _params;
31796
+ const baseCtx = { srcChainKey: params.srcChainKey, action: "cancelUnstake" };
31797
+ try {
31798
+ const txResult = await this.createCancelUnstakeIntent(_params);
31799
+ if (!txResult.ok) return { ok: false, error: txResult.error };
31800
+ let hubTxHash;
31801
+ if (!isHubChainKeyType(params.srcChainKey)) {
31802
+ const packetResult = await relayTxAndWaitPacket({
31803
+ srcTxHash: txResult.value.tx,
31804
+ data: txResult.value.relayData,
31805
+ chainKey: params.srcChainKey,
31806
+ relayerApiEndpoint: this.relayerApiEndpoint,
31807
+ timeout
31808
+ });
31809
+ if (!packetResult.ok) {
31810
+ return {
31811
+ ok: false,
31812
+ error: mapRelayFailure(packetResult.error, {
31813
+ feature: "staking",
31814
+ action: baseCtx.action,
31815
+ srcChainKey: baseCtx.srcChainKey
31816
+ })
31817
+ };
31818
+ }
31819
+ hubTxHash = packetResult.value.dst_tx_hash;
31820
+ } else {
31821
+ hubTxHash = txResult.value.tx;
31822
+ }
31823
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
31824
+ } catch (error) {
31825
+ if (isStakingOrchestrationError(error)) return { ok: false, error };
31189
31826
  return {
31190
31827
  ok: false,
31191
- error: mapRelayFailure(packetResult.error, {
31192
- feature: "staking",
31193
- action: baseCtx.action,
31194
- srcChainKey: baseCtx.srcChainKey
31195
- })
31828
+ error: executionFailed("staking", error, baseCtx)
31196
31829
  };
31197
31830
  }
31198
- hubTxHash = packetResult.value.dst_tx_hash;
31199
- } else {
31200
- hubTxHash = txResult.value.tx;
31831
+ },
31832
+ {
31833
+ start: () => ({
31834
+ srcChainKey: _params.params.srcChainKey,
31835
+ srcAddress: _params.params.srcAddress,
31836
+ requestId: _params.params.requestId
31837
+ }),
31838
+ success: (value) => ({
31839
+ srcChainTxHash: value.srcChainTxHash,
31840
+ dstChainTxHash: value.dstChainTxHash
31841
+ }),
31842
+ failure: (error) => ({ code: error.code })
31201
31843
  }
31202
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
31203
- } catch (error) {
31204
- if (isStakingOrchestrationError(error)) return { ok: false, error };
31205
- return {
31206
- ok: false,
31207
- error: executionFailed("staking", error, baseCtx)
31208
- };
31209
- }
31844
+ );
31210
31845
  }
31211
31846
  /**
31212
31847
  * Submits the cancel-unstake transaction on the spoke chain without relaying to the hub.
@@ -32580,34 +33215,56 @@ var ClService = class _ClService {
32580
33215
  * `dstChainTxHash` (hub) once the packet has been confirmed.
32581
33216
  */
32582
33217
  async supplyLiquidity(_params) {
32583
- const { params, timeout } = _params;
32584
- try {
32585
- const txResult = await this.executeSupplyLiquidity(_params);
32586
- if (!txResult.ok) {
32587
- return txResult;
32588
- }
32589
- let hubTxHash;
32590
- if (!isHubChainKeyType(params.srcChainKey)) {
32591
- const packetResult = await relayTxAndWaitPacket({
32592
- srcTxHash: txResult.value.tx,
32593
- data: txResult.value.relayData,
32594
- chainKey: params.srcChainKey,
32595
- relayerApiEndpoint: this.relayerApiEndpoint,
32596
- timeout
32597
- });
32598
- if (!packetResult.ok) return packetResult;
32599
- hubTxHash = packetResult.value.dst_tx_hash;
32600
- } else {
32601
- hubTxHash = txResult.value.tx;
33218
+ return this.config.analytics.trackResult(
33219
+ "dex",
33220
+ "supplyLiquidity",
33221
+ async () => {
33222
+ const { params, timeout } = _params;
33223
+ try {
33224
+ const txResult = await this.executeSupplyLiquidity(_params);
33225
+ if (!txResult.ok) {
33226
+ return txResult;
33227
+ }
33228
+ let hubTxHash;
33229
+ if (!isHubChainKeyType(params.srcChainKey)) {
33230
+ const packetResult = await relayTxAndWaitPacket({
33231
+ srcTxHash: txResult.value.tx,
33232
+ data: txResult.value.relayData,
33233
+ chainKey: params.srcChainKey,
33234
+ relayerApiEndpoint: this.relayerApiEndpoint,
33235
+ timeout
33236
+ });
33237
+ if (!packetResult.ok) return packetResult;
33238
+ hubTxHash = packetResult.value.dst_tx_hash;
33239
+ } else {
33240
+ hubTxHash = txResult.value.tx;
33241
+ }
33242
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
33243
+ } catch (error) {
33244
+ this.config.logger.error("supplyLiquidity error", error);
33245
+ return {
33246
+ ok: false,
33247
+ error
33248
+ };
33249
+ }
33250
+ },
33251
+ {
33252
+ start: () => ({
33253
+ srcChainKey: _params.params.srcChainKey,
33254
+ srcAddress: _params.params.srcAddress,
33255
+ currency0: _params.params.poolKey.currency0,
33256
+ currency1: _params.params.poolKey.currency1,
33257
+ fee: _params.params.poolKey.fee,
33258
+ tickLower: _params.params.tickLower,
33259
+ tickUpper: _params.params.tickUpper,
33260
+ liquidity: _params.params.liquidity,
33261
+ amount0Max: _params.params.amount0Max,
33262
+ amount1Max: _params.params.amount1Max
33263
+ }),
33264
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
33265
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
32602
33266
  }
32603
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
32604
- } catch (error) {
32605
- this.config.logger.error("supplyLiquidity error", error);
32606
- return {
32607
- ok: false,
32608
- error
32609
- };
32610
- }
33267
+ );
32611
33268
  }
32612
33269
  /**
32613
33270
  * Add liquidity to an existing position and wait for the cross-chain relay to complete.
@@ -32622,33 +33279,56 @@ var ClService = class _ClService {
32622
33279
  * `dstChainTxHash` (hub) once the packet has been confirmed.
32623
33280
  */
32624
33281
  async increaseLiquidity(_params) {
32625
- const { params, timeout } = _params;
32626
- try {
32627
- const txResult = await this.executeIncreaseLiquidity(_params);
32628
- if (!txResult.ok) {
32629
- return txResult;
32630
- }
32631
- let hubTxHash;
32632
- if (!isHubChainKeyType(params.srcChainKey)) {
32633
- const packetResult = await relayTxAndWaitPacket({
32634
- srcTxHash: txResult.value.tx,
32635
- data: txResult.value.relayData,
32636
- chainKey: params.srcChainKey,
32637
- relayerApiEndpoint: this.relayerApiEndpoint,
32638
- timeout
32639
- });
32640
- if (!packetResult.ok) return packetResult;
32641
- hubTxHash = packetResult.value.dst_tx_hash;
32642
- } else {
32643
- hubTxHash = txResult.value.tx;
33282
+ return this.config.analytics.trackResult(
33283
+ "dex",
33284
+ "increaseLiquidity",
33285
+ async () => {
33286
+ const { params, timeout } = _params;
33287
+ try {
33288
+ const txResult = await this.executeIncreaseLiquidity(_params);
33289
+ if (!txResult.ok) {
33290
+ return txResult;
33291
+ }
33292
+ let hubTxHash;
33293
+ if (!isHubChainKeyType(params.srcChainKey)) {
33294
+ const packetResult = await relayTxAndWaitPacket({
33295
+ srcTxHash: txResult.value.tx,
33296
+ data: txResult.value.relayData,
33297
+ chainKey: params.srcChainKey,
33298
+ relayerApiEndpoint: this.relayerApiEndpoint,
33299
+ timeout
33300
+ });
33301
+ if (!packetResult.ok) return packetResult;
33302
+ hubTxHash = packetResult.value.dst_tx_hash;
33303
+ } else {
33304
+ hubTxHash = txResult.value.tx;
33305
+ }
33306
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
33307
+ } catch (error) {
33308
+ return {
33309
+ ok: false,
33310
+ error
33311
+ };
33312
+ }
33313
+ },
33314
+ {
33315
+ start: () => ({
33316
+ srcChainKey: _params.params.srcChainKey,
33317
+ srcAddress: _params.params.srcAddress,
33318
+ currency0: _params.params.poolKey.currency0,
33319
+ currency1: _params.params.poolKey.currency1,
33320
+ fee: _params.params.poolKey.fee,
33321
+ tokenId: _params.params.tokenId,
33322
+ tickLower: _params.params.tickLower,
33323
+ tickUpper: _params.params.tickUpper,
33324
+ liquidity: _params.params.liquidity,
33325
+ amount0Max: _params.params.amount0Max,
33326
+ amount1Max: _params.params.amount1Max
33327
+ }),
33328
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
33329
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
32644
33330
  }
32645
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
32646
- } catch (error) {
32647
- return {
32648
- ok: false,
32649
- error
32650
- };
32651
- }
33331
+ );
32652
33332
  }
32653
33333
  /**
32654
33334
  * Remove liquidity from an existing position and wait for the cross-chain relay to complete.
@@ -32663,33 +33343,54 @@ var ClService = class _ClService {
32663
33343
  * `dstChainTxHash` (hub) once the packet has been confirmed.
32664
33344
  */
32665
33345
  async decreaseLiquidity(_params) {
32666
- const { params, timeout } = _params;
32667
- try {
32668
- const txResult = await this.executeDecreaseLiquidity(_params);
32669
- if (!txResult.ok) {
32670
- return txResult;
32671
- }
32672
- let hubTxHash;
32673
- if (!isHubChainKeyType(params.srcChainKey)) {
32674
- const packetResult = await relayTxAndWaitPacket({
32675
- srcTxHash: txResult.value.tx,
32676
- data: txResult.value.relayData,
32677
- chainKey: params.srcChainKey,
32678
- relayerApiEndpoint: this.relayerApiEndpoint,
32679
- timeout
32680
- });
32681
- if (!packetResult.ok) return packetResult;
32682
- hubTxHash = packetResult.value.dst_tx_hash;
32683
- } else {
32684
- hubTxHash = txResult.value.tx;
33346
+ return this.config.analytics.trackResult(
33347
+ "dex",
33348
+ "decreaseLiquidity",
33349
+ async () => {
33350
+ const { params, timeout } = _params;
33351
+ try {
33352
+ const txResult = await this.executeDecreaseLiquidity(_params);
33353
+ if (!txResult.ok) {
33354
+ return txResult;
33355
+ }
33356
+ let hubTxHash;
33357
+ if (!isHubChainKeyType(params.srcChainKey)) {
33358
+ const packetResult = await relayTxAndWaitPacket({
33359
+ srcTxHash: txResult.value.tx,
33360
+ data: txResult.value.relayData,
33361
+ chainKey: params.srcChainKey,
33362
+ relayerApiEndpoint: this.relayerApiEndpoint,
33363
+ timeout
33364
+ });
33365
+ if (!packetResult.ok) return packetResult;
33366
+ hubTxHash = packetResult.value.dst_tx_hash;
33367
+ } else {
33368
+ hubTxHash = txResult.value.tx;
33369
+ }
33370
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
33371
+ } catch (error) {
33372
+ return {
33373
+ ok: false,
33374
+ error
33375
+ };
33376
+ }
33377
+ },
33378
+ {
33379
+ start: () => ({
33380
+ srcChainKey: _params.params.srcChainKey,
33381
+ srcAddress: _params.params.srcAddress,
33382
+ currency0: _params.params.poolKey.currency0,
33383
+ currency1: _params.params.poolKey.currency1,
33384
+ fee: _params.params.poolKey.fee,
33385
+ tokenId: _params.params.tokenId,
33386
+ liquidity: _params.params.liquidity,
33387
+ amount0Min: _params.params.amount0Min,
33388
+ amount1Min: _params.params.amount1Min
33389
+ }),
33390
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
33391
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
32685
33392
  }
32686
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
32687
- } catch (error) {
32688
- return {
32689
- ok: false,
32690
- error
32691
- };
32692
- }
33393
+ );
32693
33394
  }
32694
33395
  /**
32695
33396
  * Fetch the reward configuration stored in the pool's hook contract.
@@ -32841,34 +33542,54 @@ var ClService = class _ClService {
32841
33542
  * `dstChainTxHash` (hub) once the packet has been confirmed.
32842
33543
  */
32843
33544
  async claimRewards(_params) {
32844
- const { params, timeout } = _params;
32845
- try {
32846
- const txResult = await this.executeClaimRewards(_params);
32847
- if (!txResult.ok) {
32848
- return txResult;
32849
- }
32850
- let hubTxHash;
32851
- if (!isHubChainKeyType(params.srcChainKey)) {
32852
- const packetResult = await relayTxAndWaitPacket({
32853
- srcTxHash: txResult.value.tx,
32854
- data: txResult.value.relayData,
32855
- chainKey: params.srcChainKey,
32856
- relayerApiEndpoint: this.relayerApiEndpoint,
32857
- timeout
32858
- });
32859
- if (!packetResult.ok) return packetResult;
32860
- hubTxHash = packetResult.value.dst_tx_hash;
32861
- } else {
32862
- hubTxHash = txResult.value.tx;
33545
+ return this.config.analytics.trackResult(
33546
+ "dex",
33547
+ "claimRewards",
33548
+ async () => {
33549
+ const { params, timeout } = _params;
33550
+ try {
33551
+ const txResult = await this.executeClaimRewards(_params);
33552
+ if (!txResult.ok) {
33553
+ return txResult;
33554
+ }
33555
+ let hubTxHash;
33556
+ if (!isHubChainKeyType(params.srcChainKey)) {
33557
+ const packetResult = await relayTxAndWaitPacket({
33558
+ srcTxHash: txResult.value.tx,
33559
+ data: txResult.value.relayData,
33560
+ chainKey: params.srcChainKey,
33561
+ relayerApiEndpoint: this.relayerApiEndpoint,
33562
+ timeout
33563
+ });
33564
+ if (!packetResult.ok) return packetResult;
33565
+ hubTxHash = packetResult.value.dst_tx_hash;
33566
+ } else {
33567
+ hubTxHash = txResult.value.tx;
33568
+ }
33569
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
33570
+ } catch (error) {
33571
+ this.config.logger.error("claimRewards error", error);
33572
+ return {
33573
+ ok: false,
33574
+ error
33575
+ };
33576
+ }
33577
+ },
33578
+ {
33579
+ start: () => ({
33580
+ srcChainKey: _params.params.srcChainKey,
33581
+ srcAddress: _params.params.srcAddress,
33582
+ currency0: _params.params.poolKey.currency0,
33583
+ currency1: _params.params.poolKey.currency1,
33584
+ fee: _params.params.poolKey.fee,
33585
+ tokenId: _params.params.tokenId,
33586
+ tickLower: _params.params.tickLower,
33587
+ tickUpper: _params.params.tickUpper
33588
+ }),
33589
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
33590
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
32863
33591
  }
32864
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: hubTxHash } };
32865
- } catch (error) {
32866
- this.config.logger.error("claimRewards error", error);
32867
- return {
32868
- ok: false,
32869
- error
32870
- };
32871
- }
33592
+ );
32872
33593
  }
32873
33594
  /**
32874
33595
  * Return the list of configured concentrated-liquidity pool keys for the SODAX DEX.
@@ -35791,50 +36512,68 @@ var MoneyMarketService = class _MoneyMarketService {
35791
36512
  * @returns A pair of transaction hashes — `srcChainTxHash` (spoke) and `dstChainTxHash` (hub).
35792
36513
  */
35793
36514
  async supply(_params) {
35794
- const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
35795
- const srcChainKey = params.srcChainKey;
35796
- const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "supply" };
35797
- try {
35798
- const txResult = await this.createSupplyIntent(_params);
35799
- if (!txResult.ok) return { ok: false, error: txResult.error };
35800
- const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
35801
- if (!verify.ok) {
35802
- return {
35803
- ok: false,
35804
- error: verifyFailed("moneyMarket", verify.error, baseCtx)
35805
- };
35806
- }
35807
- if (isHubChainKeyType(srcChainKey)) {
35808
- return {
35809
- ok: true,
35810
- value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
35811
- };
36515
+ return this.config.analytics.trackResult(
36516
+ "moneyMarket",
36517
+ "supply",
36518
+ async () => {
36519
+ const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
36520
+ const srcChainKey = params.srcChainKey;
36521
+ const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "supply" };
36522
+ try {
36523
+ const txResult = await this.createSupplyIntent(_params);
36524
+ if (!txResult.ok) return { ok: false, error: txResult.error };
36525
+ const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
36526
+ if (!verify.ok) {
36527
+ return {
36528
+ ok: false,
36529
+ error: verifyFailed("moneyMarket", verify.error, baseCtx)
36530
+ };
36531
+ }
36532
+ if (isHubChainKeyType(srcChainKey)) {
36533
+ return {
36534
+ ok: true,
36535
+ value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
36536
+ };
36537
+ }
36538
+ const packet = await relayTxAndWaitPacket({
36539
+ srcTxHash: txResult.value.tx,
36540
+ data: txResult.value.relayData,
36541
+ chainKey: srcChainKey,
36542
+ relayerApiEndpoint: this.relayerApiEndpoint,
36543
+ timeout
36544
+ });
36545
+ if (!packet.ok)
36546
+ return {
36547
+ ok: false,
36548
+ error: mapRelayFailure(packet.error, {
36549
+ feature: "moneyMarket",
36550
+ action: baseCtx.action,
36551
+ srcChainKey: baseCtx.srcChainKey,
36552
+ dstChainKey: baseCtx.dstChainKey
36553
+ })
36554
+ };
36555
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
36556
+ } catch (error) {
36557
+ if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
36558
+ return {
36559
+ ok: false,
36560
+ error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
36561
+ };
36562
+ }
36563
+ },
36564
+ {
36565
+ start: () => ({
36566
+ srcChainKey: _params.params.srcChainKey,
36567
+ srcAddress: _params.params.srcAddress,
36568
+ dstChainKey: _params.params.dstChainKey,
36569
+ dstAddress: _params.params.dstAddress,
36570
+ token: _params.params.token,
36571
+ amount: _params.params.amount
36572
+ }),
36573
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
36574
+ failure: (error) => ({ code: error.code })
35812
36575
  }
35813
- const packet = await relayTxAndWaitPacket({
35814
- srcTxHash: txResult.value.tx,
35815
- data: txResult.value.relayData,
35816
- chainKey: srcChainKey,
35817
- relayerApiEndpoint: this.relayerApiEndpoint,
35818
- timeout
35819
- });
35820
- if (!packet.ok)
35821
- return {
35822
- ok: false,
35823
- error: mapRelayFailure(packet.error, {
35824
- feature: "moneyMarket",
35825
- action: baseCtx.action,
35826
- srcChainKey: baseCtx.srcChainKey,
35827
- dstChainKey: baseCtx.dstChainKey
35828
- })
35829
- };
35830
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
35831
- } catch (error) {
35832
- if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
35833
- return {
35834
- ok: false,
35835
- error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
35836
- };
35837
- }
36576
+ );
35838
36577
  }
35839
36578
  /**
35840
36579
  * Build and optionally broadcast the spoke-side supply transaction without waiting for the
@@ -35951,58 +36690,76 @@ var MoneyMarketService = class _MoneyMarketService {
35951
36690
  * `dstChainTxHash` (hub delivery or relay destination).
35952
36691
  */
35953
36692
  async borrow(_params) {
35954
- const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
35955
- const srcChainKey = params.srcChainKey;
35956
- const hubChainId = this.hubProvider.chainConfig.chain.key;
35957
- const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "borrow" };
35958
- try {
35959
- const txResult = await this.createBorrowIntent(_params);
35960
- if (!txResult.ok) return { ok: false, error: txResult.error };
35961
- const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
35962
- if (!verify.ok) {
35963
- return {
35964
- ok: false,
35965
- error: verifyFailed("moneyMarket", verify.error, baseCtx)
35966
- };
35967
- }
35968
- const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId;
35969
- if (!needsRelay) {
35970
- return {
35971
- ok: true,
35972
- value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
35973
- };
35974
- }
35975
- const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
35976
- const packet = await relayTxAndWaitPacket({
35977
- ...relayIdentity,
35978
- chainKey: srcChainKey,
35979
- relayerApiEndpoint: this.relayerApiEndpoint,
35980
- timeout
35981
- });
35982
- if (!packet.ok)
35983
- return {
35984
- ok: false,
35985
- error: mapRelayFailure(packet.error, {
35986
- feature: "moneyMarket",
35987
- action: baseCtx.action,
35988
- srcChainKey: baseCtx.srcChainKey,
35989
- dstChainKey: baseCtx.dstChainKey
35990
- })
35991
- };
35992
- return {
35993
- ok: true,
35994
- value: {
35995
- srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
35996
- dstChainTxHash: packet.value.dst_tx_hash
36693
+ return this.config.analytics.trackResult(
36694
+ "moneyMarket",
36695
+ "borrow",
36696
+ async () => {
36697
+ const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
36698
+ const srcChainKey = params.srcChainKey;
36699
+ const hubChainId = this.hubProvider.chainConfig.chain.key;
36700
+ const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "borrow" };
36701
+ try {
36702
+ const txResult = await this.createBorrowIntent(_params);
36703
+ if (!txResult.ok) return { ok: false, error: txResult.error };
36704
+ const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
36705
+ if (!verify.ok) {
36706
+ return {
36707
+ ok: false,
36708
+ error: verifyFailed("moneyMarket", verify.error, baseCtx)
36709
+ };
36710
+ }
36711
+ const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId;
36712
+ if (!needsRelay) {
36713
+ return {
36714
+ ok: true,
36715
+ value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
36716
+ };
36717
+ }
36718
+ const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
36719
+ const packet = await relayTxAndWaitPacket({
36720
+ ...relayIdentity,
36721
+ chainKey: srcChainKey,
36722
+ relayerApiEndpoint: this.relayerApiEndpoint,
36723
+ timeout
36724
+ });
36725
+ if (!packet.ok)
36726
+ return {
36727
+ ok: false,
36728
+ error: mapRelayFailure(packet.error, {
36729
+ feature: "moneyMarket",
36730
+ action: baseCtx.action,
36731
+ srcChainKey: baseCtx.srcChainKey,
36732
+ dstChainKey: baseCtx.dstChainKey
36733
+ })
36734
+ };
36735
+ return {
36736
+ ok: true,
36737
+ value: {
36738
+ srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
36739
+ dstChainTxHash: packet.value.dst_tx_hash
36740
+ }
36741
+ };
36742
+ } catch (error) {
36743
+ if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
36744
+ return {
36745
+ ok: false,
36746
+ error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
36747
+ };
35997
36748
  }
35998
- };
35999
- } catch (error) {
36000
- if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
36001
- return {
36002
- ok: false,
36003
- error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
36004
- };
36005
- }
36749
+ },
36750
+ {
36751
+ start: () => ({
36752
+ srcChainKey: _params.params.srcChainKey,
36753
+ srcAddress: _params.params.srcAddress,
36754
+ dstChainKey: _params.params.dstChainKey,
36755
+ dstAddress: _params.params.dstAddress,
36756
+ token: _params.params.token,
36757
+ amount: _params.params.amount
36758
+ }),
36759
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
36760
+ failure: (error) => ({ code: error.code })
36761
+ }
36762
+ );
36006
36763
  }
36007
36764
  /**
36008
36765
  * Build and optionally broadcast the spoke-side borrow message without waiting for the
@@ -36100,59 +36857,77 @@ var MoneyMarketService = class _MoneyMarketService {
36100
36857
  * `dstChainTxHash` (hub or relay destination).
36101
36858
  */
36102
36859
  async withdraw(_params) {
36103
- const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
36104
- const srcChainKey = params.srcChainKey;
36105
- const hubChainId = this.hubProvider.chainConfig.chain.key;
36106
- const walletRouter = this.hubProvider.chainConfig.addresses.walletRouter;
36107
- const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "withdraw" };
36108
- try {
36109
- const txResult = await this.createWithdrawIntent(_params);
36110
- if (!txResult.ok) return { ok: false, error: txResult.error };
36111
- const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
36112
- if (!verify.ok) {
36113
- return {
36114
- ok: false,
36115
- error: verifyFailed("moneyMarket", verify.error, baseCtx)
36116
- };
36117
- }
36118
- const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId && params.dstAddress !== walletRouter;
36119
- if (!needsRelay) {
36120
- return {
36121
- ok: true,
36122
- value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
36123
- };
36124
- }
36125
- const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
36126
- const packet = await relayTxAndWaitPacket({
36127
- ...relayIdentity,
36128
- chainKey: srcChainKey,
36129
- relayerApiEndpoint: this.relayerApiEndpoint,
36130
- timeout
36131
- });
36132
- if (!packet.ok)
36133
- return {
36134
- ok: false,
36135
- error: mapRelayFailure(packet.error, {
36136
- feature: "moneyMarket",
36137
- action: baseCtx.action,
36138
- srcChainKey: baseCtx.srcChainKey,
36139
- dstChainKey: baseCtx.dstChainKey
36140
- })
36141
- };
36142
- return {
36143
- ok: true,
36144
- value: {
36145
- srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
36146
- dstChainTxHash: packet.value.dst_tx_hash
36860
+ return this.config.analytics.trackResult(
36861
+ "moneyMarket",
36862
+ "withdraw",
36863
+ async () => {
36864
+ const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
36865
+ const srcChainKey = params.srcChainKey;
36866
+ const hubChainId = this.hubProvider.chainConfig.chain.key;
36867
+ const walletRouter = this.hubProvider.chainConfig.addresses.walletRouter;
36868
+ const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "withdraw" };
36869
+ try {
36870
+ const txResult = await this.createWithdrawIntent(_params);
36871
+ if (!txResult.ok) return { ok: false, error: txResult.error };
36872
+ const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
36873
+ if (!verify.ok) {
36874
+ return {
36875
+ ok: false,
36876
+ error: verifyFailed("moneyMarket", verify.error, baseCtx)
36877
+ };
36878
+ }
36879
+ const needsRelay = srcChainKey !== hubChainId || params.dstChainKey != null && params.dstAddress != null && params.dstChainKey !== hubChainId && params.dstAddress !== walletRouter;
36880
+ if (!needsRelay) {
36881
+ return {
36882
+ ok: true,
36883
+ value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
36884
+ };
36885
+ }
36886
+ const relayIdentity = this.buildRelayIdentity(srcChainKey, txResult.value.tx, txResult.value.relayData);
36887
+ const packet = await relayTxAndWaitPacket({
36888
+ ...relayIdentity,
36889
+ chainKey: srcChainKey,
36890
+ relayerApiEndpoint: this.relayerApiEndpoint,
36891
+ timeout
36892
+ });
36893
+ if (!packet.ok)
36894
+ return {
36895
+ ok: false,
36896
+ error: mapRelayFailure(packet.error, {
36897
+ feature: "moneyMarket",
36898
+ action: baseCtx.action,
36899
+ srcChainKey: baseCtx.srcChainKey,
36900
+ dstChainKey: baseCtx.dstChainKey
36901
+ })
36902
+ };
36903
+ return {
36904
+ ok: true,
36905
+ value: {
36906
+ srcChainTxHash: relayIdentity.pollTxHash ?? txResult.value.tx,
36907
+ dstChainTxHash: packet.value.dst_tx_hash
36908
+ }
36909
+ };
36910
+ } catch (error) {
36911
+ if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
36912
+ return {
36913
+ ok: false,
36914
+ error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
36915
+ };
36147
36916
  }
36148
- };
36149
- } catch (error) {
36150
- if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
36151
- return {
36152
- ok: false,
36153
- error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
36154
- };
36155
- }
36917
+ },
36918
+ {
36919
+ start: () => ({
36920
+ srcChainKey: _params.params.srcChainKey,
36921
+ srcAddress: _params.params.srcAddress,
36922
+ dstChainKey: _params.params.dstChainKey,
36923
+ dstAddress: _params.params.dstAddress,
36924
+ token: _params.params.token,
36925
+ amount: _params.params.amount
36926
+ }),
36927
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
36928
+ failure: (error) => ({ code: error.code })
36929
+ }
36930
+ );
36156
36931
  }
36157
36932
  /**
36158
36933
  * Build and optionally broadcast the spoke-side withdraw message without waiting for the
@@ -36248,50 +37023,68 @@ var MoneyMarketService = class _MoneyMarketService {
36248
37023
  * @returns A pair of transaction hashes — `srcChainTxHash` (spoke) and `dstChainTxHash` (hub).
36249
37024
  */
36250
37025
  async repay(_params) {
36251
- const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
36252
- const srcChainKey = params.srcChainKey;
36253
- const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "repay" };
36254
- try {
36255
- const txResult = await this.createRepayIntent(_params);
36256
- if (!txResult.ok) return { ok: false, error: txResult.error };
36257
- const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
36258
- if (!verify.ok) {
36259
- return {
36260
- ok: false,
36261
- error: verifyFailed("moneyMarket", verify.error, baseCtx)
36262
- };
36263
- }
36264
- if (isHubChainKeyType(srcChainKey)) {
36265
- return {
36266
- ok: true,
36267
- value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
36268
- };
37026
+ return this.config.analytics.trackResult(
37027
+ "moneyMarket",
37028
+ "repay",
37029
+ async () => {
37030
+ const { params, timeout = DEFAULT_RELAY_TX_TIMEOUT } = _params;
37031
+ const srcChainKey = params.srcChainKey;
37032
+ const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "repay" };
37033
+ try {
37034
+ const txResult = await this.createRepayIntent(_params);
37035
+ if (!txResult.ok) return { ok: false, error: txResult.error };
37036
+ const verify = await this.spoke.verifyTxHash({ txHash: txResult.value.tx, chainKey: srcChainKey });
37037
+ if (!verify.ok) {
37038
+ return {
37039
+ ok: false,
37040
+ error: verifyFailed("moneyMarket", verify.error, baseCtx)
37041
+ };
37042
+ }
37043
+ if (isHubChainKeyType(srcChainKey)) {
37044
+ return {
37045
+ ok: true,
37046
+ value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: txResult.value.tx }
37047
+ };
37048
+ }
37049
+ const packet = await relayTxAndWaitPacket({
37050
+ srcTxHash: txResult.value.tx,
37051
+ data: txResult.value.relayData,
37052
+ chainKey: srcChainKey,
37053
+ relayerApiEndpoint: this.relayerApiEndpoint,
37054
+ timeout
37055
+ });
37056
+ if (!packet.ok)
37057
+ return {
37058
+ ok: false,
37059
+ error: mapRelayFailure(packet.error, {
37060
+ feature: "moneyMarket",
37061
+ action: baseCtx.action,
37062
+ srcChainKey: baseCtx.srcChainKey,
37063
+ dstChainKey: baseCtx.dstChainKey
37064
+ })
37065
+ };
37066
+ return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
37067
+ } catch (error) {
37068
+ if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
37069
+ return {
37070
+ ok: false,
37071
+ error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
37072
+ };
37073
+ }
37074
+ },
37075
+ {
37076
+ start: () => ({
37077
+ srcChainKey: _params.params.srcChainKey,
37078
+ srcAddress: _params.params.srcAddress,
37079
+ dstChainKey: _params.params.dstChainKey,
37080
+ dstAddress: _params.params.dstAddress,
37081
+ token: _params.params.token,
37082
+ amount: _params.params.amount
37083
+ }),
37084
+ success: (value) => ({ srcChainTxHash: value.srcChainTxHash, dstChainTxHash: value.dstChainTxHash }),
37085
+ failure: (error) => ({ code: error.code })
36269
37086
  }
36270
- const packet = await relayTxAndWaitPacket({
36271
- srcTxHash: txResult.value.tx,
36272
- data: txResult.value.relayData,
36273
- chainKey: srcChainKey,
36274
- relayerApiEndpoint: this.relayerApiEndpoint,
36275
- timeout
36276
- });
36277
- if (!packet.ok)
36278
- return {
36279
- ok: false,
36280
- error: mapRelayFailure(packet.error, {
36281
- feature: "moneyMarket",
36282
- action: baseCtx.action,
36283
- srcChainKey: baseCtx.srcChainKey,
36284
- dstChainKey: baseCtx.dstChainKey
36285
- })
36286
- };
36287
- return { ok: true, value: { srcChainTxHash: txResult.value.tx, dstChainTxHash: packet.value.dst_tx_hash } };
36288
- } catch (error) {
36289
- if (isMoneyMarketOrchestrationError(error)) return { ok: false, error };
36290
- return {
36291
- ok: false,
36292
- error: executionFailed("moneyMarket", error, { ...baseCtx, phase: "intentCreation" })
36293
- };
36294
- }
37087
+ );
36295
37088
  }
36296
37089
  /**
36297
37090
  * Build and optionally broadcast the spoke-side repay transaction without waiting for the
@@ -36992,50 +37785,67 @@ var PartnerFeeClaimService = class {
36992
37785
  * unsigned raw transaction (`raw: true`). Returns an error on failure.
36993
37786
  */
36994
37787
  async setSwapPreference(_params) {
36995
- const { params, walletProvider, raw } = _params;
36996
- try {
36997
- invariant(isHubChainKeyType(params.srcChainKey), "PartnerFeeClaimService only supports Sonic spoke provider");
36998
- invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
36999
- const outputToken = params.dstChainKey !== this.hubProvider.chainConfig.chain.key ? this.hubProvider.config.getSpokeTokenFromOriginalAssetAddress(params.dstChainKey, params.outputToken)?.hubAsset : params.outputToken;
37000
- invariant(
37001
- outputToken,
37002
- `hub asset not found for spoke chain token (params.outputToken): ${params.outputToken} with chain key: ${params.dstChainKey}`
37003
- );
37004
- const rawTx = {
37005
- from: params.srcAddress,
37006
- to: this.protocolIntentsContract,
37007
- value: 0n,
37008
- data: encodeFunctionData({
37009
- abi: ProtocolIntentsAbi,
37010
- functionName: "setAutoSwapPreferences",
37011
- args: [
37788
+ return this.config.analytics.trackResult(
37789
+ "partner",
37790
+ "setSwapPreference",
37791
+ async () => {
37792
+ const { params, walletProvider, raw } = _params;
37793
+ try {
37794
+ invariant(isHubChainKeyType(params.srcChainKey), "PartnerFeeClaimService only supports Sonic spoke provider");
37795
+ invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
37796
+ const outputToken = params.dstChainKey !== this.hubProvider.chainConfig.chain.key ? this.hubProvider.config.getSpokeTokenFromOriginalAssetAddress(params.dstChainKey, params.outputToken)?.hubAsset : params.outputToken;
37797
+ invariant(
37012
37798
  outputToken,
37013
- BigInt(getIntentRelayChainId(params.dstChainKey)),
37014
- encodeAddress(params.dstChainKey, params.dstAddress)
37015
- ]
37016
- })
37017
- };
37018
- if (raw) {
37019
- return {
37020
- ok: true,
37021
- value: rawTx
37022
- };
37799
+ `hub asset not found for spoke chain token (params.outputToken): ${params.outputToken} with chain key: ${params.dstChainKey}`
37800
+ );
37801
+ const rawTx = {
37802
+ from: params.srcAddress,
37803
+ to: this.protocolIntentsContract,
37804
+ value: 0n,
37805
+ data: encodeFunctionData({
37806
+ abi: ProtocolIntentsAbi,
37807
+ functionName: "setAutoSwapPreferences",
37808
+ args: [
37809
+ outputToken,
37810
+ BigInt(getIntentRelayChainId(params.dstChainKey)),
37811
+ encodeAddress(params.dstChainKey, params.dstAddress)
37812
+ ]
37813
+ })
37814
+ };
37815
+ if (raw) {
37816
+ return {
37817
+ ok: true,
37818
+ value: rawTx
37819
+ };
37820
+ }
37821
+ invariant(
37822
+ isEvmWalletProviderType(walletProvider),
37823
+ "PartnerFeeClaimService only supports Evm (sonic) wallet provider"
37824
+ );
37825
+ const txHash = await walletProvider.sendTransaction(rawTx);
37826
+ return {
37827
+ ok: true,
37828
+ value: txHash
37829
+ };
37830
+ } catch (error) {
37831
+ return {
37832
+ ok: false,
37833
+ error
37834
+ };
37835
+ }
37836
+ },
37837
+ {
37838
+ start: () => ({
37839
+ srcChainKey: _params.params.srcChainKey,
37840
+ srcAddress: _params.params.srcAddress,
37841
+ outputToken: _params.params.outputToken,
37842
+ dstChainKey: _params.params.dstChainKey,
37843
+ dstAddress: _params.params.dstAddress
37844
+ }),
37845
+ success: (value) => ({ txHash: value }),
37846
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
37023
37847
  }
37024
- invariant(
37025
- isEvmWalletProviderType(walletProvider),
37026
- "PartnerFeeClaimService only supports Evm (sonic) wallet provider"
37027
- );
37028
- const txHash = await walletProvider.sendTransaction(rawTx);
37029
- return {
37030
- ok: true,
37031
- value: txHash
37032
- };
37033
- } catch (error) {
37034
- return {
37035
- ok: false,
37036
- error
37037
- };
37038
- }
37848
+ );
37039
37849
  }
37040
37850
  /**
37041
37851
  * Checks whether a hub-chain ERC-20 token is already approved for the ProtocolIntents contract.
@@ -37147,6 +37957,11 @@ var PartnerFeeClaimService = class {
37147
37957
  * This is the low-level building block. Use `swap` for the full flow that also waits for
37148
37958
  * the solver to execute the intent.
37149
37959
  *
37960
+ * Guards against same-token intents: if the configured output token equals `fromToken` the solver
37961
+ * cannot fill the swap, so the call is rejected with `VALIDATION_FAILED` before any transaction is
37962
+ * built. The guard fails closed — if the preference lookup fails the call returns that error rather
37963
+ * than submitting an intent that may become unfillable.
37964
+ *
37150
37965
  * @param _params - Action descriptor containing:
37151
37966
  * - `params.srcChainKey` — must be the hub chain key (Sonic).
37152
37967
  * - `params.srcAddress` — partner's EVM address; also used as the intent creator.
@@ -37170,6 +37985,25 @@ var PartnerFeeClaimService = class {
37170
37985
  this.config.solver.protocolIntentsContract,
37171
37986
  "protocolIntentsContract is not configured in solver config"
37172
37987
  );
37988
+ const prefs = await this.getAutoSwapPreferences(params.srcAddress);
37989
+ if (!prefs.ok) return prefs;
37990
+ if (prefs.value.outputToken.toLowerCase() === params.fromToken.toLowerCase()) {
37991
+ return {
37992
+ ok: false,
37993
+ error: new SodaxError(
37994
+ "VALIDATION_FAILED",
37995
+ "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.",
37996
+ {
37997
+ feature: "partner",
37998
+ context: {
37999
+ action: "createIntentAutoSwap",
38000
+ fromToken: params.fromToken,
38001
+ outputToken: prefs.value.outputToken
38002
+ }
38003
+ }
38004
+ )
38005
+ };
38006
+ }
37173
38007
  const minOutputAmount = 0n;
37174
38008
  const rawTx = {
37175
38009
  from: params.srcAddress,
@@ -37217,47 +38051,218 @@ var PartnerFeeClaimService = class {
37217
38051
  *
37218
38052
  * On failure the `error` is tagged:
37219
38053
  * - `WAIT_INTENT_AUTO_SWAP_FAILED` — transaction was submitted but receipt polling failed.
37220
- * - Error from `createIntentAutoSwap` — if the initial submission failed.
38054
+ * - Error from `createIntentAutoSwap` — if the initial submission failed, including
38055
+ * `VALIDATION_FAILED` when the output token equals the fee token (same-token guard) or the
38056
+ * preference lookup that backs the guard fails.
37221
38057
  * - Error from `SolverApiService.postExecution` — if the solver notification failed.
37222
38058
  */
37223
38059
  async swap(_params) {
37224
- try {
37225
- const txHash = await this.createIntentAutoSwap(_params);
37226
- if (!txHash.ok) {
37227
- return txHash;
38060
+ return this.config.analytics.trackResult(
38061
+ "partner",
38062
+ "swap",
38063
+ async () => {
38064
+ try {
38065
+ const txHash = await this.createIntentAutoSwap(_params);
38066
+ if (!txHash.ok) {
38067
+ return txHash;
38068
+ }
38069
+ let intentTxHash;
38070
+ try {
38071
+ const receipt = await this.hubProvider.publicClient.waitForTransactionReceipt({ hash: txHash.value });
38072
+ intentTxHash = receipt.transactionHash;
38073
+ } catch (error) {
38074
+ return {
38075
+ ok: false,
38076
+ error: new SodaxError(
38077
+ "EXECUTION_FAILED",
38078
+ error instanceof Error ? error.message : "waitIntentAutoSwap failed",
38079
+ { feature: "partner", cause: error, context: { action: "waitAutoSwap", phase: "execution" } }
38080
+ )
38081
+ };
38082
+ }
38083
+ const solverExecutionResponse = await SolverApiService.postExecution(
38084
+ { intent_tx_hash: intentTxHash },
38085
+ this.config.solver,
38086
+ this.config.logger
38087
+ );
38088
+ if (!solverExecutionResponse.ok) {
38089
+ return solverExecutionResponse;
38090
+ }
38091
+ return {
38092
+ ok: true,
38093
+ value: {
38094
+ srcTxHash: txHash.value,
38095
+ solverExecutionResponse: solverExecutionResponse.value,
38096
+ intentTxHash
38097
+ }
38098
+ };
38099
+ } catch (error) {
38100
+ return { ok: false, error };
38101
+ }
38102
+ },
38103
+ {
38104
+ start: () => ({
38105
+ srcChainKey: _params.params.srcChainKey,
38106
+ srcAddress: _params.params.srcAddress,
38107
+ fromToken: _params.params.fromToken,
38108
+ amount: _params.params.amount
38109
+ }),
38110
+ success: (value) => ({
38111
+ srcTxHash: value.srcTxHash,
38112
+ intentTxHash: value.intentTxHash
38113
+ }),
38114
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
37228
38115
  }
37229
- let intentTxHash;
37230
- try {
37231
- const receipt = await this.hubProvider.publicClient.waitForTransactionReceipt({ hash: txHash.value });
37232
- intentTxHash = receipt.transactionHash;
37233
- } catch (error) {
38116
+ );
38117
+ }
38118
+ /**
38119
+ * Cancels a partner fee-claim auto-swap intent and refunds the input token to the partner.
38120
+ *
38121
+ * This targets the ProtocolIntents contract's own `cancelIntent(fromToken, toToken)`, which is
38122
+ * the only authorized cancel path for partner auto-swap intents: the intent's `creator` is the
38123
+ * ProtocolIntents contract (not the partner), so the generic `SwapService.cancelIntent` reverts
38124
+ * with `Unauthorized()`. ProtocolIntents looks up the caller's intent for the token pair, cancels
38125
+ * it in the main intents contract (as the creator), and transfers the locked `inputAmount` back
38126
+ * to the partner (`msg.sender`).
38127
+ *
38128
+ * Use this to recover funds stuck in an unfillable intent — most commonly a same-token claim
38129
+ * (`fromToken === toToken`) the solver refused to fill (see the guard in {@link swap}).
38130
+ *
38131
+ * @param _params - Action descriptor containing:
38132
+ * - `params.srcChainKey` — must be the hub chain key (Sonic).
38133
+ * - `params.srcAddress` — the partner's EVM address; must match the intent's owner.
38134
+ * - `params.fromToken` — the stuck intent's input (fee) token, hub-chain address.
38135
+ * - `params.toToken` — the stuck intent's output token, hub-chain address.
38136
+ * - `raw` — when `true`, returns the unsigned transaction object instead of submitting it.
38137
+ * - `walletProvider` — required when `raw` is `false`; must be an EVM wallet provider.
38138
+ * @returns A `Result` containing the submitted transaction hash (`raw: false`) or the unsigned
38139
+ * raw transaction (`raw: true`).
38140
+ */
38141
+ async cancelIntent(_params) {
38142
+ return this.config.analytics.trackResult(
38143
+ "partner",
38144
+ "cancelIntent",
38145
+ async () => {
38146
+ const { params } = _params;
38147
+ try {
38148
+ invariant(isHubChainKeyType(params.srcChainKey), "PartnerFeeClaimService only supports Hub srcChainKey");
38149
+ invariant(
38150
+ isOptionalEvmWalletProviderType(_params.walletProvider),
38151
+ "PartnerFeeClaimService only supports Evm wallet provider"
38152
+ );
38153
+ invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
38154
+ const rawTx = {
38155
+ from: params.srcAddress,
38156
+ to: this.protocolIntentsContract,
38157
+ value: 0n,
38158
+ data: encodeFunctionData({
38159
+ abi: ProtocolIntentsAbi,
38160
+ functionName: "cancelIntent",
38161
+ args: [params.fromToken, params.toToken]
38162
+ })
38163
+ };
38164
+ if (_params.raw) {
38165
+ return {
38166
+ ok: true,
38167
+ value: rawTx
38168
+ };
38169
+ }
38170
+ const txHash = await _params.walletProvider.sendTransaction(rawTx);
38171
+ return {
38172
+ ok: true,
38173
+ value: txHash
38174
+ };
38175
+ } catch (error) {
38176
+ return { ok: false, error };
38177
+ }
38178
+ },
38179
+ {
38180
+ start: () => ({
38181
+ srcChainKey: _params.params.srcChainKey,
38182
+ srcAddress: _params.params.srcAddress,
38183
+ fromToken: _params.params.fromToken,
38184
+ toToken: _params.params.toToken
38185
+ }),
38186
+ success: (value) => ({ txHash: value }),
38187
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
38188
+ }
38189
+ );
38190
+ }
38191
+ /**
38192
+ * Returns the stored intent hash for a partner's `(user, fromToken, toToken)` token pair.
38193
+ *
38194
+ * A non-zero hash means an auto-swap intent currently exists for that pair (e.g. an unfilled
38195
+ * same-token claim) and can be cancelled via {@link cancelIntent}. A zero hash
38196
+ * (`0x000…0`) means there is no open intent for the pair.
38197
+ *
38198
+ * @param params.user - The partner's EVM address on Sonic.
38199
+ * @param params.fromToken - Input (fee) token, hub-chain address.
38200
+ * @param params.toToken - Output token, hub-chain address.
38201
+ * @returns A `Result` containing the intent hash, or an `Error` tagged `LOOKUP_FAILED`.
38202
+ */
38203
+ async getUserIntent({ user, fromToken, toToken }) {
38204
+ try {
38205
+ invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
38206
+ const intentHash = await this.hubProvider.publicClient.readContract({
38207
+ address: this.protocolIntentsContract,
38208
+ abi: ProtocolIntentsAbi,
38209
+ functionName: "getUserIntent",
38210
+ args: [user, fromToken, toToken]
38211
+ });
38212
+ return { ok: true, value: intentHash };
38213
+ } catch (error) {
38214
+ return { ok: false, error: lookupFailed("partner", "getUserIntent", error) };
38215
+ }
38216
+ }
38217
+ /**
38218
+ * Reads the full {@link Intent} details for a stored intent hash from the ProtocolIntents contract.
38219
+ *
38220
+ * Useful for displaying a stuck intent before cancelling it — e.g. the locked `inputAmount` and
38221
+ * `inputToken`. Pair with {@link getUserIntent} to resolve the hash from a token pair.
38222
+ *
38223
+ * @param intentHash - The intent hash (from {@link getUserIntent}).
38224
+ * @returns A `Result` containing the `Intent`, or an `Error` tagged `LOOKUP_FAILED`.
38225
+ */
38226
+ async getIntentDetails(intentHash) {
38227
+ try {
38228
+ invariant(this.protocolIntentsContract, "protocolIntentsContract is not configured in solver config");
38229
+ const intent = await this.hubProvider.publicClient.readContract({
38230
+ address: this.protocolIntentsContract,
38231
+ abi: ProtocolIntentsAbi,
38232
+ functionName: "getIntentDetails",
38233
+ args: [intentHash]
38234
+ });
38235
+ if (!this.config.isValidIntentRelayChainId(intent.srcChain) || !this.config.isValidIntentRelayChainId(intent.dstChain)) {
37234
38236
  return {
37235
38237
  ok: false,
37236
- error: new SodaxError(
37237
- "EXECUTION_FAILED",
37238
- error instanceof Error ? error.message : "waitIntentAutoSwap failed",
37239
- { feature: "partner", cause: error, context: { action: "waitAutoSwap", phase: "execution" } }
38238
+ error: lookupFailed(
38239
+ "partner",
38240
+ "getIntentDetails",
38241
+ new Error(`Invalid intent relay chain id: ${intent.srcChain} or ${intent.dstChain}`)
37240
38242
  )
37241
38243
  };
37242
38244
  }
37243
- const solverExecutionResponse = await SolverApiService.postExecution(
37244
- { intent_tx_hash: intentTxHash },
37245
- this.config.solver,
37246
- this.config.logger
37247
- );
37248
- if (!solverExecutionResponse.ok) {
37249
- return solverExecutionResponse;
37250
- }
37251
38245
  return {
37252
38246
  ok: true,
37253
38247
  value: {
37254
- srcTxHash: txHash.value,
37255
- solverExecutionResponse: solverExecutionResponse.value,
37256
- intentTxHash
38248
+ intentId: intent.intentId,
38249
+ creator: intent.creator,
38250
+ inputToken: intent.inputToken,
38251
+ outputToken: intent.outputToken,
38252
+ inputAmount: intent.inputAmount,
38253
+ minOutputAmount: intent.minOutputAmount,
38254
+ deadline: intent.deadline,
38255
+ allowPartialFill: intent.allowPartialFill,
38256
+ srcChain: intent.srcChain,
38257
+ dstChain: intent.dstChain,
38258
+ srcAddress: intent.srcAddress,
38259
+ dstAddress: intent.dstAddress,
38260
+ solver: intent.solver,
38261
+ data: intent.data
37257
38262
  }
37258
38263
  };
37259
38264
  } catch (error) {
37260
- return { ok: false, error };
38265
+ return { ok: false, error: lookupFailed("partner", "getIntentDetails", error) };
37261
38266
  }
37262
38267
  }
37263
38268
  };
@@ -37392,42 +38397,62 @@ var RecoveryService = class {
37392
38397
  * transaction object when `raw: true`, or the broadcast transaction hash when `raw: false`.
37393
38398
  */
37394
38399
  async withdrawHubAsset(_params) {
37395
- const { params } = _params;
37396
- try {
37397
- const hubWallet = await this.hubProvider.getUserHubWalletAddress(params.srcAddress, params.srcChainKey);
37398
- const payload = EvmAssetManagerService.withdrawAssetData(
37399
- {
37400
- token: params.token,
37401
- to: encodeAddress(params.srcChainKey, params.srcAddress),
37402
- amount: params.amount
37403
- },
37404
- this.hubProvider,
37405
- params.srcChainKey
37406
- );
37407
- const coreParams = {
37408
- srcChainKey: params.srcChainKey,
37409
- srcAddress: params.srcAddress,
37410
- dstChainKey: this.hubProvider.chainConfig.chain.key,
37411
- dstAddress: hubWallet,
37412
- payload
37413
- };
37414
- const sendMessageParams = _params.raw ? { ...coreParams, raw: true } : { ...coreParams, raw: false, walletProvider: _params.walletProvider };
37415
- const txResult = await this.spoke.sendMessage(sendMessageParams);
37416
- if (!txResult.ok) return txResult;
37417
- return {
37418
- ok: true,
37419
- value: txResult.value
37420
- };
37421
- } catch (error) {
37422
- return {
37423
- ok: false,
37424
- error: new SodaxError("EXECUTION_FAILED", error instanceof Error ? error.message : "withdrawHubAsset failed", {
37425
- feature: "recovery",
37426
- cause: error,
37427
- context: { action: "withdrawHubAsset", phase: "execution" }
37428
- })
37429
- };
37430
- }
38400
+ return this.config.analytics.trackResult(
38401
+ "recovery",
38402
+ "withdrawHubAsset",
38403
+ async () => {
38404
+ const { params } = _params;
38405
+ try {
38406
+ const hubWallet = await this.hubProvider.getUserHubWalletAddress(params.srcAddress, params.srcChainKey);
38407
+ const payload = EvmAssetManagerService.withdrawAssetData(
38408
+ {
38409
+ token: params.token,
38410
+ to: encodeAddress(params.srcChainKey, params.srcAddress),
38411
+ amount: params.amount
38412
+ },
38413
+ this.hubProvider,
38414
+ params.srcChainKey
38415
+ );
38416
+ const coreParams = {
38417
+ srcChainKey: params.srcChainKey,
38418
+ srcAddress: params.srcAddress,
38419
+ dstChainKey: this.hubProvider.chainConfig.chain.key,
38420
+ dstAddress: hubWallet,
38421
+ payload
38422
+ };
38423
+ const sendMessageParams = _params.raw ? { ...coreParams, raw: true } : {
38424
+ ...coreParams,
38425
+ raw: false,
38426
+ walletProvider: _params.walletProvider
38427
+ };
38428
+ const txResult = await this.spoke.sendMessage(sendMessageParams);
38429
+ if (!txResult.ok) return txResult;
38430
+ return {
38431
+ ok: true,
38432
+ value: txResult.value
38433
+ };
38434
+ } catch (error) {
38435
+ return {
38436
+ ok: false,
38437
+ error: new SodaxError(
38438
+ "EXECUTION_FAILED",
38439
+ error instanceof Error ? error.message : "withdrawHubAsset failed",
38440
+ { feature: "recovery", cause: error, context: { action: "withdrawHubAsset", phase: "execution" } }
38441
+ )
38442
+ };
38443
+ }
38444
+ },
38445
+ {
38446
+ start: () => ({
38447
+ srcChainKey: _params.params.srcChainKey,
38448
+ srcAddress: _params.params.srcAddress,
38449
+ token: _params.params.token,
38450
+ amount: _params.params.amount
38451
+ }),
38452
+ success: (value) => ({ txHash: typeof value === "string" ? value : void 0 }),
38453
+ failure: (error) => ({ code: isSodaxError(error) ? error.code : void 0 })
38454
+ }
38455
+ );
37431
38456
  }
37432
38457
  };
37433
38458
 
@@ -37887,70 +38912,93 @@ var LeverageYieldService = class {
37887
38912
  const { params } = _params;
37888
38913
  const srcChainKey = params.srcChainKey;
37889
38914
  const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "vaultSwap" };
37890
- try {
37891
- const timeout = _params.timeout;
37892
- const createIntentResult = await this.createVaultIntent(_params);
37893
- if (!createIntentResult.ok) {
37894
- return { ok: false, error: createIntentResult.error };
37895
- }
37896
- const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
37897
- const verifyTxHashResult = await this.spoke.verifyTxHash({
37898
- txHash: spokeTxHash,
37899
- chainKey: srcChainKey
37900
- });
37901
- if (!verifyTxHashResult.ok) {
37902
- return {
37903
- ok: false,
37904
- error: verifyFailed("leverageYield", verifyTxHashResult.error, baseCtx)
37905
- };
37906
- }
37907
- let dstIntentTxHash;
37908
- if (isHubChainKeyType(srcChainKey)) {
37909
- dstIntentTxHash = spokeTxHash;
37910
- } else {
37911
- const packet = await relayTxAndWaitPacket({
37912
- srcTxHash: spokeTxHash,
37913
- data: relayData,
37914
- chainKey: srcChainKey,
37915
- relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
37916
- timeout
37917
- });
37918
- if (!packet.ok) {
38915
+ return this.config.analytics.trackResult(
38916
+ "leverageYield",
38917
+ "vaultSwap",
38918
+ async () => {
38919
+ try {
38920
+ const timeout = _params.timeout;
38921
+ const createIntentResult = await this.createVaultIntent(_params);
38922
+ if (!createIntentResult.ok) {
38923
+ return { ok: false, error: createIntentResult.error };
38924
+ }
38925
+ const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
38926
+ const verifyTxHashResult = await this.spoke.verifyTxHash({
38927
+ txHash: spokeTxHash,
38928
+ chainKey: srcChainKey
38929
+ });
38930
+ if (!verifyTxHashResult.ok) {
38931
+ return {
38932
+ ok: false,
38933
+ error: verifyFailed("leverageYield", verifyTxHashResult.error, baseCtx)
38934
+ };
38935
+ }
38936
+ let dstIntentTxHash;
38937
+ if (isHubChainKeyType(srcChainKey)) {
38938
+ dstIntentTxHash = spokeTxHash;
38939
+ } else {
38940
+ const packet = await relayTxAndWaitPacket({
38941
+ srcTxHash: spokeTxHash,
38942
+ data: relayData,
38943
+ chainKey: srcChainKey,
38944
+ relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
38945
+ timeout
38946
+ });
38947
+ if (!packet.ok) {
38948
+ return {
38949
+ ok: false,
38950
+ error: mapRelayFailure(packet.error, { feature: "leverageYield", ...baseCtx })
38951
+ };
38952
+ }
38953
+ dstIntentTxHash = packet.value.dst_tx_hash;
38954
+ }
38955
+ const postExecResult = await this.notifySolver({
38956
+ intent_tx_hash: dstIntentTxHash
38957
+ });
38958
+ if (!postExecResult.ok) {
38959
+ return { ok: false, error: postExecResult.error };
38960
+ }
38961
+ return {
38962
+ ok: true,
38963
+ value: {
38964
+ solverExecutionResponse: postExecResult.value,
38965
+ intent,
38966
+ intentDeliveryInfo: {
38967
+ srcChainKey,
38968
+ srcTxHash: spokeTxHash,
38969
+ srcAddress: params.srcAddress,
38970
+ dstChainKey: params.dstChainKey,
38971
+ dstTxHash: dstIntentTxHash,
38972
+ dstAddress: params.dstAddress
38973
+ }
38974
+ }
38975
+ };
38976
+ } catch (error) {
38977
+ if (isLeverageYieldSwapError(error)) return { ok: false, error };
37919
38978
  return {
37920
38979
  ok: false,
37921
- error: mapRelayFailure(packet.error, { feature: "leverageYield", ...baseCtx })
38980
+ error: unknownFailed("leverageYield", error, baseCtx)
37922
38981
  };
37923
38982
  }
37924
- dstIntentTxHash = packet.value.dst_tx_hash;
37925
- }
37926
- const postExecResult = await this.notifySolver({
37927
- intent_tx_hash: dstIntentTxHash
37928
- });
37929
- if (!postExecResult.ok) {
37930
- return { ok: false, error: postExecResult.error };
38983
+ },
38984
+ {
38985
+ start: () => ({
38986
+ srcChainKey: _params.params.srcChainKey,
38987
+ dstChainKey: _params.params.dstChainKey,
38988
+ srcAddress: _params.params.srcAddress,
38989
+ dstAddress: _params.params.dstAddress,
38990
+ inputToken: _params.params.inputToken,
38991
+ outputToken: _params.params.outputToken,
38992
+ inputAmount: _params.params.inputAmount
38993
+ }),
38994
+ success: (value) => ({
38995
+ intentId: value.intent.intentId,
38996
+ srcTxHash: value.intentDeliveryInfo.srcTxHash,
38997
+ dstTxHash: value.intentDeliveryInfo.dstTxHash
38998
+ }),
38999
+ failure: (error) => ({ code: error.code })
37931
39000
  }
37932
- return {
37933
- ok: true,
37934
- value: {
37935
- solverExecutionResponse: postExecResult.value,
37936
- intent,
37937
- intentDeliveryInfo: {
37938
- srcChainKey,
37939
- srcTxHash: spokeTxHash,
37940
- srcAddress: params.srcAddress,
37941
- dstChainKey: params.dstChainKey,
37942
- dstTxHash: dstIntentTxHash,
37943
- dstAddress: params.dstAddress
37944
- }
37945
- }
37946
- };
37947
- } catch (error) {
37948
- if (isLeverageYieldSwapError(error)) return { ok: false, error };
37949
- return {
37950
- ok: false,
37951
- error: unknownFailed("leverageYield", error, baseCtx)
37952
- };
37953
- }
39001
+ );
37954
39002
  }
37955
39003
  /**
37956
39004
  * Notifies the solver that the vault intent landed on the hub, triggering it to fill.
@@ -38327,6 +39375,7 @@ var Sodax = class {
38327
39375
  // spoke service enabling spoke chain operations
38328
39376
  constructor(options) {
38329
39377
  const logger = resolveLogger(options?.logger);
39378
+ const analytics = resolveAnalytics(options?.analytics);
38330
39379
  const fee = options?.fee;
38331
39380
  this.instanceConfig = options ? mergeSodaxConfig(sodaxConfig, options) : sodaxConfig;
38332
39381
  this.backendApi = new BackendApiService(this.instanceConfig.api, logger);
@@ -38335,6 +39384,7 @@ var Sodax = class {
38335
39384
  config: this.instanceConfig,
38336
39385
  userConfig: options,
38337
39386
  logger,
39387
+ analytics,
38338
39388
  fee
38339
39389
  });
38340
39390
  this.hubProvider = new EvmHubProvider({ config: this.config });
@@ -38416,4 +39466,4 @@ var isPartnerError = isCodeMember(PARTNER_CODES);
38416
39466
  (*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
38417
39467
  */
38418
39468
 
38419
- export { ALLOWANCE_CHECK_CODES, APPROVE_CODES, AssetService, BITCOIN_CHAIN_KEYS, BITCOIN_CHAIN_KEYS_SET, BTC_WALLET_ADDRESS_TYPES, BackendApiService, BalnSwapService, BigIntToHex, BigNumberZeroDecimal, BitcoinSpokeService, BnUSDMigrationService, BridgeService, CHAIN_KEYS, CONFIG_VERSION, CREATE_INTENT_CODES, ChainKeys, ChainTypeArr, ClService, ConfigService, CustomSorobanServer, CustomStellarAccount, DEFAULT_BACKEND_API_ENDPOINT, DEFAULT_BACKEND_API_HEADERS, DEFAULT_BACKEND_API_TIMEOUT, DEFAULT_DEADLINE_OFFSET, DEFAULT_MAX_RETRY, DEFAULT_RELAYER_API_ENDPOINT, DEFAULT_RELAY_TX_TIMEOUT, DEFAULT_RETRY_DELAY_MS, DexService, EVM_CHAIN_ID_TO_KEY, EVM_CHAIN_KEYS, EVM_CHAIN_KEYS_SET, EVM_SPOKE_ONLY_CHAIN_KEYS, EVM_SPOKE_ONLY_CHAIN_KEYS_SET, Erc20Service, Erc4626Service, EvmAssetManagerService, EvmHubProvider, EvmSolverService, EvmSpokeService, EvmVaultTokenService, FEE_PERCENTAGE_SCALE, GAS_ESTIMATION_CODES, HALF_RAY, HALF_WAD, HUB_CHAIN_KEY, HttpRelayError, HubVaultSymbols, ICON_CHAIN_KEYS, ICON_CHAIN_KEYS_SET, ICON_TX_RESULT_WAIT_MAX_RETRY, INJECTIVE_CHAIN_KEYS, INJECTIVE_CHAIN_KEYS_SET, INTENT_CHAIN_IDS, IconSpokeService, IcxMigrationService, Injective20Token, InjectiveSpokeService, IntentCreatedEventAbi, IntentDataType, IntentFilledEventAbi, IntentRelayChainIdToChainKey, IntentsAbi, LOOKUP_CODES, LTV_PRECISION, LendingPoolService, LeverageYieldService, LockupMultiplier, LockupPeriod, LsodaSymbols, LsodaTokens, MAX_UINT256, MigrationService, MintPositionEventAbi, MoneyMarketDataService, MoneyMarketService, NEAR_CHAIN_KEYS, NEAR_CHAIN_KEYS_SET, NEAR_DEFAULT_GAS, NEAR_STORAGE_DEPOSIT, NearSpokeService, PartnerFeeClaimService, PartnerService, Permit2Service, ProtocolIntentsAbi, RAY, RAY_DECIMALS, RELAY_ERROR_CODES, RadfiApiError, RadfiProvider, RecoveryService, RelayChainIdMap, SECONDS_PER_YEAR, SODAX_ERROR_CODES, SODAX_FEATURES, SOLANA_CHAIN_KEYS, SOLANA_CHAIN_KEYS_SET, SONIC_CHAIN_KEYS, SONIC_CHAIN_KEYS_SET, STACKS_CHAIN_KEYS, STACKS_CHAIN_KEYS_SET, STELLAR_CHAIN_KEYS, STELLAR_CHAIN_KEYS_SET, SUI_CHAIN_KEYS, SUI_CHAIN_KEYS_SET, SodaTokens, Sodax, SodaxError, SolanaSpokeService, SolverApiService, SolverIntentErrorCode, SolverIntentStatusCode, SonicSpokeService, SpokeService, StacksSpokeService, StakingLogic, StakingService, StatATokenAddresses, StellarSpokeService, SuiSpokeService, SupportedMigrationTokens, SwapService, USD_DECIMALS, UiPoolDataProviderService, VAULT_TOKEN_DECIMALS, WAD, WAD_RAY_RATIO, WEI_DECIMALS, adjustAmountByFee, allowanceCheckFailed, apiConfig, approveFailed, arbitrumSupportedTokens, assetManagerAbi, avalancheSupportedTokens, balnSwapAbi, baseChainInfo, baseSupportedTokens, binomialApproximatedRayPow, bitcoinSupportedTokens, bnUSDLegacySpokeChainIds, bnUSDLegacyTokens, bridgeConfig, bridgeInvariant, bscSupportedTokens, calcOpReturnOutputVbytes, calculateAllReserveIncentives, calculateAllUserIncentives, calculateAvailableBorrowsMarketReferenceCurrency, calculateCompoundedInterest, calculateCompoundedRate, calculateFeeAmount, calculateHealthFactorFromBalances, calculateHealthFactorFromBalancesBigUnits, calculateLinearInterest, calculatePercentageFeeAmount, clPoolAbi, clPoolManagerAbi, clPositionManagerAbi, clQuoterAbi, clRouterAbi, clTickLensAbi, concentratedLiquidityConfig, connectionAbi, consoleLogger, convertTransactionInstructionToRaw, createInvariant, deepMerge, defaultHookAbi, detectBitcoinAddressType, dexConfig, dexInvariant, dexPools, encodeAddress, encodeBtcPayloadToBytes, encodeContractCalls, erc20Abi, erc4626Abi, estimateBitcoinTxSize, ethereumSupportedTokens, executionFailed, formatBasisPoints, formatEModeCategory, formatEModes, formatPercentage, formatReserve, formatReserveUSD, formatReserves, formatReservesAndIncentives, formatUserSummary, formatUserSummaryAndIncentives, gasEstimationFailed, getAllLegacybnUSDTokens, getAndFormatReserveEModes, getAssetManagerIdl, getAssetManagerProgram, getChainKeyFromRelayChainId, getChainType, getCompoundedBalance, getConcentratedLiquidityConfig, getConnectionIdl, getConnectionProgram, getEvmChainKeyByChainId, getEvmViemChain, getIconAddressBytes, getIntentRelayChainId, getLinearBalance, getMarketReferenceCurrencyAndUsdBalance, getPacket, getProvider, getRandomBytes, getReserveNormalizedIncome, getReservesEModes, getSolanaAddressBytes, getSolverConfig, getStagingSolverTokens, getSupportedSolverTokens, getTransactionPackets, getbnUSDToken, hexToBigInt, hexToSolanaAddress, hubConfig, hyper, hyperevmSupportedTokens, iconSupportedTokens, injectiveSupportedTokens, intentCreationFailed, isBalnMigrateParams, isBitcoinChainKey, isBitcoinChainKeyType, isBitcoinWalletProviderType, isBridgeAllowanceCheckError, isBridgeApproveError, isBridgeCreateIntentError, isBridgeError, isBridgeLookupError, isBridgeOrchestrationError, isCodeMember, isDexError, isEvmChainKey, isEvmChainKeyType, isEvmSpokeChainConfig, isEvmSpokeOnlyChainKey, isEvmSpokeOnlyChainKeyType, isEvmWalletProviderType, isFeatureError, isHubChainKey, isHubChainKeyType, isIconAddress, isIconChainKey, isIconChainKeyType, isIcxCreateRevertMigrationParams, isIcxMigrateParams, isInjectiveChainKey, isInjectiveChainKeyType, isJsonRpcPayloadResponse, isLegacybnUSDChainId, isLegacybnUSDToken, isLeverageYieldAllowanceCheckError, isLeverageYieldApproveError, isLeverageYieldCreateIntentError, isLeverageYieldError, isLeverageYieldLookupError, isLeverageYieldPostExecutionError, isLeverageYieldSwapError, isMigrateOrchestrationError, isMigrationAllowanceCheckError, isMigrationApproveError, isMigrationCreateIntentError, isMigrationError, isMigrationLookupError, isMoneyMarketAllowanceCheckError, isMoneyMarketApproveError, isMoneyMarketCreateIntentError, isMoneyMarketError, isMoneyMarketGasEstimationError, isMoneyMarketOrchestrationError, isNativeToken, isNearChainKey, isNearChainKeyType, isNewbnUSDChainId, isNewbnUSDToken, isOptionalBitcoinWalletProviderType, isOptionalEvmWalletProviderType, isOptionalStellarWalletProviderType, isPartnerError, isPartnerFeeAmount, isPartnerFeePercentage, isPostExecutionError, isRawDestinationParams, isRecoveryError, isResponseAddressType, isResponseSigningType, isRevertMigrationOrchestrationError, isSodaxError, isSolanaChainKey, isSolanaChainKeyType, isSolanaNativeToken, isSonicChainKey, isSonicChainKeyType, isSpokeApproveParamsEvmSpoke, isSpokeApproveParamsHub, isSpokeApproveParamsStellar, isSpokeChainKey, isSpokeIsAllowanceValidParamsEvmSpoke, isSpokeIsAllowanceValidParamsHub, isSpokeIsAllowanceValidParamsStellar, isStacksChainKey, isStacksChainKeyType, isStakeOrchestrationError, isStakingAllowanceCheckError, isStakingApproveError, isStakingCreateIntentError, isStakingError, isStakingInfoFetchError, isStakingOrchestrationError, isStellarChainKey, isStellarChainKeyType, isStellarWalletProviderType, isSubmitSwapTxResponse, isSubmitSwapTxStatusResponse, isSuiChainKey, isSuiChainKeyType, isSupportedBitcoinAddressType, isSwapCreateIntentError, isSwapError, isSwapSupportedToken, isUndefinedOrValidWalletProviderForChainKey, isUnifiedBnUSDMigrateParams, isValidWalletProviderForChainKey, kaiaSupportedTokens, leverageYieldConfig, leverageYieldInvariant, leverageYieldVaults, lightlinkSupportedTokens, lookupFailed, mapRelayFailure, mergeSodaxConfig, messageOf, migrationInvariant, mintPositionParamsAbi, mmInvariant, modifyLiquidityParamsAbi, moneyMarketConfig, moneyMarketReserveAssets, moneyMarketSupportedTokens, nativeToUSD, nearSupportedTokens, newbnUSDSpokeChainIds, normalize, normalizeBN, normalizePsbtToBase64, normalizeSignatureToBase64, normalizedToUsd, optimismSupportedTokens, pancakeSwapInfinityDefaultHookAbi, pancakeSwapInfinityPoolManagerAbi, pancakeSwapInfinityPositionManagerAbi, parseToStroops, parseTokenArrayFromJson, partnerInvariant, permit2Abi, polygonSupportedTokens, poolAbi, poolKeyAbi, randomUint256, rayDiv, rayMul, rayPow, rayToWad, recoveryInvariant, redbellySupportedTokens, relayConfig, relayTxAndWaitPacket, requestAddress, requestJsonRpc, requestSigning, resolveLogger, retry, reverseEncodeAddress, serializeAddressData, silentLogger, sleep, sodaxConfig, sodaxInvariant, solanaSupportedTokens, solverConfig, sonicSupportedTokens, sonicWalletFactoryAbi, spokeAssetManagerAbi, spokeChainConfig, spokeChainKeysSet, stacksSupportedTokens, stagingSwapSupportedTokens, stakedSodaAbi, stakingInvariant, stakingRouterAbi, stataTokenFactoryAbi, stellarSupportedTokens, submitTransaction, suiSupportedTokens, supportedSpokeChains, supportedTokensByChain, swapExactInSingleParamsAbi, swapInvariant, swapSupportedTokens, swapsConfig, uiPoolDataAbi, universalRouterAbi, unknownFailed, usesBip322MessageSigning, valueToBigNumber, valueToZDBigNumber, variableDebtTokenAbi, vaultTokenAbi, verifyFailed, wadToRay, waitForStacksTransaction, waitForTransactionReceipt, waitUntilIntentExecuted, walletFactoryAbi, wrappedSonicAbi };
39469
+ export { ALLOWANCE_CHECK_CODES, APPROVE_CODES, AssetService, BITCOIN_CHAIN_KEYS, BITCOIN_CHAIN_KEYS_SET, BTC_WALLET_ADDRESS_TYPES, BackendApiService, BalnSwapService, BigIntToHex, BigNumberZeroDecimal, BitcoinSpokeService, BnUSDMigrationService, BridgeService, CHAIN_KEYS, CHAIN_LOGO_BASE_URL, CONFIG_VERSION, CREATE_INTENT_CODES, ChainKeys, ChainTypeArr, ClService, ConfigService, CustomSorobanServer, CustomStellarAccount, DEFAULT_BACKEND_API_ENDPOINT, DEFAULT_BACKEND_API_HEADERS, DEFAULT_BACKEND_API_TIMEOUT, DEFAULT_DEADLINE_OFFSET, DEFAULT_MAX_RETRY, DEFAULT_RELAYER_API_ENDPOINT, DEFAULT_RELAY_TX_TIMEOUT, DEFAULT_RETRY_DELAY_MS, DexService, EVM_CHAIN_ID_TO_KEY, EVM_CHAIN_KEYS, EVM_CHAIN_KEYS_SET, EVM_SPOKE_ONLY_CHAIN_KEYS, EVM_SPOKE_ONLY_CHAIN_KEYS_SET, Erc20Service, Erc4626Service, EvmAssetManagerService, EvmHubProvider, EvmSolverService, EvmSpokeService, EvmVaultTokenService, FEE_PERCENTAGE_SCALE, GAS_ESTIMATION_CODES, HALF_RAY, HALF_WAD, HUB_CHAIN_KEY, HookKind, HookService, HttpRelayError, HubVaultSymbols, ICON_CHAIN_KEYS, ICON_CHAIN_KEYS_SET, ICON_TX_RESULT_WAIT_MAX_RETRY, INJECTIVE_CHAIN_KEYS, INJECTIVE_CHAIN_KEYS_SET, INTENT_CHAIN_IDS, IconSpokeService, IcxMigrationService, Injective20Token, InjectiveSpokeService, IntentCreatedEventAbi, IntentDataService, IntentDataType, IntentFilledEventAbi, IntentRelayChainIdToChainKey, IntentsAbi, LOOKUP_CODES, LTV_PRECISION, LendingPoolService, LeverageYieldService, LockupMultiplier, LockupPeriod, LsodaSymbols, LsodaTokens, MAX_UINT256, MigrationService, MintPositionEventAbi, MoneyMarketDataService, MoneyMarketService, NEAR_CHAIN_KEYS, NEAR_CHAIN_KEYS_SET, NEAR_DEFAULT_GAS, NEAR_STORAGE_DEPOSIT, NearSpokeService, PartnerFeeClaimService, PartnerService, Permit2Service, ProtocolIntentsAbi, RAY, RAY_DECIMALS, RELAY_ERROR_CODES, RadfiApiError, RadfiProvider, RecoveryService, RelayChainIdMap, SECONDS_PER_YEAR, SODAX_ERROR_CODES, SODAX_FEATURES, SOLANA_CHAIN_KEYS, SOLANA_CHAIN_KEYS_SET, SONIC_CHAIN_KEYS, SONIC_CHAIN_KEYS_SET, STACKS_CHAIN_KEYS, STACKS_CHAIN_KEYS_SET, STELLAR_CHAIN_KEYS, STELLAR_CHAIN_KEYS_SET, SUI_CHAIN_KEYS, SUI_CHAIN_KEYS_SET, SodaTokens, Sodax, SodaxError, SolanaSpokeService, SolverApiService, SolverIntentErrorCode, SolverIntentStatusCode, SonicSpokeService, SpokeService, StacksSpokeService, StakingLogic, StakingService, StatATokenAddresses, StellarSpokeService, SuiSpokeService, SupportedMigrationTokens, SwapService, USD_DECIMALS, UiPoolDataProviderService, VAULT_TOKEN_DECIMALS, WAD, WAD_RAY_RATIO, WEI_DECIMALS, adjustAmountByFee, allowanceCheckFailed, apiConfig, approveFailed, arbitrumSupportedTokens, assetManagerAbi, avalancheSupportedTokens, balnSwapAbi, baseChainInfo, baseSupportedTokens, binomialApproximatedRayPow, bitcoinSupportedTokens, bnUSDLegacySpokeChainIds, bnUSDLegacyTokens, bridgeConfig, bridgeInvariant, bscSupportedTokens, calcOpReturnOutputVbytes, calculateAllReserveIncentives, calculateAllUserIncentives, calculateAvailableBorrowsMarketReferenceCurrency, calculateCompoundedInterest, calculateCompoundedRate, calculateFeeAmount, calculateHealthFactorFromBalances, calculateHealthFactorFromBalancesBigUnits, calculateLinearInterest, calculatePercentageFeeAmount, clPoolAbi, clPoolManagerAbi, clPositionManagerAbi, clQuoterAbi, clRouterAbi, clTickLensAbi, concentratedLiquidityConfig, connectionAbi, consoleLogger, convertTransactionInstructionToRaw, createInvariant, deepMerge, defaultHookAbi, detectBitcoinAddressType, dexConfig, dexInvariant, dexPools, encodeAddress, encodeBtcPayloadToBytes, encodeContractCalls, erc20Abi, erc4626Abi, estimateBitcoinTxSize, ethereumSupportedTokens, executionFailed, formatBasisPoints, formatEModeCategory, formatEModes, formatPercentage, formatReserve, formatReserveUSD, formatReserves, formatReservesAndIncentives, formatUserSummary, formatUserSummaryAndIncentives, gasEstimationFailed, getAllLegacybnUSDTokens, getAndFormatReserveEModes, getAssetManagerIdl, getAssetManagerProgram, getChainKeyFromRelayChainId, getChainType, getCompoundedBalance, getConcentratedLiquidityConfig, getConnectionIdl, getConnectionProgram, getEvmChainKeyByChainId, getEvmViemChain, getIconAddressBytes, getIntentRelayChainId, getLinearBalance, getMarketReferenceCurrencyAndUsdBalance, getPacket, getProvider, getRandomBytes, getReserveNormalizedIncome, getReservesEModes, getSolanaAddressBytes, getSolverConfig, getSpokeHook, getSpokeHooks, getStagingSolverTokens, getSupportedSolverTokens, getTransactionPackets, getbnUSDToken, hexToBigInt, hexToSolanaAddress, hubConfig, hyper, hyperevmSupportedTokens, iconSupportedTokens, injectiveSupportedTokens, intentCreationFailed, isBalnMigrateParams, isBitcoinChainKey, isBitcoinChainKeyType, isBitcoinWalletProviderType, isBridgeAllowanceCheckError, isBridgeApproveError, isBridgeCreateIntentError, isBridgeError, isBridgeLookupError, isBridgeOrchestrationError, isCodeMember, isDexError, isEvmChainKey, isEvmChainKeyType, isEvmSpokeChainConfig, isEvmSpokeOnlyChainKey, isEvmSpokeOnlyChainKeyType, isEvmWalletProviderType, isFeatureError, isHookSupportedToken, isHubChainKey, isHubChainKeyType, isIconAddress, isIconChainKey, isIconChainKeyType, isIcxCreateRevertMigrationParams, isIcxMigrateParams, isInjectiveChainKey, isInjectiveChainKeyType, isJsonRpcPayloadResponse, isLegacybnUSDChainId, isLegacybnUSDToken, isLeverageYieldAllowanceCheckError, isLeverageYieldApproveError, isLeverageYieldCreateIntentError, isLeverageYieldError, isLeverageYieldLookupError, isLeverageYieldPostExecutionError, isLeverageYieldSwapError, isMigrateOrchestrationError, isMigrationAllowanceCheckError, isMigrationApproveError, isMigrationCreateIntentError, isMigrationError, isMigrationLookupError, isMoneyMarketAllowanceCheckError, isMoneyMarketApproveError, isMoneyMarketCreateIntentError, isMoneyMarketError, isMoneyMarketGasEstimationError, isMoneyMarketOrchestrationError, isNativeToken, isNearChainKey, isNearChainKeyType, isNewbnUSDChainId, isNewbnUSDToken, isOptionalBitcoinWalletProviderType, isOptionalEvmWalletProviderType, isOptionalStellarWalletProviderType, isPartnerError, isPartnerFeeAmount, isPartnerFeePercentage, isPostExecutionError, isRawDestinationParams, isRecoveryError, isResponseAddressType, isResponseSigningType, isRevertMigrationOrchestrationError, isSodaxError, isSolanaChainKey, isSolanaChainKeyType, isSolanaNativeToken, isSonicChainKey, isSonicChainKeyType, isSpokeApproveParamsEvmSpoke, isSpokeApproveParamsHub, isSpokeApproveParamsStellar, isSpokeChainKey, isSpokeIsAllowanceValidParamsEvmSpoke, isSpokeIsAllowanceValidParamsHub, isSpokeIsAllowanceValidParamsStellar, isStacksChainKey, isStacksChainKeyType, isStakeOrchestrationError, isStakingAllowanceCheckError, isStakingApproveError, isStakingCreateIntentError, isStakingError, isStakingInfoFetchError, isStakingOrchestrationError, isStellarChainKey, isStellarChainKeyType, isStellarWalletProviderType, isSubmitSwapTxResponse, isSubmitSwapTxStatusResponse, isSuiChainKey, isSuiChainKeyType, isSupportedBitcoinAddressType, isSwapCreateIntentError, isSwapError, isSwapSupportedToken, isUndefinedOrValidWalletProviderForChainKey, isUnifiedBnUSDMigrateParams, isValidWalletProviderForChainKey, kaiaSupportedTokens, leverageYieldConfig, leverageYieldInvariant, leverageYieldVaults, lightlinkSupportedTokens, lookupFailed, mapRelayFailure, mergeSodaxConfig, messageOf, migrationInvariant, mintPositionParamsAbi, mmInvariant, modifyLiquidityParamsAbi, moneyMarketConfig, moneyMarketReserveAssets, moneyMarketSupportedTokens, nativeToUSD, nearSupportedTokens, newbnUSDSpokeChainIds, noopAnalytics, normalize, normalizeBN, normalizePsbtToBase64, normalizeSignatureToBase64, normalizedToUsd, optimismSupportedTokens, pancakeSwapInfinityDefaultHookAbi, pancakeSwapInfinityPoolManagerAbi, pancakeSwapInfinityPositionManagerAbi, parseToStroops, parseTokenArrayFromJson, partnerInvariant, permit2Abi, polygonSupportedTokens, poolAbi, poolKeyAbi, randomUint256, rayDiv, rayMul, rayPow, rayToWad, recoveryInvariant, redbellySupportedTokens, relayConfig, relayTxAndWaitPacket, requestAddress, requestJsonRpc, requestSigning, resolveAnalytics, resolveLogger, retry, reverseEncodeAddress, serializeAddressData, silentLogger, sleep, sodaxConfig, sodaxInvariant, solanaSupportedTokens, solverConfig, sonicSupportedTokens, sonicWalletFactoryAbi, spokeAssetManagerAbi, spokeChainConfig, spokeChainKeysSet, spokeHooks, stacksSupportedTokens, stagingSwapSupportedTokens, stakedSodaAbi, stakingInvariant, stakingRouterAbi, stataTokenFactoryAbi, stellarSupportedTokens, submitTransaction, suiSupportedTokens, supportedSpokeChains, supportedTokensByChain, swapExactInSingleParamsAbi, swapInvariant, swapSupportedTokens, swapsConfig, uiPoolDataAbi, universalRouterAbi, unknownFailed, usesBip322MessageSigning, valueToBigNumber, valueToZDBigNumber, variableDebtTokenAbi, vaultTokenAbi, verifyFailed, wadToRay, waitForStacksTransaction, waitForTransactionReceipt, waitUntilIntentExecuted, walletFactoryAbi, wrappedSonicAbi };