@t2000/sdk 3.2.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/dist/index.js CHANGED
@@ -1,13 +1,13 @@
1
- import { Transaction, coinWithBalance } from '@mysten/sui/transactions';
1
+ import { coinWithBalance, Transaction } from '@mysten/sui/transactions';
2
2
  import { AggregatorClient, Env } from '@cetusprotocol/aggregator-sdk';
3
3
  import BN from 'bn.js';
4
4
  import { EventEmitter } from 'eventemitter3';
5
5
  import { createPaymentTransactionUri } from '@mysten/payment-kit';
6
6
  import { SuiJsonRpcClient, getJsonRpcFullnodeUrl } from '@mysten/sui/jsonRpc';
7
+ import { SuiGrpcClient } from '@mysten/sui/grpc';
7
8
  import { normalizeSuiAddress, isValidSuiAddress, normalizeStructTag } from '@mysten/sui/utils';
8
9
  import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
9
10
  import { decodeSuiPrivateKey } from '@mysten/sui/cryptography';
10
- import { randomBytes, createCipheriv, createDecipheriv, scryptSync } from 'crypto';
11
11
  import { access, mkdir, writeFile, readFile } from 'fs/promises';
12
12
  import { join as join$1, dirname, resolve } from 'path';
13
13
  import { homedir } from 'os';
@@ -645,155 +645,6 @@ var require_lodash = __commonJS({
645
645
  }
646
646
  });
647
647
 
648
- // src/protocols/volo.ts
649
- var volo_exports = {};
650
- __export(volo_exports, {
651
- MIN_STAKE_MIST: () => MIN_STAKE_MIST,
652
- SUI_SYSTEM_STATE: () => SUI_SYSTEM_STATE,
653
- VOLO_METADATA: () => VOLO_METADATA,
654
- VOLO_PKG: () => VOLO_PKG,
655
- VOLO_POOL: () => VOLO_POOL,
656
- VSUI_TYPE: () => VSUI_TYPE,
657
- addStakeVSuiToTx: () => addStakeVSuiToTx,
658
- addUnstakeVSuiToTx: () => addUnstakeVSuiToTx,
659
- buildStakeVSuiTx: () => buildStakeVSuiTx,
660
- buildUnstakeVSuiTx: () => buildUnstakeVSuiTx,
661
- getVoloStats: () => getVoloStats
662
- });
663
- async function getVoloStats() {
664
- const res = await fetch(VOLO_STATS_URL, {
665
- signal: AbortSignal.timeout(8e3)
666
- });
667
- if (!res.ok) {
668
- throw new Error(`VOLO stats API error: HTTP ${res.status}`);
669
- }
670
- const data = await res.json();
671
- const d = data.data ?? data;
672
- return {
673
- apy: d.apy ?? 0,
674
- exchangeRate: d.exchange_rate ?? d.exchangeRate ?? 1,
675
- tvl: d.tvl ?? 0
676
- };
677
- }
678
- async function buildStakeVSuiTx(_client, address, amountMist) {
679
- if (amountMist < MIN_STAKE_MIST) {
680
- throw new Error(`Minimum stake is 1 SUI (${MIN_STAKE_MIST} MIST). Got: ${amountMist}`);
681
- }
682
- const tx = new Transaction();
683
- tx.setSender(address);
684
- const [suiCoin] = tx.splitCoins(tx.gas, [amountMist]);
685
- const [vSuiCoin] = tx.moveCall({
686
- target: `${VOLO_PKG}::stake_pool::stake`,
687
- arguments: [
688
- tx.object(VOLO_POOL),
689
- tx.object(VOLO_METADATA),
690
- tx.object(SUI_SYSTEM_STATE),
691
- suiCoin
692
- ]
693
- });
694
- tx.transferObjects([vSuiCoin], address);
695
- return tx;
696
- }
697
- async function buildUnstakeVSuiTx(client, address, amountMist) {
698
- const balResp = await client.getBalance({ owner: address, coinType: VSUI_TYPE });
699
- const totalBalance = BigInt(balResp.totalBalance);
700
- if (totalBalance === 0n) {
701
- throw new Error("No vSUI found in wallet.");
702
- }
703
- const tx = new Transaction();
704
- tx.setSender(address);
705
- const requested = amountMist === "all" ? totalBalance : amountMist;
706
- if (requested > totalBalance) {
707
- throw new Error(`Insufficient vSUI: need ${requested} MIST, have ${totalBalance}`);
708
- }
709
- const vSuiCoin = coinWithBalance({ type: VSUI_TYPE, balance: requested })(tx);
710
- const [suiCoin] = tx.moveCall({
711
- target: `${VOLO_PKG}::stake_pool::unstake`,
712
- arguments: [
713
- tx.object(VOLO_POOL),
714
- tx.object(VOLO_METADATA),
715
- tx.object(SUI_SYSTEM_STATE),
716
- vSuiCoin
717
- ]
718
- });
719
- tx.transferObjects([suiCoin], address);
720
- return tx;
721
- }
722
- async function addStakeVSuiToTx(tx, client, address, input) {
723
- if (input.amountMist < MIN_STAKE_MIST) {
724
- throw new Error(`Minimum stake is 1 SUI (${MIN_STAKE_MIST} MIST). Got: ${input.amountMist}`);
725
- }
726
- let suiCoin;
727
- if (input.inputCoin) {
728
- suiCoin = input.inputCoin;
729
- } else {
730
- const balResp = await client.getBalance({ owner: address, coinType: SUI_TYPE });
731
- const totalBalance = BigInt(balResp.totalBalance);
732
- if (totalBalance < input.amountMist) {
733
- throw new Error(`Insufficient SUI: need ${input.amountMist} MIST, have ${totalBalance}`);
734
- }
735
- suiCoin = coinWithBalance({
736
- type: SUI_TYPE,
737
- balance: input.amountMist,
738
- useGasCoin: false
739
- })(tx);
740
- }
741
- const [vSuiCoin] = tx.moveCall({
742
- target: `${VOLO_PKG}::stake_pool::stake`,
743
- arguments: [
744
- tx.object(VOLO_POOL),
745
- tx.object(VOLO_METADATA),
746
- tx.object(SUI_SYSTEM_STATE),
747
- suiCoin
748
- ]
749
- });
750
- return { coin: vSuiCoin, effectiveAmountMist: input.amountMist };
751
- }
752
- async function addUnstakeVSuiToTx(tx, client, address, input) {
753
- let vSuiCoin;
754
- if (input.inputCoin) {
755
- if (input.amountMist === "all") {
756
- vSuiCoin = input.inputCoin;
757
- } else {
758
- [vSuiCoin] = tx.splitCoins(input.inputCoin, [input.amountMist]);
759
- }
760
- } else {
761
- const balResp = await client.getBalance({ owner: address, coinType: VSUI_TYPE });
762
- const totalBalance = BigInt(balResp.totalBalance);
763
- if (totalBalance === 0n) {
764
- throw new Error("No vSUI found in wallet.");
765
- }
766
- const requested = input.amountMist === "all" ? totalBalance : input.amountMist;
767
- if (requested > totalBalance) {
768
- throw new Error(`Insufficient vSUI: need ${requested} MIST, have ${totalBalance}`);
769
- }
770
- vSuiCoin = coinWithBalance({ type: VSUI_TYPE, balance: requested })(tx);
771
- }
772
- const [suiCoin] = tx.moveCall({
773
- target: `${VOLO_PKG}::stake_pool::unstake`,
774
- arguments: [
775
- tx.object(VOLO_POOL),
776
- tx.object(VOLO_METADATA),
777
- tx.object(SUI_SYSTEM_STATE),
778
- vSuiCoin
779
- ]
780
- });
781
- return { coin: suiCoin, effectiveAmountMist: input.amountMist };
782
- }
783
- var VOLO_PKG, VOLO_POOL, VOLO_METADATA, VSUI_TYPE, SUI_SYSTEM_STATE, MIN_STAKE_MIST, VOLO_STATS_URL;
784
- var init_volo = __esm({
785
- "src/protocols/volo.ts"() {
786
- init_token_registry();
787
- VOLO_PKG = "0x68d22cf8bdbcd11ecba1e094922873e4080d4d11133e2443fddda0bfd11dae20";
788
- VOLO_POOL = "0x2d914e23d82fedef1b5f56a32d5c64bdcc3087ccfea2b4d6ea51a71f587840e5";
789
- VOLO_METADATA = "0x680cd26af32b2bde8d3361e804c53ec1d1cfe24c7f039eb7f549e8dfde389a60";
790
- VSUI_TYPE = "0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT";
791
- SUI_SYSTEM_STATE = "0x05";
792
- MIN_STAKE_MIST = 1000000000n;
793
- VOLO_STATS_URL = "https://open-api.naviprotocol.io/api/volo/stats";
794
- }
795
- });
796
-
797
648
  // src/wallet/coinSelection.ts
798
649
  var coinSelection_exports = {};
799
650
  __export(coinSelection_exports, {
@@ -1271,7 +1122,7 @@ var OPERATION_ASSETS = {
1271
1122
  borrow: ["USDC", "USDsui"],
1272
1123
  withdraw: "*",
1273
1124
  repay: "*",
1274
- send: "*",
1125
+ send: ["USDC", "USDsui", "SUI"],
1275
1126
  swap: "*"
1276
1127
  };
1277
1128
  function isAllowedAsset(op, asset) {
@@ -1285,28 +1136,62 @@ function assertAllowedAsset(op, asset) {
1285
1136
  if (!isAllowedAsset(op, asset)) {
1286
1137
  const allowed = OPERATION_ASSETS[op];
1287
1138
  const list = Array.isArray(allowed) ? allowed.join(", ") : "any";
1139
+ const swapHint = op === "save" ? " Swap to USDC or USDsui first." : op === "send" ? " Swap to USDC or USDsui first, or send SUI." : "";
1288
1140
  throw new T2000Error(
1289
1141
  "INVALID_ASSET",
1290
- `${op} only supports ${list}. Cannot use ${asset}.${op === "save" ? " Swap to USDC or USDsui first." : ""}`
1142
+ `${op} only supports ${list}. Cannot use ${asset}.${swapHint}`
1291
1143
  );
1292
1144
  }
1293
1145
  }
1146
+ var SENDABLE_ASSETS = ["USDC", "USDsui", "SUI"];
1147
+ var GASLESS_STABLE_TYPES = {
1148
+ USDC: SUPPORTED_ASSETS.USDC.type,
1149
+ USDsui: SUPPORTED_ASSETS.USDsui.type
1150
+ };
1294
1151
  var T2000_OVERLAY_FEE_WALLET = process.env.T2000_OVERLAY_FEE_WALLET ?? "0x5366efbf2b4fe5767fe2e78eb197aa5f5d138d88ac3333fbf3f80a1927da473a";
1295
1152
  var DEFAULT_NETWORK = "mainnet";
1296
1153
  var DEFAULT_RPC_URL = "https://fullnode.mainnet.sui.io:443";
1154
+ var DEFAULT_GRPC_URL = "https://fullnode.mainnet.sui.io:443";
1297
1155
  var DEFAULT_KEY_PATH = "~/.t2000/wallet.key";
1156
+ var GASLESS_MIN_STABLE_AMOUNT = 0.01;
1298
1157
  process.env.T2000_API_URL ?? "https://api.t2000.ai";
1299
1158
  var CETUS_USDC_SUI_POOL = "0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab";
1300
1159
  var GAS_RESERVE_MIN = 0.05;
1301
1160
 
1302
1161
  // src/utils/sui.ts
1303
1162
  init_errors();
1304
- var cachedClient = null;
1163
+ function resolveRpcUrl(rpcUrl) {
1164
+ if (rpcUrl) return rpcUrl;
1165
+ const envUrl = process.env.T2000_RPC_URL?.trim();
1166
+ if (envUrl) return envUrl;
1167
+ return DEFAULT_RPC_URL;
1168
+ }
1169
+ function resolveGrpcUrl(grpcUrl) {
1170
+ if (grpcUrl) return grpcUrl;
1171
+ const envUrl = process.env.T2000_GRPC_URL?.trim();
1172
+ if (envUrl) return envUrl;
1173
+ return DEFAULT_GRPC_URL;
1174
+ }
1175
+ var rpcClientCache = /* @__PURE__ */ new Map();
1305
1176
  function getSuiClient(rpcUrl) {
1306
- const url = rpcUrl ?? DEFAULT_RPC_URL;
1307
- if (cachedClient) return cachedClient;
1308
- cachedClient = new SuiJsonRpcClient({ url, network: "mainnet" });
1309
- return cachedClient;
1177
+ const url = resolveRpcUrl(rpcUrl);
1178
+ const cached = rpcClientCache.get(url);
1179
+ if (cached) return cached;
1180
+ const client = new SuiJsonRpcClient({ url, network: "mainnet" });
1181
+ rpcClientCache.set(url, client);
1182
+ return client;
1183
+ }
1184
+ function createSuiClient(network = "mainnet") {
1185
+ return new SuiJsonRpcClient({ url: getJsonRpcFullnodeUrl(network), network });
1186
+ }
1187
+ var grpcClientCache = /* @__PURE__ */ new Map();
1188
+ function getSuiGrpcClient(grpcUrl) {
1189
+ const baseUrl = resolveGrpcUrl(grpcUrl);
1190
+ const cached = grpcClientCache.get(baseUrl);
1191
+ if (cached) return cached;
1192
+ const client = new SuiGrpcClient({ baseUrl, network: "mainnet" });
1193
+ grpcClientCache.set(baseUrl, client);
1194
+ return client;
1310
1195
  }
1311
1196
  function validateAddress(address) {
1312
1197
  const normalized = normalizeSuiAddress(address);
@@ -1329,49 +1214,10 @@ function normalizeCoinType(coinType) {
1329
1214
 
1330
1215
  // src/wallet/keyManager.ts
1331
1216
  init_errors();
1332
- var ALGORITHM = "aes-256-gcm";
1333
- var SCRYPT_N = 2 ** 14;
1334
- var SCRYPT_R = 8;
1335
- var SCRYPT_P = 1;
1336
- var SALT_LENGTH = 32;
1337
- var IV_LENGTH = 16;
1338
1217
  function expandPath(p) {
1339
1218
  if (p.startsWith("~")) return resolve(homedir(), p.slice(2));
1340
1219
  return resolve(p);
1341
1220
  }
1342
- function deriveKey(passphrase, salt) {
1343
- return scryptSync(passphrase, salt, 32, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P });
1344
- }
1345
- function encrypt(data, passphrase) {
1346
- const salt = randomBytes(SALT_LENGTH);
1347
- const key = deriveKey(passphrase, salt);
1348
- const iv = randomBytes(IV_LENGTH);
1349
- const cipher = createCipheriv(ALGORITHM, key, iv);
1350
- const ciphertext = Buffer.concat([cipher.update(data), cipher.final()]);
1351
- const tag = cipher.getAuthTag();
1352
- return {
1353
- version: 1,
1354
- algorithm: ALGORITHM,
1355
- salt: salt.toString("hex"),
1356
- iv: iv.toString("hex"),
1357
- tag: tag.toString("hex"),
1358
- ciphertext: ciphertext.toString("hex")
1359
- };
1360
- }
1361
- function decrypt(encrypted, passphrase) {
1362
- const salt = Buffer.from(encrypted.salt, "hex");
1363
- const key = deriveKey(passphrase, salt);
1364
- const iv = Buffer.from(encrypted.iv, "hex");
1365
- const tag = Buffer.from(encrypted.tag, "hex");
1366
- const ciphertext = Buffer.from(encrypted.ciphertext, "hex");
1367
- const decipher = createDecipheriv(ALGORITHM, key, iv);
1368
- decipher.setAuthTag(tag);
1369
- try {
1370
- return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
1371
- } catch {
1372
- throw new T2000Error("WALLET_LOCKED", "Invalid PIN");
1373
- }
1374
- }
1375
1221
  function generateKeypair() {
1376
1222
  return Ed25519Keypair.generate();
1377
1223
  }
@@ -1383,7 +1229,7 @@ function keypairFromPrivateKey(privateKey) {
1383
1229
  const bytes = Buffer.from(privateKey.replace(/^0x/, ""), "hex");
1384
1230
  return Ed25519Keypair.fromSecretKey(bytes);
1385
1231
  }
1386
- async function saveKey(keypair, passphrase, keyPath) {
1232
+ async function saveKey(keypair, _passphrase, keyPath) {
1387
1233
  const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);
1388
1234
  try {
1389
1235
  await access(filePath);
@@ -1392,12 +1238,34 @@ async function saveKey(keypair, passphrase, keyPath) {
1392
1238
  if (error instanceof T2000Error) throw error;
1393
1239
  }
1394
1240
  await mkdir(dirname(filePath), { recursive: true });
1395
- const bech32Key = keypair.getSecretKey();
1396
- const encrypted = encrypt(Buffer.from(bech32Key, "utf-8"), passphrase);
1397
- await writeFile(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
1241
+ const payload = {
1242
+ version: 2,
1243
+ secret: keypair.getSecretKey()
1244
+ };
1245
+ await writeFile(filePath, JSON.stringify(payload, null, 2), { mode: 384 });
1398
1246
  return filePath;
1399
1247
  }
1400
- async function loadKey(passphrase, keyPath) {
1248
+ async function saveBech32(secret, keyPath) {
1249
+ if (!secret.startsWith("suiprivkey")) {
1250
+ throw new T2000Error(
1251
+ "INVALID_KEY",
1252
+ `Secret must be a Bech32 suiprivkey1... string. Got: ${secret.slice(0, 12)}...`
1253
+ );
1254
+ }
1255
+ decodeSuiPrivateKey(secret);
1256
+ const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);
1257
+ try {
1258
+ await access(filePath);
1259
+ throw new T2000Error("WALLET_EXISTS", `Wallet already exists at ${filePath}`);
1260
+ } catch (error) {
1261
+ if (error instanceof T2000Error) throw error;
1262
+ }
1263
+ await mkdir(dirname(filePath), { recursive: true });
1264
+ const payload = { version: 2, secret };
1265
+ await writeFile(filePath, JSON.stringify(payload, null, 2), { mode: 384 });
1266
+ return filePath;
1267
+ }
1268
+ async function loadKey(_passphrase, keyPath) {
1401
1269
  const filePath = expandPath(keyPath ?? DEFAULT_KEY_PATH);
1402
1270
  let content;
1403
1271
  try {
@@ -1405,10 +1273,22 @@ async function loadKey(passphrase, keyPath) {
1405
1273
  } catch {
1406
1274
  throw new T2000Error("WALLET_NOT_FOUND", `No wallet found at ${filePath}`);
1407
1275
  }
1408
- const encrypted = JSON.parse(content);
1409
- const decrypted = decrypt(encrypted, passphrase);
1410
- const bech32Key = decrypted.toString("utf-8");
1411
- const decoded = decodeSuiPrivateKey(bech32Key);
1276
+ let parsed;
1277
+ try {
1278
+ parsed = JSON.parse(content);
1279
+ } catch {
1280
+ throw new T2000Error(
1281
+ "WALLET_CORRUPT",
1282
+ `Wallet file at ${filePath} is not a valid v4 wallet. Move or delete the file, then run \`t2 init\`.`
1283
+ );
1284
+ }
1285
+ if (!isPlainKey(parsed)) {
1286
+ throw new T2000Error(
1287
+ "WALLET_CORRUPT",
1288
+ `Wallet file at ${filePath} is not a valid v4 wallet. Expected { version: 2, secret: "suiprivkey1..." }. Move or delete the file, then run \`t2 init\`.`
1289
+ );
1290
+ }
1291
+ const decoded = decodeSuiPrivateKey(parsed.secret);
1412
1292
  return Ed25519Keypair.fromSecretKey(decoded.secretKey);
1413
1293
  }
1414
1294
  async function walletExists(keyPath) {
@@ -1426,6 +1306,9 @@ function exportPrivateKey(keypair) {
1426
1306
  function getAddress(keypair) {
1427
1307
  return keypair.getPublicKey().toSuiAddress();
1428
1308
  }
1309
+ function isPlainKey(value) {
1310
+ return typeof value === "object" && value !== null && value.version === 2 && typeof value.secret === "string";
1311
+ }
1429
1312
 
1430
1313
  // src/wallet/keypairSigner.ts
1431
1314
  var KeypairSigner = class {
@@ -1533,12 +1416,19 @@ async function buildSendTx({
1533
1416
  address,
1534
1417
  to,
1535
1418
  amount,
1536
- asset = "USDC"
1419
+ asset
1537
1420
  }) {
1421
+ assertAllowedAsset("send", asset);
1538
1422
  const recipient = validateAddress(to);
1539
1423
  const assetInfo = SUPPORTED_ASSETS[asset];
1540
1424
  if (!assetInfo) throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
1541
1425
  if (amount <= 0) throw new T2000Error("INVALID_AMOUNT", "Amount must be greater than zero");
1426
+ if ((asset === "USDC" || asset === "USDsui") && amount < GASLESS_MIN_STABLE_AMOUNT) {
1427
+ throw new T2000Error(
1428
+ "INVALID_AMOUNT",
1429
+ `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${asset}. Got ${amount}.`
1430
+ );
1431
+ }
1542
1432
  const rawAmount = displayToRaw(amount, assetInfo.decimals);
1543
1433
  const tx = new Transaction();
1544
1434
  tx.setSender(address);
@@ -1550,8 +1440,20 @@ async function buildSendTx({
1550
1440
  required: amount
1551
1441
  });
1552
1442
  }
1553
- const sendCoin = asset === "SUI" ? tx.splitCoins(tx.gas, [rawAmount])[0] : coinWithBalance({ type: assetInfo.type, balance: rawAmount })(tx);
1554
- tx.transferObjects([sendCoin], recipient);
1443
+ if (asset === "SUI") {
1444
+ const [sendCoin] = tx.splitCoins(tx.gas, [rawAmount]);
1445
+ tx.transferObjects([sendCoin], recipient);
1446
+ return tx;
1447
+ }
1448
+ const coinType = GASLESS_STABLE_TYPES[asset];
1449
+ tx.moveCall({
1450
+ target: "0x2::balance::send_funds",
1451
+ typeArguments: [coinType],
1452
+ arguments: [
1453
+ tx.balance({ type: coinType, balance: rawAmount }),
1454
+ tx.pure.address(recipient)
1455
+ ]
1456
+ });
1555
1457
  return tx;
1556
1458
  }
1557
1459
  function addSendToTx(tx, coin, recipient) {
@@ -6521,8 +6423,7 @@ var ContactManager = class {
6521
6423
  "CONTACT_NOT_FOUND",
6522
6424
  `"${nameOrAddress}" is not a valid Sui address or saved contact.
6523
6425
  Use a SuiNS name (e.g. alex.sui \u2014 register at https://suins.io)
6524
- or paste the full Sui address (0x... 64 hex characters).
6525
- Legacy contact aliases: \`t2000 contacts add ${nameOrAddress} 0x...\` (deprecated).`
6426
+ or paste the full Sui address (0x... 64 hex characters).`
6526
6427
  );
6527
6428
  }
6528
6429
  validateName(name) {
@@ -6594,20 +6495,16 @@ var T2000 = class _T2000 extends EventEmitter {
6594
6495
  return registry;
6595
6496
  }
6596
6497
  static async create(options = {}) {
6597
- const { keyPath, pin, passphrase, rpcUrl } = options;
6598
- const secret = pin ?? passphrase;
6498
+ const { keyPath, rpcUrl } = options;
6599
6499
  const client = getSuiClient(rpcUrl);
6600
6500
  const exists = await walletExists(keyPath);
6601
6501
  if (!exists) {
6602
6502
  throw new T2000Error(
6603
6503
  "WALLET_NOT_FOUND",
6604
- "No wallet found. Run `t2000 init` to create one."
6504
+ "No wallet found. Run `t2 init` to create one."
6605
6505
  );
6606
6506
  }
6607
- if (!secret) {
6608
- throw new T2000Error("WALLET_LOCKED", "PIN required to unlock wallet");
6609
- }
6610
- const keypair = await loadKey(secret, keyPath);
6507
+ const keypair = await loadKey(void 0, keyPath);
6611
6508
  return new _T2000(keypair, client, void 0, DEFAULT_CONFIG_DIR);
6612
6509
  }
6613
6510
  static fromPrivateKey(privateKey, options = {}) {
@@ -6615,10 +6512,9 @@ var T2000 = class _T2000 extends EventEmitter {
6615
6512
  const client = getSuiClient(options.rpcUrl);
6616
6513
  return new _T2000(keypair, client);
6617
6514
  }
6618
- static async init(options) {
6619
- const secret = options.pin ?? options.passphrase ?? "";
6515
+ static async init(options = {}) {
6620
6516
  const keypair = generateKeypair();
6621
- await saveKey(keypair, secret, options.keyPath);
6517
+ await saveKey(keypair, void 0, options.keyPath);
6622
6518
  const client = getSuiClient();
6623
6519
  const agent = new _T2000(keypair, client, void 0, DEFAULT_CONFIG_DIR);
6624
6520
  const address = agent.address();
@@ -6646,7 +6542,7 @@ var T2000 = class _T2000 extends EventEmitter {
6646
6542
  this.enforcer.check({ operation: "pay", amount: options.maxPrice ?? 1 });
6647
6543
  const { Mppx } = await import('mppx/client');
6648
6544
  const { sui, USDC } = await import('@suimpp/mpp/client');
6649
- const { SuiGrpcClient } = await import('@mysten/sui/grpc');
6545
+ const { SuiGrpcClient: SuiGrpcClient2 } = await import('@mysten/sui/grpc');
6650
6546
  const client = this.client;
6651
6547
  const signer = this._signer;
6652
6548
  const signerAddress = signer.getAddress();
@@ -6654,7 +6550,7 @@ var T2000 = class _T2000 extends EventEmitter {
6654
6550
  let gasCostSui = 0;
6655
6551
  const network = client.network === "testnet" ? "testnet" : "mainnet";
6656
6552
  const grpcBaseUrl = network === "testnet" ? "https://fullnode.testnet.sui.io" : "https://fullnode.mainnet.sui.io";
6657
- const grpcClient = new SuiGrpcClient({ baseUrl: grpcBaseUrl, network });
6553
+ const grpcClient = new SuiGrpcClient2({ baseUrl: grpcBaseUrl, network });
6658
6554
  const mppx = Mppx.create({
6659
6555
  polyfill: false,
6660
6556
  methods: [sui({
@@ -6699,51 +6595,14 @@ var T2000 = class _T2000 extends EventEmitter {
6699
6595
  receipt: paymentDigest ? { reference: paymentDigest, timestamp: (/* @__PURE__ */ new Date()).toISOString() } : void 0
6700
6596
  };
6701
6597
  }
6702
- // -- VOLO vSUI Staking --
6703
- async stakeVSui(params) {
6704
- this.enforcer.assertNotLocked();
6705
- const { buildStakeVSuiTx: buildStakeVSuiTx2, getVoloStats: getVoloStats2 } = await Promise.resolve().then(() => (init_volo(), volo_exports));
6706
- const amountMist = BigInt(Math.floor(params.amount * Number(MIST_PER_SUI)));
6707
- const stats = await getVoloStats2();
6708
- const gasResult = await executeTx(this.client, this._signer, async () => {
6709
- return buildStakeVSuiTx2(this.client, this._address, amountMist);
6710
- });
6711
- const vSuiReceived = params.amount / stats.exchangeRate;
6712
- return {
6713
- success: true,
6714
- tx: gasResult.digest,
6715
- amountSui: params.amount,
6716
- vSuiReceived,
6717
- apy: stats.apy,
6718
- gasCost: gasResult.gasCostSui
6719
- };
6720
- }
6721
- async unstakeVSui(params) {
6722
- this.enforcer.assertNotLocked();
6723
- const { buildUnstakeVSuiTx: buildUnstakeVSuiTx2, getVoloStats: getVoloStats2, VSUI_TYPE: VSUI_TYPE2 } = await Promise.resolve().then(() => (init_volo(), volo_exports));
6724
- let amountMist;
6725
- let vSuiAmount;
6726
- if (params.amount === "all") {
6727
- amountMist = "all";
6728
- const bal = await this.client.getBalance({ owner: this._address, coinType: VSUI_TYPE2 });
6729
- vSuiAmount = Number(bal.totalBalance) / 1e9;
6730
- } else {
6731
- amountMist = BigInt(Math.floor(params.amount * 1e9));
6732
- vSuiAmount = params.amount;
6733
- }
6734
- const stats = await getVoloStats2();
6735
- const gasResult = await executeTx(this.client, this._signer, async () => {
6736
- return buildUnstakeVSuiTx2(this.client, this._address, amountMist);
6737
- });
6738
- const suiReceived = vSuiAmount * stats.exchangeRate;
6739
- return {
6740
- success: true,
6741
- tx: gasResult.digest,
6742
- vSuiAmount,
6743
- suiReceived,
6744
- gasCost: gasResult.gasCostSui
6745
- };
6746
- }
6598
+ // [S.323 / 2026-05-25] VOLO vSUI staking surfaces removed (full cut).
6599
+ // Engine cut Volo in S.277; SDK + CLI + MCP followed in S.323 because the
6600
+ // product surface (five products: Passport / Intelligence / Finance / Pay
6601
+ // / Store) doesn't include a staking primitive. vSUI still appears in the
6602
+ // codebase as a passive token (NAVI reward rewards, Cetus swap routing),
6603
+ // but there is no longer any way to MINT or REDEEM vSUI through t2000.
6604
+ // History: see spec/archive/v07e/AUDIT_V07E_EARNS_ITS_KEEP_2026-05-23.md
6605
+ // and the S.323 build-tracker entry.
6747
6606
  // -- Swap --
6748
6607
  async swap(params) {
6749
6608
  this.enforcer.assertNotLocked();
@@ -6874,23 +6733,52 @@ var T2000 = class _T2000 extends EventEmitter {
6874
6733
  address() {
6875
6734
  return this._address;
6876
6735
  }
6736
+ /**
6737
+ * Send `amount` of `asset` to `to` (hex address, SuiNS name, or
6738
+ * `@audric` handle / saved contact).
6739
+ *
6740
+ * [v4.0 Phase A Day 2 — SPEC_AGENT_WALLET_GREENFIELD §A]
6741
+ *
6742
+ * **Breaking changes from v3.x:**
6743
+ * - `asset` is now REQUIRED (no implicit `?? 'USDC'` default). Callers
6744
+ * must specify `'USDC' | 'USDsui' | 'SUI'`. Sending `'USDT'` /
6745
+ * `'USDe'` / `'WAL'` / `'ETH'` / `'NAVX'` / `'GOLD'` now errors
6746
+ * with `INVALID_ASSET` — swap to a stable first.
6747
+ * - USDC + USDsui builds go through `SuiGrpcClient` so the gRPC build
6748
+ * resolver auto-detects `0x2::balance::send_funds` eligibility and
6749
+ * zeros gas at simulate time. Result: **gasless USDC / USDsui sends
6750
+ * from a zero-SUI wallet.** SUI sends stay on the standard gas-paid
6751
+ * path.
6752
+ *
6753
+ * Submission stays on the JSON-RPC client (the rest of the SDK
6754
+ * expects JSON-RPC for read paths, and Sui's docs explicitly support
6755
+ * the "build via gRPC, execute via JSON-RPC" hybrid).
6756
+ */
6877
6757
  async send(params) {
6878
6758
  this.enforcer.assertNotLocked();
6879
- const asset = params.asset ?? "USDC";
6880
- if (!(asset in SUPPORTED_ASSETS)) {
6881
- throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
6759
+ const asset = params.asset;
6760
+ if (!asset) {
6761
+ throw new T2000Error(
6762
+ "INVALID_ASSET",
6763
+ "send() requires an explicit asset. Use one of: USDC, USDsui, SUI."
6764
+ );
6882
6765
  }
6766
+ assertAllowedAsset("send", asset);
6767
+ const sendableAsset = asset;
6883
6768
  const resolved = await this.resolveRecipient(params.to);
6884
6769
  const sendAmount = params.amount;
6885
6770
  const sendTo = resolved.address;
6771
+ const useGrpc = sendableAsset === "USDC" || sendableAsset === "USDsui";
6772
+ const buildClient = useGrpc ? getSuiGrpcClient() : void 0;
6886
6773
  const gasResult = await executeTx(
6887
6774
  this.client,
6888
6775
  this._signer,
6889
- () => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset })
6776
+ () => buildSendTx({ client: this.client, address: this._address, to: sendTo, amount: sendAmount, asset: sendableAsset }),
6777
+ { buildClient }
6890
6778
  );
6891
6779
  this.enforcer.recordUsage(sendAmount);
6892
6780
  const balance = await this.balance();
6893
- this.emitBalanceChange(asset, sendAmount, "send", gasResult.digest);
6781
+ this.emitBalanceChange(sendableAsset, sendAmount, "send", gasResult.digest);
6894
6782
  return {
6895
6783
  success: true,
6896
6784
  tx: gasResult.digest,
@@ -7000,11 +6888,12 @@ var T2000 = class _T2000 extends EventEmitter {
7000
6888
  };
7001
6889
  }
7002
6890
  /**
7003
- * [SPEC_AGENTIC_STACK P1 / SDK F2 (CLI rename support) 2026-05-25]
7004
- * Preferred alias of `deposit()`. The CLI surface is `t2000 fund` post-Phase 1
7005
- * (more intuitive than "deposit" which sounds like a NAVI lending action).
7006
- * `deposit()` stays as the canonical method name for back-compat; it is NOT
7007
- * deprecated. This wrapper exists so SDK consumers can mirror CLI naming.
6891
+ * [SPEC_AGENTIC_STACK P1 / SDK F2 2026-05-25; refreshed S.342 / 2026-05-26]
6892
+ * Preferred alias of `deposit()`. Was introduced to mirror the v3 `t2000 fund`
6893
+ * CLI command; the v4 CLI surface is `t2 receive` (deleted `fund` in the
6894
+ * S.332 bulk cut). `deposit()` stays as the canonical method name for
6895
+ * back-compat; `fund()` stays as a programmatic alias for audric + other
6896
+ * SDK consumers that prefer the verb.
7008
6897
  */
7009
6898
  async fund() {
7010
6899
  return this.deposit();
@@ -7339,7 +7228,7 @@ var T2000 = class _T2000 extends EventEmitter {
7339
7228
  const adapter = await this.resolveLending(params.protocol, asset, "borrow");
7340
7229
  const maxResult = await adapter.maxBorrow(this._address, asset);
7341
7230
  if (maxResult.maxAmount <= 0) {
7342
- throw new T2000Error("NO_COLLATERAL", "No collateral deposited. Save first with `t2000 save <amount>`.");
7231
+ throw new T2000Error("NO_COLLATERAL", "No collateral deposited. Make a save deposit first.");
7343
7232
  }
7344
7233
  if (params.amount > maxResult.maxAmount) {
7345
7234
  throw new T2000Error("HEALTH_FACTOR_TOO_LOW", `Max safe borrow: $${maxResult.maxAmount.toFixed(2)}. Only savings deposits count as borrowable collateral.`, {
@@ -7970,7 +7859,6 @@ async function buildHarvestRewardsTx(client, address, options = {}) {
7970
7859
 
7971
7860
  // src/composeTx.ts
7972
7861
  init_cetus_swap();
7973
- init_volo();
7974
7862
  init_coinSelection();
7975
7863
  init_token_registry();
7976
7864
  init_errors();
@@ -8098,34 +7986,68 @@ var WRITE_APPENDER_REGISTRY = {
8098
7986
  },
8099
7987
  send_transfer: async (tx, input, ctx) => {
8100
7988
  const recipient = validateAddress(input.to);
8101
- const asset = input.asset ?? "USDC";
8102
- const assetInfo = SUPPORTED_ASSETS[asset];
8103
- if (!assetInfo) {
8104
- throw new T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
7989
+ if (!input.asset) {
7990
+ throw new T2000Error(
7991
+ "INVALID_ASSET",
7992
+ "send_transfer requires an explicit asset. Use one of: USDC, USDsui, SUI."
7993
+ );
8105
7994
  }
7995
+ assertAllowedAsset("send", input.asset);
7996
+ const asset = input.asset;
7997
+ const assetInfo = SUPPORTED_ASSETS[asset];
8106
7998
  if (input.amount <= 0) {
8107
7999
  throw new T2000Error("INVALID_AMOUNT", "Send amount must be greater than zero");
8108
8000
  }
8109
8001
  const rawAmount = BigInt(Math.floor(input.amount * 10 ** assetInfo.decimals));
8110
- let coin;
8111
- let effectiveRaw;
8112
8002
  if (ctx.chainedCoin) {
8113
- coin = ctx.chainedCoin;
8114
- effectiveRaw = rawAmount;
8115
- } else if (asset === "SUI") {
8003
+ addSendToTx(tx, ctx.chainedCoin, recipient);
8004
+ return {
8005
+ preview: {
8006
+ toolName: "send_transfer",
8007
+ effectiveAmount: Number(rawAmount) / 10 ** assetInfo.decimals,
8008
+ recipient,
8009
+ asset
8010
+ }
8011
+ };
8012
+ }
8013
+ if (asset === "SUI") {
8116
8014
  const result = await selectSuiCoin(tx, ctx.client, ctx.sender, rawAmount, ctx.sponsoredContext);
8117
- coin = result.coin;
8118
- effectiveRaw = result.effectiveAmount;
8119
- } else {
8120
- const result = await selectAndSplitCoin(tx, ctx.client, ctx.sender, assetInfo.type, rawAmount);
8121
- coin = result.coin;
8122
- effectiveRaw = result.effectiveAmount;
8015
+ addSendToTx(tx, result.coin, recipient);
8016
+ return {
8017
+ preview: {
8018
+ toolName: "send_transfer",
8019
+ effectiveAmount: Number(result.effectiveAmount) / 10 ** assetInfo.decimals,
8020
+ recipient,
8021
+ asset
8022
+ }
8023
+ };
8024
+ }
8025
+ if (input.amount < GASLESS_MIN_STABLE_AMOUNT) {
8026
+ throw new T2000Error(
8027
+ "INVALID_AMOUNT",
8028
+ `Minimum gasless transfer is ${GASLESS_MIN_STABLE_AMOUNT} ${asset}. Got ${input.amount}.`
8029
+ );
8030
+ }
8031
+ const balanceResp = await ctx.client.getBalance({ owner: ctx.sender, coinType: assetInfo.type });
8032
+ if (BigInt(balanceResp.totalBalance) < rawAmount) {
8033
+ throw new T2000Error("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, {
8034
+ available: Number(balanceResp.totalBalance) / 10 ** assetInfo.decimals,
8035
+ required: input.amount
8036
+ });
8123
8037
  }
8124
- addSendToTx(tx, coin, recipient);
8038
+ const coinType = GASLESS_STABLE_TYPES[asset];
8039
+ tx.moveCall({
8040
+ target: "0x2::balance::send_funds",
8041
+ typeArguments: [coinType],
8042
+ arguments: [
8043
+ tx.balance({ type: coinType, balance: rawAmount }),
8044
+ tx.pure.address(recipient)
8045
+ ]
8046
+ });
8125
8047
  return {
8126
8048
  preview: {
8127
8049
  toolName: "send_transfer",
8128
- effectiveAmount: Number(effectiveRaw) / 10 ** assetInfo.decimals,
8050
+ effectiveAmount: Number(rawAmount) / 10 ** assetInfo.decimals,
8129
8051
  recipient,
8130
8052
  asset
8131
8053
  }
@@ -8194,63 +8116,46 @@ var WRITE_APPENDER_REGISTRY = {
8194
8116
  expectedUsdcDeposited: plan.expectedUsdcDeposited
8195
8117
  }
8196
8118
  };
8197
- },
8198
- volo_stake: async (tx, input, ctx) => {
8199
- if (input.amountSui <= 0) {
8200
- throw new T2000Error("INVALID_AMOUNT", "Stake amount must be greater than zero");
8201
- }
8202
- const amountMist = BigInt(Math.floor(input.amountSui * 1e9));
8203
- const result = await addStakeVSuiToTx(tx, ctx.client, ctx.sender, {
8204
- amountMist,
8205
- inputCoin: ctx.chainedCoin
8206
- });
8207
- if (!ctx.isOutputConsumed) {
8208
- tx.transferObjects([result.coin], ctx.sender);
8209
- }
8210
- return {
8211
- preview: { toolName: "volo_stake", effectiveAmountMist: result.effectiveAmountMist },
8212
- outputCoin: result.coin
8213
- };
8214
- },
8215
- volo_unstake: async (tx, input, ctx) => {
8216
- const amountMist = input.amountVSui === "all" ? "all" : BigInt(Math.floor(input.amountVSui * 1e9));
8217
- if (amountMist !== "all" && amountMist <= 0n) {
8218
- throw new T2000Error("INVALID_AMOUNT", "Unstake amount must be greater than zero");
8219
- }
8220
- const result = await addUnstakeVSuiToTx(tx, ctx.client, ctx.sender, {
8221
- amountMist,
8222
- inputCoin: ctx.chainedCoin
8223
- });
8224
- if (!ctx.isOutputConsumed) {
8225
- tx.transferObjects([result.coin], ctx.sender);
8226
- }
8227
- return {
8228
- preview: { toolName: "volo_unstake", effectiveAmountMist: result.effectiveAmountMist },
8229
- outputCoin: result.coin
8230
- };
8231
8119
  }
8120
+ // [S.323 / 2026-05-25] volo_stake / volo_unstake appenders removed.
8232
8121
  };
8233
8122
  function deriveAllowedAddressesFromPtb(tx) {
8234
8123
  const addresses = /* @__PURE__ */ new Set();
8235
8124
  const data = tx.getData();
8236
- for (const cmd of data.commands) {
8237
- const transferCmd = cmd.TransferObjects;
8238
- if (!transferCmd) continue;
8239
- const addressArg = transferCmd.address;
8240
- if (!addressArg) continue;
8241
- const addressInputIndex = addressArg.Input;
8242
- if (addressInputIndex === void 0) continue;
8243
- const input = data.inputs[addressInputIndex];
8244
- if (!input) continue;
8125
+ const addAddressFromInput = (inputIndex) => {
8126
+ if (inputIndex === void 0) return;
8127
+ const input = data.inputs[inputIndex];
8128
+ if (!input) return;
8245
8129
  const pureBytes = input.Pure?.bytes;
8246
- if (!pureBytes) continue;
8130
+ if (!pureBytes) return;
8247
8131
  try {
8248
8132
  const bytes = base64ToBytes(pureBytes);
8249
- if (bytes.length !== 32) continue;
8133
+ if (bytes.length !== 32) return;
8250
8134
  const hex = "0x" + Array.from(bytes).map((b2) => b2.toString(16).padStart(2, "0")).join("");
8251
8135
  addresses.add(hex);
8252
8136
  } catch {
8253
8137
  }
8138
+ };
8139
+ for (const cmd of data.commands) {
8140
+ const transferCmd = cmd.TransferObjects;
8141
+ if (transferCmd) {
8142
+ const addressArg = transferCmd.address;
8143
+ const addressInputIndex = addressArg?.Input;
8144
+ addAddressFromInput(addressInputIndex);
8145
+ continue;
8146
+ }
8147
+ const moveCall = cmd.MoveCall;
8148
+ if (moveCall) {
8149
+ const mc = moveCall;
8150
+ const isBalanceSendFunds = mc.module === "balance" && mc.function === "send_funds";
8151
+ const isCoinSendFunds = mc.module === "coin" && mc.function === "send_funds";
8152
+ if (isBalanceSendFunds || isCoinSendFunds) {
8153
+ const args = mc.arguments ?? [];
8154
+ const recipientArg = args[1];
8155
+ addAddressFromInput(recipientArg?.Input);
8156
+ }
8157
+ continue;
8158
+ }
8254
8159
  }
8255
8160
  return Array.from(addresses);
8256
8161
  }
@@ -8289,7 +8194,7 @@ async function composeTx(opts) {
8289
8194
  if (producer.toolName === "save_deposit" || producer.toolName === "repay_debt" || producer.toolName === "send_transfer" || producer.toolName === "claim_rewards") {
8290
8195
  throw new T2000Error(
8291
8196
  "CHAIN_MODE_INVALID",
8292
- `Step ${i} (${step.toolName}) references step ${idx} (${producer.toolName}) as producer, but '${producer.toolName}' is a terminal consumer that does not produce a chainable coin handle. Allowed producers: withdraw, borrow, swap_execute, volo_stake, volo_unstake.`
8197
+ `Step ${i} (${step.toolName}) references step ${idx} (${producer.toolName}) as producer, but '${producer.toolName}' is a terminal consumer that does not produce a chainable coin handle. Allowed producers: withdraw, borrow, swap_execute.`
8293
8198
  );
8294
8199
  }
8295
8200
  consumedSteps.add(idx);
@@ -8509,7 +8414,6 @@ function parseMoveAbort(errorStr) {
8509
8414
  init_swap_quote();
8510
8415
  init_cetus_swap();
8511
8416
  init_token_registry();
8512
- init_volo();
8513
8417
  var AUDRIC_PARENT_NAME = "audric.sui";
8514
8418
  var AUDRIC_PARENT_NFT_ID = "0x070456e283ec988b6302bdd6cc5172bbdcb709998cf116586fb98d19b0870198";
8515
8419
  var LABEL_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
@@ -8577,6 +8481,6 @@ function displayHandle(label) {
8577
8481
  (*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
8578
8482
  */
8579
8483
 
8580
- export { ALL_NAVI_ASSETS, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, BORROW_FEE_BPS, BPS_DENOMINATOR, CETUS_USDC_SUI_POOL, CLOCK_ID, COIN_REGISTRY, ContactManager, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, ETH_TYPE, GAS_RESERVE_MIN, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, IKA_TYPE, InvalidAddressError, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, MANIFEST_TYPE, MIST_PER_SUI, NAVX_TYPE, NaviAdapter, OPERATION_ASSETS, OUTBOUND_OPS, OVERLAY_FEE_RATE, ProtocolRegistry, SAVEABLE_ASSETS, SAVE_FEE_BPS, SPONSORED_PYTH_DEPENDENT_PROVIDERS, STABLE_ASSETS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, SuinsNotRegisteredError, SuinsRpcError, T2000, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, VOLO_METADATA, VOLO_PKG, VOLO_POOL, VSUI_TYPE, WAL_TYPE, WBTC_TYPE, WRITE_APPENDER_REGISTRY, ZkLoginSigner, addClaimRewardsToTx, addFeeTransfer, addSendToTx, addStakeVSuiToTx, addSwapToTx, addUnstakeVSuiToTx, aggregateClaimableRewards, allDescriptors, assertAllowedAsset, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildStakeVSuiTx, buildSwapTx, buildUnstakeVSuiTx, calculateFee, classifyAction, classifyLabel, classifyTransaction, composeTx, deriveAllowedAddressesFromPtb, deserializeCetusRoute, displayHandle, exportPrivateKey, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, fetchAllCoins, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fullHandle, generateKeypair, getAddress, getCoinMeta, getDecimals, getDecimalsForCoinType, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSwapQuote, getTier, getVoloStats, isAllowedAsset, isCetusRouteFresh, isInRegistry, isSupported, isTier1, isTier2, keypairFromPrivateKey, loadKey, looksLikeSuiNs, mapMoveAbortCode, mapWalletError, mistToSui, naviDescriptor, normalizeAddressInput, normalizeAsset, normalizeCoinType, parseSuiRpcTx, queryHistory, queryTransaction, rawToStable, rawToUsdc, refineLendingLabel, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, resolveSymbol, resolveTokenType, saveKey, selectAndSplitCoin, selectSuiCoin, serializeCetusRoute, simulateTransaction, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, validateLabel, verifyCetusRouteCoinMatch, walletExists };
8484
+ export { ALL_NAVI_ASSETS, AUDRIC_PARENT_NAME, AUDRIC_PARENT_NFT_ID, BORROW_FEE_BPS, BPS_DENOMINATOR, CETUS_USDC_SUI_POOL, CLOCK_ID, COIN_REGISTRY, ContactManager, DEFAULT_GRPC_URL, DEFAULT_NETWORK, DEFAULT_SAFEGUARD_CONFIG, ETH_TYPE, GASLESS_MIN_STABLE_AMOUNT, GASLESS_STABLE_TYPES, GAS_RESERVE_MIN, HF_CRITICAL_THRESHOLD, HF_WARN_THRESHOLD, IKA_TYPE, InvalidAddressError, KNOWN_TARGETS, KeypairSigner, LABEL_PATTERNS, LOFI_TYPE, MANIFEST_TYPE, MIST_PER_SUI, NAVX_TYPE, NaviAdapter, OPERATION_ASSETS, OUTBOUND_OPS, OVERLAY_FEE_RATE, ProtocolRegistry, SAVEABLE_ASSETS, SAVE_FEE_BPS, SENDABLE_ASSETS, SPONSORED_PYTH_DEPENDENT_PROVIDERS, STABLE_ASSETS, SUINS_NAME_REGEX, SUI_ADDRESS_REGEX, SUI_ADDRESS_STRICT_REGEX, SUI_DECIMALS, SUI_TYPE, SUPPORTED_ASSETS, SafeguardEnforcer, SafeguardError, SuinsNotRegisteredError, SuinsRpcError, T2000, T2000Error, T2000_OVERLAY_FEE_WALLET, TOKEN_MAP, USDC_DECIMALS, USDC_TYPE, USDE_TYPE, USDSUI_TYPE, USDT_TYPE, WAL_TYPE, WBTC_TYPE, WRITE_APPENDER_REGISTRY, ZkLoginSigner, addClaimRewardsToTx, addFeeTransfer, addSendToTx, addSwapToTx, aggregateClaimableRewards, allDescriptors, assertAllowedAsset, buildAddLeafTx, buildClaimRewardsTx, buildHarvestRewardsTx, buildRevokeLeafTx, buildSendTx, buildSwapTx, calculateFee, classifyAction, classifyLabel, classifyTransaction, composeTx, createSuiClient, deriveAllowedAddressesFromPtb, deserializeCetusRoute, displayHandle, exportPrivateKey, extractAllUserLegs, extractTransferDetails, extractTxCommands, extractTxSender, fallbackLabel, fetchAllCoins, findSwapRoute, formatAssetAmount, formatSui, formatUsd, fullHandle, generateKeypair, getAddress, getCoinMeta, getDecimals, getDecimalsForCoinType, getFinancialSummary, getPendingRewards, getPendingRewardsByAddress, getRates, getSponsoredSwapProviders, getSuiClient, getSuiGrpcClient, getSwapQuote, getTier, isAllowedAsset, isCetusRouteFresh, isInRegistry, isSupported, isTier1, isTier2, keypairFromPrivateKey, loadKey, looksLikeSuiNs, mapMoveAbortCode, mapWalletError, mistToSui, naviDescriptor, normalizeAddressInput, normalizeAsset, normalizeCoinType, parseSuiRpcTx, queryHistory, queryTransaction, rawToStable, rawToUsdc, refineLendingLabel, resolveAddressToSuinsViaRpc, resolveSuinsViaRpc, resolveSymbol, resolveTokenType, saveBech32, saveKey, selectAndSplitCoin, selectSuiCoin, serializeCetusRoute, simulateTransaction, stableToRaw, suiToMist, throwIfSimulationFailed, truncateAddress, usdcToRaw, validateAddress, validateLabel, verifyCetusRouteCoinMatch, walletExists };
8581
8485
  //# sourceMappingURL=index.js.map
8582
8486
  //# sourceMappingURL=index.js.map