@vidos-id/openid4vc-issuer-cli 0.0.0-rc.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 +207 -0
- package/dist/index.d.mts +198 -0
- package/dist/index.mjs +1055 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# @vidos-id/openid4vc-issuer-cli
|
|
2
|
+
|
|
3
|
+
Terminal client for [`@vidos-id/openid4vc-issuer-web-server`](../issuer-web-server/).
|
|
4
|
+
|
|
5
|
+
This CLI no longer issues credentials locally or manages issuer key material. It signs into a running issuer web server, manages templates and issuance offers, and exposes the same app-level workflows as the web client in a terminal-friendly form.
|
|
6
|
+
|
|
7
|
+
For wallet-side credential receipt and storage, use [`@vidos-id/openid4vc-wallet-cli`](../wallet-cli/).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Download the latest GitHub Release artifact and make it executable:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
curl -L -o openid4vc-issuer https://github.com/vidos-id/openid4vc-tools/releases/latest/download/openid4vc-issuer.js
|
|
15
|
+
chmod +x openid4vc-issuer
|
|
16
|
+
./openid4vc-issuer --help
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For development in this repo, run the bin entry directly with Bun:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun packages/issuer-cli/src/index.ts --help
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## What It Does
|
|
26
|
+
|
|
27
|
+
- sign in to a local or remote issuer web server
|
|
28
|
+
- support guest sessions and username/password accounts
|
|
29
|
+
- inspect the issuer metadata published at `/.well-known/openid-credential-issuer`
|
|
30
|
+
- list, create, and delete templates
|
|
31
|
+
- list issuances, create new issuance offers, inspect offer URIs, and update status
|
|
32
|
+
- provide an interactive terminal flow with prompts and menus
|
|
33
|
+
|
|
34
|
+
Running `openid4vc-issuer` with no subcommand starts the interactive mode by default.
|
|
35
|
+
|
|
36
|
+
## Server
|
|
37
|
+
|
|
38
|
+
Run the API separately:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
bun run --filter '@vidos-id/openid4vc-issuer-web-server' dev
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Default local server URL:
|
|
45
|
+
|
|
46
|
+
- `http://localhost:3001`
|
|
47
|
+
|
|
48
|
+
Most commands use the saved session server automatically. You can override it with `--server-url`.
|
|
49
|
+
|
|
50
|
+
## Session Storage
|
|
51
|
+
|
|
52
|
+
By default the CLI stores the authenticated session at:
|
|
53
|
+
|
|
54
|
+
- `~/.config/vidos-id/openid4vc-issuer-session.json`
|
|
55
|
+
|
|
56
|
+
Override it with `--session-file <file>`.
|
|
57
|
+
|
|
58
|
+
## Commands
|
|
59
|
+
|
|
60
|
+
### `auth signin`
|
|
61
|
+
|
|
62
|
+
Sign in with either a guest session or username/password.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
openid4vc-issuer auth signin --anonymous
|
|
66
|
+
openid4vc-issuer auth signin --server-url http://localhost:3001 --username ada --password secret
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `auth signup`
|
|
70
|
+
|
|
71
|
+
Create an account and save the resulting session.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
openid4vc-issuer auth signup --username ada --password secret
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### `auth whoami`
|
|
78
|
+
|
|
79
|
+
Show the saved session.
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
openid4vc-issuer auth whoami
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `auth signout`
|
|
86
|
+
|
|
87
|
+
Sign out and clear the saved session file.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
openid4vc-issuer auth signout
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `metadata`
|
|
94
|
+
|
|
95
|
+
Show the issuer metadata document exposed by the server.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
openid4vc-issuer metadata
|
|
99
|
+
openid4vc-issuer metadata --server-url http://localhost:3001 --output json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### `templates list`
|
|
103
|
+
|
|
104
|
+
List the predefined and custom templates visible to the current user.
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
openid4vc-issuer templates list
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### `templates create`
|
|
111
|
+
|
|
112
|
+
Create a custom template.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
openid4vc-issuer templates create \
|
|
116
|
+
--name "Conference Pass" \
|
|
117
|
+
--vct https://issuer.example/credentials/conference-pass \
|
|
118
|
+
--claims '{"given_name":"Ada","pass_level":"speaker"}'
|
|
119
|
+
|
|
120
|
+
openid4vc-issuer templates create \
|
|
121
|
+
--name "PID" \
|
|
122
|
+
--vct urn:eudi:pid:1 \
|
|
123
|
+
--claims-file examples/pid/pid-minimal.claims.json
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `templates delete`
|
|
127
|
+
|
|
128
|
+
Delete a custom template by id.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
openid4vc-issuer templates delete --template-id <template-id>
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### `issuances list`
|
|
135
|
+
|
|
136
|
+
List issuances for the current user.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
openid4vc-issuer issuances list
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### `issuances create`
|
|
143
|
+
|
|
144
|
+
Create an issuance offer from a template. The output includes the `openid-credential-offer://` URI for wallet handoff.
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
openid4vc-issuer issuances create \
|
|
148
|
+
--template-id <template-id> \
|
|
149
|
+
--claims '{"seat":"A-12"}' \
|
|
150
|
+
--status active
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### `issuances show`
|
|
154
|
+
|
|
155
|
+
Show one issuance, including its current state, claims, and offer URI.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
openid4vc-issuer issuances show --issuance-id <issuance-id>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### `issuances status`
|
|
162
|
+
|
|
163
|
+
Update credential status for an issuance.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
openid4vc-issuer issuances status --issuance-id <issuance-id> --status suspended
|
|
167
|
+
openid4vc-issuer issuances status --issuance-id <issuance-id> --status revoked
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Interactive Mode
|
|
171
|
+
|
|
172
|
+
Start the interactive terminal flow by running the CLI without a subcommand:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
openid4vc-issuer
|
|
176
|
+
openid4vc-issuer --server-url http://localhost:3001
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
The interactive mode can:
|
|
180
|
+
|
|
181
|
+
- choose the target server URL
|
|
182
|
+
- sign in as guest or with credentials
|
|
183
|
+
- inspect issuer metadata
|
|
184
|
+
- create and delete templates
|
|
185
|
+
- create issuances from a selected template
|
|
186
|
+
- inspect and update existing issuances
|
|
187
|
+
|
|
188
|
+
## Global options
|
|
189
|
+
|
|
190
|
+
- running `openid4vc-issuer` with no subcommand starts interactive mode
|
|
191
|
+
- `--server-url <url>` - override the issuer web server URL
|
|
192
|
+
- `--session-file <file>` - override the saved session file location
|
|
193
|
+
- `--verbose` - enable verbose logging to stderr
|
|
194
|
+
- `--version` - show version number
|
|
195
|
+
- `--help` - show help for a command
|
|
196
|
+
|
|
197
|
+
## Notes
|
|
198
|
+
|
|
199
|
+
- `openid4vc-issuer` is an app client of `openid4vc-issuer-web-server`; it does not issue locally
|
|
200
|
+
- `openid4vc-issuer` does not receive or store credentials; wallet redemption belongs to [`openid4vc-wallet receive`](../wallet-cli/)
|
|
201
|
+
- command output is concise text meant for terminal usage rather than raw JSON dumps
|
|
202
|
+
|
|
203
|
+
## Test
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
bun test packages/issuer-cli/src/index.test.ts
|
|
207
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
|
|
3
|
+
//#region src/program.d.ts
|
|
4
|
+
declare function createProgram(version: string): Command;
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/actions/auth.d.ts
|
|
7
|
+
type ActionDeps$4 = {
|
|
8
|
+
fetchImpl?: typeof fetch;
|
|
9
|
+
};
|
|
10
|
+
declare function authSignInAction(rawOptions: unknown, deps?: ActionDeps$4): Promise<{
|
|
11
|
+
serverUrl: string;
|
|
12
|
+
user: {
|
|
13
|
+
id: string;
|
|
14
|
+
username: string | null;
|
|
15
|
+
name: string;
|
|
16
|
+
isAnonymous: boolean;
|
|
17
|
+
createdAt: string;
|
|
18
|
+
};
|
|
19
|
+
}>;
|
|
20
|
+
declare function authSignUpAction(rawOptions: unknown, deps?: ActionDeps$4): Promise<{
|
|
21
|
+
serverUrl: string;
|
|
22
|
+
user: {
|
|
23
|
+
id: string;
|
|
24
|
+
username: string | null;
|
|
25
|
+
name: string;
|
|
26
|
+
isAnonymous: boolean;
|
|
27
|
+
createdAt: string;
|
|
28
|
+
};
|
|
29
|
+
}>;
|
|
30
|
+
declare function authWhoAmIAction(rawOptions: unknown, deps?: ActionDeps$4): Promise<{
|
|
31
|
+
serverUrl: string;
|
|
32
|
+
user: {
|
|
33
|
+
id: string;
|
|
34
|
+
username: string | null;
|
|
35
|
+
name: string;
|
|
36
|
+
isAnonymous: boolean;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
};
|
|
39
|
+
}>;
|
|
40
|
+
declare function authSignOutAction(rawOptions: unknown, deps?: ActionDeps$4): Promise<{
|
|
41
|
+
serverUrl: string;
|
|
42
|
+
}>;
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/actions/interactive.d.ts
|
|
45
|
+
type ActionDeps$3 = {
|
|
46
|
+
fetchImpl?: typeof fetch;
|
|
47
|
+
};
|
|
48
|
+
declare function interactiveAction(rawOptions: unknown, deps?: ActionDeps$3): Promise<void>;
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/actions/issuances.d.ts
|
|
51
|
+
type ActionDeps$2 = {
|
|
52
|
+
fetchImpl?: typeof fetch;
|
|
53
|
+
};
|
|
54
|
+
declare function listIssuancesAction(rawOptions: unknown, deps?: ActionDeps$2): Promise<{
|
|
55
|
+
serverUrl: string;
|
|
56
|
+
issuances: {
|
|
57
|
+
id: string;
|
|
58
|
+
ownerUserId: string;
|
|
59
|
+
templateId: string;
|
|
60
|
+
credentialConfigurationId: string;
|
|
61
|
+
vct: string;
|
|
62
|
+
claims: Record<string, unknown>;
|
|
63
|
+
state: "offered" | "redeeming" | "redeemed" | "expired" | "redemption_failed";
|
|
64
|
+
status: 0 | 1 | 2;
|
|
65
|
+
offerUri: string;
|
|
66
|
+
statusListId: string;
|
|
67
|
+
statusListIndex: number;
|
|
68
|
+
credential: string | null;
|
|
69
|
+
createdAt: string;
|
|
70
|
+
updatedAt: string;
|
|
71
|
+
}[];
|
|
72
|
+
}>;
|
|
73
|
+
declare function createIssuanceAction(rawOptions: unknown, deps?: ActionDeps$2): Promise<{
|
|
74
|
+
serverUrl: string;
|
|
75
|
+
detail: {
|
|
76
|
+
issuance: {
|
|
77
|
+
id: string;
|
|
78
|
+
ownerUserId: string;
|
|
79
|
+
templateId: string;
|
|
80
|
+
credentialConfigurationId: string;
|
|
81
|
+
vct: string;
|
|
82
|
+
claims: Record<string, unknown>;
|
|
83
|
+
state: "offered" | "redeeming" | "redeemed" | "expired" | "redemption_failed";
|
|
84
|
+
status: 0 | 1 | 2;
|
|
85
|
+
offerUri: string;
|
|
86
|
+
statusListId: string;
|
|
87
|
+
statusListIndex: number;
|
|
88
|
+
credential: string | null;
|
|
89
|
+
createdAt: string;
|
|
90
|
+
updatedAt: string;
|
|
91
|
+
};
|
|
92
|
+
qrPayload: string;
|
|
93
|
+
};
|
|
94
|
+
}>;
|
|
95
|
+
declare function showIssuanceAction(rawOptions: unknown, deps?: ActionDeps$2): Promise<{
|
|
96
|
+
serverUrl: string;
|
|
97
|
+
detail: {
|
|
98
|
+
issuance: {
|
|
99
|
+
id: string;
|
|
100
|
+
ownerUserId: string;
|
|
101
|
+
templateId: string;
|
|
102
|
+
credentialConfigurationId: string;
|
|
103
|
+
vct: string;
|
|
104
|
+
claims: Record<string, unknown>;
|
|
105
|
+
state: "offered" | "redeeming" | "redeemed" | "expired" | "redemption_failed";
|
|
106
|
+
status: 0 | 1 | 2;
|
|
107
|
+
offerUri: string;
|
|
108
|
+
statusListId: string;
|
|
109
|
+
statusListIndex: number;
|
|
110
|
+
credential: string | null;
|
|
111
|
+
createdAt: string;
|
|
112
|
+
updatedAt: string;
|
|
113
|
+
};
|
|
114
|
+
qrPayload: string;
|
|
115
|
+
};
|
|
116
|
+
}>;
|
|
117
|
+
declare function updateIssuanceStatusAction(rawOptions: unknown, deps?: ActionDeps$2): Promise<{
|
|
118
|
+
serverUrl: string;
|
|
119
|
+
detail: {
|
|
120
|
+
issuance: {
|
|
121
|
+
id: string;
|
|
122
|
+
ownerUserId: string;
|
|
123
|
+
templateId: string;
|
|
124
|
+
credentialConfigurationId: string;
|
|
125
|
+
vct: string;
|
|
126
|
+
claims: Record<string, unknown>;
|
|
127
|
+
state: "offered" | "redeeming" | "redeemed" | "expired" | "redemption_failed";
|
|
128
|
+
status: 0 | 1 | 2;
|
|
129
|
+
offerUri: string;
|
|
130
|
+
statusListId: string;
|
|
131
|
+
statusListIndex: number;
|
|
132
|
+
credential: string | null;
|
|
133
|
+
createdAt: string;
|
|
134
|
+
updatedAt: string;
|
|
135
|
+
};
|
|
136
|
+
qrPayload: string;
|
|
137
|
+
};
|
|
138
|
+
}>;
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/actions/metadata.d.ts
|
|
141
|
+
type ActionDeps$1 = {
|
|
142
|
+
fetchImpl?: typeof fetch;
|
|
143
|
+
};
|
|
144
|
+
declare function metadataAction(rawOptions: unknown, deps?: ActionDeps$1): Promise<{
|
|
145
|
+
serverUrl: string;
|
|
146
|
+
metadata: {
|
|
147
|
+
credential_issuer: string;
|
|
148
|
+
token_endpoint: string;
|
|
149
|
+
credential_endpoint: string;
|
|
150
|
+
jwks: {
|
|
151
|
+
keys: Record<string, unknown>[];
|
|
152
|
+
};
|
|
153
|
+
credential_configurations_supported: Record<string, Record<string, unknown>>;
|
|
154
|
+
nonce_endpoint?: string | undefined;
|
|
155
|
+
};
|
|
156
|
+
}>;
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/actions/templates.d.ts
|
|
159
|
+
type ActionDeps = {
|
|
160
|
+
fetchImpl?: typeof fetch;
|
|
161
|
+
};
|
|
162
|
+
declare function listTemplatesAction(rawOptions: unknown, deps?: ActionDeps): Promise<{
|
|
163
|
+
serverUrl: string;
|
|
164
|
+
templates: {
|
|
165
|
+
id: string;
|
|
166
|
+
ownerUserId: string;
|
|
167
|
+
name: string;
|
|
168
|
+
kind: "predefined" | "custom";
|
|
169
|
+
credentialConfigurationId: string;
|
|
170
|
+
vct: string;
|
|
171
|
+
defaultClaims: Record<string, unknown>;
|
|
172
|
+
createdAt: string;
|
|
173
|
+
updatedAt: string;
|
|
174
|
+
}[];
|
|
175
|
+
}>;
|
|
176
|
+
declare function createTemplateAction(rawOptions: unknown, deps?: ActionDeps): Promise<{
|
|
177
|
+
serverUrl: string;
|
|
178
|
+
template: {
|
|
179
|
+
id: string;
|
|
180
|
+
ownerUserId: string;
|
|
181
|
+
name: string;
|
|
182
|
+
kind: "predefined" | "custom";
|
|
183
|
+
credentialConfigurationId: string;
|
|
184
|
+
vct: string;
|
|
185
|
+
defaultClaims: Record<string, unknown>;
|
|
186
|
+
createdAt: string;
|
|
187
|
+
updatedAt: string;
|
|
188
|
+
};
|
|
189
|
+
}>;
|
|
190
|
+
declare function deleteTemplateAction(rawOptions: unknown, deps?: ActionDeps): Promise<{
|
|
191
|
+
serverUrl: string;
|
|
192
|
+
templateId: string;
|
|
193
|
+
}>;
|
|
194
|
+
//#endregion
|
|
195
|
+
//#region src/index.d.ts
|
|
196
|
+
declare function runCli(argv?: string[]): Promise<void>;
|
|
197
|
+
//#endregion
|
|
198
|
+
export { authSignInAction, authSignOutAction, authSignUpAction, authWhoAmIAction, createIssuanceAction, createProgram, createTemplateAction, deleteTemplateAction, interactiveAction, listIssuancesAction, listTemplatesAction, metadataAction, runCli, showIssuanceAction, updateIssuanceStatusAction };
|