@bolt-liquidity-hq/sui-client 0.1.0-beta.11 → 0.1.0-beta.13

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.js CHANGED
@@ -5,6 +5,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5
5
  // src/lib/client.ts
6
6
  import { BaseClient, MissingParameterError as MissingParameterError2 } from "@bolt-liquidity-hq/core";
7
7
  import { SuiClient } from "@mysten/sui/client";
8
+ import { normalizeStructTag as normalizeStructTag5 } from "@mysten/sui/utils";
9
+ import axios from "axios";
8
10
 
9
11
  // src/config/mainnet.ts
10
12
  import { SUI_DECIMALS, SUI_TYPE_ARG } from "@mysten/sui/utils";
@@ -40,21 +42,24 @@ var MainnetAssets = {
40
42
  coingeckoId: "usd-coin"
41
43
  }
42
44
  };
45
+ var MainnetPools = [];
43
46
 
44
47
  // src/config/testnet.ts
45
48
  import { SUI_DECIMALS as SUI_DECIMALS2, SUI_TYPE_ARG as SUI_TYPE_ARG2 } from "@mysten/sui/utils";
49
+ var TestnetConfigUrl = "https://phi-labs-ltd.github.io/sui-outpost/testnet.json";
46
50
  var TestnetChainConfig = {
47
51
  name: "Sui Testnet",
48
52
  id: "103",
49
53
  rpcEndpoint: "https://fullnode.testnet.sui.io:443"
50
54
  };
51
55
  var TestnetContracts = {
52
- oracle: "0xecece01cfb23b5439e04b18fe656eaf2746b9087cf68f1d48797c8f71a3dd93b",
53
- router: "0x3881fdcb4a7fbcda8edc230e6f92eb57b24c0be6b44af0b5e1d0b45564f3ed00"
56
+ oracle: " ",
57
+ router: " "
54
58
  };
55
- var TestnetPackageId = "0x22384b1841229e2be878bb7e88833c03e23ff5dc39accd050fb932120602f85e";
56
- var TestnetPoolGlobalConfigId = "0xa9491e59fa63e666cbfdea2e880b2d8ba0085eeb244220cefa3fb817559cd79c";
59
+ var TestnetPackageId = "";
60
+ var TestnetPoolGlobalConfigId = "";
57
61
  var TestnetNativeTokenDenom = SUI_TYPE_ARG2;
62
+ var TestnetHelperAssets = ["::test_btc::TEST_BTC", "::test_usdt::TEST_USDT"];
58
63
  var TestnetAssets = {
59
64
  [SUI_TYPE_ARG2]: {
60
65
  symbol: "SUI",
@@ -73,20 +78,32 @@ var TestnetAssets = {
73
78
  decimals: 6,
74
79
  logo: "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png",
75
80
  coingeckoId: "usd-coin"
81
+ },
82
+ "::test_btc::TEST_BTC": {
83
+ symbol: "TEST_BTC",
84
+ name: "Test BTC",
85
+ chainId: "103",
86
+ denom: "::test_btc::TEST_BTC",
87
+ decimals: 8,
88
+ logo: "https://github.com/cosmos/chain-registry/blob/master/_non-cosmos/bitcoin/images/btc.png",
89
+ coingeckoId: "bitcoin"
90
+ },
91
+ "::test_usdt::TEST_USDT": {
92
+ symbol: "TEST_USDT",
93
+ name: "Test USDT",
94
+ chainId: "103",
95
+ denom: "::test_usdt::TEST_USDT",
96
+ decimals: 6,
97
+ logo: "https://github.com/cosmos/chain-registry/blob/master/_non-cosmos/ethereum/images/usdt.png",
98
+ coingeckoId: "tether"
76
99
  }
77
100
  };
78
101
 
79
- // src/lib/oracle/get-asset-pairs.ts
80
- import { bcs as bcs6 } from "@mysten/bcs";
81
-
82
- // src/lib/constants/defaults.ts
83
- var DEFAULT_PAGINATION_LIMIT = 50;
84
-
85
102
  // src/lib/constants/sui-objects.ts
86
103
  var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000000000000000000000000000";
87
104
  var PRICE_ORACLE_MODULE = "price_oracle";
88
105
  var ROUTER_MODULE = "router";
89
- var POOL_MODULE = "settlement";
106
+ var POOL_MODULE = "pool";
90
107
 
91
108
  // src/lib/helpers/bcs-parse.ts
92
109
  import { InvalidObjectError, ParseError } from "@bolt-liquidity-hq/core";
@@ -120,9 +137,6 @@ var parseDevInspectResult = (result, bcsType, resultIndex = 0, returnValueIndex
120
137
  });
121
138
  }
122
139
  };
123
- var parseMultipleResults = (info, schema) => {
124
- return schema.map((bcsType, index) => parseDevInspectResult(info, bcsType, 0, index));
125
- };
126
140
 
127
141
  // src/lib/helpers/coin-manager.ts
128
142
  import { InsufficientFundsError, MissingParameterError } from "@bolt-liquidity-hq/core";
@@ -556,15 +570,45 @@ var queryDevInspect = async (suiClient, target, args, typeArguments, senderAddre
556
570
  }
557
571
  };
558
572
 
559
- // src/lib/helpers/txs.ts
573
+ // src/lib/helpers/transactions.ts
560
574
  import {
561
575
  DEFAULT_GAS_ADJUSTMENT,
576
+ NotFoundError,
562
577
  TransactionFailedError as TransactionFailedError2,
563
578
  UnexpectedError as UnexpectedError2
564
579
  } from "@bolt-liquidity-hq/core";
580
+ import { bcs as bcs2 } from "@mysten/bcs";
565
581
  import { Transaction as Transaction2 } from "@mysten/sui/transactions";
566
- import { SUI_TYPE_ARG as SUI_TYPE_ARG4 } from "@mysten/sui/utils";
582
+ import { normalizeStructTag, SUI_CLOCK_OBJECT_ID, SUI_TYPE_ARG as SUI_TYPE_ARG4 } from "@mysten/sui/utils";
567
583
  import { BigNumber } from "bignumber.js";
584
+ var buildSwapTxArgs = async (client, swapParams, signer) => {
585
+ const { assetIn, amountIn, assetOut, minimumAmountOut, receiver } = swapParams;
586
+ const pool = client.routerClient.getPool(assetIn, assetOut);
587
+ if (!pool) {
588
+ throw new NotFoundError(`Pool for the pair ${assetIn}/${assetOut}`);
589
+ }
590
+ const isSell = normalizeStructTag(assetIn) === pool.baseDenom;
591
+ const FUNCTION_NAME = isSell ? "swap_sell" : "swap_buy";
592
+ const finalSigner = client.getSigner(signer);
593
+ const tx = new Transaction2();
594
+ const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());
595
+ const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);
596
+ return {
597
+ signer: finalSigner,
598
+ target: [client.packageId, ROUTER_MODULE, FUNCTION_NAME],
599
+ args: [
600
+ pool.poolAddress,
601
+ client.contracts.oracle,
602
+ SUI_CLOCK_OBJECT_ID,
603
+ coinInput,
604
+ bcs2.u64().serialize(amountIn),
605
+ bcs2.option(bcs2.string()).serialize(minimumAmountOut),
606
+ bcs2.option(bcs2.string()).serialize(receiver)
607
+ ],
608
+ typeArguments: [isSell ? assetIn : assetOut, isSell ? assetOut : assetIn],
609
+ tx
610
+ };
611
+ };
568
612
  var signAndExecuteTx = async (suiClient, signer, target, args, typeArguments, transaction, options) => {
569
613
  const tx = transaction ?? new Transaction2();
570
614
  const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;
@@ -595,7 +639,7 @@ var signAndExecuteTx = async (suiClient, signer, target, args, typeArguments, tr
595
639
  });
596
640
  }
597
641
  };
598
- var estimateTxGasPrice = async (suiClient, target, args, typeArguments, transaction, gasAdjustment = DEFAULT_GAS_ADJUSTMENT) => {
642
+ var estimateTxGasPrice = async (suiClient, senderAddress, target, args, typeArguments, transaction, gasAdjustment = DEFAULT_GAS_ADJUSTMENT) => {
599
643
  const tx = transaction ?? new Transaction2();
600
644
  const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;
601
645
  const txArgs = args?.map(
@@ -606,6 +650,7 @@ var estimateTxGasPrice = async (suiClient, target, args, typeArguments, transact
606
650
  arguments: txArgs,
607
651
  typeArguments
608
652
  });
653
+ tx.setSender(senderAddress);
609
654
  try {
610
655
  const transactionBytes = await tx.build({ client: suiClient });
611
656
  const dryRunResult = await suiClient.dryRunTransactionBlock({
@@ -640,7 +685,8 @@ import { InvalidObjectError as InvalidObjectError2 } from "@bolt-liquidity-hq/co
640
685
  import { BigNumber as BigNumber2 } from "bignumber.js";
641
686
  var parseOracleConfigStructOutput = (output) => {
642
687
  return {
643
- admin: output.admin,
688
+ // TODO: try to query admin somewhere else? to fill empty value
689
+ admin: "",
644
690
  priceThresholdRatio: output.price_threshold_ratio,
645
691
  priceExpireTime: {
646
692
  secs: Number(output.default_price_expiry_seconds),
@@ -651,45 +697,44 @@ var parseOracleConfigStructOutput = (output) => {
651
697
  var parseAssetPairStructOutput = (output) => {
652
698
  return {
653
699
  base: {
654
- name: output.base_symbol,
655
- symbol: output.base_symbol,
700
+ name: output.base_name,
701
+ // TODO: map a different value for name/symbols
702
+ symbol: output.base_name,
656
703
  precision: output.base_precision
657
704
  },
658
705
  quote: {
659
- name: output.quote_symbol,
660
- symbol: output.quote_symbol,
706
+ name: output.quote_name,
707
+ // TODO: map a different value for name/symbols
708
+ symbol: output.quote_name,
661
709
  precision: output.quote_precision
662
710
  }
663
711
  };
664
712
  };
665
- var parsePriceDataStructOutput = (output) => {
713
+ var parseAssetPairsResponseStructOutput = (output) => {
714
+ return output.map((item) => parseAssetPairStructOutput(item.info));
715
+ };
716
+ var parsePriceDataStructOutput = (output, baseDenom, quoteDenom) => {
666
717
  return {
667
- baseDenom: output.base_symbol,
668
- quoteDenom: output.quote_symbol,
669
- price: output.price,
670
- expiryTime: BigNumber2(output.expiry_time_ms).times(1e6).toFixed(),
718
+ baseDenom,
719
+ quoteDenom,
720
+ price: output.price.price,
721
+ expiryTime: BigNumber2(output.price.expiry).times(1e6).toFixed(),
671
722
  isInverse: false
672
723
  };
673
724
  };
674
- var parsePriceResponseStructOutput = (output) => {
725
+ var parsePriceResponseStructOutput = (output, baseDenom, quoteDenom) => {
675
726
  if (!output.pair_data) {
676
727
  throw new InvalidObjectError2("Can't find pair data price");
677
728
  }
678
- return parsePriceDataStructOutput(output.pair_data);
679
- };
680
- var parseAssetPairsResponsePaginatedStructOutput = (output) => {
681
- return output.asset_pairs.map((item) => parseAssetPairStructOutput(item));
682
- };
683
- var parsePricesResponsePaginatedStructOutput = (output) => {
684
- return output.prices.map((item) => parsePriceDataStructOutput(item));
729
+ return parsePriceDataStructOutput(output.pair_data, baseDenom, quoteDenom);
685
730
  };
686
731
 
687
732
  // src/types/bcs.ts
688
- import { bcs as bcs2, BcsType } from "@mysten/bcs";
733
+ import { bcs as bcs3, BcsType } from "@mysten/bcs";
689
734
  var PaginationStruct = {
690
- total_count: bcs2.u64(),
691
- has_next_page: bcs2.bool(),
692
- next_cursor: bcs2.option(bcs2.string())
735
+ total_count: bcs3.u64(),
736
+ has_next_page: bcs3.bool(),
737
+ next_cursor: bcs3.option(bcs3.string())
693
738
  };
694
739
  var BcsAddressType = new BcsType({
695
740
  name: "address",
@@ -711,112 +756,114 @@ var BcsAddressType = new BcsType({
711
756
  });
712
757
 
713
758
  // src/types/oracle.ts
714
- import { bcs as bcs3 } from "@mysten/bcs";
715
- var OracleConfigStruct = bcs3.struct("Config", {
716
- admin: BcsAddressType,
717
- price_threshold_ratio: bcs3.u64(),
718
- default_price_expiry_seconds: bcs3.u64()
759
+ import { bcs as bcs4 } from "@mysten/bcs";
760
+ var OracleConfigStruct = bcs4.struct("Config", {
761
+ price_threshold_ratio: bcs4.u64(),
762
+ default_price_expiry_seconds: bcs4.u64()
719
763
  });
720
- var AssetPairStruct = bcs3.struct("AssetPair", {
721
- base_symbol: bcs3.string(),
722
- quote_symbol: bcs3.string(),
723
- base_precision: bcs3.u8(),
724
- quote_precision: bcs3.u8()
764
+ var AssetPairStruct = bcs4.struct("AssetPair", {
765
+ base_name: bcs4.string(),
766
+ quote_name: bcs4.string(),
767
+ base_precision: bcs4.u8(),
768
+ quote_precision: bcs4.u8()
725
769
  });
726
- var AssetPairsResponseStruct = bcs3.struct("AssetPairsResponse", {
727
- asset_pairs: bcs3.vector(AssetPairStruct)
770
+ var TypeNameStruct = bcs4.struct("TypeName", {
771
+ name: bcs4.string()
728
772
  });
729
- var AssetPairsResponsePaginatedStruct = bcs3.struct("AssetPairsResponsePaginated", {
730
- asset_pairs: bcs3.vector(AssetPairStruct),
731
- ...PaginationStruct
773
+ var RawPairStruct = bcs4.struct("RawPair", {
774
+ base: TypeNameStruct,
775
+ quote: TypeNameStruct
776
+ });
777
+ var AssetPairResponseStruct = bcs4.struct("AssetPairResponse", {
778
+ pair: RawPairStruct,
779
+ info: AssetPairStruct
780
+ });
781
+ var AssetPairsResponseStruct = bcs4.vector(AssetPairResponseStruct);
782
+ var RawPriceStruct = bcs4.struct("RawPrice", {
783
+ price: bcs4.u128(),
784
+ expiry: bcs4.u64()
732
785
  });
733
- var PriceDataStruct = bcs3.struct("PriceData", {
734
- base_symbol: bcs3.string(),
735
- quote_symbol: bcs3.string(),
736
- price: bcs3.u128(),
737
- expiry_time_ms: bcs3.u64(),
738
- last_updated_ms: bcs3.u64(),
786
+ var PriceDataStruct = bcs4.struct("PriceData", {
787
+ price: RawPriceStruct,
788
+ last_updated_ms: bcs4.u64(),
739
789
  updater: BcsAddressType
740
790
  });
741
- var PriceResponseStruct = bcs3.struct("PriceResponse", {
742
- pair_data: bcs3.option(PriceDataStruct)
791
+ var PriceResponseStruct = bcs4.struct("PriceResponse", {
792
+ pair_data: bcs4.option(PriceDataStruct)
743
793
  });
744
- var PricesResponsePaginatedStruct = bcs3.struct("PricesResponsePaginated", {
745
- prices: bcs3.vector(PriceDataStruct),
794
+ var PricesResponsePaginatedStruct = bcs4.struct("PricesResponsePaginated", {
795
+ prices: bcs4.vector(PriceDataStruct),
746
796
  ...PaginationStruct
747
797
  });
748
798
 
749
799
  // src/types/router.ts
750
- import { bcs as bcs4 } from "@mysten/bcs";
751
- var RouterConfigStruct = bcs4.struct("Config", {
800
+ import { bcs as bcs5 } from "@mysten/bcs";
801
+ var RouterConfigStruct = bcs5.struct("Config", {
752
802
  admin: BcsAddressType,
753
803
  default_price_oracle_contract: BcsAddressType,
754
804
  default_protocol_fee_recipient: BcsAddressType,
755
- default_protocol_fee: bcs4.u64(),
756
- default_lp_fee: bcs4.u64()
805
+ default_protocol_fee: bcs5.u64(),
806
+ default_lp_fee: bcs5.u64()
757
807
  });
758
- var MarketStruct = bcs4.struct("Market", {
759
- base_asset_symbol: bcs4.string(),
760
- quote_assets_symbols: bcs4.vector(bcs4.string()),
761
- market_address: bcs4.string(),
762
- is_permissioned: bcs4.bool(),
763
- created_at_ms: bcs4.u64()
808
+ var MarketStruct = bcs5.struct("Market", {
809
+ base_asset_symbol: bcs5.string(),
810
+ quote_assets_symbols: bcs5.vector(bcs5.string()),
811
+ market_address: bcs5.string(),
812
+ is_permissioned: bcs5.bool(),
813
+ created_at_ms: bcs5.u64()
764
814
  });
765
- var MarketResponseStruct = bcs4.struct("MarketResponse", {
766
- market: bcs4.option(MarketStruct)
815
+ var MarketResponseStruct = bcs5.struct("MarketResponse", {
816
+ market: bcs5.option(MarketStruct)
767
817
  });
768
- var MarketsResponseStruct = bcs4.struct("MarketsResponse", {
769
- markets: bcs4.vector(MarketStruct)
818
+ var MarketsResponseStruct = bcs5.struct("MarketsResponse", {
819
+ markets: bcs5.vector(MarketStruct)
770
820
  });
771
- var MarketsResponsePaginatedStruct = bcs4.struct("MarketsResponsePaginated", {
772
- markets: bcs4.vector(MarketStruct),
821
+ var MarketsResponsePaginatedStruct = bcs5.struct("MarketsResponsePaginated", {
822
+ markets: bcs5.vector(MarketStruct),
773
823
  ...PaginationStruct
774
824
  });
775
- var BaseLiquidityInfoStruct = bcs4.struct("BaseLiquidityInfo", {
776
- denom: bcs4.string(),
777
- amount: bcs4.u64()
825
+ var BaseLiquidityInfoStruct = bcs5.struct("BaseLiquidityInfo", {
826
+ denom: bcs5.string(),
827
+ amount: bcs5.u64()
778
828
  });
779
- var BaseLiquidityResponseStruct = bcs4.struct("BaseLiquidityResponse", {
780
- base_assets: bcs4.vector(BaseLiquidityInfoStruct),
829
+ var BaseLiquidityResponseStruct = bcs5.struct("BaseLiquidityResponse", {
830
+ base_assets: bcs5.vector(BaseLiquidityInfoStruct),
781
831
  ...PaginationStruct
782
832
  });
783
833
 
784
834
  // src/types/pool.ts
785
- import { bcs as bcs5 } from "@mysten/bcs";
786
- var GetPoolInfoResponseStruct = [
787
- bcs5.u64(),
788
- bcs5.u128(),
789
- BcsAddressType,
790
- bcs5.bool()
791
- ];
792
- var GetFeesResponseStruct = [bcs5.u64(), bcs5.u64(), bcs5.u64()];
835
+ import { bcs as bcs6 } from "@mysten/bcs";
836
+ var PoolInfoStruct = bcs6.struct("PoolInfo", {
837
+ base_liquidity: bcs6.u64(),
838
+ total_lp_shares: bcs6.u64(),
839
+ admin: BcsAddressType,
840
+ is_paused: bcs6.bool()
841
+ });
842
+ var PoolFeesInfoStruct = bcs6.struct("PoolFeesInfo", {
843
+ swap_fee_pct: bcs6.u64(),
844
+ lp_withdrawal_fee_pct: bcs6.u64(),
845
+ lp_fee_pct: bcs6.u64()
846
+ });
847
+ var ProtocolFeesInfoStruct = bcs6.struct("ProtocolFeesInfo", {
848
+ bolt_fee_addr: BcsAddressType,
849
+ swap_fee_pct: bcs6.u64(),
850
+ lp_withdrawal_fee_pct: bcs6.u64()
851
+ });
793
852
 
794
853
  // src/lib/oracle/get-asset-pairs.ts
795
854
  var getAssetPairs = async (client) => {
796
- const ASSET_PAIRS_PAGINATED_FUNCTION = "asset_pairs_paginated";
797
- const result = [];
798
- let currentCursor = null;
799
- let hasNextPage = true;
800
- while (hasNextPage) {
801
- const response = await queryDevInspect(
802
- client.suiClient,
803
- [client.packageId, PRICE_ORACLE_MODULE, ASSET_PAIRS_PAGINATED_FUNCTION],
804
- [
805
- client.contracts.oracle,
806
- bcs6.option(bcs6.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
807
- bcs6.option(bcs6.string()).serialize(currentCursor)
808
- ]
809
- );
810
- const output = parseDevInspectResult(response, AssetPairsResponsePaginatedStruct);
811
- const assetPairs = parseAssetPairsResponsePaginatedStructOutput(output);
812
- result.push(...assetPairs);
813
- currentCursor = output.next_cursor;
814
- hasNextPage = output.has_next_page;
815
- }
816
- return result;
855
+ const ASSET_PAIRS_FUNCTION = "asset_pairs";
856
+ const response = await queryDevInspect(
857
+ client.suiClient,
858
+ [client.packageId, PRICE_ORACLE_MODULE, ASSET_PAIRS_FUNCTION],
859
+ [client.contracts.oracle]
860
+ );
861
+ const output = parseDevInspectResult(response, AssetPairsResponseStruct);
862
+ return parseAssetPairsResponseStructOutput(output);
817
863
  };
818
864
 
819
865
  // src/lib/oracle/get-assets.ts
866
+ import { normalizeStructTag as normalizeStructTag2 } from "@mysten/sui/utils";
820
867
  var getAssets = async (client) => {
821
868
  const assetPairs = await client.getAllOracleAssetPairs();
822
869
  const uniqueOracleAssets = {};
@@ -830,7 +877,7 @@ var getAssets = async (client) => {
830
877
  symbol: item.name,
831
878
  name: item.name,
832
879
  chainId: client.chainConfig.id,
833
- denom: item.symbol,
880
+ denom: normalizeStructTag2(item.symbol),
834
881
  decimals: item.precision,
835
882
  logo: void 0,
836
883
  coingeckoId: void 0
@@ -851,248 +898,164 @@ var getOracleConfig = async (client) => {
851
898
  };
852
899
 
853
900
  // src/lib/oracle/get-price.ts
854
- import { bcs as bcs7 } from "@mysten/bcs";
855
- import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
856
901
  var getPrice = async (client, baseDenom, quoteDenom) => {
857
902
  const GET_PRICE_FUNCTION = "get_price";
858
903
  const response = await queryDevInspect(
859
904
  client.suiClient,
860
905
  [client.packageId, PRICE_ORACLE_MODULE, GET_PRICE_FUNCTION],
861
- [
862
- client.contracts.oracle,
863
- bcs7.string().serialize(baseDenom),
864
- bcs7.string().serialize(quoteDenom),
865
- SUI_CLOCK_OBJECT_ID
866
- ]
906
+ [client.contracts.oracle],
907
+ [baseDenom, quoteDenom]
867
908
  );
868
909
  const output = parseDevInspectResult(response, PriceResponseStruct);
869
910
  return parsePriceResponseStructOutput(output, baseDenom, quoteDenom);
870
911
  };
871
912
 
872
913
  // src/lib/oracle/get-prices.ts
873
- import { bcs as bcs8 } from "@mysten/bcs";
914
+ import { NotFoundError as NotFoundError2 } from "@bolt-liquidity-hq/core";
915
+ import { normalizeStructTag as normalizeStructTag3 } from "@mysten/sui/utils";
874
916
  var getPrices = async (client) => {
875
- const GET_PRICES_PAGINATED_FUNCTION = "get_prices_paginated";
876
- const result = [];
877
- let currentCursor = null;
878
- let hasNextPage = true;
879
- while (hasNextPage) {
880
- const response = await queryDevInspect(
881
- client.suiClient,
882
- [client.packageId, PRICE_ORACLE_MODULE, GET_PRICES_PAGINATED_FUNCTION],
883
- [
884
- client.contracts.oracle,
885
- bcs8.option(bcs8.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
886
- bcs8.option(bcs8.string()).serialize(currentCursor)
887
- ]
917
+ const oracleObject = await client.suiClient.getObject({
918
+ id: client.contracts.oracle,
919
+ options: { showContent: true }
920
+ });
921
+ if (!oracleObject.data?.content || oracleObject.data.content.dataType !== "moveObject") {
922
+ throw new NotFoundError2("Oracle object");
923
+ }
924
+ const pricesTableId = oracleObject.data.content.fields?.prices?.fields?.id?.id;
925
+ if (!pricesTableId) {
926
+ throw new NotFoundError2("Prices table in the Oracle contract");
927
+ }
928
+ const prices = [];
929
+ let cursor = null;
930
+ while (true) {
931
+ const dynamicFields = await client.suiClient.getDynamicFields({
932
+ parentId: pricesTableId,
933
+ cursor,
934
+ limit: 50
935
+ // Max limit per request
936
+ });
937
+ const fieldPromises = dynamicFields.data.map(
938
+ (field) => client.suiClient.getDynamicFieldObject({
939
+ parentId: pricesTableId,
940
+ name: field.name
941
+ })
888
942
  );
889
- const output = parseDevInspectResult(response, PricesResponsePaginatedStruct);
890
- const assetPairs = parsePricesResponsePaginatedStructOutput(output);
891
- result.push(...assetPairs);
892
- currentCursor = output.next_cursor;
893
- hasNextPage = output.has_next_page;
943
+ const fieldObjects = await Promise.all(fieldPromises);
944
+ fieldObjects.forEach((obj, index) => {
945
+ if (obj.data?.content?.dataType === "moveObject") {
946
+ const fields = obj.data.content.fields?.value?.fields?.price?.fields;
947
+ const pairKey = dynamicFields.data[index]?.name?.value;
948
+ if (fields && pairKey) {
949
+ prices.push({
950
+ baseDenom: normalizeStructTag3(pairKey.base.name),
951
+ quoteDenom: normalizeStructTag3(pairKey.quote.name),
952
+ price: fields.price,
953
+ expiryTime: fields.expiry
954
+ });
955
+ }
956
+ }
957
+ });
958
+ if (!dynamicFields.hasNextPage) break;
959
+ cursor = dynamicFields.nextCursor;
894
960
  }
895
- return result;
961
+ return prices;
896
962
  };
897
963
 
898
964
  // src/lib/router/estimate-swap-exact-in-gas-fees.ts
899
965
  import { DEFAULT_GAS_ADJUSTMENT as DEFAULT_GAS_ADJUSTMENT2 } from "@bolt-liquidity-hq/core";
900
- import { bcs as bcs9 } from "@mysten/bcs";
901
- import { Transaction as Transaction3 } from "@mysten/sui/transactions";
902
- import { SUI_CLOCK_OBJECT_ID as SUI_CLOCK_OBJECT_ID2 } from "@mysten/sui/utils";
903
- var estimateSwapExactInGasFees = async (client, { assetIn, amountIn, assetOut, minimumAmountOut, receiver }, signer, gasAdjustment = DEFAULT_GAS_ADJUSTMENT2) => {
904
- const SWAP_EXACT_IN_FUNCTION = "swap_exact_in";
905
- const finalSigner = client.getSigner(signer);
906
- const tx = new Transaction3();
907
- const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());
908
- const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);
966
+ var estimateSwapExactInGasFees = async (client, swapParams, signer, gasAdjustment = DEFAULT_GAS_ADJUSTMENT2) => {
967
+ const swapArgs = await buildSwapTxArgs(client, swapParams, signer);
909
968
  return await estimateTxGasPrice(
910
969
  client.suiClient,
911
- [client.packageId, ROUTER_MODULE, SWAP_EXACT_IN_FUNCTION],
912
- [
913
- client.contracts.router,
914
- bcs9.string().serialize(assetOut),
915
- "",
916
- // TODO: pass correct pool when router can actually route to the pools depending on other arguments
917
- bcs9.string().serialize(assetIn),
918
- bcs9.option(bcs9.string()).serialize(minimumAmountOut),
919
- bcs9.option(bcs9.string()).serialize(receiver),
920
- coinInput,
921
- SUI_CLOCK_OBJECT_ID2
922
- ],
923
- [assetIn, assetOut],
924
- tx,
970
+ swapArgs.signer.toSuiAddress(),
971
+ swapArgs.target,
972
+ swapArgs.args,
973
+ swapArgs.typeArguments,
974
+ swapArgs.tx,
925
975
  gasAdjustment
926
976
  );
927
977
  };
928
978
 
929
979
  // src/lib/router/get-all-base-liquidity.ts
930
- import { bcs as bcs10 } from "@mysten/bcs";
931
-
932
- // src/lib/router/parsers.ts
933
- import { NotFoundError } from "@bolt-liquidity-hq/core";
934
- var parseMarketStructOutput = (output) => {
935
- return {
936
- poolAddress: output.market_address,
937
- baseDenom: output.base_asset_symbol,
938
- quoteDenoms: output.quote_assets_symbols
939
- };
940
- };
941
- var parseMarketResponseStructOutput = (output) => {
942
- if (!output.market) {
943
- throw new NotFoundError("Market", void 0, { output });
944
- }
945
- return parseMarketStructOutput(output.market);
946
- };
947
- var parseMarketsResponsePaginatedStructOutput = (output) => {
948
- return output.markets.map((item) => parseMarketStructOutput(item));
949
- };
950
- var parseRouterConfigStructOutput = (output) => {
951
- return {
952
- admin: output.admin,
953
- defaultPriceOracleContract: output.default_price_oracle_contract,
954
- defaultProtocolFeeRecipient: output.default_protocol_fee_recipient,
955
- defaultProtocolFee: output.default_protocol_fee,
956
- defaultLpFee: output.default_lp_fee
957
- };
980
+ import {
981
+ NotImplementedError
982
+ } from "@bolt-liquidity-hq/core";
983
+ var getAllBaseLiquidity = async (_client) => {
984
+ throw new NotImplementedError("getRouterConfig on Sui Client");
958
985
  };
959
- var parseBaseLiquidityResponseStructOutput = (output) => {
960
- return output.base_assets.map((item) => ({
961
- baseLiquidity: {
962
- denom: item.denom,
963
- amount: item.amount
964
- },
965
- totalShares: ""
966
- // TODO: add real total shares if it is returned by the smart contract later
967
- }));
986
+
987
+ // src/lib/router/get-all-quotes-for-user.ts
988
+ import { NotImplementedError as NotImplementedError2 } from "@bolt-liquidity-hq/core";
989
+ var getAllQuotesForUser = async (_client, _lpAddress) => {
990
+ throw new NotImplementedError2("getRouterConfig on Sui Client");
968
991
  };
969
992
 
970
- // src/lib/router/get-all-base-liquidity.ts
971
- var getAllBaseLiquidity = async (client) => {
972
- const BASE_LIQUIDITY_ALL_PAGINATED_FUNCTION = "base_liquidity_all_paginated";
973
- const result = {};
974
- let currentCursor = null;
975
- let hasNextPage = true;
976
- while (hasNextPage) {
977
- const response = await queryDevInspect(
978
- client.suiClient,
979
- [client.packageId, ROUTER_MODULE, BASE_LIQUIDITY_ALL_PAGINATED_FUNCTION],
980
- [
981
- client.contracts.router,
982
- bcs10.option(bcs10.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
983
- bcs10.option(bcs10.string()).serialize(currentCursor)
984
- ]
985
- );
986
- const output = parseDevInspectResult(response, BaseLiquidityResponseStruct);
987
- const baseLiquidities = parseBaseLiquidityResponseStructOutput(output);
988
- for (const item of baseLiquidities) {
989
- result[item.baseLiquidity.denom] = item;
990
- }
991
- currentCursor = output.next_cursor;
992
- hasNextPage = output.has_next_page;
993
+ // src/lib/router/get-pool-by-denom.ts
994
+ import { NotFoundError as NotFoundError3 } from "@bolt-liquidity-hq/core";
995
+ var getPoolByDenom = async (client, baseDenom, quoteDenom) => {
996
+ const result = await client.routerClient.getPool(baseDenom, quoteDenom);
997
+ if (!result) {
998
+ throw new NotFoundError3("Pool", `Didn't find a pool to swap ${baseDenom} for ${quoteDenom}`);
993
999
  }
994
1000
  return result;
995
1001
  };
996
1002
 
997
- // src/lib/router/get-all-quotes-for-user.ts
998
- import { bcs as bcs11 } from "@mysten/bcs";
999
- var getAllQuotesForUser = async (client, lpAddress) => {
1000
- const QUOTES_FOR_USER_ALL_FUNCTION = "quotes_for_user_all";
1001
- const response = await queryDevInspect(
1002
- client.suiClient,
1003
- [client.packageId, ROUTER_MODULE, QUOTES_FOR_USER_ALL_FUNCTION],
1004
- [client.contracts.router, bcs11.string().serialize(lpAddress)]
1005
- );
1006
- console.log(response);
1007
- return {};
1003
+ // src/lib/router/get-pools.ts
1004
+ var getPools = async (client) => {
1005
+ return await client.routerClient.getPools();
1008
1006
  };
1009
1007
 
1010
- // src/lib/router/get-pool-for-base.ts
1011
- import { bcs as bcs12 } from "@mysten/bcs";
1012
- var getPoolForBase = async (client, baseDenom) => {
1013
- const MARKET_FOR_BASE_FUNCTION = "market_for_base";
1014
- const response = await queryDevInspect(
1015
- client.suiClient,
1016
- [client.packageId, ROUTER_MODULE, MARKET_FOR_BASE_FUNCTION],
1017
- [client.contracts.router, bcs12.string().serialize(baseDenom)]
1018
- );
1019
- const output = parseDevInspectResult(response, MarketResponseStruct);
1020
- return parseMarketResponseStructOutput(output);
1008
+ // src/lib/router/get-router-config.ts
1009
+ import { NotImplementedError as NotImplementedError3 } from "@bolt-liquidity-hq/core";
1010
+ var getRouterConfig = async (_client) => {
1011
+ throw new NotImplementedError3("getRouterConfig on Sui Client");
1021
1012
  };
1022
1013
 
1023
- // src/lib/router/get-pools.ts
1024
- import { bcs as bcs13 } from "@mysten/bcs";
1025
- var getPools = async (client) => {
1026
- const MARKETS_PAGINATED_FUNCTION = "markets_paginated";
1027
- const result = [];
1028
- let currentCursor = null;
1029
- let hasNextPage = true;
1030
- while (hasNextPage) {
1031
- const response = await queryDevInspect(
1032
- client.suiClient,
1033
- [client.packageId, ROUTER_MODULE, MARKETS_PAGINATED_FUNCTION],
1034
- [
1035
- client.contracts.router,
1036
- bcs13.option(bcs13.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
1037
- bcs13.option(bcs13.string()).serialize(currentCursor)
1038
- ]
1014
+ // src/lib/router/router-client/RouterClient.ts
1015
+ import { normalizeStructTag as normalizeStructTag4 } from "@mysten/sui/utils";
1016
+ var RouterClient = class {
1017
+ constructor(pools) {
1018
+ this.pools = pools;
1019
+ }
1020
+ getPool(denomIn, denomOut) {
1021
+ const normalizedDenomIn = normalizeStructTag4(denomIn);
1022
+ const normalizedDenomOut = normalizeStructTag4(denomOut);
1023
+ const directPairPool = this.pools.find(
1024
+ (item) => item.baseDenom === normalizedDenomIn && item.quoteDenoms.includes(normalizedDenomOut)
1025
+ );
1026
+ if (directPairPool) {
1027
+ return directPairPool;
1028
+ }
1029
+ const inversePairPool = this.pools.find(
1030
+ (item) => item.baseDenom === normalizedDenomOut && item.quoteDenoms.includes(normalizedDenomIn)
1039
1031
  );
1040
- const output = parseDevInspectResult(response, MarketsResponsePaginatedStruct);
1041
- const pools = parseMarketsResponsePaginatedStructOutput(output);
1042
- result.push(...pools);
1043
- currentCursor = output.next_cursor;
1044
- hasNextPage = output.has_next_page;
1032
+ if (inversePairPool) {
1033
+ return inversePairPool;
1034
+ }
1035
+ return;
1036
+ }
1037
+ getPools() {
1038
+ return this.pools;
1045
1039
  }
1046
- return result;
1047
- };
1048
-
1049
- // src/lib/router/get-router-config.ts
1050
- var getRouterConfig = async (client) => {
1051
- const CONFIG_FUNCTION = "config";
1052
- const response = await queryDevInspect(
1053
- client.suiClient,
1054
- [client.packageId, ROUTER_MODULE, CONFIG_FUNCTION],
1055
- [client.contracts.router]
1056
- );
1057
- const output = parseDevInspectResult(response, RouterConfigStruct);
1058
- return parseRouterConfigStructOutput(output);
1059
1040
  };
1060
1041
 
1061
1042
  // src/lib/router/swap-exact-in.ts
1062
- import { bcs as bcs14 } from "@mysten/bcs";
1063
- import { Transaction as Transaction4 } from "@mysten/sui/transactions";
1064
- import { SUI_CLOCK_OBJECT_ID as SUI_CLOCK_OBJECT_ID3 } from "@mysten/sui/utils";
1065
- var swapExactIn = async (client, { assetIn, amountIn, assetOut, minimumAmountOut, receiver }, signer) => {
1066
- const SWAP_EXACT_IN_FUNCTION = "swap_exact_in";
1067
- const finalSigner = client.getSigner(signer);
1068
- const tx = new Transaction4();
1069
- const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());
1070
- const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);
1043
+ var swapExactIn = async (client, swapParams, signer) => {
1044
+ const swapArgs = await buildSwapTxArgs(client, swapParams, signer);
1071
1045
  const txOutput = await signAndExecuteTx(
1072
1046
  client.suiClient,
1073
- finalSigner,
1074
- [client.packageId, ROUTER_MODULE, SWAP_EXACT_IN_FUNCTION],
1075
- [
1076
- client.contracts.router,
1077
- bcs14.string().serialize(assetOut),
1078
- "",
1079
- // TODO: pass correct pool when router can actually route to the pools depending on other arguments
1080
- bcs14.string().serialize(assetIn),
1081
- bcs14.option(bcs14.string()).serialize(minimumAmountOut),
1082
- bcs14.option(bcs14.string()).serialize(receiver),
1083
- coinInput,
1084
- SUI_CLOCK_OBJECT_ID3
1085
- ],
1086
- [assetIn, assetOut],
1087
- tx,
1047
+ swapArgs.signer,
1048
+ swapArgs.target,
1049
+ swapArgs.args,
1050
+ swapArgs.typeArguments,
1051
+ swapArgs.tx,
1088
1052
  { showEffects: true, showEvents: true, showBalanceChanges: true }
1089
1053
  );
1090
1054
  return {
1091
1055
  txOutput,
1092
1056
  txHash: txOutput.digest,
1093
- amountOut: "",
1094
- // TODO: implement when contract emits event
1095
- assetOut
1057
+ amountOut: txOutput.events?.at(0)?.parsedJson?.["amount_out"] ?? "0",
1058
+ assetOut: swapParams.assetOut
1096
1059
  };
1097
1060
  };
1098
1061
 
@@ -1100,57 +1063,56 @@ var swapExactIn = async (client, { assetIn, amountIn, assetOut, minimumAmountOut
1100
1063
  import { SUI_TYPE_ARG as SUI_TYPE_ARG5 } from "@mysten/sui/utils";
1101
1064
 
1102
1065
  // src/lib/settlement/parsers.ts
1103
- var parseSettlementConfigStructOutput = (globalConfig, feesOutput) => {
1066
+ var parseSettlementConfigStructOutput = (routerClient, poolFeesInfo, protocolFeesInfo, priceOracleContract) => {
1104
1067
  return {
1105
- priceOracleContract: "0x",
1106
- // Should come from pool config
1107
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
1108
- protocolFeeRecipient: globalConfig.data?.content?.fields.protocol_fee_recipient || "",
1109
- protocolFee: feesOutput[0],
1110
- // Protocol fee percentage
1111
- lpFee: feesOutput[2],
1112
- // LP fee percentage
1068
+ priceOracleContract,
1069
+ protocolFeeRecipient: protocolFeesInfo.bolt_fee_addr,
1070
+ protocolFee: poolFeesInfo.swap_fee_pct,
1071
+ lpFee: poolFeesInfo.lp_fee_pct,
1113
1072
  allowanceMode: "allow",
1114
1073
  // Should come from pool config
1115
- lps: ["0x"],
1116
- // Should come from pool config
1117
- minBaseOut: "1"
1118
- // Should come from pool config
1074
+ lps: routerClient.getPools().map((item) => item.poolAddress),
1075
+ minBaseOut: "0"
1076
+ // Should come from pool config
1119
1077
  };
1120
1078
  };
1121
1079
 
1122
1080
  // src/lib/settlement/get-pool-info.ts
1123
1081
  var getPoolInfo = async (client, contractAddress) => {
1124
- const GET_FEES_FUNCTION = "get_fees";
1125
- const [globalConfig, fees] = await Promise.all([
1126
- // Fetch the global pool configuration object
1127
- client.suiClient.getObject({
1128
- id: client.poolGlobalConfigId,
1129
- options: {
1130
- showContent: true,
1131
- showType: true
1132
- }
1133
- }),
1134
- // Query pool-specific fee structure
1082
+ const GET_POOL_FEES_INFO_FUNCTION = "get_pool_fees_info";
1083
+ const GET_PROTOCOL_FEES_INFO_FUNCTION = "get_protocol_fees_info";
1084
+ const [poolFeesInfo, protocolFeesInfo] = await Promise.all([
1085
+ // Query pool fee information
1086
+ queryDevInspect(
1087
+ client.suiClient,
1088
+ [client.packageId, POOL_MODULE, GET_POOL_FEES_INFO_FUNCTION],
1089
+ [contractAddress],
1090
+ // TODO: get the base token of the pool to pass it here instead of hardcoded SUI token
1091
+ [SUI_TYPE_ARG5]
1092
+ ),
1093
+ // Query protocol fee information
1135
1094
  queryDevInspect(
1136
1095
  client.suiClient,
1137
- [client.packageId, POOL_MODULE, GET_FEES_FUNCTION],
1096
+ [client.packageId, POOL_MODULE, GET_PROTOCOL_FEES_INFO_FUNCTION],
1138
1097
  [contractAddress],
1139
1098
  // TODO: get the base token of the pool to pass it here instead of hardcoded SUI token
1140
1099
  [SUI_TYPE_ARG5]
1141
1100
  )
1142
1101
  ]);
1143
- const feesOutput = parseMultipleResults(fees, GetFeesResponseStruct);
1144
- return parseSettlementConfigStructOutput(globalConfig, feesOutput);
1102
+ const poolFeesInfoOutput = parseDevInspectResult(poolFeesInfo, PoolFeesInfoStruct);
1103
+ const protocolFeesInfoOutput = parseDevInspectResult(protocolFeesInfo, ProtocolFeesInfoStruct);
1104
+ return parseSettlementConfigStructOutput(
1105
+ client.routerClient,
1106
+ poolFeesInfoOutput,
1107
+ protocolFeesInfoOutput,
1108
+ client.contracts.oracle
1109
+ );
1145
1110
  };
1146
1111
 
1147
- // src/tests/constants/sui-objects.ts
1148
- var TEST_POOL = "0xdd05c1caea7b6725da3f67e30e99872033fc5d3a610a4f72ac1c434bc81c3c0d";
1149
-
1150
- // src/lib/settlement/get-pool-info-for-base.ts
1151
- var getPoolInfoForBase = async (client, baseDenom) => {
1152
- const pool = await getPoolForBase(client, baseDenom && "SUI");
1153
- return await getPoolInfo(client, pool.poolAddress || TEST_POOL);
1112
+ // src/lib/settlement/get-pool-info-by-denom.ts
1113
+ var getPoolInfoByDenom = async (client, baseDenom, quoteDenom) => {
1114
+ const pool = await getPoolByDenom(client, baseDenom, quoteDenom);
1115
+ return await getPoolInfo(client, pool.poolAddress);
1154
1116
  };
1155
1117
 
1156
1118
  // src/lib/client.ts
@@ -1160,7 +1122,8 @@ var BoltSuiClient = class extends BaseClient {
1160
1122
  *
1161
1123
  * The client automatically configures itself based on the specified environment,
1162
1124
  * loading the appropriate contract addresses, chain configuration, native token denomination,
1163
- * and assets from configuration files.
1125
+ * and assets from configuration files. For testnet environments, the client can dynamically
1126
+ * fetch configuration from a remote URL.
1164
1127
  *
1165
1128
  * @param config - (Optional) Configuration for the client
1166
1129
  * @param config.environment - (Optional) The deployment environment ('mainnet' or 'testnet'). Defaults to 'mainnet'
@@ -1186,7 +1149,7 @@ var BoltSuiClient = class extends BaseClient {
1186
1149
  * // Use default configuration (Sui mainnet)
1187
1150
  * const client = new BoltSuiClient();
1188
1151
  *
1189
- * // Use testnet configuration
1152
+ * // Use testnet configuration (will fetch config dynamically)
1190
1153
  * const testnetClient = new BoltSuiClient({
1191
1154
  * environment: 'testnet'
1192
1155
  * });
@@ -1229,12 +1192,14 @@ var BoltSuiClient = class extends BaseClient {
1229
1192
  */
1230
1193
  constructor(config) {
1231
1194
  const { environment = "mainnet", customOverride, signer, suiClient } = config ?? {};
1232
- const defaultChainConfig = environment === "mainnet" ? MainnetChainConfig : TestnetChainConfig;
1233
- const defaultContracts = environment === "mainnet" ? MainnetContracts : TestnetContracts;
1234
- const defaultPackageId = environment === "mainnet" ? MainnetPackageId : TestnetPackageId;
1235
- const defaultPoolGlobalConfigId = environment === "mainnet" ? MainnetPoolGlobalConfigId : TestnetPoolGlobalConfigId;
1236
- const defaultNativeTokenDenom = environment === "mainnet" ? MainnetNativeTokenDenom : TestnetNativeTokenDenom;
1237
- const assetsConfig = environment === "mainnet" ? MainnetAssets : TestnetAssets;
1195
+ const isEnvironmentMainnet = environment === "mainnet";
1196
+ const defaultChainConfig = isEnvironmentMainnet ? MainnetChainConfig : TestnetChainConfig;
1197
+ const defaultContracts = isEnvironmentMainnet ? MainnetContracts : TestnetContracts;
1198
+ const defaultPackageId = isEnvironmentMainnet ? MainnetPackageId : TestnetPackageId;
1199
+ const defaultPoolGlobalConfigId = isEnvironmentMainnet ? MainnetPoolGlobalConfigId : TestnetPoolGlobalConfigId;
1200
+ const defaultNativeTokenDenom = isEnvironmentMainnet ? MainnetNativeTokenDenom : TestnetNativeTokenDenom;
1201
+ const assetsConfig = isEnvironmentMainnet ? MainnetAssets : TestnetAssets;
1202
+ const pools = isEnvironmentMainnet ? MainnetPools : [];
1238
1203
  const chainConfig = {
1239
1204
  id: customOverride?.chainConfig?.id ?? defaultChainConfig.id,
1240
1205
  name: customOverride?.chainConfig?.name ?? defaultChainConfig.name,
@@ -1272,18 +1237,30 @@ var BoltSuiClient = class extends BaseClient {
1272
1237
  __publicField(this, "poolGlobalConfigId");
1273
1238
  /**
1274
1239
  * Cached instance of the Signer for transaction execution
1275
- * @private
1276
1240
  */
1277
1241
  __publicField(this, "signer");
1278
1242
  /**
1279
1243
  * Instance of the Sui client to interact with the blockchain
1280
1244
  */
1281
1245
  __publicField(this, "suiClient");
1246
+ /**
1247
+ * URL for fetching testnet configuration dynamically.
1248
+ * Used to load package IDs, oracle addresses, and asset configurations for testnet environments.
1249
+ * @private
1250
+ */
1251
+ __publicField(this, "configFileUrl");
1252
+ /**
1253
+ * Router client instance for managing pool configurations and routing calculations.
1254
+ * Handles pool discovery and optimal path finding for swaps.
1255
+ */
1256
+ __publicField(this, "routerClient");
1282
1257
  this.chainConfig = chainConfig;
1283
1258
  this.packageId = packageId;
1284
1259
  this.poolGlobalConfigId = poolGlobalConfigId;
1285
1260
  this.signer = signer;
1286
1261
  this.suiClient = suiClient ?? new SuiClient({ url: chainConfig.rpcEndpoint });
1262
+ this.routerClient = new RouterClient(pools);
1263
+ this.configFileUrl = isEnvironmentMainnet ? void 0 : TestnetConfigUrl;
1287
1264
  }
1288
1265
  /**
1289
1266
  * Gets or sets the signer for transaction execution.
@@ -1319,51 +1296,81 @@ var BoltSuiClient = class extends BaseClient {
1319
1296
  // Only add documentation here if you need to override or add implementation-specific details
1320
1297
  /** @inheritdoc */
1321
1298
  async getOracleConfig() {
1299
+ await this.loadConfigFromUrl();
1322
1300
  return await getOracleConfig(this);
1323
1301
  }
1324
1302
  /** @inheritdoc */
1325
1303
  async getAllOracleAssetPairs() {
1304
+ await this.loadConfigFromUrl();
1326
1305
  return await getAssetPairs(this);
1327
1306
  }
1328
1307
  /** @inheritdoc */
1329
1308
  async getPrice(baseDenom, quoteDenom) {
1309
+ await this.loadConfigFromUrl();
1330
1310
  return await getPrice(this, baseDenom, quoteDenom);
1331
1311
  }
1332
1312
  /** @inheritdoc */
1333
1313
  async getAllPrices() {
1314
+ await this.loadConfigFromUrl();
1334
1315
  return await getPrices(this);
1335
1316
  }
1336
1317
  /** @inheritdoc */
1337
1318
  async getRouterConfig() {
1319
+ await this.loadConfigFromUrl();
1338
1320
  return await getRouterConfig(this);
1339
1321
  }
1340
1322
  /** @inheritdoc */
1341
1323
  async getAllBaseAssetsLiquidity() {
1324
+ await this.loadConfigFromUrl();
1342
1325
  return await getAllBaseLiquidity(this);
1343
1326
  }
1344
1327
  /** @inheritdoc */
1345
1328
  async getAllQuotesByUser(address) {
1329
+ await this.loadConfigFromUrl();
1346
1330
  return await getAllQuotesForUser(this, address);
1347
1331
  }
1348
- /** @inheritdoc */
1349
- async getPoolByBaseAsset(baseDenom) {
1350
- return await getPoolForBase(this, baseDenom);
1332
+ /**
1333
+ * @inheritdoc
1334
+ *
1335
+ * @remarks
1336
+ * In the Sui implementation, both `baseDenom` and `quoteDenom` parameters are required.
1337
+ * The Sui architecture uses both asset types to uniquely identify pools for specific
1338
+ * trading pairs.
1339
+ *
1340
+ * @throws Will throw an error if no pool exists for the specified base/quote asset pair
1341
+ */
1342
+ async getPoolByDenom(baseDenom, quoteDenom) {
1343
+ await this.loadConfigFromUrl();
1344
+ return await getPoolByDenom(this, baseDenom, quoteDenom);
1351
1345
  }
1352
1346
  /** @inheritdoc */
1353
1347
  async getAllPools() {
1348
+ await this.loadConfigFromUrl();
1354
1349
  return await getPools(this);
1355
1350
  }
1356
- // Satisfy the base class requirement
1351
+ /** @inheritdoc */
1357
1352
  async getPoolConfig(poolContractAddress) {
1353
+ await this.loadConfigFromUrl();
1358
1354
  return await getPoolInfo(this, poolContractAddress);
1359
1355
  }
1360
1356
  /** @inheritdoc */
1361
1357
  async getAssets() {
1358
+ await this.loadConfigFromUrl();
1362
1359
  return await getAssets(this);
1363
1360
  }
1364
- /** @inheritdoc */
1365
- async getPoolConfigByBaseAsset(baseDenom) {
1366
- return await getPoolInfoForBase(this, baseDenom);
1361
+ /**
1362
+ * @inheritdoc
1363
+ *
1364
+ * @remarks
1365
+ * In the Sui implementation, both `baseDenom` and `quoteDenom` parameters are required.
1366
+ * The Sui architecture uses both asset types to uniquely identify pools for specific
1367
+ * trading pairs.
1368
+ *
1369
+ * @throws Will throw an error if no pool exists for the specified base/quote asset pair
1370
+ */
1371
+ async getPoolConfigByDenom(baseDenom, quoteDenom) {
1372
+ await this.loadConfigFromUrl();
1373
+ return await getPoolInfoByDenom(this, baseDenom, quoteDenom);
1367
1374
  }
1368
1375
  /**
1369
1376
  * @inheritdoc
@@ -1394,6 +1401,7 @@ var BoltSuiClient = class extends BaseClient {
1394
1401
  * which includes details like gas costs, transaction effects, object changes, and events.
1395
1402
  */
1396
1403
  async swap(params, signer) {
1404
+ await this.loadConfigFromUrl();
1397
1405
  return await swapExactIn(this, params, signer);
1398
1406
  }
1399
1407
  /**
@@ -1425,28 +1433,91 @@ var BoltSuiClient = class extends BaseClient {
1425
1433
  * - Sui's gas model includes computation, storage, and storage rebates
1426
1434
  */
1427
1435
  async estimateSwapGasFees(params, signer, gasAdjustment) {
1436
+ await this.loadConfigFromUrl();
1428
1437
  return await estimateSwapExactInGasFees(this, params, signer, gasAdjustment);
1429
1438
  }
1439
+ /**
1440
+ * Loads configuration from a remote URL for testnet environments.
1441
+ *
1442
+ * This method fetches and applies dynamic configuration including:
1443
+ * - Package ID for Bolt contracts
1444
+ * - Oracle contract address
1445
+ * - Pool global configuration ID
1446
+ * - Asset mappings and metadata
1447
+ * - Pool configurations
1448
+ *
1449
+ * The method is called automatically before API operations when a config URL is set.
1450
+ * After successful loading, the config URL is cleared to prevent redundant fetches.
1451
+ *
1452
+ * @private
1453
+ * @remarks
1454
+ * - Only executes if `configFileUrl` is set (typically for testnet)
1455
+ * - Updates testnet-specific asset denoms with their actual deployed addresses
1456
+ * - Populates the router client's pool configurations
1457
+ * - Normalizes struct tags for consistency
1458
+ */
1459
+ async loadConfigFromUrl() {
1460
+ if (!this.configFileUrl) {
1461
+ return;
1462
+ }
1463
+ const response = await axios.get(this.configFileUrl);
1464
+ const { package_id, oracle_id, global_config_id, assets, pools } = response.data ?? {};
1465
+ if (!this.packageId && package_id) {
1466
+ this.packageId = package_id;
1467
+ }
1468
+ if (!this.contracts.oracle.trim() && oracle_id) {
1469
+ this.contracts.oracle = oracle_id;
1470
+ }
1471
+ if (!this.poolGlobalConfigId && global_config_id) {
1472
+ this.poolGlobalConfigId = global_config_id;
1473
+ }
1474
+ for (const item of Object.values(assets)) {
1475
+ for (const suffix of TestnetHelperAssets) {
1476
+ if (item.includes(suffix) && this.assetsConfig[suffix]) {
1477
+ this.assetsConfig[item] = {
1478
+ ...this.assetsConfig[suffix],
1479
+ denom: item
1480
+ };
1481
+ delete this.assetsConfig[suffix];
1482
+ break;
1483
+ }
1484
+ }
1485
+ }
1486
+ if (this.routerClient.pools.length === 0) {
1487
+ for (const item of pools) {
1488
+ this.routerClient.pools.push({
1489
+ poolAddress: item.pool_object_id,
1490
+ baseDenom: normalizeStructTag5(item.base),
1491
+ quoteDenoms: Object.values(assets).map((auxAsset) => normalizeStructTag5(auxAsset)).filter((auxAsset) => auxAsset !== normalizeStructTag5(item.base))
1492
+ });
1493
+ }
1494
+ }
1495
+ this.configFileUrl = void 0;
1496
+ }
1430
1497
  };
1431
1498
  export {
1499
+ AssetPairResponseStruct,
1432
1500
  AssetPairStruct,
1433
- AssetPairsResponsePaginatedStruct,
1434
1501
  AssetPairsResponseStruct,
1435
1502
  BaseLiquidityInfoStruct,
1436
1503
  BaseLiquidityResponseStruct,
1437
1504
  BcsAddressType,
1438
1505
  BoltSuiClient,
1439
- GetFeesResponseStruct,
1440
- GetPoolInfoResponseStruct,
1441
1506
  MarketResponseStruct,
1442
1507
  MarketStruct,
1443
1508
  MarketsResponsePaginatedStruct,
1444
1509
  MarketsResponseStruct,
1445
1510
  OracleConfigStruct,
1446
1511
  PaginationStruct,
1512
+ PoolFeesInfoStruct,
1513
+ PoolInfoStruct,
1447
1514
  PriceDataStruct,
1448
1515
  PriceResponseStruct,
1449
1516
  PricesResponsePaginatedStruct,
1450
- RouterConfigStruct
1517
+ ProtocolFeesInfoStruct,
1518
+ RawPairStruct,
1519
+ RawPriceStruct,
1520
+ RouterConfigStruct,
1521
+ TypeNameStruct
1451
1522
  };
1452
1523
  //# sourceMappingURL=index.js.map