@t2000/sdk 0.2.5 → 0.2.7

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
@@ -142,8 +142,39 @@ interface TransactionRecord {
142
142
  timestamp: number;
143
143
  gasMethod?: GasMethod;
144
144
  }
145
+ interface SentinelAgent {
146
+ id: string;
147
+ objectId: string;
148
+ name: string;
149
+ model: string;
150
+ systemPrompt: string;
151
+ attackFee: bigint;
152
+ prizePool: bigint;
153
+ totalAttacks: number;
154
+ successfulBreaches: number;
155
+ state: string;
156
+ }
157
+ interface SentinelVerdict {
158
+ success: boolean;
159
+ score: number;
160
+ agentResponse: string;
161
+ juryResponse: string;
162
+ funResponse: string;
163
+ signature: string;
164
+ timestampMs: number;
165
+ }
166
+ interface SentinelAttackResult {
167
+ attackObjectId: string;
168
+ sentinelId: string;
169
+ prompt: string;
170
+ verdict: SentinelVerdict;
171
+ requestTx: string;
172
+ settleTx: string;
173
+ won: boolean;
174
+ feePaid: number;
175
+ }
145
176
 
146
- 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' | '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' | 'UNKNOWN';
177
+ 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' | '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';
147
178
  interface T2000ErrorData {
148
179
  reason?: string;
149
180
  [key: string]: unknown;
@@ -277,6 +308,9 @@ declare class T2000 extends EventEmitter<T2000Events> {
277
308
  rates(): Promise<RatesResult>;
278
309
  earnings(): Promise<EarningsResult>;
279
310
  fundStatus(): Promise<FundStatusResult>;
311
+ sentinelList(): Promise<SentinelAgent[]>;
312
+ sentinelInfo(id: string): Promise<SentinelAgent>;
313
+ sentinelAttack(id: string, prompt: string, fee?: bigint): Promise<SentinelAttackResult>;
280
314
  private emitBalanceChange;
281
315
  }
282
316
 
@@ -299,6 +333,17 @@ declare const SUPPORTED_ASSETS: {
299
333
  };
300
334
  type SupportedAsset = keyof typeof SUPPORTED_ASSETS;
301
335
  declare const DEFAULT_NETWORK: "mainnet";
336
+ declare const SENTINEL: {
337
+ readonly PACKAGE: "0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7";
338
+ readonly AGENT_REGISTRY: "0xc47564f5f14c12b31e0dfa1a3dc99a6380a1edf8929c28cb0eaa3359c8db36ac";
339
+ readonly ENCLAVE: "0xfb1261aeb9583514cb1341a548a5ec12d1231bd96af22215f1792617a93e1213";
340
+ readonly PROTOCOL_CONFIG: "0x2fa4fa4a1dd0498612304635ff9334e1b922e78af325000e9d9c0e88adea459f";
341
+ readonly TEE_API: "https://app.suisentinel.xyz/api/consume-prompt";
342
+ readonly SENTINELS_API: "https://api.suisentinel.xyz/agents/mainnet";
343
+ readonly RANDOM: "0x8";
344
+ readonly MIN_FEE_MIST: 100000000n;
345
+ readonly MAX_PROMPT_TOKENS: 600;
346
+ };
302
347
 
303
348
  declare function validateAddress(address: string): string;
304
349
  declare function truncateAddress(address: string): string;
@@ -351,6 +396,19 @@ declare function getSwapQuote(client: SuiClient, fromAsset: 'USDC' | 'SUI', toAs
351
396
 
352
397
  declare function getRates(client: SuiClient): Promise<RatesResult>;
353
398
 
399
+ declare function listSentinels(): Promise<SentinelAgent[]>;
400
+ declare function getSentinelInfo(client: SuiClient, sentinelObjectId: string): Promise<SentinelAgent>;
401
+ declare function requestAttack(client: SuiClient, signer: Ed25519Keypair, sentinelObjectId: string, feeMist: bigint): Promise<{
402
+ attackObjectId: string;
403
+ digest: string;
404
+ }>;
405
+ declare function submitPrompt(agentId: string, attackObjectId: string, prompt: string): Promise<SentinelVerdict>;
406
+ declare function settleAttack(client: SuiClient, signer: Ed25519Keypair, sentinelObjectId: string, attackObjectId: string, prompt: string, verdict: SentinelVerdict): Promise<{
407
+ digest: string;
408
+ success: boolean;
409
+ }>;
410
+ declare function attack(client: SuiClient, signer: Ed25519Keypair, sentinelId: string, prompt: string, feeMist?: bigint): Promise<SentinelAttackResult>;
411
+
354
412
  interface GasExecutionResult {
355
413
  digest: string;
356
414
  effects: unknown;
@@ -390,4 +448,4 @@ interface GasStatusResponse {
390
448
  }
391
449
  declare function getGasStatus(address?: string): Promise<GasStatusResponse>;
392
450
 
393
- export { type AutoTopUpResult, BPS_DENOMINATOR, type BalanceResponse, type BorrowResult, CLOCK_ID, DEFAULT_NETWORK, type DepositInfo, type EarningsResult, type FeeOperation, type FundStatusResult, type GasExecutionResult, type GasMethod, type GasRequestType, type GasReserve, type GasSponsorResponse, type GasStatusResponse, type HealthFactorResult, MIST_PER_SUI, type MaxBorrowResult, type MaxWithdrawResult, type PositionEntry, type PositionsResult, type ProtocolFeeInfo, type RatesResult, type RepayResult, SUI_DECIMALS, SUPPORTED_ASSETS, type SaveResult, type SendResult, type SimulationResult, type SupportedAsset, type SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, type T2000Options, type TransactionRecord, USDC_DECIMALS, type WithdrawResult, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getGasStatus, getPoolPrice, getRates, getSwapQuote, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
451
+ export { type AutoTopUpResult, BPS_DENOMINATOR, type BalanceResponse, type BorrowResult, CLOCK_ID, DEFAULT_NETWORK, type DepositInfo, type EarningsResult, type FeeOperation, type FundStatusResult, type GasExecutionResult, type GasMethod, type GasRequestType, type GasReserve, type GasSponsorResponse, type GasStatusResponse, type HealthFactorResult, MIST_PER_SUI, type MaxBorrowResult, type MaxWithdrawResult, type PositionEntry, type PositionsResult, type ProtocolFeeInfo, type RatesResult, type RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SaveResult, type SendResult, type SentinelAgent, type SentinelAttackResult, type SentinelVerdict, type SimulationResult, type SupportedAsset, type SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, type T2000Options, type TransactionRecord, USDC_DECIMALS, type WithdrawResult, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getGasStatus, getPoolPrice, getRates, getSentinelInfo, getSwapQuote, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, submitPrompt, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
package/dist/index.d.ts CHANGED
@@ -142,8 +142,39 @@ interface TransactionRecord {
142
142
  timestamp: number;
143
143
  gasMethod?: GasMethod;
144
144
  }
145
+ interface SentinelAgent {
146
+ id: string;
147
+ objectId: string;
148
+ name: string;
149
+ model: string;
150
+ systemPrompt: string;
151
+ attackFee: bigint;
152
+ prizePool: bigint;
153
+ totalAttacks: number;
154
+ successfulBreaches: number;
155
+ state: string;
156
+ }
157
+ interface SentinelVerdict {
158
+ success: boolean;
159
+ score: number;
160
+ agentResponse: string;
161
+ juryResponse: string;
162
+ funResponse: string;
163
+ signature: string;
164
+ timestampMs: number;
165
+ }
166
+ interface SentinelAttackResult {
167
+ attackObjectId: string;
168
+ sentinelId: string;
169
+ prompt: string;
170
+ verdict: SentinelVerdict;
171
+ requestTx: string;
172
+ settleTx: string;
173
+ won: boolean;
174
+ feePaid: number;
175
+ }
145
176
 
146
- 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' | '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' | 'UNKNOWN';
177
+ 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' | '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';
147
178
  interface T2000ErrorData {
148
179
  reason?: string;
149
180
  [key: string]: unknown;
@@ -277,6 +308,9 @@ declare class T2000 extends EventEmitter<T2000Events> {
277
308
  rates(): Promise<RatesResult>;
278
309
  earnings(): Promise<EarningsResult>;
279
310
  fundStatus(): Promise<FundStatusResult>;
311
+ sentinelList(): Promise<SentinelAgent[]>;
312
+ sentinelInfo(id: string): Promise<SentinelAgent>;
313
+ sentinelAttack(id: string, prompt: string, fee?: bigint): Promise<SentinelAttackResult>;
280
314
  private emitBalanceChange;
281
315
  }
282
316
 
@@ -299,6 +333,17 @@ declare const SUPPORTED_ASSETS: {
299
333
  };
300
334
  type SupportedAsset = keyof typeof SUPPORTED_ASSETS;
301
335
  declare const DEFAULT_NETWORK: "mainnet";
336
+ declare const SENTINEL: {
337
+ readonly PACKAGE: "0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7";
338
+ readonly AGENT_REGISTRY: "0xc47564f5f14c12b31e0dfa1a3dc99a6380a1edf8929c28cb0eaa3359c8db36ac";
339
+ readonly ENCLAVE: "0xfb1261aeb9583514cb1341a548a5ec12d1231bd96af22215f1792617a93e1213";
340
+ readonly PROTOCOL_CONFIG: "0x2fa4fa4a1dd0498612304635ff9334e1b922e78af325000e9d9c0e88adea459f";
341
+ readonly TEE_API: "https://app.suisentinel.xyz/api/consume-prompt";
342
+ readonly SENTINELS_API: "https://api.suisentinel.xyz/agents/mainnet";
343
+ readonly RANDOM: "0x8";
344
+ readonly MIN_FEE_MIST: 100000000n;
345
+ readonly MAX_PROMPT_TOKENS: 600;
346
+ };
302
347
 
303
348
  declare function validateAddress(address: string): string;
304
349
  declare function truncateAddress(address: string): string;
@@ -351,6 +396,19 @@ declare function getSwapQuote(client: SuiClient, fromAsset: 'USDC' | 'SUI', toAs
351
396
 
352
397
  declare function getRates(client: SuiClient): Promise<RatesResult>;
353
398
 
399
+ declare function listSentinels(): Promise<SentinelAgent[]>;
400
+ declare function getSentinelInfo(client: SuiClient, sentinelObjectId: string): Promise<SentinelAgent>;
401
+ declare function requestAttack(client: SuiClient, signer: Ed25519Keypair, sentinelObjectId: string, feeMist: bigint): Promise<{
402
+ attackObjectId: string;
403
+ digest: string;
404
+ }>;
405
+ declare function submitPrompt(agentId: string, attackObjectId: string, prompt: string): Promise<SentinelVerdict>;
406
+ declare function settleAttack(client: SuiClient, signer: Ed25519Keypair, sentinelObjectId: string, attackObjectId: string, prompt: string, verdict: SentinelVerdict): Promise<{
407
+ digest: string;
408
+ success: boolean;
409
+ }>;
410
+ declare function attack(client: SuiClient, signer: Ed25519Keypair, sentinelId: string, prompt: string, feeMist?: bigint): Promise<SentinelAttackResult>;
411
+
354
412
  interface GasExecutionResult {
355
413
  digest: string;
356
414
  effects: unknown;
@@ -390,4 +448,4 @@ interface GasStatusResponse {
390
448
  }
391
449
  declare function getGasStatus(address?: string): Promise<GasStatusResponse>;
392
450
 
393
- export { type AutoTopUpResult, BPS_DENOMINATOR, type BalanceResponse, type BorrowResult, CLOCK_ID, DEFAULT_NETWORK, type DepositInfo, type EarningsResult, type FeeOperation, type FundStatusResult, type GasExecutionResult, type GasMethod, type GasRequestType, type GasReserve, type GasSponsorResponse, type GasStatusResponse, type HealthFactorResult, MIST_PER_SUI, type MaxBorrowResult, type MaxWithdrawResult, type PositionEntry, type PositionsResult, type ProtocolFeeInfo, type RatesResult, type RepayResult, SUI_DECIMALS, SUPPORTED_ASSETS, type SaveResult, type SendResult, type SimulationResult, type SupportedAsset, type SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, type T2000Options, type TransactionRecord, USDC_DECIMALS, type WithdrawResult, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getGasStatus, getPoolPrice, getRates, getSwapQuote, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
451
+ export { type AutoTopUpResult, BPS_DENOMINATOR, type BalanceResponse, type BorrowResult, CLOCK_ID, DEFAULT_NETWORK, type DepositInfo, type EarningsResult, type FeeOperation, type FundStatusResult, type GasExecutionResult, type GasMethod, type GasRequestType, type GasReserve, type GasSponsorResponse, type GasStatusResponse, type HealthFactorResult, MIST_PER_SUI, type MaxBorrowResult, type MaxWithdrawResult, type PositionEntry, type PositionsResult, type ProtocolFeeInfo, type RatesResult, type RepayResult, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, type SaveResult, type SendResult, type SentinelAgent, type SentinelAttackResult, type SentinelVerdict, type SimulationResult, type SupportedAsset, type SwapResult, T2000, T2000Error, type T2000ErrorCode, type T2000ErrorData, type T2000Options, type TransactionRecord, USDC_DECIMALS, type WithdrawResult, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getGasStatus, getPoolPrice, getRates, getSentinelInfo, getSwapQuote, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, submitPrompt, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ import { homedir } from 'os';
10
10
  import { Transaction } from '@mysten/sui/transactions';
11
11
  import { getPool, getCoins, mergeCoinsPTB, depositCoinPTB, getLendingState, withdrawCoinPTB, borrowCoinPTB, getHealthFactor as getHealthFactor$1, repayCoinPTB, getPriceFeeds, filterPriceFeeds, updateOraclePricesPTB } from '@naviprotocol/lending';
12
12
  import { CetusClmmSDK } from '@cetusprotocol/sui-clmm-sdk';
13
+ import { bcs } from '@mysten/sui/bcs';
13
14
 
14
15
  // src/t2000.ts
15
16
 
@@ -45,6 +46,18 @@ var DEFAULT_RPC_URL = "https://fullnode.mainnet.sui.io:443";
45
46
  var DEFAULT_KEY_PATH = "~/.t2000/wallet.key";
46
47
  var API_BASE_URL = process.env.T2000_API_URL ?? "https://api.t2000.ai";
47
48
  var CETUS_USDC_SUI_POOL = "0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab";
49
+ var SENTINEL = {
50
+ PACKAGE: "0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7",
51
+ AGENT_REGISTRY: "0xc47564f5f14c12b31e0dfa1a3dc99a6380a1edf8929c28cb0eaa3359c8db36ac",
52
+ ENCLAVE: "0xfb1261aeb9583514cb1341a548a5ec12d1231bd96af22215f1792617a93e1213",
53
+ PROTOCOL_CONFIG: "0x2fa4fa4a1dd0498612304635ff9334e1b922e78af325000e9d9c0e88adea459f",
54
+ TEE_API: "https://app.suisentinel.xyz/api/consume-prompt",
55
+ SENTINELS_API: "https://api.suisentinel.xyz/agents/mainnet",
56
+ RANDOM: "0x8",
57
+ MIN_FEE_MIST: 100000000n,
58
+ // 0.1 SUI
59
+ MAX_PROMPT_TOKENS: 600
60
+ };
48
61
 
49
62
  // src/errors.ts
50
63
  var T2000Error = class extends Error {
@@ -699,6 +712,190 @@ async function getFundStatus(client, keypair) {
699
712
  projectedMonthly: earnings.dailyEarning * 30
700
713
  };
701
714
  }
715
+ function mapAgent(raw) {
716
+ return {
717
+ id: raw.agent_id,
718
+ objectId: raw.agent_object_id,
719
+ name: raw.agent_name,
720
+ model: raw.model ?? "unknown",
721
+ systemPrompt: raw.prompt,
722
+ attackFee: BigInt(raw.cost_per_message),
723
+ prizePool: BigInt(raw.total_balance),
724
+ totalAttacks: raw.total_attacks,
725
+ successfulBreaches: raw.successful_breaches ?? 0,
726
+ state: raw.state
727
+ };
728
+ }
729
+ async function listSentinels() {
730
+ const res = await fetch(SENTINEL.SENTINELS_API);
731
+ if (!res.ok) {
732
+ throw new T2000Error("SENTINEL_API_ERROR", `Sentinel API returned ${res.status}`);
733
+ }
734
+ const data = await res.json();
735
+ if (!Array.isArray(data.agents)) {
736
+ throw new T2000Error("SENTINEL_API_ERROR", "Unexpected API response shape");
737
+ }
738
+ return data.agents.filter((a) => a.state === "active").map(mapAgent);
739
+ }
740
+ async function getSentinelInfo(client, sentinelObjectId) {
741
+ const agents = await listSentinels();
742
+ const match = agents.find((a) => a.objectId === sentinelObjectId || a.id === sentinelObjectId);
743
+ if (match) return match;
744
+ const obj = await client.getObject({
745
+ id: sentinelObjectId,
746
+ options: { showContent: true, showType: true }
747
+ });
748
+ if (!obj.data) {
749
+ throw new T2000Error("SENTINEL_NOT_FOUND", `Sentinel ${sentinelObjectId} not found on-chain`);
750
+ }
751
+ const content = obj.data.content;
752
+ if (!content || content.dataType !== "moveObject") {
753
+ throw new T2000Error("SENTINEL_NOT_FOUND", `Object ${sentinelObjectId} is not a Move object`);
754
+ }
755
+ const fields = content.fields;
756
+ return {
757
+ id: fields.id?.id ?? sentinelObjectId,
758
+ objectId: sentinelObjectId,
759
+ name: fields.name ?? "Unknown",
760
+ model: fields.model ?? "unknown",
761
+ systemPrompt: fields.system_prompt ?? "",
762
+ attackFee: BigInt(fields.cost_per_message ?? "0"),
763
+ prizePool: BigInt(fields.balance ?? "0"),
764
+ totalAttacks: Number(fields.total_attacks ?? "0"),
765
+ successfulBreaches: Number(fields.successful_breaches ?? "0"),
766
+ state: fields.state ?? "unknown"
767
+ };
768
+ }
769
+ async function requestAttack(client, signer, sentinelObjectId, feeMist) {
770
+ if (feeMist < SENTINEL.MIN_FEE_MIST) {
771
+ throw new T2000Error("INVALID_AMOUNT", `Attack fee must be at least 0.1 SUI (${SENTINEL.MIN_FEE_MIST} MIST)`);
772
+ }
773
+ const tx = new Transaction();
774
+ const [coin] = tx.splitCoins(tx.gas, [Number(feeMist)]);
775
+ const [attack2] = tx.moveCall({
776
+ target: `${SENTINEL.PACKAGE}::sentinel::request_attack`,
777
+ arguments: [
778
+ tx.object(SENTINEL.AGENT_REGISTRY),
779
+ tx.object(sentinelObjectId),
780
+ tx.object(SENTINEL.PROTOCOL_CONFIG),
781
+ coin,
782
+ tx.object(SENTINEL.RANDOM),
783
+ tx.object(CLOCK_ID)
784
+ ]
785
+ });
786
+ const address = signer.toSuiAddress();
787
+ tx.transferObjects([attack2], address);
788
+ const result = await client.signAndExecuteTransaction({
789
+ signer,
790
+ transaction: tx,
791
+ options: { showObjectChanges: true, showEffects: true }
792
+ });
793
+ await client.waitForTransaction({ digest: result.digest });
794
+ const attackObj = result.objectChanges?.find(
795
+ (c) => c.type === "created" && c.objectType?.includes("::sentinel::Attack")
796
+ );
797
+ const attackObjectId = attackObj && "objectId" in attackObj ? attackObj.objectId : void 0;
798
+ if (!attackObjectId) {
799
+ throw new T2000Error("SENTINEL_TX_FAILED", "Attack object was not created \u2014 transaction may have failed");
800
+ }
801
+ return { attackObjectId, digest: result.digest };
802
+ }
803
+ async function submitPrompt(agentId, attackObjectId, prompt) {
804
+ const res = await fetch(SENTINEL.TEE_API, {
805
+ method: "POST",
806
+ headers: { "Content-Type": "application/json" },
807
+ body: JSON.stringify({
808
+ agent_id: agentId,
809
+ attack_object_id: attackObjectId,
810
+ message: prompt
811
+ })
812
+ });
813
+ if (!res.ok) {
814
+ const body = await res.text().catch(() => "");
815
+ throw new T2000Error("SENTINEL_TEE_ERROR", `TEE returned ${res.status}: ${body.slice(0, 200)}`);
816
+ }
817
+ const raw = await res.json();
818
+ const envelope = raw.response ?? raw;
819
+ const data = envelope.data ?? envelope;
820
+ const signature = raw.signature ?? data.signature;
821
+ const timestampMs = envelope.timestamp_ms ?? data.timestamp_ms;
822
+ if (typeof signature !== "string") {
823
+ throw new T2000Error("SENTINEL_TEE_ERROR", "TEE response missing signature");
824
+ }
825
+ return {
826
+ success: data.success ?? data.is_success,
827
+ score: data.score,
828
+ agentResponse: data.agent_response,
829
+ juryResponse: data.jury_response,
830
+ funResponse: data.fun_response ?? "",
831
+ signature,
832
+ timestampMs
833
+ };
834
+ }
835
+ async function settleAttack(client, signer, sentinelObjectId, attackObjectId, prompt, verdict) {
836
+ const sigBytes = Array.from(Buffer.from(verdict.signature.replace(/^0x/, ""), "hex"));
837
+ const tx = new Transaction();
838
+ tx.moveCall({
839
+ target: `${SENTINEL.PACKAGE}::sentinel::consume_prompt`,
840
+ arguments: [
841
+ tx.object(SENTINEL.AGENT_REGISTRY),
842
+ tx.object(SENTINEL.PROTOCOL_CONFIG),
843
+ tx.object(sentinelObjectId),
844
+ tx.pure.bool(verdict.success),
845
+ tx.pure.string(verdict.agentResponse),
846
+ tx.pure.string(verdict.juryResponse),
847
+ tx.pure.string(verdict.funResponse),
848
+ tx.pure.string(prompt),
849
+ tx.pure.u8(verdict.score),
850
+ tx.pure.u64(verdict.timestampMs),
851
+ tx.pure(bcs.vector(bcs.u8()).serialize(sigBytes)),
852
+ tx.object(SENTINEL.ENCLAVE),
853
+ tx.object(attackObjectId),
854
+ tx.object(CLOCK_ID)
855
+ ]
856
+ });
857
+ const result = await client.signAndExecuteTransaction({
858
+ signer,
859
+ transaction: tx,
860
+ options: { showEffects: true }
861
+ });
862
+ await client.waitForTransaction({ digest: result.digest });
863
+ const txSuccess = result.effects?.status?.status === "success";
864
+ return { digest: result.digest, success: txSuccess };
865
+ }
866
+ async function attack(client, signer, sentinelId, prompt, feeMist) {
867
+ const sentinel = await getSentinelInfo(client, sentinelId);
868
+ const fee = feeMist ?? sentinel.attackFee;
869
+ if (fee < SENTINEL.MIN_FEE_MIST) {
870
+ throw new T2000Error("INVALID_AMOUNT", `Attack fee must be at least 0.1 SUI`);
871
+ }
872
+ const { attackObjectId, digest: requestTx } = await requestAttack(
873
+ client,
874
+ signer,
875
+ sentinel.objectId,
876
+ fee
877
+ );
878
+ const verdict = await submitPrompt(sentinel.id, attackObjectId, prompt);
879
+ const { digest: settleTx } = await settleAttack(
880
+ client,
881
+ signer,
882
+ sentinel.objectId,
883
+ attackObjectId,
884
+ prompt,
885
+ verdict
886
+ );
887
+ const won = verdict.success && verdict.score >= 70;
888
+ return {
889
+ attackObjectId,
890
+ sentinelId: sentinel.id,
891
+ prompt,
892
+ verdict,
893
+ requestTx,
894
+ settleTx,
895
+ won,
896
+ feePaid: Number(fee) / Number(MIST_PER_SUI)
897
+ };
898
+ }
702
899
  function hasLeadingZeroBits(hash, bits) {
703
900
  const fullBytes = Math.floor(bits / 8);
704
901
  const remainingBits = bits % 8;
@@ -1316,6 +1513,16 @@ var T2000 = class _T2000 extends EventEmitter {
1316
1513
  async fundStatus() {
1317
1514
  return getFundStatus(this.client, this.keypair);
1318
1515
  }
1516
+ // -- Sentinel --
1517
+ async sentinelList() {
1518
+ return listSentinels();
1519
+ }
1520
+ async sentinelInfo(id) {
1521
+ return getSentinelInfo(this.client, id);
1522
+ }
1523
+ async sentinelAttack(id, prompt, fee) {
1524
+ return attack(this.client, this.keypair, id, prompt, fee);
1525
+ }
1319
1526
  // -- Helpers --
1320
1527
  emitBalanceChange(asset, amount, cause, tx) {
1321
1528
  this.emit("balanceChange", { asset, previous: 0, current: 0, cause, tx });
@@ -1415,6 +1622,6 @@ function parseMoveAbort(errorStr) {
1415
1622
  return { reason: errorStr };
1416
1623
  }
1417
1624
 
1418
- export { BPS_DENOMINATOR, CLOCK_ID, DEFAULT_NETWORK, MIST_PER_SUI, SUI_DECIMALS, SUPPORTED_ASSETS, T2000, T2000Error, USDC_DECIMALS, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getGasStatus, getPoolPrice, getRates, getSwapQuote, keypairFromPrivateKey, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToUsdc, saveKey, shouldAutoTopUp, simulateTransaction, solveHashcash, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
1625
+ export { BPS_DENOMINATOR, CLOCK_ID, DEFAULT_NETWORK, MIST_PER_SUI, SENTINEL, SUI_DECIMALS, SUPPORTED_ASSETS, T2000, T2000Error, USDC_DECIMALS, calculateFee, executeAutoTopUp, executeWithGas, exportPrivateKey, formatSui, formatUsd, generateKeypair, getAddress, getGasStatus, getPoolPrice, getRates, getSentinelInfo, getSwapQuote, keypairFromPrivateKey, listSentinels, loadKey, mapMoveAbortCode, mapWalletError, mistToSui, rawToUsdc, requestAttack, saveKey, attack as sentinelAttack, settleAttack, shouldAutoTopUp, simulateTransaction, solveHashcash, submitPrompt, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, walletExists };
1419
1626
  //# sourceMappingURL=index.js.map
1420
1627
  //# sourceMappingURL=index.js.map