@t2000/sdk 3.3.0 → 4.0.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 +142 -250
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/browser.cjs +5 -0
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +2 -1
- package/dist/browser.d.ts +2 -1
- package/dist/browser.js +5 -0
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +245 -112
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +117 -16
- package/dist/index.d.ts +117 -16
- package/dist/index.js +238 -113
- package/dist/index.js.map +1 -1
- package/dist/{types-C1DH4kPA.d.cts → types-CqpN8a8R.d.cts} +55 -4
- package/dist/{types-DjeENMuV.d.ts → types-_U9XXGFR.d.ts} +55 -4
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -1,285 +1,197 @@
|
|
|
1
1
|
# @t2000/sdk
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The TypeScript SDK for Agent Wallets on Sui. Send USDC + USDsui gasless, swap via Cetus Aggregator, and pay MPP-protected APIs — all from a single class.
|
|
4
4
|
|
|
5
|
-
In Audric, this SDK powers **Audric Passport** (wallet, signing), **Audric Finance** (NAVI lending/borrowing builders, Cetus swap), and **Audric Pay** (USDC transfers, payment links), and is wrapped by `@t2000/engine` to implement **Audric Intelligence**'s Agent Harness.
|
|
5
|
+
In [Audric](https://audric.ai), this SDK powers **Audric Passport** (wallet, signing), **Audric Finance** (NAVI lending/borrowing builders, Cetus swap), and **Audric Pay** (USDC transfers, payment links), and is wrapped by [`@t2000/engine`](https://www.npmjs.com/package/@t2000/engine) to implement **Audric Intelligence**'s Agent Harness.
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/@t2000/sdk)
|
|
8
|
-
[](https://www.npmjs.com/package/@t2000/sdk)
|
|
8
|
+
[](https://www.npmjs.com/package/@t2000/cli)
|
|
9
|
+
[](https://t2000.ai)
|
|
10
|
+
[](https://github.com/mission69b/t2000/blob/main/LICENSE)
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npm install @t2000/sdk
|
|
16
|
-
# or
|
|
17
|
-
pnpm add @t2000/sdk
|
|
18
|
-
# or
|
|
19
|
-
yarn add @t2000/sdk
|
|
15
|
+
npm install @t2000/sdk # or pnpm add / yarn add
|
|
20
16
|
```
|
|
21
17
|
|
|
22
|
-
**
|
|
18
|
+
**Requires** Node.js 18+ · TypeScript 5+ (recommended).
|
|
23
19
|
|
|
24
20
|
## Quick Start
|
|
25
21
|
|
|
26
22
|
```typescript
|
|
27
23
|
import { T2000 } from '@t2000/sdk';
|
|
28
24
|
|
|
29
|
-
// Create a new
|
|
30
|
-
const { agent, address } = await T2000.init(
|
|
25
|
+
// Create a new wallet (plain Bech32, 0o600 perms, no PIN)
|
|
26
|
+
const { agent, address } = await T2000.init();
|
|
27
|
+
|
|
28
|
+
// Or load an existing wallet from ~/.t2000/wallet.key
|
|
29
|
+
const agent = await T2000.create();
|
|
31
30
|
|
|
32
|
-
// Or
|
|
33
|
-
const agent =
|
|
31
|
+
// Or from a Bech32 secret in memory (no file)
|
|
32
|
+
const agent = T2000.fromPrivateKey('suiprivkey1…');
|
|
34
33
|
|
|
35
|
-
//
|
|
34
|
+
// Inspect
|
|
36
35
|
const balance = await agent.balance();
|
|
37
36
|
console.log(`$${balance.available} USDC available`);
|
|
38
37
|
|
|
39
|
-
// Send
|
|
40
|
-
await agent.send({ to: '
|
|
41
|
-
await agent.send({ to: '
|
|
42
|
-
// Legacy contact aliases (~/.t2000/contacts.json) still work but emit a deprecation
|
|
43
|
-
// warning on first use per process. Sunset target: next major SDK release.
|
|
38
|
+
// Send — asset is REQUIRED; USDC + USDsui are gasless via 0x2::balance::send_funds
|
|
39
|
+
await agent.send({ to: 'alice.sui', amount: 5, asset: 'USDC' });
|
|
40
|
+
await agent.send({ to: '0x8b3e…', amount: 5, asset: 'USDsui' });
|
|
44
41
|
|
|
45
|
-
//
|
|
46
|
-
await agent.
|
|
42
|
+
// Swap — Cetus Aggregator V3 across 20+ Sui DEXs. Requires SUI for gas.
|
|
43
|
+
await agent.swap({ from: 'USDC', to: 'SUI', amount: 100 });
|
|
47
44
|
|
|
48
|
-
//
|
|
49
|
-
await agent.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
// Pay — MPP-protected API. Gasless USDC; handles HTTP 402 transparently.
|
|
46
|
+
const result = await agent.pay({
|
|
47
|
+
url: 'https://mpp.t2000.ai/openai/v1/chat/completions',
|
|
48
|
+
method: 'POST',
|
|
49
|
+
body: JSON.stringify({ model: 'gpt-4o-mini', messages: […] }),
|
|
50
|
+
maxPrice: 0.10,
|
|
51
|
+
});
|
|
53
52
|
```
|
|
54
53
|
|
|
55
|
-
##
|
|
54
|
+
## Factory Methods
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
| Static | Returns | Use when |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `T2000.init({ keyPath?, name? })` | `{ agent, address }` | Generating a brand-new wallet. Writes a plain Bech32 JSON file to `~/.t2000/wallet.key` (override with `keyPath`). |
|
|
59
|
+
| `T2000.create({ keyPath?, rpcUrl? })` | `T2000` | Loading the existing wallet from disk. Throws `WALLET_NOT_FOUND` if the file is missing, `WALLET_CORRUPT` if it's a v3 PIN-encrypted file or otherwise malformed. |
|
|
60
|
+
| `T2000.fromPrivateKey(secret, { network?, rpcUrl? })` | `T2000` | Synchronous in-memory load from a `suiprivkey1…` Bech32 or hex secret. No filesystem read or write. |
|
|
58
61
|
|
|
59
|
-
|
|
62
|
+
> **v3 → v4.** `T2000.create({ pin })` is gone. The `pin` and `passphrase` fields are accepted (back-compat) but **ignored** — v4 wallets are plain Bech32 JSON with `0o600` perms. If you're upgrading a v3 PIN-encrypted wallet: export the secret from the v3 binary, then `T2000.init` followed by replacing the generated file with one carrying that secret (or just use [`@t2000/cli`](https://www.npmjs.com/package/@t2000/cli)'s `t2 init --import` flow).
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
const { agent, address } = await T2000.init({
|
|
63
|
-
pin: 'my-secret', // Required — encrypts the key
|
|
64
|
-
keyPath: '~/.t2000/wallet.key', // Optional — custom key file path
|
|
65
|
-
});
|
|
66
|
-
```
|
|
64
|
+
## Agent Wallet API
|
|
67
65
|
|
|
68
|
-
|
|
66
|
+
These methods cover the v4 Agent Wallet brand — sending USDC, receiving, swapping, paying for MPP APIs. They mirror the [`@t2000/cli`](https://www.npmjs.com/package/@t2000/cli) surface 1:1.
|
|
69
67
|
|
|
70
|
-
|
|
68
|
+
| Method | Returns | Notes |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `agent.address()` | `string` | Sui address. |
|
|
71
|
+
| `agent.balance()` | `BalanceResponse` | USDC / USDsui / SUI + gas reserve + total USD. |
|
|
72
|
+
| `agent.history({ limit? })` | `TransactionRecord[]` | Sends / swaps / MPP payments with Suiscan digests. |
|
|
73
|
+
| `agent.send({ to, amount, asset })` | `SendResult` | **`asset` is required** (`'USDC'` / `'USDsui'` / `'SUI'`). USDC + USDsui are gasless via Sui foundation's `0x2::balance::send_funds` sponsor; SUI uses standard gas. `to` resolves in priority order: hex address > SuiNS name (`alice.sui`) > `@audric` handle > saved contact. |
|
|
74
|
+
| `agent.resolveRecipient(input)` | `{ address, suinsName?, contactName? }` | Public resolver — same lookup `send` uses. Handy for dry-run previews. |
|
|
75
|
+
| `agent.swap({ from, to, amount, slippage? })` | `SwapResult` | Cetus Aggregator V3 (20+ DEXs). User-friendly names (`'USDC'`, `'SUI'`, `'CETUS'`, …) or full coin types. Default slippage 1%, max 5%. **Requires SUI for gas** — Cetus is not in the gasless allowlist. |
|
|
76
|
+
| `agent.swapQuote({ from, to, amount, slippage? })` | `SwapQuoteResult` | Preview route + output + price impact (no execution). |
|
|
77
|
+
| `agent.pay(options)` | `PayResult` | MPP-protected paid API. Handles 402 → quote → USDC payment → retry. USDC transfer is gasless. `options.maxPrice` caps spend (default 1 USDC). |
|
|
78
|
+
| `agent.receive({ amount?, currency?, memo?, label? })` | `PaymentRequest` | Builds a Payment Kit `sui:pay?…` URI with a unique nonce. Scannable by any Sui wallet. |
|
|
79
|
+
| `agent.exportKey()` | `string` | Print the Bech32 (`suiprivkey1…`) secret for the underlying keypair. |
|
|
80
|
+
|
|
81
|
+
### Events
|
|
71
82
|
|
|
72
83
|
```typescript
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
});
|
|
84
|
+
agent.on('balanceChange', (e) => { /* asset, previous, current, cause, tx? */ });
|
|
85
|
+
agent.on('healthWarning', (e) => { /* healthFactor, threshold */ });
|
|
86
|
+
agent.on('healthCritical', (e) => { /* healthFactor < 1.2 */ });
|
|
87
|
+
agent.on('yield', (e) => { /* earned, total, apy, timestamp */ });
|
|
88
|
+
agent.on('error', (e) => { /* T2000Error */ });
|
|
78
89
|
```
|
|
79
90
|
|
|
80
|
-
###
|
|
91
|
+
### Exposed Internals
|
|
81
92
|
|
|
82
|
-
|
|
93
|
+
For integrations (`@suimpp/mpp`, `@t2000/engine`, audric web-v2):
|
|
83
94
|
|
|
84
95
|
```typescript
|
|
85
|
-
|
|
96
|
+
agent.suiClient; // SuiJsonRpcClient
|
|
97
|
+
agent.signer; // TransactionSigner (works for keypair + zkLogin)
|
|
98
|
+
agent.keypair; // Ed25519Keypair (throws for zkLogin instances)
|
|
86
99
|
```
|
|
87
100
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
| Method | Description | Returns |
|
|
91
|
-
|--------|-------------|---------|
|
|
92
|
-
| `agent.address()` | Wallet Sui address | `string` |
|
|
93
|
-
| `agent.balance()` | Available USDC + savings + gas reserve | `BalanceResponse` |
|
|
94
|
-
| `agent.send({ to, amount, asset? })` | Transfer USDC (or other supported asset) to a 0x address, SuiNS name (`alex.sui`), or saved contact alias. Priority: hex > SuiNS > contact. `SendResult.suinsName` / `.contactName` flag which path resolved. | `SendResult` |
|
|
95
|
-
| `agent.resolveRecipient(input)` | Public resolver — same hex / SuiNS / contact priority used by `send()`. Useful for dryRun previews where you need the resolved address before committing. | `{ address, suinsName?, contactName? }` |
|
|
96
|
-
| `agent.receive({ amount?, currency?, memo?, label? })` | Generate payment request with Payment Kit URI (`sui:pay?...`), nonce for duplicate prevention | `PaymentRequest` |
|
|
97
|
-
| `agent.save({ amount, asset?, protocol? })` | Deposit **USDC or USDsui** to NAVI savings (v0.51.0+). `asset` defaults to `'USDC'`. Auto-selects best rate or specify `protocol`. `amount` can be `'all'`. | `SaveResult` |
|
|
98
|
-
| `agent.withdraw({ amount, asset? })` | Withdraw from savings. `amount` can be `'all'`. Optional `asset` (default: USDC; also supports USDsui plus legacy USDe / SUI). | `WithdrawResult` |
|
|
99
|
-
| `agent.borrow({ amount, asset? })` | Borrow **USDC or USDsui** against collateral (v0.51.0+). `asset` defaults to `'USDC'`. | `BorrowResult` |
|
|
100
|
-
| `agent.repay({ amount, asset? })` | Repay outstanding **USDC or USDsui** debt (v0.51.1+). Pass `asset` to target a specific debt; omit for highest-APY repay. **Symmetry enforced:** USDsui debt is repaid with USDsui coins (and USDC with USDC). `amount` can be `'all'`. | `RepayResult` |
|
|
101
|
-
| `agent.swap({ from, to, amount, slippage? })` | Swap tokens via Cetus Aggregator (20+ DEXs). User-friendly names or full coin types. | `SwapResult` |
|
|
102
|
-
| `agent.exportKey()` | Export private key (bech32 format) | `string` |
|
|
103
|
-
|
|
104
|
-
### Query Methods
|
|
105
|
-
|
|
106
|
-
| Method | Description | Returns |
|
|
107
|
-
|--------|-------------|---------|
|
|
108
|
-
| `agent.healthFactor()` | Lending health factor | `HealthFactorResult` |
|
|
109
|
-
| `agent.earnings()` | Yield earned to date | `EarningsResult` |
|
|
110
|
-
| `agent.rates()` | Best save/borrow APYs across protocols | `RatesResult` |
|
|
111
|
-
| `agent.allRatesAcrossAssets()` | Per-protocol rate data across assets | `Array<{ protocol, asset, rates }>` |
|
|
112
|
-
| `agent.positions()` | All open DeFi positions | `PositionsResult` |
|
|
113
|
-
| `agent.fundStatus()` | Complete savings summary | `FundStatusResult` |
|
|
114
|
-
| `agent.maxWithdraw()` | Max safe withdrawal amount | `MaxWithdrawResult` |
|
|
115
|
-
| `agent.maxBorrow()` | Max safe borrow amount | `MaxBorrowResult` |
|
|
116
|
-
| `agent.deposit()` | Wallet address + funding instructions | `DepositInfo` |
|
|
117
|
-
| `agent.history({ limit? })` | Transaction history (default: all) | `TransactionRecord[]` |
|
|
118
|
-
| `agent.swapQuote({ from, to, amount })` | Preview swap route, output amount, and price impact (no execution) | `SwapQuoteResult` |
|
|
119
|
-
|
|
120
|
-
### Contacts Methods
|
|
121
|
-
|
|
122
|
-
| Method | Description | Returns |
|
|
123
|
-
|--------|-------------|---------|
|
|
124
|
-
| `agent.contacts.add(name, address)` | Save a named contact | `void` |
|
|
125
|
-
| `agent.contacts.remove(name)` | Remove a contact | `void` |
|
|
126
|
-
| `agent.contacts.list()` | List all saved contacts | `Contact[]` |
|
|
127
|
-
| `agent.contacts.get(name)` | Get a contact by name | `Contact` |
|
|
128
|
-
| `agent.contacts.resolve(nameOrAddress)` | Resolve name to address (passthrough if already an address) | `string` |
|
|
129
|
-
|
|
130
|
-
### Safeguards (Enforcer)
|
|
131
|
-
|
|
132
|
-
| Method | Description | Returns |
|
|
133
|
-
|--------|-------------|---------|
|
|
134
|
-
| `agent.enforcer.getConfig()` | Get safeguard settings | `SafeguardConfig` |
|
|
135
|
-
| `agent.enforcer.set({ maxPerTx?, maxDailySend? })` | Set per-transaction and/or daily send limits | `void` |
|
|
136
|
-
| `agent.enforcer.lock()` | Lock agent (freeze all operations) | `void` |
|
|
137
|
-
| `agent.enforcer.unlock(pin)` | Unlock agent | `void` |
|
|
138
|
-
| `agent.enforcer.check(amount)` | Check if amount is allowed under limits | `void` (throws `SafeguardError` if not) |
|
|
139
|
-
| `agent.enforcer.recordUsage(amount)` | Record send for daily limit tracking | `void` |
|
|
140
|
-
| `agent.enforcer.isConfigured()` | Whether safeguards are set up | `boolean` |
|
|
141
|
-
|
|
142
|
-
**Types:** `SafeguardConfig` — `{ maxPerTx?, maxDailySend?, locked? }` · `SafeguardError` — thrown when limits exceeded or agent locked
|
|
143
|
-
|
|
144
|
-
### Key Management
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
import {
|
|
148
|
-
generateKeypair,
|
|
149
|
-
keypairFromPrivateKey,
|
|
150
|
-
exportPrivateKey,
|
|
151
|
-
getAddress,
|
|
152
|
-
saveKey,
|
|
153
|
-
loadKey,
|
|
154
|
-
walletExists,
|
|
155
|
-
} from '@t2000/sdk';
|
|
101
|
+
## Programmatic DeFi API (no CLI alias)
|
|
156
102
|
|
|
157
|
-
|
|
158
|
-
const keypair = generateKeypair();
|
|
103
|
+
These methods power [Audric Finance](https://audric.ai) — save (NAVI lend), borrow (NAVI), repay, withdraw, plus the supporting read tools. **They have no `t2` CLI alias in v4** by design: the CLI is a focused Agent Wallet (send / swap / pay); DeFi flows live in consumer apps and the `@t2000/engine` Agent Harness. They are still load-bearing for `@t2000/engine` 4.x and any consumer app building on the SDK.
|
|
159
104
|
|
|
160
|
-
|
|
161
|
-
|
|
105
|
+
| Method | Notes |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `agent.save({ amount, asset?, protocol? })` | Deposit **USDC or USDsui** to NAVI savings (default `'USDC'`). `amount` can be `'all'`. |
|
|
108
|
+
| `agent.withdraw({ amount, asset?, protocol? })` | Withdraw from savings (default `'USDC'`; also supports USDsui + legacy USDe / SUI positions). `amount` can be `'all'`. |
|
|
109
|
+
| `agent.borrow({ amount, asset?, protocol? })` | Borrow USDC or USDsui against collateral (default `'USDC'`). |
|
|
110
|
+
| `agent.repay({ amount, asset?, protocol? })` | Repay outstanding debt. **Symmetry enforced** — USDsui debt is repaid with USDsui (USDC with USDC). `amount` can be `'all'`. |
|
|
111
|
+
| `agent.claimRewards()` | Claim pending NAVI rewards. |
|
|
112
|
+
| `agent.healthFactor()` | NAVI lending health factor. |
|
|
113
|
+
| `agent.maxWithdraw()` · `agent.maxBorrow()` | Safe limits without breaching health factor. |
|
|
114
|
+
| `agent.positions()` | Open save + borrow positions across protocols. |
|
|
115
|
+
| `agent.rates()` | Best save/borrow APYs across protocols. |
|
|
116
|
+
| `agent.earnings()` | Yield earned to date. |
|
|
117
|
+
| `agent.fundStatus()` | Complete savings summary. |
|
|
118
|
+
| `agent.deposit()` · `agent.fund()` | Wallet address + funding instructions (used by Audric's deposit UI). |
|
|
162
119
|
|
|
163
|
-
|
|
164
|
-
const privkey = exportPrivateKey(keypair);
|
|
165
|
-
|
|
166
|
-
// Get the Sui address
|
|
167
|
-
const address = getAddress(keypair);
|
|
168
|
-
|
|
169
|
-
// Check if wallet exists on disk
|
|
170
|
-
const exists = await walletExists();
|
|
171
|
-
|
|
172
|
-
// Save/load encrypted key
|
|
173
|
-
await saveKey(keypair, 'my-pin');
|
|
174
|
-
const loaded = await loadKey('my-pin');
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Events
|
|
120
|
+
## Utility Exports
|
|
178
121
|
|
|
179
122
|
```typescript
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
123
|
+
import {
|
|
124
|
+
// Key management
|
|
125
|
+
generateKeypair, keypairFromPrivateKey, exportPrivateKey, getAddress,
|
|
126
|
+
saveKey, loadKey, walletExists,
|
|
183
127
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
128
|
+
// Token data
|
|
129
|
+
COIN_REGISTRY, TOKEN_MAP, SUI_TYPE, USDC_TYPE,
|
|
130
|
+
isTier1, isTier2, isSupported, getTier,
|
|
131
|
+
getDecimalsForCoinType, resolveSymbol, resolveTokenType,
|
|
187
132
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
133
|
+
// Asset allowlist
|
|
134
|
+
SUPPORTED_ASSETS, SENDABLE_ASSETS, assertAllowedAsset,
|
|
135
|
+
GASLESS_MIN_STABLE_AMOUNT, GASLESS_STABLE_TYPES,
|
|
191
136
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
137
|
+
// Numbers + formatting
|
|
138
|
+
mistToSui, suiToMist, usdcToRaw, rawToUsdc,
|
|
139
|
+
formatUsd, formatSui, truncateAddress, validateAddress,
|
|
195
140
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
141
|
+
// Sui clients
|
|
142
|
+
getSuiClient, getSuiGrpcClient, DEFAULT_GRPC_URL,
|
|
143
|
+
|
|
144
|
+
// Fees (consumer apps only — SDK + CLI are fee-free)
|
|
145
|
+
addFeeTransfer, T2000_OVERLAY_FEE_WALLET,
|
|
146
|
+
} from '@t2000/sdk';
|
|
199
147
|
```
|
|
200
148
|
|
|
201
|
-
|
|
149
|
+
## Supported Assets
|
|
202
150
|
|
|
203
|
-
|
|
204
|
-
import {
|
|
205
|
-
mistToSui,
|
|
206
|
-
suiToMist,
|
|
207
|
-
usdcToRaw,
|
|
208
|
-
rawToUsdc,
|
|
209
|
-
formatUsd,
|
|
210
|
-
formatSui,
|
|
211
|
-
validateAddress,
|
|
212
|
-
truncateAddress,
|
|
213
|
-
} from '@t2000/sdk';
|
|
151
|
+
Token metadata + tiers live in `COIN_REGISTRY` (`packages/sdk/src/token-registry.ts`). **19 tokens** total.
|
|
214
152
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
truncateAddress('0xabcdef...1234'); // "0xabcd...1234"
|
|
219
|
-
validateAddress('0x...'); // throws if invalid
|
|
220
|
-
```
|
|
153
|
+
- **Tier 1 — financial layer (1):** USDC. Save / borrow / receive / yield, marketplace, MPP.
|
|
154
|
+
- **Tier 2 — swap assets (15):** SUI, wBTC, ETH, GOLD, DEEP, WAL, NS, IKA, CETUS, NAVX, vSUI, haSUI, afSUI, LOFI, MANIFEST. Hold + swap + send only.
|
|
155
|
+
- **Legacy — no tier, display only (3):** USDT, USDe, USDsui. Kept so existing NAVI positions still render accurately.
|
|
221
156
|
|
|
222
|
-
|
|
157
|
+
> **Strategic exception.** `OPERATION_ASSETS.save` and `OPERATION_ASSETS.borrow` accept **both** USDC and USDsui — USDsui is no-tier in the registry but saveable/borrowable via the allowlist (NAVI runs a separate USDsui pool, often at a different APY than the USDC pool, since v0.51.0). Repay symmetry is enforced: USDsui debt must be repaid with USDsui (USDC debt with USDC).
|
|
223
158
|
|
|
224
|
-
|
|
159
|
+
**`OPERATION_ASSETS`** constrains each write:
|
|
225
160
|
|
|
226
161
|
```typescript
|
|
227
|
-
|
|
228
|
-
agent.signer; // Ed25519Keypair
|
|
229
|
-
```
|
|
162
|
+
import { OPERATION_ASSETS, assertAllowedAsset } from '@t2000/sdk';
|
|
230
163
|
|
|
231
|
-
|
|
164
|
+
OPERATION_ASSETS.send; // ['USDC', 'USDsui', 'SUI']
|
|
165
|
+
OPERATION_ASSETS.save; // ['USDC', 'USDsui']
|
|
166
|
+
OPERATION_ASSETS.borrow; // ['USDC', 'USDsui']
|
|
232
167
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
> **Audric web app exception:** Audric web users transact under Enoki gas sponsorship (zkLogin), so `INSUFFICIENT_GAS` is not a user-facing concern there. The SDK itself is sponsorship-agnostic — sponsorship is wired in at the host layer (Audric web), not inside `@t2000/sdk`.
|
|
168
|
+
assertAllowedAsset('send', 'USDY'); // throws — not in the allowlist
|
|
169
|
+
```
|
|
236
170
|
|
|
237
|
-
|
|
171
|
+
## Gasless
|
|
238
172
|
|
|
239
|
-
|
|
173
|
+
USDC + USDsui sends and MPP USDC payments are gasless. Build path goes through `SuiGrpcClient` so the SDK's gasless-eligibility resolver detects the `0x2::balance::send_funds` Move call at build time and zeroes out `gasPrice` / `gasBudget` / `gasPayment` automatically. Submission still goes through the JSON-RPC client (hybrid pattern documented at [`docs.sui.io`](https://docs.sui.io/develop/transaction-payment/gasless-stablecoin-transfers)).
|
|
240
174
|
|
|
241
|
-
|
|
242
|
-
|---------------------|-------------|---------|
|
|
243
|
-
| `T2000_API_URL` | t2000 API base URL | `https://api.t2000.ai` |
|
|
175
|
+
Other writes (SUI sends, Cetus swaps, NAVI save / borrow / withdraw / repay / claim) require gas. Keep ~0.05 SUI on hand. The SDK throws `INSUFFICIENT_GAS` if you run dry.
|
|
244
176
|
|
|
245
|
-
|
|
177
|
+
> **Consumer apps:** sponsored gas via Enoki / zkLogin is the host's responsibility. The SDK is sponsorship-agnostic — Audric wires Enoki at the host layer (`audric/apps/web-v2`); the SDK doesn't know or care. See `audric/.cursor/rules/audric-transaction-flow.mdc` in the audric repo.
|
|
246
178
|
|
|
247
|
-
##
|
|
179
|
+
## Fees
|
|
248
180
|
|
|
249
|
-
|
|
181
|
+
The SDK + CLI are **fee-free by design** (`@t2000/sdk@1.1.0+`). No t2000 protocol fees on any operation.
|
|
250
182
|
|
|
251
|
-
|
|
252
|
-
- **Tier 2 (15):** SUI, wBTC, ETH, GOLD, DEEP, WAL, NS, IKA, CETUS, NAVX, vSUI, haSUI, afSUI, LOFI, MANIFEST — send and swap only (not for new save/borrow deposits).
|
|
253
|
-
- **Legacy (no tier):** USDT, USDe, USDSUI — display and withdraw of existing positions; still send/swap where applicable.
|
|
183
|
+
Network gas (SUI) and third-party fees (Cetus routing, NAVI lending spread) still apply at on-chain rates.
|
|
254
184
|
|
|
255
|
-
|
|
185
|
+
Consumer apps that want to charge an overlay fee — Audric does this on save / borrow / swap — call `addFeeTransfer(tx, paymentCoin, FEE_BPS, receiverAddress, amount)` inside the same PTB. The SDK never assumes a t2000 treasury; pass any receiver.
|
|
256
186
|
|
|
257
|
-
|
|
258
|
-
import {
|
|
259
|
-
COIN_REGISTRY,
|
|
260
|
-
TOKEN_MAP,
|
|
261
|
-
isTier1,
|
|
262
|
-
isTier2,
|
|
263
|
-
isSupported,
|
|
264
|
-
getTier,
|
|
265
|
-
getDecimalsForCoinType,
|
|
266
|
-
resolveSymbol,
|
|
267
|
-
resolveTokenType,
|
|
268
|
-
SUI_TYPE,
|
|
269
|
-
USDC_TYPE,
|
|
270
|
-
USDT_TYPE,
|
|
271
|
-
IKA_TYPE,
|
|
272
|
-
LOFI_TYPE,
|
|
273
|
-
MANIFEST_TYPE,
|
|
274
|
-
} from '@t2000/sdk';
|
|
187
|
+
## Configuration
|
|
275
188
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
```
|
|
189
|
+
| Env var | Effect |
|
|
190
|
+
|---|---|
|
|
191
|
+
| `T2000_RPC_URL` | Custom Sui JSON-RPC endpoint. |
|
|
192
|
+
| `T2000_GRPC_URL` | Custom Sui gRPC endpoint (defaults to `fullnode.mainnet.sui.io`). Used during gasless USDC/USDsui send + pay build paths. |
|
|
281
193
|
|
|
282
|
-
|
|
194
|
+
Per-call options like `keyPath` and `rpcUrl` are passed to `T2000.create()` / `T2000.init()`.
|
|
283
195
|
|
|
284
196
|
## Error Handling
|
|
285
197
|
|
|
@@ -287,58 +199,38 @@ Swap uses Cetus Aggregator V3. Per-call `overlayFee` is opt-in — the SDK and C
|
|
|
287
199
|
import { T2000Error } from '@t2000/sdk';
|
|
288
200
|
|
|
289
201
|
try {
|
|
290
|
-
await agent.send({ to: '
|
|
202
|
+
await agent.send({ to: 'alice.sui', amount: 1000, asset: 'USDC' });
|
|
291
203
|
} catch (e) {
|
|
292
204
|
if (e instanceof T2000Error) {
|
|
293
|
-
|
|
294
|
-
// 'INSUFFICIENT_BALANCE' | 'SUINS_NOT_REGISTERED' | 'CONTACT_NOT_FOUND' | …
|
|
295
|
-
console.log(e.message); // Human-readable message
|
|
205
|
+
// e.code + e.message
|
|
296
206
|
}
|
|
297
207
|
}
|
|
298
208
|
```
|
|
299
209
|
|
|
300
|
-
Common
|
|
210
|
+
Common codes:
|
|
301
211
|
|
|
302
|
-
|
|
212
|
+
`WALLET_NOT_FOUND` · `WALLET_CORRUPT` · `INVALID_KEY` · `INSUFFICIENT_BALANCE` · `INSUFFICIENT_GAS` · `INVALID_ADDRESS` · `INVALID_AMOUNT` · `INVALID_ASSET` · `ASSET_NOT_SUPPORTED` · `SUINS_NOT_REGISTERED` · `CONTACT_NOT_FOUND` · `SWAP_NO_ROUTE` · `SWAP_FAILED` · `HEALTH_FACTOR_TOO_LOW` · `NO_COLLATERAL` · `WITHDRAW_WOULD_LIQUIDATE` · `PROTOCOL_PAUSED` · `SIMULATION_FAILED` · `TRANSACTION_FAILED`
|
|
303
213
|
|
|
304
|
-
|
|
214
|
+
## Architecture
|
|
215
|
+
|
|
216
|
+
t2000 uses an MCP-first model for DeFi reads + thin transaction builders for writes. No protocol SDK dependencies needed in user code.
|
|
305
217
|
|
|
306
218
|
| Protocol | Integration | Used for |
|
|
307
|
-
|
|
308
|
-
|
|
|
309
|
-
| Cetus Aggregator V3 | `@cetusprotocol/aggregator-sdk` (isolated) | Multi-DEX swap routing
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| Sui foundation gasless | `0x2::balance::send_funds` Move call (built via `SuiGrpcClient`) | USDC + USDsui transfers, MPP USDC payments |
|
|
221
|
+
| Cetus Aggregator V3 | `@cetusprotocol/aggregator-sdk` (isolated to `protocols/cetus-swap.ts`) | Multi-DEX swap routing |
|
|
222
|
+
| NAVI | NAVI MCP (reads) + thin tx builders (writes) | Save / borrow / withdraw / repay / rewards / positions / rates |
|
|
223
|
+
| MPP | `mppx` + `@suimpp/mpp/client` | Paid API access — 40+ services on `mpp.t2000.ai` |
|
|
224
|
+
|
|
225
|
+
Each NAVI op exposes both `buildXxxTx()` (standalone) and `addXxxToTx()` (composable fragment) so multi-step flows compose atomically as a single Programmable Transaction Block — any step failing reverts the whole bundle.
|
|
310
226
|
|
|
311
227
|
## Testing
|
|
312
228
|
|
|
313
229
|
```bash
|
|
314
|
-
|
|
315
|
-
pnpm --filter @t2000/sdk test
|
|
316
|
-
|
|
317
|
-
# Run smoke tests against mainnet RPC (read-only, no transactions)
|
|
318
|
-
SMOKE=1 pnpm --filter @t2000/sdk test -- src/__smoke__
|
|
230
|
+
pnpm --filter @t2000/sdk test # unit
|
|
231
|
+
SMOKE=1 pnpm --filter @t2000/sdk test -- src/__smoke__ # read-only mainnet smokes
|
|
319
232
|
```
|
|
320
233
|
|
|
321
|
-
## Protocol Fees
|
|
322
|
-
|
|
323
|
-
> **The SDK and CLI are fee-free by design (as of `@t2000/sdk@1.1.0`, B5 v2 / 2026-04-30).** Direct SDK / CLI calls — `t2000 save`, `t2000 borrow`, `t2000 swap`, plus `T2000.save()` / `T2000.borrow()` / `swapExecute()` from any third-party integrator — never charge a t2000 protocol fee. The CLI is dev-focused tooling and intentionally has no monetization.
|
|
324
|
-
|
|
325
|
-
Fees only apply when the **Audric** consumer app calls these primitives. Audric layers a fee transfer step (`addFeeTransfer`) inside the same PTB and routes the USDC to `T2000_OVERLAY_FEE_WALLET`.
|
|
326
|
-
|
|
327
|
-
| Operation | Audric fee | SDK / CLI fee | Notes |
|
|
328
|
-
|-----------|-----------|--------------|-------|
|
|
329
|
-
| Save (deposit) | 0.10% | Free | USDC only; USDsui save is free in Audric too |
|
|
330
|
-
| Borrow | 0.05% | Free | USDC only; USDsui borrow is free in Audric too |
|
|
331
|
-
| Swap | 0.10% | Free | Audric passes Cetus `overlayFee`. CLI omits it. Cetus Aggregator network fees still apply both ways. |
|
|
332
|
-
| Withdraw / Repay / Send / Receive / Pay (MPP) | Free | Free | No surcharge anywhere. |
|
|
333
|
-
|
|
334
|
-
How Audric collects fees: `prepare/route.ts` calls `addFeeTransfer(tx, paymentCoin, FEE_BPS, T2000_OVERLAY_FEE_WALLET, amount)` for save/borrow and passes `overlayFee.receiver = T2000_OVERLAY_FEE_WALLET` for swaps. Both flows produce a USDC transfer to the treasury wallet inside the same atomic Payment Intent. The t2000 server-side indexer detects the on-chain USDC inflow and records a `ProtocolFeeLedger` row — no off-chain submission is involved.
|
|
335
|
-
|
|
336
|
-
Need to charge an overlay fee in your own consumer app? Import `addFeeTransfer` and `T2000_OVERLAY_FEE_WALLET` from `@t2000/sdk` (or use your own receiver address — the SDK never assumes the t2000 treasury).
|
|
337
|
-
|
|
338
|
-
## MCP Server
|
|
339
|
-
|
|
340
|
-
The SDK powers the [`@t2000/mcp`](https://www.npmjs.com/package/@t2000/mcp) server for Claude Desktop, Cursor, and any MCP-compatible AI platform. Run `t2000 mcp` to start.
|
|
341
|
-
|
|
342
234
|
## License
|
|
343
235
|
|
|
344
|
-
MIT — see [LICENSE](https://github.com/mission69b/t2000/blob/main/LICENSE)
|
|
236
|
+
MIT — see [LICENSE](https://github.com/mission69b/t2000/blob/main/LICENSE).
|