@sodax/sdk 2.0.0-rc.15 → 2.0.0-rc.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2641,6 +2641,8 @@ var RelayChainIdMap = {
2641
2641
  };
2642
2642
  var INTENT_CHAIN_IDS = Object.values(RelayChainIdMap);
2643
2643
  var IntentRelayChainIdToChainKey = Object.fromEntries(Object.entries(RelayChainIdMap).map(([chainKey, chainId]) => [chainId, chainKey]));
2644
+ var CHAIN_LOGO_BASE_URL = "https://raw.githubusercontent.com/icon-project/sodax-sdks/main/packages/assets/chain";
2645
+ var chainLogo = (key) => `${CHAIN_LOGO_BASE_URL}/${key}.png`;
2644
2646
  var baseChainInfo = {
2645
2647
  [ChainKeys.SONIC_MAINNET]: {
2646
2648
  name: "Sonic",
@@ -2648,6 +2650,7 @@ var baseChainInfo = {
2648
2650
  type: "EVM",
2649
2651
  chainId: 146,
2650
2652
  mainnet: true,
2653
+ logo: chainLogo(ChainKeys.SONIC_MAINNET),
2651
2654
  explorer: {
2652
2655
  baseUrl: "https://sonicscan.org/",
2653
2656
  txUrl: "https://sonicscan.org/tx/",
@@ -2661,6 +2664,7 @@ var baseChainInfo = {
2661
2664
  type: "SOLANA",
2662
2665
  chainId: "solana",
2663
2666
  mainnet: true,
2667
+ logo: chainLogo(ChainKeys.SOLANA_MAINNET),
2664
2668
  explorer: {
2665
2669
  baseUrl: "https://solscan.io/",
2666
2670
  txUrl: "https://solscan.io/tx/",
@@ -2674,6 +2678,7 @@ var baseChainInfo = {
2674
2678
  type: "EVM",
2675
2679
  chainId: 43114,
2676
2680
  mainnet: true,
2681
+ logo: chainLogo(ChainKeys.AVALANCHE_MAINNET),
2677
2682
  explorer: {
2678
2683
  baseUrl: "https://snowtrace.io/",
2679
2684
  txUrl: "https://snowtrace.io/tx/",
@@ -2687,6 +2692,7 @@ var baseChainInfo = {
2687
2692
  type: "EVM",
2688
2693
  chainId: 42161,
2689
2694
  mainnet: true,
2695
+ logo: chainLogo(ChainKeys.ARBITRUM_MAINNET),
2690
2696
  explorer: {
2691
2697
  baseUrl: "https://arbiscan.io/",
2692
2698
  txUrl: "https://arbiscan.io/tx/",
@@ -2700,6 +2706,7 @@ var baseChainInfo = {
2700
2706
  type: "EVM",
2701
2707
  chainId: 8453,
2702
2708
  mainnet: true,
2709
+ logo: chainLogo(ChainKeys.BASE_MAINNET),
2703
2710
  explorer: {
2704
2711
  baseUrl: "https://basescan.org/",
2705
2712
  txUrl: "https://basescan.org/tx/",
@@ -2713,6 +2720,7 @@ var baseChainInfo = {
2713
2720
  type: "EVM",
2714
2721
  chainId: 10,
2715
2722
  mainnet: true,
2723
+ logo: chainLogo(ChainKeys.OPTIMISM_MAINNET),
2716
2724
  explorer: {
2717
2725
  baseUrl: "https://optimistic.etherscan.io/",
2718
2726
  txUrl: "https://optimistic.etherscan.io/tx/",
@@ -2726,6 +2734,7 @@ var baseChainInfo = {
2726
2734
  type: "EVM",
2727
2735
  chainId: 56,
2728
2736
  mainnet: true,
2737
+ logo: chainLogo(ChainKeys.BSC_MAINNET),
2729
2738
  explorer: {
2730
2739
  baseUrl: "https://bscscan.com/",
2731
2740
  txUrl: "https://bscscan.com/tx/",
@@ -2739,6 +2748,7 @@ var baseChainInfo = {
2739
2748
  type: "EVM",
2740
2749
  chainId: 137,
2741
2750
  mainnet: true,
2751
+ logo: chainLogo(ChainKeys.POLYGON_MAINNET),
2742
2752
  explorer: {
2743
2753
  baseUrl: "https://polygonscan.com/",
2744
2754
  txUrl: "https://polygonscan.com/tx/",
@@ -2752,6 +2762,7 @@ var baseChainInfo = {
2752
2762
  type: "EVM",
2753
2763
  chainId: 999,
2754
2764
  mainnet: true,
2765
+ logo: chainLogo(ChainKeys.HYPEREVM_MAINNET),
2755
2766
  explorer: {
2756
2767
  baseUrl: "https://hyperevmscan.io/",
2757
2768
  txUrl: "https://hyperevmscan.io/tx/",
@@ -2765,6 +2776,7 @@ var baseChainInfo = {
2765
2776
  type: "EVM",
2766
2777
  chainId: 1890,
2767
2778
  mainnet: true,
2779
+ logo: chainLogo(ChainKeys.LIGHTLINK_MAINNET),
2768
2780
  explorer: {
2769
2781
  baseUrl: "https://phoenix.lightlink.io/",
2770
2782
  txUrl: "https://phoenix.lightlink.io/tx/",
@@ -2778,6 +2790,7 @@ var baseChainInfo = {
2778
2790
  type: "INJECTIVE",
2779
2791
  chainId: "injective-1",
2780
2792
  mainnet: true,
2793
+ logo: chainLogo(ChainKeys.INJECTIVE_MAINNET),
2781
2794
  explorer: {
2782
2795
  baseUrl: "https://www.mintscan.io/injective/",
2783
2796
  txUrl: "https://www.mintscan.io/injective/tx/",
@@ -2791,6 +2804,7 @@ var baseChainInfo = {
2791
2804
  type: "STELLAR",
2792
2805
  chainId: "stellar",
2793
2806
  mainnet: true,
2807
+ logo: chainLogo(ChainKeys.STELLAR_MAINNET),
2794
2808
  explorer: {
2795
2809
  baseUrl: "https://stellar.expert/explorer/public/",
2796
2810
  txUrl: "https://stellar.expert/explorer/public/tx/",
@@ -2804,6 +2818,7 @@ var baseChainInfo = {
2804
2818
  type: "SUI",
2805
2819
  chainId: "sui",
2806
2820
  mainnet: true,
2821
+ logo: chainLogo(ChainKeys.SUI_MAINNET),
2807
2822
  explorer: {
2808
2823
  baseUrl: "https://suivision.xyz/",
2809
2824
  txUrl: "https://suivision.xyz/txblock/",
@@ -2817,6 +2832,7 @@ var baseChainInfo = {
2817
2832
  type: "ICON",
2818
2833
  chainId: "0x1.icon",
2819
2834
  mainnet: true,
2835
+ logo: chainLogo(ChainKeys.ICON_MAINNET),
2820
2836
  explorer: {
2821
2837
  baseUrl: "https://tracker.icon.community/",
2822
2838
  txUrl: "https://tracker.icon.community/transaction/",
@@ -2830,6 +2846,7 @@ var baseChainInfo = {
2830
2846
  type: "NEAR",
2831
2847
  chainId: "near",
2832
2848
  mainnet: true,
2849
+ logo: chainLogo(ChainKeys.NEAR_MAINNET),
2833
2850
  explorer: {
2834
2851
  baseUrl: "https://nearblocks.io/",
2835
2852
  txUrl: "https://nearblocks.io/txns/",
@@ -2843,6 +2860,7 @@ var baseChainInfo = {
2843
2860
  type: "EVM",
2844
2861
  chainId: 1,
2845
2862
  mainnet: true,
2863
+ logo: chainLogo(ChainKeys.ETHEREUM_MAINNET),
2846
2864
  explorer: {
2847
2865
  baseUrl: "https://etherscan.io/",
2848
2866
  txUrl: "https://etherscan.io/tx/",
@@ -2856,6 +2874,7 @@ var baseChainInfo = {
2856
2874
  type: "BITCOIN",
2857
2875
  chainId: "bitcoin",
2858
2876
  mainnet: true,
2877
+ logo: chainLogo(ChainKeys.BITCOIN_MAINNET),
2859
2878
  explorer: {
2860
2879
  baseUrl: "https://mempool.space/",
2861
2880
  txUrl: "https://mempool.space/tx/",
@@ -2869,6 +2888,7 @@ var baseChainInfo = {
2869
2888
  type: "EVM",
2870
2889
  chainId: 151,
2871
2890
  mainnet: true,
2891
+ logo: chainLogo(ChainKeys.REDBELLY_MAINNET),
2872
2892
  explorer: {
2873
2893
  baseUrl: "https://redbelly.routescan.io/",
2874
2894
  txUrl: "https://redbelly.routescan.io/tx/",
@@ -2882,6 +2902,7 @@ var baseChainInfo = {
2882
2902
  type: "EVM",
2883
2903
  chainId: 8217,
2884
2904
  mainnet: true,
2905
+ logo: chainLogo(ChainKeys.KAIA_MAINNET),
2885
2906
  explorer: {
2886
2907
  baseUrl: "https://klaytnfinder.io/",
2887
2908
  txUrl: "https://klaytnfinder.io/tx/",
@@ -2895,6 +2916,7 @@ var baseChainInfo = {
2895
2916
  type: "STACKS",
2896
2917
  chainId: "stacks",
2897
2918
  mainnet: true,
2919
+ logo: chainLogo(ChainKeys.STACKS_MAINNET),
2898
2920
  explorer: {
2899
2921
  baseUrl: "https://explorer.hiro.so/",
2900
2922
  txUrl: "https://explorer.hiro.so/txid/",
@@ -3886,8 +3908,11 @@ var swapSupportedTokens = {
3886
3908
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.WAL,
3887
3909
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.NAVX
3888
3910
  ],
3889
- // Injective is currently staging-only — see stagingSwapSupportedTokens
3890
- [ChainKeys.INJECTIVE_MAINNET]: [],
3911
+ [ChainKeys.INJECTIVE_MAINNET]: [
3912
+ spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.INJ,
3913
+ spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.bnUSD,
3914
+ spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.USDC
3915
+ ],
3891
3916
  [ChainKeys.NEAR_MAINNET]: [
3892
3917
  spokeChainConfig[ChainKeys.NEAR_MAINNET].supportedTokens.NEAR,
3893
3918
  spokeChainConfig[ChainKeys.NEAR_MAINNET].supportedTokens.bnUSD,
@@ -3976,12 +4001,7 @@ var stagingSwapSupportedTokens = {
3976
4001
  [ChainKeys.ICON_MAINNET]: [],
3977
4002
  [ChainKeys.STELLAR_MAINNET]: [],
3978
4003
  [ChainKeys.SUI_MAINNET]: [spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.USDT],
3979
- [ChainKeys.INJECTIVE_MAINNET]: [
3980
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.INJ,
3981
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.bnUSD,
3982
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.USDC
3983
- // spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.SODA, // NOTE: not in solver wiki
3984
- ],
4004
+ [ChainKeys.INJECTIVE_MAINNET]: [],
3985
4005
  [ChainKeys.NEAR_MAINNET]: [],
3986
4006
  [ChainKeys.BITCOIN_MAINNET]: [],
3987
4007
  [ChainKeys.ETHEREUM_MAINNET]: [
@@ -4087,6 +4107,31 @@ function usesBip322MessageSigning(addressType) {
4087
4107
  var BTC_WALLET_ADDRESS_TYPES = ["taproot", "segwit"];
4088
4108
  var BTC_ADDRESS_TYPES = ["P2PKH", "P2SH", "P2WPKH", "P2TR"];
4089
4109
 
4110
+ // ../types/dist/hooks/hooks.js
4111
+ var HookKind = {
4112
+ /** Deposits delivered USDC into the recipient's HyperCore perps account (HyperEVM). */
4113
+ HYPERCORE_DEPOSIT: "hyperCoreDeposit"
4114
+ };
4115
+ var spokeHooks = {
4116
+ [ChainKeys.HYPEREVM_MAINNET]: [
4117
+ {
4118
+ kind: HookKind.HYPERCORE_DEPOSIT,
4119
+ address: "0xc79224a4DEE653C9a26572B941149d95a88432c4",
4120
+ supportedTokens: [spokeChainConfig[ChainKeys.HYPEREVM_MAINNET].supportedTokens.USDC.address]
4121
+ // USDC on HyperEVM
4122
+ }
4123
+ ]
4124
+ };
4125
+ var getSpokeHook = (chainKey, kind) => spokeHooks[chainKey]?.find((h) => h.kind === kind);
4126
+ var getSpokeHooks = (chainKey) => spokeHooks[chainKey] ?? [];
4127
+ var isHookSupportedToken = (chainKey, kind, token) => {
4128
+ const hook = getSpokeHook(chainKey, kind);
4129
+ if (!hook) {
4130
+ return false;
4131
+ }
4132
+ return !hook.supportedTokens || hook.supportedTokens.some((t) => t.toLowerCase() === token.toLowerCase());
4133
+ };
4134
+
4090
4135
  // ../types/dist/utils/utils.js
4091
4136
  function isHubChainKey(chainId) {
4092
4137
  return chainId === HUB_CHAIN_KEY;
@@ -4201,7 +4246,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
4201
4246
  }
4202
4247
 
4203
4248
  // ../types/dist/index.js
4204
- var CONFIG_VERSION = 213;
4249
+ var CONFIG_VERSION = 215;
4205
4250
  function isEvmSpokeChainConfig(value) {
4206
4251
  return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
4207
4252
  }
@@ -21852,9 +21897,147 @@ var NearSpokeService = class {
21852
21897
 
21853
21898
  // src/shared/types/intent-types.ts
21854
21899
  var IntentDataType = /* @__PURE__ */ ((IntentDataType2) => {
21900
+ IntentDataType2[IntentDataType2["ARRAY"] = 0] = "ARRAY";
21855
21901
  IntentDataType2[IntentDataType2["FEE"] = 1] = "FEE";
21902
+ IntentDataType2[IntentDataType2["HOOK"] = 2] = "HOOK";
21903
+ IntentDataType2[IntentDataType2["DELIVERY"] = 3] = "DELIVERY";
21856
21904
  return IntentDataType2;
21857
21905
  })(IntentDataType || {});
21906
+ var HOOK_DELIVERY_ABI = {
21907
+ // HyperCoreDepositHook expects `abi.encode(address)` — the HyperCore account to credit.
21908
+ [HookKind.HYPERCORE_DEPOSIT]: [{ name: "recipient", type: "address" }]
21909
+ };
21910
+ var HookService = class _HookService {
21911
+ constructor() {
21912
+ }
21913
+ /**
21914
+ * Encodes a hook's `deliveryData` payload. One common entry point for all hooks — the encoding is
21915
+ * selected by {@link HookRequest.kind} and uses that hook's schema from {@link HOOK_DELIVERY_ABI}.
21916
+ *
21917
+ * @param request - The hook selection (and any hook-specific params).
21918
+ * @param recipient - The end recipient the hook should credit (the intent's `dstAddress`).
21919
+ */
21920
+ static encodeDeliveryData(request, recipient) {
21921
+ switch (request.kind) {
21922
+ case HookKind.HYPERCORE_DEPOSIT:
21923
+ return viem.encodeAbiParameters(HOOK_DELIVERY_ABI[HookKind.HYPERCORE_DEPOSIT], [recipient]);
21924
+ }
21925
+ throw new Error(
21926
+ `[HookService.encodeDeliveryData] Unsupported delivery hook kind: ${request.kind}`
21927
+ );
21928
+ }
21929
+ /**
21930
+ * Resolves a high-level {@link HookRequest} to the on-chain delivery pair: the deployed hook address
21931
+ * (becomes the intent's `dstAddress`) and the encoded payload the hook expects (`deliveryData`).
21932
+ * Bundling lookup + codec here guarantees the address and its payload schema can never drift.
21933
+ *
21934
+ * @param chainKey - Destination spoke chain (must have the requested hook deployed).
21935
+ * @param request - The hook selection (and any hook-specific params).
21936
+ * @param recipient - The end recipient the hook should credit (the intent's `dstAddress`).
21937
+ */
21938
+ static resolveDeliveryHook(chainKey, request, recipient) {
21939
+ const hook = getSpokeHook(chainKey, request.kind);
21940
+ invariant(hook, `No '${request.kind}' delivery hook is deployed on chain ${chainKey}`);
21941
+ return { dstAddress: hook.address, deliveryData: _HookService.encodeDeliveryData(request, recipient) };
21942
+ }
21943
+ /**
21944
+ * Resolves the effective delivery target for an intent. When {@link CreateIntentParams.hook} is set,
21945
+ * routes the output through that registered hook (overriding `dstAddress` and deriving `deliveryData`);
21946
+ * otherwise returns the caller's `dstAddress` and low-level `deliveryData` unchanged. Centralised so
21947
+ * both the hub and Sonic intent constructors apply hooks identically.
21948
+ *
21949
+ * @returns `{ dstAddress, deliveryData }` — the address to deliver to and the payload to forward.
21950
+ */
21951
+ static resolveDelivery(params) {
21952
+ if (!params.hook) {
21953
+ return { dstAddress: params.dstAddress, deliveryData: params.deliveryData };
21954
+ }
21955
+ return _HookService.resolveDeliveryHook(params.dstChainKey, params.hook, params.dstAddress);
21956
+ }
21957
+ };
21958
+ var ARRAY_DATA_ABI = [
21959
+ {
21960
+ type: "tuple",
21961
+ components: [
21962
+ {
21963
+ name: "data",
21964
+ type: "tuple[]",
21965
+ components: [
21966
+ { name: "dataType", type: "uint8" },
21967
+ { name: "data", type: "bytes" }
21968
+ ]
21969
+ }
21970
+ ]
21971
+ }
21972
+ ];
21973
+ var IntentDataService = class _IntentDataService {
21974
+ constructor() {
21975
+ }
21976
+ /**
21977
+ * Folds a partner-fee envelope and an optional delivery payload into the final `Intent.data`:
21978
+ * - Neither → `'0x'`.
21979
+ * - Exactly one → that single packed `[uint8 type, bytes payload]` envelope (byte-identical to a
21980
+ * bare fee envelope, so a fee-only intent's `data` is unchanged and stays decode-stable).
21981
+ * - Both → a `TYPE_ARRAY` envelope wrapping `[FEE, DELIVERY]` entries.
21982
+ *
21983
+ * @param feeEnvelope - The packed fee envelope from `EvmSolverService.createIntentFeeData` (`'0x'` if no fee).
21984
+ * @param deliveryData - Opaque delivery payload (e.g. from `HookService.encodeDeliveryData`), or `undefined`.
21985
+ */
21986
+ static composeIntentData(feeEnvelope, deliveryData) {
21987
+ const entries = [];
21988
+ if (feeEnvelope !== "0x") {
21989
+ entries.push({ type: 1 /* FEE */, data: `0x${feeEnvelope.slice(4)}` });
21990
+ }
21991
+ if (deliveryData && deliveryData !== "0x") {
21992
+ entries.push({ type: 3 /* DELIVERY */, data: deliveryData });
21993
+ }
21994
+ return _IntentDataService.encodeIntentData(entries);
21995
+ }
21996
+ /**
21997
+ * Encodes a list of typed `IntentData` entries into the `Intent.data` bytes the contract decodes.
21998
+ * Empty → `'0x'`; single → a packed `[uint8 type, bytes payload]` envelope; multiple → a `TYPE_ARRAY`
21999
+ * envelope wrapping the entries as `ArrayData { DataEntry[] }`.
22000
+ */
22001
+ static encodeIntentData(entries) {
22002
+ if (entries.length === 0) {
22003
+ return "0x";
22004
+ }
22005
+ const [first] = entries;
22006
+ if (first && entries.length === 1) {
22007
+ return viem.encodePacked(["uint8", "bytes"], [first.type, first.data]);
22008
+ }
22009
+ const encodedArray = viem.encodeAbiParameters(ARRAY_DATA_ABI, [
22010
+ { data: entries.map((e) => ({ dataType: e.type, data: e.data })) }
22011
+ ]);
22012
+ return viem.encodePacked(["uint8", "bytes"], [0 /* ARRAY */, encodedArray]);
22013
+ }
22014
+ /**
22015
+ * Extracts the raw `FeeData` payload (`abi.encode(uint256 fee, address receiver)`) from an intent's
22016
+ * `data`, unwrapping whichever envelope shape it uses. Returns `undefined` when there is no fee:
22017
+ * empty `data`, a delivery-only envelope, or an unknown type byte (logged). Used by
22018
+ * `EvmSolverService.decodeIntentFeeAmount` to recover fees regardless of delivery data.
22019
+ */
22020
+ static extractFeePayload(data) {
22021
+ if (data === "0x" || data.length <= 2) {
22022
+ return void 0;
22023
+ }
22024
+ const typeByte = Number.parseInt(data.slice(2, 4), 16);
22025
+ if (typeByte === 1 /* FEE */) {
22026
+ return `0x${data.slice(4)}`;
22027
+ }
22028
+ if (typeByte === 0 /* ARRAY */) {
22029
+ const [arrayData] = viem.decodeAbiParameters(ARRAY_DATA_ABI, `0x${data.slice(4)}`);
22030
+ return arrayData.data.find((e) => e.dataType === 1 /* FEE */)?.data;
22031
+ }
22032
+ if (typeByte === 3 /* DELIVERY */) {
22033
+ return void 0;
22034
+ }
22035
+ console.error(
22036
+ `[IntentDataService.extractFeePayload] Unknown IntentData type byte: ${typeByte}. Gracefully returning no fee.`
22037
+ );
22038
+ return void 0;
22039
+ }
22040
+ };
21858
22041
  var IntentCreatedEventAbi = viem.getAbiItem({ abi: IntentsAbi, name: "IntentCreated" });
21859
22042
  var IntentFilledEventAbi = viem.getAbiItem({ abi: IntentsAbi, name: "IntentFilled" });
21860
22043
  var MintPositionEventAbi = viem.getAbiItem({ abi: infinitySdk.CLPositionManagerAbi, name: "MintPosition" });
@@ -21893,7 +22076,9 @@ var EvmSolverService = class _EvmSolverService {
21893
22076
  outputToken,
21894
22077
  `hub asset not found for spoke chain token (intent.outputToken): ${createIntentParams.outputToken}`
21895
22078
  );
21896
- const [feeData, feeAmount] = _EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22079
+ const { dstAddress, deliveryData } = HookService.resolveDelivery(createIntentParams);
22080
+ const [feeEnvelope, feeAmount] = _EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22081
+ const intentData = IntentDataService.composeIntentData(feeEnvelope, deliveryData);
21897
22082
  const calls = [];
21898
22083
  const intentsContract = config.solver.intentsContract;
21899
22084
  const intent = {
@@ -21908,10 +22093,10 @@ var EvmSolverService = class _EvmSolverService {
21908
22093
  srcChain: getIntentRelayChainId(createIntentParams.srcChainKey),
21909
22094
  dstChain: getIntentRelayChainId(createIntentParams.dstChainKey),
21910
22095
  srcAddress: encodeAddress(createIntentParams.srcChainKey, createIntentParams.srcAddress),
21911
- dstAddress: encodeAddress(createIntentParams.dstChainKey, createIntentParams.dstAddress),
22096
+ dstAddress: encodeAddress(createIntentParams.dstChainKey, dstAddress),
21912
22097
  solver: createIntentParams.solver ?? "0x0000000000000000000000000000000000000000",
21913
- data: feeData
21914
- // fee amount will be deducted from the input amount
22098
+ data: intentData
22099
+ // fee amount will be deducted from the input amount; may also carry delivery data
21915
22100
  };
21916
22101
  calls.push(Erc20Service.encodeApprove(intent.inputToken, intentsContract, createIntentParams.inputAmount));
21917
22102
  calls.push(_EvmSolverService.encodeCreateIntent(intent, intentsContract));
@@ -21972,29 +22157,25 @@ var EvmSolverService = class _EvmSolverService {
21972
22157
  /**
21973
22158
  * Recovers the partner fee amount embedded in an intent's `data` field.
21974
22159
  *
21975
- * Exact inverse of {@link createIntentFeeData}: `'0x'` means no fee (`0n`); otherwise the first
21976
- * byte is the {@link IntentDataType} tag (from the `encodePacked(['uint8','bytes'], …)` envelope)
21977
- * and the remainder is the ABI-encoded `(uint256 fee, address receiver)` struct.
22160
+ * Inverse of {@link createIntentFeeData}: returns the encoded fee, regardless of whether the `data`
22161
+ * is a bare fee envelope or a multi-entry envelope that also carries delivery data. The envelope
22162
+ * parsing lives in {@link IntentDataService.extractFeePayload}; this method just decodes the fee struct.
21978
22163
  *
21979
22164
  * @param data - The intent's `data` field (`'0x'` when no fee was configured).
21980
- * @returns The fee amount in the input token's smallest unit (`0n` when no fee data is present, or
21981
- * when the leading type byte is not {@link IntentDataType.FEE} — in which case it logs and degrades to `0n`).
22165
+ * @returns The fee amount in the input token's smallest unit (`0n` when no fee is present).
21982
22166
  */
21983
22167
  static decodeIntentFeeAmount(data) {
21984
- if (data === "0x" || data.length <= 2) {
21985
- return 0n;
21986
- }
21987
- const typeByte = Number.parseInt(data.slice(2, 4), 16);
21988
- if (typeByte !== 1 /* FEE */) {
21989
- console.error(`[decodeIntentFeeAmount] Unknown IntentData type byte: ${typeByte}. Gracefully returning 0n.`);
21990
- return 0n;
21991
- }
22168
+ const feePayload = IntentDataService.extractFeePayload(data);
22169
+ return feePayload ? _EvmSolverService.decodeFeePayload(feePayload) : 0n;
22170
+ }
22171
+ /** Decodes a raw `FeeData` payload (`abi.encode(uint256 fee, address receiver)`) to its fee amount. */
22172
+ static decodeFeePayload(payload) {
21992
22173
  const [feeAmount] = viem.decodeAbiParameters(
21993
22174
  [
21994
22175
  { name: "fee", type: "uint256" },
21995
22176
  { name: "receiver", type: "address" }
21996
22177
  ],
21997
- `0x${data.slice(4)}`
22178
+ payload
21998
22179
  );
21999
22180
  return feeAmount;
22000
22181
  }
@@ -22360,7 +22541,9 @@ var SonicSpokeService = class {
22360
22541
  outputToken,
22361
22542
  `hub asset not found for spoke chain token (intent.outputToken): ${createIntentParams.outputToken}`
22362
22543
  );
22363
- const [feeData, feeAmount] = EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22544
+ const { dstAddress, deliveryData } = HookService.resolveDelivery(createIntentParams);
22545
+ const [feeEnvelope, feeAmount] = EvmSolverService.createIntentFeeData(fee, createIntentParams.inputAmount);
22546
+ const intentData = IntentDataService.composeIntentData(feeEnvelope, deliveryData);
22364
22547
  const intentsContract = solverConfig2.intentsContract;
22365
22548
  const intent = {
22366
22549
  intentId: randomUint256(),
@@ -22374,10 +22557,10 @@ var SonicSpokeService = class {
22374
22557
  srcChain: getIntentRelayChainId(createIntentParams.srcChainKey),
22375
22558
  dstChain: getIntentRelayChainId(createIntentParams.dstChainKey),
22376
22559
  srcAddress: encodeAddress(createIntentParams.srcChainKey, createIntentParams.srcAddress),
22377
- dstAddress: encodeAddress(createIntentParams.dstChainKey, createIntentParams.dstAddress),
22560
+ dstAddress: encodeAddress(createIntentParams.dstChainKey, dstAddress),
22378
22561
  solver: createIntentParams.solver ?? "0x0000000000000000000000000000000000000000",
22379
- data: feeData
22380
- // fee amount will be deducted from the input amount
22562
+ data: intentData
22563
+ // fee amount will be deducted from the input amount; may also carry delivery data
22381
22564
  };
22382
22565
  const txData = EvmSolverService.encodeCreateIntent(intent, intentsContract);
22383
22566
  const rawTx = {
@@ -38458,6 +38641,7 @@ exports.BitcoinSpokeService = BitcoinSpokeService;
38458
38641
  exports.BnUSDMigrationService = BnUSDMigrationService;
38459
38642
  exports.BridgeService = BridgeService;
38460
38643
  exports.CHAIN_KEYS = CHAIN_KEYS;
38644
+ exports.CHAIN_LOGO_BASE_URL = CHAIN_LOGO_BASE_URL;
38461
38645
  exports.CONFIG_VERSION = CONFIG_VERSION;
38462
38646
  exports.CREATE_INTENT_CODES = CREATE_INTENT_CODES;
38463
38647
  exports.ChainKeys = ChainKeys;
@@ -38492,6 +38676,8 @@ exports.GAS_ESTIMATION_CODES = GAS_ESTIMATION_CODES;
38492
38676
  exports.HALF_RAY = HALF_RAY;
38493
38677
  exports.HALF_WAD = HALF_WAD;
38494
38678
  exports.HUB_CHAIN_KEY = HUB_CHAIN_KEY;
38679
+ exports.HookKind = HookKind;
38680
+ exports.HookService = HookService;
38495
38681
  exports.HttpRelayError = HttpRelayError;
38496
38682
  exports.HubVaultSymbols = HubVaultSymbols;
38497
38683
  exports.ICON_CHAIN_KEYS = ICON_CHAIN_KEYS;
@@ -38505,6 +38691,7 @@ exports.IcxMigrationService = IcxMigrationService;
38505
38691
  exports.Injective20Token = Injective20Token;
38506
38692
  exports.InjectiveSpokeService = InjectiveSpokeService;
38507
38693
  exports.IntentCreatedEventAbi = IntentCreatedEventAbi;
38694
+ exports.IntentDataService = IntentDataService;
38508
38695
  exports.IntentDataType = IntentDataType;
38509
38696
  exports.IntentFilledEventAbi = IntentFilledEventAbi;
38510
38697
  exports.IntentRelayChainIdToChainKey = IntentRelayChainIdToChainKey;
@@ -38659,6 +38846,8 @@ exports.getReserveNormalizedIncome = getReserveNormalizedIncome;
38659
38846
  exports.getReservesEModes = getReservesEModes;
38660
38847
  exports.getSolanaAddressBytes = getSolanaAddressBytes;
38661
38848
  exports.getSolverConfig = getSolverConfig;
38849
+ exports.getSpokeHook = getSpokeHook;
38850
+ exports.getSpokeHooks = getSpokeHooks;
38662
38851
  exports.getStagingSolverTokens = getStagingSolverTokens;
38663
38852
  exports.getSupportedSolverTokens = getSupportedSolverTokens;
38664
38853
  exports.getTransactionPackets = getTransactionPackets;
@@ -38690,6 +38879,7 @@ exports.isEvmSpokeOnlyChainKey = isEvmSpokeOnlyChainKey;
38690
38879
  exports.isEvmSpokeOnlyChainKeyType = isEvmSpokeOnlyChainKeyType;
38691
38880
  exports.isEvmWalletProviderType = isEvmWalletProviderType;
38692
38881
  exports.isFeatureError = isFeatureError;
38882
+ exports.isHookSupportedToken = isHookSupportedToken;
38693
38883
  exports.isHubChainKey = isHubChainKey;
38694
38884
  exports.isHubChainKeyType = isHubChainKeyType;
38695
38885
  exports.isIconAddress = isIconAddress;
@@ -38836,6 +39026,7 @@ exports.sonicWalletFactoryAbi = sonicWalletFactoryAbi;
38836
39026
  exports.spokeAssetManagerAbi = spokeAssetManagerAbi;
38837
39027
  exports.spokeChainConfig = spokeChainConfig;
38838
39028
  exports.spokeChainKeysSet = spokeChainKeysSet;
39029
+ exports.spokeHooks = spokeHooks;
38839
39030
  exports.stacksSupportedTokens = stacksSupportedTokens;
38840
39031
  exports.stagingSwapSupportedTokens = stagingSwapSupportedTokens;
38841
39032
  exports.stakedSodaAbi = stakedSodaAbi;