@sodax/sdk 1.0.4-beta-rc1 → 1.0.4-beta

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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { IconAddress, IInjectiveWalletProvider, InjectiveExecuteResponse, SolanaChainConfig, SolanaBase58PublicKey, SolanaRpcResponseAndContext, SolanaTokenAmount, SolanaRawTransactionInstruction, WalletAddressProvider, SolanaSerializedTransaction, ISolanaWalletProvider, StellarSpokeChainConfig, StellarRpcConfig, IStellarWalletProvider, SuiSpokeChainConfig, SuiPaginatedCoins, SuiExecutionResult, ISuiWalletProvider, Address, Erc20Token, HttpUrl, SpokeChainId, Token, GetMoneyMarketTokensApiResponse, IconSpokeChainConfig, IIconWalletProvider, EvmHubChainConfig, EvmSpokeChainConfig, IEvmWalletProvider, SpokeChainConfig, SonicSpokeChainConfig, EvmChainId, InjectiveSpokeChainConfig, JsonObject, InjectiveRawTransaction, AssetInfo, Hex as Hex$1, TokenInfo, HubAddress, ChainId, EvmRawTransaction, SolverConfig, Hash as Hash$1, IntentRelayChainId, StellarRawTransaction, MoneyMarketConfig, spokeChainConfig, ICON_MAINNET_CHAIN_ID, ChainType, BaseSpokeChainConfig, IConfigApi, GetAllConfigApiResponse, GetChainsApiResponse, GetSwapTokensApiResponse, GetSwapTokensByChainIdApiResponse, GetMoneyMarketReserveAssetsApiResponse, GetMoneyMarketTokensByChainIdApiResponse, GetHubAssetsApiResponse, GetHubAssetsByChainIdApiResponse, GetRelayChainIdMapApiResponse, GetSpokeChainConfigApiResponse, OriginalAssetAddress, HubAssetInfo, HubChainId, XToken, EvmRawTransactionReceipt, IconEoaAddress, HubChainConfig } from '@sodax/types';
1
+ import { IconAddress, IInjectiveWalletProvider, InjectiveExecuteResponse, SolanaChainConfig, SolanaBase58PublicKey, SolanaRpcResponseAndContext, SolanaTokenAmount, SolanaRawTransactionInstruction, WalletAddressProvider, SolanaSerializedTransaction, ISolanaWalletProvider, StellarSpokeChainConfig, StellarRpcConfig, IStellarWalletProvider, SuiSpokeChainConfig, SuiPaginatedCoins, SuiExecutionResult, ISuiWalletProvider, Address, Erc20Token, HttpUrl, SpokeChainId, Token, GetMoneyMarketTokensApiResponse, defaultSharedConfig, IconSpokeChainConfig, IIconWalletProvider, EvmHubChainConfig, EvmSpokeChainConfig, IEvmWalletProvider, SpokeChainConfig, SonicSpokeChainConfig, EvmChainId, InjectiveSpokeChainConfig, JsonObject, InjectiveRawTransaction, AssetInfo, Hex as Hex$1, TokenInfo, HubAddress, ChainId, EvmRawTransaction, SolverConfig, Hash as Hash$1, IntentRelayChainId, StellarRawTransaction, MoneyMarketConfig, spokeChainConfig, ICON_MAINNET_CHAIN_ID, ChainType, BaseSpokeChainConfig, IConfigApi, GetAllConfigApiResponse, GetChainsApiResponse, GetSwapTokensApiResponse, GetSwapTokensByChainIdApiResponse, GetMoneyMarketReserveAssetsApiResponse, GetMoneyMarketTokensByChainIdApiResponse, GetHubAssetsApiResponse, GetHubAssetsByChainIdApiResponse, GetRelayChainIdMapApiResponse, GetSpokeChainConfigApiResponse, OriginalAssetAddress, HubAssetInfo, HubChainId, XToken, EvmRawTransactionReceipt, IconEoaAddress, HubChainConfig, BridgeLimit } from '@sodax/types';
2
2
  export * from '@sodax/types';
3
3
  import * as viem from 'viem';
4
4
  import { Hex, PublicClient, HttpTransport, Address as Address$1, WalletClient, CustomTransport, Chain, Account as Account$1, Hash, GetLogsReturnType, TransactionReceipt } from 'viem';
@@ -6541,6 +6541,9 @@ declare class MoneyMarketService {
6541
6541
  * Approve amount spending if isAllowanceValid returns false.
6542
6542
  * For evm spoke chains, the spender is the asset manager contract while
6543
6543
  * for sonic spoke (hub) chain, the spender is the user router contract.
6544
+ * NOTE: Stellar requires trustline when being either sender or receiver. Thus
6545
+ * you should make sure that both src and destination wallets have sufficient trustlines.
6546
+ * Make sure to invoke this method using wallet address which is about to receive the tokens!
6544
6547
  * @param token - ERC20 token address
6545
6548
  * @param amount - Amount to approve
6546
6549
  * @param spender - Spender address
@@ -6941,6 +6944,7 @@ type SodaxConfig = {
6941
6944
  hubProviderConfig?: EvmHubProviderConfig;
6942
6945
  relayerApiEndpoint?: HttpUrl;
6943
6946
  backendApiConfig?: BackendApiConfig;
6947
+ sharedConfig?: typeof defaultSharedConfig;
6944
6948
  };
6945
6949
  /**
6946
6950
  * Sodax class is used to interact with the Sodax.
@@ -7384,6 +7388,14 @@ declare class EvmVaultTokenService {
7384
7388
  * @returns Token information as a TokenInfo object.
7385
7389
  */
7386
7390
  static getTokenInfo(vault: Address$1, token: Address$1, publicClient: PublicClient<HttpTransport>): Promise<TokenInfo>;
7391
+ /**
7392
+ * Fetches token information for a list of tokens in a vault using a multicall.
7393
+ * @param vault - The address of the vault contract.
7394
+ * @param tokens - An array of token addresses to fetch info for.
7395
+ * @param publicClient - The Viem PublicClient instance used to interact with the blockchain.
7396
+ * @returns A promise that resolves to an array of TokenInfo objects, one for each provided token.
7397
+ */
7398
+ static getTokenInfos(vault: Address$1, tokens: Address$1[], publicClient: PublicClient<HttpTransport>): Promise<TokenInfo[]>;
7387
7399
  /**
7388
7400
  * Retrieves the reserves of the vault.
7389
7401
  * @param vault - The address of the vault.
@@ -8983,6 +8995,14 @@ declare class StellarSpokeService {
8983
8995
  * @returns True if the user has sufficent trustline established for the token, false otherwise.
8984
8996
  */
8985
8997
  static hasSufficientTrustline(token: string, amount: bigint, spokeProvider: StellarSpokeProviderType): Promise<boolean>;
8998
+ /**
8999
+ * Check if the user has sufficent trustline established for the token.
9000
+ * @param token - The token address to check the trustline for.
9001
+ * @param amount - The amount of tokens to check the trustline for.
9002
+ * @param spokeProvider - The Stellar spoke provider.
9003
+ * @returns True if the user has sufficent trustline established for the token, false otherwise.
9004
+ */
9005
+ static walletHasSufficientTrustline(token: string, amount: bigint, walletAddress: string, horizonRpcUrl: HttpUrl): Promise<boolean>;
8986
9006
  /**
8987
9007
  * Request a trustline for a given token and amount.
8988
9008
  * @param token - The token address to request the trustline for.
@@ -9744,6 +9764,7 @@ type ConfigServiceConfig = {
9744
9764
  type ConfigServiceConstructorParams = {
9745
9765
  backendApiService: BackendApiService;
9746
9766
  config?: ConfigServiceConfig;
9767
+ sharedConfig?: typeof defaultSharedConfig;
9747
9768
  };
9748
9769
  /**
9749
9770
  * ConfigApiService - Service for fetching configuration data from the backend API or fallbacking to default values
@@ -9751,6 +9772,7 @@ type ConfigServiceConstructorParams = {
9751
9772
  declare class ConfigService {
9752
9773
  readonly serviceConfig: ConfigServiceConfig;
9753
9774
  readonly backendApiService: BackendApiService;
9775
+ readonly sharedConfig: typeof defaultSharedConfig;
9754
9776
  private initialized;
9755
9777
  private sodaxConfig;
9756
9778
  private originalAssetTohubAssetMap;
@@ -9762,7 +9784,7 @@ declare class ConfigService {
9762
9784
  private supportedTokensPerChain;
9763
9785
  private moneyMarketReserveAssetsSet;
9764
9786
  private spokeChainIdsSet;
9765
- constructor({ backendApiService, config }: ConfigServiceConstructorParams);
9787
+ constructor({ backendApiService, config, sharedConfig }: ConfigServiceConstructorParams);
9766
9788
  initialize(): Promise<Result<void>>;
9767
9789
  getChains(): GetChainsApiResponse;
9768
9790
  getSwapTokens(): GetSwapTokensApiResponse;
@@ -10422,9 +10444,9 @@ declare class BridgeService {
10422
10444
  *
10423
10445
  * @param spokeProvider - The spoke provider instance
10424
10446
  * @param token - The token address to query the balance for
10425
- * @returns {Promise<bigint>} - The token balance as a bigint value
10447
+ * @returns {Promise<BridgeLimit>} - The max bridgeable amount with corresponding decimals
10426
10448
  */
10427
- getBridgeableAmount(from: XToken, to: XToken): Promise<Result<bigint, unknown>>;
10449
+ getBridgeableAmount(from: XToken, to: XToken): Promise<Result<BridgeLimit>>;
10428
10450
  /**
10429
10451
  * Check if two assets on different chains are bridgeable
10430
10452
  * Two assets are bridgeable if they share the same vault on the hub chain
@@ -10447,6 +10469,7 @@ declare class BridgeService {
10447
10469
  */
10448
10470
  getBridgeableTokens(from: SpokeChainId, to: SpokeChainId, token: string): Result<XToken[]>;
10449
10471
  filterTokensWithSameVault(tokens: Record<string, XToken>, to: SpokeChainId, srcAssetInfo: HubAssetInfo | undefined): XToken[];
10472
+ findTokenBalanceInReserves(reserves: VaultReserves, token: XToken): bigint;
10450
10473
  }
10451
10474
 
10452
10475
  declare class StakingLogic {
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { IconAddress, IInjectiveWalletProvider, InjectiveExecuteResponse, SolanaChainConfig, SolanaBase58PublicKey, SolanaRpcResponseAndContext, SolanaTokenAmount, SolanaRawTransactionInstruction, WalletAddressProvider, SolanaSerializedTransaction, ISolanaWalletProvider, StellarSpokeChainConfig, StellarRpcConfig, IStellarWalletProvider, SuiSpokeChainConfig, SuiPaginatedCoins, SuiExecutionResult, ISuiWalletProvider, Address, Erc20Token, HttpUrl, SpokeChainId, Token, GetMoneyMarketTokensApiResponse, IconSpokeChainConfig, IIconWalletProvider, EvmHubChainConfig, EvmSpokeChainConfig, IEvmWalletProvider, SpokeChainConfig, SonicSpokeChainConfig, EvmChainId, InjectiveSpokeChainConfig, JsonObject, InjectiveRawTransaction, AssetInfo, Hex as Hex$1, TokenInfo, HubAddress, ChainId, EvmRawTransaction, SolverConfig, Hash as Hash$1, IntentRelayChainId, StellarRawTransaction, MoneyMarketConfig, spokeChainConfig, ICON_MAINNET_CHAIN_ID, ChainType, BaseSpokeChainConfig, IConfigApi, GetAllConfigApiResponse, GetChainsApiResponse, GetSwapTokensApiResponse, GetSwapTokensByChainIdApiResponse, GetMoneyMarketReserveAssetsApiResponse, GetMoneyMarketTokensByChainIdApiResponse, GetHubAssetsApiResponse, GetHubAssetsByChainIdApiResponse, GetRelayChainIdMapApiResponse, GetSpokeChainConfigApiResponse, OriginalAssetAddress, HubAssetInfo, HubChainId, XToken, EvmRawTransactionReceipt, IconEoaAddress, HubChainConfig } from '@sodax/types';
1
+ import { IconAddress, IInjectiveWalletProvider, InjectiveExecuteResponse, SolanaChainConfig, SolanaBase58PublicKey, SolanaRpcResponseAndContext, SolanaTokenAmount, SolanaRawTransactionInstruction, WalletAddressProvider, SolanaSerializedTransaction, ISolanaWalletProvider, StellarSpokeChainConfig, StellarRpcConfig, IStellarWalletProvider, SuiSpokeChainConfig, SuiPaginatedCoins, SuiExecutionResult, ISuiWalletProvider, Address, Erc20Token, HttpUrl, SpokeChainId, Token, GetMoneyMarketTokensApiResponse, defaultSharedConfig, IconSpokeChainConfig, IIconWalletProvider, EvmHubChainConfig, EvmSpokeChainConfig, IEvmWalletProvider, SpokeChainConfig, SonicSpokeChainConfig, EvmChainId, InjectiveSpokeChainConfig, JsonObject, InjectiveRawTransaction, AssetInfo, Hex as Hex$1, TokenInfo, HubAddress, ChainId, EvmRawTransaction, SolverConfig, Hash as Hash$1, IntentRelayChainId, StellarRawTransaction, MoneyMarketConfig, spokeChainConfig, ICON_MAINNET_CHAIN_ID, ChainType, BaseSpokeChainConfig, IConfigApi, GetAllConfigApiResponse, GetChainsApiResponse, GetSwapTokensApiResponse, GetSwapTokensByChainIdApiResponse, GetMoneyMarketReserveAssetsApiResponse, GetMoneyMarketTokensByChainIdApiResponse, GetHubAssetsApiResponse, GetHubAssetsByChainIdApiResponse, GetRelayChainIdMapApiResponse, GetSpokeChainConfigApiResponse, OriginalAssetAddress, HubAssetInfo, HubChainId, XToken, EvmRawTransactionReceipt, IconEoaAddress, HubChainConfig, BridgeLimit } from '@sodax/types';
2
2
  export * from '@sodax/types';
3
3
  import * as viem from 'viem';
4
4
  import { Hex, PublicClient, HttpTransport, Address as Address$1, WalletClient, CustomTransport, Chain, Account as Account$1, Hash, GetLogsReturnType, TransactionReceipt } from 'viem';
@@ -6541,6 +6541,9 @@ declare class MoneyMarketService {
6541
6541
  * Approve amount spending if isAllowanceValid returns false.
6542
6542
  * For evm spoke chains, the spender is the asset manager contract while
6543
6543
  * for sonic spoke (hub) chain, the spender is the user router contract.
6544
+ * NOTE: Stellar requires trustline when being either sender or receiver. Thus
6545
+ * you should make sure that both src and destination wallets have sufficient trustlines.
6546
+ * Make sure to invoke this method using wallet address which is about to receive the tokens!
6544
6547
  * @param token - ERC20 token address
6545
6548
  * @param amount - Amount to approve
6546
6549
  * @param spender - Spender address
@@ -6941,6 +6944,7 @@ type SodaxConfig = {
6941
6944
  hubProviderConfig?: EvmHubProviderConfig;
6942
6945
  relayerApiEndpoint?: HttpUrl;
6943
6946
  backendApiConfig?: BackendApiConfig;
6947
+ sharedConfig?: typeof defaultSharedConfig;
6944
6948
  };
6945
6949
  /**
6946
6950
  * Sodax class is used to interact with the Sodax.
@@ -7384,6 +7388,14 @@ declare class EvmVaultTokenService {
7384
7388
  * @returns Token information as a TokenInfo object.
7385
7389
  */
7386
7390
  static getTokenInfo(vault: Address$1, token: Address$1, publicClient: PublicClient<HttpTransport>): Promise<TokenInfo>;
7391
+ /**
7392
+ * Fetches token information for a list of tokens in a vault using a multicall.
7393
+ * @param vault - The address of the vault contract.
7394
+ * @param tokens - An array of token addresses to fetch info for.
7395
+ * @param publicClient - The Viem PublicClient instance used to interact with the blockchain.
7396
+ * @returns A promise that resolves to an array of TokenInfo objects, one for each provided token.
7397
+ */
7398
+ static getTokenInfos(vault: Address$1, tokens: Address$1[], publicClient: PublicClient<HttpTransport>): Promise<TokenInfo[]>;
7387
7399
  /**
7388
7400
  * Retrieves the reserves of the vault.
7389
7401
  * @param vault - The address of the vault.
@@ -8983,6 +8995,14 @@ declare class StellarSpokeService {
8983
8995
  * @returns True if the user has sufficent trustline established for the token, false otherwise.
8984
8996
  */
8985
8997
  static hasSufficientTrustline(token: string, amount: bigint, spokeProvider: StellarSpokeProviderType): Promise<boolean>;
8998
+ /**
8999
+ * Check if the user has sufficent trustline established for the token.
9000
+ * @param token - The token address to check the trustline for.
9001
+ * @param amount - The amount of tokens to check the trustline for.
9002
+ * @param spokeProvider - The Stellar spoke provider.
9003
+ * @returns True if the user has sufficent trustline established for the token, false otherwise.
9004
+ */
9005
+ static walletHasSufficientTrustline(token: string, amount: bigint, walletAddress: string, horizonRpcUrl: HttpUrl): Promise<boolean>;
8986
9006
  /**
8987
9007
  * Request a trustline for a given token and amount.
8988
9008
  * @param token - The token address to request the trustline for.
@@ -9744,6 +9764,7 @@ type ConfigServiceConfig = {
9744
9764
  type ConfigServiceConstructorParams = {
9745
9765
  backendApiService: BackendApiService;
9746
9766
  config?: ConfigServiceConfig;
9767
+ sharedConfig?: typeof defaultSharedConfig;
9747
9768
  };
9748
9769
  /**
9749
9770
  * ConfigApiService - Service for fetching configuration data from the backend API or fallbacking to default values
@@ -9751,6 +9772,7 @@ type ConfigServiceConstructorParams = {
9751
9772
  declare class ConfigService {
9752
9773
  readonly serviceConfig: ConfigServiceConfig;
9753
9774
  readonly backendApiService: BackendApiService;
9775
+ readonly sharedConfig: typeof defaultSharedConfig;
9754
9776
  private initialized;
9755
9777
  private sodaxConfig;
9756
9778
  private originalAssetTohubAssetMap;
@@ -9762,7 +9784,7 @@ declare class ConfigService {
9762
9784
  private supportedTokensPerChain;
9763
9785
  private moneyMarketReserveAssetsSet;
9764
9786
  private spokeChainIdsSet;
9765
- constructor({ backendApiService, config }: ConfigServiceConstructorParams);
9787
+ constructor({ backendApiService, config, sharedConfig }: ConfigServiceConstructorParams);
9766
9788
  initialize(): Promise<Result<void>>;
9767
9789
  getChains(): GetChainsApiResponse;
9768
9790
  getSwapTokens(): GetSwapTokensApiResponse;
@@ -10422,9 +10444,9 @@ declare class BridgeService {
10422
10444
  *
10423
10445
  * @param spokeProvider - The spoke provider instance
10424
10446
  * @param token - The token address to query the balance for
10425
- * @returns {Promise<bigint>} - The token balance as a bigint value
10447
+ * @returns {Promise<BridgeLimit>} - The max bridgeable amount with corresponding decimals
10426
10448
  */
10427
- getBridgeableAmount(from: XToken, to: XToken): Promise<Result<bigint, unknown>>;
10449
+ getBridgeableAmount(from: XToken, to: XToken): Promise<Result<BridgeLimit>>;
10428
10450
  /**
10429
10451
  * Check if two assets on different chains are bridgeable
10430
10452
  * Two assets are bridgeable if they share the same vault on the hub chain
@@ -10447,6 +10469,7 @@ declare class BridgeService {
10447
10469
  */
10448
10470
  getBridgeableTokens(from: SpokeChainId, to: SpokeChainId, token: string): Result<XToken[]>;
10449
10471
  filterTokensWithSameVault(tokens: Record<string, XToken>, to: SpokeChainId, srcAssetInfo: HubAssetInfo | undefined): XToken[];
10472
+ findTokenBalanceInReserves(reserves: VaultReserves, token: XToken): bigint;
10450
10473
  }
10451
10474
 
10452
10475
  declare class StakingLogic {
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { CHAIN_IDS, ICON_MAINNET_CHAIN_ID, spokeChainConfig, SUI_MAINNET_CHAIN_ID, STELLAR_MAINNET_CHAIN_ID, ETHEREUM_MAINNET_CHAIN_ID, LIGHTLINK_MAINNET_CHAIN_ID, HYPEREVM_MAINNET_CHAIN_ID, POLYGON_MAINNET_CHAIN_ID, BSC_MAINNET_CHAIN_ID, OPTIMISM_MAINNET_CHAIN_ID, BASE_MAINNET_CHAIN_ID, ARBITRUM_MAINNET_CHAIN_ID, AVALANCHE_MAINNET_CHAIN_ID, SONIC_MAINNET_CHAIN_ID, defaultSodaxConfig, CONFIG_VERSION, hubChainConfig, getIntentRelayChainId, SOLANA_MAINNET_CHAIN_ID, getMoneyMarketConfig, getSolverConfig, ChainIdToIntentRelayChainId } from '@sodax/types';
1
+ import { CHAIN_IDS, ICON_MAINNET_CHAIN_ID, spokeChainConfig, SUI_MAINNET_CHAIN_ID, STELLAR_MAINNET_CHAIN_ID, ETHEREUM_MAINNET_CHAIN_ID, LIGHTLINK_MAINNET_CHAIN_ID, HYPEREVM_MAINNET_CHAIN_ID, POLYGON_MAINNET_CHAIN_ID, BSC_MAINNET_CHAIN_ID, OPTIMISM_MAINNET_CHAIN_ID, BASE_MAINNET_CHAIN_ID, ARBITRUM_MAINNET_CHAIN_ID, AVALANCHE_MAINNET_CHAIN_ID, SONIC_MAINNET_CHAIN_ID, defaultSodaxConfig, defaultSharedConfig, CONFIG_VERSION, hubChainConfig, getIntentRelayChainId, SOLANA_MAINNET_CHAIN_ID, getMoneyMarketConfig, getSolverConfig, ChainIdToIntentRelayChainId } from '@sodax/types';
2
2
  export * from '@sodax/types';
3
3
  import { getAbiItem, defineChain, encodeAbiParameters, parseAbiParameters, createPublicClient, http, fromHex, encodeFunctionData, erc20Abi as erc20Abi$1, toHex, encodePacked, parseEventLogs, keccak256, decodeAbiParameters, isAddress } from 'viem';
4
4
  import { mainnet, lightlinkPhoenix, polygon, bsc, optimism, base, arbitrum, avalanche, sonic } from 'viem/chains';
@@ -6843,6 +6843,7 @@ var getAllLegacybnUSDTokens = () => {
6843
6843
  var ConfigService = class {
6844
6844
  serviceConfig;
6845
6845
  backendApiService;
6846
+ sharedConfig;
6846
6847
  initialized = false;
6847
6848
  sodaxConfig;
6848
6849
  // data structures for quick lookup
@@ -6855,7 +6856,7 @@ var ConfigService = class {
6855
6856
  supportedTokensPerChain;
6856
6857
  moneyMarketReserveAssetsSet;
6857
6858
  spokeChainIdsSet;
6858
- constructor({ backendApiService, config }) {
6859
+ constructor({ backendApiService, config, sharedConfig }) {
6859
6860
  this.serviceConfig = {
6860
6861
  backendApiUrl: config?.backendApiUrl ?? DEFAULT_BACKEND_API_ENDPOINT,
6861
6862
  timeout: config?.timeout ?? DEFAULT_BACKEND_API_TIMEOUT
@@ -6863,6 +6864,10 @@ var ConfigService = class {
6863
6864
  this.backendApiService = backendApiService;
6864
6865
  this.sodaxConfig = defaultSodaxConfig;
6865
6866
  this.loadSodaxConfigDataStructures(this.sodaxConfig);
6867
+ this.sharedConfig = {
6868
+ ...defaultSharedConfig,
6869
+ ...sharedConfig
6870
+ };
6866
6871
  }
6867
6872
  async initialize() {
6868
6873
  try {
@@ -7479,6 +7484,30 @@ var EvmVaultTokenService = class {
7479
7484
  });
7480
7485
  return { decimals, depositFee, withdrawalFee, maxDeposit, isSupported };
7481
7486
  }
7487
+ /**
7488
+ * Fetches token information for a list of tokens in a vault using a multicall.
7489
+ * @param vault - The address of the vault contract.
7490
+ * @param tokens - An array of token addresses to fetch info for.
7491
+ * @param publicClient - The Viem PublicClient instance used to interact with the blockchain.
7492
+ * @returns A promise that resolves to an array of TokenInfo objects, one for each provided token.
7493
+ */
7494
+ static async getTokenInfos(vault, tokens, publicClient) {
7495
+ const infos = await publicClient.multicall({
7496
+ contracts: tokens.map(
7497
+ (token) => ({
7498
+ address: vault,
7499
+ abi: vaultTokenAbi,
7500
+ functionName: "tokenInfo",
7501
+ args: [token]
7502
+ })
7503
+ ),
7504
+ allowFailure: false
7505
+ });
7506
+ return infos.map((info) => {
7507
+ const [decimals, depositFee, withdrawalFee, maxDeposit, isSupported] = info;
7508
+ return { decimals, depositFee, withdrawalFee, maxDeposit, isSupported };
7509
+ });
7510
+ }
7482
7511
  /**
7483
7512
  * Retrieves the reserves of the vault.
7484
7513
  * @param vault - The address of the vault.
@@ -10432,6 +10461,38 @@ var StellarSpokeService = class _StellarSpokeService {
10432
10461
  const availableTrustAmount = limit - balance;
10433
10462
  return availableTrustAmount >= amount;
10434
10463
  }
10464
+ /**
10465
+ * Check if the user has sufficent trustline established for the token.
10466
+ * @param token - The token address to check the trustline for.
10467
+ * @param amount - The amount of tokens to check the trustline for.
10468
+ * @param spokeProvider - The Stellar spoke provider.
10469
+ * @returns True if the user has sufficent trustline established for the token, false otherwise.
10470
+ */
10471
+ static async walletHasSufficientTrustline(token, amount, walletAddress, horizonRpcUrl) {
10472
+ const stellarChainConfig = spokeChainConfig[STELLAR_MAINNET_CHAIN_ID];
10473
+ if (token.toLowerCase() === stellarChainConfig.nativeToken.toLowerCase() || token.toLowerCase() === stellarChainConfig.supportedTokens.legacybnUSD.address.toLowerCase()) {
10474
+ return true;
10475
+ }
10476
+ const trustlineConfig = stellarChainConfig.trustlineConfigs.find(
10477
+ (config) => config.contractId.toLowerCase() === token.toLowerCase()
10478
+ );
10479
+ if (!trustlineConfig) {
10480
+ throw new Error(`Trustline config not found for token: ${token}`);
10481
+ }
10482
+ const server = new Horizon.Server(horizonRpcUrl, { allowHttp: true });
10483
+ const { balances } = await server.accounts().accountId(walletAddress).call();
10484
+ const tokenBalance = balances.find(
10485
+ (balance2) => "limit" in balance2 && "balance" in balance2 && "asset_code" in balance2 && trustlineConfig.assetCode.toLowerCase() === balance2.asset_code?.toLowerCase() && "asset_issuer" in balance2 && trustlineConfig.assetIssuer.toLowerCase() === balance2.asset_issuer?.toLowerCase()
10486
+ );
10487
+ if (!tokenBalance) {
10488
+ console.error(`No token balances found for token: ${token}`);
10489
+ return false;
10490
+ }
10491
+ const limit = parseToStroops(tokenBalance.limit);
10492
+ const balance = parseToStroops(tokenBalance.balance);
10493
+ const availableTrustAmount = limit - balance;
10494
+ return availableTrustAmount >= amount;
10495
+ }
10435
10496
  /**
10436
10497
  * Request a trustline for a given token and amount.
10437
10498
  * @param token - The token address to request the trustline for.
@@ -11850,7 +11911,7 @@ var SolanaSpokeService = class _SolanaSpokeService {
11850
11911
  }
11851
11912
  return spokeProvider.walletProvider.sendTransaction(serializedTransaction);
11852
11913
  }
11853
- static async waitForConfirmation(spokeProvider, signature, commitment = "finalized", timeoutMs = 12e4) {
11914
+ static async waitForConfirmation(spokeProvider, signature, commitment = "finalized", timeoutMs = 6e4) {
11854
11915
  try {
11855
11916
  const connection = new Connection(spokeProvider.chainConfig.rpcUrl, commitment);
11856
11917
  const deadline = Date.now() + timeoutMs;
@@ -13891,7 +13952,27 @@ var MoneyMarketService = class _MoneyMarketService {
13891
13952
  );
13892
13953
  }
13893
13954
  const walletAddress = await spokeProvider.walletProvider.getWalletAddress();
13894
- if (isStellarSpokeProviderType(spokeProvider) && (params.action === "supply" || params.action === "repay")) {
13955
+ if (params.toChainId === STELLAR_MAINNET_CHAIN_ID && params.toAddress) {
13956
+ const targetHasTrustline = await StellarSpokeService.walletHasSufficientTrustline(
13957
+ params.token,
13958
+ params.amount,
13959
+ params.toAddress,
13960
+ this.configService.sharedConfig[STELLAR_MAINNET_CHAIN_ID].horizonRpcUrl
13961
+ );
13962
+ let srcHasTrustline = true;
13963
+ if (isStellarSpokeProviderType(spokeProvider)) {
13964
+ srcHasTrustline = await StellarSpokeService.hasSufficientTrustline(
13965
+ params.token,
13966
+ params.amount,
13967
+ spokeProvider
13968
+ );
13969
+ }
13970
+ return {
13971
+ ok: true,
13972
+ value: targetHasTrustline && srcHasTrustline
13973
+ };
13974
+ }
13975
+ if (isStellarSpokeProviderType(spokeProvider)) {
13895
13976
  return {
13896
13977
  ok: true,
13897
13978
  value: await StellarSpokeService.hasSufficientTrustline(params.token, params.amount, spokeProvider)
@@ -13925,6 +14006,9 @@ var MoneyMarketService = class _MoneyMarketService {
13925
14006
  * Approve amount spending if isAllowanceValid returns false.
13926
14007
  * For evm spoke chains, the spender is the asset manager contract while
13927
14008
  * for sonic spoke (hub) chain, the spender is the user router contract.
14009
+ * NOTE: Stellar requires trustline when being either sender or receiver. Thus
14010
+ * you should make sure that both src and destination wallets have sufficient trustlines.
14011
+ * Make sure to invoke this method using wallet address which is about to receive the tokens!
13928
14012
  * @param token - ERC20 token address
13929
14013
  * @param amount - Amount to approve
13930
14014
  * @param spender - Spender address
@@ -13966,10 +14050,6 @@ var MoneyMarketService = class _MoneyMarketService {
13966
14050
  }
13967
14051
  const walletAddress = await spokeProvider.walletProvider.getWalletAddress();
13968
14052
  if (isStellarSpokeProviderType(spokeProvider)) {
13969
- invariant6(
13970
- params.action === "supply" || params.action === "repay",
13971
- "Invalid action (only supply and repay are supported on stellar)"
13972
- );
13973
14053
  const result = await StellarSpokeService.requestTrustline(params.token, params.amount, spokeProvider, raw);
13974
14054
  return {
13975
14055
  ok: true,
@@ -14160,7 +14240,7 @@ var MoneyMarketService = class _MoneyMarketService {
14160
14240
  ok: true,
14161
14241
  value: txResult,
14162
14242
  data: {
14163
- address: toHubWallet,
14243
+ address: fromHubWallet,
14164
14244
  payload: data
14165
14245
  }
14166
14246
  };
@@ -14227,7 +14307,7 @@ var MoneyMarketService = class _MoneyMarketService {
14227
14307
  if (spokeProvider.chainConfig.chain.id !== this.hubProvider.chainConfig.chain.id || params.toChainId && params.toAddress && params.toChainId !== this.hubProvider.chainConfig.chain.id) {
14228
14308
  const packetResult = await relayTxAndWaitPacket(
14229
14309
  txResult.value,
14230
- isSolanaSpokeProviderType(spokeProvider) ? txResult.data : void 0,
14310
+ spokeProvider instanceof SolanaSpokeProvider ? txResult.data : void 0,
14231
14311
  spokeProvider,
14232
14312
  this.config.relayerApiEndpoint,
14233
14313
  timeout
@@ -14512,7 +14592,7 @@ var MoneyMarketService = class _MoneyMarketService {
14512
14592
  if (spokeProvider.chainConfig.chain.id !== this.hubProvider.chainConfig.chain.id) {
14513
14593
  const packetResult = await relayTxAndWaitPacket(
14514
14594
  txResult.value,
14515
- spokeProvider instanceof SolanaSpokeProvider ? txResult.data : void 0,
14595
+ isSolanaSpokeProviderType(spokeProvider) ? txResult.data : void 0,
14516
14596
  spokeProvider,
14517
14597
  this.config.relayerApiEndpoint,
14518
14598
  timeout
@@ -14612,7 +14692,7 @@ var MoneyMarketService = class _MoneyMarketService {
14612
14692
  ok: true,
14613
14693
  value: txResult,
14614
14694
  data: {
14615
- address: toHubWallet,
14695
+ address: fromHubWallet,
14616
14696
  payload: data
14617
14697
  }
14618
14698
  };
@@ -15014,7 +15094,8 @@ var Sodax = class {
15014
15094
  config: {
15015
15095
  backendApiUrl: config?.backendApiConfig?.baseURL,
15016
15096
  timeout: config?.backendApiConfig?.timeout
15017
- }
15097
+ },
15098
+ sharedConfig: config?.sharedConfig
15018
15099
  });
15019
15100
  this.hubProvider = new EvmHubProvider({ config: config?.hubProviderConfig, configService: this.config });
15020
15101
  this.swaps = config && config.swaps ? new SwapService({
@@ -16501,7 +16582,7 @@ var BridgeService = class {
16501
16582
  *
16502
16583
  * @param spokeProvider - The spoke provider instance
16503
16584
  * @param token - The token address to query the balance for
16504
- * @returns {Promise<bigint>} - The token balance as a bigint value
16585
+ * @returns {Promise<BridgeLimit>} - The max bridgeable amount with corresponding decimals
16505
16586
  */
16506
16587
  async getBridgeableAmount(from, to) {
16507
16588
  try {
@@ -16509,51 +16590,59 @@ var BridgeService = class {
16509
16590
  const toHubAsset = this.configService.getHubAssetInfo(to.xChainId, to.address);
16510
16591
  invariant6(fromHubAsset, `Hub asset not found for token ${from.address} on chain ${from.xChainId}`);
16511
16592
  invariant6(toHubAsset, `Hub asset not found for token ${to.address} on chain ${to.xChainId}`);
16512
- const [depositTokenInfo, reserves] = await Promise.all([
16513
- EvmVaultTokenService.getTokenInfo(fromHubAsset.vault, fromHubAsset.asset, this.hubProvider.publicClient),
16593
+ invariant6(this.isBridgeable({ from, to }), `Tokens ${from.address} and ${to.address} are not bridgeable`);
16594
+ const [tokenInfos, reserves] = await Promise.all([
16595
+ EvmVaultTokenService.getTokenInfos(
16596
+ fromHubAsset.vault,
16597
+ [fromHubAsset.asset, toHubAsset.asset],
16598
+ this.hubProvider.publicClient
16599
+ ),
16514
16600
  EvmVaultTokenService.getVaultReserves(toHubAsset.vault, this.hubProvider.publicClient)
16515
16601
  ]);
16516
- if (!this.configService.isValidVault(fromHubAsset.asset) && this.configService.isValidVault(toHubAsset.asset)) {
16517
- const fromTokenIndex2 = reserves.tokens.findIndex((t) => t.toLowerCase() === fromHubAsset.asset.toLowerCase());
16518
- invariant6(
16519
- fromTokenIndex2 !== -1,
16520
- `Token ${fromHubAsset.asset} not found in the vault reserves for chain ${from.xChainId}`
16521
- );
16522
- const fromTokenDepositedAmount2 = reserves.balances[fromTokenIndex2] ?? 0n;
16523
- const availableDeposit2 = depositTokenInfo.maxDeposit - fromTokenDepositedAmount2;
16602
+ invariant6(tokenInfos.length === 2, `Expected 2 token infos, got ${tokenInfos.length}`);
16603
+ const [fromTokenInfo, toTokenInfo] = tokenInfos;
16604
+ invariant6(fromTokenInfo, "From token info not found");
16605
+ invariant6(toTokenInfo, "To token info not found");
16606
+ if (!fromTokenInfo.isSupported) {
16524
16607
  return {
16525
16608
  ok: true,
16526
- value: availableDeposit2
16609
+ value: {
16610
+ amount: 0n,
16611
+ decimals: fromTokenInfo.decimals,
16612
+ type: "DEPOSIT_LIMIT"
16613
+ }
16527
16614
  };
16528
16615
  }
16529
- if (this.configService.isValidVault(fromHubAsset.asset)) {
16530
- const tokenIndex2 = reserves.tokens.findIndex((t) => t.toLowerCase() === toHubAsset.asset.toLowerCase());
16531
- invariant6(
16532
- tokenIndex2 !== -1,
16533
- `Token ${toHubAsset.asset} not found in the vault reserves for chain ${to.xChainId}`
16534
- );
16535
- const assetManagerBalance2 = reserves.balances[tokenIndex2] ?? 0n;
16616
+ if (from.xChainId !== this.hubProvider.chainConfig.chain.id && to.xChainId === this.hubProvider.chainConfig.chain.id) {
16617
+ const fromTokenDepositedAmount2 = this.findTokenBalanceInReserves(reserves, from);
16618
+ const availableDeposit2 = fromTokenInfo.maxDeposit - fromTokenDepositedAmount2;
16536
16619
  return {
16537
16620
  ok: true,
16538
- value: assetManagerBalance2
16621
+ value: {
16622
+ amount: availableDeposit2,
16623
+ decimals: fromTokenInfo.decimals,
16624
+ type: "DEPOSIT_LIMIT"
16625
+ }
16539
16626
  };
16540
16627
  }
16541
- const fromTokenIndex = reserves.tokens.findIndex((t) => t.toLowerCase() === fromHubAsset.asset.toLowerCase());
16542
- invariant6(
16543
- fromTokenIndex !== -1,
16544
- `Token ${fromHubAsset.asset} not found in the vault reserves for chain ${from.xChainId}`
16545
- );
16546
- const fromTokenDepositedAmount = reserves.balances[fromTokenIndex] ?? 0n;
16547
- const availableDeposit = depositTokenInfo.maxDeposit - fromTokenDepositedAmount;
16548
- const tokenIndex = reserves.tokens.findIndex((t) => t.toLowerCase() === toHubAsset.asset.toLowerCase());
16549
- invariant6(
16550
- tokenIndex !== -1,
16551
- `Token ${toHubAsset.asset} not found in the vault reserves for chain ${to.xChainId}`
16552
- );
16553
- const assetManagerBalance = reserves.balances[tokenIndex] ?? 0n;
16628
+ if (from.xChainId === this.hubProvider.chainConfig.chain.id && to.xChainId !== this.hubProvider.chainConfig.chain.id) {
16629
+ return {
16630
+ ok: true,
16631
+ value: {
16632
+ amount: this.findTokenBalanceInReserves(reserves, to),
16633
+ decimals: toTokenInfo.decimals,
16634
+ type: "WITHDRAWAL_LIMIT"
16635
+ }
16636
+ };
16637
+ }
16638
+ const fromTokenDepositedAmount = this.findTokenBalanceInReserves(reserves, from);
16639
+ const availableDeposit = fromTokenInfo.maxDeposit - fromTokenDepositedAmount;
16640
+ const assetManagerBalance = this.findTokenBalanceInReserves(reserves, to);
16641
+ const availableDepositNormalised = BigNumber4(availableDeposit).shiftedBy(-fromTokenInfo.decimals);
16642
+ const assetManagerBalanceNormalised = BigNumber4(assetManagerBalance).shiftedBy(-toTokenInfo.decimals);
16554
16643
  return {
16555
16644
  ok: true,
16556
- value: availableDeposit < assetManagerBalance ? availableDeposit : assetManagerBalance
16645
+ value: availableDepositNormalised.isLessThan(assetManagerBalanceNormalised) ? { amount: availableDeposit, decimals: fromTokenInfo.decimals, type: "DEPOSIT_LIMIT" } : { amount: assetManagerBalance, decimals: toTokenInfo.decimals, type: "WITHDRAWAL_LIMIT" }
16557
16646
  };
16558
16647
  } catch (error) {
16559
16648
  console.error(error);
@@ -16630,6 +16719,13 @@ var BridgeService = class {
16630
16719
  }
16631
16720
  return bridgeableTokens;
16632
16721
  }
16722
+ findTokenBalanceInReserves(reserves, token) {
16723
+ const hubAsset = this.configService.getHubAssetInfo(token.xChainId, token.address);
16724
+ invariant6(hubAsset, `Hub asset not found for token ${token.address} on chain ${token.xChainId}`);
16725
+ const tokenIndex = reserves.tokens.findIndex((t) => t.toLowerCase() === hubAsset.asset.toLowerCase());
16726
+ invariant6(tokenIndex !== -1, `Token ${hubAsset.asset} not found in the vault reserves for chain ${token.xChainId}`);
16727
+ return reserves.balances[tokenIndex] ?? 0n;
16728
+ }
16633
16729
  };
16634
16730
  var StakingLogic = class _StakingLogic {
16635
16731
  constructor() {