@enbox/dwn-sdk-js 0.4.6 → 0.4.8

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 (375) hide show
  1. package/README.md +3 -1
  2. package/dist/browser.mjs +19 -78
  3. package/dist/browser.mjs.map +4 -4
  4. package/dist/esm/generated/precompiled-validators.js +2324 -1525
  5. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  6. package/dist/esm/src/core/constants.js +50 -0
  7. package/dist/esm/src/core/constants.js.map +1 -1
  8. package/dist/esm/src/core/dwn-error.js +29 -11
  9. package/dist/esm/src/core/dwn-error.js.map +1 -1
  10. package/dist/esm/src/core/encryption-control.js +785 -0
  11. package/dist/esm/src/core/encryption-control.js.map +1 -0
  12. package/dist/esm/src/core/message.js +6 -0
  13. package/dist/esm/src/core/message.js.map +1 -1
  14. package/dist/esm/src/core/messages-grant-authorization.js +36 -5
  15. package/dist/esm/src/core/messages-grant-authorization.js.map +1 -1
  16. package/dist/esm/src/core/protocol-authorization-action.js +3 -12
  17. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  18. package/dist/esm/src/core/protocol-authorization-validation.js +31 -30
  19. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  20. package/dist/esm/src/core/protocol-authorization.js +6 -0
  21. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  22. package/dist/esm/src/core/recording-validation-state-reader.js +3 -3
  23. package/dist/esm/src/core/recording-validation-state-reader.js.map +1 -1
  24. package/dist/esm/src/core/replication-apply.js +62 -108
  25. package/dist/esm/src/core/replication-apply.js.map +1 -1
  26. package/dist/esm/src/core/validation-state-reader.js +5 -6
  27. package/dist/esm/src/core/validation-state-reader.js.map +1 -1
  28. package/dist/esm/src/dwn.js +1 -2
  29. package/dist/esm/src/dwn.js.map +1 -1
  30. package/dist/esm/src/event-stream/event-emitter-wake-publisher.js +11 -11
  31. package/dist/esm/src/event-stream/event-emitter-wake-publisher.js.map +1 -1
  32. package/dist/esm/src/handlers/messages-query.js +6 -16
  33. package/dist/esm/src/handlers/messages-query.js.map +1 -1
  34. package/dist/esm/src/handlers/messages-read.js +4 -3
  35. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  36. package/dist/esm/src/handlers/messages-subscribe.js +26 -30
  37. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  38. package/dist/esm/src/handlers/protocols-configure.js +6 -4
  39. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  40. package/dist/esm/src/handlers/records-count.js +85 -10
  41. package/dist/esm/src/handlers/records-count.js.map +1 -1
  42. package/dist/esm/src/handlers/records-delete.js +11 -0
  43. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  44. package/dist/esm/src/handlers/records-query.js +140 -18
  45. package/dist/esm/src/handlers/records-query.js.map +1 -1
  46. package/dist/esm/src/handlers/records-read.js +20 -4
  47. package/dist/esm/src/handlers/records-read.js.map +1 -1
  48. package/dist/esm/src/handlers/records-subscribe.js +127 -11
  49. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  50. package/dist/esm/src/handlers/records-write.js +15 -0
  51. package/dist/esm/src/handlers/records-write.js.map +1 -1
  52. package/dist/esm/src/index.js +8 -11
  53. package/dist/esm/src/index.js.map +1 -1
  54. package/dist/esm/src/interfaces/protocols-configure.js +66 -9
  55. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  56. package/dist/esm/src/interfaces/records-write.js +43 -36
  57. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  58. package/dist/esm/src/jose/algorithms/signing/ed25519.js +5 -5
  59. package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -1
  60. package/dist/esm/src/jose/jws/general/verifier.js +1 -1
  61. package/dist/esm/src/jose/jws/general/verifier.js.map +1 -1
  62. package/dist/esm/src/protocols/encryption.js +60 -270
  63. package/dist/esm/src/protocols/encryption.js.map +1 -1
  64. package/dist/esm/src/store/blockstore-level.js +14 -23
  65. package/dist/esm/src/store/blockstore-level.js.map +1 -1
  66. package/dist/esm/src/store/blockstore-mock.js +10 -27
  67. package/dist/esm/src/store/blockstore-mock.js.map +1 -1
  68. package/dist/esm/src/store/blockstore-utils.js +45 -0
  69. package/dist/esm/src/store/blockstore-utils.js.map +1 -0
  70. package/dist/esm/src/store/blockstore.js +2 -0
  71. package/dist/esm/src/store/blockstore.js.map +1 -0
  72. package/dist/esm/src/store/data-store-level.js +4 -12
  73. package/dist/esm/src/store/data-store-level.js.map +1 -1
  74. package/dist/esm/src/store/level.js +7 -0
  75. package/dist/esm/src/store/level.js.map +1 -0
  76. package/dist/esm/src/types/encryption-types.js +4 -1
  77. package/dist/esm/src/types/encryption-types.js.map +1 -1
  78. package/dist/esm/src/utils/data-stream.js +25 -0
  79. package/dist/esm/src/utils/data-stream.js.map +1 -1
  80. package/dist/esm/src/utils/encryption.js +107 -19
  81. package/dist/esm/src/utils/encryption.js.map +1 -1
  82. package/dist/esm/src/utils/grant-key-coverage.js +180 -0
  83. package/dist/esm/src/utils/grant-key-coverage.js.map +1 -0
  84. package/dist/esm/src/utils/hd-key.js +1 -2
  85. package/dist/esm/src/utils/hd-key.js.map +1 -1
  86. package/dist/esm/src/utils/jws.js +7 -1
  87. package/dist/esm/src/utils/jws.js.map +1 -1
  88. package/dist/esm/src/utils/memory-cache.js +29 -8
  89. package/dist/esm/src/utils/memory-cache.js.map +1 -1
  90. package/dist/esm/src/utils/protocols.js +27 -0
  91. package/dist/esm/src/utils/protocols.js.map +1 -1
  92. package/dist/esm/src/utils/record-limit-occupancy.js +23 -3
  93. package/dist/esm/src/utils/record-limit-occupancy.js.map +1 -1
  94. package/dist/esm/src/utils/records.js +29 -0
  95. package/dist/esm/src/utils/records.js.map +1 -1
  96. package/dist/esm/src/utils/secp256k1.js +12 -11
  97. package/dist/esm/src/utils/secp256k1.js.map +1 -1
  98. package/dist/esm/src/utils/secp256r1.js +12 -20
  99. package/dist/esm/src/utils/secp256r1.js.map +1 -1
  100. package/dist/esm/src/utils/time.js +103 -25
  101. package/dist/esm/src/utils/time.js.map +1 -1
  102. package/dist/esm/tests/core/constants.spec.js +35 -0
  103. package/dist/esm/tests/core/constants.spec.js.map +1 -0
  104. package/dist/esm/tests/core/encryption-control.spec.js +100 -0
  105. package/dist/esm/tests/core/encryption-control.spec.js.map +1 -0
  106. package/dist/esm/tests/core/message.spec.js +35 -0
  107. package/dist/esm/tests/core/message.spec.js.map +1 -1
  108. package/dist/esm/tests/core/protocol-authorization.spec.js +1 -1
  109. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  110. package/dist/esm/tests/core/replication-apply.spec.js +157 -74
  111. package/dist/esm/tests/core/replication-apply.spec.js.map +1 -1
  112. package/dist/esm/tests/core/replication-replay-property.spec.js +2 -1
  113. package/dist/esm/tests/core/replication-replay-property.spec.js.map +1 -1
  114. package/dist/esm/tests/core/validation-read-closure.spec.js +14 -28
  115. package/dist/esm/tests/core/validation-read-closure.spec.js.map +1 -1
  116. package/dist/esm/tests/core/validation-state-reader.spec.js +19 -23
  117. package/dist/esm/tests/core/validation-state-reader.spec.js.map +1 -1
  118. package/dist/esm/tests/dwn.spec.js +2 -1
  119. package/dist/esm/tests/dwn.spec.js.map +1 -1
  120. package/dist/esm/tests/event-emitter-wake-publisher.spec.js +51 -0
  121. package/dist/esm/tests/event-emitter-wake-publisher.spec.js.map +1 -0
  122. package/dist/esm/tests/features/protocol-composition.spec.js +1 -1
  123. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  124. package/dist/esm/tests/features/records-record-limit.spec.js +1 -1
  125. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -1
  126. package/dist/esm/tests/fuzz/encryption.fuzz.spec.js +9 -1
  127. package/dist/esm/tests/fuzz/encryption.fuzz.spec.js.map +1 -1
  128. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js +1 -1
  129. package/dist/esm/tests/fuzz/process-message.fuzz.spec.js.map +1 -1
  130. package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js +29 -1
  131. package/dist/esm/tests/fuzz/protocols-utils.fuzz.spec.js.map +1 -1
  132. package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js +2 -2
  133. package/dist/esm/tests/fuzz/secp256k1.fuzz.spec.js.map +1 -1
  134. package/dist/esm/tests/fuzz/time.fuzz.spec.js +7 -1
  135. package/dist/esm/tests/fuzz/time.fuzz.spec.js.map +1 -1
  136. package/dist/esm/tests/handlers/messages-query.spec.js +123 -11
  137. package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -1
  138. package/dist/esm/tests/handlers/messages-read.spec.js +95 -0
  139. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  140. package/dist/esm/tests/handlers/messages-subscribe.spec.js +90 -0
  141. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  142. package/dist/esm/tests/handlers/protocols-configure.spec.js +66 -0
  143. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  144. package/dist/esm/tests/handlers/records-count.spec.js +370 -0
  145. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  146. package/dist/esm/tests/handlers/records-delete.spec.js +70 -1
  147. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  148. package/dist/esm/tests/handlers/records-query.spec.js +562 -1
  149. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  150. package/dist/esm/tests/handlers/records-read.spec.js +140 -2
  151. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  152. package/dist/esm/tests/handlers/records-subscribe.spec.js +241 -1
  153. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  154. package/dist/esm/tests/handlers/records-write.spec.js +1187 -29
  155. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  156. package/dist/esm/tests/interfaces/protocols-configure.spec.js +290 -2
  157. package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -1
  158. package/dist/esm/tests/interfaces/records-write.spec.js +47 -5
  159. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  160. package/dist/esm/tests/protocols/encryption.spec.js +187 -452
  161. package/dist/esm/tests/protocols/encryption.spec.js.map +1 -1
  162. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +13 -27
  163. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  164. package/dist/esm/tests/store/blockstore-level.spec.js +33 -10
  165. package/dist/esm/tests/store/blockstore-level.spec.js.map +1 -1
  166. package/dist/esm/tests/store/blockstore-mock.spec.js +31 -7
  167. package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -1
  168. package/dist/esm/tests/store/blockstore-utils.spec.js +115 -0
  169. package/dist/esm/tests/store/blockstore-utils.spec.js.map +1 -0
  170. package/dist/esm/tests/store/index-level.spec.js +3 -3
  171. package/dist/esm/tests/store/index-level.spec.js.map +1 -1
  172. package/dist/esm/tests/test-stores.js +2 -1
  173. package/dist/esm/tests/test-stores.js.map +1 -1
  174. package/dist/esm/tests/utils/cid.spec.js +15 -0
  175. package/dist/esm/tests/utils/cid.spec.js.map +1 -1
  176. package/dist/esm/tests/utils/data-stream.spec.js +30 -0
  177. package/dist/esm/tests/utils/data-stream.spec.js.map +1 -1
  178. package/dist/esm/tests/utils/encryption-control-test-utils.js +111 -0
  179. package/dist/esm/tests/utils/encryption-control-test-utils.js.map +1 -0
  180. package/dist/esm/tests/utils/encryption.spec.js +198 -5
  181. package/dist/esm/tests/utils/encryption.spec.js.map +1 -1
  182. package/dist/esm/tests/utils/grant-key-coverage.spec.js +262 -0
  183. package/dist/esm/tests/utils/grant-key-coverage.spec.js.map +1 -0
  184. package/dist/esm/tests/utils/memory-cache.spec.js +12 -0
  185. package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -1
  186. package/dist/esm/tests/utils/secp256r1.spec.js +2 -2
  187. package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -1
  188. package/dist/esm/tests/utils/test-data-generator.js +2 -1
  189. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  190. package/dist/esm/tests/utils/test-validation-state-reader.js +1 -1
  191. package/dist/esm/tests/utils/test-validation-state-reader.js.map +1 -1
  192. package/dist/esm/tests/utils/time.spec.js +26 -0
  193. package/dist/esm/tests/utils/time.spec.js.map +1 -1
  194. package/dist/esm/tests/validation/json-schemas/encryption/audience.spec.js +45 -0
  195. package/dist/esm/tests/validation/json-schemas/encryption/audience.spec.js.map +1 -0
  196. package/dist/esm/tests/validation/json-schemas/encryption/delivery.spec.js +47 -0
  197. package/dist/esm/tests/validation/json-schemas/encryption/delivery.spec.js.map +1 -0
  198. package/dist/esm/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.js +43 -0
  199. package/dist/esm/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.js.map +1 -0
  200. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +152 -0
  201. package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -1
  202. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +46 -1
  203. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  204. package/dist/types/generated/precompiled-validators.d.ts +20 -4
  205. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  206. package/dist/types/src/core/constants.d.ts +39 -0
  207. package/dist/types/src/core/constants.d.ts.map +1 -1
  208. package/dist/types/src/core/dwn-error.d.ts +29 -11
  209. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  210. package/dist/types/src/core/encryption-control.d.ts +128 -0
  211. package/dist/types/src/core/encryption-control.d.ts.map +1 -0
  212. package/dist/types/src/core/message.d.ts +4 -0
  213. package/dist/types/src/core/message.d.ts.map +1 -1
  214. package/dist/types/src/core/messages-grant-authorization.d.ts +11 -0
  215. package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -1
  216. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  217. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  218. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  219. package/dist/types/src/core/recording-validation-state-reader.d.ts +2 -3
  220. package/dist/types/src/core/recording-validation-state-reader.d.ts.map +1 -1
  221. package/dist/types/src/core/replication-apply.d.ts +10 -1
  222. package/dist/types/src/core/replication-apply.d.ts.map +1 -1
  223. package/dist/types/src/core/validation-state-reader.d.ts +2 -3
  224. package/dist/types/src/core/validation-state-reader.d.ts.map +1 -1
  225. package/dist/types/src/dwn.d.ts.map +1 -1
  226. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts +1 -1
  227. package/dist/types/src/event-stream/event-emitter-wake-publisher.d.ts.map +1 -1
  228. package/dist/types/src/handlers/messages-query.d.ts.map +1 -1
  229. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  230. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  231. package/dist/types/src/handlers/protocols-configure.d.ts +1 -0
  232. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  233. package/dist/types/src/handlers/records-count.d.ts +2 -0
  234. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  235. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  236. package/dist/types/src/handlers/records-query.d.ts +3 -0
  237. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  238. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  239. package/dist/types/src/handlers/records-subscribe.d.ts +2 -0
  240. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  241. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  242. package/dist/types/src/index.d.ts +12 -18
  243. package/dist/types/src/index.d.ts.map +1 -1
  244. package/dist/types/src/interfaces/protocols-configure.d.ts +13 -1
  245. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  246. package/dist/types/src/interfaces/records-write.d.ts +5 -1
  247. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  248. package/dist/types/src/jose/algorithms/signing/ed25519.d.ts.map +1 -1
  249. package/dist/types/src/protocols/encryption.d.ts +15 -19
  250. package/dist/types/src/protocols/encryption.d.ts.map +1 -1
  251. package/dist/types/src/store/blockstore-level.d.ts +11 -11
  252. package/dist/types/src/store/blockstore-level.d.ts.map +1 -1
  253. package/dist/types/src/store/blockstore-mock.d.ts +12 -12
  254. package/dist/types/src/store/blockstore-mock.d.ts.map +1 -1
  255. package/dist/types/src/store/blockstore-utils.d.ts +23 -0
  256. package/dist/types/src/store/blockstore-utils.d.ts.map +1 -0
  257. package/dist/types/src/store/blockstore.d.ts +3 -0
  258. package/dist/types/src/store/blockstore.d.ts.map +1 -0
  259. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  260. package/dist/types/src/store/level.d.ts +13 -0
  261. package/dist/types/src/store/level.d.ts.map +1 -0
  262. package/dist/types/src/types/cache.d.ts +2 -2
  263. package/dist/types/src/types/cache.d.ts.map +1 -1
  264. package/dist/types/src/types/encryption-types.d.ts +31 -2
  265. package/dist/types/src/types/encryption-types.d.ts.map +1 -1
  266. package/dist/types/src/types/validation-state-reader.d.ts +3 -5
  267. package/dist/types/src/types/validation-state-reader.d.ts.map +1 -1
  268. package/dist/types/src/utils/data-stream.d.ts +5 -0
  269. package/dist/types/src/utils/data-stream.d.ts.map +1 -1
  270. package/dist/types/src/utils/encryption.d.ts +53 -24
  271. package/dist/types/src/utils/encryption.d.ts.map +1 -1
  272. package/dist/types/src/utils/grant-key-coverage.d.ts +36 -0
  273. package/dist/types/src/utils/grant-key-coverage.d.ts.map +1 -0
  274. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  275. package/dist/types/src/utils/jws.d.ts.map +1 -1
  276. package/dist/types/src/utils/memory-cache.d.ts +4 -2
  277. package/dist/types/src/utils/memory-cache.d.ts.map +1 -1
  278. package/dist/types/src/utils/protocols.d.ts +11 -0
  279. package/dist/types/src/utils/protocols.d.ts.map +1 -1
  280. package/dist/types/src/utils/record-limit-occupancy.d.ts +7 -0
  281. package/dist/types/src/utils/record-limit-occupancy.d.ts.map +1 -1
  282. package/dist/types/src/utils/records.d.ts +2 -0
  283. package/dist/types/src/utils/records.d.ts.map +1 -1
  284. package/dist/types/src/utils/secp256k1.d.ts.map +1 -1
  285. package/dist/types/src/utils/secp256r1.d.ts.map +1 -1
  286. package/dist/types/src/utils/time.d.ts +21 -13
  287. package/dist/types/src/utils/time.d.ts.map +1 -1
  288. package/dist/types/tests/core/constants.spec.d.ts +2 -0
  289. package/dist/types/tests/core/constants.spec.d.ts.map +1 -0
  290. package/dist/types/tests/core/encryption-control.spec.d.ts +2 -0
  291. package/dist/types/tests/core/encryption-control.spec.d.ts.map +1 -0
  292. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  293. package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts +2 -0
  294. package/dist/types/tests/event-emitter-wake-publisher.spec.d.ts.map +1 -0
  295. package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -1
  296. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  297. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  298. package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -1
  299. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  300. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  301. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  302. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  303. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  304. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  305. package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -1
  306. package/dist/types/tests/store/blockstore-utils.spec.d.ts +2 -0
  307. package/dist/types/tests/store/blockstore-utils.spec.d.ts.map +1 -0
  308. package/dist/types/tests/test-stores.d.ts.map +1 -1
  309. package/dist/types/tests/utils/encryption-control-test-utils.d.ts +46 -0
  310. package/dist/types/tests/utils/encryption-control-test-utils.d.ts.map +1 -0
  311. package/dist/types/tests/utils/grant-key-coverage.spec.d.ts +2 -0
  312. package/dist/types/tests/utils/grant-key-coverage.spec.d.ts.map +1 -0
  313. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  314. package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts +2 -0
  315. package/dist/types/tests/validation/json-schemas/encryption/audience.spec.d.ts.map +1 -0
  316. package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts +2 -0
  317. package/dist/types/tests/validation/json-schemas/encryption/delivery.spec.d.ts.map +1 -0
  318. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts +2 -0
  319. package/dist/types/tests/validation/json-schemas/encryption/wrapped-grant-key-envelope.spec.d.ts.map +1 -0
  320. package/package.json +47 -28
  321. package/src/core/constants.ts +61 -0
  322. package/src/core/dwn-error.ts +29 -11
  323. package/src/core/encryption-control.ts +1249 -0
  324. package/src/core/message.ts +7 -0
  325. package/src/core/messages-grant-authorization.ts +60 -9
  326. package/src/core/protocol-authorization-action.ts +3 -13
  327. package/src/core/protocol-authorization-validation.ts +66 -46
  328. package/src/core/protocol-authorization.ts +7 -0
  329. package/src/core/recording-validation-state-reader.ts +4 -5
  330. package/src/core/replication-apply.ts +77 -133
  331. package/src/core/validation-state-reader.ts +6 -8
  332. package/src/dwn.ts +1 -2
  333. package/src/event-stream/event-emitter-wake-publisher.ts +10 -14
  334. package/src/handlers/messages-query.ts +6 -22
  335. package/src/handlers/messages-read.ts +4 -3
  336. package/src/handlers/messages-subscribe.ts +34 -30
  337. package/src/handlers/protocols-configure.ts +7 -4
  338. package/src/handlers/records-count.ts +111 -10
  339. package/src/handlers/records-delete.ts +15 -0
  340. package/src/handlers/records-query.ts +176 -20
  341. package/src/handlers/records-read.ts +19 -6
  342. package/src/handlers/records-subscribe.ts +158 -8
  343. package/src/handlers/records-write.ts +19 -0
  344. package/src/index.ts +50 -22
  345. package/src/interfaces/protocols-configure.ts +102 -11
  346. package/src/interfaces/records-write.ts +49 -43
  347. package/src/jose/algorithms/signing/ed25519.ts +7 -6
  348. package/src/jose/jws/general/verifier.ts +3 -3
  349. package/src/protocols/encryption.ts +94 -411
  350. package/src/store/blockstore-level.ts +33 -37
  351. package/src/store/blockstore-mock.ts +24 -38
  352. package/src/store/blockstore-utils.ts +85 -0
  353. package/src/store/blockstore.ts +8 -0
  354. package/src/store/data-store-level.ts +5 -12
  355. package/src/store/level.ts +19 -0
  356. package/src/types/cache.ts +3 -3
  357. package/src/types/encryption-types.ts +39 -2
  358. package/src/types/validation-state-reader.ts +3 -5
  359. package/src/utils/data-stream.ts +29 -1
  360. package/src/utils/encryption.ts +190 -60
  361. package/src/utils/grant-key-coverage.ts +303 -0
  362. package/src/utils/hd-key.ts +1 -2
  363. package/src/utils/jws.ts +8 -2
  364. package/src/utils/memory-cache.ts +42 -11
  365. package/src/utils/protocols.ts +32 -0
  366. package/src/utils/record-limit-occupancy.ts +34 -5
  367. package/src/utils/records.ts +36 -2
  368. package/src/utils/secp256k1.ts +12 -12
  369. package/src/utils/secp256r1.ts +12 -22
  370. package/src/utils/time.ts +145 -27
  371. package/dist/esm/tests/validation/json-schemas/encryption/audience-key.spec.js +0 -40
  372. package/dist/esm/tests/validation/json-schemas/encryption/audience-key.spec.js.map +0 -1
  373. package/dist/types/tests/validation/json-schemas/encryption/audience-key.spec.d.ts +0 -2
  374. package/dist/types/tests/validation/json-schemas/encryption/audience-key.spec.d.ts.map +0 -1
  375. package/src/types/mitt.d.ts +0 -28
@@ -1,7 +1,6 @@
1
1
  import type { Jwk } from '@enbox/crypto';
2
2
  import type { PublicKeyJwk } from '../types/jose-types.js';
3
3
 
4
- import { concatBytes } from '@noble/ciphers/utils';
5
4
  import { AesCtr, AesKw, computeJwkThumbprint, Hkdf, X25519 } from '@enbox/crypto';
6
5
 
7
6
  import { Encoder } from './encoder.js';
@@ -17,73 +16,128 @@ export enum KeyAgreementAlgorithm {
17
16
  }
18
17
 
19
18
  export const ROLE_AUDIENCE_DERIVATION_SCHEME = 'roleAudience';
19
+ export const SEAL_DERIVATION_SCHEME = 'seal';
20
20
 
21
21
  const AES_256_KEY_LENGTH_BYTES = 32;
22
22
  const AES_CTR_COUNTER_LENGTH_BYTES = 16;
23
23
  const AES_CTR_COUNTER_LENGTH_BITS = 128;
24
24
  const KEK_INFO_PREFIX = KeyAgreementAlgorithm.X25519HkdfSha256A256Kw;
25
25
 
26
- export type ProtocolPathKeyEncryption = {
26
+ function concatBytes(...arrays: Uint8Array[]): Uint8Array {
27
+ const byteLength = arrays.reduce((total, array): number => total + array.byteLength, 0);
28
+ const result = new Uint8Array(byteLength);
29
+ let offset = 0;
30
+
31
+ for (const array of arrays) {
32
+ result.set(array, offset);
33
+ offset += array.byteLength;
34
+ }
35
+
36
+ return result;
37
+ }
38
+
39
+ export type X25519KeyEncryptionBase = {
27
40
  algorithm: KeyAgreementAlgorithm.X25519HkdfSha256A256Kw;
28
41
  keyId: string;
29
- derivationScheme: KeyDerivationScheme.ProtocolPath;
30
42
  ephemeralPublicKey: PublicKeyJwk;
31
43
  encryptedKey: string;
32
44
  };
33
45
 
34
- export type RoleAudienceKeyEncryption = {
35
- algorithm: KeyAgreementAlgorithm.X25519HkdfSha256A256Kw;
36
- keyId: string;
46
+ export type ProtocolPathKeyEncryption = X25519KeyEncryptionBase & {
47
+ derivationScheme: KeyDerivationScheme.ProtocolPath;
48
+ };
49
+
50
+ export type SourceRoleAudienceKeyEncryption = X25519KeyEncryptionBase & {
37
51
  derivationScheme: typeof ROLE_AUDIENCE_DERIVATION_SCHEME;
38
52
  protocol: string;
39
- role: string;
40
- epoch: number;
41
- ephemeralPublicKey: PublicKeyJwk;
42
- encryptedKey: string;
53
+ rolePath: string;
43
54
  };
44
55
 
45
- export type KeyEncryption = ProtocolPathKeyEncryption | RoleAudienceKeyEncryption;
56
+ export type X25519KeyEncryption = ProtocolPathKeyEncryption | SourceRoleAudienceKeyEncryption;
46
57
 
47
- export type X25519KeyEncryption = ProtocolPathKeyEncryption | RoleAudienceKeyEncryption;
58
+ export type SealKeyWrap = X25519KeyEncryptionBase & {
59
+ derivationScheme: typeof SEAL_DERIVATION_SCHEME;
60
+ };
48
61
 
49
62
  export type DwnEncryption = {
50
63
  algorithm: ContentEncryptionAlgorithm.A256CTR;
51
64
  initializationVector: string;
52
- keyEncryption: KeyEncryption[];
65
+ keyEncryption: X25519KeyEncryption[];
53
66
  };
54
67
 
55
- export type ProtocolPathKeyEncryptionInput = {
68
+ export type X25519KeyEncryptionInputBase = {
69
+ algorithm: KeyAgreementAlgorithm.X25519HkdfSha256A256Kw;
56
70
  keyId: string;
57
71
  publicKey: PublicKeyJwk;
72
+ };
73
+
74
+ export type ProtocolPathKeyEncryptionInput = X25519KeyEncryptionInputBase & {
58
75
  derivationScheme: KeyDerivationScheme.ProtocolPath;
59
76
  };
60
77
 
61
- export type RoleAudienceKeyEncryptionInput = {
62
- keyId: string;
63
- publicKey: PublicKeyJwk;
78
+ export type SourceRoleAudienceKeyEncryptionInput = X25519KeyEncryptionInputBase & {
64
79
  derivationScheme: typeof ROLE_AUDIENCE_DERIVATION_SCHEME;
65
80
  protocol: string;
66
- role: string;
67
- epoch: number;
81
+ rolePath: string;
68
82
  };
69
83
 
70
- export type KeyEncryptionInput = ProtocolPathKeyEncryptionInput | RoleAudienceKeyEncryptionInput;
84
+ export type X25519KeyEncryptionInput = ProtocolPathKeyEncryptionInput | SourceRoleAudienceKeyEncryptionInput;
71
85
 
72
- export type X25519KeyEncryptionInput = ProtocolPathKeyEncryptionInput | RoleAudienceKeyEncryptionInput;
86
+ export type SealKeyWrapInput = X25519KeyEncryptionInputBase & {
87
+ derivationScheme: typeof SEAL_DERIVATION_SCHEME;
88
+ protocol: string;
89
+ rolePath: string;
90
+ contextId: string;
91
+ audienceKeyId: string;
92
+ };
73
93
 
74
94
  export type EncryptionInput = {
75
95
  algorithm?: ContentEncryptionAlgorithm;
76
96
  key: Uint8Array;
77
97
  initializationVector: Uint8Array;
78
- keyEncryptionInputs: KeyEncryptionInput[];
98
+ keyEncryptionInputs: X25519KeyEncryptionInput[];
79
99
  };
80
100
 
81
101
  export type KeyUnwrapPayload = {
82
102
  encryptedKey: Uint8Array;
83
103
  ephemeralPublicKey: PublicKeyJwk;
84
- keyEncryption: KeyEncryption;
104
+ keyEncryption: X25519KeyEncryption;
105
+ };
106
+
107
+ export type X25519KeyWrapInput = {
108
+ cek: Uint8Array;
109
+ keyInput: X25519KeyEncryptionInput;
110
+ ephemeralPrivateKey?: Jwk;
111
+ };
112
+
113
+ export type SealWrapInput = {
114
+ privateKeyBytes: Uint8Array;
115
+ keyInput: SealKeyWrapInput;
116
+ ephemeralPrivateKey?: Jwk;
117
+ };
118
+
119
+ export type SealUnwrapInput = {
120
+ seal: SealKeyWrap;
121
+ recipientPrivateKey: Jwk;
122
+ protocol: string;
123
+ rolePath: string;
124
+ contextId: string;
125
+ audienceKeyId: string;
85
126
  };
86
127
 
128
+ type SealKeyUnwrapInfo = SealKeyWrap & {
129
+ protocol: string;
130
+ rolePath: string;
131
+ contextId: string;
132
+ audienceKeyId: string;
133
+ };
134
+
135
+ type X25519KekDerivationInput =
136
+ | X25519KeyEncryptionInput
137
+ | X25519KeyEncryption
138
+ | SealKeyWrapInput
139
+ | SealKeyUnwrapInfo;
140
+
87
141
  export class Encryption {
88
142
  public static async encrypt(
89
143
  algorithm: ContentEncryptionAlgorithm,
@@ -137,31 +191,54 @@ export class Encryption {
137
191
  return Encryption.toStream(plaintext);
138
192
  }
139
193
 
140
- public static async wrapKey(
141
- recipientPublicKey: PublicKeyJwk,
142
- cek: Uint8Array,
143
- keyInput: KeyEncryptionInput,
144
- ephemeralPrivateKey?: Jwk,
145
- ): Promise<{ encryptedKey: Uint8Array; ephemeralPublicKey: PublicKeyJwk }> {
146
- return Encryption.wrapX25519Key(recipientPublicKey, cek, keyInput, ephemeralPrivateKey);
194
+ public static async wrapKey(input: X25519KeyWrapInput): Promise<{ encryptedKey: Uint8Array; ephemeralPublicKey: PublicKeyJwk }> {
195
+ if (Encryption.isX25519KeyAgreementAlgorithm(input.keyInput.algorithm)) {
196
+ return Encryption.wrapX25519Key(input);
197
+ }
198
+
199
+ throw new Error(Encryption.unsupportedKeyAgreementAlgorithmMessage(input.keyInput.algorithm));
147
200
  }
148
201
 
149
- private static async wrapX25519Key(
150
- recipientPublicKey: PublicKeyJwk,
151
- cek: Uint8Array,
152
- keyInput: X25519KeyEncryptionInput,
153
- ephemeralPrivateKey?: Jwk,
154
- ): Promise<{ encryptedKey: Uint8Array; ephemeralPublicKey: PublicKeyJwk }> {
155
- Encryption.validateContentEncryptionKey(cek);
202
+ public static async wrapSeal(input: SealWrapInput): Promise<SealKeyWrap> {
203
+ if (!Encryption.isX25519KeyAgreementAlgorithm(input.keyInput.algorithm)) {
204
+ throw new Error(Encryption.unsupportedKeyAgreementAlgorithmMessage(input.keyInput.algorithm));
205
+ }
206
+
207
+ Encryption.validateContentEncryptionKey(input.privateKeyBytes);
208
+
209
+ const privateKey = input.ephemeralPrivateKey ?? await X25519.generateKey();
210
+ const publicKey = await X25519.getPublicKey({ key: privateKey }) as PublicKeyJwk;
211
+ const sharedSecret = await X25519.sharedSecret({
212
+ privateKeyA : privateKey,
213
+ publicKeyB : input.keyInput.publicKey as Jwk,
214
+ });
215
+ const kek = await Encryption.deriveKek(sharedSecret, input.keyInput);
216
+ const unwrappedKey = await AesKw.bytesToPrivateKey({ privateKeyBytes: input.privateKeyBytes });
217
+ const encryptedKey = await AesKw.wrapKey({
218
+ encryptionKey: Encryption.toA256KwJwk(kek),
219
+ unwrappedKey,
220
+ });
156
221
 
157
- const privateKey = ephemeralPrivateKey ?? await X25519.generateKey();
222
+ return {
223
+ algorithm : input.keyInput.algorithm,
224
+ derivationScheme : SEAL_DERIVATION_SCHEME,
225
+ encryptedKey : Encoder.bytesToBase64Url(encryptedKey),
226
+ ephemeralPublicKey : publicKey,
227
+ keyId : input.keyInput.keyId,
228
+ };
229
+ }
230
+
231
+ private static async wrapX25519Key(input: X25519KeyWrapInput): Promise<{ encryptedKey: Uint8Array; ephemeralPublicKey: PublicKeyJwk }> {
232
+ Encryption.validateContentEncryptionKey(input.cek);
233
+
234
+ const privateKey = input.ephemeralPrivateKey ?? await X25519.generateKey();
158
235
  const publicKey = await X25519.getPublicKey({ key: privateKey }) as PublicKeyJwk;
159
236
  const sharedSecret = await X25519.sharedSecret({
160
237
  privateKeyA : privateKey,
161
- publicKeyB : recipientPublicKey as Jwk,
238
+ publicKeyB : input.keyInput.publicKey as Jwk,
162
239
  });
163
- const kek = await Encryption.deriveKek(sharedSecret, keyInput);
164
- const cekJwk = Encryption.toA256CtrJwk(cek);
240
+ const kek = await Encryption.deriveKek(sharedSecret, input.keyInput);
241
+ const cekJwk = Encryption.toA256CtrJwk(input.cek);
165
242
  const kekJwk: Jwk = { alg: 'A256KW', k: Encoder.bytesToBase64Url(kek), kty: 'oct' };
166
243
  const encryptedKey = await AesKw.wrapKey({ encryptionKey: kekJwk, unwrappedKey: cekJwk });
167
244
 
@@ -170,13 +247,39 @@ export class Encryption {
170
247
 
171
248
  public static async unwrapKey(
172
249
  recipientPrivateKey: Jwk,
173
- keyEncryption: KeyEncryption,
250
+ keyEncryption: X25519KeyEncryption,
174
251
  ): Promise<Uint8Array> {
175
- if (keyEncryption.algorithm === KeyAgreementAlgorithm.X25519HkdfSha256A256Kw) {
252
+ if (Encryption.isX25519KeyAgreementAlgorithm(keyEncryption.algorithm)) {
176
253
  return Encryption.unwrapX25519Key(recipientPrivateKey, keyEncryption);
177
254
  }
178
255
 
179
- throw new Error(`Unsupported key agreement algorithm: ${(keyEncryption as KeyEncryption).algorithm}`);
256
+ throw new Error(Encryption.unsupportedKeyAgreementAlgorithmMessage(keyEncryption.algorithm));
257
+ }
258
+
259
+ public static async unwrapSeal(input: SealUnwrapInput): Promise<Uint8Array> {
260
+ if (!Encryption.isX25519KeyAgreementAlgorithm(input.seal.algorithm)) {
261
+ throw new Error(Encryption.unsupportedKeyAgreementAlgorithmMessage(input.seal.algorithm));
262
+ }
263
+
264
+ const keyEncryption: SealKeyUnwrapInfo = {
265
+ ...input.seal,
266
+ audienceKeyId : input.audienceKeyId,
267
+ contextId : input.contextId,
268
+ protocol : input.protocol,
269
+ rolePath : input.rolePath,
270
+ };
271
+ const sharedSecret = await X25519.sharedSecret({
272
+ privateKeyA : input.recipientPrivateKey,
273
+ publicKeyB : input.seal.ephemeralPublicKey as Jwk,
274
+ });
275
+ const kek = await Encryption.deriveKek(sharedSecret, keyEncryption);
276
+ const unwrappedKey = await AesKw.unwrapKey({
277
+ decryptionKey : Encryption.toA256KwJwk(kek),
278
+ wrappedKeyAlgorithm : 'A256KW',
279
+ wrappedKeyBytes : Encoder.base64UrlToBytes(input.seal.encryptedKey),
280
+ });
281
+
282
+ return AesKw.privateKeyToBytes({ privateKey: unwrappedKey });
180
283
  }
181
284
 
182
285
  private static async unwrapX25519Key(
@@ -204,7 +307,7 @@ export class Encryption {
204
307
  const algorithm = encryptionInput.algorithm ?? ContentEncryptionAlgorithm.A256CTR;
205
308
  Encryption.validateContentEncryptionParameters(algorithm, encryptionInput.key, encryptionInput.initializationVector);
206
309
 
207
- const keyEncryption: KeyEncryption[] = [];
310
+ const keyEncryption: X25519KeyEncryption[] = [];
208
311
  for (const keyInput of encryptionInput.keyEncryptionInputs) {
209
312
  keyEncryption.push(await Encryption.buildKeyEncryptionEntry(encryptionInput.key, keyInput));
210
313
  }
@@ -236,15 +339,14 @@ export class Encryption {
236
339
 
237
340
  private static async buildKeyEncryptionEntry(
238
341
  cek: Uint8Array,
239
- keyInput: KeyEncryptionInput,
240
- ): Promise<KeyEncryption> {
241
- const { encryptedKey, ephemeralPublicKey } = await Encryption.wrapKey(
242
- keyInput.publicKey,
342
+ keyInput: X25519KeyEncryptionInput,
343
+ ): Promise<X25519KeyEncryption> {
344
+ const { encryptedKey, ephemeralPublicKey } = await Encryption.wrapKey({
243
345
  cek,
244
346
  keyInput,
245
- );
347
+ });
246
348
  const common = {
247
- algorithm : KeyAgreementAlgorithm.X25519HkdfSha256A256Kw,
349
+ algorithm : keyInput.algorithm,
248
350
  encryptedKey : Encoder.bytesToBase64Url(encryptedKey),
249
351
  ephemeralPublicKey,
250
352
  keyId : keyInput.keyId,
@@ -260,21 +362,20 @@ export class Encryption {
260
362
  return {
261
363
  ...common,
262
364
  derivationScheme : ROLE_AUDIENCE_DERIVATION_SCHEME,
263
- epoch : keyInput.epoch,
264
365
  protocol : keyInput.protocol,
265
- role : keyInput.role,
366
+ rolePath : keyInput.rolePath,
266
367
  };
267
368
  }
268
369
 
269
- private static validateKeyEncryptionEntry(entry: KeyEncryption): void {
270
- if (entry.algorithm === KeyAgreementAlgorithm.X25519HkdfSha256A256Kw) {
370
+ private static validateKeyEncryptionEntry(entry: X25519KeyEncryption): void {
371
+ if (Encryption.isX25519KeyAgreementAlgorithm(entry.algorithm)) {
271
372
  Encryption.validateX25519KeyEncryptionEntry(entry);
272
373
  return;
273
374
  }
274
375
 
275
376
  throw new DwnError(
276
377
  DwnErrorCode.RecordsWriteValidateIntegrityEncryptionEphemeralPublicKeyInvalid,
277
- `Unsupported key agreement algorithm: ${(entry as KeyEncryption).algorithm}`
378
+ Encryption.unsupportedKeyAgreementAlgorithmMessage(entry.algorithm)
278
379
  );
279
380
  }
280
381
 
@@ -289,7 +390,7 @@ export class Encryption {
289
390
 
290
391
  private static async deriveKek(
291
392
  sharedSecret: Uint8Array,
292
- keyEncryption: X25519KeyEncryptionInput | X25519KeyEncryption,
393
+ keyEncryption: X25519KekDerivationInput,
293
394
  ): Promise<Uint8Array> {
294
395
  Encryption.validateSharedSecret(sharedSecret);
295
396
  const info = Encryption.getKekInfo(keyEncryption);
@@ -302,12 +403,29 @@ export class Encryption {
302
403
  });
303
404
  }
304
405
 
305
- private static getKekInfo(keyEncryption: X25519KeyEncryptionInput | X25519KeyEncryption): string {
406
+ private static getKekInfo(keyEncryption: X25519KekDerivationInput): string {
407
+ if (keyEncryption.derivationScheme === SEAL_DERIVATION_SCHEME) {
408
+ return JSON.stringify([
409
+ KEK_INFO_PREFIX,
410
+ SEAL_DERIVATION_SCHEME,
411
+ keyEncryption.protocol,
412
+ keyEncryption.rolePath,
413
+ keyEncryption.contextId,
414
+ keyEncryption.audienceKeyId,
415
+ ]);
416
+ }
417
+
306
418
  if (keyEncryption.derivationScheme === ROLE_AUDIENCE_DERIVATION_SCHEME) {
307
- return `${KEK_INFO_PREFIX}|roleAudience|${keyEncryption.protocol}|${keyEncryption.role}|${keyEncryption.epoch}|${keyEncryption.keyId}`;
419
+ return JSON.stringify([
420
+ KEK_INFO_PREFIX,
421
+ ROLE_AUDIENCE_DERIVATION_SCHEME,
422
+ keyEncryption.protocol,
423
+ keyEncryption.rolePath,
424
+ keyEncryption.keyId,
425
+ ]);
308
426
  }
309
427
 
310
- return `${KEK_INFO_PREFIX}|protocolPath|${keyEncryption.keyId}`;
428
+ return JSON.stringify([KEK_INFO_PREFIX, KeyDerivationScheme.ProtocolPath, keyEncryption.keyId]);
311
429
  }
312
430
 
313
431
  private static validateContentEncryptionParameters(
@@ -338,10 +456,22 @@ export class Encryption {
338
456
  }
339
457
  }
340
458
 
459
+ private static isX25519KeyAgreementAlgorithm(algorithm: unknown): algorithm is KeyAgreementAlgorithm.X25519HkdfSha256A256Kw {
460
+ return algorithm === KeyAgreementAlgorithm.X25519HkdfSha256A256Kw;
461
+ }
462
+
463
+ private static unsupportedKeyAgreementAlgorithmMessage(algorithm: unknown): string {
464
+ return `Unsupported key agreement algorithm: ${String(algorithm)}`;
465
+ }
466
+
341
467
  private static toA256CtrJwk(keyBytes: Uint8Array): Jwk {
342
468
  return { alg: ContentEncryptionAlgorithm.A256CTR, k: Encoder.bytesToBase64Url(keyBytes), kty: 'oct' };
343
469
  }
344
470
 
471
+ private static toA256KwJwk(keyBytes: Uint8Array): Jwk {
472
+ return { alg: 'A256KW', k: Encoder.bytesToBase64Url(keyBytes), kty: 'oct' };
473
+ }
474
+
345
475
  private static async readStream(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
346
476
  const reader = stream.getReader();
347
477
  const chunks: Uint8Array[] = [];
@@ -0,0 +1,303 @@
1
+ import type { PermissionScope, RecordsPermissionScope } from '../types/permission-types.js';
2
+ import type { ProtocolDefinition, ProtocolRuleSet } from '../types/protocols-types.js';
3
+
4
+ import { KeyDerivationScheme } from './hd-key.js';
5
+ import { ProtocolAction } from '../types/protocols-types.js';
6
+ import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
7
+ import { getRuleSetAtPath, parseCrossProtocolRef } from './protocols.js';
8
+
9
+ type GrantKeyRecordsScopeBase = RecordsPermissionScope & {
10
+ interface: typeof DwnInterfaceName.Records;
11
+ protocol: string;
12
+ };
13
+
14
+ export type GrantKeyRecordsScope = GrantKeyRecordsScopeBase & {
15
+ method: typeof DwnMethodName.Read | typeof DwnMethodName.Write;
16
+ };
17
+
18
+ export type GrantKeyReadRecordsScope = GrantKeyRecordsScopeBase & {
19
+ contextId?: undefined;
20
+ method: typeof DwnMethodName.Read;
21
+ };
22
+
23
+ export type GrantKeyWriteRecordsScope = GrantKeyRecordsScopeBase & {
24
+ contextId?: undefined;
25
+ method: typeof DwnMethodName.Write;
26
+ };
27
+
28
+ export type GrantKeyEligibleRecordsScope = GrantKeyReadRecordsScope | GrantKeyWriteRecordsScope;
29
+
30
+ export type GrantKeyProtocolPathScope = {
31
+ scheme: typeof KeyDerivationScheme.ProtocolPath;
32
+ protocol: string;
33
+ protocolPath?: string;
34
+ };
35
+
36
+ type GrantKeyDeliveryScopeBuilder = (
37
+ grantScope: GrantKeyEligibleRecordsScope,
38
+ protocolDefinition?: ProtocolDefinition,
39
+ ) => GrantKeyProtocolPathScope[];
40
+
41
+ type GrantKeyCoveragePredicate = (
42
+ input: {
43
+ grantScope: GrantKeyEligibleRecordsScope;
44
+ deliveredScope: Pick<GrantKeyProtocolPathScope, 'protocol' | 'protocolPath'>;
45
+ protocolDefinition?: ProtocolDefinition;
46
+ },
47
+ ) => boolean;
48
+
49
+ const grantKeyRecordsMethods = new Set<string>([
50
+ DwnMethodName.Read,
51
+ DwnMethodName.Write,
52
+ ]);
53
+
54
+ const grantKeyDeliveryScopeBuilders: Record<GrantKeyRecordsScope['method'], GrantKeyDeliveryScopeBuilder> = {
55
+ [DwnMethodName.Read] : getReadGrantKeyDeliveryScopes,
56
+ [DwnMethodName.Write] : getWriteGrantKeyDeliveryScopes,
57
+ };
58
+
59
+ const grantKeyCoveragePredicates: Record<GrantKeyRecordsScope['method'], GrantKeyCoveragePredicate> = {
60
+ [DwnMethodName.Read] : readGrantKeyScopeCoversDeliveredScope,
61
+ [DwnMethodName.Write] : writeGrantKeyScopeCoversDeliveredScope,
62
+ };
63
+
64
+ export function isGrantKeyRecordsScope(scope: PermissionScope): scope is GrantKeyRecordsScope {
65
+ const maybeProtocol = (scope as { protocol?: unknown }).protocol;
66
+ return [
67
+ scope.interface === DwnInterfaceName.Records,
68
+ grantKeyRecordsMethods.has(scope.method),
69
+ typeof maybeProtocol === 'string',
70
+ ].every(Boolean);
71
+ }
72
+
73
+ export function isGrantKeyEligibleRecordsScope(scope: PermissionScope): scope is GrantKeyEligibleRecordsScope {
74
+ return isGrantKeyRecordsScope(scope) &&
75
+ !('contextId' in scope && scope.contextId !== undefined);
76
+ }
77
+
78
+ export function getGrantKeyDeliveryScopes(
79
+ grantScope: GrantKeyReadRecordsScope,
80
+ protocolDefinition?: ProtocolDefinition,
81
+ ): GrantKeyProtocolPathScope[];
82
+
83
+ export function getGrantKeyDeliveryScopes(
84
+ grantScope: GrantKeyWriteRecordsScope,
85
+ protocolDefinition: ProtocolDefinition,
86
+ ): GrantKeyProtocolPathScope[];
87
+
88
+ export function getGrantKeyDeliveryScopes(
89
+ grantScope: GrantKeyEligibleRecordsScope,
90
+ protocolDefinition?: ProtocolDefinition,
91
+ ): GrantKeyProtocolPathScope[] {
92
+ return uniqueGrantKeyScopes(grantKeyDeliveryScopeBuilders[grantScope.method](grantScope, protocolDefinition));
93
+ }
94
+
95
+ export function grantKeyScopeCoversDeliveredScope(input: {
96
+ grantScope: GrantKeyEligibleRecordsScope;
97
+ deliveredScope: Pick<GrantKeyProtocolPathScope, 'protocol' | 'protocolPath'>;
98
+ protocolDefinition?: ProtocolDefinition;
99
+ }): boolean {
100
+ const { grantScope, deliveredScope, protocolDefinition } = input;
101
+ if (grantScope.protocol !== deliveredScope.protocol) {
102
+ return false;
103
+ }
104
+
105
+ return grantKeyCoveragePredicates[grantScope.method]({ grantScope, deliveredScope, protocolDefinition });
106
+ }
107
+
108
+ function getReadGrantKeyDeliveryScopes(
109
+ grantScope: GrantKeyEligibleRecordsScope,
110
+ protocolDefinition?: ProtocolDefinition,
111
+ ): GrantKeyProtocolPathScope[] {
112
+ if (grantScope.protocolPath === undefined) {
113
+ return [createProtocolGrantKeyScope(grantScope.protocol)];
114
+ }
115
+
116
+ const scopes = [
117
+ createProtocolPathGrantKeyScope(grantScope.protocol, grantScope.protocolPath),
118
+ ];
119
+
120
+ if (protocolDefinition === undefined) {
121
+ return scopes;
122
+ }
123
+
124
+ for (const rolePath of getGrantKeyReadRolePathsForScope(protocolDefinition, grantScope.protocolPath)) {
125
+ scopes.push(createProtocolPathGrantKeyScope(grantScope.protocol, rolePath));
126
+ }
127
+
128
+ return scopes;
129
+ }
130
+
131
+ function getWriteGrantKeyDeliveryScopes(
132
+ grantScope: GrantKeyEligibleRecordsScope,
133
+ protocolDefinition?: ProtocolDefinition,
134
+ ): GrantKeyProtocolPathScope[] {
135
+ if (protocolDefinition === undefined) {
136
+ throw new Error('getGrantKeyDeliveryScopes: write grants require a protocol definition.');
137
+ }
138
+
139
+ return getGrantKeyRolePathsCoveredByScope(protocolDefinition, grantScope.protocolPath)
140
+ .map((rolePath) => createProtocolPathGrantKeyScope(grantScope.protocol, rolePath));
141
+ }
142
+
143
+ function createProtocolGrantKeyScope(protocol: string): GrantKeyProtocolPathScope {
144
+ return {
145
+ scheme: KeyDerivationScheme.ProtocolPath,
146
+ protocol,
147
+ };
148
+ }
149
+
150
+ function createProtocolPathGrantKeyScope(protocol: string, protocolPath: string): GrantKeyProtocolPathScope {
151
+ return {
152
+ scheme: KeyDerivationScheme.ProtocolPath,
153
+ protocol,
154
+ protocolPath,
155
+ };
156
+ }
157
+
158
+ function readGrantKeyScopeCoversDeliveredScope(input: {
159
+ grantScope: GrantKeyEligibleRecordsScope;
160
+ deliveredScope: Pick<GrantKeyProtocolPathScope, 'protocol' | 'protocolPath'>;
161
+ protocolDefinition?: ProtocolDefinition;
162
+ }): boolean {
163
+ const { grantScope, deliveredScope, protocolDefinition } = input;
164
+ const grantProtocolPath = grantScope.protocolPath;
165
+ if (grantProtocolPath === undefined) {
166
+ return true;
167
+ }
168
+
169
+ const deliveredProtocolPath = deliveredScope.protocolPath;
170
+ if (deliveredProtocolPath === undefined) {
171
+ return false;
172
+ }
173
+
174
+ if (isBoundaryAwareSubtree(grantProtocolPath, deliveredProtocolPath)) {
175
+ return true;
176
+ }
177
+
178
+ if (protocolDefinition === undefined) {
179
+ return false;
180
+ }
181
+
182
+ return grantKeyReadScopeReferencesRolePath(protocolDefinition, grantProtocolPath, deliveredProtocolPath);
183
+ }
184
+
185
+ function writeGrantKeyScopeCoversDeliveredScope(input: {
186
+ grantScope: GrantKeyEligibleRecordsScope;
187
+ deliveredScope: Pick<GrantKeyProtocolPathScope, 'protocol' | 'protocolPath'>;
188
+ protocolDefinition?: ProtocolDefinition;
189
+ }): boolean {
190
+ const { grantScope, deliveredScope, protocolDefinition } = input;
191
+ const deliveredProtocolPath = deliveredScope.protocolPath;
192
+ if (deliveredProtocolPath === undefined) {
193
+ return false;
194
+ }
195
+
196
+ if (protocolDefinition === undefined) {
197
+ return false;
198
+ }
199
+
200
+ if (!isGrantKeyLocalRolePath(protocolDefinition, deliveredProtocolPath)) {
201
+ return false;
202
+ }
203
+
204
+ const grantProtocolPath = grantScope.protocolPath;
205
+ if (grantProtocolPath === undefined) {
206
+ return true;
207
+ }
208
+
209
+ return isBoundaryAwareSubtree(grantProtocolPath, deliveredProtocolPath);
210
+ }
211
+
212
+ function getGrantKeyReadRolePathsForScope(protocolDefinition: ProtocolDefinition, scopeProtocolPath: string): string[] {
213
+ const scopedRuleSet = getRuleSetAtPath(scopeProtocolPath, protocolDefinition.structure);
214
+ if (scopedRuleSet === undefined) {
215
+ return [];
216
+ }
217
+
218
+ return [...collectReadRolePaths(protocolDefinition, scopedRuleSet)];
219
+ }
220
+
221
+ function grantKeyReadScopeReferencesRolePath(
222
+ protocolDefinition: ProtocolDefinition,
223
+ scopeProtocolPath: string,
224
+ rolePath: string,
225
+ ): boolean {
226
+ if (!isGrantKeyLocalRolePath(protocolDefinition, rolePath)) {
227
+ return false;
228
+ }
229
+
230
+ return getGrantKeyReadRolePathsForScope(protocolDefinition, scopeProtocolPath).includes(rolePath);
231
+ }
232
+
233
+ function collectReadRolePaths(protocolDefinition: ProtocolDefinition, ruleSet: ProtocolRuleSet): Set<string> {
234
+ const rolePaths = new Set<string>();
235
+
236
+ for (const actionRule of ruleSet.$actions ?? []) {
237
+ if (!actionRule.can.includes(ProtocolAction.Read) || actionRule.role === undefined || parseCrossProtocolRef(actionRule.role) !== undefined) {
238
+ continue;
239
+ }
240
+
241
+ if (isGrantKeyLocalRolePath(protocolDefinition, actionRule.role)) {
242
+ rolePaths.add(actionRule.role);
243
+ }
244
+ }
245
+
246
+ for (const [key, value] of Object.entries(ruleSet)) {
247
+ if (key.startsWith('$')) {
248
+ continue;
249
+ }
250
+ for (const rolePath of collectReadRolePaths(protocolDefinition, value as ProtocolRuleSet)) {
251
+ rolePaths.add(rolePath);
252
+ }
253
+ }
254
+
255
+ return rolePaths;
256
+ }
257
+
258
+ function getGrantKeyRolePathsCoveredByScope(protocolDefinition: ProtocolDefinition, scopeProtocolPath?: string): string[] {
259
+ return collectRolePaths(protocolDefinition, protocolDefinition.structure as ProtocolRuleSet)
260
+ .filter((rolePath) => scopeProtocolPath === undefined || isBoundaryAwareSubtree(scopeProtocolPath, rolePath));
261
+ }
262
+
263
+ function collectRolePaths(protocolDefinition: ProtocolDefinition, ruleSet: ProtocolRuleSet, parentPath: string[] = []): string[] {
264
+ const rolePaths: string[] = [];
265
+
266
+ for (const [key, value] of Object.entries(ruleSet)) {
267
+ if (key.startsWith('$')) {
268
+ continue;
269
+ }
270
+
271
+ const path = [...parentPath, key];
272
+ const protocolPath = path.join('/');
273
+ const childRuleSet = value as ProtocolRuleSet;
274
+ if (isGrantKeyLocalRolePath(protocolDefinition, protocolPath)) {
275
+ rolePaths.push(protocolPath);
276
+ }
277
+ rolePaths.push(...collectRolePaths(protocolDefinition, childRuleSet, path));
278
+ }
279
+
280
+ return rolePaths;
281
+ }
282
+
283
+ function isGrantKeyLocalRolePath(protocolDefinition: ProtocolDefinition, protocolPath: string): boolean {
284
+ const ruleSet = getRuleSetAtPath(protocolPath, protocolDefinition.structure);
285
+ return ruleSet?.$role === true && ruleSet.$keyAgreement !== undefined;
286
+ }
287
+
288
+ function isBoundaryAwareSubtree(scopePath: string, candidatePath: string): boolean {
289
+ return `${candidatePath}/`.startsWith(`${scopePath}/`);
290
+ }
291
+
292
+ function getGrantKeyScopeCacheKey(scope: GrantKeyProtocolPathScope): string {
293
+ return JSON.stringify([scope.protocol, scope.protocolPath]);
294
+ }
295
+
296
+ function uniqueGrantKeyScopes(scopes: GrantKeyProtocolPathScope[]): GrantKeyProtocolPathScope[] {
297
+ const deliveredScopes = new Map<string, GrantKeyProtocolPathScope>();
298
+ for (const scope of scopes) {
299
+ deliveredScopes.set(getGrantKeyScopeCacheKey(scope), scope);
300
+ }
301
+
302
+ return [...deliveredScopes.values()];
303
+ }