@t2000/cli 5.6.1 → 5.7.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
@@ -28900,6 +28900,7 @@ init_errors();
28900
28900
  init_swap_quote();
28901
28901
  init_cetus_swap();
28902
28902
  init_token_registry();
28903
+ var AGENT_ID_PARENT_NFT_ID = process.env.AGENT_ID_PARENT_NFT_ID ?? "0xc8c13f5b5a6d4c47c04877014794f65e67e2745d3bfa089b736eb54b0ebd5d1f";
28903
28904
  init_preflight();
28904
28905
 
28905
28906
  // ../../node_modules/.pnpm/@inquirer+core@10.3.2_@types+node@20.19.37/node_modules/@inquirer/core/dist/esm/lib/key.js
@@ -32494,7 +32495,7 @@ function registerMcpStart(parent) {
32494
32495
  parent.command("start", { isDefault: true }).description("Start MCP server (stdio transport \u2014 for AI client integration)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").action(async (opts) => {
32495
32496
  let mod2;
32496
32497
  try {
32497
- mod2 = await import("./dist-5TKR5HBZ.js");
32498
+ mod2 = await import("./dist-HTKRHJBX.js");
32498
32499
  } catch {
32499
32500
  console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
32500
32501
  process.exit(1);
@@ -32833,6 +32834,173 @@ For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
32833
32834
  registerSkillsUninstall(group);
32834
32835
  }
32835
32836
 
32837
+ // src/commands/agent/index.ts
32838
+ var DEFAULT_API_BASE = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
32839
+ function normalizeTopupAsset(input) {
32840
+ return input?.toLowerCase() === "usdsui" ? "USDsui" : "USDC";
32841
+ }
32842
+ async function fundCredit(agent, base, amountStr, assetOpt) {
32843
+ const amount = Number.parseFloat(amountStr);
32844
+ if (Number.isNaN(amount) || amount <= 0) {
32845
+ throw new Error(`amount must be a positive number (got "${amountStr}").`);
32846
+ }
32847
+ const asset = normalizeTopupAsset(assetOpt);
32848
+ const cfg = await fetchJson(`${base}/agent/topup`, { method: "GET" });
32849
+ const treasury = cfg.treasury;
32850
+ if (!treasury) {
32851
+ throw new Error("Could not resolve the t2000 treasury address.");
32852
+ }
32853
+ const sent = await agent.send({ to: treasury, amount, asset });
32854
+ const topup = await fetchJson(`${base}/agent/topup`, {
32855
+ method: "POST",
32856
+ body: { address: agent.address(), digest: sent.tx }
32857
+ });
32858
+ return { amount, asset, balanceUsd: topup.balanceUsd };
32859
+ }
32860
+ async function fetchJson(url, init) {
32861
+ const res = await fetch(url, {
32862
+ method: init.method,
32863
+ headers: init.body ? { "Content-Type": "application/json" } : void 0,
32864
+ body: init.body ? JSON.stringify(init.body) : void 0
32865
+ });
32866
+ const json = await res.json().catch(() => ({}));
32867
+ if (!res.ok) {
32868
+ const err = json.error;
32869
+ const msg = typeof err === "string" ? err : err?.message ?? `HTTP ${res.status}`;
32870
+ throw new Error(msg);
32871
+ }
32872
+ return json;
32873
+ }
32874
+ function registerAgent(program3) {
32875
+ const group = program3.command("agent").description("Agent ID \u2014 onboard this wallet to the t2000 API (api.t2000.ai)").addHelpText(
32876
+ "after",
32877
+ `
32878
+ Subcommands:
32879
+ $ t2 agent onboard --fund 5 Fund 5 USDC \u2192 mint an API key (ready to call)
32880
+ $ t2 agent onboard --fund 5 --asset USDsui
32881
+ $ t2 agent onboard Already funded \u2192 just mint a key
32882
+ `
32883
+ );
32884
+ group.command("onboard").description("Fund credit (gasless USDC/USDsui) + mint an API key for this wallet.").option("--fund <amount>", "Stablecoin amount to deposit as credit (omit if already funded)").option("--asset <asset>", "USDC (default) or USDsui", "USDC").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE})`).action(
32885
+ async (opts) => {
32886
+ try {
32887
+ const base = opts.api ?? DEFAULT_API_BASE;
32888
+ const agent = await withAgent({ keyPath: opts.key });
32889
+ const address = agent.address();
32890
+ if (opts.fund !== void 0) {
32891
+ const funded = await fundCredit(agent, base, opts.fund, opts.asset);
32892
+ if (!isJsonMode()) {
32893
+ printSuccess(
32894
+ `Funded ${formatUsd(funded.amount)} ${funded.asset} \u2192 credit $${funded.balanceUsd}`
32895
+ );
32896
+ }
32897
+ }
32898
+ const challenge = await fetchJson(`${base}/agent/challenge`, {
32899
+ method: "POST",
32900
+ body: { address }
32901
+ });
32902
+ const nonce = challenge.nonce;
32903
+ if (!nonce) {
32904
+ throw new Error("Failed to get a challenge nonce.");
32905
+ }
32906
+ const message = new TextEncoder().encode(`t2000-agent-keys:${nonce}`);
32907
+ const { signature } = await agent.keypair.signPersonalMessage(message);
32908
+ const minted = await fetchJson(`${base}/agent/keys`, {
32909
+ method: "POST",
32910
+ body: { address, nonce, signature }
32911
+ });
32912
+ const key = minted.key;
32913
+ if (!key) {
32914
+ throw new Error("Failed to mint an API key.");
32915
+ }
32916
+ if (isJsonMode()) {
32917
+ printJson({ address, apiKey: key, baseUrl: base });
32918
+ return;
32919
+ }
32920
+ printBlank();
32921
+ printSuccess("Agent onboarded \u2014 API key minted (shown once, store it now)");
32922
+ printKeyValue("Address", truncateAddress(address));
32923
+ printKeyValue("API key", key);
32924
+ printKeyValue("Base URL", base);
32925
+ printBlank();
32926
+ printInfo(`export OPENAI_BASE_URL=${base} OPENAI_API_KEY=${key}`);
32927
+ printBlank();
32928
+ } catch (error) {
32929
+ handleError(error);
32930
+ }
32931
+ }
32932
+ );
32933
+ group.command("topup").argument("<amount>", "Stablecoin amount to deposit as credit").description(
32934
+ "Top up this wallet's t2000 credit with gasless USDC/USDsui (no new key). The 'never runs dry' primitive \u2014 call it on a 402 or a schedule."
32935
+ ).option("--asset <asset>", "USDC (default) or USDsui", "USDC").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE})`).action(
32936
+ async (amount, opts) => {
32937
+ try {
32938
+ const base = opts.api ?? DEFAULT_API_BASE;
32939
+ const agent = await withAgent({ keyPath: opts.key });
32940
+ const funded = await fundCredit(agent, base, amount, opts.asset);
32941
+ if (isJsonMode()) {
32942
+ printJson({
32943
+ address: agent.address(),
32944
+ funded: funded.amount,
32945
+ asset: funded.asset,
32946
+ balanceUsd: funded.balanceUsd
32947
+ });
32948
+ return;
32949
+ }
32950
+ printBlank();
32951
+ printSuccess(
32952
+ `Topped up ${formatUsd(funded.amount)} ${funded.asset} \u2192 credit $${funded.balanceUsd}`
32953
+ );
32954
+ printBlank();
32955
+ } catch (error) {
32956
+ handleError(error);
32957
+ }
32958
+ }
32959
+ );
32960
+ group.command("handle").argument("<label>", "Desired handle (3\u201320 chars: lowercase a\u2013z, 0\u20139, hyphens)").description(
32961
+ "Claim <label>.agent-id.sui \u2192 this wallet \u2014 a human-readable Agent ID handle (custody-minted, gasless for you)."
32962
+ ).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE})`).action(
32963
+ async (label, opts) => {
32964
+ try {
32965
+ const base = opts.api ?? DEFAULT_API_BASE;
32966
+ const agent = await withAgent({ keyPath: opts.key });
32967
+ const address = agent.address();
32968
+ const challenge = await fetchJson(`${base}/agent/challenge`, {
32969
+ method: "POST",
32970
+ body: { address }
32971
+ });
32972
+ const nonce = challenge.nonce;
32973
+ if (!nonce) {
32974
+ throw new Error("Failed to get a challenge nonce.");
32975
+ }
32976
+ const message = new TextEncoder().encode(`t2000-agent-handle:${nonce}:${label}`);
32977
+ const { signature } = await agent.keypair.signPersonalMessage(message);
32978
+ const res = await fetchJson(`${base}/agent/handle`, {
32979
+ method: "POST",
32980
+ body: { address, label, nonce, signature }
32981
+ });
32982
+ if (isJsonMode()) {
32983
+ printJson({
32984
+ address,
32985
+ handle: res.handle,
32986
+ display: res.display,
32987
+ digest: res.digest
32988
+ });
32989
+ return;
32990
+ }
32991
+ printBlank();
32992
+ printSuccess(`Handle claimed: ${res.display}`);
32993
+ printKeyValue("Address", truncateAddress(address));
32994
+ printKeyValue("Handle", String(res.handle));
32995
+ printKeyValue("Tx", String(res.digest));
32996
+ printBlank();
32997
+ } catch (error) {
32998
+ handleError(error);
32999
+ }
33000
+ }
33001
+ );
33002
+ }
33003
+
32836
33004
  // src/program.ts
32837
33005
  var require3 = createRequire2(import.meta.url);
32838
33006
  var { version: CLI_VERSION2 } = require3("../package.json");
@@ -32868,6 +33036,7 @@ Examples:
32868
33036
  registerLimit(program3);
32869
33037
  registerMcp(program3);
32870
33038
  registerSkills(program3);
33039
+ registerAgent(program3);
32871
33040
  return program3;
32872
33041
  }
32873
33042