@opendatalabs/vana-sdk 3.3.0 → 3.4.1-canary.5ef490b

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 (43) hide show
  1. package/dist/index.browser.d.ts +6 -3
  2. package/dist/index.browser.js +379 -125
  3. package/dist/index.browser.js.map +4 -4
  4. package/dist/index.node.cjs +401 -130
  5. package/dist/index.node.cjs.map +4 -4
  6. package/dist/index.node.d.ts +6 -3
  7. package/dist/index.node.js +379 -125
  8. package/dist/index.node.js.map +4 -4
  9. package/dist/protocol/data-point-status.cjs +80 -0
  10. package/dist/protocol/data-point-status.cjs.map +1 -0
  11. package/dist/protocol/data-point-status.d.ts +34 -0
  12. package/dist/protocol/data-point-status.js +51 -0
  13. package/dist/protocol/data-point-status.js.map +1 -0
  14. package/dist/protocol/data-point-status.test.d.ts +1 -0
  15. package/dist/protocol/eip712.cjs +53 -31
  16. package/dist/protocol/eip712.cjs.map +1 -1
  17. package/dist/protocol/eip712.d.ts +98 -43
  18. package/dist/protocol/eip712.js +47 -27
  19. package/dist/protocol/eip712.js.map +1 -1
  20. package/dist/protocol/escrow-deposit.cjs +89 -0
  21. package/dist/protocol/escrow-deposit.cjs.map +1 -0
  22. package/dist/protocol/escrow-deposit.d.ts +47 -0
  23. package/dist/protocol/escrow-deposit.js +60 -0
  24. package/dist/protocol/escrow-deposit.js.map +1 -0
  25. package/dist/protocol/escrow-deposit.test.d.ts +1 -0
  26. package/dist/protocol/escrow-flow.test.d.ts +21 -0
  27. package/dist/protocol/fee-registry.cjs +116 -0
  28. package/dist/protocol/fee-registry.cjs.map +1 -0
  29. package/dist/protocol/fee-registry.d.ts +151 -0
  30. package/dist/protocol/fee-registry.js +89 -0
  31. package/dist/protocol/fee-registry.js.map +1 -0
  32. package/dist/protocol/fee-registry.test.d.ts +1 -0
  33. package/dist/protocol/gateway.cjs +111 -35
  34. package/dist/protocol/gateway.cjs.map +1 -1
  35. package/dist/protocol/gateway.d.ts +240 -45
  36. package/dist/protocol/gateway.js +111 -35
  37. package/dist/protocol/gateway.js.map +1 -1
  38. package/dist/protocol/grants.cjs +24 -64
  39. package/dist/protocol/grants.cjs.map +1 -1
  40. package/dist/protocol/grants.d.ts +6 -13
  41. package/dist/protocol/grants.js +24 -63
  42. package/dist/protocol/grants.js.map +1 -1
  43. package/package.json +3 -2
@@ -1,6 +1,22 @@
1
1
  export interface GatewayEnvelope<T> {
2
2
  data: T;
3
3
  proof: GatewayProof;
4
+ /**
5
+ * Cursor-based pagination metadata, present on list endpoints (e.g.
6
+ * `GET /v1/data`). A sibling of `data`, not nested inside it — so callers
7
+ * that need it must read the full envelope rather than going through
8
+ * `unwrapEnvelope`, which intentionally returns only `data`.
9
+ */
10
+ pagination?: GatewayPagination;
11
+ }
12
+ export interface GatewayPagination {
13
+ limit: number;
14
+ hasMore: boolean;
15
+ /**
16
+ * Opaque cursor for the NEXT page; pass back as the `cursor` query param.
17
+ * Null when there are no further pages.
18
+ */
19
+ nextCursor: string | null;
4
20
  }
5
21
  export interface GatewayProof {
6
22
  signature: string;
@@ -35,62 +51,71 @@ export interface ServerInfo {
35
51
  publicKey: string;
36
52
  serverUrl: string;
37
53
  addedAt: string;
54
+ revokedAt: string | null;
38
55
  }
56
+ export interface GatewayGrantFee {
57
+ asset: string;
58
+ registrationFee: string;
59
+ dataAccessFee: string;
60
+ totalDue: string;
61
+ }
62
+ export type GatewayGrantStatus = "pending" | "submitting" | "confirmed" | "finalized" | "reorged";
39
63
  export interface GatewayGrantResponse {
40
64
  id: string;
41
65
  grantorAddress: string;
42
66
  granteeId: string;
43
- grant: string;
44
- fileIds: string[];
45
- status: "pending" | "confirmed";
67
+ scopes: string[];
68
+ status: GatewayGrantStatus;
46
69
  addedAt: string;
70
+ expiresAt: string | null;
71
+ expired: boolean;
47
72
  revokedAt: string | null;
48
73
  revocationSignature: string | null;
74
+ paymentStatus: "pending" | "paid";
75
+ paidAt: string | null;
76
+ paidBy: string | null;
77
+ grantVersion: string;
78
+ settleTxHash: string | null;
79
+ settleSubmittedAt: string | null;
80
+ revocationTxHash: string | null;
81
+ revocationSubmittedAt: string | null;
82
+ fee: GatewayGrantFee;
49
83
  }
50
- export interface GrantListItem {
84
+ export type GrantListItem = GatewayGrantResponse;
85
+ export interface DataPointRecord {
51
86
  id: string;
52
- grantorAddress: string;
53
- granteeId: string;
54
- grant: string;
55
- fileIds: string[];
56
- status: "pending" | "confirmed";
87
+ ownerAddress: string;
88
+ scope: string;
89
+ dataHash: string;
90
+ metadataHash: string;
91
+ expectedVersion: string;
57
92
  addedAt: string;
58
- revokedAt: string | null;
59
- revocationSignature: string | null;
60
- }
61
- export interface FileRecord {
62
- fileId: string;
63
- owner: string;
64
- url: string;
65
- schemaId: string;
66
- createdAt: string;
67
93
  }
68
- export interface FileListResult {
69
- files: FileRecord[];
94
+ export interface DataPointListResult {
95
+ dataPoints: DataPointRecord[];
70
96
  cursor: string | null;
71
97
  }
72
- export interface RegisterFileParams {
73
- ownerAddress: string;
74
- url: string;
75
- schemaId: string;
76
- signature: string;
98
+ export interface ListDataPointsOptions {
99
+ /**
100
+ * Only return rows added at or after this ISO 8601 timestamp. Used by sync
101
+ * loops that want incremental tails — pass the last seen `addedAt`.
102
+ */
103
+ since?: string;
104
+ /** Page size. Capped at 1000 by the gateway. */
105
+ limit?: number;
77
106
  }
78
107
  export interface CreateGrantParams {
79
108
  grantorAddress: string;
80
109
  granteeId: string;
81
- grant: string;
82
- fileIds: string[];
110
+ scopes: string[];
111
+ grantVersion: string;
112
+ expiresAt: string;
83
113
  signature: string;
84
114
  }
85
115
  export interface RevokeGrantParams {
86
116
  grantId: string;
87
117
  grantorAddress: string;
88
- signature: string;
89
- }
90
- export interface DeleteFileParams {
91
- fileId: string;
92
- ownerAddress: string;
93
- /** EIP-712 FileDeletion signature, signed by the owner or the owner's registered server. */
118
+ grantVersion: string;
94
119
  signature: string;
95
120
  }
96
121
  export interface RegisterServerParams {
@@ -104,6 +129,171 @@ export interface RegisterServerResult {
104
129
  serverId?: string;
105
130
  alreadyRegistered: boolean;
106
131
  }
132
+ export interface RegisterBuilderParams {
133
+ ownerAddress: string;
134
+ granteeAddress: string;
135
+ publicKey: string;
136
+ appUrl: string;
137
+ signature: string;
138
+ }
139
+ export interface RegisterBuilderResult {
140
+ builderId?: string;
141
+ alreadyRegistered: boolean;
142
+ }
143
+ export interface RegisterDataPointParams {
144
+ ownerAddress: string;
145
+ scope: string;
146
+ dataHash: string;
147
+ metadataHash: string;
148
+ expectedVersion: string;
149
+ signature: string;
150
+ }
151
+ export interface RegisterDataPointResult {
152
+ dataPointId?: string;
153
+ expectedVersion?: string;
154
+ }
155
+ export interface AccessRecord {
156
+ dataPointId: string;
157
+ version: string;
158
+ accessor: string;
159
+ recordId: string;
160
+ signature: string;
161
+ }
162
+ export interface PayForOperationParams {
163
+ payerAddress: string;
164
+ opType: string;
165
+ opId: string;
166
+ asset: string;
167
+ amount: string;
168
+ paymentNonce: string;
169
+ signature: string;
170
+ accessRecord?: AccessRecord;
171
+ }
172
+ export interface PayForOperationResult {
173
+ opType: string;
174
+ opId: string;
175
+ payerAddress: string;
176
+ asset: string;
177
+ amount: string;
178
+ breakdown: {
179
+ registrationFee: string;
180
+ dataAccessFee: string;
181
+ registrationPaid: boolean;
182
+ };
183
+ paymentNonce: string;
184
+ paidAt: string;
185
+ }
186
+ export type SettleOpType = "grant" | "server" | "data" | "access";
187
+ export type SettleItem = {
188
+ opType: SettleOpType;
189
+ opId: string;
190
+ status: "submitting" | "confirmed";
191
+ settleTxHash: string | null;
192
+ settleSubmittedAt: string | null;
193
+ chainBlockHeight: string | null;
194
+ revocationTxHash: string | null;
195
+ revocationSubmittedAt: string | null;
196
+ placeholder: boolean;
197
+ } | {
198
+ opType: SettleOpType;
199
+ opId: string;
200
+ status: "skipped";
201
+ reason: string;
202
+ } | {
203
+ opType: SettleOpType;
204
+ opId: string;
205
+ status: "failed";
206
+ error: string;
207
+ };
208
+ export interface SettlePromoteResult {
209
+ opType: SettleOpType;
210
+ opId: string;
211
+ status: "confirmed" | "failed" | "pending" | "skipped";
212
+ txHash: string;
213
+ chainBlockHeight: string | null;
214
+ reason?: string;
215
+ }
216
+ export interface SettleReconcileItem {
217
+ opId: string;
218
+ status: "finalized" | "reorged" | "unchanged";
219
+ chainBlockHeight: string | null;
220
+ settleTxHash: string | null;
221
+ reason?: string;
222
+ }
223
+ export interface SettleParams {
224
+ limit?: number;
225
+ }
226
+ export interface SettleResult {
227
+ scanned: number;
228
+ submitted: number;
229
+ confirmed: number;
230
+ skipped: number;
231
+ failed: number;
232
+ items: SettleItem[];
233
+ promoted: {
234
+ count: number;
235
+ items: SettlePromoteResult[];
236
+ };
237
+ reconciled: {
238
+ scanned: number;
239
+ finalized: number;
240
+ reorged: number;
241
+ unchanged: number;
242
+ items: SettleReconcileItem[];
243
+ };
244
+ paced?: {
245
+ iterations: number;
246
+ };
247
+ }
248
+ export interface EscrowBalanceEntry {
249
+ asset: string;
250
+ balance: string;
251
+ pendingAmount: string;
252
+ authorizedAmount: string;
253
+ availableAmount: string;
254
+ updatedAt: string | null;
255
+ }
256
+ export interface EscrowDepositSubmitted {
257
+ txHash: string;
258
+ submittedAt: string;
259
+ claimedAsset: string;
260
+ claimedAmount: string;
261
+ }
262
+ export interface EscrowDepositFinalized {
263
+ txHash: string;
264
+ finalizedAt: string | null;
265
+ blockNumber: string | null;
266
+ claimedAsset: string;
267
+ claimedAmount: string;
268
+ }
269
+ export interface EscrowDepositFailed {
270
+ txHash: string;
271
+ submittedAt: string;
272
+ claimedAsset: string;
273
+ claimedAmount: string;
274
+ lastError: string | null;
275
+ }
276
+ export interface EscrowBalance {
277
+ account: string;
278
+ balances: EscrowBalanceEntry[];
279
+ deposits: {
280
+ submitted: EscrowDepositSubmitted[];
281
+ finalized: EscrowDepositFinalized[];
282
+ failed: EscrowDepositFailed[];
283
+ };
284
+ }
285
+ export interface SubmitDepositParams {
286
+ txHash: string;
287
+ }
288
+ export interface DepositState {
289
+ txHash: string;
290
+ account: string;
291
+ status: string;
292
+ blockNumber: string | null;
293
+ submittedAt: string;
294
+ finalizedAt: string | null;
295
+ lastError: string | null;
296
+ }
107
297
  export interface GatewayClient {
108
298
  isRegisteredBuilder(address: string): Promise<boolean>;
109
299
  getBuilder(address: string): Promise<Builder | null>;
@@ -111,23 +301,28 @@ export interface GatewayClient {
111
301
  listGrantsByUser(userAddress: string): Promise<GrantListItem[]>;
112
302
  getSchemaForScope(scope: string): Promise<Schema | null>;
113
303
  getServer(address: string): Promise<ServerInfo | null>;
114
- getFile(fileId: string): Promise<FileRecord | null>;
115
- listFilesSince(owner: string, cursor: string | null): Promise<FileListResult>;
304
+ /**
305
+ * Fetch a single data point by its deterministic id (keccak256 of (owner, scope)).
306
+ * Returns null on 404. The gateway omits `status` from the response body — read it
307
+ * from the on-chain DataRegistryV2 contract when you need the canonical lifecycle state.
308
+ */
309
+ getDataPoint(dataPointId: string): Promise<DataPointRecord | null>;
310
+ /**
311
+ * Page through an owner's data points. Cursor is opaque; pass `null` for the first
312
+ * page and feed back `result.cursor` until it returns null.
313
+ */
314
+ listDataPointsByOwner(owner: string, cursor: string | null, options?: ListDataPointsOptions): Promise<DataPointListResult>;
116
315
  getSchema(schemaId: string): Promise<Schema | null>;
117
316
  registerServer(params: RegisterServerParams): Promise<RegisterServerResult>;
118
- registerFile(params: RegisterFileParams): Promise<{
119
- fileId?: string;
120
- }>;
317
+ registerBuilder(params: RegisterBuilderParams): Promise<RegisterBuilderResult>;
318
+ registerDataPoint(params: RegisterDataPointParams): Promise<RegisterDataPointResult>;
121
319
  createGrant(params: CreateGrantParams): Promise<{
122
320
  grantId?: string;
123
321
  }>;
124
322
  revokeGrant(params: RevokeGrantParams): Promise<void>;
125
- /**
126
- * Soft-deletes (de-registers) a file at the gateway. Resolves on 200 and on 409
127
- * (already deleted) — 409 is treated as idempotent success. Other non-2xx, including
128
- * 404 (file not registered), throw; the PS delete cascade decides whether a 404 is
129
- * benign (blob already gone) or a hard failure.
130
- */
131
- deleteFile(params: DeleteFileParams): Promise<void>;
323
+ getEscrowBalance(account: string): Promise<EscrowBalance>;
324
+ submitEscrowDeposit(params: SubmitDepositParams): Promise<DepositState>;
325
+ payForOperation(params: PayForOperationParams): Promise<PayForOperationResult>;
326
+ settle(params?: SettleParams): Promise<SettleResult>;
132
327
  }
133
328
  export declare function createGatewayClient(baseUrl: string): GatewayClient;
@@ -4,15 +4,6 @@ function createGatewayClient(baseUrl) {
4
4
  const envelope = await res.json();
5
5
  return envelope.data;
6
6
  }
7
- function normalizeFileRecord(record) {
8
- return {
9
- fileId: record.fileId ?? record.id ?? "",
10
- owner: record.owner ?? record.ownerAddress ?? "",
11
- url: record.url,
12
- schemaId: record.schemaId,
13
- createdAt: record.createdAt ?? record.addedAt ?? ""
14
- };
15
- }
16
7
  function getMutationId(body, key) {
17
8
  const value = body[key] ?? body["id"];
18
9
  return typeof value === "string" ? value : void 0;
@@ -62,27 +53,34 @@ function createGatewayClient(baseUrl) {
62
53
  }
63
54
  return unwrapEnvelope(res);
64
55
  },
65
- async getFile(fileId) {
66
- const res = await fetch(`${base}/v1/files/${fileId}`);
56
+ async getDataPoint(dataPointId) {
57
+ const res = await fetch(`${base}/v1/data/${dataPointId}`);
67
58
  if (res.status === 404) return null;
68
59
  if (!res.ok) {
69
60
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
70
61
  }
71
- return normalizeFileRecord(await unwrapEnvelope(res));
62
+ return unwrapEnvelope(res);
72
63
  },
73
- async listFilesSince(owner, cursor) {
64
+ async listDataPointsByOwner(owner, cursor, options) {
74
65
  const params = new URLSearchParams({ user: owner });
75
66
  if (cursor !== null) {
76
- params.set("since", cursor);
67
+ params.set("cursor", cursor);
68
+ }
69
+ if (options?.since) {
70
+ params.set("since", options.since);
77
71
  }
78
- const res = await fetch(`${base}/v1/files?${params.toString()}`);
72
+ if (options?.limit !== void 0) {
73
+ params.set("limit", String(options.limit));
74
+ }
75
+ const res = await fetch(`${base}/v1/data?${params.toString()}`);
79
76
  if (!res.ok) {
80
77
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
81
78
  }
82
- const data = await unwrapEnvelope(res);
79
+ const envelope = await res.json();
80
+ const nextCursor = envelope.pagination?.hasMore === false ? null : envelope.pagination?.nextCursor ?? null;
83
81
  return {
84
- files: data.files.map(normalizeFileRecord),
85
- cursor: data.cursor
82
+ dataPoints: envelope.data.dataPoints,
83
+ cursor: nextCursor
86
84
  };
87
85
  },
88
86
  async getSchema(schemaId) {
@@ -123,8 +121,8 @@ function createGatewayClient(baseUrl) {
123
121
  alreadyRegistered: false
124
122
  };
125
123
  },
126
- async registerFile(params) {
127
- const res = await fetch(`${base}/v1/files`, {
124
+ async registerBuilder(params) {
125
+ const res = await fetch(`${base}/v1/builders`, {
128
126
  method: "POST",
129
127
  headers: {
130
128
  "Content-Type": "application/json",
@@ -132,22 +130,57 @@ function createGatewayClient(baseUrl) {
132
130
  },
133
131
  body: JSON.stringify({
134
132
  ownerAddress: params.ownerAddress,
135
- url: params.url,
136
- schemaId: params.schemaId
133
+ granteeAddress: params.granteeAddress,
134
+ publicKey: params.publicKey,
135
+ appUrl: params.appUrl
137
136
  })
138
137
  });
139
138
  if (res.status === 409) {
140
139
  const body2 = await res.json().catch(() => ({}));
141
140
  return {
142
- fileId: getMutationId(body2, "fileId")
141
+ builderId: getMutationId(
142
+ body2,
143
+ "builderId"
144
+ ),
145
+ alreadyRegistered: true
143
146
  };
144
147
  }
145
148
  if (!res.ok) {
146
149
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
147
150
  }
148
- const body = await res.json();
151
+ const body = await res.json().catch(() => ({}));
152
+ return {
153
+ builderId: getMutationId(body, "builderId"),
154
+ alreadyRegistered: false
155
+ };
156
+ },
157
+ async registerDataPoint(params) {
158
+ const res = await fetch(`${base}/v1/data`, {
159
+ method: "POST",
160
+ headers: {
161
+ "Content-Type": "application/json",
162
+ Authorization: `Web3Signed ${params.signature}`
163
+ },
164
+ body: JSON.stringify({
165
+ ownerAddress: params.ownerAddress,
166
+ scope: params.scope,
167
+ dataHash: params.dataHash,
168
+ metadataHash: params.metadataHash,
169
+ expectedVersion: params.expectedVersion
170
+ })
171
+ });
172
+ if (!res.ok) {
173
+ const body2 = await res.json().catch(() => ({}));
174
+ const detail = body2.error ?? res.statusText;
175
+ throw new Error(`Gateway error: ${res.status} ${detail}`);
176
+ }
177
+ const body = await res.json().catch(() => ({}));
149
178
  return {
150
- fileId: getMutationId(body, "fileId")
179
+ dataPointId: getMutationId(
180
+ body,
181
+ "dataPointId"
182
+ ),
183
+ expectedVersion: body.expectedVersion
151
184
  };
152
185
  },
153
186
  async createGrant(params) {
@@ -160,8 +193,9 @@ function createGatewayClient(baseUrl) {
160
193
  body: JSON.stringify({
161
194
  grantorAddress: params.grantorAddress,
162
195
  granteeId: params.granteeId,
163
- grant: params.grant,
164
- fileIds: params.fileIds
196
+ scopes: params.scopes,
197
+ grantVersion: params.grantVersion,
198
+ expiresAt: params.expiresAt
165
199
  })
166
200
  });
167
201
  if (res.status === 409) {
@@ -186,7 +220,8 @@ function createGatewayClient(baseUrl) {
186
220
  Authorization: `Web3Signed ${params.signature}`
187
221
  },
188
222
  body: JSON.stringify({
189
- grantorAddress: params.grantorAddress
223
+ grantorAddress: params.grantorAddress,
224
+ grantVersion: params.grantVersion
190
225
  })
191
226
  });
192
227
  if (res.status === 409) return;
@@ -194,21 +229,62 @@ function createGatewayClient(baseUrl) {
194
229
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
195
230
  }
196
231
  },
197
- async deleteFile(params) {
198
- const res = await fetch(`${base}/v1/files/${params.fileId}`, {
199
- method: "DELETE",
232
+ async getEscrowBalance(account) {
233
+ const res = await fetch(`${base}/v1/escrow/balance?account=${account}`);
234
+ if (!res.ok) {
235
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
236
+ }
237
+ return await res.json();
238
+ },
239
+ async submitEscrowDeposit(params) {
240
+ const res = await fetch(`${base}/v1/escrow/deposit`, {
241
+ method: "POST",
242
+ headers: { "Content-Type": "application/json" },
243
+ body: JSON.stringify({ txHash: params.txHash })
244
+ });
245
+ if (res.status !== 200 && res.status !== 202) {
246
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
247
+ }
248
+ return await res.json();
249
+ },
250
+ async payForOperation(params) {
251
+ const body = {
252
+ payerAddress: params.payerAddress,
253
+ opType: params.opType,
254
+ opId: params.opId,
255
+ asset: params.asset,
256
+ amount: params.amount,
257
+ paymentNonce: params.paymentNonce
258
+ };
259
+ if (params.accessRecord) {
260
+ body["accessRecord"] = params.accessRecord;
261
+ }
262
+ const res = await fetch(`${base}/v1/escrow/pay`, {
263
+ method: "POST",
200
264
  headers: {
201
265
  "Content-Type": "application/json",
202
266
  Authorization: `Web3Signed ${params.signature}`
203
267
  },
204
- body: JSON.stringify({
205
- ownerAddress: params.ownerAddress
206
- })
268
+ body: JSON.stringify(body)
269
+ });
270
+ if (!res.ok) {
271
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
272
+ }
273
+ return await res.json();
274
+ },
275
+ async settle(params) {
276
+ const res = await fetch(`${base}/v1/settle`, {
277
+ method: "POST",
278
+ headers: { "Content-Type": "application/json" },
279
+ // The gateway accepts an empty body; only `limit` is recognised.
280
+ // Always send a JSON body so the gateway's req.body shape parse
281
+ // doesn't have to deal with an undefined.
282
+ body: JSON.stringify(params ?? {})
207
283
  });
208
- if (res.status === 409) return;
209
284
  if (!res.ok) {
210
285
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
211
286
  }
287
+ return await res.json();
212
288
  }
213
289
  };
214
290
  }