@cef-ebsi/cli 1.3.2 → 1.4.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.
Files changed (187) hide show
  1. package/bin/cli.js +1 -1
  2. package/dist/abi/pilot/DidRegistry.js +568 -0
  3. package/dist/abi/pilot/DidRegistry.js.map +1 -0
  4. package/dist/abi/pilot/SchemaSCRegistry.js +264 -0
  5. package/dist/abi/pilot/SchemaSCRegistry.js.map +1 -0
  6. package/dist/abi/pilot/Timestamp.js +658 -0
  7. package/dist/abi/pilot/Timestamp.js.map +1 -0
  8. package/dist/abi/pilot/Tir.js +428 -0
  9. package/dist/abi/pilot/Tir.js.map +1 -0
  10. package/dist/abi/pilot/TnT.js +842 -0
  11. package/dist/abi/pilot/TnT.js.map +1 -0
  12. package/dist/abi/pilot/Tpr.js +492 -0
  13. package/dist/abi/pilot/Tpr.js.map +1 -0
  14. package/dist/abi/test/DidRegistry.js +144 -658
  15. package/dist/abi/test/DidRegistry.js.map +1 -1
  16. package/dist/abi/test/SchemaSCRegistry.js +101 -810
  17. package/dist/abi/test/SchemaSCRegistry.js.map +1 -1
  18. package/dist/abi/test/Timestamp.js +239 -673
  19. package/dist/abi/test/Timestamp.js.map +1 -1
  20. package/dist/abi/test/Tir.js +167 -636
  21. package/dist/abi/test/Tir.js.map +1 -1
  22. package/dist/abi/test/TnT.js +842 -0
  23. package/dist/abi/test/TnT.js.map +1 -0
  24. package/dist/abi/test/Tpr.js +166 -942
  25. package/dist/abi/test/Tpr.js.map +1 -1
  26. package/dist/app.js +444 -443
  27. package/dist/app.js.map +1 -1
  28. package/dist/buildParam/{didV3.js → didr.js} +182 -204
  29. package/dist/buildParam/didr.js.map +1 -0
  30. package/dist/buildParam/index.js +32 -48
  31. package/dist/buildParam/index.js.map +1 -1
  32. package/dist/buildParam/{timestampV2.js → timestamp.js} +137 -136
  33. package/dist/buildParam/timestamp.js.map +1 -0
  34. package/dist/buildParam/{tirV3.js → tir.js} +57 -59
  35. package/dist/buildParam/tir.js.map +1 -0
  36. package/dist/buildParam/{tntV2.js → tnt.js} +62 -61
  37. package/dist/buildParam/tnt.js.map +1 -0
  38. package/dist/buildParam/{tprV2.js → tpr.js} +34 -33
  39. package/dist/buildParam/tpr.js.map +1 -0
  40. package/dist/buildParam/{tsrV2.js → tsr.js} +39 -38
  41. package/dist/buildParam/tsr.js.map +1 -0
  42. package/dist/cli.js +1 -0
  43. package/dist/cli.js.map +1 -1
  44. package/dist/commands/{authorisation-v4.js → authorisation.js} +78 -71
  45. package/dist/commands/authorisation.js.map +1 -0
  46. package/dist/commands/compute.js +389 -389
  47. package/dist/commands/compute.js.map +1 -1
  48. package/dist/commands/{conformance-v3.js → conformance.js} +236 -248
  49. package/dist/commands/conformance.js.map +1 -0
  50. package/dist/commands/hardwarewallet.js +5 -5
  51. package/dist/commands/hardwarewallet.js.map +1 -1
  52. package/dist/commands/index.js +4 -4
  53. package/dist/commands/index.js.map +1 -1
  54. package/dist/commands/{ledger-v4.js → ledger.js} +141 -128
  55. package/dist/commands/ledger.js.map +1 -0
  56. package/dist/commands/tnl.js +10 -9
  57. package/dist/commands/tnl.js.map +1 -1
  58. package/dist/commands/tsr.js +46 -0
  59. package/dist/commands/tsr.js.map +1 -0
  60. package/dist/commands/view.js +8 -8
  61. package/dist/commands/view.js.map +1 -1
  62. package/dist/config.js +280 -279
  63. package/dist/config.js.map +1 -1
  64. package/dist/index.js +3 -3
  65. package/dist/index.js.map +1 -1
  66. package/dist/interfaces/index.js +1 -1
  67. package/dist/interfaces/index.js.map +1 -1
  68. package/dist/programs/migrateDid.js +33 -33
  69. package/dist/programs/migrateDid.js.map +1 -1
  70. package/dist/programs/migrateDids.js +39 -42
  71. package/dist/programs/migrateDids.js.map +1 -1
  72. package/dist/programs/migrateTsr.js +109 -113
  73. package/dist/programs/migrateTsr.js.map +1 -1
  74. package/dist/scripts/accreditAndAuthorize/conformance/step1 +1 -1
  75. package/dist/scripts/accreditAndAuthorize/test/step1 +1 -1
  76. package/dist/scripts/accreditTI +1 -1
  77. package/dist/scripts/assets/CTRevocableCredential.json +1 -1
  78. package/dist/scripts/assets/CredentialToAttestVerifiableAuthorisationForTrustChain.json +2 -2
  79. package/dist/scripts/assets/TrustedNodesList.json +1 -1
  80. package/dist/scripts/assets/VerifiableAccreditationToAccredit.json +2 -2
  81. package/dist/scripts/assets/VerifiableAccreditationToAttest.json +2 -2
  82. package/dist/scripts/assets/VerifiableAuthorisationForTrustChain.json +1 -1
  83. package/dist/scripts/assets/VerifiableAuthorisationToOnboard.json +1 -1
  84. package/dist/scripts/bootstrap/6-setupConformanceIssuer +1 -1
  85. package/dist/scripts/issueVcOnboard +1 -1
  86. package/dist/scripts/issueVcRootTAO +1 -1
  87. package/dist/scripts/issueVcTAO +2 -2
  88. package/dist/scripts/issueVcTI +2 -2
  89. package/dist/scripts/issueVcTnl +1 -1
  90. package/dist/scripts/issue_CTRevocableCredential +1 -1
  91. package/dist/scripts/issue_SelfAttestationSupportOffice +2 -2
  92. package/dist/scripts/issue_VerifiableAccreditationToAccredit +2 -2
  93. package/dist/scripts/issue_VerifiableAccreditationToAttest +2 -2
  94. package/dist/scripts/issue_VerifiableAuthorisationForTrustChain +1 -1
  95. package/dist/scripts/issue_VerifiableAuthorisationToOnboard +1 -1
  96. package/dist/scripts/updateVcRootTAO +1 -1
  97. package/dist/scripts/updateVcTAO +2 -2
  98. package/dist/scripts/updateVcTI +2 -2
  99. package/dist/scripts/{wctv3 → wct}/accreditAndAuthorize +1 -1
  100. package/dist/tsconfig.build.tsbuildinfo +1 -0
  101. package/dist/utils/Client.js +81 -68
  102. package/dist/utils/Client.js.map +1 -1
  103. package/dist/utils/HardwareWallet.js +169 -165
  104. package/dist/utils/HardwareWallet.js.map +1 -1
  105. package/dist/utils/http.js +24 -27
  106. package/dist/utils/http.js.map +1 -1
  107. package/dist/utils/index.js +3 -3
  108. package/dist/utils/index.js.map +1 -1
  109. package/dist/utils/jsonrpc.js +14 -14
  110. package/dist/utils/jsonrpc.js.map +1 -1
  111. package/dist/utils/print.js +19 -19
  112. package/dist/utils/print.js.map +1 -1
  113. package/dist/utils/utils.js +180 -173
  114. package/dist/utils/utils.js.map +1 -1
  115. package/package.json +70 -46
  116. package/dist/abi/pilot/DidRegistryV3.js +0 -1082
  117. package/dist/abi/pilot/DidRegistryV3.js.map +0 -1
  118. package/dist/abi/pilot/DidRegistryV4.js +0 -942
  119. package/dist/abi/pilot/DidRegistryV4.js.map +0 -1
  120. package/dist/abi/pilot/SchemaSCRegistryV2.js +0 -474
  121. package/dist/abi/pilot/SchemaSCRegistryV2.js.map +0 -1
  122. package/dist/abi/pilot/TimestampV2.js +0 -1128
  123. package/dist/abi/pilot/TimestampV2.js.map +0 -1
  124. package/dist/abi/pilot/TimestampV3.js +0 -995
  125. package/dist/abi/pilot/TimestampV3.js.map +0 -1
  126. package/dist/abi/pilot/TirV3.js +0 -496
  127. package/dist/abi/pilot/TirV3.js.map +0 -1
  128. package/dist/abi/pilot/TirV4.js +0 -710
  129. package/dist/abi/pilot/TirV4.js.map +0 -1
  130. package/dist/abi/pilot/TnTV1.js +0 -1375
  131. package/dist/abi/pilot/TnTV1.js.map +0 -1
  132. package/dist/abi/pilot/TprV2.js +0 -889
  133. package/dist/abi/pilot/TprV2.js.map +0 -1
  134. package/dist/abi/pilot/TprV3.js +0 -707
  135. package/dist/abi/pilot/TprV3.js.map +0 -1
  136. package/dist/abi/pilot/TsrV3.js +0 -571
  137. package/dist/abi/pilot/TsrV3.js.map +0 -1
  138. package/dist/abi/test/DidRegistryV3.js +0 -1089
  139. package/dist/abi/test/DidRegistryV3.js.map +0 -1
  140. package/dist/abi/test/DidRegistryV4.js +0 -960
  141. package/dist/abi/test/DidRegistryV4.js.map +0 -1
  142. package/dist/abi/test/SchemaSCRegistryV2.js +0 -474
  143. package/dist/abi/test/SchemaSCRegistryV2.js.map +0 -1
  144. package/dist/abi/test/TimestampV2.js +0 -1128
  145. package/dist/abi/test/TimestampV2.js.map +0 -1
  146. package/dist/abi/test/TimestampV3.js +0 -995
  147. package/dist/abi/test/TimestampV3.js.map +0 -1
  148. package/dist/abi/test/TirV3.js +0 -496
  149. package/dist/abi/test/TirV3.js.map +0 -1
  150. package/dist/abi/test/TirV4.js +0 -710
  151. package/dist/abi/test/TirV4.js.map +0 -1
  152. package/dist/abi/test/TnTV1.js +0 -1375
  153. package/dist/abi/test/TnTV1.js.map +0 -1
  154. package/dist/abi/test/TprV2.js +0 -889
  155. package/dist/abi/test/TprV2.js.map +0 -1
  156. package/dist/abi/test/TprV3.js +0 -707
  157. package/dist/abi/test/TprV3.js.map +0 -1
  158. package/dist/abi/test/TsrV3.js +0 -571
  159. package/dist/abi/test/TsrV3.js.map +0 -1
  160. package/dist/buildParam/didV3.js.map +0 -1
  161. package/dist/buildParam/didV4.js +0 -326
  162. package/dist/buildParam/didV4.js.map +0 -1
  163. package/dist/buildParam/timestampV2.js.map +0 -1
  164. package/dist/buildParam/timestampV3.js +0 -317
  165. package/dist/buildParam/timestampV3.js.map +0 -1
  166. package/dist/buildParam/tirV3.js.map +0 -1
  167. package/dist/buildParam/tirV4.js +0 -119
  168. package/dist/buildParam/tirV4.js.map +0 -1
  169. package/dist/buildParam/tntV1.js +0 -185
  170. package/dist/buildParam/tntV1.js.map +0 -1
  171. package/dist/buildParam/tntV2.js.map +0 -1
  172. package/dist/buildParam/tprV2.js.map +0 -1
  173. package/dist/buildParam/tprV3.js +0 -82
  174. package/dist/buildParam/tprV3.js.map +0 -1
  175. package/dist/buildParam/tsrV2.js.map +0 -1
  176. package/dist/buildParam/tsrV3.js +0 -110
  177. package/dist/buildParam/tsrV3.js.map +0 -1
  178. package/dist/commands/authorisation-v4.js.map +0 -1
  179. package/dist/commands/authorisation-v5.js +0 -119
  180. package/dist/commands/authorisation-v5.js.map +0 -1
  181. package/dist/commands/conformance-v3.js.map +0 -1
  182. package/dist/commands/ledger-v4.js.map +0 -1
  183. package/dist/tsconfig.tsbuildinfo +0 -1
  184. /package/dist/scripts/{wctv3 → wct}/holderWallet +0 -0
  185. /package/dist/scripts/{wctv3 → wct}/issueToHolder +0 -0
  186. /package/dist/scripts/{wctv3 → wct}/pda1 +0 -0
  187. /package/dist/scripts/{wctv3 → wct}/verifier +0 -0
package/dist/app.js CHANGED
@@ -1,18 +1,17 @@
1
- /* eslint-disable no-use-before-define, @typescript-eslint/no-use-before-define */
2
- import { URL } from "node:url";
3
- import { ethers } from "ethers";
4
1
  import { EbsiWallet } from "@cef-ebsi/wallet-lib";
5
- import lodashSet from "lodash.set";
6
- import { calculateJwkThumbprint } from "jose";
7
- import fs from "fs";
8
- import path from "path";
2
+ import { ethers } from "ethers";
9
3
  import Joi from "joi";
10
- import { loadConfig, } from "./config.js";
11
- import * as utils from "./utils/index.js";
4
+ import { calculateJwkThumbprint } from "jose";
5
+ import lodashSet from "lodash.set";
6
+ import fs from "node:fs";
7
+ import path from "node:path";
8
+ import { URL } from "node:url";
12
9
  import { buildParam } from "./buildParam/index.js";
13
- import { jsonrpcBody, paramSignedTransaction, parseLine, prefixWith0x, HardwareWallet, } from "./utils/index.js";
10
+ import { authorisation, compute, conformance, hardwarewallet, ledger, tnl, view, waitToBeMined, } from "./commands/index.js";
11
+ import { loadConfig, } from "./config.js";
14
12
  import { Client } from "./utils/Client.js";
15
- import { authorisationV4, compute, view, conformanceV3, ledgerV4, waitToBeMined, hardwarewallet, tnl, } from "./commands/index.js";
13
+ import * as utils from "./utils/index.js";
14
+ import { HardwareWallet, jsonrpcBody, paramSignedTransaction, parseLine, prefixWith0x, } from "./utils/index.js";
16
15
  let config = loadConfig();
17
16
  let client = new Client();
18
17
  let transactionInfo;
@@ -24,16 +23,198 @@ const rtVars = {}; // runtime variables
24
23
  const algSchema = Joi.string()
25
24
  .valid("ES256K", "ES256", "RS256", "EdDSA")
26
25
  .required();
27
- async function setVar(key, value, printVar = true) {
28
- lodashSet(rtVars, key, value);
29
- if (key.startsWith("user.")) {
30
- await execCommand("using user user");
31
- return;
26
+ export async function execCommand(command, printCommand = false) {
27
+ if (printCommand)
28
+ console.log(`==> ${command}`);
29
+ const parts = parseLine(command);
30
+ let varName = "";
31
+ if (parts.length === 0)
32
+ return 0;
33
+ if (typeof parts[0] === "string" && parts[0].includes(":")) {
34
+ varName = parts[0].replace(":", "");
35
+ parts.shift();
36
+ }
37
+ const [part0, part1] = parts;
38
+ const parts2 = parts.slice(2);
39
+ const method = part0;
40
+ const word1 = part1;
41
+ Joi.assert(method, Joi.string());
42
+ // APIs linked to smart contracts
43
+ if (["did", "timestamp", "tir", "tnt", "tpr", "tsr"].includes(method)) {
44
+ Joi.assert(word1, Joi.string());
45
+ const response = await smartContractApi(method, word1, ...parts2);
46
+ if (varName)
47
+ await setVar(varName, response);
48
+ return response;
49
+ }
50
+ const schemaStrings = Joi.array().items(Joi.string());
51
+ const context = {
52
+ client,
53
+ config,
54
+ httpOpts,
55
+ rtVars,
56
+ token,
57
+ transactionInfo,
58
+ };
59
+ // Other APIs and configurations
60
+ switch (method) {
61
+ case "authorisation": {
62
+ Joi.assert(word1, Joi.string());
63
+ Joi.assert(parts2, schemaStrings);
64
+ const inputs = parts2.map((p) => readValue(p));
65
+ const response = await authorisation(word1, inputs, context);
66
+ if (varName)
67
+ await setVar(varName, response);
68
+ return response;
69
+ }
70
+ case "compute": {
71
+ Joi.assert(word1, Joi.string());
72
+ const inputs = parts2.map((p) => readValue(p));
73
+ const response = await compute(word1, inputs, context);
74
+ if (varName)
75
+ await setVar(varName, response);
76
+ return response;
77
+ }
78
+ case "conformance": {
79
+ Joi.assert(word1, Joi.string());
80
+ const inputs = parts2.map((p) => readValue(p));
81
+ const response = await conformance(word1, inputs, context);
82
+ if (varName)
83
+ await setVar(varName, response);
84
+ return response;
85
+ }
86
+ case "domain": {
87
+ Joi.assert(word1, Joi.string());
88
+ await setDomain(word1);
89
+ return 0;
90
+ }
91
+ case "env": {
92
+ Joi.assert(word1, Joi.string().optional());
93
+ const input = readValue(word1);
94
+ await environment(input);
95
+ return 0;
96
+ }
97
+ case "exit": {
98
+ return process.exit(0);
99
+ }
100
+ case "export": {
101
+ let data = readValue(word1);
102
+ const filename = readValue(parts2[0]);
103
+ if (typeof data === "object") {
104
+ data = JSON.stringify(data, null, 2);
105
+ }
106
+ const absolutePath = path.isAbsolute(filename)
107
+ ? filename
108
+ : path.join(`${process.cwd()}`, filename);
109
+ fs.writeFileSync(filename, data);
110
+ utils.yellow(`file saved at ${absolutePath}`);
111
+ return undefined;
112
+ }
113
+ case "fs": {
114
+ Joi.assert(word1, Joi.string());
115
+ const response = fileSystem(word1, ...parts2);
116
+ console.log(response);
117
+ if (varName)
118
+ await setVar(varName, response);
119
+ return response;
120
+ }
121
+ case "get": {
122
+ Joi.assert(word1, Joi.string());
123
+ const input = readValue(word1);
124
+ const response = await utils.httpCall.get(input, context.httpOpts);
125
+ if (varName)
126
+ await setVar(varName, response.data);
127
+ return response.data;
128
+ }
129
+ case "hardwarewallet":
130
+ case "hw": {
131
+ Joi.assert(word1, Joi.string());
132
+ const inputs = parts2.map((p) => {
133
+ if (word1 === "setpin")
134
+ return p;
135
+ return readValue(p);
136
+ });
137
+ const response = await hardwarewallet(word1, inputs, context);
138
+ if (varName)
139
+ await setVar(varName, response);
140
+ return response;
141
+ }
142
+ case "ledger": {
143
+ Joi.assert(word1, Joi.string());
144
+ const inputs = parts2.map((p) => readValue(p));
145
+ const response = await ledger(word1, inputs, false, context);
146
+ if (varName)
147
+ await setVar(varName, response);
148
+ return response;
149
+ }
150
+ case "load": {
151
+ const filename = readValue(word1);
152
+ const data = readFile(filename);
153
+ let response;
154
+ try {
155
+ response = JSON.parse(data);
156
+ }
157
+ catch {
158
+ response = data;
159
+ }
160
+ if (varName)
161
+ await setVar(varName, response);
162
+ return response;
163
+ }
164
+ case "proxyledger": {
165
+ Joi.assert(word1, Joi.string());
166
+ const inputs = parts2.map((p) => readValue(p));
167
+ const response = await ledger(word1, inputs, true, context);
168
+ if (varName)
169
+ await setVar(varName, response);
170
+ return response;
171
+ }
172
+ case "run": {
173
+ Joi.assert(word1, Joi.string());
174
+ const inputs = parts2.map((p) => readValue(p));
175
+ const response = await run(word1, inputs);
176
+ if (varName)
177
+ await setVar(varName, response);
178
+ return response;
179
+ }
180
+ case "set": {
181
+ Joi.assert(word1, Joi.string());
182
+ const inputs = parts2.map((p) => readValue(p));
183
+ let value = inputs[0];
184
+ if (inputs.length > 1) {
185
+ Joi.assert(inputs, schemaStrings);
186
+ value = inputs.join("");
187
+ }
188
+ await setVar(word1, value);
189
+ return value;
190
+ }
191
+ case "tnl": {
192
+ Joi.assert(word1, Joi.string());
193
+ const inputs = parts2.map((p) => readValue(p));
194
+ const response = await tnl(word1, inputs, context);
195
+ if (varName)
196
+ await setVar(varName, response);
197
+ return response;
198
+ }
199
+ case "using": {
200
+ Joi.assert(word1, Joi.string());
201
+ const user = await using(word1, ...parts2);
202
+ return user;
203
+ }
204
+ case "version": {
205
+ Joi.assert(word1, Joi.string().optional());
206
+ const input = readValue(word1);
207
+ await setVersionApis(input);
208
+ return 0;
209
+ }
210
+ case "view": {
211
+ Joi.assert(word1, Joi.string());
212
+ return view([readValue(word1)], context);
213
+ }
214
+ default: {
215
+ throw new Error(`Invalid method '${method}'`);
216
+ }
32
217
  }
33
- if (!printVar)
34
- return;
35
- utils.cyanBold(`Value saved in '${key}':`);
36
- utils.cyan(value);
37
218
  }
38
219
  export async function initConfigVars() {
39
220
  await setVar("domain", config.domain, false);
@@ -47,41 +228,246 @@ export async function initConfigVars() {
47
228
  await setVar("ledgerUrl", config.api.ledger.url, false);
48
229
  await setVar("authorisationUrl", config.api.authorisation.url, false);
49
230
  }
50
- function updateHttpOpts() {
51
- const conformanceId = readValue("conformanceId", true);
52
- httpOpts = {
53
- headers: {
54
- ...(token && {
55
- authorization: `Bearer ${token}`,
56
- }),
57
- ...(conformanceId && { conformance: conformanceId }),
58
- },
59
- };
231
+ export async function main() {
232
+ await initConfigVars();
233
+ while (true) {
234
+ const command = await utils.askQuestion("==> ");
235
+ try {
236
+ await execCommand(command);
237
+ }
238
+ catch (error) {
239
+ utils.red(error.stack);
240
+ }
241
+ }
60
242
  }
61
- function readValue(input, required = false) {
62
- if (!input || typeof input !== "string")
63
- return input;
64
- const parts = input.split(".");
65
- let fieldName = parts[0];
66
- if (typeof rtVars[fieldName] === "undefined") {
67
- if (required)
68
- return undefined;
69
- return input;
243
+ async function environment(env) {
244
+ if (env) {
245
+ config = loadConfig(env, config.versionApis);
246
+ await initConfigVars();
247
+ utils.yellow(`Environment ${env} loaded`);
70
248
  }
71
- let i = 0;
72
- let obj = rtVars;
73
- while (i < parts.length - 1) {
74
- obj = obj[fieldName];
75
- i += 1;
76
- fieldName = parts[i];
249
+ else {
250
+ utils.yellow(`Current environment: ${config.env}`);
77
251
  }
78
- return obj[fieldName];
252
+ const { api, contractAddresses, domain, env: envConfig } = config;
253
+ utils.yellow({
254
+ contractAddresses,
255
+ domain,
256
+ env: envConfig,
257
+ urls: Object.keys(api).map((name) => api[name].url),
258
+ version: config.versionApis,
259
+ });
79
260
  }
80
- function urlPath(inputs) {
261
+ function fileSystem(method, ...params) {
262
+ switch (method) {
263
+ case "readBinaryFile": {
264
+ const [filename] = params;
265
+ Joi.assert(filename, Joi.string());
266
+ return fs.readFileSync(filename);
267
+ }
268
+ case "writeBinaryFile": {
269
+ const filename = readValue(params[0]);
270
+ const data = readValue(params[1]);
271
+ Joi.assert(filename, Joi.string());
272
+ fs.writeFileSync(filename, data);
273
+ return 0;
274
+ }
275
+ default: {
276
+ throw new Error(`Invalid method '${method}'`);
277
+ }
278
+ }
279
+ }
280
+ function readFile(filename) {
281
+ try {
282
+ // get the file from the working directory
283
+ return fs.readFileSync(filename, "utf8");
284
+ }
285
+ catch {
286
+ // otherwise get the file from the internal scripts of the CLI tool
287
+ try {
288
+ return fs.readFileSync(new URL(`scripts/${filename}`, import.meta.url), "utf8");
289
+ }
290
+ catch {
291
+ throw new Error(`Can't open script ${filename}`);
292
+ }
293
+ }
294
+ }
295
+ function readValue(input, required = false) {
296
+ if (!input || typeof input !== "string")
297
+ return input;
298
+ const parts = input.split(".");
299
+ let fieldName = parts[0];
300
+ if (rtVars[fieldName] === undefined) {
301
+ if (required)
302
+ return undefined;
303
+ return input;
304
+ }
305
+ let i = 0;
306
+ let obj = rtVars;
307
+ while (i < parts.length - 1) {
308
+ obj = obj[fieldName];
309
+ i += 1;
310
+ fieldName = parts[i];
311
+ }
312
+ return obj[fieldName];
313
+ }
314
+ async function run(filename, inputs = []) {
315
+ const filedata = readFile(filename);
316
+ const lines = filedata.split(/\r?\n/);
317
+ let response;
318
+ for (const [i, line_] of lines.entries()) {
319
+ let line = line_.trim();
320
+ if (line.length > 0 && !line.startsWith("#")) {
321
+ for (const [j, input] of inputs.entries()) {
322
+ const param = typeof input === "string" ? input : JSON.stringify(input);
323
+ line = line.replaceAll(new RegExp(`\\$${j + 1}`, "g"), param);
324
+ }
325
+ try {
326
+ response = await execCommand(line, true);
327
+ }
328
+ catch (error) {
329
+ utils.red(error.stack);
330
+ throw new Error(`Error in line ${i + 1}: ${error.message}`);
331
+ }
332
+ }
333
+ else {
334
+ console.log(line);
335
+ }
336
+ }
337
+ return response;
338
+ }
339
+ async function setDomain(dom) {
340
+ if (dom) {
341
+ for (const apiName of Object.keys(config.api)) {
342
+ config.api[apiName].url = config.api[apiName].url.replace(config.domain, dom);
343
+ }
344
+ config.domain = dom;
345
+ await setVar("domain", config.domain);
346
+ }
347
+ utils.yellow(`Current domain: ${config.domain}`);
348
+ }
349
+ async function setVar(key, value, printVar = true) {
350
+ lodashSet(rtVars, key, value);
351
+ if (key.startsWith("user.")) {
352
+ await execCommand("using user user");
353
+ return;
354
+ }
355
+ if (!printVar)
356
+ return;
357
+ utils.cyanBold(`Value saved in '${key}':`);
358
+ utils.cyan(value);
359
+ }
360
+ async function setVersionApis(version) {
361
+ if (version) {
362
+ config = loadConfig(config.env, version);
363
+ await initConfigVars();
364
+ utils.yellow(`Version ${config.versionApis} loaded`);
365
+ }
366
+ else {
367
+ utils.yellow(`Current version: ${config.versionApis}`);
368
+ }
369
+ const { api, contractAddresses, domain, env: envConfig } = config;
370
+ utils.yellow({
371
+ contractAddresses,
372
+ domain,
373
+ env: envConfig,
374
+ urls: Object.keys(api).map((name) => api[name].url),
375
+ version: config.versionApis,
376
+ });
377
+ }
378
+ async function smartContractApi(contract, method, ...inputs) {
379
+ const apiUrl = config.api[contract].url;
380
+ if (method === "get") {
381
+ const response = await utils.httpCall.get(`${apiUrl}${urlPath(inputs)}`, httpOpts);
382
+ return response.data;
383
+ }
384
+ if (method === "head") {
385
+ const response = await utils.httpCall.head(`${apiUrl}${urlPath(inputs)}`, httpOpts);
386
+ return response.data;
387
+ }
388
+ const url = `${apiUrl}/jsonrpc`;
389
+ if (method === "sendSignedTransaction") {
390
+ const unsignedTransaction = readValue(inputs[0]);
391
+ const sgnTx = readValue(inputs[1]);
392
+ Joi.assert(unsignedTransaction, Joi.object());
393
+ Joi.assert(sgnTx, Joi.string());
394
+ const bodySend = jsonrpcBody(method, [
395
+ paramSignedTransaction(unsignedTransaction, sgnTx),
396
+ ]);
397
+ const response = await utils.httpCall.post(url, bodySend, httpOpts);
398
+ // use ledger proxy is besu provider is defined
399
+ const context = {
400
+ client,
401
+ config,
402
+ httpOpts,
403
+ rtVars,
404
+ token,
405
+ transactionInfo,
406
+ };
407
+ const useProxy = !!config.besuProvider;
408
+ transactionInfo.txId = response.data.result;
409
+ transactionInfo.receipt = await waitToBeMined(response.data.result, useProxy, context);
410
+ return transactionInfo.receipt;
411
+ }
412
+ if (!method.startsWith("build-")) {
413
+ const inputsStr = inputs
414
+ .map((input) => typeof input === "string" ? input : JSON.stringify(input))
415
+ .join(" ");
416
+ const uTx = await execCommand(`${contract} build-${method} ${inputsStr}`, true);
417
+ const sgnTx = await execCommand(`compute signTransaction ${JSON.stringify(uTx)}`, true);
418
+ await execCommand(`${contract} sendSignedTransaction ${JSON.stringify(uTx)} ${sgnTx}`, true);
419
+ const txInfo = await execCommand("view transactionInfo", true);
420
+ return txInfo;
421
+ }
422
+ let m = method.replace("build-", "");
423
+ const build = await buildParam(contract, m, client, inputs.map((input) => readValue(input)), config.versionApis);
424
+ if (build.method)
425
+ m = build.method.slice(0, Math.max(0, build.method.indexOf("(")));
426
+ const param = {
427
+ from: client.ethWallet.address,
428
+ ...build.param,
429
+ };
430
+ const body = jsonrpcBody(m, [param]);
431
+ const response = await utils.httpCall.post(url, body, httpOpts);
432
+ utils.yellow(build.info.title);
433
+ utils.yellow(build.info.data);
434
+ transactionInfo = {
435
+ build,
436
+ contract,
437
+ method: m,
438
+ };
439
+ return response.data.result;
440
+ }
441
+ function updateHttpOpts() {
442
+ const conformanceId = readValue("conformanceId", true);
443
+ httpOpts = {
444
+ headers: {
445
+ ...(token && {
446
+ authorization: `Bearer ${token}`,
447
+ }),
448
+ ...(conformanceId && { conformance: conformanceId }),
449
+ },
450
+ };
451
+ }
452
+ function urlPath(inputs) {
453
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
81
454
  return inputs.map((input) => readValue(input)).join("");
82
455
  }
83
456
  async function using(method, ...params) {
84
457
  switch (method) {
458
+ case "ethuser": {
459
+ if (params[0] === "null") {
460
+ const hw = client.hardwareWallet;
461
+ client = new Client();
462
+ client.hardwareWallet = hw;
463
+ await setVar("user", client.toJSON(), false);
464
+ utils.yellow("User removed");
465
+ return client;
466
+ }
467
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
468
+ await execCommand(`using user ES256K ${params.join(" ")}`, true);
469
+ return client;
470
+ }
85
471
  case "token": {
86
472
  token = params[0] === "empty" ? null : readValue(params[0]);
87
473
  updateHttpOpts();
@@ -97,7 +483,7 @@ async function using(method, ...params) {
97
483
  client.hardwareWallet = hw;
98
484
  client.did = existingUser.did;
99
485
  client.didVersion = existingUser.didVersion;
100
- client.privateKeyHex = existingUser.privateKeyHex;
486
+ client.keys = existingUser.keys;
101
487
  client.clientId = existingUser.clientId;
102
488
  client.accreditationUrl = existingUser.accreditationUrl;
103
489
  if (existingUser.accreditationUrl) {
@@ -105,10 +491,9 @@ async function using(method, ...params) {
105
491
  }
106
492
  client.proxyId = existingUser.proxyId;
107
493
  client.issuerState = existingUser.issuerState;
108
- if (existingUser.privateKeyHex) {
109
- client.ethWallet = new ethers.Wallet(existingUser.privateKeyHex);
494
+ if (existingUser.keys?.ES256K) {
495
+ client.ethWallet = new ethers.Wallet(existingUser.keys.ES256K.privateKeyHex);
110
496
  }
111
- client.keys = existingUser.keys;
112
497
  await setVar("user", client.toJSON(), false);
113
498
  await execCommand("view user", false);
114
499
  return client;
@@ -149,15 +534,14 @@ async function using(method, ...params) {
149
534
  }
150
535
  else {
151
536
  client.ethWallet = new ethers.Wallet(utils.encodePrivateKey({
152
- key: privateKey,
153
537
  format: "hex",
538
+ key: privateKey,
154
539
  }));
155
540
  }
156
- client.privateKeyHex = client.ethWallet.privateKey;
157
541
  const privateKeyJwk = utils.encodePrivateKey({
158
- key: client.ethWallet.privateKey,
159
542
  alg,
160
543
  format: "jwk",
544
+ key: client.ethWallet.privateKey,
161
545
  });
162
546
  client.setJwk(alg, privateKeyJwk);
163
547
  }
@@ -166,24 +550,24 @@ async function using(method, ...params) {
166
550
  client.hardwareWallet = new HardwareWallet(config.openSClib);
167
551
  const publicKeyJwk = client.hardwareWallet.getPublicKey();
168
552
  const publicKeyPem = utils.encodePublicKey({
169
- key: publicKeyJwk,
170
553
  alg,
171
554
  format: "pem",
555
+ key: publicKeyJwk,
172
556
  });
173
557
  client.keys.ES256 = {
174
558
  id: "",
559
+ isHardwareWallet: true,
175
560
  kid: "",
176
561
  privateKeyJwk: undefined,
177
562
  publicKeyJwk,
178
563
  publicKeyPem,
179
- isHardwareWallet: true,
180
564
  };
181
565
  }
182
566
  else if (alg === "ES256" && typeof privateKey === "string") {
183
567
  const privateKeyJwk = utils.encodePrivateKey({
184
- key: privateKey,
185
568
  alg,
186
569
  format: "jwk",
570
+ key: privateKey,
187
571
  });
188
572
  client.setJwk(alg, privateKeyJwk);
189
573
  }
@@ -215,8 +599,9 @@ async function using(method, ...params) {
215
599
  }
216
600
  break;
217
601
  }
218
- default:
602
+ default: {
219
603
  throw new Error("did method must be 'did1' or 'did2'");
604
+ }
220
605
  }
221
606
  client.keys[alg].id = verificationMethodId;
222
607
  client.keys[alg].kid = `${client.did}#${verificationMethodId}`;
@@ -224,392 +609,8 @@ async function using(method, ...params) {
224
609
  await execCommand("view user", false);
225
610
  return client;
226
611
  }
227
- case "ethuser": {
228
- if (params[0] === "null") {
229
- const hw = client.hardwareWallet;
230
- client = new Client();
231
- client.hardwareWallet = hw;
232
- await setVar("user", client.toJSON(), false);
233
- utils.yellow("User removed");
234
- return client;
235
- }
236
- await execCommand(`using user ES256K ${params.join(" ")}`, true);
237
- return client;
238
- }
239
- default:
612
+ default: {
240
613
  throw new Error(`Invalid subject '${method}'`);
241
- }
242
- }
243
- async function smartContractApi(contract, method, ...inputs) {
244
- const apiUrl = config.api[contract].url;
245
- if (method === "get") {
246
- const response = await utils.httpCall.get(`${apiUrl}${urlPath(inputs)}`, httpOpts);
247
- return response.data;
248
- }
249
- if (method === "head") {
250
- const response = await utils.httpCall.head(`${apiUrl}${urlPath(inputs)}`, httpOpts);
251
- return response.data;
252
- }
253
- const url = `${apiUrl}/jsonrpc`;
254
- if (method === "sendSignedTransaction") {
255
- const unsignedTransaction = readValue(inputs[0]);
256
- const sgnTx = readValue(inputs[1]);
257
- Joi.assert(unsignedTransaction, Joi.object());
258
- Joi.assert(sgnTx, Joi.string());
259
- const bodySend = jsonrpcBody(method, [
260
- paramSignedTransaction(unsignedTransaction, sgnTx),
261
- ]);
262
- const response = await utils.httpCall.post(url, bodySend, httpOpts);
263
- // use ledger proxy is besu provider is defined
264
- const context = {
265
- config,
266
- httpOpts,
267
- client,
268
- rtVars,
269
- transactionInfo,
270
- token,
271
- };
272
- const useProxy = !!config.besuProvider;
273
- transactionInfo.txId = response.data.result;
274
- transactionInfo.receipt = await waitToBeMined(response.data.result, useProxy, context);
275
- return transactionInfo.receipt;
276
- }
277
- if (!method.startsWith("build-")) {
278
- const inputsStr = inputs
279
- .map((input) => typeof input === "string" ? input : JSON.stringify(input))
280
- .join(" ");
281
- const uTx = await execCommand(`${contract} build-${method} ${inputsStr}`, true);
282
- const sgnTx = await execCommand(`compute signTransaction ${JSON.stringify(uTx)}`, true);
283
- await execCommand(`${contract} sendSignedTransaction ${JSON.stringify(uTx)} ${sgnTx}`, true);
284
- const txInfo = await execCommand("view transactionInfo", true);
285
- return txInfo;
286
- }
287
- let m = method.replace("build-", "");
288
- const build = await buildParam(contract, m, client, inputs.map((input) => readValue(input)), config.versionApis);
289
- if (build.method)
290
- m = build.method.substring(0, build.method.indexOf("("));
291
- const param = {
292
- from: client.ethWallet.address,
293
- ...build.param,
294
- };
295
- const body = jsonrpcBody(m, [param]);
296
- const response = await utils.httpCall.post(url, body, httpOpts);
297
- utils.yellow(build.info.title);
298
- utils.yellow(build.info.data);
299
- transactionInfo = {
300
- contract,
301
- method: m,
302
- build,
303
- };
304
- return response.data.result;
305
- }
306
- async function environment(env) {
307
- if (env) {
308
- config = loadConfig(env, config.versionApis);
309
- await initConfigVars();
310
- utils.yellow(`Environment ${env} loaded`);
311
- }
312
- else {
313
- utils.yellow(`Current environment: ${config.env}`);
314
- }
315
- const { domain, contractAddresses, api, env: envConfig } = config;
316
- utils.yellow({
317
- domain,
318
- contractAddresses,
319
- urls: Object.keys(api).map((name) => api[name].url),
320
- env: envConfig,
321
- version: config.versionApis,
322
- });
323
- }
324
- async function setVersionApis(version) {
325
- if (version) {
326
- config = loadConfig(config.env, version);
327
- await initConfigVars();
328
- utils.yellow(`Version ${config.versionApis} loaded`);
329
- }
330
- else {
331
- utils.yellow(`Current version: ${config.versionApis}`);
332
- }
333
- const { domain, contractAddresses, api, env: envConfig } = config;
334
- utils.yellow({
335
- domain,
336
- contractAddresses,
337
- urls: Object.keys(api).map((name) => api[name].url),
338
- env: envConfig,
339
- version: config.versionApis,
340
- });
341
- }
342
- async function setDomain(dom) {
343
- if (dom) {
344
- Object.keys(config.api).forEach((apiName) => {
345
- config.api[apiName].url = config.api[apiName].url.replace(config.domain, dom);
346
- });
347
- config.domain = dom;
348
- await setVar("domain", config.domain);
349
- }
350
- utils.yellow(`Current domain: ${config.domain}`);
351
- }
352
- function fileSystem(method, ...params) {
353
- switch (method) {
354
- case "readBinaryFile": {
355
- const [filename] = params;
356
- Joi.assert(filename, Joi.string());
357
- return fs.readFileSync(filename);
358
- }
359
- case "writeBinaryFile": {
360
- const filename = readValue(params[0]);
361
- const data = readValue(params[1]);
362
- Joi.assert(filename, Joi.string());
363
- fs.writeFileSync(filename, data);
364
- return 0;
365
- }
366
- default:
367
- throw new Error(`Invalid method '${method}'`);
368
- }
369
- }
370
- function readFile(filename) {
371
- try {
372
- // get the file from the working directory
373
- return fs.readFileSync(filename, "utf-8");
374
- }
375
- catch {
376
- // otherwise get the file from the internal scripts of the CLI tool
377
- try {
378
- return fs.readFileSync(new URL(`scripts/${filename}`, import.meta.url), "utf8");
379
- }
380
- catch {
381
- throw new Error(`Can't open script ${filename}`);
382
- }
383
- }
384
- }
385
- async function run(filename, inputs = []) {
386
- const filedata = readFile(filename);
387
- const lines = filedata.split(/\r?\n/);
388
- let response;
389
- for (let i = 0; i < lines.length; i += 1) {
390
- let line = lines[i].trim();
391
- if (line.length > 0 && !line.startsWith("#")) {
392
- inputs.forEach((input, j) => {
393
- const param = typeof input === "string" ? input : JSON.stringify(input);
394
- line = line.replace(new RegExp(`\\$${j + 1}`, "g"), param);
395
- });
396
- try {
397
- response = await execCommand(line, true);
398
- }
399
- catch (error) {
400
- utils.red(error.stack);
401
- throw new Error(`Error in line ${i + 1}: ${error.message}`);
402
- }
403
- }
404
- else {
405
- console.log(line);
406
- }
407
- }
408
- return response;
409
- }
410
- export async function execCommand(command, printCommand = false) {
411
- if (printCommand)
412
- console.log(`==> ${command}`);
413
- const parts = parseLine(command);
414
- let varName = "";
415
- if (parts.length === 0)
416
- return 0;
417
- if (typeof parts[0] === "string" && parts[0].includes(":")) {
418
- varName = parts[0].replace(":", "");
419
- parts.shift();
420
- }
421
- const [part0, part1] = parts;
422
- const parts2 = parts.slice(2);
423
- const method = part0;
424
- const word1 = part1;
425
- Joi.assert(method, Joi.string());
426
- // APIs linked to smart contracts
427
- if (["timestamp", "did", "tir", "tsr", "tpr", "tnt"].includes(method)) {
428
- Joi.assert(word1, Joi.string());
429
- const response = await smartContractApi(method, word1, ...parts2);
430
- if (varName)
431
- await setVar(varName, response);
432
- return response;
433
- }
434
- const schemaStrings = Joi.array().items(Joi.string());
435
- const context = {
436
- config,
437
- httpOpts,
438
- client,
439
- rtVars,
440
- transactionInfo,
441
- token,
442
- };
443
- // Other APIs and configurations
444
- switch (method) {
445
- case "fs": {
446
- Joi.assert(word1, Joi.string());
447
- const response = fileSystem(word1, ...parts2);
448
- console.log(response);
449
- if (varName)
450
- await setVar(varName, response);
451
- return response;
452
- }
453
- case "set": {
454
- Joi.assert(word1, Joi.string());
455
- const inputs = parts2.map((p) => readValue(p));
456
- let value = inputs[0];
457
- if (inputs.length > 1) {
458
- Joi.assert(inputs, schemaStrings);
459
- value = inputs.join("");
460
- }
461
- await setVar(word1, value);
462
- return value;
463
- }
464
- case "view": {
465
- Joi.assert(word1, Joi.string());
466
- return view([readValue(word1)], context);
467
- }
468
- case "using": {
469
- Joi.assert(word1, Joi.string());
470
- const user = await using(word1, ...parts2);
471
- return user;
472
- }
473
- case "hardwarewallet":
474
- case "hw": {
475
- Joi.assert(word1, Joi.string());
476
- const inputs = parts2.map((p) => {
477
- if (word1 === "setpin")
478
- return p;
479
- return readValue(p);
480
- });
481
- const response = await hardwarewallet(word1, inputs, context);
482
- if (varName)
483
- await setVar(varName, response);
484
- return response;
485
- }
486
- case "env": {
487
- Joi.assert(word1, Joi.string().optional());
488
- const input = readValue(word1);
489
- await environment(input);
490
- return 0;
491
- }
492
- case "version": {
493
- Joi.assert(word1, Joi.string().optional());
494
- const input = readValue(word1);
495
- await setVersionApis(input);
496
- return 0;
497
- }
498
- case "domain": {
499
- Joi.assert(word1, Joi.string());
500
- await setDomain(word1);
501
- return 0;
502
- }
503
- case "get": {
504
- Joi.assert(word1, Joi.string());
505
- const input = readValue(word1);
506
- const response = await utils.httpCall.get(input, context.httpOpts);
507
- if (varName)
508
- await setVar(varName, response.data);
509
- return response.data;
510
- }
511
- case "authorisation": {
512
- Joi.assert(word1, Joi.string());
513
- Joi.assert(parts2, schemaStrings);
514
- const inputs = parts2.map((p) => readValue(p));
515
- const response = await authorisationV4(word1, inputs, context);
516
- if (varName)
517
- await setVar(varName, response);
518
- return response;
519
- }
520
- case "proxyledger": {
521
- Joi.assert(word1, Joi.string());
522
- const inputs = parts2.map((p) => readValue(p));
523
- const response = await ledgerV4(word1, inputs, true, context);
524
- if (varName)
525
- await setVar(varName, response);
526
- return response;
527
- }
528
- case "ledger": {
529
- Joi.assert(word1, Joi.string());
530
- const inputs = parts2.map((p) => readValue(p));
531
- const response = await ledgerV4(word1, inputs, false, context);
532
- if (varName)
533
- await setVar(varName, response);
534
- return response;
535
- }
536
- case "tnl": {
537
- Joi.assert(word1, Joi.string());
538
- const inputs = parts2.map((p) => readValue(p));
539
- const response = await tnl(word1, inputs, context);
540
- if (varName)
541
- await setVar(varName, response);
542
- return response;
543
- }
544
- case "conformance": {
545
- Joi.assert(word1, Joi.string());
546
- const inputs = parts2.map((p) => readValue(p));
547
- const response = await conformanceV3(word1, inputs, context);
548
- if (varName)
549
- await setVar(varName, response);
550
- return response;
551
- }
552
- case "compute": {
553
- Joi.assert(word1, Joi.string());
554
- const inputs = parts2.map((p) => readValue(p));
555
- const response = await compute(word1, inputs, context);
556
- if (varName)
557
- await setVar(varName, response);
558
- return response;
559
- }
560
- case "load": {
561
- const filename = readValue(word1);
562
- const data = readFile(filename);
563
- let response;
564
- try {
565
- response = JSON.parse(data);
566
- }
567
- catch {
568
- response = data;
569
- }
570
- if (varName)
571
- await setVar(varName, response);
572
- return response;
573
- }
574
- case "export": {
575
- let data = readValue(word1);
576
- const filename = readValue(parts2[0]);
577
- if (typeof data === "object") {
578
- data = JSON.stringify(data, null, 2);
579
- }
580
- const absolutePath = path.isAbsolute(filename)
581
- ? filename
582
- : path.join(`${process.cwd()}`, filename);
583
- fs.writeFileSync(filename, data);
584
- utils.yellow(`file saved at ${absolutePath}`);
585
- return undefined;
586
- }
587
- case "run": {
588
- Joi.assert(word1, Joi.string());
589
- const inputs = parts2.map((p) => readValue(p));
590
- const response = await run(word1, inputs);
591
- if (varName)
592
- await setVar(varName, response);
593
- return response;
594
- }
595
- case "exit": {
596
- process.exit(0);
597
- return 0;
598
- }
599
- default:
600
- throw new Error(`Invalid method '${method}'`);
601
- }
602
- }
603
- export async function main() {
604
- await initConfigVars();
605
- // eslint-disable-next-line no-constant-condition
606
- while (true) {
607
- const command = await utils.askQuestion("==> ");
608
- try {
609
- await execCommand(command);
610
- }
611
- catch (error) {
612
- utils.red(error.stack);
613
614
  }
614
615
  }
615
616
  }