@t2000/sdk 2.18.1 → 2.19.1
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 +9 -4
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +1 -1
- package/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +202 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +146 -5
- package/dist/index.d.ts +146 -5
- package/dist/index.js +193 -3
- package/dist/index.js.map +1 -1
- package/dist/{types-I7U99DvG.d.cts → types-Bk7NncQ_.d.cts} +6 -0
- package/dist/{types-I7U99DvG.d.ts → types-Bk7NncQ_.d.ts} +6 -0
- package/dist/{types-BMdhu0D7.d.ts → types-CfBlFLmU.d.ts} +2 -2
- package/dist/{types-C2Va_r0h.d.cts → types-DOnXJXL2.d.cts} +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1805,6 +1805,132 @@ function extractCommands(txBlock) {
|
|
|
1805
1805
|
// src/t2000.ts
|
|
1806
1806
|
init_token_registry();
|
|
1807
1807
|
|
|
1808
|
+
// src/utils/suins.ts
|
|
1809
|
+
var SUI_MAINNET_URL = "https://fullnode.mainnet.sui.io:443";
|
|
1810
|
+
var SUI_ADDRESS_REGEX = /^0x[a-fA-F0-9]{1,64}$/i;
|
|
1811
|
+
var SUI_ADDRESS_STRICT_REGEX = /^0x[a-fA-F0-9]{64}$/i;
|
|
1812
|
+
var SUINS_NAME_REGEX = /^[a-z0-9-]+(\.[a-z0-9-]+)*\.sui$/;
|
|
1813
|
+
var InvalidAddressError = class extends Error {
|
|
1814
|
+
constructor(raw) {
|
|
1815
|
+
super(
|
|
1816
|
+
`"${raw}" isn't a valid Sui address or SuiNS name. Pass a 0x-prefixed hex address (e.g. 0x40cd\u20263e62) or a SuiNS name ending in .sui (e.g. alex.sui).`
|
|
1817
|
+
);
|
|
1818
|
+
this.raw = raw;
|
|
1819
|
+
this.name = "InvalidAddressError";
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
var SuinsNotRegisteredError = class extends Error {
|
|
1823
|
+
constructor(name_) {
|
|
1824
|
+
super(
|
|
1825
|
+
`"${name_}" isn't a registered SuiNS name. Double-check the spelling, or paste the full Sui address (0x\u2026 64 hex characters).`
|
|
1826
|
+
);
|
|
1827
|
+
this.name_ = name_;
|
|
1828
|
+
this.name = "SuinsNotRegisteredError";
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1831
|
+
var SuinsRpcError = class extends Error {
|
|
1832
|
+
constructor(name_, detail) {
|
|
1833
|
+
super(`SuiNS lookup failed for "${name_}" (${detail}). Try again, or paste the full Sui address.`);
|
|
1834
|
+
this.name_ = name_;
|
|
1835
|
+
this.name = "SuinsRpcError";
|
|
1836
|
+
}
|
|
1837
|
+
};
|
|
1838
|
+
function looksLikeSuiNs(value) {
|
|
1839
|
+
if (!value) return false;
|
|
1840
|
+
return SUINS_NAME_REGEX.test(value.trim().toLowerCase());
|
|
1841
|
+
}
|
|
1842
|
+
async function resolveSuinsViaRpc(rawName, ctx = {}) {
|
|
1843
|
+
const name = rawName.trim().toLowerCase();
|
|
1844
|
+
if (!SUINS_NAME_REGEX.test(name)) {
|
|
1845
|
+
throw new InvalidAddressError(rawName);
|
|
1846
|
+
}
|
|
1847
|
+
const url = ctx.suiRpcUrl || SUI_MAINNET_URL;
|
|
1848
|
+
let res;
|
|
1849
|
+
try {
|
|
1850
|
+
res = await fetch(url, {
|
|
1851
|
+
method: "POST",
|
|
1852
|
+
headers: { "Content-Type": "application/json" },
|
|
1853
|
+
body: JSON.stringify({
|
|
1854
|
+
jsonrpc: "2.0",
|
|
1855
|
+
id: 1,
|
|
1856
|
+
method: "suix_resolveNameServiceAddress",
|
|
1857
|
+
params: [name]
|
|
1858
|
+
}),
|
|
1859
|
+
signal: ctx.signal ?? AbortSignal.timeout(8e3)
|
|
1860
|
+
});
|
|
1861
|
+
} catch (err) {
|
|
1862
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1863
|
+
throw new SuinsRpcError(name, msg);
|
|
1864
|
+
}
|
|
1865
|
+
if (!res.ok) {
|
|
1866
|
+
throw new SuinsRpcError(name, `HTTP ${res.status}`);
|
|
1867
|
+
}
|
|
1868
|
+
let body;
|
|
1869
|
+
try {
|
|
1870
|
+
body = await res.json();
|
|
1871
|
+
} catch (err) {
|
|
1872
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1873
|
+
throw new SuinsRpcError(name, `JSON parse failed: ${msg}`);
|
|
1874
|
+
}
|
|
1875
|
+
if (body.error) {
|
|
1876
|
+
throw new SuinsRpcError(name, body.error.message);
|
|
1877
|
+
}
|
|
1878
|
+
return body.result ?? null;
|
|
1879
|
+
}
|
|
1880
|
+
async function resolveAddressToSuinsViaRpc(rawAddress, ctx = {}) {
|
|
1881
|
+
const address = rawAddress.trim().toLowerCase();
|
|
1882
|
+
if (!SUI_ADDRESS_REGEX.test(address)) {
|
|
1883
|
+
throw new InvalidAddressError(rawAddress);
|
|
1884
|
+
}
|
|
1885
|
+
const url = ctx.suiRpcUrl || SUI_MAINNET_URL;
|
|
1886
|
+
let res;
|
|
1887
|
+
try {
|
|
1888
|
+
res = await fetch(url, {
|
|
1889
|
+
method: "POST",
|
|
1890
|
+
headers: { "Content-Type": "application/json" },
|
|
1891
|
+
body: JSON.stringify({
|
|
1892
|
+
jsonrpc: "2.0",
|
|
1893
|
+
id: 1,
|
|
1894
|
+
method: "suix_resolveNameServiceNames",
|
|
1895
|
+
params: [address]
|
|
1896
|
+
}),
|
|
1897
|
+
signal: ctx.signal ?? AbortSignal.timeout(8e3)
|
|
1898
|
+
});
|
|
1899
|
+
} catch (err) {
|
|
1900
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1901
|
+
throw new SuinsRpcError(address, msg);
|
|
1902
|
+
}
|
|
1903
|
+
if (!res.ok) {
|
|
1904
|
+
throw new SuinsRpcError(address, `HTTP ${res.status}`);
|
|
1905
|
+
}
|
|
1906
|
+
let body;
|
|
1907
|
+
try {
|
|
1908
|
+
body = await res.json();
|
|
1909
|
+
} catch (err) {
|
|
1910
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1911
|
+
throw new SuinsRpcError(address, `JSON parse failed: ${msg}`);
|
|
1912
|
+
}
|
|
1913
|
+
if (body.error) {
|
|
1914
|
+
throw new SuinsRpcError(address, body.error.message);
|
|
1915
|
+
}
|
|
1916
|
+
return body.result?.data ?? [];
|
|
1917
|
+
}
|
|
1918
|
+
async function normalizeAddressInput(value, ctx = {}) {
|
|
1919
|
+
const trimmed = value.trim();
|
|
1920
|
+
if (SUI_ADDRESS_REGEX.test(trimmed)) {
|
|
1921
|
+
return { address: trimmed.toLowerCase(), suinsName: null, raw: value };
|
|
1922
|
+
}
|
|
1923
|
+
if (looksLikeSuiNs(trimmed)) {
|
|
1924
|
+
const name = trimmed.toLowerCase();
|
|
1925
|
+
const address = await resolveSuinsViaRpc(name, ctx);
|
|
1926
|
+
if (!address) {
|
|
1927
|
+
throw new SuinsNotRegisteredError(name);
|
|
1928
|
+
}
|
|
1929
|
+
return { address: address.toLowerCase(), suinsName: name, raw: value };
|
|
1930
|
+
}
|
|
1931
|
+
throw new InvalidAddressError(value);
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1808
1934
|
// ../../node_modules/.pnpm/@mysten+bcs@2.0.2/node_modules/@mysten/bcs/dist/uleb.mjs
|
|
1809
1935
|
function ulebEncode(num) {
|
|
1810
1936
|
let bigNum = BigInt(num);
|
|
@@ -6272,6 +6398,14 @@ var SafeguardEnforcer = class {
|
|
|
6272
6398
|
};
|
|
6273
6399
|
init_errors();
|
|
6274
6400
|
var RESERVED_NAMES = /* @__PURE__ */ new Set(["to", "all", "address"]);
|
|
6401
|
+
var deprecationWarned = false;
|
|
6402
|
+
function warnContactsDeprecation() {
|
|
6403
|
+
if (deprecationWarned) return;
|
|
6404
|
+
deprecationWarned = true;
|
|
6405
|
+
console.warn(
|
|
6406
|
+
"[t2000] DEPRECATION: ~/.t2000/contacts.json alias resolution is deprecated and will be removed in the next major release. Use SuiNS names instead (e.g. `t2000 send alex.sui 10 USDC`). Register a SuiNS name at https://suins.io if you need a memorable handle."
|
|
6407
|
+
);
|
|
6408
|
+
}
|
|
6275
6409
|
var ContactManager = class {
|
|
6276
6410
|
contacts = {};
|
|
6277
6411
|
filePath;
|
|
@@ -6301,6 +6435,7 @@ var ContactManager = class {
|
|
|
6301
6435
|
const existed = key in this.contacts;
|
|
6302
6436
|
this.contacts[key] = { name, address: normalized };
|
|
6303
6437
|
this.save();
|
|
6438
|
+
warnContactsDeprecation();
|
|
6304
6439
|
return { action: existed ? "updated" : "added" };
|
|
6305
6440
|
}
|
|
6306
6441
|
remove(name) {
|
|
@@ -6325,12 +6460,15 @@ var ContactManager = class {
|
|
|
6325
6460
|
}
|
|
6326
6461
|
const contact = this.contacts[nameOrAddress.toLowerCase()];
|
|
6327
6462
|
if (contact) {
|
|
6463
|
+
warnContactsDeprecation();
|
|
6328
6464
|
return { address: contact.address, contactName: contact.name };
|
|
6329
6465
|
}
|
|
6330
6466
|
throw new exports.T2000Error(
|
|
6331
6467
|
"CONTACT_NOT_FOUND",
|
|
6332
6468
|
`"${nameOrAddress}" is not a valid Sui address or saved contact.
|
|
6333
|
-
|
|
6469
|
+
Use a SuiNS name (e.g. alex.sui \u2014 register at https://suins.io)
|
|
6470
|
+
or paste the full Sui address (0x... 64 hex characters).
|
|
6471
|
+
Legacy contact aliases: \`t2000 contacts add ${nameOrAddress} 0x...\` (deprecated).`
|
|
6334
6472
|
);
|
|
6335
6473
|
}
|
|
6336
6474
|
validateName(name) {
|
|
@@ -6700,7 +6838,7 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6700
6838
|
if (!(asset in SUPPORTED_ASSETS)) {
|
|
6701
6839
|
throw new exports.T2000Error("ASSET_NOT_SUPPORTED", `Asset ${asset} is not supported`);
|
|
6702
6840
|
}
|
|
6703
|
-
const resolved = this.
|
|
6841
|
+
const resolved = await this.resolveRecipient(params.to);
|
|
6704
6842
|
const sendAmount = params.amount;
|
|
6705
6843
|
const sendTo = resolved.address;
|
|
6706
6844
|
const gasResult = await executeTx(
|
|
@@ -6717,11 +6855,63 @@ var T2000 = class _T2000 extends eventemitter3.EventEmitter {
|
|
|
6717
6855
|
amount: sendAmount,
|
|
6718
6856
|
to: resolved.address,
|
|
6719
6857
|
contactName: resolved.contactName,
|
|
6858
|
+
suinsName: resolved.suinsName,
|
|
6720
6859
|
gasCost: gasResult.gasCostSui,
|
|
6721
6860
|
gasCostUnit: "SUI",
|
|
6722
6861
|
balance
|
|
6723
6862
|
};
|
|
6724
6863
|
}
|
|
6864
|
+
/**
|
|
6865
|
+
* [S.279 / CLI-CONTACTS-CLEANUP — 2026-05-23] Resolve a recipient
|
|
6866
|
+
* string into a canonical 0x address, trying each shape in priority
|
|
6867
|
+
* order:
|
|
6868
|
+
* 1. **hex** — `0x…` is used directly (no RPC round-trip).
|
|
6869
|
+
* 2. **SuiNS** — `alex.sui` resolves via `suix_resolveNameServiceAddress`.
|
|
6870
|
+
* 3. **saved contact** — `ContactManager.resolve()` falls back to the
|
|
6871
|
+
* legacy `~/.t2000/contacts.json` alias map. Deprecated; the
|
|
6872
|
+
* manager surfaces a one-time `console.warn` when this path fires.
|
|
6873
|
+
*
|
|
6874
|
+
* Returns `{ address, suinsName?, contactName? }` so `send()` can stamp
|
|
6875
|
+
* the name source on the receipt without re-resolving.
|
|
6876
|
+
*
|
|
6877
|
+
* Throws `T2000Error('SUINS_NOT_REGISTERED', …)` for well-formed but
|
|
6878
|
+
* unregistered SuiNS names (vs. propagating the engine-style
|
|
6879
|
+
* `SuinsNotRegisteredError` — keeps the SDK's error surface
|
|
6880
|
+
* `T2000Error`-only, consistent with every other write helper).
|
|
6881
|
+
*
|
|
6882
|
+
* [S.279.1 / 2026-05-23 — patch v2.19.1] Promoted from `private` to
|
|
6883
|
+
* `public` so MCP's `t2000_send` dryRun preview path can share the
|
|
6884
|
+
* same resolution logic as the live execute path. Pre-2.19.1 the
|
|
6885
|
+
* MCP dryRun called `agent.contacts.resolve(to)` directly, which
|
|
6886
|
+
* rejected SuiNS names — preview-then-execute flows broke for
|
|
6887
|
+
* `alex.sui`-style recipients. SSOT: never let preview and execute
|
|
6888
|
+
* resolve the same input differently.
|
|
6889
|
+
*/
|
|
6890
|
+
async resolveRecipient(input) {
|
|
6891
|
+
const trimmed = input.trim();
|
|
6892
|
+
if (SUI_ADDRESS_REGEX.test(trimmed)) {
|
|
6893
|
+
return { address: trimmed.toLowerCase() };
|
|
6894
|
+
}
|
|
6895
|
+
if (looksLikeSuiNs(trimmed)) {
|
|
6896
|
+
try {
|
|
6897
|
+
const name = trimmed.toLowerCase();
|
|
6898
|
+
const address = await resolveSuinsViaRpc(name);
|
|
6899
|
+
if (!address) {
|
|
6900
|
+
throw new SuinsNotRegisteredError(name);
|
|
6901
|
+
}
|
|
6902
|
+
return { address: address.toLowerCase(), suinsName: name };
|
|
6903
|
+
} catch (err) {
|
|
6904
|
+
if (err instanceof SuinsNotRegisteredError) {
|
|
6905
|
+
throw new exports.T2000Error(
|
|
6906
|
+
"SUINS_NOT_REGISTERED",
|
|
6907
|
+
err.message
|
|
6908
|
+
);
|
|
6909
|
+
}
|
|
6910
|
+
throw err;
|
|
6911
|
+
}
|
|
6912
|
+
}
|
|
6913
|
+
return this.contacts.resolve(input);
|
|
6914
|
+
}
|
|
6725
6915
|
async balance() {
|
|
6726
6916
|
const bal = await queryBalance(this.client, this._address);
|
|
6727
6917
|
let chainTotal = bal.available + bal.gasReserve.usdEquiv;
|
|
@@ -8398,6 +8588,7 @@ exports.DEFAULT_SAFEGUARD_CONFIG = DEFAULT_SAFEGUARD_CONFIG;
|
|
|
8398
8588
|
exports.GAS_RESERVE_MIN = GAS_RESERVE_MIN;
|
|
8399
8589
|
exports.HF_CRITICAL_THRESHOLD = HF_CRITICAL_THRESHOLD;
|
|
8400
8590
|
exports.HF_WARN_THRESHOLD = HF_WARN_THRESHOLD;
|
|
8591
|
+
exports.InvalidAddressError = InvalidAddressError;
|
|
8401
8592
|
exports.KNOWN_TARGETS = KNOWN_TARGETS;
|
|
8402
8593
|
exports.KeypairSigner = KeypairSigner;
|
|
8403
8594
|
exports.LABEL_PATTERNS = LABEL_PATTERNS;
|
|
@@ -8409,10 +8600,15 @@ exports.ProtocolRegistry = ProtocolRegistry;
|
|
|
8409
8600
|
exports.SAVE_FEE_BPS = SAVE_FEE_BPS;
|
|
8410
8601
|
exports.SPONSORED_PYTH_DEPENDENT_PROVIDERS = SPONSORED_PYTH_DEPENDENT_PROVIDERS;
|
|
8411
8602
|
exports.STABLE_ASSETS = STABLE_ASSETS;
|
|
8603
|
+
exports.SUINS_NAME_REGEX = SUINS_NAME_REGEX;
|
|
8604
|
+
exports.SUI_ADDRESS_REGEX = SUI_ADDRESS_REGEX;
|
|
8605
|
+
exports.SUI_ADDRESS_STRICT_REGEX = SUI_ADDRESS_STRICT_REGEX;
|
|
8412
8606
|
exports.SUI_DECIMALS = SUI_DECIMALS;
|
|
8413
8607
|
exports.SUPPORTED_ASSETS = SUPPORTED_ASSETS;
|
|
8414
8608
|
exports.SafeguardEnforcer = SafeguardEnforcer;
|
|
8415
8609
|
exports.SafeguardError = SafeguardError;
|
|
8610
|
+
exports.SuinsNotRegisteredError = SuinsNotRegisteredError;
|
|
8611
|
+
exports.SuinsRpcError = SuinsRpcError;
|
|
8416
8612
|
exports.T2000 = T2000;
|
|
8417
8613
|
exports.T2000_OVERLAY_FEE_WALLET = T2000_OVERLAY_FEE_WALLET;
|
|
8418
8614
|
exports.USDC_DECIMALS = USDC_DECIMALS;
|
|
@@ -8476,10 +8672,12 @@ exports.isTier1 = isTier1;
|
|
|
8476
8672
|
exports.isTier2 = isTier2;
|
|
8477
8673
|
exports.keypairFromPrivateKey = keypairFromPrivateKey;
|
|
8478
8674
|
exports.loadKey = loadKey;
|
|
8675
|
+
exports.looksLikeSuiNs = looksLikeSuiNs;
|
|
8479
8676
|
exports.mapMoveAbortCode = mapMoveAbortCode;
|
|
8480
8677
|
exports.mapWalletError = mapWalletError;
|
|
8481
8678
|
exports.mistToSui = mistToSui;
|
|
8482
8679
|
exports.naviDescriptor = naviDescriptor;
|
|
8680
|
+
exports.normalizeAddressInput = normalizeAddressInput;
|
|
8483
8681
|
exports.normalizeAsset = normalizeAsset;
|
|
8484
8682
|
exports.normalizeCoinType = normalizeCoinType;
|
|
8485
8683
|
exports.parseSuiRpcTx = parseSuiRpcTx;
|
|
@@ -8488,6 +8686,8 @@ exports.queryTransaction = queryTransaction;
|
|
|
8488
8686
|
exports.rawToStable = rawToStable;
|
|
8489
8687
|
exports.rawToUsdc = rawToUsdc;
|
|
8490
8688
|
exports.refineLendingLabel = refineLendingLabel;
|
|
8689
|
+
exports.resolveAddressToSuinsViaRpc = resolveAddressToSuinsViaRpc;
|
|
8690
|
+
exports.resolveSuinsViaRpc = resolveSuinsViaRpc;
|
|
8491
8691
|
exports.resolveSymbol = resolveSymbol;
|
|
8492
8692
|
exports.resolveTokenType = resolveTokenType;
|
|
8493
8693
|
exports.saveKey = saveKey;
|