@europeum-ebsi/cli 0.0.0 → 1.0.0-rc.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 (384) hide show
  1. package/LICENSE.txt +289 -289
  2. package/LICENSES.txt +538 -0
  3. package/README.md +1140 -98
  4. package/dist/api/client.d.ts +4 -0
  5. package/dist/api/client.d.ts.map +1 -0
  6. package/dist/api/client.js +14 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/api/fetch.d.ts +13 -0
  9. package/dist/api/fetch.d.ts.map +1 -0
  10. package/dist/api/fetch.js +30 -0
  11. package/dist/api/fetch.js.map +1 -0
  12. package/dist/api/params.d.ts +4 -0
  13. package/dist/api/params.d.ts.map +1 -0
  14. package/dist/api/params.js +9 -0
  15. package/dist/api/params.js.map +1 -0
  16. package/dist/auth/dcql.d.ts +5 -0
  17. package/dist/auth/dcql.d.ts.map +1 -0
  18. package/dist/auth/dcql.js +41 -0
  19. package/dist/auth/dcql.js.map +1 -0
  20. package/dist/auth/presentation.d.ts +30 -0
  21. package/dist/auth/presentation.d.ts.map +1 -0
  22. package/dist/auth/presentation.js +99 -0
  23. package/dist/auth/presentation.js.map +1 -0
  24. package/dist/auth/token.d.ts +11 -0
  25. package/dist/auth/token.d.ts.map +1 -0
  26. package/dist/auth/token.js +116 -0
  27. package/dist/auth/token.js.map +1 -0
  28. package/dist/cli.d.ts +3 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +96 -10
  31. package/dist/cli.js.map +1 -1
  32. package/dist/commands/auth.d.ts +3 -0
  33. package/dist/commands/auth.d.ts.map +1 -0
  34. package/dist/commands/auth.js +99 -0
  35. package/dist/commands/auth.js.map +1 -0
  36. package/dist/commands/config-cmd.d.ts +3 -0
  37. package/dist/commands/config-cmd.d.ts.map +1 -0
  38. package/dist/commands/config-cmd.js +86 -0
  39. package/dist/commands/config-cmd.js.map +1 -0
  40. package/dist/commands/contracts-registry.d.ts +3 -0
  41. package/dist/commands/contracts-registry.d.ts.map +1 -0
  42. package/dist/commands/contracts-registry.js +132 -0
  43. package/dist/commands/contracts-registry.js.map +1 -0
  44. package/dist/commands/did-registry.d.ts +3 -0
  45. package/dist/commands/did-registry.d.ts.map +1 -0
  46. package/dist/commands/did-registry.js +110 -0
  47. package/dist/commands/did-registry.js.map +1 -0
  48. package/dist/commands/faucet.d.ts +3 -0
  49. package/dist/commands/faucet.d.ts.map +1 -0
  50. package/dist/commands/faucet.js +78 -0
  51. package/dist/commands/faucet.js.map +1 -0
  52. package/dist/commands/health.d.ts +3 -0
  53. package/dist/commands/health.d.ts.map +1 -0
  54. package/dist/commands/health.js +20 -0
  55. package/dist/commands/health.js.map +1 -0
  56. package/dist/commands/issuers-registry.d.ts +3 -0
  57. package/dist/commands/issuers-registry.d.ts.map +1 -0
  58. package/dist/commands/issuers-registry.js +340 -0
  59. package/dist/commands/issuers-registry.js.map +1 -0
  60. package/dist/commands/ledger.d.ts +3 -0
  61. package/dist/commands/ledger.d.ts.map +1 -0
  62. package/dist/commands/ledger.js +549 -372
  63. package/dist/commands/ledger.js.map +1 -1
  64. package/dist/commands/onboarding.d.ts +3 -0
  65. package/dist/commands/onboarding.d.ts.map +1 -0
  66. package/dist/commands/onboarding.js +301 -0
  67. package/dist/commands/onboarding.js.map +1 -0
  68. package/dist/commands/openapi.d.ts +3 -0
  69. package/dist/commands/openapi.d.ts.map +1 -0
  70. package/dist/commands/openapi.js +37 -0
  71. package/dist/commands/openapi.js.map +1 -0
  72. package/dist/commands/policies-registry.d.ts +3 -0
  73. package/dist/commands/policies-registry.d.ts.map +1 -0
  74. package/dist/commands/policies-registry.js +198 -0
  75. package/dist/commands/policies-registry.js.map +1 -0
  76. package/dist/commands/registry.d.ts +27 -0
  77. package/dist/commands/registry.d.ts.map +1 -0
  78. package/dist/commands/registry.js +62 -0
  79. package/dist/commands/registry.js.map +1 -0
  80. package/dist/commands/schemas-registry.d.ts +3 -0
  81. package/dist/commands/schemas-registry.d.ts.map +1 -0
  82. package/dist/commands/schemas-registry.js +231 -0
  83. package/dist/commands/schemas-registry.js.map +1 -0
  84. package/dist/commands/shared/args.d.ts +2 -0
  85. package/dist/commands/shared/args.d.ts.map +1 -0
  86. package/dist/commands/shared/args.js +4 -0
  87. package/dist/commands/shared/args.js.map +1 -0
  88. package/dist/commands/shared/wallet-opts.d.ts +9 -0
  89. package/dist/commands/shared/wallet-opts.d.ts.map +1 -0
  90. package/dist/commands/shared/wallet-opts.js +44 -0
  91. package/dist/commands/shared/wallet-opts.js.map +1 -0
  92. package/dist/commands/timestamp.d.ts +3 -0
  93. package/dist/commands/timestamp.d.ts.map +1 -0
  94. package/dist/commands/timestamp.js +250 -0
  95. package/dist/commands/timestamp.js.map +1 -0
  96. package/dist/commands/track-and-trace.d.ts +3 -0
  97. package/dist/commands/track-and-trace.d.ts.map +1 -0
  98. package/dist/commands/track-and-trace.js +235 -0
  99. package/dist/commands/track-and-trace.js.map +1 -0
  100. package/dist/commands/wallet.d.ts +3 -0
  101. package/dist/commands/wallet.d.ts.map +1 -0
  102. package/dist/commands/wallet.js +123 -0
  103. package/dist/commands/wallet.js.map +1 -0
  104. package/dist/config/config.d.ts +45 -0
  105. package/dist/config/config.d.ts.map +1 -0
  106. package/dist/config/config.js +111 -0
  107. package/dist/config/config.js.map +1 -0
  108. package/dist/config/ebsi-env.d.ts +4 -0
  109. package/dist/config/ebsi-env.d.ts.map +1 -0
  110. package/dist/config/ebsi-env.js +37 -0
  111. package/dist/config/ebsi-env.js.map +1 -0
  112. package/dist/crypto/wallet.d.ts +34 -0
  113. package/dist/crypto/wallet.d.ts.map +1 -0
  114. package/dist/crypto/wallet.js +100 -0
  115. package/dist/crypto/wallet.js.map +1 -0
  116. package/dist/index.d.ts +3 -0
  117. package/dist/index.d.ts.map +1 -0
  118. package/dist/index.js +15 -6
  119. package/dist/index.js.map +1 -1
  120. package/dist/ledger/read.d.ts +11 -0
  121. package/dist/ledger/read.d.ts.map +1 -0
  122. package/dist/ledger/read.js +24 -0
  123. package/dist/ledger/read.js.map +1 -0
  124. package/dist/ledger/registries.d.ts +25 -0
  125. package/dist/ledger/registries.d.ts.map +1 -0
  126. package/dist/ledger/registries.js +111 -0
  127. package/dist/ledger/registries.js.map +1 -0
  128. package/dist/ledger/write.d.ts +43 -0
  129. package/dist/ledger/write.d.ts.map +1 -0
  130. package/dist/ledger/write.js +119 -0
  131. package/dist/ledger/write.js.map +1 -0
  132. package/dist/onboarding/vc.d.ts +18 -0
  133. package/dist/onboarding/vc.d.ts.map +1 -0
  134. package/dist/onboarding/vc.js +72 -0
  135. package/dist/onboarding/vc.js.map +1 -0
  136. package/dist/output/format.d.ts +7 -0
  137. package/dist/output/format.d.ts.map +1 -0
  138. package/dist/output/format.js +94 -0
  139. package/dist/output/format.js.map +1 -0
  140. package/dist/tui/App.d.ts +3 -0
  141. package/dist/tui/App.d.ts.map +1 -0
  142. package/dist/tui/App.js +99 -0
  143. package/dist/tui/App.js.map +1 -0
  144. package/dist/tui/CommandPalette.d.ts +8 -0
  145. package/dist/tui/CommandPalette.d.ts.map +1 -0
  146. package/dist/tui/CommandPalette.js +105 -0
  147. package/dist/tui/CommandPalette.js.map +1 -0
  148. package/package.json +66 -108
  149. package/src/api/client.ts +26 -0
  150. package/src/api/fetch.ts +53 -0
  151. package/src/api/params.ts +17 -0
  152. package/src/auth/dcql.ts +84 -0
  153. package/src/auth/presentation.ts +255 -0
  154. package/src/auth/token.ts +244 -0
  155. package/src/cli.ts +164 -0
  156. package/src/commands/auth.ts +119 -0
  157. package/src/commands/config-cmd.ts +122 -0
  158. package/src/commands/contracts-registry.ts +156 -0
  159. package/src/commands/did-registry.ts +126 -0
  160. package/src/commands/faucet.ts +112 -0
  161. package/src/commands/health.ts +21 -0
  162. package/src/commands/issuers-registry.ts +385 -0
  163. package/src/commands/ledger.ts +777 -0
  164. package/src/commands/onboarding.ts +411 -0
  165. package/src/commands/openapi.ts +42 -0
  166. package/src/commands/policies-registry.ts +218 -0
  167. package/src/commands/registry.ts +152 -0
  168. package/src/commands/schemas-registry.ts +255 -0
  169. package/src/commands/shared/args.ts +14 -0
  170. package/src/commands/shared/wallet-opts.ts +85 -0
  171. package/src/commands/timestamp.ts +272 -0
  172. package/src/commands/track-and-trace.ts +263 -0
  173. package/src/commands/wallet.ts +175 -0
  174. package/src/config/config.ts +275 -0
  175. package/src/config/ebsi-env.ts +67 -0
  176. package/src/crypto/wallet.ts +291 -0
  177. package/src/index.ts +24 -0
  178. package/src/ledger/read.ts +70 -0
  179. package/src/ledger/registries.ts +285 -0
  180. package/src/ledger/write.ts +381 -0
  181. package/src/onboarding/vc.ts +205 -0
  182. package/src/output/format.ts +157 -0
  183. package/src/tui/App.tsx +282 -0
  184. package/src/tui/CommandPalette.tsx +223 -0
  185. package/bin/cli.js +0 -13
  186. package/dist/abi/pilot/DidRegistry.js +0 -568
  187. package/dist/abi/pilot/DidRegistry.js.map +0 -1
  188. package/dist/abi/pilot/Ptr.js +0 -666
  189. package/dist/abi/pilot/Ptr.js.map +0 -1
  190. package/dist/abi/pilot/SchemaSCRegistry.js +0 -264
  191. package/dist/abi/pilot/SchemaSCRegistry.js.map +0 -1
  192. package/dist/abi/pilot/Tcr.js +0 -715
  193. package/dist/abi/pilot/Tcr.js.map +0 -1
  194. package/dist/abi/pilot/Timestamp.js +0 -658
  195. package/dist/abi/pilot/Timestamp.js.map +0 -1
  196. package/dist/abi/pilot/Tir.js +0 -428
  197. package/dist/abi/pilot/Tir.js.map +0 -1
  198. package/dist/abi/pilot/TnT.js +0 -842
  199. package/dist/abi/pilot/TnT.js.map +0 -1
  200. package/dist/abi/pilot/Tpr.js +0 -492
  201. package/dist/abi/pilot/Tpr.js.map +0 -1
  202. package/dist/abi/test/DidRegistry.js +0 -568
  203. package/dist/abi/test/DidRegistry.js.map +0 -1
  204. package/dist/abi/test/Ptr.js +0 -666
  205. package/dist/abi/test/Ptr.js.map +0 -1
  206. package/dist/abi/test/SchemaSCRegistry.js +0 -300
  207. package/dist/abi/test/SchemaSCRegistry.js.map +0 -1
  208. package/dist/abi/test/Tcr.js +0 -715
  209. package/dist/abi/test/Tcr.js.map +0 -1
  210. package/dist/abi/test/Timestamp.js +0 -658
  211. package/dist/abi/test/Timestamp.js.map +0 -1
  212. package/dist/abi/test/Tir.js +0 -428
  213. package/dist/abi/test/Tir.js.map +0 -1
  214. package/dist/abi/test/TnT.js +0 -842
  215. package/dist/abi/test/TnT.js.map +0 -1
  216. package/dist/abi/test/Tpr.js +0 -492
  217. package/dist/abi/test/Tpr.js.map +0 -1
  218. package/dist/app.js +0 -659
  219. package/dist/app.js.map +0 -1
  220. package/dist/buildParam/didr.js +0 -374
  221. package/dist/buildParam/didr.js.map +0 -1
  222. package/dist/buildParam/index.js +0 -53
  223. package/dist/buildParam/index.js.map +0 -1
  224. package/dist/buildParam/ptr.js +0 -80
  225. package/dist/buildParam/ptr.js.map +0 -1
  226. package/dist/buildParam/tcr.js +0 -36
  227. package/dist/buildParam/tcr.js.map +0 -1
  228. package/dist/buildParam/timestamp.js +0 -350
  229. package/dist/buildParam/timestamp.js.map +0 -1
  230. package/dist/buildParam/tir.js +0 -110
  231. package/dist/buildParam/tir.js.map +0 -1
  232. package/dist/buildParam/tnt.js +0 -214
  233. package/dist/buildParam/tnt.js.map +0 -1
  234. package/dist/buildParam/tpr.js +0 -91
  235. package/dist/buildParam/tpr.js.map +0 -1
  236. package/dist/buildParam/tsr.js +0 -115
  237. package/dist/buildParam/tsr.js.map +0 -1
  238. package/dist/commands/authorisation.js +0 -144
  239. package/dist/commands/authorisation.js.map +0 -1
  240. package/dist/commands/compute.js +0 -680
  241. package/dist/commands/compute.js.map +0 -1
  242. package/dist/commands/conformance.js +0 -813
  243. package/dist/commands/conformance.js.map +0 -1
  244. package/dist/commands/hardwarewallet.js +0 -41
  245. package/dist/commands/hardwarewallet.js.map +0 -1
  246. package/dist/commands/index.js +0 -8
  247. package/dist/commands/index.js.map +0 -1
  248. package/dist/commands/ptr.js +0 -54
  249. package/dist/commands/ptr.js.map +0 -1
  250. package/dist/commands/tcr.js +0 -50
  251. package/dist/commands/tcr.js.map +0 -1
  252. package/dist/commands/tir.js +0 -64
  253. package/dist/commands/tir.js.map +0 -1
  254. package/dist/commands/tnl.js +0 -81
  255. package/dist/commands/tnl.js.map +0 -1
  256. package/dist/commands/tsr.js +0 -45
  257. package/dist/commands/tsr.js.map +0 -1
  258. package/dist/commands/view.js +0 -53
  259. package/dist/commands/view.js.map +0 -1
  260. package/dist/config.js +0 -497
  261. package/dist/config.js.map +0 -1
  262. package/dist/interfaces/context.js +0 -2
  263. package/dist/interfaces/context.js.map +0 -1
  264. package/dist/interfaces/contracts/ProxyFactory.js +0 -2
  265. package/dist/interfaces/contracts/ProxyFactory.js.map +0 -1
  266. package/dist/interfaces/contracts/ProxyTemplateRegistry.js +0 -2
  267. package/dist/interfaces/contracts/ProxyTemplateRegistry.js.map +0 -1
  268. package/dist/interfaces/contracts/SchemaSCRegistry.js +0 -2
  269. package/dist/interfaces/contracts/SchemaSCRegistry.js.map +0 -1
  270. package/dist/interfaces/contracts/common.js +0 -2
  271. package/dist/interfaces/contracts/common.js.map +0 -1
  272. package/dist/interfaces/index.js +0 -5
  273. package/dist/interfaces/index.js.map +0 -1
  274. package/dist/interfaces/jsonrpc.interface.js +0 -2
  275. package/dist/interfaces/jsonrpc.interface.js.map +0 -1
  276. package/dist/interfaces/paginated-list.interface.js +0 -2
  277. package/dist/interfaces/paginated-list.interface.js.map +0 -1
  278. package/dist/interfaces/unsigned-transaction.interface.js +0 -2
  279. package/dist/interfaces/unsigned-transaction.interface.js.map +0 -1
  280. package/dist/interfaces/utils.interface.js +0 -2
  281. package/dist/interfaces/utils.interface.js.map +0 -1
  282. package/dist/programs/migrateDid.js +0 -159
  283. package/dist/programs/migrateDid.js.map +0 -1
  284. package/dist/programs/migrateDids.js +0 -232
  285. package/dist/programs/migrateDids.js.map +0 -1
  286. package/dist/programs/migrateTsr.js +0 -201
  287. package/dist/programs/migrateTsr.js.map +0 -1
  288. package/dist/scripts/accreditAndAuthorize/conformance/step1 +0 -34
  289. package/dist/scripts/accreditAndAuthorize/conformance/step2 +0 -18
  290. package/dist/scripts/accreditAndAuthorize/conformance/step3 +0 -9
  291. package/dist/scripts/accreditAndAuthorize/conformance/step4 +0 -27
  292. package/dist/scripts/accreditAndAuthorize/conformance/step5 +0 -13
  293. package/dist/scripts/accreditAndAuthorize/conformance/step6 +0 -14
  294. package/dist/scripts/accreditAndAuthorize/conformance/step7 +0 -7
  295. package/dist/scripts/accreditAndAuthorize/test/step1 +0 -34
  296. package/dist/scripts/accreditAndAuthorize/test/step2 +0 -18
  297. package/dist/scripts/accreditAndAuthorize/test/step3 +0 -9
  298. package/dist/scripts/accreditAndAuthorize/test/step4 +0 -27
  299. package/dist/scripts/accreditAndAuthorize/test/step5 +0 -13
  300. package/dist/scripts/accreditAndAuthorize/test/step6 +0 -14
  301. package/dist/scripts/accreditAndAuthorize/test/step7 +0 -7
  302. package/dist/scripts/accreditTI +0 -21
  303. package/dist/scripts/assets/Nodes.json +0 -27
  304. package/dist/scripts/assets/vcdm1.1/CTRevocableCredential.json +0 -30
  305. package/dist/scripts/assets/vcdm1.1/CredentialToAttestVerifiableAuthorisationForTrustChain.json +0 -29
  306. package/dist/scripts/assets/vcdm1.1/Nodes.json +0 -27
  307. package/dist/scripts/assets/vcdm1.1/TrustedNodesList.json +0 -35
  308. package/dist/scripts/assets/vcdm1.1/VerifiableAccreditationToAccredit.json +0 -35
  309. package/dist/scripts/assets/vcdm1.1/VerifiableAccreditationToAttest.json +0 -33
  310. package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationForTrustChain.json +0 -22
  311. package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationToInvoke.json +0 -24
  312. package/dist/scripts/assets/vcdm1.1/VerifiableAuthorisationToOnboard.json +0 -24
  313. package/dist/scripts/assets/vcdm2.0/CredentialToAttestVerifiableAuthorisationForTrustChain.json +0 -29
  314. package/dist/scripts/assets/vcdm2.0/TrustedNodesList.json +0 -36
  315. package/dist/scripts/assets/vcdm2.0/VerifiableAccreditationToAccredit.json +0 -40
  316. package/dist/scripts/assets/vcdm2.0/VerifiableAccreditationToAttest.json +0 -38
  317. package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationForTrustChain.json +0 -30
  318. package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationToInvoke.json +0 -24
  319. package/dist/scripts/assets/vcdm2.0/VerifiableAuthorisationToOnboard.json +0 -23
  320. package/dist/scripts/bootstrap/0a-loadTPROperator +0 -5
  321. package/dist/scripts/bootstrap/0b-loadAdmin +0 -8
  322. package/dist/scripts/bootstrap/1-populateTPR +0 -92
  323. package/dist/scripts/bootstrap/2-populateDID +0 -6
  324. package/dist/scripts/bootstrap/3-populateTimestamp +0 -9
  325. package/dist/scripts/bootstrap/4-populateTIR +0 -8
  326. package/dist/scripts/bootstrap/5-populateTSR +0 -85
  327. package/dist/scripts/bootstrap/6-setupConformanceIssuer +0 -35
  328. package/dist/scripts/bootstrap/README.md +0 -218
  329. package/dist/scripts/issueVcInvoke +0 -10
  330. package/dist/scripts/issueVcOnboard +0 -9
  331. package/dist/scripts/issueVcRootTAO +0 -11
  332. package/dist/scripts/issueVcTAO +0 -12
  333. package/dist/scripts/issueVcTI +0 -12
  334. package/dist/scripts/issueVcTnl +0 -32
  335. package/dist/scripts/issue_CTRevocableCredential +0 -12
  336. package/dist/scripts/issue_SelfAttestationSupportOffice +0 -10
  337. package/dist/scripts/issue_VerifiableAccreditationToAccredit +0 -11
  338. package/dist/scripts/issue_VerifiableAccreditationToAttest +0 -11
  339. package/dist/scripts/issue_VerifiableAuthorisationForTrustChain +0 -10
  340. package/dist/scripts/issue_VerifiableAuthorisationToOnboard +0 -9
  341. package/dist/scripts/preregisterIssuer +0 -6
  342. package/dist/scripts/registerDidDocument +0 -15
  343. package/dist/scripts/registerIssuer +0 -6
  344. package/dist/scripts/updateVcRootTAO +0 -10
  345. package/dist/scripts/updateVcTAO +0 -11
  346. package/dist/scripts/updateVcTI +0 -11
  347. package/dist/scripts/vcdm2.0/issueSelfAttestationSupportOffice +0 -10
  348. package/dist/scripts/vcdm2.0/issueVcInvoke +0 -12
  349. package/dist/scripts/vcdm2.0/issueVcOnboard +0 -11
  350. package/dist/scripts/vcdm2.0/issueVcRootTAO +0 -14
  351. package/dist/scripts/vcdm2.0/issueVcTAO +0 -15
  352. package/dist/scripts/vcdm2.0/issueVcTI +0 -15
  353. package/dist/scripts/vcdm2.0/issueVcTnl +0 -34
  354. package/dist/scripts/vcdm2.0/registerDidDocument +0 -15
  355. package/dist/scripts/vcdm2.0/updateVcRootTAO +0 -13
  356. package/dist/scripts/vcdm2.0/updateVcTAO +0 -14
  357. package/dist/scripts/vcdm2.0/updateVcTI +0 -14
  358. package/dist/scripts/vcdm2.0/verifyVcTnl +0 -10
  359. package/dist/scripts/verifyVcTnl +0 -10
  360. package/dist/scripts/wct/accreditAndAuthorize +0 -133
  361. package/dist/scripts/wct/accreditAndAuthorize2 +0 -89
  362. package/dist/scripts/wct/holderWallet +0 -39
  363. package/dist/scripts/wct/holderWallet2 +0 -39
  364. package/dist/scripts/wct/issueToHolder +0 -38
  365. package/dist/scripts/wct/issueToHolder2 +0 -38
  366. package/dist/scripts/wct/pda1 +0 -3
  367. package/dist/scripts/wct/verifier +0 -8
  368. package/dist/scripts/wct/verifier2 +0 -7
  369. package/dist/utils/Client.js +0 -155
  370. package/dist/utils/Client.js.map +0 -1
  371. package/dist/utils/HardwareWallet.js +0 -326
  372. package/dist/utils/HardwareWallet.js.map +0 -1
  373. package/dist/utils/http.js +0 -132
  374. package/dist/utils/http.js.map +0 -1
  375. package/dist/utils/index.js +0 -8
  376. package/dist/utils/index.js.map +0 -1
  377. package/dist/utils/jsonrpc.js +0 -38
  378. package/dist/utils/jsonrpc.js.map +0 -1
  379. package/dist/utils/print.js +0 -56
  380. package/dist/utils/print.js.map +0 -1
  381. package/dist/utils/utils.js +0 -427
  382. package/dist/utils/utils.js.map +0 -1
  383. package/dist/utils/vcdm.js +0 -47
  384. package/dist/utils/vcdm.js.map +0 -1
@@ -0,0 +1,244 @@
1
+ import { createVerifiablePresentationJwt } from "@europeum-ebsi/verifiable-presentation/vcdm11.js";
2
+ import { decodeJwt } from "jose";
3
+ import { randomUUID } from "node:crypto";
4
+
5
+ import type { CliConfig } from "../config/config.ts";
6
+ import type { WalletDetails } from "../crypto/wallet.ts";
7
+
8
+ import { buildEbsiEnvConfig } from "../config/ebsi-env.ts";
9
+ import {
10
+ buildDcqlVpToken,
11
+ createSelfAttestationVcJwt,
12
+ dcqlCredentialQueryId,
13
+ } from "./dcql.ts";
14
+ import {
15
+ buildPresentationSubmission,
16
+ requiresVc,
17
+ scopeFamilies,
18
+ } from "./presentation.ts";
19
+
20
+ const DID_REGISTRY_INVITE_FAMILY = "did-registry:invite";
21
+
22
+ export interface GetAccessTokenOptions {
23
+ config: CliConfig;
24
+ scope: string;
25
+ /**
26
+ * Which OpenID4VP grant to speak: `"draft14"` (default), the legacy
27
+ * Presentation Exchange grant, or `"1.0"`, the final DCQL grant. Both are
28
+ * accepted side by side by the Authorisation service; this only picks
29
+ * which one the CLI itself sends.
30
+ */
31
+ spec?: "1.0" | "draft14";
32
+ vcJwt?: string;
33
+ wallet: WalletDetails;
34
+ }
35
+
36
+ /**
37
+ * Obtains an EBSI access token via the OIDC4VP `vp_token` grant flow.
38
+ *
39
+ * Mirrors the behaviour of `getAccessToken.ts` from the API test helpers.
40
+ *
41
+ * @param opts.scope - The EBSI scope string, e.g. "did-registry:write" or "issuers-registry:invite"
42
+ * @param opts.spec - Which grant to speak: "draft14" (default, legacy PEX) or "1.0" (DCQL)
43
+ * @param opts.vcJwt - A VC JWT to include in the VP (required for VC-required scopes)
44
+ * @param opts.wallet - Resolved wallet details; `wallet.signingKey()` picks the
45
+ * key that signs the VP (throws if both an ES256K and an ES256 key are
46
+ * configured with no --sign-alg to choose between them)
47
+ */
48
+ export async function getAccessToken(
49
+ opts: GetAccessTokenOptions,
50
+ ): Promise<string> {
51
+ const { config, scope, spec = "draft14", vcJwt, wallet } = opts;
52
+
53
+ if (!vcJwt && requiresVc(scope)) {
54
+ throw new Error(
55
+ `Scope "${scope}" requires a Verifiable Credential. ` +
56
+ "Pass --vc <file> with a path to a VC JWT file.",
57
+ );
58
+ }
59
+
60
+ // Resolved once: throws when both keys are configured and no --sign-alg
61
+ // (or EBSI_SIGN_ALG / `ebsi config set signAlg`) chose one.
62
+ const signingKey = wallet.signingKey();
63
+
64
+ // `did-registry:invite`: the presented VerifiableAuthorisationToOnboard VC must
65
+ // authorise the signing key -- via `credentialSubject.jwkThumbprint` --
66
+ // or the Authorisation service will reject the request. Catch a mismatch
67
+ // here instead of round-tripping to the server, since it usually means
68
+ // either the wrong VC or the wrong key was passed.
69
+ if (vcJwt && scopeFamilies(scope).includes(DID_REGISTRY_INVITE_FAMILY)) {
70
+ const { vc } = decodeJwt(vcJwt) as {
71
+ vc?: { credentialSubject?: { jwkThumbprint?: unknown } };
72
+ };
73
+ const jwkThumbprint = vc?.credentialSubject?.jwkThumbprint;
74
+
75
+ if (!jwkThumbprint) {
76
+ throw new Error(
77
+ "The Verifiable Credential passed via --vc is missing " +
78
+ "credentialSubject.jwkThumbprint, which the Authorisation service " +
79
+ `requires for the "did-registry:invite" scope. Ask the issuer for a VC that ` +
80
+ `authorises this key (thumbprint: ${signingKey.thumbprint}).`,
81
+ );
82
+ }
83
+
84
+ if (typeof jwkThumbprint !== "string") {
85
+ throw new TypeError(
86
+ "The Verifiable Credential passed via --vc has an invalid " +
87
+ "credentialSubject.jwkThumbprint property (not a string).",
88
+ );
89
+ }
90
+
91
+ if (jwkThumbprint !== signingKey.thumbprint) {
92
+ throw new Error(
93
+ "The Verifiable Credential passed via --vc authorises a different " +
94
+ `key (thumbprint: ${jwkThumbprint}) than the signing key ` +
95
+ `(thumbprint: ${signingKey.thumbprint}). Use the key the VC was ` +
96
+ "issued for, request a new VC for this key, or pass --sign-alg to " +
97
+ "select the intended key.",
98
+ );
99
+ }
100
+ }
101
+
102
+ const { issuer, tokenEndpoint } = await discoverAuthEndpoints(config.baseUrl);
103
+ const ebsiEnvConfig = buildEbsiEnvConfig(config);
104
+ const nonce = randomUUID();
105
+ const now = Math.floor(Date.now() / 1000);
106
+
107
+ // On the OpenID4VP 1.0 (final)/DCQL grant, a combinable scope with no VC of
108
+ // its own (did-registry:write, issuers-registry:write, etc.) presents a self-issued placeholder
109
+ // credential instead of an empty VP -- DCQL requires `credentials` to be
110
+ // non-empty, unlike the legacy grant's `input_descriptors: []` (see
111
+ // `createSelfAttestationVcJwt`).
112
+ const dcqlSelfAttestationVc =
113
+ spec === "1.0" && !vcJwt
114
+ ? createSelfAttestationVcJwt(signingKey)
115
+ : undefined;
116
+
117
+ // Mutually exclusive by construction: `dcqlSelfAttestationVc` is only ever
118
+ // built when `!vcJwt` (see above).
119
+ const credential = vcJwt ?? dcqlSelfAttestationVc;
120
+
121
+ const vpPayload = {
122
+ "@context": ["https://www.w3.org/2018/credentials/v1"],
123
+ holder: signingKey.issuer.did,
124
+ type: ["VerifiablePresentation"],
125
+ verifiableCredential: credential ? [credential] : [],
126
+ };
127
+
128
+ const vpJwt = await createVerifiablePresentationJwt(
129
+ vpPayload,
130
+ signingKey.issuer,
131
+ issuer,
132
+ ebsiEnvConfig,
133
+ {
134
+ exp: now + 100,
135
+ // Needed only for "did-registry:invite": the holder DID isn't registered yet,
136
+ // so the server verifies the VP signature against this self-asserted
137
+ // header jwk instead of a DID Document. Every other scope's holder is
138
+ // already resolvable, so this would be superfluous there.
139
+ ...(scopeFamilies(scope).includes(DID_REGISTRY_INVITE_FAMILY) && {
140
+ header: { jwk: signingKey.publicKeyJwk },
141
+ }),
142
+ nbf: now - 100,
143
+ nonce,
144
+ skipValidation: true,
145
+ },
146
+ );
147
+
148
+ if (spec === "1.0") {
149
+ // Every combinable family shares the same DCQL credential-query id
150
+ // (self_attestation_credential), so it doesn't matter which of a
151
+ // combined request's families is used to look it up.
152
+ const credentialQueryId = dcqlCredentialQueryId(scopeFamilies(scope)[0]!);
153
+
154
+ const body = new URLSearchParams({
155
+ grant_type: "vp_token",
156
+ scope: `openid ${scope}`,
157
+ vp_token: buildDcqlVpToken(credentialQueryId, vpJwt),
158
+ });
159
+
160
+ return submitTokenRequest(tokenEndpoint, body);
161
+ }
162
+
163
+ const submissionId = randomUUID();
164
+ const presentationSubmission = buildPresentationSubmission(
165
+ scope,
166
+ submissionId,
167
+ );
168
+
169
+ const body = new URLSearchParams({
170
+ grant_type: "vp_token",
171
+ presentation_submission: JSON.stringify(presentationSubmission),
172
+ scope: `openid ${scope}`,
173
+ vp_token: vpJwt,
174
+ });
175
+
176
+ return submitTokenRequest(tokenEndpoint, body);
177
+ }
178
+
179
+ /**
180
+ * Discovers the auth token endpoint from the authorisation service's
181
+ * OpenID Connect discovery document.
182
+ *
183
+ * Returns `{ issuer, tokenEndpoint }` where `issuer` is used as the VP audience.
184
+ */
185
+ async function discoverAuthEndpoints(
186
+ baseUrl: string,
187
+ ): Promise<{ issuer: string; tokenEndpoint: string }> {
188
+ const discoveryUrl = `${baseUrl}/auth/.well-known/openid-configuration`;
189
+ const resp = await fetch(discoveryUrl, {
190
+ headers: { Accept: "application/json" },
191
+ });
192
+ if (!resp.ok) {
193
+ throw new Error(
194
+ `Failed to fetch OpenID config from ${discoveryUrl}: HTTP ${resp.status.toString()}`,
195
+ );
196
+ }
197
+ const body = (await resp.json()) as {
198
+ issuer?: string;
199
+ token_endpoint?: string;
200
+ };
201
+ const { issuer, token_endpoint: tokenEndpoint } = body;
202
+ if (!issuer || !tokenEndpoint) {
203
+ throw new Error(
204
+ `OpenID config at ${discoveryUrl} is missing 'issuer' or 'token_endpoint'`,
205
+ );
206
+ }
207
+ return { issuer, tokenEndpoint };
208
+ }
209
+
210
+ /**
211
+ * POSTs a `vp_token` grant's form body to the token endpoint and extracts
212
+ * `access_token` from the response. Shared by both the legacy (draft 14) and
213
+ * 1.0 (final) OpenID4VP grants -- once the (differently-shaped) request body
214
+ * is built, submitting it and handling the response is identical either way.
215
+ */
216
+ async function submitTokenRequest(
217
+ tokenEndpoint: string,
218
+ body: URLSearchParams,
219
+ ): Promise<string> {
220
+ const resp = await fetch(tokenEndpoint, {
221
+ body: body.toString(),
222
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
223
+ method: "POST",
224
+ });
225
+
226
+ if (!resp.ok) {
227
+ let detail: string;
228
+ try {
229
+ const errBody = await resp.text();
230
+ detail = errBody;
231
+ } catch {
232
+ detail = `HTTP ${resp.status.toString()}`;
233
+ }
234
+ throw new Error(
235
+ `Token request failed (HTTP ${resp.status.toString()}): ${detail}`,
236
+ );
237
+ }
238
+
239
+ const data = (await resp.json()) as { access_token?: string };
240
+ if (!data.access_token) {
241
+ throw new Error("Token response did not contain 'access_token'");
242
+ }
243
+ return data.access_token;
244
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,164 @@
1
+ import { Command } from "commander";
2
+
3
+ import { COMMANDS } from "./commands/registry.ts";
4
+ import { resolveConfig } from "./config/config.ts";
5
+ import { printError, printResult } from "./output/format.ts";
6
+
7
+ /**
8
+ * Builds and returns the Commander program.
9
+ *
10
+ * The command tree is assembled from the COMMANDS registry so that the same
11
+ * single source of truth drives both the non-interactive CLI and the TUI
12
+ * command palette.
13
+ */
14
+ export function buildProgram(): Command {
15
+ const program = new Command();
16
+
17
+ program
18
+ .name("ebsi")
19
+ .description("EBSI Core CLI — interact with the EBSI Core API")
20
+ .version("1.0.0-rc.0")
21
+ // Global options inherited by all sub-commands
22
+ .option(
23
+ "--env <env>",
24
+ "EBSI environment (local, test, pilot, preprod, prod)",
25
+ )
26
+ .option("--base-url <url>", "Override the API base URL (incl. /v1 prefix)")
27
+ .option("--output <format>", "Output format: pretty (default), json, table")
28
+ .option(
29
+ "--token <jwt>",
30
+ "Bearer access token for authenticated requests (e.g. POST /ledger write methods). " +
31
+ "Also read from EBSI_ACCESS_TOKEN env var or `ebsi config set token <jwt>`.",
32
+ )
33
+ .option(
34
+ "--es256k-key <hex>",
35
+ "Secp256k1 private key (0x-prefixed hex). Mandatory for anything that signs: " +
36
+ "always signs Ethereum transactions, and signs VCs/VPs unless --sign-alg is ES256. " +
37
+ "Also read from EBSI_ES256K_PRIVATE_KEY env var or `ebsi config set es256kPrivateKey <hex>`. " +
38
+ "WARNING: passing keys on the command line may expose them in shell history.",
39
+ )
40
+ .option(
41
+ "--es256-key <hex>",
42
+ "P-256 private key (hex), optional — for signing VCs/VPs only (e.g. an `auth token` " +
43
+ "request). Also read from EBSI_ES256_PRIVATE_KEY env var or " +
44
+ "`ebsi config set es256PrivateKey <hex>`.",
45
+ )
46
+ .option(
47
+ "--sign-alg <alg>",
48
+ 'Which key signs VCs/VPs: "ES256" or "ES256K". Required when both keys are ' +
49
+ "configured. Also read from EBSI_SIGN_ALG env var or `ebsi config set signAlg <alg>`.",
50
+ )
51
+ .option(
52
+ "--did <did>",
53
+ "EBSI DID (did:ebsi:...) to associate with the key(s). " +
54
+ "Also read from EBSI_DID env var or `ebsi config set did <did>`. " +
55
+ "If omitted when running `wallet create`, a new random DID is generated.",
56
+ );
57
+
58
+ // Build a sub-command tree from each descriptor's segment path, creating
59
+ // (or reusing) one Command node per segment so paths of any depth work —
60
+ // not just the "group", "group action", and "group sub action" shapes.
61
+ const nodes = new Map<string, Command>();
62
+ const configured = new Set<string>();
63
+
64
+ for (const descriptor of COMMANDS) {
65
+ let parent = program;
66
+ const path: string[] = [];
67
+
68
+ for (const [index, segment] of descriptor.segments.entries()) {
69
+ path.push(segment);
70
+ const key = path.join(".");
71
+ let node = nodes.get(key);
72
+ if (!node) {
73
+ node = new Command(segment).description(
74
+ index === 0
75
+ ? `Commands for the ${descriptor.group} API`
76
+ : `${descriptor.group} ${path.slice(1).join(" ")} commands`,
77
+ );
78
+ parent.addCommand(node);
79
+ nodes.set(key, node);
80
+ }
81
+ parent = node;
82
+ }
83
+
84
+ const leafKey = descriptor.segments.join(".");
85
+ /* v8 ignore next -- no two command descriptors share a full segment path */
86
+ if (configured.has(leafKey)) continue;
87
+ configured.add(leafKey);
88
+ configureLeaf(parent, descriptor);
89
+ }
90
+
91
+ return program;
92
+ }
93
+
94
+ /**
95
+ * Attaches positional args, options, help text, and action handler to a leaf
96
+ * Commander command from a CommandDescriptor.
97
+ */
98
+ function configureLeaf(
99
+ cmd: Command,
100
+ descriptor: (typeof COMMANDS)[number],
101
+ ): void {
102
+ cmd.description(descriptor.summary);
103
+
104
+ for (const arg of descriptor.args) {
105
+ if (arg.required) {
106
+ cmd.argument(`<${arg.name}>`, arg.description);
107
+ } else {
108
+ cmd.argument(`[${arg.name}]`, arg.description);
109
+ }
110
+ }
111
+
112
+ for (const opt of descriptor.options) {
113
+ cmd.option(opt.flags, opt.description, opt.defaultValue);
114
+ }
115
+
116
+ cmd.action(async (...cmdArgs: unknown[]) => {
117
+ // Commander passes positional args first, then the Command instance
118
+ // (and any parent option values via parent chain)
119
+ const commandInstance = cmdArgs.at(-1) as Command;
120
+
121
+ // Collect positional arg values
122
+ const positional = cmdArgs.slice(0, descriptor.args.length) as string[];
123
+ const argMap: Record<string, string> = {};
124
+ for (const [i, arg] of descriptor.args.entries()) {
125
+ argMap[arg.name] = positional[i] ?? "";
126
+ }
127
+
128
+ // optsWithGlobals() merges options from the entire parent chain
129
+ const mergedOpts =
130
+ commandInstance.optsWithGlobals<Record<string, string>>();
131
+
132
+ try {
133
+ // resolveConfig can throw (e.g. the legacy EBSI_PRIVATE_KEY migration
134
+ // error, or an invalid --sign-alg) -- resolved inside this try so that,
135
+ // like every other command error, it goes through printError/exitCode
136
+ // instead of surfacing as an unhandled rejection. `config`/`config set`
137
+ // itself stays reachable even while that migration error would
138
+ // otherwise fire everywhere else, so the user has a way to fix it.
139
+ const config = resolveConfig(
140
+ Object.fromEntries(
141
+ Object.entries({
142
+ baseUrl: mergedOpts["baseUrl"],
143
+ did: mergedOpts["did"],
144
+ env: mergedOpts["env"],
145
+ es256Key: mergedOpts["es256Key"],
146
+ es256kKey: mergedOpts["es256kKey"],
147
+ output: mergedOpts["output"],
148
+ signAlg: mergedOpts["signAlg"],
149
+ token: mergedOpts["token"],
150
+ }).filter(([, v]) => v !== undefined),
151
+ ),
152
+ { allowLegacyPrivateKey: descriptor.segments[0] === "config" },
153
+ );
154
+
155
+ const data = await descriptor.handler(argMap, mergedOpts, config);
156
+ printResult(data, config.output);
157
+ } catch (error) {
158
+ const message = error instanceof Error ? error.message : "Unknown error";
159
+ const detail = error instanceof Error ? error.cause : error;
160
+ printError(message, detail);
161
+ process.exitCode = 1;
162
+ }
163
+ });
164
+ }
@@ -0,0 +1,119 @@
1
+ import { readFileSync } from "node:fs";
2
+
3
+ import type { CommandDescriptor } from "./registry.ts";
4
+
5
+ import { KNOWN_SCOPES, validateScope } from "../auth/presentation.ts";
6
+ import { getAccessToken } from "../auth/token.ts";
7
+ import { setPersistedConfigValue } from "../config/config.ts";
8
+ import { resolveWallet, WALLET_KEY_OPTIONS } from "./shared/wallet-opts.ts";
9
+
10
+ export const authCommands: CommandDescriptor[] = [
11
+ {
12
+ args: [],
13
+ group: "Auth",
14
+ async handler(_args, opts, config) {
15
+ const scope = opts["scope"];
16
+ if (!scope) {
17
+ throw new Error(
18
+ "Missing --scope. Provide one of: " + KNOWN_SCOPES.join(", "),
19
+ );
20
+ }
21
+ // Throws a descriptive error for unknown scopes, duplicates, or an
22
+ // illegal combination (e.g. mixing an invite scope with a write scope).
23
+ validateScope(scope);
24
+
25
+ const wallet = await resolveWallet(opts, config);
26
+
27
+ // Load VC from file if provided
28
+ let vcJwt: string | undefined;
29
+ const vcFile = opts["vc"];
30
+ if (vcFile) {
31
+ try {
32
+ vcJwt = readFileSync(vcFile, "utf8").trim();
33
+ } catch (error) {
34
+ const message =
35
+ error instanceof Error ? error.message : String(error);
36
+ throw new Error(`Failed to read VC file "${vcFile}": ${message}`, {
37
+ cause: error,
38
+ });
39
+ }
40
+ }
41
+
42
+ const specOpt = opts["spec"];
43
+ if (specOpt !== undefined && specOpt !== "draft14" && specOpt !== "1.0") {
44
+ throw new Error('Invalid --spec value. Must be "draft14" or "1.0".');
45
+ }
46
+
47
+ const accessToken = await getAccessToken({
48
+ config,
49
+ scope,
50
+ wallet,
51
+ ...(specOpt !== undefined && { spec: specOpt }),
52
+ ...(vcJwt !== undefined && { vcJwt }),
53
+ });
54
+
55
+ // Optionally persist the token
56
+ const save = Boolean(opts["save"]);
57
+ if (save) {
58
+ setPersistedConfigValue("token", accessToken);
59
+ }
60
+
61
+ return {
62
+ access_token: accessToken,
63
+ did: wallet.did,
64
+ saved: save,
65
+ scope,
66
+ signedWith: wallet.signingKey().alg,
67
+ };
68
+ },
69
+ id: "auth.token",
70
+ options: [
71
+ {
72
+ description:
73
+ "EBSI authorisation scope. Required. Either a single scope " +
74
+ '(e.g. "did-registry:write", "did-registry:invite"), or a space-separated combination of ' +
75
+ 'write scopes for a multi-scope token (e.g. "did-registry:write issuers-registry:write"). ' +
76
+ "Only did-registry:write, issuers-registry:write, timestamp:write, track-and-trace:create, track-and-trace:write, policies-registry:write, " +
77
+ "and schemas-registry:write can be combined — invite/invoke scopes must be requested alone. " +
78
+ "Scopes that need a VC (did-registry:invite, ledger:invoke, issuers-registry:invite, track-and-trace:authorise) " +
79
+ "also require --vc and cannot be combined. Any scope may be suffixed with " +
80
+ '":<0x-address>" (e.g. "track-and-trace:write:0x61c36a8d610163660E21a8b7359e1Cac0C9133e1") ' +
81
+ "to target a specific deployed contract instance instead of the environment default.",
82
+ flags: "--scope <scope>",
83
+ },
84
+ {
85
+ description:
86
+ "Path to a VC JWT file. Required for invite/invoke scopes " +
87
+ "(did-registry:invite, ledger:invoke, issuers-registry:invite, track-and-trace:authorise).",
88
+ flags: "--vc <file>",
89
+ },
90
+ {
91
+ description:
92
+ "Persist the obtained access token to config (equivalent to `ebsi config set token <jwt>`).",
93
+ flags: "--save",
94
+ },
95
+ ...WALLET_KEY_OPTIONS,
96
+ {
97
+ description: "EBSI DID — overrides config/env.",
98
+ flags: "--did <did>",
99
+ },
100
+ {
101
+ description:
102
+ 'Which OpenID4VP grant to speak: "draft14" (default, legacy Presentation ' +
103
+ 'Exchange) or "1.0" (final, DCQL). Both are accepted by the Authorisation ' +
104
+ "service side by side.",
105
+ flags: "--spec <draft14|1.0>",
106
+ },
107
+ ],
108
+ segments: ["auth", "token"],
109
+ summary:
110
+ "Obtain an EBSI access token via the OIDC4VP `vp_token` grant flow. " +
111
+ "Requires a configured secp256k1 key (--es256k-key, EBSI_ES256K_PRIVATE_KEY, " +
112
+ "or `ebsi config set es256kPrivateKey`); when a P-256 key is also configured, " +
113
+ "--sign-alg picks which one signs the VP. " +
114
+ 'Pass several space-separated write scopes (e.g. --scope "did-registry:write issuers-registry:write") ' +
115
+ "to mint a single multi-scope token. " +
116
+ "Use --vc <file> for scopes that require a Verifiable Credential. " +
117
+ "Use --save to persist the token for subsequent commands.",
118
+ },
119
+ ];
@@ -0,0 +1,122 @@
1
+ import type { CommandDescriptor } from "./registry.ts";
2
+
3
+ import {
4
+ EBSI_ENVS,
5
+ getConfigFilePath,
6
+ getPersistedConfigValue,
7
+ OUTPUT_FORMATS,
8
+ setPersistedConfigValue,
9
+ SIGN_ALGS,
10
+ } from "../config/config.ts";
11
+ import { requiredArg } from "./shared/args.ts";
12
+
13
+ const SETTABLE_KEYS = [
14
+ "did",
15
+ "env",
16
+ "es256PrivateKey",
17
+ "es256kPrivateKey",
18
+ "output",
19
+ "signAlg",
20
+ "token",
21
+ ] as const;
22
+ type SettableKey = (typeof SETTABLE_KEYS)[number];
23
+
24
+ export const configCommands: CommandDescriptor[] = [
25
+ {
26
+ args: [
27
+ {
28
+ description: `Config key to read (${SETTABLE_KEYS.join(", ")})`,
29
+ example: "env",
30
+ name: "key",
31
+ required: true,
32
+ },
33
+ ],
34
+ group: "Config",
35
+ // eslint-disable-next-line @typescript-eslint/require-await
36
+ async handler(args) {
37
+ const key = args["key"] as SettableKey;
38
+ if (!SETTABLE_KEYS.includes(key)) {
39
+ throw new Error(
40
+ `Unknown config key "${key}". Valid keys: ${SETTABLE_KEYS.join(", ")}`,
41
+ );
42
+ }
43
+ const value = getPersistedConfigValue(key);
44
+ return {
45
+ configFile: getConfigFilePath(),
46
+ key,
47
+ value: value ?? undefined,
48
+ };
49
+ },
50
+ id: "config.get",
51
+ options: [],
52
+ segments: ["config", "get"],
53
+ summary:
54
+ "Show the current persisted config value for a key " +
55
+ "(did, env, es256PrivateKey, es256kPrivateKey, output, signAlg, token)",
56
+ },
57
+ {
58
+ args: [
59
+ {
60
+ description: `Config key (${SETTABLE_KEYS.join(", ")})`,
61
+ example: "env",
62
+ name: "key",
63
+ required: true,
64
+ },
65
+ {
66
+ description: "Value to set",
67
+ example: "test",
68
+ name: "value",
69
+ required: true,
70
+ },
71
+ ],
72
+ group: "Config",
73
+ // eslint-disable-next-line @typescript-eslint/require-await
74
+ async handler(args) {
75
+ const key = args["key"] as SettableKey;
76
+
77
+ if (!SETTABLE_KEYS.includes(key)) {
78
+ throw new Error(
79
+ `Unknown config key "${key}". Valid keys: ${SETTABLE_KEYS.join(", ")}`,
80
+ );
81
+ }
82
+
83
+ const value = requiredArg(args, "value");
84
+
85
+ // Validate values
86
+ if (
87
+ key === "env" &&
88
+ !EBSI_ENVS.includes(value as (typeof EBSI_ENVS)[number])
89
+ ) {
90
+ throw new Error(
91
+ `Invalid env "${value}". Valid values: ${EBSI_ENVS.join(", ")}`,
92
+ );
93
+ }
94
+ if (
95
+ key === "output" &&
96
+ !OUTPUT_FORMATS.includes(value as (typeof OUTPUT_FORMATS)[number])
97
+ ) {
98
+ throw new Error(
99
+ `Invalid output "${value}". Valid values: ${OUTPUT_FORMATS.join(", ")}`,
100
+ );
101
+ }
102
+ if (
103
+ key === "signAlg" &&
104
+ !SIGN_ALGS.includes(value.toUpperCase() as (typeof SIGN_ALGS)[number])
105
+ ) {
106
+ throw new Error(
107
+ `Invalid signAlg "${value}". Valid values: ${SIGN_ALGS.join(", ")}`,
108
+ );
109
+ }
110
+
111
+ setPersistedConfigValue(key, value);
112
+ return { configFile: getConfigFilePath(), key, value };
113
+ },
114
+ id: "config.set",
115
+ options: [],
116
+ segments: ["config", "set"],
117
+ summary:
118
+ "Persist a config value (key=did|env|es256PrivateKey|es256kPrivateKey|output|signAlg|token, " +
119
+ "value=...). WARNING: storing es256PrivateKey/es256kPrivateKey persists the key(s) as " +
120
+ "plaintext in the config file.",
121
+ },
122
+ ];