@t2000/sdk 0.10.3 → 0.11.0
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 +20 -4
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/index.cjs +184 -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 +182 -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,177 @@ 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
|
+
if (this.config.locked) {
|
|
2609
|
+
throw new SafeguardError("locked", {});
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
check(metadata) {
|
|
2613
|
+
this.assertNotLocked();
|
|
2614
|
+
if (!OUTBOUND_OPS.has(metadata.operation)) return;
|
|
2615
|
+
const amount = metadata.amount ?? 0;
|
|
2616
|
+
if (this.config.maxPerTx > 0 && amount > this.config.maxPerTx) {
|
|
2617
|
+
throw new SafeguardError("maxPerTx", {
|
|
2618
|
+
attempted: amount,
|
|
2619
|
+
limit: this.config.maxPerTx
|
|
2620
|
+
});
|
|
2621
|
+
}
|
|
2622
|
+
this.resetDailyIfNewDay();
|
|
2623
|
+
if (this.config.maxDailySend > 0 && this.config.dailyUsed + amount > this.config.maxDailySend) {
|
|
2624
|
+
throw new SafeguardError("maxDailySend", {
|
|
2625
|
+
attempted: amount,
|
|
2626
|
+
limit: this.config.maxDailySend,
|
|
2627
|
+
current: this.config.dailyUsed
|
|
2628
|
+
});
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
recordUsage(amount) {
|
|
2632
|
+
this.resetDailyIfNewDay();
|
|
2633
|
+
this.config.dailyUsed += amount;
|
|
2634
|
+
this.save();
|
|
2635
|
+
}
|
|
2636
|
+
lock() {
|
|
2637
|
+
this.config.locked = true;
|
|
2638
|
+
this.save();
|
|
2639
|
+
}
|
|
2640
|
+
unlock() {
|
|
2641
|
+
this.config.locked = false;
|
|
2642
|
+
this.save();
|
|
2643
|
+
}
|
|
2644
|
+
set(key, value) {
|
|
2645
|
+
if (key === "locked" && typeof value === "boolean") {
|
|
2646
|
+
this.config.locked = value;
|
|
2647
|
+
} else if (key === "maxPerTx" && typeof value === "number") {
|
|
2648
|
+
this.config.maxPerTx = value;
|
|
2649
|
+
} else if (key === "maxDailySend" && typeof value === "number") {
|
|
2650
|
+
this.config.maxDailySend = value;
|
|
2651
|
+
}
|
|
2652
|
+
this.save();
|
|
2653
|
+
}
|
|
2654
|
+
getConfig() {
|
|
2655
|
+
this.resetDailyIfNewDay();
|
|
2656
|
+
return { ...this.config };
|
|
2657
|
+
}
|
|
2658
|
+
isConfigured() {
|
|
2659
|
+
return this.config.maxPerTx > 0 || this.config.maxDailySend > 0;
|
|
2660
|
+
}
|
|
2661
|
+
resetDailyIfNewDay() {
|
|
2662
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
2663
|
+
if (this.config.dailyResetDate !== today) {
|
|
2664
|
+
this.config.dailyUsed = 0;
|
|
2665
|
+
this.config.dailyResetDate = today;
|
|
2666
|
+
this.save();
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
save() {
|
|
2670
|
+
if (!this.configPath) return;
|
|
2671
|
+
try {
|
|
2672
|
+
let existing = {};
|
|
2673
|
+
try {
|
|
2674
|
+
existing = JSON.parse(readFileSync(this.configPath, "utf-8"));
|
|
2675
|
+
} catch {
|
|
2676
|
+
}
|
|
2677
|
+
const merged = {
|
|
2678
|
+
...existing,
|
|
2679
|
+
locked: this.config.locked,
|
|
2680
|
+
maxPerTx: this.config.maxPerTx,
|
|
2681
|
+
maxDailySend: this.config.maxDailySend,
|
|
2682
|
+
dailyUsed: this.config.dailyUsed,
|
|
2683
|
+
dailyResetDate: this.config.dailyResetDate
|
|
2684
|
+
};
|
|
2685
|
+
const dir = this.configPath.replace(/[/\\][^/\\]+$/, "");
|
|
2686
|
+
if (!existsSync(dir)) {
|
|
2687
|
+
mkdirSync(dir, { recursive: true });
|
|
2688
|
+
}
|
|
2689
|
+
writeFileSync(this.configPath, JSON.stringify(merged, null, 2) + "\n");
|
|
2690
|
+
} catch {
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
};
|
|
2694
|
+
var DEFAULT_CONFIG_DIR = join(homedir(), ".t2000");
|
|
2535
2695
|
var T2000 = class _T2000 extends EventEmitter {
|
|
2536
2696
|
keypair;
|
|
2537
2697
|
client;
|
|
2538
2698
|
_address;
|
|
2539
2699
|
registry;
|
|
2540
|
-
|
|
2700
|
+
enforcer;
|
|
2701
|
+
constructor(keypair, client, registry, configDir) {
|
|
2541
2702
|
super();
|
|
2542
2703
|
this.keypair = keypair;
|
|
2543
2704
|
this.client = client;
|
|
2544
2705
|
this._address = getAddress(keypair);
|
|
2545
2706
|
this.registry = registry ?? _T2000.createDefaultRegistry(client);
|
|
2707
|
+
this.enforcer = new SafeguardEnforcer(configDir);
|
|
2708
|
+
this.enforcer.load();
|
|
2546
2709
|
}
|
|
2547
2710
|
static createDefaultRegistry(client) {
|
|
2548
2711
|
const registry = new ProtocolRegistry();
|
|
@@ -2566,7 +2729,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2566
2729
|
if (secret) {
|
|
2567
2730
|
await saveKey(keypair2, secret, keyPath);
|
|
2568
2731
|
}
|
|
2569
|
-
return new _T2000(keypair2, client);
|
|
2732
|
+
return new _T2000(keypair2, client, void 0, DEFAULT_CONFIG_DIR);
|
|
2570
2733
|
}
|
|
2571
2734
|
const exists = await walletExists(keyPath);
|
|
2572
2735
|
if (!exists) {
|
|
@@ -2579,7 +2742,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2579
2742
|
throw new T2000Error("WALLET_LOCKED", "PIN required to unlock wallet");
|
|
2580
2743
|
}
|
|
2581
2744
|
const keypair = await loadKey(secret, keyPath);
|
|
2582
|
-
return new _T2000(keypair, client);
|
|
2745
|
+
return new _T2000(keypair, client, void 0, DEFAULT_CONFIG_DIR);
|
|
2583
2746
|
}
|
|
2584
2747
|
static fromPrivateKey(privateKey, options = {}) {
|
|
2585
2748
|
const keypair = keypairFromPrivateKey(privateKey);
|
|
@@ -2591,7 +2754,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2591
2754
|
const keypair = generateKeypair();
|
|
2592
2755
|
await saveKey(keypair, secret, options.keyPath);
|
|
2593
2756
|
const client = getSuiClient();
|
|
2594
|
-
const agent = new _T2000(keypair, client);
|
|
2757
|
+
const agent = new _T2000(keypair, client, void 0, DEFAULT_CONFIG_DIR);
|
|
2595
2758
|
const address = agent.address();
|
|
2596
2759
|
let sponsored = false;
|
|
2597
2760
|
if (options.sponsored !== false) {
|
|
@@ -2617,6 +2780,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2617
2780
|
return this._address;
|
|
2618
2781
|
}
|
|
2619
2782
|
async send(params) {
|
|
2783
|
+
this.enforcer.assertNotLocked();
|
|
2620
2784
|
const asset = params.asset ?? "USDC";
|
|
2621
2785
|
if (!(asset in SUPPORTED_ASSETS)) {
|
|
2622
2786
|
throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
|
|
@@ -2626,8 +2790,10 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2626
2790
|
const gasResult = await executeWithGas(
|
|
2627
2791
|
this.client,
|
|
2628
2792
|
this.keypair,
|
|
2629
|
-
() => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset })
|
|
2793
|
+
() => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset }),
|
|
2794
|
+
{ metadata: { operation: "send", amount: sendAmount }, enforcer: this.enforcer }
|
|
2630
2795
|
);
|
|
2796
|
+
this.enforcer.recordUsage(sendAmount);
|
|
2631
2797
|
const balance = await this.balance();
|
|
2632
2798
|
this.emitBalanceChange(asset, sendAmount, "send", gasResult.digest);
|
|
2633
2799
|
return {
|
|
@@ -2683,6 +2849,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2683
2849
|
}
|
|
2684
2850
|
// -- Savings --
|
|
2685
2851
|
async save(params) {
|
|
2852
|
+
this.enforcer.assertNotLocked();
|
|
2686
2853
|
const asset = "USDC";
|
|
2687
2854
|
const bal = await queryBalance(this.client, this._address);
|
|
2688
2855
|
const usdcBalance = bal.stables.USDC ?? 0;
|
|
@@ -2777,6 +2944,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
2777
2944
|
};
|
|
2778
2945
|
}
|
|
2779
2946
|
async withdraw(params) {
|
|
2947
|
+
this.enforcer.assertNotLocked();
|
|
2780
2948
|
if (params.amount === "all" && !params.protocol) {
|
|
2781
2949
|
return this.withdrawAllProtocols();
|
|
2782
2950
|
}
|
|
@@ -3014,6 +3182,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3014
3182
|
}
|
|
3015
3183
|
// -- Borrowing --
|
|
3016
3184
|
async borrow(params) {
|
|
3185
|
+
this.enforcer.assertNotLocked();
|
|
3017
3186
|
const asset = "USDC";
|
|
3018
3187
|
const adapter = await this.resolveLending(params.protocol, asset, "borrow");
|
|
3019
3188
|
const maxResult = await adapter.maxBorrow(this._address, asset);
|
|
@@ -3046,6 +3215,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3046
3215
|
};
|
|
3047
3216
|
}
|
|
3048
3217
|
async repay(params) {
|
|
3218
|
+
this.enforcer.assertNotLocked();
|
|
3049
3219
|
const allPositions = await this.registry.allPositions(this._address);
|
|
3050
3220
|
const borrows = [];
|
|
3051
3221
|
for (const pos of allPositions) {
|
|
@@ -3199,6 +3369,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3199
3369
|
}
|
|
3200
3370
|
// -- Exchange --
|
|
3201
3371
|
async exchange(params) {
|
|
3372
|
+
this.enforcer.assertNotLocked();
|
|
3202
3373
|
const fromAsset = params.from;
|
|
3203
3374
|
const toAsset = params.to;
|
|
3204
3375
|
if (!(fromAsset in SUPPORTED_ASSETS) || !(toAsset in SUPPORTED_ASSETS)) {
|
|
@@ -3299,6 +3470,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3299
3470
|
return this.registry.allRatesAcrossAssets();
|
|
3300
3471
|
}
|
|
3301
3472
|
async rebalance(opts = {}) {
|
|
3473
|
+
this.enforcer.assertNotLocked();
|
|
3302
3474
|
const dryRun = opts.dryRun ?? false;
|
|
3303
3475
|
const minYieldDiff = opts.minYieldDiff ?? 0.5;
|
|
3304
3476
|
const maxBreakEven = opts.maxBreakEven ?? 30;
|
|
@@ -3580,6 +3752,7 @@ var T2000 = class _T2000 extends EventEmitter {
|
|
|
3580
3752
|
return getSentinelInfo(this.client, id);
|
|
3581
3753
|
}
|
|
3582
3754
|
async sentinelAttack(id, prompt, fee) {
|
|
3755
|
+
this.enforcer.check({ operation: "sentinel", amount: fee ? Number(fee) / 1e9 : 0.1 });
|
|
3583
3756
|
return attack(this.client, this.keypair, id, prompt, fee);
|
|
3584
3757
|
}
|
|
3585
3758
|
// -- Helpers --
|
|
@@ -3731,6 +3904,6 @@ var allDescriptors = [
|
|
|
3731
3904
|
descriptor
|
|
3732
3905
|
];
|
|
3733
3906
|
|
|
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 };
|
|
3907
|
+
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
3908
|
//# sourceMappingURL=index.js.map
|
|
3736
3909
|
//# sourceMappingURL=index.js.map
|