@ilalv3/cli 0.2.16 → 0.2.18
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 +4 -3
- package/dist/commands/credential.js +2 -2
- package/dist/commands/demo.js +2 -2
- package/dist/commands/issuer.d.ts +12 -0
- package/dist/commands/issuer.js +208 -2
- package/dist/commands/liquidity.js +1 -1
- package/dist/commands/swap.js +1 -1
- package/dist/index.js +20 -4
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ PRIVATE_KEY=0x... ilal credential mint \
|
|
|
53
53
|
--chain 84532
|
|
54
54
|
|
|
55
55
|
# Or, with the MockEAS owner key, create a fresh test attestation:
|
|
56
|
-
PRIVATE_KEY=0x... ilal
|
|
56
|
+
PRIVATE_KEY=0x... ilal issuer attest --wallet 0xYourWallet
|
|
57
57
|
PRIVATE_KEY=0xYourWalletKey ilal credential mint --attestation <uid>
|
|
58
58
|
|
|
59
59
|
# If the wallet needs more demo tokens:
|
|
@@ -132,12 +132,13 @@ ILAL_ARTIFACT_CACHE=/opt/ilal/artifacts/ilal-v1
|
|
|
132
132
|
| `ilal status` | Dashboard: credential · issuer config · pool policy |
|
|
133
133
|
| `ilal credential zk-root` | Operator helper: compute the ZK Merkle root for a demo wallet/expiry |
|
|
134
134
|
| `ilal credential prove` | Trader flow: hosted/cached ZK artifacts → local proof → mint or renew CNF |
|
|
135
|
-
| `ilal credential mint` | Mint CNF via
|
|
135
|
+
| `ilal credential mint` | Mint CNF via the issuer-configured EAS schema |
|
|
136
136
|
| `ilal credential renew` | Renew CNF via EAS attestation |
|
|
137
137
|
| `ilal issuer create` | Create issuer standard profile and return `standard_id` |
|
|
138
138
|
| `ilal issuer set-jurisdiction` | Set allowed jurisdictions |
|
|
139
139
|
| `ilal issuer set-type` | Set accredited-only requirement |
|
|
140
140
|
| `ilal issuer get` | Read standard profile and `credentialType` |
|
|
141
|
+
| `ilal issuer attest` | Issuer backend command: create an EAS attestation for a wallet |
|
|
141
142
|
| `ilal swap` | Compliant swap via ILALRouter with optional `--min-amount-out` |
|
|
142
143
|
| `ilal pool add-liquidity` | Add liquidity to a compliant pool |
|
|
143
144
|
| `ilal pool remove-liquidity` | Remove liquidity from a compliant pool |
|
|
@@ -150,7 +151,7 @@ ILAL_ARTIFACT_CACHE=/opt/ilal/artifacts/ilal-v1
|
|
|
150
151
|
| `ilal session sign` | Sign a standalone SessionToken |
|
|
151
152
|
| `ilal proof mint` | Mint CNF from existing proof.json + public.json |
|
|
152
153
|
| `ilal deploy --mock` | Deploy a seeded testnet demo stack with MockEAS, tokens, router, hook, and policy |
|
|
153
|
-
| `ilal demo attest` |
|
|
154
|
+
| `ilal demo attest` | Legacy testnet alias for MockEAS attestation |
|
|
154
155
|
| `ilal demo faucet` | Mint mock demo TOKA/TOKB to a wallet |
|
|
155
156
|
| `ilal deploy` | Deploy full ILAL contract stack |
|
|
156
157
|
|
|
@@ -39,9 +39,9 @@ export async function credentialStatus(opts) {
|
|
|
39
39
|
console.log();
|
|
40
40
|
console.log(fmt.bold(" How to get a CNF credential:"));
|
|
41
41
|
console.log();
|
|
42
|
-
console.log(fmt.bold("
|
|
42
|
+
console.log(fmt.bold(" Issuer path — issuer-created EAS attestation"));
|
|
43
43
|
console.log(` ${fmt.gray("1.")} Ask the issuer/operator to run:`);
|
|
44
|
-
console.log(` ${fmt.cyan("PRIVATE_KEY=<issuer-
|
|
44
|
+
console.log(` ${fmt.cyan("PRIVATE_KEY=<issuer-key> ilal issuer attest --wallet " + cfg.wallet)}`);
|
|
45
45
|
console.log(` ${fmt.gray("2.")} Then mint with your wallet key:`);
|
|
46
46
|
console.log(` ${fmt.cyan("PRIVATE_KEY=<wallet-key> ilal credential mint --attestation <uid>")}`);
|
|
47
47
|
console.log();
|
package/dist/commands/demo.js
CHANGED
|
@@ -444,7 +444,7 @@ export async function demoCheck(opts) {
|
|
|
444
444
|
log.command(`ilal status --wallet ${wallet}`);
|
|
445
445
|
if (!credentialReady) {
|
|
446
446
|
log.info("Credential missing: the issuer must create an attestation before the wallet can mint CNF.");
|
|
447
|
-
log.command(`PRIVATE_KEY=<issuer-
|
|
447
|
+
log.command(`PRIVATE_KEY=<issuer-key> ilal issuer attest --wallet ${wallet}`);
|
|
448
448
|
log.command("PRIVATE_KEY=<wallet-key> ilal credential mint --attestation <uid>");
|
|
449
449
|
}
|
|
450
450
|
log.command(`ilal session sign --pool ${cfg.poolId ?? "<poolId>"} --action swap --hook ${cfg.hook ?? "<hook>"} --issuer ${cfg.issuer ?? "<issuer>"} --caller ${cfg.router ?? "<router>"}`);
|
|
@@ -512,7 +512,7 @@ export async function demoAttest(opts) {
|
|
|
512
512
|
], functionName: "trustedAttester" }),
|
|
513
513
|
]);
|
|
514
514
|
if (eas === ZERO)
|
|
515
|
-
die("Configured issuer has no EAS
|
|
515
|
+
die("Configured issuer has no EAS path. Use an issuer with EAS configured or mint through ZK proof.");
|
|
516
516
|
const days = BigInt(parseInt(opts.expiresInDays ?? "90", 10));
|
|
517
517
|
const expiration = BigInt(Math.floor(Date.now() / 1000)) + days * 24n * 60n * 60n;
|
|
518
518
|
header("ILAL Demo Attestation", chain.name);
|
|
@@ -12,3 +12,15 @@ export declare function issuerSetType(opts: {
|
|
|
12
12
|
export declare function issuerGet(opts: {
|
|
13
13
|
id?: string;
|
|
14
14
|
}): Promise<void>;
|
|
15
|
+
export declare function issuerAttest(opts: {
|
|
16
|
+
wallet: string;
|
|
17
|
+
schema?: string;
|
|
18
|
+
eas?: string;
|
|
19
|
+
issuer?: string;
|
|
20
|
+
expiresInDays?: string;
|
|
21
|
+
data?: string;
|
|
22
|
+
revocable?: boolean;
|
|
23
|
+
chain?: string;
|
|
24
|
+
rpc?: string;
|
|
25
|
+
privateKey?: string;
|
|
26
|
+
}): Promise<void>;
|
package/dist/commands/issuer.js
CHANGED
|
@@ -1,8 +1,82 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
2
2
|
import { resolve } from "path";
|
|
3
|
-
import { keccak256, stringToBytes, isHex } from "viem";
|
|
4
|
-
import {
|
|
3
|
+
import { createPublicClient, createWalletClient, decodeEventLog, http, isAddress, keccak256, stringToBytes, isHex, } from "viem";
|
|
4
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
5
|
+
import { base, baseSepolia } from "viem/chains";
|
|
6
|
+
import { fmt, header, log, die, Spinner, dieOnContract, requirePrivateKey } from "../ui.js";
|
|
7
|
+
import { withConfig } from "../config.js";
|
|
5
8
|
const STORE_FILE = ".ilal-issuer-standards.json";
|
|
9
|
+
const ZERO = "0x0000000000000000000000000000000000000000";
|
|
10
|
+
const CHAINS = { "8453": base, "84532": baseSepolia };
|
|
11
|
+
const CNF_ISSUER_ATTEST_ABI = [
|
|
12
|
+
{ name: "eas", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
|
|
13
|
+
{ name: "schemaUID", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "bytes32" }] },
|
|
14
|
+
{ name: "trustedAttester", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
|
|
15
|
+
];
|
|
16
|
+
const OWNABLE_ABI = [
|
|
17
|
+
{ name: "owner", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "address" }] },
|
|
18
|
+
];
|
|
19
|
+
const MOCK_EAS_ABI = [
|
|
20
|
+
{
|
|
21
|
+
type: "event",
|
|
22
|
+
name: "AttestationCreated",
|
|
23
|
+
inputs: [
|
|
24
|
+
{ name: "uid", type: "bytes32", indexed: true },
|
|
25
|
+
{ name: "recipient", type: "address", indexed: true },
|
|
26
|
+
{ name: "attester", type: "address", indexed: true },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "attest",
|
|
31
|
+
type: "function",
|
|
32
|
+
stateMutability: "nonpayable",
|
|
33
|
+
inputs: [
|
|
34
|
+
{ name: "schema", type: "bytes32" },
|
|
35
|
+
{ name: "recipient", type: "address" },
|
|
36
|
+
{ name: "attester", type: "address" },
|
|
37
|
+
{ name: "expirationTime", type: "uint64" },
|
|
38
|
+
{ name: "data", type: "bytes" },
|
|
39
|
+
],
|
|
40
|
+
outputs: [{ name: "uid", type: "bytes32" }],
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
const EAS_ABI = [
|
|
44
|
+
{
|
|
45
|
+
type: "event",
|
|
46
|
+
name: "Attested",
|
|
47
|
+
inputs: [
|
|
48
|
+
{ name: "recipient", type: "address", indexed: true },
|
|
49
|
+
{ name: "attester", type: "address", indexed: true },
|
|
50
|
+
{ name: "uid", type: "bytes32", indexed: false },
|
|
51
|
+
{ name: "schemaUID", type: "bytes32", indexed: true },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "attest",
|
|
56
|
+
type: "function",
|
|
57
|
+
stateMutability: "payable",
|
|
58
|
+
inputs: [{
|
|
59
|
+
name: "request",
|
|
60
|
+
type: "tuple",
|
|
61
|
+
components: [
|
|
62
|
+
{ name: "schema", type: "bytes32" },
|
|
63
|
+
{
|
|
64
|
+
name: "data",
|
|
65
|
+
type: "tuple",
|
|
66
|
+
components: [
|
|
67
|
+
{ name: "recipient", type: "address" },
|
|
68
|
+
{ name: "expirationTime", type: "uint64" },
|
|
69
|
+
{ name: "revocable", type: "bool" },
|
|
70
|
+
{ name: "refUID", type: "bytes32" },
|
|
71
|
+
{ name: "data", type: "bytes" },
|
|
72
|
+
{ name: "value", type: "uint256" },
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
}],
|
|
77
|
+
outputs: [{ name: "uid", type: "bytes32" }],
|
|
78
|
+
},
|
|
79
|
+
];
|
|
6
80
|
function storePath() {
|
|
7
81
|
return resolve(process.cwd(), STORE_FILE);
|
|
8
82
|
}
|
|
@@ -57,6 +131,26 @@ function printStandard(item) {
|
|
|
57
131
|
log.kv("credentialType", fmt.cyan(item.id));
|
|
58
132
|
log.kv("updated", fmt.gray(item.updatedAt));
|
|
59
133
|
}
|
|
134
|
+
function txUrl(chain, hash) {
|
|
135
|
+
const baseUrl = chain.blockExplorers?.default?.url;
|
|
136
|
+
return baseUrl ? `${baseUrl}/tx/${hash}` : undefined;
|
|
137
|
+
}
|
|
138
|
+
function parseHexBytes(raw) {
|
|
139
|
+
if (!raw)
|
|
140
|
+
return "0x";
|
|
141
|
+
if (!isHex(raw))
|
|
142
|
+
die("--data must be hex bytes, e.g. 0x1234");
|
|
143
|
+
return raw;
|
|
144
|
+
}
|
|
145
|
+
async function isMockEAS(client, eas) {
|
|
146
|
+
try {
|
|
147
|
+
await client.readContract({ address: eas, abi: OWNABLE_ABI, functionName: "owner" });
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
60
154
|
export async function issuerCreate(opts) {
|
|
61
155
|
const standard = opts.standard.trim();
|
|
62
156
|
if (!standard)
|
|
@@ -132,3 +226,115 @@ export async function issuerGet(opts) {
|
|
|
132
226
|
log.command(`ilal pool policy set --cred-type ${item.id} --issuer <CNFIssuer> --registry <PolicyRegistry> --pool <poolId>`);
|
|
133
227
|
console.log();
|
|
134
228
|
}
|
|
229
|
+
export async function issuerAttest(opts) {
|
|
230
|
+
const cfg = withConfig(opts);
|
|
231
|
+
const rawKey = requirePrivateKey(cfg.privateKey ?? process.env["PRIVATE_KEY"]);
|
|
232
|
+
if (!isAddress(opts.wallet))
|
|
233
|
+
die(`Invalid wallet address: ${opts.wallet}`);
|
|
234
|
+
const chain = CHAINS[cfg.chain ?? "84532"] ?? baseSepolia;
|
|
235
|
+
const account = privateKeyToAccount(rawKey);
|
|
236
|
+
const transport = cfg.rpc ? http(cfg.rpc) : http();
|
|
237
|
+
const client = createPublicClient({ chain, transport });
|
|
238
|
+
const walletClient = createWalletClient({ account, chain, transport });
|
|
239
|
+
let eas = opts.eas;
|
|
240
|
+
let schema = opts.schema;
|
|
241
|
+
let trustedAttester = account.address;
|
|
242
|
+
if (cfg.issuer) {
|
|
243
|
+
if (!isAddress(cfg.issuer))
|
|
244
|
+
die(`Invalid issuer address: ${cfg.issuer}`);
|
|
245
|
+
const [issuerEAS, issuerSchema, issuerAttester] = await Promise.all([
|
|
246
|
+
client.readContract({ address: cfg.issuer, abi: CNF_ISSUER_ATTEST_ABI, functionName: "eas" }),
|
|
247
|
+
client.readContract({ address: cfg.issuer, abi: CNF_ISSUER_ATTEST_ABI, functionName: "schemaUID" }),
|
|
248
|
+
client.readContract({ address: cfg.issuer, abi: CNF_ISSUER_ATTEST_ABI, functionName: "trustedAttester" }),
|
|
249
|
+
]);
|
|
250
|
+
if (!eas && issuerEAS !== ZERO)
|
|
251
|
+
eas = issuerEAS;
|
|
252
|
+
if (!schema)
|
|
253
|
+
schema = issuerSchema;
|
|
254
|
+
trustedAttester = issuerAttester;
|
|
255
|
+
}
|
|
256
|
+
if (!eas || !isAddress(eas))
|
|
257
|
+
die("EAS contract required. Use --eas <address> or configure an issuer with eas().");
|
|
258
|
+
if (!schema || !isHex(schema) || schema.length !== 66)
|
|
259
|
+
die("Schema UID required. Use --schema <bytes32> or configure an issuer with schemaUID().");
|
|
260
|
+
const days = BigInt(parseInt(opts.expiresInDays ?? "365", 10));
|
|
261
|
+
if (days <= 0n)
|
|
262
|
+
die("--expires-in-days must be greater than 0");
|
|
263
|
+
const expiration = BigInt(Math.floor(Date.now() / 1000)) + days * 24n * 60n * 60n;
|
|
264
|
+
const data = parseHexBytes(opts.data);
|
|
265
|
+
const mock = await isMockEAS(client, eas);
|
|
266
|
+
header("Issuer Attestation", chain.name);
|
|
267
|
+
log.kv("issuer", cfg.issuer ? fmt.addr(cfg.issuer) : fmt.badge("direct EAS", "yellow"));
|
|
268
|
+
log.kv("eas", fmt.addr(eas));
|
|
269
|
+
log.kv("schema", fmt.hash(schema));
|
|
270
|
+
log.kv("recipient", fmt.addr(opts.wallet));
|
|
271
|
+
log.kv("signer", fmt.addr(account.address));
|
|
272
|
+
log.kv("attester", mock ? fmt.addr(trustedAttester) : fmt.addr(account.address));
|
|
273
|
+
log.kv("expires", new Date(Number(expiration) * 1000).toISOString());
|
|
274
|
+
log.kv("mode", mock ? "MockEAS compatibility" : "EAS attest()");
|
|
275
|
+
log.line();
|
|
276
|
+
const spin = new Spinner("Creating issuer attestation…").start();
|
|
277
|
+
let hash;
|
|
278
|
+
try {
|
|
279
|
+
if (mock) {
|
|
280
|
+
hash = await walletClient.writeContract({
|
|
281
|
+
address: eas,
|
|
282
|
+
abi: MOCK_EAS_ABI,
|
|
283
|
+
functionName: "attest",
|
|
284
|
+
args: [schema, opts.wallet, trustedAttester, expiration, data],
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
hash = await walletClient.writeContract({
|
|
289
|
+
address: eas,
|
|
290
|
+
abi: EAS_ABI,
|
|
291
|
+
functionName: "attest",
|
|
292
|
+
args: [{
|
|
293
|
+
schema: schema,
|
|
294
|
+
data: {
|
|
295
|
+
recipient: opts.wallet,
|
|
296
|
+
expirationTime: expiration,
|
|
297
|
+
revocable: opts.revocable ?? true,
|
|
298
|
+
refUID: `0x${"0".repeat(64)}`,
|
|
299
|
+
data,
|
|
300
|
+
value: 0n,
|
|
301
|
+
},
|
|
302
|
+
}],
|
|
303
|
+
value: 0n,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch (e) {
|
|
308
|
+
spin.fail("attest failed");
|
|
309
|
+
dieOnContract(e);
|
|
310
|
+
}
|
|
311
|
+
const receipt = await client.waitForTransactionReceipt({ hash });
|
|
312
|
+
spin.succeed(`Attestation tx confirmed ${fmt.gray(fmt.hash(hash))}`);
|
|
313
|
+
let uid;
|
|
314
|
+
for (const logItem of receipt.logs) {
|
|
315
|
+
if (logItem.address.toLowerCase() !== eas.toLowerCase())
|
|
316
|
+
continue;
|
|
317
|
+
try {
|
|
318
|
+
const decoded = decodeEventLog({ abi: mock ? MOCK_EAS_ABI : EAS_ABI, data: logItem.data, topics: logItem.topics });
|
|
319
|
+
if (decoded.eventName === "AttestationCreated" || decoded.eventName === "Attested") {
|
|
320
|
+
uid = decoded.args.uid;
|
|
321
|
+
break;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
catch { }
|
|
325
|
+
}
|
|
326
|
+
log.line();
|
|
327
|
+
if (uid)
|
|
328
|
+
log.kv("attestation", fmt.cyan(uid));
|
|
329
|
+
else
|
|
330
|
+
log.warn("Could not decode attestation UID from logs; inspect the tx in the explorer.");
|
|
331
|
+
log.kv("tx", fmt.gray(hash));
|
|
332
|
+
const explorer = txUrl(chain, hash);
|
|
333
|
+
if (explorer)
|
|
334
|
+
log.kv("explorer", fmt.cyan(explorer));
|
|
335
|
+
if (uid) {
|
|
336
|
+
log.callout("CNF mint path ready", "recipient can mint CNF without issuer involvement", "green");
|
|
337
|
+
log.command(`PRIVATE_KEY=<wallet-key> ilal credential mint --issuer ${cfg.issuer ?? "<CNFIssuer>"} --attestation ${uid} --chain ${chain.id}`);
|
|
338
|
+
}
|
|
339
|
+
console.log();
|
|
340
|
+
}
|
|
@@ -197,7 +197,7 @@ async function executeLiquidity(action, opts) {
|
|
|
197
197
|
if (tokenId === 0n) {
|
|
198
198
|
preflightErrors.push("wallet has no CNF credential; mint one before changing liquidity.");
|
|
199
199
|
if (hasEASPath)
|
|
200
|
-
preflightErrors.push("issuer supports EAS
|
|
200
|
+
preflightErrors.push("issuer supports EAS attestation minting: first ask issuer to run `ilal issuer attest --wallet <wallet>`, then run `ilal credential mint --attestation <uid>`.");
|
|
201
201
|
else if (hasZKPath)
|
|
202
202
|
preflightErrors.push(`issuer supports ZK minting: run \`ilal credential prove --wallet ${account.address}\`.`);
|
|
203
203
|
else
|
package/dist/commands/swap.js
CHANGED
|
@@ -221,7 +221,7 @@ export async function swap(opts) {
|
|
|
221
221
|
if (tokenId === 0n) {
|
|
222
222
|
preflightErrors.push(`wallet has no CNF credential; mint one before trading.`);
|
|
223
223
|
if (hasEASPath)
|
|
224
|
-
preflightErrors.push("issuer supports EAS
|
|
224
|
+
preflightErrors.push("issuer supports EAS attestation minting: first ask issuer to run `ilal issuer attest --wallet <wallet>`, then run `ilal credential mint --attestation <uid>`.");
|
|
225
225
|
else if (hasZKPath)
|
|
226
226
|
preflightErrors.push(`issuer supports ZK minting: run \`ilal credential prove --wallet ${account.address}\`.`);
|
|
227
227
|
else
|
package/dist/index.js
CHANGED
|
@@ -13,14 +13,14 @@ import { init } from "./commands/init.js";
|
|
|
13
13
|
import { status } from "./commands/status.js";
|
|
14
14
|
import { swap } from "./commands/swap.js";
|
|
15
15
|
import { addLiquidity, removeLiquidity } from "./commands/liquidity.js";
|
|
16
|
-
import { issuerCreate, issuerGet, issuerSetJurisdiction, issuerSetType } from "./commands/issuer.js";
|
|
16
|
+
import { issuerAttest, issuerCreate, issuerGet, issuerSetJurisdiction, issuerSetType } from "./commands/issuer.js";
|
|
17
17
|
import { fmt } from "./ui.js";
|
|
18
18
|
import { COINBASE_SCHEMA_UID } from "./constants.js";
|
|
19
19
|
const program = new Command();
|
|
20
20
|
program
|
|
21
21
|
.name("ilal")
|
|
22
22
|
.description("ILAL Protocol CLI — Uniswap v4 compliance hook toolkit")
|
|
23
|
-
.version("0.2.
|
|
23
|
+
.version("0.2.17")
|
|
24
24
|
.addHelpText("before", `\n ${fmt.bold(fmt.cyan("◆"))} ${fmt.bold("ILAL Protocol")} ${fmt.gray("Uniswap v4 Compliance Hook")}\n`);
|
|
25
25
|
// ─── init ─────────────────────────────────────────────────────────────────────
|
|
26
26
|
program
|
|
@@ -86,7 +86,7 @@ demoCommand
|
|
|
86
86
|
});
|
|
87
87
|
demoCommand
|
|
88
88
|
.command("attest")
|
|
89
|
-
.description("
|
|
89
|
+
.description("Legacy testnet alias: create a MockEAS attestation for a wallet")
|
|
90
90
|
.requiredOption("-w, --wallet <address>", "Recipient wallet that will mint the CNF")
|
|
91
91
|
.option("--expires-in-days <days>", "Attestation lifetime in days", "90")
|
|
92
92
|
.option("-k, --private-key <hex>", "MockEAS owner private key")
|
|
@@ -99,6 +99,22 @@ const err = (e) => {
|
|
|
99
99
|
};
|
|
100
100
|
// ─── issuer ──────────────────────────────────────────────────────────────────
|
|
101
101
|
const issuer = program.command("issuer").description("Issuer standard management");
|
|
102
|
+
issuer
|
|
103
|
+
.command("attest")
|
|
104
|
+
.description("Create an issuer EAS attestation for a wallet")
|
|
105
|
+
.requiredOption("-w, --wallet <address>", "Recipient wallet that will mint the CNF")
|
|
106
|
+
.option("--schema <bytes32>", "EAS schema UID (defaults to CNFIssuer.schemaUID)")
|
|
107
|
+
.option("--eas <address>", "EAS contract address (defaults to CNFIssuer.eas)")
|
|
108
|
+
.option("-i, --issuer <address>", "CNFIssuer contract address (or set in .ilal.json)")
|
|
109
|
+
.option("--expires-in-days <days>", "Attestation lifetime in days", "365")
|
|
110
|
+
.option("--data <hex>", "Optional attestation payload bytes", "0x")
|
|
111
|
+
.option("--no-revocable", "Create a non-revocable EAS attestation")
|
|
112
|
+
.option("-c, --chain <chainId>", "Chain ID", "84532")
|
|
113
|
+
.option("-r, --rpc <url>", "Custom RPC URL")
|
|
114
|
+
.option("-k, --private-key <hex>", "Issuer attester private key")
|
|
115
|
+
.action(async (opts) => {
|
|
116
|
+
await issuerAttest(opts).catch(err);
|
|
117
|
+
});
|
|
102
118
|
issuer
|
|
103
119
|
.command("create")
|
|
104
120
|
.description("Create an issuer compliance standard profile and return a standard_id")
|
|
@@ -169,7 +185,7 @@ credential
|
|
|
169
185
|
});
|
|
170
186
|
credential
|
|
171
187
|
.command("mint")
|
|
172
|
-
.description("Mint a CNF credential using
|
|
188
|
+
.description("Mint a CNF credential using the issuer-configured EAS schema")
|
|
173
189
|
.requiredOption("-a, --attestation <uid>", "EAS attestation UID (0x + 64 hex chars)")
|
|
174
190
|
.option("-i, --issuer <address>", "CNFIssuer contract address (or set in .ilal.json)")
|
|
175
191
|
.option("-c, --chain <chainId>", "Chain ID", "84532")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ilalv3/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.18",
|
|
4
4
|
"description": "ILAL Protocol CLI — compliant swaps and credential management for Uniswap v4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"commander": "^12.0.0",
|
|
40
40
|
"poseidon-lite": "^0.3.0",
|
|
41
41
|
"snarkjs": "^0.7.6",
|
|
42
|
-
"viem": "^2.
|
|
42
|
+
"viem": "^2.52.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^20",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"typescript": "^5.4.0"
|
|
48
48
|
},
|
|
49
49
|
"overrides": {
|
|
50
|
-
"underscore": "1.13.8"
|
|
50
|
+
"underscore": "1.13.8",
|
|
51
|
+
"ws": "^8.21.0"
|
|
51
52
|
}
|
|
52
53
|
}
|