@t2000/sdk 0.17.11 → 0.17.13

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
@@ -4281,13 +4281,28 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4281
4281
  if (bal.available < params.usdAmount) {
4282
4282
  throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient checking balance. Available: $${bal.available.toFixed(2)}, requested: $${params.usdAmount.toFixed(2)}`);
4283
4283
  }
4284
- const swapResult = await this.exchange({
4285
- from: "USDC",
4286
- to: params.asset,
4287
- amount: params.usdAmount,
4288
- maxSlippage: params.maxSlippage ?? defaultSlippage(params.asset),
4289
- _bypassInvestmentGuard: true
4290
- });
4284
+ let swapResult;
4285
+ const maxRetries = 3;
4286
+ for (let attempt = 0; ; attempt++) {
4287
+ try {
4288
+ swapResult = await this.exchange({
4289
+ from: "USDC",
4290
+ to: params.asset,
4291
+ amount: params.usdAmount,
4292
+ maxSlippage: params.maxSlippage ?? defaultSlippage(params.asset),
4293
+ _bypassInvestmentGuard: true
4294
+ });
4295
+ break;
4296
+ } catch (err) {
4297
+ const msg = err instanceof Error ? err.message : String(err);
4298
+ const isSlippage = msg.includes("slippage") || msg.includes("amount_out_slippage");
4299
+ if (isSlippage && attempt < maxRetries) {
4300
+ await new Promise((r) => setTimeout(r, 2e3 * (attempt + 1)));
4301
+ continue;
4302
+ }
4303
+ throw err;
4304
+ }
4305
+ }
4291
4306
  if (swapResult.toAmount === 0) {
4292
4307
  throw new T2000Error("SWAP_FAILED", "Swap returned zero tokens \u2014 try a different amount or check liquidity");
4293
4308
  }
@@ -4346,7 +4361,10 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4346
4361
  }
4347
4362
  const didAutoWithdraw = !!(pos.earning && pos.earningProtocol);
4348
4363
  if (didAutoWithdraw) {
4349
- await this.investUnearn({ asset: params.asset });
4364
+ const unearnResult = await this.investUnearn({ asset: params.asset });
4365
+ if (unearnResult.tx) {
4366
+ await this.client.waitForTransaction({ digest: unearnResult.tx, options: { showEffects: true } });
4367
+ }
4350
4368
  }
4351
4369
  const assetInfo = SUPPORTED_ASSETS[params.asset];
4352
4370
  const gasReserve = params.asset === "SUI" ? GAS_RESERVE_MIN : 0;
@@ -4357,8 +4375,8 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4357
4375
  coinType: assetInfo.type
4358
4376
  });
4359
4377
  walletAmount = Number(assetBalance.totalBalance) / 10 ** assetInfo.decimals;
4360
- if (!didAutoWithdraw || walletAmount > gasReserve || attempt >= 3) break;
4361
- await new Promise((r) => setTimeout(r, 1e3));
4378
+ if (!didAutoWithdraw || walletAmount > gasReserve || attempt >= 5) break;
4379
+ await new Promise((r) => setTimeout(r, 1500));
4362
4380
  }
4363
4381
  const maxSellable = Math.max(0, walletAmount - gasReserve);
4364
4382
  let sellAmountAsset;
@@ -4382,13 +4400,28 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4382
4400
  if (sellAmountAsset <= 0) {
4383
4401
  throw new T2000Error("INSUFFICIENT_INVESTMENT", "Nothing to sell after gas reserve");
4384
4402
  }
4385
- const swapResult = await this.exchange({
4386
- from: params.asset,
4387
- to: "USDC",
4388
- amount: sellAmountAsset,
4389
- maxSlippage: params.maxSlippage ?? defaultSlippage(params.asset),
4390
- _bypassInvestmentGuard: true
4391
- });
4403
+ let swapResult;
4404
+ const maxRetries = 3;
4405
+ for (let attempt = 0; ; attempt++) {
4406
+ try {
4407
+ swapResult = await this.exchange({
4408
+ from: params.asset,
4409
+ to: "USDC",
4410
+ amount: sellAmountAsset,
4411
+ maxSlippage: params.maxSlippage ?? defaultSlippage(params.asset),
4412
+ _bypassInvestmentGuard: true
4413
+ });
4414
+ break;
4415
+ } catch (err) {
4416
+ const msg = err instanceof Error ? err.message : String(err);
4417
+ const isSlippage = msg.includes("slippage") || msg.includes("amount_out_slippage");
4418
+ if (isSlippage && attempt < maxRetries) {
4419
+ await new Promise((r) => setTimeout(r, 2e3 * (attempt + 1)));
4420
+ continue;
4421
+ }
4422
+ throw err;
4423
+ }
4424
+ }
4392
4425
  const price = swapResult.toAmount / sellAmountAsset;
4393
4426
  const realizedPnL = this.portfolio.recordSell({
4394
4427
  id: `inv_${Date.now()}`,
@@ -4629,8 +4662,15 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4629
4662
  if (!swapAdapter?.addSwapToTx) {
4630
4663
  throw new T2000Error("PROTOCOL_UNAVAILABLE", "Swap adapter does not support composable PTB");
4631
4664
  }
4665
+ for (const pos of stratPositions) {
4666
+ const directPos = this.portfolio.getPosition(pos.asset);
4667
+ if (directPos?.earning && directPos.earningProtocol) {
4668
+ await this.investUnearn({ asset: pos.asset });
4669
+ await new Promise((r) => setTimeout(r, 1500));
4670
+ }
4671
+ }
4632
4672
  let swapMetas = [];
4633
- const gasResult = await executeWithGas(this.client, this.keypair, async () => {
4673
+ const buildSellPtb = async () => {
4634
4674
  swapMetas = [];
4635
4675
  const tx = new transactions.Transaction();
4636
4676
  tx.setSender(this._address);
@@ -4665,12 +4705,31 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4665
4705
  usdcOutputs.push(outputCoin);
4666
4706
  swapMetas.push({ asset: pos.asset, amount: sellAmount, estimatedOut, toDecimals });
4667
4707
  }
4708
+ if (usdcOutputs.length === 0) {
4709
+ throw new T2000Error("INSUFFICIENT_BALANCE", "No assets available to sell");
4710
+ }
4668
4711
  if (usdcOutputs.length > 1) {
4669
4712
  tx.mergeCoins(usdcOutputs[0], usdcOutputs.slice(1));
4670
4713
  }
4671
4714
  tx.transferObjects([usdcOutputs[0]], this._address);
4672
4715
  return tx;
4673
- });
4716
+ };
4717
+ let gasResult;
4718
+ const MAX_RETRIES = 3;
4719
+ for (let attempt = 0; ; attempt++) {
4720
+ try {
4721
+ gasResult = await executeWithGas(this.client, this.keypair, buildSellPtb);
4722
+ break;
4723
+ } catch (err) {
4724
+ const msg = err instanceof Error ? err.message : String(err);
4725
+ const isSlippage = msg.includes("slippage") || msg.includes("amount_out_slippage");
4726
+ if (isSlippage && attempt < MAX_RETRIES) {
4727
+ await new Promise((r) => setTimeout(r, 2e3 * (attempt + 1)));
4728
+ continue;
4729
+ }
4730
+ throw err;
4731
+ }
4732
+ }
4674
4733
  const digest = gasResult.digest;
4675
4734
  const now = (/* @__PURE__ */ new Date()).toISOString();
4676
4735
  const sells = [];
@@ -4705,6 +4764,9 @@ To sell investment: t2000 invest sell ${params.amount} ${fromAsset}`,
4705
4764
  totalProceeds += usdValue;
4706
4765
  totalPnL += pnl;
4707
4766
  }
4767
+ if (this.portfolio.hasStrategyPositions(params.strategy)) {
4768
+ this.portfolio.clearStrategy(params.strategy);
4769
+ }
4708
4770
  return {
4709
4771
  success: true,
4710
4772
  strategy: params.strategy,