@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 +136 -0
- package/dist/commands/identity.js +23 -3
- package/dist/commands/identity.js.map +1 -1
- package/dist/commands/keys.d.ts +9 -0
- package/dist/commands/keys.js +109 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/pending.js +13 -5
- package/dist/commands/pending.js.map +1 -1
- package/dist/commands/transaction.js +70 -8
- package/dist/commands/transaction.js.map +1 -1
- package/dist/config.js +9 -1
- package/dist/config.js.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore.d.ts +79 -0
- package/dist/keystore.js +274 -0
- package/dist/keystore.js.map +1 -0
- package/dist/passphrase.d.ts +25 -0
- package/dist/passphrase.js +111 -0
- package/dist/passphrase.js.map +1 -0
- package/dist/signer.d.ts +31 -0
- package/dist/signer.js +36 -0
- package/dist/signer.js.map +1 -0
- package/package.json +56 -56
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
|
-
.
|
|
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
|
|
22
|
-
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;
|
|
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":"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"}
|
package/dist/commands/pending.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
.
|
|
49
|
-
.
|
|
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
|
|
52
|
-
|
|
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;
|
|
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
|
-
|
|
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
|
-
.
|
|
64
|
-
.
|
|
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":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,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;
|
|
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
|
}
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAC7F,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAgBpD,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAiB;IAC3C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChG,IAAI,CAAC;QACH,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,mDAAmD;IACrD,CAAC;AACH,CAAC;AAED
|
|
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
|
-
|
|
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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|