@t2000/sdk 0.8.7 → 0.9.1
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/README.md +22 -24
- package/dist/adapters/index.cjs +0 -18
- 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 +0 -18
- package/dist/adapters/index.js.map +1 -1
- package/dist/{index-DNjooNFy.d.cts → index-C7W686z2.d.cts} +1 -4
- package/dist/{index-DNjooNFy.d.ts → index-C7W686z2.d.ts} +1 -4
- package/dist/index.cjs +208 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -41
- package/dist/index.d.ts +10 -41
- package/dist/index.js +209 -95
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1315,24 +1315,6 @@ var ProtocolRegistry = class {
|
|
|
1315
1315
|
listSwap() {
|
|
1316
1316
|
return [...this.swap.values()];
|
|
1317
1317
|
}
|
|
1318
|
-
isSupportedAsset(asset, capability) {
|
|
1319
|
-
for (const adapter of this.lending.values()) {
|
|
1320
|
-
if (!adapter.supportedAssets.includes(asset)) continue;
|
|
1321
|
-
if (capability && !adapter.capabilities.includes(capability)) continue;
|
|
1322
|
-
return true;
|
|
1323
|
-
}
|
|
1324
|
-
return false;
|
|
1325
|
-
}
|
|
1326
|
-
getSupportedAssets(capability) {
|
|
1327
|
-
const assets = /* @__PURE__ */ new Set();
|
|
1328
|
-
for (const adapter of this.lending.values()) {
|
|
1329
|
-
if (capability && !adapter.capabilities.includes(capability)) continue;
|
|
1330
|
-
for (const a of adapter.supportedAssets) {
|
|
1331
|
-
assets.add(a);
|
|
1332
|
-
}
|
|
1333
|
-
}
|
|
1334
|
-
return [...assets];
|
|
1335
|
-
}
|
|
1336
1318
|
};
|
|
1337
1319
|
|
|
1338
1320
|
// src/adapters/navi.ts
|
|
@@ -2431,43 +2413,39 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2431
2413
|
}
|
|
2432
2414
|
// -- Savings --
|
|
2433
2415
|
async save(params) {
|
|
2434
|
-
const asset =
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
throw new T2000Error("ASSET_NOT_SUPPORTED", `${asset} is not supported for save. Supported: ${supported}`);
|
|
2438
|
-
}
|
|
2416
|
+
const asset = "USDC";
|
|
2417
|
+
const bal = await queryBalance(this.client, this._address);
|
|
2418
|
+
const usdcBalance = bal.stables.USDC ?? 0;
|
|
2439
2419
|
let amount;
|
|
2440
2420
|
if (params.amount === "all") {
|
|
2441
|
-
|
|
2442
|
-
const
|
|
2443
|
-
|
|
2444
|
-
amount = assetBalance - reserve;
|
|
2421
|
+
await this._convertWalletStablesToUsdc(bal);
|
|
2422
|
+
const refreshedBal = await queryBalance(this.client, this._address);
|
|
2423
|
+
amount = (refreshedBal.stables.USDC ?? 0) - 1;
|
|
2445
2424
|
if (amount <= 0) {
|
|
2446
|
-
throw new T2000Error("INSUFFICIENT_BALANCE",
|
|
2447
|
-
reason:
|
|
2448
|
-
available:
|
|
2425
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", "Balance too low to save after $1 gas reserve", {
|
|
2426
|
+
reason: "gas_reserve_required",
|
|
2427
|
+
available: refreshedBal.stables.USDC ?? 0
|
|
2449
2428
|
});
|
|
2450
2429
|
}
|
|
2451
2430
|
} else {
|
|
2452
2431
|
amount = params.amount;
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2432
|
+
if (amount > usdcBalance) {
|
|
2433
|
+
const totalStables = bal.available;
|
|
2434
|
+
if (amount > totalStables) {
|
|
2435
|
+
throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient balance. Available: $${totalStables.toFixed(2)}, requested: $${amount.toFixed(2)}`);
|
|
2436
|
+
}
|
|
2437
|
+
await this._convertWalletStablesToUsdc(bal, amount - usdcBalance);
|
|
2457
2438
|
}
|
|
2458
2439
|
}
|
|
2459
|
-
const
|
|
2460
|
-
const fee = shouldCollectFee ? calculateFee("save", amount) : { amount: 0, rate: 0};
|
|
2440
|
+
const fee = calculateFee("save", amount);
|
|
2461
2441
|
const saveAmount = amount;
|
|
2462
2442
|
const adapter = await this.resolveLending(params.protocol, asset, "save");
|
|
2463
2443
|
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
2464
|
-
const { tx } = await adapter.buildSaveTx(this._address, saveAmount, asset, { collectFee:
|
|
2444
|
+
const { tx } = await adapter.buildSaveTx(this._address, saveAmount, asset, { collectFee: true });
|
|
2465
2445
|
return tx;
|
|
2466
2446
|
});
|
|
2467
2447
|
const rates = await adapter.getRates(asset);
|
|
2468
|
-
|
|
2469
|
-
reportFee(this._address, "save", fee.amount, fee.rate, gasResult.digest);
|
|
2470
|
-
}
|
|
2448
|
+
reportFee(this._address, "save", fee.amount, fee.rate, gasResult.digest);
|
|
2471
2449
|
this.emitBalanceChange(asset, saveAmount, "save", gasResult.digest);
|
|
2472
2450
|
let savingsBalance = saveAmount;
|
|
2473
2451
|
try {
|
|
@@ -2479,7 +2457,6 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2479
2457
|
success: true,
|
|
2480
2458
|
tx: gasResult.digest,
|
|
2481
2459
|
amount: saveAmount,
|
|
2482
|
-
asset,
|
|
2483
2460
|
apy: rates.saveApy,
|
|
2484
2461
|
fee: fee.amount,
|
|
2485
2462
|
gasCost: gasResult.gasCostSui,
|
|
@@ -2488,14 +2465,27 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2488
2465
|
};
|
|
2489
2466
|
}
|
|
2490
2467
|
async withdraw(params) {
|
|
2491
|
-
const asset = normalizeAsset(params.asset ?? "USDC");
|
|
2492
2468
|
if (params.amount === "all" && !params.protocol) {
|
|
2493
|
-
return this.withdrawAllProtocols(
|
|
2469
|
+
return this.withdrawAllProtocols();
|
|
2470
|
+
}
|
|
2471
|
+
const allPositions = await this.registry.allPositions(this._address);
|
|
2472
|
+
const supplies = [];
|
|
2473
|
+
for (const pos of allPositions) {
|
|
2474
|
+
if (params.protocol && pos.protocolId !== params.protocol) continue;
|
|
2475
|
+
for (const s of pos.positions.supplies) {
|
|
2476
|
+
if (s.amount > 1e-3) supplies.push({ protocolId: pos.protocolId, asset: s.asset, amount: s.amount, apy: s.apy });
|
|
2477
|
+
}
|
|
2494
2478
|
}
|
|
2495
|
-
|
|
2479
|
+
if (supplies.length === 0) {
|
|
2480
|
+
throw new T2000Error("NO_COLLATERAL", "No savings to withdraw");
|
|
2481
|
+
}
|
|
2482
|
+
supplies.sort((a, b) => a.apy - b.apy);
|
|
2483
|
+
const target = supplies[0];
|
|
2484
|
+
const adapter = this.registry.getLending(target.protocolId);
|
|
2485
|
+
if (!adapter) throw new T2000Error("PROTOCOL_UNAVAILABLE", `Protocol ${target.protocolId} not found`);
|
|
2496
2486
|
let amount;
|
|
2497
2487
|
if (params.amount === "all") {
|
|
2498
|
-
const maxResult = await adapter.maxWithdraw(this._address, asset);
|
|
2488
|
+
const maxResult = await adapter.maxWithdraw(this._address, target.asset);
|
|
2499
2489
|
amount = maxResult.maxAmount;
|
|
2500
2490
|
if (amount <= 0) {
|
|
2501
2491
|
throw new T2000Error("NO_COLLATERAL", "No savings to withdraw");
|
|
@@ -2504,7 +2494,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2504
2494
|
amount = params.amount;
|
|
2505
2495
|
const hf = await adapter.getHealth(this._address);
|
|
2506
2496
|
if (hf.borrowed > 0) {
|
|
2507
|
-
const maxResult = await adapter.maxWithdraw(this._address, asset);
|
|
2497
|
+
const maxResult = await adapter.maxWithdraw(this._address, target.asset);
|
|
2508
2498
|
if (amount > maxResult.maxAmount) {
|
|
2509
2499
|
throw new T2000Error(
|
|
2510
2500
|
"WITHDRAW_WOULD_LIQUIDATE",
|
|
@@ -2521,20 +2511,37 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2521
2511
|
const withdrawAmount = amount;
|
|
2522
2512
|
let effectiveAmount = withdrawAmount;
|
|
2523
2513
|
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
2524
|
-
const built = await adapter.buildWithdrawTx(this._address, withdrawAmount, asset);
|
|
2514
|
+
const built = await adapter.buildWithdrawTx(this._address, withdrawAmount, target.asset);
|
|
2525
2515
|
effectiveAmount = built.effectiveAmount;
|
|
2526
2516
|
return built.tx;
|
|
2527
2517
|
});
|
|
2528
|
-
|
|
2518
|
+
let totalGasCost = gasResult.gasCostSui;
|
|
2519
|
+
let finalAmount = effectiveAmount;
|
|
2520
|
+
let lastDigest = gasResult.digest;
|
|
2521
|
+
if (target.asset !== "USDC") {
|
|
2522
|
+
try {
|
|
2523
|
+
const swapResult = await this._swapToUsdc(target.asset, effectiveAmount);
|
|
2524
|
+
finalAmount = swapResult.usdcReceived;
|
|
2525
|
+
lastDigest = swapResult.digest;
|
|
2526
|
+
totalGasCost += swapResult.gasCost;
|
|
2527
|
+
} catch (err) {
|
|
2528
|
+
throw new T2000Error(
|
|
2529
|
+
"SWAP_FAILED",
|
|
2530
|
+
`Withdrew $${effectiveAmount.toFixed(2)} ${target.asset} but swap to USDC failed. Your ${target.asset} is safe in your wallet.`,
|
|
2531
|
+
{ withdrawDigest: gasResult.digest, originalError: err instanceof Error ? err.message : String(err) }
|
|
2532
|
+
);
|
|
2533
|
+
}
|
|
2534
|
+
}
|
|
2535
|
+
this.emitBalanceChange("USDC", finalAmount, "withdraw", lastDigest);
|
|
2529
2536
|
return {
|
|
2530
2537
|
success: true,
|
|
2531
|
-
tx:
|
|
2532
|
-
amount:
|
|
2533
|
-
gasCost:
|
|
2538
|
+
tx: lastDigest,
|
|
2539
|
+
amount: finalAmount,
|
|
2540
|
+
gasCost: totalGasCost,
|
|
2534
2541
|
gasMethod: gasResult.gasMethod
|
|
2535
2542
|
};
|
|
2536
2543
|
}
|
|
2537
|
-
async withdrawAllProtocols(
|
|
2544
|
+
async withdrawAllProtocols() {
|
|
2538
2545
|
const allPositions = await this.registry.allPositions(this._address);
|
|
2539
2546
|
const withdrawable = [];
|
|
2540
2547
|
for (const pos of allPositions) {
|
|
@@ -2547,7 +2554,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2547
2554
|
if (withdrawable.length === 0) {
|
|
2548
2555
|
throw new T2000Error("NO_COLLATERAL", "No savings to withdraw across any protocol");
|
|
2549
2556
|
}
|
|
2550
|
-
let
|
|
2557
|
+
let totalUsdcReceived = 0;
|
|
2551
2558
|
let lastDigest = "";
|
|
2552
2559
|
let totalGasCost = 0;
|
|
2553
2560
|
let lastGasMethod = "self-funded";
|
|
@@ -2562,30 +2569,88 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2562
2569
|
effectiveAmount = built.effectiveAmount;
|
|
2563
2570
|
return built.tx;
|
|
2564
2571
|
});
|
|
2565
|
-
totalWithdrawn += effectiveAmount;
|
|
2566
2572
|
lastDigest = gasResult.digest;
|
|
2567
2573
|
totalGasCost += gasResult.gasCostSui;
|
|
2568
2574
|
lastGasMethod = gasResult.gasMethod;
|
|
2569
2575
|
this.emitBalanceChange(entry.asset, effectiveAmount, "withdraw", gasResult.digest);
|
|
2576
|
+
if (entry.asset !== "USDC") {
|
|
2577
|
+
try {
|
|
2578
|
+
const swapResult = await this._swapToUsdc(entry.asset, effectiveAmount);
|
|
2579
|
+
totalUsdcReceived += swapResult.usdcReceived;
|
|
2580
|
+
lastDigest = swapResult.digest;
|
|
2581
|
+
totalGasCost += swapResult.gasCost;
|
|
2582
|
+
} catch {
|
|
2583
|
+
totalUsdcReceived += effectiveAmount;
|
|
2584
|
+
}
|
|
2585
|
+
} else {
|
|
2586
|
+
totalUsdcReceived += effectiveAmount;
|
|
2587
|
+
}
|
|
2570
2588
|
}
|
|
2571
|
-
if (
|
|
2589
|
+
if (totalUsdcReceived <= 0) {
|
|
2572
2590
|
throw new T2000Error("NO_COLLATERAL", "No savings to withdraw across any protocol");
|
|
2573
2591
|
}
|
|
2574
2592
|
return {
|
|
2575
2593
|
success: true,
|
|
2576
2594
|
tx: lastDigest,
|
|
2577
|
-
amount:
|
|
2595
|
+
amount: totalUsdcReceived,
|
|
2578
2596
|
gasCost: totalGasCost,
|
|
2579
2597
|
gasMethod: lastGasMethod
|
|
2580
2598
|
};
|
|
2581
2599
|
}
|
|
2600
|
+
async _swapToUsdc(asset, amount) {
|
|
2601
|
+
const swapAdapter = this.registry.listSwap()[0];
|
|
2602
|
+
if (!swapAdapter) throw new T2000Error("PROTOCOL_UNAVAILABLE", "No swap adapter available");
|
|
2603
|
+
let estimatedOut = 0;
|
|
2604
|
+
let toDecimals = 6;
|
|
2605
|
+
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
2606
|
+
const built = await swapAdapter.buildSwapTx(this._address, asset, "USDC", amount);
|
|
2607
|
+
estimatedOut = built.estimatedOut;
|
|
2608
|
+
toDecimals = built.toDecimals;
|
|
2609
|
+
return built.tx;
|
|
2610
|
+
});
|
|
2611
|
+
const usdcReceived = estimatedOut / 10 ** toDecimals;
|
|
2612
|
+
return { usdcReceived, digest: gasResult.digest, gasCost: gasResult.gasCostSui };
|
|
2613
|
+
}
|
|
2614
|
+
async _swapFromUsdc(toAsset, amount) {
|
|
2615
|
+
const swapAdapter = this.registry.listSwap()[0];
|
|
2616
|
+
if (!swapAdapter) throw new T2000Error("PROTOCOL_UNAVAILABLE", "No swap adapter available");
|
|
2617
|
+
let estimatedOut = 0;
|
|
2618
|
+
let toDecimals = 6;
|
|
2619
|
+
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
2620
|
+
const built = await swapAdapter.buildSwapTx(this._address, "USDC", toAsset, amount);
|
|
2621
|
+
estimatedOut = built.estimatedOut;
|
|
2622
|
+
toDecimals = built.toDecimals;
|
|
2623
|
+
return built.tx;
|
|
2624
|
+
});
|
|
2625
|
+
const received = estimatedOut / 10 ** toDecimals;
|
|
2626
|
+
return { received, digest: gasResult.digest, gasCost: gasResult.gasCostSui };
|
|
2627
|
+
}
|
|
2628
|
+
async _convertWalletStablesToUsdc(bal, amountNeeded) {
|
|
2629
|
+
const nonUsdcStables = [];
|
|
2630
|
+
for (const [asset, amount] of Object.entries(bal.stables)) {
|
|
2631
|
+
if (asset !== "USDC" && amount > 0.01) {
|
|
2632
|
+
nonUsdcStables.push({ asset, amount });
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
if (nonUsdcStables.length === 0) return;
|
|
2636
|
+
nonUsdcStables.sort((a, b) => b.amount - a.amount);
|
|
2637
|
+
let converted = 0;
|
|
2638
|
+
for (const entry of nonUsdcStables) {
|
|
2639
|
+
if (amountNeeded !== void 0 && converted >= amountNeeded) break;
|
|
2640
|
+
try {
|
|
2641
|
+
await this._swapToUsdc(entry.asset, entry.amount);
|
|
2642
|
+
converted += entry.amount;
|
|
2643
|
+
} catch {
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2582
2647
|
async maxWithdraw() {
|
|
2583
2648
|
const adapter = await this.resolveLending(void 0, "USDC", "withdraw");
|
|
2584
2649
|
return adapter.maxWithdraw(this._address, "USDC");
|
|
2585
2650
|
}
|
|
2586
2651
|
// -- Borrowing --
|
|
2587
2652
|
async borrow(params) {
|
|
2588
|
-
const asset =
|
|
2653
|
+
const asset = "USDC";
|
|
2589
2654
|
const adapter = await this.resolveLending(params.protocol, asset, "borrow");
|
|
2590
2655
|
const maxResult = await adapter.maxBorrow(this._address, asset);
|
|
2591
2656
|
if (maxResult.maxAmount <= 0) {
|
|
@@ -2597,17 +2662,14 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2597
2662
|
currentHF: maxResult.currentHF
|
|
2598
2663
|
});
|
|
2599
2664
|
}
|
|
2600
|
-
const
|
|
2601
|
-
const fee = shouldCollectFee ? calculateFee("borrow", params.amount) : { amount: 0, rate: 0};
|
|
2665
|
+
const fee = calculateFee("borrow", params.amount);
|
|
2602
2666
|
const borrowAmount = params.amount;
|
|
2603
2667
|
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
2604
|
-
const { tx } = await adapter.buildBorrowTx(this._address, borrowAmount, asset, { collectFee:
|
|
2668
|
+
const { tx } = await adapter.buildBorrowTx(this._address, borrowAmount, asset, { collectFee: true });
|
|
2605
2669
|
return tx;
|
|
2606
2670
|
});
|
|
2607
2671
|
const hf = await adapter.getHealth(this._address);
|
|
2608
|
-
|
|
2609
|
-
reportFee(this._address, "borrow", fee.amount, fee.rate, gasResult.digest);
|
|
2610
|
-
}
|
|
2672
|
+
reportFee(this._address, "borrow", fee.amount, fee.rate, gasResult.digest);
|
|
2611
2673
|
this.emitBalanceChange(asset, borrowAmount, "borrow", gasResult.digest);
|
|
2612
2674
|
return {
|
|
2613
2675
|
success: true,
|
|
@@ -2620,34 +2682,93 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2620
2682
|
};
|
|
2621
2683
|
}
|
|
2622
2684
|
async repay(params) {
|
|
2623
|
-
const
|
|
2624
|
-
const
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
const
|
|
2628
|
-
|
|
2629
|
-
if (amount <= 0) {
|
|
2630
|
-
throw new T2000Error("NO_COLLATERAL", "No outstanding borrow to repay");
|
|
2685
|
+
const allPositions = await this.registry.allPositions(this._address);
|
|
2686
|
+
const borrows = [];
|
|
2687
|
+
for (const pos of allPositions) {
|
|
2688
|
+
if (params.protocol && pos.protocolId !== params.protocol) continue;
|
|
2689
|
+
for (const b of pos.positions.borrows) {
|
|
2690
|
+
if (b.amount > 1e-3) borrows.push({ protocolId: pos.protocolId, asset: b.asset, amount: b.amount, apy: b.apy });
|
|
2631
2691
|
}
|
|
2632
|
-
} else {
|
|
2633
|
-
amount = params.amount;
|
|
2634
2692
|
}
|
|
2635
|
-
|
|
2693
|
+
if (borrows.length === 0) {
|
|
2694
|
+
throw new T2000Error("NO_COLLATERAL", "No outstanding borrow to repay");
|
|
2695
|
+
}
|
|
2696
|
+
if (params.amount === "all") {
|
|
2697
|
+
return this._repayAllBorrows(borrows);
|
|
2698
|
+
}
|
|
2699
|
+
borrows.sort((a, b) => b.apy - a.apy);
|
|
2700
|
+
const target = borrows[0];
|
|
2701
|
+
const adapter = this.registry.getLending(target.protocolId);
|
|
2702
|
+
if (!adapter) throw new T2000Error("PROTOCOL_UNAVAILABLE", `Protocol ${target.protocolId} not found`);
|
|
2703
|
+
const repayAmount = Math.min(params.amount, target.amount);
|
|
2704
|
+
let totalGasCost = 0;
|
|
2705
|
+
let lastDigest = "";
|
|
2706
|
+
if (target.asset !== "USDC") {
|
|
2707
|
+
const buffer = repayAmount * 1.005;
|
|
2708
|
+
const swapResult = await this._swapFromUsdc(target.asset, buffer);
|
|
2709
|
+
totalGasCost += swapResult.gasCost;
|
|
2710
|
+
lastDigest = swapResult.digest;
|
|
2711
|
+
}
|
|
2636
2712
|
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
2637
|
-
const { tx } = await adapter.buildRepayTx(this._address, repayAmount, asset);
|
|
2713
|
+
const { tx } = await adapter.buildRepayTx(this._address, repayAmount, target.asset);
|
|
2638
2714
|
return tx;
|
|
2639
2715
|
});
|
|
2716
|
+
totalGasCost += gasResult.gasCostSui;
|
|
2717
|
+
lastDigest = gasResult.digest;
|
|
2640
2718
|
const hf = await adapter.getHealth(this._address);
|
|
2641
|
-
this.emitBalanceChange(
|
|
2719
|
+
this.emitBalanceChange("USDC", repayAmount, "repay", lastDigest);
|
|
2642
2720
|
return {
|
|
2643
2721
|
success: true,
|
|
2644
|
-
tx:
|
|
2722
|
+
tx: lastDigest,
|
|
2645
2723
|
amount: repayAmount,
|
|
2646
2724
|
remainingDebt: hf.borrowed,
|
|
2647
|
-
gasCost:
|
|
2725
|
+
gasCost: totalGasCost,
|
|
2648
2726
|
gasMethod: gasResult.gasMethod
|
|
2649
2727
|
};
|
|
2650
2728
|
}
|
|
2729
|
+
async _repayAllBorrows(borrows) {
|
|
2730
|
+
let totalRepaid = 0;
|
|
2731
|
+
let totalGasCost = 0;
|
|
2732
|
+
let lastDigest = "";
|
|
2733
|
+
let lastGasMethod = "self-funded";
|
|
2734
|
+
borrows.sort((a, b) => b.apy - a.apy);
|
|
2735
|
+
for (const borrow of borrows) {
|
|
2736
|
+
const adapter = this.registry.getLending(borrow.protocolId);
|
|
2737
|
+
if (!adapter) continue;
|
|
2738
|
+
if (borrow.asset !== "USDC") {
|
|
2739
|
+
try {
|
|
2740
|
+
const buffer = borrow.amount * 1.005;
|
|
2741
|
+
const swapResult = await this._swapFromUsdc(borrow.asset, buffer);
|
|
2742
|
+
totalGasCost += swapResult.gasCost;
|
|
2743
|
+
} catch (err) {
|
|
2744
|
+
throw new T2000Error(
|
|
2745
|
+
"SWAP_FAILED",
|
|
2746
|
+
`Could not convert USDC to ${borrow.asset} for repayment. Try again later.`,
|
|
2747
|
+
{ originalError: err instanceof Error ? err.message : String(err) }
|
|
2748
|
+
);
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
const gasResult = await executeWithGas(this.client, this.keypair, async () => {
|
|
2752
|
+
const { tx } = await adapter.buildRepayTx(this._address, borrow.amount, borrow.asset);
|
|
2753
|
+
return tx;
|
|
2754
|
+
});
|
|
2755
|
+
totalRepaid += borrow.amount;
|
|
2756
|
+
totalGasCost += gasResult.gasCostSui;
|
|
2757
|
+
lastDigest = gasResult.digest;
|
|
2758
|
+
lastGasMethod = gasResult.gasMethod;
|
|
2759
|
+
}
|
|
2760
|
+
const firstAdapter = this.registry.getLending(borrows[0].protocolId);
|
|
2761
|
+
const hf = firstAdapter ? await firstAdapter.getHealth(this._address) : { borrowed: 0 };
|
|
2762
|
+
this.emitBalanceChange("USDC", totalRepaid, "repay", lastDigest);
|
|
2763
|
+
return {
|
|
2764
|
+
success: true,
|
|
2765
|
+
tx: lastDigest,
|
|
2766
|
+
amount: totalRepaid,
|
|
2767
|
+
remainingDebt: hf.borrowed,
|
|
2768
|
+
gasCost: totalGasCost,
|
|
2769
|
+
gasMethod: lastGasMethod
|
|
2770
|
+
};
|
|
2771
|
+
}
|
|
2651
2772
|
async maxBorrow() {
|
|
2652
2773
|
const adapter = await this.resolveLending(void 0, "USDC", "borrow");
|
|
2653
2774
|
return adapter.maxBorrow(this._address, "USDC");
|
|
@@ -2662,25 +2783,18 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2662
2783
|
}
|
|
2663
2784
|
return hf;
|
|
2664
2785
|
}
|
|
2665
|
-
// -- Swap --
|
|
2666
|
-
async
|
|
2667
|
-
const fromAsset =
|
|
2668
|
-
const toAsset =
|
|
2786
|
+
// -- Swap (internal — used by rebalance and withdraw auto-swap) --
|
|
2787
|
+
async _swap(params) {
|
|
2788
|
+
const fromAsset = params.from;
|
|
2789
|
+
const toAsset = params.to;
|
|
2669
2790
|
if (!(fromAsset in SUPPORTED_ASSETS) || !(toAsset in SUPPORTED_ASSETS)) {
|
|
2670
2791
|
throw new T2000Error("ASSET_NOT_SUPPORTED", `Swap pair ${fromAsset}/${toAsset} is not supported`);
|
|
2671
2792
|
}
|
|
2672
2793
|
if (fromAsset === toAsset) {
|
|
2673
2794
|
throw new T2000Error("INVALID_AMOUNT", "Cannot swap same asset");
|
|
2674
2795
|
}
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
const found = this.registry.getSwap(params.protocol);
|
|
2678
|
-
if (!found) throw new T2000Error("ASSET_NOT_SUPPORTED", `Swap adapter '${params.protocol}' not found`);
|
|
2679
|
-
adapter = found;
|
|
2680
|
-
} else {
|
|
2681
|
-
const best = await this.registry.bestSwapQuote(fromAsset, toAsset, params.amount);
|
|
2682
|
-
adapter = best.adapter;
|
|
2683
|
-
}
|
|
2796
|
+
const best = await this.registry.bestSwapQuote(fromAsset, toAsset, params.amount);
|
|
2797
|
+
const adapter = best.adapter;
|
|
2684
2798
|
const fee = calculateFee("swap", params.amount);
|
|
2685
2799
|
const swapAmount = params.amount;
|
|
2686
2800
|
const slippageBps = params.maxSlippage ? params.maxSlippage * 100 : void 0;
|
|
@@ -2723,9 +2837,9 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2723
2837
|
gasMethod: gasResult.gasMethod
|
|
2724
2838
|
};
|
|
2725
2839
|
}
|
|
2726
|
-
async
|
|
2727
|
-
const fromAsset =
|
|
2728
|
-
const toAsset =
|
|
2840
|
+
async _swapQuote(params) {
|
|
2841
|
+
const fromAsset = params.from;
|
|
2842
|
+
const toAsset = params.to;
|
|
2729
2843
|
const best = await this.registry.bestSwapQuote(fromAsset, toAsset, params.amount);
|
|
2730
2844
|
const fee = calculateFee("swap", params.amount);
|
|
2731
2845
|
return { ...best.quote, fee: { amount: fee.amount, rate: fee.rate } };
|
|
@@ -3162,6 +3276,6 @@ var allDescriptors = [
|
|
|
3162
3276
|
descriptor
|
|
3163
3277
|
];
|
|
3164
3278
|
|
|
3165
|
-
export { BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, DEFAULT_NETWORK, MIST_PER_SUI, NaviAdapter, ProtocolRegistry, SENTINEL,
|
|
3279
|
+
export { BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, DEFAULT_NETWORK, MIST_PER_SUI, NaviAdapter, ProtocolRegistry, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, SuilendAdapter, T2000, T2000Error, USDC_DECIMALS, addCollectFeeToTx, allDescriptors, calculateFee, descriptor3 as cetusDescriptor, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, getSentinelInfo, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, descriptor2 as naviDescriptor, rawToStable, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, descriptor as sentinelDescriptor, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, submitPrompt, suiToMist, descriptor4 as suilendDescriptor, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
|
3166
3280
|
//# sourceMappingURL=index.js.map
|
|
3167
3281
|
//# sourceMappingURL=index.js.map
|