@t2000/sdk 0.4.0 → 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.
@@ -609,38 +609,48 @@ var SuilendAdapter = class {
609
609
  suilend;
610
610
  lendingMarketType;
611
611
  initialized = false;
612
+ initPromise = null;
612
613
  async init(client) {
613
- let sdk;
614
- try {
615
- sdk = await import('@suilend/sdk');
616
- } catch {
617
- throw new T2000Error(
618
- "PROTOCOL_UNAVAILABLE",
619
- "Suilend SDK not installed. Run: npm install @suilend/sdk@^1"
620
- );
621
- }
622
614
  this.client = client;
623
- this.lendingMarketType = sdk.LENDING_MARKET_TYPE;
624
- try {
625
- this.suilend = await sdk.SuilendClient.initialize(
626
- sdk.LENDING_MARKET_ID,
627
- sdk.LENDING_MARKET_TYPE,
628
- client
629
- );
630
- } catch (err) {
631
- throw new T2000Error(
632
- "PROTOCOL_UNAVAILABLE",
633
- `Failed to initialize Suilend: ${err instanceof Error ? err.message : String(err)}`
634
- );
635
- }
636
- this.initialized = true;
615
+ await this.lazyInit();
616
+ }
617
+ initSync(client) {
618
+ this.client = client;
637
619
  }
638
- ensureInit() {
620
+ async lazyInit() {
621
+ if (this.initialized) return;
622
+ if (this.initPromise) return this.initPromise;
623
+ this.initPromise = (async () => {
624
+ let sdk;
625
+ try {
626
+ sdk = await import('@suilend/sdk');
627
+ } catch {
628
+ throw new T2000Error(
629
+ "PROTOCOL_UNAVAILABLE",
630
+ "Suilend SDK not installed. Run: npm install @suilend/sdk@^1"
631
+ );
632
+ }
633
+ this.lendingMarketType = sdk.LENDING_MARKET_TYPE;
634
+ try {
635
+ this.suilend = await sdk.SuilendClient.initialize(
636
+ sdk.LENDING_MARKET_ID,
637
+ sdk.LENDING_MARKET_TYPE,
638
+ this.client
639
+ );
640
+ } catch (err) {
641
+ this.initPromise = null;
642
+ throw new T2000Error(
643
+ "PROTOCOL_UNAVAILABLE",
644
+ `Failed to initialize Suilend: ${err instanceof Error ? err.message : String(err)}`
645
+ );
646
+ }
647
+ this.initialized = true;
648
+ })();
649
+ return this.initPromise;
650
+ }
651
+ async ensureInit() {
639
652
  if (!this.initialized) {
640
- throw new T2000Error(
641
- "PROTOCOL_UNAVAILABLE",
642
- "SuilendAdapter not initialized. Call init() first."
643
- );
653
+ await this.lazyInit();
644
654
  }
645
655
  }
646
656
  findReserve(asset) {
@@ -675,7 +685,7 @@ var SuilendAdapter = class {
675
685
  return parts[parts.length - 1] || "UNKNOWN";
676
686
  }
677
687
  async getRates(asset) {
678
- this.ensureInit();
688
+ await this.ensureInit();
679
689
  const reserve = this.findReserve(asset);
680
690
  if (!reserve) {
681
691
  throw new T2000Error("ASSET_NOT_SUPPORTED", `Suilend does not support ${asset}`);
@@ -688,7 +698,7 @@ var SuilendAdapter = class {
688
698
  };
689
699
  }
690
700
  async getPositions(address) {
691
- this.ensureInit();
701
+ await this.ensureInit();
692
702
  const supplies = [];
693
703
  const borrows = [];
694
704
  const caps = await this.getObligationCaps(address);
@@ -723,7 +733,7 @@ var SuilendAdapter = class {
723
733
  return { supplies, borrows };
724
734
  }
725
735
  async getHealth(address) {
726
- this.ensureInit();
736
+ await this.ensureInit();
727
737
  const caps = await this.getObligationCaps(address);
728
738
  if (caps.length === 0) {
729
739
  return { healthFactor: Infinity, supplied: 0, borrowed: 0, maxBorrow: 0, liquidationThreshold: 0 };
@@ -740,7 +750,7 @@ var SuilendAdapter = class {
740
750
  return { healthFactor, supplied, borrowed, maxBorrow, liquidationThreshold: liqThreshold };
741
751
  }
742
752
  async buildSaveTx(address, amount, _asset, options) {
743
- this.ensureInit();
753
+ await this.ensureInit();
744
754
  const rawAmount = usdcToRaw(amount).toString();
745
755
  const tx = new transactions.Transaction();
746
756
  tx.setSender(address);
@@ -771,7 +781,7 @@ var SuilendAdapter = class {
771
781
  return { tx };
772
782
  }
773
783
  async buildWithdrawTx(address, amount, _asset) {
774
- this.ensureInit();
784
+ await this.ensureInit();
775
785
  const caps = await this.getObligationCaps(address);
776
786
  if (caps.length === 0) {
777
787
  throw new T2000Error("NO_COLLATERAL", "No Suilend position found");
@@ -809,7 +819,7 @@ var SuilendAdapter = class {
809
819
  );
810
820
  }
811
821
  async maxWithdraw(address, _asset) {
812
- this.ensureInit();
822
+ await this.ensureInit();
813
823
  const health = await this.getHealth(address);
814
824
  let maxAmount;
815
825
  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":["getPriceFeeds","getLendingState","filterPriceFeeds","updateOraclePricesPTB","getCoins","Transaction","mergeCoinsPTB","depositCoinPTB","withdrawCoinPTB","borrowCoinPTB","repayCoinPTB","naviGetHealthFactor","getPool","AggregatorClient","Env","USDC_TYPE","MIN_HEALTH_FACTOR","normalizeStructTag"],"mappings":"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","file":"index.cjs","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":["getPriceFeeds","getLendingState","filterPriceFeeds","updateOraclePricesPTB","getCoins","Transaction","mergeCoinsPTB","depositCoinPTB","withdrawCoinPTB","borrowCoinPTB","repayCoinPTB","naviGetHealthFactor","getPool","AggregatorClient","Env","USDC_TYPE","MIN_HEALTH_FACTOR","normalizeStructTag"],"mappings":"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","file":"index.cjs","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"]}
@@ -1,3 +1,3 @@
1
- export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, C as CetusAdapter, o as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, q as ProtocolRegistry, r as SuilendAdapter, b as SwapAdapter, s as SwapQuote } from '../index-DYQv9Wxo.cjs';
1
+ export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, C as CetusAdapter, o as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, q as ProtocolRegistry, r as SuilendAdapter, b as SwapAdapter, s as SwapQuote } from '../index-BuaGAa6b.cjs';
2
2
  import '@mysten/sui/transactions';
3
3
  import '@mysten/sui/client';
@@ -1,3 +1,3 @@
1
- export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, C as CetusAdapter, o as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, q as ProtocolRegistry, r as SuilendAdapter, b as SwapAdapter, s as SwapQuote } from '../index-DYQv9Wxo.js';
1
+ export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, C as CetusAdapter, o as HealthInfo, L as LendingAdapter, h as LendingRates, N as NaviAdapter, q as ProtocolRegistry, r as SuilendAdapter, b as SwapAdapter, s as SwapQuote } from '../index-BuaGAa6b.js';
2
2
  import '@mysten/sui/transactions';
3
3
  import '@mysten/sui/client';