easctl 0.1.2 → 0.2.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/README.md CHANGED
@@ -24,7 +24,7 @@ Store your private key for persistent use:
24
24
  easctl set-key 0xYourPrivateKeyHere
25
25
  ```
26
26
 
27
- This saves the key to `~/.eas-cli` (file permissions `0600`, owner-only) and displays your wallet address for confirmation.
27
+ This saves the key to `~/.easctl` (file permissions `0600`, owner-only) and displays your wallet address for confirmation.
28
28
 
29
29
  To remove the stored key:
30
30
 
package/dist/index.js CHANGED
@@ -22504,13 +22504,16 @@ var require_dist4 = __commonJS({
22504
22504
  });
22505
22505
 
22506
22506
  // src/index.ts
22507
- var import_commander17 = require("commander");
22507
+ var import_commander19 = require("commander");
22508
22508
 
22509
22509
  // src/output.ts
22510
22510
  var jsonMode = false;
22511
22511
  function setJsonMode(enabled) {
22512
22512
  jsonMode = enabled;
22513
22513
  }
22514
+ function isJsonMode() {
22515
+ return jsonMode;
22516
+ }
22514
22517
  function output(result) {
22515
22518
  if (jsonMode) {
22516
22519
  console.log(JSON.stringify(result, bigintReplacer, 2));
@@ -30611,7 +30614,7 @@ var import_fs = require("fs");
30611
30614
  var import_os = require("os");
30612
30615
  var import_path = require("path");
30613
30616
  function getConfigPath() {
30614
- return (0, import_path.join)((0, import_os.homedir)(), ".eas-cli");
30617
+ return (0, import_path.join)((0, import_os.homedir)(), ".easctl");
30615
30618
  }
30616
30619
  function readConfig() {
30617
30620
  try {
@@ -30689,6 +30692,108 @@ async function resolveInput(value) {
30689
30692
  return value === "-" ? readStdin() : value;
30690
30693
  }
30691
30694
 
30695
+ // src/popular-schemas.ts
30696
+ var POPULAR_SCHEMAS = [
30697
+ // General
30698
+ {
30699
+ name: "make-a-statement",
30700
+ schema: "string statement",
30701
+ uid: "0xf58b8b212ef75ee8cd7e8d803c37c03e0519890502d5e99ee2412aae1456cafe",
30702
+ description: "General-purpose text statement or note",
30703
+ revocable: true,
30704
+ category: "general"
30705
+ },
30706
+ {
30707
+ name: "is-true",
30708
+ schema: "bool isTrue",
30709
+ uid: "0x4eb603f49d68888d7f8b1fadd351b35a252f287ba465408ceb2b1e1e1efd90d5",
30710
+ description: "Simple boolean assertion",
30711
+ revocable: true,
30712
+ category: "general"
30713
+ },
30714
+ {
30715
+ name: "score",
30716
+ schema: "uint256 score",
30717
+ uid: "0xef2dbf5e8da46ea760bb4c6eb2635bf04adfc1ade6158e594263363db2a55bcf",
30718
+ description: "Numeric score or rating",
30719
+ revocable: true,
30720
+ category: "general"
30721
+ },
30722
+ {
30723
+ name: "tag",
30724
+ schema: "bytes32 tag",
30725
+ uid: "0x7d105b048bfc4c781474627045d2fb9008016018b3f2af686eef31ee6d1d5857",
30726
+ description: "Arbitrary tag or label",
30727
+ revocable: true,
30728
+ category: "general"
30729
+ },
30730
+ // Identity
30731
+ {
30732
+ name: "is-a-human",
30733
+ schema: "bool isHuman",
30734
+ uid: "0x8af15e65888f2e3b487e536a4922e277dcfe85b4b18187b0cf9afdb802ba6bb6",
30735
+ description: "Humanity verification attestation",
30736
+ revocable: true,
30737
+ category: "identity"
30738
+ },
30739
+ {
30740
+ name: "verified-account",
30741
+ schema: "string platform, string username",
30742
+ uid: "0xa0ce1ea8fd393b308ec22d86a9a4451bb16e61f455f964374f2105a371077d02",
30743
+ description: "Social account verification (platform + username)",
30744
+ revocable: true,
30745
+ category: "identity"
30746
+ },
30747
+ // Social
30748
+ {
30749
+ name: "is-a-friend",
30750
+ schema: "bool isFriend",
30751
+ uid: "0x27d06e3659317e9a4f8154d1e849eb53d43d91fb4f219884d1684f86d797804a",
30752
+ description: "Friendship attestation",
30753
+ revocable: true,
30754
+ category: "social"
30755
+ },
30756
+ {
30757
+ name: "met-irl",
30758
+ schema: "bool metIRL",
30759
+ uid: "0xc59265615401143689cbfe73046a922c975c99d97e4c248070435b1104b2dea7",
30760
+ description: "Attest that you met someone in real life",
30761
+ revocable: true,
30762
+ category: "social"
30763
+ },
30764
+ {
30765
+ name: "vouch",
30766
+ schema: "address vouched, string context",
30767
+ uid: "0xec3decee9f94f4ef4d1a95b23743ac4904b1b8687164e266564945efd435cf48",
30768
+ description: "Vouch for an address with context",
30769
+ revocable: true,
30770
+ category: "social"
30771
+ },
30772
+ {
30773
+ name: "endorsement",
30774
+ schema: "string endorsement",
30775
+ uid: "0xb7fb3a3cae206db4784b42600aaaa640d20babf3b2d4b45161c4856f2b6c6aec",
30776
+ description: "Open-ended endorsement",
30777
+ revocable: true,
30778
+ category: "social"
30779
+ }
30780
+ ];
30781
+ var byName = new Map(POPULAR_SCHEMAS.map((s) => [s.name, s]));
30782
+ function resolveSchemaUID(value) {
30783
+ const schema = byName.get(value);
30784
+ return schema ? schema.uid : value;
30785
+ }
30786
+ function listPopularSchemas() {
30787
+ return POPULAR_SCHEMAS;
30788
+ }
30789
+ function listPopularSchemasByCategory() {
30790
+ const grouped = {};
30791
+ for (const s of POPULAR_SCHEMAS) {
30792
+ (grouped[s.category] ??= []).push(s);
30793
+ }
30794
+ return grouped;
30795
+ }
30796
+
30692
30797
  // src/validation.ts
30693
30798
  var ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
30694
30799
  function validateAddress(value, label) {
@@ -30702,11 +30807,16 @@ function validateBytes32(value, label) {
30702
30807
  throw new Error(`Invalid ${label}: expected 0x + 64 hex characters, got "${value}"`);
30703
30808
  }
30704
30809
  }
30810
+ function resolveAndValidateSchemaUID(value, label) {
30811
+ const resolved = resolveSchemaUID(value);
30812
+ validateBytes32(resolved, label);
30813
+ return resolved;
30814
+ }
30705
30815
 
30706
30816
  // src/commands/attest.ts
30707
- var attestCommand = new import_commander.Command("attest").description("Create an on-chain attestation").requiredOption("-s, --schema <uid>", "Schema UID to attest with").requiredOption("-d, --data <json>", 'Attestation data as JSON array: [{"name":"field","type":"uint256","value":"123"}]').option("-r, --recipient <address>", "Recipient address", "0x0000000000000000000000000000000000000000").option("--ref-uid <uid>", "Referenced attestation UID", ZERO_BYTES32).option("--expiration <timestamp>", "Expiration timestamp (0 for none)", "0").option("--revocable", "Whether the attestation is revocable", true).option("--no-revocable", "Make the attestation non-revocable").option("--value <wei>", "ETH value to send (in wei)", "0").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").option("--dry-run", "Estimate gas without sending the transaction").action(async (opts) => {
30817
+ var attestCommand = new import_commander.Command("attest").description("Create an on-chain attestation").requiredOption("-s, --schema <uid>", "Schema UID or popular schema name").requiredOption("-d, --data <json>", 'Attestation data as JSON array: [{"name":"field","type":"uint256","value":"123"}]').option("-r, --recipient <address>", "Recipient address", "0x0000000000000000000000000000000000000000").option("--ref-uid <uid>", "Referenced attestation UID", ZERO_BYTES32).option("--expiration <timestamp>", "Expiration timestamp (0 for none)", "0").option("--revocable", "Whether the attestation is revocable", true).option("--no-revocable", "Make the attestation non-revocable").option("--value <wei>", "ETH value to send (in wei)", "0").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").option("--dry-run", "Estimate gas without sending the transaction").action(async (opts) => {
30708
30818
  try {
30709
- validateBytes32(opts.schema, "schema UID");
30819
+ opts.schema = resolveAndValidateSchemaUID(opts.schema, "schema UID");
30710
30820
  if (opts.recipient !== "0x0000000000000000000000000000000000000000") {
30711
30821
  validateAddress(opts.recipient, "recipient");
30712
30822
  }
@@ -30756,9 +30866,9 @@ var attestCommand = new import_commander.Command("attest").description("Create a
30756
30866
 
30757
30867
  // src/commands/revoke.ts
30758
30868
  var import_commander2 = require("commander");
30759
- var revokeCommand = new import_commander2.Command("revoke").description("Revoke an on-chain attestation").requiredOption("-s, --schema <uid>", "Schema UID of the attestation").requiredOption("-u, --uid <uid>", "Attestation UID to revoke").option("--value <wei>", "ETH value to send (in wei)", "0").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").option("--dry-run", "Estimate gas without sending the transaction").action(async (opts) => {
30869
+ var revokeCommand = new import_commander2.Command("revoke").description("Revoke an on-chain attestation").requiredOption("-s, --schema <uid>", "Schema UID or popular schema name").requiredOption("-u, --uid <uid>", "Attestation UID to revoke").option("--value <wei>", "ETH value to send (in wei)", "0").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").option("--dry-run", "Estimate gas without sending the transaction").action(async (opts) => {
30760
30870
  try {
30761
- validateBytes32(opts.schema, "schema UID");
30871
+ opts.schema = resolveAndValidateSchemaUID(opts.schema, "schema UID");
30762
30872
  validateBytes32(opts.uid, "attestation UID");
30763
30873
  const client = createEASClient(opts.chain, opts.rpcUrl);
30764
30874
  const tx = await client.eas.revoke({
@@ -30871,9 +30981,9 @@ var schemaRegisterCommand = new import_commander4.Command("schema-register").des
30871
30981
 
30872
30982
  // src/commands/schema-get.ts
30873
30983
  var import_commander5 = require("commander");
30874
- var schemaGetCommand = new import_commander5.Command("schema-get").description("Get a schema by UID").requiredOption("-u, --uid <uid>", "Schema UID").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").action(async (opts) => {
30984
+ var schemaGetCommand = new import_commander5.Command("schema-get").description("Get a schema by UID").requiredOption("-u, --uid <uid>", "Schema UID or popular schema name").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").action(async (opts) => {
30875
30985
  try {
30876
- validateBytes32(opts.uid, "schema UID");
30986
+ opts.uid = resolveAndValidateSchemaUID(opts.uid, "schema UID");
30877
30987
  const client = createReadOnlyEASClient(opts.chain, opts.rpcUrl);
30878
30988
  const schema = await client.schemaRegistry.getSchema({ uid: opts.uid });
30879
30989
  output({
@@ -30904,6 +31014,7 @@ var multiAttestCommand = new import_commander6.Command("multi-attest").descripti
30904
31014
  }
30905
31015
  const grouped = /* @__PURE__ */ new Map();
30906
31016
  for (const input of inputs) {
31017
+ input.schema = resolveSchemaUID(input.schema);
30907
31018
  const schemaString = input.data.map((item) => `${item.type} ${item.name}`).join(", ");
30908
31019
  const encoder = new SchemaEncoder(schemaString);
30909
31020
  const encodedData = encoder.encodeData(input.data);
@@ -31087,9 +31198,9 @@ var QUERIES = {
31087
31198
  };
31088
31199
 
31089
31200
  // src/commands/offchain-attest.ts
31090
- var offchainAttestCommand = new import_commander7.Command("offchain-attest").description("Create an off-chain attestation (signed but not submitted on-chain)").requiredOption("-s, --schema <uid>", "Schema UID").requiredOption("-d, --data <json>", 'Attestation data as JSON array: [{"name":"field","type":"uint256","value":"123"}]').option("-r, --recipient <address>", "Recipient address", "0x0000000000000000000000000000000000000000").option("--ref-uid <uid>", "Referenced attestation UID", ZERO_BYTES32).option("--expiration <timestamp>", "Expiration timestamp (0 for none)", "0").option("--revocable", "Whether the attestation is revocable", true).option("--no-revocable", "Make the attestation non-revocable").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").action(async (opts) => {
31201
+ var offchainAttestCommand = new import_commander7.Command("offchain-attest").description("Create an off-chain attestation (signed but not submitted on-chain)").requiredOption("-s, --schema <uid>", "Schema UID or popular schema name").requiredOption("-d, --data <json>", 'Attestation data as JSON array: [{"name":"field","type":"uint256","value":"123"}]').option("-r, --recipient <address>", "Recipient address", "0x0000000000000000000000000000000000000000").option("--ref-uid <uid>", "Referenced attestation UID", ZERO_BYTES32).option("--expiration <timestamp>", "Expiration timestamp (0 for none)", "0").option("--revocable", "Whether the attestation is revocable", true).option("--no-revocable", "Make the attestation non-revocable").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").action(async (opts) => {
31091
31202
  try {
31092
- validateBytes32(opts.schema, "schema UID");
31203
+ opts.schema = resolveAndValidateSchemaUID(opts.schema, "schema UID");
31093
31204
  if (opts.recipient !== "0x0000000000000000000000000000000000000000") {
31094
31205
  validateAddress(opts.recipient, "recipient");
31095
31206
  }
@@ -31164,9 +31275,9 @@ var timestampCommand = new import_commander8.Command("timestamp").description("T
31164
31275
 
31165
31276
  // src/commands/query-schema.ts
31166
31277
  var import_commander9 = require("commander");
31167
- var querySchemaCommand = new import_commander9.Command("query-schema").description("Query a schema from the EAS GraphQL API").requiredOption("-u, --uid <uid>", "Schema UID").option("-c, --chain <name>", "Chain name", "ethereum").action(async (opts) => {
31278
+ var querySchemaCommand = new import_commander9.Command("query-schema").description("Query a schema from the EAS GraphQL API").requiredOption("-u, --uid <uid>", "Schema UID or popular schema name").option("-c, --chain <name>", "Chain name", "ethereum").action(async (opts) => {
31168
31279
  try {
31169
- validateBytes32(opts.uid, "schema UID");
31280
+ opts.uid = resolveAndValidateSchemaUID(opts.uid, "schema UID");
31170
31281
  const data = await graphqlQuery(opts.chain, QUERIES.getSchema, { id: opts.uid });
31171
31282
  if (!data.schema) {
31172
31283
  throw new Error(`Schema ${opts.uid} not found on ${opts.chain}`);
@@ -31201,12 +31312,12 @@ var queryAttestationCommand = new import_commander10.Command("query-attestation"
31201
31312
 
31202
31313
  // src/commands/query-attestations.ts
31203
31314
  var import_commander11 = require("commander");
31204
- var queryAttestationsCommand = new import_commander11.Command("query-attestations").description("Query attestations by schema or attester from the EAS GraphQL API").option("-s, --schema <uid>", "Filter by schema UID").option("-a, --attester <address>", "Filter by attester address").option("-n, --limit <number>", "Max results to return", "10").option("--skip <number>", "Number of results to skip (for pagination)", "0").option("-c, --chain <name>", "Chain name", "ethereum").action(async (opts) => {
31315
+ var queryAttestationsCommand = new import_commander11.Command("query-attestations").description("Query attestations by schema or attester from the EAS GraphQL API").option("-s, --schema <uid>", "Filter by schema UID or popular schema name").option("-a, --attester <address>", "Filter by attester address").option("-n, --limit <number>", "Max results to return", "10").option("--skip <number>", "Number of results to skip (for pagination)", "0").option("-c, --chain <name>", "Chain name", "ethereum").action(async (opts) => {
31205
31316
  try {
31206
31317
  if (!opts.schema && !opts.attester) {
31207
31318
  throw new Error("Provide at least one filter: --schema or --attester");
31208
31319
  }
31209
- if (opts.schema) validateBytes32(opts.schema, "schema UID");
31320
+ if (opts.schema) opts.schema = resolveAndValidateSchemaUID(opts.schema, "schema UID");
31210
31321
  if (opts.attester) validateAddress(opts.attester, "attester");
31211
31322
  const take = parseInt(opts.limit, 10);
31212
31323
  const skip = parseInt(opts.skip, 10);
@@ -31281,6 +31392,7 @@ var multiRevokeCommand = new import_commander13.Command("multi-revoke").descript
31281
31392
  }
31282
31393
  const grouped = /* @__PURE__ */ new Map();
31283
31394
  for (const input of inputs) {
31395
+ input.schema = resolveSchemaUID(input.schema);
31284
31396
  if (!grouped.has(input.schema)) {
31285
31397
  grouped.set(input.schema, { schema: input.schema, data: [] });
31286
31398
  }
@@ -31345,7 +31457,7 @@ var multiTimestampCommand = new import_commander14.Command("multi-timestamp").de
31345
31457
  // src/commands/set-key.ts
31346
31458
  var import_commander15 = require("commander");
31347
31459
  var import_ethers12 = require("ethers");
31348
- var setKeyCommand = new import_commander15.Command("set-key").description("Store your private key in ~/.eas-cli for future use").argument("<key>", "Wallet private key (hex string, with or without 0x prefix)").action((key) => {
31460
+ var setKeyCommand = new import_commander15.Command("set-key").description("Store your private key in ~/.easctl for future use").argument("<key>", "Wallet private key (hex string, with or without 0x prefix)").action((key) => {
31349
31461
  const normalized = key.startsWith("0x") ? key : `0x${key}`;
31350
31462
  try {
31351
31463
  const wallet = new import_ethers12.ethers.Wallet(normalized);
@@ -31358,7 +31470,7 @@ var setKeyCommand = new import_commander15.Command("set-key").description("Store
31358
31470
 
31359
31471
  // src/commands/clear-key.ts
31360
31472
  var import_commander16 = require("commander");
31361
- var clearKeyCommand = new import_commander16.Command("clear-key").description("Remove the stored private key from ~/.eas-cli").action(() => {
31473
+ var clearKeyCommand = new import_commander16.Command("clear-key").description("Remove the stored private key from ~/.easctl").action(() => {
31362
31474
  if (!getStoredPrivateKey()) {
31363
31475
  output({ success: true, data: { cleared: false, message: "No private key is currently stored" } });
31364
31476
  return;
@@ -31367,9 +31479,83 @@ var clearKeyCommand = new import_commander16.Command("clear-key").description("R
31367
31479
  output({ success: true, data: { cleared: true } });
31368
31480
  });
31369
31481
 
31482
+ // src/commands/popular-schemas.ts
31483
+ var import_commander17 = require("commander");
31484
+ var popularSchemasCommand = new import_commander17.Command("popular-schemas").description("List popular EAS schemas with names, UIDs, and descriptions").option("--category <name>", "Filter by category (general, identity, social)").action(async (opts) => {
31485
+ try {
31486
+ if (isJsonMode()) {
31487
+ const schemas = opts.category ? listPopularSchemas().filter((s) => s.category === opts.category) : listPopularSchemas();
31488
+ if (opts.category && schemas.length === 0) {
31489
+ const categories2 = [...new Set(listPopularSchemas().map((s) => s.category))];
31490
+ throw new Error(`Unknown category "${opts.category}". Available: ${categories2.join(", ")}`);
31491
+ }
31492
+ output({ success: true, data: { count: schemas.length, schemas } });
31493
+ return;
31494
+ }
31495
+ const byCategory = listPopularSchemasByCategory();
31496
+ const categories = opts.category ? { [opts.category]: byCategory[opts.category] } : byCategory;
31497
+ if (opts.category && !byCategory[opts.category]) {
31498
+ const available = Object.keys(byCategory).join(", ");
31499
+ throw new Error(`Unknown category "${opts.category}". Available: ${available}`);
31500
+ }
31501
+ for (const [category, schemas] of Object.entries(categories)) {
31502
+ console.log(`
31503
+ === ${category} ===
31504
+ `);
31505
+ for (const s of schemas) {
31506
+ console.log(` ${s.name}`);
31507
+ console.log(` Schema: ${s.schema}`);
31508
+ console.log(` UID: ${s.uid}`);
31509
+ console.log(` Revocable: ${s.revocable ? "yes" : "no"}`);
31510
+ console.log(` ${s.description}
31511
+ `);
31512
+ }
31513
+ }
31514
+ } catch (err2) {
31515
+ handleError(err2);
31516
+ }
31517
+ });
31518
+
31519
+ // src/commands/status.ts
31520
+ var import_commander18 = require("commander");
31521
+ var import_ethers13 = require("ethers");
31522
+ var statusCommand = new import_commander18.Command("status").description("Show current configuration: wallet, chain, and contract addresses").option("-c, --chain <name>", "Chain name", "ethereum").option("--rpc-url <url>", "Custom RPC URL").action(async (opts) => {
31523
+ const key = process.env.EAS_PRIVATE_KEY || getStoredPrivateKey();
31524
+ const source = process.env.EAS_PRIVATE_KEY ? "env" : key ? "stored" : void 0;
31525
+ let address;
31526
+ if (key) {
31527
+ try {
31528
+ const normalized = key.startsWith("0x") ? key : `0x${key}`;
31529
+ address = new import_ethers13.ethers.Wallet(normalized).address;
31530
+ } catch {
31531
+ }
31532
+ }
31533
+ const chainConfig = CHAIN_CONFIGS[opts.chain];
31534
+ const rpcUrl = opts.rpcUrl || chainConfig?.defaultRpc || "none";
31535
+ output({
31536
+ success: true,
31537
+ data: {
31538
+ wallet: {
31539
+ privateKey: source ? address ? `set (${source})` : `set (invalid format)` : "not set",
31540
+ address: address || "n/a"
31541
+ },
31542
+ chain: {
31543
+ name: opts.chain,
31544
+ chainId: chainConfig?.chainId ?? "unknown chain",
31545
+ rpcUrl
31546
+ },
31547
+ contracts: chainConfig ? {
31548
+ eas: chainConfig.eas,
31549
+ schemaRegistry: chainConfig.schemaRegistry
31550
+ } : "unknown chain",
31551
+ supportedChains: listChains().join(", ")
31552
+ }
31553
+ });
31554
+ });
31555
+
31370
31556
  // src/index.ts
31371
- var program = new import_commander17.Command();
31372
- program.name("easctl").description("Ethereum Attestation Service CLI \u2014 create, revoke, and query attestations").version("0.1.2").option("--json", "Output results as JSON (useful for agents and scripting)").hook("preAction", (thisCommand, actionCommand) => {
31557
+ var program = new import_commander19.Command();
31558
+ program.name("easctl").description("Ethereum Attestation Service CLI \u2014 create, revoke, and query attestations").version("0.2.0").option("--json", "Output results as JSON (useful for agents and scripting)").hook("preAction", (thisCommand, actionCommand) => {
31373
31559
  if (thisCommand.opts().json || actionCommand.opts().json) {
31374
31560
  setJsonMode(true);
31375
31561
  }
@@ -31382,6 +31568,7 @@ program.addCommand(multiRevokeCommand);
31382
31568
  program.addCommand(getAttestationCommand);
31383
31569
  program.addCommand(schemaRegisterCommand);
31384
31570
  program.addCommand(schemaGetCommand);
31571
+ program.addCommand(popularSchemasCommand);
31385
31572
  program.addCommand(timestampCommand);
31386
31573
  program.addCommand(multiTimestampCommand);
31387
31574
  program.addCommand(querySchemaCommand);
@@ -31390,6 +31577,7 @@ program.addCommand(queryAttestationsCommand);
31390
31577
  program.addCommand(querySchemasCommand);
31391
31578
  program.addCommand(setKeyCommand);
31392
31579
  program.addCommand(clearKeyCommand);
31580
+ program.addCommand(statusCommand);
31393
31581
  program.command("chains").description("List supported chains and their EAS contract addresses").action(() => {
31394
31582
  const chains = listChains();
31395
31583
  output({ success: true, data: { chains } });