@bolt-liquidity-hq/sui-client 0.1.0-beta.12 → 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.cjs +446 -368
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +170 -64
- package/dist/index.d.ts +170 -64
- package/dist/index.js +435 -364
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
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: "
|
|
53
|
-
router: "
|
|
56
|
+
oracle: " ",
|
|
57
|
+
router: " "
|
|
54
58
|
};
|
|
55
|
-
var TestnetPackageId = "
|
|
56
|
-
var TestnetPoolGlobalConfigId = "
|
|
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 = "
|
|
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/
|
|
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
|
-
|
|
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.
|
|
655
|
-
|
|
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.
|
|
660
|
-
|
|
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
|
|
713
|
+
var parseAssetPairsResponseStructOutput = (output) => {
|
|
714
|
+
return output.map((item) => parseAssetPairStructOutput(item.info));
|
|
715
|
+
};
|
|
716
|
+
var parsePriceDataStructOutput = (output, baseDenom, quoteDenom) => {
|
|
666
717
|
return {
|
|
667
|
-
baseDenom
|
|
668
|
-
quoteDenom
|
|
669
|
-
price: output.price,
|
|
670
|
-
expiryTime: BigNumber2(output.
|
|
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
|
|
733
|
+
import { bcs as bcs3, BcsType } from "@mysten/bcs";
|
|
689
734
|
var PaginationStruct = {
|
|
690
|
-
total_count:
|
|
691
|
-
has_next_page:
|
|
692
|
-
next_cursor:
|
|
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
|
|
715
|
-
var OracleConfigStruct =
|
|
716
|
-
|
|
717
|
-
|
|
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 =
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
base_precision:
|
|
724
|
-
quote_precision:
|
|
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
|
|
727
|
-
|
|
770
|
+
var TypeNameStruct = bcs4.struct("TypeName", {
|
|
771
|
+
name: bcs4.string()
|
|
728
772
|
});
|
|
729
|
-
var
|
|
730
|
-
|
|
731
|
-
|
|
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 =
|
|
734
|
-
|
|
735
|
-
|
|
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 =
|
|
742
|
-
pair_data:
|
|
791
|
+
var PriceResponseStruct = bcs4.struct("PriceResponse", {
|
|
792
|
+
pair_data: bcs4.option(PriceDataStruct)
|
|
743
793
|
});
|
|
744
|
-
var PricesResponsePaginatedStruct =
|
|
745
|
-
prices:
|
|
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
|
|
751
|
-
var RouterConfigStruct =
|
|
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:
|
|
756
|
-
default_lp_fee:
|
|
805
|
+
default_protocol_fee: bcs5.u64(),
|
|
806
|
+
default_lp_fee: bcs5.u64()
|
|
757
807
|
});
|
|
758
|
-
var MarketStruct =
|
|
759
|
-
base_asset_symbol:
|
|
760
|
-
quote_assets_symbols:
|
|
761
|
-
market_address:
|
|
762
|
-
is_permissioned:
|
|
763
|
-
created_at_ms:
|
|
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 =
|
|
766
|
-
market:
|
|
815
|
+
var MarketResponseStruct = bcs5.struct("MarketResponse", {
|
|
816
|
+
market: bcs5.option(MarketStruct)
|
|
767
817
|
});
|
|
768
|
-
var MarketsResponseStruct =
|
|
769
|
-
markets:
|
|
818
|
+
var MarketsResponseStruct = bcs5.struct("MarketsResponse", {
|
|
819
|
+
markets: bcs5.vector(MarketStruct)
|
|
770
820
|
});
|
|
771
|
-
var MarketsResponsePaginatedStruct =
|
|
772
|
-
markets:
|
|
821
|
+
var MarketsResponsePaginatedStruct = bcs5.struct("MarketsResponsePaginated", {
|
|
822
|
+
markets: bcs5.vector(MarketStruct),
|
|
773
823
|
...PaginationStruct
|
|
774
824
|
});
|
|
775
|
-
var BaseLiquidityInfoStruct =
|
|
776
|
-
denom:
|
|
777
|
-
amount:
|
|
825
|
+
var BaseLiquidityInfoStruct = bcs5.struct("BaseLiquidityInfo", {
|
|
826
|
+
denom: bcs5.string(),
|
|
827
|
+
amount: bcs5.u64()
|
|
778
828
|
});
|
|
779
|
-
var BaseLiquidityResponseStruct =
|
|
780
|
-
base_assets:
|
|
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
|
|
786
|
-
var
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
BcsAddressType,
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
var
|
|
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
|
|
797
|
-
const
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
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
|
-
|
|
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
|
-
return parsePriceResponseStructOutput(output);
|
|
910
|
+
return parsePriceResponseStructOutput(output, baseDenom, quoteDenom);
|
|
870
911
|
};
|
|
871
912
|
|
|
872
913
|
// src/lib/oracle/get-prices.ts
|
|
873
|
-
import {
|
|
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
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
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
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
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
|
|
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
|
-
|
|
901
|
-
|
|
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
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
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 {
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
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
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
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-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
const result =
|
|
974
|
-
|
|
975
|
-
|
|
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-
|
|
998
|
-
|
|
999
|
-
|
|
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-
|
|
1011
|
-
import {
|
|
1012
|
-
var
|
|
1013
|
-
|
|
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/
|
|
1024
|
-
import {
|
|
1025
|
-
var
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
const
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
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
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
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
|
-
|
|
1063
|
-
|
|
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
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
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
|
-
|
|
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 = (
|
|
1066
|
+
var parseSettlementConfigStructOutput = (routerClient, poolFeesInfo, protocolFeesInfo, priceOracleContract) => {
|
|
1104
1067
|
return {
|
|
1105
|
-
priceOracleContract
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
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:
|
|
1116
|
-
|
|
1117
|
-
|
|
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
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
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,
|
|
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
|
|
1144
|
-
|
|
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/
|
|
1148
|
-
var
|
|
1149
|
-
|
|
1150
|
-
|
|
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
|
|
1233
|
-
const
|
|
1234
|
-
const
|
|
1235
|
-
const
|
|
1236
|
-
const
|
|
1237
|
-
const
|
|
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
|
-
/**
|
|
1349
|
-
|
|
1350
|
-
|
|
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
|
-
|
|
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
|
-
/**
|
|
1365
|
-
|
|
1366
|
-
|
|
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
|
-
|
|
1517
|
+
ProtocolFeesInfoStruct,
|
|
1518
|
+
RawPairStruct,
|
|
1519
|
+
RawPriceStruct,
|
|
1520
|
+
RouterConfigStruct,
|
|
1521
|
+
TypeNameStruct
|
|
1451
1522
|
};
|
|
1452
1523
|
//# sourceMappingURL=index.js.map
|