@certen.io/cli 0.2.0 → 0.3.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.
package/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # `@certen.io/cli`
2
+
3
+ The `certen` command line for the [CERTEN Gateway](https://gateway.kompendium.co/reference) —
4
+ proof-gated cross-chain execution on Accumulate.
5
+
6
+ **Docs: <https://docs.kompendium.co>** · **Get an API key: <https://gateway.kompendium.co/portal>**
7
+
8
+ ```bash
9
+ npm install -g @certen.io/cli
10
+ ```
11
+
12
+ ## Five minutes, start to finish
13
+
14
+ ```bash
15
+ # 1. A key. Generated here, encrypted here, and it never leaves this machine.
16
+ certen keys generate --name dev
17
+
18
+ # 2. An API key from the portal at https://gateway.kompendium.co/portal
19
+ certen auth login --api-key ck_live_...
20
+
21
+ # 3. An identity that your key controls.
22
+ certen identity create --name my-org --sign-with dev
23
+
24
+ # 4. Watch it provision (~20s). Wait for status=active AND can_sign=true.
25
+ certen identity get <id>
26
+ ```
27
+
28
+ That is the whole onboarding path. Step 3 is the one worth understanding: `--sign-with` derives
29
+ the `public_key` and `public_key_hash` from your local key, so the ADI's key page is bound to a
30
+ key only you hold.
31
+
32
+ ## Your key never leaves this machine
33
+
34
+ `certen keys generate` creates an Ed25519 key, encrypts it with a passphrase (scrypt + AES-256-GCM),
35
+ and writes it to `~/.certen/keys/<name>.json` with `0600` permissions. The CLI sends **signatures**
36
+ to the gateway. It never sends a private key, and there is no code path that could.
37
+
38
+ ```bash
39
+ certen keys generate --name dev # prompts for a passphrase (confirmed)
40
+ certen keys generate --name ci --no-passphrase # unencrypted; file permissions only
41
+ certen keys list # metadata only — never decrypts
42
+ certen keys show dev
43
+ certen keys verify dev # proves the key decrypts and signs correctly
44
+ certen keys sign --name dev --hash <hex> # print a signature, send nothing
45
+ certen keys delete dev --yes
46
+ certen keys path
47
+ ```
48
+
49
+ Set `CERTEN_KEY_PASSPHRASE` to skip the prompt in CI. When it is set and there is no TTY, the CLI
50
+ uses it; when neither is available it fails with an explanation rather than hanging on a prompt
51
+ nobody can see.
52
+
53
+ **`certen keys sign` sends nothing anywhere.** It is the air-gapped path: generate on one machine,
54
+ carry the hash to it, carry the signature back.
55
+
56
+ ## Signing a transaction
57
+
58
+ The one-step form opens the intent, signs the returned hash, and submits the signature:
59
+
60
+ ```bash
61
+ certen tx create --identity <uuid> --to-chain ethereum-sepolia \
62
+ --to 0xRecipient --amount 1000000000000000 --sign-with dev
63
+ ```
64
+
65
+ Or drive the steps yourself — useful when the signer is an HSM, another machine, or your own
66
+ policy engine:
67
+
68
+ ```bash
69
+ certen tx create --identity <uuid> ... # returns signing_data.hash_to_sign
70
+ certen keys sign --name dev --hash <hash> # or your HSM
71
+ certen tx sign <intent-id> --signature <sig> --public-key <pub>
72
+ ```
73
+
74
+ `--signature`/`--public-key` remain first-class. `--sign-with` is a convenience, not a replacement.
75
+
76
+ ## Multi-party approvals
77
+
78
+ ```bash
79
+ certen pending list
80
+ certen pending sign <id> --identity <adi> --vote approve
81
+ certen pending submit <request-id> --sign-with dev --hash <hash>
82
+ ```
83
+
84
+ `--vote` takes `approve`, `reject`, or `abstain` — lowercase strings. Not `accept`, and not a
85
+ number.
86
+
87
+ ## Everything else
88
+
89
+ ```bash
90
+ certen identity get <id> | link-chain <id> --chain <chain>
91
+ certen portfolio # balances across every identity and chain
92
+ certen tx status <id> | list
93
+ certen governance add-delegate | set-threshold
94
+ certen admin api-keys list | create | rotate | revoke
95
+ certen admin audit-log | usage
96
+ ```
97
+
98
+ Run `certen <group> --help` for the flags on any of them.
99
+
100
+ ## Configuration
101
+
102
+ | | |
103
+ |---|---|
104
+ | `CERTEN_API_KEY` | API key. Always wins, so CI never touches the keyring or config file. |
105
+ | `CERTEN_API_URL` | Gateway base URL. Defaults to `https://gateway.kompendium.co`. |
106
+ | `CERTEN_KEY_PASSPHRASE` | Passphrase for local signing keys. |
107
+
108
+ `certen auth login` stores the API key in your OS keyring by default, or in
109
+ `~/.certen/config.json` at `0600` with `--no-keyring`.
110
+
111
+ ## Things that will bite you
112
+
113
+ **Identity creation is asynchronous.** `identity create` returns `202` and provisioning continues.
114
+ Poll until the status is terminal, and check `can_sign` — it derives from the on-chain key page, so
115
+ it can read `true` while the status is still `creating`.
116
+
117
+ **A proof cycle takes 60–110 seconds.** Real validator work, not a tunable delay. Do not wrap it in
118
+ a 30-second timeout.
119
+
120
+ **Sign the bytes, not the text.** If you are producing signatures outside this CLI: sign the raw
121
+ bytes of the hash, do not hash it again, and do not sign the ASCII of the hex string. All three
122
+ mistakes produce a well-formed 128-hex signature the gateway rejects. `certen keys sign` handles
123
+ this for you.
124
+
125
+ ## Documentation
126
+
127
+ **<https://docs.kompendium.co>** — getting started, authentication, errors, idempotency, and
128
+ task-shaped guides: onboarding an identity, external signing, proof-gating a contract call, M-of-N
129
+ panels, and verifying a proof.
130
+
131
+ The [live API reference](https://gateway.kompendium.co/reference) is generated from the running
132
+ gateway and is authoritative — when a guide and the spec disagree, the spec is right.
133
+
134
+ ## License
135
+
136
+ MIT
@@ -1,6 +1,7 @@
1
1
  import { CertenClient } from '@certen.io/sdk';
2
2
  import { getApiKey, getApiUrl } from '../config.js';
3
3
  import { printOutput } from '../output.js';
4
+ import { resolveSigner } from '../signer.js';
4
5
  async function getClient() {
5
6
  return new CertenClient({ apiKey: await getApiKey(), baseUrl: getApiUrl() });
6
7
  }
@@ -10,16 +11,35 @@ export function registerIdentityCommands(program) {
10
11
  .command('create')
11
12
  .description('Create a new identity')
12
13
  .requiredOption('--name <name>', 'Identity name')
13
- .requiredOption('--public-key-hash <hash>', 'Public key hash')
14
+ .option('--sign-with <key>', 'Local key to own this identity (see `certen keys generate`)')
15
+ .option('--public-key-hash <hash>', 'Public key hash (omit when using --sign-with)')
14
16
  .option('--public-key <key>', 'Public key (hex)')
15
17
  .option('--chains <chains>', 'Comma-separated chain IDs')
16
18
  .option('--credits <credits>', 'Initial credits', parseInt)
17
19
  .action(async (opts) => {
20
+ // --public-key-hash was required, which is why the CLI could not create an identity on its
21
+ // own: the hash is sha256 of the RAW 32-byte public key, and working that out was left to
22
+ // the user. --sign-with derives both fields from a stored key so the common case needs
23
+ // neither. The explicit flags still work for a key this machine does not hold.
24
+ let publicKeyHash = opts.publicKeyHash;
25
+ let publicKey = opts.publicKey;
26
+ if (opts.signWith) {
27
+ if (publicKeyHash || publicKey) {
28
+ throw new Error('Pass either --sign-with or --public-key-hash/--public-key, not both.');
29
+ }
30
+ const signer = await resolveSigner(opts.signWith);
31
+ publicKeyHash = signer.publicKeyHash;
32
+ publicKey = signer.publicKey;
33
+ }
34
+ 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');
37
+ }
18
38
  const client = await getClient();
19
39
  const result = await client.identity.create({
20
40
  name: opts.name,
21
- publicKeyHash: opts.publicKeyHash,
22
- publicKey: opts.publicKey,
41
+ publicKeyHash,
42
+ publicKey,
23
43
  chains: opts.chains ? opts.chains.split(',') : undefined,
24
44
  credits: opts.credits,
25
45
  });
@@ -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;AAE3C,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,cAAc,CAAC,0BAA0B,EAAE,iBAAiB,CAAC;SAC7D,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,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,EAAE,IAAI,CAAC,aAAa;YACjC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,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,9 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Local signing keys.
4
+ *
5
+ * Certen never holds these. The gateway is given a public key and a signature; the private key
6
+ * stays in ~/.certen/keys at 0600. That is the same posture the SDK documents for `sign`, made
7
+ * available to someone who is driving the CLI instead of writing code.
8
+ */
9
+ export declare function registerKeysCommands(program: Command): void;
@@ -0,0 +1,109 @@
1
+ import { printOutput } from '../output.js';
2
+ import { resolvePassphrase, resolveNewPassphrase, PASSPHRASE_ENV_VAR } from '../passphrase.js';
3
+ import { generateKey, listKeys, getKeyInfo, deleteKey, signHash, selfTest, keyPath, KEYS_DIR, } from '../keystore.js';
4
+ /**
5
+ * Local signing keys.
6
+ *
7
+ * Certen never holds these. The gateway is given a public key and a signature; the private key
8
+ * stays in ~/.certen/keys at 0600. That is the same posture the SDK documents for `sign`, made
9
+ * available to someone who is driving the CLI instead of writing code.
10
+ */
11
+ export function registerKeysCommands(program) {
12
+ const keys = program.command('keys').description('Local Ed25519 signing keys (never leave this machine)');
13
+ keys
14
+ .command('generate')
15
+ .description('Generate an Ed25519 signing key and store it encrypted')
16
+ .requiredOption('--name <name>', 'Local name for this key')
17
+ .option('--no-passphrase', 'Store the key unencrypted (0600 file permissions only)')
18
+ .action(async (opts) => {
19
+ const passphrase = await resolveNewPassphrase(opts.passphrase === false);
20
+ const info = generateKey(opts.name, passphrase);
21
+ if (passphrase === null) {
22
+ console.error(`Warning: key "${info.name}" is stored UNENCRYPTED at ${keyPath(info.name)}. `
23
+ + 'Anyone who can read that file can sign as you.');
24
+ }
25
+ printOutput({
26
+ name: info.name,
27
+ public_key: info.publicKey,
28
+ public_key_hash: info.publicKeyHash,
29
+ encrypted: info.encrypted,
30
+ path: keyPath(info.name),
31
+ created_at: info.createdAt,
32
+ });
33
+ // The hash is what `identity create` needs, and it is not obvious that it is sha256 of the
34
+ // raw public key rather than the key itself. Show the next command instead of explaining.
35
+ console.error('');
36
+ console.error(`Next: certen identity create --name <adi-name> --sign-with ${info.name}`);
37
+ });
38
+ keys
39
+ .command('list')
40
+ .description('List local signing keys (metadata only — never decrypts)')
41
+ .action(() => {
42
+ const all = listKeys();
43
+ if (all.length === 0) {
44
+ console.log(`(no keys in ${KEYS_DIR})`);
45
+ return;
46
+ }
47
+ printOutput(all.map((k) => ({
48
+ name: k.name,
49
+ public_key_hash: k.publicKeyHash,
50
+ encrypted: k.encrypted,
51
+ created_at: k.createdAt,
52
+ })));
53
+ });
54
+ keys
55
+ .command('show <name>')
56
+ .description('Show one key\'s public material')
57
+ .action((name) => {
58
+ const k = getKeyInfo(name);
59
+ printOutput({
60
+ name: k.name,
61
+ public_key: k.publicKey,
62
+ public_key_hash: k.publicKeyHash,
63
+ encrypted: k.encrypted,
64
+ path: keyPath(k.name),
65
+ created_at: k.createdAt,
66
+ });
67
+ });
68
+ keys
69
+ .command('sign')
70
+ .description('Sign a hash with a local key — prints the signature, sends nothing')
71
+ .requiredOption('--name <name>', 'Key to sign with')
72
+ .requiredOption('--hash <hex>', 'Hash to sign (hex, as returned by the gateway)')
73
+ .action(async (opts) => {
74
+ const info = getKeyInfo(opts.name);
75
+ const passphrase = await resolvePassphrase(info.encrypted, opts.name);
76
+ const signature = signHash(opts.name, passphrase, opts.hash);
77
+ printOutput({ signature, public_key: info.publicKey });
78
+ });
79
+ keys
80
+ .command('verify <name>')
81
+ .description('Check the key decrypts and produces a signature its own public key accepts')
82
+ .action(async (name) => {
83
+ const info = getKeyInfo(name);
84
+ const passphrase = await resolvePassphrase(info.encrypted, name);
85
+ const ok = selfTest(name, passphrase);
86
+ printOutput({ name, ok, public_key_hash: info.publicKeyHash });
87
+ if (!ok)
88
+ process.exitCode = 1;
89
+ });
90
+ keys
91
+ .command('delete <name>')
92
+ .description('Delete a local key file (irreversible)')
93
+ .requiredOption('--yes', 'Confirm deletion')
94
+ .action((name) => {
95
+ // No prompt: the required --yes is the confirmation. A key that controls a live key page
96
+ // should not be deletable by an accidental Enter on a y/N prompt.
97
+ const path = keyPath(name);
98
+ deleteKey(name);
99
+ console.log(`Deleted ${path}`);
100
+ console.error('If this key was on a key page, it is still on that page — remove it there too.');
101
+ });
102
+ keys
103
+ .command('path')
104
+ .description('Print where keys are stored')
105
+ .action(() => {
106
+ printOutput({ keys_dir: KEYS_DIR, passphrase_env: PASSPHRASE_ENV_VAR });
107
+ });
108
+ }
109
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EACL,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,GACpF,MAAM,gBAAgB,CAAC;AAExB;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,uDAAuD,CAAC,CAAC;IAE1G,IAAI;SACD,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,wDAAwD,CAAC;SACrE,cAAc,CAAC,eAAe,EAAE,yBAAyB,CAAC;SAC1D,MAAM,CAAC,iBAAiB,EAAE,wDAAwD,CAAC;SACnF,MAAM,CAAC,KAAK,EAAE,IAA2C,EAAE,EAAE;QAC5D,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAEhD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CACX,iBAAiB,IAAI,CAAC,IAAI,8BAA8B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;kBAC5E,gDAAgD,CACnD,CAAC;QACJ,CAAC;QAED,WAAW,CAAC;YACV,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,eAAe,EAAE,IAAI,CAAC,aAAa;YACnC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YACxB,UAAU,EAAE,IAAI,CAAC,SAAS;SAC3B,CAAC,CAAC;QAEH,2FAA2F;QAC3F,0FAA0F;QAC1F,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,8DAA8D,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,0DAA0D,CAAC;SACvE,MAAM,CAAC,GAAG,EAAE;QACX,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,GAAG,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QACD,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,eAAe,EAAE,CAAC,CAAC,aAAa;YAChC,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,UAAU,EAAE,CAAC,CAAC,SAAS;SACxB,CAAC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,iCAAiC,CAAC;SAC9C,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC3B,WAAW,CAAC;YACV,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,UAAU,EAAE,CAAC,CAAC,SAAS;YACvB,eAAe,EAAE,CAAC,CAAC,aAAa;YAChC,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;YACrB,UAAU,EAAE,CAAC,CAAC,SAAS;SACxB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,oEAAoE,CAAC;SACjF,cAAc,CAAC,eAAe,EAAE,kBAAkB,CAAC;SACnD,cAAc,CAAC,cAAc,EAAE,gDAAgD,CAAC;SAChF,MAAM,CAAC,KAAK,EAAE,IAAoC,EAAE,EAAE;QACrD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACtE,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7D,WAAW,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,4EAA4E,CAAC;SACzF,MAAM,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,UAAU,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACjE,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACtC,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QAC/D,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,wCAAwC,CAAC;SACrD,cAAc,CAAC,OAAO,EAAE,kBAAkB,CAAC;SAC3C,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;QACvB,yFAAyF;QACzF,kEAAkE;QAClE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,SAAS,CAAC,IAAI,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QAC/B,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEL,IAAI;SACD,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,GAAG,EAAE;QACX,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { CertenClient } from '@certen.io/sdk';
2
2
  import { getApiKey, getApiUrl } from '../config.js';
3
3
  import { printOutput } from '../output.js';
4
+ import { resolveSignature } from '../signer.js';
4
5
  async function getClient() {
5
6
  return new CertenClient({ apiKey: await getApiKey(), baseUrl: getApiUrl() });
6
7
  }
@@ -30,7 +31,9 @@ export function registerPendingCommands(program) {
30
31
  .description('Create a sign request for a pending action')
31
32
  .option('--identity <id>', 'Identity to sign as')
32
33
  .option('--signer-url <url>', 'Signer URL')
33
- .option('--vote <vote>', 'Vote (accept/reject)')
34
+ // Was documented as "accept/reject". The API takes a lowercase `approve` | `reject` |
35
+ // `abstain`; `accept` is rejected. The help text was sending people to a value that fails.
36
+ .option('--vote <vote>', 'Vote: approve | reject | abstain')
34
37
  .action(async (id, opts) => {
35
38
  const client = await getClient();
36
39
  const result = await client.sign.create({
@@ -45,14 +48,19 @@ export function registerPendingCommands(program) {
45
48
  pending
46
49
  .command('submit <id>')
47
50
  .description('Submit a signature for a pending sign request')
48
- .requiredOption('--signature <sig>', 'Signature (hex)')
49
- .requiredOption('--public-key <key>', 'Public key (hex)')
51
+ .option('--sign-with <key>', 'Local key to sign with (needs --hash)')
52
+ .option('--hash <hex>', 'Hash to sign, from the sign request\'s signing data')
53
+ .option('--signature <sig>', 'Signature (hex) — for an HSM or air-gapped signer')
54
+ .option('--public-key <key>', 'Public key (hex), required with --signature')
50
55
  .action(async (id, opts) => {
51
- const client = await getClient();
52
- const result = await client.sign.submitSignature(id, {
56
+ const { signature, publicKey } = await resolveSignature({
57
+ signWith: opts.signWith,
53
58
  signature: opts.signature,
54
59
  publicKey: opts.publicKey,
60
+ hash: opts.hash,
55
61
  });
62
+ const client = await getClient();
63
+ const result = await client.sign.submitSignature(id, { signature, publicKey });
56
64
  printOutput(result);
57
65
  });
58
66
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pending.js","sourceRoot":"","sources":["../../src/commands/pending.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;AAE3C,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,uBAAuB,CAAC,OAAgB;IACtD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAEhF,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sBAAsB,CAAC;SACnC,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;SAC/C,MAAM,CAAC,mBAAmB,EAAE,kBAAkB,CAAC;SAC/C,MAAM,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;SAChD,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,CAAC;SAC9C,MAAM,CAAC,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC;SAC1C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;YACvC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;SAChD,MAAM,CAAC,oBAAoB,EAAE,YAAY,CAAC;SAC1C,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC;SAC/C,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,IAAI,EAAE,EAAE;QACjC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;YACtC,IAAI,EAAE,gBAAgB;YACtB,QAAQ,EAAE,EAAE;YACZ,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAC,CAAC;QACH,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,+CAA+C,CAAC;SAC5D,cAAc,CAAC,mBAAmB,EAAE,iBAAiB,CAAC;SACtD,cAAc,CAAC,oBAAoB,EAAE,kBAAkB,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,IAAI,EAAE,EAAE;QACjC,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE;YACnD,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QACH,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"pending.js","sourceRoot":"","sources":["../../src/commands/pending.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,27 @@ import { readFileSync } from 'node:fs';
2
2
  import { CertenClient } from '@certen.io/sdk';
3
3
  import { getApiKey, getApiUrl } from '../config.js';
4
4
  import { printOutput } from '../output.js';
5
+ import { resolveSigner } from '../signer.js';
5
6
  async function getClient() {
6
7
  return new CertenClient({ apiKey: await getApiKey(), baseUrl: getApiUrl() });
7
8
  }
9
+ /**
10
+ * Pull the hash to sign out of an intent response.
11
+ *
12
+ * The gateway returns snake_case on the wire (`signing_data.hash_to_sign`), which is what the
13
+ * live OpenAPI spec documents and what `execute.ts` reads. The SDK's `TransactionResponse` type
14
+ * declares camelCase `signingData.dataToSign` and `return data` performs no transformation, so
15
+ * the declared type does not describe the value. Both spellings are accepted here rather than
16
+ * betting on which one a given gateway build emits.
17
+ */
18
+ function hashToSign(result) {
19
+ const r = result;
20
+ return r.signing_data?.hash_to_sign ?? r.signingData?.hashToSign ?? r.signingData?.dataToSign;
21
+ }
22
+ function intentIdOf(result) {
23
+ const r = result;
24
+ return r.intent_id ?? r.intentId;
25
+ }
8
26
  export function registerTransactionCommands(program) {
9
27
  const tx = program.command('tx').description('Transaction lifecycle');
10
28
  tx
@@ -25,8 +43,13 @@ export function registerTransactionCommands(program) {
25
43
  .option('--signer-key-page <url>', 'Which key page signs, e.g. acc://org.acme/book/2')
26
44
  .option('--signer-public-key <hex>', 'Which seat on the page signs (64 hex)')
27
45
  .option('--idempotency-key <key>', 'Idempotency key (one is generated if omitted)')
46
+ .option('--sign-with <key>', 'Local key: sign the returned hash and submit it in one step')
28
47
  .action(async (opts) => {
29
48
  const client = await getClient();
49
+ // Resolve (and unlock) the signer BEFORE opening the intent. Prompting for a passphrase
50
+ // after the intent exists would leave an unsigned intent behind every time someone
51
+ // mistypes it or hits Ctrl-C at the prompt.
52
+ const signer = opts.signWith ? await resolveSigner(opts.signWith) : null;
30
53
  let intent;
31
54
  if (opts.intent) {
32
55
  const raw = opts.intent.startsWith('@')
@@ -52,22 +75,61 @@ export function registerTransactionCommands(program) {
52
75
  intent,
53
76
  contractAddresses: opts.contractAddress,
54
77
  signerKeyPage: opts.signerKeyPage,
55
- signerPublicKey: opts.signerPublicKey,
78
+ signerPublicKey: opts.signerPublicKey ?? signer?.publicKey,
56
79
  idempotencyKey: opts.idempotencyKey,
57
80
  });
58
- printOutput(result);
81
+ if (!signer) {
82
+ printOutput(result);
83
+ return;
84
+ }
85
+ const hash = hashToSign(result);
86
+ const intentId = intentIdOf(result);
87
+ if (!hash || !intentId) {
88
+ // Provider mode (the gateway holds a key) returns no signing data. Printing the intent and
89
+ // stopping is honest; pretending we signed something we never saw is not.
90
+ printOutput(result);
91
+ throw new Error('Intent opened but returned no hash to sign — this gateway is in provider mode for that '
92
+ + 'identity, so --sign-with does not apply. The intent above was created.');
93
+ }
94
+ const signed = await client.transaction.submitSignature(intentId, {
95
+ signature: signer.sign(hash),
96
+ publicKey: signer.publicKey,
97
+ });
98
+ printOutput(signed);
59
99
  });
60
100
  tx
61
101
  .command('sign <id>')
62
102
  .description('Submit a signature for a transaction')
63
- .requiredOption('--signature <sig>', 'Signature (hex)')
64
- .requiredOption('--public-key <key>', 'Public key (hex)')
103
+ .option('--sign-with <key>', 'Local key to sign with (needs --hash)')
104
+ .option('--hash <hex>', 'Hash to sign, from the intent\'s signing_data.hash_to_sign')
105
+ .option('--signature <sig>', 'Signature (hex) — for an HSM or air-gapped signer')
106
+ .option('--public-key <key>', 'Public key (hex), required with --signature')
65
107
  .action(async (id, opts) => {
108
+ // --signature/--public-key were required options, so there was no way to sign from the CLI
109
+ // itself. They are now optional and --sign-with is the alternative; supplying neither is
110
+ // still an error, just a more useful one.
111
+ let signature;
112
+ let publicKey;
113
+ if (opts.signWith) {
114
+ if (opts.signature)
115
+ throw new Error('Pass either --sign-with or --signature, not both.');
116
+ if (!opts.hash) {
117
+ throw new Error('--sign-with needs --hash <hex> (the signing_data.hash_to_sign from `tx create`). '
118
+ + 'Or use `tx create --sign-with` to do both in one step.');
119
+ }
120
+ const signer = await resolveSigner(opts.signWith);
121
+ signature = signer.sign(opts.hash);
122
+ publicKey = signer.publicKey;
123
+ }
124
+ else {
125
+ if (!opts.signature || !opts.publicKey) {
126
+ throw new Error('Provide --sign-with <key> --hash <hex>, or both --signature and --public-key.');
127
+ }
128
+ signature = opts.signature;
129
+ publicKey = opts.publicKey;
130
+ }
66
131
  const client = await getClient();
67
- const result = await client.transaction.submitSignature(id, {
68
- signature: opts.signature,
69
- publicKey: opts.publicKey,
70
- });
132
+ const result = await client.transaction.submitSignature(id, { signature, publicKey });
71
133
  printOutput(result);
72
134
  });
73
135
  tx
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/commands/transaction.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/commands/transaction.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -36,11 +36,19 @@ export function writeConfig(config) {
36
36
  * If the config file exists with world/group read permissions, warn the
37
37
  * user and refuse to read the api_key. Forces explicit re-login under
38
38
  * 0600 perms, or env-var-only operation.
39
+ *
40
+ * POSIX only. This used to claim it was cross-platform, but Windows has no POSIX mode bits:
41
+ * `chmod` is a no-op there and `statSync().mode` reports a synthesized 0666 (0444 when the
42
+ * read-only attribute is set), so `mode & 0o077` is never 0 and this returned false for every
43
+ * Windows user. The effect was that `certen auth login --no-keyring` wrote a key the CLI then
44
+ * refused to read, with an error telling them to re-run the login that had just succeeded.
45
+ * Access control on Windows is the file's ACL, inherited from the user profile directory.
39
46
  */
40
47
  function configFileIsSecure() {
48
+ if (process.platform === 'win32')
49
+ return true;
41
50
  try {
42
51
  const stat = statSync(CONFIG_FILE);
43
- // Cross-platform: check that group/world have no read bits.
44
52
  const mode = stat.mode & 0o077;
45
53
  return mode === 0;
46
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,7 +1,21 @@
1
1
  #!/usr/bin/env node
2
+ import { readFileSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
2
5
  import { Command } from 'commander';
3
6
  import { CertenError } from '@certen.io/sdk';
7
+ /** Read the version from package.json — dist/ sits one level below the manifest. */
8
+ function readVersion() {
9
+ try {
10
+ const here = dirname(fileURLToPath(import.meta.url));
11
+ return JSON.parse(readFileSync(join(here, '..', 'package.json'), 'utf-8')).version;
12
+ }
13
+ catch {
14
+ return '0.0.0-unknown';
15
+ }
16
+ }
4
17
  import { registerAuthCommands } from './commands/auth.js';
18
+ import { registerKeysCommands } from './commands/keys.js';
5
19
  import { registerIdentityCommands } from './commands/identity.js';
6
20
  import { registerTransactionCommands } from './commands/transaction.js';
7
21
  import { registerPendingCommands } from './commands/pending.js';
@@ -12,8 +26,11 @@ const program = new Command();
12
26
  program
13
27
  .name('certen')
14
28
  .description('CERTEN Gateway CLI')
15
- .version('0.1.0');
29
+ // Was hardcoded to 0.1.0 while package.json said 0.2.0, so `certen --version` reported a
30
+ // release that does not exist. Read it from the manifest so the two cannot drift again.
31
+ .version(readVersion());
16
32
  registerAuthCommands(program);
33
+ registerKeysCommands(program);
17
34
  registerIdentityCommands(program);
18
35
  registerTransactionCommands(program);
19
36
  registerPendingCommands(program);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,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;AAE5D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,oBAAoB,CAAC;KACjC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAClC,2BAA2B,CAAC,OAAO,CAAC,CAAC;AACrC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,0BAA0B,CAAC,OAAO,CAAC,CAAC;AACpC,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAE/B,uBAAuB;AACvB,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACpC,OAAO,CAAC,YAAY,EAAE,CAAC;AAEvB,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;YAC/B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,IAAI,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,gDAAgD;YAChD,IAAK,GAAW,CAAC,QAAQ,KAAK,CAAC;gBAAE,OAAO;YACxC,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}