@enbox/dwn-sdk-js 0.4.5 → 0.4.7

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 (369) 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 +4465 -3861
  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 +28 -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 +7 -10
  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 +32 -274
  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 +142 -34
  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 +116 -472
  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 +240 -67
  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/grant-key.spec.js +25 -16
  199. package/dist/esm/tests/validation/json-schemas/encryption/grant-key.spec.js.map +1 -1
  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 +4 -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 +28 -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 +10 -17
  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 +2 -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 +58 -22
  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/package.json +47 -28
  319. package/src/core/constants.ts +61 -0
  320. package/src/core/dwn-error.ts +28 -11
  321. package/src/core/encryption-control.ts +1249 -0
  322. package/src/core/message.ts +7 -0
  323. package/src/core/messages-grant-authorization.ts +60 -9
  324. package/src/core/protocol-authorization-action.ts +3 -13
  325. package/src/core/protocol-authorization-validation.ts +66 -46
  326. package/src/core/protocol-authorization.ts +7 -0
  327. package/src/core/recording-validation-state-reader.ts +4 -5
  328. package/src/core/replication-apply.ts +77 -133
  329. package/src/core/validation-state-reader.ts +6 -8
  330. package/src/dwn.ts +1 -2
  331. package/src/event-stream/event-emitter-wake-publisher.ts +10 -14
  332. package/src/handlers/messages-query.ts +6 -22
  333. package/src/handlers/messages-read.ts +4 -3
  334. package/src/handlers/messages-subscribe.ts +34 -30
  335. package/src/handlers/protocols-configure.ts +7 -4
  336. package/src/handlers/records-count.ts +111 -10
  337. package/src/handlers/records-delete.ts +15 -0
  338. package/src/handlers/records-query.ts +176 -20
  339. package/src/handlers/records-read.ts +19 -6
  340. package/src/handlers/records-subscribe.ts +158 -8
  341. package/src/handlers/records-write.ts +19 -0
  342. package/src/index.ts +48 -21
  343. package/src/interfaces/protocols-configure.ts +102 -11
  344. package/src/interfaces/records-write.ts +49 -43
  345. package/src/jose/algorithms/signing/ed25519.ts +7 -6
  346. package/src/jose/jws/general/verifier.ts +3 -3
  347. package/src/protocols/encryption.ts +50 -420
  348. package/src/store/blockstore-level.ts +33 -37
  349. package/src/store/blockstore-mock.ts +24 -38
  350. package/src/store/blockstore-utils.ts +85 -0
  351. package/src/store/blockstore.ts +8 -0
  352. package/src/store/data-store-level.ts +5 -12
  353. package/src/store/level.ts +19 -0
  354. package/src/types/cache.ts +3 -3
  355. package/src/types/encryption-types.ts +39 -2
  356. package/src/types/validation-state-reader.ts +3 -5
  357. package/src/utils/data-stream.ts +29 -1
  358. package/src/utils/encryption.ts +247 -69
  359. package/src/utils/grant-key-coverage.ts +303 -0
  360. package/src/utils/hd-key.ts +1 -2
  361. package/src/utils/jws.ts +8 -2
  362. package/src/utils/memory-cache.ts +42 -11
  363. package/src/utils/protocols.ts +32 -0
  364. package/src/utils/record-limit-occupancy.ts +34 -5
  365. package/src/utils/records.ts +36 -2
  366. package/src/utils/secp256k1.ts +12 -12
  367. package/src/utils/secp256r1.ts +12 -22
  368. package/src/utils/time.ts +145 -27
  369. package/src/types/mitt.d.ts +0 -28
@@ -1,95 +1,33 @@
1
1
  import type { CoreProtocol } from '../core/core-protocol.js';
2
2
  import type { Filter } from '../types/query-types.js';
3
- import type { GenericSignaturePayload } from '../types/message-types.js';
4
3
  import type { MessagesFilter } from '../types/messages-types.js';
5
4
  import type { PermissionGrant } from './permission-grant.js';
6
5
  import type { PermissionScope } from '../types/permission-types.js';
7
- import type { PublicKeyJwk } from '../types/jose-types.js';
6
+ import type { ProtocolDefinition } from '../types/protocols-types.js';
8
7
  import type { RecordsWriteMessage } from '../types/records-types.js';
9
8
  import type { ValidationStateReader } from '../types/validation-state-reader.js';
10
- import type { ProtocolActionRule, ProtocolDefinition, ProtocolRuleSet } from '../types/protocols-types.js';
11
9
 
12
- import { checkActor } from '../core/protocol-authorization-action.js';
13
- import { Encoder } from '../utils/encoder.js';
14
- import { Encryption } from '../utils/encryption.js';
15
10
  import { ENCRYPTION_PROTOCOL_URI } from '../core/constants.js';
16
11
  import { FilterUtility } from '../utils/filter.js';
17
- import { Jws } from '../utils/jws.js';
18
12
  import { Message } from '../core/message.js';
19
13
  import { Records } from '../utils/records.js';
20
- import { validateJsonSchema } from '../schema-validator.js';
21
14
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
22
- import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
23
- import { getRuleSetAtPath, isCrossProtocolRef, parseCrossProtocolRef } from '../utils/protocols.js';
24
- import { ProtocolAction, ProtocolActor } from '../types/protocols-types.js';
25
-
26
- type AudienceTags = {
27
- protocol: string;
28
- contextId: string;
29
- role: string;
30
- epoch: number;
31
- keyId: string;
32
- };
33
-
34
- type AudienceEpochData = AudienceTags & {
35
- publicKeyJwk: PublicKeyJwk;
36
- };
15
+ import { grantKeyScopeCoversDeliveredScope, isGrantKeyEligibleRecordsScope, isGrantKeyRecordsScope } from '../utils/grant-key-coverage.js';
37
16
 
38
17
  export class EncryptionProtocol implements CoreProtocol {
39
18
  public static readonly uri = ENCRYPTION_PROTOCOL_URI;
40
- public static readonly audienceEpochPath = 'audienceEpoch';
41
- public static readonly audienceKeyPath = 'audienceKey';
42
19
  public static readonly grantKeyPath = 'grantKey';
43
20
 
44
21
  public static readonly definition: ProtocolDefinition = {
45
22
  published : true,
46
23
  protocol : EncryptionProtocol.uri,
47
24
  types : {
48
- audienceEpoch: {
49
- dataFormats : ['application/json'],
50
- schema : 'https://identity.foundation/dwn/json-schemas/encryption/audience-epoch.json',
51
- },
52
- audienceKey: {
53
- dataFormats : ['application/json'],
54
- schema : 'https://identity.foundation/dwn/json-schemas/encryption/audience-key.json',
55
- },
56
25
  grantKey: {
57
26
  dataFormats : ['application/json'],
58
27
  schema : 'https://identity.foundation/dwn/json-schemas/encryption/grant-key.json',
59
28
  },
60
29
  },
61
30
  structure: {
62
- audienceEpoch: {
63
- $actions: [
64
- { can: ['create', 'read'], who: 'anyone' },
65
- ],
66
- $immutable : true,
67
- $tags : {
68
- $allowUndefinedTags : false,
69
- $requiredTags : ['protocol', 'contextId', 'role', 'epoch', 'keyId'],
70
- contextId : { type: 'string' },
71
- epoch : { minimum: 1, type: 'integer' },
72
- keyId : { pattern: '^[A-Za-z0-9_-]{43}$', type: 'string' },
73
- protocol : { type: 'string' },
74
- role : { type: 'string' },
75
- },
76
- },
77
- audienceKey: {
78
- $actions: [
79
- { can: ['create'], who: 'anyone' },
80
- { can: ['read'], of: 'audienceKey', who: 'recipient' },
81
- ],
82
- $immutable : true,
83
- $tags : {
84
- $allowUndefinedTags : false,
85
- $requiredTags : ['protocol', 'contextId', 'role', 'epoch', 'keyId'],
86
- contextId : { type: 'string' },
87
- epoch : { minimum: 1, type: 'integer' },
88
- keyId : { pattern: '^[A-Za-z0-9_-]{43}$', type: 'string' },
89
- protocol : { type: 'string' },
90
- role : { type: 'string' },
91
- },
92
- },
93
31
  grantKey: {
94
32
  $actions: [
95
33
  { can: ['create'], who: 'anyone' },
@@ -121,119 +59,21 @@ export class EncryptionProtocol implements CoreProtocol {
121
59
  message: RecordsWriteMessage,
122
60
  validationStateReader: ValidationStateReader,
123
61
  ): Promise<void> {
124
- switch (message.descriptor.protocolPath) {
125
- case EncryptionProtocol.audienceEpochPath:
126
- await EncryptionProtocol.preProcessAudienceEpoch(tenant, message, validationStateReader);
127
- return;
128
- case EncryptionProtocol.audienceKeyPath:
129
- await EncryptionProtocol.preProcessAudienceKey(tenant, message, validationStateReader);
130
- return;
131
- case EncryptionProtocol.grantKeyPath:
62
+ if (message.descriptor.protocolPath === EncryptionProtocol.grantKeyPath) {
132
63
  await EncryptionProtocol.preProcessGrantKey(tenant, message, validationStateReader);
133
- return;
134
- default:
135
- return;
136
64
  }
137
65
  }
138
66
 
139
- public async validateRecord(message: RecordsWriteMessage, dataBytes: Uint8Array): Promise<void> {
140
- switch (message.descriptor.protocolPath) {
141
- case EncryptionProtocol.audienceEpochPath:
142
- await EncryptionProtocol.validateAudienceEpoch(message, dataBytes);
143
- return;
144
- case EncryptionProtocol.audienceKeyPath:
145
- case EncryptionProtocol.grantKeyPath:
67
+ public async validateRecord(message: RecordsWriteMessage, _dataBytes: Uint8Array): Promise<void> {
68
+ if (message.descriptor.protocolPath === EncryptionProtocol.grantKeyPath) {
146
69
  EncryptionProtocol.verifyEncryptedDelivery(message);
147
70
  return;
148
- default:
149
- throw new DwnError(
150
- DwnErrorCode.EncryptionProtocolValidateSchemaUnexpectedRecord,
151
- `Unexpected encryption record: ${message.descriptor.protocolPath}`
152
- );
153
- }
154
- }
155
-
156
- private static async preProcessAudienceEpoch(
157
- tenant: string,
158
- message: RecordsWriteMessage,
159
- validationStateReader: ValidationStateReader,
160
- ): Promise<void> {
161
- if (message.encryption !== undefined) {
162
- throw new DwnError(
163
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted,
164
- 'audienceEpoch records must be plaintext.'
165
- );
166
71
  }
167
72
 
168
- const tags = EncryptionProtocol.getAudienceTags(message, 'audienceEpoch');
169
- const { ruleSet, protocolDefinition } = await EncryptionProtocol.verifyRoleAudienceDefinition(tenant, tags, message, validationStateReader);
170
- await EncryptionProtocol.verifyWriterCanCreateRole({
171
- tenant,
172
- message,
173
- tags,
174
- ruleSet,
175
- protocolDefinition,
176
- validationStateReader,
177
- });
178
-
179
- }
180
-
181
- private static async preProcessAudienceKey(
182
- tenant: string,
183
- message: RecordsWriteMessage,
184
- validationStateReader: ValidationStateReader,
185
- ): Promise<void> {
186
- EncryptionProtocol.verifyEncryptedDelivery(message);
187
-
188
- const recipient = message.descriptor.recipient;
189
- if (recipient === undefined) {
190
- throw new DwnError(
191
- DwnErrorCode.EncryptionProtocolValidateAudienceKeyRecipientMissing,
192
- 'audienceKey records must have a recipient.'
193
- );
194
- }
195
-
196
- const tags = EncryptionProtocol.getAudienceTags(message, 'audienceKey');
197
- const { ruleSet, protocolDefinition } = await EncryptionProtocol.verifyRoleAudienceDefinition(tenant, tags, message, validationStateReader);
198
- await EncryptionProtocol.verifyWriterCanCreateRole({
199
- tenant,
200
- message,
201
- tags,
202
- ruleSet,
203
- protocolDefinition,
204
- validationStateReader,
205
- });
206
-
207
- const matchingEpochs = await validationStateReader.queryAudienceEpochs({
208
- tenant,
209
- protocol : tags.protocol,
210
- contextId : tags.contextId,
211
- role : tags.role,
212
- epoch : tags.epoch,
213
- keyId : tags.keyId,
214
- });
215
-
216
- if (matchingEpochs.length === 0) {
217
- throw new DwnError(
218
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochMissing,
219
- 'audienceKey references a missing audienceEpoch.'
220
- );
221
- }
222
-
223
- const hasRoleRecord = await validationStateReader.hasMatchingRoleRecord({
224
- tenant,
225
- protocol : tags.protocol,
226
- protocolPath : tags.role,
227
- recipient,
228
- contextIdPrefix : tags.contextId === '' ? undefined : tags.contextId,
229
- });
230
-
231
- if (!hasRoleRecord) {
232
- throw new DwnError(
233
- DwnErrorCode.EncryptionProtocolValidateAudienceKeyRoleRecordMissing,
234
- 'audienceKey recipient is not an active holder of the referenced role.'
235
- );
236
- }
73
+ throw new DwnError(
74
+ DwnErrorCode.EncryptionProtocolValidateSchemaUnexpectedRecord,
75
+ `Unexpected encryption record: ${message.descriptor.protocolPath}`
76
+ );
237
77
  }
238
78
 
239
79
  private static async preProcessGrantKey(
@@ -252,7 +92,14 @@ export class EncryptionProtocol implements CoreProtocol {
252
92
  await EncryptionProtocol.verifyGrantActive(tenant, message, grant, validationStateReader);
253
93
  EncryptionProtocol.verifyGrantKeyAuthor(message, grant);
254
94
  EncryptionProtocol.verifyGrantKeyRecipient(message, grant);
255
- EncryptionProtocol.verifyGrantKeyScope(grant.scope, protocol, protocolPath);
95
+ await EncryptionProtocol.verifyGrantKeyScope({
96
+ tenant,
97
+ message,
98
+ grantScope: grant.scope,
99
+ protocol,
100
+ protocolPath,
101
+ validationStateReader,
102
+ });
256
103
  }
257
104
 
258
105
  private static verifyEncryptedDelivery(message: RecordsWriteMessage): void {
@@ -264,79 +111,18 @@ export class EncryptionProtocol implements CoreProtocol {
264
111
  }
265
112
  }
266
113
 
267
- private static async validateAudienceEpoch(message: RecordsWriteMessage, dataBytes: Uint8Array): Promise<void> {
268
- if (message.encryption !== undefined) {
269
- throw new DwnError(
270
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochEncrypted,
271
- 'audienceEpoch records must be plaintext.'
272
- );
273
- }
274
-
275
- const dataObject = JSON.parse(Encoder.bytesToString(dataBytes)) as AudienceEpochData;
276
- validateJsonSchema('AudienceEpoch', dataObject);
277
-
278
- const tags = EncryptionProtocol.getAudienceTags(message, 'audienceEpoch');
279
- EncryptionProtocol.verifyAudiencePayloadMatchesTags(dataObject, tags);
280
-
281
- const keyId = await Encryption.getKeyId(dataObject.publicKeyJwk);
282
- if (keyId !== dataObject.keyId) {
283
- throw new DwnError(
284
- DwnErrorCode.EncryptionProtocolValidateAudienceEpochKeyIdMismatch,
285
- 'audienceEpoch keyId must match publicKeyJwk thumbprint.'
286
- );
287
- }
288
- }
289
-
290
- private static verifyAudiencePayloadMatchesTags(payload: AudienceTags, tags: AudienceTags): void {
291
- if (payload.protocol !== tags.protocol ||
292
- payload.contextId !== tags.contextId ||
293
- payload.role !== tags.role ||
294
- payload.epoch !== tags.epoch ||
295
- payload.keyId !== tags.keyId) {
296
- throw new DwnError(
297
- DwnErrorCode.EncryptionProtocolValidateAudienceTagsMismatch,
298
- 'audienceEpoch tags must match payload fields.'
299
- );
300
- }
301
- }
302
-
303
- private static getRequiredStringTag(message: RecordsWriteMessage, tag: string, recordType = 'grantKey'): string {
114
+ private static getRequiredStringTag(message: RecordsWriteMessage, tag: string): string {
304
115
  const value = message.descriptor.tags?.[tag];
305
116
  if (typeof value !== 'string') {
306
- const errorCode = recordType === 'grantKey'
307
- ? DwnErrorCode.EncryptionProtocolValidateGrantKeyMissingRequiredTag
308
- : DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag;
309
117
  throw new DwnError(
310
- errorCode,
311
- `${recordType} records must include string tag '${tag}'.`
118
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyMissingRequiredTag,
119
+ `grantKey records must include string tag '${tag}'.`
312
120
  );
313
121
  }
314
122
 
315
123
  return value;
316
124
  }
317
125
 
318
- private static getRequiredIntegerTag(message: RecordsWriteMessage, tag: string, recordType: string): number {
319
- const value = message.descriptor.tags?.[tag];
320
- if (!Number.isInteger(value)) {
321
- throw new DwnError(
322
- DwnErrorCode.EncryptionProtocolValidateAudienceMissingRequiredTag,
323
- `${recordType} records must include integer tag '${tag}'.`
324
- );
325
- }
326
-
327
- return value as number;
328
- }
329
-
330
- private static getAudienceTags(message: RecordsWriteMessage, recordType: string): AudienceTags {
331
- return {
332
- protocol : EncryptionProtocol.getRequiredStringTag(message, 'protocol', recordType),
333
- contextId : EncryptionProtocol.getRequiredStringTag(message, 'contextId', recordType),
334
- role : EncryptionProtocol.getRequiredStringTag(message, 'role', recordType),
335
- epoch : EncryptionProtocol.getRequiredIntegerTag(message, 'epoch', recordType),
336
- keyId : EncryptionProtocol.getRequiredStringTag(message, 'keyId', recordType),
337
- };
338
- }
339
-
340
126
  private static getOptionalStringTag(message: RecordsWriteMessage, tag: string): string | undefined {
341
127
  const value = message.descriptor.tags?.[tag];
342
128
  if (value === undefined) {
@@ -405,220 +191,64 @@ export class EncryptionProtocol implements CoreProtocol {
405
191
  );
406
192
  }
407
193
 
408
- private static verifyGrantKeyScope(grantScope: PermissionScope, protocol: string, protocolPath: string | undefined): void {
409
- if (!EncryptionProtocol.isReadScope(grantScope)) {
410
- throw new DwnError(
411
- DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
412
- 'grantKey must reference a read permission grant.'
413
- );
414
- }
194
+ private static async verifyGrantKeyScope(params: {
195
+ tenant: string;
196
+ message: RecordsWriteMessage;
197
+ grantScope: PermissionScope;
198
+ protocol: string;
199
+ protocolPath: string | undefined;
200
+ validationStateReader: ValidationStateReader;
201
+ }): Promise<void> {
202
+ const { grantScope, protocol, protocolPath } = params;
415
203
 
416
- if ('protocol' in grantScope && grantScope.protocol !== undefined && grantScope.protocol !== protocol) {
204
+ if (!isGrantKeyRecordsScope(grantScope)) {
417
205
  throw new DwnError(
418
206
  DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
419
- `grantKey protocol ${protocol} is outside the permission grant scope.`
207
+ 'grantKey must reference a Records.Read or Records.Write permission grant.'
420
208
  );
421
209
  }
422
210
 
423
- if (!('protocolPath' in grantScope) || grantScope.protocolPath === undefined) {
424
- return;
425
- }
426
-
427
- if (protocolPath === undefined || !EncryptionProtocol.isBoundaryAwareSubtree(grantScope.protocolPath, protocolPath)) {
211
+ if (!isGrantKeyEligibleRecordsScope(grantScope)) {
428
212
  throw new DwnError(
429
213
  DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
430
- `grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
431
- );
432
- }
433
- }
434
-
435
- private static isReadScope(scope: PermissionScope): boolean {
436
- return (scope.interface === DwnInterfaceName.Records || scope.interface === DwnInterfaceName.Messages) &&
437
- scope.method === DwnMethodName.Read;
438
- }
439
-
440
- private static isBoundaryAwareSubtree(scopePath: string, candidatePath: string): boolean {
441
- return candidatePath === scopePath || candidatePath.startsWith(scopePath + '/');
442
- }
443
-
444
- private static async verifyRoleAudienceDefinition(
445
- tenant: string,
446
- tags: AudienceTags,
447
- message: RecordsWriteMessage,
448
- validationStateReader: ValidationStateReader,
449
- ): Promise<{ protocolDefinition: ProtocolDefinition; ruleSet: ProtocolRuleSet }> {
450
- EncryptionProtocol.verifyRoleAudienceContext(tags.role, tags.contextId);
451
-
452
- const protocolDefinition = await validationStateReader.fetchProtocolDefinition(
453
- tenant,
454
- tags.protocol,
455
- message.descriptor.messageTimestamp,
456
- );
457
- const ruleSet = getRuleSetAtPath(tags.role, protocolDefinition.structure);
458
-
459
- if (ruleSet?.$role !== true || ruleSet.$keyAgreement === undefined) {
460
- throw new DwnError(
461
- DwnErrorCode.EncryptionProtocolValidateRoleAudienceInvalid,
462
- `role audience path '${tags.role}' must be a role path with $keyAgreement.`
214
+ 'grantKey must not reference a context-scoped permission grant.'
463
215
  );
464
216
  }
465
217
 
466
- return { protocolDefinition, ruleSet };
467
- }
468
-
469
- private static verifyRoleAudienceContext(rolePath: string, contextId: string): void {
470
- const parentDepth = rolePath.split('/').length - 1;
471
- if ((parentDepth === 0 && contextId !== '') || (parentDepth > 0 && contextId === '')) {
218
+ if (grantScope.protocol !== protocol) {
472
219
  throw new DwnError(
473
- DwnErrorCode.EncryptionProtocolValidateRoleAudienceContextInvalid,
474
- 'role audience contextId is inconsistent with role path depth.'
220
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
221
+ `grantKey protocol ${protocol} is outside the permission grant scope.`
475
222
  );
476
223
  }
477
- }
478
224
 
479
- private static async verifyWriterCanCreateRole(input: {
480
- tenant: string;
481
- message: RecordsWriteMessage;
482
- tags: AudienceTags;
483
- ruleSet: ProtocolRuleSet;
484
- protocolDefinition: ProtocolDefinition;
485
- validationStateReader: ValidationStateReader;
486
- }): Promise<void> {
487
- const author = Message.getAuthor(input.message);
488
- if (author === input.tenant) {
225
+ const deliveredScope = { protocol, protocolPath };
226
+ if (grantKeyScopeCoversDeliveredScope({ grantScope, deliveredScope })) {
489
227
  return;
490
228
  }
491
229
 
492
- if (author === undefined) {
230
+ if (protocolPath === undefined) {
493
231
  throw new DwnError(
494
- DwnErrorCode.EncryptionProtocolValidateAudienceWriterUnauthorized,
495
- 'audience key records must be authored by a DID authorized to create role records.'
232
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
233
+ `grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
496
234
  );
497
235
  }
498
236
 
499
- const actionRules = input.ruleSet.$actions ?? [];
500
- const recordChain = await EncryptionProtocol.constructRoleParentChain(input.tenant, input.tags, input.validationStateReader);
501
- const signaturePayload = Jws.decodePlainObjectPayload(input.message.authorization.signature) as GenericSignaturePayload;
502
-
503
- for (const actionRule of actionRules) {
504
- if (!actionRule.can.includes(ProtocolAction.Create)) {
505
- continue;
506
- }
507
-
508
- if (actionRule.who === ProtocolActor.Anyone) {
509
- return;
510
- }
511
-
512
- if (await EncryptionProtocol.roleRuleAllowsAuthor(
513
- input.tenant,
514
- author,
515
- actionRule,
516
- input.tags,
517
- input.protocolDefinition,
518
- input.validationStateReader,
519
- signaturePayload.protocolRole,
520
- )) {
521
- return;
522
- }
523
-
524
- if (await checkActor(author, actionRule, recordChain, input.protocolDefinition)) {
525
- return;
526
- }
237
+ const protocolDefinition = await params.validationStateReader.fetchProtocolDefinition(
238
+ params.tenant,
239
+ params.protocol,
240
+ params.message.descriptor.messageTimestamp,
241
+ );
242
+ if (grantKeyScopeCoversDeliveredScope({ grantScope, deliveredScope, protocolDefinition })) {
243
+ return;
527
244
  }
528
245
 
529
246
  throw new DwnError(
530
- DwnErrorCode.EncryptionProtocolValidateAudienceWriterUnauthorized,
531
- 'audience key records must be authored by a DID authorized to create role records.'
247
+ DwnErrorCode.EncryptionProtocolValidateGrantKeyGrantScopeMismatch,
248
+ `grantKey protocolPath ${protocolPath ?? '<protocol>'} is outside the permission grant scope.`
532
249
  );
533
250
  }
534
251
 
535
- private static async constructRoleParentChain(
536
- tenant: string,
537
- tags: AudienceTags,
538
- validationStateReader: ValidationStateReader,
539
- ): Promise<RecordsWriteMessage[]> {
540
- if (tags.contextId === '') {
541
- return [];
542
- }
543
-
544
- const parentRecordId = tags.contextId.split('/').pop();
545
- if (parentRecordId === undefined || parentRecordId === '') {
546
- return [];
547
- }
548
-
549
- return validationStateReader.constructRecordChain(tenant, parentRecordId);
550
- }
551
-
552
- private static async roleRuleAllowsAuthor(
553
- tenant: string,
554
- author: string,
555
- actionRule: ProtocolActionRule,
556
- tags: AudienceTags,
557
- protocolDefinition: ProtocolDefinition,
558
- validationStateReader: ValidationStateReader,
559
- invokedRole: string | undefined,
560
- ): Promise<boolean> {
561
- if (actionRule.role === undefined || invokedRole !== actionRule.role) {
562
- return false;
563
- }
564
-
565
- const roleRef = actionRule.role;
566
- return EncryptionProtocol.hasInvokedRole(tenant, author, roleRef, tags, protocolDefinition, validationStateReader);
567
- }
568
-
569
- private static async hasInvokedRole(
570
- tenant: string,
571
- author: string,
572
- roleRef: string,
573
- tags: AudienceTags,
574
- protocolDefinition: ProtocolDefinition,
575
- validationStateReader: ValidationStateReader,
576
- ): Promise<boolean> {
577
- const resolved = EncryptionProtocol.resolveRoleReference(roleRef, tags.protocol, protocolDefinition);
578
- if (resolved === undefined) {
579
- return false;
580
- }
581
-
582
- const ancestorDepth = resolved.protocolPath.split('/').length - 1;
583
- let contextIdPrefix: string | undefined;
584
- if (ancestorDepth > 0) {
585
- contextIdPrefix = tags.contextId.split('/').slice(0, ancestorDepth).join('/');
586
- if (contextIdPrefix === '') {
587
- return false;
588
- }
589
- }
590
-
591
- return validationStateReader.hasMatchingRoleRecord({
592
- tenant,
593
- protocol : resolved.protocol,
594
- protocolPath : resolved.protocolPath,
595
- recipient : author,
596
- contextIdPrefix,
597
- });
598
- }
599
-
600
- private static resolveRoleReference(
601
- roleRef: string,
602
- currentProtocol: string,
603
- protocolDefinition: ProtocolDefinition,
604
- ): { protocol: string; protocolPath: string } | undefined {
605
- if (!isCrossProtocolRef(roleRef)) {
606
- return { protocol: currentProtocol, protocolPath: roleRef };
607
- }
608
-
609
- const parsed = parseCrossProtocolRef(roleRef);
610
- if (parsed === undefined) {
611
- return undefined;
612
- }
613
-
614
- const protocol = protocolDefinition.uses?.[parsed.alias];
615
- if (protocol === undefined) {
616
- return undefined;
617
- }
618
-
619
- return { protocol, protocolPath: parsed.protocolPath };
620
- }
621
-
622
252
  public mapErrorToStatusCode(errorCode: string): number | undefined {
623
253
  if (errorCode.startsWith('EncryptionProtocolValidate')) {
624
254
  return 400;
@@ -1,7 +1,15 @@
1
- import { CID } from 'multiformats';
2
- import type { AbortOptions, AwaitIterable } from 'interface-store';
3
- import type { Blockstore, Pair } from 'interface-blockstore';
1
+ import type { Blockstore, InputPair, Pair } from 'interface-blockstore';
2
+ import type { BlockstoreAbortOptions, BlockstoreInput, BlockstoreSource } from './blockstore-utils.js';
4
3
 
4
+ import { CID } from 'multiformats';
5
+ import { NotFoundError } from 'interface-store';
6
+ import {
7
+ collectBlockstoreBytes,
8
+ deleteManyBlockstoreItems,
9
+ getManyBlockstoreItems,
10
+ putManyBlockstoreItems,
11
+ yieldBlockstoreBytes,
12
+ } from './blockstore-utils.js';
5
13
  import { createLevelDatabase, LevelWrapper } from './level-wrapper.js';
6
14
 
7
15
  // `level` works in Node.js 12+ and Electron 5+ on Linux, Mac OS, Windows and
@@ -40,63 +48,51 @@ export class BlockstoreLevel implements Blockstore {
40
48
  return new BlockstoreLevel({ ...this.config, location: '' }, db);
41
49
  }
42
50
 
43
- async put(key: CID | string, val: Uint8Array, options?: AbortOptions): Promise<CID> {
44
- await this.db.put(String(key), val, options);
51
+ async put(key: CID | string, val: BlockstoreInput, options?: BlockstoreAbortOptions): Promise<CID> {
52
+ const bytes = await collectBlockstoreBytes(val);
53
+ await this.db.put(String(key), bytes, options);
45
54
  return CID.parse(key.toString());
46
55
  }
47
56
 
48
- async get(key: CID | string, options?: AbortOptions): Promise<Uint8Array> {
57
+ async * get(key: CID | string, options?: BlockstoreAbortOptions): AsyncGenerator<Uint8Array> {
49
58
  const result = await this.db.get(String(key), options);
50
- return result!;
59
+ if (result === undefined) {
60
+ throw new NotFoundError();
61
+ }
62
+
63
+ yield result;
51
64
  }
52
65
 
53
- async has(key: CID | string, options?: AbortOptions): Promise<boolean> {
66
+ async has(key: CID | string, options?: BlockstoreAbortOptions): Promise<boolean> {
54
67
  return this.db.has(String(key), options);
55
68
  }
56
69
 
57
- async delete(key: CID | string, options?: AbortOptions): Promise<void> {
70
+ async delete(key: CID | string, options?: BlockstoreAbortOptions): Promise<void> {
58
71
  return this.db.delete(String(key), options);
59
72
  }
60
73
 
61
- async isEmpty(options?: AbortOptions): Promise<boolean> {
74
+ async isEmpty(options?: BlockstoreAbortOptions): Promise<boolean> {
62
75
  return this.db.isEmpty(options);
63
76
  }
64
77
 
65
- async * putMany(source: AwaitIterable<Pair>, options?: AbortOptions): AsyncIterable<CID> {
66
- for await (const entry of source) {
67
- await this.put(entry.cid, entry.block, options);
68
-
69
- yield entry.cid;
70
- }
78
+ async * putMany(source: BlockstoreSource<InputPair>, options?: BlockstoreAbortOptions): AsyncGenerator<CID> {
79
+ yield * putManyBlockstoreItems(this, source, options);
71
80
  }
72
81
 
73
- async * getMany(source: AwaitIterable<CID>, options?: AbortOptions): AsyncIterable<Pair> {
74
- for await (const key of source) {
75
- yield {
76
- cid : key,
77
- block : await this.get(key, options)
78
- };
79
- }
82
+ async * getMany(source: BlockstoreSource<CID>, options?: BlockstoreAbortOptions): AsyncGenerator<Pair> {
83
+ yield * getManyBlockstoreItems(this, source, options);
80
84
  }
81
85
 
82
- async * getAll(options?: AbortOptions): AsyncIterable<Pair> {
83
- // @ts-expect-error keyEncoding is 'buffer' but types for db.iterator always return the key type as 'string'
84
- const li: AsyncGenerator<[Uint8Array, Uint8Array]> = this.db.iterator({
85
- keys : true,
86
- keyEncoding : 'buffer'
87
- }, options);
86
+ async * getAll(options?: BlockstoreAbortOptions): AsyncGenerator<Pair> {
87
+ const li: AsyncGenerator<[string, Uint8Array]> = this.db.iterator({ keys: true }, options);
88
88
 
89
89
  for await (const [key, value] of li) {
90
- yield { cid: CID.decode(key), block: value };
90
+ yield { cid: CID.parse(key), bytes: yieldBlockstoreBytes(value) };
91
91
  }
92
92
  }
93
93
 
94
- async * deleteMany(source: AwaitIterable<CID>, options?: AbortOptions): AsyncIterable<CID> {
95
- for await (const key of source) {
96
- await this.delete(key, options);
97
-
98
- yield key;
99
- }
94
+ async * deleteMany(source: BlockstoreSource<CID>, options?: BlockstoreAbortOptions): AsyncGenerator<CID> {
95
+ yield * deleteManyBlockstoreItems(this, source, options);
100
96
  }
101
97
 
102
98
  /**
@@ -110,4 +106,4 @@ export class BlockstoreLevel implements Blockstore {
110
106
  export type BlockstoreLevelConfig = {
111
107
  location: string,
112
108
  createLevelDatabase?: typeof createLevelDatabase,
113
- };
109
+ };