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