@enbox/agent 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/dist/browser.js +2215 -0
  2. package/dist/browser.js.map +7 -0
  3. package/dist/browser.mjs +2215 -0
  4. package/dist/browser.mjs.map +7 -0
  5. package/dist/cjs/index.js +8530 -0
  6. package/dist/cjs/index.js.map +7 -0
  7. package/dist/cjs/package.json +1 -0
  8. package/dist/esm/agent-did-resolver-cache.js +87 -0
  9. package/dist/esm/agent-did-resolver-cache.js.map +1 -0
  10. package/dist/esm/bearer-identity.js +41 -0
  11. package/dist/esm/bearer-identity.js.map +1 -0
  12. package/dist/esm/connect.js +191 -0
  13. package/dist/esm/connect.js.map +1 -0
  14. package/dist/esm/crypto-api.js +346 -0
  15. package/dist/esm/crypto-api.js.map +1 -0
  16. package/dist/esm/did-api.js +278 -0
  17. package/dist/esm/did-api.js.map +1 -0
  18. package/dist/esm/dwn-api.js +336 -0
  19. package/dist/esm/dwn-api.js.map +1 -0
  20. package/dist/esm/dwn-registrar.js +120 -0
  21. package/dist/esm/dwn-registrar.js.map +1 -0
  22. package/dist/esm/hd-identity-vault.js +729 -0
  23. package/dist/esm/hd-identity-vault.js.map +1 -0
  24. package/dist/esm/identity-api.js +262 -0
  25. package/dist/esm/identity-api.js.map +1 -0
  26. package/dist/esm/index.js +23 -0
  27. package/dist/esm/index.js.map +1 -0
  28. package/dist/esm/local-key-manager.js +498 -0
  29. package/dist/esm/local-key-manager.js.map +1 -0
  30. package/dist/esm/oidc.js +507 -0
  31. package/dist/esm/oidc.js.map +1 -0
  32. package/dist/esm/permissions-api.js +322 -0
  33. package/dist/esm/permissions-api.js.map +1 -0
  34. package/dist/esm/prototyping/clients/dwn-rpc-types.js +2 -0
  35. package/dist/esm/prototyping/clients/dwn-rpc-types.js.map +1 -0
  36. package/dist/esm/prototyping/clients/dwn-server-info-cache-memory.js +74 -0
  37. package/dist/esm/prototyping/clients/dwn-server-info-cache-memory.js.map +1 -0
  38. package/dist/esm/prototyping/clients/http-dwn-rpc-client.js +105 -0
  39. package/dist/esm/prototyping/clients/http-dwn-rpc-client.js.map +1 -0
  40. package/dist/esm/prototyping/clients/json-rpc-socket.js +150 -0
  41. package/dist/esm/prototyping/clients/json-rpc-socket.js.map +1 -0
  42. package/dist/esm/prototyping/clients/json-rpc.js +58 -0
  43. package/dist/esm/prototyping/clients/json-rpc.js.map +1 -0
  44. package/dist/esm/prototyping/clients/server-info-types.js +2 -0
  45. package/dist/esm/prototyping/clients/server-info-types.js.map +1 -0
  46. package/dist/esm/prototyping/clients/web-socket-clients.js +90 -0
  47. package/dist/esm/prototyping/clients/web-socket-clients.js.map +1 -0
  48. package/dist/esm/prototyping/common/object.js +14 -0
  49. package/dist/esm/prototyping/common/object.js.map +1 -0
  50. package/dist/esm/prototyping/common/type-utils.js +2 -0
  51. package/dist/esm/prototyping/common/type-utils.js.map +1 -0
  52. package/dist/esm/prototyping/crypto/algorithms/aes-gcm.js +147 -0
  53. package/dist/esm/prototyping/crypto/algorithms/aes-gcm.js.map +1 -0
  54. package/dist/esm/prototyping/crypto/algorithms/aes-kw.js +137 -0
  55. package/dist/esm/prototyping/crypto/algorithms/aes-kw.js.map +1 -0
  56. package/dist/esm/prototyping/crypto/algorithms/ecdsa.js +307 -0
  57. package/dist/esm/prototyping/crypto/algorithms/ecdsa.js.map +1 -0
  58. package/dist/esm/prototyping/crypto/algorithms/eddsa.js +264 -0
  59. package/dist/esm/prototyping/crypto/algorithms/eddsa.js.map +1 -0
  60. package/dist/esm/prototyping/crypto/algorithms/hkdf.js +39 -0
  61. package/dist/esm/prototyping/crypto/algorithms/hkdf.js.map +1 -0
  62. package/dist/esm/prototyping/crypto/algorithms/pbkdf2.js +41 -0
  63. package/dist/esm/prototyping/crypto/algorithms/pbkdf2.js.map +1 -0
  64. package/dist/esm/prototyping/crypto/crypto-error.js +41 -0
  65. package/dist/esm/prototyping/crypto/crypto-error.js.map +1 -0
  66. package/dist/esm/prototyping/crypto/dsa.js +236 -0
  67. package/dist/esm/prototyping/crypto/dsa.js.map +1 -0
  68. package/dist/esm/prototyping/crypto/jose/jwe-compact.js +130 -0
  69. package/dist/esm/prototyping/crypto/jose/jwe-compact.js.map +1 -0
  70. package/dist/esm/prototyping/crypto/jose/jwe-flattened.js +294 -0
  71. package/dist/esm/prototyping/crypto/jose/jwe-flattened.js.map +1 -0
  72. package/dist/esm/prototyping/crypto/jose/jwe.js +308 -0
  73. package/dist/esm/prototyping/crypto/jose/jwe.js.map +1 -0
  74. package/dist/esm/prototyping/crypto/primitives/aes-gcm.js +352 -0
  75. package/dist/esm/prototyping/crypto/primitives/aes-gcm.js.map +1 -0
  76. package/dist/esm/prototyping/crypto/primitives/aes-kw.js +247 -0
  77. package/dist/esm/prototyping/crypto/primitives/aes-kw.js.map +1 -0
  78. package/dist/esm/prototyping/crypto/primitives/hkdf.js +80 -0
  79. package/dist/esm/prototyping/crypto/primitives/hkdf.js.map +1 -0
  80. package/dist/esm/prototyping/crypto/primitives/pbkdf2.js +85 -0
  81. package/dist/esm/prototyping/crypto/primitives/pbkdf2.js.map +1 -0
  82. package/dist/esm/prototyping/crypto/types/cipher.js +2 -0
  83. package/dist/esm/prototyping/crypto/types/cipher.js.map +1 -0
  84. package/dist/esm/prototyping/crypto/types/crypto-api.js +2 -0
  85. package/dist/esm/prototyping/crypto/types/crypto-api.js.map +1 -0
  86. package/dist/esm/prototyping/crypto/types/key-converter.js +2 -0
  87. package/dist/esm/prototyping/crypto/types/key-converter.js.map +1 -0
  88. package/dist/esm/prototyping/crypto/types/key-deriver.js +2 -0
  89. package/dist/esm/prototyping/crypto/types/key-deriver.js.map +1 -0
  90. package/dist/esm/prototyping/crypto/types/key-io.js +2 -0
  91. package/dist/esm/prototyping/crypto/types/key-io.js.map +1 -0
  92. package/dist/esm/prototyping/crypto/types/key-manager.js +2 -0
  93. package/dist/esm/prototyping/crypto/types/key-manager.js.map +1 -0
  94. package/dist/esm/prototyping/crypto/types/key-wrapper.js +2 -0
  95. package/dist/esm/prototyping/crypto/types/key-wrapper.js.map +1 -0
  96. package/dist/esm/prototyping/crypto/types/params-direct.js +2 -0
  97. package/dist/esm/prototyping/crypto/types/params-direct.js.map +1 -0
  98. package/dist/esm/prototyping/crypto/types/params-kms.js +2 -0
  99. package/dist/esm/prototyping/crypto/types/params-kms.js.map +1 -0
  100. package/dist/esm/prototyping/crypto/utils.js +19 -0
  101. package/dist/esm/prototyping/crypto/utils.js.map +1 -0
  102. package/dist/esm/prototyping/dids/resolver-cache-memory.js +77 -0
  103. package/dist/esm/prototyping/dids/resolver-cache-memory.js.map +1 -0
  104. package/dist/esm/prototyping/dids/utils.js +9 -0
  105. package/dist/esm/prototyping/dids/utils.js.map +1 -0
  106. package/dist/esm/rpc-client.js +123 -0
  107. package/dist/esm/rpc-client.js.map +1 -0
  108. package/dist/esm/store-data-protocols.js +38 -0
  109. package/dist/esm/store-data-protocols.js.map +1 -0
  110. package/dist/esm/store-data.js +320 -0
  111. package/dist/esm/store-data.js.map +1 -0
  112. package/dist/esm/store-did.js +136 -0
  113. package/dist/esm/store-did.js.map +1 -0
  114. package/dist/esm/store-identity.js +140 -0
  115. package/dist/esm/store-identity.js.map +1 -0
  116. package/dist/esm/store-key.js +136 -0
  117. package/dist/esm/store-key.js.map +1 -0
  118. package/dist/esm/sync-api.js +61 -0
  119. package/dist/esm/sync-api.js.map +1 -0
  120. package/dist/esm/sync-engine-level.js +618 -0
  121. package/dist/esm/sync-engine-level.js.map +1 -0
  122. package/dist/esm/test-harness.js +239 -0
  123. package/dist/esm/test-harness.js.map +1 -0
  124. package/dist/esm/types/agent.js +2 -0
  125. package/dist/esm/types/agent.js.map +1 -0
  126. package/dist/esm/types/dwn.js +31 -0
  127. package/dist/esm/types/dwn.js.map +1 -0
  128. package/dist/esm/types/identity-vault.js +2 -0
  129. package/dist/esm/types/identity-vault.js.map +1 -0
  130. package/dist/esm/types/identity.js +2 -0
  131. package/dist/esm/types/identity.js.map +1 -0
  132. package/dist/esm/types/key-manager.js +2 -0
  133. package/dist/esm/types/key-manager.js.map +1 -0
  134. package/dist/esm/types/permissions.js +2 -0
  135. package/dist/esm/types/permissions.js.map +1 -0
  136. package/dist/esm/types/sync.js +2 -0
  137. package/dist/esm/types/sync.js.map +1 -0
  138. package/dist/esm/types/vc.js +5 -0
  139. package/dist/esm/types/vc.js.map +1 -0
  140. package/dist/esm/utils-internal.js +147 -0
  141. package/dist/esm/utils-internal.js.map +1 -0
  142. package/dist/esm/utils.js +161 -0
  143. package/dist/esm/utils.js.map +1 -0
  144. package/dist/types/agent-did-resolver-cache.d.ts +30 -0
  145. package/dist/types/agent-did-resolver-cache.d.ts.map +1 -0
  146. package/dist/types/bearer-identity.d.ts +31 -0
  147. package/dist/types/bearer-identity.d.ts.map +1 -0
  148. package/dist/types/connect.d.ts +88 -0
  149. package/dist/types/connect.d.ts.map +1 -0
  150. package/dist/types/crypto-api.d.ts +286 -0
  151. package/dist/types/crypto-api.d.ts.map +1 -0
  152. package/dist/types/did-api.d.ts +119 -0
  153. package/dist/types/did-api.d.ts.map +1 -0
  154. package/dist/types/dwn-api.d.ts +66 -0
  155. package/dist/types/dwn-api.d.ts.map +1 -0
  156. package/dist/types/dwn-registrar.d.ts +29 -0
  157. package/dist/types/dwn-registrar.d.ts.map +1 -0
  158. package/dist/types/hd-identity-vault.d.ts +306 -0
  159. package/dist/types/hd-identity-vault.d.ts.map +1 -0
  160. package/dist/types/identity-api.d.ts +107 -0
  161. package/dist/types/identity-api.d.ts.map +1 -0
  162. package/dist/types/index.d.ts +30 -0
  163. package/dist/types/index.d.ts.map +1 -0
  164. package/dist/types/local-key-manager.d.ts +311 -0
  165. package/dist/types/local-key-manager.d.ts.map +1 -0
  166. package/dist/types/oidc.d.ts +247 -0
  167. package/dist/types/oidc.d.ts.map +1 -0
  168. package/dist/types/permissions-api.d.ts +35 -0
  169. package/dist/types/permissions-api.d.ts.map +1 -0
  170. package/dist/types/prototyping/clients/dwn-rpc-types.d.ts +45 -0
  171. package/dist/types/prototyping/clients/dwn-rpc-types.d.ts.map +1 -0
  172. package/dist/types/prototyping/clients/dwn-server-info-cache-memory.d.ts +57 -0
  173. package/dist/types/prototyping/clients/dwn-server-info-cache-memory.d.ts.map +1 -0
  174. package/dist/types/prototyping/clients/http-dwn-rpc-client.d.ts +13 -0
  175. package/dist/types/prototyping/clients/http-dwn-rpc-client.d.ts.map +1 -0
  176. package/dist/types/prototyping/clients/json-rpc-socket.d.ts +43 -0
  177. package/dist/types/prototyping/clients/json-rpc-socket.d.ts.map +1 -0
  178. package/dist/types/prototyping/clients/json-rpc.d.ts +49 -0
  179. package/dist/types/prototyping/clients/json-rpc.d.ts.map +1 -0
  180. package/dist/types/prototyping/clients/server-info-types.d.ts +20 -0
  181. package/dist/types/prototyping/clients/server-info-types.d.ts.map +1 -0
  182. package/dist/types/prototyping/clients/web-socket-clients.d.ts +10 -0
  183. package/dist/types/prototyping/clients/web-socket-clients.d.ts.map +1 -0
  184. package/dist/types/prototyping/common/object.d.ts +2 -0
  185. package/dist/types/prototyping/common/object.d.ts.map +1 -0
  186. package/dist/types/prototyping/common/type-utils.d.ts +7 -0
  187. package/dist/types/prototyping/common/type-utils.d.ts.map +1 -0
  188. package/dist/types/prototyping/crypto/algorithms/aes-gcm.d.ts +151 -0
  189. package/dist/types/prototyping/crypto/algorithms/aes-gcm.d.ts.map +1 -0
  190. package/dist/types/prototyping/crypto/algorithms/aes-kw.d.ts +109 -0
  191. package/dist/types/prototyping/crypto/algorithms/aes-kw.d.ts.map +1 -0
  192. package/dist/types/prototyping/crypto/algorithms/ecdsa.d.ts +160 -0
  193. package/dist/types/prototyping/crypto/algorithms/ecdsa.d.ts.map +1 -0
  194. package/dist/types/prototyping/crypto/algorithms/eddsa.d.ts +157 -0
  195. package/dist/types/prototyping/crypto/algorithms/eddsa.d.ts.map +1 -0
  196. package/dist/types/prototyping/crypto/algorithms/hkdf.d.ts +21 -0
  197. package/dist/types/prototyping/crypto/algorithms/hkdf.d.ts.map +1 -0
  198. package/dist/types/prototyping/crypto/algorithms/pbkdf2.d.ts +21 -0
  199. package/dist/types/prototyping/crypto/algorithms/pbkdf2.d.ts.map +1 -0
  200. package/dist/types/prototyping/crypto/crypto-error.d.ts +29 -0
  201. package/dist/types/prototyping/crypto/crypto-error.d.ts.map +1 -0
  202. package/dist/types/prototyping/crypto/dsa.d.ts +169 -0
  203. package/dist/types/prototyping/crypto/dsa.d.ts.map +1 -0
  204. package/dist/types/prototyping/crypto/jose/jwe-compact.d.ts +135 -0
  205. package/dist/types/prototyping/crypto/jose/jwe-compact.d.ts.map +1 -0
  206. package/dist/types/prototyping/crypto/jose/jwe-flattened.d.ts +134 -0
  207. package/dist/types/prototyping/crypto/jose/jwe-flattened.d.ts.map +1 -0
  208. package/dist/types/prototyping/crypto/jose/jwe.d.ts +378 -0
  209. package/dist/types/prototyping/crypto/jose/jwe.d.ts.map +1 -0
  210. package/dist/types/prototyping/crypto/primitives/aes-gcm.d.ts +245 -0
  211. package/dist/types/prototyping/crypto/primitives/aes-gcm.d.ts.map +1 -0
  212. package/dist/types/prototyping/crypto/primitives/aes-kw.d.ts +103 -0
  213. package/dist/types/prototyping/crypto/primitives/aes-kw.d.ts.map +1 -0
  214. package/dist/types/prototyping/crypto/primitives/hkdf.d.ts +90 -0
  215. package/dist/types/prototyping/crypto/primitives/hkdf.d.ts.map +1 -0
  216. package/dist/types/prototyping/crypto/primitives/pbkdf2.d.ts +84 -0
  217. package/dist/types/prototyping/crypto/primitives/pbkdf2.d.ts.map +1 -0
  218. package/dist/types/prototyping/crypto/types/cipher.d.ts +14 -0
  219. package/dist/types/prototyping/crypto/types/cipher.d.ts.map +1 -0
  220. package/dist/types/prototyping/crypto/types/crypto-api.d.ts +35 -0
  221. package/dist/types/prototyping/crypto/types/crypto-api.d.ts.map +1 -0
  222. package/dist/types/prototyping/crypto/types/key-converter.d.ts +49 -0
  223. package/dist/types/prototyping/crypto/types/key-converter.d.ts.map +1 -0
  224. package/dist/types/prototyping/crypto/types/key-deriver.d.ts +50 -0
  225. package/dist/types/prototyping/crypto/types/key-deriver.d.ts.map +1 -0
  226. package/dist/types/prototyping/crypto/types/key-io.d.ts +49 -0
  227. package/dist/types/prototyping/crypto/types/key-io.d.ts.map +1 -0
  228. package/dist/types/prototyping/crypto/types/key-manager.d.ts +69 -0
  229. package/dist/types/prototyping/crypto/types/key-manager.d.ts.map +1 -0
  230. package/dist/types/prototyping/crypto/types/key-wrapper.d.ts +14 -0
  231. package/dist/types/prototyping/crypto/types/key-wrapper.d.ts.map +1 -0
  232. package/dist/types/prototyping/crypto/types/params-direct.d.ts +75 -0
  233. package/dist/types/prototyping/crypto/types/params-direct.d.ts.map +1 -0
  234. package/dist/types/prototyping/crypto/types/params-kms.d.ts +63 -0
  235. package/dist/types/prototyping/crypto/types/params-kms.d.ts.map +1 -0
  236. package/dist/types/prototyping/crypto/utils.d.ts +7 -0
  237. package/dist/types/prototyping/crypto/utils.d.ts.map +1 -0
  238. package/dist/types/prototyping/dids/resolver-cache-memory.d.ts +57 -0
  239. package/dist/types/prototyping/dids/resolver-cache-memory.d.ts.map +1 -0
  240. package/dist/types/prototyping/dids/utils.d.ts +3 -0
  241. package/dist/types/prototyping/dids/utils.d.ts.map +1 -0
  242. package/dist/types/rpc-client.d.ts +51 -0
  243. package/dist/types/rpc-client.d.ts.map +1 -0
  244. package/dist/types/store-data-protocols.d.ts +4 -0
  245. package/dist/types/store-data-protocols.d.ts.map +1 -0
  246. package/dist/types/store-data.d.ts +95 -0
  247. package/dist/types/store-data.d.ts.map +1 -0
  248. package/dist/types/store-did.d.ts +33 -0
  249. package/dist/types/store-did.d.ts.map +1 -0
  250. package/dist/types/store-identity.d.ts +34 -0
  251. package/dist/types/store-identity.d.ts.map +1 -0
  252. package/dist/types/store-key.d.ts +32 -0
  253. package/dist/types/store-key.d.ts.map +1 -0
  254. package/dist/types/sync-api.d.ts +41 -0
  255. package/dist/types/sync-api.d.ts.map +1 -0
  256. package/dist/types/sync-engine-level.d.ts +85 -0
  257. package/dist/types/sync-engine-level.d.ts.map +1 -0
  258. package/dist/types/test-harness.d.ts +69 -0
  259. package/dist/types/test-harness.d.ts.map +1 -0
  260. package/dist/types/types/agent.d.ts +172 -0
  261. package/dist/types/types/agent.d.ts.map +1 -0
  262. package/dist/types/types/dwn.d.ts +178 -0
  263. package/dist/types/types/dwn.d.ts.map +1 -0
  264. package/dist/types/types/identity-vault.d.ts +129 -0
  265. package/dist/types/types/identity-vault.d.ts.map +1 -0
  266. package/dist/types/types/identity.d.ts +16 -0
  267. package/dist/types/types/identity.d.ts.map +1 -0
  268. package/dist/types/types/key-manager.d.ts +9 -0
  269. package/dist/types/types/key-manager.d.ts.map +1 -0
  270. package/dist/types/types/permissions.d.ts +98 -0
  271. package/dist/types/types/permissions.d.ts.map +1 -0
  272. package/dist/types/types/sync.d.ts +66 -0
  273. package/dist/types/types/sync.d.ts.map +1 -0
  274. package/dist/types/types/vc.d.ts +7 -0
  275. package/dist/types/types/vc.d.ts.map +1 -0
  276. package/dist/types/utils-internal.d.ts +50 -0
  277. package/dist/types/utils-internal.d.ts.map +1 -0
  278. package/dist/types/utils.d.ts +37 -0
  279. package/dist/types/utils.d.ts.map +1 -0
  280. package/package.json +112 -0
  281. package/src/agent-did-resolver-cache.ts +95 -0
  282. package/src/bearer-identity.ts +42 -0
  283. package/src/connect.ts +296 -0
  284. package/src/crypto-api.ts +593 -0
  285. package/src/did-api.ts +429 -0
  286. package/src/dwn-api.ts +462 -0
  287. package/src/dwn-registrar.ts +127 -0
  288. package/src/hd-identity-vault.ts +853 -0
  289. package/src/identity-api.ts +324 -0
  290. package/src/index.ts +30 -0
  291. package/src/local-key-manager.ts +672 -0
  292. package/src/oidc.ts +857 -0
  293. package/src/permissions-api.ts +408 -0
  294. package/src/prototyping/clients/dwn-rpc-types.ts +55 -0
  295. package/src/prototyping/clients/dwn-server-info-cache-memory.ts +79 -0
  296. package/src/prototyping/clients/http-dwn-rpc-client.ts +110 -0
  297. package/src/prototyping/clients/json-rpc-socket.ts +169 -0
  298. package/src/prototyping/clients/json-rpc.ts +113 -0
  299. package/src/prototyping/clients/server-info-types.ts +21 -0
  300. package/src/prototyping/clients/web-socket-clients.ts +100 -0
  301. package/src/prototyping/common/object.ts +15 -0
  302. package/src/prototyping/common/type-utils.ts +6 -0
  303. package/src/prototyping/crypto/algorithms/aes-gcm.ts +211 -0
  304. package/src/prototyping/crypto/algorithms/aes-kw.ts +164 -0
  305. package/src/prototyping/crypto/algorithms/ecdsa.ts +365 -0
  306. package/src/prototyping/crypto/algorithms/eddsa.ts +310 -0
  307. package/src/prototyping/crypto/algorithms/hkdf.ts +40 -0
  308. package/src/prototyping/crypto/algorithms/pbkdf2.ts +44 -0
  309. package/src/prototyping/crypto/crypto-error.ts +45 -0
  310. package/src/prototyping/crypto/dsa.ts +367 -0
  311. package/src/prototyping/crypto/jose/jwe-compact.ts +225 -0
  312. package/src/prototyping/crypto/jose/jwe-flattened.ts +459 -0
  313. package/src/prototyping/crypto/jose/jwe.ts +653 -0
  314. package/src/prototyping/crypto/primitives/aes-gcm.ts +374 -0
  315. package/src/prototyping/crypto/primitives/aes-kw.ts +271 -0
  316. package/src/prototyping/crypto/primitives/hkdf.ts +121 -0
  317. package/src/prototyping/crypto/primitives/pbkdf2.ts +116 -0
  318. package/src/prototyping/crypto/types/cipher.ts +17 -0
  319. package/src/prototyping/crypto/types/crypto-api.ts +78 -0
  320. package/src/prototyping/crypto/types/key-converter.ts +53 -0
  321. package/src/prototyping/crypto/types/key-deriver.ts +56 -0
  322. package/src/prototyping/crypto/types/key-io.ts +51 -0
  323. package/src/prototyping/crypto/types/key-manager.ts +83 -0
  324. package/src/prototyping/crypto/types/key-wrapper.ts +17 -0
  325. package/src/prototyping/crypto/types/params-direct.ts +95 -0
  326. package/src/prototyping/crypto/types/params-kms.ts +76 -0
  327. package/src/prototyping/crypto/utils.ts +41 -0
  328. package/src/prototyping/dids/resolver-cache-memory.ts +83 -0
  329. package/src/prototyping/dids/utils.ts +10 -0
  330. package/src/rpc-client.ts +162 -0
  331. package/src/store-data-protocols.ts +40 -0
  332. package/src/store-data.ts +400 -0
  333. package/src/store-did.ts +105 -0
  334. package/src/store-identity.ts +109 -0
  335. package/src/store-key.ts +104 -0
  336. package/src/sync-api.ts +71 -0
  337. package/src/sync-engine-level.ts +714 -0
  338. package/src/test-harness.ts +330 -0
  339. package/src/types/agent.ts +195 -0
  340. package/src/types/dwn.ts +278 -0
  341. package/src/types/identity-vault.ts +137 -0
  342. package/src/types/identity.ts +18 -0
  343. package/src/types/key-manager.ts +15 -0
  344. package/src/types/permissions.ts +115 -0
  345. package/src/types/sync.ts +58 -0
  346. package/src/types/vc.ts +7 -0
  347. package/src/utils-internal.ts +157 -0
  348. package/src/utils.ts +181 -0
@@ -0,0 +1,853 @@
1
+ import type { Jwk } from '@enbox/crypto';
2
+ import type { KeyValueStore } from '@enbox/common';
3
+ import { DidDhtCreateOptions } from '@enbox/dids';
4
+
5
+ import { HDKey } from 'ed25519-keygen/hdkey';
6
+ import { BearerDid, DidDht } from '@enbox/dids';
7
+ import { Convert, MemoryStore } from '@enbox/common';
8
+ import { wordlist } from '@scure/bip39/wordlists/english';
9
+ import { generateMnemonic, mnemonicToSeed, validateMnemonic } from '@scure/bip39';
10
+
11
+ import type { JweHeaderParams } from './prototyping/crypto/jose/jwe.js';
12
+ import type { IdentityVaultBackup, IdentityVaultBackupData, IdentityVaultStatus, IdentityVaultParams, IdentityVault } from './types/identity-vault.js';
13
+
14
+ import { AgentCryptoApi } from './crypto-api.js';
15
+ import { LocalKeyManager } from './local-key-manager.js';
16
+ import { isPortableDid } from './prototyping/dids/utils.js';
17
+ import { DeterministicKeyGenerator } from './utils-internal.js';
18
+ import { CompactJwe } from './prototyping/crypto/jose/jwe-compact.js';
19
+
20
+ /**
21
+ * Extended initialization parameters for HdIdentityVault, including an optional recovery phrase
22
+ * that can be used to derive keys to encrypt the vault and generate a DID.
23
+ */
24
+ export type HdIdentityVaultInitializeParams = {
25
+ /**
26
+ * The password used to secure the vault.
27
+ *
28
+ * The password selected should be strong and securely managed to prevent unauthorized access.
29
+ */
30
+ password: string;
31
+
32
+ /**
33
+ * An optional recovery phrase used to derive the cryptographic keys for the vault.
34
+ *
35
+ * Providing a recovery phrase can be used to recover the vault's content or establish a
36
+ * deterministic key generation scheme. If not provided, a new recovery phrase will be generated
37
+ * during the initialization process.
38
+ */
39
+ recoveryPhrase?: string;
40
+
41
+ /**
42
+ * Optional dwnEndpoints to register didService endpoints during HdIdentityVault initialization
43
+ *
44
+ * The dwnEndpoints are used to register a DWN endpoint during DidDht.create(). This allows the
45
+ * agent to properly recover connectedDids from DWN. Also, this pattern can be used on the server
46
+ * side in place of the agentDid-->connectedDids pattern.
47
+ */
48
+ dwnEndpoints?: string[];
49
+ };
50
+
51
+ /**
52
+ * Type guard function to check if a given object is an empty string or a string containing only
53
+ * whitespace.
54
+ *
55
+ * This is an internal utility function used to validate password inputs, ensuring they are not
56
+ * empty or filled with only whitespace characters, which are considered invalid for password
57
+ * purposes.
58
+ *
59
+ * @param obj - The object to be checked, typically expected to be a password string.
60
+ * @returns A boolean value indicating whether the object is an empty string or a string with only
61
+ * whitespace.
62
+ */
63
+ function isEmptyString(obj: unknown): obj is string {
64
+ return typeof obj !== 'string' || obj.trim().length === 0;
65
+ }
66
+
67
+ /**
68
+ * Type guard function to check if a given object conforms to the {@link IdentityVaultBackup}
69
+ * interface.
70
+ *
71
+ * This function is an internal utility meant to ensure the integrity and structure of the data
72
+ * assumed to be an {@link IdentityVaultBackup}. It verifies the presence and types of the
73
+ * `dateCreated`, `size`, and `data` properties, aligning with the expected structure of a backup
74
+ * object in the context of an {@link IdentityVault}.
75
+ *
76
+ * @param obj - The object to be verified against the {@link IdentityVaultBackup} interface.
77
+ * @returns A boolean value indicating whether the object is a valid {@link IdentityVaultBackup}.
78
+ */
79
+ function isIdentityVaultBackup(obj: unknown): obj is IdentityVaultBackup {
80
+ return typeof obj === 'object' && obj !== null
81
+ && 'dateCreated' in obj && typeof obj.dateCreated === 'string'
82
+ && 'size' in obj && typeof obj.size === 'number'
83
+ && 'data' in obj && typeof obj.data === 'string';
84
+ }
85
+
86
+ /**
87
+ * Internal-only type guard function that checks if a given object conforms to the
88
+ * {@link IdentityVaultStatus} interface.
89
+ *
90
+ * This function is utilized within the {@link HdIdentityVault} implementation to ensure the
91
+ * integrity of the object representing the vault's status, verifying the presence and types of
92
+ * required properties. It aasserts the presence and correct types of `initialized`, `lastBackup`,
93
+ * and `lastRestore` properties, ensuring they align with the expected structure of an identity
94
+ * vault's status.
95
+ *
96
+ * @param obj - The object to be checked against the {{@link IdentityVaultStatus} interface.
97
+ * @returns A boolean indicating whether the object is an instance of {@link IdentityVaultStatus}.
98
+ */
99
+ function isIdentityVaultStatus(obj: unknown): obj is IdentityVaultStatus {
100
+ return typeof obj === 'object' && obj !== null
101
+ && 'initialized' in obj && typeof obj.initialized === 'boolean'
102
+ && 'lastBackup' in obj
103
+ && 'lastRestore' in obj;
104
+ }
105
+
106
+ /**
107
+ * The `HdIdentityVault` class provides secure storage and management of identity data.
108
+ *
109
+ * The `HdIdentityVault` class implements the `IdentityVault` interface, providing secure storage
110
+ * and management of identity data with an added layer of security using Hierarchical Deterministic
111
+ * (HD) key derivation based on the SLIP-0010 standard for Ed25519 keys. It enhances identity
112
+ * protection by generating and securing the identity using a derived HD key, allowing for the
113
+ * deterministic regeneration of keys from a recovery phrase.
114
+ *
115
+ * The vault is capable of:
116
+ * - Secure initialization with a password and an optional recovery phrase, employing HD key
117
+ * derivation.
118
+ * - Encrypting the identity data using a derived content encryption key (CEK) which is securely
119
+ * encrypted and stored, accessible only by the correct password.
120
+ * - Securely backing up and restoring the vault’s contents, including the HD-derived keys and
121
+ * associated DID.
122
+ * - Locking and unlocking the vault, which encrypts and decrypts the CEK for secure access to the
123
+ * vault's contents.
124
+ * - Managing the DID associated with the identity, providing a secure identity layer for
125
+ * applications.
126
+ *
127
+ * Usage involves initializing the vault with a secure password (and optionally a recovery phrase),
128
+ * which then allows for the secure storage, backup, and retrieval of the identity data.
129
+ *
130
+ * Note: Ensure the password is strong and securely managed, as it is crucial for the security of the
131
+ * vault's encrypted contents.
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * const vault = new HdIdentityVault();
136
+ * await vault.initialize({ password: 'secure-unique-phrase', recoveryPhrase: 'twelve words ...' });
137
+ * const backup = await vault.backup();
138
+ * await vault.restore({ backup, password: 'secure-unique-phrase' });
139
+ * ```
140
+ */
141
+ export class HdIdentityVault implements IdentityVault<{ InitializeResult: string }> {
142
+ /** Provides cryptographic functions needed for secure storage and management of the vault. */
143
+ public crypto = new AgentCryptoApi();
144
+
145
+ /** Determines the computational intensity of the key derivation process. */
146
+ private _keyDerivationWorkFactor: number;
147
+
148
+ /** The underlying key-value store for the vault's encrypted content. */
149
+ private _store: KeyValueStore<string, string>;
150
+
151
+ /** The cryptographic key used to encrypt and decrypt the vault's content securely. */
152
+ private _contentEncryptionKey: Jwk | undefined;
153
+
154
+ /**
155
+ * Constructs an instance of `HdIdentityVault`, initializing the key derivation factor and data
156
+ * store. It sets the default key derivation work factor and initializes the internal data store,
157
+ * either with the provided store or a default in-memory store. It also establishes the initial
158
+ * status of the vault as uninitialized and locked.
159
+ *
160
+ * @param params - Optional parameters when constructing a vault instance.
161
+ * @param params.keyDerivationWorkFactor - Optionally set the computational effort for key derivation.
162
+ * @param params.store - Optionally specify a custom key-value store for vault data.
163
+ */
164
+ constructor({ keyDerivationWorkFactor, store }: IdentityVaultParams = {}) {
165
+ this._keyDerivationWorkFactor = keyDerivationWorkFactor ?? 210_000;
166
+ this._store = store ?? new MemoryStore<string, string>();
167
+ }
168
+
169
+ /**
170
+ * Creates a backup of the vault's current state, including the encrypted DID and content
171
+ * encryption key, and returns it as an `IdentityVaultBackup` object. The backup includes a
172
+ * Base64Url-encoded string representing the vault's encrypted data, encapsulating the
173
+ * {@link PortableDid}, the content encryption key, and the vault's status.
174
+ *
175
+ * This method ensures that the vault is initialized and unlocked before proceeding with the
176
+ * backup operation.
177
+ *
178
+ * @throws Error if the vault is not initialized or is locked, preventing the backup.
179
+ * @returns A promise that resolves to the `IdentityVaultBackup` object containing the vault's
180
+ * encrypted backup data.
181
+ */
182
+ public async backup(): Promise<IdentityVaultBackup> {
183
+ // Verify the identity vault has already been initialized and unlocked.
184
+ if (this.isLocked() || await this.isInitialized() === false) {
185
+ throw new Error(
186
+ 'HdIdentityVault: Unable to proceed with the backup operation because the identity vault ' +
187
+ 'has not been initialized and unlocked. Please ensure the vault is properly initialized ' +
188
+ 'with a secure password before attempting to backup its contents.'
189
+ );
190
+ }
191
+
192
+ // Encode the encrypted CEK and DID as a single Base64Url string.
193
+ const backupData: IdentityVaultBackupData = {
194
+ did : await this.getStoredDid(),
195
+ contentEncryptionKey : await this.getStoredContentEncryptionKey(),
196
+ status : await this.getStatus()
197
+ };
198
+ const backupDataString = Convert.object(backupData).toBase64Url();
199
+
200
+ // Create a backup object containing the encrypted vault contents.
201
+ const backup: IdentityVaultBackup = {
202
+ data : backupDataString,
203
+ dateCreated : new Date().toISOString(),
204
+ size : backupDataString.length
205
+ };
206
+
207
+ // Update the last backup timestamp in the data store.
208
+ await this.setStatus({ lastBackup: backup.dateCreated });
209
+
210
+ return backup;
211
+ }
212
+
213
+ /**
214
+ * Changes the password used to secure the vault.
215
+ *
216
+ * This method decrypts the existing content encryption key (CEK) with the old password, then
217
+ * re-encrypts it with the new password, updating the vault's stored encrypted CEK. It ensures
218
+ * that the vault is initialized and unlocks the vault if the password is successfully changed.
219
+ *
220
+ * @param params - Parameters required for changing the vault password.
221
+ * @param params.oldPassword - The current password used to unlock the vault.
222
+ * @param params.newPassword - The new password to replace the existing one.
223
+ * @throws Error if the vault is not initialized or the old password is incorrect.
224
+ * @returns A promise that resolves when the password change is complete.
225
+ */
226
+ public async changePassword({ oldPassword, newPassword }: {
227
+ oldPassword: string;
228
+ newPassword: string;
229
+ }): Promise<void> {
230
+ // Verify the identity vault has already been initialized.
231
+ if (await this.isInitialized() === false) {
232
+ throw new Error(
233
+ 'HdIdentityVault: Unable to proceed with the change password operation because the ' +
234
+ 'identity vault has not been initialized. Please ensure the vault is properly ' +
235
+ 'initialized with a secure password before trying again.'
236
+ );
237
+ }
238
+
239
+ // Lock the vault.
240
+ await this.lock();
241
+
242
+ // Retrieve the content encryption key (CEK) record as a compact JWE from the data store.
243
+ const cekJwe = await this.getStoredContentEncryptionKey();
244
+
245
+ // Decrypt the compact JWE using the given `oldPassword` to verify it is correct.
246
+ let protectedHeader: JweHeaderParams;
247
+ let contentEncryptionKey: Jwk;
248
+ try {
249
+ let contentEncryptionKeyBytes: Uint8Array;
250
+ ({ plaintext: contentEncryptionKeyBytes, protectedHeader } = await CompactJwe.decrypt({
251
+ jwe : cekJwe,
252
+ key : Convert.string(oldPassword).toUint8Array(),
253
+ crypto : this.crypto,
254
+ keyManager : new LocalKeyManager()
255
+ }));
256
+ contentEncryptionKey = Convert.uint8Array(contentEncryptionKeyBytes).toObject() as Jwk;
257
+
258
+ } catch (error: any) {
259
+ throw new Error(`HdIdentityVault: Unable to change the vault password due to an incorrectly entered old password.`);
260
+ }
261
+
262
+ // Re-encrypt the vault content encryption key (CEK) using the new password.
263
+ const newCekJwe = await CompactJwe.encrypt({
264
+ key : Convert.string(newPassword).toUint8Array(),
265
+ protectedHeader, // Re-use the protected header from the original JWE.
266
+ plaintext : Convert.object(contentEncryptionKey).toUint8Array(),
267
+ crypto : this.crypto,
268
+ keyManager : new LocalKeyManager()
269
+ });
270
+
271
+ // Update the vault with the new CEK JWE.
272
+ await this._store.set('contentEncryptionKey', newCekJwe);
273
+
274
+ // Update the vault CEK in memory, effectively unlocking the vault.
275
+ this._contentEncryptionKey = contentEncryptionKey;
276
+ }
277
+
278
+ /**
279
+ * Retrieves the DID (Decentralized Identifier) associated with the vault.
280
+ *
281
+ * This method ensures the vault is initialized and unlocked before decrypting and returning the
282
+ * DID. The DID is stored encrypted and is decrypted using the vault's content encryption key.
283
+ *
284
+ * @throws Error if the vault is not initialized, is locked, or the DID cannot be decrypted.
285
+ * @returns A promise that resolves with a {@link BearerDid}.
286
+ */
287
+ public async getDid(): Promise<BearerDid> {
288
+ // Verify the identity vault is unlocked.
289
+ if (this.isLocked()) {
290
+ throw new Error(`HdIdentityVault: Vault has not been initialized and unlocked.`);
291
+ }
292
+
293
+ // Retrieve the encrypted DID record as compact JWE from the vault store.
294
+ const didJwe = await this.getStoredDid();
295
+
296
+ // Decrypt the compact JWE to obtain the PortableDid as a byte array.
297
+ const { plaintext: portableDidBytes } = await CompactJwe.decrypt({
298
+ jwe : didJwe,
299
+ key : this._contentEncryptionKey!,
300
+ crypto : this.crypto,
301
+ keyManager : new LocalKeyManager()
302
+ });
303
+
304
+ // Convert the DID from a byte array to PortableDid format.
305
+ const portableDid = Convert.uint8Array(portableDidBytes).toObject();
306
+ if (!isPortableDid(portableDid)) {
307
+ throw new Error('HdIdentityVault: Unable to decode malformed DID in identity vault');
308
+ }
309
+
310
+ // Return the DID in Bearer DID format.
311
+ return await BearerDid.import({ portableDid });
312
+ }
313
+
314
+ /**
315
+ * Fetches the current status of the `HdIdentityVault`, providing details on whether it's
316
+ * initialized and the timestamps of the last backup and restore operations.
317
+ *
318
+ * @returns A promise that resolves with the current status of the `HdIdentityVault`, detailing
319
+ * its initialization, lock state, and the timestamps of the last backup and restore.
320
+ */
321
+ public async getStatus(): Promise<IdentityVaultStatus> {
322
+ const storedStatus = await this._store.get('vaultStatus');
323
+
324
+ // On the first run, the store will not contain an IdentityVaultStatus object yet, so return an
325
+ // uninitialized status.
326
+ if (!storedStatus) {
327
+ return {
328
+ initialized : false,
329
+ lastBackup : null,
330
+ lastRestore : null
331
+ };
332
+ }
333
+
334
+ const vaultStatus = Convert.string(storedStatus).toObject();
335
+ if (!isIdentityVaultStatus(vaultStatus)) {
336
+ throw new Error('HdIdentityVault: Invalid IdentityVaultStatus object in store');
337
+ }
338
+
339
+ return vaultStatus;
340
+ }
341
+
342
+ /**
343
+ * Initializes the `HdIdentityVault` with a password and an optional recovery phrase.
344
+ *
345
+ * If a recovery phrase is not provided, a new one is generated. This process sets up the vault,
346
+ * deriving the necessary cryptographic keys and preparing the vault for use. It ensures the vault
347
+ * is ready to securely store and manage identity data.
348
+ *
349
+ * @example
350
+ * ```ts
351
+ * const identityVault = new HdIdentityVault();
352
+ * const recoveryPhrase = await identityVault.initialize({
353
+ * password: 'your-secure-phrase'
354
+ * });
355
+ * console.log('Vault initialized. Recovery phrase:', recoveryPhrase);
356
+ * ```
357
+ *
358
+ * @param params - The initialization parameters.
359
+ * @param params.password - The password used to secure the vault.
360
+ * @param params.recoveryPhrase - An optional 12-word recovery phrase for key derivation. If
361
+ * omitted, a new recovery is generated.
362
+ * @returns A promise that resolves with the recovery phrase used during the initialization, which
363
+ * should be securely stored by the user.
364
+ */
365
+ public async initialize({ password, recoveryPhrase, dwnEndpoints }:
366
+ HdIdentityVaultInitializeParams
367
+ ): Promise<string> {
368
+ /**
369
+ * STEP 0: Validate the input parameters and verify the identity vault is not already
370
+ * initialized.
371
+ */
372
+
373
+ // Verify that the identity vault was not previously initialized.
374
+ if (await this.isInitialized()) {
375
+ throw new Error(`HdIdentityVault: Vault has already been initialized.`);
376
+ }
377
+
378
+ // Verify that the password is not empty.
379
+ if (isEmptyString(password)) {
380
+ throw new Error(
381
+ `HdIdentityVault: The password is required and cannot be blank. Please provide a ' +
382
+ 'valid, non-empty password.`
383
+ );
384
+ }
385
+
386
+ // If provided, verify that the recovery phrase is not empty.
387
+ if (recoveryPhrase && isEmptyString(recoveryPhrase)) {
388
+ throw new Error(
389
+ `HdIdentityVault: The password is required and cannot be blank. Please provide a ' +
390
+ 'valid, non-empty password.`
391
+ );
392
+ }
393
+
394
+ /**
395
+ * STEP 1: Derive a Hierarchical Deterministic (HD) key pair from the given (or generated)
396
+ * recoveryPhrase.
397
+ */
398
+
399
+ // Generate a 12-word (128-bit) mnemonic, if one was not provided.
400
+ recoveryPhrase ??= generateMnemonic(wordlist, 128);
401
+
402
+ // Validate the mnemonic for being 12-24 words contained in `wordlist`.
403
+ if (!validateMnemonic(recoveryPhrase, wordlist)) {
404
+ throw new Error(
405
+ 'HdIdentityVault: The provided recovery phrase is invalid. Please ensure that the ' +
406
+ 'recovery phrase is a correctly formatted series of 12 words.'
407
+ );
408
+ }
409
+
410
+ // Derive a root seed from the mnemonic.
411
+ const rootSeed = await mnemonicToSeed(recoveryPhrase);
412
+
413
+ // Derive a root key for the DID from the root seed.
414
+ const rootHdKey = HDKey.fromMasterSeed(rootSeed);
415
+
416
+ /**
417
+ * STEP 2: Derive the vault HD key pair from the root key.
418
+ */
419
+
420
+ // The vault HD key is derived using account 0 and index 0 so that it can be
421
+ // deterministically re-derived. The vault key pair serves as input keying material for:
422
+ // - deriving the vault content encryption key (CEK)
423
+ // - deriving the salt that serves as input to derive the key that encrypts the vault CEK
424
+ const vaultHdKey = rootHdKey.derive(`m/44'/0'/0'/0'/0'`);
425
+
426
+ /**
427
+ * STEP 3: Derive the vault Content Encryption Key (CEK) from the vault private
428
+ * key and a non-secret static info value.
429
+ */
430
+
431
+ // A non-secret static info value is combined with the vault private key as input to HKDF
432
+ // (Hash-based Key Derivation Function) to derive a 32-byte content encryption key (CEK).
433
+ const contentEncryptionKey = await this.crypto.deriveKey({
434
+ algorithm : 'HKDF-512', // key derivation function
435
+ baseKeyBytes : vaultHdKey.privateKey, // input keying material
436
+ salt : '', // empty salt because private key is sufficiently random
437
+ info : 'vault_cek', // non-secret application specific information
438
+ derivedKeyAlgorithm : 'A256GCM' // derived key algorithm
439
+ });
440
+
441
+ /**
442
+ * STEP 4: Using the given `password` and a `salt` derived from the vault public key, encrypt
443
+ * the vault CEK and store it in the data store as a compact JWE.
444
+ */
445
+
446
+ // A non-secret static info value is combined with the vault public key as input to HKDF
447
+ // (Hash-based Key Derivation Function) to derive a new 32-byte salt.
448
+ const saltInput = await this.crypto.deriveKeyBytes({
449
+ algorithm : 'HKDF-512', // key derivation function
450
+ baseKeyBytes : vaultHdKey.publicKey, // input keying material
451
+ salt : '', // empty salt because public key is sufficiently random
452
+ info : 'vault_unlock_salt', // non-secret application specific information
453
+ length : 256, // derived key length, in bits
454
+ });
455
+
456
+ // Construct the JWE header.
457
+ const cekJweProtectedHeader: JweHeaderParams = {
458
+ alg : 'PBES2-HS512+A256KW',
459
+ enc : 'A256GCM',
460
+ cty : 'text/plain',
461
+ p2c : this._keyDerivationWorkFactor,
462
+ p2s : Convert.uint8Array(saltInput).toBase64Url()
463
+ };
464
+
465
+ // Encrypt the vault content encryption key (CEK) to compact JWE format.
466
+ const cekJwe = await CompactJwe.encrypt({
467
+ key : Convert.string(password).toUint8Array(),
468
+ protectedHeader : cekJweProtectedHeader,
469
+ plaintext : Convert.object(contentEncryptionKey).toUint8Array(),
470
+ crypto : this.crypto,
471
+ keyManager : new LocalKeyManager()
472
+ });
473
+
474
+ // Store the compact JWE in the data store.
475
+ await this._store.set('contentEncryptionKey', cekJwe);
476
+
477
+ /**
478
+ * STEP 5: Create a DID using identity, signing, and encryption keys derived from the root key.
479
+ */
480
+
481
+ // Derive the identity key pair using index 0 and convert to JWK format.
482
+ // Note: The account is set to Unix epoch time so that in the future, the keys for a DID DHT
483
+ // document can be deterministically derived based on the versionId returned in a DID
484
+ // resolution result.
485
+ const identityHdKey = rootHdKey.derive(`m/44'/0'/1708523827'/0'/0'`);
486
+ const identityPrivateKey = await this.crypto.bytesToPrivateKey({
487
+ algorithm : 'Ed25519',
488
+ privateKeyBytes : identityHdKey.privateKey
489
+ });
490
+
491
+ // Derive the signing key using index 1 and convert to JWK format.
492
+ let signingHdKey = rootHdKey.derive(`m/44'/0'/1708523827'/0'/1'`);
493
+ const signingPrivateKey = await this.crypto.bytesToPrivateKey({
494
+ algorithm : 'Ed25519',
495
+ privateKeyBytes : signingHdKey.privateKey
496
+ });
497
+
498
+ // TODO: Enable this once DID DHT supports X25519 keys.
499
+ // Derive the encryption key using index 1 and convert to JWK format.
500
+ // const encryptionHdKey = rootHdKey.derive(`m/44'/0'/1708523827'/0'/1'`);
501
+ // const encryptionKeyEd25519 = await this.crypto.bytesToPrivateKey({
502
+ // algorithm : 'Ed25519',
503
+ // privateKeyBytes : encryptionHdKey.privateKey
504
+ // });
505
+ // const encryptionPrivateKey = await Ed25519.convertPrivateKeyToX25519({ privateKey: encryptionKeyEd25519 });
506
+
507
+ // Add the identity and signing keys to the deterministic key generator so that when the DID is
508
+ // created it will use the derived keys.
509
+ const deterministicKeyGenerator = new DeterministicKeyGenerator();
510
+ await deterministicKeyGenerator.addPredefinedKeys({
511
+ privateKeys: [identityPrivateKey, signingPrivateKey]
512
+ });
513
+
514
+ // Create the DID using the derived identity, signing, and encryption keys.
515
+ const options = {
516
+ verificationMethods: [
517
+ {
518
+ algorithm : 'Ed25519',
519
+ id : 'sig',
520
+ purposes : ['assertionMethod', 'authentication']
521
+ },
522
+ ]
523
+ } as DidDhtCreateOptions<DeterministicKeyGenerator>;
524
+
525
+ if(dwnEndpoints && !!dwnEndpoints.length) {
526
+ options.services = [
527
+ {
528
+ id : 'dwn',
529
+ type : 'DecentralizedWebNode',
530
+ serviceEndpoint : dwnEndpoints,
531
+ enc : '#enc',
532
+ sig : '#sig',
533
+ }
534
+ ];
535
+ }
536
+
537
+ const did = await DidDht.create({ keyManager: deterministicKeyGenerator, options });
538
+
539
+ /**
540
+ * STEP 6: Convert the DID to portable format and store it in the data store as a
541
+ * compact JWE.
542
+ */
543
+
544
+ // Convert the DID to a portable format.
545
+ const portableDid = await did.export();
546
+
547
+ // Construct the JWE header.
548
+ const didJweProtectedHeader: JweHeaderParams = {
549
+ alg : 'dir',
550
+ enc : 'A256GCM',
551
+ cty : 'json'
552
+ };
553
+
554
+ // Encrypt the DID to compact JWE format.
555
+ const didJwe = await CompactJwe.encrypt({
556
+ key : contentEncryptionKey,
557
+ plaintext : Convert.object(portableDid).toUint8Array(),
558
+ protectedHeader : didJweProtectedHeader,
559
+ crypto : this.crypto,
560
+ keyManager : new LocalKeyManager()
561
+ });
562
+
563
+ // Store the compact JWE in the data store.
564
+ await this._store.set('did', didJwe);
565
+
566
+ /**
567
+ * STEP 7: Set the vault CEK (effectively unlocking the vault), set the status to initialized,
568
+ * and return the mnemonic used to generate the vault key.
569
+ */
570
+
571
+ this._contentEncryptionKey = contentEncryptionKey;
572
+
573
+ await this.setStatus({ initialized: true });
574
+
575
+ // Return the recovery phrase in case it was generated so that it can be displayed to the user
576
+ // for safekeeping.
577
+ return recoveryPhrase;
578
+ }
579
+
580
+ /**
581
+ * Determines whether the vault has been initialized.
582
+ *
583
+ * This method checks the vault's current status to determine if it has been
584
+ * initialized. Initialization is a prerequisite for most operations on the vault,
585
+ * ensuring that it is ready for use.
586
+ *
587
+ * @example
588
+ * ```ts
589
+ * const isInitialized = await identityVault.isInitialized();
590
+ * console.log('Is the vault initialized?', isInitialized);
591
+ * ```
592
+ *
593
+ * @returns A promise that resolves to `true` if the vault has been initialized, otherwise `false`.
594
+ */
595
+ public async isInitialized(): Promise<boolean> {
596
+ return this.getStatus().then(({ initialized }) => initialized);
597
+ }
598
+
599
+ /**
600
+ * Checks if the vault is currently locked.
601
+ *
602
+ * This method assesses the vault's current state to determine if it is locked.
603
+ * A locked vault restricts access to its contents, requiring the correct password
604
+ * to unlock and access the stored identity data. The vault must be unlocked to
605
+ * perform operations that access or modify its contents.
606
+ *
607
+ * @example
608
+ * ```ts
609
+ * const isLocked = await identityVault.isLocked();
610
+ * console.log('Is the vault locked?', isLocked);
611
+ * ```
612
+ *
613
+ * @returns `true` if the vault is locked, otherwise `false`.
614
+ */
615
+ public isLocked(): boolean {
616
+ return !this._contentEncryptionKey;
617
+ }
618
+
619
+ /**
620
+ * Locks the `HdIdentityVault`, securing its contents by clearing the in-memory encryption key.
621
+ *
622
+ * This method ensures that the vault's sensitive data cannot be accessed without unlocking the
623
+ * vault again with the correct password. It's an essential security feature for safeguarding
624
+ * the vault's contents against unauthorized access.
625
+ *
626
+ * @example
627
+ * ```ts
628
+ * const identityVault = new HdIdentityVault();
629
+ * await identityVault.lock();
630
+ * console.log('Vault is now locked.');
631
+ * ```
632
+ * @throws An error if the identity vault has not been initialized.
633
+ * @returns A promise that resolves when the vault is successfully locked.
634
+ */
635
+ public async lock(): Promise<void> {
636
+ // Verify the identity vault has already been initialized.
637
+ if (await this.isInitialized() === false) {
638
+ throw new Error(`HdIdentityVault: Lock operation failed. Vault has not been initialized.`);
639
+ }
640
+
641
+ // Clear the vault content encryption key (CEK), effectively locking the vault.
642
+ if (this._contentEncryptionKey) this._contentEncryptionKey.k = '';
643
+ this._contentEncryptionKey = undefined;
644
+ }
645
+
646
+ /**
647
+ * Restores the vault's data from a backup object, decrypting and reinitializing the vault's
648
+ * content with the provided backup data.
649
+ *
650
+ * This operation is crucial for data recovery scenarios, allowing users to regain access to their
651
+ * encrypted data using a previously saved backup and their password.
652
+ *
653
+ * @example
654
+ * ```ts
655
+ * const identityVault = new HdIdentityVault();
656
+ * await identityVault.initialize({ password: 'your-secure-phrase' });
657
+ * // Create a backup of the vault's contents.
658
+ * const backup = await identityVault.backup();
659
+ * // Restore the vault with the same password.
660
+ * await identityVault.restore({ backup: backup, password: 'your-secure-phrase' });
661
+ * console.log('Vault restored successfully.');
662
+ * ```
663
+ *
664
+ * @param params - The parameters required for the restore operation.
665
+ * @param params.backup - The backup object containing the encrypted vault data.
666
+ * @param params.password - The password used to encrypt the backup, necessary for decryption.
667
+ * @returns A promise that resolves when the vault has been successfully restored.
668
+ * @throws An error if the backup object is invalid or if the password is incorrect.
669
+ */
670
+ public async restore({ backup, password }: {
671
+ backup: IdentityVaultBackup;
672
+ password: string;
673
+ }): Promise<void> {
674
+ // Validate the backup object.
675
+ if (!isIdentityVaultBackup(backup)) {
676
+ throw new Error(`HdIdentityVault: Restore operation failed due to invalid backup object.`);
677
+ }
678
+
679
+ // Temporarily save the status and contents of the data store while attempting to restore the
680
+ // backup so that they are not lost in case the restore operation fails.
681
+ let previousStatus: IdentityVaultStatus;
682
+ let previousContentEncryptionKey: string;
683
+ let previousDid: string;
684
+ try {
685
+ previousDid = await this.getStoredDid();
686
+ previousContentEncryptionKey = await this.getStoredContentEncryptionKey();
687
+ previousStatus = await this.getStatus();
688
+ } catch {
689
+ throw new Error(
690
+ 'HdIdentityVault: The restore operation cannot proceed because the existing vault ' +
691
+ 'contents are missing or inaccessible. If the problem persists consider re-initializing ' +
692
+ 'the vault and retrying the restore.'
693
+ );
694
+ }
695
+
696
+ try {
697
+ // Convert the backup data to a JSON object.
698
+ const backupData = Convert.base64Url(backup.data).toObject() as IdentityVaultBackupData;
699
+
700
+ // Restore the backup to the data store.
701
+ await this._store.set('did', backupData.did);
702
+ await this._store.set('contentEncryptionKey', backupData.contentEncryptionKey);
703
+ await this.setStatus(backupData.status);
704
+
705
+ // Attempt to unlock the vault with the given `password`.
706
+ await this.unlock({ password });
707
+
708
+ } catch (error: any) {
709
+ // If the restore operation fails, revert the data store to the status and contents that were
710
+ // saved before the restore operation was attempted.
711
+ await this.setStatus(previousStatus);
712
+ await this._store.set('contentEncryptionKey', previousContentEncryptionKey);
713
+ await this._store.set('did', previousDid);
714
+
715
+ throw new Error(
716
+ 'HdIdentityVault: Restore operation failed due to invalid backup data or an incorrect ' +
717
+ 'password. Please verify the password is correct for the provided backup and try again.'
718
+ );
719
+ }
720
+
721
+ // Update the last restore timestamp in the data store.
722
+ await this.setStatus({ lastRestore: new Date().toISOString() });
723
+ }
724
+
725
+ /**
726
+ * Unlocks the vault by decrypting the stored content encryption key (CEK) using the provided
727
+ * password.
728
+ *
729
+ * This method is essential for accessing the vault's encrypted contents, enabling the decryption
730
+ * of stored data and the execution of further operations requiring the vault to be unlocked.
731
+ *
732
+ * @example
733
+ * ```ts
734
+ * const identityVault = new HdIdentityVault();
735
+ * await identityVault.initialize({ password: 'your-initial-phrase' });
736
+ * // Unlock the vault with the correct password before accessing its contents
737
+ * await identityVault.unlock({ password: 'your-initial-phrase' });
738
+ * console.log('Vault unlocked successfully.');
739
+ * ```
740
+ *
741
+ *
742
+ * @param params - The parameters required for the unlock operation.
743
+ * @param params.password - The password used to encrypt the vault's CEK, necessary for
744
+ * decryption.
745
+ * @returns A promise that resolves when the vault has been successfully unlocked.
746
+ * @throws An error if the vault has not been initialized or if the provided password is
747
+ * incorrect.
748
+ */
749
+ public async unlock({ password }: { password: string }): Promise<void> {
750
+ // Lock the vault.
751
+ await this.lock();
752
+
753
+ // Retrieve the content encryption key (CEK) record as a compact JWE from the data store.
754
+ const cekJwe = await this.getStoredContentEncryptionKey();
755
+
756
+ // Decrypt the compact JWE.
757
+ try {
758
+ const { plaintext: contentEncryptionKeyBytes } = await CompactJwe.decrypt({
759
+ jwe : cekJwe,
760
+ key : Convert.string(password).toUint8Array(),
761
+ crypto : this.crypto,
762
+ keyManager : new LocalKeyManager()
763
+ });
764
+ const contentEncryptionKey = Convert.uint8Array(contentEncryptionKeyBytes).toObject() as Jwk;
765
+
766
+ // Save the content encryption key in memory, thereby unlocking the vault.
767
+ this._contentEncryptionKey = contentEncryptionKey;
768
+
769
+ } catch (error: any) {
770
+ throw new Error(`HdIdentityVault: Unable to unlock the vault due to an incorrect password.`);
771
+ }
772
+ }
773
+
774
+ /**
775
+ * Retrieves the Decentralized Identifier (DID) associated with the identity vault from the vault
776
+ * store.
777
+ *
778
+ * This DID is encrypted in compact JWE format and needs to be decrypted after the vault is
779
+ * unlocked. The method is intended to be used internally within the HdIdentityVault class to access
780
+ * the encrypted PortableDid.
781
+ *
782
+ * @returns A promise that resolves to the encrypted DID stored in the vault as a compact JWE.
783
+ * @throws Will throw an error if the DID cannot be retrieved from the vault.
784
+ */
785
+ private async getStoredDid(): Promise<string> {
786
+ // Retrieve the DID record as a compact JWE from the data store.
787
+ const didJwe = await this._store.get('did');
788
+
789
+ if (!didJwe) {
790
+ throw new Error(
791
+ 'HdIdentityVault: Unable to retrieve the DID record from the vault. Please check the ' +
792
+ 'vault status and if the problem persists consider re-initializing the vault and ' +
793
+ 'restoring the contents from a previous backup.'
794
+ );
795
+ }
796
+
797
+ return didJwe;
798
+ }
799
+
800
+ /**
801
+ * Retrieves the encrypted Content Encryption Key (CEK) from the vault's storage.
802
+ *
803
+ * This CEK is used for encrypting and decrypting the vault's contents. It is stored as a
804
+ * compact JWE and should be decrypted with the user's password to be used for further
805
+ * cryptographic operations.
806
+ *
807
+ * @returns A promise that resolves to the stored CEK as a string in compact JWE format.
808
+ * @throws Will throw an error if the CEK cannot be retrieved, indicating potential issues with
809
+ * the vault's integrity or state.
810
+ */
811
+ private async getStoredContentEncryptionKey(): Promise<string> {
812
+ // Retrieve the content encryption key (CEK) record as a compact JWE from the data store.
813
+ const cekJwe = await this._store.get('contentEncryptionKey');
814
+
815
+ if (!cekJwe) {
816
+ throw new Error(
817
+ 'HdIdentityVault: Unable to retrieve the Content Encryption Key record from the vault. ' +
818
+ 'Please check the vault status and if the problem persists consider re-initializing the ' +
819
+ 'vault and restoring the contents from a previous backup.'
820
+ );
821
+ }
822
+
823
+ return cekJwe;
824
+ }
825
+
826
+ /**
827
+ * Updates the status of the `HdIdentityVault`, reflecting changes in its initialization, lock
828
+ * state, and the timestamps of the last backup and restore operations.
829
+ *
830
+ * This method directly manipulates the internal state stored in the vault's key-value store.
831
+ *
832
+ * @param params - The status properties to be updated.
833
+ * @param params.initialized - Updates the initialization state of the vault.
834
+ * @param params.lastBackup - Updates the timestamp of the last successful backup.
835
+ * @param params.lastRestore - Updates the timestamp of the last successful restore.
836
+ * @returns A promise that resolves to a boolean indicating successful status update.
837
+ * @throws Will throw an error if the status cannot be updated in the key-value store.
838
+ */
839
+ private async setStatus({ initialized, lastBackup, lastRestore }: Partial<IdentityVaultStatus>): Promise<boolean> {
840
+ // Get the current status values from the store, if any.
841
+ let vaultStatus = await this.getStatus();
842
+
843
+ // Update the status properties with new values specified, if any.
844
+ vaultStatus.initialized = initialized ?? vaultStatus.initialized;
845
+ vaultStatus.lastBackup = lastBackup ?? vaultStatus.lastBackup;
846
+ vaultStatus.lastRestore = lastRestore ?? vaultStatus.lastRestore;
847
+
848
+ // Write the changes to the store.
849
+ await this._store.set('vaultStatus', JSON.stringify(vaultStatus));
850
+
851
+ return true;
852
+ }
853
+ }