@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.cjs
CHANGED
|
@@ -701,22 +701,18 @@ async function buildStakeVSuiTx(_client, address, amountMist) {
|
|
|
701
701
|
return tx;
|
|
702
702
|
}
|
|
703
703
|
async function buildUnstakeVSuiTx(client, address, amountMist) {
|
|
704
|
-
const
|
|
705
|
-
|
|
704
|
+
const balResp = await client.getBalance({ owner: address, coinType: exports.VSUI_TYPE });
|
|
705
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
706
|
+
if (totalBalance === 0n) {
|
|
706
707
|
throw new Error("No vSUI found in wallet.");
|
|
707
708
|
}
|
|
708
709
|
const tx = new transactions.Transaction();
|
|
709
710
|
tx.setSender(address);
|
|
710
|
-
const
|
|
711
|
-
if (
|
|
712
|
-
|
|
713
|
-
}
|
|
714
|
-
let vSuiCoin;
|
|
715
|
-
if (amountMist === "all") {
|
|
716
|
-
vSuiCoin = primary;
|
|
717
|
-
} else {
|
|
718
|
-
[vSuiCoin] = tx.splitCoins(primary, [amountMist]);
|
|
711
|
+
const requested = amountMist === "all" ? totalBalance : amountMist;
|
|
712
|
+
if (requested > totalBalance) {
|
|
713
|
+
throw new Error(`Insufficient vSUI: need ${requested} MIST, have ${totalBalance}`);
|
|
719
714
|
}
|
|
715
|
+
const vSuiCoin = transactions.coinWithBalance({ type: exports.VSUI_TYPE, balance: requested })(tx);
|
|
720
716
|
const [suiCoin] = tx.moveCall({
|
|
721
717
|
target: `${exports.VOLO_PKG}::stake_pool::unstake`,
|
|
722
718
|
arguments: [
|
|
@@ -737,19 +733,16 @@ async function addStakeVSuiToTx(tx, client, address, input) {
|
|
|
737
733
|
if (input.inputCoin) {
|
|
738
734
|
suiCoin = input.inputCoin;
|
|
739
735
|
} else {
|
|
740
|
-
const
|
|
741
|
-
|
|
742
|
-
throw new Error("No SUI coins found in wallet");
|
|
743
|
-
}
|
|
744
|
-
const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
|
|
736
|
+
const balResp = await client.getBalance({ owner: address, coinType: exports.SUI_TYPE });
|
|
737
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
745
738
|
if (totalBalance < input.amountMist) {
|
|
746
739
|
throw new Error(`Insufficient SUI: need ${input.amountMist} MIST, have ${totalBalance}`);
|
|
747
740
|
}
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
741
|
+
suiCoin = transactions.coinWithBalance({
|
|
742
|
+
type: exports.SUI_TYPE,
|
|
743
|
+
balance: input.amountMist,
|
|
744
|
+
useGasCoin: false
|
|
745
|
+
})(tx);
|
|
753
746
|
}
|
|
754
747
|
const [vSuiCoin] = tx.moveCall({
|
|
755
748
|
target: `${exports.VOLO_PKG}::stake_pool::stake`,
|
|
@@ -771,19 +764,16 @@ async function addUnstakeVSuiToTx(tx, client, address, input) {
|
|
|
771
764
|
[vSuiCoin] = tx.splitCoins(input.inputCoin, [input.amountMist]);
|
|
772
765
|
}
|
|
773
766
|
} else {
|
|
774
|
-
const
|
|
775
|
-
|
|
767
|
+
const balResp = await client.getBalance({ owner: address, coinType: exports.VSUI_TYPE });
|
|
768
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
769
|
+
if (totalBalance === 0n) {
|
|
776
770
|
throw new Error("No vSUI found in wallet.");
|
|
777
771
|
}
|
|
778
|
-
const
|
|
779
|
-
if (
|
|
780
|
-
|
|
781
|
-
}
|
|
782
|
-
if (input.amountMist === "all") {
|
|
783
|
-
vSuiCoin = primary;
|
|
784
|
-
} else {
|
|
785
|
-
[vSuiCoin] = tx.splitCoins(primary, [input.amountMist]);
|
|
772
|
+
const requested = input.amountMist === "all" ? totalBalance : input.amountMist;
|
|
773
|
+
if (requested > totalBalance) {
|
|
774
|
+
throw new Error(`Insufficient vSUI: need ${requested} MIST, have ${totalBalance}`);
|
|
786
775
|
}
|
|
776
|
+
vSuiCoin = transactions.coinWithBalance({ type: exports.VSUI_TYPE, balance: requested })(tx);
|
|
787
777
|
}
|
|
788
778
|
const [suiCoin] = tx.moveCall({
|
|
789
779
|
target: `${exports.VOLO_PKG}::stake_pool::unstake`,
|
|
@@ -796,22 +786,6 @@ async function addUnstakeVSuiToTx(tx, client, address, input) {
|
|
|
796
786
|
});
|
|
797
787
|
return { coin: suiCoin, effectiveAmountMist: input.amountMist };
|
|
798
788
|
}
|
|
799
|
-
async function fetchCoinsByType(client, owner, coinType) {
|
|
800
|
-
const all = [];
|
|
801
|
-
let cursor;
|
|
802
|
-
let hasNext = true;
|
|
803
|
-
while (hasNext) {
|
|
804
|
-
const page = await client.getCoins({
|
|
805
|
-
owner,
|
|
806
|
-
coinType,
|
|
807
|
-
cursor: cursor ?? void 0
|
|
808
|
-
});
|
|
809
|
-
all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));
|
|
810
|
-
cursor = page.nextCursor;
|
|
811
|
-
hasNext = page.hasNextPage;
|
|
812
|
-
}
|
|
813
|
-
return all;
|
|
814
|
-
}
|
|
815
789
|
exports.VOLO_PKG = void 0; exports.VOLO_POOL = void 0; exports.VOLO_METADATA = void 0; exports.VSUI_TYPE = void 0; var SUI_SYSTEM_STATE, MIN_STAKE_MIST, VOLO_STATS_URL;
|
|
816
790
|
var init_volo = __esm({
|
|
817
791
|
"src/protocols/volo.ts"() {
|
|
@@ -833,52 +807,29 @@ __export(coinSelection_exports, {
|
|
|
833
807
|
selectAndSplitCoin: () => selectAndSplitCoin,
|
|
834
808
|
selectSuiCoin: () => selectSuiCoin
|
|
835
809
|
});
|
|
836
|
-
function getMergeCache(tx) {
|
|
837
|
-
let cache = ptbMergeCache.get(tx);
|
|
838
|
-
if (!cache) {
|
|
839
|
-
cache = /* @__PURE__ */ new Map();
|
|
840
|
-
ptbMergeCache.set(tx, cache);
|
|
841
|
-
}
|
|
842
|
-
return cache;
|
|
843
|
-
}
|
|
844
810
|
async function fetchAllCoins(client, owner, coinType) {
|
|
845
|
-
const ids = [
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
811
|
+
const [balance, ids] = await Promise.all([
|
|
812
|
+
client.getBalance({ owner, coinType }),
|
|
813
|
+
(async () => {
|
|
814
|
+
const out = [];
|
|
815
|
+
let cursor;
|
|
816
|
+
let hasNext = true;
|
|
817
|
+
while (hasNext) {
|
|
818
|
+
const page = await client.getCoins({ owner, coinType, cursor: cursor ?? void 0 });
|
|
819
|
+
for (const c of page.data) out.push(c.coinObjectId);
|
|
820
|
+
cursor = page.nextCursor;
|
|
821
|
+
hasNext = page.hasNextPage;
|
|
822
|
+
}
|
|
823
|
+
return out;
|
|
824
|
+
})()
|
|
825
|
+
]);
|
|
826
|
+
return { ids, totalBalance: BigInt(balance.totalBalance) };
|
|
859
827
|
}
|
|
860
828
|
async function selectAndSplitCoin(tx, client, owner, coinType, amount, options = {}) {
|
|
861
|
-
const
|
|
862
|
-
const
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
const allowSwapAll2 = options.allowSwapAll ?? true;
|
|
866
|
-
if (amount !== "all" && amount > cached.remaining && !allowSwapAll2) {
|
|
867
|
-
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient balance for ${coinType}`, {
|
|
868
|
-
available: cached.remaining.toString(),
|
|
869
|
-
required: amount.toString()
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
const requested2 = amount === "all" ? cached.remaining : amount;
|
|
873
|
-
const swapAll2 = amount === "all" || requested2 >= cached.remaining;
|
|
874
|
-
const effectiveAmount2 = swapAll2 ? cached.remaining : requested2;
|
|
875
|
-
const coin2 = swapAll2 ? cached.primary : tx.splitCoins(cached.primary, [effectiveAmount2])[0];
|
|
876
|
-
cached.remaining = swapAll2 ? 0n : cached.remaining - effectiveAmount2;
|
|
877
|
-
return { coin: coin2, effectiveAmount: effectiveAmount2, swapAll: swapAll2 };
|
|
878
|
-
}
|
|
879
|
-
const { ids, totalBalance } = await fetchAllCoins(client, owner, coinType);
|
|
880
|
-
if (ids.length === 0) {
|
|
881
|
-
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `No coins found for ${coinType}`);
|
|
829
|
+
const balanceResp = await client.getBalance({ owner, coinType });
|
|
830
|
+
const totalBalance = BigInt(balanceResp.totalBalance);
|
|
831
|
+
if (totalBalance === 0n) {
|
|
832
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `No balance found for ${coinType}`);
|
|
882
833
|
}
|
|
883
834
|
const allowSwapAll = options.allowSwapAll ?? true;
|
|
884
835
|
if (amount !== "all" && amount > totalBalance && !allowSwapAll) {
|
|
@@ -890,30 +841,29 @@ async function selectAndSplitCoin(tx, client, owner, coinType, amount, options =
|
|
|
890
841
|
const requested = amount === "all" ? totalBalance : amount;
|
|
891
842
|
const swapAll = amount === "all" || requested >= totalBalance;
|
|
892
843
|
const effectiveAmount = swapAll ? totalBalance : requested;
|
|
893
|
-
const
|
|
894
|
-
if (ids.length > 1) {
|
|
895
|
-
tx.mergeCoins(primary, ids.slice(1).map((id) => tx.object(id)));
|
|
896
|
-
}
|
|
897
|
-
const coin = swapAll ? primary : tx.splitCoins(primary, [effectiveAmount])[0];
|
|
898
|
-
cache.set(cacheKey, {
|
|
899
|
-
primary,
|
|
900
|
-
remaining: swapAll ? 0n : totalBalance - effectiveAmount
|
|
901
|
-
});
|
|
844
|
+
const coin = transactions.coinWithBalance({ type: coinType, balance: effectiveAmount })(tx);
|
|
902
845
|
return { coin, effectiveAmount, swapAll };
|
|
903
846
|
}
|
|
904
847
|
async function selectSuiCoin(tx, client, owner, amountMist, sponsoredContext) {
|
|
905
848
|
if (sponsoredContext) {
|
|
906
849
|
const { SUI_TYPE: SUI_TYPE2 } = await Promise.resolve().then(() => (init_token_registry(), token_registry_exports));
|
|
907
|
-
|
|
850
|
+
const balanceResp = await client.getBalance({ owner, coinType: SUI_TYPE2 });
|
|
851
|
+
const totalBalance = BigInt(balanceResp.totalBalance);
|
|
852
|
+
if (totalBalance < amountMist) {
|
|
853
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient SUI balance`, {
|
|
854
|
+
available: totalBalance.toString(),
|
|
855
|
+
required: amountMist.toString()
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
const coin2 = transactions.coinWithBalance({ type: SUI_TYPE2, balance: amountMist, useGasCoin: false })(tx);
|
|
859
|
+
return { coin: coin2, effectiveAmount: amountMist, swapAll: false };
|
|
908
860
|
}
|
|
909
861
|
const [coin] = tx.splitCoins(tx.gas, [amountMist]);
|
|
910
862
|
return { coin, effectiveAmount: amountMist, swapAll: false };
|
|
911
863
|
}
|
|
912
|
-
var ptbMergeCache;
|
|
913
864
|
var init_coinSelection = __esm({
|
|
914
865
|
"src/wallet/coinSelection.ts"() {
|
|
915
866
|
init_errors();
|
|
916
|
-
ptbMergeCache = /* @__PURE__ */ new WeakMap();
|
|
917
867
|
}
|
|
918
868
|
});
|
|
919
869
|
|
|
@@ -1121,6 +1071,17 @@ async function addSwapToTx(tx, client, address, input) {
|
|
|
1121
1071
|
if (input.inputCoin) {
|
|
1122
1072
|
inputCoin = input.inputCoin;
|
|
1123
1073
|
effectiveRaw = requestedRaw;
|
|
1074
|
+
} else if (fromType === "0x2::sui::SUI") {
|
|
1075
|
+
const { selectSuiCoin: selectSuiCoin2 } = await Promise.resolve().then(() => (init_coinSelection(), coinSelection_exports));
|
|
1076
|
+
const result = await selectSuiCoin2(
|
|
1077
|
+
tx,
|
|
1078
|
+
client,
|
|
1079
|
+
address,
|
|
1080
|
+
requestedRaw,
|
|
1081
|
+
input.sponsoredContext ?? false
|
|
1082
|
+
);
|
|
1083
|
+
inputCoin = result.coin;
|
|
1084
|
+
effectiveRaw = result.effectiveAmount;
|
|
1124
1085
|
} else {
|
|
1125
1086
|
const { selectAndSplitCoin: selectAndSplitCoin2 } = await Promise.resolve().then(() => (init_coinSelection(), coinSelection_exports));
|
|
1126
1087
|
const result = await selectAndSplitCoin2(tx, client, address, fromType, requestedRaw);
|
|
@@ -1527,26 +1488,16 @@ async function buildSendTx({
|
|
|
1527
1488
|
const rawAmount = displayToRaw(amount, assetInfo.decimals);
|
|
1528
1489
|
const tx = new transactions.Transaction();
|
|
1529
1490
|
tx.setSender(address);
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
if (totalBalance < rawAmount) {
|
|
1538
|
-
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, {
|
|
1539
|
-
available: Number(totalBalance) / 10 ** assetInfo.decimals,
|
|
1540
|
-
required: amount
|
|
1541
|
-
});
|
|
1542
|
-
}
|
|
1543
|
-
const primaryCoin = tx.object(coins.data[0].coinObjectId);
|
|
1544
|
-
if (coins.data.length > 1) {
|
|
1545
|
-
tx.mergeCoins(primaryCoin, coins.data.slice(1).map((c) => tx.object(c.coinObjectId)));
|
|
1546
|
-
}
|
|
1547
|
-
const [sendCoin] = tx.splitCoins(primaryCoin, [rawAmount]);
|
|
1548
|
-
tx.transferObjects([sendCoin], recipient);
|
|
1491
|
+
const balanceResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
1492
|
+
const totalBalance = BigInt(balanceResp.totalBalance);
|
|
1493
|
+
if (totalBalance < rawAmount) {
|
|
1494
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, {
|
|
1495
|
+
available: Number(totalBalance) / 10 ** assetInfo.decimals,
|
|
1496
|
+
required: amount
|
|
1497
|
+
});
|
|
1549
1498
|
}
|
|
1499
|
+
const sendCoin = asset === "SUI" ? tx.splitCoins(tx.gas, [rawAmount])[0] : transactions.coinWithBalance({ type: assetInfo.type, balance: rawAmount })(tx);
|
|
1500
|
+
tx.transferObjects([sendCoin], recipient);
|
|
1550
1501
|
return tx;
|
|
1551
1502
|
}
|
|
1552
1503
|
function addSendToTx(tx, coin, recipient) {
|
|
@@ -5493,26 +5444,6 @@ function resolveAssetInfo(asset) {
|
|
|
5493
5444
|
}
|
|
5494
5445
|
throw new exports.T2000Error("ASSET_NOT_SUPPORTED", `Unknown asset: ${asset}`);
|
|
5495
5446
|
}
|
|
5496
|
-
async function fetchCoins(client, owner, coinType) {
|
|
5497
|
-
const all = [];
|
|
5498
|
-
let cursor;
|
|
5499
|
-
let hasNext = true;
|
|
5500
|
-
while (hasNext) {
|
|
5501
|
-
const page = await client.getCoins({ owner, coinType, cursor: cursor ?? void 0 });
|
|
5502
|
-
all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));
|
|
5503
|
-
cursor = page.nextCursor;
|
|
5504
|
-
hasNext = page.hasNextPage;
|
|
5505
|
-
}
|
|
5506
|
-
return all;
|
|
5507
|
-
}
|
|
5508
|
-
function mergeCoins(tx, coins) {
|
|
5509
|
-
if (coins.length === 0) throw new exports.T2000Error("INSUFFICIENT_BALANCE", "No coins to merge");
|
|
5510
|
-
const primary = tx.object(coins[0].coinObjectId);
|
|
5511
|
-
if (coins.length > 1) {
|
|
5512
|
-
tx.mergeCoins(primary, coins.slice(1).map((c) => tx.object(c.coinObjectId)));
|
|
5513
|
-
}
|
|
5514
|
-
return primary;
|
|
5515
|
-
}
|
|
5516
5447
|
async function getPositions(client, address) {
|
|
5517
5448
|
try {
|
|
5518
5449
|
const naviPositions = await $e(address, {
|
|
@@ -5603,13 +5534,15 @@ async function buildSaveTx(client, address, amount, options = {}) {
|
|
|
5603
5534
|
}
|
|
5604
5535
|
const asset = options.asset ?? "USDC";
|
|
5605
5536
|
const assetInfo = resolveAssetInfo(asset);
|
|
5606
|
-
const
|
|
5607
|
-
|
|
5608
|
-
|
|
5537
|
+
const balResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
5538
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
5539
|
+
if (totalBalance === 0n) {
|
|
5540
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} balance found`);
|
|
5541
|
+
}
|
|
5609
5542
|
const tx = new transactions.Transaction();
|
|
5610
5543
|
tx.setSender(address);
|
|
5611
|
-
const coinObj = mergeCoins(tx, coins);
|
|
5612
5544
|
const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
|
|
5545
|
+
const coinObj = transactions.coinWithBalance({ type: assetInfo.type, balance: BigInt(rawAmount) })(tx);
|
|
5613
5546
|
try {
|
|
5614
5547
|
await Ce(tx, assetInfo.type, coinObj, {
|
|
5615
5548
|
...sdkOptions(client),
|
|
@@ -5741,18 +5674,19 @@ async function buildRepayTx(client, address, amount, options = {}) {
|
|
|
5741
5674
|
}
|
|
5742
5675
|
const asset = options.asset ?? "USDC";
|
|
5743
5676
|
const assetInfo = resolveAssetInfo(asset);
|
|
5744
|
-
const
|
|
5745
|
-
|
|
5746
|
-
|
|
5677
|
+
const balResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
5678
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
5679
|
+
if (totalBalance === 0n) {
|
|
5680
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} to repay with. Withdraw some savings first to get cash.`);
|
|
5681
|
+
}
|
|
5747
5682
|
const rawRequested = Number(stableToRaw(amount, assetInfo.decimals));
|
|
5748
5683
|
if (Number(totalBalance) < rawRequested && Number(totalBalance) < 1e3) {
|
|
5749
5684
|
throw new exports.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.`);
|
|
5750
5685
|
}
|
|
5751
5686
|
const tx = new transactions.Transaction();
|
|
5752
5687
|
tx.setSender(address);
|
|
5753
|
-
const coinObj = mergeCoins(tx, coins);
|
|
5754
5688
|
const rawAmount = Math.min(rawRequested, Number(totalBalance));
|
|
5755
|
-
const
|
|
5689
|
+
const repayCoin = transactions.coinWithBalance({ type: assetInfo.type, balance: BigInt(rawAmount) })(tx);
|
|
5756
5690
|
await refreshOracle(tx, client, address, {
|
|
5757
5691
|
skipOracle: options.skipOracle,
|
|
5758
5692
|
skipPythUpdate: options.skipPythUpdate
|
|
@@ -6415,10 +6349,10 @@ var ContactManager = class {
|
|
|
6415
6349
|
}
|
|
6416
6350
|
};
|
|
6417
6351
|
var DEFAULT_CONFIG_DIR = path.join(os.homedir(), ".t2000");
|
|
6418
|
-
async function executeTx(client, signer, buildTx) {
|
|
6352
|
+
async function executeTx(client, signer, buildTx, options = {}) {
|
|
6419
6353
|
const tx = await buildTx();
|
|
6420
6354
|
tx.setSender(signer.getAddress());
|
|
6421
|
-
const txBytes = await tx.build({ client });
|
|
6355
|
+
const txBytes = await tx.build({ client: options.buildClient ?? client });
|
|
6422
6356
|
const { signature } = await signer.signTransaction(txBytes);
|
|
6423
6357
|
const result = await client.executeTransactionBlock({
|
|
6424
6358
|
transactionBlock: txBytes,
|
|
@@ -6520,10 +6454,15 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6520
6454
|
this.enforcer.check({ operation: "pay", amount: options.maxPrice ?? 1 });
|
|
6521
6455
|
const { Mppx } = await import('mppx/client');
|
|
6522
6456
|
const { sui, USDC } = await import('@suimpp/mpp/client');
|
|
6457
|
+
const { SuiGrpcClient } = await import('@mysten/sui/grpc');
|
|
6523
6458
|
const client = this.client;
|
|
6524
6459
|
const signer = this._signer;
|
|
6525
6460
|
const signerAddress = signer.getAddress();
|
|
6526
6461
|
let paymentDigest;
|
|
6462
|
+
let gasCostSui = 0;
|
|
6463
|
+
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
6464
|
+
const grpcBaseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
6465
|
+
const grpcClient = new SuiGrpcClient({ baseUrl: grpcBaseUrl, network });
|
|
6527
6466
|
const mppx = Mppx.create({
|
|
6528
6467
|
polyfill: false,
|
|
6529
6468
|
methods: [sui({
|
|
@@ -6534,8 +6473,9 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6534
6473
|
signPersonalMessage: (bytes) => signer.signPersonalMessage(bytes)
|
|
6535
6474
|
},
|
|
6536
6475
|
execute: async (tx) => {
|
|
6537
|
-
const result = await executeTx(client, signer, () => tx);
|
|
6476
|
+
const result = await executeTx(client, signer, () => tx, { buildClient: grpcClient });
|
|
6538
6477
|
paymentDigest = result.digest;
|
|
6478
|
+
gasCostSui = result.gasCostSui;
|
|
6539
6479
|
return { digest: result.digest };
|
|
6540
6480
|
}
|
|
6541
6481
|
})]
|
|
@@ -6563,6 +6503,7 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6563
6503
|
body,
|
|
6564
6504
|
paid,
|
|
6565
6505
|
cost: paid ? options.maxPrice ?? void 0 : void 0,
|
|
6506
|
+
gasCostSui: paid ? gasCostSui : void 0,
|
|
6566
6507
|
receipt: paymentDigest ? { reference: paymentDigest, timestamp: (/* @__PURE__ */ new Date()).toISOString() } : void 0
|
|
6567
6508
|
};
|
|
6568
6509
|
}
|
|
@@ -6592,8 +6533,8 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6592
6533
|
let vSuiAmount;
|
|
6593
6534
|
if (params.amount === "all") {
|
|
6594
6535
|
amountMist = "all";
|
|
6595
|
-
const
|
|
6596
|
-
vSuiAmount =
|
|
6536
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: VSUI_TYPE2 });
|
|
6537
|
+
vSuiAmount = Number(bal.totalBalance) / 1e9;
|
|
6597
6538
|
} else {
|
|
6598
6539
|
amountMist = BigInt(Math.floor(params.amount * 1e9));
|
|
6599
6540
|
vSuiAmount = params.amount;
|
|
@@ -6649,10 +6590,14 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6649
6590
|
if (fromType === "0x2::sui::SUI") {
|
|
6650
6591
|
[inputCoin] = tx.splitCoins(tx.gas, [rawAmount]);
|
|
6651
6592
|
} else {
|
|
6652
|
-
const
|
|
6653
|
-
if (
|
|
6654
|
-
|
|
6655
|
-
|
|
6593
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: fromType });
|
|
6594
|
+
if (BigInt(bal.totalBalance) < rawAmount) {
|
|
6595
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${params.from} balance.`, {
|
|
6596
|
+
available: Number(bal.totalBalance) / 10 ** fromDecimals,
|
|
6597
|
+
required: params.amount
|
|
6598
|
+
});
|
|
6599
|
+
}
|
|
6600
|
+
inputCoin = transactions.coinWithBalance({ type: fromType, balance: rawAmount })(tx);
|
|
6656
6601
|
}
|
|
6657
6602
|
const outputCoin = await buildSwapTx2({
|
|
6658
6603
|
walletAddress: this._address,
|
|
@@ -6909,11 +6854,15 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6909
6854
|
if (canPTB) {
|
|
6910
6855
|
const tx2 = new transactions.Transaction();
|
|
6911
6856
|
tx2.setSender(this._address);
|
|
6912
|
-
const coins = await this._fetchCoins(assetInfo.type);
|
|
6913
|
-
if (coins.length === 0) throw new exports.T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins found`);
|
|
6914
|
-
const merged = this._mergeCoinsInTx(tx2, coins);
|
|
6915
6857
|
const rawAmount = BigInt(Math.floor(saveAmount * 10 ** assetInfo.decimals));
|
|
6916
|
-
const
|
|
6858
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: assetInfo.type });
|
|
6859
|
+
if (BigInt(bal.totalBalance) < rawAmount) {
|
|
6860
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${assetInfo.displayName} balance`, {
|
|
6861
|
+
available: Number(bal.totalBalance) / 10 ** assetInfo.decimals,
|
|
6862
|
+
required: saveAmount
|
|
6863
|
+
});
|
|
6864
|
+
}
|
|
6865
|
+
const inputCoin = transactions.coinWithBalance({ type: assetInfo.type, balance: rawAmount })(tx2);
|
|
6917
6866
|
await adapter.addSaveToTx(tx2, this._address, inputCoin, asset);
|
|
6918
6867
|
return tx2;
|
|
6919
6868
|
}
|
|
@@ -7108,52 +7057,6 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7108
7057
|
return 0;
|
|
7109
7058
|
}
|
|
7110
7059
|
}
|
|
7111
|
-
async _fetchCoins(coinType) {
|
|
7112
|
-
const all = [];
|
|
7113
|
-
let cursor;
|
|
7114
|
-
let hasNext = true;
|
|
7115
|
-
while (hasNext) {
|
|
7116
|
-
const page = await this.client.getCoins({ owner: this._address, coinType, cursor: cursor ?? void 0 });
|
|
7117
|
-
all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));
|
|
7118
|
-
cursor = page.nextCursor;
|
|
7119
|
-
hasNext = page.hasNextPage;
|
|
7120
|
-
}
|
|
7121
|
-
if (all.length > 0) {
|
|
7122
|
-
this._lastFundDigest = void 0;
|
|
7123
|
-
return all;
|
|
7124
|
-
}
|
|
7125
|
-
if (this._lastFundDigest && coinType === SUPPORTED_ASSETS.USDC.type) {
|
|
7126
|
-
const txInfo = await this.client.getTransactionBlock({
|
|
7127
|
-
digest: this._lastFundDigest,
|
|
7128
|
-
options: { showObjectChanges: true }
|
|
7129
|
-
});
|
|
7130
|
-
const coinIds = (txInfo.objectChanges ?? []).filter(
|
|
7131
|
-
(c) => (c.type === "created" || c.type === "mutated") && "objectType" in c && typeof c.objectType === "string" && c.objectType.includes("0x2::coin::Coin") && c.objectType.includes(coinType)
|
|
7132
|
-
).map((c) => c.objectId);
|
|
7133
|
-
if (coinIds.length > 0) {
|
|
7134
|
-
const objects = await this.client.multiGetObjects({
|
|
7135
|
-
ids: coinIds,
|
|
7136
|
-
options: { showContent: true, showOwner: true }
|
|
7137
|
-
});
|
|
7138
|
-
for (const obj of objects) {
|
|
7139
|
-
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) {
|
|
7140
|
-
const fields = obj.data.content.fields;
|
|
7141
|
-
all.push({ coinObjectId: obj.data.objectId, balance: String(fields.balance ?? "0") });
|
|
7142
|
-
}
|
|
7143
|
-
}
|
|
7144
|
-
}
|
|
7145
|
-
}
|
|
7146
|
-
return all;
|
|
7147
|
-
}
|
|
7148
|
-
_mergeCoinsInTx(tx, coins) {
|
|
7149
|
-
if (coins.length === 0) throw new exports.T2000Error("INSUFFICIENT_BALANCE", "No coins to merge");
|
|
7150
|
-
const primary = tx.object(coins[0].coinObjectId);
|
|
7151
|
-
if (coins.length > 1) {
|
|
7152
|
-
tx.mergeCoins(primary, coins.slice(1).map((c) => tx.object(c.coinObjectId)));
|
|
7153
|
-
}
|
|
7154
|
-
return primary;
|
|
7155
|
-
}
|
|
7156
|
-
_lastFundDigest;
|
|
7157
7060
|
async _autoFundFromSavings(shortfall) {
|
|
7158
7061
|
const positions = await this.positions();
|
|
7159
7062
|
const savingsTotal = positions.positions.filter((p) => p.type === "save").reduce((sum, p) => sum + p.amount, 0);
|
|
@@ -7181,7 +7084,6 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7181
7084
|
if (!usdcReceived) {
|
|
7182
7085
|
throw new exports.T2000Error("WITHDRAW_FAILED", "Withdraw TX did not produce USDC");
|
|
7183
7086
|
}
|
|
7184
|
-
this._lastFundDigest = result.tx;
|
|
7185
7087
|
}
|
|
7186
7088
|
async maxWithdraw() {
|
|
7187
7089
|
const adapter = await this.resolveLending(void 0, "USDC", "withdraw");
|
|
@@ -7250,11 +7152,18 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7250
7152
|
if (adapter.addRepayToTx) {
|
|
7251
7153
|
const tx2 = new transactions.Transaction();
|
|
7252
7154
|
tx2.setSender(this._address);
|
|
7253
|
-
const coins = await this._fetchCoins(targetAssetInfo.type);
|
|
7254
|
-
if (coins.length === 0) throw new exports.T2000Error("INSUFFICIENT_BALANCE", `No ${targetAssetInfo.displayName} coins`);
|
|
7255
|
-
const merged = this._mergeCoinsInTx(tx2, coins);
|
|
7256
7155
|
const raw = BigInt(Math.floor(repayAmount * 10 ** targetAssetInfo.decimals));
|
|
7257
|
-
const
|
|
7156
|
+
const bal = await this.client.getBalance({
|
|
7157
|
+
owner: this._address,
|
|
7158
|
+
coinType: targetAssetInfo.type
|
|
7159
|
+
});
|
|
7160
|
+
if (BigInt(bal.totalBalance) < raw) {
|
|
7161
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${targetAssetInfo.displayName} balance for repayment`, {
|
|
7162
|
+
available: Number(bal.totalBalance) / 10 ** targetAssetInfo.decimals,
|
|
7163
|
+
required: repayAmount
|
|
7164
|
+
});
|
|
7165
|
+
}
|
|
7166
|
+
const repayCoin = transactions.coinWithBalance({ type: targetAssetInfo.type, balance: raw })(tx2);
|
|
7258
7167
|
await adapter.addRepayToTx(tx2, this._address, repayCoin, target.asset);
|
|
7259
7168
|
return tx2;
|
|
7260
7169
|
}
|
|
@@ -7285,20 +7194,23 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7285
7194
|
if (canPTB) {
|
|
7286
7195
|
const tx = new transactions.Transaction();
|
|
7287
7196
|
tx.setSender(this._address);
|
|
7288
|
-
const assetMerged = /* @__PURE__ */ new Map();
|
|
7289
7197
|
const uniqueAssets = Array.from(new Set(entries.map((e) => e.borrow.asset)));
|
|
7290
7198
|
for (const asset of uniqueAssets) {
|
|
7291
7199
|
const info = SUPPORTED_ASSETS[asset];
|
|
7292
7200
|
if (!info) throw new exports.T2000Error("ASSET_NOT_SUPPORTED", `Cannot repay unknown asset: ${asset}`);
|
|
7293
|
-
const
|
|
7294
|
-
|
|
7295
|
-
|
|
7201
|
+
const required = entries.filter((e) => e.borrow.asset === asset).reduce((sum, e) => sum + BigInt(Math.floor(e.borrow.amount * 10 ** info.decimals)), 0n);
|
|
7202
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: info.type });
|
|
7203
|
+
if (BigInt(bal.totalBalance) < required) {
|
|
7204
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${info.displayName} balance for repayment`, {
|
|
7205
|
+
available: Number(bal.totalBalance) / 10 ** info.decimals,
|
|
7206
|
+
required: Number(required) / 10 ** info.decimals
|
|
7207
|
+
});
|
|
7208
|
+
}
|
|
7296
7209
|
}
|
|
7297
7210
|
for (const { borrow, adapter } of entries) {
|
|
7298
7211
|
const info = SUPPORTED_ASSETS[borrow.asset];
|
|
7299
|
-
const merged = assetMerged.get(borrow.asset);
|
|
7300
7212
|
const raw = BigInt(Math.floor(borrow.amount * 10 ** info.decimals));
|
|
7301
|
-
const
|
|
7213
|
+
const repayCoin = transactions.coinWithBalance({ type: info.type, balance: raw })(tx);
|
|
7302
7214
|
await adapter.addRepayToTx(tx, this._address, repayCoin, borrow.asset);
|
|
7303
7215
|
totalRepaid += borrow.amount;
|
|
7304
7216
|
}
|
|
@@ -7429,8 +7341,8 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7429
7341
|
totalGasCost: 0
|
|
7430
7342
|
};
|
|
7431
7343
|
}
|
|
7432
|
-
const
|
|
7433
|
-
const preUsdcRaw =
|
|
7344
|
+
const preUsdcBal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7345
|
+
const preUsdcRaw = BigInt(preUsdcBal.totalBalance);
|
|
7434
7346
|
const claimResult = await this.claimRewards();
|
|
7435
7347
|
if (!claimResult.tx) {
|
|
7436
7348
|
return {
|
|
@@ -7453,8 +7365,8 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7453
7365
|
const decimals = getDecimalsForCoinType(reward.coinType) ?? 9;
|
|
7454
7366
|
const rawAmount = BigInt(Math.floor(reward.amount * 10 ** decimals));
|
|
7455
7367
|
if (rawAmount <= 0n) continue;
|
|
7456
|
-
const
|
|
7457
|
-
if (
|
|
7368
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: reward.coinType });
|
|
7369
|
+
if (BigInt(bal.totalBalance) < rawAmount) continue;
|
|
7458
7370
|
const route = await findSwapRoute2({
|
|
7459
7371
|
walletAddress: this._address,
|
|
7460
7372
|
from: reward.coinType,
|
|
@@ -7466,10 +7378,9 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7466
7378
|
const swapResult = await executeTx(this.client, this._signer, async () => {
|
|
7467
7379
|
const tx = new transactions.Transaction();
|
|
7468
7380
|
tx.setSender(this._address);
|
|
7469
|
-
const
|
|
7470
|
-
if (
|
|
7471
|
-
const
|
|
7472
|
-
const [inputCoin] = tx.splitCoins(merged, [rawAmount]);
|
|
7381
|
+
const freshBal = await this.client.getBalance({ owner: this._address, coinType: reward.coinType });
|
|
7382
|
+
if (BigInt(freshBal.totalBalance) < rawAmount) return tx;
|
|
7383
|
+
const inputCoin = transactions.coinWithBalance({ type: reward.coinType, balance: rawAmount })(tx);
|
|
7473
7384
|
const outputCoin = await buildSwapTx2({
|
|
7474
7385
|
walletAddress: this._address,
|
|
7475
7386
|
route,
|
|
@@ -7486,8 +7397,8 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7486
7397
|
console.warn(`[compound] Failed to swap ${reward.symbol}:`, err instanceof Error ? err.message : err);
|
|
7487
7398
|
}
|
|
7488
7399
|
}
|
|
7489
|
-
const
|
|
7490
|
-
const postUsdcRaw =
|
|
7400
|
+
const postUsdcBal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7401
|
+
const postUsdcRaw = BigInt(postUsdcBal.totalBalance);
|
|
7491
7402
|
const gainedRaw = postUsdcRaw > preUsdcRaw ? postUsdcRaw - preUsdcRaw : 0n;
|
|
7492
7403
|
const depositUsdc = Number(gainedRaw) / 10 ** USDC_DEC;
|
|
7493
7404
|
let depositTx = "";
|
|
@@ -7497,10 +7408,11 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
7497
7408
|
const depositResult = await executeTx(this.client, this._signer, async () => {
|
|
7498
7409
|
const tx = new transactions.Transaction();
|
|
7499
7410
|
tx.setSender(this._address);
|
|
7500
|
-
const
|
|
7501
|
-
if (
|
|
7502
|
-
|
|
7503
|
-
|
|
7411
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7412
|
+
if (BigInt(bal.totalBalance) < gainedRaw) {
|
|
7413
|
+
throw new exports.T2000Error("INSUFFICIENT_BALANCE", "No USDC available after swap");
|
|
7414
|
+
}
|
|
7415
|
+
const inputCoin = transactions.coinWithBalance({ type: USDC_TYPE2, balance: gainedRaw })(tx);
|
|
7504
7416
|
await adapter.addSaveToTx(tx, this._address, inputCoin, "USDC");
|
|
7505
7417
|
return tx;
|
|
7506
7418
|
});
|
|
@@ -7996,7 +7908,8 @@ var WRITE_APPENDER_REGISTRY = {
|
|
|
7996
7908
|
overlayFee: ctx.overlayFee,
|
|
7997
7909
|
providers,
|
|
7998
7910
|
inputCoin: ctx.chainedCoin,
|
|
7999
|
-
precomputedRoute: input.precomputedRoute
|
|
7911
|
+
precomputedRoute: input.precomputedRoute,
|
|
7912
|
+
sponsoredContext: ctx.sponsoredContext
|
|
8000
7913
|
});
|
|
8001
7914
|
if (!ctx.isOutputConsumed) {
|
|
8002
7915
|
tx.transferObjects([result.coin], ctx.sender);
|