@sherwoodagent/cli 0.76.0 → 0.78.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
@@ -3945,6 +3945,7 @@ async function ownerOfOnIssuingChain(issuingChainId, tokenId) {
3945
3945
  args: [tokenId]
3946
3946
  });
3947
3947
  }
3948
+ var WALLET_ONLY_CHAIN_ID = 0;
3948
3949
  var VID_TAG_RE = /\s*\[vid:(v\d+):(\d+):(\d+):(0x[0-9a-fA-F]{40}):(self|0x[0-9a-fA-F]{130})\]\s*$/;
3949
3950
  function formatVidTag(tag) {
3950
3951
  return `[vid:${BINDING_VERSION}:${tag.issuingChainId}:${tag.tokenId}:${tag.wallet.toLowerCase()}:${tag.signature}]`;
@@ -3984,6 +3985,9 @@ async function verifyVidTag(tag, attester, ownerOf = ownerOfOnIssuingChain) {
3984
3985
  if (!bindingOk) {
3985
3986
  return { bindingOk: false, ownerOk: false, error: "binding failed \u2014 ownership check skipped" };
3986
3987
  }
3988
+ if (tag.issuingChainId === WALLET_ONLY_CHAIN_ID) {
3989
+ return { bindingOk, ownerOk: true, walletOnly: true };
3990
+ }
3987
3991
  try {
3988
3992
  const owner = await ownerOf(tag.issuingChainId, tag.tokenId);
3989
3993
  return {
@@ -4165,10 +4169,10 @@ function registerIdentityCommands(program2) {
4165
4169
  process.exit(1);
4166
4170
  }
4167
4171
  });
4168
- identity.command("link-virtuals").description("Link a Virtuals economyOS agent identity (ERC-8004 on Base) to this Sherwood install").option("--wallet <address>", "economyOS agent wallet (default: auto-detect via `acp wallet address`)").option("--agent-id <tokenId>", "ERC-8004 token ID on the issuing chain (default: resolve via Agent0 SDK)").option("--chain-id <id>", "Issuing chain ID (4663 = Robinhood Chain, 8453 = Base, 84532 = Base Sepolia)", String(DEFAULT_ISSUING_CHAIN_ID)).option("--binding-sig <hex>", "EIP-191 signature of the binding message by the economyOS wallet").action(async (opts) => {
4172
+ identity.command("link-virtuals").description("Link a Virtuals economyOS agent identity (ERC-8004 on Base) to this Sherwood install").option("--wallet <address>", "economyOS agent wallet (default: auto-detect via `acp wallet address`)").option("--agent-id <tokenId>", "ERC-8004 token ID on the issuing chain (default: resolve via Agent0 SDK)").option("--chain-id <id>", "Issuing chain ID (4663 = Robinhood Chain, 8453 = Base, 84532 = Base Sepolia)", String(DEFAULT_ISSUING_CHAIN_ID)).option("--binding-sig <hex>", "EIP-191 signature of the binding message by the economyOS wallet").option("--wallet-only", "Link without an ERC-8004 registration \u2014 the economyOS wallet + binding signature are the identity (agentId 0)").action(async (opts) => {
4169
4173
  const account = getAccount();
4170
- const issuingChainId = parseInt(opts.chainId, 10);
4171
- if (!ISSUING_CHAINS[issuingChainId]) {
4174
+ const issuingChainId = opts.walletOnly ? WALLET_ONLY_CHAIN_ID : parseInt(opts.chainId, 10);
4175
+ if (!opts.walletOnly && !ISSUING_CHAINS[issuingChainId]) {
4172
4176
  console.error(chalk4.red(`Unsupported issuing chain ${opts.chainId}. Supported: ${Object.keys(ISSUING_CHAINS).join(", ")}`));
4173
4177
  process.exit(1);
4174
4178
  }
@@ -4190,7 +4194,9 @@ function registerIdentityCommands(program2) {
4190
4194
  process.exit(1);
4191
4195
  }
4192
4196
  let tokenId;
4193
- if (opts.agentId) {
4197
+ if (opts.walletOnly) {
4198
+ tokenId = 0n;
4199
+ } else if (opts.agentId) {
4194
4200
  tokenId = BigInt(opts.agentId);
4195
4201
  } else {
4196
4202
  spinner.text = `Searching ERC-8004 registry on chain ${issuingChainId} for ${virtualsWallet}...`;
@@ -4208,6 +4214,7 @@ function registerIdentityCommands(program2) {
4208
4214
  console.error(chalk4.dim(" Register first via the Virtuals CLI:"));
4209
4215
  console.error(chalk4.dim(` acp agent register-erc8004 --agent-id ${virtualsAgentId ?? "<id>"} --chain-id ${issuingChainId}`));
4210
4216
  console.error(chalk4.dim(" Then re-run this command (or pass --agent-id <tokenId> directly)."));
4217
+ console.error(chalk4.dim(" No registration possible yet? Link without one: --wallet-only"));
4211
4218
  process.exit(1);
4212
4219
  }
4213
4220
  if (results.length > 1) {
@@ -4227,11 +4234,13 @@ function registerIdentityCommands(program2) {
4227
4234
  spinner.fail(`Token ID ${tokenId} exceeds Number.MAX_SAFE_INTEGER \u2014 cannot be stored in config`);
4228
4235
  process.exit(1);
4229
4236
  }
4230
- spinner.text = `Verifying ownerOf(#${tokenId}) on chain ${issuingChainId}...`;
4231
- const owner = await ownerOfOnIssuingChain(issuingChainId, tokenId);
4232
- if (owner.toLowerCase() !== virtualsWallet.toLowerCase()) {
4233
- spinner.fail(`Agent #${tokenId} on chain ${issuingChainId} is owned by ${owner}, not ${virtualsWallet}`);
4234
- process.exit(1);
4237
+ if (!opts.walletOnly) {
4238
+ spinner.text = `Verifying ownerOf(#${tokenId}) on chain ${issuingChainId}...`;
4239
+ const owner = await ownerOfOnIssuingChain(issuingChainId, tokenId);
4240
+ if (owner.toLowerCase() !== virtualsWallet.toLowerCase()) {
4241
+ spinner.fail(`Agent #${tokenId} on chain ${issuingChainId} is owned by ${owner}, not ${virtualsWallet}`);
4242
+ process.exit(1);
4243
+ }
4235
4244
  }
4236
4245
  const self = virtualsWallet.toLowerCase() === account.address.toLowerCase();
4237
4246
  const bindingMessage = buildBindingMessage(account.address, issuingChainId, tokenId);
@@ -4268,7 +4277,9 @@ function registerIdentityCommands(program2) {
4268
4277
  wallet: virtualsWallet,
4269
4278
  binding
4270
4279
  });
4271
- spinner.succeed(`Virtuals identity linked: agent #${tokenId} (chain ${issuingChainId})`);
4280
+ spinner.succeed(
4281
+ opts.walletOnly ? "Virtuals identity linked: wallet-only (no ERC-8004 \u2014 upgrade later by re-linking after registration)" : `Virtuals identity linked: agent #${tokenId} (chain ${issuingChainId})`
4282
+ );
4272
4283
  console.log(chalk4.dim(` economyOS wallet: ${virtualsWallet}`));
4273
4284
  if (virtualsAgentId) console.log(chalk4.dim(` Virtuals agent: ${virtualsAgentId}`));
4274
4285
  console.log(chalk4.dim(` Sherwood wallet: ${account.address}${self ? " (same as economyOS wallet \u2014 no binding needed)" : " (bound via signature)"}`));
@@ -4338,13 +4349,18 @@ function registerIdentityCommands(program2) {
4338
4349
  console.log(` Sherwood wallet: ${account.address}`);
4339
4350
  console.log(` economyOS wallet: ${virtuals?.wallet ?? chalk4.red("(missing)")}`);
4340
4351
  if (virtuals?.agentId) console.log(` Virtuals agent: ${virtuals.agentId}`);
4341
- console.log(` Issuing chain: ${issuingChainId ?? chalk4.red("(missing)")}`);
4342
- console.log(` Saved ID: ${savedId != null ? `#${savedId}` : chalk4.red("(missing)")}`);
4352
+ const walletOnly = issuingChainId === WALLET_ONLY_CHAIN_ID;
4353
+ console.log(` Issuing chain: ${walletOnly ? chalk4.yellow("wallet-only (no ERC-8004)") : issuingChainId ?? chalk4.red("(missing)")}`);
4354
+ console.log(` Saved ID: ${savedId != null ? walletOnly ? chalk4.dim("0 (wallet-only)") : `#${savedId}` : chalk4.red("(missing)")}`);
4343
4355
  if (virtuals?.wallet && savedId != null && issuingChainId != null) {
4344
4356
  const spinner2 = ora4("Re-verifying link...").start();
4345
4357
  try {
4346
- const owner = await ownerOfOnIssuingChain(issuingChainId, BigInt(savedId));
4347
- const ownerOk = owner.toLowerCase() === virtuals.wallet.toLowerCase();
4358
+ let ownerOk = true;
4359
+ let owner;
4360
+ if (!walletOnly) {
4361
+ owner = await ownerOfOnIssuingChain(issuingChainId, BigInt(savedId));
4362
+ ownerOk = owner.toLowerCase() === virtuals.wallet.toLowerCase();
4363
+ }
4348
4364
  let bindingOk = virtuals.wallet.toLowerCase() === account.address.toLowerCase();
4349
4365
  if (!bindingOk && virtuals.binding?.sig) {
4350
4366
  bindingOk = await verifyBinding({
@@ -4356,11 +4372,19 @@ function registerIdentityCommands(program2) {
4356
4372
  });
4357
4373
  }
4358
4374
  spinner2.stop();
4359
- console.log(` NFT ownership: ${ownerOk ? chalk4.green("verified") : chalk4.red(`FAILED (owner is ${owner})`)}`);
4375
+ if (walletOnly) {
4376
+ console.log(` NFT ownership: ${chalk4.dim("n/a (wallet-only link)")}`);
4377
+ } else {
4378
+ console.log(` NFT ownership: ${ownerOk ? chalk4.green("verified") : chalk4.red(`FAILED (owner is ${owner})`)}`);
4379
+ }
4360
4380
  console.log(` Binding: ${bindingOk ? chalk4.green("verified") : chalk4.red("FAILED")}`);
4361
4381
  if (!ownerOk) {
4362
4382
  console.log(chalk4.yellow(" The NFT moved since linking \u2014 re-run 'sherwood identity link-virtuals'."));
4363
4383
  }
4384
+ if (walletOnly) {
4385
+ console.log(chalk4.dim(" Upgrade to a registered link once ERC-8004 registration is available:"));
4386
+ console.log(chalk4.dim(" acp agent register-erc8004 ... && sherwood identity link-virtuals"));
4387
+ }
4364
4388
  } catch (err) {
4365
4389
  spinner2.warn("Could not re-verify against the issuing chain");
4366
4390
  console.log(chalk4.dim(` ${err.message}`));
@@ -6856,11 +6880,25 @@ function registerGuardianCommands(program2) {
6856
6880
  process.exit(1);
6857
6881
  }
6858
6882
  });
6859
- guardian.command("stake <amount>").description("Stake as a guardian. Amount in WOOD (min = registry.minGuardianStake).").option("--agent-id <id>", "ERC-8004 agent ID to associate (first-stake only)", "0").action(async (amountStr, opts) => {
6883
+ guardian.command("stake <amount>").description("Stake as a guardian. Amount in WOOD (min = registry.minGuardianStake).").option("--agent-id <id>", "ERC-8004 agent ID to associate (first-stake only; default: your linked identity, else 0)").action(async (amountStr, opts) => {
6860
6884
  const amount = parseUnits6(amountStr, 18);
6861
- const agentId = BigInt(opts.agentId);
6885
+ let agentIdStr = opts.agentId;
6886
+ if (agentIdStr == null) {
6887
+ const linked = getAgentId();
6888
+ if (linked != null) {
6889
+ agentIdStr = String(linked);
6890
+ const provider = getIdentityProvider();
6891
+ const chainNote = provider === "virtuals" ? getIdentityChainId() === 0 ? " (Virtuals, wallet-only)" : ` (Virtuals, chain ${getIdentityChainId()})` : "";
6892
+ console.log(chalk9.dim(` Associating linked identity #${linked}${chainNote} \u2014 override with --agent-id`));
6893
+ } else {
6894
+ agentIdStr = "0";
6895
+ console.log(chalk9.dim(" No linked identity \u2014 staking with agentId 0."));
6896
+ console.log(chalk9.dim(" Tip: sherwood identity mint / identity link-virtuals first to attribute your guardian work."));
6897
+ }
6898
+ }
6899
+ const agentId = BigInt(agentIdStr);
6862
6900
  if (isCalldataOnly()) {
6863
- emitCalldata(encodeGuardianStake({ amount, agentId: opts.agentId }, getChain().id));
6901
+ emitCalldata(encodeGuardianStake({ amount, agentId: agentIdStr }, getChain().id));
6864
6902
  return;
6865
6903
  }
6866
6904
  await ensureWoodAllowance(amount);
@@ -9593,7 +9631,7 @@ try {
9593
9631
  } catch {
9594
9632
  }
9595
9633
  var require2 = createRequire(import.meta.url);
9596
- var CLI_VERSION = "0.76.0";
9634
+ var CLI_VERSION = "0.78.0";
9597
9635
  async function loadXmtp() {
9598
9636
  return import("./xmtp-OZ5PJFCT.js");
9599
9637
  }
@@ -10510,7 +10548,8 @@ fund.command("requests").description("View pending join requests for a fund (cre
10510
10548
  const v = await verifyVidTag(vid, req.attester, ownerOfCached);
10511
10549
  const verified = v.bindingOk && v.ownerOk;
10512
10550
  const badge = verified ? G6("\u2714 verified") : chalk16.red("\u2718 FAILED");
10513
- console.log(W6(` Virtuals: ${badge} ${DIM6(`(agent #${vid.tokenId} on chain ${vid.issuingChainId}, wallet ${vid.wallet})`)}`));
10551
+ const detail = v.walletOnly ? `(wallet-only \u2014 no ERC-8004, wallet ${vid.wallet})` : `(agent #${vid.tokenId} on chain ${vid.issuingChainId}, wallet ${vid.wallet})`;
10552
+ console.log(W6(` Virtuals: ${badge} ${DIM6(detail)}`));
10514
10553
  if (!v.bindingOk) console.log(chalk16.red(` binding signature invalid \u2014 do not approve based on this identity`));
10515
10554
  else if (!v.ownerOk) console.log(chalk16.red(` NFT ownership check failed${v.owner ? ` (owner is ${v.owner})` : v.error ? ` (${v.error})` : ""}`));
10516
10555
  }