@enbox/dwn-sdk-js 0.0.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/dist/browser.mjs +8 -8
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/generated/precompiled-validators.js +817 -911
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/constants.js +11 -0
  6. package/dist/esm/src/core/constants.js.map +1 -0
  7. package/dist/esm/src/core/core-protocol.js +44 -0
  8. package/dist/esm/src/core/core-protocol.js.map +1 -0
  9. package/dist/esm/src/core/dwn-error.js +12 -12
  10. package/dist/esm/src/core/dwn-error.js.map +1 -1
  11. package/dist/esm/src/core/grant-authorization.js +16 -3
  12. package/dist/esm/src/core/grant-authorization.js.map +1 -1
  13. package/dist/esm/src/core/protocol-authorization-action.js +5 -0
  14. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  15. package/dist/esm/src/core/protocol-authorization-validation.js +91 -0
  16. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  17. package/dist/esm/src/core/protocol-authorization.js +53 -30
  18. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  19. package/dist/esm/src/core/records-grant-authorization.js +6 -8
  20. package/dist/esm/src/core/records-grant-authorization.js.map +1 -1
  21. package/dist/esm/src/core/resumable-task-manager.js +2 -0
  22. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  23. package/dist/esm/src/dwn.js +42 -18
  24. package/dist/esm/src/dwn.js.map +1 -1
  25. package/dist/esm/src/event-stream/event-emitter-event-log.js +204 -0
  26. package/dist/esm/src/event-stream/event-emitter-event-log.js.map +1 -0
  27. package/dist/esm/src/handlers/messages-read.js +7 -11
  28. package/dist/esm/src/handlers/messages-read.js.map +1 -1
  29. package/dist/esm/src/handlers/messages-subscribe.js +22 -24
  30. package/dist/esm/src/handlers/messages-subscribe.js.map +1 -1
  31. package/dist/esm/src/handlers/messages-sync.js +11 -15
  32. package/dist/esm/src/handlers/messages-sync.js.map +1 -1
  33. package/dist/esm/src/handlers/protocols-configure.js +37 -27
  34. package/dist/esm/src/handlers/protocols-configure.js.map +1 -1
  35. package/dist/esm/src/handlers/protocols-query.js +7 -11
  36. package/dist/esm/src/handlers/protocols-query.js.map +1 -1
  37. package/dist/esm/src/handlers/records-count.js +10 -12
  38. package/dist/esm/src/handlers/records-count.js.map +1 -1
  39. package/dist/esm/src/handlers/records-delete.js +10 -18
  40. package/dist/esm/src/handlers/records-delete.js.map +1 -1
  41. package/dist/esm/src/handlers/records-query.js +11 -15
  42. package/dist/esm/src/handlers/records-query.js.map +1 -1
  43. package/dist/esm/src/handlers/records-read.js +31 -26
  44. package/dist/esm/src/handlers/records-read.js.map +1 -1
  45. package/dist/esm/src/handlers/records-subscribe.js +39 -26
  46. package/dist/esm/src/handlers/records-subscribe.js.map +1 -1
  47. package/dist/esm/src/handlers/records-write.js +128 -105
  48. package/dist/esm/src/handlers/records-write.js.map +1 -1
  49. package/dist/esm/src/index.js +5 -2
  50. package/dist/esm/src/index.js.map +1 -1
  51. package/dist/esm/src/interfaces/messages-subscribe.js +1 -0
  52. package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -1
  53. package/dist/esm/src/interfaces/protocols-configure.js +33 -3
  54. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  55. package/dist/esm/src/interfaces/records-count.js +1 -1
  56. package/dist/esm/src/interfaces/records-count.js.map +1 -1
  57. package/dist/esm/src/interfaces/records-delete.js +1 -1
  58. package/dist/esm/src/interfaces/records-delete.js.map +1 -1
  59. package/dist/esm/src/interfaces/records-query.js +1 -1
  60. package/dist/esm/src/interfaces/records-query.js.map +1 -1
  61. package/dist/esm/src/interfaces/records-read.js +1 -1
  62. package/dist/esm/src/interfaces/records-read.js.map +1 -1
  63. package/dist/esm/src/interfaces/records-subscribe.js +2 -1
  64. package/dist/esm/src/interfaces/records-subscribe.js.map +1 -1
  65. package/dist/esm/src/interfaces/records-write-signing.js +1 -12
  66. package/dist/esm/src/interfaces/records-write-signing.js.map +1 -1
  67. package/dist/esm/src/interfaces/records-write.js +25 -41
  68. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  69. package/dist/esm/src/protocols/permission-grant.js +1 -1
  70. package/dist/esm/src/protocols/permission-grant.js.map +1 -1
  71. package/dist/esm/src/protocols/permission-request.js +1 -1
  72. package/dist/esm/src/protocols/permission-request.js.map +1 -1
  73. package/dist/esm/src/protocols/permissions.js +113 -5
  74. package/dist/esm/src/protocols/permissions.js.map +1 -1
  75. package/dist/esm/src/state-index/state-index-level.js +5 -7
  76. package/dist/esm/src/state-index/state-index-level.js.map +1 -1
  77. package/dist/esm/src/store/data-store-level.js +110 -33
  78. package/dist/esm/src/store/data-store-level.js.map +1 -1
  79. package/dist/esm/src/store/index-level.js +42 -32
  80. package/dist/esm/src/store/index-level.js.map +1 -1
  81. package/dist/esm/src/store/storage-controller.js +70 -6
  82. package/dist/esm/src/store/storage-controller.js.map +1 -1
  83. package/dist/esm/src/types/permission-types.js.map +1 -1
  84. package/dist/esm/src/types/protocols-types.js +11 -0
  85. package/dist/esm/src/types/protocols-types.js.map +1 -1
  86. package/dist/esm/src/types/records-types.js.map +1 -1
  87. package/dist/esm/src/utils/hd-key.js +0 -8
  88. package/dist/esm/src/utils/hd-key.js.map +1 -1
  89. package/dist/esm/src/utils/messages.js +16 -34
  90. package/dist/esm/src/utils/messages.js.map +1 -1
  91. package/dist/esm/src/utils/records.js +5 -43
  92. package/dist/esm/src/utils/records.js.map +1 -1
  93. package/dist/esm/tests/core/protocol-authorization.spec.js +2 -1
  94. package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -1
  95. package/dist/esm/tests/dwn.spec.js +32 -43
  96. package/dist/esm/tests/dwn.spec.js.map +1 -1
  97. package/dist/esm/tests/event-emitter-event-log.spec.js +305 -0
  98. package/dist/esm/tests/event-emitter-event-log.spec.js.map +1 -0
  99. package/dist/esm/tests/features/author-delegated-grant.spec.js +14 -7
  100. package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -1
  101. package/dist/esm/tests/features/owner-delegated-grant.spec.js +9 -5
  102. package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -1
  103. package/dist/esm/tests/features/owner-signature.spec.js +14 -7
  104. package/dist/esm/tests/features/owner-signature.spec.js.map +1 -1
  105. package/dist/esm/tests/features/permissions.spec.js +12 -12
  106. package/dist/esm/tests/features/permissions.spec.js.map +1 -1
  107. package/dist/esm/tests/features/protocol-composition.spec.js +636 -5
  108. package/dist/esm/tests/features/protocol-composition.spec.js.map +1 -1
  109. package/dist/esm/tests/features/protocol-create-action.spec.js +4 -4
  110. package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -1
  111. package/dist/esm/tests/features/protocol-delete-action.spec.js +7 -7
  112. package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -1
  113. package/dist/esm/tests/features/protocol-update-action.spec.js +4 -4
  114. package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -1
  115. package/dist/esm/tests/features/records-delivery.spec.js +236 -0
  116. package/dist/esm/tests/features/records-delivery.spec.js.map +1 -0
  117. package/dist/esm/tests/features/records-immutable.spec.js +315 -0
  118. package/dist/esm/tests/features/records-immutable.spec.js.map +1 -0
  119. package/dist/esm/tests/features/records-prune.spec.js +4 -4
  120. package/dist/esm/tests/features/records-prune.spec.js.map +1 -1
  121. package/dist/esm/tests/features/records-record-limit.spec.js +542 -0
  122. package/dist/esm/tests/features/records-record-limit.spec.js.map +1 -0
  123. package/dist/esm/tests/features/records-squash.spec.js +1055 -0
  124. package/dist/esm/tests/features/records-squash.spec.js.map +1 -0
  125. package/dist/esm/tests/features/records-tags.spec.js +16 -4
  126. package/dist/esm/tests/features/records-tags.spec.js.map +1 -1
  127. package/dist/esm/tests/features/resumable-tasks.spec.js +7 -8
  128. package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -1
  129. package/dist/esm/tests/handlers/messages-read.spec.js +11 -5
  130. package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -1
  131. package/dist/esm/tests/handlers/messages-subscribe.spec.js +169 -22
  132. package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -1
  133. package/dist/esm/tests/handlers/messages-sync.spec.js +103 -21
  134. package/dist/esm/tests/handlers/messages-sync.spec.js.map +1 -1
  135. package/dist/esm/tests/handlers/protocols-configure.spec.js +5 -5
  136. package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -1
  137. package/dist/esm/tests/handlers/protocols-query.spec.js +5 -5
  138. package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -1
  139. package/dist/esm/tests/handlers/records-count.spec.js +9 -4
  140. package/dist/esm/tests/handlers/records-count.spec.js.map +1 -1
  141. package/dist/esm/tests/handlers/records-delete.spec.js +24 -25
  142. package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -1
  143. package/dist/esm/tests/handlers/records-query.spec.js +68 -9
  144. package/dist/esm/tests/handlers/records-query.spec.js.map +1 -1
  145. package/dist/esm/tests/handlers/records-read.spec.js +24 -138
  146. package/dist/esm/tests/handlers/records-read.spec.js.map +1 -1
  147. package/dist/esm/tests/handlers/records-subscribe.spec.js +175 -35
  148. package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -1
  149. package/dist/esm/tests/handlers/records-write.spec.js +176 -72
  150. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  151. package/dist/esm/tests/interfaces/records-write.spec.js +52 -68
  152. package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -1
  153. package/dist/esm/tests/protocols/permission-grant.spec.js +6 -6
  154. package/dist/esm/tests/protocols/permission-grant.spec.js.map +1 -1
  155. package/dist/esm/tests/protocols/permission-request.spec.js +4 -4
  156. package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -1
  157. package/dist/esm/tests/protocols/permissions.spec.js +4 -4
  158. package/dist/esm/tests/protocols/permissions.spec.js.map +1 -1
  159. package/dist/esm/tests/scenarios/aggregator.spec.js +4 -4
  160. package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -1
  161. package/dist/esm/tests/scenarios/deleted-record.spec.js +350 -5
  162. package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -1
  163. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +4 -4
  164. package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -1
  165. package/dist/esm/tests/scenarios/nested-roles.spec.js +4 -4
  166. package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -1
  167. package/dist/esm/tests/scenarios/subscriptions.spec.js +93 -40
  168. package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -1
  169. package/dist/esm/tests/store/data-store-level.spec.js +102 -41
  170. package/dist/esm/tests/store/data-store-level.spec.js.map +1 -1
  171. package/dist/esm/tests/test-event-stream.js +12 -13
  172. package/dist/esm/tests/test-event-stream.js.map +1 -1
  173. package/dist/esm/tests/test-suite.js +10 -4
  174. package/dist/esm/tests/test-suite.js.map +1 -1
  175. package/dist/esm/tests/utils/messages.spec.js +12 -5
  176. package/dist/esm/tests/utils/messages.spec.js.map +1 -1
  177. package/dist/esm/tests/utils/records.spec.js +8 -12
  178. package/dist/esm/tests/utils/records.spec.js.map +1 -1
  179. package/dist/esm/tests/utils/test-data-generator.js +36 -2
  180. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  181. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +37 -8
  182. package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -1
  183. package/dist/types/generated/precompiled-validators.d.ts +49 -40
  184. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  185. package/dist/types/src/core/constants.d.ts +11 -0
  186. package/dist/types/src/core/constants.d.ts.map +1 -0
  187. package/dist/types/src/core/core-protocol.d.ts +89 -0
  188. package/dist/types/src/core/core-protocol.d.ts.map +1 -0
  189. package/dist/types/src/core/dwn-error.d.ts +12 -12
  190. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  191. package/dist/types/src/core/grant-authorization.d.ts +6 -2
  192. package/dist/types/src/core/grant-authorization.d.ts.map +1 -1
  193. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  194. package/dist/types/src/core/protocol-authorization-validation.d.ts +30 -0
  195. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  196. package/dist/types/src/core/protocol-authorization.d.ts +19 -11
  197. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  198. package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -1
  199. package/dist/types/src/core/resumable-task-manager.d.ts +2 -1
  200. package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
  201. package/dist/types/src/dwn.d.ts +19 -7
  202. package/dist/types/src/dwn.d.ts.map +1 -1
  203. package/dist/types/src/event-stream/event-emitter-event-log.d.ts +50 -0
  204. package/dist/types/src/event-stream/event-emitter-event-log.d.ts.map +1 -0
  205. package/dist/types/src/handlers/messages-read.d.ts +3 -8
  206. package/dist/types/src/handlers/messages-read.d.ts.map +1 -1
  207. package/dist/types/src/handlers/messages-subscribe.d.ts +6 -10
  208. package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -1
  209. package/dist/types/src/handlers/messages-sync.d.ts +3 -8
  210. package/dist/types/src/handlers/messages-sync.d.ts.map +1 -1
  211. package/dist/types/src/handlers/protocols-configure.d.ts +3 -10
  212. package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -1
  213. package/dist/types/src/handlers/protocols-query.d.ts +3 -8
  214. package/dist/types/src/handlers/protocols-query.d.ts.map +1 -1
  215. package/dist/types/src/handlers/records-count.d.ts +3 -6
  216. package/dist/types/src/handlers/records-count.d.ts.map +1 -1
  217. package/dist/types/src/handlers/records-delete.d.ts +3 -8
  218. package/dist/types/src/handlers/records-delete.d.ts.map +1 -1
  219. package/dist/types/src/handlers/records-query.d.ts +3 -8
  220. package/dist/types/src/handlers/records-query.d.ts.map +1 -1
  221. package/dist/types/src/handlers/records-read.d.ts +3 -8
  222. package/dist/types/src/handlers/records-read.d.ts.map +1 -1
  223. package/dist/types/src/handlers/records-subscribe.d.ts +8 -10
  224. package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -1
  225. package/dist/types/src/handlers/records-write.d.ts +12 -25
  226. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  227. package/dist/types/src/index.d.ts +8 -4
  228. package/dist/types/src/index.d.ts.map +1 -1
  229. package/dist/types/src/interfaces/messages-subscribe.d.ts +5 -0
  230. package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -1
  231. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  232. package/dist/types/src/interfaces/records-subscribe.d.ts +5 -0
  233. package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -1
  234. package/dist/types/src/interfaces/records-write-signing.d.ts +3 -4
  235. package/dist/types/src/interfaces/records-write-signing.d.ts.map +1 -1
  236. package/dist/types/src/interfaces/records-write.d.ts +11 -11
  237. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  238. package/dist/types/src/protocols/permission-grant.d.ts +1 -1
  239. package/dist/types/src/protocols/permission-grant.d.ts.map +1 -1
  240. package/dist/types/src/protocols/permission-request.d.ts +1 -1
  241. package/dist/types/src/protocols/permission-request.d.ts.map +1 -1
  242. package/dist/types/src/protocols/permissions.d.ts +40 -3
  243. package/dist/types/src/protocols/permissions.d.ts.map +1 -1
  244. package/dist/types/src/state-index/state-index-level.d.ts.map +1 -1
  245. package/dist/types/src/store/data-store-level.d.ts +20 -4
  246. package/dist/types/src/store/data-store-level.d.ts.map +1 -1
  247. package/dist/types/src/store/index-level.d.ts +4 -0
  248. package/dist/types/src/store/index-level.d.ts.map +1 -1
  249. package/dist/types/src/store/storage-controller.d.ts +20 -6
  250. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  251. package/dist/types/src/types/message-types.d.ts +3 -3
  252. package/dist/types/src/types/message-types.d.ts.map +1 -1
  253. package/dist/types/src/types/messages-types.d.ts +12 -3
  254. package/dist/types/src/types/messages-types.d.ts.map +1 -1
  255. package/dist/types/src/types/method-handler.d.ts +24 -3
  256. package/dist/types/src/types/method-handler.d.ts.map +1 -1
  257. package/dist/types/src/types/permission-types.d.ts +7 -0
  258. package/dist/types/src/types/permission-types.d.ts.map +1 -1
  259. package/dist/types/src/types/protocols-types.d.ts +69 -2
  260. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  261. package/dist/types/src/types/records-types.d.ts +23 -6
  262. package/dist/types/src/types/records-types.d.ts.map +1 -1
  263. package/dist/types/src/types/subscriptions.d.ts +151 -13
  264. package/dist/types/src/types/subscriptions.d.ts.map +1 -1
  265. package/dist/types/src/utils/hd-key.d.ts +1 -9
  266. package/dist/types/src/utils/hd-key.d.ts.map +1 -1
  267. package/dist/types/src/utils/messages.d.ts +7 -5
  268. package/dist/types/src/utils/messages.d.ts.map +1 -1
  269. package/dist/types/src/utils/records.d.ts +1 -11
  270. package/dist/types/src/utils/records.d.ts.map +1 -1
  271. package/dist/types/tests/dwn.spec.d.ts.map +1 -1
  272. package/dist/types/tests/event-emitter-event-log.spec.d.ts +2 -0
  273. package/dist/types/tests/event-emitter-event-log.spec.d.ts.map +1 -0
  274. package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -1
  275. package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -1
  276. package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -1
  277. package/dist/types/tests/features/protocol-composition.spec.d.ts.map +1 -1
  278. package/dist/types/tests/features/records-delivery.spec.d.ts +2 -0
  279. package/dist/types/tests/features/records-delivery.spec.d.ts.map +1 -0
  280. package/dist/types/tests/features/records-immutable.spec.d.ts +2 -0
  281. package/dist/types/tests/features/records-immutable.spec.d.ts.map +1 -0
  282. package/dist/types/tests/features/records-record-limit.spec.d.ts +2 -0
  283. package/dist/types/tests/features/records-record-limit.spec.d.ts.map +1 -0
  284. package/dist/types/tests/features/records-squash.spec.d.ts +2 -0
  285. package/dist/types/tests/features/records-squash.spec.d.ts.map +1 -0
  286. package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -1
  287. package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -1
  288. package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -1
  289. package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -1
  290. package/dist/types/tests/handlers/messages-sync.spec.d.ts.map +1 -1
  291. package/dist/types/tests/handlers/records-count.spec.d.ts.map +1 -1
  292. package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -1
  293. package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -1
  294. package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -1
  295. package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -1
  296. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  297. package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -1
  298. package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -1
  299. package/dist/types/tests/test-event-stream.d.ts +11 -12
  300. package/dist/types/tests/test-event-stream.d.ts.map +1 -1
  301. package/dist/types/tests/test-suite.d.ts +2 -2
  302. package/dist/types/tests/test-suite.d.ts.map +1 -1
  303. package/dist/types/tests/utils/test-data-generator.d.ts +19 -0
  304. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  305. package/package.json +5 -4
  306. package/src/core/constants.ts +11 -0
  307. package/src/core/core-protocol.ts +129 -0
  308. package/src/core/dwn-error.ts +18 -12
  309. package/src/core/grant-authorization.ts +20 -3
  310. package/src/core/protocol-authorization-action.ts +5 -0
  311. package/src/core/protocol-authorization-validation.ts +133 -0
  312. package/src/core/protocol-authorization.ts +71 -23
  313. package/src/core/records-grant-authorization.ts +6 -8
  314. package/src/core/resumable-task-manager.ts +3 -1
  315. package/src/dwn.ts +58 -73
  316. package/src/event-stream/event-emitter-event-log.ts +283 -0
  317. package/src/handlers/messages-read.ts +8 -9
  318. package/src/handlers/messages-subscribe.ts +24 -28
  319. package/src/handlers/messages-sync.ts +10 -16
  320. package/src/handlers/protocols-configure.ts +47 -32
  321. package/src/handlers/protocols-query.ts +6 -9
  322. package/src/handlers/records-count.ts +11 -10
  323. package/src/handlers/records-delete.ts +12 -21
  324. package/src/handlers/records-query.ts +12 -12
  325. package/src/handlers/records-read.ts +34 -22
  326. package/src/handlers/records-subscribe.ts +47 -26
  327. package/src/handlers/records-write.ts +152 -119
  328. package/src/index.ts +9 -5
  329. package/src/interfaces/messages-subscribe.ts +7 -1
  330. package/src/interfaces/protocols-configure.ts +51 -3
  331. package/src/interfaces/records-count.ts +1 -1
  332. package/src/interfaces/records-delete.ts +1 -1
  333. package/src/interfaces/records-query.ts +1 -1
  334. package/src/interfaces/records-read.ts +1 -1
  335. package/src/interfaces/records-subscribe.ts +8 -1
  336. package/src/interfaces/records-write-signing.ts +2 -22
  337. package/src/interfaces/records-write.ts +35 -48
  338. package/src/protocols/permission-grant.ts +1 -1
  339. package/src/protocols/permission-request.ts +1 -1
  340. package/src/protocols/permissions.ts +148 -6
  341. package/src/state-index/state-index-level.ts +5 -7
  342. package/src/store/data-store-level.ts +124 -34
  343. package/src/store/index-level.ts +44 -35
  344. package/src/store/storage-controller.ts +89 -12
  345. package/src/types/message-types.ts +3 -3
  346. package/src/types/messages-types.ts +12 -3
  347. package/src/types/method-handler.ts +26 -4
  348. package/src/types/mitt.d.ts +28 -0
  349. package/src/types/permission-types.ts +7 -0
  350. package/src/types/protocols-types.ts +78 -1
  351. package/src/types/records-types.ts +24 -6
  352. package/src/types/subscriptions.ts +178 -14
  353. package/src/utils/hd-key.ts +0 -9
  354. package/src/utils/messages.ts +17 -37
  355. package/src/utils/records.ts +7 -58
  356. package/dist/esm/src/event-stream/event-emitter-stream.js +0 -46
  357. package/dist/esm/src/event-stream/event-emitter-stream.js.map +0 -1
  358. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js +0 -68
  359. package/dist/esm/tests/event-stream/event-emitter-stream.spec.js.map +0 -1
  360. package/dist/esm/tests/event-stream/event-stream.spec.js +0 -114
  361. package/dist/esm/tests/event-stream/event-stream.spec.js.map +0 -1
  362. package/dist/types/src/event-stream/event-emitter-stream.d.ts +0 -23
  363. package/dist/types/src/event-stream/event-emitter-stream.d.ts.map +0 -1
  364. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts +0 -2
  365. package/dist/types/tests/event-stream/event-emitter-stream.spec.d.ts.map +0 -1
  366. package/dist/types/tests/event-stream/event-stream.spec.d.ts +0 -2
  367. package/dist/types/tests/event-stream/event-stream.spec.d.ts.map +0 -1
  368. package/src/event-stream/event-emitter-stream.ts +0 -69
@@ -12,6 +12,7 @@ import recipientCanProtocol from '../vectors/protocol-definitions/recipient-can.
12
12
  import sinon from 'sinon';
13
13
  import socialMediaProtocolDefinition from '../vectors/protocol-definitions/social-media.json' with { type: 'json' };
14
14
  import threadRoleProtocolDefinition from '../vectors/protocol-definitions/thread-role.json' with { type: 'json' };
15
+ import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
15
16
  import { ArrayUtility } from '../../src/utils/array.js';
16
17
  import { base64url } from 'multiformats/bases/base64';
17
18
  import { Cid } from '../../src/utils/cid.js';
@@ -22,18 +23,18 @@ import { GeneralJwsBuilder } from '../../src/jose/jws/general/builder.js';
22
23
  import { Jws } from '../../src/utils/jws.js';
23
24
  import { Message } from '../../src/core/message.js';
24
25
  import { PermissionConditionPublication } from '../../src/types/permission-types.js';
26
+ import { ProtocolAuthorization } from '../../src/core/protocol-authorization.js';
25
27
  import { RecordsRead } from '../../src/interfaces/records-read.js';
26
28
  import { RecordsWrite } from '../../src/interfaces/records-write.js';
27
29
  import { RecordsWriteHandler } from '../../src/handlers/records-write.js';
28
- import { TestDataGenerator } from '../utils/test-data-generator.js';
29
- import { TestEventStream } from '../test-event-stream.js';
30
+ import { TestEventLog } from '../test-event-stream.js';
30
31
  import { TestStores } from '../test-stores.js';
31
32
  import { TestStubGenerator } from '../utils/test-stub-generator.js';
32
33
  import { Time } from '../../src/utils/time.js';
33
34
  import { X25519 } from '@enbox/crypto';
34
- import { afterAll, beforeAll, beforeEach, describe, expect, it } from 'bun:test';
35
35
  import { ContentEncryptionAlgorithm, Encryption } from '../../src/utils/encryption.js';
36
- import { DataStoreLevel, DwnConstant, DwnInterfaceName, DwnMethodName, KeyDerivationScheme, MessageStoreLevel, PermissionsProtocol, RecordsDelete, RecordsQuery } from '../../src/index.js';
36
+ import { CoreProtocolRegistry, DataStoreLevel, DwnConstant, DwnInterfaceName, DwnMethodName, KeyDerivationScheme, MessageStoreLevel, PermissionsProtocol, RecordsDelete, RecordsQuery } from '../../src/index.js';
37
+ import { defaultTestProtocolDefinition, TestDataGenerator } from '../utils/test-data-generator.js';
37
38
  import { DidKey, UniversalResolver } from '@enbox/dids';
38
39
  import { DwnError, DwnErrorCode } from '../../src/core/dwn-error.js';
39
40
  export function testRecordsWriteHandler() {
@@ -43,7 +44,7 @@ export function testRecordsWriteHandler() {
43
44
  let dataStore;
44
45
  let resumableTaskStore;
45
46
  let stateIndex;
46
- let eventStream;
47
+ let eventLog;
47
48
  let dwn;
48
49
  beforeEach(() => {
49
50
  sinon.restore();
@@ -58,8 +59,9 @@ export function testRecordsWriteHandler() {
58
59
  dataStore = stores.dataStore;
59
60
  resumableTaskStore = stores.resumableTaskStore;
60
61
  stateIndex = stores.stateIndex;
61
- eventStream = TestEventStream.get();
62
- dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, eventStream, resumableTaskStore });
62
+ eventLog = TestEventLog.get();
63
+ eventLog = TestEventLog.get();
64
+ dwn = await Dwn.create({ didResolver, messageStore, dataStore, stateIndex, eventLog, resumableTaskStore });
63
65
  });
64
66
  beforeEach(async () => {
65
67
  // clean up before each test rather than after so that a test does not depend on other tests to do the clean up
@@ -71,26 +73,38 @@ export function testRecordsWriteHandler() {
71
73
  afterAll(async () => {
72
74
  await dwn.close();
73
75
  });
74
- it('should call preProcessingForCoreRecordsWrite after authorization and before storage', async () => {
75
- // We create spy or stub for authorization, preProcessingForCoreRecordsWrite and processMessageWithDataStream methods
76
- // When we trigger a failure for `preProcessingForCoreRecordsWrite`, we expect the `processMessageWithDataStream` method to not be called
77
- const authorizationSpy = sinon.spy(RecordsWriteHandler, 'authorizeRecordsWrite');
78
- const processDataStreamSpy = sinon.spy(RecordsWriteHandler.prototype, 'processMessageWithDataStream');
79
- const preProcessingForCoreRecordsWriteSpy = sinon.stub(RecordsWriteHandler.prototype, 'preProcessingForCoreRecordsWrite')
80
- .throws(new DwnError(DwnErrorCode.PermissionsProtocolValidateScopeProtocolMismatch, 'Some Error'));
76
+ it('should dispatch preProcessWrite hook via CoreProtocolRegistry and abort before storage on failure', async () => {
77
+ // Register a mock core protocol whose preProcessWrite hook throws.
78
+ // Verify that authorization completes but processMessageWithDataStream is never reached.
81
79
  const alice = await TestDataGenerator.generateDidKeyPersona();
80
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
81
+ const authorizationSpy = sinon.spy(RecordsWriteHandler.prototype, 'authorizeRecordsWrite');
82
+ const processDataStreamSpy = sinon.spy(RecordsWriteHandler.prototype, 'processMessageWithDataStream');
83
+ // Register a mock core protocol that matches the default test protocol's URI
84
+ const coreProtocols = dwn._coreProtocols;
85
+ const protocolUri = defaultTestProtocolDefinition.protocol;
86
+ coreProtocols.register({
87
+ uri: protocolUri,
88
+ definition: defaultTestProtocolDefinition,
89
+ preProcessWrite: () => {
90
+ throw new DwnError(DwnErrorCode.PermissionsProtocolValidateScopeProtocolMismatch, 'mock pre-process failure');
91
+ },
92
+ mapErrorToStatusCode: (code) => {
93
+ return code.startsWith('PermissionsProtocolValidate') ? 400 : undefined;
94
+ },
95
+ });
82
96
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice });
83
97
  const reply = await dwn.processMessage(alice.did, message, { dataStream });
84
98
  expect(reply.status.code).toBe(400);
85
- // expect that authorization and preProcessingForCoreRecordsWrite are both called once
86
99
  expect(authorizationSpy.calledOnce).toBe(true);
87
- expect(preProcessingForCoreRecordsWriteSpy.calledOnce).toBe(true);
88
- // expect that processMessageWithDataStream is NOT called since preProcessingForCoreRecordsWrite failed before reaching it
89
100
  expect(processDataStreamSpy.called).toBe(false);
101
+ // Cleanup: unregister the mock so it doesn't affect other tests
102
+ coreProtocols._protocols.delete(protocolUri);
90
103
  });
91
104
  it('should only be able to overwrite existing record if new record has a later `messageTimestamp` value', async () => {
92
105
  // write a message into DB
93
106
  const author = await TestDataGenerator.generateDidKeyPersona();
107
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
94
108
  const data1 = new TextEncoder().encode('data1');
95
109
  const recordsWriteMessageData = await TestDataGenerator.generateRecordsWrite({ author, data: data1 });
96
110
  const tenant = author.did;
@@ -137,12 +151,13 @@ export function testRecordsWriteHandler() {
137
151
  // start by writing an originating message
138
152
  const author = await TestDataGenerator.generatePersona();
139
153
  const tenant = author.did;
154
+ // setting up a stub DID resolver
155
+ TestStubGenerator.stubDidResolver(didResolver, [author]);
156
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
140
157
  const originatingMessageData = await TestDataGenerator.generateRecordsWrite({
141
158
  author,
142
159
  data: Encoder.stringToBytes('unused')
143
160
  });
144
- // setting up a stub DID resolver
145
- TestStubGenerator.stubDidResolver(didResolver, [author]);
146
161
  const originatingMessageWriteReply = await dwn.processMessage(tenant, originatingMessageData.message, { dataStream: originatingMessageData.dataStream });
147
162
  expect(originatingMessageWriteReply.status.code).toBe(202);
148
163
  // generate two new RecordsWrite messages with the same `messageTimestamp` value
@@ -204,10 +219,12 @@ export function testRecordsWriteHandler() {
204
219
  expect(thirdRecordsQueryReply.entries[0].descriptor.dataCid)
205
220
  .toBe(newerWrite.message.descriptor.dataCid); // expecting unchanged
206
221
  });
207
- it('#690 - should allow data format of a flat-space record to be updated to any value', async () => {
208
- const initialWriteData = await TestDataGenerator.generateRecordsWrite();
209
- const tenant = initialWriteData.author.did;
210
- TestStubGenerator.stubDidResolver(didResolver, [initialWriteData.author]);
222
+ it('#690 - should allow data format of a record to be updated to any value', async () => {
223
+ const author = await TestDataGenerator.generatePersona();
224
+ const tenant = author.did;
225
+ TestStubGenerator.stubDidResolver(didResolver, [author]);
226
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
227
+ const initialWriteData = await TestDataGenerator.generateRecordsWrite({ author });
211
228
  const initialWriteReply = await dwn.processMessage(tenant, initialWriteData.message, { dataStream: initialWriteData.dataStream });
212
229
  expect(initialWriteReply.status.code).toBe(202);
213
230
  const newDataFormat = 'any-new-data-format';
@@ -215,7 +232,7 @@ export function testRecordsWriteHandler() {
215
232
  const updateWrite = await RecordsWrite.createFrom({
216
233
  recordsWriteMessage: initialWriteData.message,
217
234
  dataFormat: newDataFormat,
218
- signer: Jws.createSigner(initialWriteData.author),
235
+ signer: Jws.createSigner(author),
219
236
  data: newDataBytes
220
237
  });
221
238
  const newDataStream = DataStream.fromBytes(newDataBytes);
@@ -224,16 +241,18 @@ export function testRecordsWriteHandler() {
224
241
  // verify the data format of the record is updated
225
242
  const recordsRead = await RecordsRead.create({
226
243
  filter: { recordId: initialWriteData.message.recordId },
227
- signer: Jws.createSigner(initialWriteData.author),
244
+ signer: Jws.createSigner(author),
228
245
  });
229
246
  const recordsReadReply = await dwn.processMessage(tenant, recordsRead.message);
230
247
  expect(recordsReadReply.status.code).toBe(200);
231
248
  expect(recordsReadReply.entry.recordsWrite?.descriptor.dataFormat).toBe(newDataFormat);
232
249
  });
233
250
  it('should not allow changes to immutable properties', async () => {
234
- const initialWriteData = await TestDataGenerator.generateRecordsWrite();
235
- const tenant = initialWriteData.author.did;
236
- TestStubGenerator.stubDidResolver(didResolver, [initialWriteData.author]);
251
+ const author = await TestDataGenerator.generatePersona();
252
+ const tenant = author.did;
253
+ TestStubGenerator.stubDidResolver(didResolver, [author]);
254
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
255
+ const initialWriteData = await TestDataGenerator.generateRecordsWrite({ author });
237
256
  const initialWriteReply = await dwn.processMessage(tenant, initialWriteData.message, { dataStream: initialWriteData.dataStream });
238
257
  expect(initialWriteReply.status.code).toBe(202);
239
258
  const recordId = initialWriteData.message.recordId;
@@ -241,7 +260,7 @@ export function testRecordsWriteHandler() {
241
260
  const schema = initialWriteData.message.descriptor.schema;
242
261
  // dateCreated test
243
262
  let childMessageData = await TestDataGenerator.generateRecordsWrite({
244
- author: initialWriteData.author,
263
+ author,
245
264
  recordId,
246
265
  schema,
247
266
  dateCreated: Time.getCurrentTimestamp(), // should not be allowed to be modified
@@ -252,7 +271,7 @@ export function testRecordsWriteHandler() {
252
271
  expect(reply.status.detail).toContain('dateCreated is an immutable property');
253
272
  // schema test
254
273
  childMessageData = await TestDataGenerator.generateRecordsWrite({
255
- author: initialWriteData.author,
274
+ author,
256
275
  recordId,
257
276
  schema: 'should-not-allowed-to-be-modified',
258
277
  dateCreated,
@@ -263,11 +282,14 @@ export function testRecordsWriteHandler() {
263
282
  expect(reply.status.detail).toContain('schema is an immutable property');
264
283
  });
265
284
  it('should inherit data from previous RecordsWrite given a matching dataCid and dataSize and no dataStream', async () => {
266
- const { message, author, dataStream, dataBytes } = await TestDataGenerator.generateRecordsWrite({
267
- published: false
268
- });
285
+ const author = await TestDataGenerator.generatePersona();
269
286
  const tenant = author.did;
270
287
  TestStubGenerator.stubDidResolver(didResolver, [author]);
288
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
289
+ const { message, dataStream, dataBytes } = await TestDataGenerator.generateRecordsWrite({
290
+ author,
291
+ published: false
292
+ });
271
293
  const initialWriteReply = await dwn.processMessage(tenant, message, { dataStream });
272
294
  expect(initialWriteReply.status.code).toBe(202);
273
295
  const write2 = await RecordsWrite.createFrom({
@@ -292,6 +314,7 @@ export function testRecordsWriteHandler() {
292
314
  //scenario: you have an initial write without the data and a subsequent write with data to be able to write.
293
315
  // the DWN should accept an initial write without data, however prevent the user from querying for it until it's updated.
294
316
  const alice = await TestDataGenerator.generateDidKeyPersona();
317
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
295
318
  const { recordsWrite } = await TestDataGenerator.generateRecordsWrite({ author: alice });
296
319
  // simulate synchronize of pruned initial `RecordsWrite`
297
320
  const reply = await dwn.processMessage(alice.did, recordsWrite.message);
@@ -324,6 +347,7 @@ export function testRecordsWriteHandler() {
324
347
  //scenario: you have an initial write without the data and a subsequent write with data to be able to write.
325
348
  // the DWN should accept an initial write without data, however prevent the user from querying for it until it's updated.
326
349
  const alice = await TestDataGenerator.generateDidKeyPersona();
350
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
327
351
  // write a record into the dwn
328
352
  const { recordsWrite, dataStream, dataBytes } = await TestDataGenerator.generateRecordsWrite({ author: alice });
329
353
  const reply = await dwn.processMessage(alice.did, recordsWrite.message, { dataStream });
@@ -356,12 +380,15 @@ export function testRecordsWriteHandler() {
356
380
  });
357
381
  describe('should inherit data from previous RecordsWrite given a matching dataCid and dataSize and no dataStream', () => {
358
382
  it('with data above the threshold for encodedData', async () => {
359
- const { message, author, dataStream, dataBytes } = await TestDataGenerator.generateRecordsWrite({
383
+ const author = await TestDataGenerator.generatePersona();
384
+ const tenant = author.did;
385
+ TestStubGenerator.stubDidResolver(didResolver, [author]);
386
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
387
+ const { message, dataStream, dataBytes } = await TestDataGenerator.generateRecordsWrite({
388
+ author,
360
389
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1),
361
390
  published: false
362
391
  });
363
- const tenant = author.did;
364
- TestStubGenerator.stubDidResolver(didResolver, [author]);
365
392
  const initialWriteReply = await dwn.processMessage(tenant, message, { dataStream });
366
393
  expect(initialWriteReply.status.code).toBe(202);
367
394
  const write2 = await RecordsWrite.createFrom({
@@ -383,12 +410,15 @@ export function testRecordsWriteHandler() {
383
410
  expect(data).toEqual(dataBytes);
384
411
  });
385
412
  it('with data equal to or below the threshold for encodedData', async () => {
386
- const { message, author, dataStream, dataBytes } = await TestDataGenerator.generateRecordsWrite({
413
+ const author = await TestDataGenerator.generatePersona();
414
+ const tenant = author.did;
415
+ TestStubGenerator.stubDidResolver(didResolver, [author]);
416
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
417
+ const { message, dataStream, dataBytes } = await TestDataGenerator.generateRecordsWrite({
418
+ author,
387
419
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded),
388
420
  published: false
389
421
  });
390
- const tenant = author.did;
391
- TestStubGenerator.stubDidResolver(didResolver, [author]);
392
422
  const initialWriteReply = await dwn.processMessage(tenant, message, { dataStream });
393
423
  expect(initialWriteReply.status.code).toBe(202);
394
424
  const write2 = await RecordsWrite.createFrom({
@@ -413,24 +443,27 @@ export function testRecordsWriteHandler() {
413
443
  describe('should return 400 if actual data size mismatches with `dataSize` in descriptor', () => {
414
444
  it('with dataStream and `dataSize` larger than encodedData threshold', async () => {
415
445
  const alice = await TestDataGenerator.generateDidKeyPersona();
446
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
416
447
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({
417
448
  author: alice,
418
449
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1)
419
450
  });
420
- // replace the dataSize to simulate mismatch, will need to generate `recordId` and `authorization` property again
451
+ // replace the dataSize to simulate mismatch, will need to generate `recordId`, `contextId`, and `authorization` property again
421
452
  message.descriptor.dataSize = DwnConstant.maxDataSizeAllowedToBeEncoded + 100;
422
453
  const descriptorCid = await Cid.computeCid(message.descriptor);
423
454
  const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
455
+ const contextId = recordId; // contextId is deterministic: for root records it equals recordId
424
456
  const signer = Jws.createSigner(alice);
425
457
  const signature = await RecordsWrite.createSignerSignature({
426
458
  recordId,
427
- contextId: message.contextId,
459
+ contextId,
428
460
  descriptorCid,
429
461
  attestation: message.attestation,
430
462
  encryption: message.encryption,
431
463
  signer
432
464
  });
433
465
  message.recordId = recordId;
466
+ message.contextId = contextId;
434
467
  message.authorization = { signature };
435
468
  const reply = await dwn.processMessage(alice.did, message, { dataStream });
436
469
  expect(reply.status.code).toBe(400);
@@ -438,24 +471,27 @@ export function testRecordsWriteHandler() {
438
471
  });
439
472
  it('with only `dataSize` larger than encodedData threshold', async () => {
440
473
  const alice = await TestDataGenerator.generateDidKeyPersona();
474
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
441
475
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({
442
476
  author: alice,
443
477
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded)
444
478
  });
445
- // replace the dataSize to simulate mismatch, will need to generate `recordId` and `authorization` property again
479
+ // replace the dataSize to simulate mismatch, will need to generate `recordId`, `contextId`, and `authorization` property again
446
480
  message.descriptor.dataSize = DwnConstant.maxDataSizeAllowedToBeEncoded + 100;
447
481
  const descriptorCid = await Cid.computeCid(message.descriptor);
448
482
  const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
483
+ const contextId = recordId; // contextId is deterministic: for root records it equals recordId
449
484
  const signer = Jws.createSigner(alice);
450
485
  const signature = await RecordsWrite.createSignerSignature({
451
486
  recordId,
452
- contextId: message.contextId,
487
+ contextId,
453
488
  descriptorCid,
454
489
  attestation: message.attestation,
455
490
  encryption: message.encryption,
456
491
  signer
457
492
  });
458
493
  message.recordId = recordId;
494
+ message.contextId = contextId;
459
495
  message.authorization = { signature };
460
496
  const reply = await dwn.processMessage(alice.did, message, { dataStream });
461
497
  expect(reply.status.code).toBe(400);
@@ -463,24 +499,27 @@ export function testRecordsWriteHandler() {
463
499
  });
464
500
  it('with only dataStream larger than encodedData threshold', async () => {
465
501
  const alice = await TestDataGenerator.generateDidKeyPersona();
502
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
466
503
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({
467
504
  author: alice,
468
505
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1)
469
506
  });
470
- // replace the dataSize to simulate mismatch, will need to generate `recordId` and `authorization` property again
507
+ // replace the dataSize to simulate mismatch, will need to generate `recordId`, `contextId`, and `authorization` property again
471
508
  message.descriptor.dataSize = 1;
472
509
  const descriptorCid = await Cid.computeCid(message.descriptor);
473
510
  const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
511
+ const contextId = recordId; // contextId is deterministic: for root records it equals recordId
474
512
  const signer = Jws.createSigner(alice);
475
513
  const signature = await RecordsWrite.createSignerSignature({
476
514
  recordId,
477
- contextId: message.contextId,
515
+ contextId,
478
516
  descriptorCid,
479
517
  attestation: message.attestation,
480
518
  encryption: message.encryption,
481
519
  signer
482
520
  });
483
521
  message.recordId = recordId;
522
+ message.contextId = contextId;
484
523
  message.authorization = { signature };
485
524
  const reply = await dwn.processMessage(alice.did, message, { dataStream });
486
525
  expect(reply.status.code).toBe(400);
@@ -488,23 +527,26 @@ export function testRecordsWriteHandler() {
488
527
  });
489
528
  it('with both `dataSize` and dataStream below than encodedData threshold', async () => {
490
529
  const alice = await TestDataGenerator.generateDidKeyPersona();
530
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
491
531
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({
492
532
  author: alice
493
533
  });
494
- // replace the dataSize to simulate mismatch, will need to generate `recordId` and `authorization` property again
534
+ // replace the dataSize to simulate mismatch, will need to generate `recordId`, `contextId`, and `authorization` property again
495
535
  message.descriptor.dataSize = 1;
496
536
  const descriptorCid = await Cid.computeCid(message.descriptor);
497
537
  const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
538
+ const contextId = recordId; // contextId is deterministic: for root records it equals recordId
498
539
  const signer = Jws.createSigner(alice);
499
540
  const signature = await RecordsWrite.createSignerSignature({
500
541
  recordId,
501
- contextId: message.contextId,
542
+ contextId,
502
543
  descriptorCid,
503
544
  attestation: message.attestation,
504
545
  encryption: message.encryption,
505
546
  signer
506
547
  });
507
548
  message.recordId = recordId;
549
+ message.contextId = contextId;
508
550
  message.authorization = { signature };
509
551
  const reply = await dwn.processMessage(alice.did, message, { dataStream });
510
552
  expect(reply.status.code).toBe(400);
@@ -513,6 +555,7 @@ export function testRecordsWriteHandler() {
513
555
  });
514
556
  it('should return 400 for data CID mismatch with both dataStream and `dataSize` larger than encodedData threshold', async () => {
515
557
  const alice = await TestDataGenerator.generateDidKeyPersona();
558
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
516
559
  const { message } = await TestDataGenerator.generateRecordsWrite({
517
560
  author: alice,
518
561
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1)
@@ -524,6 +567,7 @@ export function testRecordsWriteHandler() {
524
567
  });
525
568
  it('should return 400 for data CID mismatch with `dataSize` larger than encodedData threshold', async () => {
526
569
  const alice = await TestDataGenerator.generateDidKeyPersona();
570
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
527
571
  const { message } = await TestDataGenerator.generateRecordsWrite({
528
572
  author: alice,
529
573
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1)
@@ -535,6 +579,7 @@ export function testRecordsWriteHandler() {
535
579
  });
536
580
  it('should return 400 for data CID mismatch with dataStream larger than encodedData threshold', async () => {
537
581
  const alice = await TestDataGenerator.generateDidKeyPersona();
582
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
538
583
  const { message } = await TestDataGenerator.generateRecordsWrite({
539
584
  author: alice,
540
585
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded)
@@ -546,6 +591,7 @@ export function testRecordsWriteHandler() {
546
591
  });
547
592
  it('should return 400 for data CID mismatch with both dataStream and `dataSize` below than encodedData threshold', async () => {
548
593
  const alice = await TestDataGenerator.generateDidKeyPersona();
594
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
549
595
  const { message } = await TestDataGenerator.generateRecordsWrite({
550
596
  author: alice,
551
597
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded)
@@ -557,6 +603,7 @@ export function testRecordsWriteHandler() {
557
603
  });
558
604
  it('#359 - should not allow access of data by referencing a different`dataCid` in "modify" `RecordsWrite` with large data', async () => {
559
605
  const alice = await TestDataGenerator.generateDidKeyPersona();
606
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
560
607
  // alice writes a record
561
608
  const dataString = TestDataGenerator.randomString(DwnConstant.maxDataSizeAllowedToBeEncoded + 1);
562
609
  const dataSize = dataString.length;
@@ -602,6 +649,7 @@ export function testRecordsWriteHandler() {
602
649
  });
603
650
  it('#359 - should not allow access of data by referencing a different`dataCid` in "modify" `RecordsWrite`', async () => {
604
651
  const alice = await TestDataGenerator.generateDidKeyPersona();
652
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
605
653
  // alice writes a record
606
654
  const dataString = TestDataGenerator.randomString(DwnConstant.maxDataSizeAllowedToBeEncoded);
607
655
  const dataSize = dataString.length;
@@ -650,14 +698,17 @@ export function testRecordsWriteHandler() {
650
698
  it('should accept a published RecordsWrite using createFrom() without specifying `data` or `datePublished`', async () => {
651
699
  const data = Encoder.stringToBytes('test');
652
700
  const encodedData = Encoder.bytesToBase64Url(data);
701
+ const author = await TestDataGenerator.generatePersona();
702
+ const tenant = author.did;
703
+ // setting up a stub DID resolver
704
+ TestStubGenerator.stubDidResolver(didResolver, [author]);
705
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
653
706
  // new record
654
- const { message, author, recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
707
+ const { message, recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
708
+ author,
655
709
  published: false,
656
710
  data,
657
711
  });
658
- const tenant = author.did;
659
- // setting up a stub DID resolver
660
- TestStubGenerator.stubDidResolver(didResolver, [author]);
661
712
  const reply = await dwn.processMessage(tenant, message, { dataStream });
662
713
  expect(reply.status.code).toBe(202);
663
714
  // changing the `published` property
@@ -681,12 +732,15 @@ export function testRecordsWriteHandler() {
681
732
  expect(recordsQueryReply.entries[0].encodedData).toBe(encodedData);
682
733
  });
683
734
  it('should inherit parent published state when using createFrom() to create RecordsWrite', async () => {
684
- const { message, author, recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
685
- published: true
686
- });
735
+ const author = await TestDataGenerator.generatePersona();
687
736
  const tenant = author.did;
688
737
  // setting up a stub DID resolver
689
738
  TestStubGenerator.stubDidResolver(didResolver, [author]);
739
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
740
+ const { message, recordsWrite, dataStream } = await TestDataGenerator.generateRecordsWrite({
741
+ author,
742
+ published: true
743
+ });
690
744
  const reply = await dwn.processMessage(tenant, message, { dataStream });
691
745
  expect(reply.status.code).toBe(202);
692
746
  const newData = Encoder.stringToBytes('new data');
@@ -719,6 +773,7 @@ export function testRecordsWriteHandler() {
719
773
  });
720
774
  const tenant = author.did;
721
775
  TestStubGenerator.stubDidResolver(didResolver, [author]);
776
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
722
777
  const reply = await dwn.processMessage(tenant, message, { dataStream });
723
778
  expect(reply.status.code).toBe(400);
724
779
  expect(reply.status.detail).toContain(DwnErrorCode.RecordsWriteGetInitialWriteNotFound);
@@ -730,6 +785,7 @@ export function testRecordsWriteHandler() {
730
785
  });
731
786
  const tenant = author.did;
732
787
  TestStubGenerator.stubDidResolver(didResolver, [author]);
788
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
733
789
  const reply = await dwn.processMessage(tenant, message, { dataStream });
734
790
  expect(reply.status.code).toBe(400);
735
791
  expect(reply.status.detail).toContain('must match dateCreated');
@@ -745,18 +801,22 @@ export function testRecordsWriteHandler() {
745
801
  });
746
802
  describe('state index', () => {
747
803
  it('should add an entry to the state index on initial write', async () => {
748
- const { message, author, dataStream } = await TestDataGenerator.generateRecordsWrite();
804
+ const author = await TestDataGenerator.generatePersona();
749
805
  TestStubGenerator.stubDidResolver(didResolver, [author]);
806
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
807
+ const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author });
750
808
  const reply = await dwn.processMessage(author.did, message, { dataStream });
751
809
  expect(reply.status.code).toBe(202);
752
810
  const events = await stateIndex.getLeaves(author.did, []);
753
- expect(events.length).toBe(1);
811
+ expect(events.length).toBe(2); // 1 for protocol configure + 1 for record write
754
812
  const messageCid = await Message.getCid(message);
755
- expect(events[0]).toBe(messageCid);
813
+ expect(events).toContain(messageCid);
756
814
  });
757
815
  it('should only keep first write and latest write when subsequent writes happen', async () => {
758
- const { message, author, dataStream, recordsWrite } = await TestDataGenerator.generateRecordsWrite();
816
+ const author = await TestDataGenerator.generatePersona();
759
817
  TestStubGenerator.stubDidResolver(didResolver, [author]);
818
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
819
+ const { message, dataStream, recordsWrite } = await TestDataGenerator.generateRecordsWrite({ author });
760
820
  const reply = await dwn.processMessage(author.did, message, { dataStream });
761
821
  expect(reply.status.code).toBe(202);
762
822
  const newWrite = await RecordsWrite.createFrom({
@@ -774,7 +834,7 @@ export function testRecordsWriteHandler() {
774
834
  const newestWriteReply = await dwn.processMessage(author.did, newestWrite.message);
775
835
  expect(newestWriteReply.status.code).toBe(202);
776
836
  const events = await stateIndex.getLeaves(author.did, []);
777
- expect(events.length).toBe(2);
837
+ expect(events.length).toBe(3); // 1 for protocol configure + 2 for record writes (first + latest)
778
838
  const deletedMessageCid = await Message.getCid(newWrite.message);
779
839
  for (const messageCid of events) {
780
840
  if (messageCid === deletedMessageCid) {
@@ -2463,7 +2523,9 @@ export function testRecordsWriteHandler() {
2463
2523
  });
2464
2524
  // replace valid `encryption` property with a mismatching one — mutate the iv to cause CID mismatch
2465
2525
  message.encryption.iv = Encoder.stringToBase64Url('any value which will result in a different CID');
2466
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStore, dataStore, stateIndex, eventStream);
2526
+ const recordsWriteHandler = new RecordsWriteHandler({
2527
+ didResolver, messageStore, dataStore, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
2528
+ });
2467
2529
  const writeReply = await recordsWriteHandler.handle({ tenant: alice.did, message, dataStream: dataStream });
2468
2530
  expect(writeReply.status.code).toBe(400);
2469
2531
  expect(writeReply.status.detail).toContain(DwnErrorCode.RecordsWriteValidateIntegrityEncryptionCidMismatch);
@@ -2505,6 +2567,7 @@ export function testRecordsWriteHandler() {
2505
2567
  it('#359 - should not allow access of data by referencing `dataCid` in protocol authorized `RecordsWrite`', async () => {
2506
2568
  const alice = await TestDataGenerator.generateDidKeyPersona();
2507
2569
  const bob = await TestDataGenerator.generateDidKeyPersona();
2570
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
2508
2571
  // alice writes a private record
2509
2572
  const dataString = TestDataGenerator.randomString(DwnConstant.maxDataSizeAllowedToBeEncoded);
2510
2573
  const dataSize = dataString.length;
@@ -2586,6 +2649,7 @@ export function testRecordsWriteHandler() {
2586
2649
  it('#359 - should not allow access of data by referencing `dataCid` in protocol authorized `RecordsWrite` with large data', async () => {
2587
2650
  const alice = await TestDataGenerator.generateDidKeyPersona();
2588
2651
  const bob = await TestDataGenerator.generateDidKeyPersona();
2652
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
2589
2653
  // alice writes a private record
2590
2654
  const dataString = TestDataGenerator.randomString(DwnConstant.maxDataSizeAllowedToBeEncoded + 1);
2591
2655
  const dataSize = dataString.length;
@@ -3394,6 +3458,7 @@ export function testRecordsWriteHandler() {
3394
3458
  // Pruned RecordsWrite
3395
3459
  // Data large enough to use the DataStore
3396
3460
  const alice = await TestDataGenerator.generateDidKeyPersona();
3461
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3397
3462
  const data = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1);
3398
3463
  const prunedRecordsWrite = await TestDataGenerator.generateRecordsWrite({
3399
3464
  author: alice,
@@ -3419,6 +3484,7 @@ export function testRecordsWriteHandler() {
3419
3484
  // Pruned RecordsWrite
3420
3485
  // Data that would be encoded within the message
3421
3486
  const alice = await TestDataGenerator.generateDidKeyPersona();
3487
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3422
3488
  const data = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded);
3423
3489
  const prunedRecordsWrite = await TestDataGenerator.generateRecordsWrite({
3424
3490
  author: alice,
@@ -3439,12 +3505,15 @@ export function testRecordsWriteHandler() {
3439
3505
  expect(recordsWriteReply.status.detail).toContain(DwnErrorCode.RecordsWriteMissingEncodedDataInPrevious);
3440
3506
  });
3441
3507
  it('should return 400 if attempting a write after a delete', async () => {
3442
- const { message, author, dataStream } = await TestDataGenerator.generateRecordsWrite({
3508
+ const author = await TestDataGenerator.generatePersona();
3509
+ const tenant = author.did;
3510
+ TestStubGenerator.stubDidResolver(didResolver, [author]);
3511
+ await TestDataGenerator.installDefaultTestProtocol(dwn, author);
3512
+ const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({
3513
+ author,
3443
3514
  data: TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded),
3444
3515
  published: false
3445
3516
  });
3446
- const tenant = author.did;
3447
- TestStubGenerator.stubDidResolver(didResolver, [author]);
3448
3517
  const initialWriteReply = await dwn.processMessage(tenant, message, { dataStream });
3449
3518
  expect(initialWriteReply.status.code).toBe(202);
3450
3519
  const recordsDelete = await RecordsDelete.create({
@@ -3466,6 +3535,8 @@ export function testRecordsWriteHandler() {
3466
3535
  it('should not allow referencing data across tenants', async () => {
3467
3536
  const alice = await TestDataGenerator.generateDidKeyPersona();
3468
3537
  const bob = await TestDataGenerator.generateDidKeyPersona();
3538
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3539
+ await TestDataGenerator.installDefaultTestProtocol(dwn, bob);
3469
3540
  const data = Encoder.stringToBytes('test');
3470
3541
  const dataCid = await Cid.computeDagPbCidFromBytes(data);
3471
3542
  const encodedData = Encoder.bytesToBase64Url(data);
@@ -3512,6 +3583,7 @@ export function testRecordsWriteHandler() {
3512
3583
  describe('encodedData threshold', () => {
3513
3584
  it('should call cloneAndAddEncodedData if dataSize is less than or equal to the threshold', async () => {
3514
3585
  const alice = await TestDataGenerator.generateDidKeyPersona();
3586
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3515
3587
  const dataBytes = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded);
3516
3588
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice, data: dataBytes });
3517
3589
  const processEncoded = sinon.spy(RecordsWriteHandler.prototype, 'cloneAndAddEncodedData');
@@ -3521,6 +3593,7 @@ export function testRecordsWriteHandler() {
3521
3593
  });
3522
3594
  it('should not call cloneAndAddEncodedData if dataSize is greater than the threshold', async () => {
3523
3595
  const alice = await TestDataGenerator.generateDidKeyPersona();
3596
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3524
3597
  const dataBytes = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1);
3525
3598
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice, data: dataBytes });
3526
3599
  const processEncoded = sinon.spy(RecordsWriteHandler.prototype, 'cloneAndAddEncodedData');
@@ -3530,6 +3603,7 @@ export function testRecordsWriteHandler() {
3530
3603
  });
3531
3604
  it('should have encodedData field if dataSize is less than or equal to the threshold', async () => {
3532
3605
  const alice = await TestDataGenerator.generateDidKeyPersona();
3606
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3533
3607
  const dataBytes = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded);
3534
3608
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice, data: dataBytes });
3535
3609
  const writeMessage = await dwn.processMessage(alice.did, message, { dataStream });
@@ -3540,6 +3614,7 @@ export function testRecordsWriteHandler() {
3540
3614
  });
3541
3615
  it('should not have encodedData field if dataSize greater than threshold', async () => {
3542
3616
  const alice = await TestDataGenerator.generateDidKeyPersona();
3617
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3543
3618
  const dataBytes = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded + 1);
3544
3619
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice, data: dataBytes });
3545
3620
  const writeMessage = await dwn.processMessage(alice.did, message, { dataStream });
@@ -3550,6 +3625,7 @@ export function testRecordsWriteHandler() {
3550
3625
  });
3551
3626
  it('should retain original RecordsWrite message but without the encodedData if data is under threshold', async () => {
3552
3627
  const alice = await TestDataGenerator.generateDidKeyPersona();
3628
+ await TestDataGenerator.installDefaultTestProtocol(dwn, alice);
3553
3629
  const dataBytes = TestDataGenerator.randomBytes(DwnConstant.maxDataSizeAllowedToBeEncoded);
3554
3630
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice, data: dataBytes });
3555
3631
  const writeMessage = await dwn.processMessage(alice.did, message, { dataStream });
@@ -3588,7 +3664,9 @@ export function testRecordsWriteHandler() {
3588
3664
  const didResolver = TestStubGenerator.createDidResolverStub(author);
3589
3665
  const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
3590
3666
  const dataStoreStub = sinon.createStubInstance(DataStoreLevel);
3591
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStoreStub, dataStoreStub, stateIndex, eventStream);
3667
+ const recordsWriteHandler = new RecordsWriteHandler({
3668
+ didResolver, messageStore: messageStoreStub, dataStore: dataStoreStub, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3669
+ });
3592
3670
  const reply = await recordsWriteHandler.handle({ tenant, message, dataStream: dataStream });
3593
3671
  expect(reply.status.code).toBe(400);
3594
3672
  expect(reply.status.detail).toContain('does not match recordId in authorization');
@@ -3607,7 +3685,9 @@ export function testRecordsWriteHandler() {
3607
3685
  const didResolver = sinon.createStubInstance(UniversalResolver);
3608
3686
  const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
3609
3687
  const dataStoreStub = sinon.createStubInstance(DataStoreLevel);
3610
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStoreStub, dataStoreStub, stateIndex, eventStream);
3688
+ const recordsWriteHandler = new RecordsWriteHandler({
3689
+ didResolver, messageStore: messageStoreStub, dataStore: dataStoreStub, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3690
+ });
3611
3691
  const reply = await recordsWriteHandler.handle({ tenant, message, dataStream: dataStream });
3612
3692
  expect(reply.status.code).toBe(400);
3613
3693
  expect(reply.status.detail).toContain('does not match contextId in authorization');
@@ -3621,7 +3701,11 @@ export function testRecordsWriteHandler() {
3621
3701
  const didResolver = TestStubGenerator.createDidResolverStub(mismatchingPersona);
3622
3702
  const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
3623
3703
  const dataStoreStub = sinon.createStubInstance(DataStoreLevel);
3624
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStoreStub, dataStoreStub, stateIndex, eventStream);
3704
+ // stub protocol validation so the handler reaches authentication/authorization
3705
+ sinon.stub(ProtocolAuthorization, 'validateReferentialIntegrity').resolves();
3706
+ const recordsWriteHandler = new RecordsWriteHandler({
3707
+ didResolver, messageStore: messageStoreStub, dataStore: dataStoreStub, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3708
+ });
3625
3709
  const reply = await recordsWriteHandler.handle({ tenant, message, dataStream: dataStream });
3626
3710
  expect(reply.status.code).toBe(401);
3627
3711
  });
@@ -3632,7 +3716,11 @@ export function testRecordsWriteHandler() {
3632
3716
  const didResolver = TestStubGenerator.createDidResolverStub(author);
3633
3717
  const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
3634
3718
  const dataStoreStub = sinon.createStubInstance(DataStoreLevel);
3635
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStoreStub, dataStoreStub, stateIndex, eventStream);
3719
+ // stub protocol validation so the handler reaches authentication/authorization
3720
+ sinon.stub(ProtocolAuthorization, 'validateReferentialIntegrity').resolves();
3721
+ const recordsWriteHandler = new RecordsWriteHandler({
3722
+ didResolver, messageStore: messageStoreStub, dataStore: dataStoreStub, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3723
+ });
3636
3724
  const tenant = await (await TestDataGenerator.generatePersona()).did; // unauthorized tenant
3637
3725
  const reply = await recordsWriteHandler.handle({ tenant, message, dataStream: dataStream });
3638
3726
  expect(reply.status.code).toBe(401);
@@ -3658,7 +3746,9 @@ export function testRecordsWriteHandler() {
3658
3746
  const didResolver = TestStubGenerator.createDidResolverStub(author);
3659
3747
  const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
3660
3748
  const dataStoreStub = sinon.createStubInstance(DataStoreLevel);
3661
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStoreStub, dataStoreStub, stateIndex, eventStream);
3749
+ const recordsWriteHandler = new RecordsWriteHandler({
3750
+ didResolver, messageStore: messageStoreStub, dataStore: dataStoreStub, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3751
+ });
3662
3752
  const reply = await recordsWriteHandler.handle({ tenant, message, dataStream: dataStream });
3663
3753
  expect(reply.status.code).toBe(400);
3664
3754
  expect(reply.status.detail).toContain(`Only 'descriptorCid' is allowed in attestation payload`);
@@ -3667,7 +3757,9 @@ export function testRecordsWriteHandler() {
3667
3757
  const alice = await TestDataGenerator.generateDidKeyPersona();
3668
3758
  const bob = await TestDataGenerator.generateDidKeyPersona();
3669
3759
  const { message, dataStream } = await TestDataGenerator.generateRecordsWrite({ author: alice, attesters: [alice, bob] });
3670
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStore, dataStore, stateIndex, eventStream);
3760
+ const recordsWriteHandler = new RecordsWriteHandler({
3761
+ didResolver, messageStore, dataStore, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3762
+ });
3671
3763
  const writeReply = await recordsWriteHandler.handle({ tenant: alice.did, message, dataStream: dataStream });
3672
3764
  expect(writeReply.status.code).toBe(400);
3673
3765
  expect(writeReply.status.detail).toContain('implementation only supports 1 attester');
@@ -3678,7 +3770,9 @@ export function testRecordsWriteHandler() {
3678
3770
  // create another write and use its `attestation` value instead, that `attestation` will point to an entirely different `descriptorCid`
3679
3771
  const anotherWrite = await TestDataGenerator.generateRecordsWrite({ attesters: [alice] });
3680
3772
  message.attestation = anotherWrite.message.attestation;
3681
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStore, dataStore, stateIndex, eventStream);
3773
+ const recordsWriteHandler = new RecordsWriteHandler({
3774
+ didResolver, messageStore, dataStore, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3775
+ });
3682
3776
  const writeReply = await recordsWriteHandler.handle({ tenant: alice.did, message, dataStream: dataStream });
3683
3777
  expect(writeReply.status.code).toBe(400);
3684
3778
  expect(writeReply.status.detail).toContain('does not match expected descriptorCid');
@@ -3691,7 +3785,9 @@ export function testRecordsWriteHandler() {
3691
3785
  const descriptorCid = await Cid.computeCid(message.descriptor);
3692
3786
  const attestationNotReferencedByAuthorization = await RecordsWrite['createAttestation'](descriptorCid, Jws.createSigners([bob]));
3693
3787
  message.attestation = attestationNotReferencedByAuthorization;
3694
- const recordsWriteHandler = new RecordsWriteHandler(didResolver, messageStore, dataStore, stateIndex, eventStream);
3788
+ const recordsWriteHandler = new RecordsWriteHandler({
3789
+ didResolver, messageStore, dataStore, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3790
+ });
3695
3791
  const writeReply = await recordsWriteHandler.handle({ tenant: alice.did, message, dataStream: dataStream });
3696
3792
  expect(writeReply.status.code).toBe(400);
3697
3793
  expect(writeReply.status.detail).toContain('does not match attestationCid');
@@ -3709,7 +3805,15 @@ export function testRecordsWriteHandler() {
3709
3805
  const messageStoreStub = sinon.createStubInstance(MessageStoreLevel);
3710
3806
  messageStoreStub.query.resolves({ messages: [initialWriteMessage] });
3711
3807
  const dataStoreStub = sinon.createStubInstance(DataStoreLevel);
3712
- const recordsWriteHandler = new RecordsWriteHandler(didResolverStub, messageStoreStub, dataStoreStub, stateIndex, eventStream);
3808
+ // stub protocol validation so the handler reaches the process methods
3809
+ sinon.stub(ProtocolAuthorization, 'validateReferentialIntegrity').resolves();
3810
+ const recordsWriteHandler = new RecordsWriteHandler({
3811
+ didResolver: didResolverStub, messageStore: messageStoreStub,
3812
+ dataStore: dataStoreStub, stateIndex, coreProtocols: new CoreProtocolRegistry(), eventLog,
3813
+ });
3814
+ // stub the squash backstop so the stubbed messageStore (which returns RecordsWrite messages
3815
+ // for all queries) does not interfere with the flow reaching the process methods
3816
+ sinon.stub(recordsWriteHandler, 'enforceSquashBackstop').resolves();
3713
3817
  // simulate throwing unexpected error
3714
3818
  sinon.stub(recordsWriteHandler, 'processMessageWithoutDataStream').throws(new Error('an unknown error in recordsWriteHandler.processMessageWithoutDataStream()'));
3715
3819
  sinon.stub(recordsWriteHandler, 'processMessageWithDataStream').throws(new Error('an unknown error in recordsWriteHandler.processMessageWithDataStream()'));