@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 +59 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
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(
|
|
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
|
-
|
|
4342
|
-
console.log(`
|
|
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
|
-
|
|
4347
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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.
|
|
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
|
-
|
|
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
|
}
|