@t2000/sdk 2.13.1 → 2.14.0
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 +139 -237
- 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 +140 -238
- package/dist/index.js.map +1 -1
- package/dist/{types-BY6ovQGK.d.cts → types-1WUNZK-9.d.cts} +1 -1
- package/dist/{types-epj9U13o.d.cts → types-CFJrgLm2.d.cts} +21 -13
- package/dist/{types-epj9U13o.d.ts → types-CFJrgLm2.d.ts} +21 -13
- package/dist/{types-WeZQDV54.d.ts → types-D65N3sBO.d.ts} +1 -1
- 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
|
|
|
@@ -1521,26 +1471,16 @@ async function buildSendTx({
|
|
|
1521
1471
|
const rawAmount = displayToRaw(amount, assetInfo.decimals);
|
|
1522
1472
|
const tx = new Transaction();
|
|
1523
1473
|
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);
|
|
1474
|
+
const balanceResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
1475
|
+
const totalBalance = BigInt(balanceResp.totalBalance);
|
|
1476
|
+
if (totalBalance < rawAmount) {
|
|
1477
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, {
|
|
1478
|
+
available: Number(totalBalance) / 10 ** assetInfo.decimals,
|
|
1479
|
+
required: amount
|
|
1480
|
+
});
|
|
1543
1481
|
}
|
|
1482
|
+
const sendCoin = asset === "SUI" ? tx.splitCoins(tx.gas, [rawAmount])[0] : coinWithBalance({ type: assetInfo.type, balance: rawAmount })(tx);
|
|
1483
|
+
tx.transferObjects([sendCoin], recipient);
|
|
1544
1484
|
return tx;
|
|
1545
1485
|
}
|
|
1546
1486
|
function addSendToTx(tx, coin, recipient) {
|
|
@@ -5487,26 +5427,6 @@ function resolveAssetInfo(asset) {
|
|
|
5487
5427
|
}
|
|
5488
5428
|
throw new T2000Error("ASSET_NOT_SUPPORTED", `Unknown asset: ${asset}`);
|
|
5489
5429
|
}
|
|
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
5430
|
async function getPositions(client, address) {
|
|
5511
5431
|
try {
|
|
5512
5432
|
const naviPositions = await $e(address, {
|
|
@@ -5597,13 +5517,15 @@ async function buildSaveTx(client, address, amount, options = {}) {
|
|
|
5597
5517
|
}
|
|
5598
5518
|
const asset = options.asset ?? "USDC";
|
|
5599
5519
|
const assetInfo = resolveAssetInfo(asset);
|
|
5600
|
-
const
|
|
5601
|
-
|
|
5602
|
-
|
|
5520
|
+
const balResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
5521
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
5522
|
+
if (totalBalance === 0n) {
|
|
5523
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} balance found`);
|
|
5524
|
+
}
|
|
5603
5525
|
const tx = new Transaction();
|
|
5604
5526
|
tx.setSender(address);
|
|
5605
|
-
const coinObj = mergeCoins(tx, coins);
|
|
5606
5527
|
const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
|
|
5528
|
+
const coinObj = coinWithBalance({ type: assetInfo.type, balance: BigInt(rawAmount) })(tx);
|
|
5607
5529
|
try {
|
|
5608
5530
|
await Ce(tx, assetInfo.type, coinObj, {
|
|
5609
5531
|
...sdkOptions(client),
|
|
@@ -5735,18 +5657,19 @@ async function buildRepayTx(client, address, amount, options = {}) {
|
|
|
5735
5657
|
}
|
|
5736
5658
|
const asset = options.asset ?? "USDC";
|
|
5737
5659
|
const assetInfo = resolveAssetInfo(asset);
|
|
5738
|
-
const
|
|
5739
|
-
|
|
5740
|
-
|
|
5660
|
+
const balResp = await client.getBalance({ owner: address, coinType: assetInfo.type });
|
|
5661
|
+
const totalBalance = BigInt(balResp.totalBalance);
|
|
5662
|
+
if (totalBalance === 0n) {
|
|
5663
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} to repay with. Withdraw some savings first to get cash.`);
|
|
5664
|
+
}
|
|
5741
5665
|
const rawRequested = Number(stableToRaw(amount, assetInfo.decimals));
|
|
5742
5666
|
if (Number(totalBalance) < rawRequested && Number(totalBalance) < 1e3) {
|
|
5743
5667
|
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
5668
|
}
|
|
5745
5669
|
const tx = new Transaction();
|
|
5746
5670
|
tx.setSender(address);
|
|
5747
|
-
const coinObj = mergeCoins(tx, coins);
|
|
5748
5671
|
const rawAmount = Math.min(rawRequested, Number(totalBalance));
|
|
5749
|
-
const
|
|
5672
|
+
const repayCoin = coinWithBalance({ type: assetInfo.type, balance: BigInt(rawAmount) })(tx);
|
|
5750
5673
|
await refreshOracle(tx, client, address, {
|
|
5751
5674
|
skipOracle: options.skipOracle,
|
|
5752
5675
|
skipPythUpdate: options.skipPythUpdate
|
|
@@ -6409,10 +6332,10 @@ var ContactManager = class {
|
|
|
6409
6332
|
}
|
|
6410
6333
|
};
|
|
6411
6334
|
var DEFAULT_CONFIG_DIR = join$1(homedir(), ".t2000");
|
|
6412
|
-
async function executeTx(client, signer, buildTx) {
|
|
6335
|
+
async function executeTx(client, signer, buildTx, options = {}) {
|
|
6413
6336
|
const tx = await buildTx();
|
|
6414
6337
|
tx.setSender(signer.getAddress());
|
|
6415
|
-
const txBytes = await tx.build({ client });
|
|
6338
|
+
const txBytes = await tx.build({ client: options.buildClient ?? client });
|
|
6416
6339
|
const { signature } = await signer.signTransaction(txBytes);
|
|
6417
6340
|
const result = await client.executeTransactionBlock({
|
|
6418
6341
|
transactionBlock: txBytes,
|
|
@@ -6514,9 +6437,15 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6514
6437
|
this.enforcer.check({ operation: "pay", amount: options.maxPrice ?? 1 });
|
|
6515
6438
|
const { Mppx } = await import('mppx/client');
|
|
6516
6439
|
const { sui, USDC } = await import('@suimpp/mpp/client');
|
|
6440
|
+
const { SuiGrpcClient } = await import('@mysten/sui/grpc');
|
|
6517
6441
|
const client = this.client;
|
|
6518
6442
|
const signer = this._signer;
|
|
6519
6443
|
const signerAddress = signer.getAddress();
|
|
6444
|
+
let paymentDigest;
|
|
6445
|
+
let gasCostSui = 0;
|
|
6446
|
+
const network = client.network === "testnet" ? "testnet" : "mainnet";
|
|
6447
|
+
const grpcBaseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
|
|
6448
|
+
const grpcClient = new SuiGrpcClient({ baseUrl: grpcBaseUrl, network });
|
|
6520
6449
|
const mppx = Mppx.create({
|
|
6521
6450
|
polyfill: false,
|
|
6522
6451
|
methods: [sui({
|
|
@@ -6527,7 +6456,9 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6527
6456
|
signPersonalMessage: (bytes) => signer.signPersonalMessage(bytes)
|
|
6528
6457
|
},
|
|
6529
6458
|
execute: async (tx) => {
|
|
6530
|
-
const result = await executeTx(client, signer, () => tx);
|
|
6459
|
+
const result = await executeTx(client, signer, () => tx, { buildClient: grpcClient });
|
|
6460
|
+
paymentDigest = result.digest;
|
|
6461
|
+
gasCostSui = result.gasCostSui;
|
|
6531
6462
|
return { digest: result.digest };
|
|
6532
6463
|
}
|
|
6533
6464
|
})]
|
|
@@ -6546,8 +6477,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6546
6477
|
} catch {
|
|
6547
6478
|
body = null;
|
|
6548
6479
|
}
|
|
6549
|
-
const
|
|
6550
|
-
const paid = !!receiptHeader;
|
|
6480
|
+
const paid = !!paymentDigest;
|
|
6551
6481
|
if (paid) {
|
|
6552
6482
|
this.enforcer.recordUsage(options.maxPrice ?? 1);
|
|
6553
6483
|
}
|
|
@@ -6556,7 +6486,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6556
6486
|
body,
|
|
6557
6487
|
paid,
|
|
6558
6488
|
cost: paid ? options.maxPrice ?? void 0 : void 0,
|
|
6559
|
-
|
|
6489
|
+
gasCostSui: paid ? gasCostSui : void 0,
|
|
6490
|
+
receipt: paymentDigest ? { reference: paymentDigest, timestamp: (/* @__PURE__ */ new Date()).toISOString() } : void 0
|
|
6560
6491
|
};
|
|
6561
6492
|
}
|
|
6562
6493
|
// -- VOLO vSUI Staking --
|
|
@@ -6585,8 +6516,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6585
6516
|
let vSuiAmount;
|
|
6586
6517
|
if (params.amount === "all") {
|
|
6587
6518
|
amountMist = "all";
|
|
6588
|
-
const
|
|
6589
|
-
vSuiAmount =
|
|
6519
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: VSUI_TYPE2 });
|
|
6520
|
+
vSuiAmount = Number(bal.totalBalance) / 1e9;
|
|
6590
6521
|
} else {
|
|
6591
6522
|
amountMist = BigInt(Math.floor(params.amount * 1e9));
|
|
6592
6523
|
vSuiAmount = params.amount;
|
|
@@ -6642,10 +6573,14 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6642
6573
|
if (fromType === "0x2::sui::SUI") {
|
|
6643
6574
|
[inputCoin] = tx.splitCoins(tx.gas, [rawAmount]);
|
|
6644
6575
|
} else {
|
|
6645
|
-
const
|
|
6646
|
-
if (
|
|
6647
|
-
|
|
6648
|
-
|
|
6576
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: fromType });
|
|
6577
|
+
if (BigInt(bal.totalBalance) < rawAmount) {
|
|
6578
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${params.from} balance.`, {
|
|
6579
|
+
available: Number(bal.totalBalance) / 10 ** fromDecimals,
|
|
6580
|
+
required: params.amount
|
|
6581
|
+
});
|
|
6582
|
+
}
|
|
6583
|
+
inputCoin = coinWithBalance({ type: fromType, balance: rawAmount })(tx);
|
|
6649
6584
|
}
|
|
6650
6585
|
const outputCoin = await buildSwapTx2({
|
|
6651
6586
|
walletAddress: this._address,
|
|
@@ -6902,11 +6837,15 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
6902
6837
|
if (canPTB) {
|
|
6903
6838
|
const tx2 = new Transaction();
|
|
6904
6839
|
tx2.setSender(this._address);
|
|
6905
|
-
const coins = await this._fetchCoins(assetInfo.type);
|
|
6906
|
-
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins found`);
|
|
6907
|
-
const merged = this._mergeCoinsInTx(tx2, coins);
|
|
6908
6840
|
const rawAmount = BigInt(Math.floor(saveAmount * 10 ** assetInfo.decimals));
|
|
6909
|
-
const
|
|
6841
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: assetInfo.type });
|
|
6842
|
+
if (BigInt(bal.totalBalance) < rawAmount) {
|
|
6843
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${assetInfo.displayName} balance`, {
|
|
6844
|
+
available: Number(bal.totalBalance) / 10 ** assetInfo.decimals,
|
|
6845
|
+
required: saveAmount
|
|
6846
|
+
});
|
|
6847
|
+
}
|
|
6848
|
+
const inputCoin = coinWithBalance({ type: assetInfo.type, balance: rawAmount })(tx2);
|
|
6910
6849
|
await adapter.addSaveToTx(tx2, this._address, inputCoin, asset);
|
|
6911
6850
|
return tx2;
|
|
6912
6851
|
}
|
|
@@ -7101,52 +7040,6 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7101
7040
|
return 0;
|
|
7102
7041
|
}
|
|
7103
7042
|
}
|
|
7104
|
-
async _fetchCoins(coinType) {
|
|
7105
|
-
const all = [];
|
|
7106
|
-
let cursor;
|
|
7107
|
-
let hasNext = true;
|
|
7108
|
-
while (hasNext) {
|
|
7109
|
-
const page = await this.client.getCoins({ owner: this._address, coinType, cursor: cursor ?? void 0 });
|
|
7110
|
-
all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));
|
|
7111
|
-
cursor = page.nextCursor;
|
|
7112
|
-
hasNext = page.hasNextPage;
|
|
7113
|
-
}
|
|
7114
|
-
if (all.length > 0) {
|
|
7115
|
-
this._lastFundDigest = void 0;
|
|
7116
|
-
return all;
|
|
7117
|
-
}
|
|
7118
|
-
if (this._lastFundDigest && coinType === SUPPORTED_ASSETS.USDC.type) {
|
|
7119
|
-
const txInfo = await this.client.getTransactionBlock({
|
|
7120
|
-
digest: this._lastFundDigest,
|
|
7121
|
-
options: { showObjectChanges: true }
|
|
7122
|
-
});
|
|
7123
|
-
const coinIds = (txInfo.objectChanges ?? []).filter(
|
|
7124
|
-
(c) => (c.type === "created" || c.type === "mutated") && "objectType" in c && typeof c.objectType === "string" && c.objectType.includes("0x2::coin::Coin") && c.objectType.includes(coinType)
|
|
7125
|
-
).map((c) => c.objectId);
|
|
7126
|
-
if (coinIds.length > 0) {
|
|
7127
|
-
const objects = await this.client.multiGetObjects({
|
|
7128
|
-
ids: coinIds,
|
|
7129
|
-
options: { showContent: true, showOwner: true }
|
|
7130
|
-
});
|
|
7131
|
-
for (const obj of objects) {
|
|
7132
|
-
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) {
|
|
7133
|
-
const fields = obj.data.content.fields;
|
|
7134
|
-
all.push({ coinObjectId: obj.data.objectId, balance: String(fields.balance ?? "0") });
|
|
7135
|
-
}
|
|
7136
|
-
}
|
|
7137
|
-
}
|
|
7138
|
-
}
|
|
7139
|
-
return all;
|
|
7140
|
-
}
|
|
7141
|
-
_mergeCoinsInTx(tx, coins) {
|
|
7142
|
-
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", "No coins to merge");
|
|
7143
|
-
const primary = tx.object(coins[0].coinObjectId);
|
|
7144
|
-
if (coins.length > 1) {
|
|
7145
|
-
tx.mergeCoins(primary, coins.slice(1).map((c) => tx.object(c.coinObjectId)));
|
|
7146
|
-
}
|
|
7147
|
-
return primary;
|
|
7148
|
-
}
|
|
7149
|
-
_lastFundDigest;
|
|
7150
7043
|
async _autoFundFromSavings(shortfall) {
|
|
7151
7044
|
const positions = await this.positions();
|
|
7152
7045
|
const savingsTotal = positions.positions.filter((p) => p.type === "save").reduce((sum, p) => sum + p.amount, 0);
|
|
@@ -7174,7 +7067,6 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7174
7067
|
if (!usdcReceived) {
|
|
7175
7068
|
throw new T2000Error("WITHDRAW_FAILED", "Withdraw TX did not produce USDC");
|
|
7176
7069
|
}
|
|
7177
|
-
this._lastFundDigest = result.tx;
|
|
7178
7070
|
}
|
|
7179
7071
|
async maxWithdraw() {
|
|
7180
7072
|
const adapter = await this.resolveLending(void 0, "USDC", "withdraw");
|
|
@@ -7243,11 +7135,18 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7243
7135
|
if (adapter.addRepayToTx) {
|
|
7244
7136
|
const tx2 = new Transaction();
|
|
7245
7137
|
tx2.setSender(this._address);
|
|
7246
|
-
const coins = await this._fetchCoins(targetAssetInfo.type);
|
|
7247
|
-
if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${targetAssetInfo.displayName} coins`);
|
|
7248
|
-
const merged = this._mergeCoinsInTx(tx2, coins);
|
|
7249
7138
|
const raw = BigInt(Math.floor(repayAmount * 10 ** targetAssetInfo.decimals));
|
|
7250
|
-
const
|
|
7139
|
+
const bal = await this.client.getBalance({
|
|
7140
|
+
owner: this._address,
|
|
7141
|
+
coinType: targetAssetInfo.type
|
|
7142
|
+
});
|
|
7143
|
+
if (BigInt(bal.totalBalance) < raw) {
|
|
7144
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${targetAssetInfo.displayName} balance for repayment`, {
|
|
7145
|
+
available: Number(bal.totalBalance) / 10 ** targetAssetInfo.decimals,
|
|
7146
|
+
required: repayAmount
|
|
7147
|
+
});
|
|
7148
|
+
}
|
|
7149
|
+
const repayCoin = coinWithBalance({ type: targetAssetInfo.type, balance: raw })(tx2);
|
|
7251
7150
|
await adapter.addRepayToTx(tx2, this._address, repayCoin, target.asset);
|
|
7252
7151
|
return tx2;
|
|
7253
7152
|
}
|
|
@@ -7278,20 +7177,23 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7278
7177
|
if (canPTB) {
|
|
7279
7178
|
const tx = new Transaction();
|
|
7280
7179
|
tx.setSender(this._address);
|
|
7281
|
-
const assetMerged = /* @__PURE__ */ new Map();
|
|
7282
7180
|
const uniqueAssets = Array.from(new Set(entries.map((e) => e.borrow.asset)));
|
|
7283
7181
|
for (const asset of uniqueAssets) {
|
|
7284
7182
|
const info = SUPPORTED_ASSETS[asset];
|
|
7285
7183
|
if (!info) throw new T2000Error("ASSET_NOT_SUPPORTED", `Cannot repay unknown asset: ${asset}`);
|
|
7286
|
-
const
|
|
7287
|
-
|
|
7288
|
-
|
|
7184
|
+
const required = entries.filter((e) => e.borrow.asset === asset).reduce((sum, e) => sum + BigInt(Math.floor(e.borrow.amount * 10 ** info.decimals)), 0n);
|
|
7185
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: info.type });
|
|
7186
|
+
if (BigInt(bal.totalBalance) < required) {
|
|
7187
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${info.displayName} balance for repayment`, {
|
|
7188
|
+
available: Number(bal.totalBalance) / 10 ** info.decimals,
|
|
7189
|
+
required: Number(required) / 10 ** info.decimals
|
|
7190
|
+
});
|
|
7191
|
+
}
|
|
7289
7192
|
}
|
|
7290
7193
|
for (const { borrow, adapter } of entries) {
|
|
7291
7194
|
const info = SUPPORTED_ASSETS[borrow.asset];
|
|
7292
|
-
const merged = assetMerged.get(borrow.asset);
|
|
7293
7195
|
const raw = BigInt(Math.floor(borrow.amount * 10 ** info.decimals));
|
|
7294
|
-
const
|
|
7196
|
+
const repayCoin = coinWithBalance({ type: info.type, balance: raw })(tx);
|
|
7295
7197
|
await adapter.addRepayToTx(tx, this._address, repayCoin, borrow.asset);
|
|
7296
7198
|
totalRepaid += borrow.amount;
|
|
7297
7199
|
}
|
|
@@ -7422,8 +7324,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7422
7324
|
totalGasCost: 0
|
|
7423
7325
|
};
|
|
7424
7326
|
}
|
|
7425
|
-
const
|
|
7426
|
-
const preUsdcRaw =
|
|
7327
|
+
const preUsdcBal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7328
|
+
const preUsdcRaw = BigInt(preUsdcBal.totalBalance);
|
|
7427
7329
|
const claimResult = await this.claimRewards();
|
|
7428
7330
|
if (!claimResult.tx) {
|
|
7429
7331
|
return {
|
|
@@ -7446,8 +7348,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7446
7348
|
const decimals = getDecimalsForCoinType(reward.coinType) ?? 9;
|
|
7447
7349
|
const rawAmount = BigInt(Math.floor(reward.amount * 10 ** decimals));
|
|
7448
7350
|
if (rawAmount <= 0n) continue;
|
|
7449
|
-
const
|
|
7450
|
-
if (
|
|
7351
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: reward.coinType });
|
|
7352
|
+
if (BigInt(bal.totalBalance) < rawAmount) continue;
|
|
7451
7353
|
const route = await findSwapRoute2({
|
|
7452
7354
|
walletAddress: this._address,
|
|
7453
7355
|
from: reward.coinType,
|
|
@@ -7459,10 +7361,9 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7459
7361
|
const swapResult = await executeTx(this.client, this._signer, async () => {
|
|
7460
7362
|
const tx = new Transaction();
|
|
7461
7363
|
tx.setSender(this._address);
|
|
7462
|
-
const
|
|
7463
|
-
if (
|
|
7464
|
-
const
|
|
7465
|
-
const [inputCoin] = tx.splitCoins(merged, [rawAmount]);
|
|
7364
|
+
const freshBal = await this.client.getBalance({ owner: this._address, coinType: reward.coinType });
|
|
7365
|
+
if (BigInt(freshBal.totalBalance) < rawAmount) return tx;
|
|
7366
|
+
const inputCoin = coinWithBalance({ type: reward.coinType, balance: rawAmount })(tx);
|
|
7466
7367
|
const outputCoin = await buildSwapTx2({
|
|
7467
7368
|
walletAddress: this._address,
|
|
7468
7369
|
route,
|
|
@@ -7479,8 +7380,8 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7479
7380
|
console.warn(`[compound] Failed to swap ${reward.symbol}:`, err instanceof Error ? err.message : err);
|
|
7480
7381
|
}
|
|
7481
7382
|
}
|
|
7482
|
-
const
|
|
7483
|
-
const postUsdcRaw =
|
|
7383
|
+
const postUsdcBal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7384
|
+
const postUsdcRaw = BigInt(postUsdcBal.totalBalance);
|
|
7484
7385
|
const gainedRaw = postUsdcRaw > preUsdcRaw ? postUsdcRaw - preUsdcRaw : 0n;
|
|
7485
7386
|
const depositUsdc = Number(gainedRaw) / 10 ** USDC_DEC;
|
|
7486
7387
|
let depositTx = "";
|
|
@@ -7490,10 +7391,11 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
7490
7391
|
const depositResult = await executeTx(this.client, this._signer, async () => {
|
|
7491
7392
|
const tx = new Transaction();
|
|
7492
7393
|
tx.setSender(this._address);
|
|
7493
|
-
const
|
|
7494
|
-
if (
|
|
7495
|
-
|
|
7496
|
-
|
|
7394
|
+
const bal = await this.client.getBalance({ owner: this._address, coinType: USDC_TYPE2 });
|
|
7395
|
+
if (BigInt(bal.totalBalance) < gainedRaw) {
|
|
7396
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", "No USDC available after swap");
|
|
7397
|
+
}
|
|
7398
|
+
const inputCoin = coinWithBalance({ type: USDC_TYPE2, balance: gainedRaw })(tx);
|
|
7497
7399
|
await adapter.addSaveToTx(tx, this._address, inputCoin, "USDC");
|
|
7498
7400
|
return tx;
|
|
7499
7401
|
});
|