@t2000/sdk 0.19.22 → 0.19.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -43,7 +43,7 @@ declare class ZkLoginSigner implements TransactionSigner {
43
43
  isExpired(currentEpoch: number): boolean;
44
44
  }
45
45
 
46
- type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'WITHDRAW_FAILED' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'CONTACT_NOT_FOUND' | 'INVALID_CONTACT_NAME' | 'FACILITATOR_TIMEOUT' | 'SAFEGUARD_BLOCKED' | 'INSUFFICIENT_INVESTMENT' | 'INVESTMENT_LOCKED' | 'INVEST_ALREADY_EARNING' | 'INVEST_NOT_EARNING' | 'BORROW_GUARD_INVESTMENT' | 'STRATEGY_NOT_FOUND' | 'STRATEGY_INVALID_ALLOCATIONS' | 'STRATEGY_HAS_POSITIONS' | 'STRATEGY_BUILTIN' | 'STRATEGY_MIN_AMOUNT' | 'AUTO_INVEST_NOT_FOUND' | 'AUTO_INVEST_INSUFFICIENT' | 'MARKET_NOT_SUPPORTED' | 'LEVERAGE_EXCEEDED' | 'POSITION_SIZE_EXCEEDED' | 'BLUEFIN_AUTH_FAILED' | 'BLUEFIN_API_ERROR' | 'POSITION_NOT_FOUND' | 'UNKNOWN';
46
+ type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'USDC_SPONSOR_FAILED' | 'USDC_SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'WITHDRAW_FAILED' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'CONTACT_NOT_FOUND' | 'INVALID_CONTACT_NAME' | 'FACILITATOR_TIMEOUT' | 'SAFEGUARD_BLOCKED' | 'INSUFFICIENT_INVESTMENT' | 'INVESTMENT_LOCKED' | 'INVEST_ALREADY_EARNING' | 'INVEST_NOT_EARNING' | 'BORROW_GUARD_INVESTMENT' | 'STRATEGY_NOT_FOUND' | 'STRATEGY_INVALID_ALLOCATIONS' | 'STRATEGY_HAS_POSITIONS' | 'STRATEGY_BUILTIN' | 'STRATEGY_MIN_AMOUNT' | 'AUTO_INVEST_NOT_FOUND' | 'AUTO_INVEST_INSUFFICIENT' | 'MARKET_NOT_SUPPORTED' | 'LEVERAGE_EXCEEDED' | 'POSITION_SIZE_EXCEEDED' | 'BLUEFIN_AUTH_FAILED' | 'BLUEFIN_API_ERROR' | 'POSITION_NOT_FOUND' | 'UNKNOWN';
47
47
  interface T2000ErrorData {
48
48
  reason?: string;
49
49
  [key: string]: unknown;
@@ -412,6 +412,7 @@ declare class T2000 extends EventEmitter<T2000Events> {
412
412
  agent: T2000;
413
413
  address: string;
414
414
  sponsored: boolean;
415
+ usdcSponsored: boolean;
415
416
  }>;
416
417
  /** SuiJsonRpcClient used by this agent — exposed for integrations. */
417
418
  get suiClient(): SuiJsonRpcClient;
package/dist/index.d.ts CHANGED
@@ -43,7 +43,7 @@ declare class ZkLoginSigner implements TransactionSigner {
43
43
  isExpired(currentEpoch: number): boolean;
44
44
  }
45
45
 
46
- type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'WITHDRAW_FAILED' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'CONTACT_NOT_FOUND' | 'INVALID_CONTACT_NAME' | 'FACILITATOR_TIMEOUT' | 'SAFEGUARD_BLOCKED' | 'INSUFFICIENT_INVESTMENT' | 'INVESTMENT_LOCKED' | 'INVEST_ALREADY_EARNING' | 'INVEST_NOT_EARNING' | 'BORROW_GUARD_INVESTMENT' | 'STRATEGY_NOT_FOUND' | 'STRATEGY_INVALID_ALLOCATIONS' | 'STRATEGY_HAS_POSITIONS' | 'STRATEGY_BUILTIN' | 'STRATEGY_MIN_AMOUNT' | 'AUTO_INVEST_NOT_FOUND' | 'AUTO_INVEST_INSUFFICIENT' | 'MARKET_NOT_SUPPORTED' | 'LEVERAGE_EXCEEDED' | 'POSITION_SIZE_EXCEEDED' | 'BLUEFIN_AUTH_FAILED' | 'BLUEFIN_API_ERROR' | 'POSITION_NOT_FOUND' | 'UNKNOWN';
46
+ type T2000ErrorCode = 'INSUFFICIENT_BALANCE' | 'INSUFFICIENT_GAS' | 'INVALID_ADDRESS' | 'INVALID_AMOUNT' | 'WALLET_NOT_FOUND' | 'WALLET_LOCKED' | 'WALLET_EXISTS' | 'SPONSOR_FAILED' | 'SPONSOR_RATE_LIMITED' | 'USDC_SPONSOR_FAILED' | 'USDC_SPONSOR_RATE_LIMITED' | 'GAS_STATION_UNAVAILABLE' | 'GAS_FEE_EXCEEDED' | 'SIMULATION_FAILED' | 'TRANSACTION_FAILED' | 'ASSET_NOT_SUPPORTED' | 'SWAP_FAILED' | 'SLIPPAGE_EXCEEDED' | 'HEALTH_FACTOR_TOO_LOW' | 'WITHDRAW_WOULD_LIQUIDATE' | 'WITHDRAW_FAILED' | 'NO_COLLATERAL' | 'PROTOCOL_PAUSED' | 'PROTOCOL_UNAVAILABLE' | 'RPC_ERROR' | 'RPC_UNREACHABLE' | 'SPONSOR_UNAVAILABLE' | 'AUTO_TOPUP_FAILED' | 'PRICE_EXCEEDS_LIMIT' | 'UNSUPPORTED_NETWORK' | 'PAYMENT_EXPIRED' | 'DUPLICATE_PAYMENT' | 'FACILITATOR_REJECTION' | 'CONTACT_NOT_FOUND' | 'INVALID_CONTACT_NAME' | 'FACILITATOR_TIMEOUT' | 'SAFEGUARD_BLOCKED' | 'INSUFFICIENT_INVESTMENT' | 'INVESTMENT_LOCKED' | 'INVEST_ALREADY_EARNING' | 'INVEST_NOT_EARNING' | 'BORROW_GUARD_INVESTMENT' | 'STRATEGY_NOT_FOUND' | 'STRATEGY_INVALID_ALLOCATIONS' | 'STRATEGY_HAS_POSITIONS' | 'STRATEGY_BUILTIN' | 'STRATEGY_MIN_AMOUNT' | 'AUTO_INVEST_NOT_FOUND' | 'AUTO_INVEST_INSUFFICIENT' | 'MARKET_NOT_SUPPORTED' | 'LEVERAGE_EXCEEDED' | 'POSITION_SIZE_EXCEEDED' | 'BLUEFIN_AUTH_FAILED' | 'BLUEFIN_API_ERROR' | 'POSITION_NOT_FOUND' | 'UNKNOWN';
47
47
  interface T2000ErrorData {
48
48
  reason?: string;
49
49
  [key: string]: unknown;
@@ -412,6 +412,7 @@ declare class T2000 extends EventEmitter<T2000Events> {
412
412
  agent: T2000;
413
413
  address: string;
414
414
  sponsored: boolean;
415
+ usdcSponsored: boolean;
415
416
  }>;
416
417
  /** SuiJsonRpcClient used by this agent — exposed for integrations. */
417
418
  get suiClient(): SuiJsonRpcClient;
package/dist/index.js CHANGED
@@ -181,6 +181,8 @@ function mapMoveAbortCode(code) {
181
181
  1503: 'Withdrawal amount is invalid (zero or dust) \u2014 try a specific amount instead of "all"',
182
182
  1600: "Health factor too low \u2014 withdrawal would risk liquidation",
183
183
  1605: "Asset borrowing is disabled or at capacity on this protocol",
184
+ // NAVI utils abort codes
185
+ 46e3: "Insufficient balance to repay \u2014 withdraw some savings first to get cash",
184
186
  // Cetus DEX abort codes
185
187
  46001: "Swap failed \u2014 the DEX pool rejected the trade (liquidity or routing issue). Try again."
186
188
  };
@@ -995,12 +997,16 @@ async function buildRepayTx(client, address, amount, options = {}) {
995
997
  const asset = options.asset ?? "USDC";
996
998
  const assetInfo = resolveAssetInfo(asset);
997
999
  const coins = await fetchCoins(client, address, assetInfo.type);
998
- if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins to repay with`);
1000
+ if (coins.length === 0) throw new T2000Error("INSUFFICIENT_BALANCE", `No ${assetInfo.displayName} coins to repay with. Withdraw some savings first to get cash.`);
999
1001
  const totalBalance = coins.reduce((sum, c) => sum + BigInt(c.balance), 0n);
1002
+ const rawRequested = Number(stableToRaw(amount, assetInfo.decimals));
1003
+ if (Number(totalBalance) < rawRequested && Number(totalBalance) < 1e3) {
1004
+ throw new T2000Error("INSUFFICIENT_BALANCE", `Not enough ${assetInfo.displayName} to repay (need $${amount.toFixed(2)}, wallet has ~$${(Number(totalBalance) / 10 ** assetInfo.decimals).toFixed(4)}). Withdraw some savings first.`);
1005
+ }
1000
1006
  const tx = new Transaction();
1001
1007
  tx.setSender(address);
1002
1008
  const coinObj = mergeCoins(tx, coins);
1003
- const rawAmount = Math.min(Number(stableToRaw(amount, assetInfo.decimals)), Number(totalBalance));
1009
+ const rawAmount = Math.min(rawRequested, Number(totalBalance));
1004
1010
  const [repayCoin] = tx.splitCoins(coinObj, [rawAmount]);
1005
1011
  await refreshOracle(tx, client, address, {
1006
1012
  skipPythUpdate: options.sponsored,
@@ -3279,14 +3285,20 @@ var T2000 = class _T2000 extends EventEmitter {
3279
3285
  const agent = new _T2000(keypair, client, void 0, DEFAULT_CONFIG_DIR);
3280
3286
  const address = agent.address();
3281
3287
  let sponsored = false;
3288
+ let usdcSponsored = false;
3282
3289
  if (options.sponsored !== false) {
3283
3290
  try {
3284
3291
  await callSponsorApi(address, options.name);
3285
3292
  sponsored = true;
3286
3293
  } catch {
3287
3294
  }
3295
+ try {
3296
+ await callUsdcSponsorApi(address);
3297
+ usdcSponsored = true;
3298
+ } catch {
3299
+ }
3288
3300
  }
3289
- return { agent, address, sponsored };
3301
+ return { agent, address, sponsored, usdcSponsored };
3290
3302
  }
3291
3303
  // -- Gas --
3292
3304
  /** SuiJsonRpcClient used by this agent — exposed for integrations. */
@@ -5828,6 +5840,30 @@ async function callSponsorApi(address, name) {
5828
5840
  throw new T2000Error("SPONSOR_FAILED", "Sponsor API unavailable");
5829
5841
  }
5830
5842
  }
5843
+ async function callUsdcSponsorApi(address) {
5844
+ const res = await fetch(`${API_BASE_URL}/api/sponsor/usdc`, {
5845
+ method: "POST",
5846
+ headers: { "Content-Type": "application/json" },
5847
+ body: JSON.stringify({ address, source: "cli" })
5848
+ });
5849
+ if (res.status === 429) {
5850
+ const data = await res.json();
5851
+ if (data.challenge) {
5852
+ const proof = solveHashcash(data.challenge);
5853
+ const retry = await fetch(`${API_BASE_URL}/api/sponsor/usdc`, {
5854
+ method: "POST",
5855
+ headers: { "Content-Type": "application/json" },
5856
+ body: JSON.stringify({ address, source: "cli", proof })
5857
+ });
5858
+ if (!retry.ok) throw new T2000Error("USDC_SPONSOR_RATE_LIMITED", "USDC sponsor rate limited");
5859
+ return;
5860
+ }
5861
+ }
5862
+ if (res.status === 409) return;
5863
+ if (!res.ok) {
5864
+ throw new T2000Error("USDC_SPONSOR_FAILED", "USDC sponsor unavailable");
5865
+ }
5866
+ }
5831
5867
 
5832
5868
  // src/utils/simulate.ts
5833
5869
  async function simulateTransaction(client, tx, sender) {