@weaveprotocol/core 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 (430) hide show
  1. package/README.md +1106 -0
  2. package/dist/elements/auth-styles.d.ts +18 -0
  3. package/dist/elements/auth-styles.d.ts.map +1 -0
  4. package/dist/elements/auth-styles.js +150 -0
  5. package/dist/elements/auth-styles.js.map +1 -0
  6. package/dist/elements/dom.d.ts +28 -0
  7. package/dist/elements/dom.d.ts.map +1 -0
  8. package/dist/elements/dom.js +74 -0
  9. package/dist/elements/dom.js.map +1 -0
  10. package/dist/elements/index.d.ts +13 -0
  11. package/dist/elements/index.d.ts.map +1 -0
  12. package/dist/elements/index.js +11 -0
  13. package/dist/elements/index.js.map +1 -0
  14. package/dist/elements/weave-auth.d.ts +52 -0
  15. package/dist/elements/weave-auth.d.ts.map +1 -0
  16. package/dist/elements/weave-auth.js +427 -0
  17. package/dist/elements/weave-auth.js.map +1 -0
  18. package/dist/identity/account-store.d.ts +113 -0
  19. package/dist/identity/account-store.d.ts.map +1 -0
  20. package/dist/identity/account-store.js +305 -0
  21. package/dist/identity/account-store.js.map +1 -0
  22. package/dist/identity/account-vault.d.ts +199 -0
  23. package/dist/identity/account-vault.d.ts.map +1 -0
  24. package/dist/identity/account-vault.js +251 -0
  25. package/dist/identity/account-vault.js.map +1 -0
  26. package/dist/identity/agent-note.d.ts +19 -0
  27. package/dist/identity/agent-note.d.ts.map +1 -0
  28. package/dist/identity/agent-note.js +29 -0
  29. package/dist/identity/agent-note.js.map +1 -0
  30. package/dist/identity/crypto-p256.d.ts +7 -0
  31. package/dist/identity/crypto-p256.d.ts.map +1 -0
  32. package/dist/identity/crypto-p256.js +84 -0
  33. package/dist/identity/crypto-p256.js.map +1 -0
  34. package/dist/identity/device-key.d.ts +60 -0
  35. package/dist/identity/device-key.d.ts.map +1 -0
  36. package/dist/identity/device-key.js +103 -0
  37. package/dist/identity/device-key.js.map +1 -0
  38. package/dist/identity/did.d.ts +22 -0
  39. package/dist/identity/did.d.ts.map +1 -0
  40. package/dist/identity/did.js +37 -0
  41. package/dist/identity/did.js.map +1 -0
  42. package/dist/identity/folder-account.d.ts +65 -0
  43. package/dist/identity/folder-account.d.ts.map +1 -0
  44. package/dist/identity/folder-account.js +115 -0
  45. package/dist/identity/folder-account.js.map +1 -0
  46. package/dist/identity/identity-manager.d.ts +36 -0
  47. package/dist/identity/identity-manager.d.ts.map +1 -0
  48. package/dist/identity/identity-manager.js +115 -0
  49. package/dist/identity/identity-manager.js.map +1 -0
  50. package/dist/identity/index.d.ts +10 -0
  51. package/dist/identity/index.d.ts.map +1 -0
  52. package/dist/identity/index.js +10 -0
  53. package/dist/identity/index.js.map +1 -0
  54. package/dist/identity/keys.d.ts +24 -0
  55. package/dist/identity/keys.d.ts.map +1 -0
  56. package/dist/identity/keys.js +38 -0
  57. package/dist/identity/keys.js.map +1 -0
  58. package/dist/identity/pairing.d.ts +83 -0
  59. package/dist/identity/pairing.d.ts.map +1 -0
  60. package/dist/identity/pairing.js +120 -0
  61. package/dist/identity/pairing.js.map +1 -0
  62. package/dist/identity/passkey-diagnostics.d.ts +54 -0
  63. package/dist/identity/passkey-diagnostics.d.ts.map +1 -0
  64. package/dist/identity/passkey-diagnostics.js +178 -0
  65. package/dist/identity/passkey-diagnostics.js.map +1 -0
  66. package/dist/identity/recovery-code.d.ts +50 -0
  67. package/dist/identity/recovery-code.d.ts.map +1 -0
  68. package/dist/identity/recovery-code.js +116 -0
  69. package/dist/identity/recovery-code.js.map +1 -0
  70. package/dist/identity/root-signer.d.ts +59 -0
  71. package/dist/identity/root-signer.d.ts.map +1 -0
  72. package/dist/identity/root-signer.js +44 -0
  73. package/dist/identity/root-signer.js.map +1 -0
  74. package/dist/identity/ucan.d.ts +164 -0
  75. package/dist/identity/ucan.d.ts.map +1 -0
  76. package/dist/identity/ucan.js +273 -0
  77. package/dist/identity/ucan.js.map +1 -0
  78. package/dist/identity/webauthn.d.ts +87 -0
  79. package/dist/identity/webauthn.d.ts.map +1 -0
  80. package/dist/identity/webauthn.js +155 -0
  81. package/dist/identity/webauthn.js.map +1 -0
  82. package/dist/index.d.ts +116 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +85 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/network/index.d.ts +17 -0
  87. package/dist/network/index.d.ts.map +1 -0
  88. package/dist/network/index.js +10 -0
  89. package/dist/network/index.js.map +1 -0
  90. package/dist/network/introductions.d.ts +85 -0
  91. package/dist/network/introductions.d.ts.map +1 -0
  92. package/dist/network/introductions.js +94 -0
  93. package/dist/network/introductions.js.map +1 -0
  94. package/dist/network/local-transport.d.ts +22 -0
  95. package/dist/network/local-transport.d.ts.map +1 -0
  96. package/dist/network/local-transport.js +55 -0
  97. package/dist/network/local-transport.js.map +1 -0
  98. package/dist/network/mesh.d.ts +31 -0
  99. package/dist/network/mesh.d.ts.map +1 -0
  100. package/dist/network/mesh.js +332 -0
  101. package/dist/network/mesh.js.map +1 -0
  102. package/dist/network/multi-signaling.d.ts +29 -0
  103. package/dist/network/multi-signaling.d.ts.map +1 -0
  104. package/dist/network/multi-signaling.js +125 -0
  105. package/dist/network/multi-signaling.js.map +1 -0
  106. package/dist/network/network-manager.d.ts +37 -0
  107. package/dist/network/network-manager.d.ts.map +1 -0
  108. package/dist/network/network-manager.js +64 -0
  109. package/dist/network/network-manager.js.map +1 -0
  110. package/dist/network/peer-auth.d.ts +98 -0
  111. package/dist/network/peer-auth.d.ts.map +1 -0
  112. package/dist/network/peer-auth.js +86 -0
  113. package/dist/network/peer-auth.js.map +1 -0
  114. package/dist/network/rtc-transport.d.ts +18 -0
  115. package/dist/network/rtc-transport.d.ts.map +1 -0
  116. package/dist/network/rtc-transport.js +149 -0
  117. package/dist/network/rtc-transport.js.map +1 -0
  118. package/dist/network/signaling.d.ts +40 -0
  119. package/dist/network/signaling.d.ts.map +1 -0
  120. package/dist/network/signaling.js +124 -0
  121. package/dist/network/signaling.js.map +1 -0
  122. package/dist/network/transport.d.ts +50 -0
  123. package/dist/network/transport.d.ts.map +1 -0
  124. package/dist/network/transport.js +13 -0
  125. package/dist/network/transport.js.map +1 -0
  126. package/dist/network/ws-transport.d.ts +42 -0
  127. package/dist/network/ws-transport.d.ts.map +1 -0
  128. package/dist/network/ws-transport.js +194 -0
  129. package/dist/network/ws-transport.js.map +1 -0
  130. package/dist/node/actions.d.ts +62 -0
  131. package/dist/node/actions.d.ts.map +1 -0
  132. package/dist/node/actions.js +500 -0
  133. package/dist/node/actions.js.map +1 -0
  134. package/dist/node/carrier.d.ts +85 -0
  135. package/dist/node/carrier.d.ts.map +1 -0
  136. package/dist/node/carrier.js +192 -0
  137. package/dist/node/carrier.js.map +1 -0
  138. package/dist/node/copy.d.ts +38 -0
  139. package/dist/node/copy.d.ts.map +1 -0
  140. package/dist/node/copy.js +53 -0
  141. package/dist/node/copy.js.map +1 -0
  142. package/dist/node/index.d.ts +16 -0
  143. package/dist/node/index.d.ts.map +1 -0
  144. package/dist/node/index.js +11 -0
  145. package/dist/node/index.js.map +1 -0
  146. package/dist/node/node.d.ts +12 -0
  147. package/dist/node/node.d.ts.map +1 -0
  148. package/dist/node/node.js +872 -0
  149. package/dist/node/node.js.map +1 -0
  150. package/dist/node/space-runtime.d.ts +144 -0
  151. package/dist/node/space-runtime.d.ts.map +1 -0
  152. package/dist/node/space-runtime.js +1221 -0
  153. package/dist/node/space-runtime.js.map +1 -0
  154. package/dist/node/stores.d.ts +45 -0
  155. package/dist/node/stores.d.ts.map +1 -0
  156. package/dist/node/stores.js +31 -0
  157. package/dist/node/stores.js.map +1 -0
  158. package/dist/node/types.d.ts +508 -0
  159. package/dist/node/types.d.ts.map +1 -0
  160. package/dist/node/types.js +2 -0
  161. package/dist/node/types.js.map +1 -0
  162. package/dist/privacy/index.d.ts +4 -0
  163. package/dist/privacy/index.d.ts.map +1 -0
  164. package/dist/privacy/index.js +4 -0
  165. package/dist/privacy/index.js.map +1 -0
  166. package/dist/privacy/key-distribution.d.ts +42 -0
  167. package/dist/privacy/key-distribution.d.ts.map +1 -0
  168. package/dist/privacy/key-distribution.js +50 -0
  169. package/dist/privacy/key-distribution.js.map +1 -0
  170. package/dist/privacy/privacy-guard.d.ts +24 -0
  171. package/dist/privacy/privacy-guard.d.ts.map +1 -0
  172. package/dist/privacy/privacy-guard.js +87 -0
  173. package/dist/privacy/privacy-guard.js.map +1 -0
  174. package/dist/privacy/space-encryption.d.ts +48 -0
  175. package/dist/privacy/space-encryption.d.ts.map +1 -0
  176. package/dist/privacy/space-encryption.js +61 -0
  177. package/dist/privacy/space-encryption.js.map +1 -0
  178. package/dist/query/engine.d.ts +27 -0
  179. package/dist/query/engine.d.ts.map +1 -0
  180. package/dist/query/engine.js +84 -0
  181. package/dist/query/engine.js.map +1 -0
  182. package/dist/query/filter.d.ts +15 -0
  183. package/dist/query/filter.d.ts.map +1 -0
  184. package/dist/query/filter.js +207 -0
  185. package/dist/query/filter.js.map +1 -0
  186. package/dist/query/types.d.ts +144 -0
  187. package/dist/query/types.d.ts.map +1 -0
  188. package/dist/query/types.js +22 -0
  189. package/dist/query/types.js.map +1 -0
  190. package/dist/react/context.d.ts +81 -0
  191. package/dist/react/context.d.ts.map +1 -0
  192. package/dist/react/context.js +95 -0
  193. package/dist/react/context.js.map +1 -0
  194. package/dist/react/index.d.ts +40 -0
  195. package/dist/react/index.d.ts.map +1 -0
  196. package/dist/react/index.js +36 -0
  197. package/dist/react/index.js.map +1 -0
  198. package/dist/react/use-live.d.ts +16 -0
  199. package/dist/react/use-live.d.ts.map +1 -0
  200. package/dist/react/use-live.js +55 -0
  201. package/dist/react/use-live.js.map +1 -0
  202. package/dist/react/use-query.d.ts +17 -0
  203. package/dist/react/use-query.d.ts.map +1 -0
  204. package/dist/react/use-query.js +23 -0
  205. package/dist/react/use-query.js.map +1 -0
  206. package/dist/react/use-space.d.ts +29 -0
  207. package/dist/react/use-space.d.ts.map +1 -0
  208. package/dist/react/use-space.js +48 -0
  209. package/dist/react/use-space.js.map +1 -0
  210. package/dist/react/use-spaces.d.ts +19 -0
  211. package/dist/react/use-spaces.d.ts.map +1 -0
  212. package/dist/react/use-spaces.js +55 -0
  213. package/dist/react/use-spaces.js.map +1 -0
  214. package/dist/react/use-weave-auth.d.ts +10 -0
  215. package/dist/react/use-weave-auth.d.ts.map +1 -0
  216. package/dist/react/use-weave-auth.js +15 -0
  217. package/dist/react/use-weave-auth.js.map +1 -0
  218. package/dist/react/weave-auth.d.ts +17 -0
  219. package/dist/react/weave-auth.d.ts.map +1 -0
  220. package/dist/react/weave-auth.js +38 -0
  221. package/dist/react/weave-auth.js.map +1 -0
  222. package/dist/records/describe.d.ts +38 -0
  223. package/dist/records/describe.d.ts.map +1 -0
  224. package/dist/records/describe.js +101 -0
  225. package/dist/records/describe.js.map +1 -0
  226. package/dist/records/links.d.ts +14 -0
  227. package/dist/records/links.d.ts.map +1 -0
  228. package/dist/records/links.js +25 -0
  229. package/dist/records/links.js.map +1 -0
  230. package/dist/records/rules.d.ts +59 -0
  231. package/dist/records/rules.d.ts.map +1 -0
  232. package/dist/records/rules.js +118 -0
  233. package/dist/records/rules.js.map +1 -0
  234. package/dist/records/version.d.ts +54 -0
  235. package/dist/records/version.d.ts.map +1 -0
  236. package/dist/records/version.js +70 -0
  237. package/dist/records/version.js.map +1 -0
  238. package/dist/schema/collection-def.d.ts +96 -0
  239. package/dist/schema/collection-def.d.ts.map +1 -0
  240. package/dist/schema/collection-def.js +272 -0
  241. package/dist/schema/collection-def.js.map +1 -0
  242. package/dist/schema/expression.d.ts +69 -0
  243. package/dist/schema/expression.d.ts.map +1 -0
  244. package/dist/schema/expression.js +92 -0
  245. package/dist/schema/expression.js.map +1 -0
  246. package/dist/schema/index.d.ts +4 -0
  247. package/dist/schema/index.d.ts.map +1 -0
  248. package/dist/schema/index.js +4 -0
  249. package/dist/schema/index.js.map +1 -0
  250. package/dist/schema/schema-engine.d.ts +42 -0
  251. package/dist/schema/schema-engine.d.ts.map +1 -0
  252. package/dist/schema/schema-engine.js +36 -0
  253. package/dist/schema/schema-engine.js.map +1 -0
  254. package/dist/schema/signer.d.ts +27 -0
  255. package/dist/schema/signer.d.ts.map +1 -0
  256. package/dist/schema/signer.js +36 -0
  257. package/dist/schema/signer.js.map +1 -0
  258. package/dist/schemas/apps.d.ts +88 -0
  259. package/dist/schemas/apps.d.ts.map +1 -0
  260. package/dist/schemas/apps.js +168 -0
  261. package/dist/schemas/apps.js.map +1 -0
  262. package/dist/schemas/index.d.ts +410 -0
  263. package/dist/schemas/index.d.ts.map +1 -0
  264. package/dist/schemas/index.js +208 -0
  265. package/dist/schemas/index.js.map +1 -0
  266. package/dist/schemas/screens.d.ts +67 -0
  267. package/dist/schemas/screens.d.ts.map +1 -0
  268. package/dist/schemas/screens.js +242 -0
  269. package/dist/schemas/screens.js.map +1 -0
  270. package/dist/session/agent-link.d.ts +79 -0
  271. package/dist/session/agent-link.d.ts.map +1 -0
  272. package/dist/session/agent-link.js +251 -0
  273. package/dist/session/agent-link.js.map +1 -0
  274. package/dist/session/auth.d.ts +233 -0
  275. package/dist/session/auth.d.ts.map +1 -0
  276. package/dist/session/auth.js +783 -0
  277. package/dist/session/auth.js.map +1 -0
  278. package/dist/session/connect.d.ts +211 -0
  279. package/dist/session/connect.d.ts.map +1 -0
  280. package/dist/session/connect.js +355 -0
  281. package/dist/session/connect.js.map +1 -0
  282. package/dist/session/connection.d.ts +70 -0
  283. package/dist/session/connection.d.ts.map +1 -0
  284. package/dist/session/connection.js +120 -0
  285. package/dist/session/connection.js.map +1 -0
  286. package/dist/session/credentials.d.ts +44 -0
  287. package/dist/session/credentials.d.ts.map +1 -0
  288. package/dist/session/credentials.js +60 -0
  289. package/dist/session/credentials.js.map +1 -0
  290. package/dist/session/index.d.ts +25 -0
  291. package/dist/session/index.d.ts.map +1 -0
  292. package/dist/session/index.js +18 -0
  293. package/dist/session/index.js.map +1 -0
  294. package/dist/session/pairing.d.ts +59 -0
  295. package/dist/session/pairing.d.ts.map +1 -0
  296. package/dist/session/pairing.js +144 -0
  297. package/dist/session/pairing.js.map +1 -0
  298. package/dist/session/places.d.ts +62 -0
  299. package/dist/session/places.d.ts.map +1 -0
  300. package/dist/session/places.js +101 -0
  301. package/dist/session/places.js.map +1 -0
  302. package/dist/session/stay-signed-in.d.ts +37 -0
  303. package/dist/session/stay-signed-in.d.ts.map +1 -0
  304. package/dist/session/stay-signed-in.js +124 -0
  305. package/dist/session/stay-signed-in.js.map +1 -0
  306. package/dist/space/account-registry.d.ts +64 -0
  307. package/dist/space/account-registry.d.ts.map +1 -0
  308. package/dist/space/account-registry.js +66 -0
  309. package/dist/space/account-registry.js.map +1 -0
  310. package/dist/space/index.d.ts +3 -0
  311. package/dist/space/index.d.ts.map +1 -0
  312. package/dist/space/index.js +3 -0
  313. package/dist/space/index.js.map +1 -0
  314. package/dist/space/pass.d.ts +63 -0
  315. package/dist/space/pass.d.ts.map +1 -0
  316. package/dist/space/pass.js +54 -0
  317. package/dist/space/pass.js.map +1 -0
  318. package/dist/space/presets.d.ts +31 -0
  319. package/dist/space/presets.d.ts.map +1 -0
  320. package/dist/space/presets.js +24 -0
  321. package/dist/space/presets.js.map +1 -0
  322. package/dist/space/roles.d.ts +186 -0
  323. package/dist/space/roles.d.ts.map +1 -0
  324. package/dist/space/roles.js +500 -0
  325. package/dist/space/roles.js.map +1 -0
  326. package/dist/space/space-access.d.ts +80 -0
  327. package/dist/space/space-access.d.ts.map +1 -0
  328. package/dist/space/space-access.js +135 -0
  329. package/dist/space/space-access.js.map +1 -0
  330. package/dist/space/space-manager.d.ts +87 -0
  331. package/dist/space/space-manager.d.ts.map +1 -0
  332. package/dist/space/space-manager.js +187 -0
  333. package/dist/space/space-manager.js.map +1 -0
  334. package/dist/storage/directory-access.d.ts +78 -0
  335. package/dist/storage/directory-access.d.ts.map +1 -0
  336. package/dist/storage/directory-access.js +164 -0
  337. package/dist/storage/directory-access.js.map +1 -0
  338. package/dist/storage/encrypted-adapter.d.ts +49 -0
  339. package/dist/storage/encrypted-adapter.d.ts.map +1 -0
  340. package/dist/storage/encrypted-adapter.js +106 -0
  341. package/dist/storage/encrypted-adapter.js.map +1 -0
  342. package/dist/storage/folder-adapter.d.ts +105 -0
  343. package/dist/storage/folder-adapter.d.ts.map +1 -0
  344. package/dist/storage/folder-adapter.js +280 -0
  345. package/dist/storage/folder-adapter.js.map +1 -0
  346. package/dist/storage/folder-reconcile.d.ts +53 -0
  347. package/dist/storage/folder-reconcile.d.ts.map +1 -0
  348. package/dist/storage/folder-reconcile.js +65 -0
  349. package/dist/storage/folder-reconcile.js.map +1 -0
  350. package/dist/storage/index.d.ts +10 -0
  351. package/dist/storage/index.d.ts.map +1 -0
  352. package/dist/storage/index.js +9 -0
  353. package/dist/storage/index.js.map +1 -0
  354. package/dist/storage/indexeddb-adapter.d.ts +12 -0
  355. package/dist/storage/indexeddb-adapter.d.ts.map +1 -0
  356. package/dist/storage/indexeddb-adapter.js +190 -0
  357. package/dist/storage/indexeddb-adapter.js.map +1 -0
  358. package/dist/storage/mst.d.ts +121 -0
  359. package/dist/storage/mst.d.ts.map +1 -0
  360. package/dist/storage/mst.js +402 -0
  361. package/dist/storage/mst.js.map +1 -0
  362. package/dist/storage/storage-provider.d.ts +85 -0
  363. package/dist/storage/storage-provider.d.ts.map +1 -0
  364. package/dist/storage/storage-provider.js +220 -0
  365. package/dist/storage/storage-provider.js.map +1 -0
  366. package/dist/sync/anti-entropy.d.ts +49 -0
  367. package/dist/sync/anti-entropy.d.ts.map +1 -0
  368. package/dist/sync/anti-entropy.js +62 -0
  369. package/dist/sync/anti-entropy.js.map +1 -0
  370. package/dist/sync/index.d.ts +4 -0
  371. package/dist/sync/index.d.ts.map +1 -0
  372. package/dist/sync/index.js +4 -0
  373. package/dist/sync/index.js.map +1 -0
  374. package/dist/sync/sync-engine.d.ts +71 -0
  375. package/dist/sync/sync-engine.d.ts.map +1 -0
  376. package/dist/sync/sync-engine.js +309 -0
  377. package/dist/sync/sync-engine.js.map +1 -0
  378. package/dist/sync/sync-messages.d.ts +75 -0
  379. package/dist/sync/sync-messages.d.ts.map +1 -0
  380. package/dist/sync/sync-messages.js +12 -0
  381. package/dist/sync/sync-messages.js.map +1 -0
  382. package/dist/types.d.ts +243 -0
  383. package/dist/types.d.ts.map +1 -0
  384. package/dist/types.js +7 -0
  385. package/dist/types.js.map +1 -0
  386. package/dist/utils/encoding.d.ts +63 -0
  387. package/dist/utils/encoding.d.ts.map +1 -0
  388. package/dist/utils/encoding.js +130 -0
  389. package/dist/utils/encoding.js.map +1 -0
  390. package/dist/utils/errors.d.ts +43 -0
  391. package/dist/utils/errors.d.ts.map +1 -0
  392. package/dist/utils/errors.js +28 -0
  393. package/dist/utils/errors.js.map +1 -0
  394. package/dist/utils/events.d.ts +19 -0
  395. package/dist/utils/events.d.ts.map +1 -0
  396. package/dist/utils/events.js +27 -0
  397. package/dist/utils/events.js.map +1 -0
  398. package/dist/utils/hash.d.ts +23 -0
  399. package/dist/utils/hash.d.ts.map +1 -0
  400. package/dist/utils/hash.js +49 -0
  401. package/dist/utils/hash.js.map +1 -0
  402. package/dist/utils/index.d.ts +9 -0
  403. package/dist/utils/index.d.ts.map +1 -0
  404. package/dist/utils/index.js +9 -0
  405. package/dist/utils/index.js.map +1 -0
  406. package/dist/validation/capability-gate.d.ts +50 -0
  407. package/dist/validation/capability-gate.d.ts.map +1 -0
  408. package/dist/validation/capability-gate.js +71 -0
  409. package/dist/validation/capability-gate.js.map +1 -0
  410. package/dist/validation/crypto-gate.d.ts +16 -0
  411. package/dist/validation/crypto-gate.d.ts.map +1 -0
  412. package/dist/validation/crypto-gate.js +37 -0
  413. package/dist/validation/crypto-gate.js.map +1 -0
  414. package/dist/validation/index.d.ts +6 -0
  415. package/dist/validation/index.d.ts.map +1 -0
  416. package/dist/validation/index.js +6 -0
  417. package/dist/validation/index.js.map +1 -0
  418. package/dist/validation/stateful-gate.d.ts +15 -0
  419. package/dist/validation/stateful-gate.d.ts.map +1 -0
  420. package/dist/validation/stateful-gate.js +50 -0
  421. package/dist/validation/stateful-gate.js.map +1 -0
  422. package/dist/validation/structural-gate.d.ts +18 -0
  423. package/dist/validation/structural-gate.d.ts.map +1 -0
  424. package/dist/validation/structural-gate.js +54 -0
  425. package/dist/validation/structural-gate.js.map +1 -0
  426. package/dist/validation/validation-engine.d.ts +28 -0
  427. package/dist/validation/validation-engine.d.ts.map +1 -0
  428. package/dist/validation/validation-engine.js +38 -0
  429. package/dist/validation/validation-engine.js.map +1 -0
  430. package/package.json +107 -0
@@ -0,0 +1,251 @@
1
+ /**
2
+ * @module account-vault
3
+ * The lock on a data folder.
4
+ *
5
+ * A folder that holds its seed in the clear is a bearer token: whoever copies it
6
+ * is you, and the AES key for every private space sits in the same directory as
7
+ * the ciphertext it opens. So the seed is never stored — only **wrapped copies**
8
+ * of it are, one per way of unlocking.
9
+ *
10
+ * ```
11
+ * account seed (16 bytes, never written in the clear)
12
+ * ├── HKDF → vault key ──encrypts──> space keys and space records at rest
13
+ * └── stored only as wraps:
14
+ * device a random key in this origin's storage, gated by a passkey
15
+ * passphrase PBKDF2-SHA256 → AES-GCM
16
+ * ```
17
+ *
18
+ * Both wraps are shortcuts for one origin, and neither carries the account
19
+ * anywhere — that is what the code is for. Adding an app means adding a wrap
20
+ * there, and two shortcuts end up meaning one account without a delegation
21
+ * chain anywhere in sight.
22
+ *
23
+ * The recovery code needs no wrap at all: it *is* the seed, in printable form.
24
+ * It is shown once and never stored, and it is the way in when no wrap fits —
25
+ * a phone, Safari, or an origin that has never seen this folder.
26
+ *
27
+ * ## What this does not protect
28
+ *
29
+ * Expression files keep their author DID, timestamps and collection names in
30
+ * the clear, and public spaces keep their bodies that way by design. Locking
31
+ * those too would mean an opaque blob store, which would cost the property that
32
+ * makes a folder worth having — that you can open it and see what is in it.
33
+ */
34
+ import { base64UrlEncode, base64UrlDecode, utf8Encode } from '../utils/encoding.js';
35
+ import { protocolError } from '../utils/errors.js';
36
+ /** AES-GCM wants 96 bits of nonce. */
37
+ const IV_BYTES = 12;
38
+ const SALT_BYTES = 16;
39
+ /**
40
+ * PBKDF2 rounds for a passphrase wrap.
41
+ *
42
+ * Tuned to roughly a quarter-second in a browser, on the reasoning that this
43
+ * runs once per unlock and the thing it guards is an identity rather than a
44
+ * session.
45
+ */
46
+ export const PASSPHRASE_ITERATIONS = 600_000;
47
+ const VAULT_KEY_INFO = utf8Encode('weave-vault-key-v1');
48
+ /** Random bytes as base64url, for salts and nonces. */
49
+ function randomBytes(length) {
50
+ return globalThis.crypto.getRandomValues(new Uint8Array(length));
51
+ }
52
+ /** A short opaque id for a wrap. */
53
+ function wrapId() {
54
+ return base64UrlEncode(randomBytes(8));
55
+ }
56
+ /**
57
+ * Encrypts a seed under a key.
58
+ * @param seed The seed to protect
59
+ * @param key An AES-GCM key
60
+ * @returns The nonce and ciphertext, base64url encoded
61
+ */
62
+ async function seal(seed, key) {
63
+ const iv = randomBytes(IV_BYTES);
64
+ const ciphertext = await globalThis.crypto.subtle.encrypt({ name: 'AES-GCM', iv: iv }, key, seed);
65
+ return { iv: base64UrlEncode(iv), ciphertext: base64UrlEncode(new Uint8Array(ciphertext)) };
66
+ }
67
+ /**
68
+ * Decrypts a seed, turning the failure into something a UI can say out loud.
69
+ * @param wrap The wrap to open
70
+ * @param key The key it should be under
71
+ * @returns The seed
72
+ */
73
+ async function open(wrap, key) {
74
+ try {
75
+ const plain = await globalThis.crypto.subtle.decrypt({ name: 'AES-GCM', iv: base64UrlDecode(wrap.iv) }, key, base64UrlDecode(wrap.ciphertext));
76
+ return new Uint8Array(plain);
77
+ }
78
+ catch {
79
+ // AES-GCM authenticates, so this is the wrong key rather than corruption.
80
+ throw protocolError('VAULT_UNLOCK_FAILED', 'That did not unlock the folder.', 'Check the passphrase, or use your recovery code instead.');
81
+ }
82
+ }
83
+ /**
84
+ * Stretches a passphrase into the key that wraps a seed.
85
+ * @param passphrase What the user typed
86
+ * @param salt Per-wrap salt
87
+ * @param iterations PBKDF2 rounds, read from the wrap so old ones stay openable
88
+ * @returns An AES-GCM key
89
+ */
90
+ async function passphraseWrappingKey(passphrase, salt, iterations) {
91
+ const material = await globalThis.crypto.subtle.importKey('raw', utf8Encode(passphrase.normalize('NFKC')), { name: 'PBKDF2' }, false, ['deriveKey']);
92
+ return globalThis.crypto.subtle.deriveKey({ name: 'PBKDF2', hash: 'SHA-256', salt: salt, iterations }, material, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
93
+ }
94
+ /**
95
+ * Wraps a seed under this device's key.
96
+ *
97
+ * The key is random and lives in this origin's storage; the passkey recorded
98
+ * alongside is the gate in front of it, not the source of it. See
99
+ * {@link module:device-key}.
100
+ *
101
+ * @param seed The account seed
102
+ * @param deviceKey The local key, from `createDeviceKey`
103
+ * @param meta Which origin this belongs to, and the passkey gating it
104
+ * @returns A wrap ready to append to the account file
105
+ */
106
+ export async function wrapSeedWithDeviceKey(seed, deviceKey, meta) {
107
+ const sealed = await seal(seed, deviceKey.key);
108
+ return {
109
+ kind: 'device',
110
+ id: wrapId(),
111
+ label: meta.label ?? meta.rpId,
112
+ rpId: meta.rpId,
113
+ deviceKeyId: deviceKey.id,
114
+ ...(meta.credentialId ? { credentialId: meta.credentialId } : {}),
115
+ ...(meta.userHandle ? { userHandle: meta.userHandle } : {}),
116
+ addedAt: new Date().toISOString(),
117
+ // Nothing is stretched into this key, so there is no salt to record.
118
+ salt: '',
119
+ ...sealed,
120
+ };
121
+ }
122
+ /**
123
+ * Opens a device wrap.
124
+ * @param wrap The wrap to open
125
+ * @param deviceKey The local key it names
126
+ * @returns The seed
127
+ */
128
+ export async function unwrapSeedWithDeviceKey(wrap, deviceKey) {
129
+ return open(wrap, deviceKey);
130
+ }
131
+ /**
132
+ * Wraps a seed under a passphrase — the portable way back in.
133
+ * @param seed The account seed
134
+ * @param passphrase What the user chose
135
+ * @param label What to call this wrap
136
+ * @returns A wrap ready to append to the account file
137
+ */
138
+ export async function wrapSeedWithPassphrase(seed, passphrase, label = 'Passphrase') {
139
+ const salt = randomBytes(SALT_BYTES);
140
+ const sealed = await seal(seed, await passphraseWrappingKey(passphrase, salt, PASSPHRASE_ITERATIONS));
141
+ return {
142
+ kind: 'passphrase',
143
+ id: wrapId(),
144
+ label,
145
+ addedAt: new Date().toISOString(),
146
+ salt: base64UrlEncode(salt),
147
+ iterations: PASSPHRASE_ITERATIONS,
148
+ ...sealed,
149
+ };
150
+ }
151
+ /**
152
+ * Opens a passphrase wrap.
153
+ * @param wrap The wrap to open
154
+ * @param passphrase What the user typed
155
+ * @returns The seed
156
+ */
157
+ export async function unwrapSeedWithPassphrase(wrap, passphrase) {
158
+ const key = await passphraseWrappingKey(passphrase, base64UrlDecode(wrap.salt), wrap.iterations);
159
+ return open(wrap, key);
160
+ }
161
+ /**
162
+ * The vault key as raw bytes.
163
+ *
164
+ * {@link deriveVaultKey} returns a key that cannot be exported, which is right
165
+ * for a page — it should not be able to leak what it was given. A node derives
166
+ * the account registry from the key, so it is handed the bytes directly
167
+ * rather than the protocol relaxing that for everyone.
168
+ *
169
+ * Identical material to `deriveVaultKey`: same input, same info, same length.
170
+ * If those ever drift, the registry and the folder would be sealed under two
171
+ * different keys.
172
+ *
173
+ * @param seed The account seed
174
+ * @returns 32 bytes, ready to import as AES-GCM
175
+ */
176
+ export async function deriveVaultKeyBytes(seed) {
177
+ const material = await globalThis.crypto.subtle.importKey('raw', seed, { name: 'HKDF' }, false, ['deriveBits']);
178
+ const bits = await globalThis.crypto.subtle.deriveBits({
179
+ name: 'HKDF',
180
+ hash: 'SHA-256',
181
+ salt: new Uint8Array(0),
182
+ info: VAULT_KEY_INFO,
183
+ }, material, 256);
184
+ return new Uint8Array(bits);
185
+ }
186
+ /**
187
+ * Derives the key that encrypts a folder's contents at rest.
188
+ *
189
+ * Separate from the signing key, and from every wrapping key, so that handing
190
+ * one out never implies the others.
191
+ *
192
+ * @param seed The account seed
193
+ * @returns An AES-GCM key for space keys and space records
194
+ */
195
+ export async function deriveVaultKey(seed) {
196
+ const material = await globalThis.crypto.subtle.importKey('raw', seed, { name: 'HKDF' }, false, ['deriveKey']);
197
+ return globalThis.crypto.subtle.deriveKey({
198
+ name: 'HKDF',
199
+ hash: 'SHA-256',
200
+ salt: new Uint8Array(0),
201
+ info: VAULT_KEY_INFO,
202
+ }, material, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
203
+ }
204
+ /**
205
+ * The device wraps this origin could actually attempt.
206
+ *
207
+ * The key a wrap names lives in the storage of the origin that made it, so one
208
+ * from another app is not merely likely to fail — it is unreachable from here.
209
+ *
210
+ * @param vault The account file
211
+ * @param rpId This origin's relying-party id, usually its hostname
212
+ * @returns The device wraps belonging to this origin
213
+ */
214
+ export function deviceWrapsFor(vault, rpId) {
215
+ return vault.wraps.filter((wrap) => wrap.kind === 'device' && wrap.rpId === rpId);
216
+ }
217
+ /** Whether a passphrase would get anyone in. */
218
+ export function hasPassphraseWrap(vault) {
219
+ return vault.wraps.some((wrap) => wrap.kind === 'passphrase');
220
+ }
221
+ /**
222
+ * Adds a wrap, replacing any earlier one for the same passkey.
223
+ *
224
+ * Re-registering on an origin should leave one usable wrap rather than a pile of
225
+ * stale ones, and a wrap whose credential is gone is only clutter.
226
+ *
227
+ * @param vault The account file
228
+ * @param wrap The wrap to add
229
+ * @returns The updated account file
230
+ */
231
+ export function withWrap(vault, wrap) {
232
+ // One device wrap per origin: re-adding the shortcut should replace it, not
233
+ // leave an older one pointing at a key nobody will use again.
234
+ const superseded = (existing) => existing.kind === 'device' && wrap.kind === 'device' && existing.rpId === wrap.rpId;
235
+ return { ...vault, wraps: [...vault.wraps.filter((existing) => !superseded(existing)), wrap] };
236
+ }
237
+ /**
238
+ * Removes a wrap by id.
239
+ *
240
+ * Removing the last one is allowed, and leaves the account in the state a new
241
+ * one starts in: openable by its code and nothing else. The wraps are
242
+ * shortcuts, not the keys to the building.
243
+ *
244
+ * @param vault The account file
245
+ * @param id The wrap to remove
246
+ * @returns The updated account file
247
+ */
248
+ export function withoutWrap(vault, id) {
249
+ return { ...vault, wraps: vault.wraps.filter((wrap) => wrap.id !== id) };
250
+ }
251
+ //# sourceMappingURL=account-vault.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account-vault.js","sourceRoot":"","sources":["../../src/identity/account-vault.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @module identity/agent-note
3
+ * A note that says its key is an agent's.
4
+ *
5
+ * An agent isn't an identity of its own: it writes for a person, under a note
6
+ * from their account, like any app. What sets it apart is one fact the account
7
+ * signs into that note — so every peer can tell a record was written "via
8
+ * agent", and can refuse what an agent must never do alone: change the space's
9
+ * collections, or who may do what. Those always need a person.
10
+ *
11
+ * The fact is the account's word, carried in a note it signed. A note without
12
+ * it is an ordinary app's; nothing about the key itself says "agent".
13
+ */
14
+ import { type Fact } from './ucan.js';
15
+ /** The fact an agent's note carries */
16
+ export declare const AGENT_FACT: Fact;
17
+ /** Whether a note (an encoded UCAN) was made out to an agent. False for anything unreadable. */
18
+ export declare function isAgentNote(encoded: string | null | undefined): boolean;
19
+ //# sourceMappingURL=agent-note.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-note.d.ts","sourceRoot":"","sources":["../../src/identity/agent-note.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAa,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjD,uCAAuC;AACvC,eAAO,MAAM,UAAU,EAAE,IAAwC,CAAC;AAElE,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAQvE"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @module identity/agent-note
3
+ * A note that says its key is an agent's.
4
+ *
5
+ * An agent isn't an identity of its own: it writes for a person, under a note
6
+ * from their account, like any app. What sets it apart is one fact the account
7
+ * signs into that note — so every peer can tell a record was written "via
8
+ * agent", and can refuse what an agent must never do alone: change the space's
9
+ * collections, or who may do what. Those always need a person.
10
+ *
11
+ * The fact is the account's word, carried in a note it signed. A note without
12
+ * it is an ordinary app's; nothing about the key itself says "agent".
13
+ */
14
+ import { parseUCAN } from './ucan.js';
15
+ /** The fact an agent's note carries */
16
+ export const AGENT_FACT = Object.freeze({ weave: 'agent' });
17
+ /** Whether a note (an encoded UCAN) was made out to an agent. False for anything unreadable. */
18
+ export function isAgentNote(encoded) {
19
+ if (!encoded)
20
+ return false;
21
+ try {
22
+ const facts = parseUCAN(encoded).payload.fct;
23
+ return Array.isArray(facts) && facts.some((fact) => fact?.weave === AGENT_FACT.weave);
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ //# sourceMappingURL=agent-note.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-note.js","sourceRoot":"","sources":["../../src/identity/agent-note.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,SAAS,EAAa,MAAM,WAAW,CAAC;AAEjD,uCAAuC;AACvC,MAAM,CAAC,MAAM,UAAU,GAAS,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;AAElE,gGAAgG;AAChG,MAAM,UAAU,WAAW,CAAC,OAAkC;IAC5D,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;QAC7C,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { CryptoProvider } from '../types.js';
2
+ /**
3
+ * Creates a CryptoProvider using the Web Crypto API with ECDSA P-256.
4
+ * @returns {CryptoProvider} A crypto provider implementation for ECDSA P-256.
5
+ */
6
+ export declare function createP256Provider(): CryptoProvider;
7
+ //# sourceMappingURL=crypto-p256.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-p256.d.ts","sourceRoot":"","sources":["../../src/identity/crypto-p256.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAuB,MAAM,aAAa,CAAC;AAqBlE;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,cAAc,CAmHnD"}
@@ -0,0 +1,84 @@
1
+ import { base64UrlEncode } from '../utils/encoding.js';
2
+ import { p256 } from '@noble/curves/nist.js';
3
+ /** 48 bytes: the 32-byte group order plus 16 more, so reducing mod n is unbiased */
4
+ const P256_SEED_BYTES = 48;
5
+ /** Domain separation for identity keys. Changing it changes every derived DID. */
6
+ const P256_KEY_INFO = new TextEncoder().encode('weave/p256-identity-key/v1');
7
+ /** HKDF-SHA256 with an empty salt: the seed is already uniformly random. */
8
+ async function hkdf(ikm, info, length) {
9
+ const key = await globalThis.crypto.subtle.importKey('raw', ikm, 'HKDF', false, ['deriveBits']);
10
+ const bits = await globalThis.crypto.subtle.deriveBits({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(0), info: info }, key, length * 8);
11
+ return new Uint8Array(bits);
12
+ }
13
+ /**
14
+ * Creates a CryptoProvider using the Web Crypto API with ECDSA P-256.
15
+ * @returns {CryptoProvider} A crypto provider implementation for ECDSA P-256.
16
+ */
17
+ export function createP256Provider() {
18
+ return Object.freeze({
19
+ algorithm: 'ECDSA-P256',
20
+ async generateKeyPair() {
21
+ const keyPair = await globalThis.crypto.subtle.generateKey({
22
+ name: 'ECDSA',
23
+ namedCurve: 'P-256'
24
+ },
25
+ // Not extractable: a script that gets into the page can sign with the
26
+ // key while it is there, but cannot carry it off and keep signing.
27
+ // The public half exports regardless.
28
+ false, ['sign', 'verify']);
29
+ return Object.freeze({
30
+ publicKey: keyPair.publicKey,
31
+ privateKey: keyPair.privateKey
32
+ });
33
+ },
34
+ async deriveKeyPairFromSeed(seed) {
35
+ // HKDF stretches the seed to the 48 bytes FIPS 186-5 (appendix A.2) asks
36
+ // for, and noble reduces them to a scalar in [1, n-1] with negligible bias.
37
+ // Web Crypto can sign with a scalar but cannot compute its public point,
38
+ // which is the one step noble supplies.
39
+ const expanded = await hkdf(seed, P256_KEY_INFO, P256_SEED_BYTES);
40
+ const secretKey = p256.utils.randomSecretKey(expanded);
41
+ const point = p256.getPublicKey(secretKey, false); // 0x04 ‖ x ‖ y
42
+ const x = base64UrlEncode(point.subarray(1, 33));
43
+ const y = base64UrlEncode(point.subarray(33, 65));
44
+ const d = base64UrlEncode(secretKey);
45
+ const algorithm = { name: 'ECDSA', namedCurve: 'P-256' };
46
+ const privateKey = await globalThis.crypto.subtle.importKey('jwk', { kty: 'EC', crv: 'P-256', x, y, d, ext: false, key_ops: ['sign'] }, algorithm, false, ['sign']);
47
+ const publicKey = await globalThis.crypto.subtle.importKey('jwk', { kty: 'EC', crv: 'P-256', x, y, ext: true, key_ops: ['verify'] }, algorithm, true, ['verify']);
48
+ return Object.freeze({ publicKey, privateKey });
49
+ },
50
+ async sign(privateKey, data) {
51
+ const signature = await globalThis.crypto.subtle.sign({
52
+ name: 'ECDSA',
53
+ hash: { name: 'SHA-256' }
54
+ }, privateKey, data);
55
+ return new Uint8Array(signature);
56
+ },
57
+ async verify(publicKey, signature, data) {
58
+ return await globalThis.crypto.subtle.verify({
59
+ name: 'ECDSA',
60
+ hash: { name: 'SHA-256' }
61
+ }, publicKey, signature, data);
62
+ },
63
+ /** The 33-byte compressed point — the form did:key specifies for P-256. */
64
+ async exportPublicKey(key) {
65
+ const raw = new Uint8Array(await globalThis.crypto.subtle.exportKey('raw', key));
66
+ return p256.Point.fromBytes(raw).toBytes(true);
67
+ },
68
+ /** Accepts a compressed or uncompressed point; Web Crypto only reliably imports the latter. */
69
+ async importPublicKey(bytes) {
70
+ const uncompressed = p256.Point.fromBytes(bytes).toBytes(false);
71
+ return await globalThis.crypto.subtle.importKey('raw', uncompressed, {
72
+ name: 'ECDSA',
73
+ namedCurve: 'P-256'
74
+ }, true, ['verify']);
75
+ },
76
+ async importPrivateKey(bytes) {
77
+ return await globalThis.crypto.subtle.importKey('pkcs8', bytes, {
78
+ name: 'ECDSA',
79
+ namedCurve: 'P-256'
80
+ }, false, ['sign']);
81
+ }
82
+ });
83
+ }
84
+ //# sourceMappingURL=crypto-p256.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crypto-p256.js","sourceRoot":"","sources":["../../src/identity/crypto-p256.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @module device-key
3
+ * The key that unlocks an account on one device.
4
+ *
5
+ * A passkey can only hand back a secret through the PRF extension, and several
6
+ * widely used providers — Bitwarden among them — store passkeys without it. So
7
+ * the shortcut does not ask the passkey for key material at all. It keeps a
8
+ * random key here, and uses the passkey as the gate in front of it.
9
+ *
10
+ * ```
11
+ * random key, non-extractable, in this origin's storage
12
+ * └─ wraps the account seed, which lives in the vault
13
+ * a passkey assertion decides whether we reach for it
14
+ * ```
15
+ *
16
+ * **Be clear about what that is.** The gate is enforced by this code, not by
17
+ * cryptography: anything that can reach this origin's storage can use the key
18
+ * without ever touching the passkey. What it does protect against is the case
19
+ * that motivates the vault in the first place — someone holding a copy of the
20
+ * folder, who has the wrapped seed and none of this.
21
+ *
22
+ * The key is generated non-extractable, so script can use it in place but
23
+ * cannot copy it out. Malware on the machine can decrypt; it cannot walk away
24
+ * with something that keeps working elsewhere.
25
+ */
26
+ /** A local key, and the id a wrap records to find it again. */
27
+ export interface DeviceKey {
28
+ readonly id: string;
29
+ readonly key: CryptoKey;
30
+ }
31
+ /**
32
+ * Makes a key for this device and remembers it.
33
+ *
34
+ * Non-extractable on purpose: a CryptoKey survives being stored and fetched
35
+ * from IndexedDB, and staying non-extractable the whole time means no code
36
+ * path — ours or anyone's — can turn it back into bytes.
37
+ *
38
+ * @param dbName Overridable for tests
39
+ * @returns The key, and the id a wrap should record
40
+ */
41
+ export declare function createDeviceKey(dbName?: string): Promise<DeviceKey>;
42
+ /**
43
+ * Finds a device key by id.
44
+ *
45
+ * Absent is a normal answer, not a failure: it means this wrap was made in
46
+ * another browser, or storage has been cleared since. The account is still
47
+ * openable by its password.
48
+ *
49
+ * @param id The id recorded in the wrap
50
+ * @param dbName Overridable for tests
51
+ * @returns The key, or null when this device does not have it
52
+ */
53
+ export declare function getDeviceKey(id: string, dbName?: string): Promise<CryptoKey | null>;
54
+ /**
55
+ * Forgets a device key, which makes its wrap permanently unopenable.
56
+ * @param id The id recorded in the wrap
57
+ * @param dbName Overridable for tests
58
+ */
59
+ export declare function deleteDeviceKey(id: string, dbName?: string): Promise<void>;
60
+ //# sourceMappingURL=device-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-key.d.ts","sourceRoot":"","sources":["../../src/identity/device-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAOH,+DAA+D;AAC/D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;CACzB;AAiCD;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CAAC,MAAM,GAAE,MAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAWlF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,MAAM,GAAE,MAAgB,GACvB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAM3B;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,GAAE,MAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMzF"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @module device-key
3
+ * The key that unlocks an account on one device.
4
+ *
5
+ * A passkey can only hand back a secret through the PRF extension, and several
6
+ * widely used providers — Bitwarden among them — store passkeys without it. So
7
+ * the shortcut does not ask the passkey for key material at all. It keeps a
8
+ * random key here, and uses the passkey as the gate in front of it.
9
+ *
10
+ * ```
11
+ * random key, non-extractable, in this origin's storage
12
+ * └─ wraps the account seed, which lives in the vault
13
+ * a passkey assertion decides whether we reach for it
14
+ * ```
15
+ *
16
+ * **Be clear about what that is.** The gate is enforced by this code, not by
17
+ * cryptography: anything that can reach this origin's storage can use the key
18
+ * without ever touching the passkey. What it does protect against is the case
19
+ * that motivates the vault in the first place — someone holding a copy of the
20
+ * folder, who has the wrapped seed and none of this.
21
+ *
22
+ * The key is generated non-extractable, so script can use it in place but
23
+ * cannot copy it out. Malware on the machine can decrypt; it cannot walk away
24
+ * with something that keeps working elsewhere.
25
+ */
26
+ import { base64UrlEncode } from '../utils/encoding.js';
27
+ const DB_NAME = 'weave-device-keys';
28
+ const STORE = 'keys';
29
+ function openDb(dbName) {
30
+ return new Promise((resolve, reject) => {
31
+ const request = globalThis.indexedDB.open(dbName, 1);
32
+ request.onupgradeneeded = () => {
33
+ if (!request.result.objectStoreNames.contains(STORE)) {
34
+ request.result.createObjectStore(STORE);
35
+ }
36
+ };
37
+ request.onsuccess = () => resolve(request.result);
38
+ request.onerror = () => reject(request.error);
39
+ });
40
+ }
41
+ async function withStore(dbName, mode, run) {
42
+ const db = await openDb(dbName);
43
+ try {
44
+ return await new Promise((resolve, reject) => {
45
+ const tx = db.transaction(STORE, mode);
46
+ const request = run(tx.objectStore(STORE));
47
+ request.onsuccess = () => resolve(request.result);
48
+ request.onerror = () => reject(request.error);
49
+ });
50
+ }
51
+ finally {
52
+ db.close();
53
+ }
54
+ }
55
+ /**
56
+ * Makes a key for this device and remembers it.
57
+ *
58
+ * Non-extractable on purpose: a CryptoKey survives being stored and fetched
59
+ * from IndexedDB, and staying non-extractable the whole time means no code
60
+ * path — ours or anyone's — can turn it back into bytes.
61
+ *
62
+ * @param dbName Overridable for tests
63
+ * @returns The key, and the id a wrap should record
64
+ */
65
+ export async function createDeviceKey(dbName = DB_NAME) {
66
+ const key = await globalThis.crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
67
+ const id = base64UrlEncode(globalThis.crypto.getRandomValues(new Uint8Array(12)));
68
+ await withStore(dbName, 'readwrite', (store) => store.put(key, id));
69
+ return { id, key };
70
+ }
71
+ /**
72
+ * Finds a device key by id.
73
+ *
74
+ * Absent is a normal answer, not a failure: it means this wrap was made in
75
+ * another browser, or storage has been cleared since. The account is still
76
+ * openable by its password.
77
+ *
78
+ * @param id The id recorded in the wrap
79
+ * @param dbName Overridable for tests
80
+ * @returns The key, or null when this device does not have it
81
+ */
82
+ export async function getDeviceKey(id, dbName = DB_NAME) {
83
+ try {
84
+ return (await withStore(dbName, 'readonly', (store) => store.get(id))) ?? null;
85
+ }
86
+ catch {
87
+ return null;
88
+ }
89
+ }
90
+ /**
91
+ * Forgets a device key, which makes its wrap permanently unopenable.
92
+ * @param id The id recorded in the wrap
93
+ * @param dbName Overridable for tests
94
+ */
95
+ export async function deleteDeviceKey(id, dbName = DB_NAME) {
96
+ try {
97
+ await withStore(dbName, 'readwrite', (store) => store.delete(id));
98
+ }
99
+ catch {
100
+ // Already gone.
101
+ }
102
+ }
103
+ //# sourceMappingURL=device-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-key.js","sourceRoot":"","sources":["../../src/identity/device-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,OAAO,GAAG,mBAAmB,CAAC;AACpC,MAAM,KAAK,GAAG,MAAM,CAAC;AAQrB,SAAS,MAAM,CAAC,MAAc;IAC5B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,eAAe,GAAG,GAAG,EAAE;YAC7B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CAAC;QACF,OAAO,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClD,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,MAAc,EACd,IAAwB,EACxB,GAA0C;IAE1C,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9C,MAAM,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3C,OAAO,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAW,CAAC,CAAC;YACvD,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB,OAAO;IAC5D,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CACpD,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAChC,KAAK,EACL,CAAC,SAAS,EAAE,SAAS,CAAC,CACvB,CAAC;IAEF,MAAM,EAAE,GAAG,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClF,MAAM,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;IAEpE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;AACrB,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,EAAU,EACV,SAAiB,OAAO;IAExB,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,SAAS,CAAwB,MAAM,EAAE,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACxG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAU,EAAE,SAAiB,OAAO;IACxE,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Multicodec `p256-pub` (0x1200) as a varint. Per the did:key spec the key that
3
+ * follows is the 33-byte compressed point, which is why P-256 DIDs start `zDn`.
4
+ */
5
+ export declare const P256_MULTICODEC: Uint8Array<ArrayBuffer>;
6
+ /**
7
+ * Converts a public key to a did:key string.
8
+ * @param {Uint8Array} publicKeyBytes The public key bytes.
9
+ * @param {Uint8Array} multicodecPrefix The multicodec prefix for the key type.
10
+ * @returns {string} The formatted did:key string.
11
+ */
12
+ export declare function publicKeyToDid(publicKeyBytes: Uint8Array, multicodecPrefix: Uint8Array): string;
13
+ /**
14
+ * Parses a did:key string into its public key and multicodec prefix.
15
+ * @param {string} did The did:key string.
16
+ * @returns {{ publicKeyBytes: Uint8Array; multicodecPrefix: Uint8Array }} The parsed components.
17
+ */
18
+ export declare function didToPublicKey(did: string): {
19
+ publicKeyBytes: Uint8Array;
20
+ multicodecPrefix: Uint8Array;
21
+ };
22
+ //# sourceMappingURL=did.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"did.d.ts","sourceRoot":"","sources":["../../src/identity/did.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,eAAe,yBAA+B,CAAC;AAE5D;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,cAAc,EAAE,UAAU,EAAE,gBAAgB,EAAE,UAAU,GAAG,MAAM,CAG/F;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,cAAc,EAAE,UAAU,CAAC;IAAC,gBAAgB,EAAE,UAAU,CAAA;CAAE,CAiBxG"}