@credda/cli 0.1.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/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # @credda/cli
2
+
3
+ The official Credda CLI — portable trust from the terminal. A thin client
4
+ over [`@credda/js`](../sdk)'s headless export; **no scoring logic lives
5
+ here** (the deterministic score is computed only by the API's
6
+ `score.service`).
7
+
8
+ ## Install / run
9
+
10
+ Not yet published to npm (same status as `@credda/mcp-server`). Run from a
11
+ checkout:
12
+
13
+ ```sh
14
+ pnpm --filter @credda/js run build # build the SDK first (dist/ is gitignored)
15
+ pnpm --filter @credda/cli run build
16
+ node packages/cli/dist/index.js help
17
+ ```
18
+
19
+ ## Commands
20
+
21
+ Public — no API key:
22
+
23
+ ```sh
24
+ credda lookup <token> # trust check for a share token (GET /verify/:token)
25
+ credda export <token> # full self-verifying trust export bundle
26
+ credda verify <file|-> # OFFLINE-verify a credential someone handed you:
27
+ # a W3C VC-JWT, a compact Trust Credential, or a
28
+ # saved trust-export bundle — auto-detected.
29
+ # '-' reads stdin. Exit 0 valid / 2 invalid.
30
+ credda registry # federated trust registry (/.well-known)
31
+ credda did # issuer DID document
32
+ ```
33
+
34
+ Platform — set `CREDDA_API_KEY` (a `crd_live_…` platform key):
35
+
36
+ ```sh
37
+ credda score <userId> # current score
38
+ credda explain <userId> # factor-level explanation
39
+ credda components <userId> # six named 0-100 components
40
+ credda risk <userId> # advisory risk signals
41
+ credda usage [days] # your platform's metered usage
42
+ credda mint <userId> # mint a share token
43
+ credda revoke <userId> # revoke a share token
44
+ ```
45
+
46
+ Webhooks — set `CREDDA_API_KEY`:
47
+
48
+ ```sh
49
+ credda webhooks list
50
+ credda webhooks create https://hooks.you/credda score.updated score.band_changed
51
+ # signing secret shown ONCE
52
+ credda webhooks delete <id>
53
+ credda webhooks test <id> # synthetic signed delivery
54
+ credda webhooks deliveries <id> # recent attempts, incl. retries
55
+ ```
56
+
57
+ Local development:
58
+
59
+ ```sh
60
+ CREDDA_WEBHOOK_SECRET=whsec_... credda listen 4141
61
+ ```
62
+
63
+ `credda listen` runs a local receiver that HMAC-verifies each delivery (the
64
+ same check your production handler must do) and pretty-prints the payload.
65
+ Credda delivers to public HTTPS only, so expose the port with your own tunnel
66
+ (e.g. `cloudflared tunnel --url http://localhost:4141`) and register the
67
+ tunnel URL as the webhook — the Stripe-CLI-style local loop without Credda
68
+ running a tunneling service.
69
+
70
+ Environment: `CREDDA_API_URL` overrides the API base (default
71
+ `https://api.credda.io`); `CREDDA_WEBHOOK_SECRET` enables signature
72
+ verification in `credda listen`.
73
+
74
+ ## Design
75
+
76
+ - `src/cli.ts` is the pure command router — no `process`, `fs`, or env access,
77
+ so the whole surface is unit-tested with a mocked `CreddaClient` (same
78
+ pattern as `packages/mcp`'s `tools.ts`).
79
+ - `src/index.ts` only wires the real environment (env vars, stdin/file
80
+ reading, exit codes).
81
+ - `verify` uses the SDK's offline verifiers (WebCrypto Ed25519 + StatusList
82
+ revocation) — the point is that a received credential can be checked
83
+ without trusting the wire it arrived on.
84
+ - Every command is read-only against the score. `mint`/`revoke` manage a
85
+ share token — a capability, not a score write.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Command router — pure of process/env/fs so it's testable with a mocked
3
+ * context (same pattern as packages/mcp's tools.ts).
4
+ *
5
+ * Every command is READ-ONLY against Credda's deterministic score. Nothing
6
+ * here writes an Event, adjusts a score, or makes a trust decision — the CLI
7
+ * looks up and offline-verifies EXISTING, already-computed trust facts.
8
+ * `mint`/`revoke` manage a share token (a capability, not a score write).
9
+ */
10
+ import type { CreddaClient, VerifiedCredential, VerifiedVc, VerifiedTrustExport, TrustExport } from '@credda/js/headless';
11
+ export interface CliContext {
12
+ client: CreddaClient;
13
+ /** Platform API key from CREDDA_API_KEY — only needed for keyed commands. */
14
+ apiKey?: string;
15
+ out: (line: string) => void;
16
+ err: (line: string) => void;
17
+ readInput: (pathOrDash: string) => Promise<string>;
18
+ /** Injected so tests can mock offline verification. */
19
+ verifiers: {
20
+ trustCredential: (credential: string) => Promise<VerifiedCredential>;
21
+ verifiableCredential: (vcJwt: string) => Promise<VerifiedVc>;
22
+ trustExport: (bundle: TrustExport) => Promise<VerifiedTrustExport>;
23
+ };
24
+ /** whsec_… signing secret from CREDDA_WEBHOOK_SECRET — used by `listen`. */
25
+ webhookSecret?: string;
26
+ /**
27
+ * Starts the local webhook receiver (`credda listen`). Injected so the pure
28
+ * router stays free of node:http; resolves when the server has stopped.
29
+ */
30
+ startListener?: (opts: {
31
+ port: number;
32
+ secret?: string;
33
+ }) => Promise<void>;
34
+ }
35
+ export declare const VERSION = "0.0.1";
36
+ export declare const HELP = "credda \u2014 portable trust from the terminal\n\nPublic (no API key):\n credda lookup <token> Trust check for a share token\n credda export <token> Full self-verifying trust export bundle\n credda verify <file|-> Offline-verify a credential: a W3C VC-JWT,\n a compact Trust Credential, or a saved trust\n export bundle (auto-detected). '-' = stdin.\n credda registry Federated trust registry\n credda did Issuer DID document\n\nPlatform (needs CREDDA_API_KEY):\n credda score <userId> Current score\n credda explain <userId> Factor-level score explanation\n credda components <userId> Six named 0-100 score components\n credda risk <userId> Advisory risk signals\n credda usage [days] Your platform's metered API usage\n credda mint <userId> Mint a share token for a user\n credda revoke <userId> Revoke a user's share token\n\nWebhooks (needs CREDDA_API_KEY):\n credda webhooks list Your webhook subscriptions\n credda webhooks create <url> <event..> Subscribe (secret shown ONCE)\n credda webhooks delete <id> Remove a webhook\n credda webhooks test <id> Send a synthetic signed delivery\n credda webhooks deliveries <id> Recent delivery attempts (incl. retries)\n\nLocal development:\n credda listen [port] Local webhook receiver: verifies each delivery's\n HMAC signature (CREDDA_WEBHOOK_SECRET) and\n pretty-prints the payload. Default port 4141.\n Credda delivers to public HTTPS only \u2014 expose\n this port with your own tunnel (e.g. cloudflared).\n\nEnvironment:\n CREDDA_API_URL API base (default https://api.credda.io)\n CREDDA_API_KEY Platform API key for keyed commands\n CREDDA_WEBHOOK_SECRET whsec_\u2026 signing secret for \"credda listen\"\n\nExit codes: 0 ok/valid \u00B7 1 error \u00B7 2 credential failed verification";
37
+ /** Classify verify input: trust-export bundle JSON, VC-JWT, or compact credential. */
38
+ export declare function classifyCredentialInput(raw: string): {
39
+ kind: 'export';
40
+ bundle: TrustExport;
41
+ } | {
42
+ kind: 'vc-jwt';
43
+ jwt: string;
44
+ } | {
45
+ kind: 'compact';
46
+ credential: string;
47
+ };
48
+ /** Run one CLI invocation. Returns the process exit code. */
49
+ export declare function runCli(argv: string[], ctx: CliContext): Promise<number>;
50
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACV,mBAAmB,EACnB,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,uDAAuD;IACvD,SAAS,EAAE;QACT,eAAe,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;QACrE,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;QAC7D,WAAW,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;KACpE,CAAC;IACF,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E;AAED,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,eAAO,MAAM,IAAI,4oEAuCmD,CAAC;AAmBrE,sFAAsF;AACtF,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,GACV;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAcrH;AAED,6DAA6D;AAC7D,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA6I7E"}
package/dist/cli.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Command router — pure of process/env/fs so it's testable with a mocked
3
+ * context (same pattern as packages/mcp's tools.ts).
4
+ *
5
+ * Every command is READ-ONLY against Credda's deterministic score. Nothing
6
+ * here writes an Event, adjusts a score, or makes a trust decision — the CLI
7
+ * looks up and offline-verifies EXISTING, already-computed trust facts.
8
+ * `mint`/`revoke` manage a share token (a capability, not a score write).
9
+ */
10
+ export const VERSION = '0.0.1';
11
+ export const HELP = `credda — portable trust from the terminal
12
+
13
+ Public (no API key):
14
+ credda lookup <token> Trust check for a share token
15
+ credda export <token> Full self-verifying trust export bundle
16
+ credda verify <file|-> Offline-verify a credential: a W3C VC-JWT,
17
+ a compact Trust Credential, or a saved trust
18
+ export bundle (auto-detected). '-' = stdin.
19
+ credda registry Federated trust registry
20
+ credda did Issuer DID document
21
+
22
+ Platform (needs CREDDA_API_KEY):
23
+ credda score <userId> Current score
24
+ credda explain <userId> Factor-level score explanation
25
+ credda components <userId> Six named 0-100 score components
26
+ credda risk <userId> Advisory risk signals
27
+ credda usage [days] Your platform's metered API usage
28
+ credda mint <userId> Mint a share token for a user
29
+ credda revoke <userId> Revoke a user's share token
30
+
31
+ Webhooks (needs CREDDA_API_KEY):
32
+ credda webhooks list Your webhook subscriptions
33
+ credda webhooks create <url> <event..> Subscribe (secret shown ONCE)
34
+ credda webhooks delete <id> Remove a webhook
35
+ credda webhooks test <id> Send a synthetic signed delivery
36
+ credda webhooks deliveries <id> Recent delivery attempts (incl. retries)
37
+
38
+ Local development:
39
+ credda listen [port] Local webhook receiver: verifies each delivery's
40
+ HMAC signature (CREDDA_WEBHOOK_SECRET) and
41
+ pretty-prints the payload. Default port 4141.
42
+ Credda delivers to public HTTPS only — expose
43
+ this port with your own tunnel (e.g. cloudflared).
44
+
45
+ Environment:
46
+ CREDDA_API_URL API base (default https://api.credda.io)
47
+ CREDDA_API_KEY Platform API key for keyed commands
48
+ CREDDA_WEBHOOK_SECRET whsec_… signing secret for "credda listen"
49
+
50
+ Exit codes: 0 ok/valid · 1 error · 2 credential failed verification`;
51
+ function requireKey(ctx) {
52
+ if (!ctx.apiKey) {
53
+ throw new Error('this command needs CREDDA_API_KEY set (a platform API key)');
54
+ }
55
+ return ctx.apiKey;
56
+ }
57
+ function requireArg(args, name) {
58
+ const v = args[0];
59
+ if (!v)
60
+ throw new Error(`missing required argument <${name}> — see "credda help"`);
61
+ return v;
62
+ }
63
+ function show(ctx, value) {
64
+ ctx.out(JSON.stringify(value, null, 2));
65
+ }
66
+ /** Classify verify input: trust-export bundle JSON, VC-JWT, or compact credential. */
67
+ export function classifyCredentialInput(raw) {
68
+ const trimmed = raw.trim();
69
+ try {
70
+ const parsed = JSON.parse(trimmed);
71
+ if (parsed && typeof parsed === 'object' && parsed.format === 'credda-trust-export/1') {
72
+ return { kind: 'export', bundle: parsed };
73
+ }
74
+ }
75
+ catch {
76
+ // not JSON — fall through to string formats
77
+ }
78
+ if (/^eyJ[\w-]*\.[\w-]+\.[\w-]+$/.test(trimmed)) {
79
+ return { kind: 'vc-jwt', jwt: trimmed };
80
+ }
81
+ return { kind: 'compact', credential: trimmed };
82
+ }
83
+ /** Run one CLI invocation. Returns the process exit code. */
84
+ export async function runCli(argv, ctx) {
85
+ const [command, ...args] = argv;
86
+ try {
87
+ switch (command) {
88
+ case undefined:
89
+ case 'help':
90
+ case '--help':
91
+ case '-h':
92
+ ctx.out(HELP);
93
+ return 0;
94
+ case 'version':
95
+ case '--version':
96
+ case '-v':
97
+ ctx.out(VERSION);
98
+ return 0;
99
+ case 'lookup':
100
+ show(ctx, await ctx.client.resolveToken(requireArg(args, 'token')));
101
+ return 0;
102
+ case 'export':
103
+ show(ctx, await ctx.client.getTrustExport(requireArg(args, 'token')));
104
+ return 0;
105
+ case 'verify': {
106
+ const raw = await ctx.readInput(requireArg(args, 'file'));
107
+ const input = classifyCredentialInput(raw);
108
+ try {
109
+ if (input.kind === 'export') {
110
+ const verified = await ctx.verifiers.trustExport(input.bundle);
111
+ show(ctx, { valid: true, kind: 'trust-export', facts: verified.credential.cred });
112
+ }
113
+ else if (input.kind === 'vc-jwt') {
114
+ const verified = await ctx.verifiers.verifiableCredential(input.jwt);
115
+ show(ctx, { valid: true, kind: 'w3c-vc', facts: verified.cred });
116
+ }
117
+ else {
118
+ const verified = await ctx.verifiers.trustCredential(input.credential);
119
+ show(ctx, { valid: true, kind: 'trust-credential', facts: verified.cred });
120
+ }
121
+ return 0;
122
+ }
123
+ catch (e) {
124
+ show(ctx, { valid: false, kind: input.kind, reason: e instanceof Error ? e.message : String(e) });
125
+ return 2;
126
+ }
127
+ }
128
+ case 'registry':
129
+ show(ctx, await ctx.client.getTrustRegistry());
130
+ return 0;
131
+ case 'did':
132
+ show(ctx, await ctx.client.getDidDocument());
133
+ return 0;
134
+ case 'score':
135
+ show(ctx, await ctx.client.getScore(requireArg(args, 'userId'), requireKey(ctx)));
136
+ return 0;
137
+ case 'explain':
138
+ show(ctx, await ctx.client.getScoreExplain(requireArg(args, 'userId'), requireKey(ctx)));
139
+ return 0;
140
+ case 'components':
141
+ show(ctx, await ctx.client.getScoreComponents(requireArg(args, 'userId'), requireKey(ctx)));
142
+ return 0;
143
+ case 'risk':
144
+ show(ctx, await ctx.client.getRisk(requireArg(args, 'userId'), requireKey(ctx)));
145
+ return 0;
146
+ case 'usage': {
147
+ const days = args[0] ? Number(args[0]) : undefined;
148
+ if (days !== undefined && (!Number.isInteger(days) || days < 1)) {
149
+ throw new Error('usage [days] — days must be a positive integer');
150
+ }
151
+ show(ctx, await ctx.client.getUsage(requireKey(ctx), days));
152
+ return 0;
153
+ }
154
+ case 'webhooks': {
155
+ const [sub, ...rest] = args;
156
+ const key = requireKey(ctx);
157
+ switch (sub) {
158
+ case 'list':
159
+ show(ctx, await ctx.client.listWebhooks(key));
160
+ return 0;
161
+ case 'create': {
162
+ const url = requireArg(rest, 'url');
163
+ const events = rest.slice(1);
164
+ if (events.length === 0) {
165
+ throw new Error('webhooks create <url> <event...> — provide at least one event (score.updated, score.band_changed, dispute.resolved)');
166
+ }
167
+ const created = await ctx.client.createWebhook({ url, events: events }, key);
168
+ ctx.err('NOTE: the signing secret below is shown ONCE — store it now.');
169
+ show(ctx, created);
170
+ return 0;
171
+ }
172
+ case 'delete':
173
+ await ctx.client.deleteWebhook(requireArg(rest, 'id'), key);
174
+ show(ctx, { deleted: true });
175
+ return 0;
176
+ case 'test':
177
+ show(ctx, await ctx.client.testWebhook(requireArg(rest, 'id'), key));
178
+ return 0;
179
+ case 'deliveries':
180
+ show(ctx, await ctx.client.getWebhookDeliveries(requireArg(rest, 'id'), key, 25));
181
+ return 0;
182
+ default:
183
+ throw new Error(`unknown webhooks subcommand "${sub ?? ''}" — see "credda help"`);
184
+ }
185
+ }
186
+ case 'listen': {
187
+ if (!ctx.startListener)
188
+ throw new Error('listen is not available in this environment');
189
+ const port = args[0] ? Number(args[0]) : 4141;
190
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
191
+ throw new Error('listen [port] — port must be 1-65535');
192
+ }
193
+ await ctx.startListener({ port, secret: ctx.webhookSecret });
194
+ return 0;
195
+ }
196
+ case 'mint':
197
+ show(ctx, await ctx.client.mintShareToken(requireArg(args, 'userId'), requireKey(ctx)));
198
+ return 0;
199
+ case 'revoke':
200
+ await ctx.client.revokeShareToken(requireArg(args, 'userId'), requireKey(ctx));
201
+ show(ctx, { revoked: true });
202
+ return 0;
203
+ default:
204
+ throw new Error(`unknown command "${command}" — see "credda help"`);
205
+ }
206
+ }
207
+ catch (e) {
208
+ const message = e instanceof Error ? e.message : String(e);
209
+ // SDK errors already carry a "credda:" prefix — don't double it.
210
+ ctx.err(message.startsWith('credda:') ? message : `credda: ${message}`);
211
+ return 1;
212
+ }
213
+ }
214
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.test.d.ts","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,159 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+ import { classifyCredentialInput, runCli } from './cli.js';
3
+ function makeCtx(overrides = {}) {
4
+ const lines = [];
5
+ const errors = [];
6
+ const client = {
7
+ resolveToken: vi.fn().mockResolvedValue({ token: 'tok', finalScore: 87 }),
8
+ getTrustExport: vi.fn().mockResolvedValue({ format: 'credda-trust-export/1' }),
9
+ getTrustRegistry: vi.fn().mockResolvedValue({ issuers: [] }),
10
+ getDidDocument: vi.fn().mockResolvedValue({ id: 'did:web:api.credda.io' }),
11
+ getScore: vi.fn().mockResolvedValue({ finalScore: 87 }),
12
+ getScoreExplain: vi.fn().mockResolvedValue({ factors: [] }),
13
+ getScoreComponents: vi.fn().mockResolvedValue({ components: [] }),
14
+ getRisk: vi.fn().mockResolvedValue({ signals: [] }),
15
+ getUsage: vi.fn().mockResolvedValue({ days: [] }),
16
+ mintShareToken: vi.fn().mockResolvedValue({ token: 'newtok' }),
17
+ revokeShareToken: vi.fn().mockResolvedValue(undefined),
18
+ listWebhooks: vi.fn().mockResolvedValue({ data: [] }),
19
+ createWebhook: vi.fn().mockResolvedValue({ webhook: { id: 'wh_1' }, secret: 'whsec_x' }),
20
+ deleteWebhook: vi.fn().mockResolvedValue(undefined),
21
+ testWebhook: vi.fn().mockResolvedValue({ success: true }),
22
+ getWebhookDeliveries: vi.fn().mockResolvedValue({ data: [], nextCursor: null }),
23
+ };
24
+ return {
25
+ client,
26
+ apiKey: undefined,
27
+ out: (l) => lines.push(l),
28
+ err: (l) => errors.push(l),
29
+ readInput: vi.fn().mockResolvedValue(''),
30
+ verifiers: {
31
+ trustCredential: vi.fn().mockResolvedValue({ valid: true, cred: { scoreBand: 'GOOD' } }),
32
+ verifiableCredential: vi.fn().mockResolvedValue({ valid: true, cred: { scoreBand: 'GOOD' } }),
33
+ trustExport: vi.fn().mockResolvedValue({ credential: { cred: { scoreBand: 'GOOD' } } }),
34
+ },
35
+ lines,
36
+ errors,
37
+ ...overrides,
38
+ };
39
+ }
40
+ describe('classifyCredentialInput', () => {
41
+ it('detects a trust-export bundle by its format marker', () => {
42
+ const raw = JSON.stringify({ format: 'credda-trust-export/1', score: {} });
43
+ expect(classifyCredentialInput(raw)).toMatchObject({ kind: 'export' });
44
+ });
45
+ it('detects a VC-JWT by its three-part eyJ shape', () => {
46
+ expect(classifyCredentialInput('eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiJ4In0.c2ln')).toMatchObject({ kind: 'vc-jwt' });
47
+ });
48
+ it('falls back to compact trust credential for anything else', () => {
49
+ expect(classifyCredentialInput('CRD1.someopaquecredential')).toMatchObject({ kind: 'compact' });
50
+ // JSON that is NOT an export bundle is still treated as an opaque string
51
+ expect(classifyCredentialInput('{"foo":1}')).toMatchObject({ kind: 'compact' });
52
+ });
53
+ });
54
+ describe('runCli', () => {
55
+ it('help exits 0 and prints usage', async () => {
56
+ const ctx = makeCtx();
57
+ expect(await runCli(['help'], ctx)).toBe(0);
58
+ expect(ctx.lines.join('\n')).toContain('credda lookup');
59
+ });
60
+ it('no command behaves like help', async () => {
61
+ const ctx = makeCtx();
62
+ expect(await runCli([], ctx)).toBe(0);
63
+ expect(ctx.lines.join('\n')).toContain('Exit codes');
64
+ });
65
+ it('lookup resolves the token and prints JSON', async () => {
66
+ const ctx = makeCtx();
67
+ expect(await runCli(['lookup', 'tok'], ctx)).toBe(0);
68
+ expect(ctx.client.resolveToken).toHaveBeenCalledWith('tok');
69
+ expect(JSON.parse(ctx.lines[0])).toMatchObject({ finalScore: 87 });
70
+ });
71
+ it('lookup without a token is a usage error (exit 1)', async () => {
72
+ const ctx = makeCtx();
73
+ expect(await runCli(['lookup'], ctx)).toBe(1);
74
+ expect(ctx.errors[0]).toContain('missing required argument');
75
+ });
76
+ it('unknown command exits 1 with a pointer to help', async () => {
77
+ const ctx = makeCtx();
78
+ expect(await runCli(['frobnicate'], ctx)).toBe(1);
79
+ expect(ctx.errors[0]).toContain('unknown command');
80
+ });
81
+ it('keyed commands refuse to run without CREDDA_API_KEY', async () => {
82
+ const ctx = makeCtx();
83
+ expect(await runCli(['score', 'user_1'], ctx)).toBe(1);
84
+ expect(ctx.errors[0]).toContain('CREDDA_API_KEY');
85
+ expect(ctx.client.getScore).not.toHaveBeenCalled();
86
+ });
87
+ it('score passes the key through when present', async () => {
88
+ const ctx = makeCtx({ apiKey: 'crd_live_x' });
89
+ expect(await runCli(['score', 'user_1'], ctx)).toBe(0);
90
+ expect(ctx.client.getScore).toHaveBeenCalledWith('user_1', 'crd_live_x');
91
+ });
92
+ it('usage validates the optional days argument', async () => {
93
+ const ctx = makeCtx({ apiKey: 'k' });
94
+ expect(await runCli(['usage', 'nope'], ctx)).toBe(1);
95
+ expect(await runCli(['usage', '30'], ctx)).toBe(0);
96
+ expect(ctx.client.getUsage).toHaveBeenCalledWith('k', 30);
97
+ });
98
+ it('verify routes a VC-JWT to the vc verifier and exits 0 when valid', async () => {
99
+ const ctx = makeCtx({
100
+ readInput: vi.fn().mockResolvedValue('eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiJ4In0.c2ln'),
101
+ });
102
+ expect(await runCli(['verify', 'cred.jwt'], ctx)).toBe(0);
103
+ expect(ctx.verifiers.verifiableCredential).toHaveBeenCalled();
104
+ expect(JSON.parse(ctx.lines[0])).toMatchObject({ valid: true, kind: 'w3c-vc' });
105
+ });
106
+ it('verify exits 2 (not 1) when the credential fails verification', async () => {
107
+ const ctx = makeCtx({
108
+ readInput: vi.fn().mockResolvedValue('eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiJ4In0.c2ln'),
109
+ verifiers: {
110
+ trustCredential: vi.fn(),
111
+ verifiableCredential: vi.fn().mockRejectedValue(new Error('credda: signature verification failed')),
112
+ trustExport: vi.fn(),
113
+ },
114
+ });
115
+ expect(await runCli(['verify', 'cred.jwt'], ctx)).toBe(2);
116
+ expect(JSON.parse(ctx.lines[0])).toMatchObject({ valid: false, kind: 'vc-jwt' });
117
+ });
118
+ it('verify routes a trust-export bundle to the export verifier', async () => {
119
+ const ctx = makeCtx({
120
+ readInput: vi.fn().mockResolvedValue(JSON.stringify({ format: 'credda-trust-export/1' })),
121
+ });
122
+ expect(await runCli(['verify', 'export.json'], ctx)).toBe(0);
123
+ expect(ctx.verifiers.trustExport).toHaveBeenCalled();
124
+ expect(JSON.parse(ctx.lines[0])).toMatchObject({ valid: true, kind: 'trust-export' });
125
+ });
126
+ it('webhooks subcommands require a key and route to the client', async () => {
127
+ const noKey = makeCtx();
128
+ expect(await runCli(['webhooks', 'list'], noKey)).toBe(1);
129
+ expect(noKey.errors[0]).toContain('CREDDA_API_KEY');
130
+ const ctx = makeCtx({ apiKey: 'k' });
131
+ expect(await runCli(['webhooks', 'list'], ctx)).toBe(0);
132
+ expect(ctx.client.listWebhooks).toHaveBeenCalledWith('k');
133
+ expect(await runCli(['webhooks', 'create', 'https://h.example/w', 'score.updated'], ctx)).toBe(0);
134
+ expect(ctx.client.createWebhook).toHaveBeenCalledWith({ url: 'https://h.example/w', events: ['score.updated'] }, 'k');
135
+ expect(ctx.errors.join(' ')).toContain('shown ONCE');
136
+ expect(await runCli(['webhooks', 'create', 'https://h.example/w'], ctx)).toBe(1); // no events
137
+ expect(await runCli(['webhooks', 'test', 'wh_1'], ctx)).toBe(0);
138
+ expect(await runCli(['webhooks', 'deliveries', 'wh_1'], ctx)).toBe(0);
139
+ expect(await runCli(['webhooks', 'nope'], ctx)).toBe(1);
140
+ });
141
+ it('listen validates the port and delegates to the injected listener', async () => {
142
+ const started = [];
143
+ const ctx = makeCtx({
144
+ webhookSecret: 'whsec_s',
145
+ startListener: async (o) => { started.push(o); },
146
+ });
147
+ expect(await runCli(['listen'], ctx)).toBe(0);
148
+ expect(started[0]).toEqual({ port: 4141, secret: 'whsec_s' });
149
+ expect(await runCli(['listen', '9999'], ctx)).toBe(0);
150
+ expect(started[1].port).toBe(9999);
151
+ expect(await runCli(['listen', 'abc'], ctx)).toBe(1);
152
+ });
153
+ it('revoke reports success as JSON', async () => {
154
+ const ctx = makeCtx({ apiKey: 'k' });
155
+ expect(await runCli(['revoke', 'user_1'], ctx)).toBe(0);
156
+ expect(JSON.parse(ctx.lines[0])).toEqual({ revoked: true });
157
+ });
158
+ });
159
+ //# sourceMappingURL=cli.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../src/cli.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `credda` — entry point. All logic lives in cli.ts (testable); this file only
4
+ * wires the real environment: env vars, stdin/file reading, process exit.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `credda` — entry point. All logic lives in cli.ts (testable); this file only
4
+ * wires the real environment: env vars, stdin/file reading, process exit.
5
+ */
6
+ import { readFile } from 'node:fs/promises';
7
+ import { CreddaClient, verifyTrustCredential, verifyVerifiableCredential, verifyTrustExport, } from '@credda/js/headless';
8
+ import { runCli } from './cli.js';
9
+ import { startListener } from './listener.js';
10
+ async function readInput(pathOrDash) {
11
+ if (pathOrDash === '-') {
12
+ const chunks = [];
13
+ for await (const chunk of process.stdin)
14
+ chunks.push(chunk);
15
+ return Buffer.concat(chunks).toString('utf8');
16
+ }
17
+ return readFile(pathOrDash, 'utf8');
18
+ }
19
+ // process.exitCode (not process.exit()) — a hard exit right after a fetch
20
+ // trips a libuv assertion on Windows Node while handles are still closing.
21
+ process.exitCode = await runCli(process.argv.slice(2), {
22
+ client: new CreddaClient({ apiBase: process.env.CREDDA_API_URL }),
23
+ apiKey: process.env.CREDDA_API_KEY,
24
+ webhookSecret: process.env.CREDDA_WEBHOOK_SECRET,
25
+ startListener,
26
+ out: (line) => console.log(line),
27
+ err: (line) => console.error(line),
28
+ readInput,
29
+ verifiers: {
30
+ trustCredential: (credential) => verifyTrustCredential(credential),
31
+ verifiableCredential: (vcJwt) => verifyVerifiableCredential(vcJwt),
32
+ trustExport: (bundle) => verifyTrustExport(bundle),
33
+ },
34
+ });
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,KAAK,UAAU,SAAS,CAAC,UAAkB;IACzC,IAAI,UAAU,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;YAAE,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;QACtE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AACtC,CAAC;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,OAAO,CAAC,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACrD,MAAM,EAAE,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;IACjE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc;IAClC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB;IAChD,aAAa;IACb,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;IAClC,SAAS;IACT,SAAS,EAAE;QACT,eAAe,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,qBAAqB,CAAC,UAAU,CAAC;QAClE,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,0BAA0B,CAAC,KAAK,CAAC;QAClE,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC;KACnD;CACF,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `credda listen` — a local webhook receiver for development.
3
+ *
4
+ * Accepts POSTs on a local port, verifies each delivery's HMAC signature with
5
+ * the webhook's signing secret (when provided), and pretty-prints the payload.
6
+ * Responds 200 so a tunneled Credda delivery counts as delivered.
7
+ *
8
+ * Honest scope: Credda only delivers to public HTTPS endpoints, so this does
9
+ * NOT tunnel by itself — put your own tunnel in front (cloudflared, ngrok, …)
10
+ * and register the tunnel URL as the webhook. What this gives you is the
11
+ * Stripe-CLI-style local loop: see every delivery, verify its signature the
12
+ * same way your production handler must, and iterate without redeploying.
13
+ */
14
+ export declare function startListener(opts: {
15
+ port: number;
16
+ secret?: string;
17
+ }): Promise<void>;
18
+ //# sourceMappingURL=listener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listener.d.ts","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8DpF"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * `credda listen` — a local webhook receiver for development.
3
+ *
4
+ * Accepts POSTs on a local port, verifies each delivery's HMAC signature with
5
+ * the webhook's signing secret (when provided), and pretty-prints the payload.
6
+ * Responds 200 so a tunneled Credda delivery counts as delivered.
7
+ *
8
+ * Honest scope: Credda only delivers to public HTTPS endpoints, so this does
9
+ * NOT tunnel by itself — put your own tunnel in front (cloudflared, ngrok, …)
10
+ * and register the tunnel URL as the webhook. What this gives you is the
11
+ * Stripe-CLI-style local loop: see every delivery, verify its signature the
12
+ * same way your production handler must, and iterate without redeploying.
13
+ */
14
+ import { createServer } from 'node:http';
15
+ import { verifyWebhookSignature } from '@credda/js/headless';
16
+ export function startListener(opts) {
17
+ return new Promise((resolve, reject) => {
18
+ const server = createServer((req, res) => {
19
+ const chunks = [];
20
+ req.on('data', (c) => chunks.push(c));
21
+ req.on('end', () => {
22
+ void (async () => {
23
+ const rawBody = Buffer.concat(chunks).toString('utf8');
24
+ const time = new Date().toISOString();
25
+ let verdict = 'unverified (set CREDDA_WEBHOOK_SECRET to verify signatures)';
26
+ if (opts.secret) {
27
+ try {
28
+ const result = await verifyWebhookSignature({
29
+ secret: opts.secret,
30
+ rawBody,
31
+ signatureHeader: req.headers['x-credda-signature'],
32
+ timestampHeader: req.headers['x-credda-timestamp'],
33
+ });
34
+ verdict = result.valid ? 'signature VERIFIED' : `signature INVALID — ${result.reason}`;
35
+ }
36
+ catch (e) {
37
+ verdict = `signature check errored — ${e instanceof Error ? e.message : String(e)}`;
38
+ }
39
+ }
40
+ let pretty = rawBody;
41
+ let eventType = req.headers['x-credda-event'] ?? '?';
42
+ try {
43
+ const parsed = JSON.parse(rawBody);
44
+ if (parsed.type)
45
+ eventType = parsed.type;
46
+ pretty = JSON.stringify(parsed, null, 2);
47
+ }
48
+ catch {
49
+ // non-JSON body — print raw
50
+ }
51
+ console.log(`\n── ${time} · ${req.method} ${req.url} · ${String(eventType)} · ${verdict}`);
52
+ console.log(pretty);
53
+ res.writeHead(200, { 'content-type': 'application/json' });
54
+ res.end('{"received":true}');
55
+ })();
56
+ });
57
+ });
58
+ server.on('error', reject);
59
+ server.listen(opts.port, () => {
60
+ console.error(`credda listen — receiving webhook deliveries on http://localhost:${opts.port}`);
61
+ console.error(opts.secret
62
+ ? 'Signatures will be verified with CREDDA_WEBHOOK_SECRET.'
63
+ : 'No CREDDA_WEBHOOK_SECRET set — payloads will print unverified.');
64
+ console.error('Expose this port with your own tunnel and register the HTTPS URL as your webhook. Ctrl+C to stop.');
65
+ });
66
+ // Runs until the process is interrupted.
67
+ process.on('SIGINT', () => {
68
+ server.close(() => resolve());
69
+ // Give close a moment, then let the default handler end the process.
70
+ setTimeout(() => resolve(), 200);
71
+ });
72
+ });
73
+ }
74
+ //# sourceMappingURL=listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listener.js","sourceRoot":"","sources":["../src/listener.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@credda/cli",
3
+ "version": "0.1.0",
4
+ "description": "Official Credda CLI \u2014 look up and offline-verify portable trust from the terminal: public trust checks, credential verification, platform score reads, share-token minting. A thin client over @credda/js; no scoring logic lives here.",
5
+ "type": "module",
6
+ "bin": {
7
+ "credda": "dist/index.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc -p tsconfig.json",
15
+ "start": "node dist/index.js",
16
+ "dev": "tsx src/index.ts",
17
+ "typecheck": "tsc --noEmit",
18
+ "test": "vitest run"
19
+ },
20
+ "dependencies": {
21
+ "@credda/js": "workspace:*"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "^20.14.2",
25
+ "tsx": "^4.15.2",
26
+ "typescript": "^5.4.5",
27
+ "vitest": "^1.6.0"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ }
32
+ }