@certen.io/cli 0.5.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.
- package/CHANGELOG.md +407 -0
- package/README.md +232 -160
- package/dist/chains.d.ts +67 -0
- package/dist/chains.js +242 -0
- package/dist/chains.js.map +1 -0
- package/dist/commands/admin.js +49 -4
- package/dist/commands/admin.js.map +1 -1
- package/dist/commands/auth.js +145 -12
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/billing.js +648 -40
- package/dist/commands/billing.js.map +1 -1
- package/dist/commands/call.d.ts +2 -0
- package/dist/commands/call.js +168 -0
- package/dist/commands/call.js.map +1 -0
- package/dist/commands/chains.d.ts +2 -0
- package/dist/commands/chains.js +123 -0
- package/dist/commands/chains.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.js +171 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/errors-catalogue.d.ts +2 -0
- package/dist/commands/errors-catalogue.js +83 -0
- package/dist/commands/errors-catalogue.js.map +1 -0
- package/dist/commands/identity.js +269 -19
- package/dist/commands/identity.js.map +1 -1
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +307 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/keys.js +2 -0
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/oauth-clients.d.ts +2 -0
- package/dist/commands/oauth-clients.js +131 -0
- package/dist/commands/oauth-clients.js.map +1 -0
- package/dist/commands/orgs.d.ts +2 -0
- package/dist/commands/orgs.js +117 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/pending.js +13 -1
- package/dist/commands/pending.js.map +1 -1
- package/dist/commands/portfolio.js +34 -1
- package/dist/commands/portfolio.js.map +1 -1
- package/dist/commands/proof.d.ts +2 -0
- package/dist/commands/proof.js +400 -0
- package/dist/commands/proof.js.map +1 -0
- package/dist/commands/signup.d.ts +14 -0
- package/dist/commands/signup.js +271 -0
- package/dist/commands/signup.js.map +1 -0
- package/dist/commands/transaction.js +139 -21
- package/dist/commands/transaction.js.map +1 -1
- package/dist/commands/webhooks.d.ts +2 -0
- package/dist/commands/webhooks.js +200 -0
- package/dist/commands/webhooks.js.map +1 -0
- package/dist/commands/whoami.d.ts +16 -0
- package/dist/commands/whoami.js +98 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/config.d.ts +56 -0
- package/dist/config.js +51 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +14 -1
- package/dist/errors.js +15 -1
- package/dist/errors.js.map +1 -1
- package/dist/funding-guard.d.ts +40 -0
- package/dist/funding-guard.js +120 -0
- package/dist/funding-guard.js.map +1 -0
- package/dist/help-root.d.ts +2 -0
- package/dist/help-root.js +94 -0
- package/dist/help-root.js.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -1
- package/dist/output.d.ts +23 -0
- package/dist/output.js +46 -0
- package/dist/output.js.map +1 -1
- package/dist/passphrase.d.ts +18 -0
- package/dist/passphrase.js +35 -3
- package/dist/passphrase.js.map +1 -1
- package/dist/payment-uri.d.ts +76 -0
- package/dist/payment-uri.js +135 -0
- package/dist/payment-uri.js.map +1 -0
- package/dist/signer.js +6 -3
- package/dist/signer.js.map +1 -1
- package/dist/solidity-args.d.ts +31 -0
- package/dist/solidity-args.js +111 -0
- package/dist/solidity-args.js.map +1 -0
- package/dist/wait.d.ts +79 -0
- package/dist/wait.js +168 -0
- package/dist/wait.js.map +1 -0
- 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,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
|
@@ -26,6 +26,18 @@ import { registerGovernanceCommands } from './commands/governance.js';
|
|
|
26
26
|
import { registerPortfolioCommands } from './commands/portfolio.js';
|
|
27
27
|
import { registerAdminCommands } from './commands/admin.js';
|
|
28
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';
|
|
29
41
|
const VERSION = readVersion();
|
|
30
42
|
export function buildProgram() {
|
|
31
43
|
const program = new Command();
|
|
@@ -38,20 +50,35 @@ export function buildProgram() {
|
|
|
38
50
|
// Declared so it appears in --help. It is stripped from argv before parsing (see run()), because
|
|
39
51
|
// a global flag that may appear after a subcommand is not something commander models.
|
|
40
52
|
.option('--json', 'Emit one JSON envelope on stdout; human output goes to stderr');
|
|
53
|
+
registerSignupCommands(program);
|
|
54
|
+
registerInitCommands(program);
|
|
55
|
+
registerChainsCommands(program);
|
|
41
56
|
registerAuthCommands(program);
|
|
42
57
|
registerKeysCommands(program);
|
|
58
|
+
registerDoctorCommands(program);
|
|
59
|
+
registerWhoamiCommands(program);
|
|
43
60
|
registerIdentityCommands(program);
|
|
44
61
|
registerTransactionCommands(program);
|
|
62
|
+
registerCallCommands(program);
|
|
63
|
+
registerProofCommands(program);
|
|
45
64
|
registerPendingCommands(program);
|
|
46
65
|
registerGovernanceCommands(program);
|
|
47
66
|
registerPortfolioCommands(program);
|
|
48
67
|
registerBillingCommands(program);
|
|
49
68
|
registerAdminCommands(program);
|
|
69
|
+
registerWebhookCommands(program);
|
|
70
|
+
registerOAuthClientCommands(program);
|
|
71
|
+
registerOrgCommands(program);
|
|
72
|
+
registerErrorsCommands(program);
|
|
50
73
|
// Every command, not just the root. `exitOverride()` is NOT inherited by subcommands, so without
|
|
51
74
|
// this walk a missing required flag on `identity create` called process.exit(1) inside commander:
|
|
52
75
|
// stdout stayed empty, no envelope was ever emitted, and a usage error was indistinguishable from
|
|
53
76
|
// a failed request. Every nested command has to opt in explicitly.
|
|
54
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 });
|
|
55
82
|
return program;
|
|
56
83
|
}
|
|
57
84
|
function applyExitOverride(cmd) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAiB,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,oFAAoF;AACpF,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,OAAiB,CAAC;IAC/F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC;AACD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;
|
|
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
|
@@ -41,6 +41,8 @@ export function printOutput(data, opts) {
|
|
|
41
41
|
console.log(JSON.stringify(data, null, 2));
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
|
+
if (opts?.machineOnly)
|
|
45
|
+
return;
|
|
44
46
|
printTable(data);
|
|
45
47
|
}
|
|
46
48
|
/**
|
|
@@ -59,6 +61,37 @@ export function human(message) {
|
|
|
59
61
|
export function hint(message) {
|
|
60
62
|
console.error(message);
|
|
61
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
|
+
}
|
|
62
95
|
/**
|
|
63
96
|
* Emit the success envelope. No-op outside JSON mode, and safe to call more than once.
|
|
64
97
|
*
|
|
@@ -100,6 +133,9 @@ export function emitFailure(err) {
|
|
|
100
133
|
retryable,
|
|
101
134
|
...(e.status !== undefined ? { status: e.status } : {}),
|
|
102
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 } : {}),
|
|
103
139
|
// Additive: a consumer that ignores unknown keys is unaffected, and one
|
|
104
140
|
// that wants to settle automatically no longer has to parse prose.
|
|
105
141
|
...(payment
|
|
@@ -153,6 +189,16 @@ function resolveExitCode(e) {
|
|
|
153
189
|
// status 0 is how the SDK reports "the request never reached the gateway".
|
|
154
190
|
if (e.code === 'NETWORK_ERROR' || e.status === 0)
|
|
155
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
|
+
}
|
|
156
202
|
return EXIT.FAILED;
|
|
157
203
|
}
|
|
158
204
|
// ── table rendering (human mode only) ───────────────────────────────────────────────────────────
|
package/dist/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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,
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
|
package/dist/passphrase.d.ts
CHANGED
|
@@ -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 };
|
package/dist/passphrase.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
package/dist/passphrase.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passphrase.js","sourceRoot":"","sources":["../src/passphrase.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,OAAO,GAAG,uBAAuB,CAAC;AAExC,MAAM,UAAU,iBAAiB;IAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACtC,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"passphrase.js","sourceRoot":"","sources":["../src/passphrase.ts"],"names":[],"mappings":"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"}
|