@opendatalabs/vana-sdk 3.0.1 → 3.2.0-canary.88d802d

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 (110) hide show
  1. package/README.md +2 -1
  2. package/dist/__tests__/interop-personal-server.test.d.ts +1 -0
  3. package/dist/account/personal-server-lite-owner-binding.cjs +81 -0
  4. package/dist/account/personal-server-lite-owner-binding.cjs.map +1 -0
  5. package/dist/account/personal-server-lite-owner-binding.d.ts +30 -0
  6. package/dist/account/personal-server-lite-owner-binding.js +59 -0
  7. package/dist/account/personal-server-lite-owner-binding.js.map +1 -0
  8. package/dist/account/personal-server-lite-owner-binding.test.d.ts +1 -0
  9. package/dist/account/personal-server-registration.cjs +263 -0
  10. package/dist/account/personal-server-registration.cjs.map +1 -0
  11. package/dist/account/personal-server-registration.d.ts +66 -0
  12. package/dist/account/personal-server-registration.js +240 -0
  13. package/dist/account/personal-server-registration.js.map +1 -0
  14. package/dist/account/personal-server-registration.test.d.ts +1 -0
  15. package/dist/auth/errors.js +1 -1
  16. package/dist/auth/oauth-client.cjs +250 -0
  17. package/dist/auth/oauth-client.cjs.map +1 -0
  18. package/dist/auth/oauth-client.d.ts +90 -0
  19. package/dist/auth/oauth-client.js +228 -0
  20. package/dist/auth/oauth-client.js.map +1 -0
  21. package/dist/auth/oauth-client.test.d.ts +1 -0
  22. package/dist/auth/web3-signed-builder.js +1 -1
  23. package/dist/auth/web3-signed.js +3 -3
  24. package/dist/browser.js +1 -1
  25. package/dist/chains/definitions.js +1 -1
  26. package/dist/chains/index.js +1 -1
  27. package/dist/chains.browser.js +1 -1
  28. package/dist/chains.js +1 -1
  29. package/dist/chains.node.js +1 -1
  30. package/dist/contracts/contractController.js +4 -4
  31. package/dist/core/client.js +1 -1
  32. package/dist/crypto/ecies/base.js +3 -3
  33. package/dist/crypto/ecies/browser.js +1 -1
  34. package/dist/crypto/ecies/index.js +1 -1
  35. package/dist/crypto/ecies/interface.js +1 -1
  36. package/dist/crypto/ecies/node.js +1 -1
  37. package/dist/crypto/services/WalletKeyEncryptionService.js +1 -1
  38. package/dist/generated/abi/index.js +26 -26
  39. package/dist/index.browser.d.ts +9 -3
  40. package/dist/index.browser.js +930 -73
  41. package/dist/index.browser.js.map +4 -4
  42. package/dist/index.node.cjs +958 -74
  43. package/dist/index.node.cjs.map +4 -4
  44. package/dist/index.node.d.ts +9 -3
  45. package/dist/index.node.js +930 -73
  46. package/dist/index.node.js.map +4 -4
  47. package/dist/node.js +1 -1
  48. package/dist/platform/browser-only.js +1 -1
  49. package/dist/platform/browser-safe.js +1 -1
  50. package/dist/platform/browser.js +6 -6
  51. package/dist/platform/index.js +4 -4
  52. package/dist/platform/node.js +8 -8
  53. package/dist/platform/utils.js +2 -2
  54. package/dist/platform.browser.js +3 -3
  55. package/dist/platform.js +4 -4
  56. package/dist/platform.node.js +4 -4
  57. package/dist/protocol/eip712.cjs +58 -3
  58. package/dist/protocol/eip712.cjs.map +1 -1
  59. package/dist/protocol/eip712.d.ts +98 -7
  60. package/dist/protocol/eip712.js +52 -3
  61. package/dist/protocol/eip712.js.map +1 -1
  62. package/dist/protocol/escrow-deposit.cjs +89 -0
  63. package/dist/protocol/escrow-deposit.cjs.map +1 -0
  64. package/dist/protocol/escrow-deposit.d.ts +47 -0
  65. package/dist/protocol/escrow-deposit.js +60 -0
  66. package/dist/protocol/escrow-deposit.js.map +1 -0
  67. package/dist/protocol/escrow-deposit.test.d.ts +1 -0
  68. package/dist/protocol/escrow-flow.test.d.ts +21 -0
  69. package/dist/protocol/gateway.cjs +124 -3
  70. package/dist/protocol/gateway.cjs.map +1 -1
  71. package/dist/protocol/gateway.d.ts +196 -16
  72. package/dist/protocol/gateway.js +124 -3
  73. package/dist/protocol/gateway.js.map +1 -1
  74. package/dist/protocol/grants.cjs +24 -64
  75. package/dist/protocol/grants.cjs.map +1 -1
  76. package/dist/protocol/grants.d.ts +6 -13
  77. package/dist/protocol/grants.js +25 -64
  78. package/dist/protocol/grants.js.map +1 -1
  79. package/dist/protocol/personal-server-lite-owner-binding.cjs +93 -0
  80. package/dist/protocol/personal-server-lite-owner-binding.cjs.map +1 -0
  81. package/dist/protocol/personal-server-lite-owner-binding.d.ts +44 -0
  82. package/dist/protocol/personal-server-lite-owner-binding.js +65 -0
  83. package/dist/protocol/personal-server-lite-owner-binding.js.map +1 -0
  84. package/dist/protocol/personal-server-lite-owner-binding.test.d.ts +1 -0
  85. package/dist/protocol/personal-server-registration.cjs +122 -0
  86. package/dist/protocol/personal-server-registration.cjs.map +1 -0
  87. package/dist/protocol/personal-server-registration.d.ts +62 -0
  88. package/dist/protocol/personal-server-registration.js +97 -0
  89. package/dist/protocol/personal-server-registration.js.map +1 -0
  90. package/dist/protocol/personal-server-registration.test.d.ts +1 -0
  91. package/dist/storage/default.js +1 -1
  92. package/dist/storage/index.cjs.map +1 -1
  93. package/dist/storage/index.d.ts +1 -1
  94. package/dist/storage/index.js +10 -10
  95. package/dist/storage/index.js.map +1 -1
  96. package/dist/storage/manager.js +1 -1
  97. package/dist/storage/providers/callback-storage.js +1 -1
  98. package/dist/storage/providers/dropbox.js +1 -1
  99. package/dist/storage/providers/google-drive.js +1 -1
  100. package/dist/storage/providers/ipfs.js +2 -2
  101. package/dist/storage/providers/pinata.js +1 -1
  102. package/dist/storage/providers/r2.js +1 -1
  103. package/dist/storage/providers/vana-storage.cjs +1 -1
  104. package/dist/storage/providers/vana-storage.cjs.map +1 -1
  105. package/dist/storage/providers/vana-storage.d.ts +2 -2
  106. package/dist/storage/providers/vana-storage.js +3 -3
  107. package/dist/storage/providers/vana-storage.js.map +1 -1
  108. package/dist/types/index.js +2 -2
  109. package/dist/types.js +1 -1
  110. package/package.json +7 -3
@@ -36,28 +36,35 @@ export interface ServerInfo {
36
36
  serverUrl: string;
37
37
  addedAt: string;
38
38
  }
39
- export interface GatewayGrantResponse {
40
- id: string;
41
- grantorAddress: string;
42
- granteeId: string;
43
- grant: string;
44
- fileIds: string[];
45
- status: "pending" | "confirmed";
46
- addedAt: string;
47
- revokedAt: string | null;
48
- revocationSignature: string | null;
39
+ export interface GatewayGrantFee {
40
+ asset: string;
41
+ registrationFee: string;
42
+ dataAccessFee: string;
43
+ totalDue: string;
49
44
  }
50
- export interface GrantListItem {
45
+ export type GatewayGrantStatus = "pending" | "submitting" | "confirmed" | "finalized" | "reorged";
46
+ export interface GatewayGrantResponse {
51
47
  id: string;
52
48
  grantorAddress: string;
53
49
  granteeId: string;
54
- grant: string;
55
- fileIds: string[];
56
- status: "pending" | "confirmed";
50
+ scopes: string[];
51
+ status: GatewayGrantStatus;
57
52
  addedAt: string;
53
+ expiresAt: string | null;
54
+ expired: boolean;
58
55
  revokedAt: string | null;
59
56
  revocationSignature: string | null;
57
+ paymentStatus: "pending" | "paid";
58
+ paidAt: string | null;
59
+ paidBy: string | null;
60
+ grantVersion: string;
61
+ settleTxHash: string | null;
62
+ settleSubmittedAt: string | null;
63
+ revocationTxHash: string | null;
64
+ revocationSubmittedAt: string | null;
65
+ fee: GatewayGrantFee;
60
66
  }
67
+ export type GrantListItem = GatewayGrantResponse;
61
68
  export interface FileRecord {
62
69
  fileId: string;
63
70
  owner: string;
@@ -78,13 +85,15 @@ export interface RegisterFileParams {
78
85
  export interface CreateGrantParams {
79
86
  grantorAddress: string;
80
87
  granteeId: string;
81
- grant: string;
82
- fileIds: string[];
88
+ scopes: string[];
89
+ grantVersion: string;
90
+ expiresAt: string;
83
91
  signature: string;
84
92
  }
85
93
  export interface RevokeGrantParams {
86
94
  grantId: string;
87
95
  grantorAddress: string;
96
+ grantVersion: string;
88
97
  signature: string;
89
98
  }
90
99
  export interface RegisterServerParams {
@@ -98,6 +107,171 @@ export interface RegisterServerResult {
98
107
  serverId?: string;
99
108
  alreadyRegistered: boolean;
100
109
  }
110
+ export interface RegisterBuilderParams {
111
+ ownerAddress: string;
112
+ granteeAddress: string;
113
+ publicKey: string;
114
+ appUrl: string;
115
+ signature: string;
116
+ }
117
+ export interface RegisterBuilderResult {
118
+ builderId?: string;
119
+ alreadyRegistered: boolean;
120
+ }
121
+ export interface RegisterDataPointParams {
122
+ ownerAddress: string;
123
+ scope: string;
124
+ dataHash: string;
125
+ metadataHash: string;
126
+ expectedVersion: string;
127
+ signature: string;
128
+ }
129
+ export interface RegisterDataPointResult {
130
+ dataPointId?: string;
131
+ expectedVersion?: string;
132
+ }
133
+ export interface AccessRecord {
134
+ dataPointId: string;
135
+ version: string;
136
+ accessor: string;
137
+ recordId: string;
138
+ signature: string;
139
+ }
140
+ export interface PayForOperationParams {
141
+ payerAddress: string;
142
+ opType: string;
143
+ opId: string;
144
+ asset: string;
145
+ amount: string;
146
+ paymentNonce: string;
147
+ signature: string;
148
+ accessRecord?: AccessRecord;
149
+ }
150
+ export interface PayForOperationResult {
151
+ opType: string;
152
+ opId: string;
153
+ payerAddress: string;
154
+ asset: string;
155
+ amount: string;
156
+ breakdown: {
157
+ registrationFee: string;
158
+ dataAccessFee: string;
159
+ registrationPaid: boolean;
160
+ };
161
+ paymentNonce: string;
162
+ paidAt: string;
163
+ }
164
+ export type SettleOpType = "grant" | "server" | "data" | "access";
165
+ export type SettleItem = {
166
+ opType: SettleOpType;
167
+ opId: string;
168
+ status: "submitting" | "confirmed";
169
+ settleTxHash: string | null;
170
+ settleSubmittedAt: string | null;
171
+ chainBlockHeight: string | null;
172
+ revocationTxHash: string | null;
173
+ revocationSubmittedAt: string | null;
174
+ placeholder: boolean;
175
+ } | {
176
+ opType: SettleOpType;
177
+ opId: string;
178
+ status: "skipped";
179
+ reason: string;
180
+ } | {
181
+ opType: SettleOpType;
182
+ opId: string;
183
+ status: "failed";
184
+ error: string;
185
+ };
186
+ export interface SettlePromoteResult {
187
+ opType: SettleOpType;
188
+ opId: string;
189
+ status: "confirmed" | "failed" | "pending" | "skipped";
190
+ txHash: string;
191
+ chainBlockHeight: string | null;
192
+ reason?: string;
193
+ }
194
+ export interface SettleReconcileItem {
195
+ opId: string;
196
+ status: "finalized" | "reorged" | "unchanged";
197
+ chainBlockHeight: string | null;
198
+ settleTxHash: string | null;
199
+ reason?: string;
200
+ }
201
+ export interface SettleParams {
202
+ limit?: number;
203
+ }
204
+ export interface SettleResult {
205
+ scanned: number;
206
+ submitted: number;
207
+ confirmed: number;
208
+ skipped: number;
209
+ failed: number;
210
+ items: SettleItem[];
211
+ promoted: {
212
+ count: number;
213
+ items: SettlePromoteResult[];
214
+ };
215
+ reconciled: {
216
+ scanned: number;
217
+ finalized: number;
218
+ reorged: number;
219
+ unchanged: number;
220
+ items: SettleReconcileItem[];
221
+ };
222
+ paced?: {
223
+ iterations: number;
224
+ };
225
+ }
226
+ export interface EscrowBalanceEntry {
227
+ asset: string;
228
+ balance: string;
229
+ pendingAmount: string;
230
+ authorizedAmount: string;
231
+ availableAmount: string;
232
+ updatedAt: string | null;
233
+ }
234
+ export interface EscrowDepositSubmitted {
235
+ txHash: string;
236
+ submittedAt: string;
237
+ claimedAsset: string;
238
+ claimedAmount: string;
239
+ }
240
+ export interface EscrowDepositFinalized {
241
+ txHash: string;
242
+ finalizedAt: string | null;
243
+ blockNumber: string | null;
244
+ claimedAsset: string;
245
+ claimedAmount: string;
246
+ }
247
+ export interface EscrowDepositFailed {
248
+ txHash: string;
249
+ submittedAt: string;
250
+ claimedAsset: string;
251
+ claimedAmount: string;
252
+ lastError: string | null;
253
+ }
254
+ export interface EscrowBalance {
255
+ account: string;
256
+ balances: EscrowBalanceEntry[];
257
+ deposits: {
258
+ submitted: EscrowDepositSubmitted[];
259
+ finalized: EscrowDepositFinalized[];
260
+ failed: EscrowDepositFailed[];
261
+ };
262
+ }
263
+ export interface SubmitDepositParams {
264
+ txHash: string;
265
+ }
266
+ export interface DepositState {
267
+ txHash: string;
268
+ account: string;
269
+ status: string;
270
+ blockNumber: string | null;
271
+ submittedAt: string;
272
+ finalizedAt: string | null;
273
+ lastError: string | null;
274
+ }
101
275
  export interface GatewayClient {
102
276
  isRegisteredBuilder(address: string): Promise<boolean>;
103
277
  getBuilder(address: string): Promise<Builder | null>;
@@ -109,6 +283,8 @@ export interface GatewayClient {
109
283
  listFilesSince(owner: string, cursor: string | null): Promise<FileListResult>;
110
284
  getSchema(schemaId: string): Promise<Schema | null>;
111
285
  registerServer(params: RegisterServerParams): Promise<RegisterServerResult>;
286
+ registerBuilder(params: RegisterBuilderParams): Promise<RegisterBuilderResult>;
287
+ registerDataPoint(params: RegisterDataPointParams): Promise<RegisterDataPointResult>;
112
288
  registerFile(params: RegisterFileParams): Promise<{
113
289
  fileId?: string;
114
290
  }>;
@@ -116,5 +292,9 @@ export interface GatewayClient {
116
292
  grantId?: string;
117
293
  }>;
118
294
  revokeGrant(params: RevokeGrantParams): Promise<void>;
295
+ getEscrowBalance(account: string): Promise<EscrowBalance>;
296
+ submitEscrowDeposit(params: SubmitDepositParams): Promise<DepositState>;
297
+ payForOperation(params: PayForOperationParams): Promise<PayForOperationResult>;
298
+ settle(params?: SettleParams): Promise<SettleResult>;
119
299
  }
120
300
  export declare function createGatewayClient(baseUrl: string): GatewayClient;
@@ -123,6 +123,68 @@ function createGatewayClient(baseUrl) {
123
123
  alreadyRegistered: false
124
124
  };
125
125
  },
126
+ async registerBuilder(params) {
127
+ const res = await fetch(`${base}/v1/builders`, {
128
+ method: "POST",
129
+ headers: {
130
+ "Content-Type": "application/json",
131
+ Authorization: `Web3Signed ${params.signature}`
132
+ },
133
+ body: JSON.stringify({
134
+ ownerAddress: params.ownerAddress,
135
+ granteeAddress: params.granteeAddress,
136
+ publicKey: params.publicKey,
137
+ appUrl: params.appUrl
138
+ })
139
+ });
140
+ if (res.status === 409) {
141
+ const body2 = await res.json().catch(() => ({}));
142
+ return {
143
+ builderId: getMutationId(
144
+ body2,
145
+ "builderId"
146
+ ),
147
+ alreadyRegistered: true
148
+ };
149
+ }
150
+ if (!res.ok) {
151
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
152
+ }
153
+ const body = await res.json().catch(() => ({}));
154
+ return {
155
+ builderId: getMutationId(body, "builderId"),
156
+ alreadyRegistered: false
157
+ };
158
+ },
159
+ async registerDataPoint(params) {
160
+ const res = await fetch(`${base}/v1/data`, {
161
+ method: "POST",
162
+ headers: {
163
+ "Content-Type": "application/json",
164
+ Authorization: `Web3Signed ${params.signature}`
165
+ },
166
+ body: JSON.stringify({
167
+ ownerAddress: params.ownerAddress,
168
+ scope: params.scope,
169
+ dataHash: params.dataHash,
170
+ metadataHash: params.metadataHash,
171
+ expectedVersion: params.expectedVersion
172
+ })
173
+ });
174
+ if (!res.ok) {
175
+ const body2 = await res.json().catch(() => ({}));
176
+ const detail = body2.error ?? res.statusText;
177
+ throw new Error(`Gateway error: ${res.status} ${detail}`);
178
+ }
179
+ const body = await res.json().catch(() => ({}));
180
+ return {
181
+ dataPointId: getMutationId(
182
+ body,
183
+ "dataPointId"
184
+ ),
185
+ expectedVersion: body.expectedVersion
186
+ };
187
+ },
126
188
  async registerFile(params) {
127
189
  const res = await fetch(`${base}/v1/files`, {
128
190
  method: "POST",
@@ -160,8 +222,9 @@ function createGatewayClient(baseUrl) {
160
222
  body: JSON.stringify({
161
223
  grantorAddress: params.grantorAddress,
162
224
  granteeId: params.granteeId,
163
- grant: params.grant,
164
- fileIds: params.fileIds
225
+ scopes: params.scopes,
226
+ grantVersion: params.grantVersion,
227
+ expiresAt: params.expiresAt
165
228
  })
166
229
  });
167
230
  if (res.status === 409) {
@@ -186,13 +249,71 @@ function createGatewayClient(baseUrl) {
186
249
  Authorization: `Web3Signed ${params.signature}`
187
250
  },
188
251
  body: JSON.stringify({
189
- grantorAddress: params.grantorAddress
252
+ grantorAddress: params.grantorAddress,
253
+ grantVersion: params.grantVersion
190
254
  })
191
255
  });
192
256
  if (res.status === 409) return;
193
257
  if (!res.ok) {
194
258
  throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
195
259
  }
260
+ },
261
+ async getEscrowBalance(account) {
262
+ const res = await fetch(`${base}/v1/escrow/balance?account=${account}`);
263
+ if (!res.ok) {
264
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
265
+ }
266
+ return await res.json();
267
+ },
268
+ async submitEscrowDeposit(params) {
269
+ const res = await fetch(`${base}/v1/escrow/deposit`, {
270
+ method: "POST",
271
+ headers: { "Content-Type": "application/json" },
272
+ body: JSON.stringify({ txHash: params.txHash })
273
+ });
274
+ if (res.status !== 200 && res.status !== 202) {
275
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
276
+ }
277
+ return await res.json();
278
+ },
279
+ async payForOperation(params) {
280
+ const body = {
281
+ payerAddress: params.payerAddress,
282
+ opType: params.opType,
283
+ opId: params.opId,
284
+ asset: params.asset,
285
+ amount: params.amount,
286
+ paymentNonce: params.paymentNonce
287
+ };
288
+ if (params.accessRecord) {
289
+ body["accessRecord"] = params.accessRecord;
290
+ }
291
+ const res = await fetch(`${base}/v1/escrow/pay`, {
292
+ method: "POST",
293
+ headers: {
294
+ "Content-Type": "application/json",
295
+ Authorization: `Web3Signed ${params.signature}`
296
+ },
297
+ body: JSON.stringify(body)
298
+ });
299
+ if (!res.ok) {
300
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
301
+ }
302
+ return await res.json();
303
+ },
304
+ async settle(params) {
305
+ const res = await fetch(`${base}/v1/settle`, {
306
+ method: "POST",
307
+ headers: { "Content-Type": "application/json" },
308
+ // The gateway accepts an empty body; only `limit` is recognised.
309
+ // Always send a JSON body so the gateway's req.body shape parse
310
+ // doesn't have to deal with an undefined.
311
+ body: JSON.stringify(params ?? {})
312
+ });
313
+ if (!res.ok) {
314
+ throw new Error(`Gateway error: ${res.status} ${res.statusText}`);
315
+ }
316
+ return await res.json();
196
317
  }
197
318
  };
198
319
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/protocol/gateway.ts"],"sourcesContent":["export interface GatewayEnvelope<T> {\n data: T;\n proof: GatewayProof;\n}\n\nexport interface GatewayProof {\n signature: string;\n timestamp: string;\n gatewayAddress: string;\n requestHash: string;\n responseHash: string;\n userSignature: string;\n status: string;\n chainBlockHeight: number;\n}\n\nexport interface Builder {\n id: string;\n ownerAddress: string;\n granteeAddress: string;\n publicKey: string;\n appUrl: string;\n addedAt: string;\n}\n\nexport interface Schema {\n id: string;\n ownerAddress: string;\n name: string;\n definitionUrl: string;\n scope: string;\n addedAt: string;\n}\n\nexport interface ServerInfo {\n id: string;\n ownerAddress: string;\n serverAddress: string;\n publicKey: string;\n serverUrl: string;\n addedAt: string;\n}\n\nexport interface GatewayGrantResponse {\n id: string;\n grantorAddress: string;\n granteeId: string;\n grant: string;\n fileIds: string[];\n status: \"pending\" | \"confirmed\";\n addedAt: string;\n revokedAt: string | null;\n revocationSignature: string | null;\n}\n\nexport interface GrantListItem {\n id: string;\n grantorAddress: string;\n granteeId: string;\n grant: string;\n fileIds: string[];\n status: \"pending\" | \"confirmed\";\n addedAt: string;\n revokedAt: string | null;\n revocationSignature: string | null;\n}\n\nexport interface FileRecord {\n fileId: string;\n owner: string;\n url: string;\n schemaId: string;\n createdAt: string;\n}\n\nexport interface FileListResult {\n files: FileRecord[];\n cursor: string | null;\n}\n\ninterface GatewayFileRecord {\n id?: string;\n fileId?: string;\n ownerAddress?: string;\n owner?: string;\n url: string;\n schemaId: string;\n addedAt?: string;\n createdAt?: string;\n}\n\nexport interface RegisterFileParams {\n ownerAddress: string;\n url: string;\n schemaId: string;\n signature: string;\n}\n\nexport interface CreateGrantParams {\n grantorAddress: string;\n granteeId: string;\n grant: string;\n fileIds: string[];\n signature: string;\n}\n\nexport interface RevokeGrantParams {\n grantId: string;\n grantorAddress: string;\n signature: string;\n}\n\nexport interface RegisterServerParams {\n ownerAddress: string;\n serverAddress: string;\n publicKey: string;\n serverUrl: string;\n signature: string;\n}\n\nexport interface RegisterServerResult {\n serverId?: string;\n alreadyRegistered: boolean;\n}\n\nexport interface GatewayClient {\n isRegisteredBuilder(address: string): Promise<boolean>;\n getBuilder(address: string): Promise<Builder | null>;\n getGrant(grantId: string): Promise<GatewayGrantResponse | null>;\n listGrantsByUser(userAddress: string): Promise<GrantListItem[]>;\n getSchemaForScope(scope: string): Promise<Schema | null>;\n getServer(address: string): Promise<ServerInfo | null>;\n getFile(fileId: string): Promise<FileRecord | null>;\n listFilesSince(owner: string, cursor: string | null): Promise<FileListResult>;\n getSchema(schemaId: string): Promise<Schema | null>;\n registerServer(params: RegisterServerParams): Promise<RegisterServerResult>;\n registerFile(params: RegisterFileParams): Promise<{ fileId?: string }>;\n createGrant(params: CreateGrantParams): Promise<{ grantId?: string }>;\n revokeGrant(params: RevokeGrantParams): Promise<void>;\n}\n\nexport function createGatewayClient(baseUrl: string): GatewayClient {\n const base = baseUrl.replace(/\\/+$/, \"\");\n\n async function unwrapEnvelope<T>(res: Response): Promise<T> {\n const envelope = (await res.json()) as GatewayEnvelope<T>;\n return envelope.data;\n }\n\n function normalizeFileRecord(record: GatewayFileRecord): FileRecord {\n return {\n fileId: record.fileId ?? record.id ?? \"\",\n owner: record.owner ?? record.ownerAddress ?? \"\",\n url: record.url,\n schemaId: record.schemaId,\n createdAt: record.createdAt ?? record.addedAt ?? \"\",\n };\n }\n\n function getMutationId(\n body: Record<string, unknown>,\n key: string,\n ): string | undefined {\n const value = body[key] ?? body[\"id\"];\n return typeof value === \"string\" ? value : undefined;\n }\n\n return {\n async isRegisteredBuilder(address: string): Promise<boolean> {\n const builder = await this.getBuilder(address);\n return builder !== null;\n },\n\n async getBuilder(address: string): Promise<Builder | null> {\n const res = await fetch(`${base}/v1/builders/${address}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<Builder>(res);\n },\n\n async getGrant(grantId: string): Promise<GatewayGrantResponse | null> {\n const res = await fetch(`${base}/v1/grants/${grantId}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<GatewayGrantResponse>(res);\n },\n\n async listGrantsByUser(userAddress: string): Promise<GrantListItem[]> {\n const res = await fetch(`${base}/v1/grants?user=${userAddress}`);\n if (res.status === 404) return [];\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<GrantListItem[]>(res);\n },\n\n async getSchemaForScope(scope: string): Promise<Schema | null> {\n const res = await fetch(`${base}/v1/schemas?scope=${scope}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<Schema>(res);\n },\n\n async getServer(address: string): Promise<ServerInfo | null> {\n const res = await fetch(`${base}/v1/servers/${address}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<ServerInfo>(res);\n },\n\n async getFile(fileId: string): Promise<FileRecord | null> {\n const res = await fetch(`${base}/v1/files/${fileId}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return normalizeFileRecord(await unwrapEnvelope<GatewayFileRecord>(res));\n },\n\n async listFilesSince(\n owner: string,\n cursor: string | null,\n ): Promise<FileListResult> {\n const params = new URLSearchParams({ user: owner });\n if (cursor !== null) {\n params.set(\"since\", cursor);\n }\n const res = await fetch(`${base}/v1/files?${params.toString()}`);\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const data = await unwrapEnvelope<{\n files: GatewayFileRecord[];\n cursor: string | null;\n }>(res);\n return {\n files: data.files.map(normalizeFileRecord),\n cursor: data.cursor,\n };\n },\n\n async getSchema(schemaId: string): Promise<Schema | null> {\n const res = await fetch(`${base}/v1/schemas/${schemaId}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<Schema>(res);\n },\n\n async registerServer(\n params: RegisterServerParams,\n ): Promise<RegisterServerResult> {\n const res = await fetch(`${base}/v1/servers`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n ownerAddress: params.ownerAddress,\n serverAddress: params.serverAddress,\n publicKey: params.publicKey,\n serverUrl: params.serverUrl,\n }),\n });\n if (res.status === 409) {\n const body = await res.json().catch(() => ({}));\n return {\n serverId: getMutationId(body as Record<string, unknown>, \"serverId\"),\n alreadyRegistered: true,\n };\n }\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const body = await res.json().catch(() => ({}));\n return {\n serverId: getMutationId(body as Record<string, unknown>, \"serverId\"),\n alreadyRegistered: false,\n };\n },\n\n async registerFile(\n params: RegisterFileParams,\n ): Promise<{ fileId?: string }> {\n const res = await fetch(`${base}/v1/files`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n ownerAddress: params.ownerAddress,\n url: params.url,\n schemaId: params.schemaId,\n }),\n });\n if (res.status === 409) {\n const body = await res.json().catch(() => ({}));\n return {\n fileId: getMutationId(body as Record<string, unknown>, \"fileId\"),\n };\n }\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const body = await res.json();\n return {\n fileId: getMutationId(body as Record<string, unknown>, \"fileId\"),\n };\n },\n\n async createGrant(\n params: CreateGrantParams,\n ): Promise<{ grantId?: string }> {\n const res = await fetch(`${base}/v1/grants`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n grantorAddress: params.grantorAddress,\n granteeId: params.granteeId,\n grant: params.grant,\n fileIds: params.fileIds,\n }),\n });\n if (res.status === 409) {\n const body = await res.json().catch(() => ({}));\n return {\n grantId: getMutationId(body as Record<string, unknown>, \"grantId\"),\n };\n }\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const body = await res.json();\n return {\n grantId: getMutationId(body as Record<string, unknown>, \"grantId\"),\n };\n },\n\n async revokeGrant(params: RevokeGrantParams): Promise<void> {\n const res = await fetch(`${base}/v1/grants/${params.grantId}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n grantorAddress: params.grantorAddress,\n }),\n });\n if (res.status === 409) return;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n },\n };\n}\n"],"mappings":"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","names":["body"]}
1
+ {"version":3,"sources":["../../src/protocol/gateway.ts"],"sourcesContent":["export interface GatewayEnvelope<T> {\n data: T;\n proof: GatewayProof;\n}\n\nexport interface GatewayProof {\n signature: string;\n timestamp: string;\n gatewayAddress: string;\n requestHash: string;\n responseHash: string;\n userSignature: string;\n status: string;\n chainBlockHeight: number;\n}\n\nexport interface Builder {\n id: string;\n ownerAddress: string;\n granteeAddress: string;\n publicKey: string;\n appUrl: string;\n addedAt: string;\n}\n\nexport interface Schema {\n id: string;\n ownerAddress: string;\n name: string;\n definitionUrl: string;\n scope: string;\n addedAt: string;\n}\n\nexport interface ServerInfo {\n id: string;\n ownerAddress: string;\n serverAddress: string;\n publicKey: string;\n serverUrl: string;\n addedAt: string;\n}\n\n// Fee annotation surfaced on every GET grant response. Amounts are decimal\n// uint256 strings to match `/v1/escrow/pay`'s wire format. totalDue is a\n// snapshot — the gateway re-resolves fees at pay time, so clients shouldn't\n// cache this across requests.\nexport interface GatewayGrantFee {\n asset: string;\n registrationFee: string;\n dataAccessFee: string;\n totalDue: string;\n}\n\n// Lifecycle of a grant's on-chain settlement, tracked separately from the\n// fee-payment lifecycle (paymentStatus). Driven by POST /v1/settle:\n// pending — nothing on-chain yet\n// submitting — settle tx broadcast but receipt not yet observed\n// confirmed — settle tx mined successfully\n// finalized — finalized tip past the settle block, reorg-safe\n// reorged — finalized observation reverted; back to 'pending' on next settle\nexport type GatewayGrantStatus =\n | \"pending\"\n | \"submitting\"\n | \"confirmed\"\n | \"finalized\"\n | \"reorged\";\n\nexport interface GatewayGrantResponse {\n id: string;\n grantorAddress: string;\n granteeId: string;\n scopes: string[];\n status: GatewayGrantStatus;\n addedAt: string;\n // Grantor-signed deadline. null = perpetual grant (signed value was 0).\n expiresAt: string | null;\n // Derived at read time from expiresAt vs the gateway's clock — a snapshot,\n // not a cached truth. Re-check against expiresAt locally if you care.\n expired: boolean;\n revokedAt: string | null;\n revocationSignature: string | null;\n // 'pending' until the grant registration fee is settled via /v1/escrow/pay.\n paymentStatus: \"pending\" | \"paid\";\n paidAt: string | null;\n paidBy: string | null;\n // Decimal-string uint256 monotonic nonce; advances on every state change.\n grantVersion: string;\n // Settle metadata — populated as the grant progresses through the chain\n // lifecycle. Null while `status === 'pending'`.\n settleTxHash: string | null;\n settleSubmittedAt: string | null;\n // Revocation metadata — populated independently when the grantor signs\n // and the gateway pushes a deregister tx.\n revocationTxHash: string | null;\n revocationSubmittedAt: string | null;\n fee: GatewayGrantFee;\n}\n\nexport type GrantListItem = GatewayGrantResponse;\n\nexport interface FileRecord {\n fileId: string;\n owner: string;\n url: string;\n schemaId: string;\n createdAt: string;\n}\n\nexport interface FileListResult {\n files: FileRecord[];\n cursor: string | null;\n}\n\ninterface GatewayFileRecord {\n id?: string;\n fileId?: string;\n ownerAddress?: string;\n owner?: string;\n url: string;\n schemaId: string;\n addedAt?: string;\n createdAt?: string;\n}\n\nexport interface RegisterFileParams {\n ownerAddress: string;\n url: string;\n schemaId: string;\n signature: string;\n}\n\n// grantVersion and expiresAt are decimal-string uint256s — same wire format\n// the gateway expects. The caller is responsible for converting their bigint\n// to a decimal string and for signing GRANT_REGISTRATION_TYPES with matching\n// bigint values.\nexport interface CreateGrantParams {\n grantorAddress: string;\n granteeId: string;\n scopes: string[];\n grantVersion: string;\n expiresAt: string;\n signature: string;\n}\n\nexport interface RevokeGrantParams {\n grantId: string;\n grantorAddress: string;\n grantVersion: string;\n signature: string;\n}\n\nexport interface RegisterServerParams {\n ownerAddress: string;\n serverAddress: string;\n publicKey: string;\n serverUrl: string;\n signature: string;\n}\n\nexport interface RegisterServerResult {\n serverId?: string;\n alreadyRegistered: boolean;\n}\n\nexport interface RegisterBuilderParams {\n ownerAddress: string;\n // Wallet the builder authenticates to the Personal Server with. The\n // builderId is deterministically derived from (owner, grantee, publicKey,\n // appUrl) so this triple pins the on-chain identity.\n granteeAddress: string;\n publicKey: string;\n appUrl: string;\n signature: string;\n}\n\nexport interface RegisterBuilderResult {\n builderId?: string;\n alreadyRegistered: boolean;\n}\n\n// AddData on DataRegistryV2. dataHash + metadataHash are bytes32 commitments\n// to the off-chain payload + its metadata. expectedVersion is a CAS knob —\n// the gateway/contract rejects on 409 if a higher version is already stored,\n// and the error body surfaces `currentExpectedVersion` so callers can re-sign.\nexport interface RegisterDataPointParams {\n ownerAddress: string;\n scope: string;\n dataHash: string;\n metadataHash: string;\n expectedVersion: string;\n signature: string;\n}\n\nexport interface RegisterDataPointResult {\n dataPointId?: string;\n expectedVersion?: string;\n}\n\n// ── Escrow / data-access payment path ───────────────────────────────────────\n// /v1/escrow/pay debits the payer's escrow balance for a payable op. For a\n// grant: opType = 'grant', opId = the bytes32 grantId. amount, paymentNonce,\n// and asset are decimal-uint256 strings on the wire. The signature is the\n// raw EIP-712 hex of GENERIC_PAYMENT_TYPES against escrowPaymentDomain.\n\n// A server-signed delivery receipt attached to a data-access payment. The\n// signature is over RECORD_DATA_ACCESS_TYPES against dataRegistryDomain; the\n// signer must be a personal server the data point's owner has registered as\n// trusted. The gateway re-uses this signature verbatim on-chain in the next\n// /v1/settle pass via DataRegistryV2.recordDataAccess, where `recordId`\n// dedupes via `_usedRecordIds`.\nexport interface AccessRecord {\n dataPointId: string;\n // Decimal-string uint256 — the data point version being attested to.\n version: string;\n // Must equal the enclosing payment's payerAddress (the gateway enforces).\n accessor: string;\n recordId: string;\n signature: string;\n}\n\nexport interface PayForOperationParams {\n payerAddress: string;\n opType: string;\n opId: string;\n asset: string;\n amount: string;\n // Per-payer monotonic; (payer, nonce, kind) must be unique. The gateway\n // returns 409 if reused — bump and re-sign.\n paymentNonce: string;\n signature: string;\n // Optional: attach a server-signed access record so the next /v1/settle\n // pass submits a recordDataAccess tx alongside the payment settlement.\n // Required for data-access payments (the second-and-onward payments per\n // grant) that want their on-chain `totalAccesses` counter to advance.\n accessRecord?: AccessRecord;\n}\n\nexport interface PayForOperationResult {\n opType: string;\n opId: string;\n payerAddress: string;\n asset: string;\n amount: string;\n // Echoes how the gateway split this payment. `registrationPaid` is true on\n // the first payment for a grant (which bundles both fees) and false on\n // subsequent data-access-only payments. Off-chain ledger state only — the\n // on-chain settlement of the registration is tracked by the grant's\n // `status` field, not this flag.\n breakdown: {\n registrationFee: string;\n dataAccessFee: string;\n registrationPaid: boolean;\n };\n paymentNonce: string;\n paidAt: string;\n}\n\n// ── Settle / reconcile ──────────────────────────────────────────────────────\n// POST /v1/settle drains pending-on-chain rows (grants, servers, data points,\n// access records) to the relayer, then promotes 'submitting' → 'confirmed'\n// and 'confirmed' → 'finalized' for previously-submitted rows. One call does\n// all three; the response surfaces each phase's outcomes.\n\n// The four op-types the settle endpoint knows about. Kept as a union so\n// callers can narrow inside the discriminated SettleItem shape.\nexport type SettleOpType = \"grant\" | \"server\" | \"data\" | \"access\";\n\nexport type SettleItem =\n | {\n opType: SettleOpType;\n opId: string;\n // 'confirmed' when the submit function waited for the receipt and it\n // mined (registerAndSettle path); 'submitting' when only the tx was\n // sent (no receipt wait).\n status: \"submitting\" | \"confirmed\";\n settleTxHash: string | null;\n settleSubmittedAt: string | null;\n // Block height the tx mined in; only set when status === 'confirmed'.\n chainBlockHeight: string | null;\n revocationTxHash: string | null;\n revocationSubmittedAt: string | null;\n // True while lib/settle.ts is in placeholder mode for this row's pass.\n placeholder: boolean;\n }\n | {\n opType: SettleOpType;\n opId: string;\n status: \"skipped\";\n reason: string;\n }\n | {\n opType: SettleOpType;\n opId: string;\n status: \"failed\";\n error: string;\n };\n\n// Outcome of the housekeeping pass that retries earlier `submitting` rows\n// whose receipt arrived after the prior /v1/settle's wait budget elapsed.\nexport interface SettlePromoteResult {\n opType: SettleOpType;\n opId: string;\n status: \"confirmed\" | \"failed\" | \"pending\" | \"skipped\";\n txHash: string;\n chainBlockHeight: string | null;\n reason?: string;\n}\n\n// Outcome of the reconcile pass that advances 'confirmed' → 'finalized' once\n// the chain's finalized tip catches up past the tx's block (or reverts to\n// 'pending' on reorg detection).\nexport interface SettleReconcileItem {\n opId: string;\n status: \"finalized\" | \"reorged\" | \"unchanged\";\n chainBlockHeight: string | null;\n settleTxHash: string | null;\n reason?: string;\n}\n\nexport interface SettleParams {\n // Per-phase cap. Bounded by MAX_LIMIT on the gateway side; omit to use\n // the gateway's default BATCH_LIMIT.\n limit?: number;\n}\n\nexport interface SettleResult {\n scanned: number;\n submitted: number;\n confirmed: number;\n skipped: number;\n failed: number;\n items: SettleItem[];\n promoted: { count: number; items: SettlePromoteResult[] };\n reconciled: {\n scanned: number;\n finalized: number;\n reorged: number;\n unchanged: number;\n items: SettleReconcileItem[];\n };\n // Present only when the gateway is configured for paced submission —\n // spreads work across several blocks within one /v1/settle invocation.\n paced?: { iterations: number };\n}\n\n// /v1/escrow/balance?account=... — pure read. Returns finalized balances by\n// asset, plus the lifecycle breakdown of deposits.\nexport interface EscrowBalanceEntry {\n asset: string;\n // Gross credited deposits for (account, asset). Decremented only when the\n // reconcile pass marks a payment finalized — NOT on /v1/escrow/pay.\n balance: string;\n // Sum of claimedAmount for deposits still in 'submitted' status — surfaced\n // separately so clients don't conflate \"credited\" with \"deposit announced\n // but not yet confirmed.\"\n pendingAmount: string;\n // Sum of payments.amount for (account, asset) regardless of settled status —\n // mirrors the /v1/escrow/pay handler's soft-lock counter. Subtract from\n // `balance` to see how much the payer can still authorise.\n authorizedAmount: string;\n // `max(balance − authorizedAmount, 0)`. The headroom a payer has against\n // the soft-lock before /v1/escrow/pay starts returning 402.\n availableAmount: string;\n updatedAt: string | null;\n}\n\nexport interface EscrowDepositSubmitted {\n txHash: string;\n submittedAt: string;\n claimedAsset: string;\n claimedAmount: string;\n}\n\nexport interface EscrowDepositFinalized {\n txHash: string;\n finalizedAt: string | null;\n blockNumber: string | null;\n claimedAsset: string;\n claimedAmount: string;\n}\n\nexport interface EscrowDepositFailed {\n txHash: string;\n submittedAt: string;\n claimedAsset: string;\n claimedAmount: string;\n lastError: string | null;\n}\n\nexport interface EscrowBalance {\n account: string;\n balances: EscrowBalanceEntry[];\n deposits: {\n submitted: EscrowDepositSubmitted[];\n finalized: EscrowDepositFinalized[];\n failed: EscrowDepositFailed[];\n };\n}\n\n// /v1/escrow/deposit announces an on-chain deposit tx so the gateway can\n// reconcile it into the payer's balance. The gateway extracts the credited\n// account from calldata — no off-chain claim about who paid.\nexport interface SubmitDepositParams {\n txHash: string;\n}\n\nexport interface DepositState {\n txHash: string;\n account: string;\n // 'submitted' | 'finalized' | 'failed' — kept open since the gateway adds\n // states (e.g. 'orphaned') as the deposit flow evolves.\n status: string;\n blockNumber: string | null;\n submittedAt: string;\n finalizedAt: string | null;\n lastError: string | null;\n}\n\nexport interface GatewayClient {\n isRegisteredBuilder(address: string): Promise<boolean>;\n getBuilder(address: string): Promise<Builder | null>;\n getGrant(grantId: string): Promise<GatewayGrantResponse | null>;\n listGrantsByUser(userAddress: string): Promise<GrantListItem[]>;\n getSchemaForScope(scope: string): Promise<Schema | null>;\n getServer(address: string): Promise<ServerInfo | null>;\n getFile(fileId: string): Promise<FileRecord | null>;\n listFilesSince(owner: string, cursor: string | null): Promise<FileListResult>;\n getSchema(schemaId: string): Promise<Schema | null>;\n registerServer(params: RegisterServerParams): Promise<RegisterServerResult>;\n registerBuilder(\n params: RegisterBuilderParams,\n ): Promise<RegisterBuilderResult>;\n registerDataPoint(\n params: RegisterDataPointParams,\n ): Promise<RegisterDataPointResult>;\n registerFile(params: RegisterFileParams): Promise<{ fileId?: string }>;\n createGrant(params: CreateGrantParams): Promise<{ grantId?: string }>;\n revokeGrant(params: RevokeGrantParams): Promise<void>;\n getEscrowBalance(account: string): Promise<EscrowBalance>;\n submitEscrowDeposit(params: SubmitDepositParams): Promise<DepositState>;\n payForOperation(\n params: PayForOperationParams,\n ): Promise<PayForOperationResult>;\n settle(params?: SettleParams): Promise<SettleResult>;\n}\n\nexport function createGatewayClient(baseUrl: string): GatewayClient {\n const base = baseUrl.replace(/\\/+$/, \"\");\n\n async function unwrapEnvelope<T>(res: Response): Promise<T> {\n const envelope = (await res.json()) as GatewayEnvelope<T>;\n return envelope.data;\n }\n\n function normalizeFileRecord(record: GatewayFileRecord): FileRecord {\n return {\n fileId: record.fileId ?? record.id ?? \"\",\n owner: record.owner ?? record.ownerAddress ?? \"\",\n url: record.url,\n schemaId: record.schemaId,\n createdAt: record.createdAt ?? record.addedAt ?? \"\",\n };\n }\n\n function getMutationId(\n body: Record<string, unknown>,\n key: string,\n ): string | undefined {\n const value = body[key] ?? body[\"id\"];\n return typeof value === \"string\" ? value : undefined;\n }\n\n return {\n async isRegisteredBuilder(address: string): Promise<boolean> {\n const builder = await this.getBuilder(address);\n return builder !== null;\n },\n\n async getBuilder(address: string): Promise<Builder | null> {\n const res = await fetch(`${base}/v1/builders/${address}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<Builder>(res);\n },\n\n async getGrant(grantId: string): Promise<GatewayGrantResponse | null> {\n const res = await fetch(`${base}/v1/grants/${grantId}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<GatewayGrantResponse>(res);\n },\n\n async listGrantsByUser(userAddress: string): Promise<GrantListItem[]> {\n const res = await fetch(`${base}/v1/grants?user=${userAddress}`);\n if (res.status === 404) return [];\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<GrantListItem[]>(res);\n },\n\n async getSchemaForScope(scope: string): Promise<Schema | null> {\n const res = await fetch(`${base}/v1/schemas?scope=${scope}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<Schema>(res);\n },\n\n async getServer(address: string): Promise<ServerInfo | null> {\n const res = await fetch(`${base}/v1/servers/${address}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<ServerInfo>(res);\n },\n\n async getFile(fileId: string): Promise<FileRecord | null> {\n const res = await fetch(`${base}/v1/files/${fileId}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return normalizeFileRecord(await unwrapEnvelope<GatewayFileRecord>(res));\n },\n\n async listFilesSince(\n owner: string,\n cursor: string | null,\n ): Promise<FileListResult> {\n const params = new URLSearchParams({ user: owner });\n if (cursor !== null) {\n params.set(\"since\", cursor);\n }\n const res = await fetch(`${base}/v1/files?${params.toString()}`);\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const data = await unwrapEnvelope<{\n files: GatewayFileRecord[];\n cursor: string | null;\n }>(res);\n return {\n files: data.files.map(normalizeFileRecord),\n cursor: data.cursor,\n };\n },\n\n async getSchema(schemaId: string): Promise<Schema | null> {\n const res = await fetch(`${base}/v1/schemas/${schemaId}`);\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return unwrapEnvelope<Schema>(res);\n },\n\n async registerServer(\n params: RegisterServerParams,\n ): Promise<RegisterServerResult> {\n const res = await fetch(`${base}/v1/servers`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n ownerAddress: params.ownerAddress,\n serverAddress: params.serverAddress,\n publicKey: params.publicKey,\n serverUrl: params.serverUrl,\n }),\n });\n if (res.status === 409) {\n const body = await res.json().catch(() => ({}));\n return {\n serverId: getMutationId(body as Record<string, unknown>, \"serverId\"),\n alreadyRegistered: true,\n };\n }\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const body = await res.json().catch(() => ({}));\n return {\n serverId: getMutationId(body as Record<string, unknown>, \"serverId\"),\n alreadyRegistered: false,\n };\n },\n\n async registerBuilder(\n params: RegisterBuilderParams,\n ): Promise<RegisterBuilderResult> {\n const res = await fetch(`${base}/v1/builders`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n ownerAddress: params.ownerAddress,\n granteeAddress: params.granteeAddress,\n publicKey: params.publicKey,\n appUrl: params.appUrl,\n }),\n });\n // 409 is idempotent — the gateway's current 409 body doesn't include\n // the builderId, but we tolerate it in case that changes (mirrors the\n // registerServer / createGrant shape).\n if (res.status === 409) {\n const body = await res.json().catch(() => ({}));\n return {\n builderId: getMutationId(\n body as Record<string, unknown>,\n \"builderId\",\n ),\n alreadyRegistered: true,\n };\n }\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const body = await res.json().catch(() => ({}));\n return {\n builderId: getMutationId(body as Record<string, unknown>, \"builderId\"),\n alreadyRegistered: false,\n };\n },\n\n async registerDataPoint(\n params: RegisterDataPointParams,\n ): Promise<RegisterDataPointResult> {\n const res = await fetch(`${base}/v1/data`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n ownerAddress: params.ownerAddress,\n scope: params.scope,\n dataHash: params.dataHash,\n metadataHash: params.metadataHash,\n expectedVersion: params.expectedVersion,\n }),\n });\n // 409 is a real failure here (stale CAS), not an idempotent replay —\n // surface the gateway's error message verbatim so the caller knows\n // what `currentExpectedVersion` to re-sign against.\n if (!res.ok) {\n const body = (await res.json().catch(() => ({}))) as {\n error?: string;\n };\n const detail = body.error ?? res.statusText;\n throw new Error(`Gateway error: ${res.status} ${detail}`);\n }\n const body = (await res.json().catch(() => ({}))) as {\n dataPointId?: string;\n expectedVersion?: string;\n };\n return {\n dataPointId: getMutationId(\n body as Record<string, unknown>,\n \"dataPointId\",\n ),\n expectedVersion: body.expectedVersion,\n };\n },\n\n async registerFile(\n params: RegisterFileParams,\n ): Promise<{ fileId?: string }> {\n const res = await fetch(`${base}/v1/files`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n ownerAddress: params.ownerAddress,\n url: params.url,\n schemaId: params.schemaId,\n }),\n });\n if (res.status === 409) {\n const body = await res.json().catch(() => ({}));\n return {\n fileId: getMutationId(body as Record<string, unknown>, \"fileId\"),\n };\n }\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const body = await res.json();\n return {\n fileId: getMutationId(body as Record<string, unknown>, \"fileId\"),\n };\n },\n\n async createGrant(\n params: CreateGrantParams,\n ): Promise<{ grantId?: string }> {\n const res = await fetch(`${base}/v1/grants`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n grantorAddress: params.grantorAddress,\n granteeId: params.granteeId,\n scopes: params.scopes,\n grantVersion: params.grantVersion,\n expiresAt: params.expiresAt,\n }),\n });\n if (res.status === 409) {\n const body = await res.json().catch(() => ({}));\n return {\n grantId: getMutationId(body as Record<string, unknown>, \"grantId\"),\n };\n }\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n const body = await res.json();\n return {\n grantId: getMutationId(body as Record<string, unknown>, \"grantId\"),\n };\n },\n\n async revokeGrant(params: RevokeGrantParams): Promise<void> {\n const res = await fetch(`${base}/v1/grants/${params.grantId}`, {\n method: \"DELETE\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify({\n grantorAddress: params.grantorAddress,\n grantVersion: params.grantVersion,\n }),\n });\n if (res.status === 409) return;\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n },\n\n async getEscrowBalance(account: string): Promise<EscrowBalance> {\n const res = await fetch(`${base}/v1/escrow/balance?account=${account}`);\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n // Unlike the rest of /v1, the balance endpoint returns the body\n // directly (no GatewayEnvelope wrap) — it's a pure read with no\n // gateway-signed attestation. See data-gateway api/v1/escrow/balance.ts.\n return (await res.json()) as EscrowBalance;\n },\n\n async submitEscrowDeposit(\n params: SubmitDepositParams,\n ): Promise<DepositState> {\n const res = await fetch(`${base}/v1/escrow/deposit`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ txHash: params.txHash }),\n });\n // The gateway returns 202 for \"accepted (still confirming)\" and 200 for\n // duplicate idempotent replays. Both carry the deposit's current state.\n if (res.status !== 200 && res.status !== 202) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return (await res.json()) as DepositState;\n },\n\n async payForOperation(\n params: PayForOperationParams,\n ): Promise<PayForOperationResult> {\n // Build the body without the accessRecord key when absent so the\n // gateway's \"missing optional\" branch matches the no-receipt case\n // exactly (an explicit `accessRecord: undefined` would JSON-serialize\n // to nothing — same result — but keeping it conditional makes wire\n // traces easier to read).\n const body: Record<string, unknown> = {\n payerAddress: params.payerAddress,\n opType: params.opType,\n opId: params.opId,\n asset: params.asset,\n amount: params.amount,\n paymentNonce: params.paymentNonce,\n };\n if (params.accessRecord) {\n body[\"accessRecord\"] = params.accessRecord;\n }\n const res = await fetch(`${base}/v1/escrow/pay`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Web3Signed ${params.signature}`,\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return (await res.json()) as PayForOperationResult;\n },\n\n async settle(params?: SettleParams): Promise<SettleResult> {\n const res = await fetch(`${base}/v1/settle`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n // The gateway accepts an empty body; only `limit` is recognised.\n // Always send a JSON body so the gateway's req.body shape parse\n // doesn't have to deal with an undefined.\n body: JSON.stringify(params ?? {}),\n });\n if (!res.ok) {\n throw new Error(`Gateway error: ${res.status} ${res.statusText}`);\n }\n return (await res.json()) as SettleResult;\n },\n };\n}\n"],"mappings":"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","names":["body"]}
@@ -19,7 +19,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var grants_exports = {};
20
20
  __export(grants_exports, {
21
21
  isDataPortabilityGatewayConfig: () => isDataPortabilityGatewayConfig,
22
- parseGrantRegistrationPayload: () => parseGrantRegistrationPayload,
23
22
  verifyGrantRegistration: () => verifyGrantRegistration
24
23
  });
25
24
  module.exports = __toCommonJS(grants_exports);
@@ -38,67 +37,31 @@ function isDataPortabilityGatewayConfig(value) {
38
37
  return false;
39
38
  }
40
39
  const c = contracts;
41
- return isHexString(c["dataRegistry"]) && isHexString(c["dataPortabilityPermissions"]) && isHexString(c["dataPortabilityServer"]) && isHexString(c["dataPortabilityGrantees"]);
40
+ return isHexString(c["dataRegistry"]) && isHexString(c["dataPortabilityPermissions"]) && isHexString(c["dataPortabilityServer"]) && isHexString(c["dataPortabilityGrantees"]) && isHexString(c["dataPortabilityEscrow"]);
42
41
  }
43
- function parseGrantRegistrationPayload(grant) {
44
- let parsed;
42
+ function toUint256(value) {
45
43
  try {
46
- parsed = JSON.parse(grant);
47
- } catch {
48
- return null;
49
- }
50
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
51
- return null;
52
- }
53
- const value = parsed;
54
- if (!Array.isArray(value["scopes"]) || value["scopes"].length === 0) {
55
- return null;
56
- }
57
- if (!value["scopes"].every((scope) => typeof scope === "string")) {
58
- return null;
59
- }
60
- if (typeof value["expiresAt"] !== "number" || !Number.isFinite(value["expiresAt"])) {
61
- return null;
62
- }
63
- if (value["user"] !== void 0 && !isHexString(value["user"])) {
64
- return null;
65
- }
66
- if (value["builder"] !== void 0 && !isHexString(value["builder"])) {
67
- return null;
68
- }
69
- if (value["nonce"] !== void 0 && (typeof value["nonce"] !== "number" || !Number.isFinite(value["nonce"]))) {
70
- return null;
71
- }
72
- return {
73
- user: value["user"],
74
- builder: value["builder"],
75
- scopes: value["scopes"],
76
- expiresAt: value["expiresAt"],
77
- nonce: value["nonce"]
78
- };
79
- }
80
- function parseFileIds(fileIds) {
81
- try {
82
- const values = (fileIds ?? []).map((fileId) => BigInt(fileId));
83
- return {
84
- values,
85
- display: values.map((fileId) => fileId.toString())
86
- };
44
+ const big = typeof value === "bigint" ? value : BigInt(value);
45
+ if (big < 0n) return null;
46
+ return big;
87
47
  } catch {
88
48
  return null;
89
49
  }
90
50
  }
91
51
  async function verifyGrantRegistration(input) {
92
- const payload = parseGrantRegistrationPayload(input.grant);
93
- if (!payload) {
94
- return {
95
- valid: false,
96
- error: "Grant must be JSON with scopes and expiresAt"
97
- };
52
+ if (!Array.isArray(input.scopes) || input.scopes.length === 0) {
53
+ return { valid: false, error: "scopes must be a non-empty array" };
98
54
  }
99
- const fileIds = parseFileIds(input.fileIds);
100
- if (!fileIds) {
101
- return { valid: false, error: "fileIds must contain integer values" };
55
+ if (!input.scopes.every((scope) => typeof scope === "string")) {
56
+ return { valid: false, error: "scopes must contain only strings" };
57
+ }
58
+ const grantVersion = toUint256(input.grantVersion);
59
+ if (grantVersion === null || grantVersion < 1n) {
60
+ return { valid: false, error: "grantVersion must be a uint256 >= 1" };
61
+ }
62
+ const expiresAt = toUint256(input.expiresAt);
63
+ if (expiresAt === null) {
64
+ return { valid: false, error: "expiresAt must be a non-negative uint256" };
102
65
  }
103
66
  let valid;
104
67
  try {
@@ -110,8 +73,9 @@ async function verifyGrantRegistration(input) {
110
73
  message: {
111
74
  grantorAddress: input.grantorAddress,
112
75
  granteeId: input.granteeId,
113
- grant: input.grant,
114
- fileIds: fileIds.values
76
+ scopes: input.scopes,
77
+ grantVersion,
78
+ expiresAt
115
79
  },
116
80
  signature: input.signature
117
81
  });
@@ -122,25 +86,21 @@ async function verifyGrantRegistration(input) {
122
86
  return { valid: false, error: "Grant signature does not match grantor" };
123
87
  }
124
88
  const nowSeconds = input.nowSeconds ?? Math.floor(Date.now() / 1e3);
125
- if (payload.expiresAt > 0 && payload.expiresAt < nowSeconds) {
89
+ if (expiresAt > 0n && expiresAt < BigInt(nowSeconds)) {
126
90
  return { valid: false, error: "Grant has expired" };
127
91
  }
128
- if (payload.user !== void 0 && payload.user.toLowerCase() !== input.grantorAddress.toLowerCase()) {
129
- return { valid: false, error: "Grant user does not match grantorAddress" };
130
- }
131
92
  return {
132
93
  valid: true,
133
94
  grantorAddress: input.grantorAddress,
134
95
  granteeId: input.granteeId,
135
- grant: input.grant,
136
- payload,
137
- fileIds: fileIds.display
96
+ scopes: input.scopes,
97
+ grantVersion: grantVersion.toString(),
98
+ expiresAt: expiresAt.toString()
138
99
  };
139
100
  }
140
101
  // Annotate the CommonJS export names for ESM import in node:
141
102
  0 && (module.exports = {
142
103
  isDataPortabilityGatewayConfig,
143
- parseGrantRegistrationPayload,
144
104
  verifyGrantRegistration
145
105
  });
146
106
  //# sourceMappingURL=grants.cjs.map