@twin.org/identity-cli 0.0.1-next.3
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/LICENSE +201 -0
- package/README.md +21 -0
- package/bin/index.js +10 -0
- package/dist/cjs/index.cjs +1137 -0
- package/dist/esm/index.mjs +1110 -0
- package/dist/locales/en.json +784 -0
- package/dist/types/cli.d.ts +13 -0
- package/dist/types/commands/identityCreate.d.ts +19 -0
- package/dist/types/commands/identityResolve.d.ts +19 -0
- package/dist/types/commands/proofCreate.d.ts +21 -0
- package/dist/types/commands/proofVerify.d.ts +23 -0
- package/dist/types/commands/serviceAdd.d.ts +27 -0
- package/dist/types/commands/serviceRemove.d.ts +20 -0
- package/dist/types/commands/setupCommands.d.ts +4 -0
- package/dist/types/commands/verifiableCredentialCreate.d.ts +29 -0
- package/dist/types/commands/verifiableCredentialRevoke.d.ts +20 -0
- package/dist/types/commands/verifiableCredentialUnrevoke.d.ts +20 -0
- package/dist/types/commands/verifiableCredentialVerify.d.ts +17 -0
- package/dist/types/commands/verificationMethodAdd.d.ts +26 -0
- package/dist/types/commands/verificationMethodRemove.d.ts +20 -0
- package/dist/types/index.d.ts +13 -0
- package/docs/changelog.md +5 -0
- package/docs/examples.md +210 -0
- package/docs/reference/classes/CLI.md +45 -0
- package/docs/reference/functions/actionCommandIdentityCreate.md +15 -0
- package/docs/reference/functions/actionCommandIdentityResolve.md +15 -0
- package/docs/reference/functions/actionCommandProofCreate.md +15 -0
- package/docs/reference/functions/actionCommandProofVerify.md +15 -0
- package/docs/reference/functions/actionCommandServiceAdd.md +15 -0
- package/docs/reference/functions/actionCommandServiceRemove.md +31 -0
- package/docs/reference/functions/actionCommandVerifiableCredentialCreate.md +15 -0
- package/docs/reference/functions/actionCommandVerifiableCredentialRevoke.md +31 -0
- package/docs/reference/functions/actionCommandVerifiableCredentialUnrevoke.md +31 -0
- package/docs/reference/functions/actionCommandVerifiableCredentialVerify.md +15 -0
- package/docs/reference/functions/actionCommandVerificationMethodAdd.md +15 -0
- package/docs/reference/functions/actionCommandVerificationMethodRemove.md +31 -0
- package/docs/reference/functions/buildCommandIdentityCreate.md +11 -0
- package/docs/reference/functions/buildCommandIdentityResolve.md +11 -0
- package/docs/reference/functions/buildCommandProofCreate.md +11 -0
- package/docs/reference/functions/buildCommandProofVerify.md +11 -0
- package/docs/reference/functions/buildCommandServiceAdd.md +11 -0
- package/docs/reference/functions/buildCommandServiceRemove.md +11 -0
- package/docs/reference/functions/buildCommandVerifiableCredentialCreate.md +11 -0
- package/docs/reference/functions/buildCommandVerifiableCredentialRevoke.md +11 -0
- package/docs/reference/functions/buildCommandVerifiableCredentialUnrevoke.md +11 -0
- package/docs/reference/functions/buildCommandVerifiableCredentialVerify.md +11 -0
- package/docs/reference/functions/buildCommandVerificationMethodAdd.md +11 -0
- package/docs/reference/functions/buildCommandVerificationMethodRemove.md +11 -0
- package/docs/reference/index.md +32 -0
- package/locales/en.json +336 -0
- package/package.json +86 -0
|
@@ -0,0 +1,1110 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { CLIOptions, CLIParam, CLIDisplay, CLIUtils, CLIBase } from '@twin.org/cli-core';
|
|
4
|
+
import { buildCommandMnemonic, buildCommandAddress } from '@twin.org/crypto-cli';
|
|
5
|
+
import { buildCommandFaucet, buildCommandTransfer } from '@twin.org/wallet-cli';
|
|
6
|
+
import { I18n, Converter, Is, StringHelper, Guards, Coerce, GeneralError } from '@twin.org/core';
|
|
7
|
+
import { IotaIdentityConnector, IotaIdentityUtils } from '@twin.org/identity-connector-iota';
|
|
8
|
+
import { VaultConnectorFactory, VaultKeyType } from '@twin.org/vault-models';
|
|
9
|
+
import { IotaWalletConnector } from '@twin.org/wallet-connector-iota';
|
|
10
|
+
import { WalletConnectorFactory } from '@twin.org/wallet-models';
|
|
11
|
+
import { Command, Option } from 'commander';
|
|
12
|
+
import { MemoryEntityStorageConnector } from '@twin.org/entity-storage-connector-memory';
|
|
13
|
+
import { EntityStorageConnectorFactory } from '@twin.org/entity-storage-models';
|
|
14
|
+
import { initSchema, EntityStorageVaultConnector } from '@twin.org/vault-connector-entity-storage';
|
|
15
|
+
import { DocumentHelper } from '@twin.org/identity-models';
|
|
16
|
+
import { DidVerificationMethodType } from '@twin.org/standards-w3c-did';
|
|
17
|
+
|
|
18
|
+
// Copyright 2024 IOTA Stiftung.
|
|
19
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
20
|
+
/**
|
|
21
|
+
* Setup the vault for use in the CLI commands.
|
|
22
|
+
*/
|
|
23
|
+
function setupVault() {
|
|
24
|
+
initSchema();
|
|
25
|
+
EntityStorageConnectorFactory.register("vault-key", () => new MemoryEntityStorageConnector({
|
|
26
|
+
entitySchema: "VaultKey"
|
|
27
|
+
}));
|
|
28
|
+
EntityStorageConnectorFactory.register("vault-secret", () => new MemoryEntityStorageConnector({
|
|
29
|
+
entitySchema: "VaultSecret"
|
|
30
|
+
}));
|
|
31
|
+
const vaultConnector = new EntityStorageVaultConnector();
|
|
32
|
+
VaultConnectorFactory.register("vault", () => vaultConnector);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Copyright 2024 IOTA Stiftung.
|
|
36
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
37
|
+
/**
|
|
38
|
+
* Build the identity create command for the CLI.
|
|
39
|
+
* @returns The command.
|
|
40
|
+
*/
|
|
41
|
+
function buildCommandIdentityCreate() {
|
|
42
|
+
const command = new Command();
|
|
43
|
+
command
|
|
44
|
+
.name("identity-create")
|
|
45
|
+
.summary(I18n.formatMessage("commands.identity-create.summary"))
|
|
46
|
+
.description(I18n.formatMessage("commands.identity-create.description"))
|
|
47
|
+
.requiredOption(I18n.formatMessage("commands.identity-create.options.seed.param"), I18n.formatMessage("commands.identity-create.options.seed.description"));
|
|
48
|
+
CLIOptions.output(command, {
|
|
49
|
+
noConsole: true,
|
|
50
|
+
json: true,
|
|
51
|
+
env: true,
|
|
52
|
+
mergeJson: true,
|
|
53
|
+
mergeEnv: true
|
|
54
|
+
});
|
|
55
|
+
command
|
|
56
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
57
|
+
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
58
|
+
.action(actionCommandIdentityCreate);
|
|
59
|
+
return command;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Action the identity create command.
|
|
63
|
+
* @param opts The options for the command.
|
|
64
|
+
* @param opts.seed The private key for the controller.
|
|
65
|
+
* @param opts.node The node URL.
|
|
66
|
+
* @param opts.explorer The explorer URL.
|
|
67
|
+
*/
|
|
68
|
+
async function actionCommandIdentityCreate(opts) {
|
|
69
|
+
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
70
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
71
|
+
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
72
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
73
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explorer"), explorerEndpoint);
|
|
74
|
+
CLIDisplay.break();
|
|
75
|
+
setupVault();
|
|
76
|
+
const vaultSeedId = "local-seed";
|
|
77
|
+
const localIdentity = "local";
|
|
78
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
79
|
+
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
80
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
81
|
+
config: {
|
|
82
|
+
clientOptions: {
|
|
83
|
+
nodes: [nodeEndpoint],
|
|
84
|
+
localPow: true
|
|
85
|
+
},
|
|
86
|
+
vaultSeedId
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
90
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
91
|
+
config: {
|
|
92
|
+
clientOptions: {
|
|
93
|
+
nodes: [nodeEndpoint],
|
|
94
|
+
localPow: true
|
|
95
|
+
},
|
|
96
|
+
vaultSeedId
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
CLIDisplay.task(I18n.formatMessage("commands.identity-create.progress.creatingIdentity"));
|
|
100
|
+
CLIDisplay.break();
|
|
101
|
+
CLIDisplay.spinnerStart();
|
|
102
|
+
const document = await iotaIdentityConnector.createDocument(localIdentity);
|
|
103
|
+
CLIDisplay.spinnerStop();
|
|
104
|
+
if (opts.console) {
|
|
105
|
+
CLIDisplay.value(I18n.formatMessage("commands.identity-create.labels.identity"), document.id);
|
|
106
|
+
CLIDisplay.break();
|
|
107
|
+
}
|
|
108
|
+
if (Is.stringValue(opts?.json)) {
|
|
109
|
+
await CLIUtils.writeJsonFile(opts.json, { did: document.id }, opts.mergeJson);
|
|
110
|
+
}
|
|
111
|
+
if (Is.stringValue(opts?.env)) {
|
|
112
|
+
await CLIUtils.writeEnvFile(opts.env, [`DID="${document.id}"`], opts.mergeEnv);
|
|
113
|
+
}
|
|
114
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaIdentityUtils.didToAddress(document.id)}?tab=DID`);
|
|
115
|
+
CLIDisplay.break();
|
|
116
|
+
CLIDisplay.done();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Copyright 2024 IOTA Stiftung.
|
|
120
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
121
|
+
/**
|
|
122
|
+
* Build the identity resolve command for the CLI.
|
|
123
|
+
* @returns The command.
|
|
124
|
+
*/
|
|
125
|
+
function buildCommandIdentityResolve() {
|
|
126
|
+
const command = new Command();
|
|
127
|
+
command
|
|
128
|
+
.name("identity-resolve")
|
|
129
|
+
.summary(I18n.formatMessage("commands.identity-resolve.summary"))
|
|
130
|
+
.description(I18n.formatMessage("commands.identity-resolve.description"))
|
|
131
|
+
.requiredOption(I18n.formatMessage("commands.identity-resolve.options.did.param"), I18n.formatMessage("commands.identity-resolve.options.did.description"));
|
|
132
|
+
CLIOptions.output(command, {
|
|
133
|
+
noConsole: true,
|
|
134
|
+
json: true,
|
|
135
|
+
env: false,
|
|
136
|
+
mergeJson: true,
|
|
137
|
+
mergeEnv: false
|
|
138
|
+
});
|
|
139
|
+
command
|
|
140
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
141
|
+
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
142
|
+
.action(actionCommandIdentityResolve);
|
|
143
|
+
return command;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Action the identity resolve command.
|
|
147
|
+
* @param opts The options for the command.
|
|
148
|
+
* @param opts.did The identity to resolve.
|
|
149
|
+
* @param opts.node The node URL.
|
|
150
|
+
* @param opts.explorer The explorer URL.
|
|
151
|
+
*/
|
|
152
|
+
async function actionCommandIdentityResolve(opts) {
|
|
153
|
+
const did = CLIParam.stringValue("did", opts.did);
|
|
154
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
155
|
+
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
156
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.did"), did);
|
|
157
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
158
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explorer"), explorerEndpoint);
|
|
159
|
+
CLIDisplay.break();
|
|
160
|
+
setupVault();
|
|
161
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
162
|
+
config: {
|
|
163
|
+
clientOptions: {
|
|
164
|
+
nodes: [nodeEndpoint],
|
|
165
|
+
localPow: true
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
170
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
171
|
+
config: {
|
|
172
|
+
clientOptions: {
|
|
173
|
+
nodes: [nodeEndpoint],
|
|
174
|
+
localPow: true
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
CLIDisplay.task(I18n.formatMessage("commands.identity-resolve.progress.resolvingIdentity"));
|
|
179
|
+
CLIDisplay.break();
|
|
180
|
+
CLIDisplay.spinnerStart();
|
|
181
|
+
const document = await iotaIdentityConnector.resolveDocument(did);
|
|
182
|
+
CLIDisplay.spinnerStop();
|
|
183
|
+
if (opts.console) {
|
|
184
|
+
CLIDisplay.section(I18n.formatMessage("commands.identity-resolve.labels.didDocument"));
|
|
185
|
+
CLIDisplay.json(document);
|
|
186
|
+
CLIDisplay.break();
|
|
187
|
+
}
|
|
188
|
+
if (Is.stringValue(opts?.json)) {
|
|
189
|
+
await CLIUtils.writeJsonFile(opts.json, document, opts.mergeJson);
|
|
190
|
+
}
|
|
191
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaIdentityUtils.didToAddress(document.id)}?tab=DID`);
|
|
192
|
+
CLIDisplay.break();
|
|
193
|
+
CLIDisplay.done();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Copyright 2024 IOTA Stiftung.
|
|
197
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
198
|
+
/**
|
|
199
|
+
* Build the proof create command for the CLI.
|
|
200
|
+
* @returns The command.
|
|
201
|
+
*/
|
|
202
|
+
function buildCommandProofCreate() {
|
|
203
|
+
const command = new Command();
|
|
204
|
+
command
|
|
205
|
+
.name("proof-create")
|
|
206
|
+
.summary(I18n.formatMessage("commands.proof-create.summary"))
|
|
207
|
+
.description(I18n.formatMessage("commands.proof-create.description"))
|
|
208
|
+
.requiredOption(I18n.formatMessage("commands.proof-create.options.id.param"), I18n.formatMessage("commands.proof-create.options.id.description"))
|
|
209
|
+
.requiredOption(I18n.formatMessage("commands.proof-create.options.private-key.param"), I18n.formatMessage("commands.proof-create.options.private-key.description"))
|
|
210
|
+
.requiredOption(I18n.formatMessage("commands.proof-create.options.data.param"), I18n.formatMessage("commands.proof-create.options.data.description"));
|
|
211
|
+
CLIOptions.output(command, {
|
|
212
|
+
noConsole: true,
|
|
213
|
+
json: true,
|
|
214
|
+
env: true,
|
|
215
|
+
mergeJson: true,
|
|
216
|
+
mergeEnv: true
|
|
217
|
+
});
|
|
218
|
+
command
|
|
219
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
220
|
+
.action(actionCommandProofCreate);
|
|
221
|
+
return command;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Action the proof create command.
|
|
225
|
+
* @param opts The options for the command.
|
|
226
|
+
* @param opts.id The id of the verification method to use for the credential.
|
|
227
|
+
* @param opts.privateKey The private key for the verification method.
|
|
228
|
+
* @param opts.data The data to create the proof for.
|
|
229
|
+
* @param opts.node The node URL.
|
|
230
|
+
*/
|
|
231
|
+
async function actionCommandProofCreate(opts) {
|
|
232
|
+
const id = CLIParam.stringValue("id", opts.id);
|
|
233
|
+
const privateKey = CLIParam.hexBase64("private-key", opts.privateKey);
|
|
234
|
+
const data = CLIParam.hexBase64("data", opts.data);
|
|
235
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
236
|
+
CLIDisplay.value(I18n.formatMessage("commands.proof-create.labels.verificationMethodId"), id);
|
|
237
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
238
|
+
CLIDisplay.break();
|
|
239
|
+
setupVault();
|
|
240
|
+
const localIdentity = "local";
|
|
241
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
242
|
+
await vaultConnector.addKey(`${localIdentity}/${id}`, VaultKeyType.Ed25519, privateKey, new Uint8Array());
|
|
243
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
244
|
+
config: {
|
|
245
|
+
clientOptions: {
|
|
246
|
+
nodes: [nodeEndpoint],
|
|
247
|
+
localPow: true
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
252
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
253
|
+
config: {
|
|
254
|
+
clientOptions: {
|
|
255
|
+
nodes: [nodeEndpoint],
|
|
256
|
+
localPow: true
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
CLIDisplay.task(I18n.formatMessage("commands.proof-create.progress.creatingProof"));
|
|
261
|
+
CLIDisplay.break();
|
|
262
|
+
CLIDisplay.spinnerStart();
|
|
263
|
+
const proof = await iotaIdentityConnector.createProof(localIdentity, id, data);
|
|
264
|
+
const proofValue = Converter.bytesToBase64(proof.value);
|
|
265
|
+
CLIDisplay.spinnerStop();
|
|
266
|
+
if (opts.console) {
|
|
267
|
+
CLIDisplay.value(I18n.formatMessage("commands.proof-create.labels.type"), proof.type);
|
|
268
|
+
CLIDisplay.value(I18n.formatMessage("commands.proof-create.labels.value"), proofValue);
|
|
269
|
+
CLIDisplay.break();
|
|
270
|
+
}
|
|
271
|
+
if (Is.stringValue(opts?.json)) {
|
|
272
|
+
await CLIUtils.writeJsonFile(opts.json, { type: proof.type, value: proofValue }, opts.mergeJson);
|
|
273
|
+
}
|
|
274
|
+
if (Is.stringValue(opts?.env)) {
|
|
275
|
+
await CLIUtils.writeEnvFile(opts.env, [`DID_PROOF_TYPE="${proof.type}"`, `DID_PROOF_VALUE="${proofValue}"`], opts.mergeEnv);
|
|
276
|
+
}
|
|
277
|
+
CLIDisplay.done();
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// Copyright 2024 IOTA Stiftung.
|
|
281
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
282
|
+
/**
|
|
283
|
+
* Build the proof verify command for the CLI.
|
|
284
|
+
* @returns The command.
|
|
285
|
+
*/
|
|
286
|
+
function buildCommandProofVerify() {
|
|
287
|
+
const command = new Command();
|
|
288
|
+
command
|
|
289
|
+
.name("proof-verify")
|
|
290
|
+
.summary(I18n.formatMessage("commands.proof-verify.summary"))
|
|
291
|
+
.description(I18n.formatMessage("commands.proof-verify.description"))
|
|
292
|
+
.requiredOption(I18n.formatMessage("commands.proof-verify.options.id.param"), I18n.formatMessage("commands.proof-verify.options.id.description"))
|
|
293
|
+
.requiredOption(I18n.formatMessage("commands.proof-verify.options.data.param"), I18n.formatMessage("commands.proof-verify.options.data.description"))
|
|
294
|
+
.requiredOption(I18n.formatMessage("commands.proof-verify.options.type.param"), I18n.formatMessage("commands.proof-verify.options.type.description"))
|
|
295
|
+
.requiredOption(I18n.formatMessage("commands.proof-verify.options.value.param"), I18n.formatMessage("commands.proof-verify.options.value.description"));
|
|
296
|
+
CLIOptions.output(command, {
|
|
297
|
+
noConsole: true,
|
|
298
|
+
json: true,
|
|
299
|
+
env: true,
|
|
300
|
+
mergeJson: true,
|
|
301
|
+
mergeEnv: true
|
|
302
|
+
});
|
|
303
|
+
command
|
|
304
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
305
|
+
.action(actionCommandProofVerify);
|
|
306
|
+
return command;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Action the proof verify command.
|
|
310
|
+
* @param opts The options for the command.
|
|
311
|
+
* @param opts.id The id of the verification method to use for the credential.
|
|
312
|
+
* @param opts.data The data to verify the proof for.
|
|
313
|
+
* @param opts.type The type of the proof.
|
|
314
|
+
* @param opts.value The proof value.
|
|
315
|
+
* @param opts.node The node URL.
|
|
316
|
+
*/
|
|
317
|
+
async function actionCommandProofVerify(opts) {
|
|
318
|
+
const id = CLIParam.stringValue("id", opts.id);
|
|
319
|
+
const data = CLIParam.hexBase64("data", opts.data);
|
|
320
|
+
const type = CLIParam.stringValue("type", opts.type);
|
|
321
|
+
const value = CLIParam.hexBase64("value", opts.value);
|
|
322
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
323
|
+
CLIDisplay.value(I18n.formatMessage("commands.proof-verify.labels.verificationMethodId"), id);
|
|
324
|
+
CLIDisplay.value(I18n.formatMessage("commands.proof-verify.labels.type"), type);
|
|
325
|
+
CLIDisplay.value(I18n.formatMessage("commands.proof-verify.labels.value"), Converter.bytesToBase64(value));
|
|
326
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
327
|
+
CLIDisplay.break();
|
|
328
|
+
setupVault();
|
|
329
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
330
|
+
config: {
|
|
331
|
+
clientOptions: {
|
|
332
|
+
nodes: [nodeEndpoint],
|
|
333
|
+
localPow: true
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
338
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
339
|
+
config: {
|
|
340
|
+
clientOptions: {
|
|
341
|
+
nodes: [nodeEndpoint],
|
|
342
|
+
localPow: true
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
CLIDisplay.task(I18n.formatMessage("commands.proof-verify.progress.verifyingProof"));
|
|
347
|
+
CLIDisplay.break();
|
|
348
|
+
CLIDisplay.spinnerStart();
|
|
349
|
+
const isVerified = await iotaIdentityConnector.verifyProof(id, data, type, value);
|
|
350
|
+
CLIDisplay.spinnerStop();
|
|
351
|
+
if (opts.console) {
|
|
352
|
+
CLIDisplay.value(I18n.formatMessage("commands.proof-verify.labels.isVerified"), isVerified);
|
|
353
|
+
CLIDisplay.break();
|
|
354
|
+
}
|
|
355
|
+
if (Is.stringValue(opts?.json)) {
|
|
356
|
+
await CLIUtils.writeJsonFile(opts.json, { isVerified }, opts.mergeJson);
|
|
357
|
+
}
|
|
358
|
+
if (Is.stringValue(opts?.env)) {
|
|
359
|
+
await CLIUtils.writeEnvFile(opts.env, [`DID_PROOF_VERIFIED="${isVerified}"`], opts.mergeEnv);
|
|
360
|
+
}
|
|
361
|
+
CLIDisplay.done();
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Copyright 2024 IOTA Stiftung.
|
|
365
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
366
|
+
/**
|
|
367
|
+
* Build the service add command for the CLI.
|
|
368
|
+
* @returns The command.
|
|
369
|
+
*/
|
|
370
|
+
function buildCommandServiceAdd() {
|
|
371
|
+
const command = new Command();
|
|
372
|
+
command
|
|
373
|
+
.name("service-add")
|
|
374
|
+
.summary(I18n.formatMessage("commands.service-add.summary"))
|
|
375
|
+
.description(I18n.formatMessage("commands.service-add.description"))
|
|
376
|
+
.requiredOption(I18n.formatMessage("commands.service-add.options.seed.param"), I18n.formatMessage("commands.service-add.options.seed.description"))
|
|
377
|
+
.requiredOption(I18n.formatMessage("commands.service-add.options.did.param"), I18n.formatMessage("commands.service-add.options.did.description"))
|
|
378
|
+
.requiredOption(I18n.formatMessage("commands.service-add.options.id.param"), I18n.formatMessage("commands.service-add.options.id.description"))
|
|
379
|
+
.requiredOption(I18n.formatMessage("commands.service-add.options.type.param"), I18n.formatMessage("commands.service-add.options.type.description"))
|
|
380
|
+
.requiredOption(I18n.formatMessage("commands.service-add.options.endpoint.param"), I18n.formatMessage("commands.service-add.options.endpoint.description"));
|
|
381
|
+
CLIOptions.output(command, {
|
|
382
|
+
noConsole: true,
|
|
383
|
+
json: true,
|
|
384
|
+
env: true,
|
|
385
|
+
mergeJson: true,
|
|
386
|
+
mergeEnv: true
|
|
387
|
+
});
|
|
388
|
+
command
|
|
389
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
390
|
+
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
391
|
+
.action(actionCommandServiceAdd);
|
|
392
|
+
return command;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Action the service add command.
|
|
396
|
+
* @param opts The options for the command.
|
|
397
|
+
* @param opts.seed The private key for the controller.
|
|
398
|
+
* @param opts.did The identity of the document to add to.
|
|
399
|
+
* @param opts.id The id of the service to add.
|
|
400
|
+
* @param opts.type The type of the service to add.
|
|
401
|
+
* @param opts.endpoint The service endpoint.
|
|
402
|
+
* @param opts.node The node URL.
|
|
403
|
+
* @param opts.explorer The explorer URL.
|
|
404
|
+
*/
|
|
405
|
+
async function actionCommandServiceAdd(opts) {
|
|
406
|
+
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
407
|
+
const did = CLIParam.stringValue("did", opts.did);
|
|
408
|
+
const id = CLIParam.stringValue("id", opts.id);
|
|
409
|
+
const type = CLIParam.stringValue("type", opts.type);
|
|
410
|
+
const endpoint = CLIParam.url("endpoint", opts.endpoint);
|
|
411
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
412
|
+
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
413
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.did"), did);
|
|
414
|
+
CLIDisplay.value(I18n.formatMessage("commands.service-add.labels.serviceId"), id);
|
|
415
|
+
CLIDisplay.value(I18n.formatMessage("commands.service-add.labels.serviceType"), type);
|
|
416
|
+
CLIDisplay.value(I18n.formatMessage("commands.service-add.labels.serviceEndpoint"), endpoint);
|
|
417
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
418
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explorer"), explorerEndpoint);
|
|
419
|
+
CLIDisplay.break();
|
|
420
|
+
setupVault();
|
|
421
|
+
const vaultSeedId = "local-seed";
|
|
422
|
+
const localIdentity = "local";
|
|
423
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
424
|
+
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
425
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
426
|
+
config: {
|
|
427
|
+
clientOptions: {
|
|
428
|
+
nodes: [nodeEndpoint],
|
|
429
|
+
localPow: true
|
|
430
|
+
},
|
|
431
|
+
vaultSeedId
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
435
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
436
|
+
config: {
|
|
437
|
+
clientOptions: {
|
|
438
|
+
nodes: [nodeEndpoint],
|
|
439
|
+
localPow: true
|
|
440
|
+
},
|
|
441
|
+
vaultSeedId
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
CLIDisplay.task(I18n.formatMessage("commands.service-add.progress.addingService"));
|
|
445
|
+
CLIDisplay.break();
|
|
446
|
+
CLIDisplay.spinnerStart();
|
|
447
|
+
const service = await iotaIdentityConnector.addService(localIdentity, did, id, type, endpoint);
|
|
448
|
+
CLIDisplay.spinnerStop();
|
|
449
|
+
if (Is.stringValue(opts?.json)) {
|
|
450
|
+
await CLIUtils.writeJsonFile(opts.json, service, opts.mergeJson);
|
|
451
|
+
}
|
|
452
|
+
if (Is.stringValue(opts?.env)) {
|
|
453
|
+
await CLIUtils.writeEnvFile(opts.env, [
|
|
454
|
+
`DID_SERVICE_ID="${service.id}"`,
|
|
455
|
+
`DID_SERVICE_TYPE="${service.type}"`,
|
|
456
|
+
`DID_SERVICE_ENDPOINT="${service.serviceEndpoint}"`
|
|
457
|
+
], opts.mergeEnv);
|
|
458
|
+
}
|
|
459
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaIdentityUtils.didToAddress(did)}?tab=DID`);
|
|
460
|
+
CLIDisplay.break();
|
|
461
|
+
CLIDisplay.done();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// Copyright 2024 IOTA Stiftung.
|
|
465
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
466
|
+
/**
|
|
467
|
+
* Build the service remove command for the CLI.
|
|
468
|
+
* @returns The command.
|
|
469
|
+
*/
|
|
470
|
+
function buildCommandServiceRemove() {
|
|
471
|
+
const command = new Command();
|
|
472
|
+
command
|
|
473
|
+
.name("service-remove")
|
|
474
|
+
.summary(I18n.formatMessage("commands.service-remove.summary"))
|
|
475
|
+
.description(I18n.formatMessage("commands.service-remove.description"))
|
|
476
|
+
.requiredOption(I18n.formatMessage("commands.service-remove.options.seed.param"), I18n.formatMessage("commands.service-remove.options.seed.description"))
|
|
477
|
+
.requiredOption(I18n.formatMessage("commands.service-remove.options.id.param"), I18n.formatMessage("commands.service-remove.options.id.description"));
|
|
478
|
+
CLIOptions.output(command, {
|
|
479
|
+
noConsole: true,
|
|
480
|
+
json: true,
|
|
481
|
+
env: true,
|
|
482
|
+
mergeJson: true,
|
|
483
|
+
mergeEnv: true
|
|
484
|
+
});
|
|
485
|
+
command
|
|
486
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
487
|
+
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
488
|
+
.action(actionCommandServiceRemove);
|
|
489
|
+
return command;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* Action the service remove command.
|
|
493
|
+
* @param opts The options for the command.
|
|
494
|
+
* @param opts.seed The private key for the controller.
|
|
495
|
+
* @param opts.id The id of the service to remove.
|
|
496
|
+
* @param opts.node The node URL.
|
|
497
|
+
* @param opts.explorer The explorer URL.
|
|
498
|
+
*/
|
|
499
|
+
async function actionCommandServiceRemove(opts) {
|
|
500
|
+
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
501
|
+
const id = CLIParam.stringValue("id", opts.id);
|
|
502
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
503
|
+
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
504
|
+
CLIDisplay.value(I18n.formatMessage("commands.service-remove.labels.serviceId"), id);
|
|
505
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
506
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explorer"), explorerEndpoint);
|
|
507
|
+
CLIDisplay.break();
|
|
508
|
+
setupVault();
|
|
509
|
+
const vaultSeedId = "local-seed";
|
|
510
|
+
const localIdentity = "local";
|
|
511
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
512
|
+
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
513
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
514
|
+
config: {
|
|
515
|
+
clientOptions: {
|
|
516
|
+
nodes: [nodeEndpoint],
|
|
517
|
+
localPow: true
|
|
518
|
+
},
|
|
519
|
+
vaultSeedId
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
523
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
524
|
+
config: {
|
|
525
|
+
clientOptions: {
|
|
526
|
+
nodes: [nodeEndpoint],
|
|
527
|
+
localPow: true
|
|
528
|
+
},
|
|
529
|
+
vaultSeedId
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
CLIDisplay.task(I18n.formatMessage("commands.service-remove.progress.removingService"));
|
|
533
|
+
CLIDisplay.break();
|
|
534
|
+
CLIDisplay.spinnerStart();
|
|
535
|
+
await iotaIdentityConnector.removeService(localIdentity, id);
|
|
536
|
+
CLIDisplay.spinnerStop();
|
|
537
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaIdentityUtils.didToAddress(DocumentHelper.parse(id).id)}?tab=DID`);
|
|
538
|
+
CLIDisplay.break();
|
|
539
|
+
CLIDisplay.done();
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Copyright 2024 IOTA Stiftung.
|
|
543
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
544
|
+
/**
|
|
545
|
+
* Build the verifiable credential create command for the CLI.
|
|
546
|
+
* @returns The command.
|
|
547
|
+
*/
|
|
548
|
+
function buildCommandVerifiableCredentialCreate() {
|
|
549
|
+
const command = new Command();
|
|
550
|
+
command
|
|
551
|
+
.name("verifiable-credential-create")
|
|
552
|
+
.summary(I18n.formatMessage("commands.verifiable-credential-create.summary"))
|
|
553
|
+
.description(I18n.formatMessage("commands.verifiable-credential-create.description"))
|
|
554
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-create.options.id.param"), I18n.formatMessage("commands.verifiable-credential-create.options.id.description"))
|
|
555
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-create.options.private-key.param"), I18n.formatMessage("commands.verifiable-credential-create.options.private-key.description"))
|
|
556
|
+
.option(I18n.formatMessage("commands.verifiable-credential-create.options.credential-id.param"), I18n.formatMessage("commands.verifiable-credential-create.options.credential-id.description"))
|
|
557
|
+
.option(I18n.formatMessage("commands.verifiable-credential-create.options.types.param"), I18n.formatMessage("commands.verifiable-credential-create.options.types.description"))
|
|
558
|
+
.option(I18n.formatMessage("commands.verifiable-credential-create.options.contexts.param"), I18n.formatMessage("commands.verifiable-credential-create.options.contexts.description"))
|
|
559
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-create.options.subject-json.param"), I18n.formatMessage("commands.verifiable-credential-create.options.subject-json.description"))
|
|
560
|
+
.option(I18n.formatMessage("commands.verifiable-credential-create.options.revocation-index.param"), I18n.formatMessage("commands.verifiable-credential-create.options.revocation-index.description"));
|
|
561
|
+
CLIOptions.output(command, {
|
|
562
|
+
noConsole: true,
|
|
563
|
+
json: true,
|
|
564
|
+
env: true,
|
|
565
|
+
mergeJson: true,
|
|
566
|
+
mergeEnv: true
|
|
567
|
+
});
|
|
568
|
+
command
|
|
569
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
570
|
+
.action(actionCommandVerifiableCredentialCreate);
|
|
571
|
+
return command;
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Action the verifiable credential create command.
|
|
575
|
+
* @param opts The options for the command.
|
|
576
|
+
* @param opts.id The id of the verification method to use for the credential.
|
|
577
|
+
* @param opts.privateKey The private key for the verification method.
|
|
578
|
+
* @param opts.credentialId The id of the credential.
|
|
579
|
+
* @param opts.types The types for the credential.
|
|
580
|
+
* @param opts.subjectJson The JSON data for the subject.
|
|
581
|
+
* @param opts.contexts The contexts for the credential.
|
|
582
|
+
* @param opts.revocationIndex The revocation index for the credential.
|
|
583
|
+
* @param opts.node The node URL.
|
|
584
|
+
*/
|
|
585
|
+
async function actionCommandVerifiableCredentialCreate(opts) {
|
|
586
|
+
if (!Is.undefined(opts.types)) {
|
|
587
|
+
Guards.arrayValue("commands", "types", opts.types);
|
|
588
|
+
}
|
|
589
|
+
if (!Is.undefined(opts.contexts)) {
|
|
590
|
+
Guards.arrayValue("commands", "contexts", opts.contexts);
|
|
591
|
+
}
|
|
592
|
+
const id = CLIParam.stringValue("id", opts.id);
|
|
593
|
+
const privateKey = CLIParam.hexBase64("private-key", opts.privateKey);
|
|
594
|
+
const credentialId = CLIParam.stringValue("credential-id", opts.credentialId);
|
|
595
|
+
const types = opts.types;
|
|
596
|
+
const contexts = opts.contexts;
|
|
597
|
+
const subjectJson = path.resolve(CLIParam.stringValue("subject-json", opts.subjectJson));
|
|
598
|
+
const revocationIndex = Coerce.number(opts.revocationIndex);
|
|
599
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
600
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-create.labels.verificationMethodId"), id);
|
|
601
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-create.labels.credentialId"), credentialId);
|
|
602
|
+
if (Is.arrayValue(types)) {
|
|
603
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-create.labels.types"), types.join(","));
|
|
604
|
+
}
|
|
605
|
+
if (Is.arrayValue(contexts)) {
|
|
606
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-create.labels.contexts"), contexts.join(","));
|
|
607
|
+
}
|
|
608
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-create.labels.subjectJson"), subjectJson);
|
|
609
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-create.labels.revocationIndex"), revocationIndex);
|
|
610
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
611
|
+
CLIDisplay.break();
|
|
612
|
+
setupVault();
|
|
613
|
+
const localIdentity = "local";
|
|
614
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
615
|
+
await vaultConnector.addKey(`${localIdentity}/${id}`, VaultKeyType.Ed25519, privateKey, new Uint8Array());
|
|
616
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
617
|
+
config: {
|
|
618
|
+
clientOptions: {
|
|
619
|
+
nodes: [nodeEndpoint],
|
|
620
|
+
localPow: true
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
625
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
626
|
+
config: {
|
|
627
|
+
clientOptions: {
|
|
628
|
+
nodes: [nodeEndpoint],
|
|
629
|
+
localPow: true
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
CLIDisplay.task(I18n.formatMessage("commands.verifiable-credential-create.progress.loadingSubjectData"));
|
|
634
|
+
CLIDisplay.break();
|
|
635
|
+
const jsonData = await CLIUtils.readJsonFile(subjectJson);
|
|
636
|
+
if (Is.undefined(jsonData)) {
|
|
637
|
+
throw new GeneralError("commands", "commands.verifiable-credential-create.subjectJsonFileNotFound");
|
|
638
|
+
}
|
|
639
|
+
CLIDisplay.task(I18n.formatMessage("commands.verifiable-credential-create.progress.creatingVerifiableCredential"));
|
|
640
|
+
CLIDisplay.break();
|
|
641
|
+
CLIDisplay.spinnerStart();
|
|
642
|
+
const verifiableCredential = await iotaIdentityConnector.createVerifiableCredential(localIdentity, id, credentialId, types, jsonData, contexts, revocationIndex);
|
|
643
|
+
CLIDisplay.spinnerStop();
|
|
644
|
+
if (opts.console) {
|
|
645
|
+
CLIDisplay.section(I18n.formatMessage("commands.verifiable-credential-create.labels.verifiableCredential"));
|
|
646
|
+
CLIDisplay.write(verifiableCredential.jwt);
|
|
647
|
+
CLIDisplay.break();
|
|
648
|
+
CLIDisplay.break();
|
|
649
|
+
}
|
|
650
|
+
if (Is.stringValue(opts?.json)) {
|
|
651
|
+
await CLIUtils.writeJsonFile(opts.json, { verifiableCredentialJwt: verifiableCredential.jwt }, opts.mergeJson);
|
|
652
|
+
}
|
|
653
|
+
if (Is.stringValue(opts?.env)) {
|
|
654
|
+
await CLIUtils.writeEnvFile(opts.env, [`DID_VERIFIABLE_CREDENTIAL_JWT="${verifiableCredential.jwt}"`], opts.mergeEnv);
|
|
655
|
+
}
|
|
656
|
+
CLIDisplay.done();
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Copyright 2024 IOTA Stiftung.
|
|
660
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
661
|
+
/**
|
|
662
|
+
* Build the verifiable credential revoke command for the CLI.
|
|
663
|
+
* @returns The command.
|
|
664
|
+
*/
|
|
665
|
+
function buildCommandVerifiableCredentialRevoke() {
|
|
666
|
+
const command = new Command();
|
|
667
|
+
command
|
|
668
|
+
.name("verifiable-credential-revoke")
|
|
669
|
+
.summary(I18n.formatMessage("commands.verifiable-credential-revoke.summary"))
|
|
670
|
+
.description(I18n.formatMessage("commands.verifiable-credential-revoke.description"))
|
|
671
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-revoke.options.seed.param"), I18n.formatMessage("commands.verifiable-credential-revoke.options.seed.description"))
|
|
672
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-revoke.options.did.param"), I18n.formatMessage("commands.verifiable-credential-revoke.options.did.description"))
|
|
673
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-revoke.options.revocation-index.param"), I18n.formatMessage("commands.verifiable-credential-revoke.options.revocation-index.description"));
|
|
674
|
+
command
|
|
675
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
676
|
+
.action(actionCommandVerifiableCredentialRevoke);
|
|
677
|
+
return command;
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Action the verifiable credential revoke command.
|
|
681
|
+
* @param opts The options for the command.
|
|
682
|
+
* @param opts.seed The seed to generate the private key for the controller.
|
|
683
|
+
* @param opts.did The id of the document to revoke the index.
|
|
684
|
+
* @param opts.revocationIndex The revocation index for the credential.
|
|
685
|
+
* @param opts.node The node URL.
|
|
686
|
+
*/
|
|
687
|
+
async function actionCommandVerifiableCredentialRevoke(opts) {
|
|
688
|
+
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
689
|
+
const did = CLIParam.stringValue("did", opts.did);
|
|
690
|
+
const revocationIndex = CLIParam.integer("revocation-index", opts.revocationIndex);
|
|
691
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
692
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.did"), did);
|
|
693
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-revoke.labels.revocationIndex"), revocationIndex);
|
|
694
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
695
|
+
CLIDisplay.break();
|
|
696
|
+
setupVault();
|
|
697
|
+
const vaultSeedId = "local-seed";
|
|
698
|
+
const localIdentity = "local";
|
|
699
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
700
|
+
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
701
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
702
|
+
config: {
|
|
703
|
+
clientOptions: {
|
|
704
|
+
nodes: [nodeEndpoint],
|
|
705
|
+
localPow: true
|
|
706
|
+
},
|
|
707
|
+
vaultSeedId
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
711
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
712
|
+
config: {
|
|
713
|
+
clientOptions: {
|
|
714
|
+
nodes: [nodeEndpoint],
|
|
715
|
+
localPow: true
|
|
716
|
+
},
|
|
717
|
+
vaultSeedId
|
|
718
|
+
}
|
|
719
|
+
});
|
|
720
|
+
CLIDisplay.task(I18n.formatMessage("commands.verifiable-credential-revoke.progress.revokingCredential"));
|
|
721
|
+
CLIDisplay.break();
|
|
722
|
+
CLIDisplay.spinnerStart();
|
|
723
|
+
await iotaIdentityConnector.revokeVerifiableCredentials(localIdentity, did, [revocationIndex]);
|
|
724
|
+
CLIDisplay.spinnerStop();
|
|
725
|
+
CLIDisplay.done();
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
// Copyright 2024 IOTA Stiftung.
|
|
729
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
730
|
+
/**
|
|
731
|
+
* Build the verifiable credential unrevoke command for the CLI.
|
|
732
|
+
* @returns The command.
|
|
733
|
+
*/
|
|
734
|
+
function buildCommandVerifiableCredentialUnrevoke() {
|
|
735
|
+
const command = new Command();
|
|
736
|
+
command
|
|
737
|
+
.name("verifiable-credential-unrevoke")
|
|
738
|
+
.summary(I18n.formatMessage("commands.verifiable-credential-unrevoke.summary"))
|
|
739
|
+
.description(I18n.formatMessage("commands.verifiable-credential-unrevoke.description"))
|
|
740
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-unrevoke.options.seed.param"), I18n.formatMessage("commands.verifiable-credential-unrevoke.options.seed.description"))
|
|
741
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-unrevoke.options.did.param"), I18n.formatMessage("commands.verifiable-credential-unrevoke.options.did.description"))
|
|
742
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-unrevoke.options.revocation-index.param"), I18n.formatMessage("commands.verifiable-credential-unrevoke.options.revocation-index.description"));
|
|
743
|
+
command
|
|
744
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
745
|
+
.action(actionCommandVerifiableCredentialUnrevoke);
|
|
746
|
+
return command;
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Action the verifiable credential unrevoke command.
|
|
750
|
+
* @param opts The options for the command.
|
|
751
|
+
* @param opts.seed The seed to generate the private key for the controller.
|
|
752
|
+
* @param opts.did The id of the document to unrevoke the index.
|
|
753
|
+
* @param opts.revocationIndex The revocation index for the credential.
|
|
754
|
+
* @param opts.node The node URL.
|
|
755
|
+
*/
|
|
756
|
+
async function actionCommandVerifiableCredentialUnrevoke(opts) {
|
|
757
|
+
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
758
|
+
const did = CLIParam.stringValue("did", opts.did);
|
|
759
|
+
const revocationIndex = CLIParam.integer("revocation-index", opts.revocationIndex);
|
|
760
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
761
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.did"), did);
|
|
762
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-unrevoke.labels.revocationIndex"), revocationIndex);
|
|
763
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
764
|
+
CLIDisplay.break();
|
|
765
|
+
setupVault();
|
|
766
|
+
const vaultSeedId = "local-seed";
|
|
767
|
+
const localIdentity = "local";
|
|
768
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
769
|
+
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
770
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
771
|
+
config: {
|
|
772
|
+
clientOptions: {
|
|
773
|
+
nodes: [nodeEndpoint],
|
|
774
|
+
localPow: true
|
|
775
|
+
},
|
|
776
|
+
vaultSeedId
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
780
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
781
|
+
config: {
|
|
782
|
+
clientOptions: {
|
|
783
|
+
nodes: [nodeEndpoint],
|
|
784
|
+
localPow: true
|
|
785
|
+
},
|
|
786
|
+
vaultSeedId
|
|
787
|
+
}
|
|
788
|
+
});
|
|
789
|
+
CLIDisplay.task(I18n.formatMessage("commands.verifiable-credential-unrevoke.progress.unrevokingCredential"));
|
|
790
|
+
CLIDisplay.break();
|
|
791
|
+
CLIDisplay.spinnerStart();
|
|
792
|
+
await iotaIdentityConnector.unrevokeVerifiableCredentials(localIdentity, did, [revocationIndex]);
|
|
793
|
+
CLIDisplay.spinnerStop();
|
|
794
|
+
CLIDisplay.done();
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// Copyright 2024 IOTA Stiftung.
|
|
798
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
799
|
+
/**
|
|
800
|
+
* Build the verifiable credential verify command for the CLI.
|
|
801
|
+
* @returns The command.
|
|
802
|
+
*/
|
|
803
|
+
function buildCommandVerifiableCredentialVerify() {
|
|
804
|
+
const command = new Command();
|
|
805
|
+
command
|
|
806
|
+
.name("verifiable-credential-verify")
|
|
807
|
+
.summary(I18n.formatMessage("commands.verifiable-credential-verify.summary"))
|
|
808
|
+
.description(I18n.formatMessage("commands.verifiable-credential-verify.description"))
|
|
809
|
+
.requiredOption(I18n.formatMessage("commands.verifiable-credential-verify.options.jwt.param"), I18n.formatMessage("commands.verifiable-credential-verify.options.jwt.description"));
|
|
810
|
+
CLIOptions.output(command, {
|
|
811
|
+
noConsole: true,
|
|
812
|
+
json: true,
|
|
813
|
+
env: true,
|
|
814
|
+
mergeJson: true,
|
|
815
|
+
mergeEnv: true
|
|
816
|
+
});
|
|
817
|
+
command
|
|
818
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
819
|
+
.action(actionCommandVerifiableCredentialVerify);
|
|
820
|
+
return command;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Action the verifiable credential verify command.
|
|
824
|
+
* @param opts The options for the command.
|
|
825
|
+
* @param opts.jwt The JSON web token for the verifiable credential.
|
|
826
|
+
* @param opts.node The node URL.
|
|
827
|
+
*/
|
|
828
|
+
async function actionCommandVerifiableCredentialVerify(opts) {
|
|
829
|
+
const jwt = CLIParam.stringValue("jwt", opts.jwt);
|
|
830
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
831
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-verify.labels.jwt"), jwt);
|
|
832
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
833
|
+
CLIDisplay.break();
|
|
834
|
+
setupVault();
|
|
835
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
836
|
+
config: {
|
|
837
|
+
clientOptions: {
|
|
838
|
+
nodes: [nodeEndpoint],
|
|
839
|
+
localPow: true
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
844
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
845
|
+
config: {
|
|
846
|
+
clientOptions: {
|
|
847
|
+
nodes: [nodeEndpoint],
|
|
848
|
+
localPow: true
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
CLIDisplay.task(I18n.formatMessage("commands.verifiable-credential-verify.progress.verifyingCredential"));
|
|
853
|
+
CLIDisplay.break();
|
|
854
|
+
CLIDisplay.spinnerStart();
|
|
855
|
+
const verification = await iotaIdentityConnector.checkVerifiableCredential(jwt);
|
|
856
|
+
const isVerified = Is.notEmpty(verification.verifiableCredential);
|
|
857
|
+
const isRevoked = verification.revoked;
|
|
858
|
+
CLIDisplay.spinnerStop();
|
|
859
|
+
if (opts.console) {
|
|
860
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-verify.labels.isVerified"), isVerified);
|
|
861
|
+
CLIDisplay.value(I18n.formatMessage("commands.verifiable-credential-verify.labels.isRevoked"), isRevoked);
|
|
862
|
+
CLIDisplay.break();
|
|
863
|
+
}
|
|
864
|
+
if (Is.stringValue(opts?.json)) {
|
|
865
|
+
await CLIUtils.writeJsonFile(opts.json, { isVerified, isRevoked }, opts.mergeJson);
|
|
866
|
+
}
|
|
867
|
+
if (Is.stringValue(opts?.env)) {
|
|
868
|
+
await CLIUtils.writeEnvFile(opts.env, [
|
|
869
|
+
`DID_VERIFIABLE_CREDENTIAL_VERIFIED="${isVerified}"`,
|
|
870
|
+
`DID_VERIFIABLE_CREDENTIAL_REVOKED="${isRevoked}"`
|
|
871
|
+
], opts.mergeEnv);
|
|
872
|
+
}
|
|
873
|
+
CLIDisplay.done();
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// Copyright 2024 IOTA Stiftung.
|
|
877
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
878
|
+
/**
|
|
879
|
+
* Build the verification method add command for the CLI.
|
|
880
|
+
* @returns The command.
|
|
881
|
+
*/
|
|
882
|
+
function buildCommandVerificationMethodAdd() {
|
|
883
|
+
const command = new Command();
|
|
884
|
+
command
|
|
885
|
+
.name("verification-method-add")
|
|
886
|
+
.summary(I18n.formatMessage("commands.verification-method-add.summary"))
|
|
887
|
+
.description(I18n.formatMessage("commands.verification-method-add.description"))
|
|
888
|
+
.requiredOption(I18n.formatMessage("commands.verification-method-add.options.seed.param"), I18n.formatMessage("commands.verification-method-add.options.seed.description"))
|
|
889
|
+
.requiredOption(I18n.formatMessage("commands.verification-method-add.options.did.param"), I18n.formatMessage("commands.verification-method-add.options.did.description"))
|
|
890
|
+
.addOption(new Option(I18n.formatMessage("commands.verification-method-add.options.type.param"), I18n.formatMessage("commands.verification-method-add.options.type.description"))
|
|
891
|
+
.choices(Object.values(DidVerificationMethodType))
|
|
892
|
+
.makeOptionMandatory())
|
|
893
|
+
.option(I18n.formatMessage("commands.verification-method-add.options.id.param"), I18n.formatMessage("commands.verification-method-add.options.id.description"));
|
|
894
|
+
CLIOptions.output(command, {
|
|
895
|
+
noConsole: true,
|
|
896
|
+
json: true,
|
|
897
|
+
env: true,
|
|
898
|
+
mergeJson: true,
|
|
899
|
+
mergeEnv: true
|
|
900
|
+
});
|
|
901
|
+
command
|
|
902
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
903
|
+
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
904
|
+
.action(actionCommandVerificationMethodAdd);
|
|
905
|
+
return command;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Action the verification method add command.
|
|
909
|
+
* @param opts The options for the command.
|
|
910
|
+
* @param opts.seed The private key for the controller.
|
|
911
|
+
* @param opts.did The identity of the document to add to.
|
|
912
|
+
* @param opts.type The type of the verification method to add.
|
|
913
|
+
* @param opts.id The id of the verification method to add.
|
|
914
|
+
* @param opts.node The node URL.
|
|
915
|
+
* @param opts.explorer The explorer URL.
|
|
916
|
+
*/
|
|
917
|
+
async function actionCommandVerificationMethodAdd(opts) {
|
|
918
|
+
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
919
|
+
const did = CLIParam.stringValue("did", opts.did);
|
|
920
|
+
const type = CLIParam.stringValue("type", opts.type);
|
|
921
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
922
|
+
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
923
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.did"), did);
|
|
924
|
+
CLIDisplay.value(I18n.formatMessage("commands.verification-method-add.labels.verificationMethodType"), type);
|
|
925
|
+
if (Is.stringValue(opts.id)) {
|
|
926
|
+
CLIDisplay.value(I18n.formatMessage("commands.verification-method-add.labels.verificationMethodId"), opts?.id);
|
|
927
|
+
}
|
|
928
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
929
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explorer"), explorerEndpoint);
|
|
930
|
+
CLIDisplay.break();
|
|
931
|
+
setupVault();
|
|
932
|
+
const vaultSeedId = "local-seed";
|
|
933
|
+
const localIdentity = "local";
|
|
934
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
935
|
+
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
936
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
937
|
+
config: {
|
|
938
|
+
clientOptions: {
|
|
939
|
+
nodes: [nodeEndpoint],
|
|
940
|
+
localPow: true
|
|
941
|
+
},
|
|
942
|
+
vaultSeedId
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
946
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
947
|
+
config: {
|
|
948
|
+
clientOptions: {
|
|
949
|
+
nodes: [nodeEndpoint],
|
|
950
|
+
localPow: true
|
|
951
|
+
},
|
|
952
|
+
vaultSeedId
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
CLIDisplay.task(I18n.formatMessage("commands.verification-method-add.progress.addingVerificationMethod"));
|
|
956
|
+
CLIDisplay.break();
|
|
957
|
+
CLIDisplay.spinnerStart();
|
|
958
|
+
const verificationMethod = await iotaIdentityConnector.addVerificationMethod(localIdentity, did, type, opts?.id);
|
|
959
|
+
CLIDisplay.spinnerStop();
|
|
960
|
+
const keyPair = await vaultConnector.getKey(`${localIdentity}/${verificationMethod.id}`);
|
|
961
|
+
const privateKey = Converter.bytesToBase64(keyPair.privateKey);
|
|
962
|
+
const publicKey = Converter.bytesToBase64(keyPair.publicKey);
|
|
963
|
+
if (opts.console) {
|
|
964
|
+
CLIDisplay.value(I18n.formatMessage("commands.verification-method-add.labels.verificationMethodId"), verificationMethod.id);
|
|
965
|
+
CLIDisplay.value(I18n.formatMessage("commands.verification-method-add.labels.privateKey"), privateKey);
|
|
966
|
+
CLIDisplay.value(I18n.formatMessage("commands.verification-method-add.labels.publicKey"), publicKey);
|
|
967
|
+
CLIDisplay.break();
|
|
968
|
+
}
|
|
969
|
+
if (Is.stringValue(opts?.json)) {
|
|
970
|
+
await CLIUtils.writeJsonFile(opts.json, { verificationMethodId: verificationMethod.id, privateKey, publicKey }, opts.mergeJson);
|
|
971
|
+
}
|
|
972
|
+
if (Is.stringValue(opts?.env)) {
|
|
973
|
+
await CLIUtils.writeEnvFile(opts.env, [
|
|
974
|
+
`DID_VERIFICATION_METHOD_ID="${verificationMethod.id}"`,
|
|
975
|
+
`DID_VERIFICATION_METHOD_PRIVATE_KEY="${privateKey}"`,
|
|
976
|
+
`DID_VERIFICATION_METHOD_PUBLIC_KEY="${publicKey}"`
|
|
977
|
+
], opts.mergeEnv);
|
|
978
|
+
}
|
|
979
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaIdentityUtils.didToAddress(did)}?tab=DID`);
|
|
980
|
+
CLIDisplay.break();
|
|
981
|
+
CLIDisplay.done();
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// Copyright 2024 IOTA Stiftung.
|
|
985
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
986
|
+
/**
|
|
987
|
+
* Build the verification method remove command for the CLI.
|
|
988
|
+
* @returns The command.
|
|
989
|
+
*/
|
|
990
|
+
function buildCommandVerificationMethodRemove() {
|
|
991
|
+
const command = new Command();
|
|
992
|
+
command
|
|
993
|
+
.name("verification-method-remove")
|
|
994
|
+
.summary(I18n.formatMessage("commands.verification-method-remove.summary"))
|
|
995
|
+
.description(I18n.formatMessage("commands.verification-method-remove.description"))
|
|
996
|
+
.requiredOption(I18n.formatMessage("commands.verification-method-remove.options.seed.param"), I18n.formatMessage("commands.verification-method-remove.options.seed.description"))
|
|
997
|
+
.requiredOption(I18n.formatMessage("commands.verification-method-remove.options.id.param"), I18n.formatMessage("commands.verification-method-remove.options.id.description"));
|
|
998
|
+
CLIOptions.output(command, {
|
|
999
|
+
noConsole: true,
|
|
1000
|
+
json: true,
|
|
1001
|
+
env: true,
|
|
1002
|
+
mergeJson: true,
|
|
1003
|
+
mergeEnv: true
|
|
1004
|
+
});
|
|
1005
|
+
command
|
|
1006
|
+
.option(I18n.formatMessage("commands.common.options.node.param"), I18n.formatMessage("commands.common.options.node.description"), "!NODE_URL")
|
|
1007
|
+
.option(I18n.formatMessage("commands.common.options.explorer.param"), I18n.formatMessage("commands.common.options.explorer.description"), "!EXPLORER_URL")
|
|
1008
|
+
.action(actionCommandVerificationMethodRemove);
|
|
1009
|
+
return command;
|
|
1010
|
+
}
|
|
1011
|
+
/**
|
|
1012
|
+
* Action the verification method remove command.
|
|
1013
|
+
* @param opts The options for the command.
|
|
1014
|
+
* @param opts.seed The private key for the controller.
|
|
1015
|
+
* @param opts.id The id of the verification method to remove.
|
|
1016
|
+
* @param opts.node The node URL.
|
|
1017
|
+
* @param opts.explorer The explorer URL.
|
|
1018
|
+
*/
|
|
1019
|
+
async function actionCommandVerificationMethodRemove(opts) {
|
|
1020
|
+
const seed = CLIParam.hexBase64("seed", opts.seed);
|
|
1021
|
+
const id = CLIParam.stringValue("id", opts.id);
|
|
1022
|
+
const nodeEndpoint = CLIParam.url("node", opts.node);
|
|
1023
|
+
const explorerEndpoint = CLIParam.url("explorer", opts.explorer);
|
|
1024
|
+
CLIDisplay.value(I18n.formatMessage("commands.verification-method-add.labels.verificationMethodId"), id);
|
|
1025
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.node"), nodeEndpoint);
|
|
1026
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explorer"), explorerEndpoint);
|
|
1027
|
+
CLIDisplay.break();
|
|
1028
|
+
setupVault();
|
|
1029
|
+
const vaultSeedId = "local-seed";
|
|
1030
|
+
const localIdentity = "local";
|
|
1031
|
+
const vaultConnector = VaultConnectorFactory.get("vault");
|
|
1032
|
+
await vaultConnector.setSecret(`${localIdentity}/${vaultSeedId}`, Converter.bytesToBase64(seed));
|
|
1033
|
+
const iotaWalletConnector = new IotaWalletConnector({
|
|
1034
|
+
config: {
|
|
1035
|
+
clientOptions: {
|
|
1036
|
+
nodes: [nodeEndpoint],
|
|
1037
|
+
localPow: true
|
|
1038
|
+
},
|
|
1039
|
+
vaultSeedId
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
WalletConnectorFactory.register("wallet", () => iotaWalletConnector);
|
|
1043
|
+
const iotaIdentityConnector = new IotaIdentityConnector({
|
|
1044
|
+
config: {
|
|
1045
|
+
clientOptions: {
|
|
1046
|
+
nodes: [nodeEndpoint],
|
|
1047
|
+
localPow: true
|
|
1048
|
+
},
|
|
1049
|
+
vaultSeedId
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1052
|
+
CLIDisplay.task(I18n.formatMessage("commands.verification-method-remove.progress.removingVerificationMethod"));
|
|
1053
|
+
CLIDisplay.break();
|
|
1054
|
+
CLIDisplay.spinnerStart();
|
|
1055
|
+
await iotaIdentityConnector.removeVerificationMethod(localIdentity, id);
|
|
1056
|
+
CLIDisplay.spinnerStop();
|
|
1057
|
+
CLIDisplay.value(I18n.formatMessage("commands.common.labels.explore"), `${StringHelper.trimTrailingSlashes(explorerEndpoint)}/addr/${IotaIdentityUtils.didToAddress(DocumentHelper.parse(id).id)}?tab=DID`);
|
|
1058
|
+
CLIDisplay.break();
|
|
1059
|
+
CLIDisplay.done();
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
// Copyright 2024 IOTA Stiftung.
|
|
1063
|
+
// SPDX-License-Identifier: Apache-2.0.
|
|
1064
|
+
/**
|
|
1065
|
+
* The main entry point for the CLI.
|
|
1066
|
+
*/
|
|
1067
|
+
class CLI extends CLIBase {
|
|
1068
|
+
/**
|
|
1069
|
+
* Run the app.
|
|
1070
|
+
* @param argv The process arguments.
|
|
1071
|
+
* @param localesDirectory The directory for the locales, default to relative to the script.
|
|
1072
|
+
* @returns The exit code.
|
|
1073
|
+
*/
|
|
1074
|
+
async run(argv, localesDirectory) {
|
|
1075
|
+
return this.execute({
|
|
1076
|
+
title: "TWIN Identity",
|
|
1077
|
+
appName: "twin-identity",
|
|
1078
|
+
version: "0.0.3-next.18",
|
|
1079
|
+
icon: "🌍",
|
|
1080
|
+
supportsEnvFiles: true
|
|
1081
|
+
}, localesDirectory ?? path.join(path.dirname(fileURLToPath(import.meta.url)), "../locales"), argv);
|
|
1082
|
+
}
|
|
1083
|
+
/**
|
|
1084
|
+
* Get the commands for the CLI.
|
|
1085
|
+
* @param program The main program to add the commands to.
|
|
1086
|
+
* @internal
|
|
1087
|
+
*/
|
|
1088
|
+
getCommands(program) {
|
|
1089
|
+
return [
|
|
1090
|
+
buildCommandMnemonic(),
|
|
1091
|
+
buildCommandAddress(),
|
|
1092
|
+
buildCommandFaucet(),
|
|
1093
|
+
buildCommandTransfer(),
|
|
1094
|
+
buildCommandIdentityCreate(),
|
|
1095
|
+
buildCommandIdentityResolve(),
|
|
1096
|
+
buildCommandVerificationMethodAdd(),
|
|
1097
|
+
buildCommandVerificationMethodRemove(),
|
|
1098
|
+
buildCommandServiceAdd(),
|
|
1099
|
+
buildCommandServiceRemove(),
|
|
1100
|
+
buildCommandVerifiableCredentialCreate(),
|
|
1101
|
+
buildCommandVerifiableCredentialVerify(),
|
|
1102
|
+
buildCommandVerifiableCredentialRevoke(),
|
|
1103
|
+
buildCommandVerifiableCredentialUnrevoke(),
|
|
1104
|
+
buildCommandProofCreate(),
|
|
1105
|
+
buildCommandProofVerify()
|
|
1106
|
+
];
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
export { CLI, actionCommandIdentityCreate, actionCommandIdentityResolve, actionCommandProofCreate, actionCommandProofVerify, actionCommandServiceAdd, actionCommandServiceRemove, actionCommandVerifiableCredentialCreate, actionCommandVerifiableCredentialRevoke, actionCommandVerifiableCredentialUnrevoke, actionCommandVerifiableCredentialVerify, actionCommandVerificationMethodAdd, actionCommandVerificationMethodRemove, buildCommandIdentityCreate, buildCommandIdentityResolve, buildCommandProofCreate, buildCommandProofVerify, buildCommandServiceAdd, buildCommandServiceRemove, buildCommandVerifiableCredentialCreate, buildCommandVerifiableCredentialRevoke, buildCommandVerifiableCredentialUnrevoke, buildCommandVerifiableCredentialVerify, buildCommandVerificationMethodAdd, buildCommandVerificationMethodRemove };
|