@t2000/sdk 0.10.4 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -1
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/index.cjs +189 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -3
- package/dist/index.d.ts +61 -3
- package/dist/index.js +187 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ import { T as T2000Options, S as SendResult, B as BalanceResponse, a as Transact
|
|
|
5
5
|
export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, n as AssetRates, C as CetusAdapter, o as GasReserve, p as HealthInfo, N as NaviAdapter, q as PositionEntry, r as ProtocolDescriptor, s as ProtocolRegistry, t as RebalanceStep, u as SentinelVerdict, v as SuilendAdapter, w as SwapQuote, x as allDescriptors, y as cetusDescriptor, z as getSentinelInfo, I as listSentinels, J as naviDescriptor, K as requestAttack, O as sentinelAttack, Q as sentinelDescriptor, U as settleAttack, V as submitPrompt, X as suilendDescriptor } from './index-UOQejD-B.cjs';
|
|
6
6
|
import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
7
7
|
|
|
8
|
-
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' | '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' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'UNKNOWN';
|
|
8
|
+
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' | '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' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'SAFEGUARD_BLOCKED' | 'UNKNOWN';
|
|
9
9
|
interface T2000ErrorData {
|
|
10
10
|
reason?: string;
|
|
11
11
|
[key: string]: unknown;
|
|
@@ -25,6 +25,37 @@ declare class T2000Error extends Error {
|
|
|
25
25
|
declare function mapWalletError(error: unknown): T2000Error;
|
|
26
26
|
declare function mapMoveAbortCode(code: number): string;
|
|
27
27
|
|
|
28
|
+
interface SafeguardConfig {
|
|
29
|
+
locked: boolean;
|
|
30
|
+
maxPerTx: number;
|
|
31
|
+
maxDailySend: number;
|
|
32
|
+
dailyUsed: number;
|
|
33
|
+
dailyResetDate: string;
|
|
34
|
+
}
|
|
35
|
+
interface TxMetadata {
|
|
36
|
+
operation: 'send' | 'save' | 'withdraw' | 'borrow' | 'repay' | 'exchange' | 'rebalance' | 'pay' | 'sentinel';
|
|
37
|
+
amount?: number;
|
|
38
|
+
}
|
|
39
|
+
declare const OUTBOUND_OPS: Set<"save" | "borrow" | "withdraw" | "repay" | "sentinel" | "send" | "exchange" | "rebalance" | "pay">;
|
|
40
|
+
declare const DEFAULT_SAFEGUARD_CONFIG: SafeguardConfig;
|
|
41
|
+
|
|
42
|
+
declare class SafeguardEnforcer {
|
|
43
|
+
private config;
|
|
44
|
+
private readonly configPath;
|
|
45
|
+
constructor(configDir?: string);
|
|
46
|
+
load(): void;
|
|
47
|
+
assertNotLocked(): void;
|
|
48
|
+
check(metadata: TxMetadata): void;
|
|
49
|
+
recordUsage(amount: number): void;
|
|
50
|
+
lock(): void;
|
|
51
|
+
unlock(): void;
|
|
52
|
+
set(key: string, value: unknown): void;
|
|
53
|
+
getConfig(): SafeguardConfig;
|
|
54
|
+
isConfigured(): boolean;
|
|
55
|
+
private resetDailyIfNewDay;
|
|
56
|
+
private save;
|
|
57
|
+
}
|
|
58
|
+
|
|
28
59
|
interface T2000Events {
|
|
29
60
|
balanceChange: (event: {
|
|
30
61
|
asset: string;
|
|
@@ -65,6 +96,7 @@ declare class T2000 extends EventEmitter<T2000Events> {
|
|
|
65
96
|
private readonly client;
|
|
66
97
|
private readonly _address;
|
|
67
98
|
private readonly registry;
|
|
99
|
+
readonly enforcer: SafeguardEnforcer;
|
|
68
100
|
private constructor();
|
|
69
101
|
private static createDefaultRegistry;
|
|
70
102
|
static create(options?: T2000Options): Promise<T2000>;
|
|
@@ -278,6 +310,29 @@ declare function getPoolPrice(client: SuiJsonRpcClient): Promise<number>;
|
|
|
278
310
|
|
|
279
311
|
declare function getRates(client: SuiJsonRpcClient): Promise<RatesResult>;
|
|
280
312
|
|
|
313
|
+
type SafeguardRule = 'locked' | 'maxPerTx' | 'maxDailySend';
|
|
314
|
+
interface SafeguardErrorDetails {
|
|
315
|
+
attempted?: number;
|
|
316
|
+
limit?: number;
|
|
317
|
+
current?: number;
|
|
318
|
+
}
|
|
319
|
+
declare class SafeguardError extends T2000Error {
|
|
320
|
+
readonly rule: SafeguardRule;
|
|
321
|
+
readonly details: SafeguardErrorDetails;
|
|
322
|
+
constructor(rule: SafeguardRule, details: SafeguardErrorDetails, message?: string);
|
|
323
|
+
toJSON(): {
|
|
324
|
+
error: "SAFEGUARD_BLOCKED";
|
|
325
|
+
message: string;
|
|
326
|
+
retryable: boolean;
|
|
327
|
+
data: {
|
|
328
|
+
attempted?: number;
|
|
329
|
+
limit?: number;
|
|
330
|
+
current?: number;
|
|
331
|
+
rule: SafeguardRule;
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
281
336
|
interface GasExecutionResult {
|
|
282
337
|
digest: string;
|
|
283
338
|
effects: unknown;
|
|
@@ -291,7 +346,10 @@ interface GasExecutionResult {
|
|
|
291
346
|
* 3. Gas Station sponsored (fallback)
|
|
292
347
|
* 4. Fail with INSUFFICIENT_GAS
|
|
293
348
|
*/
|
|
294
|
-
declare function executeWithGas(client: SuiJsonRpcClient, keypair: Ed25519Keypair, buildTx: () => Transaction | Promise<Transaction
|
|
349
|
+
declare function executeWithGas(client: SuiJsonRpcClient, keypair: Ed25519Keypair, buildTx: () => Transaction | Promise<Transaction>, options?: {
|
|
350
|
+
metadata?: TxMetadata;
|
|
351
|
+
enforcer?: SafeguardEnforcer;
|
|
352
|
+
}): Promise<GasExecutionResult>;
|
|
295
353
|
|
|
296
354
|
interface AutoTopUpResult {
|
|
297
355
|
success: boolean;
|
|
@@ -317,4 +375,4 @@ interface GasStatusResponse {
|
|
|
317
375
|
}
|
|
318
376
|
declare function getGasStatus(address?: string): Promise<GasStatusResponse>;
|
|
319
377
|
|
|
320
|
-
export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, DEFAULT_NETWORK, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
|
378
|
+
export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, OUTBOUND_OPS, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SafeguardConfig, SafeguardEnforcer, SafeguardError, type SafeguardErrorDetails, type SafeguardRule, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, type TxMetadata, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { T as T2000Options, S as SendResult, B as BalanceResponse, a as Transact
|
|
|
5
5
|
export { A as AdapterCapability, l as AdapterPositions, m as AdapterTxResult, n as AssetRates, C as CetusAdapter, o as GasReserve, p as HealthInfo, N as NaviAdapter, q as PositionEntry, r as ProtocolDescriptor, s as ProtocolRegistry, t as RebalanceStep, u as SentinelVerdict, v as SuilendAdapter, w as SwapQuote, x as allDescriptors, y as cetusDescriptor, z as getSentinelInfo, I as listSentinels, J as naviDescriptor, K as requestAttack, O as sentinelAttack, Q as sentinelDescriptor, U as settleAttack, V as submitPrompt, X as suilendDescriptor } from './index-UOQejD-B.js';
|
|
6
6
|
import { Transaction, TransactionObjectArgument } from '@mysten/sui/transactions';
|
|
7
7
|
|
|
8
|
-
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' | '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' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'UNKNOWN';
|
|
8
|
+
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' | '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' | 'FACILITATOR_TIMEOUT' | 'SENTINEL_API_ERROR' | 'SENTINEL_NOT_FOUND' | 'SENTINEL_TX_FAILED' | 'SENTINEL_TEE_ERROR' | 'SAFEGUARD_BLOCKED' | 'UNKNOWN';
|
|
9
9
|
interface T2000ErrorData {
|
|
10
10
|
reason?: string;
|
|
11
11
|
[key: string]: unknown;
|
|
@@ -25,6 +25,37 @@ declare class T2000Error extends Error {
|
|
|
25
25
|
declare function mapWalletError(error: unknown): T2000Error;
|
|
26
26
|
declare function mapMoveAbortCode(code: number): string;
|
|
27
27
|
|
|
28
|
+
interface SafeguardConfig {
|
|
29
|
+
locked: boolean;
|
|
30
|
+
maxPerTx: number;
|
|
31
|
+
maxDailySend: number;
|
|
32
|
+
dailyUsed: number;
|
|
33
|
+
dailyResetDate: string;
|
|
34
|
+
}
|
|
35
|
+
interface TxMetadata {
|
|
36
|
+
operation: 'send' | 'save' | 'withdraw' | 'borrow' | 'repay' | 'exchange' | 'rebalance' | 'pay' | 'sentinel';
|
|
37
|
+
amount?: number;
|
|
38
|
+
}
|
|
39
|
+
declare const OUTBOUND_OPS: Set<"save" | "borrow" | "withdraw" | "repay" | "sentinel" | "send" | "exchange" | "rebalance" | "pay">;
|
|
40
|
+
declare const DEFAULT_SAFEGUARD_CONFIG: SafeguardConfig;
|
|
41
|
+
|
|
42
|
+
declare class SafeguardEnforcer {
|
|
43
|
+
private config;
|
|
44
|
+
private readonly configPath;
|
|
45
|
+
constructor(configDir?: string);
|
|
46
|
+
load(): void;
|
|
47
|
+
assertNotLocked(): void;
|
|
48
|
+
check(metadata: TxMetadata): void;
|
|
49
|
+
recordUsage(amount: number): void;
|
|
50
|
+
lock(): void;
|
|
51
|
+
unlock(): void;
|
|
52
|
+
set(key: string, value: unknown): void;
|
|
53
|
+
getConfig(): SafeguardConfig;
|
|
54
|
+
isConfigured(): boolean;
|
|
55
|
+
private resetDailyIfNewDay;
|
|
56
|
+
private save;
|
|
57
|
+
}
|
|
58
|
+
|
|
28
59
|
interface T2000Events {
|
|
29
60
|
balanceChange: (event: {
|
|
30
61
|
asset: string;
|
|
@@ -65,6 +96,7 @@ declare class T2000 extends EventEmitter<T2000Events> {
|
|
|
65
96
|
private readonly client;
|
|
66
97
|
private readonly _address;
|
|
67
98
|
private readonly registry;
|
|
99
|
+
readonly enforcer: SafeguardEnforcer;
|
|
68
100
|
private constructor();
|
|
69
101
|
private static createDefaultRegistry;
|
|
70
102
|
static create(options?: T2000Options): Promise<T2000>;
|
|
@@ -278,6 +310,29 @@ declare function getPoolPrice(client: SuiJsonRpcClient): Promise<number>;
|
|
|
278
310
|
|
|
279
311
|
declare function getRates(client: SuiJsonRpcClient): Promise<RatesResult>;
|
|
280
312
|
|
|
313
|
+
type SafeguardRule = 'locked' | 'maxPerTx' | 'maxDailySend';
|
|
314
|
+
interface SafeguardErrorDetails {
|
|
315
|
+
attempted?: number;
|
|
316
|
+
limit?: number;
|
|
317
|
+
current?: number;
|
|
318
|
+
}
|
|
319
|
+
declare class SafeguardError extends T2000Error {
|
|
320
|
+
readonly rule: SafeguardRule;
|
|
321
|
+
readonly details: SafeguardErrorDetails;
|
|
322
|
+
constructor(rule: SafeguardRule, details: SafeguardErrorDetails, message?: string);
|
|
323
|
+
toJSON(): {
|
|
324
|
+
error: "SAFEGUARD_BLOCKED";
|
|
325
|
+
message: string;
|
|
326
|
+
retryable: boolean;
|
|
327
|
+
data: {
|
|
328
|
+
attempted?: number;
|
|
329
|
+
limit?: number;
|
|
330
|
+
current?: number;
|
|
331
|
+
rule: SafeguardRule;
|
|
332
|
+
};
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
281
336
|
interface GasExecutionResult {
|
|
282
337
|
digest: string;
|
|
283
338
|
effects: unknown;
|
|
@@ -291,7 +346,10 @@ interface GasExecutionResult {
|
|
|
291
346
|
* 3. Gas Station sponsored (fallback)
|
|
292
347
|
* 4. Fail with INSUFFICIENT_GAS
|
|
293
348
|
*/
|
|
294
|
-
declare function executeWithGas(client: SuiJsonRpcClient, keypair: Ed25519Keypair, buildTx: () => Transaction | Promise<Transaction
|
|
349
|
+
declare function executeWithGas(client: SuiJsonRpcClient, keypair: Ed25519Keypair, buildTx: () => Transaction | Promise<Transaction>, options?: {
|
|
350
|
+
metadata?: TxMetadata;
|
|
351
|
+
enforcer?: SafeguardEnforcer;
|
|
352
|
+
}): Promise<GasExecutionResult>;
|
|
295
353
|
|
|
296
354
|
interface AutoTopUpResult {
|
|
297
355
|
success: boolean;
|
|
@@ -317,4 +375,4 @@ interface GasStatusResponse {
|
|
|
317
375
|
}
|
|
318
376
|
declare function getGasStatus(address?: string): Promise<GasStatusResponse>;
|
|
319
377
|
|
|
320
|
-
export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, DEFAULT_NETWORK, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
|
378
|
+
export { type AutoTopUpResult, BPS_DENOMINATOR, BalanceResponse, BorrowResult, CLOCK_ID, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, DepositInfo, EarningsResult, type FeeOperation, FundStatusResult, type GasExecutionResult, GasMethod, type GasRequestType, type GasSponsorResponse, type GasStatusResponse, HealthFactorResult, LendingAdapter, LendingRates, MIST_PER_SUI, MaxBorrowResult, MaxWithdrawResult, OUTBOUND_OPS, PositionsResult, type ProtocolFeeInfo, RatesResult, RebalanceResult, RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SafeguardConfig, SafeguardEnforcer, SafeguardError, type SafeguardErrorDetails, type SafeguardRule, SaveResult, SendResult, SentinelAgent, SentinelAttackResult, type SimulationResult, type SupportedAsset, SwapAdapter, SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, T2000Options, TransactionRecord, type TxMetadata, USDC_DECIMALS, WithdrawResult, addCollectFeeToTx, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToStable, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,11 @@ import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
|
|
|
6
6
|
import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
|
|
7
7
|
import { createHash, randomBytes, createCipheriv, createDecipheriv, scryptSync } from 'crypto';
|
|
8
8
|
import { access, mkdir, writeFile, readFile } from 'fs/promises';
|
|
9
|
-
import { dirname, resolve } from 'path';
|
|
9
|
+
import { join, dirname, resolve } from 'path';
|
|
10
10
|
import { homedir } from 'os';
|
|
11
11
|
import { bcs } from '@mysten/sui/bcs';
|
|
12
12
|
import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
|
|
13
|
+
import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
13
14
|
|
|
14
15
|
// src/t2000.ts
|
|
15
16
|
|
|
@@ -2494,7 +2495,10 @@ async function trySponsored(client, keypair, tx) {
|
|
|
2494
2495
|
gasCostSui: gasCost
|
|
2495
2496
|
};
|
|
2496
2497
|
}
|
|
2497
|
-
async function executeWithGas(client, keypair, buildTx) {
|
|
2498
|
+
async function executeWithGas(client, keypair, buildTx, options) {
|
|
2499
|
+
if (options?.enforcer && options?.metadata) {
|
|
2500
|
+
options.enforcer.check(options.metadata);
|
|
2501
|
+
}
|
|
2498
2502
|
const errors = [];
|
|
2499
2503
|
try {
|
|
2500
2504
|
const tx = await buildTx();
|
|
@@ -2531,18 +2535,182 @@ async function executeWithGas(client, keypair, buildTx) {
|
|
|
2531
2535
|
);
|
|
2532
2536
|
}
|
|
2533
2537
|
|
|
2534
|
-
// src/
|
|
2538
|
+
// src/safeguards/types.ts
|
|
2539
|
+
var OUTBOUND_OPS = /* @__PURE__ */ new Set([
|
|
2540
|
+
"send",
|
|
2541
|
+
"pay",
|
|
2542
|
+
"sentinel"
|
|
2543
|
+
]);
|
|
2544
|
+
var DEFAULT_SAFEGUARD_CONFIG = {
|
|
2545
|
+
locked: false,
|
|
2546
|
+
maxPerTx: 0,
|
|
2547
|
+
maxDailySend: 0,
|
|
2548
|
+
dailyUsed: 0,
|
|
2549
|
+
dailyResetDate: ""
|
|
2550
|
+
};
|
|
2551
|
+
|
|
2552
|
+
// src/safeguards/errors.ts
|
|
2553
|
+
var SafeguardError = class extends T2000Error {
|
|
2554
|
+
rule;
|
|
2555
|
+
details;
|
|
2556
|
+
constructor(rule, details, message) {
|
|
2557
|
+
const msg = message ?? buildMessage(rule, details);
|
|
2558
|
+
super("SAFEGUARD_BLOCKED", msg, { rule, ...details });
|
|
2559
|
+
this.name = "SafeguardError";
|
|
2560
|
+
this.rule = rule;
|
|
2561
|
+
this.details = details;
|
|
2562
|
+
}
|
|
2563
|
+
toJSON() {
|
|
2564
|
+
return {
|
|
2565
|
+
error: "SAFEGUARD_BLOCKED",
|
|
2566
|
+
message: this.message,
|
|
2567
|
+
retryable: this.retryable,
|
|
2568
|
+
data: { rule: this.rule, ...this.details }
|
|
2569
|
+
};
|
|
2570
|
+
}
|
|
2571
|
+
};
|
|
2572
|
+
function buildMessage(rule, details) {
|
|
2573
|
+
switch (rule) {
|
|
2574
|
+
case "locked":
|
|
2575
|
+
return "Agent is locked. All operations are frozen.";
|
|
2576
|
+
case "maxPerTx":
|
|
2577
|
+
return `Amount $${(details.attempted ?? 0).toFixed(2)} exceeds per-transaction limit ($${(details.limit ?? 0).toFixed(2)})`;
|
|
2578
|
+
case "maxDailySend":
|
|
2579
|
+
return `Daily send limit reached ($${(details.current ?? 0).toFixed(2)}/$${(details.limit ?? 0).toFixed(2)} used today)`;
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
// src/safeguards/enforcer.ts
|
|
2584
|
+
var SafeguardEnforcer = class {
|
|
2585
|
+
config;
|
|
2586
|
+
configPath;
|
|
2587
|
+
constructor(configDir) {
|
|
2588
|
+
this.config = { ...DEFAULT_SAFEGUARD_CONFIG };
|
|
2589
|
+
this.configPath = configDir ? join(configDir, "config.json") : null;
|
|
2590
|
+
}
|
|
2591
|
+
load() {
|
|
2592
|
+
if (!this.configPath) return;
|
|
2593
|
+
try {
|
|
2594
|
+
const raw = JSON.parse(readFileSync(this.configPath, "utf-8"));
|
|
2595
|
+
this.config = {
|
|
2596
|
+
...DEFAULT_SAFEGUARD_CONFIG,
|
|
2597
|
+
locked: raw.locked ?? false,
|
|
2598
|
+
maxPerTx: raw.maxPerTx ?? 0,
|
|
2599
|
+
maxDailySend: raw.maxDailySend ?? 0,
|
|
2600
|
+
dailyUsed: raw.dailyUsed ?? 0,
|
|
2601
|
+
dailyResetDate: raw.dailyResetDate ?? ""
|
|
2602
|
+
};
|
|
2603
|
+
} catch {
|
|
2604
|
+
this.config = { ...DEFAULT_SAFEGUARD_CONFIG };
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
assertNotLocked() {
|
|
2608
|
+
this.load();
|
|
2609
|
+
if (this.config.locked) {
|
|
2610
|
+
throw new SafeguardError("locked", {});
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
check(metadata) {
|
|
2614
|
+
this.load();
|
|
2615
|
+
if (this.config.locked) {
|
|
2616
|
+
throw new SafeguardError("locked", {});
|
|
2617
|
+
}
|
|
2618
|
+
if (!OUTBOUND_OPS.has(metadata.operation)) return;
|
|
2619
|
+
const amount = metadata.amount ?? 0;
|
|
2620
|
+
if (this.config.maxPerTx > 0 && amount > this.config.maxPerTx) {
|
|
2621
|
+
throw new SafeguardError("maxPerTx", {
|
|
2622
|
+
attempted: amount,
|
|
2623
|
+
limit: this.config.maxPerTx
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
this.resetDailyIfNewDay();
|
|
2627
|
+
if (this.config.maxDailySend > 0 && this.config.dailyUsed + amount > this.config.maxDailySend) {
|
|
2628
|
+
throw new SafeguardError("maxDailySend", {
|
|
2629
|
+
attempted: amount,
|
|
2630
|
+
limit: this.config.maxDailySend,
|
|
2631
|
+
current: this.config.dailyUsed
|
|
2632
|
+
});
|
|
2633
|
+
}
|
|
2634
|
+
}
|
|
2635
|
+
recordUsage(amount) {
|
|
2636
|
+
this.resetDailyIfNewDay();
|
|
2637
|
+
this.config.dailyUsed += amount;
|
|
2638
|
+
this.save();
|
|
2639
|
+
}
|
|
2640
|
+
lock() {
|
|
2641
|
+
this.config.locked = true;
|
|
2642
|
+
this.save();
|
|
2643
|
+
}
|
|
2644
|
+
unlock() {
|
|
2645
|
+
this.config.locked = false;
|
|
2646
|
+
this.save();
|
|
2647
|
+
}
|
|
2648
|
+
set(key, value) {
|
|
2649
|
+
if (key === "locked" && typeof value === "boolean") {
|
|
2650
|
+
this.config.locked = value;
|
|
2651
|
+
} else if (key === "maxPerTx" && typeof value === "number") {
|
|
2652
|
+
this.config.maxPerTx = value;
|
|
2653
|
+
} else if (key === "maxDailySend" && typeof value === "number") {
|
|
2654
|
+
this.config.maxDailySend = value;
|
|
2655
|
+
}
|
|
2656
|
+
this.save();
|
|
2657
|
+
}
|
|
2658
|
+
getConfig() {
|
|
2659
|
+
this.load();
|
|
2660
|
+
this.resetDailyIfNewDay();
|
|
2661
|
+
return { ...this.config };
|
|
2662
|
+
}
|
|
2663
|
+
isConfigured() {
|
|
2664
|
+
return this.config.maxPerTx > 0 || this.config.maxDailySend > 0;
|
|
2665
|
+
}
|
|
2666
|
+
resetDailyIfNewDay() {
|
|
2667
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2668
|
+
if (this.config.dailyResetDate !== today) {
|
|
2669
|
+
this.config.dailyUsed = 0;
|
|
2670
|
+
this.config.dailyResetDate = today;
|
|
2671
|
+
this.save();
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
save() {
|
|
2675
|
+
if (!this.configPath) return;
|
|
2676
|
+
try {
|
|
2677
|
+
let existing = {};
|
|
2678
|
+
try {
|
|
2679
|
+
existing = JSON.parse(readFileSync(this.configPath, "utf-8"));
|
|
2680
|
+
} catch {
|
|
2681
|
+
}
|
|
2682
|
+
const merged = {
|
|
2683
|
+
...existing,
|
|
2684
|
+
locked: this.config.locked,
|
|
2685
|
+
maxPerTx: this.config.maxPerTx,
|
|
2686
|
+
maxDailySend: this.config.maxDailySend,
|
|
2687
|
+
dailyUsed: this.config.dailyUsed,
|
|
2688
|
+
dailyResetDate: this.config.dailyResetDate
|
|
2689
|
+
};
|
|
2690
|
+
const dir = this.configPath.replace(/[/\\][^/\\]+$/, "");
|
|
2691
|
+
if (!existsSync(dir)) {
|
|
2692
|
+
mkdirSync(dir, { recursive: true });
|
|
2693
|
+
}
|
|
2694
|
+
writeFileSync(this.configPath, JSON.stringify(merged, null, 2) + "\n");
|
|
2695
|
+
} catch {
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
};
|
|
2699
|
+
var DEFAULT_CONFIG_DIR = join(homedir(), ".t2000");
|
|
2535
2700
|
var T2000 = class _T2000 extends EventEmitter {
|
|
2536
2701
|
keypair;
|
|
2537
2702
|
client;
|
|
2538
2703
|
_address;
|
|
2539
2704
|
registry;
|
|
2540
|
-
|
|
2705
|
+
enforcer;
|
|
2706
|
+
constructor(keypair, client, registry, configDir) {
|
|
2541
2707
|
super();
|
|
2542
2708
|
this.keypair = keypair;
|
|
2543
2709
|
this.client = client;
|
|
2544
2710
|
this._address = getAddress(keypair);
|
|
2545
2711
|
this.registry = registry ?? _T2000.createDefaultRegistry(client);
|
|
2712
|
+
this.enforcer = new SafeguardEnforcer(configDir);
|
|
2713
|
+
this.enforcer.load();
|
|
2546
2714
|
}
|
|
2547
2715
|
static createDefaultRegistry(client) {
|
|
2548
2716
|
const registry = new ProtocolRegistry();
|
|
@@ -2566,7 +2734,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2566
2734
|
if (secret) {
|
|
2567
2735
|
await saveKey(keypair2, secret, keyPath);
|
|
2568
2736
|
}
|
|
2569
|
-
return new _T2000(keypair2, client);
|
|
2737
|
+
return new _T2000(keypair2, client, void 0, DEFAULT_CONFIG_DIR);
|
|
2570
2738
|
}
|
|
2571
2739
|
const exists = await walletExists(keyPath);
|
|
2572
2740
|
if (!exists) {
|
|
@@ -2579,7 +2747,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2579
2747
|
throw new T2000Error("WALLET_LOCKED", "PIN required to unlock wallet");
|
|
2580
2748
|
}
|
|
2581
2749
|
const keypair = await loadKey(secret, keyPath);
|
|
2582
|
-
return new _T2000(keypair, client);
|
|
2750
|
+
return new _T2000(keypair, client, void 0, DEFAULT_CONFIG_DIR);
|
|
2583
2751
|
}
|
|
2584
2752
|
static fromPrivateKey(privateKey, options = {}) {
|
|
2585
2753
|
const keypair = keypairFromPrivateKey(privateKey);
|
|
@@ -2591,7 +2759,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2591
2759
|
const keypair = generateKeypair();
|
|
2592
2760
|
await saveKey(keypair, secret, options.keyPath);
|
|
2593
2761
|
const client = getSuiClient();
|
|
2594
|
-
const agent = new _T2000(keypair, client);
|
|
2762
|
+
const agent = new _T2000(keypair, client, void 0, DEFAULT_CONFIG_DIR);
|
|
2595
2763
|
const address = agent.address();
|
|
2596
2764
|
let sponsored = false;
|
|
2597
2765
|
if (options.sponsored !== false) {
|
|
@@ -2617,6 +2785,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2617
2785
|
return this._address;
|
|
2618
2786
|
}
|
|
2619
2787
|
async send(params) {
|
|
2788
|
+
this.enforcer.assertNotLocked();
|
|
2620
2789
|
const asset = params.asset ?? "USDC";
|
|
2621
2790
|
if (!(asset in SUPPORTED_ASSETS)) {
|
|
2622
2791
|
throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
|
|
@@ -2626,8 +2795,10 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2626
2795
|
const gasResult = await executeWithGas(
|
|
2627
2796
|
this.client,
|
|
2628
2797
|
this.keypair,
|
|
2629
|
-
() => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset })
|
|
2798
|
+
() => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset }),
|
|
2799
|
+
{ metadata: { operation: "send", amount: sendAmount }, enforcer: this.enforcer }
|
|
2630
2800
|
);
|
|
2801
|
+
this.enforcer.recordUsage(sendAmount);
|
|
2631
2802
|
const balance = await this.balance();
|
|
2632
2803
|
this.emitBalanceChange(asset, sendAmount, "send", gasResult.digest);
|
|
2633
2804
|
return {
|
|
@@ -2683,6 +2854,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2683
2854
|
}
|
|
2684
2855
|
// -- Savings --
|
|
2685
2856
|
async save(params) {
|
|
2857
|
+
this.enforcer.assertNotLocked();
|
|
2686
2858
|
const asset = "USDC";
|
|
2687
2859
|
const bal = await queryBalance(this.client, this._address);
|
|
2688
2860
|
const usdcBalance = bal.stables.USDC ?? 0;
|
|
@@ -2777,6 +2949,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2777
2949
|
};
|
|
2778
2950
|
}
|
|
2779
2951
|
async withdraw(params) {
|
|
2952
|
+
this.enforcer.assertNotLocked();
|
|
2780
2953
|
if (params.amount === "all" && !params.protocol) {
|
|
2781
2954
|
return this.withdrawAllProtocols();
|
|
2782
2955
|
}
|
|
@@ -3014,6 +3187,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3014
3187
|
}
|
|
3015
3188
|
// -- Borrowing --
|
|
3016
3189
|
async borrow(params) {
|
|
3190
|
+
this.enforcer.assertNotLocked();
|
|
3017
3191
|
const asset = "USDC";
|
|
3018
3192
|
const adapter = await this.resolveLending(params.protocol, asset, "borrow");
|
|
3019
3193
|
const maxResult = await adapter.maxBorrow(this._address, asset);
|
|
@@ -3046,6 +3220,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3046
3220
|
};
|
|
3047
3221
|
}
|
|
3048
3222
|
async repay(params) {
|
|
3223
|
+
this.enforcer.assertNotLocked();
|
|
3049
3224
|
const allPositions = await this.registry.allPositions(this._address);
|
|
3050
3225
|
const borrows = [];
|
|
3051
3226
|
for (const pos of allPositions) {
|
|
@@ -3199,6 +3374,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3199
3374
|
}
|
|
3200
3375
|
// -- Exchange --
|
|
3201
3376
|
async exchange(params) {
|
|
3377
|
+
this.enforcer.assertNotLocked();
|
|
3202
3378
|
const fromAsset = params.from;
|
|
3203
3379
|
const toAsset = params.to;
|
|
3204
3380
|
if (!(fromAsset in SUPPORTED_ASSETS) || !(toAsset in SUPPORTED_ASSETS)) {
|
|
@@ -3299,6 +3475,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3299
3475
|
return this.registry.allRatesAcrossAssets();
|
|
3300
3476
|
}
|
|
3301
3477
|
async rebalance(opts = {}) {
|
|
3478
|
+
this.enforcer.assertNotLocked();
|
|
3302
3479
|
const dryRun = opts.dryRun ?? false;
|
|
3303
3480
|
const minYieldDiff = opts.minYieldDiff ?? 0.5;
|
|
3304
3481
|
const maxBreakEven = opts.maxBreakEven ?? 30;
|
|
@@ -3580,6 +3757,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3580
3757
|
return getSentinelInfo(this.client, id);
|
|
3581
3758
|
}
|
|
3582
3759
|
async sentinelAttack(id, prompt, fee) {
|
|
3760
|
+
this.enforcer.check({ operation: "sentinel", amount: fee ? Number(fee) / 1e9 : 0.1 });
|
|
3583
3761
|
return attack(this.client, this.keypair, id, prompt, fee);
|
|
3584
3762
|
}
|
|
3585
3763
|
// -- Helpers --
|
|
@@ -3731,6 +3909,6 @@ var allDescriptors = [
|
|
|
3731
3909
|
descriptor
|
|
3732
3910
|
];
|
|
3733
3911
|
|
|
3734
|
-
export { BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, DEFAULT_NETWORK, MIST_PER_SUI, NaviAdapter, ProtocolRegistry, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, SuilendAdapter, T2000, T2000Error, USDC_DECIMALS, addCollectFeeToTx, allDescriptors, calculateFee, descriptor3 as cetusDescriptor, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, getSentinelInfo, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, descriptor2 as naviDescriptor, rawToStable, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, descriptor as sentinelDescriptor, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, submitPrompt, suiToMist, descriptor4 as suilendDescriptor, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
|
3912
|
+
export { BPS_DENOMINATOR, CLOCK_ID, CetusAdapter, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, MIST_PER_SUI, NaviAdapter, OUTBOUND_OPS, ProtocolRegistry, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, SuilendAdapter, T2000, T2000Error, USDC_DECIMALS, addCollectFeeToTx, allDescriptors, calculateFee, descriptor3 as cetusDescriptor, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getDecimals, getGasStatus, getPoolPrice, getRates, getSentinelInfo, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, descriptor2 as naviDescriptor, rawToStable, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, descriptor as sentinelDescriptor, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, stableToRaw, submitPrompt, suiToMist, descriptor4 as suilendDescriptor, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
|
|
3735
3913
|
//# sourceMappingURL=index.js.map
|
|
3736
3914
|
//# sourceMappingURL=index.js.map
|