@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/README.md CHANGED
@@ -24,7 +24,10 @@ yarn add @t2000/sdk
24
24
  ```typescript
25
25
  import { T2000 } from '@t2000/sdk';
26
26
 
27
- // Create or load a bank account
27
+ // Create a new bank account
28
+ const { agent, address } = await T2000.init({ pin: 'my-secret' });
29
+
30
+ // Or load an existing one
28
31
  const agent = await T2000.create({ pin: 'my-secret' });
29
32
 
30
33
  // Check balance
@@ -46,30 +49,53 @@ await agent.borrow({ amount: 20, asset: 'USDC' });
46
49
 
47
50
  ## API Reference
48
51
 
49
- ### `T2000.create(options)`
52
+ ### `T2000.init(options)` — Create a new wallet
53
+
54
+ Creates a new bank account (generates keypair, encrypts, and saves to disk).
55
+
56
+ ```typescript
57
+ const { agent, address, sponsored } = await T2000.init({
58
+ pin: 'my-secret', // Required — encrypts the key
59
+ keyPath: '~/.t2000/wallet.key', // Optional — custom key file path
60
+ name: 'my-agent', // Optional — agent name for sponsor registration
61
+ sponsored: true, // Optional — register with gas station (default: true)
62
+ });
63
+ ```
64
+
65
+ ### `T2000.create(options)` — Load an existing wallet
50
66
 
51
- Creates a new bank account or loads an existing one.
67
+ Loads an existing bank account from an encrypted key file. Throws `WALLET_NOT_FOUND` if no wallet exists.
52
68
 
53
69
  ```typescript
54
70
  const agent = await T2000.create({
55
- pin: 'my-secret', // Required — encrypts/decrypts the key
56
- network: 'mainnet', // 'mainnet' | 'testnet' (default: 'mainnet')
57
- rpcUrl: 'https://...', // Custom RPC endpoint (optional)
58
- keyPath: '~/.t2000/wallet.key', // Custom key file path (optional)
71
+ pin: 'my-secret', // Required — decrypts the key
72
+ keyPath: '~/.t2000/wallet.key', // Optional custom key file path
73
+ rpcUrl: 'https://...', // Optional — custom Sui RPC endpoint
59
74
  });
60
75
  ```
61
76
 
77
+ ### `T2000.fromPrivateKey(key, options?)` — Load from raw key
78
+
79
+ Synchronous factory that creates an agent from a raw private key (bech32 `suiprivkey1...` or hex).
80
+
81
+ ```typescript
82
+ const agent = T2000.fromPrivateKey('suiprivkey1q...');
83
+ ```
84
+
62
85
  ### Core Methods
63
86
 
64
87
  | Method | Description | Returns |
65
88
  |--------|-------------|---------|
89
+ | `agent.address()` | Wallet Sui address | `string` |
66
90
  | `agent.balance()` | Available USDC + savings + gas reserve | `BalanceResponse` |
67
- | `agent.send({ to, amount })` | Transfer USDC to any Sui address | `SendResult` |
68
- | `agent.save({ amount, asset: 'USDC' })` | Deposit USDC to NAVI Protocol (earn APY) | `SaveResult` |
69
- | `agent.withdraw({ amount, asset: 'USDC' })` | Withdraw USDC from savings | `WithdrawResult` |
70
- | `agent.swap({ from, to, amount })` | Swap via Cetus CLMM DEX | `SwapResult` |
71
- | `agent.borrow({ amount, asset: 'USDC' })` | Borrow USDC against collateral | `BorrowResult` |
72
- | `agent.repay({ amount, asset: 'USDC' })` | Repay outstanding borrows | `RepayResult` |
91
+ | `agent.send({ to, amount, asset? })` | Transfer USDC to any Sui address | `SendResult` |
92
+ | `agent.save({ amount, asset })` | Deposit USDC to NAVI Protocol (earn APY). `amount` can be `'all'`. | `SaveResult` |
93
+ | `agent.withdraw({ amount, asset })` | Withdraw USDC from savings. `amount` can be `'all'`. | `WithdrawResult` |
94
+ | `agent.swap({ from, to, amount, maxSlippage? })` | Swap via Cetus CLMM DEX. `maxSlippage` in % (default: 3). | `SwapResult` |
95
+ | `agent.swapQuote({ from, to, amount })` | Get swap quote without executing | `SwapQuote` |
96
+ | `agent.borrow({ amount, asset })` | Borrow USDC against collateral | `BorrowResult` |
97
+ | `agent.repay({ amount, asset })` | Repay outstanding borrows. `amount` can be `'all'`. | `RepayResult` |
98
+ | `agent.exportKey()` | Export private key (bech32 format) | `string` |
73
99
 
74
100
  ### Query Methods
75
101
 
@@ -83,7 +109,15 @@ const agent = await T2000.create({
83
109
  | `agent.maxWithdraw()` | Max safe withdrawal amount | `MaxWithdrawResult` |
84
110
  | `agent.maxBorrow()` | Max safe borrow amount | `MaxBorrowResult` |
85
111
  | `agent.deposit()` | Wallet address + funding instructions | `DepositInfo` |
86
- | `agent.history()` | Transaction history | `TransactionRecord[]` |
112
+ | `agent.history({ limit? })` | Transaction history (default: all) | `TransactionRecord[]` |
113
+
114
+ ### Sentinel Methods
115
+
116
+ | Method | Description | Returns |
117
+ |--------|-------------|---------|
118
+ | `agent.sentinelList()` | List active sentinels with prize pools | `SentinelAgent[]` |
119
+ | `agent.sentinelInfo(id)` | Get sentinel details (from API or on-chain) | `SentinelAgent` |
120
+ | `agent.sentinelAttack(id, prompt, fee?)` | Full attack flow: request → TEE → settle | `SentinelAttackResult` |
87
121
 
88
122
  ### Key Management
89
123
 
@@ -93,6 +127,9 @@ import {
93
127
  keypairFromPrivateKey,
94
128
  exportPrivateKey,
95
129
  getAddress,
130
+ saveKey,
131
+ loadKey,
132
+ walletExists,
96
133
  } from '@t2000/sdk';
97
134
 
98
135
  // Generate a new keypair
@@ -106,21 +143,44 @@ const privkey = exportPrivateKey(keypair);
106
143
 
107
144
  // Get the Sui address
108
145
  const address = getAddress(keypair);
146
+
147
+ // Check if wallet exists on disk
148
+ const exists = await walletExists();
149
+
150
+ // Save/load encrypted key
151
+ await saveKey(keypair, 'my-pin');
152
+ const loaded = await loadKey('my-pin');
109
153
  ```
110
154
 
111
155
  ### Events
112
156
 
113
157
  ```typescript
114
158
  agent.on('balanceChange', (e) => {
115
- console.log(`${e.cause}: ${e.asset} changed`);
159
+ console.log(`${e.cause}: ${e.asset} ${e.previous} → ${e.current}`);
116
160
  });
117
161
 
118
162
  agent.on('healthWarning', (e) => {
119
- console.log(`Health factor: ${e.healthFactor}`);
163
+ console.log(`Health factor: ${e.healthFactor} (warning)`);
164
+ });
165
+
166
+ agent.on('healthCritical', (e) => {
167
+ console.log(`Health factor: ${e.healthFactor} (critical — below 1.2)`);
120
168
  });
121
169
 
122
170
  agent.on('yield', (e) => {
123
- console.log(`Earned: $${e.earned}`);
171
+ console.log(`Earned: $${e.earned}, total: $${e.total}`);
172
+ });
173
+
174
+ agent.on('gasAutoTopUp', (e) => {
175
+ console.log(`Auto-topped up gas: $${e.usdcSpent} USDC → ${e.suiReceived} SUI`);
176
+ });
177
+
178
+ agent.on('gasStationFallback', (e) => {
179
+ console.log(`Gas station fallback: ${e.reason}`);
180
+ });
181
+
182
+ agent.on('error', (e) => {
183
+ console.error(`Error: ${e.code} — ${e.message}`);
124
184
  });
125
185
  ```
126
186
 
@@ -140,11 +200,20 @@ import {
140
200
 
141
201
  mistToSui(1_000_000_000n); // 1.0
142
202
  usdcToRaw(10.50); // 10_500_000n
143
- formatUsd(1234.5); // "$1,234.50"
144
- truncateAddress('0xabcd...1234'); // "0xabcd...1234"
203
+ formatUsd(1234.5); // "$1234.50"
204
+ truncateAddress('0xabcdef...1234'); // "0xabcd...1234"
145
205
  validateAddress('0x...'); // throws if invalid
146
206
  ```
147
207
 
208
+ ### Advanced: Exposed Internals
209
+
210
+ For integrations (like `@t2000/x402`), the agent exposes:
211
+
212
+ ```typescript
213
+ agent.suiClient; // SuiClient instance
214
+ agent.signer; // Ed25519Keypair
215
+ ```
216
+
148
217
  ## Gas Abstraction
149
218
 
150
219
  Every operation (send, save, borrow, repay, withdraw, swap) routes through a 3-step gas resolution chain via `executeWithGas()`. The agent never fails due to low gas if it has USDC or the Gas Station is reachable:
@@ -164,12 +233,10 @@ Every transaction result includes a `gasMethod` field (`'self-funded'` | `'auto-
164
233
 
165
234
  | Environment Variable | Description | Default |
166
235
  |---------------------|-------------|---------|
167
- | `T2000_PIN` | Bank account PIN | — |
168
- | `T2000_NETWORK` | `mainnet` or `testnet` | `mainnet` |
169
- | `T2000_RPC_URL` | Custom Sui RPC URL | Sui public fullnode |
170
- | `T2000_KEY_PATH` | Path to encrypted key file | `~/.t2000/wallet.key` |
171
236
  | `T2000_API_URL` | t2000 API base URL | `https://api.t2000.ai` |
172
237
 
238
+ Options like `pin`, `keyPath`, and `rpcUrl` are passed directly to `T2000.create()` or `T2000.init()`. The CLI handles env vars like `T2000_PIN` — see the [CLI README](https://www.npmjs.com/package/@t2000/cli).
239
+
173
240
  ## Supported Assets
174
241
 
175
242
  | Asset | Type | Decimals |
@@ -192,12 +259,12 @@ try {
192
259
  }
193
260
  ```
194
261
 
195
- Common error codes: `INSUFFICIENT_BALANCE` · `INVALID_ADDRESS` · `INVALID_AMOUNT` · `HEALTH_FACTOR_TOO_LOW` · `NO_COLLATERAL` · `WALLET_NOT_FOUND` · `SIMULATION_FAILED` · `TRANSACTION_FAILED` · `PROTOCOL_PAUSED` · `INSUFFICIENT_GAS` · `SLIPPAGE_EXCEEDED` · `ASSET_NOT_SUPPORTED` · `WITHDRAW_WOULD_LIQUIDATE`
262
+ Common error codes: `INSUFFICIENT_BALANCE` · `INVALID_ADDRESS` · `INVALID_AMOUNT` · `HEALTH_FACTOR_TOO_LOW` · `NO_COLLATERAL` · `WALLET_NOT_FOUND` · `WALLET_LOCKED` · `WALLET_EXISTS` · `SIMULATION_FAILED` · `TRANSACTION_FAILED` · `PROTOCOL_PAUSED` · `INSUFFICIENT_GAS` · `SLIPPAGE_EXCEEDED` · `ASSET_NOT_SUPPORTED` · `WITHDRAW_WOULD_LIQUIDATE` · `AUTO_TOPUP_FAILED` · `GAS_STATION_UNAVAILABLE`
196
263
 
197
264
  ## Testing
198
265
 
199
266
  ```bash
200
- # Run all SDK unit tests (92 tests)
267
+ # Run all SDK unit tests (122 tests)
201
268
  pnpm --filter @t2000/sdk test
202
269
  ```
203
270
 
@@ -210,6 +277,10 @@ pnpm --filter @t2000/sdk test
210
277
  | `keyManager.test.ts` | Key generation, encryption, decryption, import/export |
211
278
  | `errors.test.ts` | `T2000Error` construction, serialization, `mapWalletError`, `mapMoveAbortCode` |
212
279
  | `navi.test.ts` | NAVI math utilities (health factor, APY, position calculations) |
280
+ | `send.test.ts` | Send transaction building and validation |
281
+ | `manager.test.ts` | Gas resolution chain (self-fund, auto-topup, sponsored fallback) |
282
+ | `autoTopUp.test.ts` | Auto-topup threshold logic and swap execution |
283
+ | `serialization.test.ts` | Transaction JSON serialization roundtrip |
213
284
 
214
285
  ## Protocol Fees
215
286
 
package/dist/index.cjs CHANGED
@@ -12,6 +12,7 @@ var os = require('os');
12
12
  var transactions = require('@mysten/sui/transactions');
13
13
  var lending = require('@naviprotocol/lending');
14
14
  var suiClmmSdk = require('@cetusprotocol/sui-clmm-sdk');
15
+ var bcs = require('@mysten/sui/bcs');
15
16
 
16
17
  // src/t2000.ts
17
18
 
@@ -47,6 +48,18 @@ var DEFAULT_RPC_URL = "https://fullnode.mainnet.sui.io:443";
47
48
  var DEFAULT_KEY_PATH = "~/.t2000/wallet.key";
48
49
  var API_BASE_URL = process.env.T2000_API_URL ?? "https://api.t2000.ai";
49
50
  var CETUS_USDC_SUI_POOL = "0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab";
51
+ var SENTINEL = {
52
+ PACKAGE: "0x88b83f36dafcd5f6dcdcf1d2cb5889b03f61264ab3cee9cae35db7aa940a21b7",
53
+ AGENT_REGISTRY: "0xc47564f5f14c12b31e0dfa1a3dc99a6380a1edf8929c28cb0eaa3359c8db36ac",
54
+ ENCLAVE: "0xfb1261aeb9583514cb1341a548a5ec12d1231bd96af22215f1792617a93e1213",
55
+ PROTOCOL_CONFIG: "0x2fa4fa4a1dd0498612304635ff9334e1b922e78af325000e9d9c0e88adea459f",
56
+ TEE_API: "https://app.suisentinel.xyz/api/consume-prompt",
57
+ SENTINELS_API: "https://api.suisentinel.xyz/agents/mainnet",
58
+ RANDOM: "0x8",
59
+ MIN_FEE_MIST: 100000000n,
60
+ // 0.1 SUI
61
+ MAX_PROMPT_TOKENS: 600
62
+ };
50
63
 
51
64
  // src/errors.ts
52
65
  var T2000Error = class extends Error {
@@ -701,6 +714,190 @@ async function getFundStatus(client, keypair) {
701
714
  projectedMonthly: earnings.dailyEarning * 30
702
715
  };
703
716
  }
717
+ function mapAgent(raw) {
718
+ return {
719
+ id: raw.agent_id,
720
+ objectId: raw.agent_object_id,
721
+ name: raw.agent_name,
722
+ model: raw.model ?? "unknown",
723
+ systemPrompt: raw.prompt,
724
+ attackFee: BigInt(raw.cost_per_message),
725
+ prizePool: BigInt(raw.total_balance),
726
+ totalAttacks: raw.total_attacks,
727
+ successfulBreaches: raw.successful_breaches ?? 0,
728
+ state: raw.state
729
+ };
730
+ }
731
+ async function listSentinels() {
732
+ const res = await fetch(SENTINEL.SENTINELS_API);
733
+ if (!res.ok) {
734
+ throw new T2000Error("SENTINEL_API_ERROR", `Sentinel API returned ${res.status}`);
735
+ }
736
+ const data = await res.json();
737
+ if (!Array.isArray(data.agents)) {
738
+ throw new T2000Error("SENTINEL_API_ERROR", "Unexpected API response shape");
739
+ }
740
+ return data.agents.filter((a) => a.state === "active").map(mapAgent);
741
+ }
742
+ async function getSentinelInfo(client, sentinelObjectId) {
743
+ const agents = await listSentinels();
744
+ const match = agents.find((a) => a.objectId === sentinelObjectId || a.id === sentinelObjectId);
745
+ if (match) return match;
746
+ const obj = await client.getObject({
747
+ id: sentinelObjectId,
748
+ options: { showContent: true, showType: true }
749
+ });
750
+ if (!obj.data) {
751
+ throw new T2000Error("SENTINEL_NOT_FOUND", `Sentinel ${sentinelObjectId} not found on-chain`);
752
+ }
753
+ const content = obj.data.content;
754
+ if (!content || content.dataType !== "moveObject") {
755
+ throw new T2000Error("SENTINEL_NOT_FOUND", `Object ${sentinelObjectId} is not a Move object`);
756
+ }
757
+ const fields = content.fields;
758
+ return {
759
+ id: fields.id?.id ?? sentinelObjectId,
760
+ objectId: sentinelObjectId,
761
+ name: fields.name ?? "Unknown",
762
+ model: fields.model ?? "unknown",
763
+ systemPrompt: fields.system_prompt ?? "",
764
+ attackFee: BigInt(fields.cost_per_message ?? "0"),
765
+ prizePool: BigInt(fields.balance ?? "0"),
766
+ totalAttacks: Number(fields.total_attacks ?? "0"),
767
+ successfulBreaches: Number(fields.successful_breaches ?? "0"),
768
+ state: fields.state ?? "unknown"
769
+ };
770
+ }
771
+ async function requestAttack(client, signer, sentinelObjectId, feeMist) {
772
+ if (feeMist < SENTINEL.MIN_FEE_MIST) {
773
+ throw new T2000Error("INVALID_AMOUNT", `Attack fee must be at least 0.1 SUI (${SENTINEL.MIN_FEE_MIST} MIST)`);
774
+ }
775
+ const tx = new transactions.Transaction();
776
+ const [coin] = tx.splitCoins(tx.gas, [Number(feeMist)]);
777
+ const [attack2] = tx.moveCall({
778
+ target: `${SENTINEL.PACKAGE}::sentinel::request_attack`,
779
+ arguments: [
780
+ tx.object(SENTINEL.AGENT_REGISTRY),
781
+ tx.object(sentinelObjectId),
782
+ tx.object(SENTINEL.PROTOCOL_CONFIG),
783
+ coin,
784
+ tx.object(SENTINEL.RANDOM),
785
+ tx.object(CLOCK_ID)
786
+ ]
787
+ });
788
+ const address = signer.toSuiAddress();
789
+ tx.transferObjects([attack2], address);
790
+ const result = await client.signAndExecuteTransaction({
791
+ signer,
792
+ transaction: tx,
793
+ options: { showObjectChanges: true, showEffects: true }
794
+ });
795
+ await client.waitForTransaction({ digest: result.digest });
796
+ const attackObj = result.objectChanges?.find(
797
+ (c) => c.type === "created" && c.objectType?.includes("::sentinel::Attack")
798
+ );
799
+ const attackObjectId = attackObj && "objectId" in attackObj ? attackObj.objectId : void 0;
800
+ if (!attackObjectId) {
801
+ throw new T2000Error("SENTINEL_TX_FAILED", "Attack object was not created \u2014 transaction may have failed");
802
+ }
803
+ return { attackObjectId, digest: result.digest };
804
+ }
805
+ async function submitPrompt(agentId, attackObjectId, prompt) {
806
+ const res = await fetch(SENTINEL.TEE_API, {
807
+ method: "POST",
808
+ headers: { "Content-Type": "application/json" },
809
+ body: JSON.stringify({
810
+ agent_id: agentId,
811
+ attack_object_id: attackObjectId,
812
+ message: prompt
813
+ })
814
+ });
815
+ if (!res.ok) {
816
+ const body = await res.text().catch(() => "");
817
+ throw new T2000Error("SENTINEL_TEE_ERROR", `TEE returned ${res.status}: ${body.slice(0, 200)}`);
818
+ }
819
+ const raw = await res.json();
820
+ const envelope = raw.response ?? raw;
821
+ const data = envelope.data ?? envelope;
822
+ const signature = raw.signature ?? data.signature;
823
+ const timestampMs = envelope.timestamp_ms ?? data.timestamp_ms;
824
+ if (typeof signature !== "string") {
825
+ throw new T2000Error("SENTINEL_TEE_ERROR", "TEE response missing signature");
826
+ }
827
+ return {
828
+ success: data.success ?? data.is_success,
829
+ score: data.score,
830
+ agentResponse: data.agent_response,
831
+ juryResponse: data.jury_response,
832
+ funResponse: data.fun_response ?? "",
833
+ signature,
834
+ timestampMs
835
+ };
836
+ }
837
+ async function settleAttack(client, signer, sentinelObjectId, attackObjectId, prompt, verdict) {
838
+ const sigBytes = Array.from(Buffer.from(verdict.signature.replace(/^0x/, ""), "hex"));
839
+ const tx = new transactions.Transaction();
840
+ tx.moveCall({
841
+ target: `${SENTINEL.PACKAGE}::sentinel::consume_prompt`,
842
+ arguments: [
843
+ tx.object(SENTINEL.AGENT_REGISTRY),
844
+ tx.object(SENTINEL.PROTOCOL_CONFIG),
845
+ tx.object(sentinelObjectId),
846
+ tx.pure.bool(verdict.success),
847
+ tx.pure.string(verdict.agentResponse),
848
+ tx.pure.string(verdict.juryResponse),
849
+ tx.pure.string(verdict.funResponse),
850
+ tx.pure.string(prompt),
851
+ tx.pure.u8(verdict.score),
852
+ tx.pure.u64(verdict.timestampMs),
853
+ tx.pure(bcs.bcs.vector(bcs.bcs.u8()).serialize(sigBytes)),
854
+ tx.object(SENTINEL.ENCLAVE),
855
+ tx.object(attackObjectId),
856
+ tx.object(CLOCK_ID)
857
+ ]
858
+ });
859
+ const result = await client.signAndExecuteTransaction({
860
+ signer,
861
+ transaction: tx,
862
+ options: { showEffects: true }
863
+ });
864
+ await client.waitForTransaction({ digest: result.digest });
865
+ const txSuccess = result.effects?.status?.status === "success";
866
+ return { digest: result.digest, success: txSuccess };
867
+ }
868
+ async function attack(client, signer, sentinelId, prompt, feeMist) {
869
+ const sentinel = await getSentinelInfo(client, sentinelId);
870
+ const fee = feeMist ?? sentinel.attackFee;
871
+ if (fee < SENTINEL.MIN_FEE_MIST) {
872
+ throw new T2000Error("INVALID_AMOUNT", `Attack fee must be at least 0.1 SUI`);
873
+ }
874
+ const { attackObjectId, digest: requestTx } = await requestAttack(
875
+ client,
876
+ signer,
877
+ sentinel.objectId,
878
+ fee
879
+ );
880
+ const verdict = await submitPrompt(sentinel.id, attackObjectId, prompt);
881
+ const { digest: settleTx } = await settleAttack(
882
+ client,
883
+ signer,
884
+ sentinel.objectId,
885
+ attackObjectId,
886
+ prompt,
887
+ verdict
888
+ );
889
+ const won = verdict.success && verdict.score >= 70;
890
+ return {
891
+ attackObjectId,
892
+ sentinelId: sentinel.id,
893
+ prompt,
894
+ verdict,
895
+ requestTx,
896
+ settleTx,
897
+ won,
898
+ feePaid: Number(fee) / Number(MIST_PER_SUI)
899
+ };
900
+ }
704
901
  function hasLeadingZeroBits(hash, bits) {
705
902
  const fullBytes = Math.floor(bits / 8);
706
903
  const remainingBits = bits % 8;
@@ -1318,6 +1515,16 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
1318
1515
  async fundStatus() {
1319
1516
  return getFundStatus(this.client, this.keypair);
1320
1517
  }
1518
+ // -- Sentinel --
1519
+ async sentinelList() {
1520
+ return listSentinels();
1521
+ }
1522
+ async sentinelInfo(id) {
1523
+ return getSentinelInfo(this.client, id);
1524
+ }
1525
+ async sentinelAttack(id, prompt, fee) {
1526
+ return attack(this.client, this.keypair, id, prompt, fee);
1527
+ }
1321
1528
  // -- Helpers --
1322
1529
  emitBalanceChange(asset, amount, cause, tx) {
1323
1530
  this.emit("balanceChange", { asset, previous: 0, current: 0, cause, tx });
@@ -1421,6 +1628,7 @@ exports.BPS_DENOMINATOR = BPS_DENOMINATOR;
1421
1628
  exports.CLOCK_ID = CLOCK_ID;
1422
1629
  exports.DEFAULT_NETWORK = DEFAULT_NETWORK;
1423
1630
  exports.MIST_PER_SUI = MIST_PER_SUI;
1631
+ exports.SENTINEL = SENTINEL;
1424
1632
  exports.SUI_DECIMALS = SUI_DECIMALS;
1425
1633
  exports.SUPPORTED_ASSETS = SUPPORTED_ASSETS;
1426
1634
  exports.T2000 = T2000;
@@ -1437,17 +1645,23 @@ exports.getAddress = getAddress;
1437
1645
  exports.getGasStatus = getGasStatus;
1438
1646
  exports.getPoolPrice = getPoolPrice;
1439
1647
  exports.getRates = getRates;
1648
+ exports.getSentinelInfo = getSentinelInfo;
1440
1649
  exports.getSwapQuote = getSwapQuote;
1441
1650
  exports.keypairFromPrivateKey = keypairFromPrivateKey;
1651
+ exports.listSentinels = listSentinels;
1442
1652
  exports.loadKey = loadKey;
1443
1653
  exports.mapMoveAbortCode = mapMoveAbortCode;
1444
1654
  exports.mapWalletError = mapWalletError;
1445
1655
  exports.mistToSui = mistToSui;
1446
1656
  exports.rawToUsdc = rawToUsdc;
1657
+ exports.requestAttack = requestAttack;
1447
1658
  exports.saveKey = saveKey;
1659
+ exports.sentinelAttack = attack;
1660
+ exports.settleAttack = settleAttack;
1448
1661
  exports.shouldAutoTopUp = shouldAutoTopUp;
1449
1662
  exports.simulateTransaction = simulateTransaction;
1450
1663
  exports.solveHashcash = solveHashcash;
1664
+ exports.submitPrompt = submitPrompt;
1451
1665
  exports.suiToMist = suiToMist;
1452
1666
  exports.throwIfSimulationFailed = throwIfSimulationFailed;
1453
1667
  exports.truncateAddress = truncateAddress;