@certen.io/cli 0.4.0 → 0.7.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.
Files changed (87) hide show
  1. package/CHANGELOG.md +440 -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.d.ts +2 -0
  11. package/dist/commands/billing.js +782 -0
  12. package/dist/commands/billing.js.map +1 -0
  13. package/dist/commands/call.d.ts +2 -0
  14. package/dist/commands/call.js +168 -0
  15. package/dist/commands/call.js.map +1 -0
  16. package/dist/commands/chains.d.ts +2 -0
  17. package/dist/commands/chains.js +123 -0
  18. package/dist/commands/chains.js.map +1 -0
  19. package/dist/commands/doctor.d.ts +2 -0
  20. package/dist/commands/doctor.js +171 -0
  21. package/dist/commands/doctor.js.map +1 -0
  22. package/dist/commands/errors-catalogue.d.ts +2 -0
  23. package/dist/commands/errors-catalogue.js +83 -0
  24. package/dist/commands/errors-catalogue.js.map +1 -0
  25. package/dist/commands/identity.js +269 -19
  26. package/dist/commands/identity.js.map +1 -1
  27. package/dist/commands/init.d.ts +2 -0
  28. package/dist/commands/init.js +307 -0
  29. package/dist/commands/init.js.map +1 -0
  30. package/dist/commands/keys.js +2 -0
  31. package/dist/commands/keys.js.map +1 -1
  32. package/dist/commands/oauth-clients.d.ts +2 -0
  33. package/dist/commands/oauth-clients.js +131 -0
  34. package/dist/commands/oauth-clients.js.map +1 -0
  35. package/dist/commands/orgs.d.ts +2 -0
  36. package/dist/commands/orgs.js +117 -0
  37. package/dist/commands/orgs.js.map +1 -0
  38. package/dist/commands/pending.js +13 -1
  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 +144 -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 +40 -8
  69. package/dist/index.js.map +1 -1
  70. package/dist/output.d.ts +23 -0
  71. package/dist/output.js +90 -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,120 @@
1
+ import { CliError, EXIT } from './errors.js';
2
+ import { normalizeChain } from './chains.js';
3
+ /**
4
+ * The zero-balance abstract account guard.
5
+ *
6
+ * This is the most expensive silent failure in the product, and it is documented everywhere
7
+ * except where it happens. A fresh identity gets a deterministic abstract account on each linked
8
+ * chain, with a zero balance. An intent that moves value from it is accepted, signed and
9
+ * submitted — every step reports success — and then parks at `anchoring` forever, because the
10
+ * execution leg cannot run on chain. Nothing in any API response says so. The intent simply never
11
+ * reaches a terminal state, and the user is left debugging a gateway that is behaving correctly.
12
+ *
13
+ * So: refuse before submitting, and name the address that needs funding.
14
+ *
15
+ * The check is deliberately one-directional. It refuses ONLY on a positively observed zero
16
+ * balance. If the balance cannot be read — the chain is not in the portfolio, the account is not
17
+ * deployed yet, the lookup fails — the intent proceeds. A guard that blocked on missing data
18
+ * would break legitimate work every time the portfolio view lagged, which is a worse failure than
19
+ * the one it prevents.
20
+ */
21
+ /** Where to send testnet gas, per chain. Printed with the refusal, because the fix is the point. */
22
+ const FAUCETS = {
23
+ 'ethereum-sepolia': 'https://sepoliafaucet.com',
24
+ 'base-sepolia': 'https://www.alchemy.com/faucets/base-sepolia',
25
+ 'arbitrum-sepolia': 'https://www.alchemy.com/faucets/arbitrum-sepolia',
26
+ };
27
+ export function faucetFor(chain) {
28
+ return FAUCETS[chain];
29
+ }
30
+ /** Does this intent move value? A zero or absent amount needs no funded account. */
31
+ export function movesValue(intent) {
32
+ const amount = intent.amount ?? intent.value;
33
+ if (amount === undefined || amount === null)
34
+ return false;
35
+ const n = Number(String(amount));
36
+ // A non-numeric amount is not evidence of zero — let the gateway judge the shape.
37
+ return Number.isFinite(n) ? n > 0 : true;
38
+ }
39
+ function fromKnown(balances, chain) {
40
+ const want = normalizeChain(chain);
41
+ const onChain = balances.filter((b) => normalizeChain(b.chain_id) === want);
42
+ if (onChain.length === 0)
43
+ return null;
44
+ // The NATIVE balance is what pays for execution; a token balance on the same account does not
45
+ // make the execution leg runnable.
46
+ const native = onChain.find((b) => !b.token || b.token === 'ETH' || b.token === 'native');
47
+ return {
48
+ address: onChain[0].address,
49
+ balance: native ? native.balance : null,
50
+ // Not reported by this endpoint, and not read by anything: the guard decides on the balance.
51
+ deployed: true,
52
+ };
53
+ }
54
+ async function fundingFor(client, identityId, chain) {
55
+ try {
56
+ const portfolio = await client.portfolio.get(identityId);
57
+ // Both sides are normalized: the gateway returns `chain_id` as a slug on some chain accounts
58
+ // and as a numeric EVM id on others, in the same response. Comparing raw strings matched the
59
+ // slug entries and silently skipped the numeric ones — so the guard did nothing on exactly
60
+ // the accounts it was written to protect.
61
+ const want = normalizeChain(chain);
62
+ for (const identity of portfolio.identities ?? []) {
63
+ for (const c of identity.chains ?? []) {
64
+ if (normalizeChain(c.chain_id) !== want)
65
+ continue;
66
+ // The native balance is the one that pays for execution. A token balance on the same
67
+ // account does not make the execution leg runnable.
68
+ const native = (c.balances ?? []).find((b) => !b.token || b.token === 'ETH' || b.token === 'native');
69
+ return {
70
+ address: c.address,
71
+ balance: native ? native.balance : null,
72
+ deployed: c.deployed,
73
+ };
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ catch {
79
+ // An unavailable portfolio must never block a transaction. The guard is a courtesy, not a
80
+ // gate the product depends on.
81
+ return null;
82
+ }
83
+ }
84
+ /**
85
+ * Refuse a value-moving intent from an abstract account that is positively known to be empty.
86
+ *
87
+ * `force` exists because someone deliberately exercising the anchoring path should be able to,
88
+ * and because a guard with no override becomes something people work around rather than with.
89
+ */
90
+ export async function assertFundedForValue(client, identityId, chain, intent, force,
91
+ /**
92
+ * Balances the caller has ALREADY fetched, from `identity.get()`.
93
+ *
94
+ * `GET /v1/identity/{id}` returns a `balances` array carrying the same chain, address and native
95
+ * balance this guard reads out of `/v1/portfolio`. `certen call` fetches the identity first (it
96
+ * needs `can_sign` before prompting for a passphrase) and then paid for a second read of numbers
97
+ * it was already holding — a round trip on the critical path of the main flow, for nothing.
98
+ *
99
+ * Omit it and the portfolio is fetched as before; `certen tx create` has no identity in hand.
100
+ */
101
+ known) {
102
+ if (force || !chain || !movesValue(intent))
103
+ return;
104
+ const funding = known ? fromKnown(known, chain) : await fundingFor(client, identityId, chain);
105
+ if (!funding)
106
+ return;
107
+ const balance = funding.balance;
108
+ if (balance === null)
109
+ return;
110
+ if (Number(balance) > 0)
111
+ return;
112
+ const named = normalizeChain(chain);
113
+ const faucet = faucetFor(named);
114
+ throw new CliError(`The abstract account ${funding.address} on ${named} holds no ${named.includes('sepolia') ? 'testnet ' : ''}`
115
+ + 'gas. This intent would be accepted, signed and submitted, and would then park at "anchoring" '
116
+ + 'forever, because the execution leg cannot run on chain.\n'
117
+ + ` Fund it first${faucet ? `: ${faucet}` : '.'}\n`
118
+ + ' Then run this command again. Pass --force to submit anyway.', 'ABSTRACT_ACCOUNT_UNFUNDED', EXIT.FAILED);
119
+ }
120
+ //# sourceMappingURL=funding-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"funding-guard.js","sourceRoot":"","sources":["../src/funding-guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command, Help } from 'commander';
2
+ export declare function formatRootHelp(cmd: Command, helper: Help): string;
@@ -0,0 +1,94 @@
1
+ import { Help } from 'commander';
2
+ /**
3
+ * The order here is the order of the journey, not of importance. Anything not listed still
4
+ * appears, under "Other" — a command must never become invisible because someone added it
5
+ * without touching this file.
6
+ */
7
+ const GROUPS = [
8
+ {
9
+ title: 'Get started',
10
+ blurb: 'from nothing to a working setup',
11
+ commands: ['login', 'signup', 'init', 'chains', 'auth', 'keys', 'doctor', 'whoami'],
12
+ },
13
+ {
14
+ title: 'Build',
15
+ blurb: 'identities, and the work they authorize',
16
+ commands: ['identity', 'call', 'tx', 'proof'],
17
+ },
18
+ {
19
+ title: 'Approve',
20
+ blurb: 'multi-party signing',
21
+ commands: ['pending', 'governance'],
22
+ },
23
+ {
24
+ title: 'Money',
25
+ blurb: 'what it costs and how to pay',
26
+ commands: ['pricing', 'balance', 'quote', 'fund', 'payers'],
27
+ },
28
+ {
29
+ title: 'Audit',
30
+ blurb: 'what you were charged, and proof of it',
31
+ commands: ['ledger', 'receipts', 'verify'],
32
+ },
33
+ {
34
+ title: 'Operate',
35
+ blurb: 'across every identity and key',
36
+ commands: ['portfolio', 'webhooks', 'oauth-clients', 'orgs', 'admin', 'scopes', 'errors'],
37
+ },
38
+ ];
39
+ const QUICKSTART = `
40
+ From nothing to a proof:
41
+
42
+ certen login # approve this machine in the portal
43
+ certen init # key, identity, funding — all checked
44
+ certen call --identity <id> --chain base-sepolia --to 0xContract \\
45
+ --fn 'confirm(bytes32)' --arg 0x... --sign-with dev --wait
46
+ certen proof get <intent-id> # the evidence, to hand over
47
+
48
+ Stuck? Run: certen doctor
49
+ `;
50
+ export function formatRootHelp(cmd, helper) {
51
+ // Subcommands inherit this configuration, so anything that is not the root is handed straight
52
+ // back to commander's own renderer. Calling `helper.formatHelp` here would recurse into this
53
+ // function, because that is the property being overridden.
54
+ if (cmd.parent !== null) {
55
+ return Help.prototype.formatHelp.call(helper, cmd, helper);
56
+ }
57
+ const visible = cmd.commands.filter((c) => !c._hidden);
58
+ const byName = new Map(visible.map((c) => [c.name(), c]));
59
+ const grouped = new Set(GROUPS.flatMap((g) => g.commands));
60
+ const width = Math.max(...visible.map((c) => c.name().length), 10) + 2;
61
+ const lines = [];
62
+ lines.push(`${cmd.name()} — ${cmd.description()}`);
63
+ lines.push('');
64
+ lines.push(`Usage: ${cmd.name()} [options] <command> [args]`);
65
+ lines.push(QUICKSTART.replace(/^\n/, ''));
66
+ for (const group of GROUPS) {
67
+ const present = group.commands.filter((name) => byName.has(name));
68
+ if (present.length === 0)
69
+ continue;
70
+ lines.push(`${group.title} — ${group.blurb}`);
71
+ for (const name of present) {
72
+ lines.push(` ${name.padEnd(width)}${byName.get(name).description()}`);
73
+ }
74
+ lines.push('');
75
+ }
76
+ const ungrouped = visible.filter((c) => !grouped.has(c.name()));
77
+ if (ungrouped.length > 0) {
78
+ lines.push('Other');
79
+ for (const c of ungrouped) {
80
+ lines.push(` ${c.name().padEnd(width)}${c.description()}`);
81
+ }
82
+ lines.push('');
83
+ }
84
+ lines.push('Options');
85
+ for (const option of helper.visibleOptions(cmd)) {
86
+ lines.push(` ${helper.optionTerm(option).padEnd(width + 12)}${helper.optionDescription(option)}`);
87
+ }
88
+ lines.push('');
89
+ lines.push(`Run \`${cmd.name()} <command> --help\` for the flags on any of them.`);
90
+ lines.push(`Scripting? \`${cmd.name()} --help --json\` returns the whole tree in one call.`);
91
+ lines.push('');
92
+ return lines.join('\n');
93
+ }
94
+ //# sourceMappingURL=help-root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-root.js","sourceRoot":"","sources":["../src/help-root.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -25,6 +25,19 @@ import { registerPendingCommands } from './commands/pending.js';
25
25
  import { registerGovernanceCommands } from './commands/governance.js';
26
26
  import { registerPortfolioCommands } from './commands/portfolio.js';
27
27
  import { registerAdminCommands } from './commands/admin.js';
28
+ import { registerBillingCommands } from './commands/billing.js';
29
+ import { registerChainsCommands } from './commands/chains.js';
30
+ import { registerWhoamiCommands } from './commands/whoami.js';
31
+ import { registerDoctorCommands } from './commands/doctor.js';
32
+ import { registerProofCommands } from './commands/proof.js';
33
+ import { registerCallCommands } from './commands/call.js';
34
+ import { registerInitCommands } from './commands/init.js';
35
+ import { registerSignupCommands } from './commands/signup.js';
36
+ import { registerWebhookCommands } from './commands/webhooks.js';
37
+ import { registerOAuthClientCommands } from './commands/oauth-clients.js';
38
+ import { registerOrgCommands } from './commands/orgs.js';
39
+ import { registerErrorsCommands } from './commands/errors-catalogue.js';
40
+ import { formatRootHelp } from './help-root.js';
28
41
  const VERSION = readVersion();
29
42
  export function buildProgram() {
30
43
  const program = new Command();
@@ -37,19 +50,35 @@ export function buildProgram() {
37
50
  // Declared so it appears in --help. It is stripped from argv before parsing (see run()), because
38
51
  // a global flag that may appear after a subcommand is not something commander models.
39
52
  .option('--json', 'Emit one JSON envelope on stdout; human output goes to stderr');
53
+ registerSignupCommands(program);
54
+ registerInitCommands(program);
55
+ registerChainsCommands(program);
40
56
  registerAuthCommands(program);
41
57
  registerKeysCommands(program);
58
+ registerDoctorCommands(program);
59
+ registerWhoamiCommands(program);
42
60
  registerIdentityCommands(program);
43
61
  registerTransactionCommands(program);
62
+ registerCallCommands(program);
63
+ registerProofCommands(program);
44
64
  registerPendingCommands(program);
45
65
  registerGovernanceCommands(program);
46
66
  registerPortfolioCommands(program);
67
+ registerBillingCommands(program);
47
68
  registerAdminCommands(program);
69
+ registerWebhookCommands(program);
70
+ registerOAuthClientCommands(program);
71
+ registerOrgCommands(program);
72
+ registerErrorsCommands(program);
48
73
  // Every command, not just the root. `exitOverride()` is NOT inherited by subcommands, so without
49
74
  // this walk a missing required flag on `identity create` called process.exit(1) inside commander:
50
75
  // stdout stayed empty, no envelope was ever emitted, and a usage error was indistinguishable from
51
76
  // a failed request. Every nested command has to opt in explicitly.
52
77
  applyExitOverride(program);
78
+ // Grouped by journey stage rather than alphabetically. Applied AFTER every command is
79
+ // registered, so nothing can be missing from the listing it builds. Subcommand help is
80
+ // untouched — see help-root.ts.
81
+ program.configureHelp({ formatHelp: formatRootHelp });
53
82
  return program;
54
83
  }
55
84
  function applyExitOverride(cmd) {
@@ -77,14 +106,17 @@ function handleError(err) {
77
106
  });
78
107
  }
79
108
  if (err instanceof CertenError) {
80
- // isRetryable is the SDK's own judgement reuse it so both transports agree.
81
- return emitFailure({
82
- message: err.message,
83
- code: err.code,
84
- status: err.status,
85
- requestId: err.requestId,
86
- isRetryable: err.isRetryable,
87
- });
109
+ // Pass the ERROR, not a copy of its fields.
110
+ //
111
+ // This used to flatten it into an object literal. The literal carried the same
112
+ // values but destroyed the class identity, so a 402 reached the reporter as an
113
+ // anonymous shape and its payment target was silently dropped — the refusal
114
+ // printed a code and a message while the fix sat unread on the error.
115
+ //
116
+ // Nothing is lost by passing the instance: message, code, status and requestId
117
+ // are all readable on it, and `isRetryable` is a getter, so the SDK's own retry
118
+ // judgement still reaches both transports.
119
+ return emitFailure(err);
88
120
  }
89
121
  return emitFailure(err);
90
122
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/output.d.ts CHANGED
@@ -8,6 +8,14 @@ export declare function resetOutput(): void;
8
8
  */
9
9
  export declare function printOutput(data: Record<string, unknown>[] | Record<string, unknown>, opts?: {
10
10
  forceJson?: boolean;
11
+ /**
12
+ * Emit for machines only, and print nothing in table mode.
13
+ *
14
+ * For a command that renders its own readable summary. Without this the payload and the summary
15
+ * both reach a person, so every figure appears twice — and any long or nested field (a payment
16
+ * URI, a credit object) lands in the middle of the instructions someone is trying to follow.
17
+ */
18
+ machineOnly?: boolean;
11
19
  }): void;
12
20
  /**
13
21
  * A human-facing note — "API key saved", "(no keys)".
@@ -18,6 +26,21 @@ export declare function printOutput(data: Record<string, unknown>[] | Record<str
18
26
  export declare function human(message: string): void;
19
27
  /** A hint or warning. Always stderr — it is never the result of the command. */
20
28
  export declare function hint(message: string): void;
29
+ /**
30
+ * `"12.340000"` -> `"$12.34"`, and `"-72.355716"` -> `"-$72.36"`.
31
+ *
32
+ * One implementation, here, because there were two. `billing.ts` handled a leading minus and
33
+ * `whoami.ts` did not, so the same drawn-down account rendered `-$72.35` in one command and the
34
+ * malformed `$-72.35` in the other. A money formatter is exactly the kind of four-line helper that
35
+ * gets copied rather than imported, and exactly the kind where the copy is wrong in the case nobody
36
+ * had yet.
37
+ *
38
+ * Works on the STRING. The gateway sends fixed-point decimal strings, and parsing money into a
39
+ * float to format it reintroduces the representation error those strings exist to avoid. The cents
40
+ * are rounded half-up from the remaining digits rather than truncated, so a balance of
41
+ * `-72.355716` reads `-$72.36` — a displayed figure should never flatter the account by a cent.
42
+ */
43
+ export declare function usd(amount: string | number): string;
21
44
  /**
22
45
  * Emit the success envelope. No-op outside JSON mode, and safe to call more than once.
23
46
  *
package/dist/output.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { CertenPaymentRequiredError } from '@certen.io/sdk';
1
2
  import { getOutputFormat } from './config.js';
2
3
  import { CliError, EXIT } from './errors.js';
3
4
  /**
@@ -40,6 +41,8 @@ export function printOutput(data, opts) {
40
41
  console.log(JSON.stringify(data, null, 2));
41
42
  return;
42
43
  }
44
+ if (opts?.machineOnly)
45
+ return;
43
46
  printTable(data);
44
47
  }
45
48
  /**
@@ -58,6 +61,37 @@ export function human(message) {
58
61
  export function hint(message) {
59
62
  console.error(message);
60
63
  }
64
+ /**
65
+ * `"12.340000"` -> `"$12.34"`, and `"-72.355716"` -> `"-$72.36"`.
66
+ *
67
+ * One implementation, here, because there were two. `billing.ts` handled a leading minus and
68
+ * `whoami.ts` did not, so the same drawn-down account rendered `-$72.35` in one command and the
69
+ * malformed `$-72.35` in the other. A money formatter is exactly the kind of four-line helper that
70
+ * gets copied rather than imported, and exactly the kind where the copy is wrong in the case nobody
71
+ * had yet.
72
+ *
73
+ * Works on the STRING. The gateway sends fixed-point decimal strings, and parsing money into a
74
+ * float to format it reintroduces the representation error those strings exist to avoid. The cents
75
+ * are rounded half-up from the remaining digits rather than truncated, so a balance of
76
+ * `-72.355716` reads `-$72.36` — a displayed figure should never flatter the account by a cent.
77
+ */
78
+ export function usd(amount) {
79
+ const raw = String(amount);
80
+ const negative = raw.trimStart().startsWith('-');
81
+ const [whole, frac = ''] = raw.replace('-', '').split('.');
82
+ // Round on the digit AFTER the cents, carrying into the whole part when it overflows.
83
+ const cents = Number((frac + '000').slice(0, 3));
84
+ let dollars = BigInt(whole || '0');
85
+ let rounded = Math.round(cents / 10);
86
+ if (rounded === 100) {
87
+ dollars += 1n;
88
+ rounded = 0;
89
+ }
90
+ // A residue too small to show is not a debt. `-0.004` rounding to `-$0.00` would be the only
91
+ // place in the CLI where zero has a sign.
92
+ const sign = negative && (dollars !== 0n || rounded !== 0) ? '-' : '';
93
+ return `${sign}$${dollars}.${String(rounded).padStart(2, '0')}`;
94
+ }
61
95
  /**
62
96
  * Emit the success envelope. No-op outside JSON mode, and safe to call more than once.
63
97
  *
@@ -85,6 +119,10 @@ export function emitFailure(err) {
85
119
  const code = e.code ?? 'UNKNOWN_ERROR';
86
120
  const retryable = e instanceof CliError ? e.retryable : Boolean(e.isRetryable);
87
121
  const exitCode = resolveExitCode(e);
122
+ // A refusal for lack of funds is the one failure that carries its own fix, so it
123
+ // is rendered rather than reduced to a code and a message. The developer is
124
+ // already in a terminal; the next command belongs there, not in documentation.
125
+ const payment = err instanceof CertenPaymentRequiredError ? err : null;
88
126
  if (jsonMode) {
89
127
  flushed = true;
90
128
  process.stdout.write(`${JSON.stringify({
@@ -95,20 +133,72 @@ export function emitFailure(err) {
95
133
  retryable,
96
134
  ...(e.status !== undefined ? { status: e.status } : {}),
97
135
  ...(e.requestId ? { requestId: e.requestId } : {}),
136
+ // A failure that still produced a result carries it, rather than throwing the result
137
+ // away in order to signal the failure. See CliError.details.
138
+ ...(e.details ? { details: e.details } : {}),
139
+ // Additive: a consumer that ignores unknown keys is unaffected, and one
140
+ // that wants to settle automatically no longer has to parse prose.
141
+ ...(payment
142
+ ? {
143
+ shortfall_usd: payment.shortfallUsd,
144
+ quote_id: payment.quoteId,
145
+ resolve: payment.resolution,
146
+ }
147
+ : {}),
98
148
  },
99
149
  })}\n`);
100
150
  }
101
151
  else {
102
152
  console.error(code === 'UNKNOWN_ERROR' ? `Error: ${message}` : `Error [${code}]: ${message}`);
153
+ if (payment)
154
+ emitPaymentFix(payment);
103
155
  }
104
156
  return exitCode;
105
157
  }
158
+ /**
159
+ * Print the way out of a 402.
160
+ *
161
+ * All on stderr: it is guidance, not the result of the command, and a caller
162
+ * piping stdout must still get clean output (or, in JSON mode, exactly one
163
+ * envelope). The closing line matters as much as the address — a developer whose
164
+ * request was refused needs to know nothing was charged and nothing started.
165
+ */
166
+ function emitPaymentFix(payment) {
167
+ console.error('');
168
+ console.error(` ${payment.summary}`);
169
+ const r = payment.resolution;
170
+ if (r) {
171
+ console.error('');
172
+ console.error(` Send exactly ${r.amount_usd} USD on ${r.chain} to:`);
173
+ console.error(` ${r.to_address}`);
174
+ console.error(` Reference ${r.payment_intent}`);
175
+ console.error('');
176
+ console.error(` Or run: ${r.cli_command}`);
177
+ console.error(` Portal: ${r.portal_url}`);
178
+ }
179
+ if (payment.quoteId) {
180
+ console.error('');
181
+ console.error(` Then retry with --quote-id ${payment.quoteId} to keep this price.`);
182
+ }
183
+ console.error('');
184
+ console.error(' Nothing was charged and no work was started.');
185
+ }
106
186
  function resolveExitCode(e) {
107
187
  if (typeof e.exitCode === 'number')
108
188
  return e.exitCode;
109
189
  // status 0 is how the SDK reports "the request never reached the gateway".
110
190
  if (e.code === 'NETWORK_ERROR' || e.status === 0)
111
191
  return EXIT.UNREACHABLE;
192
+ // Falling through to FAILED is correct for a genuine operation failure and WRONG for a plain
193
+ // `throw new Error('you forgot a flag')`, which should be a usage error and exit 2. Several
194
+ // commands shipped that mistake, and it is invisible: both cases exit 1 and read identically.
195
+ // There is no safe way to guess here — a bare Error carries nothing to distinguish them — so
196
+ // the fix is at the throw site, and this makes the throw site findable rather than silent.
197
+ if (process.env.CERTEN_DEBUG === '1' && e.code === undefined) {
198
+ const name = e.constructor?.name ?? 'unknown';
199
+ console.error(`[certen debug] exit 1 from an untyped ${name} — if this is a wrong invocation it should `
200
+ + 'throw UsageError and exit 2.');
201
+ }
112
202
  return EXIT.FAILED;
113
203
  }
114
204
  // ── table rendering (human mode only) ───────────────────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAiB,MAAM,aAAa,CAAC;AAE5D;;;;;;;;;;GAUG;AAEH,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,0FAA0F;AAC1F,IAAI,SAAS,GAAc,EAAE,CAAC;AAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,MAAM,UAAU,WAAW,CAAC,EAAW;IACrC,QAAQ,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,WAAW;IACzB,QAAQ,GAAG,KAAK,CAAC;IACjB,SAAS,GAAG,EAAE,CAAC;IACf,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,IAAyD,EACzD,IAUC;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IAC5D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,IAAI,IAAI,EAAE,WAAW;QAAE,OAAO;IAC9B,UAAU,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,IAAI,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;;QAChC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,GAAG,CAAC,MAAuB;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,QAAQ,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE3D,sFAAsF;IACtF,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;IACnC,IAAI,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACrC,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;QAAC,OAAO,IAAI,EAAE,CAAC;QAAC,OAAO,GAAG,CAAC,CAAC;IAAC,CAAC;IAEpD,6FAA6F;IAC7F,0CAA0C;IAC1C,MAAM,IAAI,GAAG,QAAQ,IAAI,CAAC,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,OAAO,GAAG,IAAI,IAAI,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,QAAQ,IAAI,OAAO;QAAE,OAAO;IACjC,OAAO,GAAG,IAAI,CAAC;IACf,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAYD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAc,CAAC;IACnC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC;IACvC,MAAM,SAAS,GAAG,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAEpC,iFAAiF;IACjF,4EAA4E;IAC5E,+EAA+E;IAC/E,MAAM,OAAO,GAAG,GAAG,YAAY,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;YAChB,EAAE,EAAE,KAAK;YACT,KAAK,EAAE;gBACL,IAAI;gBACJ,OAAO;gBACP,SAAS;gBACT,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,qFAAqF;gBACrF,6DAA6D;gBAC7D,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5C,wEAAwE;gBACxE,mEAAmE;gBACnE,GAAG,CAAC,OAAO;oBACT,CAAC,CAAC;wBACA,aAAa,EAAE,OAAO,CAAC,YAAY;wBACnC,QAAQ,EAAE,OAAO,CAAC,OAAO;wBACzB,OAAO,EAAE,OAAO,CAAC,UAAU;qBAC5B;oBACD,CAAC,CAAC,EAAE,CAAC;aACR;SACF,CAAC,IAAI,CACP,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;QAC9F,IAAI,OAAO;YAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,OAAmC;IACzD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEtC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,UAAU,WAAW,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QACtE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gCAAgC,OAAO,CAAC,OAAO,sBAAsB,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,eAAe,CAAC,CAAY;IACnC,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,QAAoB,CAAC;IAClE,2EAA2E;IAC3E,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,WAAW,CAAC;IAE1E,6FAA6F;IAC7F,4FAA4F;IAC5F,8FAA8F;IAC9F,6FAA6F;IAC7F,2FAA2F;IAC3F,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAI,CAAyC,CAAC,WAAW,EAAE,IAAI,IAAI,SAAS,CAAC;QACvF,OAAO,CAAC,KAAK,CACX,yCAAyC,IAAI,6CAA6C;cACxF,8BAA8B,CACjC,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,mGAAmG;AAEnG,SAAS,UAAU,CAAC,IAAyD;IAC3E,uCAAuC;IACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAC7F,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO;IACT,CAAC;IAED,qBAAqB;IACrB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,SAAS;IACT,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAElE,OAAO;IACP,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC"}
@@ -7,6 +7,16 @@
7
7
  */
8
8
  declare const ENV_VAR = "CERTEN_KEY_PASSPHRASE";
9
9
  export declare function passphraseFromEnv(): string | null;
10
+ export declare function isInteractive(): boolean;
11
+ /**
12
+ * Read a secret from stdin when it is a pipe rather than a terminal.
13
+ *
14
+ * This is what makes `--api-key -` work: `echo $KEY | certen auth login --api-key -` keeps the
15
+ * secret out of shell history and out of the process table, which passing it as an argument
16
+ * cannot do. Only the first line is taken, so a trailing newline from `echo` is not part of the
17
+ * key.
18
+ */
19
+ export declare function readSecretFromStdin(): Promise<string>;
10
20
  /**
11
21
  * Resolve the passphrase for reading an existing key.
12
22
  *
@@ -22,4 +32,12 @@ export declare function resolvePassphrase(encrypted: boolean, keyName: string):
22
32
  * because a script that set it once cannot mistype it twice differently.
23
33
  */
24
34
  export declare function resolveNewPassphrase(noPassphrase: boolean): Promise<string | null>;
35
+ /**
36
+ * Prompt for a secret on the TTY without echoing it.
37
+ *
38
+ * Exported so `auth login` can ask for an API key the same way key commands ask for a passphrase.
39
+ * A key pasted at a hidden prompt never reaches shell history; one passed as `--api-key <value>`
40
+ * always does.
41
+ */
42
+ export declare function promptSecret(prompt: string): Promise<string>;
25
43
  export { ENV_VAR as PASSPHRASE_ENV_VAR };
@@ -5,14 +5,33 @@
5
5
  * TTY, and the interactive prompt is the fallback rather than the default. A command that blocks
6
6
  * on a hidden prompt inside a pipeline looks like a hang, which is the worst failure mode here.
7
7
  */
8
+ import { UsageError } from './errors.js';
8
9
  const ENV_VAR = 'CERTEN_KEY_PASSPHRASE';
9
10
  export function passphraseFromEnv() {
10
11
  const v = process.env[ENV_VAR];
11
12
  return v && v.length > 0 ? v : null;
12
13
  }
13
- function isInteractive() {
14
+ export function isInteractive() {
14
15
  return Boolean(process.stdin.isTTY && process.stdout.isTTY);
15
16
  }
17
+ /**
18
+ * Read a secret from stdin when it is a pipe rather than a terminal.
19
+ *
20
+ * This is what makes `--api-key -` work: `echo $KEY | certen auth login --api-key -` keeps the
21
+ * secret out of shell history and out of the process table, which passing it as an argument
22
+ * cannot do. Only the first line is taken, so a trailing newline from `echo` is not part of the
23
+ * key.
24
+ */
25
+ export function readSecretFromStdin() {
26
+ return new Promise((resolve, reject) => {
27
+ let buf = '';
28
+ process.stdin.setEncoding('utf8');
29
+ process.stdin.on('data', (chunk) => { buf += chunk; });
30
+ process.stdin.on('end', () => resolve(buf.split(/\r?\n/)[0].trim()));
31
+ process.stdin.on('error', reject);
32
+ process.stdin.resume();
33
+ });
34
+ }
16
35
  /**
17
36
  * Read a line from the TTY without echoing it.
18
37
  *
@@ -79,7 +98,7 @@ export async function resolvePassphrase(encrypted, keyName) {
79
98
  if (fromEnv !== null)
80
99
  return fromEnv;
81
100
  if (!isInteractive()) {
82
- throw new Error(`Key "${keyName}" is encrypted and there is no TTY to prompt on. Set ${ENV_VAR}, or run this interactively.`);
101
+ throw new UsageError(`Key "${keyName}" is encrypted and there is no TTY to prompt on. Set ${ENV_VAR}, or run this interactively.`, 'PASSPHRASE_REQUIRED');
83
102
  }
84
103
  return readHidden(`Passphrase for key "${keyName}": `);
85
104
  }
@@ -97,7 +116,7 @@ export async function resolveNewPassphrase(noPassphrase) {
97
116
  if (fromEnv !== null)
98
117
  return fromEnv;
99
118
  if (!isInteractive()) {
100
- throw new Error(`No TTY to prompt for a passphrase. Set ${ENV_VAR}, or pass --no-passphrase to store the key unencrypted.`);
119
+ throw new UsageError(`No TTY to prompt for a passphrase. Set ${ENV_VAR}, or pass --no-passphrase to store the key unencrypted.`, 'PASSPHRASE_REQUIRED');
101
120
  }
102
121
  const first = await readHidden('Passphrase for the new key (empty to store unencrypted): ');
103
122
  if (first.length === 0)
@@ -107,5 +126,18 @@ export async function resolveNewPassphrase(noPassphrase) {
107
126
  throw new Error('Passphrases did not match. Nothing was written.');
108
127
  return first;
109
128
  }
129
+ /**
130
+ * Prompt for a secret on the TTY without echoing it.
131
+ *
132
+ * Exported so `auth login` can ask for an API key the same way key commands ask for a passphrase.
133
+ * A key pasted at a hidden prompt never reaches shell history; one passed as `--api-key <value>`
134
+ * always does.
135
+ */
136
+ export async function promptSecret(prompt) {
137
+ if (!isInteractive()) {
138
+ throw new Error('No TTY to prompt on.');
139
+ }
140
+ return readHidden(prompt);
141
+ }
110
142
  export { ENV_VAR as PASSPHRASE_ENV_VAR };
111
143
  //# sourceMappingURL=passphrase.js.map