@sodax/sdk 2.0.0-rc.12 → 2.0.0-rc.14

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
@@ -1,8 +1,8 @@
1
- import { getAbiItem, isAddress, toHex, hexToBytes, encodeAbiParameters, parseAbiParameters, defineChain, encodeFunctionData, erc20Abi as erc20Abi$1, createPublicClient, http, bytesToHex, keccak256, stringToBytes, fromHex, encodePacked, decodeAbiParameters, parseEventLogs, maxUint160, maxUint48 } from 'viem';
1
+ import { getAbiItem, parseAbi, isAddress, toHex, hexToBytes, encodeAbiParameters, parseAbiParameters, defineChain, encodeFunctionData, erc20Abi as erc20Abi$1, createPublicClient, http, bytesToHex, keccak256, stringToBytes, fromHex, encodePacked, decodeAbiParameters, parseEventLogs, maxUint160, maxUint48 } from 'viem';
2
2
  import { bcs } from '@mysten/sui/bcs';
3
3
  import { PublicKey, Connection, VersionedTransaction, SystemProgram, ComputeBudgetProgram, TransactionMessage, TransactionInstruction } from '@solana/web3.js';
4
4
  import { rpc, Address, xdr, Account, Horizon, Contract, TransactionBuilder, nativeToScVal, TimeoutInfinite, scValToBigInt, Operation, Asset, FeeBumpTransaction } from '@stellar/stellar-sdk';
5
- import { serializeCV, Cl, deserializeCV, cvToString, createNetwork, fetchFeeEstimateTransaction, fetchCallReadOnlyFunction, parseContractId, PostConditionMode, noneCV, someCV, uintCV, validateStacksAddress, makeUnsignedContractCall, serializePayloadBytes } from '@sodax/libs/stacks/core';
5
+ import { serializeCV, Cl, deserializeCV, cvToString, createNetwork, fetchFeeEstimateTransaction, fetchCallReadOnlyFunction, parseContractId, PostConditionMode, noneCV, someCV, uintCV, getAddressFromPublicKey, makeUnsignedContractCall, serializePayloadBytes } from '@sodax/libs/stacks/core';
6
6
  import { kaia, redbellyMainnet, mainnet, lightlinkPhoenix, polygon, bsc, optimism, base, arbitrum, avalanche, sonic } from 'viem/chains';
7
7
  import * as rlp from 'rlp';
8
8
  import { initEccLib, networks, Transaction, Psbt, payments, opcodes, script } from 'bitcoinjs-lib';
@@ -14,7 +14,8 @@ import { TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, getAssociatedTokenAddress } fr
14
14
  import { AnchorProvider, Program } from '@coral-xyz/anchor';
15
15
  import BN from 'bn.js';
16
16
  import * as IconSdkRaw from 'icon-sdk-js';
17
- import { ChainGrpcWasmApi, TxGrpcApi, CosmosTxV1Beta1TxPb, toBase64, fromBase64, MsgExecuteContract, createTransactionForAddressAndMsg } from '@injectivelabs/sdk-ts';
17
+ import { ChainGrpcWasmApi, TxGrpcApi, toBase64, fromBase64, MsgExecuteContract, ChainRestAuthApi, BaseAccount, createTransaction } from '@injectivelabs/sdk-ts';
18
+ import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx.js';
18
19
  import { getNetworkEndpoints, Network } from '@injectivelabs/networks';
19
20
  import BigNumber5, { BigNumber } from 'bignumber.js';
20
21
  import { Token, Price } from '@pancakeswap/swap-sdk-core';
@@ -169,7 +170,8 @@ var SODAX_FEATURES = [
169
170
  "migration",
170
171
  "dex",
171
172
  "partner",
172
- "recovery"
173
+ "recovery",
174
+ "leverageYield"
173
175
  ];
174
176
 
175
177
  // src/shared/utils/tiny-invariant.ts
@@ -302,7 +304,8 @@ var HubVaultSymbols = [
302
304
  "sodaNEAR",
303
305
  "sodaKAIA",
304
306
  "sodaSTX",
305
- "sodaUSDS"
307
+ "sodaUSDS",
308
+ "sodaJITOSOL"
306
309
  ];
307
310
  var SodaTokens = {
308
311
  sodaBNB: {
@@ -529,6 +532,45 @@ var SodaTokens = {
529
532
  chainKey: ChainKeys.SONIC_MAINNET,
530
533
  hubAsset: "0x243b0c26c8b38793908d7C64e8510f21B19B4613",
531
534
  vault: "0x243b0c26c8b38793908d7C64e8510f21B19B4613"
535
+ },
536
+ sodaJITOSOL: {
537
+ symbol: "sodaJITOSOL",
538
+ name: "Soda JITOSOL",
539
+ decimals: 18,
540
+ address: "0xe1bad4400d947Bc4fa66f9c0A143D800002083a0",
541
+ chainKey: ChainKeys.SONIC_MAINNET,
542
+ hubAsset: "0xe1bad4400d947Bc4fa66f9c0A143D800002083a0",
543
+ vault: "0xe1bad4400d947Bc4fa66f9c0A143D800002083a0"
544
+ }
545
+ };
546
+ var LsodaSymbols = ["lsodaWEETH", "lsodaWSTETH", "lsodaJITOSOL"];
547
+ var LsodaTokens = {
548
+ lsodaWEETH: {
549
+ symbol: "lsodaWEETH",
550
+ name: "Leveraged Soda weETH",
551
+ decimals: 18,
552
+ address: "0xD09de2f5070699A909c0FD32fb5A909d3886701D",
553
+ chainKey: ChainKeys.SONIC_MAINNET,
554
+ hubAsset: "0xD09de2f5070699A909c0FD32fb5A909d3886701D",
555
+ vault: "0xD09de2f5070699A909c0FD32fb5A909d3886701D"
556
+ },
557
+ lsodaWSTETH: {
558
+ symbol: "lsodaWSTETH",
559
+ name: "Leveraged Soda wstETH",
560
+ decimals: 18,
561
+ address: "0x136E5D1CEC5db1829E24941Eddd9C8640E02Ce7a",
562
+ chainKey: ChainKeys.SONIC_MAINNET,
563
+ hubAsset: "0x136E5D1CEC5db1829E24941Eddd9C8640E02Ce7a",
564
+ vault: "0x136E5D1CEC5db1829E24941Eddd9C8640E02Ce7a"
565
+ },
566
+ lsodaJITOSOL: {
567
+ symbol: "lsodaJITOSOL",
568
+ name: "Leveraged Soda JITOSOL",
569
+ decimals: 18,
570
+ address: "0xD7Ae4853E0f93682F5DaA14734F5D18cBa09Bd78",
571
+ chainKey: ChainKeys.SONIC_MAINNET,
572
+ hubAsset: "0xD7Ae4853E0f93682F5DaA14734F5D18cBa09Bd78",
573
+ vault: "0xD7Ae4853E0f93682F5DaA14734F5D18cBa09Bd78"
532
574
  }
533
575
  };
534
576
  var sonicSupportedTokens = {
@@ -595,7 +637,8 @@ var sonicSupportedTokens = {
595
637
  hubAsset: "0x7c7d53EEcda37a87ce0D5bf8E0b24512A48dC963",
596
638
  vault: SodaTokens.sodaSODA.address
597
639
  },
598
- ...SodaTokens
640
+ ...SodaTokens,
641
+ ...LsodaTokens
599
642
  };
600
643
  var redbellySupportedTokens = {
601
644
  RBNT: {
@@ -805,7 +848,7 @@ var solanaSupportedTokens = {
805
848
  address: "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn",
806
849
  chainKey: ChainKeys.SOLANA_MAINNET,
807
850
  hubAsset: "0x942f89a324d2652e447b9fcf08effc9f9776a680",
808
- vault: "0x942f89a324d2652e447b9fcf08effc9f9776a680"
851
+ vault: SodaTokens.sodaJITOSOL.address
809
852
  },
810
853
  mSOL: {
811
854
  symbol: "mSOL",
@@ -1238,6 +1281,15 @@ var baseSupportedTokens = {
1238
1281
  chainKey: ChainKeys.BASE_MAINNET,
1239
1282
  hubAsset: "0xaa81bb5ba3c972ab53605d3ba7e443a3de6d1cb9",
1240
1283
  vault: "0xaa81bb5ba3c972ab53605d3ba7e443a3de6d1cb9"
1284
+ },
1285
+ AERO: {
1286
+ symbol: "AERO",
1287
+ name: "Aerodrome Finance",
1288
+ decimals: 18,
1289
+ address: "0x940181a94A35A4569e4529A3CDfB74e38FD98631",
1290
+ chainKey: ChainKeys.BASE_MAINNET,
1291
+ hubAsset: "0x348e086ab6f424dfc575a325c28624ed23973173",
1292
+ vault: "0x348e086ab6f424dfc575a325c28624ed23973173"
1241
1293
  }
1242
1294
  };
1243
1295
  var optimismSupportedTokens = {
@@ -1920,6 +1972,33 @@ var stellarSupportedTokens = {
1920
1972
  chainKey: ChainKeys.STELLAR_MAINNET,
1921
1973
  hubAsset: "0xD749B5FfFED7cEDaa3239abDd16D677179C29AEc",
1922
1974
  vault: SodaTokens.sodaSODA.address
1975
+ },
1976
+ sodaETH: {
1977
+ symbol: "sodaETH",
1978
+ name: "Soda ETH",
1979
+ decimals: 7,
1980
+ address: "CDK5EWVTZLGSLI6D5OSES7XUKWZUKBXDRNOWUVDNPP5RJRP5EYWCW7SL",
1981
+ chainKey: ChainKeys.STELLAR_MAINNET,
1982
+ hubAsset: "0x4985a4b72ac723723e9ae82382d12d77e9a715de",
1983
+ vault: SodaTokens.sodaETH.address
1984
+ },
1985
+ sodaBTC: {
1986
+ symbol: "sodaBTC",
1987
+ name: "Soda BTC",
1988
+ decimals: 7,
1989
+ address: "CD6XWBW74YVFDQQYUM2GALCULMA5MAWGP6NTCWF3ZYXP4Z7MEVY4JKBX",
1990
+ chainKey: ChainKeys.STELLAR_MAINNET,
1991
+ hubAsset: "0xddee01f63c18843e2bac30cb702864d7632c83a2",
1992
+ vault: SodaTokens.sodaBTC.address
1993
+ },
1994
+ sodaBNB: {
1995
+ symbol: "sodaBNB",
1996
+ name: "Soda BNB",
1997
+ decimals: 7,
1998
+ address: "CCXTXZAFLVNTMORVWYB6BGL7YEW3U3ONDAL2FGBRGDUQH7AGANVQPRS6",
1999
+ chainKey: ChainKeys.STELLAR_MAINNET,
2000
+ hubAsset: "0xa10be5f5c2dea7d272555dc73ea2a7317c3c5b63",
2001
+ vault: SodaTokens.sodaBNB.address
1923
2002
  }
1924
2003
  };
1925
2004
  var suiSupportedTokens = {
@@ -3059,6 +3138,21 @@ var spokeChainConfig = {
3059
3138
  assetCode: "SODA",
3060
3139
  contractId: "CAH5LKJC2ZB4RVUVEVL2QWJWNJLHQE2UF767ILLQ5EQ4O3OURR2XIUGM",
3061
3140
  assetIssuer: "GDYUTHY75A7WUZJQDPOP66FB32BOYGZRXHWTWO4Q6LQTANT5X3V5HNFA"
3141
+ },
3142
+ {
3143
+ assetCode: "sodaETH",
3144
+ contractId: "CDK5EWVTZLGSLI6D5OSES7XUKWZUKBXDRNOWUVDNPP5RJRP5EYWCW7SL",
3145
+ assetIssuer: "GDYUTHY75A7WUZJQDPOP66FB32BOYGZRXHWTWO4Q6LQTANT5X3V5HNFA"
3146
+ },
3147
+ {
3148
+ assetCode: "sodaBTC",
3149
+ contractId: "CD6XWBW74YVFDQQYUM2GALCULMA5MAWGP6NTCWF3ZYXP4Z7MEVY4JKBX",
3150
+ assetIssuer: "GDYUTHY75A7WUZJQDPOP66FB32BOYGZRXHWTWO4Q6LQTANT5X3V5HNFA"
3151
+ },
3152
+ {
3153
+ assetCode: "sodaBNB",
3154
+ contractId: "CCXTXZAFLVNTMORVWYB6BGL7YEW3U3ONDAL2FGBRGDUQH7AGANVQPRS6",
3155
+ assetIssuer: "GDYUTHY75A7WUZJQDPOP66FB32BOYGZRXHWTWO4Q6LQTANT5X3V5HNFA"
3062
3156
  }
3063
3157
  ],
3064
3158
  supportedTokens: stellarSupportedTokens,
@@ -3334,7 +3428,8 @@ var moneyMarketSupportedTokens = {
3334
3428
  spokeChainConfig[ChainKeys.SOLANA_MAINNET].supportedTokens.bnUSD,
3335
3429
  spokeChainConfig[ChainKeys.SOLANA_MAINNET].supportedTokens.USDC,
3336
3430
  spokeChainConfig[ChainKeys.SOLANA_MAINNET].supportedTokens.SODA,
3337
- spokeChainConfig[ChainKeys.SOLANA_MAINNET].supportedTokens.USDT
3431
+ spokeChainConfig[ChainKeys.SOLANA_MAINNET].supportedTokens.USDT,
3432
+ spokeChainConfig[ChainKeys.SOLANA_MAINNET].supportedTokens.JitoSOL
3338
3433
  ],
3339
3434
  [ChainKeys.ICON_MAINNET]: [
3340
3435
  // spokeChainConfig[ChainKeys.ICON].supportedTokens.ICX,
@@ -3345,7 +3440,10 @@ var moneyMarketSupportedTokens = {
3345
3440
  spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.XLM,
3346
3441
  spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.bnUSD,
3347
3442
  spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.SODA,
3348
- spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.USDC
3443
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.USDC,
3444
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.sodaETH,
3445
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.sodaBTC,
3446
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.sodaBNB
3349
3447
  ],
3350
3448
  [ChainKeys.SUI_MAINNET]: [
3351
3449
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.SUI,
@@ -3596,7 +3694,9 @@ var swapSupportedTokens = {
3596
3694
  spokeChainConfig[ChainKeys.SONIC_MAINNET].supportedTokens.USDT,
3597
3695
  spokeChainConfig[ChainKeys.SONIC_MAINNET].supportedTokens.wS,
3598
3696
  spokeChainConfig[ChainKeys.SONIC_MAINNET].supportedTokens.SODA,
3599
- ...Object.values(SodaTokens)
3697
+ // sodaUSDS is staging-only — see stagingSwapSupportedTokens
3698
+ ...Object.values(SodaTokens).filter((t) => t !== SodaTokens.sodaUSDS),
3699
+ ...Object.values(LsodaTokens)
3600
3700
  ],
3601
3701
  [ChainKeys.AVALANCHE_MAINNET]: [
3602
3702
  spokeChainConfig[ChainKeys.AVALANCHE_MAINNET].supportedTokens.AVAX,
@@ -3615,36 +3715,35 @@ var swapSupportedTokens = {
3615
3715
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.tBTC,
3616
3716
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.USDC,
3617
3717
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.USDT,
3618
- spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.SODA,
3619
3718
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.ARB,
3620
3719
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.AAVE,
3621
3720
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.LINK,
3622
3721
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.UNI,
3623
3722
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.CRV,
3624
3723
  spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.PENDLE,
3625
- spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.rETH
3724
+ spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.rETH,
3725
+ spokeChainConfig[ChainKeys.ARBITRUM_MAINNET].supportedTokens.SODA
3626
3726
  ],
3627
3727
  [ChainKeys.BASE_MAINNET]: [
3628
3728
  spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.ETH,
3629
- spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.bnUSD,
3630
3729
  spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.weETH,
3631
3730
  spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.USDC,
3632
3731
  spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.wstETH,
3633
3732
  spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.cbBTC,
3634
- spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.SODA,
3635
3733
  spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.VIRTUAL,
3636
- spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.cbETH
3734
+ spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.cbETH,
3735
+ spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.SODA
3637
3736
  ],
3638
3737
  [ChainKeys.OPTIMISM_MAINNET]: [
3639
3738
  spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.ETH,
3640
- spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.bnUSD,
3641
3739
  spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.USDC,
3642
3740
  spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.wstETH,
3643
3741
  // spokeChainConfig[OPTIMISM_MAINNET_CHAIN_ID].supportedTokens.weETH, // NOTE: Not Implemented
3644
3742
  spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.USDT,
3645
3743
  spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.SODA,
3646
3744
  spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.OP,
3647
- spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.WBTC
3745
+ spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.WBTC,
3746
+ spokeChainConfig[ChainKeys.OPTIMISM_MAINNET].supportedTokens.bnUSD
3648
3747
  ],
3649
3748
  [ChainKeys.POLYGON_MAINNET]: [
3650
3749
  spokeChainConfig[ChainKeys.POLYGON_MAINNET].supportedTokens.POL,
@@ -3700,7 +3799,6 @@ var swapSupportedTokens = {
3700
3799
  spokeChainConfig[ChainKeys.LIGHTLINK_MAINNET].supportedTokens["SUI.LL"],
3701
3800
  spokeChainConfig[ChainKeys.LIGHTLINK_MAINNET].supportedTokens["S.LL"],
3702
3801
  spokeChainConfig[ChainKeys.LIGHTLINK_MAINNET].supportedTokens["POL.LL"],
3703
- spokeChainConfig[ChainKeys.LIGHTLINK_MAINNET].supportedTokens["HYPE.LL"],
3704
3802
  spokeChainConfig[ChainKeys.LIGHTLINK_MAINNET].supportedTokens.LL
3705
3803
  ],
3706
3804
  [ChainKeys.SOLANA_MAINNET]: [
@@ -3739,7 +3837,10 @@ var swapSupportedTokens = {
3739
3837
  spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.bnUSD,
3740
3838
  // NOTE: Not Implemented
3741
3839
  spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.USDC,
3742
- spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.SODA
3840
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.SODA,
3841
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.sodaETH,
3842
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.sodaBTC,
3843
+ spokeChainConfig[ChainKeys.STELLAR_MAINNET].supportedTokens.sodaBNB
3743
3844
  ],
3744
3845
  [ChainKeys.SUI_MAINNET]: [
3745
3846
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.SUI,
@@ -3757,12 +3858,8 @@ var swapSupportedTokens = {
3757
3858
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.WAL,
3758
3859
  spokeChainConfig[ChainKeys.SUI_MAINNET].supportedTokens.NAVX
3759
3860
  ],
3760
- [ChainKeys.INJECTIVE_MAINNET]: [
3761
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.INJ,
3762
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.bnUSD,
3763
- spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.USDC
3764
- // spokeChainConfig[ChainKeys.INJECTIVE_MAINNET].supportedTokens.SODA, // NOTE: not in solver wiki
3765
- ],
3861
+ // Injective is currently staging-only — see stagingSwapSupportedTokens
3862
+ [ChainKeys.INJECTIVE_MAINNET]: [],
3766
3863
  [ChainKeys.NEAR_MAINNET]: [
3767
3864
  spokeChainConfig[ChainKeys.NEAR_MAINNET].supportedTokens.NEAR,
3768
3865
  spokeChainConfig[ChainKeys.NEAR_MAINNET].supportedTokens.bnUSD,
@@ -3829,24 +3926,112 @@ var swapSupportedTokens = {
3829
3926
  spokeChainConfig[ChainKeys.STACKS_MAINNET].supportedTokens.USDC
3830
3927
  ]
3831
3928
  };
3929
+ var stagingSwapSupportedTokens = {
3930
+ [ChainKeys.SONIC_MAINNET]: [SodaTokens.sodaUSDS],
3931
+ [ChainKeys.AVALANCHE_MAINNET]: [],
3932
+ [ChainKeys.ARBITRUM_MAINNET]: [],
3933
+ [ChainKeys.BASE_MAINNET]: [
3934
+ spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.bnUSD,
3935
+ spokeChainConfig[ChainKeys.BASE_MAINNET].supportedTokens.AERO
3936
+ ],
3937
+ [ChainKeys.OPTIMISM_MAINNET]: [],
3938
+ [ChainKeys.POLYGON_MAINNET]: [
3939
+ spokeChainConfig[ChainKeys.POLYGON_MAINNET].supportedTokens.USDT,
3940
+ spokeChainConfig[ChainKeys.POLYGON_MAINNET].supportedTokens.wstETH
3941
+ ],
3942
+ [ChainKeys.BSC_MAINNET]: [],
3943
+ [ChainKeys.HYPEREVM_MAINNET]: [],
3944
+ [ChainKeys.LIGHTLINK_MAINNET]: [
3945
+ spokeChainConfig[ChainKeys.LIGHTLINK_MAINNET].supportedTokens["HYPE.LL"]
3946
+ ],
3947
+ [ChainKeys.SOLANA_MAINNET]: [],
3948
+ [ChainKeys.ICON_MAINNET]: [],
3949
+ [ChainKeys.STELLAR_MAINNET]: [],
3950
+ [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
+ ],
3957
+ [ChainKeys.NEAR_MAINNET]: [],
3958
+ [ChainKeys.BITCOIN_MAINNET]: [],
3959
+ [ChainKeys.ETHEREUM_MAINNET]: [
3960
+ spokeChainConfig[ChainKeys.ETHEREUM_MAINNET].supportedTokens.wstETH,
3961
+ spokeChainConfig[ChainKeys.ETHEREUM_MAINNET].supportedTokens.weETH
3962
+ ],
3963
+ [ChainKeys.REDBELLY_MAINNET]: [],
3964
+ [ChainKeys.KAIA_MAINNET]: [],
3965
+ [ChainKeys.STACKS_MAINNET]: []
3966
+ };
3832
3967
  var swapsConfig = {
3833
- partnerFee: void 0,
3834
3968
  supportedTokens: swapSupportedTokens
3835
3969
  };
3836
3970
  var getSupportedSolverTokens = (chainId) => swapSupportedTokens[chainId];
3837
- var isSwapSupportedToken = (chainId, token) => swapSupportedTokens[chainId].some((t) => t.address.toLowerCase() === token.toLowerCase());
3971
+ var getStagingSolverTokens = (chainId) => [
3972
+ ...swapSupportedTokens[chainId],
3973
+ ...stagingSwapSupportedTokens[chainId]
3974
+ ];
3975
+ var isSwapSupportedToken = (chainId, token) => [...swapSupportedTokens[chainId], ...stagingSwapSupportedTokens[chainId]].some((t) => t.address.toLowerCase() === token.toLowerCase());
3838
3976
 
3839
- // ../types/dist/sodax-config/sodax-config.js
3840
- var bridgeConfig = {
3841
- partnerFee: void 0
3977
+ // ../types/dist/leverageYield/leverageYield.js
3978
+ var leverageYieldVaults = [
3979
+ {
3980
+ name: LsodaTokens.lsodaWEETH.symbol,
3981
+ vault: LsodaTokens.lsodaWEETH.vault,
3982
+ asset: SodaTokens.sodaWEETH.address,
3983
+ // sodaWEETH on Sonic
3984
+ borrowToken: SodaTokens.sodaETH.address,
3985
+ // sodaETH on Sonic
3986
+ lsdSource: {
3987
+ // DefiLlama pool for EtherFi's weETH on Ethereum (project: 'ether.fi-stake').
3988
+ poolId: "46bd2bdf-6d92-4066-b482-e885ee172264",
3989
+ fallbackAprPct: 3,
3990
+ label: "EtherFi (weETH)"
3991
+ }
3992
+ },
3993
+ {
3994
+ name: LsodaTokens.lsodaWSTETH.symbol,
3995
+ vault: LsodaTokens.lsodaWSTETH.vault,
3996
+ asset: SodaTokens.sodaWSTETH.address,
3997
+ // sodaWSTETH on Sonic
3998
+ borrowToken: SodaTokens.sodaETH.address,
3999
+ // sodaETH on Sonic
4000
+ lsdSource: {
4001
+ // DefiLlama pool for Lido's stETH on Ethereum (wstETH inherits this rate via redeem).
4002
+ poolId: "747c1d2a-c668-4682-b9f9-296708a3dd90",
4003
+ fallbackAprPct: 2.4,
4004
+ label: "Lido (stETH)"
4005
+ }
4006
+ },
4007
+ {
4008
+ name: LsodaTokens.lsodaJITOSOL.symbol,
4009
+ vault: LsodaTokens.lsodaJITOSOL.vault,
4010
+ asset: SodaTokens.sodaJITOSOL.address,
4011
+ // sodaJITOSOL on Sonic
4012
+ borrowToken: SodaTokens.sodaSOL.address,
4013
+ // sodaSOL on Sonic
4014
+ lsdSource: {
4015
+ // DefiLlama pool for Jito's JitoSOL native staking on Solana (project: 'jito-liquid-staking').
4016
+ poolId: "0e7d0722-9054-4907-8593-567b353c0900",
4017
+ fallbackAprPct: 5.5,
4018
+ label: "Jito (JitoSOL)"
4019
+ }
4020
+ }
4021
+ ];
4022
+ var leverageYieldConfig = {
4023
+ vaults: leverageYieldVaults
3842
4024
  };
4025
+
4026
+ // ../types/dist/sodax-config/sodax-config.js
4027
+ var bridgeConfig = {};
3843
4028
  var sodaxConfig = {
3844
- fee: void 0,
3845
4029
  chains: spokeChainConfig,
3846
4030
  swaps: swapsConfig,
3847
4031
  moneyMarket: moneyMarketConfig,
3848
4032
  bridge: bridgeConfig,
3849
4033
  dex: dexConfig,
4034
+ leverageYield: leverageYieldConfig,
3850
4035
  hub: hubConfig,
3851
4036
  api: apiConfig,
3852
4037
  solver: solverConfig,
@@ -3988,7 +4173,7 @@ function isValidWalletProviderForChainKey(chainKey, walletProvider) {
3988
4173
  }
3989
4174
 
3990
4175
  // ../types/dist/index.js
3991
- var CONFIG_VERSION = 210;
4176
+ var CONFIG_VERSION = 212;
3992
4177
  function isEvmSpokeChainConfig(value) {
3993
4178
  return typeof value === "object" && value !== null && value.chain.type === "EVM" && value.chain.key !== HUB_CHAIN_KEY;
3994
4179
  }
@@ -4375,7 +4560,10 @@ async function pollForExecutedPacket(payload) {
4375
4560
  }
4376
4561
  const txPackets = txPacketsResult.value;
4377
4562
  if (txPackets.success && txPackets.data.length > 0) {
4378
- const packet = txPackets.data.find((packet2) => packet2.src_tx_hash.toLowerCase() === payload.srcTxHash.toLowerCase());
4563
+ const candidates = txPackets.data.filter(
4564
+ (packet2) => packet2.src_tx_hash.toLowerCase() === payload.srcTxHash.toLowerCase()
4565
+ );
4566
+ const packet = payload.selectPacket ? payload.selectPacket(candidates) : candidates[0];
4379
4567
  if (packet?.status === "executed") {
4380
4568
  return { kind: "found", packet };
4381
4569
  }
@@ -13265,14 +13453,7 @@ function deepMerge(target, source) {
13265
13453
 
13266
13454
  // src/shared/config/mergeSodaxConfig.ts
13267
13455
  function mergeSodaxConfig(base2, override) {
13268
- const merged = deepMerge(base2, override);
13269
- if (override.fee !== void 0) {
13270
- merged.fee = override.fee;
13271
- }
13272
- if (override.bridge?.partnerFee !== void 0) {
13273
- merged.bridge.partnerFee = override.bridge.partnerFee;
13274
- }
13275
- return merged;
13456
+ return deepMerge(base2, override);
13276
13457
  }
13277
13458
 
13278
13459
  // src/shared/logger.ts
@@ -13312,6 +13493,12 @@ var ConfigService = class {
13312
13493
  * {@link initialize}'s dynamic-config swap never clobbers it. Read by services via `config.logger`.
13313
13494
  */
13314
13495
  logger;
13496
+ /**
13497
+ * Global partner fee. Resolved once at construction and kept independent of {@link sodax} so that
13498
+ * {@link initialize}'s dynamic-config swap never clobbers it. The backend never supplies it — it is
13499
+ * a client-side option set via `new Sodax({ fee })`. Per-feature overrides live on the feature config.
13500
+ */
13501
+ fee;
13315
13502
  initialized = false;
13316
13503
  // data structures for quick lookup
13317
13504
  supportedHubAssetsSet;
@@ -13323,11 +13510,12 @@ var ConfigService = class {
13323
13510
  stakedATokenAddressesSet;
13324
13511
  chainToSupportedTokenAddressMap;
13325
13512
  hubAssetToXTokenMap;
13326
- constructor({ api, config, userConfig, logger }) {
13513
+ constructor({ api, config, userConfig, logger, fee }) {
13327
13514
  this.api = api;
13328
13515
  this.sodax = config;
13329
13516
  this.userConfig = userConfig;
13330
13517
  this.logger = logger ?? resolveLogger(void 0);
13518
+ this.fee = fee;
13331
13519
  this.loadSodaxConfigDataStructures(config);
13332
13520
  }
13333
13521
  async initialize() {
@@ -13560,6 +13748,24 @@ var ConfigService = class {
13560
13748
  get moneyMarket() {
13561
13749
  return this.sodax.moneyMarket;
13562
13750
  }
13751
+ get leverageYield() {
13752
+ return this.sodax.leverageYield;
13753
+ }
13754
+ // Effective partner fee per feature: the feature-specific override if set, otherwise the global
13755
+ // `fee` client option ({@link fee}). The global fee is the default, overridable per-feature. `??`
13756
+ // (never a merge) keeps the chosen PartnerFee variant intact — no discriminated-union hybrid.
13757
+ get swapPartnerFee() {
13758
+ return this.swaps.partnerFee ?? this.fee;
13759
+ }
13760
+ get moneyMarketPartnerFee() {
13761
+ return this.moneyMarket.partnerFee ?? this.fee;
13762
+ }
13763
+ get bridgePartnerFee() {
13764
+ return this.bridge.partnerFee ?? this.fee;
13765
+ }
13766
+ get leverageYieldPartnerFee() {
13767
+ return this.leverageYield.partnerFee ?? this.fee;
13768
+ }
13563
13769
  get dex() {
13564
13770
  return this.sodax.dex;
13565
13771
  }
@@ -14371,12 +14577,23 @@ var StacksSpokeService = class {
14371
14577
  postConditionMode: PostConditionMode.Allow
14372
14578
  };
14373
14579
  if (params.raw === true) {
14374
- if (validateStacksAddress(params.srcAddress)) {
14375
- throw new Error('When using raw transactions, the public key must be provided as "from" parameter');
14580
+ if (!params.srcPublicKey) {
14581
+ throw new Error("Stacks raw transactions require srcPublicKey (the signer public key for srcAddress).");
14582
+ }
14583
+ let derivedAddress;
14584
+ try {
14585
+ derivedAddress = getAddressFromPublicKey(params.srcPublicKey, this.network);
14586
+ } catch (error) {
14587
+ throw new Error(`srcPublicKey is not a valid Stacks public key: ${error.message}`);
14588
+ }
14589
+ if (derivedAddress !== params.srcAddress) {
14590
+ throw new Error(
14591
+ `srcPublicKey does not match srcAddress: it derives ${derivedAddress}, but srcAddress is ${params.srcAddress}.`
14592
+ );
14376
14593
  }
14377
14594
  const tx = await makeUnsignedContractCall({
14378
14595
  ...reqData,
14379
- publicKey: params.srcAddress,
14596
+ publicKey: params.srcPublicKey,
14380
14597
  network: this.network,
14381
14598
  fee: 0,
14382
14599
  // placeholder — we'll estimate
@@ -17332,8 +17549,8 @@ function chain(...args) {
17332
17549
  const id = (a) => a;
17333
17550
  const wrap = (a, b) => (c) => a(b(c));
17334
17551
  const encode3 = args.map((x) => x.encode).reduceRight(wrap, id);
17335
- const decode = args.map((x) => x.decode).reduce(wrap, id);
17336
- return { encode: encode3, decode };
17552
+ const decode2 = args.map((x) => x.decode).reduce(wrap, id);
17553
+ return { encode: encode3, decode: decode2 };
17337
17554
  }
17338
17555
  // @__NO_SIDE_EFFECTS__
17339
17556
  function alphabet(letters) {
@@ -22267,17 +22484,11 @@ var SuiSpokeService = class {
22267
22484
  ]
22268
22485
  });
22269
22486
  if (params.raw === true) {
22270
- tx.setSender(from);
22271
- const transactionRaw = await tx.build({
22272
- client: this.publicClient,
22273
- onlyTransactionKind: true
22274
- });
22275
- const transactionRawBase64String = Buffer.from(transactionRaw).toString("base64");
22276
22487
  return {
22277
22488
  from,
22278
22489
  to: `${assetManager.packageId}::${assetManager.moduleId}::transfer`,
22279
22490
  value: amount,
22280
- data: transactionRawBase64String
22491
+ data: tx.serialize()
22281
22492
  };
22282
22493
  }
22283
22494
  return params.walletProvider.signAndExecuteTxn(tx);
@@ -22297,17 +22508,11 @@ var SuiSpokeService = class {
22297
22508
  ]
22298
22509
  });
22299
22510
  if (params.raw === true) {
22300
- txb.setSender(from);
22301
- const transactionRaw = await txb.build({
22302
- client: this.publicClient,
22303
- onlyTransactionKind: true
22304
- });
22305
- const transactionRawBase64String = Buffer.from(transactionRaw).toString("base64");
22306
22511
  return {
22307
22512
  from,
22308
22513
  to: `${connection.packageId}::${connection.moduleId}::send_message_ua`,
22309
22514
  value: 0n,
22310
- data: transactionRawBase64String
22515
+ data: txb.serialize()
22311
22516
  };
22312
22517
  }
22313
22518
  return params.walletProvider.signAndExecuteTxn(txb);
@@ -22318,7 +22523,7 @@ var SuiSpokeService = class {
22318
22523
  * @returns {Promise<bigint>} The estimated computation cost.
22319
22524
  */
22320
22525
  async estimateGas({ tx }) {
22321
- const txb = Transaction$1.fromKind(tx.data);
22526
+ const txb = Transaction$1.from(tx.data);
22322
22527
  const result = await this.publicClient.devInspectTransactionBlock({
22323
22528
  sender: tx.from,
22324
22529
  transactionBlock: txb
@@ -22549,6 +22754,7 @@ var CustomStellarAccount = class {
22549
22754
  decrementSequenceNumber() {
22550
22755
  if (this.sequenceNumber > this.startingSequenceNumber) {
22551
22756
  this.sequenceNumber--;
22757
+ return;
22552
22758
  }
22553
22759
  throw new Error(
22554
22760
  `Sequence number cannot be decremented below the starting sequence number: ${this.startingSequenceNumber}`
@@ -22655,7 +22861,7 @@ var StellarSpokeService = class {
22655
22861
  );
22656
22862
  const assembledPriorityTx = rpc.assembleTransaction(rawPriorityTx, simulation).build();
22657
22863
  if (params.raw) {
22658
- const transactionXdr = rawPriorityTx.toXDR();
22864
+ const transactionXdr = assembledPriorityTx.toXDR();
22659
22865
  return {
22660
22866
  from,
22661
22867
  to: this.config.getChainConfig(srcChainKey).addresses.assetManager,
@@ -22772,7 +22978,7 @@ var StellarSpokeService = class {
22772
22978
  );
22773
22979
  const assembledPriorityTx = rpc.assembleTransaction(rawPriorityTx, simulation).build();
22774
22980
  if (params.raw) {
22775
- const transactionXdr = rawPriorityTx.toXDR();
22981
+ const transactionXdr = assembledPriorityTx.toXDR();
22776
22982
  return {
22777
22983
  from,
22778
22984
  to: this.config.getChainConfig(srcChainKey).addresses.assetManager,
@@ -23445,6 +23651,8 @@ var IconSpokeService = class {
23445
23651
  };
23446
23652
  }
23447
23653
  };
23654
+ var GAS_BUFFER_MULTIPLIER = 1.2;
23655
+ var GAS_PRICE_REGEX = /^(\d+)(.*)$/;
23448
23656
  var InjectiveSpokeService = class {
23449
23657
  config;
23450
23658
  chainGrpcWasmApi;
@@ -23452,6 +23660,7 @@ var InjectiveSpokeService = class {
23452
23660
  endpoints;
23453
23661
  pollingIntervalMs;
23454
23662
  maxTimeoutMs;
23663
+ gasPrice;
23455
23664
  constructor(config) {
23456
23665
  this.config = config;
23457
23666
  this.endpoints = getNetworkEndpoints(Network.Mainnet);
@@ -23459,6 +23668,16 @@ var InjectiveSpokeService = class {
23459
23668
  this.txClient = new TxGrpcApi(this.endpoints.grpc);
23460
23669
  this.pollingIntervalMs = this.config.sodaxConfig.chains[ChainKeys.INJECTIVE_MAINNET].pollingConfig.pollingIntervalMs;
23461
23670
  this.maxTimeoutMs = this.config.sodaxConfig.chains[ChainKeys.INJECTIVE_MAINNET].pollingConfig.maxTimeoutMs;
23671
+ this.gasPrice = this.config.getChainConfig(ChainKeys.INJECTIVE_MAINNET).gasPrice;
23672
+ }
23673
+ /** Parse a chain-config gas price like `"500000000inj"` into its numeric price and denom. */
23674
+ parseGasPrice(gasPrice) {
23675
+ const match = GAS_PRICE_REGEX.exec(gasPrice);
23676
+ const price = match?.[1];
23677
+ if (price === void 0) {
23678
+ throw new Error(`Invalid Injective gasPrice config: ${gasPrice}`);
23679
+ }
23680
+ return { price: BigInt(price), denom: match?.[2] || "inj" };
23462
23681
  }
23463
23682
  /**
23464
23683
  * Estimate the gas for a transaction.
@@ -23467,7 +23686,7 @@ var InjectiveSpokeService = class {
23467
23686
  * @returns {Promise<InjectiveGasEstimate>} The estimated gas for the transaction.
23468
23687
  */
23469
23688
  async estimateGas({ tx }) {
23470
- const txRaw = CosmosTxV1Beta1TxPb.TxRaw.fromPartial({
23689
+ const txRaw = TxRaw.fromPartial({
23471
23690
  bodyBytes: tx.signedDoc.bodyBytes,
23472
23691
  authInfoBytes: tx.signedDoc.authInfoBytes,
23473
23692
  signatures: []
@@ -23506,7 +23725,9 @@ var InjectiveSpokeService = class {
23506
23725
  chainConfig.networkId,
23507
23726
  from,
23508
23727
  chainConfig.addresses.assetManager,
23509
- msg
23728
+ msg,
23729
+ void 0,
23730
+ funds
23510
23731
  );
23511
23732
  }
23512
23733
  const res = await params.walletProvider.execute(from, chainConfig.addresses.assetManager, msg, funds);
@@ -23527,27 +23748,50 @@ var InjectiveSpokeService = class {
23527
23748
  );
23528
23749
  return BigInt(fromBase64(response.data));
23529
23750
  }
23530
- async getRawTransaction(chainId, senderAddress, contractAddress, msg, memo) {
23751
+ async getRawTransaction(chainId, senderAddress, contractAddress, msg, memo, funds = []) {
23531
23752
  const msgExec = MsgExecuteContract.fromJSON({
23532
23753
  contractAddress,
23533
23754
  sender: senderAddress,
23534
23755
  msg,
23535
- funds: []
23756
+ funds
23536
23757
  });
23537
- const { txRaw } = await createTransactionForAddressAndMsg({
23758
+ const accountResponse = await new ChainRestAuthApi(this.endpoints.rest).fetchCosmosAccount(senderAddress);
23759
+ const baseAccount = BaseAccount.fromRestCosmosApi(accountResponse);
23760
+ const pubKey = baseAccount.pubKey.key;
23761
+ if (!pubKey) {
23762
+ throw new Error(`The pubKey for ${senderAddress} is missing \u2014 the account has not signed a transaction yet.`);
23763
+ }
23764
+ const txArgs = {
23538
23765
  message: msgExec,
23539
23766
  memo: memo || "",
23540
- address: senderAddress,
23541
- endpoint: this.endpoints.grpc,
23767
+ pubKey,
23768
+ sequence: baseAccount.sequence,
23769
+ accountNumber: baseAccount.accountNumber,
23542
23770
  chainId
23543
- });
23771
+ };
23772
+ const draft = createTransaction(txArgs);
23773
+ const { gasInfo } = await this.txClient.simulate(
23774
+ TxRaw.fromPartial({
23775
+ bodyBytes: draft.txRaw.bodyBytes,
23776
+ authInfoBytes: draft.txRaw.authInfoBytes,
23777
+ signatures: []
23778
+ // not required for simulation
23779
+ })
23780
+ );
23781
+ const gas = Math.ceil(gasInfo.gasUsed * GAS_BUFFER_MULTIPLIER);
23782
+ const { price, denom } = this.parseGasPrice(this.gasPrice);
23783
+ const fee = {
23784
+ amount: [{ denom, amount: (BigInt(gas) * price).toString() }],
23785
+ gas: gas.toString()
23786
+ };
23787
+ const { txRaw, signDoc } = createTransaction({ ...txArgs, fee });
23544
23788
  const rawTx = {
23545
23789
  from: senderAddress,
23546
23790
  to: contractAddress,
23547
23791
  signedDoc: {
23548
23792
  bodyBytes: txRaw.bodyBytes,
23549
23793
  chainId,
23550
- accountNumber: BigInt(0),
23794
+ accountNumber: BigInt(signDoc.accountNumber),
23551
23795
  authInfoBytes: txRaw.authInfoBytes
23552
23796
  }
23553
23797
  };
@@ -25686,6 +25930,24 @@ var SolverApiService = class {
25686
25930
  }
25687
25931
  }
25688
25932
  };
25933
+ function decodePacketIntentTarget(payload) {
25934
+ try {
25935
+ const hex = payload.startsWith("0x") ? payload.slice(2) : payload;
25936
+ const decoded = rlp.decode(Buffer.from(hex, "hex"));
25937
+ const field1 = decoded?.[1];
25938
+ if (!field1 || field1.length === 0) return void 0;
25939
+ return `0x${Buffer.from(field1).toString("hex")}`.toLowerCase();
25940
+ } catch {
25941
+ return void 0;
25942
+ }
25943
+ }
25944
+ function selectSolvedIntentPacket(packets, intentsContract) {
25945
+ if (packets.length <= 1) return packets[0];
25946
+ const target = intentsContract.toLowerCase();
25947
+ const matched = packets.find((packet) => decodePacketIntentTarget(packet.payload) === target);
25948
+ if (matched) return matched;
25949
+ return packets.reduce((highest, packet) => packet.conn_sn > highest.conn_sn ? packet : highest);
25950
+ }
25689
25951
 
25690
25952
  // src/swap/errors.ts
25691
25953
  var swapInvariant = createInvariant("swap");
@@ -25721,7 +25983,7 @@ var SwapService = class {
25721
25983
  relayerApiEndpoint;
25722
25984
  constructor({ config, hubProvider, spoke }) {
25723
25985
  this.solver = config.solver;
25724
- this.partnerFee = config.swaps.partnerFee;
25986
+ this.partnerFee = config.swapPartnerFee;
25725
25987
  this.relayerApiEndpoint = config.relay.relayerApiEndpoint;
25726
25988
  this.config = config;
25727
25989
  this.hubProvider = hubProvider;
@@ -25739,10 +26001,13 @@ var SwapService = class {
25739
26001
  /**
25740
26002
  * Requests a price quote from the solver API for a given token pair and amount.
25741
26003
  *
25742
- * Adjusts `payload.amount` by the configured partner fee before forwarding to the solver,
25743
- * so the returned `quoted_amount` reflects the net output the user actually receives.
26004
+ * Adjusts `payload.amount` by the partner fee before forwarding to the solver, so the returned
26005
+ * `quoted_amount` reflects the net output the user actually receives. Pass `partnerFee` to match
26006
+ * a per-action override supplied to `createIntent` (`extras.partnerFee`); omit it to use the
26007
+ * configured swap fee.
25744
26008
  *
25745
- * @param payload - Source/destination tokens, chain IDs, input amount, and quote type.
26009
+ * @param payload - The solver quote request, optionally carrying a per-call `partnerFee` override
26010
+ * (defaults to the configured swap partner fee). `partnerFee` is stripped before forwarding.
25746
26011
  * @returns A `Result` containing `{ quoted_amount: bigint }` on success, or a
25747
26012
  * `SolverErrorResponse` (with a `SolverIntentErrorCode`) on failure.
25748
26013
  *
@@ -25758,11 +26023,12 @@ var SwapService = class {
25758
26023
  * if (response.ok) console.log('Quoted amount:', response.value.quoted_amount);
25759
26024
  */
25760
26025
  async getQuote(payload) {
25761
- payload = {
25762
- ...payload,
25763
- amount: adjustAmountByFee(payload.amount, this.partnerFee, payload.quote_type)
26026
+ const { partnerFee = this.partnerFee, ...request } = payload;
26027
+ const adjustedPayload = {
26028
+ ...request,
26029
+ amount: adjustAmountByFee(request.amount, partnerFee, request.quote_type)
25764
26030
  };
25765
- return SolverApiService.getQuote(payload, this.solver, this.config);
26031
+ return SolverApiService.getQuote(adjustedPayload, this.solver, this.config);
25766
26032
  }
25767
26033
  /**
25768
26034
  * Calculates the partner fee that will be deducted from the given input amount.
@@ -26112,7 +26378,8 @@ var SwapService = class {
26112
26378
  * - `UNKNOWN` — defensive fallback.
26113
26379
  */
26114
26380
  async createIntent(_params) {
26115
- const { params, skipSimulation } = _params;
26381
+ const { params, skipSimulation, extras } = _params;
26382
+ const partnerFee = extras?.partnerFee ?? this.partnerFee;
26116
26383
  const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
26117
26384
  try {
26118
26385
  swapInvariant(
@@ -26147,6 +26414,13 @@ var SwapService = class {
26147
26414
  { ...baseCtx, field: "minOutputAmount" }
26148
26415
  );
26149
26416
  }
26417
+ if (isStacksChainKeyType(params.srcChainKey) && _params.raw === true) {
26418
+ swapInvariant(
26419
+ extras?.srcPublicKey !== void 0,
26420
+ "srcPublicKey is required for Stacks createIntent (raw) \u2014 the source tx is built unsigned and needs the signer public key",
26421
+ { ...baseCtx, field: "srcPublicKey" }
26422
+ );
26423
+ }
26150
26424
  const personalAddress = params.srcAddress;
26151
26425
  let walletAddress = personalAddress;
26152
26426
  if (isBitcoinChainKeyType(params.srcChainKey) && _params.raw === false) {
@@ -26164,7 +26438,7 @@ var SwapService = class {
26164
26438
  createIntentParams: params,
26165
26439
  creatorHubWalletAddress,
26166
26440
  solverConfig: this.solver,
26167
- fee: this.config.swaps.partnerFee,
26441
+ fee: partnerFee,
26168
26442
  hubProvider: this.hubProvider
26169
26443
  };
26170
26444
  const [txResult2, intent2, feeAmount2, data2] = await SonicSpokeService.createSwapIntent(
@@ -26190,11 +26464,12 @@ var SwapService = class {
26190
26464
  },
26191
26465
  creatorHubWalletAddress,
26192
26466
  this.config,
26193
- this.config.swaps.partnerFee
26467
+ partnerFee
26194
26468
  );
26195
26469
  const coreDepositParams = {
26196
26470
  srcChainKey: params.srcChainKey,
26197
26471
  srcAddress: walletAddress,
26472
+ srcPublicKey: extras?.srcPublicKey,
26198
26473
  to: creatorHubWalletAddress,
26199
26474
  token: params.inputToken,
26200
26475
  amount: params.inputAmount,
@@ -26513,6 +26788,11 @@ var SwapService = class {
26513
26788
  * Use this after `getStatus` returns `SolverIntentStatusCode.SOLVED (3)` to obtain the
26514
26789
  * destination-chain transaction hash from `packet.dst_tx_hash`.
26515
26790
  *
26791
+ * A single solver fill tx emits multiple relay packets sharing the same `src_tx_hash`. The
26792
+ * user-facing `IntentFilled` delivery is the packet whose payload targets the hub intents
26793
+ * contract; `selectSolvedIntentPacket` disambiguates so the returned `dst_tx_hash` is the
26794
+ * destination delivery tx rather than an internal hop.
26795
+ *
26516
26796
  * @param chainId - The destination spoke chain key (where output tokens are delivered).
26517
26797
  * @param fillTxHash - The solver's fill transaction hash, obtained from `getStatus.fill_tx_hash`.
26518
26798
  * @param timeout - Poll timeout in milliseconds. Defaults to `DEFAULT_RELAY_TX_TIMEOUT` (120 s).
@@ -26528,7 +26808,8 @@ var SwapService = class {
26528
26808
  intentRelayChainId: getIntentRelayChainId(chainId).toString(),
26529
26809
  srcTxHash: fillTxHash,
26530
26810
  timeout,
26531
- apiUrl: this.relayerApiEndpoint
26811
+ apiUrl: this.relayerApiEndpoint,
26812
+ selectPacket: (packets) => selectSolvedIntentPacket(packets, this.solver.intentsContract)
26532
26813
  });
26533
26814
  }
26534
26815
  /**
@@ -29053,10 +29334,10 @@ var BridgeService = class {
29053
29334
  * @returns Fee amount to be deducted, in the same units as `inputAmount`.
29054
29335
  */
29055
29336
  getFee(inputAmount) {
29056
- if (!this.config.bridge.partnerFee) {
29337
+ if (!this.config.bridgePartnerFee) {
29057
29338
  return 0n;
29058
29339
  }
29059
- return calculateFeeAmount(inputAmount, this.config.bridge.partnerFee);
29340
+ return calculateFeeAmount(inputAmount, this.config.bridgePartnerFee);
29060
29341
  }
29061
29342
  /**
29062
29343
  * Checks whether the caller has sufficient token allowance to execute the bridge.
@@ -29333,7 +29614,7 @@ var BridgeService = class {
29333
29614
  }
29334
29615
  const hubWallet = await this.hubProvider.getUserHubWalletAddress(walletAddress, params.srcChainKey);
29335
29616
  const effectiveSkipSimulation = skipSimulation || isBitcoinChainKeyType(params.srcChainKey) && this.spoke.bitcoin.walletMode === "USER";
29336
- const data = this.buildBridgeData(params, srcToken, dstToken, this.config.bridge.partnerFee);
29617
+ const data = this.buildBridgeData(params, srcToken, dstToken, this.config.bridgePartnerFee);
29337
29618
  const coreParams = {
29338
29619
  srcChainKey: params.srcChainKey,
29339
29620
  srcAddress: walletAddress,
@@ -35212,7 +35493,7 @@ var MoneyMarketService = class _MoneyMarketService {
35212
35493
  this.config = config;
35213
35494
  this.hubProvider = hubProvider;
35214
35495
  this.spoke = spoke;
35215
- this.partnerFee = config.moneyMarket.partnerFee;
35496
+ this.partnerFee = config.moneyMarketPartnerFee;
35216
35497
  this.relayerApiEndpoint = config.relay.relayerApiEndpoint;
35217
35498
  this.data = new MoneyMarketDataService({ hubProvider, config });
35218
35499
  }
@@ -36985,7 +37266,12 @@ var RecoveryService = class {
36985
37266
  srcChainKey: chainKey,
36986
37267
  field: "chainKey"
36987
37268
  });
36988
- const entries = Object.values(chainConfig.supportedTokens).filter((token) => isAddress(token.hubAsset));
37269
+ const leverageVaultAddresses = new Set(
37270
+ this.config.sodaxConfig.leverageYield.vaults.map((vault) => vault.vault.toLowerCase())
37271
+ );
37272
+ const entries = Object.values(chainConfig.supportedTokens).filter(
37273
+ (token) => isAddress(token.hubAsset) && !leverageVaultAddresses.has(token.hubAsset.toLowerCase())
37274
+ );
36989
37275
  if (entries.length === 0) {
36990
37276
  return { ok: true, value: [] };
36991
37277
  }
@@ -37087,6 +37373,871 @@ var RecoveryService = class {
37087
37373
  }
37088
37374
  };
37089
37375
 
37376
+ // src/leverageYield/errors.ts
37377
+ var leverageYieldInvariant = createInvariant("leverageYield");
37378
+ var LEVERAGE_YIELD_CODES = /* @__PURE__ */ new Set([
37379
+ "VALIDATION_FAILED",
37380
+ "INTENT_CREATION_FAILED",
37381
+ "APPROVE_FAILED",
37382
+ "ALLOWANCE_CHECK_FAILED",
37383
+ "LOOKUP_FAILED",
37384
+ "TX_VERIFICATION_FAILED",
37385
+ "TX_SUBMIT_FAILED",
37386
+ "RELAY_TIMEOUT",
37387
+ "RELAY_FAILED",
37388
+ "EXECUTION_FAILED",
37389
+ "EXTERNAL_API_ERROR",
37390
+ "UNKNOWN"
37391
+ ]);
37392
+ var LEVERAGE_YIELD_POST_EXECUTION_CODES = /* @__PURE__ */ new Set([
37393
+ "EXECUTION_FAILED",
37394
+ "EXTERNAL_API_ERROR",
37395
+ "UNKNOWN"
37396
+ ]);
37397
+ var LEVERAGE_YIELD_SWAP_CODES = /* @__PURE__ */ new Set([
37398
+ "VALIDATION_FAILED",
37399
+ "INTENT_CREATION_FAILED",
37400
+ "TX_VERIFICATION_FAILED",
37401
+ "TX_SUBMIT_FAILED",
37402
+ "RELAY_TIMEOUT",
37403
+ "RELAY_FAILED",
37404
+ "EXECUTION_FAILED",
37405
+ "EXTERNAL_API_ERROR",
37406
+ "UNKNOWN"
37407
+ ]);
37408
+ var isLeverageYieldCreateIntentError = isCodeMember(CREATE_INTENT_CODES);
37409
+ var isLeverageYieldApproveError = isCodeMember(APPROVE_CODES);
37410
+ var isLeverageYieldAllowanceCheckError = isCodeMember(ALLOWANCE_CHECK_CODES);
37411
+ var isLeverageYieldLookupError = isCodeMember(LOOKUP_CODES);
37412
+ var isLeverageYieldPostExecutionError = isCodeMember(
37413
+ LEVERAGE_YIELD_POST_EXECUTION_CODES
37414
+ );
37415
+ var isLeverageYieldSwapError = isCodeMember(LEVERAGE_YIELD_SWAP_CODES);
37416
+ var isLeverageYieldError = isCodeMember(LEVERAGE_YIELD_CODES);
37417
+
37418
+ // src/leverageYield/LeverageYieldService.ts
37419
+ var leverageYieldVaultAbi = parseAbi([
37420
+ "function asset() view returns (address)",
37421
+ "function getPositionDetails() view returns (uint256 collateral, uint256 debt, uint256 ltv, uint256 healthFactor, uint256 idleAsset)",
37422
+ // Used by getApr() — read-only metadata that doesn't change per pass.
37423
+ "function pool() view returns (address)",
37424
+ "function borrowToken() view returns (address)",
37425
+ "function targetLTV() view returns (uint256)"
37426
+ ]);
37427
+ var INTENT_DEADLINE_BUFFER_SECONDS = 5 * 60;
37428
+ var ANY_SOLVER_ADDRESS = "0x0000000000000000000000000000000000000000";
37429
+ var MAX_WITHDRAW_DUST_BUFFER = 1000n;
37430
+ function pctToRay(aprPct) {
37431
+ return BigInt(Math.round(aprPct * 1e9)) * 10n ** 16n;
37432
+ }
37433
+ var DEFILLAMA_FETCH_TIMEOUT_MS = 1e4;
37434
+ var DEFILLAMA_FETCH_MAX_ATTEMPTS = 2;
37435
+ async function fetchWithTimeout(url, timeoutMs) {
37436
+ const controller = new AbortController();
37437
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
37438
+ try {
37439
+ return await fetch(url, { signal: controller.signal });
37440
+ } finally {
37441
+ clearTimeout(timeoutId);
37442
+ }
37443
+ }
37444
+ async function fetchDefillamaApr(poolId) {
37445
+ return retry(async () => {
37446
+ const response = await fetchWithTimeout(`https://yields.llama.fi/chart/${poolId}`, DEFILLAMA_FETCH_TIMEOUT_MS);
37447
+ if (!response.ok) throw new Error(`DefiLlama APR fetch failed: HTTP ${response.status}`);
37448
+ const json = await response.json();
37449
+ const series = json?.data;
37450
+ if (!Array.isArray(series) || series.length === 0) {
37451
+ throw new Error("DefiLlama APR response: empty time series");
37452
+ }
37453
+ const latest = series[series.length - 1]?.apy;
37454
+ if (typeof latest !== "number") throw new Error("DefiLlama APR: latest entry missing numeric apy");
37455
+ return latest;
37456
+ }, DEFILLAMA_FETCH_MAX_ATTEMPTS);
37457
+ }
37458
+ var LeverageYieldService = class {
37459
+ hubProvider;
37460
+ config;
37461
+ spoke;
37462
+ constructor({ hubProvider, config, spoke }) {
37463
+ this.hubProvider = hubProvider;
37464
+ this.config = config;
37465
+ this.spoke = spoke;
37466
+ }
37467
+ // ─── Registry ──────────────────────────────────────────────────────────
37468
+ /** Returns the static registry of known leverage-yield vaults. */
37469
+ listVaults() {
37470
+ return this.config.sodaxConfig.leverageYield.vaults;
37471
+ }
37472
+ /** Looks up a vault by its `name` field. Returns `undefined` when not registered. */
37473
+ getVault(name) {
37474
+ return this.listVaults().find((v) => v.name === name);
37475
+ }
37476
+ /**
37477
+ * Looks up a registered vault by its on-chain proxy address (case-insensitive).
37478
+ * Returns `undefined` when the address isn't in the registry.
37479
+ */
37480
+ getVaultByAddress(address) {
37481
+ const normalized = address.toLowerCase();
37482
+ return this.listVaults().find((v) => v.vault.toLowerCase() === normalized);
37483
+ }
37484
+ /**
37485
+ * Resolves the intent `deadline`: returns the caller-supplied value verbatim, otherwise
37486
+ * derives a default from the hub-chain (Sonic) block timestamp plus
37487
+ * {@link INTENT_DEADLINE_BUFFER_SECONDS}. The deadline is enforced on-chain against the hub
37488
+ * block time, so the default is anchored to that block — never the client clock, which can
37489
+ * drift and produce an already-expired or over-extended deadline.
37490
+ *
37491
+ * Returns a {@link Result}: a `getBlock` RPC outage is a read failure, surfaced as
37492
+ * `LOOKUP_FAILED` (`method: 'resolveDeadline'`) rather than masquerading as an intent-build
37493
+ * failure. The `deposit` / `withdraw` callers forward it verbatim.
37494
+ */
37495
+ async resolveDeadline(deadline, srcChainKey) {
37496
+ if (deadline !== void 0) return { ok: true, value: deadline };
37497
+ try {
37498
+ const block = await this.hubProvider.publicClient.getBlock({
37499
+ includeTransactions: false,
37500
+ blockTag: "latest"
37501
+ });
37502
+ return { ok: true, value: block.timestamp + BigInt(INTENT_DEADLINE_BUFFER_SECONDS) };
37503
+ } catch (error) {
37504
+ return { ok: false, error: lookupFailed("leverageYield", "resolveDeadline", error, { srcChainKey }) };
37505
+ }
37506
+ }
37507
+ /**
37508
+ * Builds the {@link LeverageYieldSwapPayload} for a leverage-yield deposit (any token → lsoda*).
37509
+ * The lsoda* output is delivered to the user's hub wallet on Sonic so a later
37510
+ * {@link LeverageYieldService.withdraw} can swap it back. Spread the result into
37511
+ * {@link LeverageYieldService.vaultSwap}: `vaultSwap({ ...payload, walletProvider })`.
37512
+ * An optional `partnerFee` is forwarded on the payload as the per-intent fee override.
37513
+ *
37514
+ * For `minOutputAmount`, quote via `sodax.swaps.getQuote` with the vault address as the
37515
+ * destination token (`token_dst`) — vault shares are solver-tradeable, so the generic swap
37516
+ * quote applies; then subtract your slippage tolerance.
37517
+ */
37518
+ async deposit(params) {
37519
+ const baseCtx = { srcChainKey: params.srcChainKey, action: "deposit" };
37520
+ try {
37521
+ leverageYieldInvariant(params.inputAmount > 0n, "inputAmount must be greater than 0", {
37522
+ ...baseCtx,
37523
+ field: "inputAmount"
37524
+ });
37525
+ leverageYieldInvariant(params.vault.length > 0, "Vault address is required", { ...baseCtx, field: "vault" });
37526
+ leverageYieldInvariant(params.inputToken.length > 0, "inputToken is required", {
37527
+ ...baseCtx,
37528
+ field: "inputToken"
37529
+ });
37530
+ const hubWallet = await this.hubProvider.getUserHubWalletAddress(params.srcAddress, params.srcChainKey);
37531
+ const deadlineResult = await this.resolveDeadline(params.deadline, params.srcChainKey);
37532
+ if (!deadlineResult.ok) return deadlineResult;
37533
+ const deadline = deadlineResult.value;
37534
+ return {
37535
+ ok: true,
37536
+ value: {
37537
+ params: {
37538
+ inputToken: params.inputToken,
37539
+ outputToken: params.vault,
37540
+ inputAmount: params.inputAmount,
37541
+ minOutputAmount: params.minOutputAmount,
37542
+ deadline,
37543
+ allowPartialFill: false,
37544
+ srcChainKey: params.srcChainKey,
37545
+ dstChainKey: this.hubProvider.chainConfig.chain.key,
37546
+ srcAddress: params.srcAddress,
37547
+ dstAddress: hubWallet,
37548
+ solver: params.solver ?? ANY_SOLVER_ADDRESS,
37549
+ data: "0x"
37550
+ },
37551
+ // Per-intent fee override — only included when the caller supplies one, so the
37552
+ // payload stays free of undefined-valued keys.
37553
+ ...params.partnerFee !== void 0 && { partnerFee: params.partnerFee }
37554
+ }
37555
+ };
37556
+ } catch (error) {
37557
+ if (isLeverageYieldCreateIntentError(error)) return { ok: false, error };
37558
+ return { ok: false, error: intentCreationFailed("leverageYield", error, baseCtx) };
37559
+ }
37560
+ }
37561
+ /**
37562
+ * Builds the {@link LeverageYieldSwapPayload} for a leverage-yield withdraw (lsoda* → any
37563
+ * token). The payload carries `hubWalletSwap: true` — {@link LeverageYieldService.vaultSwap}
37564
+ * then spends the lsoda* held in the user's hub wallet by authorising it via a
37565
+ * `Connection.sendMessage` the user signs on `srcChainKey`. Wrapped in a {@link Result} for
37566
+ * a call shape uniform with {@link LeverageYieldService.deposit}; async because the default
37567
+ * `deadline` is read from the hub block timestamp.
37568
+ *
37569
+ * For `minOutputAmount`, quote via `sodax.swaps.getQuote` with the vault address as the
37570
+ * source token (`token_src`) — vault shares are solver-tradeable, so the generic swap quote
37571
+ * applies; then subtract your slippage tolerance.
37572
+ */
37573
+ async withdraw(params) {
37574
+ const baseCtx = { srcChainKey: params.srcChainKey, action: "withdraw" };
37575
+ try {
37576
+ leverageYieldInvariant(params.inputAmount > 0n, "inputAmount must be greater than 0", {
37577
+ ...baseCtx,
37578
+ field: "inputAmount"
37579
+ });
37580
+ leverageYieldInvariant(params.vault.length > 0, "Vault address is required", { ...baseCtx, field: "vault" });
37581
+ leverageYieldInvariant(params.outputToken.length > 0, "outputToken is required", {
37582
+ ...baseCtx,
37583
+ field: "outputToken"
37584
+ });
37585
+ const deadlineResult = await this.resolveDeadline(params.deadline, params.srcChainKey);
37586
+ if (!deadlineResult.ok) return deadlineResult;
37587
+ const deadline = deadlineResult.value;
37588
+ return {
37589
+ ok: true,
37590
+ value: {
37591
+ params: {
37592
+ inputToken: params.vault,
37593
+ outputToken: params.outputToken,
37594
+ inputAmount: params.inputAmount,
37595
+ minOutputAmount: params.minOutputAmount,
37596
+ deadline,
37597
+ allowPartialFill: false,
37598
+ srcChainKey: params.srcChainKey,
37599
+ dstChainKey: params.dstChainKey,
37600
+ srcAddress: params.srcAddress,
37601
+ dstAddress: params.recipient ?? params.srcAddress,
37602
+ solver: params.solver ?? ANY_SOLVER_ADDRESS,
37603
+ data: "0x"
37604
+ },
37605
+ hubWalletSwap: true
37606
+ }
37607
+ };
37608
+ } catch (error) {
37609
+ if (isLeverageYieldCreateIntentError(error)) return { ok: false, error };
37610
+ return { ok: false, error: intentCreationFailed("leverageYield", error, baseCtx) };
37611
+ }
37612
+ }
37613
+ /**
37614
+ * Creates a vault swap intent on the user's source spoke chain without submitting it to
37615
+ * the solver. Leverage-yield copy of the swap domain's `createIntent`, specialised for
37616
+ * vault flows — duplicated deliberately so the vault-specific execution modifiers
37617
+ * (`hubWalletSwap`, per-intent `partnerFee`) stay off the generic swap surface.
37618
+ *
37619
+ * Use {@link LeverageYieldService.vaultSwap} for the full end-to-end flow
37620
+ * (create → relay → notify solver); use this directly when you need the raw transaction
37621
+ * or drive the relay yourself (e.g. the backend submit-tx path). To complete a manual flow,
37622
+ * relay the returned `relayData` (the shared `relayTxAndWaitPacket` helper) and then call
37623
+ * {@link LeverageYieldService.notifySolver} with the hub-side intent tx hash.
37624
+ *
37625
+ * @param _params - Intent parameters, source chain key, wallet provider (when `raw: false`),
37626
+ * and optional `skipSimulation` / `hubWalletSwap` / `partnerFee`.
37627
+ * @returns A `Result<CreateVaultIntentResult<K, Raw>, LeverageYieldCreateIntentError>`.
37628
+ * On success contains:
37629
+ * - `tx` — chain-specific tx hash (executed) or raw tx data (raw mode).
37630
+ * - `intent` — the fully constructed `Intent` object augmented with `feeAmount`.
37631
+ * - `relayData` — `{ address, payload }` needed to submit the intent to the relayer.
37632
+ *
37633
+ * On failure `result.error` is a SodaxError with `VALIDATION_FAILED` (invariant
37634
+ * precondition), `INTENT_CREATION_FAILED` (spoke-side creation/deposit failed) or
37635
+ * `UNKNOWN` (defensive fallback).
37636
+ */
37637
+ async createVaultIntent(_params) {
37638
+ const { params, skipSimulation, hubWalletSwap, partnerFee = this.config.swapPartnerFee } = _params;
37639
+ const baseCtx = { srcChainKey: params.srcChainKey, dstChainKey: params.dstChainKey };
37640
+ try {
37641
+ leverageYieldInvariant(
37642
+ isUndefinedOrValidWalletProviderForChainKey(params.srcChainKey, _params.walletProvider),
37643
+ `Invalid wallet provider for chain key: ${params.srcChainKey}`,
37644
+ baseCtx
37645
+ );
37646
+ const hubChainKey = this.hubProvider.chainConfig.chain.key;
37647
+ const inputTokenChainKey = hubWalletSwap ? hubChainKey : params.srcChainKey;
37648
+ leverageYieldInvariant(
37649
+ this.config.isValidOriginalAssetAddress(inputTokenChainKey, params.inputToken),
37650
+ `Unsupported spoke chain token (srcChainKey: ${inputTokenChainKey}, inputToken: ${params.inputToken})`,
37651
+ { ...baseCtx, field: "inputToken" }
37652
+ );
37653
+ leverageYieldInvariant(
37654
+ this.config.isValidOriginalAssetAddress(params.dstChainKey, params.outputToken),
37655
+ `Unsupported spoke chain token (params.dstChain: ${params.dstChainKey}, params.outputToken: ${params.outputToken})`,
37656
+ { ...baseCtx, field: "outputToken" }
37657
+ );
37658
+ leverageYieldInvariant(
37659
+ this.config.isValidSpokeChainKey(params.srcChainKey),
37660
+ `Invalid spoke chain (srcChainKey): ${params.srcChainKey}`,
37661
+ { ...baseCtx, field: "srcChainKey" }
37662
+ );
37663
+ leverageYieldInvariant(
37664
+ this.config.isValidSpokeChainKey(params.dstChainKey),
37665
+ `Invalid spoke chain (params.dstChain): ${params.dstChainKey}`,
37666
+ { ...baseCtx, field: "dstChainKey" }
37667
+ );
37668
+ if (isBitcoinChainKey(params.dstChainKey) && params.outputToken === "BTC") {
37669
+ leverageYieldInvariant(
37670
+ params.minOutputAmount >= 546n,
37671
+ `Invalid minOutputAmount (params.minOutputAmount): ${params.minOutputAmount}`,
37672
+ { ...baseCtx, field: "minOutputAmount" }
37673
+ );
37674
+ }
37675
+ const personalAddress = params.srcAddress;
37676
+ let walletAddress = personalAddress;
37677
+ if (isBitcoinChainKeyType(params.srcChainKey) && _params.raw === false) {
37678
+ leverageYieldInvariant(
37679
+ isBitcoinWalletProviderType(_params.walletProvider),
37680
+ `Invalid wallet provider for chain key: ${params.srcChainKey}`,
37681
+ baseCtx
37682
+ );
37683
+ walletAddress = await this.spoke.bitcoin.getEffectiveWalletAddress(personalAddress);
37684
+ await this.spoke.bitcoin.radfi.ensureRadfiAccessToken(_params.walletProvider);
37685
+ }
37686
+ const creatorHubWalletAddress = await this.hubProvider.getUserHubWalletAddress(walletAddress, params.srcChainKey);
37687
+ if (hubWalletSwap) {
37688
+ const [data2, intent2, feeAmount2] = EvmSolverService.constructCreateIntentData(
37689
+ { ...params, srcChainKey: hubChainKey, srcAddress: creatorHubWalletAddress },
37690
+ creatorHubWalletAddress,
37691
+ this.config,
37692
+ partnerFee
37693
+ );
37694
+ const coreSendMessageParams = {
37695
+ srcChainKey: params.srcChainKey,
37696
+ // Personal address — NOT the resolved trading `walletAddress`. SpokeService.sendMessage
37697
+ // re-resolves the effective (Bitcoin trading) address itself; passing the already-resolved
37698
+ // trading address here would double-resolve it (getTradingWallet(tradingAddress) →
37699
+ // "Trading wallet not found"). The trading address is used only for the hub-wallet
37700
+ // derivation above (creatorHubWalletAddress). Mirrors MoneyMarketService borrow/withdraw.
37701
+ srcAddress: personalAddress,
37702
+ dstChainKey: hubChainKey,
37703
+ dstAddress: creatorHubWalletAddress,
37704
+ payload: data2,
37705
+ skipSimulation
37706
+ };
37707
+ const txResult2 = await this.spoke.sendMessage(
37708
+ _params.raw ? { ...coreSendMessageParams, raw: true } : {
37709
+ ...coreSendMessageParams,
37710
+ raw: false,
37711
+ walletProvider: _params.walletProvider
37712
+ }
37713
+ );
37714
+ if (!txResult2.ok) {
37715
+ if (isLeverageYieldCreateIntentError(txResult2.error)) {
37716
+ return { ok: false, error: txResult2.error };
37717
+ }
37718
+ return { ok: false, error: intentCreationFailed("leverageYield", txResult2.error, baseCtx) };
37719
+ }
37720
+ return {
37721
+ ok: true,
37722
+ value: {
37723
+ tx: txResult2.value,
37724
+ intent: { ...intent2, feeAmount: feeAmount2 },
37725
+ relayData: { address: creatorHubWalletAddress, payload: data2 }
37726
+ }
37727
+ };
37728
+ }
37729
+ if (isHubChainKeyType(params.srcChainKey) && isSonicChainKeyType(params.srcChainKey)) {
37730
+ const coreSonicParams = {
37731
+ createIntentParams: params,
37732
+ creatorHubWalletAddress,
37733
+ solverConfig: this.config.solver,
37734
+ fee: partnerFee,
37735
+ hubProvider: this.hubProvider
37736
+ };
37737
+ const [txResult2, intent2, feeAmount2, data2] = await SonicSpokeService.createSwapIntent(
37738
+ _params.raw ? { ...coreSonicParams, raw: true } : {
37739
+ ...coreSonicParams,
37740
+ raw: false,
37741
+ walletProvider: _params.walletProvider
37742
+ }
37743
+ );
37744
+ return {
37745
+ ok: true,
37746
+ value: {
37747
+ tx: txResult2,
37748
+ intent: { ...intent2, feeAmount: feeAmount2 },
37749
+ relayData: { address: intent2.creator, payload: data2 }
37750
+ }
37751
+ };
37752
+ }
37753
+ const [data, intent, feeAmount] = EvmSolverService.constructCreateIntentData(
37754
+ {
37755
+ ...params,
37756
+ srcAddress: walletAddress
37757
+ },
37758
+ creatorHubWalletAddress,
37759
+ this.config,
37760
+ partnerFee
37761
+ );
37762
+ const coreDepositParams = {
37763
+ srcChainKey: params.srcChainKey,
37764
+ srcAddress: walletAddress,
37765
+ to: creatorHubWalletAddress,
37766
+ token: params.inputToken,
37767
+ amount: params.inputAmount,
37768
+ data,
37769
+ skipSimulation
37770
+ };
37771
+ const txResult = await this.spoke.deposit(
37772
+ _params.raw ? {
37773
+ ...coreDepositParams,
37774
+ raw: true
37775
+ } : {
37776
+ ...coreDepositParams,
37777
+ raw: false,
37778
+ walletProvider: _params.walletProvider
37779
+ }
37780
+ );
37781
+ if (!txResult.ok) {
37782
+ if (isLeverageYieldCreateIntentError(txResult.error)) {
37783
+ return { ok: false, error: txResult.error };
37784
+ }
37785
+ return {
37786
+ ok: false,
37787
+ error: intentCreationFailed("leverageYield", txResult.error, baseCtx)
37788
+ };
37789
+ }
37790
+ return {
37791
+ ok: true,
37792
+ value: {
37793
+ tx: txResult.value,
37794
+ intent: { ...intent, feeAmount },
37795
+ relayData: { address: intent.creator, payload: data }
37796
+ }
37797
+ };
37798
+ } catch (error) {
37799
+ if (isLeverageYieldCreateIntentError(error)) return { ok: false, error };
37800
+ return {
37801
+ ok: false,
37802
+ error: intentCreationFailed("leverageYield", error, baseCtx)
37803
+ };
37804
+ }
37805
+ }
37806
+ /**
37807
+ * Executes a full end-to-end leverage-yield vault swap (deposit or withdraw).
37808
+ * Leverage-yield copy of the swap domain's `swap()` orchestrator:
37809
+ * 1. Calls {@link LeverageYieldService.createVaultIntent} to submit the intent
37810
+ * transaction on the source spoke chain.
37811
+ * 2. Verifies the spoke transaction landed on-chain.
37812
+ * 3. For non-hub source chains: submits the spoke tx to the relayer and waits for the
37813
+ * relay packet to land on the hub (Sonic). Skipped when `srcChainKey` is the hub.
37814
+ * 4. Notifies the solver, triggering it to fill the intent.
37815
+ *
37816
+ * Spread a {@link LeverageYieldSwapPayload} from `deposit` / `withdraw` into this method
37817
+ * alongside the wallet provider: `vaultSwap({ ...payload, walletProvider })`.
37818
+ *
37819
+ * @returns A `Result<VaultSwapResponse, LeverageYieldSwapError>`. On success:
37820
+ * - `solverExecutionResponse` — solver acknowledgement (`{ answer: 'OK', intent_hash }`).
37821
+ * - `intent` — the on-chain intent object that was created.
37822
+ * - `intentDeliveryInfo` — source/destination chain keys, tx hashes, and user addresses.
37823
+ *
37824
+ * On failure `result.error` carries one of the create-intent codes plus
37825
+ * `TX_VERIFICATION_FAILED`, `TX_SUBMIT_FAILED`, `RELAY_TIMEOUT`, `RELAY_FAILED`,
37826
+ * `EXECUTION_FAILED`, `EXTERNAL_API_ERROR` or `UNKNOWN`.
37827
+ */
37828
+ async vaultSwap(_params) {
37829
+ const { params } = _params;
37830
+ const srcChainKey = params.srcChainKey;
37831
+ const baseCtx = { srcChainKey, dstChainKey: params.dstChainKey, action: "vaultSwap" };
37832
+ try {
37833
+ const timeout = _params.timeout;
37834
+ const createIntentResult = await this.createVaultIntent(_params);
37835
+ if (!createIntentResult.ok) {
37836
+ return { ok: false, error: createIntentResult.error };
37837
+ }
37838
+ const { tx: spokeTxHash, intent, relayData } = createIntentResult.value;
37839
+ const verifyTxHashResult = await this.spoke.verifyTxHash({
37840
+ txHash: spokeTxHash,
37841
+ chainKey: srcChainKey
37842
+ });
37843
+ if (!verifyTxHashResult.ok) {
37844
+ return {
37845
+ ok: false,
37846
+ error: verifyFailed("leverageYield", verifyTxHashResult.error, baseCtx)
37847
+ };
37848
+ }
37849
+ let dstIntentTxHash;
37850
+ if (isHubChainKeyType(srcChainKey)) {
37851
+ dstIntentTxHash = spokeTxHash;
37852
+ } else {
37853
+ const packet = await relayTxAndWaitPacket({
37854
+ srcTxHash: spokeTxHash,
37855
+ data: relayData,
37856
+ chainKey: srcChainKey,
37857
+ relayerApiEndpoint: this.config.relay.relayerApiEndpoint,
37858
+ timeout
37859
+ });
37860
+ if (!packet.ok) {
37861
+ return {
37862
+ ok: false,
37863
+ error: mapRelayFailure(packet.error, { feature: "leverageYield", ...baseCtx })
37864
+ };
37865
+ }
37866
+ dstIntentTxHash = packet.value.dst_tx_hash;
37867
+ }
37868
+ const postExecResult = await this.notifySolver({
37869
+ intent_tx_hash: dstIntentTxHash
37870
+ });
37871
+ if (!postExecResult.ok) {
37872
+ return { ok: false, error: postExecResult.error };
37873
+ }
37874
+ return {
37875
+ ok: true,
37876
+ value: {
37877
+ solverExecutionResponse: postExecResult.value,
37878
+ intent,
37879
+ intentDeliveryInfo: {
37880
+ srcChainKey,
37881
+ srcTxHash: spokeTxHash,
37882
+ srcAddress: params.srcAddress,
37883
+ dstChainKey: params.dstChainKey,
37884
+ dstTxHash: dstIntentTxHash,
37885
+ dstAddress: params.dstAddress
37886
+ }
37887
+ }
37888
+ };
37889
+ } catch (error) {
37890
+ if (isLeverageYieldSwapError(error)) return { ok: false, error };
37891
+ return {
37892
+ ok: false,
37893
+ error: unknownFailed("leverageYield", error, baseCtx)
37894
+ };
37895
+ }
37896
+ }
37897
+ /**
37898
+ * Notifies the solver that the vault intent landed on the hub, triggering it to fill.
37899
+ * Leverage-yield copy of the swap domain's `postExecution` — emits only
37900
+ * `EXECUTION_FAILED` / `EXTERNAL_API_ERROR` / `UNKNOWN` (relay/verify codes appear only
37901
+ * on {@link LeverageYieldService.vaultSwap}, which owns the verify + relay steps).
37902
+ *
37903
+ * Called automatically by {@link LeverageYieldService.vaultSwap} after the relay packet
37904
+ * lands on the hub. Public so callers who created the intent via
37905
+ * {@link LeverageYieldService.createVaultIntent} and relayed it themselves can finish the
37906
+ * flow manually.
37907
+ *
37908
+ * @param request - `{ intent_tx_hash }` — the hub-chain (Sonic) tx hash where the intent
37909
+ * was registered (the relay packet's `dst_tx_hash`, or the spoke tx hash for hub-sourced
37910
+ * intents).
37911
+ */
37912
+ async notifySolver(request) {
37913
+ try {
37914
+ const result = await SolverApiService.postExecution(request, this.config.solver, this.config.logger);
37915
+ if (result.ok) return result;
37916
+ const detail = result.error?.detail ?? {
37917
+ code: -999,
37918
+ // SolverIntentErrorCode.UNKNOWN
37919
+ message: "Solver returned malformed error response"
37920
+ };
37921
+ return {
37922
+ ok: false,
37923
+ error: new SodaxError("EXTERNAL_API_ERROR", detail.message, {
37924
+ feature: "leverageYield",
37925
+ context: {
37926
+ phase: "postExecution",
37927
+ api: "solver",
37928
+ solverCode: detail.code,
37929
+ solverDetail: detail
37930
+ }
37931
+ })
37932
+ };
37933
+ } catch (error) {
37934
+ if (isLeverageYieldPostExecutionError(error)) return { ok: false, error };
37935
+ return { ok: false, error: executionFailed("leverageYield", error, { phase: "postExecution" }) };
37936
+ }
37937
+ }
37938
+ /**
37939
+ * Approves the vault's underlying asset to the leverage vault on Sonic. For callers
37940
+ * interacting with the vault directly on the hub — the swap-style {@link
37941
+ * LeverageYieldService.deposit} flow handles its own approvals.
37942
+ */
37943
+ async approve(params) {
37944
+ const baseCtx = { action: "approve" };
37945
+ try {
37946
+ leverageYieldInvariant(params.amount > 0n, "Amount must be greater than 0", { ...baseCtx, field: "amount" });
37947
+ leverageYieldInvariant(params.vault.length > 0, "Vault address is required", { ...baseCtx, field: "vault" });
37948
+ const assetResult = await this.getAsset(params.vault);
37949
+ if (!assetResult.ok) {
37950
+ return { ok: false, error: approveFailed("leverageYield", assetResult.error, baseCtx) };
37951
+ }
37952
+ const from = await params.walletProvider.getWalletAddress();
37953
+ const baseApprove = {
37954
+ token: assetResult.value,
37955
+ amount: params.amount,
37956
+ from,
37957
+ spender: params.vault
37958
+ };
37959
+ if (params.raw) {
37960
+ const tx2 = await Erc20Service.approve({ ...baseApprove, raw: true });
37961
+ return { ok: true, value: tx2 };
37962
+ }
37963
+ const tx = await Erc20Service.approve({
37964
+ ...baseApprove,
37965
+ raw: false,
37966
+ walletProvider: params.walletProvider
37967
+ });
37968
+ return { ok: true, value: tx };
37969
+ } catch (error) {
37970
+ if (isLeverageYieldApproveError(error)) return { ok: false, error };
37971
+ return { ok: false, error: approveFailed("leverageYield", error, baseCtx) };
37972
+ }
37973
+ }
37974
+ /**
37975
+ * Reads on-chain allowance of the vault's underlying asset for `owner → vault`. Returns
37976
+ * `true` when the allowance covers `amount`. Use before a direct
37977
+ * {@link LeverageYieldService.deposit}.
37978
+ */
37979
+ async isAllowanceValid(params) {
37980
+ const baseCtx = { action: "allowanceCheck" };
37981
+ try {
37982
+ leverageYieldInvariant(params.amount > 0n, "Amount must be greater than 0", { ...baseCtx, field: "amount" });
37983
+ const assetResult = await this.getAsset(params.vault);
37984
+ if (!assetResult.ok) {
37985
+ return { ok: false, error: allowanceCheckFailed("leverageYield", assetResult.error, baseCtx) };
37986
+ }
37987
+ const allowance = await this.hubProvider.publicClient.readContract({
37988
+ address: assetResult.value,
37989
+ abi: erc20Abi$1,
37990
+ functionName: "allowance",
37991
+ args: [params.owner, params.vault]
37992
+ });
37993
+ return { ok: true, value: allowance >= params.amount };
37994
+ } catch (error) {
37995
+ if (isLeverageYieldAllowanceCheckError(error)) return { ok: false, error };
37996
+ return { ok: false, error: allowanceCheckFailed("leverageYield", error, baseCtx) };
37997
+ }
37998
+ }
37999
+ // ─── Reads ──────────────────────────────────────────────────────────────
38000
+ /** ERC-4626 `asset()` of the vault — the sodaWEETH-style underlying. */
38001
+ async getAsset(vault) {
38002
+ try {
38003
+ const value = await this.hubProvider.publicClient.readContract({
38004
+ address: vault,
38005
+ abi: leverageYieldVaultAbi,
38006
+ functionName: "asset"
38007
+ });
38008
+ return { ok: true, value };
38009
+ } catch (error) {
38010
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38011
+ return { ok: false, error: lookupFailed("leverageYield", "getAsset", error) };
38012
+ }
38013
+ }
38014
+ /** Reads the vault's leveraged position snapshot via the non-standard `getPositionDetails`. */
38015
+ async getPosition(vault) {
38016
+ try {
38017
+ const [collateral, debt, ltv, healthFactor, idleAsset] = await this.hubProvider.publicClient.readContract({
38018
+ address: vault,
38019
+ abi: leverageYieldVaultAbi,
38020
+ functionName: "getPositionDetails"
38021
+ });
38022
+ return { ok: true, value: { collateral, debt, ltv, healthFactor, idleAsset } };
38023
+ } catch (error) {
38024
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38025
+ return { ok: false, error: lookupFailed("leverageYield", "getPosition", error) };
38026
+ }
38027
+ }
38028
+ /**
38029
+ * Computes the steady-state APR of a leverage-yield vault from the AAVE supply/borrow
38030
+ * rates of its asset and borrowToken, scaled by the vault's target leverage. Matches the
38031
+ * convention used by leveraged-LSD vaults (Origami, Gearbox, etc.) — assumes constant
38032
+ * LTV at `targetLTV` and constant AAVE rates.
38033
+ *
38034
+ * Returns raw fields in RAY (1e27, AAVE's native rate scale) plus the leverage multiplier
38035
+ * in WAD (1e18). See {@link LeverageYieldApr} for the formula and caveats.
38036
+ */
38037
+ async getApr(vault) {
38038
+ try {
38039
+ const [pool, asset, borrowToken, targetLtvBps] = await Promise.all([
38040
+ this.hubProvider.publicClient.readContract({
38041
+ address: vault,
38042
+ abi: leverageYieldVaultAbi,
38043
+ functionName: "pool"
38044
+ }),
38045
+ this.hubProvider.publicClient.readContract({
38046
+ address: vault,
38047
+ abi: leverageYieldVaultAbi,
38048
+ functionName: "asset"
38049
+ }),
38050
+ this.hubProvider.publicClient.readContract({
38051
+ address: vault,
38052
+ abi: leverageYieldVaultAbi,
38053
+ functionName: "borrowToken"
38054
+ }),
38055
+ this.hubProvider.publicClient.readContract({
38056
+ address: vault,
38057
+ abi: leverageYieldVaultAbi,
38058
+ functionName: "targetLTV"
38059
+ })
38060
+ ]);
38061
+ const [assetReserve, borrowReserve] = await Promise.all([
38062
+ this.hubProvider.publicClient.readContract({
38063
+ address: pool,
38064
+ abi: poolAbi,
38065
+ functionName: "getReserveData",
38066
+ args: [asset]
38067
+ }),
38068
+ this.hubProvider.publicClient.readContract({
38069
+ address: pool,
38070
+ abi: poolAbi,
38071
+ functionName: "getReserveData",
38072
+ args: [borrowToken]
38073
+ })
38074
+ ]);
38075
+ const supplyAprRay = assetReserve.currentLiquidityRate;
38076
+ const borrowAprRay = borrowReserve.currentVariableBorrowRate;
38077
+ const BPS = 10000n;
38078
+ const WAD2 = 1000000000000000000n;
38079
+ leverageYieldInvariant(targetLtvBps < BPS, `targetLTV (${targetLtvBps}) must be < 100% (10_000 bps)`, {
38080
+ method: "getApr",
38081
+ field: "targetLtvBps"
38082
+ });
38083
+ const leverageMultiplierWad = targetLtvBps * WAD2 / (BPS - targetLtvBps);
38084
+ const spreadRay = supplyAprRay - borrowAprRay;
38085
+ const netAprRay = supplyAprRay + spreadRay * leverageMultiplierWad / WAD2;
38086
+ return {
38087
+ ok: true,
38088
+ value: { supplyAprRay, borrowAprRay, targetLtvBps, leverageMultiplierWad, netAprRay }
38089
+ };
38090
+ } catch (error) {
38091
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38092
+ return { ok: false, error: lookupFailed("leverageYield", "getApr", error) };
38093
+ }
38094
+ }
38095
+ /**
38096
+ * Off-chain LSD staking-APR for the vault's underlying asset. Looks the vault up in the
38097
+ * registry, hits DefiLlama's per-pool chart endpoint for the configured `poolId`, and on
38098
+ * any fetch failure returns the registry's hardcoded `fallbackAprPct` with `stale: true`.
38099
+ *
38100
+ * Always resolves to `{ ok: true, ... }` for a known vault — the fallback path replaces
38101
+ * the error, since a missing LSD APR shouldn't break the parent call. Returns
38102
+ * `{ aprRay: 0n, stale: true, label: 'no LSD source' }` for vaults without an
38103
+ * `lsdSource` configured (non-LSD strategies); callers can treat that as "skip LSD".
38104
+ */
38105
+ async getLsdApr(vault) {
38106
+ try {
38107
+ const cfg = this.getVaultByAddress(vault);
38108
+ const source = cfg?.lsdSource;
38109
+ if (!source) {
38110
+ return { ok: true, value: { aprRay: 0n, label: "no LSD source", stale: true } };
38111
+ }
38112
+ try {
38113
+ const aprPct = await fetchDefillamaApr(source.poolId);
38114
+ return { ok: true, value: { aprRay: pctToRay(aprPct), label: source.label, stale: false } };
38115
+ } catch (fetchError) {
38116
+ this.config.logger.warn("[leverageYield] DefiLlama APR fetch failed; using fallbackAprPct", {
38117
+ vault,
38118
+ poolId: source.poolId,
38119
+ fallbackAprPct: source.fallbackAprPct,
38120
+ error: fetchError instanceof Error ? fetchError.message : String(fetchError)
38121
+ });
38122
+ return {
38123
+ ok: true,
38124
+ value: { aprRay: pctToRay(source.fallbackAprPct), label: `${source.label} (fallback)`, stale: true }
38125
+ };
38126
+ }
38127
+ } catch (error) {
38128
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38129
+ return { ok: false, error: lookupFailed("leverageYield", "getLsdApr", error) };
38130
+ }
38131
+ }
38132
+ /**
38133
+ * Combined view of {@link getApr} + {@link getLsdApr}: re-applies the vault's leverage
38134
+ * formula with the LSD's native staking yield folded into the supply side, exposing the
38135
+ * **effective** net APR that LSD-backed strategies actually earn. The AAVE-only
38136
+ * `netAprRay` is preserved on the return value for callers who want to display both.
38137
+ *
38138
+ * effectiveSupply = supplyAprRay + lsdApr.aprRay
38139
+ * effectiveNet = effectiveSupply + leverage × (effectiveSupply − borrowAprRay)
38140
+ *
38141
+ * Fetches AAVE rates and the LSD APR in parallel for one round-trip's worth of latency.
38142
+ */
38143
+ async getEffectiveApr(vault) {
38144
+ try {
38145
+ const [aprResult, lsdResult] = await Promise.all([this.getApr(vault), this.getLsdApr(vault)]);
38146
+ if (!aprResult.ok) return aprResult;
38147
+ if (!lsdResult.ok) return lsdResult;
38148
+ const apr = aprResult.value;
38149
+ const lsd = lsdResult.value;
38150
+ const effectiveSupplyAprRay = apr.supplyAprRay + lsd.aprRay;
38151
+ const spreadRay = effectiveSupplyAprRay - apr.borrowAprRay;
38152
+ const WAD2 = 1000000000000000000n;
38153
+ const effectiveNetAprRay = effectiveSupplyAprRay + spreadRay * apr.leverageMultiplierWad / WAD2;
38154
+ return {
38155
+ ok: true,
38156
+ value: { ...apr, lsdApr: lsd, effectiveSupplyAprRay, effectiveNetAprRay }
38157
+ };
38158
+ } catch (error) {
38159
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38160
+ return { ok: false, error: lookupFailed("leverageYield", "getEffectiveApr", error) };
38161
+ }
38162
+ }
38163
+ /** Synchronously withdrawable assets for `owner` (clamped against leverage HF floor). */
38164
+ async getMaxWithdraw(vault, owner) {
38165
+ const inner = await Erc4626Service.getMaxWithdraw(vault, owner, this.hubProvider.publicClient);
38166
+ if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "getMaxWithdraw", inner.error) };
38167
+ return { ok: true, value: inner.value };
38168
+ }
38169
+ /** Total underlying assets currently held by the vault (vault-asset units, 18 decimals) — TVL. */
38170
+ async getTotalAssets(vault) {
38171
+ const inner = await Erc4626Service.getTotalAssets(vault, this.hubProvider.publicClient);
38172
+ if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "getTotalAssets", inner.error) };
38173
+ return { ok: true, value: inner.value };
38174
+ }
38175
+ /** Shares minted for a given asset deposit. */
38176
+ async previewDeposit(vault, assets) {
38177
+ const inner = await Erc4626Service.previewDeposit(vault, assets, this.hubProvider.publicClient);
38178
+ if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "previewDeposit", inner.error) };
38179
+ return { ok: true, value: inner.value };
38180
+ }
38181
+ /** Shares burned for a given asset withdrawal. */
38182
+ async previewWithdraw(vault, assets) {
38183
+ const inner = await Erc4626Service.previewWithdraw(vault, assets, this.hubProvider.publicClient);
38184
+ if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "previewWithdraw", inner.error) };
38185
+ return { ok: true, value: inner.value };
38186
+ }
38187
+ /** Assets received for a given share redemption. */
38188
+ async previewRedeem(vault, shares) {
38189
+ const inner = await Erc4626Service.previewRedeem(vault, shares, this.hubProvider.publicClient);
38190
+ if (!inner.ok) return { ok: false, error: lookupFailed("leverageYield", "previewRedeem", inner.error) };
38191
+ return { ok: true, value: inner.value };
38192
+ }
38193
+ /** Vault shares held by `owner`. */
38194
+ async getShareBalance(vault, owner) {
38195
+ try {
38196
+ const value = await this.hubProvider.publicClient.readContract({
38197
+ address: vault,
38198
+ abi: erc20Abi$1,
38199
+ functionName: "balanceOf",
38200
+ args: [owner]
38201
+ });
38202
+ return { ok: true, value };
38203
+ } catch (error) {
38204
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38205
+ return { ok: false, error: lookupFailed("leverageYield", "getShareBalance", error) };
38206
+ }
38207
+ }
38208
+ /**
38209
+ * Convenience: resolves the user's hub wallet from `(srcChainKey, srcAddress)` and
38210
+ * returns its on-chain `maxWithdraw`, less {@link MAX_WITHDRAW_DUST_BUFFER}. The trim
38211
+ * keeps the value safe for an asset-denominated ERC-4626 `withdraw` — the raw
38212
+ * `maxWithdraw` can trip the round-up that asks for one more share than the user holds.
38213
+ */
38214
+ async getMaxWithdrawForUser(vault, srcChainKey, srcAddress) {
38215
+ try {
38216
+ const hubWallet = await this.hubProvider.getUserHubWalletAddress(srcAddress, srcChainKey);
38217
+ const maxWithdrawResult = await this.getMaxWithdraw(vault, hubWallet);
38218
+ if (!maxWithdrawResult.ok) return maxWithdrawResult;
38219
+ const buffered = maxWithdrawResult.value > MAX_WITHDRAW_DUST_BUFFER ? maxWithdrawResult.value - MAX_WITHDRAW_DUST_BUFFER : 0n;
38220
+ return { ok: true, value: buffered };
38221
+ } catch (error) {
38222
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38223
+ return { ok: false, error: lookupFailed("leverageYield", "getMaxWithdrawForUser", error, { srcChainKey }) };
38224
+ }
38225
+ }
38226
+ /**
38227
+ * Convenience: resolves the user's hub wallet from `(srcChainKey, srcAddress)` and
38228
+ * returns its on-chain share balance.
38229
+ */
38230
+ async getShareBalanceForUser(vault, srcChainKey, srcAddress) {
38231
+ try {
38232
+ const hubWallet = await this.hubProvider.getUserHubWalletAddress(srcAddress, srcChainKey);
38233
+ return await this.getShareBalance(vault, hubWallet);
38234
+ } catch (error) {
38235
+ if (isLeverageYieldLookupError(error)) return { ok: false, error };
38236
+ return { ok: false, error: lookupFailed("leverageYield", "getShareBalanceForUser", error, { srcChainKey }) };
38237
+ }
38238
+ }
38239
+ };
38240
+
37090
38241
  // src/shared/entities/Sodax.ts
37091
38242
  var Sodax = class {
37092
38243
  instanceConfig;
@@ -37108,17 +38259,26 @@ var Sodax = class {
37108
38259
  // Recovery service for withdrawing stuck hub-wallet assets back to a spoke chain
37109
38260
  dex;
37110
38261
  // Dex service enabling DEX operations
38262
+ leverageYield;
38263
+ // Leverage-yield service: cross-chain deposits / withdrawals into ERC-4626 leverage vaults on Sonic
37111
38264
  config;
37112
38265
  // Config service enabling configuration data fetching from the backend API or fallbacking to default values
37113
38266
  hubProvider;
37114
38267
  // hub provider for the hub chain (e.g. Sonic mainnet)
37115
38268
  spoke;
37116
38269
  // spoke service enabling spoke chain operations
37117
- constructor(config) {
37118
- const logger = resolveLogger(config?.logger);
37119
- this.instanceConfig = config ? mergeSodaxConfig(sodaxConfig, config) : sodaxConfig;
38270
+ constructor(options) {
38271
+ const logger = resolveLogger(options?.logger);
38272
+ const fee = options?.fee;
38273
+ this.instanceConfig = options ? mergeSodaxConfig(sodaxConfig, options) : sodaxConfig;
37120
38274
  this.backendApi = new BackendApiService(this.instanceConfig.api, logger);
37121
- this.config = new ConfigService({ api: this.backendApi, config: this.instanceConfig, userConfig: config, logger });
38275
+ this.config = new ConfigService({
38276
+ api: this.backendApi,
38277
+ config: this.instanceConfig,
38278
+ userConfig: options,
38279
+ logger,
38280
+ fee
38281
+ });
37122
38282
  this.hubProvider = new EvmHubProvider({ config: this.config });
37123
38283
  this.spoke = new SpokeService({ config: this.config, hubProvider: this.hubProvider });
37124
38284
  this.swaps = new SwapService({
@@ -37153,6 +38313,11 @@ var Sodax = class {
37153
38313
  config: this.config,
37154
38314
  spoke: this.spoke
37155
38315
  });
38316
+ this.leverageYield = new LeverageYieldService({
38317
+ hubProvider: this.hubProvider,
38318
+ config: this.config,
38319
+ spoke: this.spoke
38320
+ });
37156
38321
  }
37157
38322
  /**
37158
38323
  * Initializes the Sodax instance with dynamic configuration.
@@ -37193,4 +38358,4 @@ var isPartnerError = isCodeMember(PARTNER_CODES);
37193
38358
  (*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
37194
38359
  */
37195
38360
 
37196
- 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, LockupMultiplier, LockupPeriod, 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, 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, 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, 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, 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 };
38361
+ 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 };