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