@sherwoodagent/cli 0.75.0 → 0.77.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 +61 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3888,7 +3888,24 @@ async function verifyBinding(params) {
|
|
|
3888
3888
|
return false;
|
|
3889
3889
|
}
|
|
3890
3890
|
}
|
|
3891
|
+
var robinhoodChain = {
|
|
3892
|
+
id: 4663,
|
|
3893
|
+
name: "Robinhood Chain",
|
|
3894
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
3895
|
+
rpcUrls: { default: { http: ["https://rpc.mainnet.chain.robinhood.com"] } },
|
|
3896
|
+
blockExplorers: {
|
|
3897
|
+
default: {
|
|
3898
|
+
name: "Robinhood Chain Explorer",
|
|
3899
|
+
url: "https://explorer.mainnet.chain.robinhood.com"
|
|
3900
|
+
}
|
|
3901
|
+
}
|
|
3902
|
+
};
|
|
3903
|
+
var DEFAULT_ISSUING_CHAIN_ID = robinhoodChain.id;
|
|
3891
3904
|
var ISSUING_CHAINS = {
|
|
3905
|
+
[robinhoodChain.id]: {
|
|
3906
|
+
chain: robinhoodChain,
|
|
3907
|
+
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
|
|
3908
|
+
},
|
|
3892
3909
|
[base.id]: {
|
|
3893
3910
|
chain: base,
|
|
3894
3911
|
identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432"
|
|
@@ -3908,6 +3925,7 @@ var OWNER_OF_ABI = [
|
|
|
3908
3925
|
}
|
|
3909
3926
|
];
|
|
3910
3927
|
var ISSUING_RPC_ENV = {
|
|
3928
|
+
[robinhoodChain.id]: "ROBINHOOD_RPC_URL",
|
|
3911
3929
|
[base.id]: "BASE_RPC_URL",
|
|
3912
3930
|
[baseSepolia.id]: "BASE_SEPOLIA_RPC_URL"
|
|
3913
3931
|
};
|
|
@@ -3927,6 +3945,7 @@ async function ownerOfOnIssuingChain(issuingChainId, tokenId) {
|
|
|
3927
3945
|
args: [tokenId]
|
|
3928
3946
|
});
|
|
3929
3947
|
}
|
|
3948
|
+
var WALLET_ONLY_CHAIN_ID = 0;
|
|
3930
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*$/;
|
|
3931
3950
|
function formatVidTag(tag) {
|
|
3932
3951
|
return `[vid:${BINDING_VERSION}:${tag.issuingChainId}:${tag.tokenId}:${tag.wallet.toLowerCase()}:${tag.signature}]`;
|
|
@@ -3966,6 +3985,9 @@ async function verifyVidTag(tag, attester, ownerOf = ownerOfOnIssuingChain) {
|
|
|
3966
3985
|
if (!bindingOk) {
|
|
3967
3986
|
return { bindingOk: false, ownerOk: false, error: "binding failed \u2014 ownership check skipped" };
|
|
3968
3987
|
}
|
|
3988
|
+
if (tag.issuingChainId === WALLET_ONLY_CHAIN_ID) {
|
|
3989
|
+
return { bindingOk, ownerOk: true, walletOnly: true };
|
|
3990
|
+
}
|
|
3969
3991
|
try {
|
|
3970
3992
|
const owner = await ownerOf(tag.issuingChainId, tag.tokenId);
|
|
3971
3993
|
return {
|
|
@@ -4147,10 +4169,10 @@ function registerIdentityCommands(program2) {
|
|
|
4147
4169
|
process.exit(1);
|
|
4148
4170
|
}
|
|
4149
4171
|
});
|
|
4150
|
-
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 (8453 = Base, 84532 = Base Sepolia)",
|
|
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) => {
|
|
4151
4173
|
const account = getAccount();
|
|
4152
|
-
const issuingChainId = parseInt(opts.chainId, 10);
|
|
4153
|
-
if (!ISSUING_CHAINS[issuingChainId]) {
|
|
4174
|
+
const issuingChainId = opts.walletOnly ? WALLET_ONLY_CHAIN_ID : parseInt(opts.chainId, 10);
|
|
4175
|
+
if (!opts.walletOnly && !ISSUING_CHAINS[issuingChainId]) {
|
|
4154
4176
|
console.error(chalk4.red(`Unsupported issuing chain ${opts.chainId}. Supported: ${Object.keys(ISSUING_CHAINS).join(", ")}`));
|
|
4155
4177
|
process.exit(1);
|
|
4156
4178
|
}
|
|
@@ -4172,7 +4194,9 @@ function registerIdentityCommands(program2) {
|
|
|
4172
4194
|
process.exit(1);
|
|
4173
4195
|
}
|
|
4174
4196
|
let tokenId;
|
|
4175
|
-
if (opts.
|
|
4197
|
+
if (opts.walletOnly) {
|
|
4198
|
+
tokenId = 0n;
|
|
4199
|
+
} else if (opts.agentId) {
|
|
4176
4200
|
tokenId = BigInt(opts.agentId);
|
|
4177
4201
|
} else {
|
|
4178
4202
|
spinner.text = `Searching ERC-8004 registry on chain ${issuingChainId} for ${virtualsWallet}...`;
|
|
@@ -4190,6 +4214,7 @@ function registerIdentityCommands(program2) {
|
|
|
4190
4214
|
console.error(chalk4.dim(" Register first via the Virtuals CLI:"));
|
|
4191
4215
|
console.error(chalk4.dim(` acp agent register-erc8004 --agent-id ${virtualsAgentId ?? "<id>"} --chain-id ${issuingChainId}`));
|
|
4192
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"));
|
|
4193
4218
|
process.exit(1);
|
|
4194
4219
|
}
|
|
4195
4220
|
if (results.length > 1) {
|
|
@@ -4209,11 +4234,13 @@ function registerIdentityCommands(program2) {
|
|
|
4209
4234
|
spinner.fail(`Token ID ${tokenId} exceeds Number.MAX_SAFE_INTEGER \u2014 cannot be stored in config`);
|
|
4210
4235
|
process.exit(1);
|
|
4211
4236
|
}
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
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
|
+
}
|
|
4217
4244
|
}
|
|
4218
4245
|
const self = virtualsWallet.toLowerCase() === account.address.toLowerCase();
|
|
4219
4246
|
const bindingMessage = buildBindingMessage(account.address, issuingChainId, tokenId);
|
|
@@ -4250,7 +4277,9 @@ function registerIdentityCommands(program2) {
|
|
|
4250
4277
|
wallet: virtualsWallet,
|
|
4251
4278
|
binding
|
|
4252
4279
|
});
|
|
4253
|
-
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
|
+
);
|
|
4254
4283
|
console.log(chalk4.dim(` economyOS wallet: ${virtualsWallet}`));
|
|
4255
4284
|
if (virtualsAgentId) console.log(chalk4.dim(` Virtuals agent: ${virtualsAgentId}`));
|
|
4256
4285
|
console.log(chalk4.dim(` Sherwood wallet: ${account.address}${self ? " (same as economyOS wallet \u2014 no binding needed)" : " (bound via signature)"}`));
|
|
@@ -4320,13 +4349,18 @@ function registerIdentityCommands(program2) {
|
|
|
4320
4349
|
console.log(` Sherwood wallet: ${account.address}`);
|
|
4321
4350
|
console.log(` economyOS wallet: ${virtuals?.wallet ?? chalk4.red("(missing)")}`);
|
|
4322
4351
|
if (virtuals?.agentId) console.log(` Virtuals agent: ${virtuals.agentId}`);
|
|
4323
|
-
|
|
4324
|
-
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)")}`);
|
|
4325
4355
|
if (virtuals?.wallet && savedId != null && issuingChainId != null) {
|
|
4326
4356
|
const spinner2 = ora4("Re-verifying link...").start();
|
|
4327
4357
|
try {
|
|
4328
|
-
|
|
4329
|
-
|
|
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
|
+
}
|
|
4330
4364
|
let bindingOk = virtuals.wallet.toLowerCase() === account.address.toLowerCase();
|
|
4331
4365
|
if (!bindingOk && virtuals.binding?.sig) {
|
|
4332
4366
|
bindingOk = await verifyBinding({
|
|
@@ -4338,11 +4372,19 @@ function registerIdentityCommands(program2) {
|
|
|
4338
4372
|
});
|
|
4339
4373
|
}
|
|
4340
4374
|
spinner2.stop();
|
|
4341
|
-
|
|
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
|
+
}
|
|
4342
4380
|
console.log(` Binding: ${bindingOk ? chalk4.green("verified") : chalk4.red("FAILED")}`);
|
|
4343
4381
|
if (!ownerOk) {
|
|
4344
4382
|
console.log(chalk4.yellow(" The NFT moved since linking \u2014 re-run 'sherwood identity link-virtuals'."));
|
|
4345
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
|
+
}
|
|
4346
4388
|
} catch (err) {
|
|
4347
4389
|
spinner2.warn("Could not re-verify against the issuing chain");
|
|
4348
4390
|
console.log(chalk4.dim(` ${err.message}`));
|
|
@@ -9575,7 +9617,7 @@ try {
|
|
|
9575
9617
|
} catch {
|
|
9576
9618
|
}
|
|
9577
9619
|
var require2 = createRequire(import.meta.url);
|
|
9578
|
-
var CLI_VERSION = "0.
|
|
9620
|
+
var CLI_VERSION = "0.77.0";
|
|
9579
9621
|
async function loadXmtp() {
|
|
9580
9622
|
return import("./xmtp-OZ5PJFCT.js");
|
|
9581
9623
|
}
|
|
@@ -10315,7 +10357,7 @@ fund.command("join").description("Request to join a fund (creates an EAS attesta
|
|
|
10315
10357
|
const virtualsIdentity = getVirtualsIdentity();
|
|
10316
10358
|
if (getIdentityProvider() === "virtuals" && virtualsIdentity) {
|
|
10317
10359
|
joinMessage = appendVidTag(joinMessage, {
|
|
10318
|
-
issuingChainId: getIdentityChainId() ??
|
|
10360
|
+
issuingChainId: getIdentityChainId() ?? DEFAULT_ISSUING_CHAIN_ID,
|
|
10319
10361
|
tokenId: BigInt(agentId),
|
|
10320
10362
|
wallet: virtualsIdentity.wallet,
|
|
10321
10363
|
signature: virtualsIdentity.binding?.sig ?? "self"
|
|
@@ -10492,7 +10534,8 @@ fund.command("requests").description("View pending join requests for a fund (cre
|
|
|
10492
10534
|
const v = await verifyVidTag(vid, req.attester, ownerOfCached);
|
|
10493
10535
|
const verified = v.bindingOk && v.ownerOk;
|
|
10494
10536
|
const badge = verified ? G6("\u2714 verified") : chalk16.red("\u2718 FAILED");
|
|
10495
|
-
|
|
10537
|
+
const detail = v.walletOnly ? `(wallet-only \u2014 no ERC-8004, wallet ${vid.wallet})` : `(agent #${vid.tokenId} on chain ${vid.issuingChainId}, wallet ${vid.wallet})`;
|
|
10538
|
+
console.log(W6(` Virtuals: ${badge} ${DIM6(detail)}`));
|
|
10496
10539
|
if (!v.bindingOk) console.log(chalk16.red(` binding signature invalid \u2014 do not approve based on this identity`));
|
|
10497
10540
|
else if (!v.ownerOk) console.log(chalk16.red(` NFT ownership check failed${v.owner ? ` (owner is ${v.owner})` : v.error ? ` (${v.error})` : ""}`));
|
|
10498
10541
|
}
|