@certen.io/cli 0.5.0 → 0.7.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.
Files changed (87) hide show
  1. package/CHANGELOG.md +431 -0
  2. package/README.md +232 -160
  3. package/dist/chains.d.ts +67 -0
  4. package/dist/chains.js +242 -0
  5. package/dist/chains.js.map +1 -0
  6. package/dist/commands/admin.js +49 -4
  7. package/dist/commands/admin.js.map +1 -1
  8. package/dist/commands/auth.js +145 -12
  9. package/dist/commands/auth.js.map +1 -1
  10. package/dist/commands/billing.js +648 -40
  11. package/dist/commands/billing.js.map +1 -1
  12. package/dist/commands/call.d.ts +2 -0
  13. package/dist/commands/call.js +168 -0
  14. package/dist/commands/call.js.map +1 -0
  15. package/dist/commands/chains.d.ts +2 -0
  16. package/dist/commands/chains.js +123 -0
  17. package/dist/commands/chains.js.map +1 -0
  18. package/dist/commands/doctor.d.ts +2 -0
  19. package/dist/commands/doctor.js +171 -0
  20. package/dist/commands/doctor.js.map +1 -0
  21. package/dist/commands/errors-catalogue.d.ts +2 -0
  22. package/dist/commands/errors-catalogue.js +83 -0
  23. package/dist/commands/errors-catalogue.js.map +1 -0
  24. package/dist/commands/identity.js +269 -19
  25. package/dist/commands/identity.js.map +1 -1
  26. package/dist/commands/init.d.ts +2 -0
  27. package/dist/commands/init.js +307 -0
  28. package/dist/commands/init.js.map +1 -0
  29. package/dist/commands/keys.js +2 -0
  30. package/dist/commands/keys.js.map +1 -1
  31. package/dist/commands/oauth-clients.d.ts +2 -0
  32. package/dist/commands/oauth-clients.js +131 -0
  33. package/dist/commands/oauth-clients.js.map +1 -0
  34. package/dist/commands/orgs.d.ts +2 -0
  35. package/dist/commands/orgs.js +117 -0
  36. package/dist/commands/orgs.js.map +1 -0
  37. package/dist/commands/pending.d.ts +19 -0
  38. package/dist/commands/pending.js +117 -15
  39. package/dist/commands/pending.js.map +1 -1
  40. package/dist/commands/portfolio.js +34 -1
  41. package/dist/commands/portfolio.js.map +1 -1
  42. package/dist/commands/proof.d.ts +2 -0
  43. package/dist/commands/proof.js +400 -0
  44. package/dist/commands/proof.js.map +1 -0
  45. package/dist/commands/signup.d.ts +14 -0
  46. package/dist/commands/signup.js +271 -0
  47. package/dist/commands/signup.js.map +1 -0
  48. package/dist/commands/transaction.js +139 -21
  49. package/dist/commands/transaction.js.map +1 -1
  50. package/dist/commands/webhooks.d.ts +2 -0
  51. package/dist/commands/webhooks.js +200 -0
  52. package/dist/commands/webhooks.js.map +1 -0
  53. package/dist/commands/whoami.d.ts +16 -0
  54. package/dist/commands/whoami.js +98 -0
  55. package/dist/commands/whoami.js.map +1 -0
  56. package/dist/config.d.ts +56 -0
  57. package/dist/config.js +51 -0
  58. package/dist/config.js.map +1 -1
  59. package/dist/errors.d.ts +14 -1
  60. package/dist/errors.js +15 -1
  61. package/dist/errors.js.map +1 -1
  62. package/dist/funding-guard.d.ts +40 -0
  63. package/dist/funding-guard.js +120 -0
  64. package/dist/funding-guard.js.map +1 -0
  65. package/dist/help-root.d.ts +2 -0
  66. package/dist/help-root.js +94 -0
  67. package/dist/help-root.js.map +1 -0
  68. package/dist/index.js +27 -0
  69. package/dist/index.js.map +1 -1
  70. package/dist/output.d.ts +23 -0
  71. package/dist/output.js +46 -0
  72. package/dist/output.js.map +1 -1
  73. package/dist/passphrase.d.ts +18 -0
  74. package/dist/passphrase.js +35 -3
  75. package/dist/passphrase.js.map +1 -1
  76. package/dist/payment-uri.d.ts +76 -0
  77. package/dist/payment-uri.js +135 -0
  78. package/dist/payment-uri.js.map +1 -0
  79. package/dist/signer.js +6 -3
  80. package/dist/signer.js.map +1 -1
  81. package/dist/solidity-args.d.ts +31 -0
  82. package/dist/solidity-args.js +111 -0
  83. package/dist/solidity-args.js.map +1 -0
  84. package/dist/wait.d.ts +79 -0
  85. package/dist/wait.js +168 -0
  86. package/dist/wait.js.map +1 -0
  87. package/package.json +5 -4
@@ -0,0 +1,83 @@
1
+ import { CertenClient } from '@certen.io/sdk';
2
+ import { getApiUrl, getOutputFormat } from '../config.js';
3
+ import { printOutput, human, hint, isJsonMode } from '../output.js';
4
+ import { CliError, EXIT } from '../errors.js';
5
+ /**
6
+ * The error vocabulary, read from the gateway you are actually talking to.
7
+ *
8
+ * The catalogue was published in the gateway and then had no client surface for a release — so the
9
+ * codes stayed exactly as discoverable as before, which is to say you found them by provoking them
10
+ * in production. Worse, the SDK ships a vendored copy that is only as current as its release, so a
11
+ * gateway ahead of the SDK raises codes nothing local has heard of.
12
+ *
13
+ * `certen errors <CODE>` is the command that earns this: it is the thing to run when a code shows
14
+ * up in a log and the question is whether to retry, pay, or wake someone.
15
+ */
16
+ /** No API key: understanding an error should never require holding a credential. */
17
+ function publicClient() {
18
+ return new CertenClient({ apiKey: process.env.CERTEN_API_KEY ?? 'public', baseUrl: getApiUrl() });
19
+ }
20
+ const machineOutput = () => isJsonMode() || getOutputFormat() === 'json';
21
+ function describe(e) {
22
+ human('');
23
+ human(` ${e.code} HTTP ${e.status}`);
24
+ human('');
25
+ human(` ${e.meaning}`);
26
+ human('');
27
+ // These two are the whole decision. `retryable` says whether the same request can ever work;
28
+ // `audience` says whether there is anything on your side to change at all — and being told
29
+ // "nothing you can do" is genuinely useful, because it stops the debugging.
30
+ human(` Retrying this exact request: ${e.retryable ? 'can succeed' : 'will not help'}`);
31
+ if (e.audience === 'platform') {
32
+ human(' Cause: on CERTEN\'s side. Nothing in your request changes this.');
33
+ }
34
+ if (e.action) {
35
+ human('');
36
+ human(` ${e.action}`);
37
+ }
38
+ human('');
39
+ }
40
+ export function registerErrorsCommands(program) {
41
+ program
42
+ .command('errors [code]')
43
+ .description('Every error code this API can return, and what to do about each')
44
+ .option('--retryable', 'Only codes where repeating the request can succeed')
45
+ .action(async (code, opts) => {
46
+ const { errors } = await publicClient().admin.errors();
47
+ if (code) {
48
+ const wanted = code.toUpperCase();
49
+ const found = errors.find((e) => e.code.toUpperCase() === wanted);
50
+ if (!found) {
51
+ // Near-misses beat a bare "not found": the usual reason to be here is a code copied out
52
+ // of a log with a typo, or one this gateway does not raise.
53
+ const near = errors
54
+ .filter((e) => e.code.includes(wanted) || wanted.includes(e.code))
55
+ .map((e) => e.code);
56
+ throw new CliError(`This gateway does not raise "${code}".`
57
+ + (near.length ? ` Did you mean: ${near.join(', ')}?` : ' See them all: certen errors'), 'UNKNOWN_ERROR_CODE', EXIT.USAGE);
58
+ }
59
+ if (machineOutput()) {
60
+ printOutput({ ...found });
61
+ return;
62
+ }
63
+ describe(found);
64
+ return;
65
+ }
66
+ const shown = opts.retryable ? errors.filter((e) => e.retryable) : errors;
67
+ if (machineOutput()) {
68
+ printOutput({ errors: shown });
69
+ return;
70
+ }
71
+ const w = Math.max(...shown.map((e) => e.code.length), 4);
72
+ human('');
73
+ for (const e of shown) {
74
+ // `retry` is the one column worth carrying in a list — it is what someone scanning for a
75
+ // code in a log actually wants to know before reading the description.
76
+ human(` ${e.code.padEnd(w)} ${String(e.status).padEnd(3)} ${e.retryable ? 'retry' : ' '} ${e.meaning}`);
77
+ }
78
+ human('');
79
+ human(` ${shown.length} code(s)${opts.retryable ? ' where retrying can succeed' : ''}.`);
80
+ hint('certen errors PLAN_QUOTA_EXCEEDED # what one code means and what to do');
81
+ });
82
+ }
83
+ //# sourceMappingURL=errors-catalogue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-catalogue.js","sourceRoot":"","sources":["../../src/commands/errors-catalogue.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,49 @@
1
- import { CertenClient } from '@certen.io/sdk';
2
- import { getApiKey, getApiUrl } from '../config.js';
3
- import { printOutput } from '../output.js';
1
+ import { writeFileSync, chmodSync } from 'node:fs';
2
+ import { CertenClient, parseMnemonicTarget } from '@certen.io/sdk';
3
+ import { getApiKey, getApiUrl, getOutputFormat, rememberIdentity, forgetIdentity } from '../config.js';
4
+ import { printOutput, hint, human, isJsonMode } from '../output.js';
4
5
  import { resolveSigner } from '../signer.js';
6
+ import { publicKeyHashOf } from '../keystore.js';
7
+ import { assertChain, assertChains } from '../chains.js';
8
+ import { UsageError } from '../errors.js';
9
+ import { resolveWait, parseWaitBudget, waitForIdentity, IDENTITY_WAIT } from '../wait.js';
10
+ import { faucetFor } from '../funding-guard.js';
5
11
  async function getClient() {
6
12
  return new CertenClient({ apiKey: await getApiKey(), baseUrl: getApiUrl() });
7
13
  }
14
+ /**
15
+ * Render an identity for whoever is reading.
16
+ *
17
+ * Machine consumers get the response verbatim — same keys whether or not the command waited, so
18
+ * nothing has to branch on which flags were passed. Humans get the six fields that decide what to
19
+ * do next, because the table renderer serialises any nested object to a single JSON line: the raw
20
+ * response arrived as one unreadable blob with `can_sign` — the field that determines whether the
21
+ * identity works at all — buried in the middle of it.
22
+ *
23
+ * Table output is explicitly not a contract (docs/CLI-CONTRACT.md), which is what makes this
24
+ * divergence safe.
25
+ */
26
+ function printIdentity(response) {
27
+ // One parameter, not two. It took a `response` and an `identity` back when the gateway nested the
28
+ // identity inside the response; now that the response carries those fields itself, passing both
29
+ // would be passing the same object twice — and the JSON branch below re-attached the inner object
30
+ // under an `identity` key, reintroducing the shape on the machine interface after the API had
31
+ // dropped it.
32
+ if (isJsonMode() || getOutputFormat() === 'json') {
33
+ printOutput({ ...response });
34
+ return;
35
+ }
36
+ printOutput({
37
+ id: response.id,
38
+ adi_url: response.adi_url,
39
+ status: response.status,
40
+ // `?? 'unknown'` is load-bearing: `can_sign` is three-valued and null means the key page could
41
+ // not be read. Printing an empty cell would read as "no".
42
+ can_sign: response.can_sign ?? 'unknown',
43
+ key_page_url: response.key_page_url ?? '-',
44
+ credit_balance: response.credit_balance,
45
+ });
46
+ }
8
47
  export function registerIdentityCommands(program) {
9
48
  const identity = program.command('identity').description('Identity management');
10
49
  identity
@@ -14,8 +53,15 @@ export function registerIdentityCommands(program) {
14
53
  .option('--sign-with <key>', 'Local key to own this identity (see `certen keys generate`)')
15
54
  .option('--public-key-hash <hash>', 'Public key hash (omit when using --sign-with)')
16
55
  .option('--public-key <key>', 'Public key (hex)')
17
- .option('--chains <chains>', 'Comma-separated chain IDs')
56
+ .option('--chains <chains>', 'Comma-separated chains, e.g. base-sepolia,arbitrum-sepolia')
18
57
  .option('--credits <credits>', 'Initial credits', parseInt)
58
+ // Creation is asynchronous and the response says nothing about whether the identity works.
59
+ // Human mode waits; --json keeps the old fire-and-forget default so existing scripts do not
60
+ // silently start blocking. See resolveWait().
61
+ .option('--wait', 'Wait until the identity is provisioned AND can sign (default off --json)')
62
+ .option('--no-wait', 'Return as soon as the gateway accepts the request')
63
+ .option('--timeout <minutes>', `How long to wait (default ${IDENTITY_WAIT.timeoutMin})`)
64
+ .option('--poll-interval <seconds>', `How often to check (default ${IDENTITY_WAIT.intervalSec})`)
19
65
  .action(async (opts) => {
20
66
  // --public-key-hash was required, which is why the CLI could not create an identity on its
21
67
  // own: the hash is sha256 of the RAW 32-byte public key, and working that out was left to
@@ -23,39 +69,151 @@ export function registerIdentityCommands(program) {
23
69
  // neither. The explicit flags still work for a key this machine does not hold.
24
70
  let publicKeyHash = opts.publicKeyHash;
25
71
  let publicKey = opts.publicKey;
72
+ // Chains are validated BEFORE the signer is unlocked and before the request goes out. A
73
+ // typo'd chain used to reach the gateway and come back as a rejection with no visible link
74
+ // to the flag that caused it — after the passphrase prompt, which made the round trip worse.
75
+ const chains = opts.chains ? assertChains(opts.chains) : undefined;
76
+ // Same reasoning for the wait options: a typo'd --timeout must not be discovered after an
77
+ // identity has already been created and has already consumed a slot against the org quota.
78
+ const wait = resolveWait();
79
+ const budget = parseWaitBudget(opts.timeout, opts.pollInterval, IDENTITY_WAIT);
26
80
  if (opts.signWith) {
27
81
  if (publicKeyHash || publicKey) {
28
- throw new Error('Pass either --sign-with or --public-key-hash/--public-key, not both.');
82
+ throw new UsageError('Pass either --sign-with or --public-key-hash/--public-key, not both.', 'CONFLICTING_KEY_FLAGS');
29
83
  }
30
84
  const signer = await resolveSigner(opts.signWith);
31
85
  publicKeyHash = signer.publicKeyHash;
32
86
  publicKey = signer.publicKey;
33
87
  }
88
+ // Derive the hash from the public key rather than demanding both.
89
+ //
90
+ // The hash is sha256 of the RAW 32-byte key — a fact this file already documented while still
91
+ // making the caller compute it. Requiring it alongside the key was pure friction: the CLI has
92
+ // the bytes and the function, and every caller who supplied only `--public-key` was refused
93
+ // and sent to work out a digest by hand.
94
+ //
95
+ // Worse, the refusal steered them wrong. It said `--public-key-hash <hash>` was sufficient,
96
+ // and the gateway rejects a hash-only identity for external signing mode — correctly, since a
97
+ // hash cannot sign. So following the CLI's own advice produced an identity that consumes org
98
+ // quota and can never be used. Found by the end-to-end check on its first real run.
99
+ if (!publicKeyHash && publicKey) {
100
+ const clean = publicKey.trim().toLowerCase().replace(/^0x/, '');
101
+ if (!/^[0-9a-f]{64}$/.test(clean)) {
102
+ throw new UsageError(`"${publicKey}" is not a public key. Expected 64 hex characters (32 bytes).`, 'INVALID_PUBLIC_KEY');
103
+ }
104
+ publicKey = clean;
105
+ publicKeyHash = publicKeyHashOf(Buffer.from(clean, 'hex'));
106
+ }
34
107
  if (!publicKeyHash) {
35
- throw new Error('Provide --sign-with <key>, or --public-key-hash <hash>. '
36
- + 'To make a key: certen keys generate --name dev');
108
+ throw new UsageError('Provide --sign-with <key>, or --public-key <hex>. '
109
+ + 'To make a key: certen keys generate --name dev', 'MISSING_SIGNING_KEY');
110
+ }
111
+ // A hash with no key is accepted here and refused by the gateway, because a hash cannot sign.
112
+ // Saying so now costs nothing; discovering it after creation costs an identity slot.
113
+ if (!publicKey) {
114
+ hint('No --public-key given, only its hash. The gateway refuses this for external signing:');
115
+ hint('a hash cannot sign, so the identity would consume quota and never be usable.');
37
116
  }
38
117
  const client = await getClient();
39
118
  const result = await client.identity.create({
40
119
  name: opts.name,
41
120
  publicKeyHash,
42
121
  publicKey,
43
- chains: opts.chains ? opts.chains.split(',') : undefined,
122
+ chains,
44
123
  credits: opts.credits,
45
124
  });
46
- printOutput(result);
125
+ const id = result.id;
126
+ // Recorded the moment it exists. The gateway has no identity list route and the portfolio
127
+ // view returns no UUIDs, so an id that is only printed is an id that can be lost.
128
+ if (id)
129
+ rememberIdentity({ id, adi_url: result.adi_url, chains: chains ?? [] });
130
+ if (!wait || !id) {
131
+ if (result.id)
132
+ printIdentity(result);
133
+ else
134
+ printOutput(result);
135
+ hint('');
136
+ hint('Provisioning continues in the background. It is not usable until status is terminal');
137
+ hint('AND can_sign is true:');
138
+ hint(` certen identity get ${id ?? '<id>'}`);
139
+ return;
140
+ }
141
+ // Waiting means the printed result is the one the user can act on, not the 202. Emitting
142
+ // both would put two payloads in the --json envelope for no benefit.
143
+ //
144
+ // The SHAPE stays identical to the no-wait response, because a consumer must not have to
145
+ // parse two different layouts depending on which flags were passed.
146
+ const identity = await waitForIdentity(client, id, budget);
147
+ // Merged, not replaced. `result` carries fields that only the create returns —
148
+ // `mnemonic_retrieval`, `status_url`, `warning` — and `identity` carries the refreshed state.
149
+ // Printing `identity` alone would drop the one-shot mnemonic URL for provider-mode
150
+ // identities, which cannot be recovered afterwards.
151
+ printIdentity({ ...result, ...identity });
152
+ if (isJsonMode())
153
+ return;
154
+ human('');
155
+ human(` Identity ${identity.adi_url} is active and can sign.`);
156
+ human(` ID ${identity.id}`);
157
+ // The abstract account is msg.sender for everything this identity executes, and it starts
158
+ // empty. It was previously buried in a JSON blob under a name that does not say so, which
159
+ // is how the "parks at anchoring forever" failure finds people.
160
+ const accounts = identity.chain_accounts ?? [];
161
+ if (accounts.length > 0) {
162
+ human('');
163
+ human(' Abstract accounts (msg.sender on chain — these need gas before they can execute):');
164
+ for (const account of accounts) {
165
+ human(` ${account.chain_id.padEnd(18)} ${account.address || '(not deployed)'}`);
166
+ }
167
+ const faucets = accounts.map((a) => faucetFor(a.chain_id)).filter(Boolean);
168
+ if (faucets.length > 0) {
169
+ human('');
170
+ human(` Fund them: ${[...new Set(faucets)].join(' ')}`);
171
+ }
172
+ }
173
+ hint('');
174
+ hint(`Next: certen tx create --identity ${identity.id} --to-chain <chain> --to <addr> --amount <n> --sign-with <key>`);
47
175
  });
48
176
  identity
49
177
  .command('list')
50
- .description('(unavailable the gateway has no identity list endpoint)')
51
- .action(() => {
178
+ .description('List the identities in your organization (via the portfolio view)')
179
+ .action(async () => {
52
180
  // This called GET /v1/identities, which 404s: the gateway serves /v1/identity (POST) and
53
- // /v1/identity/{id} (GET/PATCH/DELETE) and has no collection route. Failing with an explanation
54
- // beats failing with a 404 the user has to go decode. Kept as a command so it explains itself
55
- // rather than printing "unknown command".
56
- throw new Error('The gateway has no identity list endpoint — GET /v1/identities does not exist. '
57
- + 'Use `certen identity get <id>` for an identity you know, or `certen portfolio` for a '
58
- + 'cross-identity view of the org.');
181
+ // /v1/identity/{id} (GET/PATCH/DELETE) and has no collection route. It then spent a release
182
+ // as a command whose only behaviour was to explain that it did not work honest, but the
183
+ // user's actual question ("what identities do I have") was answerable the whole time from
184
+ // /v1/portfolio.
185
+ //
186
+ // It then spent a release answering that question WITHOUT the ids, because the portfolio view
187
+ // withheld them — so anyone who had lost the UUID printed at create time could see their
188
+ // identity listed and still not act on it. The gateway now returns `id` there (it had it in
189
+ // hand all along), and this command is finally a complete answer rather than a partial one
190
+ // with a footnote.
191
+ const client = await getClient();
192
+ const portfolio = await client.portfolio.get();
193
+ const identities = portfolio.identities ?? [];
194
+ if (identities.length === 0) {
195
+ printOutput([]);
196
+ hint('No identities yet. Create one: certen identity create --name <name> --sign-with <key>');
197
+ return;
198
+ }
199
+ // `id` first: it is the field every other command takes as an argument, so it is the one a
200
+ // reader is scanning for.
201
+ printOutput(identities.map((i) => ({
202
+ id: i.id ?? '—',
203
+ adi_url: i.adi_url,
204
+ status: i.status,
205
+ credit_balance: i.credit_balance,
206
+ chains: i.chains?.length ?? 0,
207
+ pending_actions: i.pending_actions,
208
+ })));
209
+ // A gateway older than 2026-08 does not return `id` here, and the CLI ships independently of
210
+ // it. Say so only when it is actually true — a permanent caveat about a fixed problem trains
211
+ // people to skip the notes that matter.
212
+ if (identities.some((i) => !i.id)) {
213
+ hint('');
214
+ hint('This gateway does not return identity ids in the portfolio view, so `id` reads "—".');
215
+ hint('Upgrade the gateway, or use the id printed when the identity was created.');
216
+ }
59
217
  });
60
218
  identity
61
219
  .command('get <id>')
@@ -64,18 +222,110 @@ export function registerIdentityCommands(program) {
64
222
  const client = await getClient();
65
223
  // No `--include`: the route takes no query parameters. It used to be sent and silently ignored.
66
224
  const result = await client.identity.get(id);
225
+ printIdentity(result);
226
+ if (isJsonMode())
227
+ return;
228
+ const identity = result;
229
+ // `can_sign` is the field that decides whether this identity is usable, and reading it out
230
+ // of a printed blob is exactly the step people skip. State the conclusion.
231
+ if (identity.can_sign === true) {
232
+ hint('');
233
+ hint(`Ready. Next: certen tx create --identity ${identity.id} --to-chain <chain> --to <addr> --amount <n> --sign-with <key>`);
234
+ }
235
+ else if (identity.can_sign === false) {
236
+ hint('');
237
+ hint('This identity CANNOT sign — its key page is not held by your key. It will fail at the');
238
+ hint('signing step of every flow.');
239
+ }
240
+ else if (['provisioning', 'pending', 'creating'].includes(identity.status)) {
241
+ hint('');
242
+ hint(`Still provisioning. Wait for it: certen identity get ${identity.id}`);
243
+ }
244
+ else {
245
+ // null on a terminal status: unknown, not a soft yes. Never round it up.
246
+ hint('');
247
+ hint('Whether this identity can sign is UNKNOWN — its on-chain key page could not be read.');
248
+ hint('Treat it as unusable until that resolves.');
249
+ }
250
+ });
251
+ identity
252
+ .command('retire <id>')
253
+ .description('Retire an identity, freeing the org quota slot it occupies')
254
+ .requiredOption('--yes', 'Confirm. There is no prompt — see below')
255
+ .action(async (id) => {
256
+ // No y/N prompt: the required --yes IS the confirmation, matching `keys delete`. An identity
257
+ // that a live integration depends on should not be retirable by an accidental Enter.
258
+ const client = await getClient();
259
+ // Resolved first so the confirmation message names what is being retired. An id pasted from
260
+ // the wrong terminal is the mistake worth catching, and it is invisible until something says
261
+ // the ADI out loud.
262
+ // No enrichments: this read exists to name the ADI in the confirmation prompt. Fetching
263
+ // governance, per-chain balances and pending counts to print one URL is work nobody sees.
264
+ const before = await client.identity.get(id, { include: [] }).catch(() => null);
265
+ const result = await client.identity.retire(id);
266
+ // Dropped from the local record too, so `certen init` does not offer to reuse it.
267
+ forgetIdentity(id);
67
268
  printOutput(result);
269
+ if (isJsonMode())
270
+ return;
271
+ human('');
272
+ human(` Retired ${before?.adi_url ?? id}. The org quota slot is free.`);
273
+ human('');
274
+ // The distinction people get wrong, and the one that matters if they were retiring for
275
+ // security reasons rather than housekeeping.
276
+ human(' This is a soft delete INSIDE CERTEN. The on-chain ADI, its key book and its key page');
277
+ human(' still exist on Accumulate and are untouched. Retiring is not a way to revoke a key.');
68
278
  });
69
279
  identity
70
280
  .command('link-chain <id>')
71
281
  .description('Link a chain to an identity')
72
- .requiredOption('--chain <chain>', 'Chain ID to link')
282
+ .requiredOption('--chain <chain>', 'Chain to link, e.g. base-sepolia')
73
283
  .action(async (id, opts) => {
284
+ const chain = assertChain(opts.chain);
74
285
  const client = await getClient();
75
286
  const result = await client.identity.update(id, {
76
- linkChains: [opts.chain],
287
+ linkChains: [chain],
77
288
  });
78
289
  printOutput(result);
79
290
  });
291
+ identity
292
+ .command('mnemonic <id-or-url> [token]')
293
+ .description('Collect a provider-mode mnemonic — works exactly once')
294
+ .option('--out <file>', 'Where to write it. Defaults to ./<id>-mnemonic.txt, mode 0600.')
295
+ .option('--print', 'Print it to the terminal instead of writing a file')
296
+ .action(async (idOrUrl, token, opts) => {
297
+ const client = await getClient();
298
+ const { mnemonic } = await client.identity.retrieveMnemonic(idOrUrl, token);
299
+ // A machine consumer asked for the value in its output, so give it the value. Anything else
300
+ // would mean a script has to go read a file the CLI chose the name of.
301
+ if (isJsonMode() || getOutputFormat() === 'json') {
302
+ printOutput({ mnemonic });
303
+ return;
304
+ }
305
+ if (opts.print) {
306
+ human('');
307
+ human(` ${mnemonic}`);
308
+ human('');
309
+ human(' That was the only read. The URL is dead now, and this phrase is in your');
310
+ human(' terminal scrollback — move it somewhere you trust and clear the buffer.');
311
+ return;
312
+ }
313
+ // Writing beats printing by default. A seed phrase on stdout lands in scrollback, in CI
314
+ // logs, and in whatever is recording the session — all places it outlives its usefulness by
315
+ // years. `--print` is there for anyone who genuinely wants that.
316
+ const { id } = parseMnemonicTarget(idOrUrl, token);
317
+ const path = opts.out ?? `${id}-mnemonic.txt`;
318
+ writeFileSync(path, `${mnemonic}\n`, { encoding: 'utf-8', mode: 0o600 });
319
+ try {
320
+ chmodSync(path, 0o600);
321
+ }
322
+ catch {
323
+ // Windows has no POSIX mode. The file is still written; permissions are the OS's business.
324
+ }
325
+ human('');
326
+ human(` Written to ${path}`);
327
+ human(' Read once and gone — the retrieval URL no longer works, and CERTEN cannot');
328
+ human(' produce this phrase again. Move it into your secret store and delete the file.');
329
+ });
80
330
  }
81
331
  //# sourceMappingURL=identity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/commands/identity.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,KAAK,UAAU,SAAS;IACtB,OAAO,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAAgB;IACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,qBAAqB,CAAC,CAAC;IAEhF,QAAQ;SACL,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,uBAAuB,CAAC;SACpC,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC;SAChD,MAAM,CAAC,mBAAmB,EAAE,6DAA6D,CAAC;SAC1F,MAAM,CAAC,0BAA0B,EAAE,+CAA+C,CAAC;SACnF,MAAM,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;SAChD,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC;SACxD,MAAM,CAAC,qBAAqB,EAAE,iBAAiB,EAAE,QAAQ,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,2FAA2F;QAC3F,0FAA0F;QAC1F,uFAAuF;QACvF,+EAA+E;QAC/E,IAAI,aAAa,GAAuB,IAAI,CAAC,aAAa,CAAC;QAC3D,IAAI,SAAS,GAAuB,IAAI,CAAC,SAAS,CAAC;QAEnD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,aAAa,IAAI,SAAS,EAAE,CAAC;gBAC/B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;YAC1F,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClD,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;YACrC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,0DAA0D;kBACxD,gDAAgD,CACnD,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC1C,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,aAAa;YACb,SAAS;YACT,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;YACxD,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QACH,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,2DAA2D,CAAC;SACxE,MAAM,CAAC,GAAG,EAAE;QACX,yFAAyF;QACzF,gGAAgG;QAChG,8FAA8F;QAC9F,0CAA0C;QAC1C,MAAM,IAAI,KAAK,CACb,iFAAiF;cAC/E,uFAAuF;cACvF,iCAAiC,CACpC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,sBAAsB,CAAC;SACnC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,gGAAgG;QAChG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7C,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,QAAQ;SACL,OAAO,CAAC,iBAAiB,CAAC;SAC1B,WAAW,CAAC,6BAA6B,CAAC;SAC1C,cAAc,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;SACrD,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,IAAI,EAAE,EAAE;QACjC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE;YAC9C,UAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC;SACzB,CAAC,CAAC;QACH,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/commands/identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerInitCommands(program: Command): void;