@t2000/cli 5.7.0 → 5.7.2
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.
|
@@ -80332,7 +80332,7 @@ Through this wallet you can reach essentially any major external API, billed to
|
|
|
80332
80332
|
CRITICAL: When the user asks to use any external or paid API, names a provider (e.g. "via fal.ai", "with ElevenLabs"), or requests a capability one of the services above provides, DO NOT say you cannot reach that service, that it isn't on an allowlist, or that there's no connector \u2014 and do NOT fall back to writing a script for the user to run. You CAN do it directly through this wallet. Use t2000_services to discover the endpoint and request shape, then t2000_pay to execute, then show the user the result (display image/audio URLs returned in the response).
|
|
80333
80333
|
|
|
80334
80334
|
Spending is the user's own USDC and every t2000_pay call is bounded by maxPrice. For larger or multi-step spends, state the estimated cost first and proceed once the user is happy. Use t2000_balance to check funds. The v4 wallet is payments-only; savings / lending live on audric.ai.`;
|
|
80335
|
-
var PKG_VERSION = "5.7.
|
|
80335
|
+
var PKG_VERSION = "5.7.2";
|
|
80336
80336
|
console.log = (...args) => console.error("[log]", ...args);
|
|
80337
80337
|
console.warn = (...args) => console.error("[warn]", ...args);
|
|
80338
80338
|
async function startMcpServer(opts) {
|
|
@@ -80398,4 +80398,4 @@ mime-types/index.js:
|
|
|
80398
80398
|
@scure/bip39/index.js:
|
|
80399
80399
|
(*! scure-bip39 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
80400
80400
|
*/
|
|
80401
|
-
//# sourceMappingURL=dist-
|
|
80401
|
+
//# sourceMappingURL=dist-MPQLFHSY.js.map
|
package/dist/index.js
CHANGED
|
@@ -31313,7 +31313,65 @@ async function askHidden(message) {
|
|
|
31313
31313
|
return esm_default9({ message });
|
|
31314
31314
|
}
|
|
31315
31315
|
|
|
31316
|
+
// src/lib/agent-register.ts
|
|
31317
|
+
async function postJson(url, body) {
|
|
31318
|
+
const res = await fetch(url, {
|
|
31319
|
+
method: "POST",
|
|
31320
|
+
headers: { "Content-Type": "application/json" },
|
|
31321
|
+
body: JSON.stringify(body)
|
|
31322
|
+
});
|
|
31323
|
+
const json = await res.json().catch(() => ({}));
|
|
31324
|
+
if (!res.ok) {
|
|
31325
|
+
const err = json.error;
|
|
31326
|
+
const msg = typeof err === "string" ? err : err?.message ?? `HTTP ${res.status}`;
|
|
31327
|
+
throw new Error(msg);
|
|
31328
|
+
}
|
|
31329
|
+
return json;
|
|
31330
|
+
}
|
|
31331
|
+
async function runSponsoredTx(opts) {
|
|
31332
|
+
const prep = await postJson(opts.prepareUrl, opts.prepareBody);
|
|
31333
|
+
const nonce = prep.nonce;
|
|
31334
|
+
const txBytes = prep.txBytes;
|
|
31335
|
+
if (!(nonce && txBytes)) {
|
|
31336
|
+
throw new Error("Failed to prepare the transaction.");
|
|
31337
|
+
}
|
|
31338
|
+
const bytes = new Uint8Array(Buffer.from(txBytes, "base64"));
|
|
31339
|
+
const { signature } = await opts.keypair.signTransaction(bytes);
|
|
31340
|
+
const res = await postJson(opts.submitUrl, {
|
|
31341
|
+
nonce,
|
|
31342
|
+
address: opts.actor,
|
|
31343
|
+
signature
|
|
31344
|
+
});
|
|
31345
|
+
return { digest: res.digest };
|
|
31346
|
+
}
|
|
31347
|
+
async function registerWallet(opts) {
|
|
31348
|
+
const prep = await postJson(`${opts.base}/agent/register/prepare`, {
|
|
31349
|
+
address: opts.address
|
|
31350
|
+
});
|
|
31351
|
+
if (prep.alreadyRegistered === true) {
|
|
31352
|
+
return { alreadyRegistered: true };
|
|
31353
|
+
}
|
|
31354
|
+
const regNonce = prep.regNonce;
|
|
31355
|
+
const txBytes = prep.txBytes;
|
|
31356
|
+
if (!(regNonce && txBytes)) {
|
|
31357
|
+
throw new Error("Failed to prepare registration.");
|
|
31358
|
+
}
|
|
31359
|
+
const bytes = new Uint8Array(Buffer.from(txBytes, "base64"));
|
|
31360
|
+
const { signature } = await opts.keypair.signTransaction(bytes);
|
|
31361
|
+
const res = await postJson(`${opts.base}/agent/register/submit`, {
|
|
31362
|
+
regNonce,
|
|
31363
|
+
address: opts.address,
|
|
31364
|
+
agentSignature: signature
|
|
31365
|
+
});
|
|
31366
|
+
return {
|
|
31367
|
+
digest: res.digest,
|
|
31368
|
+
alreadyRegistered: Boolean(res.alreadyRegistered)
|
|
31369
|
+
};
|
|
31370
|
+
}
|
|
31371
|
+
|
|
31316
31372
|
// src/commands/init.ts
|
|
31373
|
+
var DEFAULT_API_BASE = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
31374
|
+
var REGISTER_TIMEOUT_MS = 1e4;
|
|
31317
31375
|
var DEFAULT_PER_TX_USD = 25;
|
|
31318
31376
|
var DEFAULT_DAILY_USD = 100;
|
|
31319
31377
|
var limitsFooter = (perTx, daily) => `Spending limits ON: $${perTx}/tx, $${daily}/day (cumulative). Change with \`t2 limit set\`, or override a single call with --force.`;
|
|
@@ -31321,6 +31379,9 @@ function registerInit(program3) {
|
|
|
31321
31379
|
program3.command("init").description("Create a new Agent Wallet (no PIN; plain Bech32 key file with 0o600 perms)").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option(
|
|
31322
31380
|
"--import [secret]",
|
|
31323
31381
|
"Import an existing wallet via Bech32 secret. Omit the value for an interactive hidden-input prompt."
|
|
31382
|
+
).option(
|
|
31383
|
+
"--no-register",
|
|
31384
|
+
"Skip the best-effort on-chain Agent ID registration (offline/CI)."
|
|
31324
31385
|
).action(async (opts) => {
|
|
31325
31386
|
try {
|
|
31326
31387
|
if (await walletExists(opts.key)) {
|
|
@@ -31330,18 +31391,35 @@ function registerInit(program3) {
|
|
|
31330
31391
|
}
|
|
31331
31392
|
let address;
|
|
31332
31393
|
let imported = false;
|
|
31394
|
+
let signingKeypair;
|
|
31333
31395
|
if (opts.import !== void 0) {
|
|
31334
31396
|
const secret = typeof opts.import === "string" && opts.import.length > 0 ? opts.import : await askHidden("Paste your suiprivkey1... secret:");
|
|
31335
31397
|
if (typeof opts.import === "string" && opts.import.length > 0) {
|
|
31336
31398
|
printWarning("Private key passed as a CLI flag will be in shell history. Prefer the interactive prompt: `t2 init --import` (no value).");
|
|
31337
31399
|
}
|
|
31400
|
+
const kp = keypairFromPrivateKey(secret);
|
|
31338
31401
|
await saveBech32(secret, opts.key);
|
|
31339
|
-
address = getAddress(
|
|
31402
|
+
address = getAddress(kp);
|
|
31403
|
+
signingKeypair = kp;
|
|
31340
31404
|
imported = true;
|
|
31341
31405
|
} else {
|
|
31342
31406
|
const keypair = generateKeypair();
|
|
31343
31407
|
await saveKey(keypair, void 0, opts.key);
|
|
31344
31408
|
address = getAddress(keypair);
|
|
31409
|
+
signingKeypair = keypair;
|
|
31410
|
+
}
|
|
31411
|
+
let registered = false;
|
|
31412
|
+
if (opts.register !== false) {
|
|
31413
|
+
try {
|
|
31414
|
+
await Promise.race([
|
|
31415
|
+
registerWallet({ keypair: signingKeypair, address, base: DEFAULT_API_BASE }),
|
|
31416
|
+
new Promise(
|
|
31417
|
+
(_, reject) => setTimeout(() => reject(new Error("timeout")), REGISTER_TIMEOUT_MS)
|
|
31418
|
+
)
|
|
31419
|
+
]);
|
|
31420
|
+
registered = true;
|
|
31421
|
+
} catch {
|
|
31422
|
+
}
|
|
31345
31423
|
}
|
|
31346
31424
|
if (!hasLimits()) {
|
|
31347
31425
|
setLimits({ perTxUsd: DEFAULT_PER_TX_USD, dailyUsd: DEFAULT_DAILY_USD });
|
|
@@ -31350,6 +31428,7 @@ function registerInit(program3) {
|
|
|
31350
31428
|
printJson({
|
|
31351
31429
|
address,
|
|
31352
31430
|
imported,
|
|
31431
|
+
registered,
|
|
31353
31432
|
configPath: opts.key ?? "~/.t2000/wallet.key",
|
|
31354
31433
|
limits: { perTxUsd: DEFAULT_PER_TX_USD, dailyUsd: DEFAULT_DAILY_USD }
|
|
31355
31434
|
});
|
|
@@ -31359,6 +31438,12 @@ function registerInit(program3) {
|
|
|
31359
31438
|
printSuccess(imported ? "Wallet imported" : "Wallet created");
|
|
31360
31439
|
printKeyValue("Address", address);
|
|
31361
31440
|
printKeyValue("Path", opts.key ?? "~/.t2000/wallet.key");
|
|
31441
|
+
if (opts.register !== false) {
|
|
31442
|
+
printKeyValue(
|
|
31443
|
+
"Agent ID",
|
|
31444
|
+
registered ? "registered" : "pending (run: t2 agent register)"
|
|
31445
|
+
);
|
|
31446
|
+
}
|
|
31362
31447
|
printBlank();
|
|
31363
31448
|
printLine(`\u26A0 ${limitsFooter(DEFAULT_PER_TX_USD, DEFAULT_DAILY_USD)}`);
|
|
31364
31449
|
printBlank();
|
|
@@ -32495,7 +32580,7 @@ function registerMcpStart(parent) {
|
|
|
32495
32580
|
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) => {
|
|
32496
32581
|
let mod2;
|
|
32497
32582
|
try {
|
|
32498
|
-
mod2 = await import("./dist-
|
|
32583
|
+
mod2 = await import("./dist-MPQLFHSY.js");
|
|
32499
32584
|
} catch {
|
|
32500
32585
|
console.error("MCP server not installed. Run:\n npm install -g @t2000/mcp");
|
|
32501
32586
|
process.exit(1);
|
|
@@ -32835,7 +32920,7 @@ For MCP-aware clients (Claude Desktop, Cursor, Windsurf), prefer
|
|
|
32835
32920
|
}
|
|
32836
32921
|
|
|
32837
32922
|
// src/commands/agent/index.ts
|
|
32838
|
-
var
|
|
32923
|
+
var DEFAULT_API_BASE2 = process.env.T2000_API_URL ?? "https://api.t2000.ai/v1";
|
|
32839
32924
|
function normalizeTopupAsset(input) {
|
|
32840
32925
|
return input?.toLowerCase() === "usdsui" ? "USDsui" : "USDC";
|
|
32841
32926
|
}
|
|
@@ -32881,10 +32966,10 @@ Subcommands:
|
|
|
32881
32966
|
$ t2 agent onboard Already funded \u2192 just mint a key
|
|
32882
32967
|
`
|
|
32883
32968
|
);
|
|
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 ${
|
|
32969
|
+
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_BASE2})`).action(
|
|
32885
32970
|
async (opts) => {
|
|
32886
32971
|
try {
|
|
32887
|
-
const base = opts.api ??
|
|
32972
|
+
const base = opts.api ?? DEFAULT_API_BASE2;
|
|
32888
32973
|
const agent = await withAgent({ keyPath: opts.key });
|
|
32889
32974
|
const address = agent.address();
|
|
32890
32975
|
if (opts.fund !== void 0) {
|
|
@@ -32913,14 +32998,24 @@ Subcommands:
|
|
|
32913
32998
|
if (!key) {
|
|
32914
32999
|
throw new Error("Failed to mint an API key.");
|
|
32915
33000
|
}
|
|
33001
|
+
let registered = false;
|
|
33002
|
+
try {
|
|
33003
|
+
await registerWallet({ keypair: agent.keypair, address, base });
|
|
33004
|
+
registered = true;
|
|
33005
|
+
} catch {
|
|
33006
|
+
}
|
|
32916
33007
|
if (isJsonMode()) {
|
|
32917
|
-
printJson({ address, apiKey: key, baseUrl: base });
|
|
33008
|
+
printJson({ address, apiKey: key, baseUrl: base, registered });
|
|
32918
33009
|
return;
|
|
32919
33010
|
}
|
|
32920
33011
|
printBlank();
|
|
32921
33012
|
printSuccess("Agent onboarded \u2014 API key minted (shown once, store it now)");
|
|
32922
33013
|
printKeyValue("Address", truncateAddress(address));
|
|
32923
33014
|
printKeyValue("API key", key);
|
|
33015
|
+
printKeyValue(
|
|
33016
|
+
"Agent ID",
|
|
33017
|
+
registered ? "registered" : "pending (retry: t2 agent register)"
|
|
33018
|
+
);
|
|
32924
33019
|
printKeyValue("Base URL", base);
|
|
32925
33020
|
printBlank();
|
|
32926
33021
|
printInfo(`export OPENAI_BASE_URL=${base} OPENAI_API_KEY=${key}`);
|
|
@@ -32932,10 +33027,10 @@ Subcommands:
|
|
|
32932
33027
|
);
|
|
32933
33028
|
group.command("topup").argument("<amount>", "Stablecoin amount to deposit as credit").description(
|
|
32934
33029
|
"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 ${
|
|
33030
|
+
).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_BASE2})`).action(
|
|
32936
33031
|
async (amount, opts) => {
|
|
32937
33032
|
try {
|
|
32938
|
-
const base = opts.api ??
|
|
33033
|
+
const base = opts.api ?? DEFAULT_API_BASE2;
|
|
32939
33034
|
const agent = await withAgent({ keyPath: opts.key });
|
|
32940
33035
|
const funded = await fundCredit(agent, base, amount, opts.asset);
|
|
32941
33036
|
if (isJsonMode()) {
|
|
@@ -32957,12 +33052,97 @@ Subcommands:
|
|
|
32957
33052
|
}
|
|
32958
33053
|
}
|
|
32959
33054
|
);
|
|
32960
|
-
group.command("
|
|
32961
|
-
"
|
|
32962
|
-
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${
|
|
33055
|
+
group.command("register").description(
|
|
33056
|
+
"Register this wallet on-chain as an Agent ID (sponsored, gasless). Idempotent \u2014 safe to re-run."
|
|
33057
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE2})`).action(async (opts) => {
|
|
33058
|
+
try {
|
|
33059
|
+
const base = opts.api ?? DEFAULT_API_BASE2;
|
|
33060
|
+
const agent = await withAgent({ keyPath: opts.key });
|
|
33061
|
+
const address = agent.address();
|
|
33062
|
+
const reg = await registerWallet({ keypair: agent.keypair, address, base });
|
|
33063
|
+
if (isJsonMode()) {
|
|
33064
|
+
printJson({
|
|
33065
|
+
address,
|
|
33066
|
+
registered: true,
|
|
33067
|
+
alreadyRegistered: reg.alreadyRegistered,
|
|
33068
|
+
digest: reg.digest
|
|
33069
|
+
});
|
|
33070
|
+
return;
|
|
33071
|
+
}
|
|
33072
|
+
printBlank();
|
|
33073
|
+
printSuccess(
|
|
33074
|
+
reg.alreadyRegistered ? "Already registered as an Agent ID" : "Registered as an Agent ID"
|
|
33075
|
+
);
|
|
33076
|
+
printKeyValue("Address", truncateAddress(address));
|
|
33077
|
+
if (reg.digest) {
|
|
33078
|
+
printKeyValue("Tx", reg.digest);
|
|
33079
|
+
}
|
|
33080
|
+
printBlank();
|
|
33081
|
+
} catch (error) {
|
|
33082
|
+
handleError(error);
|
|
33083
|
+
}
|
|
33084
|
+
});
|
|
33085
|
+
group.command("link").argument("<owner>", "The owner's Sui address (Passport) to propose").description(
|
|
33086
|
+
"Propose an owner for this agent (two-sided \u2014 the owner must then confirm). Sponsored, gasless."
|
|
33087
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE2})`).action(async (owner, opts) => {
|
|
33088
|
+
try {
|
|
33089
|
+
const base = opts.api ?? DEFAULT_API_BASE2;
|
|
33090
|
+
const agent = await withAgent({ keyPath: opts.key });
|
|
33091
|
+
const address = agent.address();
|
|
33092
|
+
const { digest } = await runSponsoredTx({
|
|
33093
|
+
keypair: agent.keypair,
|
|
33094
|
+
actor: address,
|
|
33095
|
+
prepareUrl: `${base}/agent/owner/propose`,
|
|
33096
|
+
prepareBody: { address, owner },
|
|
33097
|
+
submitUrl: `${base}/agent/owner/submit`
|
|
33098
|
+
});
|
|
33099
|
+
if (isJsonMode()) {
|
|
33100
|
+
printJson({ agent: address, pendingOwner: owner, digest });
|
|
33101
|
+
return;
|
|
33102
|
+
}
|
|
33103
|
+
printBlank();
|
|
33104
|
+
printSuccess(`Proposed owner: ${truncateAddress(owner)}`);
|
|
33105
|
+
printInfo(
|
|
33106
|
+
`They must confirm: \`t2 agent confirm ${address}\` (or via the console).`
|
|
33107
|
+
);
|
|
33108
|
+
printKeyValue("Tx", String(digest));
|
|
33109
|
+
printBlank();
|
|
33110
|
+
} catch (error) {
|
|
33111
|
+
handleError(error);
|
|
33112
|
+
}
|
|
33113
|
+
});
|
|
33114
|
+
group.command("confirm").argument("<agent>", "The agent Sui address to confirm ownership of").description(
|
|
33115
|
+
"Confirm ownership of an agent that proposed you as its owner. Sponsored, gasless."
|
|
33116
|
+
).option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE2})`).action(async (agentAddress, opts) => {
|
|
33117
|
+
try {
|
|
33118
|
+
const base = opts.api ?? DEFAULT_API_BASE2;
|
|
33119
|
+
const owner = await withAgent({ keyPath: opts.key });
|
|
33120
|
+
const address = owner.address();
|
|
33121
|
+
const { digest } = await runSponsoredTx({
|
|
33122
|
+
keypair: owner.keypair,
|
|
33123
|
+
actor: address,
|
|
33124
|
+
prepareUrl: `${base}/agent/owner/confirm`,
|
|
33125
|
+
prepareBody: { owner: address, agent: agentAddress },
|
|
33126
|
+
submitUrl: `${base}/agent/owner/submit`
|
|
33127
|
+
});
|
|
33128
|
+
if (isJsonMode()) {
|
|
33129
|
+
printJson({ owner: address, agent: agentAddress, digest });
|
|
33130
|
+
return;
|
|
33131
|
+
}
|
|
33132
|
+
printBlank();
|
|
33133
|
+
printSuccess(`Confirmed ownership of ${truncateAddress(agentAddress)}`);
|
|
33134
|
+
printKeyValue("Tx", String(digest));
|
|
33135
|
+
printBlank();
|
|
33136
|
+
} catch (error) {
|
|
33137
|
+
handleError(error);
|
|
33138
|
+
}
|
|
33139
|
+
});
|
|
33140
|
+
group.command("handle").argument("<label>", "Handle label (3\u201320 chars: lowercase a\u2013z, 0\u20139, hyphens)").description(
|
|
33141
|
+
"Claim <label>.agent-id.sui \u2192 this wallet (custody-minted, gasless). Use --release to give it up."
|
|
33142
|
+
).option("--release", "Release (revoke) this handle instead of claiming it").option("--key <path>", "Custom wallet path (default ~/.t2000/wallet.key)").option("--api <url>", `API base URL (default ${DEFAULT_API_BASE2})`).action(
|
|
32963
33143
|
async (label, opts) => {
|
|
32964
33144
|
try {
|
|
32965
|
-
const base = opts.api ??
|
|
33145
|
+
const base = opts.api ?? DEFAULT_API_BASE2;
|
|
32966
33146
|
const agent = await withAgent({ keyPath: opts.key });
|
|
32967
33147
|
const address = agent.address();
|
|
32968
33148
|
const challenge = await fetchJson(`${base}/agent/challenge`, {
|
|
@@ -32973,25 +33153,26 @@ Subcommands:
|
|
|
32973
33153
|
if (!nonce) {
|
|
32974
33154
|
throw new Error("Failed to get a challenge nonce.");
|
|
32975
33155
|
}
|
|
32976
|
-
const
|
|
33156
|
+
const action = opts.release ? "t2000-agent-handle-release" : "t2000-agent-handle";
|
|
33157
|
+
const message = new TextEncoder().encode(`${action}:${nonce}:${label}`);
|
|
32977
33158
|
const { signature } = await agent.keypair.signPersonalMessage(message);
|
|
32978
|
-
const
|
|
33159
|
+
const path2 = opts.release ? "/agent/handle/release" : "/agent/handle";
|
|
33160
|
+
const res = await fetchJson(`${base}${path2}`, {
|
|
32979
33161
|
method: "POST",
|
|
32980
33162
|
body: { address, label, nonce, signature }
|
|
32981
33163
|
});
|
|
32982
33164
|
if (isJsonMode()) {
|
|
32983
|
-
printJson({
|
|
32984
|
-
address,
|
|
32985
|
-
handle: res.handle,
|
|
32986
|
-
display: res.display,
|
|
32987
|
-
digest: res.digest
|
|
32988
|
-
});
|
|
33165
|
+
printJson({ address, ...res });
|
|
32989
33166
|
return;
|
|
32990
33167
|
}
|
|
32991
33168
|
printBlank();
|
|
32992
|
-
|
|
33169
|
+
if (opts.release) {
|
|
33170
|
+
printSuccess(`Handle released: ${String(res.handle)}`);
|
|
33171
|
+
} else {
|
|
33172
|
+
printSuccess(`Handle claimed: ${String(res.display)}`);
|
|
33173
|
+
printKeyValue("Handle", String(res.handle));
|
|
33174
|
+
}
|
|
32993
33175
|
printKeyValue("Address", truncateAddress(address));
|
|
32994
|
-
printKeyValue("Handle", String(res.handle));
|
|
32995
33176
|
printKeyValue("Tx", String(res.digest));
|
|
32996
33177
|
printBlank();
|
|
32997
33178
|
} catch (error) {
|