@ilalv3/cli 0.2.15 → 0.2.16

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
@@ -134,6 +134,10 @@ ILAL_ARTIFACT_CACHE=/opt/ilal/artifacts/ilal-v1
134
134
  | `ilal credential prove` | Trader flow: hosted/cached ZK artifacts → local proof → mint or renew CNF |
135
135
  | `ilal credential mint` | Mint CNF via Coinbase EAS attestation |
136
136
  | `ilal credential renew` | Renew CNF via EAS attestation |
137
+ | `ilal issuer create` | Create issuer standard profile and return `standard_id` |
138
+ | `ilal issuer set-jurisdiction` | Set allowed jurisdictions |
139
+ | `ilal issuer set-type` | Set accredited-only requirement |
140
+ | `ilal issuer get` | Read standard profile and `credentialType` |
137
141
  | `ilal swap` | Compliant swap via ILALRouter with optional `--min-amount-out` |
138
142
  | `ilal pool add-liquidity` | Add liquidity to a compliant pool |
139
143
  | `ilal pool remove-liquidity` | Remove liquidity from a compliant pool |
@@ -152,6 +156,19 @@ ILAL_ARTIFACT_CACHE=/opt/ilal/artifacts/ilal-v1
152
156
 
153
157
  Session note: ILAL hookData is a one-time EIP-712 authorization with a deadline and nonce. The expensive compliance step is the CNF issuance or renewal; swaps do not verify a fresh ZK proof. Use `ilal session sign` to export hookData, and `ilal swap --hook-data <hex>` to execute with an externally signed authorization.
154
158
 
159
+ ## Issuer standards
160
+
161
+ External issuers can define a compliance standard and use its `standard_id` as the on-chain `credentialType` for pool policy registration:
162
+
163
+ ```bash
164
+ ilal issuer create --standard "Goldfinch Accredited Investor"
165
+ ilal issuer set-jurisdiction --allow US,EU,SG
166
+ ilal issuer set-type --accredited-only true
167
+ ilal issuer get
168
+ ```
169
+
170
+ Profiles are stored in `.ilal-issuer-standards.json`. Pools enforce the returned `standard_id` through `PolicyRegistry.requiredCredentialType`.
171
+
155
172
  ## Configuration
156
173
 
157
174
  The CLI reads `.ilal.json` in the current directory. Run `ilal init` to create it, or pass flags directly:
@@ -0,0 +1,14 @@
1
+ export declare function issuerCreate(opts: {
2
+ standard: string;
3
+ }): Promise<void>;
4
+ export declare function issuerSetJurisdiction(opts: {
5
+ id?: string;
6
+ allow: string;
7
+ }): Promise<void>;
8
+ export declare function issuerSetType(opts: {
9
+ id?: string;
10
+ accreditedOnly: string | boolean;
11
+ }): Promise<void>;
12
+ export declare function issuerGet(opts: {
13
+ id?: string;
14
+ }): Promise<void>;
@@ -0,0 +1,134 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "fs";
2
+ import { resolve } from "path";
3
+ import { keccak256, stringToBytes, isHex } from "viem";
4
+ import { fmt, header, log, die } from "../ui.js";
5
+ const STORE_FILE = ".ilal-issuer-standards.json";
6
+ function storePath() {
7
+ return resolve(process.cwd(), STORE_FILE);
8
+ }
9
+ function loadStore() {
10
+ const path = storePath();
11
+ if (!existsSync(path))
12
+ return { version: 1, standards: {} };
13
+ try {
14
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
15
+ return {
16
+ version: 1,
17
+ latest: parsed.latest,
18
+ standards: parsed.standards ?? {},
19
+ };
20
+ }
21
+ catch {
22
+ die(`Could not parse ${STORE_FILE}. Fix or remove the file and try again.`);
23
+ }
24
+ }
25
+ function saveStore(store) {
26
+ writeFileSync(storePath(), JSON.stringify(store, null, 2) + "\n");
27
+ }
28
+ function normalizeId(id, store) {
29
+ const resolved = id ?? store?.latest;
30
+ if (!resolved)
31
+ die("Standard id required. Pass --id <standard_id> or run `ilal issuer create` first.");
32
+ if (!isHex(resolved) || resolved.length !== 66)
33
+ die("standard_id must be 0x + 32 bytes.");
34
+ return resolved;
35
+ }
36
+ function parseJurisdictions(raw) {
37
+ const list = raw.split(",").map((item) => item.trim()).filter(Boolean);
38
+ if (list.length === 0)
39
+ die("--allow must include at least one jurisdiction, e.g. US,EU,SG");
40
+ return [...new Set(list)];
41
+ }
42
+ function parseBool(raw) {
43
+ if (typeof raw === "boolean")
44
+ return raw;
45
+ const value = raw.trim().toLowerCase();
46
+ if (["true", "1", "yes", "y"].includes(value))
47
+ return true;
48
+ if (["false", "0", "no", "n"].includes(value))
49
+ return false;
50
+ die("--accredited-only must be true or false");
51
+ }
52
+ function printStandard(item) {
53
+ log.kv("standard_id", fmt.cyan(item.id));
54
+ log.kv("standard", item.standard);
55
+ log.kv("jurisdictions", item.allowedJurisdictions.length ? item.allowedJurisdictions.join(", ") : fmt.badge("unset", "yellow"));
56
+ log.kv("accredited only", item.accreditedOnly === null ? fmt.badge("unset", "yellow") : String(item.accreditedOnly));
57
+ log.kv("credentialType", fmt.cyan(item.id));
58
+ log.kv("updated", fmt.gray(item.updatedAt));
59
+ }
60
+ export async function issuerCreate(opts) {
61
+ const standard = opts.standard.trim();
62
+ if (!standard)
63
+ die("--standard <name> required");
64
+ const store = loadStore();
65
+ const now = new Date().toISOString();
66
+ const id = keccak256(stringToBytes(`ILAL_STANDARD_V1:${standard}`));
67
+ const existing = store.standards[id];
68
+ const item = existing ?? {
69
+ id,
70
+ standard,
71
+ allowedJurisdictions: [],
72
+ accreditedOnly: null,
73
+ createdAt: now,
74
+ updatedAt: now,
75
+ };
76
+ item.standard = standard;
77
+ item.updatedAt = now;
78
+ store.standards[id] = item;
79
+ store.latest = id;
80
+ saveStore(store);
81
+ header("Issuer Standard Created");
82
+ log.section("Standard");
83
+ printStandard(item);
84
+ log.line();
85
+ log.callout("Use this id as credentialType", `ilal pool policy set --cred-type ${id}`, "green");
86
+ log.kv("file", fmt.gray(storePath()));
87
+ console.log();
88
+ }
89
+ export async function issuerSetJurisdiction(opts) {
90
+ const store = loadStore();
91
+ const id = normalizeId(opts.id, store);
92
+ const item = store.standards[id];
93
+ if (!item)
94
+ die(`Unknown standard_id ${id}. Run \`ilal issuer create --standard <name>\` first.`);
95
+ item.allowedJurisdictions = parseJurisdictions(opts.allow);
96
+ item.updatedAt = new Date().toISOString();
97
+ store.latest = id;
98
+ saveStore(store);
99
+ header("Issuer Jurisdiction Updated");
100
+ log.section("Standard");
101
+ printStandard(item);
102
+ log.kv("file", fmt.gray(storePath()));
103
+ console.log();
104
+ }
105
+ export async function issuerSetType(opts) {
106
+ const store = loadStore();
107
+ const id = normalizeId(opts.id, store);
108
+ const item = store.standards[id];
109
+ if (!item)
110
+ die(`Unknown standard_id ${id}. Run \`ilal issuer create --standard <name>\` first.`);
111
+ item.accreditedOnly = parseBool(opts.accreditedOnly);
112
+ item.updatedAt = new Date().toISOString();
113
+ store.latest = id;
114
+ saveStore(store);
115
+ header("Issuer Investor Type Updated");
116
+ log.section("Standard");
117
+ printStandard(item);
118
+ log.kv("file", fmt.gray(storePath()));
119
+ console.log();
120
+ }
121
+ export async function issuerGet(opts) {
122
+ const store = loadStore();
123
+ const id = normalizeId(opts.id, store);
124
+ const item = store.standards[id];
125
+ if (!item)
126
+ die(`Unknown standard_id ${id}. Available standards: ${Object.keys(store.standards).length}`);
127
+ header("Issuer Standard");
128
+ log.section("Standard");
129
+ printStandard(item);
130
+ log.line();
131
+ log.info("This CLI profile is the issuer-side descriptor. Pools enforce the matching credentialType on-chain via PolicyRegistry.");
132
+ log.command(`ilal pool policy set --cred-type ${item.id} --issuer <CNFIssuer> --registry <PolicyRegistry> --pool <poolId>`);
133
+ console.log();
134
+ }
package/dist/index.js CHANGED
@@ -13,13 +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
17
  import { fmt } from "./ui.js";
17
18
  import { COINBASE_SCHEMA_UID } from "./constants.js";
18
19
  const program = new Command();
19
20
  program
20
21
  .name("ilal")
21
22
  .description("ILAL Protocol CLI — Uniswap v4 compliance hook toolkit")
22
- .version("0.2.15")
23
+ .version("0.2.16")
23
24
  .addHelpText("before", `\n ${fmt.bold(fmt.cyan("◆"))} ${fmt.bold("ILAL Protocol")} ${fmt.gray("Uniswap v4 Compliance Hook")}\n`);
24
25
  // ─── init ─────────────────────────────────────────────────────────────────────
25
26
  program
@@ -96,6 +97,38 @@ const err = (e) => {
96
97
  console.error(fmt.red(`\nError: ${e instanceof Error ? e.message : String(e)}\n`));
97
98
  process.exit(1);
98
99
  };
100
+ // ─── issuer ──────────────────────────────────────────────────────────────────
101
+ const issuer = program.command("issuer").description("Issuer standard management");
102
+ issuer
103
+ .command("create")
104
+ .description("Create an issuer compliance standard profile and return a standard_id")
105
+ .requiredOption("--standard <name>", "Compliance standard name, e.g. Goldfinch Accredited Investor")
106
+ .action(async (opts) => {
107
+ await issuerCreate(opts).catch(err);
108
+ });
109
+ issuer
110
+ .command("set-jurisdiction")
111
+ .description("Set allowed jurisdictions for an issuer standard")
112
+ .option("--id <standard_id>", "Standard id (defaults to latest created standard)")
113
+ .requiredOption("--allow <list>", "Comma-separated jurisdictions, e.g. US,EU,SG")
114
+ .action(async (opts) => {
115
+ await issuerSetJurisdiction(opts).catch(err);
116
+ });
117
+ issuer
118
+ .command("set-type")
119
+ .description("Set investor type requirements for an issuer standard")
120
+ .option("--id <standard_id>", "Standard id (defaults to latest created standard)")
121
+ .requiredOption("--accredited-only <bool>", "true or false")
122
+ .action(async (opts) => {
123
+ await issuerSetType(opts).catch(err);
124
+ });
125
+ issuer
126
+ .command("get")
127
+ .description("Read an issuer standard profile")
128
+ .option("--id <standard_id>", "Standard id (defaults to latest created standard)")
129
+ .action(async (opts) => {
130
+ await issuerGet(opts).catch(err);
131
+ });
99
132
  // ─── credential ───────────────────────────────────────────────────────────────
100
133
  const credential = program.command("credential").description("Manage compliance credentials (CNF)");
101
134
  credential
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ilalv3/cli",
3
- "version": "0.2.15",
3
+ "version": "0.2.16",
4
4
  "description": "ILAL Protocol CLI — compliant swaps and credential management for Uniswap v4",
5
5
  "type": "module",
6
6
  "bin": {