@t2000/sdk 0.17.10 → 0.17.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -4346,7 +4346,10 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4346
4346
  }
4347
4347
  const didAutoWithdraw = !!(pos.earning && pos.earningProtocol);
4348
4348
  if (didAutoWithdraw) {
4349
- await this.investUnearn({ asset: params.asset });
4349
+ const unearnResult = await this.investUnearn({ asset: params.asset });
4350
+ if (unearnResult.tx) {
4351
+ await this.client.waitForTransaction({ digest: unearnResult.tx, options: { showEffects: true } });
4352
+ }
4350
4353
  }
4351
4354
  const assetInfo = SUPPORTED_ASSETS[params.asset];
4352
4355
  const gasReserve = params.asset === "SUI" ? GAS_RESERVE_MIN : 0;
@@ -4357,8 +4360,8 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4357
4360
  coinType: assetInfo.type
4358
4361
  });
4359
4362
  walletAmount = Number(assetBalance.totalBalance) / 10 ** assetInfo.decimals;
4360
- if (!didAutoWithdraw || walletAmount > gasReserve || attempt >= 3) break;
4361
- await new Promise((r) => setTimeout(r, 1e3));
4363
+ if (!didAutoWithdraw || walletAmount > gasReserve || attempt >= 5) break;
4364
+ await new Promise((r) => setTimeout(r, 1500));
4362
4365
  }
4363
4366
  const maxSellable = Math.max(0, walletAmount - gasReserve);
4364
4367
  let sellAmountAsset;
@@ -4629,25 +4632,33 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4629
4632
  if (!swapAdapter?.addSwapToTx) {
4630
4633
  throw new T2000Error("PROTOCOL_UNAVAILABLE", "Swap adapter does not support composable PTB");
4631
4634
  }
4635
+ for (const pos of stratPositions) {
4636
+ const directPos = this.portfolio.getPosition(pos.asset);
4637
+ if (directPos?.earning && directPos.earningProtocol) {
4638
+ await this.investUnearn({ asset: pos.asset });
4639
+ await new Promise((r) => setTimeout(r, 1500));
4640
+ }
4641
+ }
4632
4642
  let swapMetas = [];
4633
- const gasResult = await executeWithGas(this.client, this.keypair, async () => {
4643
+ const buildSellPtb = async () => {
4634
4644
  swapMetas = [];
4635
4645
  const tx = new transactions.Transaction();
4636
4646
  tx.setSender(this._address);
4637
4647
  const usdcOutputs = [];
4638
4648
  for (const pos of stratPositions) {
4639
4649
  const assetInfo = SUPPORTED_ASSETS[pos.asset];
4650
+ const bal = await this.client.getBalance({ owner: this._address, coinType: assetInfo.type });
4651
+ const walletAmount = Number(bal.totalBalance) / 10 ** assetInfo.decimals;
4640
4652
  const gasReserve = pos.asset === "SUI" ? GAS_RESERVE_MIN : 0;
4641
- const sellAmount = Math.max(0, pos.totalAmount - gasReserve);
4653
+ const sellAmount = Math.max(0, Math.min(pos.totalAmount, walletAmount) - gasReserve);
4654
+ if (sellAmount <= 0) continue;
4642
4655
  const rawAmount = BigInt(Math.floor(sellAmount * 10 ** assetInfo.decimals));
4643
4656
  let splitCoin;
4644
4657
  if (pos.asset === "SUI") {
4645
4658
  [splitCoin] = tx.splitCoins(tx.gas, [rawAmount]);
4646
4659
  } else {
4647
4660
  const coins = await this._fetchCoins(assetInfo.type);
4648
- if (coins.length === 0) {
4649
- throw new T2000Error("INSUFFICIENT_BALANCE", `No ${pos.asset} coins in wallet`);
4650
- }
4661
+ if (coins.length === 0) continue;
4651
4662
  const merged = this._mergeCoinsInTx(tx, coins);
4652
4663
  [splitCoin] = tx.splitCoins(merged, [rawAmount]);
4653
4664
  }
@@ -4664,12 +4675,31 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4664
4675
  usdcOutputs.push(outputCoin);
4665
4676
  swapMetas.push({ asset: pos.asset, amount: sellAmount, estimatedOut, toDecimals });
4666
4677
  }
4678
+ if (usdcOutputs.length === 0) {
4679
+ throw new T2000Error("INSUFFICIENT_BALANCE", "No assets available to sell");
4680
+ }
4667
4681
  if (usdcOutputs.length > 1) {
4668
4682
  tx.mergeCoins(usdcOutputs[0], usdcOutputs.slice(1));
4669
4683
  }
4670
4684
  tx.transferObjects([usdcOutputs[0]], this._address);
4671
4685
  return tx;
4672
- });
4686
+ };
4687
+ let gasResult;
4688
+ const MAX_RETRIES = 3;
4689
+ for (let attempt = 0; ; attempt++) {
4690
+ try {
4691
+ gasResult = await executeWithGas(this.client, this.keypair, buildSellPtb);
4692
+ break;
4693
+ } catch (err) {
4694
+ const msg = err instanceof Error ? err.message : String(err);
4695
+ const isSlippage = msg.includes("slippage") || msg.includes("amount_out_slippage");
4696
+ if (isSlippage && attempt < MAX_RETRIES) {
4697
+ await new Promise((r) => setTimeout(r, 2e3 * (attempt + 1)));
4698
+ continue;
4699
+ }
4700
+ throw err;
4701
+ }
4702
+ }
4673
4703
  const digest = gasResult.digest;
4674
4704
  const now = (/* @__PURE__ */ new Date()).toISOString();
4675
4705
  const sells = [];
@@ -4704,6 +4734,9 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4704
4734
  totalProceeds += usdValue;
4705
4735
  totalPnL += pnl;
4706
4736
  }
4737
+ if (this.portfolio.hasStrategyPositions(params.strategy)) {
4738
+ this.portfolio.clearStrategy(params.strategy);
4739
+ }
4707
4740
  return {
4708
4741
  success: true,
4709
4742
  strategy: params.strategy,
@@ -4777,8 +4810,11 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4777
4810
  const usdcCoins = [];
4778
4811
  for (const sell of sellOps) {
4779
4812
  const assetInfo = SUPPORTED_ASSETS[sell.asset];
4813
+ const bal = await this.client.getBalance({ owner: this._address, coinType: assetInfo.type });
4814
+ const walletAmount = Number(bal.totalBalance) / 10 ** assetInfo.decimals;
4780
4815
  const gasReserve = sell.asset === "SUI" ? GAS_RESERVE_MIN : 0;
4781
- const sellAmount = Math.max(0, sell.assetAmount - gasReserve);
4816
+ const sellAmount = Math.max(0, Math.min(sell.assetAmount, walletAmount) - gasReserve);
4817
+ if (sellAmount <= 0) continue;
4782
4818
  const rawAmount = BigInt(Math.floor(sellAmount * 10 ** assetInfo.decimals));
4783
4819
  let splitCoin;
4784
4820
  if (sell.asset === "SUI") {