@learncard/network-brain-service 3.19.0 → 4.0.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 (507) hide show
  1. package/.env.example +47 -82
  2. package/AGENTS.md +52 -0
  3. package/CHANGELOG.md +147 -0
  4. package/README.md +51 -2
  5. package/bootstrapLambda.test.ts +72 -0
  6. package/config/config.dev.json +29 -0
  7. package/config/config.example.json +29 -0
  8. package/config/config.json +1 -0
  9. package/config/config.production.json +29 -0
  10. package/config/config.scouts.dev.json +24 -0
  11. package/config/config.scouts.production.json +24 -0
  12. package/contractEventsLambda.ts +18 -0
  13. package/contractEventsLambdaApp.ts +19 -0
  14. package/didWebLambda.ts +13 -18
  15. package/didWebLambdaApp.ts +22 -0
  16. package/dist/accesslayer/app-manifest-version/create.d.ts +10 -0
  17. package/dist/accesslayer/app-manifest-version/create.d.ts.map +1 -0
  18. package/dist/accesslayer/app-manifest-version/read.d.ts +11 -0
  19. package/dist/accesslayer/app-manifest-version/read.d.ts.map +1 -0
  20. package/dist/accesslayer/app-manifest-version/update.d.ts +7 -0
  21. package/dist/accesslayer/app-manifest-version/update.d.ts.map +1 -0
  22. package/dist/accesslayer/app-store-listing/read.d.ts +2 -1
  23. package/dist/accesslayer/app-store-listing/read.d.ts.map +1 -1
  24. package/dist/accesslayer/app-store-listing/relationships/create.d.ts +1 -0
  25. package/dist/accesslayer/app-store-listing/relationships/create.d.ts.map +1 -1
  26. package/dist/accesslayer/app-store-listing/relationships/read.d.ts +2 -0
  27. package/dist/accesslayer/app-store-listing/relationships/read.d.ts.map +1 -1
  28. package/dist/accesslayer/app-store-listing/update.d.ts +1 -0
  29. package/dist/accesslayer/app-store-listing/update.d.ts.map +1 -1
  30. package/dist/accesslayer/boost/relationships/create.d.ts +2 -1
  31. package/dist/accesslayer/boost/relationships/create.d.ts.map +1 -1
  32. package/dist/accesslayer/consentflowcontract/create.d.ts +9 -1
  33. package/dist/accesslayer/consentflowcontract/create.d.ts.map +1 -1
  34. package/dist/accesslayer/consentflowcontract/read.d.ts +34 -3
  35. package/dist/accesslayer/consentflowcontract/read.d.ts.map +1 -1
  36. package/dist/accesslayer/consentflowcontract/relationships/create.d.ts +4 -1
  37. package/dist/accesslayer/consentflowcontract/relationships/create.d.ts.map +1 -1
  38. package/dist/accesslayer/consentflowcontract/relationships/delete.d.ts.map +1 -1
  39. package/dist/accesslayer/consentflowcontract/relationships/read.d.ts +3 -2
  40. package/dist/accesslayer/consentflowcontract/relationships/read.d.ts.map +1 -1
  41. package/dist/accesslayer/consentflowcontract/relationships/recipients.d.ts +12 -0
  42. package/dist/accesslayer/consentflowcontract/relationships/recipients.d.ts.map +1 -0
  43. package/dist/accesslayer/consentflowcontract/relationships/smartResume.d.ts +12 -0
  44. package/dist/accesslayer/consentflowcontract/relationships/smartResume.d.ts.map +1 -0
  45. package/dist/accesslayer/consentflowcontract/relationships/update.d.ts +8 -5
  46. package/dist/accesslayer/consentflowcontract/relationships/update.d.ts.map +1 -1
  47. package/dist/accesslayer/credential/create.d.ts +2 -1
  48. package/dist/accesslayer/credential/create.d.ts.map +1 -1
  49. package/dist/accesslayer/credential/relationships/create.d.ts +4 -3
  50. package/dist/accesslayer/credential/relationships/create.d.ts.map +1 -1
  51. package/dist/accesslayer/inbox-credential/relationships/create.d.ts +2 -1
  52. package/dist/accesslayer/inbox-credential/relationships/create.d.ts.map +1 -1
  53. package/dist/accesslayer/inbox-credential/update.d.ts +2 -1
  54. package/dist/accesslayer/inbox-credential/update.d.ts.map +1 -1
  55. package/dist/accesslayer/presentation/read.d.ts.map +1 -1
  56. package/dist/accesslayer/presentation/relationships/create.d.ts +2 -2
  57. package/dist/accesslayer/presentation/relationships/create.d.ts.map +1 -1
  58. package/dist/accesslayer/presentation/relationships/read.d.ts.map +1 -1
  59. package/dist/accesslayer/share-link/abandon.d.ts +3 -0
  60. package/dist/accesslayer/share-link/abandon.d.ts.map +1 -0
  61. package/dist/accesslayer/share-link/attachment.d.ts +37 -0
  62. package/dist/accesslayer/share-link/attachment.d.ts.map +1 -0
  63. package/dist/accesslayer/share-link/cleanup.d.ts +6 -0
  64. package/dist/accesslayer/share-link/cleanup.d.ts.map +1 -0
  65. package/dist/accesslayer/share-link/errors.d.ts +8 -0
  66. package/dist/accesslayer/share-link/errors.d.ts.map +1 -0
  67. package/dist/accesslayer/share-link/finalize.d.ts +3 -0
  68. package/dist/accesslayer/share-link/finalize.d.ts.map +1 -0
  69. package/dist/accesslayer/share-link/helpers.d.ts +59 -0
  70. package/dist/accesslayer/share-link/helpers.d.ts.map +1 -0
  71. package/dist/accesslayer/share-link/index.d.ts +12 -0
  72. package/dist/accesslayer/share-link/index.d.ts.map +1 -0
  73. package/dist/accesslayer/share-link/list.d.ts +5 -0
  74. package/dist/accesslayer/share-link/list.d.ts.map +1 -0
  75. package/dist/accesslayer/share-link/read.d.ts +5 -0
  76. package/dist/accesslayer/share-link/read.d.ts.map +1 -0
  77. package/dist/accesslayer/share-link/receipt.d.ts +11 -0
  78. package/dist/accesslayer/share-link/receipt.d.ts.map +1 -0
  79. package/dist/accesslayer/share-link/recovery.d.ts +6 -0
  80. package/dist/accesslayer/share-link/recovery.d.ts.map +1 -0
  81. package/dist/accesslayer/share-link/reserve.d.ts +4 -0
  82. package/dist/accesslayer/share-link/reserve.d.ts.map +1 -0
  83. package/dist/accesslayer/share-link/revoke.d.ts +3 -0
  84. package/dist/accesslayer/share-link/revoke.d.ts.map +1 -0
  85. package/dist/accesslayer/share-link/transaction-execution.d.ts +18 -0
  86. package/dist/accesslayer/share-link/transaction-execution.d.ts.map +1 -0
  87. package/dist/accesslayer/share-link/transaction.d.ts +15 -0
  88. package/dist/accesslayer/share-link/transaction.d.ts.map +1 -0
  89. package/dist/accesslayer/share-link/types.d.ts +375 -0
  90. package/dist/accesslayer/share-link/types.d.ts.map +1 -0
  91. package/dist/app.d.ts +4 -0
  92. package/dist/app.d.ts.map +1 -1
  93. package/dist/cache/app-store.caches.d.ts +49 -0
  94. package/dist/cache/app-store.caches.d.ts.map +1 -1
  95. package/dist/config/applyDockerStageConfig.d.ts +2 -0
  96. package/dist/config/applyDockerStageConfig.d.ts.map +1 -0
  97. package/dist/config/environment.d.ts +14 -0
  98. package/dist/config/environment.d.ts.map +1 -1
  99. package/dist/config/serverlessFunctionEnv.test.d.ts +2 -0
  100. package/dist/config/serverlessFunctionEnv.test.d.ts.map +1 -0
  101. package/dist/config/stageConfig.d.ts +112 -0
  102. package/dist/config/stageConfig.d.ts.map +1 -0
  103. package/dist/config/stageConfig.test.d.ts +2 -0
  104. package/dist/config/stageConfig.test.d.ts.map +1 -0
  105. package/dist/constants/auth-grant.d.ts +2 -0
  106. package/dist/constants/auth-grant.d.ts.map +1 -1
  107. package/dist/didkit_wasm_bg.wasm +0 -0
  108. package/dist/docker-entry.d.ts +1 -1
  109. package/dist/docker-entry.d.ts.map +1 -1
  110. package/dist/helpers/app-manifest.helpers.d.ts +5 -0
  111. package/dist/helpers/app-manifest.helpers.d.ts.map +1 -0
  112. package/dist/helpers/boost.helpers.d.ts.map +1 -1
  113. package/dist/helpers/claim-hooks.helpers.d.ts +2 -1
  114. package/dist/helpers/claim-hooks.helpers.d.ts.map +1 -1
  115. package/dist/helpers/consent-referral.helpers.d.ts +2 -0
  116. package/dist/helpers/consent-referral.helpers.d.ts.map +1 -0
  117. package/dist/helpers/consent-scopes.helpers.d.ts +7 -0
  118. package/dist/helpers/consent-scopes.helpers.d.ts.map +1 -0
  119. package/dist/helpers/contract-event-maintenance.helpers.d.ts +3 -0
  120. package/dist/helpers/contract-event-maintenance.helpers.d.ts.map +1 -0
  121. package/dist/helpers/contract-events.helpers.d.ts +25 -0
  122. package/dist/helpers/contract-events.helpers.d.ts.map +1 -0
  123. package/dist/helpers/contract-requests.helpers.d.ts +19 -0
  124. package/dist/helpers/contract-requests.helpers.d.ts.map +1 -0
  125. package/dist/helpers/credentialSubject.helpers.d.ts +3 -0
  126. package/dist/helpers/credentialSubject.helpers.d.ts.map +1 -0
  127. package/dist/helpers/credentialSubject.helpers.test.d.ts +2 -0
  128. package/dist/helpers/credentialSubject.helpers.test.d.ts.map +1 -0
  129. package/dist/helpers/finalize-inbox.helpers.d.ts +3 -3
  130. package/dist/helpers/finalize-inbox.helpers.d.ts.map +1 -1
  131. package/dist/helpers/inbox.helpers.d.ts.map +1 -1
  132. package/dist/helpers/inline-template.helpers.d.ts +45 -0
  133. package/dist/helpers/inline-template.helpers.d.ts.map +1 -0
  134. package/dist/helpers/notificationMessages.d.ts +1 -1
  135. package/dist/helpers/notificationMessages.d.ts.map +1 -1
  136. package/dist/helpers/notificationQueue.helpers.d.ts.map +1 -1
  137. package/dist/helpers/notifications.helpers.d.ts +6 -0
  138. package/dist/helpers/notifications.helpers.d.ts.map +1 -1
  139. package/dist/helpers/presentation-metadata.d.ts +4 -0
  140. package/dist/helpers/presentation-metadata.d.ts.map +1 -0
  141. package/dist/helpers/presentation.helpers.d.ts +1 -1
  142. package/dist/helpers/presentation.helpers.d.ts.map +1 -1
  143. package/dist/helpers/profile.helpers.d.ts +2 -0
  144. package/dist/helpers/profile.helpers.d.ts.map +1 -1
  145. package/dist/helpers/share-content-client/adapters.d.ts +10 -0
  146. package/dist/helpers/share-content-client/adapters.d.ts.map +1 -0
  147. package/dist/helpers/share-content-client/canonical.d.ts +7 -0
  148. package/dist/helpers/share-content-client/canonical.d.ts.map +1 -0
  149. package/dist/helpers/share-content-client/client.d.ts +5 -0
  150. package/dist/helpers/share-content-client/client.d.ts.map +1 -0
  151. package/dist/helpers/share-content-client/config.d.ts +11 -0
  152. package/dist/helpers/share-content-client/config.d.ts.map +1 -0
  153. package/dist/helpers/share-content-client/index.d.ts +6 -0
  154. package/dist/helpers/share-content-client/index.d.ts.map +1 -0
  155. package/dist/helpers/share-content-client/responses.d.ts +16 -0
  156. package/dist/helpers/share-content-client/responses.d.ts.map +1 -0
  157. package/dist/helpers/share-content-client/types.d.ts +145 -0
  158. package/dist/helpers/share-content-client/types.d.ts.map +1 -0
  159. package/dist/helpers/share-link-attachment-access.d.ts +4 -0
  160. package/dist/helpers/share-link-attachment-access.d.ts.map +1 -0
  161. package/dist/helpers/share-link-attachment.d.ts +18 -0
  162. package/dist/helpers/share-link-attachment.d.ts.map +1 -0
  163. package/dist/helpers/share-link-coordinator/attachment-stat.d.ts +5 -0
  164. package/dist/helpers/share-link-coordinator/attachment-stat.d.ts.map +1 -0
  165. package/dist/helpers/share-link-coordinator/budget-helpers.d.ts +5 -0
  166. package/dist/helpers/share-link-coordinator/budget-helpers.d.ts.map +1 -0
  167. package/dist/helpers/share-link-coordinator/cleanup-runner.d.ts +3 -0
  168. package/dist/helpers/share-link-coordinator/cleanup-runner.d.ts.map +1 -0
  169. package/dist/helpers/share-link-coordinator/coordinator.d.ts +4 -0
  170. package/dist/helpers/share-link-coordinator/coordinator.d.ts.map +1 -0
  171. package/dist/helpers/share-link-coordinator/index.d.ts +5 -0
  172. package/dist/helpers/share-link-coordinator/index.d.ts.map +1 -0
  173. package/dist/helpers/share-link-coordinator/recovery-runner.d.ts +9 -0
  174. package/dist/helpers/share-link-coordinator/recovery-runner.d.ts.map +1 -0
  175. package/dist/helpers/share-link-coordinator/runtime.d.ts +11 -0
  176. package/dist/helpers/share-link-coordinator/runtime.d.ts.map +1 -0
  177. package/dist/helpers/share-link-coordinator/stat.d.ts +4 -0
  178. package/dist/helpers/share-link-coordinator/stat.d.ts.map +1 -0
  179. package/dist/helpers/share-link-coordinator/types.d.ts +160 -0
  180. package/dist/helpers/share-link-coordinator/types.d.ts.map +1 -0
  181. package/dist/helpers/share-link-lifecycle/index.d.ts +5 -0
  182. package/dist/helpers/share-link-lifecycle/index.d.ts.map +1 -0
  183. package/dist/helpers/share-link-lifecycle/lease.helpers.d.ts +4 -0
  184. package/dist/helpers/share-link-lifecycle/lease.helpers.d.ts.map +1 -0
  185. package/dist/helpers/share-link-lifecycle/recovery.helpers.d.ts +21 -0
  186. package/dist/helpers/share-link-lifecycle/recovery.helpers.d.ts.map +1 -0
  187. package/dist/helpers/share-link-lifecycle/request-hash.helpers.d.ts +9 -0
  188. package/dist/helpers/share-link-lifecycle/request-hash.helpers.d.ts.map +1 -0
  189. package/dist/helpers/share-link-lifecycle/types.d.ts +14 -0
  190. package/dist/helpers/share-link-lifecycle/types.d.ts.map +1 -0
  191. package/dist/helpers/share-link-maintenance/budget.d.ts +12 -0
  192. package/dist/helpers/share-link-maintenance/budget.d.ts.map +1 -0
  193. package/dist/helpers/share-link-maintenance/config.d.ts +48 -0
  194. package/dist/helpers/share-link-maintenance/config.d.ts.map +1 -0
  195. package/dist/helpers/share-link-maintenance/index.d.ts +8 -0
  196. package/dist/helpers/share-link-maintenance/index.d.ts.map +1 -0
  197. package/dist/helpers/share-link-maintenance/runner.d.ts +20 -0
  198. package/dist/helpers/share-link-maintenance/runner.d.ts.map +1 -0
  199. package/dist/helpers/share-link-maintenance/runtime.d.ts +38 -0
  200. package/dist/helpers/share-link-maintenance/runtime.d.ts.map +1 -0
  201. package/dist/helpers/share-link-maintenance/scheduler.d.ts +18 -0
  202. package/dist/helpers/share-link-maintenance/scheduler.d.ts.map +1 -0
  203. package/dist/helpers/share-link-maintenance/telemetry.d.ts +5 -0
  204. package/dist/helpers/share-link-maintenance/telemetry.d.ts.map +1 -0
  205. package/dist/helpers/share-link-maintenance/types.d.ts +56 -0
  206. package/dist/helpers/share-link-maintenance/types.d.ts.map +1 -0
  207. package/dist/helpers/share-link-owner/config.d.ts +16 -0
  208. package/dist/helpers/share-link-owner/config.d.ts.map +1 -0
  209. package/dist/helpers/share-link-owner/diagnostics.d.ts +26 -0
  210. package/dist/helpers/share-link-owner/diagnostics.d.ts.map +1 -0
  211. package/dist/helpers/share-link-owner/lazy-initializer.d.ts +2 -0
  212. package/dist/helpers/share-link-owner/lazy-initializer.d.ts.map +1 -0
  213. package/dist/helpers/share-link-owner-projection.d.ts +4 -0
  214. package/dist/helpers/share-link-owner-projection.d.ts.map +1 -0
  215. package/dist/helpers/share-link-passcode-abuse.d.ts +2 -0
  216. package/dist/helpers/share-link-passcode-abuse.d.ts.map +1 -0
  217. package/dist/helpers/share-link-passcode.d.ts +6 -0
  218. package/dist/helpers/share-link-passcode.d.ts.map +1 -0
  219. package/dist/helpers/share-link-policy/index.d.ts +4 -0
  220. package/dist/helpers/share-link-policy/index.d.ts.map +1 -0
  221. package/dist/helpers/share-link-policy/production.d.ts +11 -0
  222. package/dist/helpers/share-link-policy/production.d.ts.map +1 -0
  223. package/dist/helpers/share-link-policy/resolver.d.ts +6 -0
  224. package/dist/helpers/share-link-policy/resolver.d.ts.map +1 -0
  225. package/dist/helpers/share-link-policy/types.d.ts +22 -0
  226. package/dist/helpers/share-link-policy/types.d.ts.map +1 -0
  227. package/dist/helpers/share-link-public/config.d.ts +13 -0
  228. package/dist/helpers/share-link-public/config.d.ts.map +1 -0
  229. package/dist/helpers/share-link-view-notification.d.ts +2 -0
  230. package/dist/helpers/share-link-view-notification.d.ts.map +1 -0
  231. package/dist/helpers/signingAuthority.helpers.d.ts.map +1 -1
  232. package/dist/helpers/smartResume.helpers.d.ts +3 -0
  233. package/dist/helpers/smartResume.helpers.d.ts.map +1 -0
  234. package/dist/index.js +2 -2
  235. package/dist/models/AppManifestVersion.d.ts +20 -0
  236. package/dist/models/AppManifestVersion.d.ts.map +1 -0
  237. package/dist/models/AppStoreListing.d.ts +13 -0
  238. package/dist/models/AppStoreListing.d.ts.map +1 -1
  239. package/dist/models/ConsentFlowContract.d.ts +13 -2
  240. package/dist/models/ConsentFlowContract.d.ts.map +1 -1
  241. package/dist/models/ConsentFlowTerms.d.ts.map +1 -1
  242. package/dist/models/ConsentFlowTransaction.d.ts.map +1 -1
  243. package/dist/models/Integration.d.ts +2 -0
  244. package/dist/models/Integration.d.ts.map +1 -1
  245. package/dist/models/Presentation.d.ts +2 -0
  246. package/dist/models/Presentation.d.ts.map +1 -1
  247. package/dist/models/Profile.d.ts +2 -0
  248. package/dist/models/Profile.d.ts.map +1 -1
  249. package/dist/models/ShareLink.d.ts +46 -0
  250. package/dist/models/ShareLink.d.ts.map +1 -0
  251. package/dist/models/ShareViewReceipt.d.ts +22 -0
  252. package/dist/models/ShareViewReceipt.d.ts.map +1 -0
  253. package/dist/models/index.d.ts +2 -0
  254. package/dist/models/index.d.ts.map +1 -1
  255. package/dist/models/share-link-constraints.d.ts +3 -0
  256. package/dist/models/share-link-constraints.d.ts.map +1 -0
  257. package/dist/openapi.d.ts +1 -1
  258. package/dist/openapi.d.ts.map +1 -1
  259. package/dist/public-share-link-http.d.ts +4 -0
  260. package/dist/public-share-link-http.d.ts.map +1 -0
  261. package/dist/routes/app-store.d.ts +619 -0
  262. package/dist/routes/app-store.d.ts.map +1 -1
  263. package/dist/routes/boosts.d.ts +2 -2
  264. package/dist/routes/boosts.d.ts.map +1 -1
  265. package/dist/routes/contracts.d.ts +148 -5
  266. package/dist/routes/contracts.d.ts.map +1 -1
  267. package/dist/routes/credentials.d.ts +35 -1
  268. package/dist/routes/credentials.d.ts.map +1 -1
  269. package/dist/routes/inbox.d.ts +52 -2
  270. package/dist/routes/inbox.d.ts.map +1 -1
  271. package/dist/routes/index.d.ts +153 -0
  272. package/dist/routes/index.d.ts.map +1 -1
  273. package/dist/routes/presentations.d.ts +1 -0
  274. package/dist/routes/presentations.d.ts.map +1 -1
  275. package/dist/routes/profile-manager.d.ts.map +1 -1
  276. package/dist/routes/profiles.d.ts.map +1 -1
  277. package/dist/routes/public-share-links.d.ts +285 -0
  278. package/dist/routes/public-share-links.d.ts.map +1 -0
  279. package/dist/routes/share-links.d.ts +1005 -0
  280. package/dist/routes/share-links.d.ts.map +1 -0
  281. package/dist/routes/test.d.ts +5 -0
  282. package/dist/routes/test.d.ts.map +1 -1
  283. package/dist/routes/workflows.d.ts.map +1 -1
  284. package/dist/services/delivery/adapters/postmark.adapter.d.ts.map +1 -1
  285. package/dist/types/app-manifest.d.ts +339 -0
  286. package/dist/types/app-manifest.d.ts.map +1 -0
  287. package/dist/types/app-store-listing.d.ts +34 -0
  288. package/dist/types/app-store-listing.d.ts.map +1 -1
  289. package/dist/types/consentflowcontract.d.ts +31 -4
  290. package/dist/types/consentflowcontract.d.ts.map +1 -1
  291. package/dist/types/credential-refresh.d.ts +1 -1
  292. package/esbuildPlugins.cjs +1 -0
  293. package/lambda.ts +49 -192
  294. package/lambdaApp.ts +203 -0
  295. package/package.json +25 -17
  296. package/scripts/export-openapi.ts +20 -0
  297. package/scripts/offline-schema-environment.ts +18 -0
  298. package/scripts/seed-demo-persona.ts +425 -0
  299. package/scripts/verify-python-contracts.ts +72 -0
  300. package/serverless-local.yml +3 -6
  301. package/serverless.function-env.cjs +50 -0
  302. package/serverless.local.yml +0 -1
  303. package/serverless.yml +44 -55
  304. package/shareLinkMaintenanceLambda.ts +18 -0
  305. package/shareLinkMaintenanceLambdaApp.ts +50 -0
  306. package/src/accesslayer/app-manifest-version/create.ts +57 -0
  307. package/src/accesslayer/app-manifest-version/read.ts +129 -0
  308. package/src/accesslayer/app-manifest-version/update.ts +61 -0
  309. package/src/accesslayer/app-store-listing/read.ts +6 -0
  310. package/src/accesslayer/app-store-listing/relationships/create.ts +20 -0
  311. package/src/accesslayer/app-store-listing/relationships/read.ts +24 -1
  312. package/src/accesslayer/app-store-listing/update.ts +15 -0
  313. package/src/accesslayer/boost/relationships/create.ts +8 -2
  314. package/src/accesslayer/consentflowcontract/create.ts +81 -8
  315. package/src/accesslayer/consentflowcontract/read.ts +84 -10
  316. package/src/accesslayer/consentflowcontract/relationships/create.ts +125 -109
  317. package/src/accesslayer/consentflowcontract/relationships/delete.ts +1 -0
  318. package/src/accesslayer/consentflowcontract/relationships/read.ts +184 -108
  319. package/src/accesslayer/consentflowcontract/relationships/recipients.ts +125 -0
  320. package/src/accesslayer/consentflowcontract/relationships/smartResume.ts +125 -0
  321. package/src/accesslayer/consentflowcontract/relationships/update.ts +255 -217
  322. package/src/accesslayer/credential/create.test.ts +2 -115
  323. package/src/accesslayer/credential/create.ts +11 -6
  324. package/src/accesslayer/credential/relationships/create.ts +17 -10
  325. package/src/accesslayer/inbox-credential/relationships/create.ts +70 -48
  326. package/src/accesslayer/inbox-credential/update.ts +4 -2
  327. package/src/accesslayer/presentation/read.ts +57 -25
  328. package/src/accesslayer/presentation/relationships/create.ts +54 -11
  329. package/src/accesslayer/presentation/relationships/read.ts +21 -6
  330. package/src/accesslayer/share-link/abandon.ts +120 -0
  331. package/src/accesslayer/share-link/attachment.ts +360 -0
  332. package/src/accesslayer/share-link/cleanup.ts +271 -0
  333. package/src/accesslayer/share-link/errors.ts +32 -0
  334. package/src/accesslayer/share-link/finalize.ts +313 -0
  335. package/src/accesslayer/share-link/helpers.ts +450 -0
  336. package/src/accesslayer/share-link/index.ts +11 -0
  337. package/src/accesslayer/share-link/list.ts +162 -0
  338. package/src/accesslayer/share-link/read.ts +107 -0
  339. package/src/accesslayer/share-link/receipt.ts +548 -0
  340. package/src/accesslayer/share-link/recovery.ts +565 -0
  341. package/src/accesslayer/share-link/reserve.ts +763 -0
  342. package/src/accesslayer/share-link/revoke.ts +232 -0
  343. package/src/accesslayer/share-link/transaction-execution.ts +72 -0
  344. package/src/accesslayer/share-link/transaction.ts +126 -0
  345. package/src/accesslayer/share-link/types.ts +606 -0
  346. package/src/app.ts +6 -0
  347. package/src/cache/app-store.caches.ts +35 -0
  348. package/src/config/applyDockerStageConfig.ts +6 -0
  349. package/src/config/environment.test.ts +17 -12
  350. package/src/config/environment.ts +15 -0
  351. package/src/config/serverlessFunctionEnv.test.ts +105 -0
  352. package/src/config/stageConfig.test.ts +25 -0
  353. package/src/config/stageConfig.ts +24 -0
  354. package/src/constants/auth-grant.ts +5 -0
  355. package/src/docker-entry.ts +81 -0
  356. package/src/helpers/app-manifest.helpers.ts +185 -0
  357. package/src/helpers/boost.helpers.ts +4 -31
  358. package/src/helpers/claim-hooks.helpers.ts +20 -7
  359. package/src/helpers/consent-referral.helpers.ts +6 -0
  360. package/src/helpers/consent-scopes.helpers.ts +58 -0
  361. package/src/helpers/contract-event-maintenance.helpers.ts +43 -0
  362. package/src/helpers/contract-events.helpers.ts +540 -0
  363. package/src/helpers/contract-requests.helpers.ts +211 -0
  364. package/src/helpers/credentialSubject.helpers.test.ts +114 -0
  365. package/src/helpers/credentialSubject.helpers.ts +40 -0
  366. package/src/helpers/finalize-inbox.helpers.ts +163 -44
  367. package/src/helpers/inbox.helpers.ts +58 -70
  368. package/src/helpers/inline-template.helpers.ts +560 -0
  369. package/src/helpers/notificationMessages.ts +77 -1
  370. package/src/helpers/notificationQueue.helpers.ts +23 -5
  371. package/src/helpers/notifications.helpers.ts +25 -1
  372. package/src/helpers/presentation-metadata.ts +41 -0
  373. package/src/helpers/presentation.helpers.ts +27 -20
  374. package/src/helpers/profile.helpers.ts +13 -0
  375. package/src/helpers/share-content-client/adapters.ts +55 -0
  376. package/src/helpers/share-content-client/canonical.ts +25 -0
  377. package/src/helpers/share-content-client/client.ts +440 -0
  378. package/src/helpers/share-content-client/config.ts +189 -0
  379. package/src/helpers/share-content-client/index.ts +27 -0
  380. package/src/helpers/share-content-client/responses.ts +273 -0
  381. package/src/helpers/share-content-client/types.ts +253 -0
  382. package/src/helpers/share-link-attachment-access.ts +87 -0
  383. package/src/helpers/share-link-attachment.ts +115 -0
  384. package/src/helpers/share-link-coordinator/attachment-stat.ts +41 -0
  385. package/src/helpers/share-link-coordinator/budget-helpers.ts +53 -0
  386. package/src/helpers/share-link-coordinator/cleanup-runner.ts +286 -0
  387. package/src/helpers/share-link-coordinator/coordinator.ts +727 -0
  388. package/src/helpers/share-link-coordinator/index.ts +8 -0
  389. package/src/helpers/share-link-coordinator/recovery-runner.ts +443 -0
  390. package/src/helpers/share-link-coordinator/runtime.ts +88 -0
  391. package/src/helpers/share-link-coordinator/stat.ts +30 -0
  392. package/src/helpers/share-link-coordinator/types.ts +353 -0
  393. package/src/helpers/share-link-lifecycle/index.ts +4 -0
  394. package/src/helpers/share-link-lifecycle/lease.helpers.ts +35 -0
  395. package/src/helpers/share-link-lifecycle/recovery.helpers.ts +173 -0
  396. package/src/helpers/share-link-lifecycle/request-hash.helpers.ts +130 -0
  397. package/src/helpers/share-link-lifecycle/types.ts +58 -0
  398. package/src/helpers/share-link-maintenance/budget.ts +63 -0
  399. package/src/helpers/share-link-maintenance/config.ts +312 -0
  400. package/src/helpers/share-link-maintenance/index.ts +24 -0
  401. package/src/helpers/share-link-maintenance/runner.ts +251 -0
  402. package/src/helpers/share-link-maintenance/runtime.ts +340 -0
  403. package/src/helpers/share-link-maintenance/scheduler.ts +126 -0
  404. package/src/helpers/share-link-maintenance/telemetry.ts +73 -0
  405. package/src/helpers/share-link-maintenance/types.ts +91 -0
  406. package/src/helpers/share-link-owner/config.ts +48 -0
  407. package/src/helpers/share-link-owner/diagnostics.ts +89 -0
  408. package/src/helpers/share-link-owner/lazy-initializer.ts +29 -0
  409. package/src/helpers/share-link-owner-projection.ts +54 -0
  410. package/src/helpers/share-link-passcode-abuse.ts +36 -0
  411. package/src/helpers/share-link-passcode.ts +47 -0
  412. package/src/helpers/share-link-policy/index.ts +7 -0
  413. package/src/helpers/share-link-policy/production.ts +108 -0
  414. package/src/helpers/share-link-policy/resolver.ts +113 -0
  415. package/src/helpers/share-link-policy/types.ts +56 -0
  416. package/src/helpers/share-link-public/config.ts +41 -0
  417. package/src/helpers/share-link-view-notification.ts +18 -0
  418. package/src/helpers/signingAuthority.helpers.ts +23 -14
  419. package/src/helpers/smartResume.helpers.ts +123 -0
  420. package/src/models/AppManifestVersion.ts +43 -0
  421. package/src/models/AppStoreListing.ts +32 -0
  422. package/src/models/ConsentFlowContract.ts +34 -3
  423. package/src/models/ConsentFlowTerms.ts +10 -0
  424. package/src/models/ConsentFlowTransaction.ts +3 -0
  425. package/src/models/Integration.ts +2 -0
  426. package/src/models/Presentation.ts +2 -2
  427. package/src/models/Profile.ts +3 -2
  428. package/src/models/ShareLink.ts +134 -0
  429. package/src/models/ShareViewReceipt.ts +69 -0
  430. package/src/models/index.ts +25 -0
  431. package/src/models/share-link-constraints.ts +98 -0
  432. package/src/openapi.ts +44 -8
  433. package/src/public-share-link-http.ts +49 -0
  434. package/src/routes/app-store.ts +1056 -38
  435. package/src/routes/boosts.ts +14 -25
  436. package/src/routes/contracts.ts +384 -273
  437. package/src/routes/inbox.ts +4 -2
  438. package/src/routes/index.ts +142 -44
  439. package/src/routes/presentations.ts +19 -3
  440. package/src/routes/profile-manager.ts +29 -2
  441. package/src/routes/profiles.ts +29 -6
  442. package/src/routes/public-share-links.ts +983 -0
  443. package/src/routes/share-links.ts +709 -0
  444. package/src/routes/workflows.ts +3 -2
  445. package/src/services/delivery/adapters/postmark.adapter.ts +4 -1
  446. package/src/types/app-manifest.ts +28 -0
  447. package/src/types/app-store-listing.ts +13 -0
  448. package/src/types/consentflowcontract.ts +25 -4
  449. package/test/app-manifest.helpers.spec.ts +170 -0
  450. package/test/app-manifest.routes.spec.ts +299 -0
  451. package/test/app-store-listing-updates.spec.ts +236 -0
  452. package/test/app-store-listing.spec.ts +65 -3
  453. package/test/consent-data-boundaries.spec.ts +352 -0
  454. package/test/consent-recipients.spec.ts +513 -0
  455. package/test/consent-scopes.helpers.spec.ts +67 -0
  456. package/test/consentflow.spec.ts +63 -2
  457. package/test/contract-requests.spec.ts +1588 -0
  458. package/test/credential-storage.neo4j.spec.ts +122 -0
  459. package/test/dids.spec.ts +10 -1
  460. package/test/guardian-gated-routes.spec.ts +49 -0
  461. package/test/helpers/share-link-fixtures.ts +94 -0
  462. package/test/inbox-security.e2e.ts +26 -10
  463. package/test/inbox.spec.ts +184 -8
  464. package/test/inline-template.helpers.spec.ts +49 -0
  465. package/test/managed-recipient-inbox.spec.ts +152 -0
  466. package/test/notificationMessages.spec.ts +13 -0
  467. package/test/openapi.spec.ts +14 -53
  468. package/test/presentations.spec.ts +54 -6
  469. package/test/profiles.spec.ts +97 -1
  470. package/test/share-content-client.contract.spec.ts +365 -0
  471. package/test/share-content-client.unit.spec.ts +462 -0
  472. package/test/share-link-abuse.unit.spec.ts +65 -0
  473. package/test/share-link-attachment.neo4j.spec.ts +262 -0
  474. package/test/share-link-attachment.unit.spec.ts +244 -0
  475. package/test/share-link-coordinator.neo4j.spec.ts +684 -0
  476. package/test/share-link-coordinator.unit.spec.ts +990 -0
  477. package/test/share-link-dependency-diagnostics.unit.spec.ts +127 -0
  478. package/test/share-link-lifecycle.neo4j.spec.ts +1411 -0
  479. package/test/share-link-lifecycle.unit.spec.ts +205 -0
  480. package/test/share-link-list-cursor.unit.spec.ts +86 -0
  481. package/test/share-link-list.neo4j.spec.ts +324 -0
  482. package/test/share-link-maintenance.neo4j.spec.ts +355 -0
  483. package/test/share-link-maintenance.unit.spec.ts +1140 -0
  484. package/test/share-link-owner-policy.unit.spec.ts +210 -0
  485. package/test/share-link-owner-route.unit.spec.ts +820 -0
  486. package/test/share-link-owner-runtime.unit.spec.ts +102 -0
  487. package/test/share-link-passcode.unit.spec.ts +29 -0
  488. package/test/share-link-policy.unit.spec.ts +149 -0
  489. package/test/share-link-presentation-metadata.unit.spec.ts +49 -0
  490. package/test/share-link-production-policy.unit.spec.ts +126 -0
  491. package/test/share-link-public-config.unit.spec.ts +64 -0
  492. package/test/share-link-public-http-adapter.unit.spec.ts +315 -0
  493. package/test/share-link-public-route.unit.spec.ts +1079 -0
  494. package/test/share-link-receipt.neo4j.spec.ts +943 -0
  495. package/test/share-link-recovery.neo4j.spec.ts +935 -0
  496. package/test/share-link-recovery.unit.spec.ts +726 -0
  497. package/test/share-link-service-policy.neo4j.spec.ts +403 -0
  498. package/test/signing-authority-encryption.spec.ts +75 -0
  499. package/test/smart-resume-consent.spec.ts +233 -0
  500. package/test/smart-resume-upload.spec.ts +65 -0
  501. package/tsconfig.build.json +1 -1
  502. package/tsconfig.json +1 -0
  503. package/vitest.config.ts +14 -0
  504. package/vitest.inbox-e2e.config.ts +2 -0
  505. package/vitest.share-links-neo4j.config.ts +19 -0
  506. package/vitest.share-links-unit.config.ts +28 -0
  507. package/workerLambda.test.ts +100 -0
@@ -0,0 +1,560 @@
1
+ import crypto from 'node:crypto';
2
+
3
+ import { z } from 'zod';
4
+ import { TRPCError } from '@trpc/server';
5
+ import type { UnsignedVC } from '@learncard/types';
6
+ import type { InlineCredentialTemplate, VariableManifest } from '@learncard/partner-connect-core';
7
+ import {
8
+ canonicalJsonString,
9
+ compileInlineTemplate,
10
+ validateInlineTemplate,
11
+ validateTemplateData,
12
+ } from '@learncard/partner-connect-core';
13
+
14
+ import { getBoostUri } from '@helpers/boost.helpers';
15
+ import { getAppDidWeb, getDidWeb } from '@helpers/did.helpers';
16
+ import { getDidWebLearnCard, getLearnCard } from '@helpers/learnCard.helpers';
17
+ import { inflateObject } from '@helpers/objects.helpers';
18
+ import { createBoostForListing } from '@accesslayer/boost/create';
19
+ import { updateBoost } from '@accesslayer/boost/update';
20
+ import { removeBoostFromListing } from '@accesslayer/app-store-listing/relationships/delete';
21
+ import {
22
+ associateBoostWithListing,
23
+ associateListingWithSigningAuthority,
24
+ } from '@accesslayer/app-store-listing/relationships/create';
25
+ import { getBoostForListingByTemplateAlias } from '@accesslayer/app-store-listing/relationships/read';
26
+ import { upsertSigningAuthority } from '@accesslayer/signing-authority/create';
27
+ import { createUseSigningAuthorityRelationship } from '@accesslayer/signing-authority/relationships/create';
28
+ import {
29
+ getPrimarySigningAuthorityForListing,
30
+ getPrimarySigningAuthorityForIntegration,
31
+ getPrimarySigningAuthorityForUser,
32
+ } from '@accesslayer/signing-authority/relationships/read';
33
+ import {
34
+ invalidateBoostForListingCache,
35
+ invalidateListingSigningAuthorityCache,
36
+ } from '@cache/app-store.caches';
37
+ import { deleteDidDocForProfile } from '@cache/did-docs';
38
+ import { neogma } from '@instance';
39
+ import { environment } from '@environment';
40
+ import { Boost, type BoostInstance } from '@models';
41
+ import type { AppStoreListingType } from 'types/app-store-listing';
42
+ import type { IntegrationType } from 'types/integration';
43
+ import type { ProfileType, SigningAuthorityForUserType } from 'types/profile';
44
+
45
+ type InlineTemplateBoostMeta = {
46
+ integrationId?: string;
47
+ templateAlias?: string;
48
+ inlineTemplateHash?: string;
49
+ inlineTemplateVersion?: number;
50
+ inlineVariableManifest?: string;
51
+ source?: string;
52
+ supersededAt?: string;
53
+ supersededBy?: string;
54
+ };
55
+
56
+ type UpsertInlineTemplateBoostResult = {
57
+ boost: BoostInstance;
58
+ boostUri: string;
59
+ templateVersion: number;
60
+ manifest: VariableManifest;
61
+ };
62
+
63
+ const INLINE_TEMPLATE_SOURCE = 'partner-connect-inline';
64
+ const DEFAULT_SIGNING_AUTHORITY_ENDPOINT =
65
+ environment.SIGNING_AUTHORITY_ENDPOINT ?? 'http://localhost:5100/api';
66
+ const MAX_SIGNING_AUTHORITY_NAME_LENGTH = 15;
67
+ const SIGNING_AUTHORITY_PREFIX = 'app-';
68
+
69
+ const getBoostMeta = (boost: BoostInstance): InlineTemplateBoostMeta => {
70
+ const inflated = inflateObject<Record<string, unknown>>(
71
+ boost.getDataValues() as Record<string, unknown>
72
+ );
73
+ return (inflated.meta as InlineTemplateBoostMeta | undefined) ?? {};
74
+ };
75
+
76
+ export const readInlineTemplateBoostMeta = async (
77
+ boostOrId: BoostInstance | string
78
+ ): Promise<InlineTemplateBoostMeta> => {
79
+ const boostId = typeof boostOrId === 'string' ? boostOrId : boostOrId.id;
80
+ const inMemoryMeta = typeof boostOrId === 'string' ? undefined : getBoostMeta(boostOrId);
81
+
82
+ if (
83
+ inMemoryMeta?.inlineTemplateHash ||
84
+ typeof inMemoryMeta?.inlineTemplateVersion === 'number' ||
85
+ inMemoryMeta?.templateAlias
86
+ ) {
87
+ return inMemoryMeta;
88
+ }
89
+
90
+ const result = await neogma.queryRunner.run(
91
+ `MATCH (boost:Boost {id: $boostId})
92
+ RETURN boost.\`meta.integrationId\` AS integrationId,
93
+ boost.\`meta.templateAlias\` AS templateAlias,
94
+ boost.\`meta.inlineTemplateHash\` AS inlineTemplateHash,
95
+ boost.\`meta.inlineTemplateVersion\` AS inlineTemplateVersion,
96
+ boost.\`meta.inlineVariableManifest\` AS inlineVariableManifest,
97
+ boost.\`meta.source\` AS source,
98
+ boost.\`meta.supersededAt\` AS supersededAt,
99
+ boost.\`meta.supersededBy\` AS supersededBy`,
100
+ { boostId }
101
+ );
102
+
103
+ const record = result.records[0];
104
+
105
+ if (!record) {
106
+ return {};
107
+ }
108
+
109
+ const rawVersion = record.get('inlineTemplateVersion') as { toNumber?: () => number } | number;
110
+
111
+ return {
112
+ integrationId: record.get('integrationId') ?? undefined,
113
+ templateAlias: record.get('templateAlias') ?? undefined,
114
+ inlineTemplateHash: record.get('inlineTemplateHash') ?? undefined,
115
+ inlineTemplateVersion:
116
+ typeof rawVersion === 'number' ? rawVersion : rawVersion?.toNumber?.(),
117
+ inlineVariableManifest: record.get('inlineVariableManifest') ?? undefined,
118
+ source: record.get('source') ?? undefined,
119
+ supersededAt: record.get('supersededAt') ?? undefined,
120
+ supersededBy: record.get('supersededBy') ?? undefined,
121
+ };
122
+ };
123
+
124
+ const joinTemplateErrors = (errors: Array<{ message: string }>): string => {
125
+ return errors.map(error => error.message).join('; ');
126
+ };
127
+
128
+ export const getInlineTemplateVersion = (boost: BoostInstance): number | undefined => {
129
+ const version = getBoostMeta(boost).inlineTemplateVersion;
130
+ return typeof version === 'number' && Number.isFinite(version) ? version : undefined;
131
+ };
132
+
133
+ export const getInlineTemplateHashForBoost = (boost: BoostInstance): string | undefined => {
134
+ const inlineTemplateHash = getBoostMeta(boost).inlineTemplateHash;
135
+ return typeof inlineTemplateHash === 'string' ? inlineTemplateHash : undefined;
136
+ };
137
+
138
+ export const isInlineTemplateBoostVersionMatch = (
139
+ boost: BoostInstance,
140
+ templateHash: string,
141
+ templateVersion: number
142
+ ): boolean => {
143
+ return (
144
+ getInlineTemplateHashForBoost(boost) === templateHash &&
145
+ getInlineTemplateVersion(boost) === templateVersion
146
+ );
147
+ };
148
+
149
+ export const computeInlineTemplateHash = (
150
+ template: InlineCredentialTemplate
151
+ ): {
152
+ credentialTemplateJson: string;
153
+ variableManifest: VariableManifest;
154
+ category: string;
155
+ walletSkills?: unknown;
156
+ contentHash: string;
157
+ } => {
158
+ const compiled = compileInlineTemplate(template);
159
+ const contentHash = crypto
160
+ .createHash('sha256')
161
+ .update(
162
+ canonicalJsonString({
163
+ credentialTemplateJson: compiled.credentialTemplateJson,
164
+ category: compiled.category,
165
+ walletSkills: compiled.walletSkills,
166
+ })
167
+ )
168
+ .digest('hex');
169
+
170
+ return {
171
+ ...compiled,
172
+ contentHash,
173
+ };
174
+ };
175
+
176
+ export const validateInlineTemplateOrThrow = (template: InlineCredentialTemplate): void => {
177
+ const errors = validateInlineTemplate(template);
178
+
179
+ if (errors.length === 0) {
180
+ return;
181
+ }
182
+
183
+ throw new TRPCError({
184
+ code: 'BAD_REQUEST',
185
+ message: `TEMPLATE_INVALID: ${joinTemplateErrors(errors)}`,
186
+ });
187
+ };
188
+
189
+ export const validateInlineTemplateDataOrThrow = (
190
+ manifest: VariableManifest,
191
+ templateData: Record<string, unknown> | undefined
192
+ ): void => {
193
+ const errors = validateTemplateData(manifest, templateData);
194
+
195
+ if (errors.length === 0) {
196
+ return;
197
+ }
198
+
199
+ throw new TRPCError({
200
+ code: 'BAD_REQUEST',
201
+ message: `TEMPLATE_DATA_INVALID: ${joinTemplateErrors(errors)}`,
202
+ });
203
+ };
204
+
205
+ const ensureListingSigningAuthorityRelationship = async (
206
+ listing: AppStoreListingType,
207
+ signingAuthority: SigningAuthorityForUserType
208
+ ): Promise<void> => {
209
+ const listingSigningAuthority = await getPrimarySigningAuthorityForListing(listing);
210
+
211
+ if (
212
+ listingSigningAuthority &&
213
+ listingSigningAuthority.signingAuthority.endpoint ===
214
+ signingAuthority.signingAuthority.endpoint &&
215
+ listingSigningAuthority.relationship.name === signingAuthority.relationship.name &&
216
+ listingSigningAuthority.relationship.did === signingAuthority.relationship.did
217
+ ) {
218
+ return;
219
+ }
220
+
221
+ await associateListingWithSigningAuthority(
222
+ listing.listing_id,
223
+ signingAuthority.signingAuthority.endpoint,
224
+ {
225
+ name: signingAuthority.relationship.name,
226
+ did: signingAuthority.relationship.did,
227
+ isPrimary: true,
228
+ }
229
+ );
230
+
231
+ invalidateListingSigningAuthorityCache(listing.listing_id);
232
+ };
233
+
234
+ const buildManagedSigningAuthorityName = (listing: AppStoreListingType): string => {
235
+ const base = (listing.slug || listing.listing_id).toLowerCase().replace(/[^a-z0-9-]/g, '');
236
+ const trimmed = base.slice(
237
+ 0,
238
+ MAX_SIGNING_AUTHORITY_NAME_LENGTH - SIGNING_AUTHORITY_PREFIX.length
239
+ );
240
+ return `${SIGNING_AUTHORITY_PREFIX}${trimmed || 'app'}`.slice(
241
+ 0,
242
+ MAX_SIGNING_AUTHORITY_NAME_LENGTH
243
+ );
244
+ };
245
+
246
+ const ManagedSigningAuthorityResponseValidator = z.object({ did: z.string().min(1) });
247
+
248
+ /**
249
+ * Gets or creates the app's signing authority through LCA API, which owns key generation
250
+ * and encrypts the seed at rest. Brain authenticates as a trusted service DID.
251
+ */
252
+ const provisionManagedSigningAuthority = async (
253
+ endpoint: string,
254
+ ownerDid: string,
255
+ name: string
256
+ ): Promise<string> => {
257
+ // Tests mock signing-authority issuance, so derive a stable DID without calling LCA API.
258
+ if (environment.NODE_ENV === 'test') {
259
+ return (await getLearnCard('e'.repeat(64))).id.did();
260
+ }
261
+
262
+ try {
263
+ const learnCard = await getDidWebLearnCard();
264
+ const didJwt = await learnCard.invoke.getDidAuthVp({ proofFormat: 'jwt' });
265
+
266
+ const response = await fetch(`${endpoint}/signing-authority/managed`, {
267
+ method: 'POST',
268
+ headers: {
269
+ 'Content-Type': 'application/json',
270
+ 'Authorization': `Bearer ${didJwt}`,
271
+ },
272
+ body: JSON.stringify({ ownerDid, name }),
273
+ });
274
+
275
+ if (!response.ok) {
276
+ throw new Error(`LCA API responded with ${response.status}`);
277
+ }
278
+
279
+ return ManagedSigningAuthorityResponseValidator.parse(await response.json()).did;
280
+ } catch (error) {
281
+ const message = error instanceof Error ? error.message : String(error);
282
+ throw new TRPCError({
283
+ code: 'INTERNAL_SERVER_ERROR',
284
+ message: `Unable to auto-provision app signing authority: ${message}`,
285
+ cause: error,
286
+ });
287
+ }
288
+ };
289
+
290
+ export const ensureManagedSigningAuthorityForListing = async (
291
+ listing: AppStoreListingType,
292
+ integration: IntegrationType,
293
+ integrationOwner: ProfileType,
294
+ domain: string
295
+ ): Promise<SigningAuthorityForUserType> => {
296
+ const existingListingSa = await getPrimarySigningAuthorityForListing(listing);
297
+ if (existingListingSa) {
298
+ return existingListingSa;
299
+ }
300
+
301
+ const existingIntegrationSa = await getPrimarySigningAuthorityForIntegration(integration.id);
302
+ if (existingIntegrationSa) {
303
+ await ensureListingSigningAuthorityRelationship(listing, existingIntegrationSa);
304
+ return existingIntegrationSa;
305
+ }
306
+
307
+ const existingOwnerSa = await getPrimarySigningAuthorityForUser(integrationOwner);
308
+ if (existingOwnerSa) {
309
+ await ensureListingSigningAuthorityRelationship(listing, existingOwnerSa);
310
+ return existingOwnerSa;
311
+ }
312
+
313
+ const ownerDid = listing.slug
314
+ ? getAppDidWeb(domain, listing.slug)
315
+ : getDidWeb(domain, integrationOwner.profileId);
316
+ const name = buildManagedSigningAuthorityName(listing);
317
+ const did = await provisionManagedSigningAuthority(
318
+ DEFAULT_SIGNING_AUTHORITY_ENDPOINT,
319
+ ownerDid,
320
+ name
321
+ );
322
+ const signingAuthority = await upsertSigningAuthority(DEFAULT_SIGNING_AUTHORITY_ENDPOINT);
323
+
324
+ await createUseSigningAuthorityRelationship(
325
+ integrationOwner,
326
+ signingAuthority,
327
+ name,
328
+ did,
329
+ true
330
+ );
331
+ await associateListingWithSigningAuthority(
332
+ listing.listing_id,
333
+ DEFAULT_SIGNING_AUTHORITY_ENDPOINT,
334
+ {
335
+ name,
336
+ did,
337
+ isPrimary: true,
338
+ }
339
+ );
340
+ invalidateListingSigningAuthorityCache(listing.listing_id);
341
+ await deleteDidDocForProfile(integrationOwner.profileId);
342
+
343
+ return {
344
+ signingAuthority: { endpoint: DEFAULT_SIGNING_AUTHORITY_ENDPOINT },
345
+ relationship: { name, did, isPrimary: true },
346
+ } as SigningAuthorityForUserType;
347
+ };
348
+
349
+ const getReusableInlineTemplateBoost = async ({
350
+ integrationId,
351
+ templateAlias,
352
+ contentHash,
353
+ templateVersion,
354
+ }: {
355
+ integrationId: string;
356
+ templateAlias: string;
357
+ contentHash: string;
358
+ templateVersion: number;
359
+ }): Promise<BoostInstance | null> => {
360
+ const result = await neogma.queryRunner.run(
361
+ `MATCH (boost:Boost)
362
+ WHERE boost.\`meta.integrationId\` = $integrationId
363
+ AND boost.\`meta.templateAlias\` = $templateAlias
364
+ AND boost.\`meta.inlineTemplateHash\` = $contentHash
365
+ AND boost.\`meta.inlineTemplateVersion\` = $templateVersion
366
+ RETURN boost.id AS id
367
+ ORDER BY boost.id DESC
368
+ LIMIT 1`,
369
+ {
370
+ integrationId,
371
+ templateAlias,
372
+ contentHash,
373
+ templateVersion,
374
+ }
375
+ );
376
+
377
+ const id = result.records[0]?.get('id');
378
+
379
+ if (typeof id !== 'string') {
380
+ return null;
381
+ }
382
+
383
+ return Boost.findOne({ where: { id } });
384
+ };
385
+
386
+ export const upsertInlineTemplateBoostForListing = async ({
387
+ listing,
388
+ integration,
389
+ templateAlias,
390
+ template,
391
+ domain,
392
+ desiredVersion,
393
+ }: {
394
+ listing: AppStoreListingType;
395
+ integration: IntegrationType;
396
+ templateAlias: string;
397
+ template: InlineCredentialTemplate;
398
+ domain: string;
399
+ desiredVersion?: number;
400
+ }): Promise<UpsertInlineTemplateBoostResult> => {
401
+ validateInlineTemplateOrThrow(template);
402
+
403
+ const { credentialTemplateJson, variableManifest, category, walletSkills, contentHash } =
404
+ computeInlineTemplateHash(template);
405
+ const existing = await getBoostForListingByTemplateAlias(
406
+ listing.listing_id,
407
+ templateAlias,
408
+ domain
409
+ );
410
+
411
+ if (existing) {
412
+ const existingMeta = await readInlineTemplateBoostMeta(existing.boost);
413
+ const existingVersion =
414
+ typeof existingMeta.inlineTemplateVersion === 'number'
415
+ ? existingMeta.inlineTemplateVersion
416
+ : 1;
417
+ const targetVersion = desiredVersion ?? existingVersion;
418
+
419
+ if (existingMeta.inlineTemplateHash === contentHash && existingVersion === targetVersion) {
420
+ return {
421
+ boost: existing.boost,
422
+ boostUri: existing.boostUri,
423
+ templateVersion: targetVersion,
424
+ manifest: variableManifest,
425
+ };
426
+ }
427
+
428
+ const reusableBoost = await getReusableInlineTemplateBoost({
429
+ integrationId: integration.id,
430
+ templateAlias,
431
+ contentHash,
432
+ templateVersion: targetVersion,
433
+ });
434
+
435
+ if (reusableBoost) {
436
+ const reusableBoostUri = getBoostUri(reusableBoost.id, domain);
437
+
438
+ await updateBoost(existing.boost, {
439
+ meta: {
440
+ supersededAt: new Date().toISOString(),
441
+ supersededBy: reusableBoostUri,
442
+ },
443
+ });
444
+ await removeBoostFromListing(listing.listing_id, templateAlias);
445
+ await associateBoostWithListing(listing.listing_id, reusableBoostUri, templateAlias);
446
+ invalidateBoostForListingCache(listing.listing_id, templateAlias, domain);
447
+
448
+ return {
449
+ boost: reusableBoost,
450
+ boostUri: reusableBoostUri,
451
+ templateVersion: targetVersion,
452
+ manifest: variableManifest,
453
+ };
454
+ }
455
+
456
+ const nextVersion = desiredVersion ?? existingVersion + 1;
457
+
458
+ const newBoost = await createBoostForListing(
459
+ parseInlineTemplateJson(credentialTemplateJson) as UnsignedVC,
460
+ listing,
461
+ {
462
+ status: 'LIVE',
463
+ category,
464
+ meta: {
465
+ integrationId: integration.id,
466
+ templateAlias,
467
+ inlineTemplateHash: contentHash,
468
+ inlineTemplateVersion: nextVersion,
469
+ inlineVariableManifest: JSON.stringify(variableManifest),
470
+ inlineWalletSkills: walletSkills ? JSON.stringify(walletSkills) : undefined,
471
+ source: INLINE_TEMPLATE_SOURCE,
472
+ },
473
+ },
474
+ domain
475
+ );
476
+ const newBoostUri = getBoostUri(newBoost.id, domain);
477
+
478
+ await updateBoost(existing.boost, {
479
+ meta: {
480
+ supersededAt: new Date().toISOString(),
481
+ supersededBy: newBoostUri,
482
+ },
483
+ });
484
+ await removeBoostFromListing(listing.listing_id, templateAlias);
485
+ await associateBoostWithListing(listing.listing_id, newBoostUri, templateAlias);
486
+ invalidateBoostForListingCache(listing.listing_id, templateAlias, domain);
487
+
488
+ return {
489
+ boost: newBoost,
490
+ boostUri: newBoostUri,
491
+ templateVersion: nextVersion,
492
+ manifest: variableManifest,
493
+ };
494
+ }
495
+
496
+ const initialVersion = desiredVersion ?? 1;
497
+
498
+ const reusableBoost = await getReusableInlineTemplateBoost({
499
+ integrationId: integration.id,
500
+ templateAlias,
501
+ contentHash,
502
+ templateVersion: initialVersion,
503
+ });
504
+
505
+ if (reusableBoost) {
506
+ const reusableBoostUri = getBoostUri(reusableBoost.id, domain);
507
+
508
+ await associateBoostWithListing(listing.listing_id, reusableBoostUri, templateAlias);
509
+ invalidateBoostForListingCache(listing.listing_id, templateAlias, domain);
510
+
511
+ return {
512
+ boost: reusableBoost,
513
+ boostUri: reusableBoostUri,
514
+ templateVersion: initialVersion,
515
+ manifest: variableManifest,
516
+ };
517
+ }
518
+
519
+ const boost = await createBoostForListing(
520
+ parseInlineTemplateJson(credentialTemplateJson) as UnsignedVC,
521
+ listing,
522
+ {
523
+ status: 'LIVE',
524
+ category,
525
+ meta: {
526
+ integrationId: integration.id,
527
+ templateAlias,
528
+ inlineTemplateHash: contentHash,
529
+ inlineTemplateVersion: initialVersion,
530
+ inlineVariableManifest: JSON.stringify(variableManifest),
531
+ inlineWalletSkills: walletSkills ? JSON.stringify(walletSkills) : undefined,
532
+ source: INLINE_TEMPLATE_SOURCE,
533
+ },
534
+ },
535
+ domain
536
+ );
537
+ const boostUri = getBoostUri(boost.id, domain);
538
+
539
+ await associateBoostWithListing(listing.listing_id, boostUri, templateAlias);
540
+ invalidateBoostForListingCache(listing.listing_id, templateAlias, domain);
541
+
542
+ return {
543
+ boost,
544
+ boostUri,
545
+ templateVersion: initialVersion,
546
+ manifest: variableManifest,
547
+ };
548
+ };
549
+
550
+ const parseInlineTemplateJson = (templateJson: string): Record<string, unknown> => {
551
+ try {
552
+ return JSON.parse(templateJson) as Record<string, unknown>;
553
+ } catch (error) {
554
+ const message = error instanceof Error ? error.message : String(error);
555
+ throw new TRPCError({
556
+ code: 'INTERNAL_SERVER_ERROR',
557
+ message: `Compiled inline template produced invalid JSON: ${message}`,
558
+ });
559
+ }
560
+ };
@@ -38,6 +38,10 @@ export type NotificationMessageKey =
38
38
  | 'appListingWithdrawn'
39
39
  | 'appListingApproved'
40
40
  | 'appListingRejected'
41
+ | 'contractRequestReceived'
42
+ | 'contractRequestAccepted'
43
+ | 'contractRequestDenied'
44
+ | 'contractRequestCancelled'
41
45
  | 'consentFlowViewRequest'
42
46
  | 'consentFlowInvite'
43
47
  | 'consentFlowShare'
@@ -57,7 +61,8 @@ export type NotificationMessageKey =
57
61
  | 'credentialRestoredUnnamed'
58
62
  // --- Managed credential refresh (LC-2136) — generic copy only: never name the
59
63
  // credential, the holder's claims, or implementation terms (refresh/sync/etc.) ---
60
- | 'credentialRefreshed';
64
+ | 'credentialRefreshed'
65
+ | 'shareViewed';
61
66
 
62
67
  type MessageTemplate = { title: string; body: string };
63
68
  type LocaleCatalog = Record<NotificationMessageKey, MessageTemplate>;
@@ -148,6 +153,22 @@ const en: LocaleCatalog = {
148
153
  title: 'App Listing Needs Changes',
149
154
  body: '"{displayName}" was not approved. Please review and resubmit.',
150
155
  },
156
+ contractRequestReceived: {
157
+ title: 'Connection request',
158
+ body: '{referrer} would like to connect you with {contractOwner}.',
159
+ },
160
+ contractRequestAccepted: {
161
+ title: 'Connection request accepted',
162
+ body: '{name} accepted the request.',
163
+ },
164
+ contractRequestDenied: {
165
+ title: 'Connection request declined',
166
+ body: '{name} declined the request.',
167
+ },
168
+ contractRequestCancelled: {
169
+ title: 'Connection request cancelled',
170
+ body: '{name} cancelled the request.',
171
+ },
151
172
  consentFlowViewRequest: {
152
173
  title: 'AI Insights',
153
174
  body: '{name} has requested to view your insights.',
@@ -216,6 +237,10 @@ const en: LocaleCatalog = {
216
237
  title: 'Credential updated',
217
238
  body: '{from} updated one of your credentials.',
218
239
  },
240
+ shareViewed: {
241
+ title: 'Share viewed',
242
+ body: 'Your share “{title} ({count})” was viewed.',
243
+ },
219
244
  };
220
245
 
221
246
  const es: LocaleCatalog = {
@@ -299,6 +324,22 @@ const es: LocaleCatalog = {
299
324
  title: 'La aplicación necesita cambios',
300
325
  body: '"{displayName}" no fue aprobada. Revísala y vuelve a enviarla.',
301
326
  },
327
+ contractRequestReceived: {
328
+ title: 'Solicitud de conexión',
329
+ body: '{referrer} quiere conectarte con {contractOwner}.',
330
+ },
331
+ contractRequestAccepted: {
332
+ title: 'Solicitud de conexión aceptada',
333
+ body: '{name} aceptó la solicitud.',
334
+ },
335
+ contractRequestDenied: {
336
+ title: 'Solicitud de conexión rechazada',
337
+ body: '{name} rechazó la solicitud.',
338
+ },
339
+ contractRequestCancelled: {
340
+ title: 'Solicitud de conexión cancelada',
341
+ body: '{name} canceló la solicitud.',
342
+ },
302
343
  consentFlowViewRequest: {
303
344
  title: 'AI Insights',
304
345
  body: '{name} ha solicitado ver tus análisis.',
@@ -367,6 +408,10 @@ const es: LocaleCatalog = {
367
408
  title: 'Credencial actualizada',
368
409
  body: '{from} actualizó una de tus credenciales.',
369
410
  },
411
+ shareViewed: {
412
+ title: 'Enlace visto',
413
+ body: 'Se vio tu enlace «{title} ({count})».',
414
+ },
370
415
  };
371
416
 
372
417
  const fr: LocaleCatalog = {
@@ -450,6 +495,22 @@ const fr: LocaleCatalog = {
450
495
  title: "L'application nécessite des modifications",
451
496
  body: "« {displayName} » n'a pas été approuvée. Veuillez la réviser et la soumettre à nouveau.",
452
497
  },
498
+ contractRequestReceived: {
499
+ title: 'Demande de connexion',
500
+ body: '{referrer} souhaite vous mettre en relation avec {contractOwner}.',
501
+ },
502
+ contractRequestAccepted: {
503
+ title: 'Demande de connexion acceptée',
504
+ body: '{name} a accepté la demande.',
505
+ },
506
+ contractRequestDenied: {
507
+ title: 'Demande de connexion refusée',
508
+ body: '{name} a refusé la demande.',
509
+ },
510
+ contractRequestCancelled: {
511
+ title: 'Demande de connexion annulée',
512
+ body: '{name} a annulé la demande.',
513
+ },
453
514
  consentFlowViewRequest: {
454
515
  title: 'AI Insights',
455
516
  body: '{name} a demandé à consulter vos analyses.',
@@ -518,6 +579,10 @@ const fr: LocaleCatalog = {
518
579
  title: 'Titre mis à jour',
519
580
  body: "{from} a mis à jour l'un de vos titres.",
520
581
  },
582
+ shareViewed: {
583
+ title: 'Partage consulté',
584
+ body: 'Votre partage « {title} ({count}) » a été consulté.',
585
+ },
521
586
  };
522
587
 
523
588
  const ar: LocaleCatalog = {
@@ -601,6 +666,13 @@ const ar: LocaleCatalog = {
601
666
  title: 'التطبيق يحتاج إلى تعديلات',
602
667
  body: 'لم تتم الموافقة على "{displayName}". يرجى مراجعته وإعادة إرساله.',
603
668
  },
669
+ contractRequestReceived: {
670
+ title: 'طلب اتصال',
671
+ body: 'يريد {referrer} توصيلك بـ {contractOwner}.',
672
+ },
673
+ contractRequestAccepted: { title: 'تم قبول طلب الاتصال', body: 'قبل {name} الطلب.' },
674
+ contractRequestDenied: { title: 'تم رفض طلب الاتصال', body: 'رفض {name} الطلب.' },
675
+ contractRequestCancelled: { title: 'تم إلغاء طلب الاتصال', body: 'ألغى {name} الطلب.' },
604
676
  consentFlowViewRequest: {
605
677
  title: 'رؤى الذكاء الاصطناعي',
606
678
  body: 'طلب {name} الاطلاع على رؤاك.',
@@ -669,6 +741,10 @@ const ar: LocaleCatalog = {
669
741
  title: 'تم تحديث الشهادة',
670
742
  body: 'قام {from} بتحديث إحدى شهاداتك.',
671
743
  },
744
+ shareViewed: {
745
+ title: 'تمت مشاهدة المشاركة',
746
+ body: 'تمت مشاهدة مشاركتك «{title} ({count})».',
747
+ },
672
748
  };
673
749
 
674
750
  const CATALOGS: Record<NotificationLocale, LocaleCatalog> = { en, es, fr, ar };