@opendatalabs/personal-server-ts-core 0.0.1-canary.01ca694 → 0.0.1-canary.052d47e

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 (322) hide show
  1. package/dist/api/index.d.ts +282 -9
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +867 -163
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/auth/request.d.ts.map +1 -1
  6. package/dist/auth/request.js.map +1 -1
  7. package/dist/client.d.ts +8 -1
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +21 -3
  10. package/dist/client.js.map +1 -1
  11. package/dist/contracts/binary.d.ts +12 -0
  12. package/dist/contracts/binary.d.ts.map +1 -1
  13. package/dist/contracts/binary.js +31 -0
  14. package/dist/contracts/binary.js.map +1 -1
  15. package/dist/contracts/data.d.ts +51 -5
  16. package/dist/contracts/data.d.ts.map +1 -1
  17. package/dist/contracts/data.js +166 -30
  18. package/dist/contracts/data.js.map +1 -1
  19. package/dist/contracts/grants.d.ts +7 -5
  20. package/dist/contracts/grants.d.ts.map +1 -1
  21. package/dist/contracts/grants.js +60 -37
  22. package/dist/contracts/grants.js.map +1 -1
  23. package/dist/contracts/index.d.ts +1 -1
  24. package/dist/contracts/index.d.ts.map +1 -1
  25. package/dist/contracts/index.js +1 -1
  26. package/dist/contracts/index.js.map +1 -1
  27. package/dist/derivatives/api.d.ts +48 -0
  28. package/dist/derivatives/api.d.ts.map +1 -0
  29. package/dist/derivatives/api.js +366 -0
  30. package/dist/derivatives/api.js.map +1 -0
  31. package/dist/derivatives/compute.d.ts +106 -0
  32. package/dist/derivatives/compute.d.ts.map +1 -0
  33. package/dist/derivatives/compute.js +414 -0
  34. package/dist/derivatives/compute.js.map +1 -0
  35. package/dist/derivatives/e2ee/aad.d.ts +22 -0
  36. package/dist/derivatives/e2ee/aad.d.ts.map +1 -0
  37. package/dist/derivatives/e2ee/aad.js +32 -0
  38. package/dist/derivatives/e2ee/aad.js.map +1 -0
  39. package/dist/derivatives/e2ee/attestation.d.ts +134 -0
  40. package/dist/derivatives/e2ee/attestation.d.ts.map +1 -0
  41. package/dist/derivatives/e2ee/attestation.js +248 -0
  42. package/dist/derivatives/e2ee/attestation.js.map +1 -0
  43. package/dist/derivatives/e2ee/index.d.ts +6 -0
  44. package/dist/derivatives/e2ee/index.d.ts.map +1 -0
  45. package/dist/derivatives/e2ee/index.js +6 -0
  46. package/dist/derivatives/e2ee/index.js.map +1 -0
  47. package/dist/derivatives/e2ee/jcs.d.ts +17 -0
  48. package/dist/derivatives/e2ee/jcs.d.ts.map +1 -0
  49. package/dist/derivatives/e2ee/jcs.js +55 -0
  50. package/dist/derivatives/e2ee/jcs.js.map +1 -0
  51. package/dist/derivatives/e2ee/phala.d.ts +62 -0
  52. package/dist/derivatives/e2ee/phala.d.ts.map +1 -0
  53. package/dist/derivatives/e2ee/phala.js +168 -0
  54. package/dist/derivatives/e2ee/phala.js.map +1 -0
  55. package/dist/derivatives/e2ee/suite.d.ts +56 -0
  56. package/dist/derivatives/e2ee/suite.d.ts.map +1 -0
  57. package/dist/derivatives/e2ee/suite.js +164 -0
  58. package/dist/derivatives/e2ee/suite.js.map +1 -0
  59. package/dist/derivatives/index.d.ts +10 -0
  60. package/dist/derivatives/index.d.ts.map +1 -0
  61. package/dist/derivatives/index.js +10 -0
  62. package/dist/derivatives/index.js.map +1 -0
  63. package/dist/derivatives/inference.d.ts +151 -0
  64. package/dist/derivatives/inference.d.ts.map +1 -0
  65. package/dist/derivatives/inference.js +262 -0
  66. package/dist/derivatives/inference.js.map +1 -0
  67. package/dist/derivatives/prompt.d.ts +64 -0
  68. package/dist/derivatives/prompt.d.ts.map +1 -0
  69. package/dist/derivatives/prompt.js +193 -0
  70. package/dist/derivatives/prompt.js.map +1 -0
  71. package/dist/derivatives/registration.d.ts +54 -0
  72. package/dist/derivatives/registration.d.ts.map +1 -0
  73. package/dist/derivatives/registration.js +180 -0
  74. package/dist/derivatives/registration.js.map +1 -0
  75. package/dist/derivatives/scheduler.d.ts +84 -0
  76. package/dist/derivatives/scheduler.d.ts.map +1 -0
  77. package/dist/derivatives/scheduler.js +257 -0
  78. package/dist/derivatives/scheduler.js.map +1 -0
  79. package/dist/derivatives/store.d.ts +14 -0
  80. package/dist/derivatives/store.d.ts.map +1 -0
  81. package/dist/derivatives/store.js +77 -0
  82. package/dist/derivatives/store.js.map +1 -0
  83. package/dist/derivatives/types.d.ts +92 -0
  84. package/dist/derivatives/types.d.ts.map +1 -0
  85. package/dist/derivatives/types.js +27 -0
  86. package/dist/derivatives/types.js.map +1 -0
  87. package/dist/errors/catalog.d.ts +75 -0
  88. package/dist/errors/catalog.d.ts.map +1 -1
  89. package/dist/errors/catalog.js +104 -0
  90. package/dist/errors/catalog.js.map +1 -1
  91. package/dist/grants/index.d.ts +2 -1
  92. package/dist/grants/index.d.ts.map +1 -1
  93. package/dist/grants/index.js +1 -1
  94. package/dist/grants/index.js.map +1 -1
  95. package/dist/keys/index.d.ts +1 -0
  96. package/dist/keys/index.d.ts.map +1 -1
  97. package/dist/keys/index.js +1 -1
  98. package/dist/keys/index.js.map +1 -1
  99. package/dist/keys/public-only-account.d.ts +8 -0
  100. package/dist/keys/public-only-account.d.ts.map +1 -0
  101. package/dist/keys/public-only-account.js +21 -0
  102. package/dist/keys/public-only-account.js.map +1 -0
  103. package/dist/keys/server-account.d.ts +2 -2
  104. package/dist/keys/server-account.d.ts.map +1 -1
  105. package/dist/lineage/attestation.d.ts +42 -0
  106. package/dist/lineage/attestation.d.ts.map +1 -0
  107. package/dist/lineage/attestation.js +25 -0
  108. package/dist/lineage/attestation.js.map +1 -0
  109. package/dist/lineage/gateway.d.ts +105 -0
  110. package/dist/lineage/gateway.d.ts.map +1 -0
  111. package/dist/lineage/gateway.js +242 -0
  112. package/dist/lineage/gateway.js.map +1 -0
  113. package/dist/lineage/index.d.ts +5 -0
  114. package/dist/lineage/index.d.ts.map +1 -0
  115. package/dist/lineage/index.js +5 -0
  116. package/dist/lineage/index.js.map +1 -0
  117. package/dist/lineage/lineage.d.ts +141 -0
  118. package/dist/lineage/lineage.d.ts.map +1 -0
  119. package/dist/lineage/lineage.js +255 -0
  120. package/dist/lineage/lineage.js.map +1 -0
  121. package/dist/logging/access-log.d.ts +10 -1
  122. package/dist/logging/access-log.d.ts.map +1 -1
  123. package/dist/mcp/activity.d.ts.map +1 -1
  124. package/dist/mcp/activity.js.map +1 -1
  125. package/dist/mcp/connection-api.d.ts.map +1 -1
  126. package/dist/mcp/connection-api.js +0 -1
  127. package/dist/mcp/connection-api.js.map +1 -1
  128. package/dist/mcp/index.d.ts +1 -0
  129. package/dist/mcp/index.d.ts.map +1 -1
  130. package/dist/mcp/index.js +1 -0
  131. package/dist/mcp/index.js.map +1 -1
  132. package/dist/mcp/read-client.d.ts +61 -1
  133. package/dist/mcp/read-client.d.ts.map +1 -1
  134. package/dist/mcp/read-client.js +397 -42
  135. package/dist/mcp/read-client.js.map +1 -1
  136. package/dist/mcp/resources.d.ts +37 -0
  137. package/dist/mcp/resources.d.ts.map +1 -0
  138. package/dist/mcp/resources.js +114 -0
  139. package/dist/mcp/resources.js.map +1 -0
  140. package/dist/mcp/search/index.d.ts.map +1 -1
  141. package/dist/mcp/search/index.js +108 -21
  142. package/dist/mcp/search/index.js.map +1 -1
  143. package/dist/mcp/server.d.ts.map +1 -1
  144. package/dist/mcp/server.js +27 -9
  145. package/dist/mcp/server.js.map +1 -1
  146. package/dist/mcp/session.d.ts +160 -0
  147. package/dist/mcp/session.d.ts.map +1 -0
  148. package/dist/mcp/session.js +243 -0
  149. package/dist/mcp/session.js.map +1 -0
  150. package/dist/mcp/tools.d.ts +29 -3
  151. package/dist/mcp/tools.d.ts.map +1 -1
  152. package/dist/mcp/tools.js +515 -48
  153. package/dist/mcp/tools.js.map +1 -1
  154. package/dist/mcp/types.d.ts.map +1 -1
  155. package/dist/payment/index.d.ts +2 -0
  156. package/dist/payment/index.d.ts.map +1 -0
  157. package/dist/payment/index.js +2 -0
  158. package/dist/payment/index.js.map +1 -0
  159. package/dist/payment/x402.d.ts +155 -0
  160. package/dist/payment/x402.d.ts.map +1 -0
  161. package/dist/payment/x402.js +402 -0
  162. package/dist/payment/x402.js.map +1 -0
  163. package/dist/policy/data-read.d.ts +18 -2
  164. package/dist/policy/data-read.d.ts.map +1 -1
  165. package/dist/policy/data-read.js +80 -49
  166. package/dist/policy/data-read.js.map +1 -1
  167. package/dist/policy/data-write.d.ts +69 -0
  168. package/dist/policy/data-write.d.ts.map +1 -0
  169. package/dist/policy/data-write.js +131 -0
  170. package/dist/policy/data-write.js.map +1 -0
  171. package/dist/policy/index.d.ts +3 -1
  172. package/dist/policy/index.d.ts.map +1 -1
  173. package/dist/policy/index.js +3 -1
  174. package/dist/policy/index.js.map +1 -1
  175. package/dist/policy/signed-artifacts.d.ts +17 -0
  176. package/dist/policy/signed-artifacts.d.ts.map +1 -0
  177. package/dist/policy/signed-artifacts.js +110 -0
  178. package/dist/policy/signed-artifacts.js.map +1 -0
  179. package/dist/ports/index.d.ts +159 -32
  180. package/dist/ports/index.d.ts.map +1 -1
  181. package/dist/ports/index.js +6 -5
  182. package/dist/ports/index.js.map +1 -1
  183. package/dist/schemas/server-config.d.ts +49 -4
  184. package/dist/schemas/server-config.d.ts.map +1 -1
  185. package/dist/schemas/server-config.js +95 -13
  186. package/dist/schemas/server-config.js.map +1 -1
  187. package/dist/signing/index.d.ts +2 -2
  188. package/dist/signing/index.d.ts.map +1 -1
  189. package/dist/signing/index.js +1 -1
  190. package/dist/signing/index.js.map +1 -1
  191. package/dist/signing/request-signer.d.ts +2 -0
  192. package/dist/signing/request-signer.d.ts.map +1 -1
  193. package/dist/signing/request-signer.js +1 -0
  194. package/dist/signing/request-signer.js.map +1 -1
  195. package/dist/signing/signer.d.ts +27 -25
  196. package/dist/signing/signer.d.ts.map +1 -1
  197. package/dist/signing/signer.js +27 -51
  198. package/dist/signing/signer.js.map +1 -1
  199. package/dist/storage/adapters/index.d.ts +1 -1
  200. package/dist/storage/adapters/index.d.ts.map +1 -1
  201. package/dist/storage/adapters/index.js +1 -1
  202. package/dist/storage/adapters/index.js.map +1 -1
  203. package/dist/storage/adapters/interface.d.ts +10 -0
  204. package/dist/storage/adapters/interface.d.ts.map +1 -1
  205. package/dist/storage/adapters/sdk.d.ts +11 -1
  206. package/dist/storage/adapters/sdk.d.ts.map +1 -1
  207. package/dist/storage/adapters/sdk.js +38 -3
  208. package/dist/storage/adapters/sdk.js.map +1 -1
  209. package/dist/storage/adapters/vana.d.ts +3 -0
  210. package/dist/storage/adapters/vana.d.ts.map +1 -1
  211. package/dist/storage/adapters/vana.js +95 -2
  212. package/dist/storage/adapters/vana.js.map +1 -1
  213. package/dist/storage/blocks/errors.d.ts.map +1 -1
  214. package/dist/storage/blocks/errors.js.map +1 -1
  215. package/dist/storage/blocks/index.d.ts +2 -0
  216. package/dist/storage/blocks/index.d.ts.map +1 -1
  217. package/dist/storage/blocks/index.js +2 -0
  218. package/dist/storage/blocks/index.js.map +1 -1
  219. package/dist/storage/blocks/select.d.ts +29 -0
  220. package/dist/storage/blocks/select.d.ts.map +1 -0
  221. package/dist/storage/blocks/select.js +120 -0
  222. package/dist/storage/blocks/select.js.map +1 -0
  223. package/dist/storage/blocks/types.d.ts +7 -0
  224. package/dist/storage/blocks/types.d.ts.map +1 -1
  225. package/dist/storage/index/manager.d.ts +30 -2
  226. package/dist/storage/index/manager.d.ts.map +1 -1
  227. package/dist/storage/index/schema.d.ts +1 -1
  228. package/dist/storage/index/schema.js +1 -1
  229. package/dist/storage/index/types.d.ts +6 -1
  230. package/dist/storage/index/types.d.ts.map +1 -1
  231. package/dist/sync/data-point-feed.d.ts +35 -0
  232. package/dist/sync/data-point-feed.d.ts.map +1 -0
  233. package/dist/sync/data-point-feed.js +122 -0
  234. package/dist/sync/data-point-feed.js.map +1 -0
  235. package/dist/sync/data-point-id.d.ts +7 -0
  236. package/dist/sync/data-point-id.d.ts.map +1 -0
  237. package/dist/sync/data-point-id.js +16 -0
  238. package/dist/sync/data-point-id.js.map +1 -0
  239. package/dist/sync/delete-data-port.d.ts +50 -0
  240. package/dist/sync/delete-data-port.d.ts.map +1 -0
  241. package/dist/sync/delete-data-port.js +244 -0
  242. package/dist/sync/delete-data-port.js.map +1 -0
  243. package/dist/sync/engine/sync-manager.d.ts +16 -4
  244. package/dist/sync/engine/sync-manager.d.ts.map +1 -1
  245. package/dist/sync/engine/sync-manager.js +93 -32
  246. package/dist/sync/engine/sync-manager.js.map +1 -1
  247. package/dist/sync/index.d.ts +7 -0
  248. package/dist/sync/index.d.ts.map +1 -1
  249. package/dist/sync/index.js +7 -0
  250. package/dist/sync/index.js.map +1 -1
  251. package/dist/sync/issues.d.ts.map +1 -1
  252. package/dist/sync/issues.js +21 -3
  253. package/dist/sync/issues.js.map +1 -1
  254. package/dist/sync/pending-blob-deletions.d.ts +29 -0
  255. package/dist/sync/pending-blob-deletions.d.ts.map +1 -0
  256. package/dist/sync/pending-blob-deletions.js +116 -0
  257. package/dist/sync/pending-blob-deletions.js.map +1 -0
  258. package/dist/sync/retry-memory.d.ts +33 -0
  259. package/dist/sync/retry-memory.d.ts.map +1 -0
  260. package/dist/sync/retry-memory.js +68 -0
  261. package/dist/sync/retry-memory.js.map +1 -0
  262. package/dist/sync/scope-deletions.d.ts +155 -0
  263. package/dist/sync/scope-deletions.d.ts.map +1 -0
  264. package/dist/sync/scope-deletions.js +225 -0
  265. package/dist/sync/scope-deletions.js.map +1 -0
  266. package/dist/sync/tombstone.d.ts +27 -0
  267. package/dist/sync/tombstone.d.ts.map +1 -0
  268. package/dist/sync/tombstone.js +28 -0
  269. package/dist/sync/tombstone.js.map +1 -0
  270. package/dist/sync/workers/delete.d.ts +152 -31
  271. package/dist/sync/workers/delete.d.ts.map +1 -1
  272. package/dist/sync/workers/delete.js +457 -55
  273. package/dist/sync/workers/delete.js.map +1 -1
  274. package/dist/sync/workers/download.d.ts +108 -27
  275. package/dist/sync/workers/download.d.ts.map +1 -1
  276. package/dist/sync/workers/download.js +321 -126
  277. package/dist/sync/workers/download.js.map +1 -1
  278. package/dist/sync/workers/upload.d.ts +65 -10
  279. package/dist/sync/workers/upload.d.ts.map +1 -1
  280. package/dist/sync/workers/upload.js +371 -42
  281. package/dist/sync/workers/upload.js.map +1 -1
  282. package/dist/test-utils/e2ee-fixtures.d.ts +94 -0
  283. package/dist/test-utils/e2ee-fixtures.d.ts.map +1 -0
  284. package/dist/test-utils/e2ee-fixtures.js +116 -0
  285. package/dist/test-utils/e2ee-fixtures.js.map +1 -0
  286. package/dist/test-utils/e2ee-gateway.d.ts +61 -0
  287. package/dist/test-utils/e2ee-gateway.d.ts.map +1 -0
  288. package/dist/test-utils/e2ee-gateway.js +248 -0
  289. package/dist/test-utils/e2ee-gateway.js.map +1 -0
  290. package/dist/test-utils/index.d.ts +3 -0
  291. package/dist/test-utils/index.d.ts.map +1 -1
  292. package/dist/test-utils/index.js +3 -0
  293. package/dist/test-utils/index.js.map +1 -1
  294. package/dist/test-utils/memory-storage.d.ts +12 -0
  295. package/dist/test-utils/memory-storage.d.ts.map +1 -0
  296. package/dist/test-utils/memory-storage.js +146 -0
  297. package/dist/test-utils/memory-storage.js.map +1 -0
  298. package/dist/test-utils/wallet.d.ts +6 -0
  299. package/dist/test-utils/wallet.d.ts.map +1 -1
  300. package/dist/test-utils/wallet.js +46 -0
  301. package/dist/test-utils/wallet.js.map +1 -1
  302. package/dist/write/attribution.d.ts +185 -0
  303. package/dist/write/attribution.d.ts.map +1 -0
  304. package/dist/write/attribution.js +450 -0
  305. package/dist/write/attribution.js.map +1 -0
  306. package/dist/write/authorize.d.ts +77 -0
  307. package/dist/write/authorize.d.ts.map +1 -0
  308. package/dist/write/authorize.js +109 -0
  309. package/dist/write/authorize.js.map +1 -0
  310. package/dist/write/index.d.ts +5 -0
  311. package/dist/write/index.d.ts.map +1 -0
  312. package/dist/write/index.js +5 -0
  313. package/dist/write/index.js.map +1 -0
  314. package/dist/write/route.d.ts +61 -0
  315. package/dist/write/route.d.ts.map +1 -0
  316. package/dist/write/route.js +132 -0
  317. package/dist/write/route.js.map +1 -0
  318. package/dist/write/session.d.ts +96 -0
  319. package/dist/write/session.d.ts.map +1 -0
  320. package/dist/write/session.js +136 -0
  321. package/dist/write/session.js.map +1 -0
  322. package/package.json +19 -3
@@ -0,0 +1,69 @@
1
+ import type { GatewayGrantResponse } from "@opendatalabs/vana-sdk/browser";
2
+ import { type AuthSessionVerifierPort, type GrantVerifierPort, type RuntimeAvailabilityPort } from "../ports/index.js";
3
+ /**
4
+ * Write-grant encoding: a grant scope entry prefixed with `write:` authorizes
5
+ * the grantee to WRITE into the scope it names (e.g. `write:notes.entries`,
6
+ * `write:notes.*`). The suffix uses the same pattern grammar as read scopes
7
+ * (`*` / `{prefix}.*` / exact), evaluated with the SDK's scopeMatchesPattern.
8
+ *
9
+ * Why a scope-entry prefix and not a new grant field: the gateway's grant
10
+ * shape (GatewayGrantResponse) has no permission axis — `scopes` is its only
11
+ * capability carrier — and the gateway validates scope entries as opaque
12
+ * non-empty strings, so `write:`-prefixed entries flow through createGrant /
13
+ * getGrant / the EIP-712 GrantRegistration signature unchanged. The Personal
14
+ * Server is the sole interpreter.
15
+ *
16
+ * Separation of powers falls out of the encoding:
17
+ * - read policy matches the REQUESTED scope against grant entries verbatim
18
+ * (scopeCoveredByGrant), and a requested scope never carries the prefix,
19
+ * so `write:x` entries can never satisfy a read;
20
+ * - write policy (below) only honors `write:`-prefixed entries, so plain
21
+ * read entries can never satisfy a write.
22
+ */
23
+ export declare const WRITE_SCOPE_PREFIX = "write:";
24
+ export declare function isWriteScopeEntry(entry: string): boolean;
25
+ /** The scope patterns a grant authorizes for writing (prefix stripped). */
26
+ export declare function writeScopePatterns(grantScopes: readonly string[]): string[];
27
+ export declare function scopeCoveredByWriteGrant(requestedScope: string, grantScopes: readonly string[]): boolean;
28
+ /**
29
+ * Fee seam for builder writes. Write fee mechanics are undecided — the
30
+ * default (no port wired) is FREE. When a fee model lands (x402-style like
31
+ * reads, or something else), implement this port and wire it into
32
+ * DataWritePolicyPorts; the policy calls it after all authorization
33
+ * invariants pass, so a fee rejection never masks an auth failure.
34
+ */
35
+ export interface WriteFeeVerifierPort {
36
+ assertWriteAllowed(input: {
37
+ builder: `0x${string}`;
38
+ grant: GatewayGrantResponse;
39
+ scope: string;
40
+ }): Promise<void>;
41
+ }
42
+ export interface DataWritePolicyInput {
43
+ signer: `0x${string}`;
44
+ grantId?: string;
45
+ requestedScope: string;
46
+ /**
47
+ * This server's owner address. The grant's grantor MUST equal it — a grant
48
+ * issued by a different owner is rejected. Required (not optional) so that
49
+ * TypeScript flags any caller that fails to bind the write to the server
50
+ * owner; the check also fails closed at runtime for untyped/JS callers.
51
+ */
52
+ serverOwner: `0x${string}`;
53
+ }
54
+ export interface DataWritePolicyPorts {
55
+ authSessionVerifier: AuthSessionVerifierPort;
56
+ grantVerifier: GrantVerifierPort;
57
+ runtimeAvailability?: RuntimeAvailabilityPort;
58
+ /** Absent = writes are free (see WriteFeeVerifierPort). */
59
+ writeFeeVerifier?: WriteFeeVerifierPort;
60
+ }
61
+ /**
62
+ * Authorize one builder write against a write-grant. Mirrors
63
+ * verifyDataReadPolicy invariant-for-invariant (builder registered, grant
64
+ * present / not revoked / not expired, scope coverage, grantee binding,
65
+ * owner binding) — but scope coverage only honors `write:`-prefixed grant
66
+ * entries, so a read-grant never confers write access.
67
+ */
68
+ export declare function verifyDataWritePolicy(input: DataWritePolicyInput, ports: DataWritePolicyPorts): Promise<GatewayGrantResponse>;
69
+ //# sourceMappingURL=data-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-write.d.ts","sourceRoot":"","sources":["../../src/policy/data-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAa3E,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB,WAAW,CAAC;AAE3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAK3E;AAED,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAIT;AAED;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,CAAC,KAAK,EAAE;QACxB,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;QACvB,KAAK,EAAE,oBAAoB,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,aAAa,EAAE,iBAAiB,CAAC;IACjC,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;IAC9C,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;CACzC;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,oBAAoB,EAC3B,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,oBAAoB,CAAC,CAkG/B"}
@@ -0,0 +1,131 @@
1
+ import { scopeMatchesPattern } from "@opendatalabs/vana-sdk/browser";
2
+ import { GrantExpiredError, GrantOwnerMismatchError, GrantRequiredError, GrantRevokedError, InvalidSignatureError, PsUnavailableError, ScopeMismatchError, ServerNotConfiguredError, UnregisteredBuilderError, } from "../errors/catalog.js";
3
+ import { parseGrantExpiresAtSeconds } from "./data-read.js";
4
+ /**
5
+ * Write-grant encoding: a grant scope entry prefixed with `write:` authorizes
6
+ * the grantee to WRITE into the scope it names (e.g. `write:notes.entries`,
7
+ * `write:notes.*`). The suffix uses the same pattern grammar as read scopes
8
+ * (`*` / `{prefix}.*` / exact), evaluated with the SDK's scopeMatchesPattern.
9
+ *
10
+ * Why a scope-entry prefix and not a new grant field: the gateway's grant
11
+ * shape (GatewayGrantResponse) has no permission axis — `scopes` is its only
12
+ * capability carrier — and the gateway validates scope entries as opaque
13
+ * non-empty strings, so `write:`-prefixed entries flow through createGrant /
14
+ * getGrant / the EIP-712 GrantRegistration signature unchanged. The Personal
15
+ * Server is the sole interpreter.
16
+ *
17
+ * Separation of powers falls out of the encoding:
18
+ * - read policy matches the REQUESTED scope against grant entries verbatim
19
+ * (scopeCoveredByGrant), and a requested scope never carries the prefix,
20
+ * so `write:x` entries can never satisfy a read;
21
+ * - write policy (below) only honors `write:`-prefixed entries, so plain
22
+ * read entries can never satisfy a write.
23
+ */
24
+ export const WRITE_SCOPE_PREFIX = "write:";
25
+ export function isWriteScopeEntry(entry) {
26
+ return entry.startsWith(WRITE_SCOPE_PREFIX);
27
+ }
28
+ /** The scope patterns a grant authorizes for writing (prefix stripped). */
29
+ export function writeScopePatterns(grantScopes) {
30
+ return grantScopes
31
+ .filter(isWriteScopeEntry)
32
+ .map((entry) => entry.slice(WRITE_SCOPE_PREFIX.length))
33
+ .filter((pattern) => pattern.length > 0);
34
+ }
35
+ export function scopeCoveredByWriteGrant(requestedScope, grantScopes) {
36
+ return writeScopePatterns(grantScopes).some((pattern) => scopeMatchesPattern(requestedScope, pattern));
37
+ }
38
+ /**
39
+ * Authorize one builder write against a write-grant. Mirrors
40
+ * verifyDataReadPolicy invariant-for-invariant (builder registered, grant
41
+ * present / not revoked / not expired, scope coverage, grantee binding,
42
+ * owner binding) — but scope coverage only honors `write:`-prefixed grant
43
+ * entries, so a read-grant never confers write access.
44
+ */
45
+ export async function verifyDataWritePolicy(input, ports) {
46
+ const available = await ports.runtimeAvailability?.isAvailable();
47
+ if (available === false) {
48
+ throw new PsUnavailableError();
49
+ }
50
+ const builder = await ports.authSessionVerifier.getBuilder(input.signer);
51
+ if (!builder) {
52
+ throw new UnregisteredBuilderError();
53
+ }
54
+ if (!input.grantId) {
55
+ throw new GrantRequiredError({
56
+ reason: "No grantId bound to the write session",
57
+ });
58
+ }
59
+ const grant = await ports.grantVerifier.getGrant(input.grantId);
60
+ if (!grant) {
61
+ throw new GrantRequiredError({
62
+ reason: "Grant not found",
63
+ grantId: input.grantId,
64
+ });
65
+ }
66
+ if (grant.revokedAt !== null) {
67
+ throw new GrantRevokedError({ grantId: grant.id });
68
+ }
69
+ if (!grant.scopes || writeScopePatterns(grant.scopes).length === 0) {
70
+ throw new ScopeMismatchError({
71
+ requestedScope: input.requestedScope,
72
+ reason: "Grant has no write scopes",
73
+ });
74
+ }
75
+ if (grant.expiresAt !== null && grant.expiresAt !== undefined) {
76
+ const expiresAtSec = parseGrantExpiresAtSeconds(grant.expiresAt);
77
+ if (expiresAtSec === null) {
78
+ throw new ScopeMismatchError({
79
+ requestedScope: input.requestedScope,
80
+ reason: "Grant expiry is invalid",
81
+ });
82
+ }
83
+ if (expiresAtSec > 0) {
84
+ const nowSec = Math.floor(Date.now() / 1000);
85
+ if (expiresAtSec < nowSec) {
86
+ throw new GrantExpiredError({
87
+ expiresAt: expiresAtSec,
88
+ });
89
+ }
90
+ }
91
+ }
92
+ if (!scopeCoveredByWriteGrant(input.requestedScope, grant.scopes)) {
93
+ throw new ScopeMismatchError({
94
+ requestedScope: input.requestedScope,
95
+ grantedScopes: grant.scopes,
96
+ reason: "Grant does not authorize writing to this scope",
97
+ });
98
+ }
99
+ if (builder.id.toLowerCase() !== grant.granteeId.toLowerCase()) {
100
+ throw new InvalidSignatureError({
101
+ reason: "Write signer is not the grant builder",
102
+ expected: grant.granteeId,
103
+ actual: input.signer,
104
+ });
105
+ }
106
+ // Ownership binding — the grant MUST have been issued by THIS server's
107
+ // owner (same fail-closed rules as verifyDataReadPolicy: a missing
108
+ // serverOwner or a grantor-less gateway response rejects, never skips).
109
+ if (!input.serverOwner) {
110
+ throw new ServerNotConfiguredError({
111
+ reason: "serverOwner is required to verify grant ownership",
112
+ });
113
+ }
114
+ if (!grant.grantorAddress ||
115
+ grant.grantorAddress.toLowerCase() !== input.serverOwner.toLowerCase()) {
116
+ throw new GrantOwnerMismatchError({
117
+ grantId: grant.id,
118
+ expected: input.serverOwner,
119
+ actual: grant.grantorAddress ?? null,
120
+ });
121
+ }
122
+ // All authorization invariants passed — apply the fee seam last (default
123
+ // free; see WriteFeeVerifierPort).
124
+ await ports.writeFeeVerifier?.assertWriteAllowed({
125
+ builder: input.signer,
126
+ grant,
127
+ scope: input.requestedScope,
128
+ });
129
+ return grant;
130
+ }
131
+ //# sourceMappingURL=data-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-write.js","sourceRoot":"","sources":["../../src/policy/data-write.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,4 @@
1
- export { verifyDataReadPolicy, type DataReadPolicyInput, type DataReadPolicyPorts, } from "./data-read.js";
1
+ export { verifyDataReadPolicy, parseGrantExpiresAtSeconds, type DataReadPolicyInput, type DataReadPolicyPorts, } from "./data-read.js";
2
+ export { deriveBuilderId, verifySignedArtifacts, type SignedArtifactInput, type SignedBuilder, type SignedGrant, } from "./signed-artifacts.js";
3
+ export { WRITE_SCOPE_PREFIX, isWriteScopeEntry, writeScopePatterns, scopeCoveredByWriteGrant, verifyDataWritePolicy, type DataWritePolicyInput, type DataWritePolicyPorts, type WriteFeeVerifierPort, } from "./data-write.js";
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,WAAW,GACjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,iBAAiB,CAAC"}
@@ -1,2 +1,4 @@
1
- export { verifyDataReadPolicy, } from "./data-read.js";
1
+ export { verifyDataReadPolicy, parseGrantExpiresAtSeconds, } from "./data-read.js";
2
+ export { deriveBuilderId, verifySignedArtifacts, } from "./signed-artifacts.js";
3
+ export { WRITE_SCOPE_PREFIX, isWriteScopeEntry, writeScopePatterns, scopeCoveredByWriteGrant, verifyDataWritePolicy, } from "./data-write.js";
2
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAGrB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,0BAA0B,GAG3B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,EACf,qBAAqB,GAItB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,GAItB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type Builder, type DataPortabilityGatewayConfig, type GatewayGrantResponse } from "@opendatalabs/vana-sdk/browser";
2
+ import { type Address, type Hex } from "viem";
3
+ export type SignedGrant = GatewayGrantResponse & {
4
+ signature?: string;
5
+ };
6
+ export type SignedBuilder = Builder & {
7
+ signature?: string;
8
+ };
9
+ export interface SignedArtifactInput {
10
+ grant: SignedGrant;
11
+ builder: SignedBuilder;
12
+ gatewayConfig: DataPortabilityGatewayConfig;
13
+ ownerAddress: Address;
14
+ }
15
+ export declare function verifySignedArtifacts(input: SignedArtifactInput): Promise<void>;
16
+ export declare function deriveBuilderId(builder: Pick<Builder, "ownerAddress" | "granteeAddress" | "publicKey" | "appUrl">, gatewayConfig: DataPortabilityGatewayConfig): Hex;
17
+ //# sourceMappingURL=signed-artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signed-artifacts.d.ts","sourceRoot":"","sources":["../../src/policy/signed-artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,4BAA4B,EACjC,KAAK,oBAAoB,EAC1B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAML,KAAK,OAAO,EACZ,KAAK,GAAG,EACT,MAAM,MAAM,CAAC;AAQd,MAAM,MAAM,WAAW,GAAG,oBAAoB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACxE,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAgB7D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,aAAa,CAAC;IACvB,aAAa,EAAE,4BAA4B,CAAC;IAC5C,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,IAAI,CAAC,CAiEf;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CACX,OAAO,EACP,cAAc,GAAG,gBAAgB,GAAG,WAAW,GAAG,QAAQ,CAC3D,EACD,aAAa,EAAE,4BAA4B,GAC1C,GAAG,CAoCL"}
@@ -0,0 +1,110 @@
1
+ import { BUILDER_REGISTRATION_TYPES, builderRegistrationDomain, verifyGrantRegistration, } from "@opendatalabs/vana-sdk/browser";
2
+ import { encodeAbiParameters, isAddressEqual, keccak256, recoverTypedDataAddress, toHex, } from "viem";
3
+ import { publicKeyToAddress } from "viem/accounts";
4
+ import { GrantRevokedError, SignedArtifactInvalidError, SignedArtifactMissingError, } from "../errors/catalog.js";
5
+ const DOMAIN_TYPE = "DataPortabilityDomain(uint256 chainId,address verifyingContract)";
6
+ const DOMAIN_TYPE_HASH = keccak256(toHex(DOMAIN_TYPE));
7
+ function grantExpiryToUint256(value) {
8
+ if (value === null || value === "" || value === "0")
9
+ return "0";
10
+ if (/^\d+$/u.test(value))
11
+ return value;
12
+ const millis = Date.parse(value);
13
+ if (!Number.isNaN(millis))
14
+ return String(Math.floor(millis / 1000));
15
+ throw new SignedArtifactInvalidError({ artifact: "grant" });
16
+ }
17
+ export async function verifySignedArtifacts(input) {
18
+ // TODO(step-4): revokedAt is Gateway-attested; verify revocation on-chain (contract s1 step 6).
19
+ if (input.grant.revokedAt !== null) {
20
+ throw new GrantRevokedError({ grantId: input.grant.id });
21
+ }
22
+ if (!input.grant.signature || !input.builder.signature) {
23
+ throw new SignedArtifactMissingError();
24
+ }
25
+ let grant;
26
+ try {
27
+ grant = await verifyGrantRegistration({
28
+ gatewayConfig: input.gatewayConfig,
29
+ grantorAddress: input.grant.grantorAddress,
30
+ granteeId: input.grant.granteeId,
31
+ scopes: input.grant.scopes,
32
+ grantVersion: input.grant.grantVersion,
33
+ expiresAt: grantExpiryToUint256(input.grant.expiresAt),
34
+ signature: input.grant.signature,
35
+ });
36
+ }
37
+ catch {
38
+ throw new SignedArtifactInvalidError({ artifact: "grant" });
39
+ }
40
+ if (!grant.valid ||
41
+ !sameAddress(grant.grantorAddress, input.ownerAddress) ||
42
+ !sameAddress(grant.grantorAddress, input.grant.grantorAddress)) {
43
+ throw new SignedArtifactInvalidError({ artifact: "grant" });
44
+ }
45
+ let recoveredBuilder;
46
+ let publicKeyAddress;
47
+ let builderId;
48
+ try {
49
+ recoveredBuilder = await recoverTypedDataAddress({
50
+ domain: builderRegistrationDomain(input.gatewayConfig),
51
+ types: BUILDER_REGISTRATION_TYPES,
52
+ primaryType: "BuilderRegistration",
53
+ message: {
54
+ ownerAddress: input.builder.ownerAddress,
55
+ granteeAddress: input.builder.granteeAddress,
56
+ publicKey: input.builder.publicKey,
57
+ appUrl: input.builder.appUrl,
58
+ },
59
+ signature: input.builder.signature,
60
+ });
61
+ publicKeyAddress = publicKeyToAddress(input.builder.publicKey);
62
+ builderId = deriveBuilderId(input.builder, input.gatewayConfig);
63
+ }
64
+ catch {
65
+ throw new SignedArtifactInvalidError({ artifact: "builder" });
66
+ }
67
+ if (!sameAddress(recoveredBuilder, input.builder.ownerAddress) ||
68
+ !sameAddress(publicKeyAddress, input.builder.granteeAddress) ||
69
+ // id is not signed; rebinding it to the signed fields stops a Gateway from
70
+ // pairing an attacker's signed builder with the owner's grant.
71
+ builderId.toLowerCase() !== input.builder.id.toLowerCase() ||
72
+ builderId.toLowerCase() !== input.grant.granteeId.toLowerCase()) {
73
+ throw new SignedArtifactInvalidError({ artifact: "builder" });
74
+ }
75
+ }
76
+ export function deriveBuilderId(builder, gatewayConfig) {
77
+ const domain = builderRegistrationDomain(gatewayConfig);
78
+ if (domain.chainId === undefined || domain.verifyingContract === undefined) {
79
+ throw new Error("Builder registration domain is incomplete");
80
+ }
81
+ // Gateway/on-chain IDs use this custom domain separator, distinct from the
82
+ // standard EIP-712 domain hash used to verify the builder signature above.
83
+ const domainSeparator = keccak256(encodeAbiParameters([
84
+ { name: "typeHash", type: "bytes32" },
85
+ { name: "chainId", type: "uint256" },
86
+ { name: "verifyingContract", type: "address" },
87
+ ], [DOMAIN_TYPE_HASH, BigInt(domain.chainId), domain.verifyingContract]));
88
+ return keccak256(encodeAbiParameters([
89
+ { name: "domainSeparator", type: "bytes32" },
90
+ { name: "owner", type: "address" },
91
+ { name: "granteeAddress", type: "address" },
92
+ { name: "publicKey", type: "string" },
93
+ { name: "appUrl", type: "string" },
94
+ ], [
95
+ domainSeparator,
96
+ builder.ownerAddress,
97
+ builder.granteeAddress,
98
+ builder.publicKey,
99
+ builder.appUrl,
100
+ ]));
101
+ }
102
+ function sameAddress(left, right) {
103
+ try {
104
+ return isAddressEqual(left, right);
105
+ }
106
+ catch {
107
+ return false;
108
+ }
109
+ }
110
+ //# sourceMappingURL=signed-artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signed-artifacts.js","sourceRoot":"","sources":["../../src/policy/signed-artifacts.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,uBAAuB,GAIxB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,KAAK,GAGN,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EACL,iBAAiB,EACjB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAK9B,MAAM,WAAW,GACf,kEAAkE,CAAC;AACrE,MAAM,gBAAgB,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;AAEvD,SAAS,oBAAoB,CAAC,KAAoB;IAChD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,GAAG,CAAC;IAChE,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEvC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAEpE,MAAM,IAAI,0BAA0B,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;AAC9D,CAAC;AASD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAA0B;IAE1B,gGAAgG;IAChG,IAAI,KAAK,CAAC,KAAK,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,iBAAiB,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;QACvD,MAAM,IAAI,0BAA0B,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,uBAAuB,CAAC;YACpC,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,cAAyB;YACrD,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAA0B;YACjD,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;YAC1B,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY;YACtC,SAAS,EAAE,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC;YACtD,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAA0B;SAClD,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,0BAA0B,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,IACE,CAAC,KAAK,CAAC,KAAK;QACZ,CAAC,WAAW,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,YAAY,CAAC;QACtD,CAAC,WAAW,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,EAC9D,CAAC;QACD,MAAM,IAAI,0BAA0B,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,gBAAyB,CAAC;IAC9B,IAAI,gBAAyB,CAAC;IAC9B,IAAI,SAAc,CAAC;IACnB,IAAI,CAAC;QACH,gBAAgB,GAAG,MAAM,uBAAuB,CAAC;YAC/C,MAAM,EAAE,yBAAyB,CAAC,KAAK,CAAC,aAAa,CAAC;YACtD,KAAK,EAAE,0BAA0B;YACjC,WAAW,EAAE,qBAAqB;YAClC,OAAO,EAAE;gBACP,YAAY,EAAE,KAAK,CAAC,OAAO,CAAC,YAAuB;gBACnD,cAAc,EAAE,KAAK,CAAC,OAAO,CAAC,cAAyB;gBACvD,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS;gBAClC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;aAC7B;YACD,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,SAA0B;SACpD,CAAC,CAAC;QACH,gBAAgB,GAAG,kBAAkB,CACnC,KAAK,CAAC,OAAO,CAAC,SAA0B,CACzC,CAAC;QACF,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,0BAA0B,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,IACE,CAAC,WAAW,CAAC,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QAC1D,CAAC,WAAW,CAAC,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC;QAC5D,2EAA2E;QAC3E,+DAA+D;QAC/D,SAAS,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE;QAC1D,SAAS,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,EAC/D,CAAC;QACD,MAAM,IAAI,0BAA0B,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,OAGC,EACD,aAA2C;IAE3C,MAAM,MAAM,GAAG,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACxD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IACD,2EAA2E;IAC3E,2EAA2E;IAC3E,MAAM,eAAe,GAAG,SAAS,CAC/B,mBAAmB,CACjB;QACE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE;QACrC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;QACpC,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE;KAC/C,EACD,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,iBAAiB,CAAC,CACrE,CACF,CAAC;IAEF,OAAO,SAAS,CACd,mBAAmB,CACjB;QACE,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,SAAS,EAAE;QAC5C,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE;QAClC,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,SAAS,EAAE;QAC3C,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE;QACrC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE;KACnC,EACD;QACE,eAAe;QACf,OAAO,CAAC,YAAuB;QAC/B,OAAO,CAAC,cAAyB;QACjC,OAAO,CAAC,SAAS;QACjB,OAAO,CAAC,MAAM;KACf,CACF,CACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,KAAa;IAC9C,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,IAAe,EAAE,KAAgB,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { Builder, DataFileEnvelope, FileListResult, FileRecord, GatewayGrantResponse, Schema, ServerInfo } from "@opendatalabs/vana-sdk/browser";
1
+ import type { Builder, DataFileEnvelope, DataPointListResult, DataPointRecord, GatewayGrantResponse, ListDataPointsOptions, Schema, ServerInfo } from "@opendatalabs/vana-sdk/browser";
2
2
  import type { WriteResult } from "../storage/hierarchy/index.js";
3
3
  import type { DataBlockManifest, DataScopeBlock, ReadScopeBlocksResponse } from "../storage/blocks/index.js";
4
4
  import type { IndexEntry, NewIndexEntry, ScopeSummary } from "../storage/index/types.js";
@@ -7,8 +7,8 @@ export interface ProtocolGatewayPort {
7
7
  getGrant(grantId: string): Promise<GatewayGrantResponse | null>;
8
8
  getSchemaForScope(scope: string): Promise<Schema | null>;
9
9
  getServer(address: string): Promise<ServerInfo | null>;
10
- getFile(fileId: string): Promise<FileRecord | null>;
11
- listFilesSince(owner: string, cursor: string | null): Promise<FileListResult>;
10
+ getDataPoint(dataPointId: string): Promise<DataPointRecord | null>;
11
+ listDataPointsByOwner(owner: string, cursor: string | null, options?: ListDataPointsOptions): Promise<DataPointListResult>;
12
12
  }
13
13
  export interface GrantVerifierPort {
14
14
  getGrant(grantId: string): Promise<GatewayGrantResponse | null>;
@@ -16,25 +16,9 @@ export interface GrantVerifierPort {
16
16
  export interface AuthSessionVerifierPort {
17
17
  getBuilder(address: string): Promise<Builder | null>;
18
18
  }
19
- export interface SchemaResolverPort {
20
- getSchemaForScope(scope: string): Promise<Schema | null>;
21
- }
22
- /** Result of registering (or idempotently resolving) a schema for a scope. */
23
- export interface RegisteredSchema {
24
- schemaId: string;
25
- definitionUrl: string;
26
- }
27
- /**
28
- * Registers a permissive "no-schema" schema for scopes that carry unstructured
29
- * data (e.g. binary blobs). Idempotent on scope at the gateway: registering an
30
- * already-registered scope returns its existing schemaId.
31
- */
32
- export interface SchemaRegistrarPort {
33
- registerNoSchema(scope: string): Promise<RegisteredSchema>;
34
- }
35
19
  export interface FileRegistrySyncRegistryPort {
36
- getFile(fileId: string): Promise<FileRecord | null>;
37
- listFilesSince(owner: string, cursor: string | null): Promise<FileListResult>;
20
+ getDataPoint(dataPointId: string): Promise<DataPointRecord | null>;
21
+ listDataPointsByOwner(owner: string, cursor: string | null, options?: ListDataPointsOptions): Promise<DataPointListResult>;
38
22
  }
39
23
  export interface PlatformCryptoPort {
40
24
  randomBytes(length: number): Uint8Array;
@@ -67,6 +51,8 @@ export interface DataStoragePort extends RuntimeStoragePort {
67
51
  countVersions(scope: string): number;
68
52
  findEntry(lookup: DataStorageEntryLookup): IndexEntry | undefined;
69
53
  findByFileId(fileId: string): IndexEntry | undefined;
54
+ /** Dedup lookup for the download worker: find an entry by its DPv2 data-point id. */
55
+ findByDataPointId(dataPointId: string): IndexEntry | undefined;
70
56
  findUnsynced(options?: {
71
57
  limit?: number;
72
58
  }): IndexEntry[];
@@ -77,12 +63,35 @@ export interface DataStoragePort extends RuntimeStoragePort {
77
63
  readScopeBlocks?(scope: string, collectedAt: string, options: {
78
64
  cursor?: string;
79
65
  maxBytes: number;
66
+ /**
67
+ * Block-addressed read: return only these blocks, in this order. When
68
+ * set, `cursor` is ignored and no `nextCursor` is produced; `maxBytes`
69
+ * still applies and any ids it cuts off are reported as warnings.
70
+ */
71
+ blockIds?: readonly string[];
80
72
  }): Promise<ReadScopeBlocksResponse>;
73
+ /**
74
+ * Read a scope's block manifest (table of contents) without reading any block
75
+ * values. Returns null when the scope has no manifest yet.
76
+ */
77
+ readBlockManifest?(scope: string, collectedAt: string): Promise<DataBlockManifest | null>;
81
78
  hasScopeBlocks?(scope: string, collectedAt: string): boolean | Promise<boolean>;
79
+ canReadScopeBlocks?(scope: string, collectedAt: string): boolean | Promise<boolean>;
82
80
  writeEnvelope(envelope: DataFileEnvelope): Promise<WriteResult>;
83
81
  writeBlockManifest?(scope: string, collectedAt: string, manifest: DataBlockManifest, blocks: DataScopeBlock[]): Promise<void>;
84
82
  insertEntry(entry: NewIndexEntry): IndexEntry | Promise<IndexEntry>;
85
83
  updateFileId(path: string, fileId: string): boolean | Promise<boolean>;
84
+ /** Highest stored DPv2 `version` for a scope; 0 if none. */
85
+ findLatestVersionByScope(scope: string): number | Promise<number>;
86
+ /** Stamps the DPv2 dataPointId on an entry after registerDataPoint. */
87
+ updateDataPointId(path: string, dataPointId: string): boolean | Promise<boolean>;
88
+ /**
89
+ * Rewrites the DPv2 `version` on an entry. Used when the upload worker
90
+ * rebases a registration onto the registry's live version after a
91
+ * stale-expectedVersion conflict — the blob key embeds the version, so
92
+ * the local row must follow the registered one.
93
+ */
94
+ updateEntryVersion(path: string, version: number): boolean | Promise<boolean>;
86
95
  deleteScope(scope: string): Promise<number>;
87
96
  /**
88
97
  * Delete a single version (index entry + its local blob) by its gateway fileId.
@@ -90,23 +99,141 @@ export interface DataStoragePort extends RuntimeStoragePort {
90
99
  * Used by sync delete-reconciliation to drop a copy the gateway reports as deleted.
91
100
  */
92
101
  deleteByFileId(fileId: string): Promise<boolean>;
102
+ /**
103
+ * Delete a single version (index entry + its local blob + block sidecars)
104
+ * by its DPv2 identity (scope, collectedAt). Returns true if a local copy
105
+ * existed and was removed, false if none was present (no-op). Used by sync
106
+ * deletion reconciliation to drop the exact versions a gateway tombstone
107
+ * covers while leaving a newer local re-ingest in place.
108
+ */
109
+ deleteVersion(scope: string, collectedAt: string): Promise<boolean>;
110
+ /**
111
+ * Drop a single unsynced index entry by path, WITHOUT touching any blob.
112
+ * Used by the upload worker to evict an orphaned row whose local payload
113
+ * file is already gone (e.g. a manual `data/<scope>` deletion): the row can
114
+ * never upload, so retrying it head-blocks the scope forever. Returns true
115
+ * if a row was removed. No-op-safe when the path is unknown.
116
+ */
117
+ dropUnsyncedEntry?(path: string): boolean | Promise<boolean>;
93
118
  }
94
119
  export interface RuntimeAvailabilityPort {
95
120
  isAvailable(): boolean | Promise<boolean>;
96
121
  }
97
- export interface FeeVerificationInput {
98
- grantId: string;
99
- builderAddress: `0x${string}`;
100
- requestedScope: string;
122
+ /**
123
+ * A gateway data-point row as seen by sync, including the deletion marker the
124
+ * plain SDK `DataPointRecord` does not model. `deletedAt` is null while the
125
+ * point is live and an ISO timestamp once the owner has tombstoned it.
126
+ */
127
+ export interface DataPointFeedRecord extends DataPointRecord {
128
+ deletedAt: string | null;
129
+ }
130
+ export interface DataPointFeedListOptions extends ListDataPointsOptions {
131
+ /**
132
+ * Ask the gateway to include tombstoned rows (with `deletedAt` set). Sync
133
+ * always passes true: deletions must reach every replica or the local copy
134
+ * would be re-uploaded and resurrect the point.
135
+ */
136
+ includeDeleted?: boolean;
137
+ }
138
+ export interface DataPointFeedListResult {
139
+ dataPoints: DataPointFeedRecord[];
140
+ cursor: string | null;
101
141
  }
102
- export type FeeVerificationResult = {
103
- ok: true;
142
+ /**
143
+ * Deletion-aware view of the gateway data-point registry. Mirrors the SDK
144
+ * `GatewayClient` listing/lookup shape but surfaces `deletedAt`, which the
145
+ * SDK client (3.14) neither requests (`includeDeleted`) nor types.
146
+ */
147
+ export interface DataPointFeedPort {
148
+ listDataPointsByOwner(owner: string, cursor: string | null, options?: DataPointFeedListOptions): Promise<DataPointFeedListResult>;
149
+ /**
150
+ * Current registry row for (owner, scope), deleted or not. Null when the
151
+ * point was never registered. A tombstoned point comes back with
152
+ * `deletedAt` set (never as a thrown 410).
153
+ */
154
+ getDataPoint(input: {
155
+ ownerAddress: string;
156
+ scope: string;
157
+ }): Promise<DataPointFeedRecord | null>;
158
+ }
159
+ export type TombstoneOutcome = {
160
+ status: "tombstoned";
161
+ dataPointId: string;
162
+ /** The tombstone's own version (previous current + 1). */
163
+ version: string;
164
+ deletedAt: string | null;
104
165
  } | {
105
- ok: false;
106
- reason?: string;
166
+ status: "already-deleted";
167
+ dataPointId: string;
168
+ /**
169
+ * The winning tombstone's registry version as the gateway reports it
170
+ * (possibly higher than the version this replica attempted), or null
171
+ * when the gateway did not say. Null means the covered key range is
172
+ * unknown, so callers defer enumeration rather than guess.
173
+ */
174
+ version: string | null;
175
+ deletedAt: string | null;
176
+ } | {
177
+ /** The gateway has no row for (owner, scope): nothing to tombstone. */
178
+ status: "not-registered";
179
+ dataPointId: string;
107
180
  };
108
- export interface FeeVerifierPort {
109
- verifyDataReadFee(input: FeeVerificationInput): Promise<FeeVerificationResult>;
181
+ export interface DeleteBlobVersionsOutcome {
182
+ /** Versions whose blob existed and was deleted. */
183
+ deleted: string[];
184
+ /** Versions with no blob in storage (404): nothing to do, counts as done. */
185
+ missing: string[];
186
+ /** Versions whose delete failed (rate limit, 5xx, network); retry later. */
187
+ failed: Array<{
188
+ version: string;
189
+ error: string;
190
+ }>;
191
+ }
192
+ /**
193
+ * Remote side of durable deletion. `tombstone` is the durable fact (an
194
+ * owner-signed AddData with the tombstone commitments, recorded by the
195
+ * gateway); `deleteBlobVersions` removes the ciphertext of exactly the given
196
+ * versions, one exact-key delete per version, never a scope-wide prefix: a
197
+ * re-add registered after the tombstone lives under a higher version key and
198
+ * is untouched by construction. Callers MUST run tombstone first: a blob
199
+ * delete without a tombstone leaves a live registry row every replica would
200
+ * 404 on and then wedge.
201
+ */
202
+ export interface DeleteDataPort {
203
+ tombstone(scope: string): Promise<TombstoneOutcome>;
204
+ deleteBlobVersions(scope: string, versions: string[]): Promise<DeleteBlobVersionsOutcome>;
205
+ }
206
+ /**
207
+ * Blob deletion work still to do after a tombstone landed, in one of three
208
+ * shapes:
209
+ * - an exact key: `{ scope, version }`;
210
+ * - a contiguous version range `{ scope, version: null, range }` (both
211
+ * bounds inclusive, decimal strings): the registry versions a tombstone
212
+ * covers, kept as bounds so a large tombstone version never has to be
213
+ * materialised key by key; passes take keys from the head and advance
214
+ * `from`;
215
+ * - an unexpanded marker `{ scope, version: null }` (no range): the gateway
216
+ * did not report the tombstone's version, so the covered range is not
217
+ * known yet; the retry expands it once the registry answers.
218
+ */
219
+ export interface PendingBlobDeletion {
220
+ scope: string;
221
+ version: string | null;
222
+ range?: {
223
+ from: string;
224
+ to: string;
225
+ };
226
+ }
227
+ /**
228
+ * Durable retry marker for blob deletions that could not complete AFTER the
229
+ * gateway tombstone landed (storage failure, rate limit, or a batch larger
230
+ * than one pass may send). The tombstone already makes the deletion stick;
231
+ * this only exists so later sync cycles finish removing the ciphertext, key
232
+ * by key.
233
+ */
234
+ export interface PendingBlobDeletionStore {
235
+ list(): Promise<PendingBlobDeletion[]>;
236
+ add(keys: PendingBlobDeletion[]): Promise<void>;
237
+ remove(keys: PendingBlobDeletion[]): Promise<void>;
110
238
  }
111
- export declare const allowAllFeeVerifier: FeeVerifierPort;
112
239
  //# sourceMappingURL=index.d.ts.map