@t2000/sdk 0.4.1 → 0.4.2

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.
@@ -607,38 +607,48 @@ var SuilendAdapter = class {
607
607
  suilend;
608
608
  lendingMarketType;
609
609
  initialized = false;
610
+ initPromise = null;
610
611
  async init(client) {
611
- let sdk;
612
- try {
613
- sdk = await import('@suilend/sdk');
614
- } catch {
615
- throw new T2000Error(
616
- "PROTOCOL_UNAVAILABLE",
617
- "Suilend SDK not installed. Run: npm install @suilend/sdk@^1"
618
- );
619
- }
620
612
  this.client = client;
621
- this.lendingMarketType = sdk.LENDING_MARKET_TYPE;
622
- try {
623
- this.suilend = await sdk.SuilendClient.initialize(
624
- sdk.LENDING_MARKET_ID,
625
- sdk.LENDING_MARKET_TYPE,
626
- client
627
- );
628
- } catch (err) {
629
- throw new T2000Error(
630
- "PROTOCOL_UNAVAILABLE",
631
- `Failed to initialize Suilend: ${err instanceof Error ? err.message : String(err)}`
632
- );
633
- }
634
- this.initialized = true;
613
+ await this.lazyInit();
614
+ }
615
+ initSync(client) {
616
+ this.client = client;
635
617
  }
636
- ensureInit() {
618
+ async lazyInit() {
619
+ if (this.initialized) return;
620
+ if (this.initPromise) return this.initPromise;
621
+ this.initPromise = (async () => {
622
+ let sdk;
623
+ try {
624
+ sdk = await import('@suilend/sdk');
625
+ } catch {
626
+ throw new T2000Error(
627
+ "PROTOCOL_UNAVAILABLE",
628
+ "Suilend SDK not installed. Run: npm install @suilend/sdk@^1"
629
+ );
630
+ }
631
+ this.lendingMarketType = sdk.LENDING_MARKET_TYPE;
632
+ try {
633
+ this.suilend = await sdk.SuilendClient.initialize(
634
+ sdk.LENDING_MARKET_ID,
635
+ sdk.LENDING_MARKET_TYPE,
636
+ this.client
637
+ );
638
+ } catch (err) {
639
+ this.initPromise = null;
640
+ throw new T2000Error(
641
+ "PROTOCOL_UNAVAILABLE",
642
+ `Failed to initialize Suilend: ${err instanceof Error ? err.message : String(err)}`
643
+ );
644
+ }
645
+ this.initialized = true;
646
+ })();
647
+ return this.initPromise;
648
+ }
649
+ async ensureInit() {
637
650
  if (!this.initialized) {
638
- throw new T2000Error(
639
- "PROTOCOL_UNAVAILABLE",
640
- "SuilendAdapter not initialized. Call init() first."
641
- );
651
+ await this.lazyInit();
642
652
  }
643
653
  }
644
654
  findReserve(asset) {
@@ -673,7 +683,7 @@ var SuilendAdapter = class {
673
683
  return parts[parts.length - 1] || "UNKNOWN";
674
684
  }
675
685
  async getRates(asset) {
676
- this.ensureInit();
686
+ await this.ensureInit();
677
687
  const reserve = this.findReserve(asset);
678
688
  if (!reserve) {
679
689
  throw new T2000Error("ASSET_NOT_SUPPORTED", `Suilend does not support ${asset}`);
@@ -686,7 +696,7 @@ var SuilendAdapter = class {
686
696
  };
687
697
  }
688
698
  async getPositions(address) {
689
- this.ensureInit();
699
+ await this.ensureInit();
690
700
  const supplies = [];
691
701
  const borrows = [];
692
702
  const caps = await this.getObligationCaps(address);
@@ -721,7 +731,7 @@ var SuilendAdapter = class {
721
731
  return { supplies, borrows };
722
732
  }
723
733
  async getHealth(address) {
724
- this.ensureInit();
734
+ await this.ensureInit();
725
735
  const caps = await this.getObligationCaps(address);
726
736
  if (caps.length === 0) {
727
737
  return { healthFactor: Infinity, supplied: 0, borrowed: 0, maxBorrow: 0, liquidationThreshold: 0 };
@@ -738,7 +748,7 @@ var SuilendAdapter = class {
738
748
  return { healthFactor, supplied, borrowed, maxBorrow, liquidationThreshold: liqThreshold };
739
749
  }
740
750
  async buildSaveTx(address, amount, _asset, options) {
741
- this.ensureInit();
751
+ await this.ensureInit();
742
752
  const rawAmount = usdcToRaw(amount).toString();
743
753
  const tx = new Transaction();
744
754
  tx.setSender(address);
@@ -769,7 +779,7 @@ var SuilendAdapter = class {
769
779
  return { tx };
770
780
  }
771
781
  async buildWithdrawTx(address, amount, _asset) {
772
- this.ensureInit();
782
+ await this.ensureInit();
773
783
  const caps = await this.getObligationCaps(address);
774
784
  if (caps.length === 0) {
775
785
  throw new T2000Error("NO_COLLATERAL", "No Suilend position found");
@@ -807,7 +817,7 @@ var SuilendAdapter = class {
807
817
  );
808
818
  }
809
819
  async maxWithdraw(address, _asset) {
810
- this.ensureInit();
820
+ await this.ensureInit();
811
821
  const health = await this.getHealth(address);
812
822
  let maxAmount;
813
823
  if (health.borrowed === 0) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/registry.ts","../../src/constants.ts","../../src/errors.ts","../../src/utils/format.ts","../../src/protocols/protocolFee.ts","../../src/protocols/navi.ts","../../src/adapters/navi.ts","../../src/protocols/cetus.ts","../../src/adapters/cetus.ts","../../src/adapters/suilend.ts"],"names":["naviGetHealthFactor","Transaction","USDC_TYPE","MIN_HEALTH_FACTOR"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n LendingAdapter,\n SwapAdapter,\n LendingRates,\n SwapQuote,\n AdapterPositions,\n} from './types.js';\n\nexport class ProtocolRegistry {\n private lending: Map<string, LendingAdapter> = new Map();\n private swap: Map<string, SwapAdapter> = new Map();\n\n registerLending(adapter: LendingAdapter): void {\n this.lending.set(adapter.id, adapter);\n }\n\n registerSwap(adapter: SwapAdapter): void {\n this.swap.set(adapter.id, adapter);\n }\n\n async bestSaveRate(asset: string): Promise<{ adapter: LendingAdapter; rate: LendingRates }> {\n const candidates: Array<{ adapter: LendingAdapter; rate: LendingRates }> = [];\n\n for (const adapter of this.lending.values()) {\n if (!adapter.supportedAssets.includes(asset)) continue;\n if (!adapter.capabilities.includes('save')) continue;\n try {\n const rate = await adapter.getRates(asset);\n candidates.push({ adapter, rate });\n } catch {\n // skip adapters that fail to fetch rates\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(`No lending adapter supports saving ${asset}`);\n }\n\n candidates.sort((a, b) => b.rate.saveApy - a.rate.saveApy);\n return candidates[0];\n }\n\n async bestBorrowRate(asset: string, opts?: { requireSameAssetBorrow?: boolean }): Promise<{ adapter: LendingAdapter; rate: LendingRates }> {\n const candidates: Array<{ adapter: LendingAdapter; rate: LendingRates }> = [];\n\n for (const adapter of this.lending.values()) {\n if (!adapter.supportedAssets.includes(asset)) continue;\n if (!adapter.capabilities.includes('borrow')) continue;\n if (opts?.requireSameAssetBorrow && !adapter.supportsSameAssetBorrow) continue;\n try {\n const rate = await adapter.getRates(asset);\n candidates.push({ adapter, rate });\n } catch {\n // skip\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(`No lending adapter supports borrowing ${asset}`);\n }\n\n candidates.sort((a, b) => a.rate.borrowApy - b.rate.borrowApy);\n return candidates[0];\n }\n\n async bestSwapQuote(from: string, to: string, amount: number): Promise<{ adapter: SwapAdapter; quote: SwapQuote }> {\n const candidates: Array<{ adapter: SwapAdapter; quote: SwapQuote }> = [];\n\n for (const adapter of this.swap.values()) {\n const pairs = adapter.getSupportedPairs();\n if (!pairs.some(p => p.from === from && p.to === to)) continue;\n try {\n const quote = await adapter.getQuote(from, to, amount);\n candidates.push({ adapter, quote });\n } catch {\n // skip\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(`No swap adapter supports ${from} → ${to}`);\n }\n\n candidates.sort((a, b) => b.quote.expectedOutput - a.quote.expectedOutput);\n return candidates[0];\n }\n\n async allRates(asset: string): Promise<Array<{ protocol: string; protocolId: string; rates: LendingRates }>> {\n const results: Array<{ protocol: string; protocolId: string; rates: LendingRates }> = [];\n for (const adapter of this.lending.values()) {\n if (!adapter.supportedAssets.includes(asset)) continue;\n try {\n const rates = await adapter.getRates(asset);\n results.push({ protocol: adapter.name, protocolId: adapter.id, rates });\n } catch {\n // skip\n }\n }\n return results;\n }\n\n async allPositions(address: string): Promise<Array<{ protocol: string; protocolId: string; positions: AdapterPositions }>> {\n const results: Array<{ protocol: string; protocolId: string; positions: AdapterPositions }> = [];\n for (const adapter of this.lending.values()) {\n try {\n const positions = await adapter.getPositions(address);\n if (positions.supplies.length > 0 || positions.borrows.length > 0) {\n results.push({ protocol: adapter.name, protocolId: adapter.id, positions });\n }\n } catch {\n // skip\n }\n }\n return results;\n }\n\n getLending(id: string): LendingAdapter | undefined {\n return this.lending.get(id);\n }\n\n getSwap(id: string): SwapAdapter | undefined {\n return this.swap.get(id);\n }\n\n listLending(): LendingAdapter[] {\n return [...this.lending.values()];\n }\n\n listSwap(): SwapAdapter[] {\n return [...this.swap.values()];\n }\n}\n","export const MIST_PER_SUI = 1_000_000_000n;\nexport const SUI_DECIMALS = 9;\nexport const USDC_DECIMALS = 6;\n\nexport const BPS_DENOMINATOR = 10_000n;\nexport const PRECISION = 1_000_000_000_000_000_000n;\n\nexport const MIN_DEPOSIT = 1_000_000n; // 1 USDC (6 decimals)\nexport const GAS_RESERVE_USDC = 1_000_000n; // $1 USDC reserved for gas\nexport const AUTO_TOPUP_THRESHOLD = 50_000_000n; // 0.05 SUI\nexport const AUTO_TOPUP_AMOUNT = 1_000_000n; // $1 USDC worth of SUI\nexport const AUTO_TOPUP_MIN_USDC = 2_000_000n; // $2 USDC minimum to trigger auto-topup\nexport const BOOTSTRAP_LIMIT = 10;\nexport const GAS_FEE_CEILING_USD = 0.05;\n\nexport const SAVE_FEE_BPS = 10n; // 0.1%\nexport const SWAP_FEE_BPS = 0n; // Free — Cetus already charges pool fees\nexport const BORROW_FEE_BPS = 5n; // 0.05%\n\nexport const CLOCK_ID = '0x6';\n\nexport const SUPPORTED_ASSETS = {\n USDC: {\n type: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n symbol: 'USDC',\n },\n SUI: {\n type: '0x2::sui::SUI',\n decimals: 9,\n symbol: 'SUI',\n },\n} as const;\n\nexport type SupportedAsset = keyof typeof SUPPORTED_ASSETS;\n\nexport const T2000_PACKAGE_ID = process.env.T2000_PACKAGE_ID ?? '0xab92e9f1fe549ad3d6a52924a73181b45791e76120b975138fac9ec9b75db9f3';\nexport const T2000_CONFIG_ID = process.env.T2000_CONFIG_ID ?? '0x408add9aa9322f93cfd87523d8f603006eb8713894f4c460283c58a6888dae8a';\nexport const T2000_ADMIN_CAP_ID = '0x863d1b02cba1b93d0fe9b87eb92d58b60c1e85c001022cb2a760e07bade47e65';\nexport const T2000_UPGRADE_CAP_ID = '0xef28746d40f43ca6be1352102cef0152133bf5594e69caab28f40b1de74490c1';\nexport const T2000_TREASURY_ID = process.env.T2000_TREASURY_ID ?? '0x3bb501b8300125dca59019247941a42af6b292a150ce3cfcce9449456be2ec91';\n\nexport const DEFAULT_NETWORK = 'mainnet' as const;\nexport const DEFAULT_RPC_URL = 'https://fullnode.mainnet.sui.io:443';\nexport const DEFAULT_KEY_PATH = '~/.t2000/wallet.key';\nexport const DEFAULT_CONFIG_PATH = '~/.t2000/config.json';\n\nexport const API_BASE_URL = process.env.T2000_API_URL ?? 'https://api.t2000.ai';\n\nexport const CETUS_USDC_SUI_POOL = '0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab';\nexport const CETUS_GLOBAL_CONFIG = '0xdaa46292632c3c4d8f31f23ea0f9b36a28ff3677e9684980e4438403a67a3d8f';\nexport const CETUS_PACKAGE = '0x1eabed72c53feb3805120a081dc15963c204dc8d091542592abaf7a35689b2fb';\n\nexport const SENTINEL = {\n PACKAGE: '0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7',\n AGENT_REGISTRY: '0xc47564f5f14c12b31e0dfa1a3dc99a6380a1edf8929c28cb0eaa3359c8db36ac',\n ENCLAVE: '0xfb1261aeb9583514cb1341a548a5ec12d1231bd96af22215f1792617a93e1213',\n PROTOCOL_CONFIG: '0x2fa4fa4a1dd0498612304635ff9334e1b922e78af325000e9d9c0e88adea459f',\n TEE_API: 'https://app.suisentinel.xyz/api/consume-prompt',\n SENTINELS_API: 'https://api.suisentinel.xyz/agents/mainnet',\n RANDOM: '0x8',\n MIN_FEE_MIST: 100_000_000n, // 0.1 SUI\n MAX_PROMPT_TOKENS: 600,\n} as const;\n","export type T2000ErrorCode =\n | 'INSUFFICIENT_BALANCE'\n | 'INSUFFICIENT_GAS'\n | 'INVALID_ADDRESS'\n | 'INVALID_AMOUNT'\n | 'WALLET_NOT_FOUND'\n | 'WALLET_LOCKED'\n | 'WALLET_EXISTS'\n | 'SPONSOR_FAILED'\n | 'SPONSOR_RATE_LIMITED'\n | 'GAS_STATION_UNAVAILABLE'\n | 'GAS_FEE_EXCEEDED'\n | 'SIMULATION_FAILED'\n | 'TRANSACTION_FAILED'\n | 'ASSET_NOT_SUPPORTED'\n | 'SLIPPAGE_EXCEEDED'\n | 'HEALTH_FACTOR_TOO_LOW'\n | 'WITHDRAW_WOULD_LIQUIDATE'\n | 'NO_COLLATERAL'\n | 'PROTOCOL_PAUSED'\n | 'PROTOCOL_UNAVAILABLE'\n | 'RPC_ERROR'\n | 'RPC_UNREACHABLE'\n | 'SPONSOR_UNAVAILABLE'\n | 'AUTO_TOPUP_FAILED'\n | 'PRICE_EXCEEDS_LIMIT'\n | 'UNSUPPORTED_NETWORK'\n | 'PAYMENT_EXPIRED'\n | 'DUPLICATE_PAYMENT'\n | 'FACILITATOR_REJECTION'\n | 'FACILITATOR_TIMEOUT'\n | 'SENTINEL_API_ERROR'\n | 'SENTINEL_NOT_FOUND'\n | 'SENTINEL_TX_FAILED'\n | 'SENTINEL_TEE_ERROR'\n | 'UNKNOWN';\n\nexport interface T2000ErrorData {\n reason?: string;\n [key: string]: unknown;\n}\n\nexport class T2000Error extends Error {\n readonly code: T2000ErrorCode;\n readonly data?: T2000ErrorData;\n readonly retryable: boolean;\n\n constructor(code: T2000ErrorCode, message: string, data?: T2000ErrorData, retryable = false) {\n super(message);\n this.name = 'T2000Error';\n this.code = code;\n this.data = data;\n this.retryable = retryable;\n }\n\n toJSON() {\n return {\n error: this.code,\n message: this.message,\n ...(this.data && { data: this.data }),\n retryable: this.retryable,\n };\n }\n}\n\nexport function mapWalletError(error: unknown): T2000Error {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes('rejected') || msg.includes('cancelled')) {\n return new T2000Error('TRANSACTION_FAILED', 'Transaction cancelled');\n }\n if (msg.includes('Insufficient') || msg.includes('insufficient')) {\n return new T2000Error('INSUFFICIENT_BALANCE', 'Insufficient balance');\n }\n\n return new T2000Error('UNKNOWN', msg, undefined, true);\n}\n\nexport function mapMoveAbortCode(code: number): string {\n const abortMessages: Record<number, string> = {\n 1: 'Protocol is temporarily paused',\n 2: 'Amount must be greater than zero',\n 3: 'Invalid operation type',\n 4: 'Fee rate exceeds maximum',\n 5: 'Insufficient treasury balance',\n 6: 'Not authorized',\n 7: 'Package version mismatch — upgrade required',\n 8: 'Timelock is active — wait for expiry',\n 9: 'No pending change to execute',\n 10: 'Already at current version',\n };\n return abortMessages[code] ?? `Move abort code: ${code}`;\n}\n","import { MIST_PER_SUI, BPS_DENOMINATOR, USDC_DECIMALS, SUI_DECIMALS } from '../constants.js';\n\nexport function mistToSui(mist: bigint): number {\n return Number(mist) / Number(MIST_PER_SUI);\n}\n\nexport function suiToMist(sui: number): bigint {\n return BigInt(Math.round(sui * Number(MIST_PER_SUI)));\n}\n\nexport function usdcToRaw(amount: number): bigint {\n return BigInt(Math.round(amount * 10 ** USDC_DECIMALS));\n}\n\nexport function rawToUsdc(raw: bigint): number {\n return Number(raw) / 10 ** USDC_DECIMALS;\n}\n\nexport function rawToDisplay(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nexport function displayToRaw(amount: number, decimals: number): bigint {\n return BigInt(Math.round(amount * 10 ** decimals));\n}\n\nexport function bpsToPercent(bps: bigint): number {\n return Number(bps) / Number(BPS_DENOMINATOR) * 100;\n}\n\nexport function formatUsd(amount: number): string {\n return `$${amount.toFixed(2)}`;\n}\n\nexport function formatSui(amount: number): string {\n if (amount < 0.001) return `${amount.toFixed(6)} SUI`;\n return `${amount.toFixed(3)} SUI`;\n}\n\nexport function formatLargeNumber(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return n.toFixed(2);\n}\n","import { Transaction, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport type { SuiClient } from '@mysten/sui/client';\nimport {\n SAVE_FEE_BPS,\n SWAP_FEE_BPS,\n BORROW_FEE_BPS,\n BPS_DENOMINATOR,\n SUPPORTED_ASSETS,\n T2000_PACKAGE_ID,\n T2000_TREASURY_ID,\n T2000_CONFIG_ID,\n API_BASE_URL,\n} from '../constants.js';\nimport { usdcToRaw } from '../utils/format.js';\n\nexport type FeeOperation = 'save' | 'swap' | 'borrow';\n\nexport interface ProtocolFeeInfo {\n amount: number;\n asset: string;\n rate: number;\n rawAmount: bigint;\n}\n\nconst FEE_RATES: Record<FeeOperation, bigint> = {\n save: SAVE_FEE_BPS,\n swap: SWAP_FEE_BPS,\n borrow: BORROW_FEE_BPS,\n};\n\nconst OP_CODES: Record<FeeOperation, number> = {\n save: 0,\n swap: 1,\n borrow: 2,\n};\n\nexport function calculateFee(operation: FeeOperation, amount: number): ProtocolFeeInfo {\n const bps = FEE_RATES[operation];\n const feeAmount = amount * Number(bps) / Number(BPS_DENOMINATOR);\n const rawAmount = usdcToRaw(feeAmount);\n\n return {\n amount: feeAmount,\n asset: 'USDC',\n rate: Number(bps) / Number(BPS_DENOMINATOR),\n rawAmount,\n };\n}\n\n/**\n * Add on-chain fee collection to an existing PTB via t2000::treasury::collect_fee().\n * The Move function splits the fee from the payment coin and stores it in the\n * Treasury's internal Balance<T>. Atomic — reverts with the operation if it fails.\n */\nexport function addCollectFeeToTx(\n tx: Transaction,\n paymentCoin: TransactionObjectArgument,\n operation: FeeOperation,\n): void {\n const bps = FEE_RATES[operation];\n if (bps <= 0n) return;\n\n tx.moveCall({\n target: `${T2000_PACKAGE_ID}::treasury::collect_fee`,\n typeArguments: [SUPPORTED_ASSETS.USDC.type],\n arguments: [\n tx.object(T2000_TREASURY_ID),\n tx.object(T2000_CONFIG_ID),\n paymentCoin,\n tx.pure.u8(OP_CODES[operation]),\n ],\n });\n}\n\nexport async function reportFee(\n agentAddress: string,\n operation: string,\n feeAmount: number,\n feeRate: number,\n txDigest: string,\n): Promise<void> {\n try {\n await fetch(`${API_BASE_URL}/api/fees`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agentAddress,\n operation,\n feeAmount: feeAmount.toString(),\n feeRate: feeRate.toString(),\n txDigest,\n }),\n });\n } catch {\n // Non-critical — best-effort reporting\n }\n}\n","import {\n getPool,\n getLendingState,\n getHealthFactor as naviGetHealthFactor,\n getCoins,\n mergeCoinsPTB,\n depositCoinPTB,\n withdrawCoinPTB,\n borrowCoinPTB,\n repayCoinPTB,\n getPriceFeeds,\n filterPriceFeeds,\n updateOraclePricesPTB,\n} from '@naviprotocol/lending';\nimport type { SuiClient } from '@mysten/sui/client';\nimport type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport { SUPPORTED_ASSETS } from '../constants.js';\nimport { T2000Error } from '../errors.js';\nimport { usdcToRaw } from '../utils/format.js';\nimport { addCollectFeeToTx } from './protocolFee.js';\nimport type {\n SaveResult,\n WithdrawResult,\n BorrowResult,\n RepayResult,\n GasMethod,\n RatesResult,\n PositionsResult,\n PositionEntry,\n HealthFactorResult,\n MaxWithdrawResult,\n MaxBorrowResult,\n} from '../types.js';\n\nconst ENV = { env: 'prod' as const };\nconst USDC_TYPE = SUPPORTED_ASSETS.USDC.type;\nconst RATE_DECIMALS = 27;\nconst LTV_DECIMALS = 27;\nconst MIN_HEALTH_FACTOR = 1.5;\nconst WITHDRAW_DUST_BUFFER = 0.001;\n\n// NAVI normalizes all internal balances (supplyBalance, borrowBalance) to 9 decimal\n// places regardless of the token's native decimals. USDC is 6 on-chain, but NAVI\n// reports it with 3 extra decimals of precision. Verified empirically: depositing\n// 2_000_000 raw USDC (6-dec = $2) results in supplyBalance ≈ 2_000_000_000 (9-dec).\n// PTB functions (deposit/withdraw/borrow/repay) still use native 6-dec amounts.\nconst NAVI_BALANCE_DECIMALS = 9;\n\nfunction clientOpt(client: SuiClient, fresh = false) {\n return { client, ...ENV, ...(fresh ? { disableCache: true } : {}) };\n}\n\nfunction extractGasCost(effects: { gasUsed?: { computationCost: string; storageCost: string; storageRebate: string } } | undefined | null): number {\n if (!effects?.gasUsed) return 0;\n return Math.abs(\n (Number(effects.gasUsed.computationCost) +\n Number(effects.gasUsed.storageCost) -\n Number(effects.gasUsed.storageRebate)) /\n 1e9\n );\n}\n\nfunction rateToApy(rawRate: string): number {\n if (!rawRate || rawRate === '0') return 0;\n return Number(BigInt(rawRate)) / 10 ** RATE_DECIMALS * 100;\n}\n\nfunction parseLtv(rawLtv: string): number {\n if (!rawLtv || rawLtv === '0') return 0.75;\n return Number(BigInt(rawLtv)) / 10 ** LTV_DECIMALS;\n}\n\nfunction parseLiqThreshold(val: string | number): number {\n if (typeof val === 'number') return val;\n // NAVI returns thresholds as 27-decimal BigInt strings (e.g. \"850000000000000000000000000\"\n // for 0.85). If parseFloat yields > 1, it's a raw BigInt string needing conversion.\n const n = Number(val);\n if (n > 1) return Number(BigInt(val)) / 10 ** LTV_DECIMALS;\n return n;\n}\n\nfunction findUsdcPosition<T extends { pool: { token: { symbol: string }; coinType: string } }>(\n state: T[],\n): T | undefined {\n return state.find(\n (p) => p.pool.token.symbol === 'USDC' || p.pool.coinType.toLowerCase().includes('usdc'),\n );\n}\n\nasync function updateOracle(tx: Transaction, client: SuiClient, address: string): Promise<void> {\n try {\n const [feeds, state] = await Promise.all([\n getPriceFeeds(ENV),\n getLendingState(address, clientOpt(client)),\n ]);\n const relevant = filterPriceFeeds(feeds, { lendingState: state });\n if (relevant.length > 0) {\n await updateOraclePricesPTB(tx, relevant, { ...ENV, updatePythPriceFeeds: true });\n }\n } catch {\n // Oracle update failure is non-fatal — transaction may still succeed\n }\n}\n\nexport async function buildSaveTx(\n client: SuiClient,\n address: string,\n amount: number,\n options: { collectFee?: boolean } = {},\n): Promise<Transaction> {\n const rawAmount = Number(usdcToRaw(amount));\n\n const coins = await getCoins(address, { coinType: USDC_TYPE, client });\n if (!coins || coins.length === 0) {\n throw new T2000Error('INSUFFICIENT_BALANCE', 'No USDC coins found');\n }\n\n const tx = new Transaction();\n tx.setSender(address);\n\n const coinObj = mergeCoinsPTB(tx, coins, { balance: rawAmount });\n\n if (options.collectFee) {\n addCollectFeeToTx(tx, coinObj as TransactionObjectArgument, 'save');\n }\n\n await depositCoinPTB(tx, USDC_TYPE, coinObj, ENV);\n\n return tx;\n}\n\nexport async function save(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<SaveResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const tx = await buildSaveTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n const rates = await getRates(client);\n\n return {\n success: true,\n tx: result.digest,\n amount,\n apy: rates.USDC.saveApy,\n fee: 0,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n savingsBalance: amount,\n };\n}\n\nexport async function buildWithdrawTx(\n client: SuiClient,\n address: string,\n amount: number,\n): Promise<{ tx: Transaction; effectiveAmount: number }> {\n const state = await getLendingState(address, clientOpt(client, true));\n const usdcPos = findUsdcPosition(state);\n const deposited = usdcPos ? Number(usdcPos.supplyBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n\n const effectiveAmount = Math.min(amount, Math.max(0, deposited - WITHDRAW_DUST_BUFFER));\n if (effectiveAmount <= 0) throw new T2000Error('NO_COLLATERAL', 'Nothing to withdraw');\n\n const rawAmount = Number(usdcToRaw(effectiveAmount));\n\n const tx = new Transaction();\n tx.setSender(address);\n\n await updateOracle(tx, client, address);\n\n const withdrawnCoin = await withdrawCoinPTB(tx, USDC_TYPE, rawAmount, ENV);\n tx.transferObjects([withdrawnCoin], address);\n\n return { tx, effectiveAmount };\n}\n\nexport async function withdraw(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<WithdrawResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const { tx, effectiveAmount } = await buildWithdrawTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n return {\n success: true,\n tx: result.digest,\n amount: effectiveAmount,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n };\n}\n\nexport async function buildBorrowTx(\n client: SuiClient,\n address: string,\n amount: number,\n options: { collectFee?: boolean } = {},\n): Promise<Transaction> {\n const rawAmount = Number(usdcToRaw(amount));\n\n const tx = new Transaction();\n tx.setSender(address);\n\n await updateOracle(tx, client, address);\n\n const borrowedCoin = await borrowCoinPTB(tx, USDC_TYPE, rawAmount, ENV);\n\n if (options.collectFee) {\n addCollectFeeToTx(tx, borrowedCoin, 'borrow');\n }\n\n tx.transferObjects([borrowedCoin], address);\n\n return tx;\n}\n\nexport async function borrow(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<BorrowResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const tx = await buildBorrowTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n const hf = await naviGetHealthFactor(address, clientOpt(client, true));\n\n return {\n success: true,\n tx: result.digest,\n amount,\n fee: 0,\n healthFactor: hf,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n };\n}\n\nexport async function buildRepayTx(\n client: SuiClient,\n address: string,\n amount: number,\n): Promise<Transaction> {\n const rawAmount = Number(usdcToRaw(amount));\n\n const coins = await getCoins(address, { coinType: USDC_TYPE, client });\n if (!coins || coins.length === 0) {\n throw new T2000Error('INSUFFICIENT_BALANCE', 'No USDC coins to repay with');\n }\n\n const tx = new Transaction();\n tx.setSender(address);\n\n const coinObj = mergeCoinsPTB(tx, coins, { balance: rawAmount });\n await repayCoinPTB(tx, USDC_TYPE, coinObj, { ...ENV, amount: rawAmount });\n\n return tx;\n}\n\nexport async function repay(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<RepayResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const tx = await buildRepayTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n const state = await getLendingState(address, clientOpt(client, true));\n const usdcPos = findUsdcPosition(state);\n const remainingDebt = usdcPos ? Number(usdcPos.borrowBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n\n return {\n success: true,\n tx: result.digest,\n amount,\n remainingDebt,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n };\n}\n\nexport async function getHealthFactor(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<HealthFactorResult> {\n const address = typeof addressOrKeypair === 'string'\n ? addressOrKeypair\n : addressOrKeypair.getPublicKey().toSuiAddress();\n\n const [healthFactor, state, pool] = await Promise.all([\n naviGetHealthFactor(address, clientOpt(client, true)),\n getLendingState(address, clientOpt(client, true)),\n getPool(USDC_TYPE, ENV),\n ]);\n\n const usdcPos = findUsdcPosition(state);\n\n const supplied = usdcPos ? Number(usdcPos.supplyBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n const borrowed = usdcPos ? Number(usdcPos.borrowBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n\n const ltv = parseLtv(pool.ltv);\n const liqThreshold = parseLiqThreshold(pool.liquidationFactor.threshold);\n const maxBorrowVal = Math.max(0, supplied * ltv - borrowed);\n\n return {\n healthFactor: borrowed > 0 ? healthFactor : Infinity,\n supplied,\n borrowed,\n maxBorrow: maxBorrowVal,\n liquidationThreshold: liqThreshold,\n };\n}\n\nexport async function getRates(client: SuiClient): Promise<RatesResult> {\n try {\n const pool = await getPool(USDC_TYPE, ENV);\n\n let saveApy = rateToApy(pool.currentSupplyRate);\n let borrowApy = rateToApy(pool.currentBorrowRate);\n\n if (saveApy <= 0 || saveApy > 100) saveApy = 4.0;\n if (borrowApy <= 0 || borrowApy > 100) borrowApy = 6.0;\n\n return { USDC: { saveApy, borrowApy } };\n } catch {\n return { USDC: { saveApy: 4.0, borrowApy: 6.0 } };\n }\n}\n\nexport async function getPositions(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<PositionsResult> {\n const address = typeof addressOrKeypair === 'string'\n ? addressOrKeypair\n : addressOrKeypair.getPublicKey().toSuiAddress();\n\n const state = await getLendingState(address, clientOpt(client, true));\n const positions: PositionEntry[] = [];\n\n for (const pos of state) {\n const symbol = pos.pool.token?.symbol ?? 'UNKNOWN';\n const supplyBal = Number(pos.supplyBalance) / 10 ** NAVI_BALANCE_DECIMALS;\n const borrowBal = Number(pos.borrowBalance) / 10 ** NAVI_BALANCE_DECIMALS;\n\n if (supplyBal > 0.0001) {\n positions.push({\n protocol: 'navi',\n asset: symbol,\n type: 'save',\n amount: supplyBal,\n apy: rateToApy(pos.pool.currentSupplyRate),\n });\n }\n\n if (borrowBal > 0.0001) {\n positions.push({\n protocol: 'navi',\n asset: symbol,\n type: 'borrow',\n amount: borrowBal,\n apy: rateToApy(pos.pool.currentBorrowRate),\n });\n }\n }\n\n return { positions };\n}\n\nexport async function maxWithdrawAmount(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<MaxWithdrawResult> {\n const hf = await getHealthFactor(client, addressOrKeypair);\n const ltv = hf.liquidationThreshold > 0 ? hf.liquidationThreshold : 0.75;\n\n let maxAmount: number;\n if (hf.borrowed === 0) {\n maxAmount = hf.supplied;\n } else {\n maxAmount = Math.max(0, hf.supplied - (hf.borrowed * MIN_HEALTH_FACTOR / ltv));\n }\n\n const remainingSupply = hf.supplied - maxAmount;\n const hfAfter = hf.borrowed > 0 ? remainingSupply / hf.borrowed : Infinity;\n\n return {\n maxAmount,\n healthFactorAfter: hfAfter,\n currentHF: hf.healthFactor,\n };\n}\n\nexport async function maxBorrowAmount(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<MaxBorrowResult> {\n const hf = await getHealthFactor(client, addressOrKeypair);\n const ltv = hf.liquidationThreshold > 0 ? hf.liquidationThreshold : 0.75;\n\n const maxAmount = Math.max(0, hf.supplied * ltv / MIN_HEALTH_FACTOR - hf.borrowed);\n\n return {\n maxAmount,\n healthFactorAfter: MIN_HEALTH_FACTOR,\n currentHF: hf.healthFactor,\n };\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport type {\n LendingAdapter,\n LendingRates,\n AdapterPositions,\n HealthInfo,\n AdapterTxResult,\n AdapterCapability,\n} from './types.js';\nimport * as naviProtocol from '../protocols/navi.js';\n\nexport class NaviAdapter implements LendingAdapter {\n readonly id = 'navi';\n readonly name = 'NAVI Protocol';\n readonly version = '1.0.0';\n readonly capabilities: readonly AdapterCapability[] = ['save', 'withdraw', 'borrow', 'repay'];\n readonly supportedAssets: readonly string[] = ['USDC'];\n readonly supportsSameAssetBorrow = true;\n\n private client!: SuiClient;\n\n async init(client: SuiClient): Promise<void> {\n this.client = client;\n }\n\n initSync(client: SuiClient): void {\n this.client = client;\n }\n\n async getRates(asset: string): Promise<LendingRates> {\n const rates = await naviProtocol.getRates(this.client);\n const key = asset.toUpperCase() as keyof typeof rates;\n const r = rates[key];\n if (!r) throw new Error(`NAVI does not support ${asset}`);\n return { asset, saveApy: r.saveApy, borrowApy: r.borrowApy };\n }\n\n async getPositions(address: string): Promise<AdapterPositions> {\n const result = await naviProtocol.getPositions(this.client, address);\n return {\n supplies: result.positions\n .filter(p => p.type === 'save')\n .map(p => ({ asset: p.asset, amount: p.amount, apy: p.apy })),\n borrows: result.positions\n .filter(p => p.type === 'borrow')\n .map(p => ({ asset: p.asset, amount: p.amount, apy: p.apy })),\n };\n }\n\n async getHealth(address: string): Promise<HealthInfo> {\n return naviProtocol.getHealthFactor(this.client, address);\n }\n\n async buildSaveTx(\n address: string,\n amount: number,\n _asset: string,\n options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n const tx = await naviProtocol.buildSaveTx(this.client, address, amount, options);\n return { tx };\n }\n\n async buildWithdrawTx(\n address: string,\n amount: number,\n _asset: string,\n ): Promise<AdapterTxResult & { effectiveAmount: number }> {\n const result = await naviProtocol.buildWithdrawTx(this.client, address, amount);\n return { tx: result.tx, effectiveAmount: result.effectiveAmount };\n }\n\n async buildBorrowTx(\n address: string,\n amount: number,\n _asset: string,\n options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n const tx = await naviProtocol.buildBorrowTx(this.client, address, amount, options);\n return { tx };\n }\n\n async buildRepayTx(\n address: string,\n amount: number,\n _asset: string,\n ): Promise<AdapterTxResult> {\n const tx = await naviProtocol.buildRepayTx(this.client, address, amount);\n return { tx };\n }\n\n async maxWithdraw(address: string, _asset: string) {\n return naviProtocol.maxWithdrawAmount(this.client, address);\n }\n\n async maxBorrow(address: string, _asset: string) {\n return naviProtocol.maxBorrowAmount(this.client, address);\n }\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';\nimport { SUPPORTED_ASSETS, CETUS_USDC_SUI_POOL } from '../constants.js';\nimport { T2000Error } from '../errors.js';\nimport type { GasMethod } from '../types.js';\n\nconst DEFAULT_SLIPPAGE_BPS = 300; // 3%\n\nexport interface SwapParams {\n client: SuiClient;\n keypair: Ed25519Keypair;\n fromAsset: 'USDC' | 'SUI';\n toAsset: 'USDC' | 'SUI';\n amount: number;\n maxSlippageBps?: number;\n}\n\nexport interface SwapTxResult {\n digest: string;\n fromAmount: number;\n fromAsset: string;\n toAmount: number;\n toAsset: string;\n priceImpact: number;\n gasCost: number;\n}\n\nfunction extractGasCost(\n effects: { gasUsed?: { computationCost: string; storageCost: string; storageRebate: string } } | undefined | null,\n): number {\n if (!effects?.gasUsed) return 0;\n return (\n Number(effects.gasUsed.computationCost) +\n Number(effects.gasUsed.storageCost) -\n Number(effects.gasUsed.storageRebate)\n ) / 1e9;\n}\n\nexport interface SwapBuildResult {\n tx: Transaction;\n estimatedOut: number;\n toDecimals: number;\n}\n\nfunction createAggregatorClient(client: SuiClient, signer?: string): AggregatorClient {\n return new AggregatorClient({\n client,\n signer,\n env: Env.Mainnet,\n });\n}\n\nexport async function buildSwapTx(params: {\n client: SuiClient;\n address: string;\n fromAsset: 'USDC' | 'SUI';\n toAsset: 'USDC' | 'SUI';\n amount: number;\n maxSlippageBps?: number;\n}): Promise<SwapBuildResult> {\n const { client, address, fromAsset, toAsset, amount, maxSlippageBps = DEFAULT_SLIPPAGE_BPS } = params;\n\n const fromInfo = SUPPORTED_ASSETS[fromAsset];\n const toInfo = SUPPORTED_ASSETS[toAsset];\n const rawAmount = BigInt(Math.floor(amount * 10 ** fromInfo.decimals));\n\n const aggClient = createAggregatorClient(client, address);\n\n const result = await aggClient.findRouters({\n from: fromInfo.type,\n target: toInfo.type,\n amount: rawAmount,\n byAmountIn: true,\n });\n\n if (!result || result.insufficientLiquidity) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `No swap route found for ${fromAsset} → ${toAsset}`,\n );\n }\n\n const tx = new Transaction();\n const slippage = maxSlippageBps / 10000;\n\n await aggClient.fastRouterSwap({\n router: result,\n txb: tx,\n slippage,\n });\n\n const estimatedOut = Number(result.amountOut.toString());\n\n return {\n tx,\n estimatedOut,\n toDecimals: toInfo.decimals,\n };\n}\n\nexport async function executeSwap(params: SwapParams): Promise<SwapTxResult> {\n const { client, keypair, fromAsset, toAsset, amount, maxSlippageBps } = params;\n const address = keypair.getPublicKey().toSuiAddress();\n const toInfo = SUPPORTED_ASSETS[toAsset];\n\n const { tx, estimatedOut, toDecimals } = await buildSwapTx({\n client,\n address,\n fromAsset,\n toAsset,\n amount,\n maxSlippageBps,\n });\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true, showBalanceChanges: true },\n });\n\n await client.waitForTransaction({ digest: result.digest });\n\n let actualReceived = 0;\n if (result.balanceChanges) {\n for (const change of result.balanceChanges) {\n if (\n change.coinType === toInfo.type &&\n change.owner &&\n typeof change.owner === 'object' &&\n 'AddressOwner' in change.owner &&\n change.owner.AddressOwner === address\n ) {\n const amt = Number(change.amount) / 10 ** toInfo.decimals;\n if (amt > 0) actualReceived += amt;\n }\n }\n }\n\n const expectedOutput = estimatedOut / 10 ** toDecimals;\n if (actualReceived === 0) actualReceived = expectedOutput;\n\n const priceImpact = expectedOutput > 0\n ? Math.abs(actualReceived - expectedOutput) / expectedOutput\n : 0;\n\n return {\n digest: result.digest,\n fromAmount: amount,\n fromAsset,\n toAmount: actualReceived,\n toAsset,\n priceImpact,\n gasCost: extractGasCost(result.effects as Parameters<typeof extractGasCost>[0]),\n };\n}\n\nexport async function getPoolPrice(client: SuiClient): Promise<number> {\n try {\n const pool = await client.getObject({\n id: CETUS_USDC_SUI_POOL,\n options: { showContent: true },\n });\n\n if (pool.data?.content?.dataType === 'moveObject') {\n const fields = pool.data.content.fields as Record<string, unknown>;\n const currentSqrtPrice = BigInt(String(fields.current_sqrt_price ?? '0'));\n\n if (currentSqrtPrice > 0n) {\n const Q64 = 2n ** 64n;\n const sqrtPriceFloat = Number(currentSqrtPrice) / Number(Q64);\n const rawPrice = sqrtPriceFloat * sqrtPriceFloat;\n const suiPriceUsd = 1e3 / rawPrice;\n if (suiPriceUsd > 0.01 && suiPriceUsd < 1000) return suiPriceUsd;\n }\n }\n } catch {\n // Fallback\n }\n\n return 3.5;\n}\n\nexport async function getSwapQuote(\n client: SuiClient,\n fromAsset: 'USDC' | 'SUI',\n toAsset: 'USDC' | 'SUI',\n amount: number,\n): Promise<{ expectedOutput: number; priceImpact: number; poolPrice: number }> {\n const fromInfo = SUPPORTED_ASSETS[fromAsset];\n const toInfo = SUPPORTED_ASSETS[toAsset];\n const rawAmount = BigInt(Math.floor(amount * 10 ** fromInfo.decimals));\n\n const poolPrice = await getPoolPrice(client);\n\n try {\n const aggClient = createAggregatorClient(client);\n\n const result = await aggClient.findRouters({\n from: fromInfo.type,\n target: toInfo.type,\n amount: rawAmount,\n byAmountIn: true,\n });\n\n if (!result || result.insufficientLiquidity) {\n return fallbackQuote(fromAsset, amount, poolPrice);\n }\n\n const expectedOutput = Number(result.amountOut.toString()) / 10 ** toInfo.decimals;\n const priceImpact = result.deviationRatio ?? 0;\n\n return { expectedOutput, priceImpact, poolPrice };\n } catch {\n return fallbackQuote(fromAsset, amount, poolPrice);\n }\n}\n\nfunction fallbackQuote(\n fromAsset: string,\n amount: number,\n poolPrice: number,\n): { expectedOutput: number; priceImpact: number; poolPrice: number } {\n const expectedOutput = fromAsset === 'USDC'\n ? amount / poolPrice\n : amount * poolPrice;\n return { expectedOutput, priceImpact: 0, poolPrice };\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport type {\n SwapAdapter,\n SwapQuote,\n AdapterTxResult,\n AdapterCapability,\n} from './types.js';\nimport * as cetusProtocol from '../protocols/cetus.js';\n\nexport class CetusAdapter implements SwapAdapter {\n readonly id = 'cetus';\n readonly name = 'Cetus';\n readonly version = '1.0.0';\n readonly capabilities: readonly AdapterCapability[] = ['swap'];\n\n private client!: SuiClient;\n\n async init(client: SuiClient): Promise<void> {\n this.client = client;\n }\n\n initSync(client: SuiClient): void {\n this.client = client;\n }\n\n async getQuote(from: string, to: string, amount: number): Promise<SwapQuote> {\n return cetusProtocol.getSwapQuote(\n this.client,\n from.toUpperCase() as 'USDC' | 'SUI',\n to.toUpperCase() as 'USDC' | 'SUI',\n amount,\n );\n }\n\n async buildSwapTx(\n address: string,\n from: string,\n to: string,\n amount: number,\n maxSlippageBps?: number,\n ): Promise<AdapterTxResult & { estimatedOut: number; toDecimals: number }> {\n const result = await cetusProtocol.buildSwapTx({\n client: this.client,\n address,\n fromAsset: from.toUpperCase() as 'USDC' | 'SUI',\n toAsset: to.toUpperCase() as 'USDC' | 'SUI',\n amount,\n maxSlippageBps,\n });\n return {\n tx: result.tx,\n estimatedOut: result.estimatedOut,\n toDecimals: result.toDecimals,\n };\n }\n\n getSupportedPairs(): Array<{ from: string; to: string }> {\n return [\n { from: 'USDC', to: 'SUI' },\n { from: 'SUI', to: 'USDC' },\n ];\n }\n\n async getPoolPrice(): Promise<number> {\n return cetusProtocol.getPoolPrice(this.client);\n }\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { normalizeStructTag } from '@mysten/sui/utils';\nimport type {\n LendingAdapter,\n LendingRates,\n AdapterPositions,\n HealthInfo,\n AdapterTxResult,\n AdapterCapability,\n} from './types.js';\nimport { SUPPORTED_ASSETS } from '../constants.js';\nimport { usdcToRaw } from '../utils/format.js';\nimport { T2000Error } from '../errors.js';\nimport { addCollectFeeToTx } from '../protocols/protocolFee.js';\nimport type { TransactionObjectArgument } from '@mysten/sui/transactions';\n\nconst USDC_TYPE = SUPPORTED_ASSETS.USDC.type;\nconst USDC_DECIMALS = SUPPORTED_ASSETS.USDC.decimals;\nconst WAD = 1e18;\nconst MIN_HEALTH_FACTOR = 1.5;\n\ninterface SuilendSdk {\n SuilendClient: {\n initialize(id: string, type: string, client: SuiClient): Promise<SuilendClientInstance>;\n getObligationOwnerCaps(\n ownerId: string,\n typeArgs: string[],\n client: SuiClient,\n ): Promise<ObligationOwnerCap[]>;\n };\n LENDING_MARKET_ID: string;\n LENDING_MARKET_TYPE: string;\n}\n\ninterface SuilendClientInstance {\n lendingMarket: {\n id: string;\n $typeArgs: string[];\n reserves: SuilendReserve[];\n };\n createObligation(tx: Transaction): [TransactionObjectArgument];\n deposit(\n coin: TransactionObjectArgument,\n coinType: string,\n obligationOwnerCap: TransactionObjectArgument | string,\n tx: Transaction,\n ): void;\n withdrawAndSendToUser(\n ownerId: string,\n obligationOwnerCap: string,\n obligationId: string,\n coinType: string,\n value: string,\n tx: Transaction,\n ): Promise<void>;\n getObligation(obligationId: string): Promise<SuilendObligation>;\n findReserveArrayIndex(coinType: string): bigint;\n}\n\ninterface SuilendReserve {\n coinType: { name: string };\n mintDecimals: number;\n availableAmount: bigint;\n borrowedAmount: { value: bigint };\n ctokenSupply: bigint;\n unclaimedSpreadFees: { value: bigint };\n cumulativeBorrowRate: { value: bigint };\n price: { value: bigint };\n config: {\n element: {\n openLtvPct: number;\n closeLtvPct: number;\n spreadFeeBps: bigint | number;\n interestRateUtils: (bigint | number)[];\n interestRateAprs: (bigint | number)[];\n } | null;\n };\n}\n\ninterface ObligationOwnerCap {\n id: string;\n obligationId: string;\n}\n\ninterface SuilendObligation {\n id: string;\n deposits: Array<{\n coinType: { name: string };\n depositedCtokenAmount: bigint;\n reserveArrayIndex: bigint;\n }>;\n borrows: Array<{\n coinType: { name: string };\n borrowedAmount: { value: bigint };\n cumulativeBorrowRate: { value: bigint };\n reserveArrayIndex: bigint;\n }>;\n}\n\nfunction interpolateRate(\n utilBreakpoints: number[],\n aprBreakpoints: number[],\n utilizationPct: number,\n): number {\n if (utilBreakpoints.length === 0) return 0;\n if (utilizationPct <= utilBreakpoints[0]) return aprBreakpoints[0];\n if (utilizationPct >= utilBreakpoints[utilBreakpoints.length - 1]) {\n return aprBreakpoints[aprBreakpoints.length - 1];\n }\n\n for (let i = 1; i < utilBreakpoints.length; i++) {\n if (utilizationPct <= utilBreakpoints[i]) {\n const t =\n (utilizationPct - utilBreakpoints[i - 1]) /\n (utilBreakpoints[i] - utilBreakpoints[i - 1]);\n return aprBreakpoints[i - 1] + t * (aprBreakpoints[i] - aprBreakpoints[i - 1]);\n }\n }\n return aprBreakpoints[aprBreakpoints.length - 1];\n}\n\nfunction computeRatesFromReserve(reserve: SuilendReserve): {\n borrowAprPct: number;\n depositAprPct: number;\n utilizationPct: number;\n} {\n const decimals = reserve.mintDecimals;\n const available = Number(reserve.availableAmount) / 10 ** decimals;\n const borrowed =\n Number(reserve.borrowedAmount.value) / WAD / 10 ** decimals;\n const totalDeposited = available + borrowed;\n const utilizationPct =\n totalDeposited > 0 ? (borrowed / totalDeposited) * 100 : 0;\n\n const config = reserve.config.element;\n if (!config) return { borrowAprPct: 0, depositAprPct: 0, utilizationPct: 0 };\n\n const utils = config.interestRateUtils.map(Number);\n const aprs = config.interestRateAprs.map((a) => Number(a) / 100);\n\n const borrowAprPct = interpolateRate(utils, aprs, utilizationPct);\n const spreadFeeBps = Number(config.spreadFeeBps);\n const depositAprPct =\n (utilizationPct / 100) *\n (borrowAprPct / 100) *\n (1 - spreadFeeBps / 10000) *\n 100;\n\n return { borrowAprPct, depositAprPct, utilizationPct };\n}\n\nfunction cTokenRatio(reserve: SuilendReserve): number {\n if (reserve.ctokenSupply === 0n) return 1;\n\n const available = Number(reserve.availableAmount);\n const borrowed = Number(reserve.borrowedAmount.value) / WAD;\n const spreadFees = Number(reserve.unclaimedSpreadFees.value) / WAD;\n const totalSupply = available + borrowed - spreadFees;\n\n return totalSupply / Number(reserve.ctokenSupply);\n}\n\n/**\n * Suilend adapter — save + withdraw for USDC.\n * Borrow/repay deferred to Phase 10 (requires multi-stable support).\n *\n * Uses the @suilend/sdk package (optional peer dependency). Users must\n * install it separately: `npm install @suilend/sdk@^1`\n *\n * @see https://docs.suilend.fi/ecosystem/suilend-sdk-guide\n */\nexport class SuilendAdapter implements LendingAdapter {\n readonly id = 'suilend';\n readonly name = 'Suilend';\n readonly version = '1.0.0';\n readonly capabilities: readonly AdapterCapability[] = ['save', 'withdraw'];\n readonly supportedAssets: readonly string[] = ['USDC'];\n readonly supportsSameAssetBorrow = false;\n\n private client!: SuiClient;\n private suilend!: SuilendClientInstance;\n private lendingMarketType!: string;\n private initialized = false;\n\n async init(client: SuiClient): Promise<void> {\n let sdk: SuilendSdk;\n try {\n sdk = (await import('@suilend/sdk')) as unknown as SuilendSdk;\n } catch {\n throw new T2000Error(\n 'PROTOCOL_UNAVAILABLE',\n 'Suilend SDK not installed. Run: npm install @suilend/sdk@^1',\n );\n }\n\n this.client = client;\n this.lendingMarketType = sdk.LENDING_MARKET_TYPE;\n\n try {\n this.suilend = await sdk.SuilendClient.initialize(\n sdk.LENDING_MARKET_ID,\n sdk.LENDING_MARKET_TYPE,\n client,\n );\n } catch (err) {\n throw new T2000Error(\n 'PROTOCOL_UNAVAILABLE',\n `Failed to initialize Suilend: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n this.initialized = true;\n }\n\n private ensureInit(): void {\n if (!this.initialized) {\n throw new T2000Error(\n 'PROTOCOL_UNAVAILABLE',\n 'SuilendAdapter not initialized. Call init() first.',\n );\n }\n }\n\n private findReserve(asset: string): SuilendReserve | undefined {\n const upper = asset.toUpperCase();\n let coinType: string;\n if (upper === 'USDC') coinType = USDC_TYPE;\n else if (upper === 'SUI') coinType = '0x2::sui::SUI';\n else if (asset.includes('::')) coinType = asset;\n else return undefined;\n\n try {\n const normalized = normalizeStructTag(coinType);\n return this.suilend.lendingMarket.reserves.find(\n (r) => normalizeStructTag(r.coinType.name) === normalized,\n );\n } catch {\n return undefined;\n }\n }\n\n private async getObligationCaps(address: string): Promise<ObligationOwnerCap[]> {\n const SuilendClientStatic = ((await import('@suilend/sdk')) as unknown as SuilendSdk).SuilendClient;\n return SuilendClientStatic.getObligationOwnerCaps(\n address,\n [this.lendingMarketType],\n this.client,\n );\n }\n\n private resolveSymbol(coinType: string): string {\n const normalized = normalizeStructTag(coinType);\n if (normalized === normalizeStructTag(USDC_TYPE)) return 'USDC';\n if (normalized === normalizeStructTag('0x2::sui::SUI')) return 'SUI';\n const parts = coinType.split('::');\n return parts[parts.length - 1] || 'UNKNOWN';\n }\n\n async getRates(asset: string): Promise<LendingRates> {\n this.ensureInit();\n\n const reserve = this.findReserve(asset);\n if (!reserve) {\n throw new T2000Error('ASSET_NOT_SUPPORTED', `Suilend does not support ${asset}`);\n }\n\n const { borrowAprPct, depositAprPct } = computeRatesFromReserve(reserve);\n\n return {\n asset,\n saveApy: depositAprPct,\n borrowApy: borrowAprPct,\n };\n }\n\n async getPositions(address: string): Promise<AdapterPositions> {\n this.ensureInit();\n\n const supplies: Array<{ asset: string; amount: number; apy: number }> = [];\n const borrows: Array<{ asset: string; amount: number; apy: number }> = [];\n\n const caps = await this.getObligationCaps(address);\n if (caps.length === 0) return { supplies, borrows };\n\n const obligation = await this.suilend.getObligation(caps[0].obligationId);\n\n for (const deposit of obligation.deposits) {\n const coinType = normalizeStructTag(deposit.coinType.name);\n const reserve = this.suilend.lendingMarket.reserves.find(\n (r) => normalizeStructTag(r.coinType.name) === coinType,\n );\n if (!reserve) continue;\n\n const ctokenAmount = Number(deposit.depositedCtokenAmount.toString());\n const ratio = cTokenRatio(reserve);\n const amount = (ctokenAmount * ratio) / 10 ** reserve.mintDecimals;\n const { depositAprPct } = computeRatesFromReserve(reserve);\n\n supplies.push({ asset: this.resolveSymbol(coinType), amount, apy: depositAprPct });\n }\n\n for (const borrow of obligation.borrows) {\n const coinType = normalizeStructTag(borrow.coinType.name);\n const reserve = this.suilend.lendingMarket.reserves.find(\n (r) => normalizeStructTag(r.coinType.name) === coinType,\n );\n if (!reserve) continue;\n\n const rawBorrowed = Number(borrow.borrowedAmount.value.toString()) / WAD;\n const amount = rawBorrowed / 10 ** reserve.mintDecimals;\n\n const reserveRate = Number(reserve.cumulativeBorrowRate.value.toString()) / WAD;\n const posRate = Number(borrow.cumulativeBorrowRate.value.toString()) / WAD;\n const compounded = posRate > 0 ? amount * (reserveRate / posRate) : amount;\n\n const { borrowAprPct } = computeRatesFromReserve(reserve);\n borrows.push({ asset: this.resolveSymbol(coinType), amount: compounded, apy: borrowAprPct });\n }\n\n return { supplies, borrows };\n }\n\n async getHealth(address: string): Promise<HealthInfo> {\n this.ensureInit();\n\n const caps = await this.getObligationCaps(address);\n if (caps.length === 0) {\n return { healthFactor: Infinity, supplied: 0, borrowed: 0, maxBorrow: 0, liquidationThreshold: 0 };\n }\n\n const positions = await this.getPositions(address);\n const supplied = positions.supplies.reduce((s, p) => s + p.amount, 0);\n const borrowed = positions.borrows.reduce((s, p) => s + p.amount, 0);\n\n const reserve = this.findReserve('USDC');\n const closeLtv = reserve?.config?.element?.closeLtvPct ?? 75;\n const openLtv = reserve?.config?.element?.openLtvPct ?? 70;\n const liqThreshold = closeLtv / 100;\n\n const healthFactor = borrowed > 0\n ? (supplied * liqThreshold) / borrowed\n : Infinity;\n\n const maxBorrow = Math.max(0, supplied * (openLtv / 100) - borrowed);\n\n return { healthFactor, supplied, borrowed, maxBorrow, liquidationThreshold: liqThreshold };\n }\n\n async buildSaveTx(\n address: string,\n amount: number,\n _asset: string,\n options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n this.ensureInit();\n\n const rawAmount = usdcToRaw(amount).toString();\n const tx = new Transaction();\n tx.setSender(address);\n\n const caps = await this.getObligationCaps(address);\n let capRef: TransactionObjectArgument | string;\n\n if (caps.length === 0) {\n const [newCap] = this.suilend.createObligation(tx);\n capRef = newCap;\n } else {\n capRef = caps[0].id;\n }\n\n const allCoins = await this.fetchAllCoins(address, USDC_TYPE);\n if (allCoins.length === 0) {\n throw new T2000Error('INSUFFICIENT_BALANCE', 'No USDC coins found');\n }\n\n const primaryCoinId = allCoins[0].coinObjectId;\n if (allCoins.length > 1) {\n tx.mergeCoins(\n tx.object(primaryCoinId),\n allCoins.slice(1).map((c) => tx.object(c.coinObjectId)),\n );\n }\n\n const [depositCoin] = tx.splitCoins(tx.object(primaryCoinId), [rawAmount]);\n\n if (options?.collectFee) {\n addCollectFeeToTx(tx, depositCoin as TransactionObjectArgument, 'save');\n }\n\n this.suilend.deposit(depositCoin as TransactionObjectArgument, USDC_TYPE, capRef, tx);\n\n return { tx };\n }\n\n async buildWithdrawTx(\n address: string,\n amount: number,\n _asset: string,\n ): Promise<AdapterTxResult & { effectiveAmount: number }> {\n this.ensureInit();\n\n const caps = await this.getObligationCaps(address);\n if (caps.length === 0) {\n throw new T2000Error('NO_COLLATERAL', 'No Suilend position found');\n }\n\n const positions = await this.getPositions(address);\n const usdcSupply = positions.supplies.find((s) => s.asset === 'USDC');\n const deposited = usdcSupply?.amount ?? 0;\n\n const effectiveAmount = Math.min(amount, deposited);\n if (effectiveAmount <= 0) {\n throw new T2000Error('NO_COLLATERAL', 'Nothing to withdraw from Suilend');\n }\n\n const rawAmount = usdcToRaw(effectiveAmount).toString();\n const tx = new Transaction();\n tx.setSender(address);\n\n await this.suilend.withdrawAndSendToUser(\n address,\n caps[0].id,\n caps[0].obligationId,\n USDC_TYPE,\n rawAmount,\n tx,\n );\n\n return { tx, effectiveAmount };\n }\n\n async buildBorrowTx(\n _address: string,\n _amount: number,\n _asset: string,\n _options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n 'SuilendAdapter.buildBorrowTx() not available — Suilend requires different collateral/borrow assets. Deferred to Phase 10.',\n );\n }\n\n async buildRepayTx(\n _address: string,\n _amount: number,\n _asset: string,\n ): Promise<AdapterTxResult> {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n 'SuilendAdapter.buildRepayTx() not available — deferred to Phase 10.',\n );\n }\n\n async maxWithdraw(\n address: string,\n _asset: string,\n ): Promise<{ maxAmount: number; healthFactorAfter: number; currentHF: number }> {\n this.ensureInit();\n\n const health = await this.getHealth(address);\n\n let maxAmount: number;\n if (health.borrowed === 0) {\n maxAmount = health.supplied;\n } else {\n maxAmount = Math.max(\n 0,\n health.supplied - (health.borrowed * MIN_HEALTH_FACTOR) / health.liquidationThreshold,\n );\n }\n\n const remainingSupply = health.supplied - maxAmount;\n const hfAfter = health.borrowed > 0\n ? (remainingSupply * health.liquidationThreshold) / health.borrowed\n : Infinity;\n\n return {\n maxAmount,\n healthFactorAfter: hfAfter,\n currentHF: health.healthFactor,\n };\n }\n\n async maxBorrow(\n _address: string,\n _asset: string,\n ): Promise<{ maxAmount: number; healthFactorAfter: number; currentHF: number }> {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n 'SuilendAdapter.maxBorrow() not available — deferred to Phase 10.',\n );\n }\n\n private async fetchAllCoins(\n owner: string,\n coinType: string,\n ): Promise<Array<{ coinObjectId: string; balance: string }>> {\n const all: Array<{ coinObjectId: string; balance: string }> = [];\n let cursor: string | null | undefined = null;\n let hasNext = true;\n\n while (hasNext) {\n const page = await this.client.getCoins({ owner, coinType, cursor: cursor ?? undefined });\n all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));\n cursor = page.nextCursor;\n hasNext = page.hasNextPage;\n }\n\n return all;\n }\n}\n"]}
1
+ {"version":3,"sources":["../../src/adapters/registry.ts","../../src/constants.ts","../../src/errors.ts","../../src/utils/format.ts","../../src/protocols/protocolFee.ts","../../src/protocols/navi.ts","../../src/adapters/navi.ts","../../src/protocols/cetus.ts","../../src/adapters/cetus.ts","../../src/adapters/suilend.ts"],"names":["naviGetHealthFactor","Transaction","USDC_TYPE","MIN_HEALTH_FACTOR"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n LendingAdapter,\n SwapAdapter,\n LendingRates,\n SwapQuote,\n AdapterPositions,\n} from './types.js';\n\nexport class ProtocolRegistry {\n private lending: Map<string, LendingAdapter> = new Map();\n private swap: Map<string, SwapAdapter> = new Map();\n\n registerLending(adapter: LendingAdapter): void {\n this.lending.set(adapter.id, adapter);\n }\n\n registerSwap(adapter: SwapAdapter): void {\n this.swap.set(adapter.id, adapter);\n }\n\n async bestSaveRate(asset: string): Promise<{ adapter: LendingAdapter; rate: LendingRates }> {\n const candidates: Array<{ adapter: LendingAdapter; rate: LendingRates }> = [];\n\n for (const adapter of this.lending.values()) {\n if (!adapter.supportedAssets.includes(asset)) continue;\n if (!adapter.capabilities.includes('save')) continue;\n try {\n const rate = await adapter.getRates(asset);\n candidates.push({ adapter, rate });\n } catch {\n // skip adapters that fail to fetch rates\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(`No lending adapter supports saving ${asset}`);\n }\n\n candidates.sort((a, b) => b.rate.saveApy - a.rate.saveApy);\n return candidates[0];\n }\n\n async bestBorrowRate(asset: string, opts?: { requireSameAssetBorrow?: boolean }): Promise<{ adapter: LendingAdapter; rate: LendingRates }> {\n const candidates: Array<{ adapter: LendingAdapter; rate: LendingRates }> = [];\n\n for (const adapter of this.lending.values()) {\n if (!adapter.supportedAssets.includes(asset)) continue;\n if (!adapter.capabilities.includes('borrow')) continue;\n if (opts?.requireSameAssetBorrow && !adapter.supportsSameAssetBorrow) continue;\n try {\n const rate = await adapter.getRates(asset);\n candidates.push({ adapter, rate });\n } catch {\n // skip\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(`No lending adapter supports borrowing ${asset}`);\n }\n\n candidates.sort((a, b) => a.rate.borrowApy - b.rate.borrowApy);\n return candidates[0];\n }\n\n async bestSwapQuote(from: string, to: string, amount: number): Promise<{ adapter: SwapAdapter; quote: SwapQuote }> {\n const candidates: Array<{ adapter: SwapAdapter; quote: SwapQuote }> = [];\n\n for (const adapter of this.swap.values()) {\n const pairs = adapter.getSupportedPairs();\n if (!pairs.some(p => p.from === from && p.to === to)) continue;\n try {\n const quote = await adapter.getQuote(from, to, amount);\n candidates.push({ adapter, quote });\n } catch {\n // skip\n }\n }\n\n if (candidates.length === 0) {\n throw new Error(`No swap adapter supports ${from} → ${to}`);\n }\n\n candidates.sort((a, b) => b.quote.expectedOutput - a.quote.expectedOutput);\n return candidates[0];\n }\n\n async allRates(asset: string): Promise<Array<{ protocol: string; protocolId: string; rates: LendingRates }>> {\n const results: Array<{ protocol: string; protocolId: string; rates: LendingRates }> = [];\n for (const adapter of this.lending.values()) {\n if (!adapter.supportedAssets.includes(asset)) continue;\n try {\n const rates = await adapter.getRates(asset);\n results.push({ protocol: adapter.name, protocolId: adapter.id, rates });\n } catch {\n // skip\n }\n }\n return results;\n }\n\n async allPositions(address: string): Promise<Array<{ protocol: string; protocolId: string; positions: AdapterPositions }>> {\n const results: Array<{ protocol: string; protocolId: string; positions: AdapterPositions }> = [];\n for (const adapter of this.lending.values()) {\n try {\n const positions = await adapter.getPositions(address);\n if (positions.supplies.length > 0 || positions.borrows.length > 0) {\n results.push({ protocol: adapter.name, protocolId: adapter.id, positions });\n }\n } catch {\n // skip\n }\n }\n return results;\n }\n\n getLending(id: string): LendingAdapter | undefined {\n return this.lending.get(id);\n }\n\n getSwap(id: string): SwapAdapter | undefined {\n return this.swap.get(id);\n }\n\n listLending(): LendingAdapter[] {\n return [...this.lending.values()];\n }\n\n listSwap(): SwapAdapter[] {\n return [...this.swap.values()];\n }\n}\n","export const MIST_PER_SUI = 1_000_000_000n;\nexport const SUI_DECIMALS = 9;\nexport const USDC_DECIMALS = 6;\n\nexport const BPS_DENOMINATOR = 10_000n;\nexport const PRECISION = 1_000_000_000_000_000_000n;\n\nexport const MIN_DEPOSIT = 1_000_000n; // 1 USDC (6 decimals)\nexport const GAS_RESERVE_USDC = 1_000_000n; // $1 USDC reserved for gas\nexport const AUTO_TOPUP_THRESHOLD = 50_000_000n; // 0.05 SUI\nexport const AUTO_TOPUP_AMOUNT = 1_000_000n; // $1 USDC worth of SUI\nexport const AUTO_TOPUP_MIN_USDC = 2_000_000n; // $2 USDC minimum to trigger auto-topup\nexport const BOOTSTRAP_LIMIT = 10;\nexport const GAS_FEE_CEILING_USD = 0.05;\n\nexport const SAVE_FEE_BPS = 10n; // 0.1%\nexport const SWAP_FEE_BPS = 0n; // Free — Cetus already charges pool fees\nexport const BORROW_FEE_BPS = 5n; // 0.05%\n\nexport const CLOCK_ID = '0x6';\n\nexport const SUPPORTED_ASSETS = {\n USDC: {\n type: '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC',\n decimals: 6,\n symbol: 'USDC',\n },\n SUI: {\n type: '0x2::sui::SUI',\n decimals: 9,\n symbol: 'SUI',\n },\n} as const;\n\nexport type SupportedAsset = keyof typeof SUPPORTED_ASSETS;\n\nexport const T2000_PACKAGE_ID = process.env.T2000_PACKAGE_ID ?? '0xab92e9f1fe549ad3d6a52924a73181b45791e76120b975138fac9ec9b75db9f3';\nexport const T2000_CONFIG_ID = process.env.T2000_CONFIG_ID ?? '0x408add9aa9322f93cfd87523d8f603006eb8713894f4c460283c58a6888dae8a';\nexport const T2000_ADMIN_CAP_ID = '0x863d1b02cba1b93d0fe9b87eb92d58b60c1e85c001022cb2a760e07bade47e65';\nexport const T2000_UPGRADE_CAP_ID = '0xef28746d40f43ca6be1352102cef0152133bf5594e69caab28f40b1de74490c1';\nexport const T2000_TREASURY_ID = process.env.T2000_TREASURY_ID ?? '0x3bb501b8300125dca59019247941a42af6b292a150ce3cfcce9449456be2ec91';\n\nexport const DEFAULT_NETWORK = 'mainnet' as const;\nexport const DEFAULT_RPC_URL = 'https://fullnode.mainnet.sui.io:443';\nexport const DEFAULT_KEY_PATH = '~/.t2000/wallet.key';\nexport const DEFAULT_CONFIG_PATH = '~/.t2000/config.json';\n\nexport const API_BASE_URL = process.env.T2000_API_URL ?? 'https://api.t2000.ai';\n\nexport const CETUS_USDC_SUI_POOL = '0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab';\nexport const CETUS_GLOBAL_CONFIG = '0xdaa46292632c3c4d8f31f23ea0f9b36a28ff3677e9684980e4438403a67a3d8f';\nexport const CETUS_PACKAGE = '0x1eabed72c53feb3805120a081dc15963c204dc8d091542592abaf7a35689b2fb';\n\nexport const SENTINEL = {\n PACKAGE: '0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7',\n AGENT_REGISTRY: '0xc47564f5f14c12b31e0dfa1a3dc99a6380a1edf8929c28cb0eaa3359c8db36ac',\n ENCLAVE: '0xfb1261aeb9583514cb1341a548a5ec12d1231bd96af22215f1792617a93e1213',\n PROTOCOL_CONFIG: '0x2fa4fa4a1dd0498612304635ff9334e1b922e78af325000e9d9c0e88adea459f',\n TEE_API: 'https://app.suisentinel.xyz/api/consume-prompt',\n SENTINELS_API: 'https://api.suisentinel.xyz/agents/mainnet',\n RANDOM: '0x8',\n MIN_FEE_MIST: 100_000_000n, // 0.1 SUI\n MAX_PROMPT_TOKENS: 600,\n} as const;\n","export type T2000ErrorCode =\n | 'INSUFFICIENT_BALANCE'\n | 'INSUFFICIENT_GAS'\n | 'INVALID_ADDRESS'\n | 'INVALID_AMOUNT'\n | 'WALLET_NOT_FOUND'\n | 'WALLET_LOCKED'\n | 'WALLET_EXISTS'\n | 'SPONSOR_FAILED'\n | 'SPONSOR_RATE_LIMITED'\n | 'GAS_STATION_UNAVAILABLE'\n | 'GAS_FEE_EXCEEDED'\n | 'SIMULATION_FAILED'\n | 'TRANSACTION_FAILED'\n | 'ASSET_NOT_SUPPORTED'\n | 'SLIPPAGE_EXCEEDED'\n | 'HEALTH_FACTOR_TOO_LOW'\n | 'WITHDRAW_WOULD_LIQUIDATE'\n | 'NO_COLLATERAL'\n | 'PROTOCOL_PAUSED'\n | 'PROTOCOL_UNAVAILABLE'\n | 'RPC_ERROR'\n | 'RPC_UNREACHABLE'\n | 'SPONSOR_UNAVAILABLE'\n | 'AUTO_TOPUP_FAILED'\n | 'PRICE_EXCEEDS_LIMIT'\n | 'UNSUPPORTED_NETWORK'\n | 'PAYMENT_EXPIRED'\n | 'DUPLICATE_PAYMENT'\n | 'FACILITATOR_REJECTION'\n | 'FACILITATOR_TIMEOUT'\n | 'SENTINEL_API_ERROR'\n | 'SENTINEL_NOT_FOUND'\n | 'SENTINEL_TX_FAILED'\n | 'SENTINEL_TEE_ERROR'\n | 'UNKNOWN';\n\nexport interface T2000ErrorData {\n reason?: string;\n [key: string]: unknown;\n}\n\nexport class T2000Error extends Error {\n readonly code: T2000ErrorCode;\n readonly data?: T2000ErrorData;\n readonly retryable: boolean;\n\n constructor(code: T2000ErrorCode, message: string, data?: T2000ErrorData, retryable = false) {\n super(message);\n this.name = 'T2000Error';\n this.code = code;\n this.data = data;\n this.retryable = retryable;\n }\n\n toJSON() {\n return {\n error: this.code,\n message: this.message,\n ...(this.data && { data: this.data }),\n retryable: this.retryable,\n };\n }\n}\n\nexport function mapWalletError(error: unknown): T2000Error {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes('rejected') || msg.includes('cancelled')) {\n return new T2000Error('TRANSACTION_FAILED', 'Transaction cancelled');\n }\n if (msg.includes('Insufficient') || msg.includes('insufficient')) {\n return new T2000Error('INSUFFICIENT_BALANCE', 'Insufficient balance');\n }\n\n return new T2000Error('UNKNOWN', msg, undefined, true);\n}\n\nexport function mapMoveAbortCode(code: number): string {\n const abortMessages: Record<number, string> = {\n 1: 'Protocol is temporarily paused',\n 2: 'Amount must be greater than zero',\n 3: 'Invalid operation type',\n 4: 'Fee rate exceeds maximum',\n 5: 'Insufficient treasury balance',\n 6: 'Not authorized',\n 7: 'Package version mismatch — upgrade required',\n 8: 'Timelock is active — wait for expiry',\n 9: 'No pending change to execute',\n 10: 'Already at current version',\n };\n return abortMessages[code] ?? `Move abort code: ${code}`;\n}\n","import { MIST_PER_SUI, BPS_DENOMINATOR, USDC_DECIMALS, SUI_DECIMALS } from '../constants.js';\n\nexport function mistToSui(mist: bigint): number {\n return Number(mist) / Number(MIST_PER_SUI);\n}\n\nexport function suiToMist(sui: number): bigint {\n return BigInt(Math.round(sui * Number(MIST_PER_SUI)));\n}\n\nexport function usdcToRaw(amount: number): bigint {\n return BigInt(Math.round(amount * 10 ** USDC_DECIMALS));\n}\n\nexport function rawToUsdc(raw: bigint): number {\n return Number(raw) / 10 ** USDC_DECIMALS;\n}\n\nexport function rawToDisplay(raw: bigint, decimals: number): number {\n return Number(raw) / 10 ** decimals;\n}\n\nexport function displayToRaw(amount: number, decimals: number): bigint {\n return BigInt(Math.round(amount * 10 ** decimals));\n}\n\nexport function bpsToPercent(bps: bigint): number {\n return Number(bps) / Number(BPS_DENOMINATOR) * 100;\n}\n\nexport function formatUsd(amount: number): string {\n return `$${amount.toFixed(2)}`;\n}\n\nexport function formatSui(amount: number): string {\n if (amount < 0.001) return `${amount.toFixed(6)} SUI`;\n return `${amount.toFixed(3)} SUI`;\n}\n\nexport function formatLargeNumber(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return n.toFixed(2);\n}\n","import { Transaction, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport type { SuiClient } from '@mysten/sui/client';\nimport {\n SAVE_FEE_BPS,\n SWAP_FEE_BPS,\n BORROW_FEE_BPS,\n BPS_DENOMINATOR,\n SUPPORTED_ASSETS,\n T2000_PACKAGE_ID,\n T2000_TREASURY_ID,\n T2000_CONFIG_ID,\n API_BASE_URL,\n} from '../constants.js';\nimport { usdcToRaw } from '../utils/format.js';\n\nexport type FeeOperation = 'save' | 'swap' | 'borrow';\n\nexport interface ProtocolFeeInfo {\n amount: number;\n asset: string;\n rate: number;\n rawAmount: bigint;\n}\n\nconst FEE_RATES: Record<FeeOperation, bigint> = {\n save: SAVE_FEE_BPS,\n swap: SWAP_FEE_BPS,\n borrow: BORROW_FEE_BPS,\n};\n\nconst OP_CODES: Record<FeeOperation, number> = {\n save: 0,\n swap: 1,\n borrow: 2,\n};\n\nexport function calculateFee(operation: FeeOperation, amount: number): ProtocolFeeInfo {\n const bps = FEE_RATES[operation];\n const feeAmount = amount * Number(bps) / Number(BPS_DENOMINATOR);\n const rawAmount = usdcToRaw(feeAmount);\n\n return {\n amount: feeAmount,\n asset: 'USDC',\n rate: Number(bps) / Number(BPS_DENOMINATOR),\n rawAmount,\n };\n}\n\n/**\n * Add on-chain fee collection to an existing PTB via t2000::treasury::collect_fee().\n * The Move function splits the fee from the payment coin and stores it in the\n * Treasury's internal Balance<T>. Atomic — reverts with the operation if it fails.\n */\nexport function addCollectFeeToTx(\n tx: Transaction,\n paymentCoin: TransactionObjectArgument,\n operation: FeeOperation,\n): void {\n const bps = FEE_RATES[operation];\n if (bps <= 0n) return;\n\n tx.moveCall({\n target: `${T2000_PACKAGE_ID}::treasury::collect_fee`,\n typeArguments: [SUPPORTED_ASSETS.USDC.type],\n arguments: [\n tx.object(T2000_TREASURY_ID),\n tx.object(T2000_CONFIG_ID),\n paymentCoin,\n tx.pure.u8(OP_CODES[operation]),\n ],\n });\n}\n\nexport async function reportFee(\n agentAddress: string,\n operation: string,\n feeAmount: number,\n feeRate: number,\n txDigest: string,\n): Promise<void> {\n try {\n await fetch(`${API_BASE_URL}/api/fees`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n agentAddress,\n operation,\n feeAmount: feeAmount.toString(),\n feeRate: feeRate.toString(),\n txDigest,\n }),\n });\n } catch {\n // Non-critical — best-effort reporting\n }\n}\n","import {\n getPool,\n getLendingState,\n getHealthFactor as naviGetHealthFactor,\n getCoins,\n mergeCoinsPTB,\n depositCoinPTB,\n withdrawCoinPTB,\n borrowCoinPTB,\n repayCoinPTB,\n getPriceFeeds,\n filterPriceFeeds,\n updateOraclePricesPTB,\n} from '@naviprotocol/lending';\nimport type { SuiClient } from '@mysten/sui/client';\nimport type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction, type TransactionObjectArgument } from '@mysten/sui/transactions';\nimport { SUPPORTED_ASSETS } from '../constants.js';\nimport { T2000Error } from '../errors.js';\nimport { usdcToRaw } from '../utils/format.js';\nimport { addCollectFeeToTx } from './protocolFee.js';\nimport type {\n SaveResult,\n WithdrawResult,\n BorrowResult,\n RepayResult,\n GasMethod,\n RatesResult,\n PositionsResult,\n PositionEntry,\n HealthFactorResult,\n MaxWithdrawResult,\n MaxBorrowResult,\n} from '../types.js';\n\nconst ENV = { env: 'prod' as const };\nconst USDC_TYPE = SUPPORTED_ASSETS.USDC.type;\nconst RATE_DECIMALS = 27;\nconst LTV_DECIMALS = 27;\nconst MIN_HEALTH_FACTOR = 1.5;\nconst WITHDRAW_DUST_BUFFER = 0.001;\n\n// NAVI normalizes all internal balances (supplyBalance, borrowBalance) to 9 decimal\n// places regardless of the token's native decimals. USDC is 6 on-chain, but NAVI\n// reports it with 3 extra decimals of precision. Verified empirically: depositing\n// 2_000_000 raw USDC (6-dec = $2) results in supplyBalance ≈ 2_000_000_000 (9-dec).\n// PTB functions (deposit/withdraw/borrow/repay) still use native 6-dec amounts.\nconst NAVI_BALANCE_DECIMALS = 9;\n\nfunction clientOpt(client: SuiClient, fresh = false) {\n return { client, ...ENV, ...(fresh ? { disableCache: true } : {}) };\n}\n\nfunction extractGasCost(effects: { gasUsed?: { computationCost: string; storageCost: string; storageRebate: string } } | undefined | null): number {\n if (!effects?.gasUsed) return 0;\n return Math.abs(\n (Number(effects.gasUsed.computationCost) +\n Number(effects.gasUsed.storageCost) -\n Number(effects.gasUsed.storageRebate)) /\n 1e9\n );\n}\n\nfunction rateToApy(rawRate: string): number {\n if (!rawRate || rawRate === '0') return 0;\n return Number(BigInt(rawRate)) / 10 ** RATE_DECIMALS * 100;\n}\n\nfunction parseLtv(rawLtv: string): number {\n if (!rawLtv || rawLtv === '0') return 0.75;\n return Number(BigInt(rawLtv)) / 10 ** LTV_DECIMALS;\n}\n\nfunction parseLiqThreshold(val: string | number): number {\n if (typeof val === 'number') return val;\n // NAVI returns thresholds as 27-decimal BigInt strings (e.g. \"850000000000000000000000000\"\n // for 0.85). If parseFloat yields > 1, it's a raw BigInt string needing conversion.\n const n = Number(val);\n if (n > 1) return Number(BigInt(val)) / 10 ** LTV_DECIMALS;\n return n;\n}\n\nfunction findUsdcPosition<T extends { pool: { token: { symbol: string }; coinType: string } }>(\n state: T[],\n): T | undefined {\n return state.find(\n (p) => p.pool.token.symbol === 'USDC' || p.pool.coinType.toLowerCase().includes('usdc'),\n );\n}\n\nasync function updateOracle(tx: Transaction, client: SuiClient, address: string): Promise<void> {\n try {\n const [feeds, state] = await Promise.all([\n getPriceFeeds(ENV),\n getLendingState(address, clientOpt(client)),\n ]);\n const relevant = filterPriceFeeds(feeds, { lendingState: state });\n if (relevant.length > 0) {\n await updateOraclePricesPTB(tx, relevant, { ...ENV, updatePythPriceFeeds: true });\n }\n } catch {\n // Oracle update failure is non-fatal — transaction may still succeed\n }\n}\n\nexport async function buildSaveTx(\n client: SuiClient,\n address: string,\n amount: number,\n options: { collectFee?: boolean } = {},\n): Promise<Transaction> {\n const rawAmount = Number(usdcToRaw(amount));\n\n const coins = await getCoins(address, { coinType: USDC_TYPE, client });\n if (!coins || coins.length === 0) {\n throw new T2000Error('INSUFFICIENT_BALANCE', 'No USDC coins found');\n }\n\n const tx = new Transaction();\n tx.setSender(address);\n\n const coinObj = mergeCoinsPTB(tx, coins, { balance: rawAmount });\n\n if (options.collectFee) {\n addCollectFeeToTx(tx, coinObj as TransactionObjectArgument, 'save');\n }\n\n await depositCoinPTB(tx, USDC_TYPE, coinObj, ENV);\n\n return tx;\n}\n\nexport async function save(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<SaveResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const tx = await buildSaveTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n const rates = await getRates(client);\n\n return {\n success: true,\n tx: result.digest,\n amount,\n apy: rates.USDC.saveApy,\n fee: 0,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n savingsBalance: amount,\n };\n}\n\nexport async function buildWithdrawTx(\n client: SuiClient,\n address: string,\n amount: number,\n): Promise<{ tx: Transaction; effectiveAmount: number }> {\n const state = await getLendingState(address, clientOpt(client, true));\n const usdcPos = findUsdcPosition(state);\n const deposited = usdcPos ? Number(usdcPos.supplyBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n\n const effectiveAmount = Math.min(amount, Math.max(0, deposited - WITHDRAW_DUST_BUFFER));\n if (effectiveAmount <= 0) throw new T2000Error('NO_COLLATERAL', 'Nothing to withdraw');\n\n const rawAmount = Number(usdcToRaw(effectiveAmount));\n\n const tx = new Transaction();\n tx.setSender(address);\n\n await updateOracle(tx, client, address);\n\n const withdrawnCoin = await withdrawCoinPTB(tx, USDC_TYPE, rawAmount, ENV);\n tx.transferObjects([withdrawnCoin], address);\n\n return { tx, effectiveAmount };\n}\n\nexport async function withdraw(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<WithdrawResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const { tx, effectiveAmount } = await buildWithdrawTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n return {\n success: true,\n tx: result.digest,\n amount: effectiveAmount,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n };\n}\n\nexport async function buildBorrowTx(\n client: SuiClient,\n address: string,\n amount: number,\n options: { collectFee?: boolean } = {},\n): Promise<Transaction> {\n const rawAmount = Number(usdcToRaw(amount));\n\n const tx = new Transaction();\n tx.setSender(address);\n\n await updateOracle(tx, client, address);\n\n const borrowedCoin = await borrowCoinPTB(tx, USDC_TYPE, rawAmount, ENV);\n\n if (options.collectFee) {\n addCollectFeeToTx(tx, borrowedCoin, 'borrow');\n }\n\n tx.transferObjects([borrowedCoin], address);\n\n return tx;\n}\n\nexport async function borrow(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<BorrowResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const tx = await buildBorrowTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n const hf = await naviGetHealthFactor(address, clientOpt(client, true));\n\n return {\n success: true,\n tx: result.digest,\n amount,\n fee: 0,\n healthFactor: hf,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n };\n}\n\nexport async function buildRepayTx(\n client: SuiClient,\n address: string,\n amount: number,\n): Promise<Transaction> {\n const rawAmount = Number(usdcToRaw(amount));\n\n const coins = await getCoins(address, { coinType: USDC_TYPE, client });\n if (!coins || coins.length === 0) {\n throw new T2000Error('INSUFFICIENT_BALANCE', 'No USDC coins to repay with');\n }\n\n const tx = new Transaction();\n tx.setSender(address);\n\n const coinObj = mergeCoinsPTB(tx, coins, { balance: rawAmount });\n await repayCoinPTB(tx, USDC_TYPE, coinObj, { ...ENV, amount: rawAmount });\n\n return tx;\n}\n\nexport async function repay(\n client: SuiClient,\n keypair: Ed25519Keypair,\n amount: number,\n): Promise<RepayResult> {\n const address = keypair.getPublicKey().toSuiAddress();\n const tx = await buildRepayTx(client, address, amount);\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true },\n });\n await client.waitForTransaction({ digest: result.digest });\n\n const state = await getLendingState(address, clientOpt(client, true));\n const usdcPos = findUsdcPosition(state);\n const remainingDebt = usdcPos ? Number(usdcPos.borrowBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n\n return {\n success: true,\n tx: result.digest,\n amount,\n remainingDebt,\n gasCost: extractGasCost(result.effects),\n gasMethod: 'self-funded' as GasMethod,\n };\n}\n\nexport async function getHealthFactor(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<HealthFactorResult> {\n const address = typeof addressOrKeypair === 'string'\n ? addressOrKeypair\n : addressOrKeypair.getPublicKey().toSuiAddress();\n\n const [healthFactor, state, pool] = await Promise.all([\n naviGetHealthFactor(address, clientOpt(client, true)),\n getLendingState(address, clientOpt(client, true)),\n getPool(USDC_TYPE, ENV),\n ]);\n\n const usdcPos = findUsdcPosition(state);\n\n const supplied = usdcPos ? Number(usdcPos.supplyBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n const borrowed = usdcPos ? Number(usdcPos.borrowBalance) / 10 ** NAVI_BALANCE_DECIMALS : 0;\n\n const ltv = parseLtv(pool.ltv);\n const liqThreshold = parseLiqThreshold(pool.liquidationFactor.threshold);\n const maxBorrowVal = Math.max(0, supplied * ltv - borrowed);\n\n return {\n healthFactor: borrowed > 0 ? healthFactor : Infinity,\n supplied,\n borrowed,\n maxBorrow: maxBorrowVal,\n liquidationThreshold: liqThreshold,\n };\n}\n\nexport async function getRates(client: SuiClient): Promise<RatesResult> {\n try {\n const pool = await getPool(USDC_TYPE, ENV);\n\n let saveApy = rateToApy(pool.currentSupplyRate);\n let borrowApy = rateToApy(pool.currentBorrowRate);\n\n if (saveApy <= 0 || saveApy > 100) saveApy = 4.0;\n if (borrowApy <= 0 || borrowApy > 100) borrowApy = 6.0;\n\n return { USDC: { saveApy, borrowApy } };\n } catch {\n return { USDC: { saveApy: 4.0, borrowApy: 6.0 } };\n }\n}\n\nexport async function getPositions(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<PositionsResult> {\n const address = typeof addressOrKeypair === 'string'\n ? addressOrKeypair\n : addressOrKeypair.getPublicKey().toSuiAddress();\n\n const state = await getLendingState(address, clientOpt(client, true));\n const positions: PositionEntry[] = [];\n\n for (const pos of state) {\n const symbol = pos.pool.token?.symbol ?? 'UNKNOWN';\n const supplyBal = Number(pos.supplyBalance) / 10 ** NAVI_BALANCE_DECIMALS;\n const borrowBal = Number(pos.borrowBalance) / 10 ** NAVI_BALANCE_DECIMALS;\n\n if (supplyBal > 0.0001) {\n positions.push({\n protocol: 'navi',\n asset: symbol,\n type: 'save',\n amount: supplyBal,\n apy: rateToApy(pos.pool.currentSupplyRate),\n });\n }\n\n if (borrowBal > 0.0001) {\n positions.push({\n protocol: 'navi',\n asset: symbol,\n type: 'borrow',\n amount: borrowBal,\n apy: rateToApy(pos.pool.currentBorrowRate),\n });\n }\n }\n\n return { positions };\n}\n\nexport async function maxWithdrawAmount(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<MaxWithdrawResult> {\n const hf = await getHealthFactor(client, addressOrKeypair);\n const ltv = hf.liquidationThreshold > 0 ? hf.liquidationThreshold : 0.75;\n\n let maxAmount: number;\n if (hf.borrowed === 0) {\n maxAmount = hf.supplied;\n } else {\n maxAmount = Math.max(0, hf.supplied - (hf.borrowed * MIN_HEALTH_FACTOR / ltv));\n }\n\n const remainingSupply = hf.supplied - maxAmount;\n const hfAfter = hf.borrowed > 0 ? remainingSupply / hf.borrowed : Infinity;\n\n return {\n maxAmount,\n healthFactorAfter: hfAfter,\n currentHF: hf.healthFactor,\n };\n}\n\nexport async function maxBorrowAmount(\n client: SuiClient,\n addressOrKeypair: string | Ed25519Keypair,\n): Promise<MaxBorrowResult> {\n const hf = await getHealthFactor(client, addressOrKeypair);\n const ltv = hf.liquidationThreshold > 0 ? hf.liquidationThreshold : 0.75;\n\n const maxAmount = Math.max(0, hf.supplied * ltv / MIN_HEALTH_FACTOR - hf.borrowed);\n\n return {\n maxAmount,\n healthFactorAfter: MIN_HEALTH_FACTOR,\n currentHF: hf.healthFactor,\n };\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport type {\n LendingAdapter,\n LendingRates,\n AdapterPositions,\n HealthInfo,\n AdapterTxResult,\n AdapterCapability,\n} from './types.js';\nimport * as naviProtocol from '../protocols/navi.js';\n\nexport class NaviAdapter implements LendingAdapter {\n readonly id = 'navi';\n readonly name = 'NAVI Protocol';\n readonly version = '1.0.0';\n readonly capabilities: readonly AdapterCapability[] = ['save', 'withdraw', 'borrow', 'repay'];\n readonly supportedAssets: readonly string[] = ['USDC'];\n readonly supportsSameAssetBorrow = true;\n\n private client!: SuiClient;\n\n async init(client: SuiClient): Promise<void> {\n this.client = client;\n }\n\n initSync(client: SuiClient): void {\n this.client = client;\n }\n\n async getRates(asset: string): Promise<LendingRates> {\n const rates = await naviProtocol.getRates(this.client);\n const key = asset.toUpperCase() as keyof typeof rates;\n const r = rates[key];\n if (!r) throw new Error(`NAVI does not support ${asset}`);\n return { asset, saveApy: r.saveApy, borrowApy: r.borrowApy };\n }\n\n async getPositions(address: string): Promise<AdapterPositions> {\n const result = await naviProtocol.getPositions(this.client, address);\n return {\n supplies: result.positions\n .filter(p => p.type === 'save')\n .map(p => ({ asset: p.asset, amount: p.amount, apy: p.apy })),\n borrows: result.positions\n .filter(p => p.type === 'borrow')\n .map(p => ({ asset: p.asset, amount: p.amount, apy: p.apy })),\n };\n }\n\n async getHealth(address: string): Promise<HealthInfo> {\n return naviProtocol.getHealthFactor(this.client, address);\n }\n\n async buildSaveTx(\n address: string,\n amount: number,\n _asset: string,\n options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n const tx = await naviProtocol.buildSaveTx(this.client, address, amount, options);\n return { tx };\n }\n\n async buildWithdrawTx(\n address: string,\n amount: number,\n _asset: string,\n ): Promise<AdapterTxResult & { effectiveAmount: number }> {\n const result = await naviProtocol.buildWithdrawTx(this.client, address, amount);\n return { tx: result.tx, effectiveAmount: result.effectiveAmount };\n }\n\n async buildBorrowTx(\n address: string,\n amount: number,\n _asset: string,\n options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n const tx = await naviProtocol.buildBorrowTx(this.client, address, amount, options);\n return { tx };\n }\n\n async buildRepayTx(\n address: string,\n amount: number,\n _asset: string,\n ): Promise<AdapterTxResult> {\n const tx = await naviProtocol.buildRepayTx(this.client, address, amount);\n return { tx };\n }\n\n async maxWithdraw(address: string, _asset: string) {\n return naviProtocol.maxWithdrawAmount(this.client, address);\n }\n\n async maxBorrow(address: string, _asset: string) {\n return naviProtocol.maxBorrowAmount(this.client, address);\n }\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport type { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';\nimport { SUPPORTED_ASSETS, CETUS_USDC_SUI_POOL } from '../constants.js';\nimport { T2000Error } from '../errors.js';\nimport type { GasMethod } from '../types.js';\n\nconst DEFAULT_SLIPPAGE_BPS = 300; // 3%\n\nexport interface SwapParams {\n client: SuiClient;\n keypair: Ed25519Keypair;\n fromAsset: 'USDC' | 'SUI';\n toAsset: 'USDC' | 'SUI';\n amount: number;\n maxSlippageBps?: number;\n}\n\nexport interface SwapTxResult {\n digest: string;\n fromAmount: number;\n fromAsset: string;\n toAmount: number;\n toAsset: string;\n priceImpact: number;\n gasCost: number;\n}\n\nfunction extractGasCost(\n effects: { gasUsed?: { computationCost: string; storageCost: string; storageRebate: string } } | undefined | null,\n): number {\n if (!effects?.gasUsed) return 0;\n return (\n Number(effects.gasUsed.computationCost) +\n Number(effects.gasUsed.storageCost) -\n Number(effects.gasUsed.storageRebate)\n ) / 1e9;\n}\n\nexport interface SwapBuildResult {\n tx: Transaction;\n estimatedOut: number;\n toDecimals: number;\n}\n\nfunction createAggregatorClient(client: SuiClient, signer?: string): AggregatorClient {\n return new AggregatorClient({\n client,\n signer,\n env: Env.Mainnet,\n });\n}\n\nexport async function buildSwapTx(params: {\n client: SuiClient;\n address: string;\n fromAsset: 'USDC' | 'SUI';\n toAsset: 'USDC' | 'SUI';\n amount: number;\n maxSlippageBps?: number;\n}): Promise<SwapBuildResult> {\n const { client, address, fromAsset, toAsset, amount, maxSlippageBps = DEFAULT_SLIPPAGE_BPS } = params;\n\n const fromInfo = SUPPORTED_ASSETS[fromAsset];\n const toInfo = SUPPORTED_ASSETS[toAsset];\n const rawAmount = BigInt(Math.floor(amount * 10 ** fromInfo.decimals));\n\n const aggClient = createAggregatorClient(client, address);\n\n const result = await aggClient.findRouters({\n from: fromInfo.type,\n target: toInfo.type,\n amount: rawAmount,\n byAmountIn: true,\n });\n\n if (!result || result.insufficientLiquidity) {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n `No swap route found for ${fromAsset} → ${toAsset}`,\n );\n }\n\n const tx = new Transaction();\n const slippage = maxSlippageBps / 10000;\n\n await aggClient.fastRouterSwap({\n router: result,\n txb: tx,\n slippage,\n });\n\n const estimatedOut = Number(result.amountOut.toString());\n\n return {\n tx,\n estimatedOut,\n toDecimals: toInfo.decimals,\n };\n}\n\nexport async function executeSwap(params: SwapParams): Promise<SwapTxResult> {\n const { client, keypair, fromAsset, toAsset, amount, maxSlippageBps } = params;\n const address = keypair.getPublicKey().toSuiAddress();\n const toInfo = SUPPORTED_ASSETS[toAsset];\n\n const { tx, estimatedOut, toDecimals } = await buildSwapTx({\n client,\n address,\n fromAsset,\n toAsset,\n amount,\n maxSlippageBps,\n });\n\n const result = await client.signAndExecuteTransaction({\n signer: keypair,\n transaction: tx,\n options: { showEffects: true, showBalanceChanges: true },\n });\n\n await client.waitForTransaction({ digest: result.digest });\n\n let actualReceived = 0;\n if (result.balanceChanges) {\n for (const change of result.balanceChanges) {\n if (\n change.coinType === toInfo.type &&\n change.owner &&\n typeof change.owner === 'object' &&\n 'AddressOwner' in change.owner &&\n change.owner.AddressOwner === address\n ) {\n const amt = Number(change.amount) / 10 ** toInfo.decimals;\n if (amt > 0) actualReceived += amt;\n }\n }\n }\n\n const expectedOutput = estimatedOut / 10 ** toDecimals;\n if (actualReceived === 0) actualReceived = expectedOutput;\n\n const priceImpact = expectedOutput > 0\n ? Math.abs(actualReceived - expectedOutput) / expectedOutput\n : 0;\n\n return {\n digest: result.digest,\n fromAmount: amount,\n fromAsset,\n toAmount: actualReceived,\n toAsset,\n priceImpact,\n gasCost: extractGasCost(result.effects as Parameters<typeof extractGasCost>[0]),\n };\n}\n\nexport async function getPoolPrice(client: SuiClient): Promise<number> {\n try {\n const pool = await client.getObject({\n id: CETUS_USDC_SUI_POOL,\n options: { showContent: true },\n });\n\n if (pool.data?.content?.dataType === 'moveObject') {\n const fields = pool.data.content.fields as Record<string, unknown>;\n const currentSqrtPrice = BigInt(String(fields.current_sqrt_price ?? '0'));\n\n if (currentSqrtPrice > 0n) {\n const Q64 = 2n ** 64n;\n const sqrtPriceFloat = Number(currentSqrtPrice) / Number(Q64);\n const rawPrice = sqrtPriceFloat * sqrtPriceFloat;\n const suiPriceUsd = 1e3 / rawPrice;\n if (suiPriceUsd > 0.01 && suiPriceUsd < 1000) return suiPriceUsd;\n }\n }\n } catch {\n // Fallback\n }\n\n return 3.5;\n}\n\nexport async function getSwapQuote(\n client: SuiClient,\n fromAsset: 'USDC' | 'SUI',\n toAsset: 'USDC' | 'SUI',\n amount: number,\n): Promise<{ expectedOutput: number; priceImpact: number; poolPrice: number }> {\n const fromInfo = SUPPORTED_ASSETS[fromAsset];\n const toInfo = SUPPORTED_ASSETS[toAsset];\n const rawAmount = BigInt(Math.floor(amount * 10 ** fromInfo.decimals));\n\n const poolPrice = await getPoolPrice(client);\n\n try {\n const aggClient = createAggregatorClient(client);\n\n const result = await aggClient.findRouters({\n from: fromInfo.type,\n target: toInfo.type,\n amount: rawAmount,\n byAmountIn: true,\n });\n\n if (!result || result.insufficientLiquidity) {\n return fallbackQuote(fromAsset, amount, poolPrice);\n }\n\n const expectedOutput = Number(result.amountOut.toString()) / 10 ** toInfo.decimals;\n const priceImpact = result.deviationRatio ?? 0;\n\n return { expectedOutput, priceImpact, poolPrice };\n } catch {\n return fallbackQuote(fromAsset, amount, poolPrice);\n }\n}\n\nfunction fallbackQuote(\n fromAsset: string,\n amount: number,\n poolPrice: number,\n): { expectedOutput: number; priceImpact: number; poolPrice: number } {\n const expectedOutput = fromAsset === 'USDC'\n ? amount / poolPrice\n : amount * poolPrice;\n return { expectedOutput, priceImpact: 0, poolPrice };\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport type {\n SwapAdapter,\n SwapQuote,\n AdapterTxResult,\n AdapterCapability,\n} from './types.js';\nimport * as cetusProtocol from '../protocols/cetus.js';\n\nexport class CetusAdapter implements SwapAdapter {\n readonly id = 'cetus';\n readonly name = 'Cetus';\n readonly version = '1.0.0';\n readonly capabilities: readonly AdapterCapability[] = ['swap'];\n\n private client!: SuiClient;\n\n async init(client: SuiClient): Promise<void> {\n this.client = client;\n }\n\n initSync(client: SuiClient): void {\n this.client = client;\n }\n\n async getQuote(from: string, to: string, amount: number): Promise<SwapQuote> {\n return cetusProtocol.getSwapQuote(\n this.client,\n from.toUpperCase() as 'USDC' | 'SUI',\n to.toUpperCase() as 'USDC' | 'SUI',\n amount,\n );\n }\n\n async buildSwapTx(\n address: string,\n from: string,\n to: string,\n amount: number,\n maxSlippageBps?: number,\n ): Promise<AdapterTxResult & { estimatedOut: number; toDecimals: number }> {\n const result = await cetusProtocol.buildSwapTx({\n client: this.client,\n address,\n fromAsset: from.toUpperCase() as 'USDC' | 'SUI',\n toAsset: to.toUpperCase() as 'USDC' | 'SUI',\n amount,\n maxSlippageBps,\n });\n return {\n tx: result.tx,\n estimatedOut: result.estimatedOut,\n toDecimals: result.toDecimals,\n };\n }\n\n getSupportedPairs(): Array<{ from: string; to: string }> {\n return [\n { from: 'USDC', to: 'SUI' },\n { from: 'SUI', to: 'USDC' },\n ];\n }\n\n async getPoolPrice(): Promise<number> {\n return cetusProtocol.getPoolPrice(this.client);\n }\n}\n","import type { SuiClient } from '@mysten/sui/client';\nimport { Transaction } from '@mysten/sui/transactions';\nimport { normalizeStructTag } from '@mysten/sui/utils';\nimport type {\n LendingAdapter,\n LendingRates,\n AdapterPositions,\n HealthInfo,\n AdapterTxResult,\n AdapterCapability,\n} from './types.js';\nimport { SUPPORTED_ASSETS } from '../constants.js';\nimport { usdcToRaw } from '../utils/format.js';\nimport { T2000Error } from '../errors.js';\nimport { addCollectFeeToTx } from '../protocols/protocolFee.js';\nimport type { TransactionObjectArgument } from '@mysten/sui/transactions';\n\nconst USDC_TYPE = SUPPORTED_ASSETS.USDC.type;\nconst USDC_DECIMALS = SUPPORTED_ASSETS.USDC.decimals;\nconst WAD = 1e18;\nconst MIN_HEALTH_FACTOR = 1.5;\n\ninterface SuilendSdk {\n SuilendClient: {\n initialize(id: string, type: string, client: SuiClient): Promise<SuilendClientInstance>;\n getObligationOwnerCaps(\n ownerId: string,\n typeArgs: string[],\n client: SuiClient,\n ): Promise<ObligationOwnerCap[]>;\n };\n LENDING_MARKET_ID: string;\n LENDING_MARKET_TYPE: string;\n}\n\ninterface SuilendClientInstance {\n lendingMarket: {\n id: string;\n $typeArgs: string[];\n reserves: SuilendReserve[];\n };\n createObligation(tx: Transaction): [TransactionObjectArgument];\n deposit(\n coin: TransactionObjectArgument,\n coinType: string,\n obligationOwnerCap: TransactionObjectArgument | string,\n tx: Transaction,\n ): void;\n withdrawAndSendToUser(\n ownerId: string,\n obligationOwnerCap: string,\n obligationId: string,\n coinType: string,\n value: string,\n tx: Transaction,\n ): Promise<void>;\n getObligation(obligationId: string): Promise<SuilendObligation>;\n findReserveArrayIndex(coinType: string): bigint;\n}\n\ninterface SuilendReserve {\n coinType: { name: string };\n mintDecimals: number;\n availableAmount: bigint;\n borrowedAmount: { value: bigint };\n ctokenSupply: bigint;\n unclaimedSpreadFees: { value: bigint };\n cumulativeBorrowRate: { value: bigint };\n price: { value: bigint };\n config: {\n element: {\n openLtvPct: number;\n closeLtvPct: number;\n spreadFeeBps: bigint | number;\n interestRateUtils: (bigint | number)[];\n interestRateAprs: (bigint | number)[];\n } | null;\n };\n}\n\ninterface ObligationOwnerCap {\n id: string;\n obligationId: string;\n}\n\ninterface SuilendObligation {\n id: string;\n deposits: Array<{\n coinType: { name: string };\n depositedCtokenAmount: bigint;\n reserveArrayIndex: bigint;\n }>;\n borrows: Array<{\n coinType: { name: string };\n borrowedAmount: { value: bigint };\n cumulativeBorrowRate: { value: bigint };\n reserveArrayIndex: bigint;\n }>;\n}\n\nfunction interpolateRate(\n utilBreakpoints: number[],\n aprBreakpoints: number[],\n utilizationPct: number,\n): number {\n if (utilBreakpoints.length === 0) return 0;\n if (utilizationPct <= utilBreakpoints[0]) return aprBreakpoints[0];\n if (utilizationPct >= utilBreakpoints[utilBreakpoints.length - 1]) {\n return aprBreakpoints[aprBreakpoints.length - 1];\n }\n\n for (let i = 1; i < utilBreakpoints.length; i++) {\n if (utilizationPct <= utilBreakpoints[i]) {\n const t =\n (utilizationPct - utilBreakpoints[i - 1]) /\n (utilBreakpoints[i] - utilBreakpoints[i - 1]);\n return aprBreakpoints[i - 1] + t * (aprBreakpoints[i] - aprBreakpoints[i - 1]);\n }\n }\n return aprBreakpoints[aprBreakpoints.length - 1];\n}\n\nfunction computeRatesFromReserve(reserve: SuilendReserve): {\n borrowAprPct: number;\n depositAprPct: number;\n utilizationPct: number;\n} {\n const decimals = reserve.mintDecimals;\n const available = Number(reserve.availableAmount) / 10 ** decimals;\n const borrowed =\n Number(reserve.borrowedAmount.value) / WAD / 10 ** decimals;\n const totalDeposited = available + borrowed;\n const utilizationPct =\n totalDeposited > 0 ? (borrowed / totalDeposited) * 100 : 0;\n\n const config = reserve.config.element;\n if (!config) return { borrowAprPct: 0, depositAprPct: 0, utilizationPct: 0 };\n\n const utils = config.interestRateUtils.map(Number);\n const aprs = config.interestRateAprs.map((a) => Number(a) / 100);\n\n const borrowAprPct = interpolateRate(utils, aprs, utilizationPct);\n const spreadFeeBps = Number(config.spreadFeeBps);\n const depositAprPct =\n (utilizationPct / 100) *\n (borrowAprPct / 100) *\n (1 - spreadFeeBps / 10000) *\n 100;\n\n return { borrowAprPct, depositAprPct, utilizationPct };\n}\n\nfunction cTokenRatio(reserve: SuilendReserve): number {\n if (reserve.ctokenSupply === 0n) return 1;\n\n const available = Number(reserve.availableAmount);\n const borrowed = Number(reserve.borrowedAmount.value) / WAD;\n const spreadFees = Number(reserve.unclaimedSpreadFees.value) / WAD;\n const totalSupply = available + borrowed - spreadFees;\n\n return totalSupply / Number(reserve.ctokenSupply);\n}\n\n/**\n * Suilend adapter — save + withdraw for USDC.\n * Borrow/repay deferred to Phase 10 (requires multi-stable support).\n *\n * Uses the @suilend/sdk package (optional peer dependency). Users must\n * install it separately: `npm install @suilend/sdk@^1`\n *\n * @see https://docs.suilend.fi/ecosystem/suilend-sdk-guide\n */\nexport class SuilendAdapter implements LendingAdapter {\n readonly id = 'suilend';\n readonly name = 'Suilend';\n readonly version = '1.0.0';\n readonly capabilities: readonly AdapterCapability[] = ['save', 'withdraw'];\n readonly supportedAssets: readonly string[] = ['USDC'];\n readonly supportsSameAssetBorrow = false;\n\n private client!: SuiClient;\n private suilend!: SuilendClientInstance;\n private lendingMarketType!: string;\n private initialized = false;\n private initPromise: Promise<void> | null = null;\n\n async init(client: SuiClient): Promise<void> {\n this.client = client;\n await this.lazyInit();\n }\n\n initSync(client: SuiClient): void {\n this.client = client;\n }\n\n private async lazyInit(): Promise<void> {\n if (this.initialized) return;\n if (this.initPromise) return this.initPromise;\n\n this.initPromise = (async () => {\n let sdk: SuilendSdk;\n try {\n sdk = (await import('@suilend/sdk')) as unknown as SuilendSdk;\n } catch {\n throw new T2000Error(\n 'PROTOCOL_UNAVAILABLE',\n 'Suilend SDK not installed. Run: npm install @suilend/sdk@^1',\n );\n }\n\n this.lendingMarketType = sdk.LENDING_MARKET_TYPE;\n\n try {\n this.suilend = await sdk.SuilendClient.initialize(\n sdk.LENDING_MARKET_ID,\n sdk.LENDING_MARKET_TYPE,\n this.client,\n );\n } catch (err) {\n this.initPromise = null;\n throw new T2000Error(\n 'PROTOCOL_UNAVAILABLE',\n `Failed to initialize Suilend: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n\n this.initialized = true;\n })();\n\n return this.initPromise;\n }\n\n private async ensureInit(): Promise<void> {\n if (!this.initialized) {\n await this.lazyInit();\n }\n }\n\n private findReserve(asset: string): SuilendReserve | undefined {\n const upper = asset.toUpperCase();\n let coinType: string;\n if (upper === 'USDC') coinType = USDC_TYPE;\n else if (upper === 'SUI') coinType = '0x2::sui::SUI';\n else if (asset.includes('::')) coinType = asset;\n else return undefined;\n\n try {\n const normalized = normalizeStructTag(coinType);\n return this.suilend.lendingMarket.reserves.find(\n (r) => normalizeStructTag(r.coinType.name) === normalized,\n );\n } catch {\n return undefined;\n }\n }\n\n private async getObligationCaps(address: string): Promise<ObligationOwnerCap[]> {\n const SuilendClientStatic = ((await import('@suilend/sdk')) as unknown as SuilendSdk).SuilendClient;\n return SuilendClientStatic.getObligationOwnerCaps(\n address,\n [this.lendingMarketType],\n this.client,\n );\n }\n\n private resolveSymbol(coinType: string): string {\n const normalized = normalizeStructTag(coinType);\n if (normalized === normalizeStructTag(USDC_TYPE)) return 'USDC';\n if (normalized === normalizeStructTag('0x2::sui::SUI')) return 'SUI';\n const parts = coinType.split('::');\n return parts[parts.length - 1] || 'UNKNOWN';\n }\n\n async getRates(asset: string): Promise<LendingRates> {\n await this.ensureInit();\n\n const reserve = this.findReserve(asset);\n if (!reserve) {\n throw new T2000Error('ASSET_NOT_SUPPORTED', `Suilend does not support ${asset}`);\n }\n\n const { borrowAprPct, depositAprPct } = computeRatesFromReserve(reserve);\n\n return {\n asset,\n saveApy: depositAprPct,\n borrowApy: borrowAprPct,\n };\n }\n\n async getPositions(address: string): Promise<AdapterPositions> {\n await this.ensureInit();\n\n const supplies: Array<{ asset: string; amount: number; apy: number }> = [];\n const borrows: Array<{ asset: string; amount: number; apy: number }> = [];\n\n const caps = await this.getObligationCaps(address);\n if (caps.length === 0) return { supplies, borrows };\n\n const obligation = await this.suilend.getObligation(caps[0].obligationId);\n\n for (const deposit of obligation.deposits) {\n const coinType = normalizeStructTag(deposit.coinType.name);\n const reserve = this.suilend.lendingMarket.reserves.find(\n (r) => normalizeStructTag(r.coinType.name) === coinType,\n );\n if (!reserve) continue;\n\n const ctokenAmount = Number(deposit.depositedCtokenAmount.toString());\n const ratio = cTokenRatio(reserve);\n const amount = (ctokenAmount * ratio) / 10 ** reserve.mintDecimals;\n const { depositAprPct } = computeRatesFromReserve(reserve);\n\n supplies.push({ asset: this.resolveSymbol(coinType), amount, apy: depositAprPct });\n }\n\n for (const borrow of obligation.borrows) {\n const coinType = normalizeStructTag(borrow.coinType.name);\n const reserve = this.suilend.lendingMarket.reserves.find(\n (r) => normalizeStructTag(r.coinType.name) === coinType,\n );\n if (!reserve) continue;\n\n const rawBorrowed = Number(borrow.borrowedAmount.value.toString()) / WAD;\n const amount = rawBorrowed / 10 ** reserve.mintDecimals;\n\n const reserveRate = Number(reserve.cumulativeBorrowRate.value.toString()) / WAD;\n const posRate = Number(borrow.cumulativeBorrowRate.value.toString()) / WAD;\n const compounded = posRate > 0 ? amount * (reserveRate / posRate) : amount;\n\n const { borrowAprPct } = computeRatesFromReserve(reserve);\n borrows.push({ asset: this.resolveSymbol(coinType), amount: compounded, apy: borrowAprPct });\n }\n\n return { supplies, borrows };\n }\n\n async getHealth(address: string): Promise<HealthInfo> {\n await this.ensureInit();\n\n const caps = await this.getObligationCaps(address);\n if (caps.length === 0) {\n return { healthFactor: Infinity, supplied: 0, borrowed: 0, maxBorrow: 0, liquidationThreshold: 0 };\n }\n\n const positions = await this.getPositions(address);\n const supplied = positions.supplies.reduce((s, p) => s + p.amount, 0);\n const borrowed = positions.borrows.reduce((s, p) => s + p.amount, 0);\n\n const reserve = this.findReserve('USDC');\n const closeLtv = reserve?.config?.element?.closeLtvPct ?? 75;\n const openLtv = reserve?.config?.element?.openLtvPct ?? 70;\n const liqThreshold = closeLtv / 100;\n\n const healthFactor = borrowed > 0\n ? (supplied * liqThreshold) / borrowed\n : Infinity;\n\n const maxBorrow = Math.max(0, supplied * (openLtv / 100) - borrowed);\n\n return { healthFactor, supplied, borrowed, maxBorrow, liquidationThreshold: liqThreshold };\n }\n\n async buildSaveTx(\n address: string,\n amount: number,\n _asset: string,\n options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n await this.ensureInit();\n\n const rawAmount = usdcToRaw(amount).toString();\n const tx = new Transaction();\n tx.setSender(address);\n\n const caps = await this.getObligationCaps(address);\n let capRef: TransactionObjectArgument | string;\n\n if (caps.length === 0) {\n const [newCap] = this.suilend.createObligation(tx);\n capRef = newCap;\n } else {\n capRef = caps[0].id;\n }\n\n const allCoins = await this.fetchAllCoins(address, USDC_TYPE);\n if (allCoins.length === 0) {\n throw new T2000Error('INSUFFICIENT_BALANCE', 'No USDC coins found');\n }\n\n const primaryCoinId = allCoins[0].coinObjectId;\n if (allCoins.length > 1) {\n tx.mergeCoins(\n tx.object(primaryCoinId),\n allCoins.slice(1).map((c) => tx.object(c.coinObjectId)),\n );\n }\n\n const [depositCoin] = tx.splitCoins(tx.object(primaryCoinId), [rawAmount]);\n\n if (options?.collectFee) {\n addCollectFeeToTx(tx, depositCoin as TransactionObjectArgument, 'save');\n }\n\n this.suilend.deposit(depositCoin as TransactionObjectArgument, USDC_TYPE, capRef, tx);\n\n return { tx };\n }\n\n async buildWithdrawTx(\n address: string,\n amount: number,\n _asset: string,\n ): Promise<AdapterTxResult & { effectiveAmount: number }> {\n await this.ensureInit();\n\n const caps = await this.getObligationCaps(address);\n if (caps.length === 0) {\n throw new T2000Error('NO_COLLATERAL', 'No Suilend position found');\n }\n\n const positions = await this.getPositions(address);\n const usdcSupply = positions.supplies.find((s) => s.asset === 'USDC');\n const deposited = usdcSupply?.amount ?? 0;\n\n const effectiveAmount = Math.min(amount, deposited);\n if (effectiveAmount <= 0) {\n throw new T2000Error('NO_COLLATERAL', 'Nothing to withdraw from Suilend');\n }\n\n const rawAmount = usdcToRaw(effectiveAmount).toString();\n const tx = new Transaction();\n tx.setSender(address);\n\n await this.suilend.withdrawAndSendToUser(\n address,\n caps[0].id,\n caps[0].obligationId,\n USDC_TYPE,\n rawAmount,\n tx,\n );\n\n return { tx, effectiveAmount };\n }\n\n async buildBorrowTx(\n _address: string,\n _amount: number,\n _asset: string,\n _options?: { collectFee?: boolean },\n ): Promise<AdapterTxResult> {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n 'SuilendAdapter.buildBorrowTx() not available — Suilend requires different collateral/borrow assets. Deferred to Phase 10.',\n );\n }\n\n async buildRepayTx(\n _address: string,\n _amount: number,\n _asset: string,\n ): Promise<AdapterTxResult> {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n 'SuilendAdapter.buildRepayTx() not available — deferred to Phase 10.',\n );\n }\n\n async maxWithdraw(\n address: string,\n _asset: string,\n ): Promise<{ maxAmount: number; healthFactorAfter: number; currentHF: number }> {\n await this.ensureInit();\n\n const health = await this.getHealth(address);\n\n let maxAmount: number;\n if (health.borrowed === 0) {\n maxAmount = health.supplied;\n } else {\n maxAmount = Math.max(\n 0,\n health.supplied - (health.borrowed * MIN_HEALTH_FACTOR) / health.liquidationThreshold,\n );\n }\n\n const remainingSupply = health.supplied - maxAmount;\n const hfAfter = health.borrowed > 0\n ? (remainingSupply * health.liquidationThreshold) / health.borrowed\n : Infinity;\n\n return {\n maxAmount,\n healthFactorAfter: hfAfter,\n currentHF: health.healthFactor,\n };\n }\n\n async maxBorrow(\n _address: string,\n _asset: string,\n ): Promise<{ maxAmount: number; healthFactorAfter: number; currentHF: number }> {\n throw new T2000Error(\n 'ASSET_NOT_SUPPORTED',\n 'SuilendAdapter.maxBorrow() not available — deferred to Phase 10.',\n );\n }\n\n private async fetchAllCoins(\n owner: string,\n coinType: string,\n ): Promise<Array<{ coinObjectId: string; balance: string }>> {\n const all: Array<{ coinObjectId: string; balance: string }> = [];\n let cursor: string | null | undefined = null;\n let hasNext = true;\n\n while (hasNext) {\n const page = await this.client.getCoins({ owner, coinType, cursor: cursor ?? undefined });\n all.push(...page.data.map((c) => ({ coinObjectId: c.coinObjectId, balance: c.balance })));\n cursor = page.nextCursor;\n hasNext = page.hasNextPage;\n }\n\n return all;\n }\n}\n"]}
@@ -359,7 +359,10 @@ declare class SuilendAdapter implements LendingAdapter {
359
359
  private suilend;
360
360
  private lendingMarketType;
361
361
  private initialized;
362
+ private initPromise;
362
363
  init(client: SuiClient): Promise<void>;
364
+ initSync(client: SuiClient): void;
365
+ private lazyInit;
363
366
  private ensureInit;
364
367
  private findReserve;
365
368
  private getObligationCaps;
@@ -359,7 +359,10 @@ declare class SuilendAdapter implements LendingAdapter {
359
359
  private suilend;
360
360
  private lendingMarketType;
361
361
  private initialized;
362
+ private initPromise;
362
363
  init(client: SuiClient): Promise<void>;
364
+ initSync(client: SuiClient): void;
365
+ private lazyInit;
363
366
  private ensureInit;
364
367
  private findReserve;
365
368
  private getObligationCaps;