@t2000/sdk 2.13.2 → 2.14.1
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/adapters/index.cjs +12 -29
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +13 -30
- package/dist/adapters/index.js.map +1 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +148 -235
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -80
- package/dist/index.d.ts +74 -80
- package/dist/index.js +149 -236
- package/dist/index.js.map +1 -1
- package/dist/{types-WeZQDV54.d.ts → types-BMdhu0D7.d.ts} +1 -1
- package/dist/{types-BY6ovQGK.d.cts → types-C2Va_r0h.d.cts} +1 -1
- package/dist/{types-epj9U13o.d.cts → types-I7U99DvG.d.cts} +38 -13
- package/dist/{types-epj9U13o.d.ts → types-I7U99DvG.d.ts} +38 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Transaction } from '@mysten/sui/transactions';
|
|
1
|
+
import { Transaction, coinWithBalance } from '@mysten/sui/transactions';
|
|
2
2
|
import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
|
|
3
3
|
import BN from 'bn.js';
|
|
4
4
|
import { EventEmitter } from 'eventemitter3';
|
|
@@ -695,22 +695,18 @@ async function buildStakeVSuiTx(_client, address, amountMist) {
|
|
|
695
695
|
return tx;
|
|
696
696
|
}
|
|
697
697
|
async function buildUnstakeVSuiTx(client, address, amountMist) {
|
|
698
|
-
const
|
|
699
|
-
|
|
698
|
+
const balResp = await client.getBalance({ owner: address, coinType: VSUI_TYPE });
|
|
699
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
700
|
+
if (totalBalance === 0n) {
|
|
700
701
|
throw new Error("No vSUI found in wallet.");
|
|
701
702
|
}
|
|
702
703
|
const tx = new Transaction();
|
|
703
704
|
tx.setSender(address);
|
|
704
|
-
const
|
|
705
|
-
if (
|
|
706
|
-
|
|
707
|
-
}
|
|
708
|
-
let vSuiCoin;
|
|
709
|
-
if (amountMist === "all") {
|
|
710
|
-
vSuiCoin = primary;
|
|
711
|
-
} else {
|
|
712
|
-
[vSuiCoin] = tx.splitCoins(primary, [amountMist]);
|
|
705
|
+
const requested = amountMist === "all" ? totalBalance : amountMist;
|
|
706
|
+
if (requested > totalBalance) {
|
|
707
|
+
throw new Error(`Insufficient vSUI: need ${requested} MIST, have ${totalBalance}`);
|
|
713
708
|
}
|
|
709
|
+
const vSuiCoin = coinWithBalance({ type: VSUI_TYPE, balance: requested })(tx);
|
|
714
710
|
const [suiCoin] = tx.moveCall({
|
|
715
711
|
target: `${VOLO_PKG}::stake_pool::unstake`,
|
|
716
712
|
arguments: [
|
|
@@ -731,19 +727,16 @@ async function addStakeVSuiToTx(tx, client, address, input) {
|
|
|
731
727
|
if (input.inputCoin) {
|
|
732
728
|
suiCoin = input.inputCoin;
|
|
733
729
|
} else {
|
|
734
|
-
const
|
|
735
|
-
|
|
736
|
-
throw new Error("No SUI coins found in wallet");
|
|
737
|
-
}
|
|
738
|
-
const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
|
|
730
|
+
const balResp = await client.getBalance({ owner: address, coinType: SUI_TYPE });
|
|
731
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
739
732
|
if (totalBalance < input.amountMist) {
|
|
740
733
|
throw new Error(`Insufficient SUI: need ${input.amountMist} MIST, have ${totalBalance}`);
|
|
741
734
|
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
735
|
+
suiCoin = coinWithBalance({
|
|
736
|
+
type: SUI_TYPE,
|
|
737
|
+
balance: input.amountMist,
|
|
738
|
+
useGasCoin: false
|
|
739
|
+
})(tx);
|
|
747
740
|
}
|
|
748
741
|
const [vSuiCoin] = tx.moveCall({
|
|
749
742
|
target: `${VOLO_PKG}::stake_pool::stake`,
|
|
@@ -765,19 +758,16 @@ async function addUnstakeVSuiToTx(tx, client, address, input) {
|
|
|
765
758
|
[vSuiCoin] = tx.splitCoins(input.inputCoin, [input.amountMist]);
|
|
766
759
|
}
|
|
767
760
|
} else {
|
|
768
|
-
const
|
|
769
|
-
|
|
761
|
+
const balResp = await client.getBalance({ owner: address, coinType: VSUI_TYPE });
|
|
762
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
763
|
+
if (totalBalance === 0n) {
|
|
770
764
|
throw new Error("No vSUI found in wallet.");
|
|
771
765
|
}
|
|
772
|
-
const
|
|
773
|
-
if (
|
|
774
|
-
|
|
775
|
-
}
|
|
776
|
-
if (input.amountMist === "all") {
|
|
777
|
-
vSuiCoin = primary;
|
|
778
|
-
} else {
|
|
779
|
-
[vSuiCoin] = tx.splitCoins(primary, [input.amountMist]);
|
|
766
|
+
const requested = input.amountMist === "all" ? totalBalance : input.amountMist;
|
|
767
|
+
if (requested > totalBalance) {
|
|
768
|
+
throw new Error(`Insufficient vSUI: need ${requested} MIST, have ${totalBalance}`);
|
|
780
769
|
}
|
|
770
|
+
vSuiCoin = coinWithBalance({ type: VSUI_TYPE, balance: requested })(tx);
|
|
781
771
|
}
|
|
782
772
|
const [suiCoin] = tx.moveCall({
|
|
783
773
|
target: `${VOLO_PKG}::stake_pool::unstake`,
|
|
@@ -790,22 +780,6 @@ async function addUnstakeVSuiToTx(tx, client, address, input) {
|
|
|
790
780
|
});
|
|
791
781
|
return { coin: suiCoin, effectiveAmountMist: input.amountMist };
|
|
792
782
|
}
|
|
793
|
-
async function fetchCoinsByType(client, owner, coinType) {
|
|
794
|
-
const all = [];
|
|
795
|
-
let cursor;
|
|
796
|
-
let hasNext = true;
|
|
797
|
-
while (hasNext) {
|
|
798
|
-
const page = await client.getCoins({
|
|
799
|
-
owner,
|
|
800
|
-
coinType,
|
|
801
|
-
cursor: cursor ?? void 0
|
|
802
|
-
});
|
|
803
|
-
all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));
|
|
804
|
-
cursor = page.nextCursor;
|
|
805
|
-
hasNext = page.hasNextPage;
|
|
806
|
-
}
|
|
807
|
-
return all;
|
|
808
|
-
}
|
|
809
783
|
var VOLO_PKG, VOLO_POOL, VOLO_METADATA, VSUI_TYPE, SUI_SYSTEM_STATE, MIN_STAKE_MIST, VOLO_STATS_URL;
|
|
810
784
|
var init_volo = __esm({
|
|
811
785
|
"src/protocols/volo.ts"() {
|
|
@@ -827,52 +801,29 @@ __export(coinSelection_exports, {
|
|
|
827
801
|
selectAndSplitCoin: () => selectAndSplitCoin,
|
|
828
802
|
selectSuiCoin: () => selectSuiCoin
|
|
829
803
|
});
|
|
830
|
-
function getMergeCache(tx) {
|
|
831
|
-
let cache = ptbMergeCache.get(tx);
|
|
832
|
-
if (!cache) {
|
|
833
|
-
cache = /* @__PURE__ */ new Map();
|
|
834
|
-
ptbMergeCache.set(tx, cache);
|
|
835
|
-
}
|
|
836
|
-
return cache;
|
|
837
|
-
}
|
|
838
804
|
async function fetchAllCoins(client, owner, coinType) {
|
|
839
|
-
const ids = [
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
805
|
+
const [balance, ids] = await Promise.all([
|
|
806
|
+
client.getBalance({ owner, coinType }),
|
|
807
|
+
(async () => {
|
|
808
|
+
const out = [];
|
|
809
|
+
let cursor;
|
|
810
|
+
let hasNext = true;
|
|
811
|
+
while (hasNext) {
|
|
812
|
+
const page = await client.getCoins({ owner, coinType, cursor: cursor ?? void 0 });
|
|
813
|
+
for (const c of page.data) out.push(c.coinObjectId);
|
|
814
|
+
cursor = page.nextCursor;
|
|
815
|
+
hasNext = page.hasNextPage;
|
|
816
|
+
}
|
|
817
|
+
return out;
|
|
818
|
+
})()
|
|
819
|
+
]);
|
|
820
|
+
return { ids, totalBalance: BigInt(balance.totalBalance) };
|
|
853
821
|
}
|
|
854
822
|
async function selectAndSplitCoin(tx, client, owner, coinType, amount, options = {}) {
|
|
855
|
-
const
|
|
856
|
-
const
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
const allowSwapAll2 = options.allowSwapAll ?? true;
|
|
860
|
-
if (amount !== "all" && amount > cached.remaining && !allowSwapAll2) {
|
|
861
|
-
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient balance for ${coinType}`, {
|
|
862
|
-
available: cached.remaining.toString(),
|
|
863
|
-
required: amount.toString()
|
|
864
|
-
});
|
|
865
|
-
}
|
|
866
|
-
const requested2 = amount === "all" ? cached.remaining : amount;
|
|
867
|
-
const swapAll2 = amount === "all" || requested2 >= cached.remaining;
|
|
868
|
-
const effectiveAmount2 = swapAll2 ? cached.remaining : requested2;
|
|
869
|
-
const coin2 = swapAll2 ? cached.primary : tx.splitCoins(cached.primary, [effectiveAmount2])[0];
|
|
870
|
-
cached.remaining = swapAll2 ? 0n : cached.remaining - effectiveAmount2;
|
|
871
|
-
return { coin: coin2, effectiveAmount: effectiveAmount2, swapAll: swapAll2 };
|
|
872
|
-
}
|
|
873
|
-
const { ids, totalBalance } = await fetchAllCoins(client, owner, coinType);
|
|
874
|
-
if (ids.length === 0) {
|
|
875
|
-
throw new T2000Error("INSUFFICIENT_BALANCE", `No coins found for ${coinType}`);
|
|
823
|
+
const balanceResp = await client.getBalance({ owner, coinType });
|
|
824
|
+
const totalBalance = BigInt(balanceResp.totalBalance);
|
|
825
|
+
if (totalBalance === 0n) {
|
|
826
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `No balance found for ${coinType}`);
|
|
876
827
|
}
|
|
877
828
|
const allowSwapAll = options.allowSwapAll ?? true;
|
|
878
829
|
if (amount !== "all" && amount > totalBalance && !allowSwapAll) {
|
|
@@ -884,30 +835,29 @@ async function selectAndSplitCoin(tx, client, owner, coinType, amount, options =
|
|
|
884
835
|
const requested = amount === "all" ? totalBalance : amount;
|
|
885
836
|
const swapAll = amount === "all" || requested >= totalBalance;
|
|
886
837
|
const effectiveAmount = swapAll ? totalBalance : requested;
|
|
887
|
-
const
|
|
888
|
-
if (ids.length > 1) {
|
|
889
|
-
tx.mergeCoins(primary, ids.slice(1).map((id) => tx.object(id)));
|
|
890
|
-
}
|
|
891
|
-
const coin = swapAll ? primary : tx.splitCoins(primary, [effectiveAmount])[0];
|
|
892
|
-
cache.set(cacheKey, {
|
|
893
|
-
primary,
|
|
894
|
-
remaining: swapAll ? 0n : totalBalance - effectiveAmount
|
|
895
|
-
});
|
|
838
|
+
const coin = coinWithBalance({ type: coinType, balance: effectiveAmount })(tx);
|
|
896
839
|
return { coin, effectiveAmount, swapAll };
|
|
897
840
|
}
|
|
898
841
|
async function selectSuiCoin(tx, client, owner, amountMist, sponsoredContext) {
|
|
899
842
|
if (sponsoredContext) {
|
|
900
843
|
const { SUI_TYPE: SUI_TYPE2 } = await Promise.resolve().then(() => (init_token_registry(), token_registry_exports));
|
|
901
|
-
|
|
844
|
+
const balanceResp = await client.getBalance({ owner, coinType: SUI_TYPE2 });
|
|
845
|
+
const totalBalance = BigInt(balanceResp.totalBalance);
|
|
846
|
+
if (totalBalance < amountMist) {
|
|
847
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient SUI balance`, {
|
|
848
|
+
available: totalBalance.toString(),
|
|
849
|
+
required: amountMist.toString()
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
const coin2 = coinWithBalance({ type: SUI_TYPE2, balance: amountMist, useGasCoin: false })(tx);
|
|
853
|
+
return { coin: coin2, effectiveAmount: amountMist, swapAll: false };
|
|
902
854
|
}
|
|
903
855
|
const [coin] = tx.splitCoins(tx.gas, [amountMist]);
|
|
904
856
|
return { coin, effectiveAmount: amountMist, swapAll: false };
|
|
905
857
|
}
|
|
906
|
-
var ptbMergeCache;
|
|
907
858
|
var init_coinSelection = __esm({
|
|
908
859
|
"src/wallet/coinSelection.ts"() {
|
|
909
860
|
init_errors();
|
|
910
|
-
ptbMergeCache = /* @__PURE__ */ new WeakMap();
|
|
911
861
|
}
|
|
912
862
|
});
|
|
913
863
|
|
|
@@ -1115,6 +1065,17 @@ async function addSwapToTx(tx, client, address, input) {
|
|
|
1115
1065
|
if (input.inputCoin) {
|
|
1116
1066
|
inputCoin = input.inputCoin;
|
|
1117
1067
|
effectiveRaw = requestedRaw;
|
|
1068
|
+
} else if (fromType === "0x2::sui::SUI") {
|
|
1069
|
+
const { selectSuiCoin: selectSuiCoin2 } = await Promise.resolve().then(() => (init_coinSelection(), coinSelection_exports));
|
|
1070
|
+
const result = await selectSuiCoin2(
|
|
1071
|
+
tx,
|
|
1072
|
+
client,
|
|
1073
|
+
address,
|
|
1074
|
+
requestedRaw,
|
|
1075
|
+
input.sponsoredContext ?? false
|
|
1076
|
+
);
|
|
1077
|
+
inputCoin = result.coin;
|
|
1078
|
+
effectiveRaw = result.effectiveAmount;
|
|
1118
1079
|
} else {
|
|
1119
1080
|
const { selectAndSplitCoin: selectAndSplitCoin2 } = await Promise.resolve().then(() => (init_coinSelection(), coinSelection_exports));
|
|
1120
1081
|
const result = await selectAndSplitCoin2(tx, client, address, fromType, requestedRaw);
|
|
@@ -1521,26 +1482,16 @@ async function buildSendTx({
|
|
|
1521
1482
|
const rawAmount = displayToRaw(amount, assetInfo.decimals);
|
|
1522
1483
|
const tx = new Transaction();
|
|
1523
1484
|
tx.setSender(address);
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
if (totalBalance < rawAmount) {
|
|
1532
|
-
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, {
|
|
1533
|
-
available: Number(totalBalance) / 10 ** assetInfo.decimals,
|
|
1534
|
-
required: amount
|
|
1535
|
-
});
|
|
1536
|
-
}
|
|
1537
|
-
const primaryCoin = tx.object(coins.data[0].coinObjectId);
|
|
1538
|
-
if (coins.data.length > 1) {
|
|
1539
|
-
tx.mergeCoins(primaryCoin, coins.data.slice(1).map((c) => tx.object(c.coinObjectId)));
|
|
1540
|
-
}
|
|
1541
|
-
const [sendCoin] = tx.splitCoins(primaryCoin, [rawAmount]);
|
|
1542
|
-
tx.transferObjects([sendCoin], recipient);
|
|
1485
|
+
const balanceResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
1486
|
+
const totalBalance = BigInt(balanceResp.totalBalance);
|
|
1487
|
+
if (totalBalance < rawAmount) {
|
|
1488
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, {
|
|
1489
|
+
available: Number(totalBalance) / 10 ** assetInfo.decimals,
|
|
1490
|
+
required: amount
|
|
1491
|
+
});
|
|
1543
1492
|
}
|
|
1493
|
+
const sendCoin = asset === "SUI" ? tx.splitCoins(tx.gas, [rawAmount])[0] : coinWithBalance({ type: assetInfo.type, balance: rawAmount })(tx);
|
|
1494
|
+
tx.transferObjects([sendCoin], recipient);
|
|
1544
1495
|
return tx;
|
|
1545
1496
|
}
|
|
1546
1497
|
function addSendToTx(tx, coin, recipient) {
|
|
@@ -5487,26 +5438,6 @@ function resolveAssetInfo(asset) {
|
|
|
5487
5438
|
}
|
|
5488
5439
|
throw new T2000Error("ASSET_NOT_SUPPORTED", `Unknown asset: ${asset}`);
|
|
5489
5440
|
}
|
|
5490
|
-
async function fetchCoins(client, owner, coinType) {
|
|
5491
|
-
const all = [];
|
|
5492
|
-
let cursor;
|
|
5493
|
-
let hasNext = true;
|
|
5494
|
-
while (hasNext) {
|
|
5495
|
-
const page = await client.getCoins({ owner, coinType, cursor: cursor ?? void 0 });
|
|
5496
|
-
all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));
|
|
5497
|
-
cursor = page.nextCursor;
|
|
5498
|
-
hasNext = page.hasNextPage;
|
|
5499
|
-
}
|
|
5500
|
-
return all;
|
|
5501
|
-
}
|
|
5502
|
-
function mergeCoins(tx, coins) {
|
|
5503
|
-
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No coins to merge");
|
|
5504
|
-
const primary = tx.object(coins[0].coinObjectId);
|
|
5505
|
-
if (coins.length > 1) {
|
|
5506
|
-
tx.mergeCoins(primary, coins.slice(1).map((c) => tx.object(c.coinObjectId)));
|
|
5507
|
-
}
|
|
5508
|
-
return primary;
|
|
5509
|
-
}
|
|
5510
5441
|
async function getPositions(client, address) {
|
|
5511
5442
|
try {
|
|
5512
5443
|
const naviPositions = await $e(address, {
|
|
@@ -5597,13 +5528,15 @@ async function buildSaveTx(client, address, amount, options = {}) {
|
|
|
5597
5528
|
}
|
|
5598
5529
|
const asset = options.asset ?? "USDC";
|
|
5599
5530
|
const assetInfo = resolveAssetInfo(asset);
|
|
5600
|
-
const
|
|
5601
|
-
|
|
5602
|
-
|
|
5531
|
+
const balResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
5532
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
5533
|
+
if (totalBalance === 0n) {
|
|
5534
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} balance found`);
|
|
5535
|
+
}
|
|
5603
5536
|
const tx = new Transaction();
|
|
5604
5537
|
tx.setSender(address);
|
|
5605
|
-
const coinObj = mergeCoins(tx, coins);
|
|
5606
5538
|
const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
|
|
5539
|
+
const coinObj = coinWithBalance({ type: assetInfo.type, balance: BigInt(rawAmount) })(tx);
|
|
5607
5540
|
try {
|
|
5608
5541
|
await Ce(tx, assetInfo.type, coinObj, {
|
|
5609
5542
|
...sdkOptions(client),
|
|
@@ -5735,18 +5668,19 @@ async function buildRepayTx(client, address, amount, options = {}) {
|
|
|
5735
5668
|
}
|
|
5736
5669
|
const asset = options.asset ?? "USDC";
|
|
5737
5670
|
const assetInfo = resolveAssetInfo(asset);
|
|
5738
|
-
const
|
|
5739
|
-
|
|
5740
|
-
|
|
5671
|
+
const balResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
5672
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
5673
|
+
if (totalBalance === 0n) {
|
|
5674
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} to repay with. Withdraw some savings first to get cash.`);
|
|
5675
|
+
}
|
|
5741
5676
|
const rawRequested = Number(stableToRaw(amount, assetInfo.decimals));
|
|
5742
5677
|
if (Number(totalBalance) < rawRequested && Number(totalBalance) < 1e3) {
|
|
5743
5678
|
throw new T2000Error("INSUFFICIENT_BALANCE", `Not enough ${assetInfo.displayName} to repay (need $${amount.toFixed(2)}, wallet has ~$${(Number(totalBalance) / 10 ** assetInfo.decimals).toFixed(4)}). Withdraw some savings first.`);
|
|
5744
5679
|
}
|
|
5745
5680
|
const tx = new Transaction();
|
|
5746
5681
|
tx.setSender(address);
|
|
5747
|
-
const coinObj = mergeCoins(tx, coins);
|
|
5748
5682
|
const rawAmount = Math.min(rawRequested, Number(totalBalance));
|
|
5749
|
-
const
|
|
5683
|
+
const repayCoin = coinWithBalance({ type: assetInfo.type, balance: BigInt(rawAmount) })(tx);
|
|
5750
5684
|
await refreshOracle(tx, client, address, {
|
|
5751
5685
|
skipOracle: options.skipOracle,
|
|
5752
5686
|
skipPythUpdate: options.skipPythUpdate
|
|
@@ -6409,10 +6343,10 @@ var ContactManager = class {
|
|
|
6409
6343
|
}
|
|
6410
6344
|
};
|
|
6411
6345
|
var DEFAULT_CONFIG_DIR = join$1(homedir(), ".t2000");
|
|
6412
|
-
async function executeTx(client, signer, buildTx) {
|
|
6346
|
+
async function executeTx(client, signer, buildTx, options = {}) {
|
|
6413
6347
|
const tx = await buildTx();
|
|
6414
6348
|
tx.setSender(signer.getAddress());
|
|
6415
|
-
const txBytes = await tx.build({ client });
|
|
6349
|
+
const txBytes = await tx.build({ client: options.buildClient ?? client });
|
|
6416
6350
|
const { signature } = await signer.signTransaction(txBytes);
|
|
6417
6351
|
const result = await client.executeTransactionBlock({
|
|
6418
6352
|
transactionBlock: txBytes,
|
|
@@ -6514,10 +6448,15 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6514
6448
|
this.enforcer.check({ operation: "pay", amount: options.maxPrice ?? 1 });
|
|
6515
6449
|
const { Mppx } = await import('mppx/client');
|
|
6516
6450
|
const { sui, USDC } = await import('@suimpp/mpp/client');
|
|
6451
|
+
const { SuiGrpcClient } = await import('@mysten/sui/grpc');
|
|
6517
6452
|
const client = this.client;
|
|
6518
6453
|
const signer = this._signer;
|
|
6519
6454
|
const signerAddress = signer.getAddress();
|
|
6520
6455
|
let paymentDigest;
|
|
6456
|
+
let gasCostSui = 0;
|
|
6457
|
+
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
6458
|
+
const grpcBaseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
6459
|
+
const grpcClient = new SuiGrpcClient({ baseUrl: grpcBaseUrl, network });
|
|
6521
6460
|
const mppx = Mppx.create({
|
|
6522
6461
|
polyfill: false,
|
|
6523
6462
|
methods: [sui({
|
|
@@ -6528,8 +6467,9 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6528
6467
|
signPersonalMessage: (bytes) => signer.signPersonalMessage(bytes)
|
|
6529
6468
|
},
|
|
6530
6469
|
execute: async (tx) => {
|
|
6531
|
-
const result = await executeTx(client, signer, () => tx);
|
|
6470
|
+
const result = await executeTx(client, signer, () => tx, { buildClient: grpcClient });
|
|
6532
6471
|
paymentDigest = result.digest;
|
|
6472
|
+
gasCostSui = result.gasCostSui;
|
|
6533
6473
|
return { digest: result.digest };
|
|
6534
6474
|
}
|
|
6535
6475
|
})]
|
|
@@ -6557,6 +6497,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6557
6497
|
body,
|
|
6558
6498
|
paid,
|
|
6559
6499
|
cost: paid ? options.maxPrice ?? void 0 : void 0,
|
|
6500
|
+
gasCostSui: paid ? gasCostSui : void 0,
|
|
6560
6501
|
receipt: paymentDigest ? { reference: paymentDigest, timestamp: (/* @__PURE__ */ new Date()).toISOString() } : void 0
|
|
6561
6502
|
};
|
|
6562
6503
|
}
|
|
@@ -6586,8 +6527,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6586
6527
|
let vSuiAmount;
|
|
6587
6528
|
if (params.amount === "all") {
|
|
6588
6529
|
amountMist = "all";
|
|
6589
|
-
const
|
|
6590
|
-
vSuiAmount =
|
|
6530
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: VSUI_TYPE2 });
|
|
6531
|
+
vSuiAmount = Number(bal.totalBalance) / 1e9;
|
|
6591
6532
|
} else {
|
|
6592
6533
|
amountMist = BigInt(Math.floor(params.amount * 1e9));
|
|
6593
6534
|
vSuiAmount = params.amount;
|
|
@@ -6643,10 +6584,14 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6643
6584
|
if (fromType === "0x2::sui::SUI") {
|
|
6644
6585
|
[inputCoin] = tx.splitCoins(tx.gas, [rawAmount]);
|
|
6645
6586
|
} else {
|
|
6646
|
-
const
|
|
6647
|
-
if (
|
|
6648
|
-
|
|
6649
|
-
|
|
6587
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: fromType });
|
|
6588
|
+
if (BigInt(bal.totalBalance) < rawAmount) {
|
|
6589
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${params.from} balance.`, {
|
|
6590
|
+
available: Number(bal.totalBalance) / 10 ** fromDecimals,
|
|
6591
|
+
required: params.amount
|
|
6592
|
+
});
|
|
6593
|
+
}
|
|
6594
|
+
inputCoin = coinWithBalance({ type: fromType, balance: rawAmount })(tx);
|
|
6650
6595
|
}
|
|
6651
6596
|
const outputCoin = await buildSwapTx2({
|
|
6652
6597
|
walletAddress: this._address,
|
|
@@ -6903,11 +6848,15 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6903
6848
|
if (canPTB) {
|
|
6904
6849
|
const tx2 = new Transaction();
|
|
6905
6850
|
tx2.setSender(this._address);
|
|
6906
|
-
const coins = await this._fetchCoins(assetInfo.type);
|
|
6907
|
-
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins found`);
|
|
6908
|
-
const merged = this._mergeCoinsInTx(tx2, coins);
|
|
6909
6851
|
const rawAmount = BigInt(Math.floor(saveAmount * 10 ** assetInfo.decimals));
|
|
6910
|
-
const
|
|
6852
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: assetInfo.type });
|
|
6853
|
+
if (BigInt(bal.totalBalance) < rawAmount) {
|
|
6854
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${assetInfo.displayName} balance`, {
|
|
6855
|
+
available: Number(bal.totalBalance) / 10 ** assetInfo.decimals,
|
|
6856
|
+
required: saveAmount
|
|
6857
|
+
});
|
|
6858
|
+
}
|
|
6859
|
+
const inputCoin = coinWithBalance({ type: assetInfo.type, balance: rawAmount })(tx2);
|
|
6911
6860
|
await adapter.addSaveToTx(tx2, this._address, inputCoin, asset);
|
|
6912
6861
|
return tx2;
|
|
6913
6862
|
}
|
|
@@ -7102,52 +7051,6 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7102
7051
|
return 0;
|
|
7103
7052
|
}
|
|
7104
7053
|
}
|
|
7105
|
-
async _fetchCoins(coinType) {
|
|
7106
|
-
const all = [];
|
|
7107
|
-
let cursor;
|
|
7108
|
-
let hasNext = true;
|
|
7109
|
-
while (hasNext) {
|
|
7110
|
-
const page = await this.client.getCoins({ owner: this._address, coinType, cursor: cursor ?? void 0 });
|
|
7111
|
-
all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));
|
|
7112
|
-
cursor = page.nextCursor;
|
|
7113
|
-
hasNext = page.hasNextPage;
|
|
7114
|
-
}
|
|
7115
|
-
if (all.length > 0) {
|
|
7116
|
-
this._lastFundDigest = void 0;
|
|
7117
|
-
return all;
|
|
7118
|
-
}
|
|
7119
|
-
if (this._lastFundDigest && coinType === SUPPORTED_ASSETS.USDC.type) {
|
|
7120
|
-
const txInfo = await this.client.getTransactionBlock({
|
|
7121
|
-
digest: this._lastFundDigest,
|
|
7122
|
-
options: { showObjectChanges: true }
|
|
7123
|
-
});
|
|
7124
|
-
const coinIds = (txInfo.objectChanges ?? []).filter(
|
|
7125
|
-
(c) => (c.type === "created" || c.type === "mutated") && "objectType" in c && typeof c.objectType === "string" && c.objectType.includes("0x2::coin::Coin") && c.objectType.includes(coinType)
|
|
7126
|
-
).map((c) => c.objectId);
|
|
7127
|
-
if (coinIds.length > 0) {
|
|
7128
|
-
const objects = await this.client.multiGetObjects({
|
|
7129
|
-
ids: coinIds,
|
|
7130
|
-
options: { showContent: true, showOwner: true }
|
|
7131
|
-
});
|
|
7132
|
-
for (const obj of objects) {
|
|
7133
|
-
if (obj.data?.content?.dataType === "moveObject" && obj.data.owner && typeof obj.data.owner === "object" && "AddressOwner" in obj.data.owner && obj.data.owner.AddressOwner === this._address) {
|
|
7134
|
-
const fields = obj.data.content.fields;
|
|
7135
|
-
all.push({ coinObjectId: obj.data.objectId, balance: String(fields.balance ?? "0") });
|
|
7136
|
-
}
|
|
7137
|
-
}
|
|
7138
|
-
}
|
|
7139
|
-
}
|
|
7140
|
-
return all;
|
|
7141
|
-
}
|
|
7142
|
-
_mergeCoinsInTx(tx, coins) {
|
|
7143
|
-
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No coins to merge");
|
|
7144
|
-
const primary = tx.object(coins[0].coinObjectId);
|
|
7145
|
-
if (coins.length > 1) {
|
|
7146
|
-
tx.mergeCoins(primary, coins.slice(1).map((c) => tx.object(c.coinObjectId)));
|
|
7147
|
-
}
|
|
7148
|
-
return primary;
|
|
7149
|
-
}
|
|
7150
|
-
_lastFundDigest;
|
|
7151
7054
|
async _autoFundFromSavings(shortfall) {
|
|
7152
7055
|
const positions = await this.positions();
|
|
7153
7056
|
const savingsTotal = positions.positions.filter((p) => p.type === "save").reduce((sum, p) => sum + p.amount, 0);
|
|
@@ -7175,7 +7078,6 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7175
7078
|
if (!usdcReceived) {
|
|
7176
7079
|
throw new T2000Error("WITHDRAW_FAILED", "Withdraw TX did not produce USDC");
|
|
7177
7080
|
}
|
|
7178
|
-
this._lastFundDigest = result.tx;
|
|
7179
7081
|
}
|
|
7180
7082
|
async maxWithdraw() {
|
|
7181
7083
|
const adapter = await this.resolveLending(void 0, "USDC", "withdraw");
|
|
@@ -7244,11 +7146,18 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7244
7146
|
if (adapter.addRepayToTx) {
|
|
7245
7147
|
const tx2 = new Transaction();
|
|
7246
7148
|
tx2.setSender(this._address);
|
|
7247
|
-
const coins = await this._fetchCoins(targetAssetInfo.type);
|
|
7248
|
-
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${targetAssetInfo.displayName} coins`);
|
|
7249
|
-
const merged = this._mergeCoinsInTx(tx2, coins);
|
|
7250
7149
|
const raw = BigInt(Math.floor(repayAmount * 10 ** targetAssetInfo.decimals));
|
|
7251
|
-
const
|
|
7150
|
+
const bal = await this.client.getBalance({
|
|
7151
|
+
owner: this._address,
|
|
7152
|
+
coinType: targetAssetInfo.type
|
|
7153
|
+
});
|
|
7154
|
+
if (BigInt(bal.totalBalance) < raw) {
|
|
7155
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${targetAssetInfo.displayName} balance for repayment`, {
|
|
7156
|
+
available: Number(bal.totalBalance) / 10 ** targetAssetInfo.decimals,
|
|
7157
|
+
required: repayAmount
|
|
7158
|
+
});
|
|
7159
|
+
}
|
|
7160
|
+
const repayCoin = coinWithBalance({ type: targetAssetInfo.type, balance: raw })(tx2);
|
|
7252
7161
|
await adapter.addRepayToTx(tx2, this._address, repayCoin, target.asset);
|
|
7253
7162
|
return tx2;
|
|
7254
7163
|
}
|
|
@@ -7279,20 +7188,23 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7279
7188
|
if (canPTB) {
|
|
7280
7189
|
const tx = new Transaction();
|
|
7281
7190
|
tx.setSender(this._address);
|
|
7282
|
-
const assetMerged = /* @__PURE__ */ new Map();
|
|
7283
7191
|
const uniqueAssets = Array.from(new Set(entries.map((e) => e.borrow.asset)));
|
|
7284
7192
|
for (const asset of uniqueAssets) {
|
|
7285
7193
|
const info = SUPPORTED_ASSETS[asset];
|
|
7286
7194
|
if (!info) throw new T2000Error("ASSET_NOT_SUPPORTED", `Cannot repay unknown asset: ${asset}`);
|
|
7287
|
-
const
|
|
7288
|
-
|
|
7289
|
-
|
|
7195
|
+
const required = entries.filter((e) => e.borrow.asset === asset).reduce((sum, e) => sum + BigInt(Math.floor(e.borrow.amount * 10 ** info.decimals)), 0n);
|
|
7196
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: info.type });
|
|
7197
|
+
if (BigInt(bal.totalBalance) < required) {
|
|
7198
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${info.displayName} balance for repayment`, {
|
|
7199
|
+
available: Number(bal.totalBalance) / 10 ** info.decimals,
|
|
7200
|
+
required: Number(required) / 10 ** info.decimals
|
|
7201
|
+
});
|
|
7202
|
+
}
|
|
7290
7203
|
}
|
|
7291
7204
|
for (const { borrow, adapter } of entries) {
|
|
7292
7205
|
const info = SUPPORTED_ASSETS[borrow.asset];
|
|
7293
|
-
const merged = assetMerged.get(borrow.asset);
|
|
7294
7206
|
const raw = BigInt(Math.floor(borrow.amount * 10 ** info.decimals));
|
|
7295
|
-
const
|
|
7207
|
+
const repayCoin = coinWithBalance({ type: info.type, balance: raw })(tx);
|
|
7296
7208
|
await adapter.addRepayToTx(tx, this._address, repayCoin, borrow.asset);
|
|
7297
7209
|
totalRepaid += borrow.amount;
|
|
7298
7210
|
}
|
|
@@ -7423,8 +7335,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7423
7335
|
totalGasCost: 0
|
|
7424
7336
|
};
|
|
7425
7337
|
}
|
|
7426
|
-
const
|
|
7427
|
-
const preUsdcRaw =
|
|
7338
|
+
const preUsdcBal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7339
|
+
const preUsdcRaw = BigInt(preUsdcBal.totalBalance);
|
|
7428
7340
|
const claimResult = await this.claimRewards();
|
|
7429
7341
|
if (!claimResult.tx) {
|
|
7430
7342
|
return {
|
|
@@ -7447,8 +7359,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7447
7359
|
const decimals = getDecimalsForCoinType(reward.coinType) ?? 9;
|
|
7448
7360
|
const rawAmount = BigInt(Math.floor(reward.amount * 10 ** decimals));
|
|
7449
7361
|
if (rawAmount <= 0n) continue;
|
|
7450
|
-
const
|
|
7451
|
-
if (
|
|
7362
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: reward.coinType });
|
|
7363
|
+
if (BigInt(bal.totalBalance) < rawAmount) continue;
|
|
7452
7364
|
const route = await findSwapRoute2({
|
|
7453
7365
|
walletAddress: this._address,
|
|
7454
7366
|
from: reward.coinType,
|
|
@@ -7460,10 +7372,9 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7460
7372
|
const swapResult = await executeTx(this.client, this._signer, async () => {
|
|
7461
7373
|
const tx = new Transaction();
|
|
7462
7374
|
tx.setSender(this._address);
|
|
7463
|
-
const
|
|
7464
|
-
if (
|
|
7465
|
-
const
|
|
7466
|
-
const [inputCoin] = tx.splitCoins(merged, [rawAmount]);
|
|
7375
|
+
const freshBal = await this.client.getBalance({ owner: this._address, coinType: reward.coinType });
|
|
7376
|
+
if (BigInt(freshBal.totalBalance) < rawAmount) return tx;
|
|
7377
|
+
const inputCoin = coinWithBalance({ type: reward.coinType, balance: rawAmount })(tx);
|
|
7467
7378
|
const outputCoin = await buildSwapTx2({
|
|
7468
7379
|
walletAddress: this._address,
|
|
7469
7380
|
route,
|
|
@@ -7480,8 +7391,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7480
7391
|
console.warn(`[compound] Failed to swap ${reward.symbol}:`, err instanceof Error ? err.message : err);
|
|
7481
7392
|
}
|
|
7482
7393
|
}
|
|
7483
|
-
const
|
|
7484
|
-
const postUsdcRaw =
|
|
7394
|
+
const postUsdcBal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7395
|
+
const postUsdcRaw = BigInt(postUsdcBal.totalBalance);
|
|
7485
7396
|
const gainedRaw = postUsdcRaw > preUsdcRaw ? postUsdcRaw - preUsdcRaw : 0n;
|
|
7486
7397
|
const depositUsdc = Number(gainedRaw) / 10 ** USDC_DEC;
|
|
7487
7398
|
let depositTx = "";
|
|
@@ -7491,10 +7402,11 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7491
7402
|
const depositResult = await executeTx(this.client, this._signer, async () => {
|
|
7492
7403
|
const tx = new Transaction();
|
|
7493
7404
|
tx.setSender(this._address);
|
|
7494
|
-
const
|
|
7495
|
-
if (
|
|
7496
|
-
|
|
7497
|
-
|
|
7405
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7406
|
+
if (BigInt(bal.totalBalance) < gainedRaw) {
|
|
7407
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC available after swap");
|
|
7408
|
+
}
|
|
7409
|
+
const inputCoin = coinWithBalance({ type: USDC_TYPE2, balance: gainedRaw })(tx);
|
|
7498
7410
|
await adapter.addSaveToTx(tx, this._address, inputCoin, "USDC");
|
|
7499
7411
|
return tx;
|
|
7500
7412
|
});
|
|
@@ -7990,7 +7902,8 @@ var WRITE_APPENDER_REGISTRY = {
|
|
|
7990
7902
|
overlayFee: ctx.overlayFee,
|
|
7991
7903
|
providers,
|
|
7992
7904
|
inputCoin: ctx.chainedCoin,
|
|
7993
|
-
precomputedRoute: input.precomputedRoute
|
|
7905
|
+
precomputedRoute: input.precomputedRoute,
|
|
7906
|
+
sponsoredContext: ctx.sponsoredContext
|
|
7994
7907
|
});
|
|
7995
7908
|
if (!ctx.isOutputConsumed) {
|
|
7996
7909
|
tx.transferObjects([result.coin], ctx.sender);
|