easctl 0.1.3 → 0.2.1
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 +21 -1
- package/dist/index.js +234 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/commands/attest.test.ts +1 -0
- package/src/__tests__/commands/multi-attest.test.ts +4 -0
- package/src/__tests__/commands/multi-revoke.test.ts +4 -0
- package/src/__tests__/commands/offchain-attest.test.ts +1 -0
- package/src/__tests__/commands/query-attestations.test.ts +16 -0
- package/src/__tests__/commands/query-schema.test.ts +1 -0
- package/src/__tests__/commands/revoke.test.ts +1 -0
- package/src/__tests__/commands/schema-get.test.ts +1 -0
- package/src/__tests__/commands/status.test.ts +121 -0
- package/src/__tests__/integration/graphql-live.test.ts +10 -0
- package/src/commands/attest.ts +3 -3
- package/src/commands/multi-attest.ts +2 -0
- package/src/commands/multi-revoke.ts +2 -0
- package/src/commands/offchain-attest.ts +3 -3
- package/src/commands/popular-schemas.ts +43 -0
- package/src/commands/query-attestations.ts +14 -6
- package/src/commands/query-schema.ts +3 -3
- package/src/commands/revoke.ts +3 -3
- package/src/commands/schema-get.ts +3 -3
- package/src/commands/status.ts +49 -0
- package/src/graphql.ts +18 -0
- package/src/index.ts +6 -0
- package/src/popular-schemas.ts +119 -0
- package/src/validation.ts +8 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Command-line interface for the [Ethereum Attestation Service](https://attest.org). Built on [EAS SDK v2](https://github.com/ethereum-attestation-service/eas-sdk-v2) and [ethers](https://docs.ethers.org).
|
|
4
4
|
|
|
5
|
-
All commands support `--json` for structured output
|
|
5
|
+
All commands support `--json` for structured output, `--dry-run` for gas estimation, and popular schema names (e.g. `--schema make-a-statement`) instead of raw UIDs.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -88,8 +88,24 @@ easctl schema-register --schema "uint256 score, string comment" --chain sepolia
|
|
|
88
88
|
|
|
89
89
|
# Get a schema by UID (read-only)
|
|
90
90
|
easctl schema-get --uid 0xSchemaUID --chain sepolia
|
|
91
|
+
|
|
92
|
+
# Browse popular schemas
|
|
93
|
+
easctl popular-schemas
|
|
94
|
+
easctl popular-schemas --category social
|
|
95
|
+
easctl popular-schemas --json
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### Popular Schema Names
|
|
99
|
+
|
|
100
|
+
Instead of raw UIDs, you can use popular schema names anywhere a schema UID is accepted:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
easctl attest --schema make-a-statement --data '[{"name":"statement","type":"string","value":"Hello EAS"}]'
|
|
104
|
+
easctl query-attestations --schema is-a-friend --chain base
|
|
91
105
|
```
|
|
92
106
|
|
|
107
|
+
Run `easctl popular-schemas` to see all available names.
|
|
108
|
+
|
|
93
109
|
### Timestamps
|
|
94
110
|
|
|
95
111
|
```bash
|
|
@@ -122,6 +138,10 @@ easctl query-schemas --creator 0xAddress --limit 20 --chain sepolia
|
|
|
122
138
|
### Utility
|
|
123
139
|
|
|
124
140
|
```bash
|
|
141
|
+
# Show wallet, chain, and contract configuration
|
|
142
|
+
easctl status
|
|
143
|
+
easctl status --chain base
|
|
144
|
+
|
|
125
145
|
# List supported chains
|
|
126
146
|
easctl chains
|
|
127
147
|
```
|
package/dist/index.js
CHANGED
|
@@ -22504,13 +22504,16 @@ var require_dist4 = __commonJS({
|
|
|
22504
22504
|
});
|
|
22505
22505
|
|
|
22506
22506
|
// src/index.ts
|
|
22507
|
-
var
|
|
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)(), ".
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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);
|
|
@@ -31053,6 +31164,24 @@ var QUERIES = {
|
|
|
31053
31164
|
}
|
|
31054
31165
|
}
|
|
31055
31166
|
`,
|
|
31167
|
+
getAttestationsByRecipient: `
|
|
31168
|
+
query GetAttestationsByRecipient($recipient: String!, $take: Int, $skip: Int) {
|
|
31169
|
+
attestations(
|
|
31170
|
+
where: { recipient: { equals: $recipient } }
|
|
31171
|
+
take: $take
|
|
31172
|
+
skip: $skip
|
|
31173
|
+
orderBy: [{ time: desc }]
|
|
31174
|
+
) {
|
|
31175
|
+
id
|
|
31176
|
+
attester
|
|
31177
|
+
schemaId
|
|
31178
|
+
time
|
|
31179
|
+
revoked
|
|
31180
|
+
decodedDataJson
|
|
31181
|
+
isOffchain
|
|
31182
|
+
}
|
|
31183
|
+
}
|
|
31184
|
+
`,
|
|
31056
31185
|
getSchemata: `
|
|
31057
31186
|
query GetSchemata($take: Int, $skip: Int) {
|
|
31058
31187
|
schemata(
|
|
@@ -31087,9 +31216,9 @@ var QUERIES = {
|
|
|
31087
31216
|
};
|
|
31088
31217
|
|
|
31089
31218
|
// 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) => {
|
|
31219
|
+
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
31220
|
try {
|
|
31092
|
-
|
|
31221
|
+
opts.schema = resolveAndValidateSchemaUID(opts.schema, "schema UID");
|
|
31093
31222
|
if (opts.recipient !== "0x0000000000000000000000000000000000000000") {
|
|
31094
31223
|
validateAddress(opts.recipient, "recipient");
|
|
31095
31224
|
}
|
|
@@ -31164,9 +31293,9 @@ var timestampCommand = new import_commander8.Command("timestamp").description("T
|
|
|
31164
31293
|
|
|
31165
31294
|
// src/commands/query-schema.ts
|
|
31166
31295
|
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) => {
|
|
31296
|
+
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
31297
|
try {
|
|
31169
|
-
|
|
31298
|
+
opts.uid = resolveAndValidateSchemaUID(opts.uid, "schema UID");
|
|
31170
31299
|
const data = await graphqlQuery(opts.chain, QUERIES.getSchema, { id: opts.uid });
|
|
31171
31300
|
if (!data.schema) {
|
|
31172
31301
|
throw new Error(`Schema ${opts.uid} not found on ${opts.chain}`);
|
|
@@ -31201,13 +31330,14 @@ var queryAttestationCommand = new import_commander10.Command("query-attestation"
|
|
|
31201
31330
|
|
|
31202
31331
|
// src/commands/query-attestations.ts
|
|
31203
31332
|
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) => {
|
|
31333
|
+
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("-r, --recipient <address>", "Filter by recipient 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
31334
|
try {
|
|
31206
|
-
if (!opts.schema && !opts.attester) {
|
|
31207
|
-
throw new Error("Provide at least one filter: --schema or --
|
|
31335
|
+
if (!opts.schema && !opts.attester && !opts.recipient) {
|
|
31336
|
+
throw new Error("Provide at least one filter: --schema, --attester, or --recipient");
|
|
31208
31337
|
}
|
|
31209
|
-
if (opts.schema)
|
|
31338
|
+
if (opts.schema) opts.schema = resolveAndValidateSchemaUID(opts.schema, "schema UID");
|
|
31210
31339
|
if (opts.attester) validateAddress(opts.attester, "attester");
|
|
31340
|
+
if (opts.recipient) validateAddress(opts.recipient, "recipient");
|
|
31211
31341
|
const take = parseInt(opts.limit, 10);
|
|
31212
31342
|
const skip = parseInt(opts.skip, 10);
|
|
31213
31343
|
if (isNaN(take) || take < 1) throw new Error("--limit must be a positive integer");
|
|
@@ -31219,12 +31349,18 @@ var queryAttestationsCommand = new import_commander11.Command("query-attestation
|
|
|
31219
31349
|
take,
|
|
31220
31350
|
skip
|
|
31221
31351
|
});
|
|
31222
|
-
} else {
|
|
31352
|
+
} else if (opts.attester) {
|
|
31223
31353
|
data = await graphqlQuery(opts.chain, QUERIES.getAttestationsByAttester, {
|
|
31224
31354
|
attester: opts.attester,
|
|
31225
31355
|
take,
|
|
31226
31356
|
skip
|
|
31227
31357
|
});
|
|
31358
|
+
} else {
|
|
31359
|
+
data = await graphqlQuery(opts.chain, QUERIES.getAttestationsByRecipient, {
|
|
31360
|
+
recipient: opts.recipient,
|
|
31361
|
+
take,
|
|
31362
|
+
skip
|
|
31363
|
+
});
|
|
31228
31364
|
}
|
|
31229
31365
|
const attestations = data.attestations || [];
|
|
31230
31366
|
for (const att of attestations) {
|
|
@@ -31281,6 +31417,7 @@ var multiRevokeCommand = new import_commander13.Command("multi-revoke").descript
|
|
|
31281
31417
|
}
|
|
31282
31418
|
const grouped = /* @__PURE__ */ new Map();
|
|
31283
31419
|
for (const input of inputs) {
|
|
31420
|
+
input.schema = resolveSchemaUID(input.schema);
|
|
31284
31421
|
if (!grouped.has(input.schema)) {
|
|
31285
31422
|
grouped.set(input.schema, { schema: input.schema, data: [] });
|
|
31286
31423
|
}
|
|
@@ -31345,7 +31482,7 @@ var multiTimestampCommand = new import_commander14.Command("multi-timestamp").de
|
|
|
31345
31482
|
// src/commands/set-key.ts
|
|
31346
31483
|
var import_commander15 = require("commander");
|
|
31347
31484
|
var import_ethers12 = require("ethers");
|
|
31348
|
-
var setKeyCommand = new import_commander15.Command("set-key").description("Store your private key in ~/.
|
|
31485
|
+
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
31486
|
const normalized = key.startsWith("0x") ? key : `0x${key}`;
|
|
31350
31487
|
try {
|
|
31351
31488
|
const wallet = new import_ethers12.ethers.Wallet(normalized);
|
|
@@ -31358,7 +31495,7 @@ var setKeyCommand = new import_commander15.Command("set-key").description("Store
|
|
|
31358
31495
|
|
|
31359
31496
|
// src/commands/clear-key.ts
|
|
31360
31497
|
var import_commander16 = require("commander");
|
|
31361
|
-
var clearKeyCommand = new import_commander16.Command("clear-key").description("Remove the stored private key from ~/.
|
|
31498
|
+
var clearKeyCommand = new import_commander16.Command("clear-key").description("Remove the stored private key from ~/.easctl").action(() => {
|
|
31362
31499
|
if (!getStoredPrivateKey()) {
|
|
31363
31500
|
output({ success: true, data: { cleared: false, message: "No private key is currently stored" } });
|
|
31364
31501
|
return;
|
|
@@ -31367,9 +31504,83 @@ var clearKeyCommand = new import_commander16.Command("clear-key").description("R
|
|
|
31367
31504
|
output({ success: true, data: { cleared: true } });
|
|
31368
31505
|
});
|
|
31369
31506
|
|
|
31507
|
+
// src/commands/popular-schemas.ts
|
|
31508
|
+
var import_commander17 = require("commander");
|
|
31509
|
+
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) => {
|
|
31510
|
+
try {
|
|
31511
|
+
if (isJsonMode()) {
|
|
31512
|
+
const schemas = opts.category ? listPopularSchemas().filter((s) => s.category === opts.category) : listPopularSchemas();
|
|
31513
|
+
if (opts.category && schemas.length === 0) {
|
|
31514
|
+
const categories2 = [...new Set(listPopularSchemas().map((s) => s.category))];
|
|
31515
|
+
throw new Error(`Unknown category "${opts.category}". Available: ${categories2.join(", ")}`);
|
|
31516
|
+
}
|
|
31517
|
+
output({ success: true, data: { count: schemas.length, schemas } });
|
|
31518
|
+
return;
|
|
31519
|
+
}
|
|
31520
|
+
const byCategory = listPopularSchemasByCategory();
|
|
31521
|
+
const categories = opts.category ? { [opts.category]: byCategory[opts.category] } : byCategory;
|
|
31522
|
+
if (opts.category && !byCategory[opts.category]) {
|
|
31523
|
+
const available = Object.keys(byCategory).join(", ");
|
|
31524
|
+
throw new Error(`Unknown category "${opts.category}". Available: ${available}`);
|
|
31525
|
+
}
|
|
31526
|
+
for (const [category, schemas] of Object.entries(categories)) {
|
|
31527
|
+
console.log(`
|
|
31528
|
+
=== ${category} ===
|
|
31529
|
+
`);
|
|
31530
|
+
for (const s of schemas) {
|
|
31531
|
+
console.log(` ${s.name}`);
|
|
31532
|
+
console.log(` Schema: ${s.schema}`);
|
|
31533
|
+
console.log(` UID: ${s.uid}`);
|
|
31534
|
+
console.log(` Revocable: ${s.revocable ? "yes" : "no"}`);
|
|
31535
|
+
console.log(` ${s.description}
|
|
31536
|
+
`);
|
|
31537
|
+
}
|
|
31538
|
+
}
|
|
31539
|
+
} catch (err2) {
|
|
31540
|
+
handleError(err2);
|
|
31541
|
+
}
|
|
31542
|
+
});
|
|
31543
|
+
|
|
31544
|
+
// src/commands/status.ts
|
|
31545
|
+
var import_commander18 = require("commander");
|
|
31546
|
+
var import_ethers13 = require("ethers");
|
|
31547
|
+
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) => {
|
|
31548
|
+
const key = process.env.EAS_PRIVATE_KEY || getStoredPrivateKey();
|
|
31549
|
+
const source = process.env.EAS_PRIVATE_KEY ? "env" : key ? "stored" : void 0;
|
|
31550
|
+
let address;
|
|
31551
|
+
if (key) {
|
|
31552
|
+
try {
|
|
31553
|
+
const normalized = key.startsWith("0x") ? key : `0x${key}`;
|
|
31554
|
+
address = new import_ethers13.ethers.Wallet(normalized).address;
|
|
31555
|
+
} catch {
|
|
31556
|
+
}
|
|
31557
|
+
}
|
|
31558
|
+
const chainConfig = CHAIN_CONFIGS[opts.chain];
|
|
31559
|
+
const rpcUrl = opts.rpcUrl || chainConfig?.defaultRpc || "none";
|
|
31560
|
+
output({
|
|
31561
|
+
success: true,
|
|
31562
|
+
data: {
|
|
31563
|
+
wallet: {
|
|
31564
|
+
privateKey: source ? address ? `set (${source})` : `set (invalid format)` : "not set",
|
|
31565
|
+
address: address || "n/a"
|
|
31566
|
+
},
|
|
31567
|
+
chain: {
|
|
31568
|
+
name: opts.chain,
|
|
31569
|
+
chainId: chainConfig?.chainId ?? "unknown chain",
|
|
31570
|
+
rpcUrl
|
|
31571
|
+
},
|
|
31572
|
+
contracts: chainConfig ? {
|
|
31573
|
+
eas: chainConfig.eas,
|
|
31574
|
+
schemaRegistry: chainConfig.schemaRegistry
|
|
31575
|
+
} : "unknown chain",
|
|
31576
|
+
supportedChains: listChains().join(", ")
|
|
31577
|
+
}
|
|
31578
|
+
});
|
|
31579
|
+
});
|
|
31580
|
+
|
|
31370
31581
|
// src/index.ts
|
|
31371
|
-
var program = new
|
|
31372
|
-
program.name("easctl").description("Ethereum Attestation Service CLI \u2014 create, revoke, and query attestations").version("0.1
|
|
31582
|
+
var program = new import_commander19.Command();
|
|
31583
|
+
program.name("easctl").description("Ethereum Attestation Service CLI \u2014 create, revoke, and query attestations").version("0.2.1").option("--json", "Output results as JSON (useful for agents and scripting)").hook("preAction", (thisCommand, actionCommand) => {
|
|
31373
31584
|
if (thisCommand.opts().json || actionCommand.opts().json) {
|
|
31374
31585
|
setJsonMode(true);
|
|
31375
31586
|
}
|
|
@@ -31382,6 +31593,7 @@ program.addCommand(multiRevokeCommand);
|
|
|
31382
31593
|
program.addCommand(getAttestationCommand);
|
|
31383
31594
|
program.addCommand(schemaRegisterCommand);
|
|
31384
31595
|
program.addCommand(schemaGetCommand);
|
|
31596
|
+
program.addCommand(popularSchemasCommand);
|
|
31385
31597
|
program.addCommand(timestampCommand);
|
|
31386
31598
|
program.addCommand(multiTimestampCommand);
|
|
31387
31599
|
program.addCommand(querySchemaCommand);
|
|
@@ -31390,6 +31602,7 @@ program.addCommand(queryAttestationsCommand);
|
|
|
31390
31602
|
program.addCommand(querySchemasCommand);
|
|
31391
31603
|
program.addCommand(setKeyCommand);
|
|
31392
31604
|
program.addCommand(clearKeyCommand);
|
|
31605
|
+
program.addCommand(statusCommand);
|
|
31393
31606
|
program.command("chains").description("List supported chains and their EAS contract addresses").action(() => {
|
|
31394
31607
|
const chains = listChains();
|
|
31395
31608
|
output({ success: true, data: { chains } });
|