@bolt-liquidity-hq/sui-client 0.1.0-beta.12 → 0.1.0-beta.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.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
9
  var __export = (target, all) => {
@@ -16,40 +18,57 @@ var __copyProps = (to, from, except, desc) => {
16
18
  }
17
19
  return to;
18
20
  };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
19
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
30
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
31
 
22
32
  // src/index.ts
23
33
  var index_exports = {};
24
34
  __export(index_exports, {
35
+ AssetPairResponseStruct: () => AssetPairResponseStruct,
25
36
  AssetPairStruct: () => AssetPairStruct,
26
- AssetPairsResponsePaginatedStruct: () => AssetPairsResponsePaginatedStruct,
27
37
  AssetPairsResponseStruct: () => AssetPairsResponseStruct,
28
38
  BaseLiquidityInfoStruct: () => BaseLiquidityInfoStruct,
29
39
  BaseLiquidityResponseStruct: () => BaseLiquidityResponseStruct,
30
40
  BcsAddressType: () => BcsAddressType,
31
41
  BoltSuiClient: () => BoltSuiClient,
32
- GetFeesResponseStruct: () => GetFeesResponseStruct,
33
- GetPoolInfoResponseStruct: () => GetPoolInfoResponseStruct,
34
42
  MarketResponseStruct: () => MarketResponseStruct,
35
43
  MarketStruct: () => MarketStruct,
36
44
  MarketsResponsePaginatedStruct: () => MarketsResponsePaginatedStruct,
37
45
  MarketsResponseStruct: () => MarketsResponseStruct,
38
46
  OracleConfigStruct: () => OracleConfigStruct,
39
47
  PaginationStruct: () => PaginationStruct,
48
+ PoolFeesInfoStruct: () => PoolFeesInfoStruct,
49
+ PoolInfoStruct: () => PoolInfoStruct,
40
50
  PriceDataStruct: () => PriceDataStruct,
41
51
  PriceResponseStruct: () => PriceResponseStruct,
42
- PricesResponsePaginatedStruct: () => PricesResponsePaginatedStruct,
43
- RouterConfigStruct: () => RouterConfigStruct
52
+ ProtocolFeesInfoStruct: () => ProtocolFeesInfoStruct,
53
+ RawPairStruct: () => RawPairStruct,
54
+ RawPriceStruct: () => RawPriceStruct,
55
+ RouterConfigStruct: () => RouterConfigStruct,
56
+ TypeNameStruct: () => TypeNameStruct
44
57
  });
45
58
  module.exports = __toCommonJS(index_exports);
46
59
 
47
60
  // src/lib/client.ts
48
- var import_core8 = require("@bolt-liquidity-hq/core");
61
+ var import_core13 = require("@bolt-liquidity-hq/core");
49
62
  var import_client = require("@mysten/sui/client");
63
+ var import_utils9 = require("@mysten/sui/utils");
64
+ var import_axios = __toESM(require("axios"), 1);
50
65
 
51
- // src/config/mainnet.ts
66
+ // src/config/common.ts
52
67
  var import_utils = require("@mysten/sui/utils");
68
+ var SUI_TOKEN_DENOM = (0, import_utils.normalizeStructTag)(import_utils.SUI_TYPE_ARG);
69
+
70
+ // src/config/mainnet.ts
71
+ var import_utils2 = require("@mysten/sui/utils");
53
72
  var MainnetChainConfig = {
54
73
  name: "Sui",
55
74
  id: "101",
@@ -61,14 +80,14 @@ var MainnetContracts = {
61
80
  };
62
81
  var MainnetPackageId = "0x...";
63
82
  var MainnetPoolGlobalConfigId = "0x...";
64
- var MainnetNativeTokenDenom = import_utils.SUI_TYPE_ARG;
83
+ var MainnetNativeTokenDenom = SUI_TOKEN_DENOM;
65
84
  var MainnetAssets = {
66
- [import_utils.SUI_TYPE_ARG]: {
85
+ [SUI_TOKEN_DENOM]: {
67
86
  symbol: "SUI",
68
87
  name: "Sui",
69
88
  chainId: "101",
70
- denom: import_utils.SUI_TYPE_ARG,
71
- decimals: import_utils.SUI_DECIMALS,
89
+ denom: SUI_TOKEN_DENOM,
90
+ decimals: import_utils2.SUI_DECIMALS,
72
91
  logo: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/sui/info/logo.png",
73
92
  coingeckoId: "sui"
74
93
  },
@@ -82,28 +101,31 @@ var MainnetAssets = {
82
101
  coingeckoId: "usd-coin"
83
102
  }
84
103
  };
104
+ var MainnetPools = [];
85
105
 
86
106
  // src/config/testnet.ts
87
- var import_utils2 = require("@mysten/sui/utils");
107
+ var import_utils3 = require("@mysten/sui/utils");
108
+ var TestnetConfigUrl = "https://phi-labs-ltd.github.io/sui-outpost/testnet.json";
88
109
  var TestnetChainConfig = {
89
110
  name: "Sui Testnet",
90
111
  id: "103",
91
112
  rpcEndpoint: "https://fullnode.testnet.sui.io:443"
92
113
  };
93
114
  var TestnetContracts = {
94
- oracle: "0xecece01cfb23b5439e04b18fe656eaf2746b9087cf68f1d48797c8f71a3dd93b",
95
- router: "0x3881fdcb4a7fbcda8edc230e6f92eb57b24c0be6b44af0b5e1d0b45564f3ed00"
115
+ oracle: " ",
116
+ router: " "
96
117
  };
97
- var TestnetPackageId = "0x22384b1841229e2be878bb7e88833c03e23ff5dc39accd050fb932120602f85e";
98
- var TestnetPoolGlobalConfigId = "0xa9491e59fa63e666cbfdea2e880b2d8ba0085eeb244220cefa3fb817559cd79c";
99
- var TestnetNativeTokenDenom = import_utils2.SUI_TYPE_ARG;
118
+ var TestnetPackageId = "";
119
+ var TestnetPoolGlobalConfigId = "";
120
+ var TestnetNativeTokenDenom = SUI_TOKEN_DENOM;
121
+ var TestnetHelperAssets = ["::test_btc::TEST_BTC", "::test_usdt::TEST_USDT"];
100
122
  var TestnetAssets = {
101
- [import_utils2.SUI_TYPE_ARG]: {
123
+ [SUI_TOKEN_DENOM]: {
102
124
  symbol: "SUI",
103
125
  name: "Sui",
104
126
  chainId: "103",
105
- denom: import_utils2.SUI_TYPE_ARG,
106
- decimals: import_utils2.SUI_DECIMALS,
127
+ denom: SUI_TOKEN_DENOM,
128
+ decimals: import_utils3.SUI_DECIMALS,
107
129
  logo: "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/sui/info/logo.png",
108
130
  coingeckoId: "sui"
109
131
  },
@@ -115,20 +137,32 @@ var TestnetAssets = {
115
137
  decimals: 6,
116
138
  logo: "https://raw.githubusercontent.com/cosmos/chain-registry/master/noble/images/USDCoin.png",
117
139
  coingeckoId: "usd-coin"
140
+ },
141
+ "::test_btc::TEST_BTC": {
142
+ symbol: "TEST_BTC",
143
+ name: "Test BTC",
144
+ chainId: "103",
145
+ denom: "::test_btc::TEST_BTC",
146
+ decimals: 8,
147
+ logo: "https://raw.githubusercontent.com/cosmos/chain-registry/refs/heads/master/_non-cosmos/bitcoin/images/btc.svg",
148
+ coingeckoId: "bitcoin"
149
+ },
150
+ "::test_usdt::TEST_USDT": {
151
+ symbol: "TEST_USDT",
152
+ name: "Test USDT",
153
+ chainId: "103",
154
+ denom: "::test_usdt::TEST_USDT",
155
+ decimals: 6,
156
+ logo: "https://raw.githubusercontent.com/cosmos/chain-registry/refs/heads/master/_non-cosmos/ethereum/images/usdt.svg",
157
+ coingeckoId: "tether"
118
158
  }
119
159
  };
120
160
 
121
- // src/lib/oracle/get-asset-pairs.ts
122
- var import_bcs9 = require("@mysten/bcs");
123
-
124
- // src/lib/constants/defaults.ts
125
- var DEFAULT_PAGINATION_LIMIT = 50;
126
-
127
161
  // src/lib/constants/sui-objects.ts
128
162
  var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000000000000000000000000000";
129
163
  var PRICE_ORACLE_MODULE = "price_oracle";
130
164
  var ROUTER_MODULE = "router";
131
- var POOL_MODULE = "settlement";
165
+ var POOL_MODULE = "pool";
132
166
 
133
167
  // src/lib/helpers/bcs-parse.ts
134
168
  var import_core = require("@bolt-liquidity-hq/core");
@@ -162,13 +196,10 @@ var parseDevInspectResult = (result, bcsType, resultIndex = 0, returnValueIndex
162
196
  });
163
197
  }
164
198
  };
165
- var parseMultipleResults = (info, schema) => {
166
- return schema.map((bcsType, index) => parseDevInspectResult(info, bcsType, 0, index));
167
- };
168
199
 
169
200
  // src/lib/helpers/coin-manager.ts
170
201
  var import_core2 = require("@bolt-liquidity-hq/core");
171
- var import_utils3 = require("@mysten/sui/utils");
202
+ var import_utils4 = require("@mysten/sui/utils");
172
203
  var CoinManager = class {
173
204
  /**
174
205
  * Creates a new CoinManager instance.
@@ -535,7 +566,7 @@ var CoinManager = class {
535
566
  */
536
567
  async prepareCoinInput(tx, coinType, amount, options = {}, owner) {
537
568
  const ownerAddress = this.getOwnerAddress(owner);
538
- if (coinType === import_utils3.SUI_TYPE_ARG) {
569
+ if ((0, import_utils4.normalizeStructTag)(coinType) === SUI_TOKEN_DENOM) {
539
570
  const [coin] = tx.splitCoins(tx.gas, [amount]);
540
571
  return coin;
541
572
  }
@@ -598,11 +629,42 @@ var queryDevInspect = async (suiClient, target, args, typeArguments, senderAddre
598
629
  }
599
630
  };
600
631
 
601
- // src/lib/helpers/txs.ts
632
+ // src/lib/helpers/transactions.ts
602
633
  var import_core4 = require("@bolt-liquidity-hq/core");
634
+ var import_bcs2 = require("@mysten/bcs");
603
635
  var import_transactions2 = require("@mysten/sui/transactions");
604
- var import_utils4 = require("@mysten/sui/utils");
636
+ var import_utils5 = require("@mysten/sui/utils");
605
637
  var import_bignumber = require("bignumber.js");
638
+ var buildSwapTxArgs = async (client, swapParams, signer) => {
639
+ const { assetIn, amountIn, assetOut, minimumAmountOut, receiver } = swapParams;
640
+ const pool = client.routerClient.getPool(assetIn, assetOut);
641
+ if (!pool) {
642
+ throw new import_core4.NotFoundError(`Pool for the pair ${assetIn}/${assetOut}`);
643
+ }
644
+ const isSell = (0, import_utils5.normalizeStructTag)(assetIn) === pool.baseDenom;
645
+ const FUNCTION_NAME = isSell ? "swap_sell" : "swap_buy";
646
+ const finalSigner = client.getSigner(signer);
647
+ const tx = new import_transactions2.Transaction();
648
+ const signerAddress = getSignerAddress(finalSigner);
649
+ const coinManager = new CoinManager(client.suiClient, signerAddress);
650
+ const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);
651
+ return {
652
+ signer: finalSigner,
653
+ signerAddress,
654
+ target: [client.packageId, ROUTER_MODULE, FUNCTION_NAME],
655
+ args: [
656
+ pool.poolAddress,
657
+ client.contracts.oracle,
658
+ import_utils5.SUI_CLOCK_OBJECT_ID,
659
+ coinInput,
660
+ import_bcs2.bcs.u64().serialize(amountIn),
661
+ import_bcs2.bcs.option(import_bcs2.bcs.u64()).serialize(minimumAmountOut),
662
+ import_bcs2.bcs.option(import_bcs2.bcs.string()).serialize(receiver)
663
+ ],
664
+ typeArguments: [isSell ? assetIn : assetOut, isSell ? assetOut : assetIn],
665
+ tx
666
+ };
667
+ };
606
668
  var signAndExecuteTx = async (suiClient, signer, target, args, typeArguments, transaction, options) => {
607
669
  const tx = transaction ?? new import_transactions2.Transaction();
608
670
  const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;
@@ -615,15 +677,29 @@ var signAndExecuteTx = async (suiClient, signer, target, args, typeArguments, tr
615
677
  typeArguments
616
678
  });
617
679
  try {
618
- const result = await suiClient.signAndExecuteTransaction({
619
- signer,
620
- transaction: tx,
621
- options
622
- });
623
- if (result.effects?.status.status === "success") {
624
- return result;
680
+ if ("toSuiAddress" in signer) {
681
+ const result = await suiClient.signAndExecuteTransaction({
682
+ signer,
683
+ transaction: tx,
684
+ options
685
+ });
686
+ if (result.effects?.status.status === "success") {
687
+ return result;
688
+ } else {
689
+ throw new import_core4.TransactionFailedError(result.digest, result.effects?.status.error, { result });
690
+ }
625
691
  } else {
626
- throw new import_core4.TransactionFailedError(result.digest, result.effects?.status.error, { result });
692
+ const result = await signer.signAndExecuteTransaction({
693
+ transaction: tx
694
+ });
695
+ if (!result.digest) {
696
+ throw new import_core4.TransactionFailedError("not found");
697
+ }
698
+ const fullTx = await suiClient.waitForTransaction({
699
+ digest: result.digest,
700
+ options
701
+ });
702
+ return fullTx;
627
703
  }
628
704
  } catch (error) {
629
705
  throw import_core4.UnexpectedError.from(error, "Failed to execute transaction", {
@@ -633,7 +709,7 @@ var signAndExecuteTx = async (suiClient, signer, target, args, typeArguments, tr
633
709
  });
634
710
  }
635
711
  };
636
- var estimateTxGasPrice = async (suiClient, target, args, typeArguments, transaction, gasAdjustment = import_core4.DEFAULT_GAS_ADJUSTMENT) => {
712
+ var estimateTxGasPrice = async (suiClient, senderAddress, target, args, typeArguments, transaction, gasAdjustment = import_core4.DEFAULT_GAS_ADJUSTMENT) => {
637
713
  const tx = transaction ?? new import_transactions2.Transaction();
638
714
  const targetString = Array.isArray(target) ? `${target[0]}::${target[1]}::${target[2]}` : target;
639
715
  const txArgs = args?.map(
@@ -644,6 +720,7 @@ var estimateTxGasPrice = async (suiClient, target, args, typeArguments, transact
644
720
  arguments: txArgs,
645
721
  typeArguments
646
722
  });
723
+ tx.setSender(senderAddress);
647
724
  try {
648
725
  const transactionBytes = await tx.build({ client: suiClient });
649
726
  const dryRunResult = await suiClient.dryRunTransactionBlock({
@@ -665,20 +742,28 @@ var estimateTxGasPrice = async (suiClient, target, args, typeArguments, transact
665
742
  const totalGasCost = (0, import_bignumber.BigNumber)(gasUsed.computationCost).plus(gasUsed.storageCost).minus(gasUsed.storageRebate);
666
743
  const adjustedGasCost = totalGasCost.times(gasAdjustment);
667
744
  return {
668
- denom: import_utils4.SUI_TYPE_ARG,
745
+ denom: SUI_TOKEN_DENOM,
669
746
  amount: adjustedGasCost.toFixed(0, import_bignumber.BigNumber.ROUND_CEIL)
670
747
  };
671
748
  } catch {
672
749
  return;
673
750
  }
674
751
  };
752
+ var getSignerAddress = (signer) => {
753
+ const address = "address" in signer ? signer.address : signer.toSuiAddress?.();
754
+ if (!address) {
755
+ throw new import_core4.NotFoundError("Signer account's address");
756
+ }
757
+ return address;
758
+ };
675
759
 
676
760
  // src/lib/oracle/parsers.ts
677
761
  var import_core5 = require("@bolt-liquidity-hq/core");
678
762
  var import_bignumber2 = require("bignumber.js");
679
763
  var parseOracleConfigStructOutput = (output) => {
680
764
  return {
681
- admin: output.admin,
765
+ // TODO: try to query admin somewhere else? to fill empty value
766
+ admin: "",
682
767
  priceThresholdRatio: output.price_threshold_ratio,
683
768
  priceExpireTime: {
684
769
  secs: Number(output.default_price_expiry_seconds),
@@ -689,47 +774,46 @@ var parseOracleConfigStructOutput = (output) => {
689
774
  var parseAssetPairStructOutput = (output) => {
690
775
  return {
691
776
  base: {
692
- name: output.base_symbol,
693
- symbol: output.base_symbol,
777
+ name: output.base_name,
778
+ // TODO: map a different value for name/symbols
779
+ symbol: output.base_name,
694
780
  precision: output.base_precision
695
781
  },
696
782
  quote: {
697
- name: output.quote_symbol,
698
- symbol: output.quote_symbol,
783
+ name: output.quote_name,
784
+ // TODO: map a different value for name/symbols
785
+ symbol: output.quote_name,
699
786
  precision: output.quote_precision
700
787
  }
701
788
  };
702
789
  };
703
- var parsePriceDataStructOutput = (output) => {
790
+ var parseAssetPairsResponseStructOutput = (output) => {
791
+ return output.map((item) => parseAssetPairStructOutput(item.info));
792
+ };
793
+ var parsePriceDataStructOutput = (output, baseDenom, quoteDenom, isInverted) => {
704
794
  return {
705
- baseDenom: output.base_symbol,
706
- quoteDenom: output.quote_symbol,
707
- price: output.price,
708
- expiryTime: (0, import_bignumber2.BigNumber)(output.expiry_time_ms).times(1e6).toFixed(),
709
- isInverse: false
795
+ baseDenom,
796
+ quoteDenom,
797
+ price: output.price.price,
798
+ expiryTime: (0, import_bignumber2.BigNumber)(output.price.expiry).times(1e6).toFixed(),
799
+ isInverse: isInverted ?? false
710
800
  };
711
801
  };
712
- var parsePriceResponseStructOutput = (output) => {
802
+ var parsePriceResponseStructOutput = (output, baseDenom, quoteDenom) => {
713
803
  if (!output.pair_data) {
714
804
  throw new import_core5.InvalidObjectError("Can't find pair data price");
715
805
  }
716
- return parsePriceDataStructOutput(output.pair_data);
717
- };
718
- var parseAssetPairsResponsePaginatedStructOutput = (output) => {
719
- return output.asset_pairs.map((item) => parseAssetPairStructOutput(item));
720
- };
721
- var parsePricesResponsePaginatedStructOutput = (output) => {
722
- return output.prices.map((item) => parsePriceDataStructOutput(item));
806
+ return parsePriceDataStructOutput(output.pair_data, baseDenom, quoteDenom, output.is_inverted);
723
807
  };
724
808
 
725
809
  // src/types/bcs.ts
726
- var import_bcs2 = require("@mysten/bcs");
810
+ var import_bcs3 = require("@mysten/bcs");
727
811
  var PaginationStruct = {
728
- total_count: import_bcs2.bcs.u64(),
729
- has_next_page: import_bcs2.bcs.bool(),
730
- next_cursor: import_bcs2.bcs.option(import_bcs2.bcs.string())
812
+ total_count: import_bcs3.bcs.u64(),
813
+ has_next_page: import_bcs3.bcs.bool(),
814
+ next_cursor: import_bcs3.bcs.option(import_bcs3.bcs.string())
731
815
  };
732
- var BcsAddressType = new import_bcs2.BcsType({
816
+ var BcsAddressType = new import_bcs3.BcsType({
733
817
  name: "address",
734
818
  read(reader) {
735
819
  const bytes = new Uint8Array(32);
@@ -749,118 +833,123 @@ var BcsAddressType = new import_bcs2.BcsType({
749
833
  });
750
834
 
751
835
  // src/types/oracle.ts
752
- var import_bcs3 = require("@mysten/bcs");
753
- var OracleConfigStruct = import_bcs3.bcs.struct("Config", {
754
- admin: BcsAddressType,
755
- price_threshold_ratio: import_bcs3.bcs.u64(),
756
- default_price_expiry_seconds: import_bcs3.bcs.u64()
836
+ var import_bcs4 = require("@mysten/bcs");
837
+ var OracleConfigStruct = import_bcs4.bcs.struct("Config", {
838
+ price_threshold_ratio: import_bcs4.bcs.u64(),
839
+ default_price_expiry_seconds: import_bcs4.bcs.u64()
757
840
  });
758
- var AssetPairStruct = import_bcs3.bcs.struct("AssetPair", {
759
- base_symbol: import_bcs3.bcs.string(),
760
- quote_symbol: import_bcs3.bcs.string(),
761
- base_precision: import_bcs3.bcs.u8(),
762
- quote_precision: import_bcs3.bcs.u8()
841
+ var AssetPairStruct = import_bcs4.bcs.struct("AssetPair", {
842
+ base_name: import_bcs4.bcs.string(),
843
+ quote_name: import_bcs4.bcs.string(),
844
+ base_precision: import_bcs4.bcs.u8(),
845
+ quote_precision: import_bcs4.bcs.u8()
763
846
  });
764
- var AssetPairsResponseStruct = import_bcs3.bcs.struct("AssetPairsResponse", {
765
- asset_pairs: import_bcs3.bcs.vector(AssetPairStruct)
847
+ var TypeNameStruct = import_bcs4.bcs.struct("TypeName", {
848
+ name: import_bcs4.bcs.string()
766
849
  });
767
- var AssetPairsResponsePaginatedStruct = import_bcs3.bcs.struct("AssetPairsResponsePaginated", {
768
- asset_pairs: import_bcs3.bcs.vector(AssetPairStruct),
769
- ...PaginationStruct
850
+ var RawPairStruct = import_bcs4.bcs.struct("RawPair", {
851
+ base: TypeNameStruct,
852
+ quote: TypeNameStruct
770
853
  });
771
- var PriceDataStruct = import_bcs3.bcs.struct("PriceData", {
772
- base_symbol: import_bcs3.bcs.string(),
773
- quote_symbol: import_bcs3.bcs.string(),
774
- price: import_bcs3.bcs.u128(),
775
- expiry_time_ms: import_bcs3.bcs.u64(),
776
- last_updated_ms: import_bcs3.bcs.u64(),
777
- updater: BcsAddressType
854
+ var AssetPairResponseStruct = import_bcs4.bcs.struct("AssetPairResponse", {
855
+ pair: RawPairStruct,
856
+ info: AssetPairStruct
778
857
  });
779
- var PriceResponseStruct = import_bcs3.bcs.struct("PriceResponse", {
780
- pair_data: import_bcs3.bcs.option(PriceDataStruct)
858
+ var AssetPairsResponseStruct = import_bcs4.bcs.vector(AssetPairResponseStruct);
859
+ var RawPriceStruct = import_bcs4.bcs.struct("RawPrice", {
860
+ price: import_bcs4.bcs.u128(),
861
+ expiry: import_bcs4.bcs.u64()
781
862
  });
782
- var PricesResponsePaginatedStruct = import_bcs3.bcs.struct("PricesResponsePaginated", {
783
- prices: import_bcs3.bcs.vector(PriceDataStruct),
784
- ...PaginationStruct
863
+ var PriceDataStruct = import_bcs4.bcs.struct("PriceData", {
864
+ price: RawPriceStruct,
865
+ last_updated_ms: import_bcs4.bcs.u64(),
866
+ updater: BcsAddressType
867
+ });
868
+ var PriceResponseStruct = import_bcs4.bcs.struct("PriceResponse", {
869
+ pair_data: import_bcs4.bcs.option(PriceDataStruct),
870
+ is_inverted: import_bcs4.bcs.bool()
785
871
  });
786
872
 
787
873
  // src/types/router.ts
788
- var import_bcs5 = require("@mysten/bcs");
789
- var RouterConfigStruct = import_bcs5.bcs.struct("Config", {
874
+ var import_bcs6 = require("@mysten/bcs");
875
+ var RouterConfigStruct = import_bcs6.bcs.struct("Config", {
790
876
  admin: BcsAddressType,
791
877
  default_price_oracle_contract: BcsAddressType,
792
878
  default_protocol_fee_recipient: BcsAddressType,
793
- default_protocol_fee: import_bcs5.bcs.u64(),
794
- default_lp_fee: import_bcs5.bcs.u64()
879
+ default_protocol_fee: import_bcs6.bcs.u64(),
880
+ default_lp_fee: import_bcs6.bcs.u64()
795
881
  });
796
- var MarketStruct = import_bcs5.bcs.struct("Market", {
797
- base_asset_symbol: import_bcs5.bcs.string(),
798
- quote_assets_symbols: import_bcs5.bcs.vector(import_bcs5.bcs.string()),
799
- market_address: import_bcs5.bcs.string(),
800
- is_permissioned: import_bcs5.bcs.bool(),
801
- created_at_ms: import_bcs5.bcs.u64()
882
+ var MarketStruct = import_bcs6.bcs.struct("Market", {
883
+ base_asset_symbol: import_bcs6.bcs.string(),
884
+ quote_assets_symbols: import_bcs6.bcs.vector(import_bcs6.bcs.string()),
885
+ market_address: import_bcs6.bcs.string(),
886
+ is_permissioned: import_bcs6.bcs.bool(),
887
+ created_at_ms: import_bcs6.bcs.u64()
802
888
  });
803
- var MarketResponseStruct = import_bcs5.bcs.struct("MarketResponse", {
804
- market: import_bcs5.bcs.option(MarketStruct)
889
+ var MarketResponseStruct = import_bcs6.bcs.struct("MarketResponse", {
890
+ market: import_bcs6.bcs.option(MarketStruct)
805
891
  });
806
- var MarketsResponseStruct = import_bcs5.bcs.struct("MarketsResponse", {
807
- markets: import_bcs5.bcs.vector(MarketStruct)
892
+ var MarketsResponseStruct = import_bcs6.bcs.struct("MarketsResponse", {
893
+ markets: import_bcs6.bcs.vector(MarketStruct)
808
894
  });
809
- var MarketsResponsePaginatedStruct = import_bcs5.bcs.struct("MarketsResponsePaginated", {
810
- markets: import_bcs5.bcs.vector(MarketStruct),
895
+ var MarketsResponsePaginatedStruct = import_bcs6.bcs.struct("MarketsResponsePaginated", {
896
+ markets: import_bcs6.bcs.vector(MarketStruct),
811
897
  ...PaginationStruct
812
898
  });
813
- var BaseLiquidityInfoStruct = import_bcs5.bcs.struct("BaseLiquidityInfo", {
814
- denom: import_bcs5.bcs.string(),
815
- amount: import_bcs5.bcs.u64()
899
+ var BaseLiquidityInfoStruct = import_bcs6.bcs.struct("BaseLiquidityInfo", {
900
+ denom: import_bcs6.bcs.string(),
901
+ amount: import_bcs6.bcs.u64()
816
902
  });
817
- var BaseLiquidityResponseStruct = import_bcs5.bcs.struct("BaseLiquidityResponse", {
818
- base_assets: import_bcs5.bcs.vector(BaseLiquidityInfoStruct),
903
+ var BaseLiquidityResponseStruct = import_bcs6.bcs.struct("BaseLiquidityResponse", {
904
+ base_assets: import_bcs6.bcs.vector(BaseLiquidityInfoStruct),
819
905
  ...PaginationStruct
820
906
  });
821
907
 
822
908
  // src/types/pool.ts
823
- var import_bcs7 = require("@mysten/bcs");
824
- var GetPoolInfoResponseStruct = [
825
- import_bcs7.bcs.u64(),
826
- import_bcs7.bcs.u128(),
827
- BcsAddressType,
828
- import_bcs7.bcs.bool()
829
- ];
830
- var GetFeesResponseStruct = [import_bcs7.bcs.u64(), import_bcs7.bcs.u64(), import_bcs7.bcs.u64()];
909
+ var import_bcs8 = require("@mysten/bcs");
910
+ var PoolInfoStruct = import_bcs8.bcs.struct("PoolInfo", {
911
+ base_liquidity: import_bcs8.bcs.u64(),
912
+ total_lp_shares: import_bcs8.bcs.u64(),
913
+ admin: BcsAddressType,
914
+ is_paused: import_bcs8.bcs.bool()
915
+ });
916
+ var PoolFeesInfoStruct = import_bcs8.bcs.struct("PoolFeesInfo", {
917
+ swap_fee_pct: import_bcs8.bcs.u64(),
918
+ lp_withdrawal_fee_pct: import_bcs8.bcs.u64(),
919
+ lp_fee_pct: import_bcs8.bcs.u64()
920
+ });
921
+ var ProtocolFeesInfoStruct = import_bcs8.bcs.struct("ProtocolFeesInfo", {
922
+ bolt_fee_addr: BcsAddressType,
923
+ swap_fee_pct: import_bcs8.bcs.u64(),
924
+ lp_withdrawal_fee_pct: import_bcs8.bcs.u64()
925
+ });
831
926
 
832
927
  // src/lib/oracle/get-asset-pairs.ts
833
928
  var getAssetPairs = async (client) => {
834
- const ASSET_PAIRS_PAGINATED_FUNCTION = "asset_pairs_paginated";
835
- const result = [];
836
- let currentCursor = null;
837
- let hasNextPage = true;
838
- while (hasNextPage) {
839
- const response = await queryDevInspect(
840
- client.suiClient,
841
- [client.packageId, PRICE_ORACLE_MODULE, ASSET_PAIRS_PAGINATED_FUNCTION],
842
- [
843
- client.contracts.oracle,
844
- import_bcs9.bcs.option(import_bcs9.bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
845
- import_bcs9.bcs.option(import_bcs9.bcs.string()).serialize(currentCursor)
846
- ]
847
- );
848
- const output = parseDevInspectResult(response, AssetPairsResponsePaginatedStruct);
849
- const assetPairs = parseAssetPairsResponsePaginatedStructOutput(output);
850
- result.push(...assetPairs);
851
- currentCursor = output.next_cursor;
852
- hasNextPage = output.has_next_page;
853
- }
854
- return result;
929
+ const ASSET_PAIRS_FUNCTION = "asset_pairs";
930
+ const response = await queryDevInspect(
931
+ client.suiClient,
932
+ [client.packageId, PRICE_ORACLE_MODULE, ASSET_PAIRS_FUNCTION],
933
+ [client.contracts.oracle]
934
+ );
935
+ const output = parseDevInspectResult(response, AssetPairsResponseStruct);
936
+ return parseAssetPairsResponseStructOutput(output);
855
937
  };
856
938
 
857
939
  // src/lib/oracle/get-assets.ts
940
+ var import_utils6 = require("@mysten/sui/utils");
858
941
  var getAssets = async (client) => {
859
942
  const assetPairs = await client.getAllOracleAssetPairs();
860
943
  const uniqueOracleAssets = {};
861
944
  for (const item of assetPairs) {
862
- uniqueOracleAssets[item.base.symbol] = item.base;
863
- uniqueOracleAssets[item.quote.symbol] = item.quote;
945
+ uniqueOracleAssets[(0, import_utils6.normalizeStructTag)(item.base.symbol)] = {
946
+ ...item.base,
947
+ symbol: (0, import_utils6.normalizeStructTag)(item.base.symbol)
948
+ };
949
+ uniqueOracleAssets[(0, import_utils6.normalizeStructTag)(item.quote.symbol)] = {
950
+ ...item.quote,
951
+ symbol: (0, import_utils6.normalizeStructTag)(item.quote.symbol)
952
+ };
864
953
  }
865
954
  return Object.values(uniqueOracleAssets).map(
866
955
  (item) => client.assetsConfig[item.symbol] ?? // Fallback to minimal asset data from oracle
@@ -868,7 +957,7 @@ var getAssets = async (client) => {
868
957
  symbol: item.name,
869
958
  name: item.name,
870
959
  chainId: client.chainConfig.id,
871
- denom: item.symbol,
960
+ denom: (0, import_utils6.normalizeStructTag)(item.symbol),
872
961
  decimals: item.precision,
873
962
  logo: void 0,
874
963
  coingeckoId: void 0
@@ -889,316 +978,233 @@ var getOracleConfig = async (client) => {
889
978
  };
890
979
 
891
980
  // src/lib/oracle/get-price.ts
892
- var import_bcs10 = require("@mysten/bcs");
893
- var import_utils5 = require("@mysten/sui/utils");
894
981
  var getPrice = async (client, baseDenom, quoteDenom) => {
895
982
  const GET_PRICE_FUNCTION = "get_price";
896
983
  const response = await queryDevInspect(
897
984
  client.suiClient,
898
985
  [client.packageId, PRICE_ORACLE_MODULE, GET_PRICE_FUNCTION],
899
- [
900
- client.contracts.oracle,
901
- import_bcs10.bcs.string().serialize(baseDenom),
902
- import_bcs10.bcs.string().serialize(quoteDenom),
903
- import_utils5.SUI_CLOCK_OBJECT_ID
904
- ]
986
+ [client.contracts.oracle],
987
+ [baseDenom, quoteDenom]
905
988
  );
906
989
  const output = parseDevInspectResult(response, PriceResponseStruct);
907
- return parsePriceResponseStructOutput(output);
990
+ return parsePriceResponseStructOutput(output, baseDenom, quoteDenom);
908
991
  };
909
992
 
910
993
  // src/lib/oracle/get-prices.ts
911
- var import_bcs11 = require("@mysten/bcs");
994
+ var import_core6 = require("@bolt-liquidity-hq/core");
995
+ var import_utils7 = require("@mysten/sui/utils");
912
996
  var getPrices = async (client) => {
913
- const GET_PRICES_PAGINATED_FUNCTION = "get_prices_paginated";
914
- const result = [];
915
- let currentCursor = null;
916
- let hasNextPage = true;
917
- while (hasNextPage) {
918
- const response = await queryDevInspect(
919
- client.suiClient,
920
- [client.packageId, PRICE_ORACLE_MODULE, GET_PRICES_PAGINATED_FUNCTION],
921
- [
922
- client.contracts.oracle,
923
- import_bcs11.bcs.option(import_bcs11.bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
924
- import_bcs11.bcs.option(import_bcs11.bcs.string()).serialize(currentCursor)
925
- ]
997
+ const oracleObject = await client.suiClient.getObject({
998
+ id: client.contracts.oracle,
999
+ options: { showContent: true }
1000
+ });
1001
+ if (!oracleObject.data?.content || oracleObject.data.content.dataType !== "moveObject") {
1002
+ throw new import_core6.NotFoundError("Oracle object");
1003
+ }
1004
+ const pricesTableId = oracleObject.data.content.fields?.prices?.fields?.id?.id;
1005
+ if (!pricesTableId) {
1006
+ throw new import_core6.NotFoundError("Prices table in the Oracle contract");
1007
+ }
1008
+ const prices = [];
1009
+ let cursor = null;
1010
+ while (true) {
1011
+ const dynamicFields = await client.suiClient.getDynamicFields({
1012
+ parentId: pricesTableId,
1013
+ cursor,
1014
+ limit: 50
1015
+ // Max limit per request
1016
+ });
1017
+ const fieldPromises = dynamicFields.data.map(
1018
+ (field) => client.suiClient.getDynamicFieldObject({
1019
+ parentId: pricesTableId,
1020
+ name: field.name
1021
+ })
926
1022
  );
927
- const output = parseDevInspectResult(response, PricesResponsePaginatedStruct);
928
- const assetPairs = parsePricesResponsePaginatedStructOutput(output);
929
- result.push(...assetPairs);
930
- currentCursor = output.next_cursor;
931
- hasNextPage = output.has_next_page;
1023
+ const fieldObjects = await Promise.all(fieldPromises);
1024
+ fieldObjects.forEach((obj, index) => {
1025
+ if (obj.data?.content?.dataType === "moveObject") {
1026
+ const fields = obj.data.content.fields?.value?.fields?.price?.fields;
1027
+ const pairKey = dynamicFields.data[index]?.name?.value;
1028
+ if (fields && pairKey) {
1029
+ prices.push({
1030
+ baseDenom: (0, import_utils7.normalizeStructTag)(pairKey.base.name),
1031
+ quoteDenom: (0, import_utils7.normalizeStructTag)(pairKey.quote.name),
1032
+ price: fields.price,
1033
+ expiryTime: fields.expiry
1034
+ });
1035
+ }
1036
+ }
1037
+ });
1038
+ if (!dynamicFields.hasNextPage) break;
1039
+ cursor = dynamicFields.nextCursor;
932
1040
  }
933
- return result;
1041
+ return prices;
934
1042
  };
935
1043
 
936
1044
  // src/lib/router/estimate-swap-exact-in-gas-fees.ts
937
- var import_core6 = require("@bolt-liquidity-hq/core");
938
- var import_bcs12 = require("@mysten/bcs");
939
- var import_transactions3 = require("@mysten/sui/transactions");
940
- var import_utils6 = require("@mysten/sui/utils");
941
- var estimateSwapExactInGasFees = async (client, { assetIn, amountIn, assetOut, minimumAmountOut, receiver }, signer, gasAdjustment = import_core6.DEFAULT_GAS_ADJUSTMENT) => {
942
- const SWAP_EXACT_IN_FUNCTION = "swap_exact_in";
943
- const finalSigner = client.getSigner(signer);
944
- const tx = new import_transactions3.Transaction();
945
- const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());
946
- const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);
1045
+ var import_core7 = require("@bolt-liquidity-hq/core");
1046
+ var estimateSwapExactInGasFees = async (client, swapParams, signer, gasAdjustment = import_core7.DEFAULT_GAS_ADJUSTMENT) => {
1047
+ const swapArgs = await buildSwapTxArgs(client, swapParams, signer);
947
1048
  return await estimateTxGasPrice(
948
1049
  client.suiClient,
949
- [client.packageId, ROUTER_MODULE, SWAP_EXACT_IN_FUNCTION],
950
- [
951
- client.contracts.router,
952
- import_bcs12.bcs.string().serialize(assetOut),
953
- "",
954
- // TODO: pass correct pool when router can actually route to the pools depending on other arguments
955
- import_bcs12.bcs.string().serialize(assetIn),
956
- import_bcs12.bcs.option(import_bcs12.bcs.string()).serialize(minimumAmountOut),
957
- import_bcs12.bcs.option(import_bcs12.bcs.string()).serialize(receiver),
958
- coinInput,
959
- import_utils6.SUI_CLOCK_OBJECT_ID
960
- ],
961
- [assetIn, assetOut],
962
- tx,
1050
+ swapArgs.signerAddress,
1051
+ swapArgs.target,
1052
+ swapArgs.args,
1053
+ swapArgs.typeArguments,
1054
+ swapArgs.tx,
963
1055
  gasAdjustment
964
1056
  );
965
1057
  };
966
1058
 
967
1059
  // src/lib/router/get-all-base-liquidity.ts
968
- var import_bcs13 = require("@mysten/bcs");
969
-
970
- // src/lib/router/parsers.ts
971
- var import_core7 = require("@bolt-liquidity-hq/core");
972
- var parseMarketStructOutput = (output) => {
973
- return {
974
- poolAddress: output.market_address,
975
- baseDenom: output.base_asset_symbol,
976
- quoteDenoms: output.quote_assets_symbols
977
- };
978
- };
979
- var parseMarketResponseStructOutput = (output) => {
980
- if (!output.market) {
981
- throw new import_core7.NotFoundError("Market", void 0, { output });
982
- }
983
- return parseMarketStructOutput(output.market);
984
- };
985
- var parseMarketsResponsePaginatedStructOutput = (output) => {
986
- return output.markets.map((item) => parseMarketStructOutput(item));
987
- };
988
- var parseRouterConfigStructOutput = (output) => {
989
- return {
990
- admin: output.admin,
991
- defaultPriceOracleContract: output.default_price_oracle_contract,
992
- defaultProtocolFeeRecipient: output.default_protocol_fee_recipient,
993
- defaultProtocolFee: output.default_protocol_fee,
994
- defaultLpFee: output.default_lp_fee
995
- };
1060
+ var import_core8 = require("@bolt-liquidity-hq/core");
1061
+ var getAllBaseLiquidity = async (_client) => {
1062
+ throw new import_core8.NotImplementedError("getRouterConfig on Sui Client");
996
1063
  };
997
- var parseBaseLiquidityResponseStructOutput = (output) => {
998
- return output.base_assets.map((item) => ({
999
- baseLiquidity: {
1000
- denom: item.denom,
1001
- amount: item.amount
1002
- },
1003
- totalShares: ""
1004
- // TODO: add real total shares if it is returned by the smart contract later
1005
- }));
1064
+
1065
+ // src/lib/router/get-all-quotes-for-user.ts
1066
+ var import_core9 = require("@bolt-liquidity-hq/core");
1067
+ var getAllQuotesForUser = async (_client, _lpAddress) => {
1068
+ throw new import_core9.NotImplementedError("getRouterConfig on Sui Client");
1006
1069
  };
1007
1070
 
1008
- // src/lib/router/get-all-base-liquidity.ts
1009
- var getAllBaseLiquidity = async (client) => {
1010
- const BASE_LIQUIDITY_ALL_PAGINATED_FUNCTION = "base_liquidity_all_paginated";
1011
- const result = {};
1012
- let currentCursor = null;
1013
- let hasNextPage = true;
1014
- while (hasNextPage) {
1015
- const response = await queryDevInspect(
1016
- client.suiClient,
1017
- [client.packageId, ROUTER_MODULE, BASE_LIQUIDITY_ALL_PAGINATED_FUNCTION],
1018
- [
1019
- client.contracts.router,
1020
- import_bcs13.bcs.option(import_bcs13.bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
1021
- import_bcs13.bcs.option(import_bcs13.bcs.string()).serialize(currentCursor)
1022
- ]
1023
- );
1024
- const output = parseDevInspectResult(response, BaseLiquidityResponseStruct);
1025
- const baseLiquidities = parseBaseLiquidityResponseStructOutput(output);
1026
- for (const item of baseLiquidities) {
1027
- result[item.baseLiquidity.denom] = item;
1028
- }
1029
- currentCursor = output.next_cursor;
1030
- hasNextPage = output.has_next_page;
1071
+ // src/lib/router/get-pool-by-denom.ts
1072
+ var import_core10 = require("@bolt-liquidity-hq/core");
1073
+ var getPoolByDenom = async (client, baseDenom, quoteDenom) => {
1074
+ const result = await client.routerClient.getPool(quoteDenom, baseDenom);
1075
+ if (!result) {
1076
+ throw new import_core10.NotFoundError("Pool", `Didn't find a pool to swap ${quoteDenom} for ${baseDenom}`);
1031
1077
  }
1032
1078
  return result;
1033
1079
  };
1034
1080
 
1035
- // src/lib/router/get-all-quotes-for-user.ts
1036
- var import_bcs14 = require("@mysten/bcs");
1037
- var getAllQuotesForUser = async (client, lpAddress) => {
1038
- const QUOTES_FOR_USER_ALL_FUNCTION = "quotes_for_user_all";
1039
- const response = await queryDevInspect(
1040
- client.suiClient,
1041
- [client.packageId, ROUTER_MODULE, QUOTES_FOR_USER_ALL_FUNCTION],
1042
- [client.contracts.router, import_bcs14.bcs.string().serialize(lpAddress)]
1043
- );
1044
- console.log(response);
1045
- return {};
1081
+ // src/lib/router/get-pools.ts
1082
+ var getPools = async (client) => {
1083
+ return await client.routerClient.getPools();
1046
1084
  };
1047
1085
 
1048
- // src/lib/router/get-pool-for-base.ts
1049
- var import_bcs15 = require("@mysten/bcs");
1050
- var getPoolForBase = async (client, baseDenom) => {
1051
- const MARKET_FOR_BASE_FUNCTION = "market_for_base";
1052
- const response = await queryDevInspect(
1053
- client.suiClient,
1054
- [client.packageId, ROUTER_MODULE, MARKET_FOR_BASE_FUNCTION],
1055
- [client.contracts.router, import_bcs15.bcs.string().serialize(baseDenom)]
1056
- );
1057
- const output = parseDevInspectResult(response, MarketResponseStruct);
1058
- return parseMarketResponseStructOutput(output);
1086
+ // src/lib/router/get-router-config.ts
1087
+ var import_core11 = require("@bolt-liquidity-hq/core");
1088
+ var getRouterConfig = async (_client) => {
1089
+ throw new import_core11.NotImplementedError("getRouterConfig on Sui Client");
1059
1090
  };
1060
1091
 
1061
- // src/lib/router/get-pools.ts
1062
- var import_bcs16 = require("@mysten/bcs");
1063
- var getPools = async (client) => {
1064
- const MARKETS_PAGINATED_FUNCTION = "markets_paginated";
1065
- const result = [];
1066
- let currentCursor = null;
1067
- let hasNextPage = true;
1068
- while (hasNextPage) {
1069
- const response = await queryDevInspect(
1070
- client.suiClient,
1071
- [client.packageId, ROUTER_MODULE, MARKETS_PAGINATED_FUNCTION],
1072
- [
1073
- client.contracts.router,
1074
- import_bcs16.bcs.option(import_bcs16.bcs.u64()).serialize(DEFAULT_PAGINATION_LIMIT),
1075
- import_bcs16.bcs.option(import_bcs16.bcs.string()).serialize(currentCursor)
1076
- ]
1092
+ // src/lib/router/router-client/RouterClient.ts
1093
+ var import_utils8 = require("@mysten/sui/utils");
1094
+ var RouterClient = class {
1095
+ constructor(pools) {
1096
+ this.pools = pools;
1097
+ }
1098
+ getPool(denomIn, denomOut) {
1099
+ const normalizedDenomIn = (0, import_utils8.normalizeStructTag)(denomIn);
1100
+ const normalizedDenomOut = (0, import_utils8.normalizeStructTag)(denomOut);
1101
+ const directPairPool = this.pools.find(
1102
+ (item) => item.baseDenom === normalizedDenomOut && item.quoteDenoms.includes(normalizedDenomIn)
1103
+ );
1104
+ if (directPairPool) {
1105
+ return directPairPool;
1106
+ }
1107
+ const inversePairPool = this.pools.find(
1108
+ (item) => item.baseDenom === normalizedDenomIn && item.quoteDenoms.includes(normalizedDenomOut)
1077
1109
  );
1078
- const output = parseDevInspectResult(response, MarketsResponsePaginatedStruct);
1079
- const pools = parseMarketsResponsePaginatedStructOutput(output);
1080
- result.push(...pools);
1081
- currentCursor = output.next_cursor;
1082
- hasNextPage = output.has_next_page;
1110
+ if (inversePairPool) {
1111
+ return inversePairPool;
1112
+ }
1113
+ return;
1114
+ }
1115
+ getPools() {
1116
+ return this.pools;
1083
1117
  }
1084
- return result;
1085
- };
1086
-
1087
- // src/lib/router/get-router-config.ts
1088
- var getRouterConfig = async (client) => {
1089
- const CONFIG_FUNCTION = "config";
1090
- const response = await queryDevInspect(
1091
- client.suiClient,
1092
- [client.packageId, ROUTER_MODULE, CONFIG_FUNCTION],
1093
- [client.contracts.router]
1094
- );
1095
- const output = parseDevInspectResult(response, RouterConfigStruct);
1096
- return parseRouterConfigStructOutput(output);
1097
1118
  };
1098
1119
 
1099
1120
  // src/lib/router/swap-exact-in.ts
1100
- var import_bcs17 = require("@mysten/bcs");
1101
- var import_transactions4 = require("@mysten/sui/transactions");
1102
- var import_utils7 = require("@mysten/sui/utils");
1103
- var swapExactIn = async (client, { assetIn, amountIn, assetOut, minimumAmountOut, receiver }, signer) => {
1104
- const SWAP_EXACT_IN_FUNCTION = "swap_exact_in";
1105
- const finalSigner = client.getSigner(signer);
1106
- const tx = new import_transactions4.Transaction();
1107
- const coinManager = new CoinManager(client.suiClient, finalSigner.toSuiAddress());
1108
- const coinInput = await coinManager.prepareCoinInput(tx, assetIn, amountIn);
1121
+ var swapExactIn = async (client, swapParams, signer) => {
1122
+ const swapArgs = await buildSwapTxArgs(client, swapParams, signer);
1109
1123
  const txOutput = await signAndExecuteTx(
1110
1124
  client.suiClient,
1111
- finalSigner,
1112
- [client.packageId, ROUTER_MODULE, SWAP_EXACT_IN_FUNCTION],
1113
- [
1114
- client.contracts.router,
1115
- import_bcs17.bcs.string().serialize(assetOut),
1116
- "",
1117
- // TODO: pass correct pool when router can actually route to the pools depending on other arguments
1118
- import_bcs17.bcs.string().serialize(assetIn),
1119
- import_bcs17.bcs.option(import_bcs17.bcs.string()).serialize(minimumAmountOut),
1120
- import_bcs17.bcs.option(import_bcs17.bcs.string()).serialize(receiver),
1121
- coinInput,
1122
- import_utils7.SUI_CLOCK_OBJECT_ID
1123
- ],
1124
- [assetIn, assetOut],
1125
- tx,
1125
+ swapArgs.signer,
1126
+ swapArgs.target,
1127
+ swapArgs.args,
1128
+ swapArgs.typeArguments,
1129
+ swapArgs.tx,
1126
1130
  { showEffects: true, showEvents: true, showBalanceChanges: true }
1127
1131
  );
1128
1132
  return {
1129
1133
  txOutput,
1130
1134
  txHash: txOutput.digest,
1131
- amountOut: "",
1132
- // TODO: implement when contract emits event
1133
- assetOut
1135
+ amountOut: txOutput.events?.at(0)?.parsedJson?.["amount_out"] ?? "0",
1136
+ assetOut: swapParams.assetOut
1134
1137
  };
1135
1138
  };
1136
1139
 
1137
1140
  // src/lib/settlement/get-pool-info.ts
1138
- var import_utils8 = require("@mysten/sui/utils");
1141
+ var import_core12 = require("@bolt-liquidity-hq/core");
1139
1142
 
1140
1143
  // src/lib/settlement/parsers.ts
1141
- var parseSettlementConfigStructOutput = (globalConfig, feesOutput) => {
1144
+ var import_bignumber3 = require("bignumber.js");
1145
+ var parseSettlementConfigStructOutput = (routerClient, poolFeesInfo, protocolFeesInfo, priceOracleContract) => {
1142
1146
  return {
1143
- priceOracleContract: "0x",
1144
- // Should come from pool config
1145
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
1146
- protocolFeeRecipient: globalConfig.data?.content?.fields.protocol_fee_recipient || "",
1147
- protocolFee: feesOutput[0],
1148
- // Protocol fee percentage
1149
- lpFee: feesOutput[2],
1150
- // LP fee percentage
1147
+ priceOracleContract,
1148
+ protocolFeeRecipient: protocolFeesInfo.bolt_fee_addr,
1149
+ protocolFee: (0, import_bignumber3.BigNumber)(poolFeesInfo.swap_fee_pct).div(100).toFixed(),
1150
+ lpFee: (0, import_bignumber3.BigNumber)(poolFeesInfo.lp_fee_pct).div(100).toFixed(),
1151
1151
  allowanceMode: "allow",
1152
1152
  // Should come from pool config
1153
- lps: ["0x"],
1154
- // Should come from pool config
1155
- minBaseOut: "1"
1156
- // Should come from pool config
1153
+ lps: routerClient.getPools().map((item) => item.poolAddress),
1154
+ minBaseOut: "0"
1155
+ // Should come from pool config
1157
1156
  };
1158
1157
  };
1159
1158
 
1160
1159
  // src/lib/settlement/get-pool-info.ts
1161
1160
  var getPoolInfo = async (client, contractAddress) => {
1162
- const GET_FEES_FUNCTION = "get_fees";
1163
- const [globalConfig, fees] = await Promise.all([
1164
- // Fetch the global pool configuration object
1165
- client.suiClient.getObject({
1166
- id: client.poolGlobalConfigId,
1167
- options: {
1168
- showContent: true,
1169
- showType: true
1170
- }
1171
- }),
1172
- // Query pool-specific fee structure
1161
+ const GET_POOL_FEES_INFO_FUNCTION = "get_pool_fees_info";
1162
+ const GET_PROTOCOL_FEES_INFO_FUNCTION = "get_protocol_fees_info";
1163
+ const pool = client.routerClient.pools.find((item) => item.poolAddress === contractAddress);
1164
+ if (!pool) {
1165
+ throw new import_core12.NotFoundError(`Pool with the address ${contractAddress}`);
1166
+ }
1167
+ const [poolFeesInfo, protocolFeesInfo] = await Promise.all([
1168
+ // Query pool fee information
1169
+ queryDevInspect(
1170
+ client.suiClient,
1171
+ [client.packageId, POOL_MODULE, GET_POOL_FEES_INFO_FUNCTION],
1172
+ [contractAddress],
1173
+ [pool.baseDenom]
1174
+ ),
1175
+ // Query protocol fee information
1173
1176
  queryDevInspect(
1174
1177
  client.suiClient,
1175
- [client.packageId, POOL_MODULE, GET_FEES_FUNCTION],
1178
+ [client.packageId, POOL_MODULE, GET_PROTOCOL_FEES_INFO_FUNCTION],
1176
1179
  [contractAddress],
1177
- // TODO: get the base token of the pool to pass it here instead of hardcoded SUI token
1178
- [import_utils8.SUI_TYPE_ARG]
1180
+ [pool.baseDenom]
1179
1181
  )
1180
1182
  ]);
1181
- const feesOutput = parseMultipleResults(fees, GetFeesResponseStruct);
1182
- return parseSettlementConfigStructOutput(globalConfig, feesOutput);
1183
+ const poolFeesInfoOutput = parseDevInspectResult(poolFeesInfo, PoolFeesInfoStruct);
1184
+ const protocolFeesInfoOutput = parseDevInspectResult(protocolFeesInfo, ProtocolFeesInfoStruct);
1185
+ return parseSettlementConfigStructOutput(
1186
+ client.routerClient,
1187
+ poolFeesInfoOutput,
1188
+ protocolFeesInfoOutput,
1189
+ client.contracts.oracle
1190
+ );
1183
1191
  };
1184
1192
 
1185
- // src/tests/constants/sui-objects.ts
1186
- var TEST_POOL = "0xdd05c1caea7b6725da3f67e30e99872033fc5d3a610a4f72ac1c434bc81c3c0d";
1187
-
1188
- // src/lib/settlement/get-pool-info-for-base.ts
1189
- var getPoolInfoForBase = async (client, baseDenom) => {
1190
- const pool = await getPoolForBase(client, baseDenom && "SUI");
1191
- return await getPoolInfo(client, pool.poolAddress || TEST_POOL);
1193
+ // src/lib/settlement/get-pool-info-by-denom.ts
1194
+ var getPoolInfoByDenom = async (client, baseDenom, quoteDenom) => {
1195
+ const pool = await getPoolByDenom(client, baseDenom, quoteDenom);
1196
+ return await getPoolInfo(client, pool.poolAddress);
1192
1197
  };
1193
1198
 
1194
1199
  // src/lib/client.ts
1195
- var BoltSuiClient = class extends import_core8.BaseClient {
1200
+ var BoltSuiClient = class extends import_core13.BaseClient {
1196
1201
  /**
1197
1202
  * Creates a new instance of the BoltSuiClient.
1198
1203
  *
1199
1204
  * The client automatically configures itself based on the specified environment,
1200
1205
  * loading the appropriate contract addresses, chain configuration, native token denomination,
1201
- * and assets from configuration files.
1206
+ * and assets from configuration files. For testnet environments, the client can dynamically
1207
+ * fetch configuration from a remote URL.
1202
1208
  *
1203
1209
  * @param config - (Optional) Configuration for the client
1204
1210
  * @param config.environment - (Optional) The deployment environment ('mainnet' or 'testnet'). Defaults to 'mainnet'
@@ -1224,7 +1230,7 @@ var BoltSuiClient = class extends import_core8.BaseClient {
1224
1230
  * // Use default configuration (Sui mainnet)
1225
1231
  * const client = new BoltSuiClient();
1226
1232
  *
1227
- * // Use testnet configuration
1233
+ * // Use testnet configuration (will fetch config dynamically)
1228
1234
  * const testnetClient = new BoltSuiClient({
1229
1235
  * environment: 'testnet'
1230
1236
  * });
@@ -1267,12 +1273,14 @@ var BoltSuiClient = class extends import_core8.BaseClient {
1267
1273
  */
1268
1274
  constructor(config) {
1269
1275
  const { environment = "mainnet", customOverride, signer, suiClient } = config ?? {};
1270
- const defaultChainConfig = environment === "mainnet" ? MainnetChainConfig : TestnetChainConfig;
1271
- const defaultContracts = environment === "mainnet" ? MainnetContracts : TestnetContracts;
1272
- const defaultPackageId = environment === "mainnet" ? MainnetPackageId : TestnetPackageId;
1273
- const defaultPoolGlobalConfigId = environment === "mainnet" ? MainnetPoolGlobalConfigId : TestnetPoolGlobalConfigId;
1274
- const defaultNativeTokenDenom = environment === "mainnet" ? MainnetNativeTokenDenom : TestnetNativeTokenDenom;
1275
- const assetsConfig = environment === "mainnet" ? MainnetAssets : TestnetAssets;
1276
+ const isEnvironmentMainnet = environment === "mainnet";
1277
+ const defaultChainConfig = isEnvironmentMainnet ? MainnetChainConfig : TestnetChainConfig;
1278
+ const defaultContracts = isEnvironmentMainnet ? MainnetContracts : TestnetContracts;
1279
+ const defaultPackageId = isEnvironmentMainnet ? MainnetPackageId : TestnetPackageId;
1280
+ const defaultPoolGlobalConfigId = isEnvironmentMainnet ? MainnetPoolGlobalConfigId : TestnetPoolGlobalConfigId;
1281
+ const defaultNativeTokenDenom = isEnvironmentMainnet ? MainnetNativeTokenDenom : TestnetNativeTokenDenom;
1282
+ const assetsConfig = isEnvironmentMainnet ? MainnetAssets : TestnetAssets;
1283
+ const pools = isEnvironmentMainnet ? MainnetPools : [];
1276
1284
  const chainConfig = {
1277
1285
  id: customOverride?.chainConfig?.id ?? defaultChainConfig.id,
1278
1286
  name: customOverride?.chainConfig?.name ?? defaultChainConfig.name,
@@ -1310,18 +1318,30 @@ var BoltSuiClient = class extends import_core8.BaseClient {
1310
1318
  __publicField(this, "poolGlobalConfigId");
1311
1319
  /**
1312
1320
  * Cached instance of the Signer for transaction execution
1313
- * @private
1314
1321
  */
1315
1322
  __publicField(this, "signer");
1316
1323
  /**
1317
1324
  * Instance of the Sui client to interact with the blockchain
1318
1325
  */
1319
1326
  __publicField(this, "suiClient");
1327
+ /**
1328
+ * URL for fetching testnet configuration dynamically.
1329
+ * Used to load package IDs, oracle addresses, and asset configurations for testnet environments.
1330
+ * @private
1331
+ */
1332
+ __publicField(this, "configFileUrl");
1333
+ /**
1334
+ * Router client instance for managing pool configurations and routing calculations.
1335
+ * Handles pool discovery and optimal path finding for swaps.
1336
+ */
1337
+ __publicField(this, "routerClient");
1320
1338
  this.chainConfig = chainConfig;
1321
1339
  this.packageId = packageId;
1322
1340
  this.poolGlobalConfigId = poolGlobalConfigId;
1323
1341
  this.signer = signer;
1324
1342
  this.suiClient = suiClient ?? new import_client.SuiClient({ url: chainConfig.rpcEndpoint });
1343
+ this.routerClient = new RouterClient(pools);
1344
+ this.configFileUrl = isEnvironmentMainnet ? void 0 : TestnetConfigUrl;
1325
1345
  }
1326
1346
  /**
1327
1347
  * Gets or sets the signer for transaction execution.
@@ -1349,7 +1369,7 @@ var BoltSuiClient = class extends import_core8.BaseClient {
1349
1369
  getSigner(newSigner) {
1350
1370
  this.signer = newSigner ?? this.signer;
1351
1371
  if (!this.signer) {
1352
- throw new import_core8.MissingParameterError("signer");
1372
+ throw new import_core13.MissingParameterError("signer");
1353
1373
  }
1354
1374
  return this.signer;
1355
1375
  }
@@ -1357,51 +1377,81 @@ var BoltSuiClient = class extends import_core8.BaseClient {
1357
1377
  // Only add documentation here if you need to override or add implementation-specific details
1358
1378
  /** @inheritdoc */
1359
1379
  async getOracleConfig() {
1380
+ await this.loadConfigFromUrl();
1360
1381
  return await getOracleConfig(this);
1361
1382
  }
1362
1383
  /** @inheritdoc */
1363
1384
  async getAllOracleAssetPairs() {
1385
+ await this.loadConfigFromUrl();
1364
1386
  return await getAssetPairs(this);
1365
1387
  }
1366
1388
  /** @inheritdoc */
1367
1389
  async getPrice(baseDenom, quoteDenom) {
1390
+ await this.loadConfigFromUrl();
1368
1391
  return await getPrice(this, baseDenom, quoteDenom);
1369
1392
  }
1370
1393
  /** @inheritdoc */
1371
1394
  async getAllPrices() {
1395
+ await this.loadConfigFromUrl();
1372
1396
  return await getPrices(this);
1373
1397
  }
1374
1398
  /** @inheritdoc */
1375
1399
  async getRouterConfig() {
1400
+ await this.loadConfigFromUrl();
1376
1401
  return await getRouterConfig(this);
1377
1402
  }
1378
1403
  /** @inheritdoc */
1379
1404
  async getAllBaseAssetsLiquidity() {
1405
+ await this.loadConfigFromUrl();
1380
1406
  return await getAllBaseLiquidity(this);
1381
1407
  }
1382
1408
  /** @inheritdoc */
1383
1409
  async getAllQuotesByUser(address) {
1410
+ await this.loadConfigFromUrl();
1384
1411
  return await getAllQuotesForUser(this, address);
1385
1412
  }
1386
- /** @inheritdoc */
1387
- async getPoolByBaseAsset(baseDenom) {
1388
- return await getPoolForBase(this, baseDenom);
1413
+ /**
1414
+ * @inheritdoc
1415
+ *
1416
+ * @remarks
1417
+ * In the Sui implementation, both `baseDenom` and `quoteDenom` parameters are required.
1418
+ * The Sui architecture uses both asset types to uniquely identify pools for specific
1419
+ * trading pairs.
1420
+ *
1421
+ * @throws Will throw an error if no pool exists for the specified base/quote asset pair
1422
+ */
1423
+ async getPoolByDenom(baseDenom, quoteDenom) {
1424
+ await this.loadConfigFromUrl();
1425
+ return await getPoolByDenom(this, baseDenom, quoteDenom);
1389
1426
  }
1390
1427
  /** @inheritdoc */
1391
1428
  async getAllPools() {
1429
+ await this.loadConfigFromUrl();
1392
1430
  return await getPools(this);
1393
1431
  }
1394
- // Satisfy the base class requirement
1432
+ /** @inheritdoc */
1395
1433
  async getPoolConfig(poolContractAddress) {
1434
+ await this.loadConfigFromUrl();
1396
1435
  return await getPoolInfo(this, poolContractAddress);
1397
1436
  }
1398
1437
  /** @inheritdoc */
1399
1438
  async getAssets() {
1439
+ await this.loadConfigFromUrl();
1400
1440
  return await getAssets(this);
1401
1441
  }
1402
- /** @inheritdoc */
1403
- async getPoolConfigByBaseAsset(baseDenom) {
1404
- return await getPoolInfoForBase(this, baseDenom);
1442
+ /**
1443
+ * @inheritdoc
1444
+ *
1445
+ * @remarks
1446
+ * In the Sui implementation, both `baseDenom` and `quoteDenom` parameters are required.
1447
+ * The Sui architecture uses both asset types to uniquely identify pools for specific
1448
+ * trading pairs.
1449
+ *
1450
+ * @throws Will throw an error if no pool exists for the specified base/quote asset pair
1451
+ */
1452
+ async getPoolConfigByDenom(baseDenom, quoteDenom) {
1453
+ await this.loadConfigFromUrl();
1454
+ return await getPoolInfoByDenom(this, baseDenom, quoteDenom);
1405
1455
  }
1406
1456
  /**
1407
1457
  * @inheritdoc
@@ -1432,6 +1482,7 @@ var BoltSuiClient = class extends import_core8.BaseClient {
1432
1482
  * which includes details like gas costs, transaction effects, object changes, and events.
1433
1483
  */
1434
1484
  async swap(params, signer) {
1485
+ await this.loadConfigFromUrl();
1435
1486
  return await swapExactIn(this, params, signer);
1436
1487
  }
1437
1488
  /**
@@ -1463,7 +1514,66 @@ var BoltSuiClient = class extends import_core8.BaseClient {
1463
1514
  * - Sui's gas model includes computation, storage, and storage rebates
1464
1515
  */
1465
1516
  async estimateSwapGasFees(params, signer, gasAdjustment) {
1517
+ await this.loadConfigFromUrl();
1466
1518
  return await estimateSwapExactInGasFees(this, params, signer, gasAdjustment);
1467
1519
  }
1520
+ /**
1521
+ * Loads configuration from a remote URL for testnet environments.
1522
+ *
1523
+ * This method fetches and applies dynamic configuration including:
1524
+ * - Package ID for Bolt contracts
1525
+ * - Oracle contract address
1526
+ * - Pool global configuration ID
1527
+ * - Asset mappings and metadata
1528
+ * - Pool configurations
1529
+ *
1530
+ * The method is called automatically before API operations when a config URL is set.
1531
+ * After successful loading, the config URL is cleared to prevent redundant fetches.
1532
+ *
1533
+ * @private
1534
+ * @remarks
1535
+ * - Only executes if `configFileUrl` is set (typically for testnet)
1536
+ * - Updates testnet-specific asset denoms with their actual deployed addresses
1537
+ * - Populates the router client's pool configurations
1538
+ * - Normalizes struct tags for consistency
1539
+ */
1540
+ async loadConfigFromUrl() {
1541
+ if (!this.configFileUrl) {
1542
+ return;
1543
+ }
1544
+ const response = await import_axios.default.get(this.configFileUrl);
1545
+ const { package_id, oracle_id, global_config_id, assets, pools } = response.data ?? {};
1546
+ if (!this.packageId && package_id) {
1547
+ this.packageId = package_id;
1548
+ }
1549
+ if (!this.contracts.oracle.trim() && oracle_id) {
1550
+ this.contracts.oracle = oracle_id;
1551
+ }
1552
+ if (!this.poolGlobalConfigId && global_config_id) {
1553
+ this.poolGlobalConfigId = global_config_id;
1554
+ }
1555
+ for (const item of Object.values(assets)) {
1556
+ for (const suffix of TestnetHelperAssets) {
1557
+ if (item.includes(suffix) && this.assetsConfig[suffix]) {
1558
+ this.assetsConfig[item] = {
1559
+ ...this.assetsConfig[suffix],
1560
+ denom: item
1561
+ };
1562
+ delete this.assetsConfig[suffix];
1563
+ break;
1564
+ }
1565
+ }
1566
+ }
1567
+ if (this.routerClient.pools.length === 0) {
1568
+ for (const item of pools) {
1569
+ this.routerClient.pools.push({
1570
+ poolAddress: item.pool_object_id,
1571
+ baseDenom: (0, import_utils9.normalizeStructTag)(item.base),
1572
+ quoteDenoms: Object.values(assets).map((auxAsset) => (0, import_utils9.normalizeStructTag)(auxAsset)).filter((auxAsset) => auxAsset !== (0, import_utils9.normalizeStructTag)(item.base))
1573
+ });
1574
+ }
1575
+ }
1576
+ this.configFileUrl = void 0;
1577
+ }
1468
1578
  };
1469
1579
  //# sourceMappingURL=index.cjs.map