@cef-ebsi/cli 1.3.2 → 1.5.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 (202) 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/{test/TirV4.js → pilot/Ptr.js} +255 -299
  5. package/dist/abi/pilot/Ptr.js.map +1 -0
  6. package/dist/abi/pilot/SchemaSCRegistry.js +264 -0
  7. package/dist/abi/pilot/SchemaSCRegistry.js.map +1 -0
  8. package/dist/abi/{test/TprV3.js → pilot/Tcr.js} +269 -261
  9. package/dist/abi/pilot/Tcr.js.map +1 -0
  10. package/dist/abi/pilot/Timestamp.js +658 -0
  11. package/dist/abi/pilot/Timestamp.js.map +1 -0
  12. package/dist/abi/pilot/Tir.js +428 -0
  13. package/dist/abi/pilot/Tir.js.map +1 -0
  14. package/dist/abi/pilot/TnT.js +842 -0
  15. package/dist/abi/pilot/TnT.js.map +1 -0
  16. package/dist/abi/pilot/Tpr.js +492 -0
  17. package/dist/abi/pilot/Tpr.js.map +1 -0
  18. package/dist/abi/test/DidRegistry.js +144 -658
  19. package/dist/abi/test/DidRegistry.js.map +1 -1
  20. package/dist/abi/{pilot/TirV4.js → test/Ptr.js} +255 -299
  21. package/dist/abi/test/Ptr.js.map +1 -0
  22. package/dist/abi/test/SchemaSCRegistry.js +122 -795
  23. package/dist/abi/test/SchemaSCRegistry.js.map +1 -1
  24. package/dist/abi/{pilot/TprV3.js → test/Tcr.js} +269 -261
  25. package/dist/abi/test/Tcr.js.map +1 -0
  26. package/dist/abi/test/Timestamp.js +239 -673
  27. package/dist/abi/test/Timestamp.js.map +1 -1
  28. package/dist/abi/test/Tir.js +167 -636
  29. package/dist/abi/test/Tir.js.map +1 -1
  30. package/dist/abi/test/TnT.js +842 -0
  31. package/dist/abi/test/TnT.js.map +1 -0
  32. package/dist/abi/test/Tpr.js +166 -942
  33. package/dist/abi/test/Tpr.js.map +1 -1
  34. package/dist/app.js +447 -443
  35. package/dist/app.js.map +1 -1
  36. package/dist/buildParam/{didV3.js → didr.js} +210 -204
  37. package/dist/buildParam/didr.js.map +1 -0
  38. package/dist/buildParam/index.js +42 -48
  39. package/dist/buildParam/index.js.map +1 -1
  40. package/dist/buildParam/ptr.js +80 -0
  41. package/dist/buildParam/ptr.js.map +1 -0
  42. package/dist/buildParam/tcr.js +36 -0
  43. package/dist/buildParam/tcr.js.map +1 -0
  44. package/dist/buildParam/{timestampV3.js → timestamp.js} +179 -136
  45. package/dist/buildParam/timestamp.js.map +1 -0
  46. package/dist/buildParam/{tirV3.js → tir.js} +67 -59
  47. package/dist/buildParam/tir.js.map +1 -0
  48. package/dist/buildParam/{tntV1.js → tnt.js} +90 -61
  49. package/dist/buildParam/tnt.js.map +1 -0
  50. package/dist/buildParam/{tprV2.js → tpr.js} +44 -33
  51. package/dist/buildParam/tpr.js.map +1 -0
  52. package/dist/buildParam/{tsrV2.js → tsr.js} +45 -40
  53. package/dist/buildParam/tsr.js.map +1 -0
  54. package/dist/cli.js +1 -0
  55. package/dist/cli.js.map +1 -1
  56. package/dist/commands/{authorisation-v5.js → authorisation.js} +95 -72
  57. package/dist/commands/authorisation.js.map +1 -0
  58. package/dist/commands/compute.js +429 -389
  59. package/dist/commands/compute.js.map +1 -1
  60. package/dist/commands/{conformance-v3.js → conformance.js} +236 -248
  61. package/dist/commands/conformance.js.map +1 -0
  62. package/dist/commands/hardwarewallet.js +5 -5
  63. package/dist/commands/hardwarewallet.js.map +1 -1
  64. package/dist/commands/index.js +4 -4
  65. package/dist/commands/index.js.map +1 -1
  66. package/dist/commands/{ledger-v4.js → ledger.js} +203 -127
  67. package/dist/commands/ledger.js.map +1 -0
  68. package/dist/commands/ptr.js +56 -0
  69. package/dist/commands/ptr.js.map +1 -0
  70. package/dist/commands/tcr.js +51 -0
  71. package/dist/commands/tcr.js.map +1 -0
  72. package/dist/commands/tnl.js +10 -9
  73. package/dist/commands/tnl.js.map +1 -1
  74. package/dist/commands/tsr.js +46 -0
  75. package/dist/commands/tsr.js.map +1 -0
  76. package/dist/commands/view.js +8 -8
  77. package/dist/commands/view.js.map +1 -1
  78. package/dist/config.js +311 -279
  79. package/dist/config.js.map +1 -1
  80. package/dist/index.js +3 -3
  81. package/dist/index.js.map +1 -1
  82. package/dist/interfaces/index.js +1 -1
  83. package/dist/interfaces/index.js.map +1 -1
  84. package/dist/programs/migrateDid.js +33 -33
  85. package/dist/programs/migrateDid.js.map +1 -1
  86. package/dist/programs/migrateDids.js +39 -42
  87. package/dist/programs/migrateDids.js.map +1 -1
  88. package/dist/programs/migrateTsr.js +153 -113
  89. package/dist/programs/migrateTsr.js.map +1 -1
  90. package/dist/scripts/accreditAndAuthorize/conformance/step1 +1 -1
  91. package/dist/scripts/accreditAndAuthorize/test/step1 +1 -1
  92. package/dist/scripts/accreditTI +1 -1
  93. package/dist/scripts/assets/CTRevocableCredential.json +1 -1
  94. package/dist/scripts/assets/CredentialToAttestVerifiableAuthorisationForTrustChain.json +2 -2
  95. package/dist/scripts/assets/TrustedNodesList.json +1 -1
  96. package/dist/scripts/assets/VerifiableAccreditationToAccredit.json +2 -2
  97. package/dist/scripts/assets/VerifiableAccreditationToAttest.json +2 -2
  98. package/dist/scripts/assets/VerifiableAuthorisationForTrustChain.json +1 -1
  99. package/dist/scripts/assets/VerifiableAuthorisationToInvoke.json +24 -0
  100. package/dist/scripts/assets/VerifiableAuthorisationToOnboard.json +1 -1
  101. package/dist/scripts/bootstrap/1-populateTPR +18 -15
  102. package/dist/scripts/bootstrap/6-setupConformanceIssuer +1 -1
  103. package/dist/scripts/issueVcInvoke +10 -0
  104. package/dist/scripts/issueVcOnboard +1 -1
  105. package/dist/scripts/issueVcRootTAO +1 -1
  106. package/dist/scripts/issueVcTAO +2 -2
  107. package/dist/scripts/issueVcTI +2 -2
  108. package/dist/scripts/issueVcTnl +1 -1
  109. package/dist/scripts/issue_CTRevocableCredential +1 -1
  110. package/dist/scripts/issue_SelfAttestationSupportOffice +2 -2
  111. package/dist/scripts/issue_VerifiableAccreditationToAccredit +2 -2
  112. package/dist/scripts/issue_VerifiableAccreditationToAttest +2 -2
  113. package/dist/scripts/issue_VerifiableAuthorisationForTrustChain +1 -1
  114. package/dist/scripts/issue_VerifiableAuthorisationToOnboard +1 -1
  115. package/dist/scripts/updateVcRootTAO +1 -1
  116. package/dist/scripts/updateVcTAO +2 -2
  117. package/dist/scripts/updateVcTI +2 -2
  118. package/dist/scripts/{wctv3 → wct}/accreditAndAuthorize +1 -1
  119. package/dist/tsconfig.build.tsbuildinfo +1 -0
  120. package/dist/utils/Client.js +81 -68
  121. package/dist/utils/Client.js.map +1 -1
  122. package/dist/utils/HardwareWallet.js +169 -165
  123. package/dist/utils/HardwareWallet.js.map +1 -1
  124. package/dist/utils/http.js +24 -27
  125. package/dist/utils/http.js.map +1 -1
  126. package/dist/utils/index.js +3 -3
  127. package/dist/utils/index.js.map +1 -1
  128. package/dist/utils/jsonrpc.js +14 -14
  129. package/dist/utils/jsonrpc.js.map +1 -1
  130. package/dist/utils/print.js +19 -19
  131. package/dist/utils/print.js.map +1 -1
  132. package/dist/utils/utils.js +180 -173
  133. package/dist/utils/utils.js.map +1 -1
  134. package/package.json +70 -46
  135. package/dist/abi/pilot/DidRegistryV3.js +0 -1082
  136. package/dist/abi/pilot/DidRegistryV3.js.map +0 -1
  137. package/dist/abi/pilot/DidRegistryV4.js +0 -942
  138. package/dist/abi/pilot/DidRegistryV4.js.map +0 -1
  139. package/dist/abi/pilot/SchemaSCRegistryV2.js +0 -474
  140. package/dist/abi/pilot/SchemaSCRegistryV2.js.map +0 -1
  141. package/dist/abi/pilot/TimestampV2.js +0 -1128
  142. package/dist/abi/pilot/TimestampV2.js.map +0 -1
  143. package/dist/abi/pilot/TimestampV3.js +0 -995
  144. package/dist/abi/pilot/TimestampV3.js.map +0 -1
  145. package/dist/abi/pilot/TirV3.js +0 -496
  146. package/dist/abi/pilot/TirV3.js.map +0 -1
  147. package/dist/abi/pilot/TirV4.js.map +0 -1
  148. package/dist/abi/pilot/TnTV1.js +0 -1375
  149. package/dist/abi/pilot/TnTV1.js.map +0 -1
  150. package/dist/abi/pilot/TprV2.js +0 -889
  151. package/dist/abi/pilot/TprV2.js.map +0 -1
  152. package/dist/abi/pilot/TprV3.js.map +0 -1
  153. package/dist/abi/pilot/TsrV3.js +0 -571
  154. package/dist/abi/pilot/TsrV3.js.map +0 -1
  155. package/dist/abi/test/DidRegistryV3.js +0 -1089
  156. package/dist/abi/test/DidRegistryV3.js.map +0 -1
  157. package/dist/abi/test/DidRegistryV4.js +0 -960
  158. package/dist/abi/test/DidRegistryV4.js.map +0 -1
  159. package/dist/abi/test/SchemaSCRegistryV2.js +0 -474
  160. package/dist/abi/test/SchemaSCRegistryV2.js.map +0 -1
  161. package/dist/abi/test/TimestampV2.js +0 -1128
  162. package/dist/abi/test/TimestampV2.js.map +0 -1
  163. package/dist/abi/test/TimestampV3.js +0 -995
  164. package/dist/abi/test/TimestampV3.js.map +0 -1
  165. package/dist/abi/test/TirV3.js +0 -496
  166. package/dist/abi/test/TirV3.js.map +0 -1
  167. package/dist/abi/test/TirV4.js.map +0 -1
  168. package/dist/abi/test/TnTV1.js +0 -1375
  169. package/dist/abi/test/TnTV1.js.map +0 -1
  170. package/dist/abi/test/TprV2.js +0 -889
  171. package/dist/abi/test/TprV2.js.map +0 -1
  172. package/dist/abi/test/TprV3.js.map +0 -1
  173. package/dist/abi/test/TsrV3.js +0 -571
  174. package/dist/abi/test/TsrV3.js.map +0 -1
  175. package/dist/buildParam/didV3.js.map +0 -1
  176. package/dist/buildParam/didV4.js +0 -326
  177. package/dist/buildParam/didV4.js.map +0 -1
  178. package/dist/buildParam/timestampV2.js +0 -317
  179. package/dist/buildParam/timestampV2.js.map +0 -1
  180. package/dist/buildParam/timestampV3.js.map +0 -1
  181. package/dist/buildParam/tirV3.js.map +0 -1
  182. package/dist/buildParam/tirV4.js +0 -119
  183. package/dist/buildParam/tirV4.js.map +0 -1
  184. package/dist/buildParam/tntV1.js.map +0 -1
  185. package/dist/buildParam/tntV2.js +0 -185
  186. package/dist/buildParam/tntV2.js.map +0 -1
  187. package/dist/buildParam/tprV2.js.map +0 -1
  188. package/dist/buildParam/tprV3.js +0 -82
  189. package/dist/buildParam/tprV3.js.map +0 -1
  190. package/dist/buildParam/tsrV2.js.map +0 -1
  191. package/dist/buildParam/tsrV3.js +0 -110
  192. package/dist/buildParam/tsrV3.js.map +0 -1
  193. package/dist/commands/authorisation-v4.js +0 -119
  194. package/dist/commands/authorisation-v4.js.map +0 -1
  195. package/dist/commands/authorisation-v5.js.map +0 -1
  196. package/dist/commands/conformance-v3.js.map +0 -1
  197. package/dist/commands/ledger-v4.js.map +0 -1
  198. package/dist/tsconfig.tsbuildinfo +0 -1
  199. /package/dist/scripts/{wctv3 → wct}/holderWallet +0 -0
  200. /package/dist/scripts/{wctv3 → wct}/issueToHolder +0 -0
  201. /package/dist/scripts/{wctv3 → wct}/pda1 +0 -0
  202. /package/dist/scripts/{wctv3 → wct}/verifier +0 -0
@@ -1,271 +1,29 @@
1
- import { randomUUID, randomBytes, createHash, } from "node:crypto";
2
- import Multihash from "multihashes";
3
- import { ethers } from "ethers";
4
- import { base64url, calculateJwkThumbprint } from "jose";
5
1
  import { util } from "@cef-ebsi/ebsi-did-resolver";
6
- import Joi from "joi";
7
- import { decodeJWT } from "did-jwt";
8
2
  import { ValidationError, verifyCredentialJwt, } from "@cef-ebsi/verifiable-credential";
9
3
  import { verifyPresentationJwt, } from "@cef-ebsi/verifiable-presentation";
10
4
  import { EbsiWallet } from "@cef-ebsi/wallet-lib";
11
- import { formatEthersUnsignedTransaction, removePrefix0x, yellow, red, computeSchemaId, multibaseEncode, encodePublicKey, encodePrivateKey, } from "../utils/index.js";
12
- import { ledgerGetTransaction, ledgerGetTransactionReceipt, } from "./ledger-v4.js";
13
- export function getUserPin(did) {
14
- return createHash("sha256")
15
- .update(did)
16
- .digest()
17
- .slice(-4)
18
- .map((byte) => byte % 10)
19
- .reduce((acc, digit) => `${acc}${digit}`, "");
20
- }
21
- export async function computeVerifyVcJwt(inputs, context) {
22
- const [vcJwt, options, expectedResult] = inputs;
23
- const ebsiEnvConfig = {
24
- hosts: [context.config.domain.replace(/^https?:\/\//, "")],
25
- scheme: "ebsi",
26
- network: {
27
- name: context.config.env,
28
- isOptional: false,
29
- },
30
- services: {
31
- "did-registry": context.config.api.did.version,
32
- "trusted-issuers-registry": context.config.api.tir.version,
33
- "trusted-policies-registry": context.config.api.tpr.version,
34
- "trusted-schemas-registry": context.config.api.tsr.version,
35
- },
36
- };
37
- try {
38
- await verifyCredentialJwt(vcJwt, ebsiEnvConfig, options);
39
- switch (expectedResult) {
40
- case "expectRevoked": {
41
- throw new Error("Credential is not revoked");
42
- }
43
- default:
44
- return "Verifiable Credential is valid";
45
- }
46
- }
47
- catch (error) {
48
- if (expectedResult === "expectRevoked") {
49
- if (error.message === "Credential is not revoked")
50
- throw error;
51
- if (error.message.includes("revoked")) {
52
- return "Verifiable Credential is revoked";
53
- }
54
- }
55
- throw error;
56
- }
57
- }
58
- export async function computeVerifyVpJwt(inputs, context) {
59
- const [vpJwt, audience, options] = inputs;
60
- const ebsiEnvConfig = {
61
- hosts: [context.config.domain.replace(/^https?:\/\//, "")],
62
- scheme: "ebsi",
63
- network: {
64
- name: context.config.env,
65
- isOptional: false,
66
- },
67
- services: {
68
- "did-registry": context.config.api.did.version,
69
- "trusted-issuers-registry": context.config.api.tir.version,
70
- "trusted-policies-registry": context.config.api.tpr.version,
71
- "trusted-schemas-registry": context.config.api.tsr.version,
72
- },
73
- };
74
- await verifyPresentationJwt(vpJwt, audience, ebsiEnvConfig, options);
75
- return "Verifiable Presentation is valid";
76
- }
77
- export function sha256(data) {
78
- let hash = createHash("sha256");
79
- if (data.startsWith("0x")) {
80
- hash = hash.update(removePrefix0x(data), "hex");
81
- }
82
- else {
83
- hash = hash.update(data, "utf8");
84
- }
85
- return hash.digest().toString("hex");
86
- }
87
- export function getProperties(input) {
88
- return Object.keys(input)
89
- .filter((key) => Number.isNaN(Number(key)))
90
- .reduce((obj, key) => {
91
- /* eslint-disable-next-line no-param-reassign */
92
- obj[key] = input[key];
93
- return obj;
94
- }, {});
95
- }
96
- export function getApiByContractId(contractId, context) {
97
- const apiName = Object.keys(context.config.api).find((a) => {
98
- const api = context.config.api[a];
99
- return (api.contract &&
100
- contractId.toLowerCase() === api.contract.address.toLowerCase());
101
- });
102
- if (!apiName)
103
- throw new Error(`cannot get API with address ${contractId}`);
104
- return context.config.api[apiName];
105
- }
106
- export function decodeLog(log, context) {
107
- const api = getApiByContractId(log.address, context);
108
- const logDecoded = api.contract.interface.parseLog(log);
109
- const { name, signature, topic, args: argsWithArray } = logDecoded;
110
- const args = getProperties(argsWithArray);
111
- return { name, signature, topic, args };
112
- }
113
- export async function decodeLogs(input, context) {
114
- if (!input)
115
- throw new Error("Invalid logs: no input provided");
116
- let receipt;
117
- let logs;
118
- if (typeof input === "string") {
119
- receipt = await ledgerGetTransactionReceipt([input], false, context);
120
- }
121
- if (input.receipt) {
122
- receipt = input.receipt;
123
- }
124
- if (input.logs) {
125
- receipt = input;
126
- }
127
- if (receipt) {
128
- if (!Array.isArray(receipt.logs)) {
129
- throw new Error("Invalid logs: The input must be a transaction hash, a transaction receipt, or an array of logs");
130
- }
131
- logs = receipt.logs;
132
- }
133
- else {
134
- if (!Array.isArray(input)) {
135
- throw new Error("Invalid logs: The input must be a transaction hash, a transaction receipt, or an array of logs");
136
- }
137
- logs = input;
138
- }
139
- return logs.map((log) => decodeLog(log, context));
140
- }
141
- export async function decodeTransaction(tx, context) {
142
- let txData;
143
- if (typeof tx === "string") {
144
- txData = (await ledgerGetTransaction([tx], false, context));
145
- }
146
- else {
147
- txData = tx;
148
- }
149
- if (!txData.data && !txData.input) {
150
- throw new Error("Invalid transaction: There is no input or data");
151
- }
152
- const api = getApiByContractId(txData.to, context);
153
- const { args, functionFragment } = api.contract.interface.parseTransaction({
154
- data: (txData.data || txData.input),
155
- });
156
- return { name: functionFragment.name, args: getProperties(args) };
157
- }
5
+ import { decodeJWT } from "did-jwt";
6
+ import { ethers } from "ethers";
7
+ import Joi from "joi";
8
+ import { base64url, calculateJwkThumbprint } from "jose";
9
+ import Multihash from "multihashes";
10
+ import { createHash, randomBytes, randomUUID, } from "node:crypto";
11
+ import { computeSchemaId, encodePrivateKey, encodePublicKey, formatEthersUnsignedTransaction, JoiHexadecimal, multibaseEncode, prefixWith0x, red, removePrefix0x, yellow, } from "../utils/index.js";
12
+ import { ledgerGetTransaction, ledgerGetTransactionReceipt } from "./ledger.js";
158
13
  export async function compute(method, inputs, context) {
159
14
  const { client } = context;
160
15
  switch (method) {
161
- case "signTransaction": {
162
- const unsignedTransaction = inputs[0];
163
- const uTx = formatEthersUnsignedTransaction(JSON.parse(JSON.stringify(unsignedTransaction)));
164
- const sgnTx = await client.ethWallet.signTransaction(uTx);
165
- yellow(sgnTx);
166
- return sgnTx;
167
- }
168
- case "createVpJwt": {
169
- const inputVerifiableCredential = inputs[0];
170
- const payloadVp = inputs[1];
171
- const payloadJwt = inputs[2];
172
- const alg = inputs[3] || "ES256K";
173
- const verifiableCredential = typeof inputVerifiableCredential === "string"
174
- ? [inputVerifiableCredential]
175
- : inputVerifiableCredential;
176
- // NOTE: We cannot use @cef-ebsi/verifiable-presentation library
177
- // because it requires the private key and the CLI tool
178
- // now supports Hardware Wallets, which do not expose private keys.
179
- const now = Math.floor(Date.now() / 1000);
180
- const jti = `urn:did:${randomUUID()}`;
181
- const payload = {
182
- iat: now,
183
- jti,
184
- nbf: now - 60, // 1 minute in the past
185
- exp: now + 120, // 2 minutes in the future
186
- sub: client.did,
187
- iss: client.did,
188
- vp: {
189
- "@context": ["https://www.w3.org/2018/credentials/v1"],
190
- id: jti,
191
- type: ["VerifiablePresentation"],
192
- holder: client.did,
193
- verifiableCredential,
194
- ...payloadVp,
195
- },
196
- aud: "any",
197
- nonce: randomUUID(),
198
- ...payloadJwt,
199
- };
200
- const vp = await client.signJWT(payload, {}, alg);
201
- yellow(vp);
202
- return vp;
203
- }
204
- case "createVcJwt": {
205
- const payloadVc = inputs[0];
206
- const payloadJwt = inputs[1];
207
- const alg = (inputs[2] || "ES256K");
208
- Joi.assert(alg, Joi.string().valid("ES256K", "ES256", "RS256", "EdDSA").required());
209
- const iat = Math.floor(Date.now() / 1000) - 10;
210
- const exp = iat + 5 * 365 * 24 * 3600;
211
- const issuanceDate = `${new Date(iat * 1000)
212
- .toISOString()
213
- .slice(0, -5)}Z`;
214
- const expirationDate = `${new Date(exp * 1000)
215
- .toISOString()
216
- .slice(0, -5)}Z`;
217
- const jti = payloadVc.id || `urn:uuid:${randomUUID()}`;
218
- const sub = payloadVc.credentialSubject?.id;
219
- const payload = {
220
- iat,
221
- jti,
222
- nbf: iat,
223
- exp,
224
- sub,
225
- iss: client.did,
226
- vc: {
227
- "@context": ["https://www.w3.org/2018/credentials/v1"],
228
- id: jti,
229
- type: ["VerifiableCredential"],
230
- issuer: client.did,
231
- issuanceDate,
232
- issued: issuanceDate,
233
- validFrom: issuanceDate,
234
- expirationDate,
235
- ...payloadVc,
236
- },
237
- ...payloadJwt,
238
- };
239
- const vc = await client.signJWT(payload, {}, alg);
240
- yellow(vc);
241
- return vc;
242
- }
243
- case "signJwt": {
244
- const [payload, alg, headers] = inputs;
245
- const jwt = await client.signJWT(payload, headers, alg);
246
- yellow(jwt);
247
- return jwt;
248
- }
249
- case "wait": {
250
- const [seconds] = inputs;
251
- const milliseconds = Math.round(Number(seconds) * 1000);
252
- console.log(`waiting ${milliseconds / 1000} seconds`);
253
- await new Promise((r) => {
254
- setTimeout(r, milliseconds);
255
- });
256
- return 0;
257
- }
258
- case "userPin": {
259
- const [did] = inputs;
260
- const userPin = getUserPin(did);
261
- yellow(userPin);
262
- return userPin;
263
- }
264
- case "schemaId": {
265
- const [schema, base] = inputs;
266
- const schemaId = await computeSchemaId(schema, base);
267
- yellow(schemaId);
268
- return schemaId;
16
+ case "address": {
17
+ const [hexOrJwk] = inputs;
18
+ const publicKeyHex = typeof hexOrJwk === "string"
19
+ ? hexOrJwk
20
+ : encodePublicKey({
21
+ format: "hex",
22
+ key: hexOrJwk,
23
+ });
24
+ const address = ethers.utils.computeAddress(publicKeyHex);
25
+ yellow(address);
26
+ return address;
269
27
  }
270
28
  case "checkStatusList2021CredentialSchema": {
271
29
  const [credential] = inputs;
@@ -279,24 +37,24 @@ export async function compute(method, inputs, context) {
279
37
  .required())
280
38
  .items(Joi.string().uri())
281
39
  .required(),
282
- type: Joi.array()
283
- .ordered(
284
- // First item must be "VerifiableCredential"
285
- Joi.string().valid("VerifiableCredential").required())
286
- .items(
287
- // "StatusList2021Credential" must be present
288
- Joi.string().valid("StatusList2021Credential").required(), Joi.string())
289
- .required(),
290
40
  credentialSubject: Joi.object({
41
+ encodedList: Joi.string().required(),
291
42
  id: Joi.string().uri().required(),
292
- type: Joi.string().valid("StatusList2021").required(),
293
43
  statusPurpose: Joi.string()
294
44
  .valid("revocation", "suspension")
295
45
  .required(),
296
- encodedList: Joi.string().required(),
46
+ type: Joi.string().valid("StatusList2021").required(),
297
47
  })
298
48
  .unknown(true)
299
49
  .required(),
50
+ type: Joi.array()
51
+ .ordered(
52
+ // First item must be "VerifiableCredential"
53
+ Joi.string().valid("VerifiableCredential").required())
54
+ .items(
55
+ // "StatusList2021Credential" must be present
56
+ Joi.string().valid("StatusList2021Credential").required(), Joi.string())
57
+ .required(),
300
58
  })
301
59
  // Allow additional properties
302
60
  .unknown(true));
@@ -346,58 +104,80 @@ export async function compute(method, inputs, context) {
346
104
  yellow(did);
347
105
  return did;
348
106
  }
349
- case "sha256": {
350
- const [data] = inputs;
351
- if (typeof data === "object") {
352
- return sha256(JSON.stringify(data));
353
- }
354
- return sha256(data);
355
- }
356
- case "decodeJWT": {
357
- const jwt = inputs[0];
358
- Joi.assert(jwt, Joi.string());
359
- const decoded = decodeJWT(jwt);
360
- yellow(decoded);
361
- return decoded;
362
- }
363
- case "encodePublicKey": {
364
- const [key, options] = inputs;
365
- Joi.assert(options, Joi.object({
366
- format: Joi.string().valid("jwk", "hex", "pem"),
367
- alg: Joi.string()
368
- .valid("ES256K", "ES256", "RS256", "EdDSA")
369
- .optional(),
370
- }));
371
- const result = encodePublicKey({ key, ...options });
372
- yellow(result);
373
- return result;
374
- }
375
- case "encodePrivateKey": {
376
- const [key, options] = inputs;
377
- Joi.assert(options, Joi.object({
378
- format: Joi.string().valid("jwk", "hex", "pem"),
379
- alg: Joi.string()
380
- .valid("ES256K", "ES256", "RS256", "EdDSA")
381
- .optional(),
382
- type: Joi.string().valid("pkcs1", "pkcs8", "sec1", "spki").optional(),
383
- }));
384
- const result = encodePrivateKey({ key, ...options });
385
- yellow(result);
386
- return result;
387
- }
388
- case "encodeBase64": {
389
- const dec = inputs[0];
390
- Joi.assert(dec, Joi.string());
391
- const encoded = Buffer.from(removePrefix0x(dec), "hex").toString("base64");
392
- yellow(encoded);
393
- return encoded;
107
+ case "createVcJwt": {
108
+ const payloadVc = inputs[0];
109
+ const payloadJwt = inputs[1];
110
+ const alg = (inputs[2] || "ES256K");
111
+ Joi.assert(alg, Joi.string().valid("ES256K", "ES256", "RS256", "EdDSA").required());
112
+ const iat = Math.floor(Date.now() / 1000) - 10;
113
+ const exp = iat + 5 * 365 * 24 * 3600;
114
+ const issuanceDate = `${new Date(iat * 1000)
115
+ .toISOString()
116
+ .slice(0, -5)}Z`;
117
+ const expirationDate = `${new Date(exp * 1000)
118
+ .toISOString()
119
+ .slice(0, -5)}Z`;
120
+ const jti = payloadVc.id || `urn:uuid:${randomUUID()}`;
121
+ const sub = payloadVc.credentialSubject?.id;
122
+ const payload = {
123
+ exp,
124
+ iat,
125
+ iss: client.did,
126
+ jti,
127
+ nbf: iat,
128
+ sub,
129
+ vc: {
130
+ "@context": ["https://www.w3.org/2018/credentials/v1"],
131
+ expirationDate,
132
+ id: jti,
133
+ issuanceDate,
134
+ issued: issuanceDate,
135
+ issuer: client.did,
136
+ type: ["VerifiableCredential"],
137
+ validFrom: issuanceDate,
138
+ ...payloadVc,
139
+ },
140
+ ...payloadJwt,
141
+ };
142
+ const vc = await client.signJWT(payload, {}, alg);
143
+ yellow(vc);
144
+ return vc;
394
145
  }
395
- case "encodeBase64url": {
396
- const dec = inputs[0];
397
- Joi.assert(dec, Joi.string());
398
- const encoded = base64url.encode(Buffer.from(removePrefix0x(dec), "hex"));
399
- yellow(encoded);
400
- return encoded;
146
+ case "createVpJwt": {
147
+ const inputVerifiableCredential = inputs[0];
148
+ const payloadVp = inputs[1];
149
+ const payloadJwt = inputs[2];
150
+ const alg = inputs[3] || "ES256K";
151
+ const verifiableCredential = typeof inputVerifiableCredential === "string"
152
+ ? [inputVerifiableCredential]
153
+ : inputVerifiableCredential;
154
+ // NOTE: We cannot use @cef-ebsi/verifiable-presentation library
155
+ // because it requires the private key and the CLI tool
156
+ // now supports Hardware Wallets, which do not expose private keys.
157
+ const now = Math.floor(Date.now() / 1000);
158
+ const jti = `urn:did:${randomUUID()}`;
159
+ const payload = {
160
+ aud: "any",
161
+ exp: now + 120, // 2 minutes in the future
162
+ iat: now,
163
+ iss: client.did,
164
+ jti,
165
+ nbf: now - 60, // 1 minute in the past
166
+ nonce: randomUUID(),
167
+ sub: client.did,
168
+ vp: {
169
+ "@context": ["https://www.w3.org/2018/credentials/v1"],
170
+ holder: client.did,
171
+ id: jti,
172
+ type: ["VerifiablePresentation"],
173
+ verifiableCredential,
174
+ ...payloadVp,
175
+ },
176
+ ...payloadJwt,
177
+ };
178
+ const vp = await client.signJWT(payload, {}, alg);
179
+ yellow(vp);
180
+ return vp;
401
181
  }
402
182
  case "decodeBase64": {
403
183
  const enc = inputs[0];
@@ -424,6 +204,28 @@ export async function compute(method, inputs, context) {
424
204
  yellow(decoded);
425
205
  return decoded;
426
206
  }
207
+ case "decodeContractData": {
208
+ const [types, dataInput, hasFn] = inputs;
209
+ Joi.assert(types, Joi.array().items(Joi.string()));
210
+ Joi.assert(dataInput, JoiHexadecimal);
211
+ Joi.assert(hasFn, Joi.string().valid("true", "false").optional());
212
+ let fn;
213
+ let data;
214
+ if (hasFn === "true") {
215
+ fn = `0x${removePrefix0x(dataInput).slice(0, 8)}`;
216
+ data = `0x${removePrefix0x(dataInput).slice(8)}`;
217
+ }
218
+ else {
219
+ data = dataInput;
220
+ }
221
+ const decoded = ethers.utils.defaultAbiCoder.decode(types, data);
222
+ const result = {
223
+ data: decoded,
224
+ ...(fn && { functionSig: fn }),
225
+ };
226
+ yellow(result);
227
+ return result;
228
+ }
427
229
  case "decodeHex": {
428
230
  const enc = inputs[0];
429
231
  Joi.assert(enc, Joi.string());
@@ -431,26 +233,102 @@ export async function compute(method, inputs, context) {
431
233
  yellow(decoded);
432
234
  return decoded;
433
235
  }
236
+ case "decodeJWT": {
237
+ const jwt = inputs[0];
238
+ Joi.assert(jwt, Joi.string());
239
+ const decoded = decodeJWT(jwt);
240
+ yellow(decoded);
241
+ return decoded;
242
+ }
434
243
  case "decodeLogs": {
435
244
  const logs = inputs[0];
436
245
  const logsDecoded = await decodeLogs(logs, context);
437
246
  yellow(logsDecoded);
438
247
  return logsDecoded;
439
248
  }
440
- case "decodeTransaction": {
441
- const tx = inputs[0];
442
- const txDecoded = await decodeTransaction(tx, context);
443
- yellow(txDecoded);
444
- return txDecoded;
249
+ case "decodeTransaction": {
250
+ const tx = inputs[0];
251
+ const txDecoded = await decodeTransaction(tx, context);
252
+ yellow(txDecoded);
253
+ return txDecoded;
254
+ }
255
+ case "encodeBase64": {
256
+ const dec = inputs[0];
257
+ Joi.assert(dec, Joi.string());
258
+ const encoded = Buffer.from(removePrefix0x(dec), "hex").toString("base64");
259
+ yellow(encoded);
260
+ return encoded;
261
+ }
262
+ case "encodeBase64url": {
263
+ const dec = inputs[0];
264
+ Joi.assert(dec, Joi.string());
265
+ const encoded = base64url.encode(Buffer.from(removePrefix0x(dec), "hex"));
266
+ yellow(encoded);
267
+ return encoded;
268
+ }
269
+ case "encodeContractData": {
270
+ const [types, data, fn] = inputs;
271
+ Joi.assert(data, Joi.array().items(Joi.string()));
272
+ Joi.assert(types, Joi.array().items(Joi.string()));
273
+ Joi.assert(fn, Joi.string().optional());
274
+ const encoded = ethers.utils.defaultAbiCoder.encode(types, data);
275
+ let result = encoded;
276
+ if (fn) {
277
+ // get the function hash
278
+ const fnHash = /^(?:0x)?[0-9a-fA-F]+$/.test(fn)
279
+ ? fn
280
+ : ethers.utils.keccak256(Buffer.from(fn)).slice(0, 10);
281
+ // prefix the function hash with the encoded data
282
+ result = `${prefixWith0x(fnHash)}${encoded.slice(2)}`;
283
+ }
284
+ yellow(result);
285
+ return result;
286
+ }
287
+ case "encodePrivateKey": {
288
+ const [key, options] = inputs;
289
+ Joi.assert(options, Joi.object({
290
+ alg: Joi.string()
291
+ .valid("ES256K", "ES256", "RS256", "EdDSA")
292
+ .optional(),
293
+ format: Joi.string().valid("jwk", "hex", "pem"),
294
+ type: Joi.string().valid("pkcs1", "pkcs8", "sec1", "spki").optional(),
295
+ }));
296
+ const result = encodePrivateKey({ key, ...options });
297
+ yellow(result);
298
+ return result;
299
+ }
300
+ case "encodePublicKey": {
301
+ const [key, options] = inputs;
302
+ Joi.assert(options, Joi.object({
303
+ alg: Joi.string()
304
+ .valid("ES256K", "ES256", "RS256", "EdDSA")
305
+ .optional(),
306
+ format: Joi.string().valid("jwk", "hex", "pem"),
307
+ }));
308
+ const result = encodePublicKey({ key, ...options });
309
+ yellow(result);
310
+ return result;
311
+ }
312
+ case "epochtime": {
313
+ let result;
314
+ if (!inputs[0])
315
+ result = Math.round(Date.now() / 1000);
316
+ else if (typeof inputs[0] === "string")
317
+ result = Math.round(new Date(inputs[0]).getTime() / 1000);
318
+ else
319
+ result = new Date(inputs[0] * 1000).toISOString();
320
+ yellow(result);
321
+ return result;
322
+ }
323
+ case "length": {
324
+ const [array] = inputs;
325
+ Joi.assert(array, Joi.array());
326
+ const len = array.length;
327
+ yellow(len);
328
+ return len;
445
329
  }
446
- case "timestampId": {
447
- const hash = inputs[0];
448
- Joi.assert(hash, Joi.string());
449
- const bufferSha256 = Buffer.from(sha256(hash), "hex");
450
- const multihash = Multihash.encode(bufferSha256, "sha2-256", 32);
451
- const timestampId = `u${base64url.encode(multihash)}`;
452
- yellow(timestampId);
453
- return timestampId;
330
+ case "randomID": {
331
+ return randomBytes(32).toString("hex");
454
332
  }
455
333
  case "recordId": {
456
334
  const [address, blockNumber, hashValue] = inputs;
@@ -461,37 +339,33 @@ export async function compute(method, inputs, context) {
461
339
  yellow(recordId);
462
340
  return recordId;
463
341
  }
464
- case "randomID": {
465
- return randomBytes(32).toString("hex");
342
+ case "schemaId": {
343
+ const [schema, base] = inputs;
344
+ const schemaId = await computeSchemaId(schema, base);
345
+ yellow(schemaId);
346
+ return schemaId;
466
347
  }
467
- case "length": {
468
- const [array] = inputs;
469
- Joi.assert(array, Joi.array());
470
- const len = array.length;
471
- yellow(len);
472
- return len;
348
+ case "sha256": {
349
+ const [data] = inputs;
350
+ if (typeof data === "object") {
351
+ return sha256(JSON.stringify(data));
352
+ }
353
+ return sha256(data);
473
354
  }
474
- case "epochtime": {
475
- let result;
476
- if (!inputs[0])
477
- result = Math.round(Date.now() / 1000);
478
- else if (typeof inputs[0] === "string")
479
- result = Math.round(new Date(inputs[0]).getTime() / 1000);
480
- else
481
- result = new Date(inputs[0] * 1000).toISOString();
482
- yellow(result);
483
- return result;
355
+ case "signJwt": {
356
+ const [payload, alg, headers] = inputs;
357
+ const jwt = await client.signJWT(payload, headers, alg);
358
+ yellow(jwt);
359
+ return jwt;
484
360
  }
485
- case "subaccountDid": {
486
- const [did] = inputs;
487
- Joi.assert(did, Joi.string());
488
- const subaccountMsiBytes = createHash("sha256")
489
- .update(did, "utf8")
490
- .digest()
491
- .slice(0, 16);
492
- const subaccount = util.createDid(subaccountMsiBytes);
493
- yellow(subaccount);
494
- return subaccount;
361
+ case "signTransaction": {
362
+ const unsignedTransaction = inputs[0];
363
+ const uTx = formatEthersUnsignedTransaction(
364
+ // eslint-disable-next-line unicorn/prefer-structured-clone
365
+ JSON.parse(JSON.stringify(unsignedTransaction)));
366
+ const sgnTx = await client.ethWallet.signTransaction(uTx);
367
+ yellow(sgnTx);
368
+ return sgnTx;
495
369
  }
496
370
  case "statusListIndex": {
497
371
  const [did] = inputs;
@@ -500,46 +374,212 @@ export async function compute(method, inputs, context) {
500
374
  .update(did, "utf8")
501
375
  .digest()
502
376
  .slice(0, 6)
503
- .readUInt32BE() % 131072).toString();
377
+ .readUInt32BE() % 131_072).toString();
504
378
  yellow(statusListIndex);
505
379
  return statusListIndex;
506
380
  }
381
+ case "subaccountDid": {
382
+ const [did] = inputs;
383
+ Joi.assert(did, Joi.string());
384
+ const subaccountMsiBytes = createHash("sha256")
385
+ .update(did, "utf8")
386
+ .digest()
387
+ .slice(0, 16);
388
+ const subaccount = util.createDid(subaccountMsiBytes);
389
+ yellow(subaccount);
390
+ return subaccount;
391
+ }
507
392
  case "thumbprint": {
508
393
  const [hexOrJwk, alg] = inputs;
509
- let publicKeyJwk;
510
- if (typeof hexOrJwk === "string") {
511
- publicKeyJwk = encodePublicKey({
512
- key: hexOrJwk,
513
- format: "jwk",
394
+ const publicKeyJwk = typeof hexOrJwk === "string"
395
+ ? encodePublicKey({
514
396
  alg,
515
- });
516
- }
517
- else {
518
- publicKeyJwk = hexOrJwk;
519
- }
397
+ format: "jwk",
398
+ key: hexOrJwk,
399
+ })
400
+ : hexOrJwk;
520
401
  const thumbprint = await calculateJwkThumbprint(publicKeyJwk, "sha256");
521
402
  yellow(thumbprint);
522
403
  return thumbprint;
523
404
  }
524
- case "address": {
525
- const [hexOrJwk] = inputs;
526
- let publicKeyHex;
527
- if (typeof hexOrJwk === "string") {
528
- publicKeyHex = hexOrJwk;
405
+ case "timestampId": {
406
+ const hash = inputs[0];
407
+ Joi.assert(hash, Joi.string());
408
+ const bufferSha256 = Buffer.from(sha256(hash), "hex");
409
+ const multihash = Multihash.encode(bufferSha256, "sha2-256", 32);
410
+ const timestampId = `u${base64url.encode(multihash)}`;
411
+ yellow(timestampId);
412
+ return timestampId;
413
+ }
414
+ case "userPin": {
415
+ const [did] = inputs;
416
+ const userPin = getUserPin(did);
417
+ yellow(userPin);
418
+ return userPin;
419
+ }
420
+ case "wait": {
421
+ const [seconds] = inputs;
422
+ const milliseconds = Math.round(Number(seconds) * 1000);
423
+ console.log(`waiting ${milliseconds / 1000} seconds`);
424
+ await new Promise((r) => {
425
+ setTimeout(r, milliseconds);
426
+ });
427
+ return 0;
428
+ }
429
+ default: {
430
+ throw new Error(`Invalid method '${method}'`);
431
+ }
432
+ }
433
+ }
434
+ export async function computeVerifyVcJwt(inputs, context) {
435
+ const [vcJwt, options, expectedResult] = inputs;
436
+ const ebsiEnvConfig = {
437
+ hosts: [context.config.domain.replace(/^https?:\/\//, "")],
438
+ network: {
439
+ isOptional: false,
440
+ name: context.config.env,
441
+ },
442
+ scheme: "ebsi",
443
+ services: {
444
+ "did-registry": context.config.api.did.version,
445
+ "trusted-issuers-registry": context.config.api.tir.version,
446
+ "trusted-policies-registry": context.config.api.tpr.version,
447
+ "trusted-schemas-registry": context.config.api.tsr.version,
448
+ },
449
+ };
450
+ try {
451
+ await verifyCredentialJwt(vcJwt, ebsiEnvConfig, options);
452
+ switch (expectedResult) {
453
+ case "expectRevoked": {
454
+ throw new Error("Credential is not revoked");
529
455
  }
530
- else {
531
- publicKeyHex = encodePublicKey({
532
- key: hexOrJwk,
533
- format: "hex",
534
- });
456
+ default: {
457
+ return "Verifiable Credential is valid";
535
458
  }
536
- const address = ethers.utils.computeAddress(publicKeyHex);
537
- yellow(address);
538
- return address;
539
459
  }
540
- default:
541
- throw new Error(`Invalid method '${method}'`);
542
460
  }
461
+ catch (error) {
462
+ if (expectedResult === "expectRevoked") {
463
+ if (error.message === "Credential is not revoked")
464
+ throw error;
465
+ if (error.message.includes("revoked")) {
466
+ return "Verifiable Credential is revoked";
467
+ }
468
+ }
469
+ throw error;
470
+ }
471
+ }
472
+ export async function computeVerifyVpJwt(inputs, context) {
473
+ const [vpJwt, audience, options] = inputs;
474
+ const ebsiEnvConfig = {
475
+ hosts: [context.config.domain.replace(/^https?:\/\//, "")],
476
+ network: {
477
+ isOptional: false,
478
+ name: context.config.env,
479
+ },
480
+ scheme: "ebsi",
481
+ services: {
482
+ "did-registry": context.config.api.did.version,
483
+ "trusted-issuers-registry": context.config.api.tir.version,
484
+ "trusted-policies-registry": context.config.api.tpr.version,
485
+ "trusted-schemas-registry": context.config.api.tsr.version,
486
+ },
487
+ };
488
+ await verifyPresentationJwt(vpJwt, audience, ebsiEnvConfig, options);
489
+ return "Verifiable Presentation is valid";
490
+ }
491
+ export function decodeLog(log, context) {
492
+ const api = getApiByContractId(log.address, context);
493
+ const logDecoded = api.contract.interface.parseLog(log);
494
+ const { args: argsWithArray, name, signature, topic } = logDecoded;
495
+ const args = getProperties(argsWithArray);
496
+ return { args, name, signature, topic };
497
+ }
498
+ export async function decodeLogs(input, context) {
499
+ if (!input)
500
+ throw new Error("Invalid logs: no input provided");
501
+ let receipt;
502
+ let logs;
503
+ if (typeof input === "string") {
504
+ receipt = await ledgerGetTransactionReceipt([input], false, context);
505
+ }
506
+ if (input.receipt) {
507
+ receipt = input.receipt;
508
+ }
509
+ if (input.logs) {
510
+ receipt = input;
511
+ }
512
+ if (receipt) {
513
+ if (!Array.isArray(receipt.logs)) {
514
+ throw new TypeError("Invalid logs: The input must be a transaction hash, a transaction receipt, or an array of logs");
515
+ }
516
+ logs = receipt.logs;
517
+ }
518
+ else {
519
+ if (!Array.isArray(input)) {
520
+ throw new TypeError("Invalid logs: The input must be a transaction hash, a transaction receipt, or an array of logs");
521
+ }
522
+ logs = input;
523
+ }
524
+ return logs.map((log) => decodeLog(log, context));
525
+ }
526
+ export async function decodeTransaction(tx, context) {
527
+ let txData;
528
+ if (typeof tx === "string") {
529
+ txData =
530
+ tx.length <= 66
531
+ ? // it is a tx hash
532
+ (await ledgerGetTransaction([tx], false, context))
533
+ : // it is a signed transaction
534
+ ethers.utils.parseTransaction(tx);
535
+ }
536
+ else {
537
+ txData = tx;
538
+ }
539
+ if (!txData.data && !txData.input) {
540
+ throw new Error("Invalid transaction: There is no input or data");
541
+ }
542
+ const api = getApiByContractId(txData.to, context);
543
+ const { args, functionFragment } = api.contract.interface.parseTransaction({
544
+ data: (txData.data || txData.input),
545
+ });
546
+ return {
547
+ dataDecoded: { args: getProperties(args), name: functionFragment.name },
548
+ tx: txData,
549
+ };
550
+ }
551
+ export function getApiByContractId(contractId, context) {
552
+ const apiName = Object.keys(context.config.api).find((a) => {
553
+ const api = context.config.api[a];
554
+ return (api.contract &&
555
+ contractId.toLowerCase() === api.contract.address.toLowerCase());
556
+ });
557
+ if (!apiName)
558
+ throw new Error(`cannot get API with address ${contractId}`);
559
+ return context.config.api[apiName];
560
+ }
561
+ export function getProperties(input) {
562
+ return Object.keys(input)
563
+ .filter((key) => Number.isNaN(Number(key)))
564
+ .reduce((obj, key) => {
565
+ obj[key] = input[key];
566
+ return obj;
567
+ }, {});
568
+ }
569
+ export function getUserPin(did) {
570
+ return createHash("sha256")
571
+ .update(did)
572
+ .digest()
573
+ .slice(-4)
574
+ .map((byte) => byte % 10)
575
+ .reduce((acc, digit) => `${acc}${digit}`, "");
576
+ }
577
+ export function sha256(data) {
578
+ let hash = createHash("sha256");
579
+ hash = data.startsWith("0x")
580
+ ? hash.update(removePrefix0x(data), "hex")
581
+ : hash.update(data, "utf8");
582
+ return hash.digest().toString("hex");
543
583
  }
544
584
  export default compute;
545
585
  //# sourceMappingURL=compute.js.map