@opendatalabs/personal-server-ts-core 0.2.0 → 1.0.1
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.
- package/dist/api/index.d.ts +160 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +774 -0
- package/dist/api/index.js.map +1 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/request.d.ts +28 -0
- package/dist/auth/request.d.ts.map +1 -0
- package/dist/auth/request.js +106 -0
- package/dist/auth/request.js.map +1 -0
- package/dist/client.d.ts +233 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +243 -0
- package/dist/client.js.map +1 -0
- package/dist/config/defaults.d.ts +5 -5
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +3 -5
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +0 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/paths.d.ts.map +1 -1
- package/dist/config/paths.js +1 -9
- package/dist/config/paths.js.map +1 -1
- package/dist/contracts/access-logs.d.ts +8 -0
- package/dist/contracts/access-logs.d.ts.map +1 -0
- package/dist/contracts/access-logs.js +7 -0
- package/dist/contracts/access-logs.js.map +1 -0
- package/dist/contracts/auth-device.d.ts +70 -0
- package/dist/contracts/auth-device.d.ts.map +1 -0
- package/dist/contracts/auth-device.js +163 -0
- package/dist/contracts/auth-device.js.map +1 -0
- package/dist/contracts/binary.d.ts +54 -0
- package/dist/contracts/binary.d.ts.map +1 -0
- package/dist/contracts/binary.js +92 -0
- package/dist/contracts/binary.js.map +1 -0
- package/dist/contracts/config.d.ts +5 -0
- package/dist/contracts/config.d.ts.map +1 -0
- package/dist/contracts/config.js +30 -0
- package/dist/contracts/config.js.map +1 -0
- package/dist/contracts/data.d.ts +115 -0
- package/dist/contracts/data.d.ts.map +1 -0
- package/dist/contracts/data.js +237 -0
- package/dist/contracts/data.js.map +1 -0
- package/dist/contracts/grants.d.ts +45 -0
- package/dist/contracts/grants.d.ts.map +1 -0
- package/dist/contracts/grants.js +177 -0
- package/dist/contracts/grants.js.map +1 -0
- package/dist/contracts/http.d.ts +21 -0
- package/dist/contracts/http.d.ts.map +1 -0
- package/dist/contracts/http.js +49 -0
- package/dist/contracts/http.js.map +1 -0
- package/dist/contracts/index.d.ts +16 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +10 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/oauth.d.ts +38 -0
- package/dist/contracts/oauth.d.ts.map +1 -0
- package/dist/contracts/oauth.js +130 -0
- package/dist/contracts/oauth.js.map +1 -0
- package/dist/contracts/sync.d.ts +10 -0
- package/dist/contracts/sync.d.ts.map +1 -0
- package/dist/contracts/sync.js +34 -0
- package/dist/contracts/sync.js.map +1 -0
- package/dist/errors/catalog.d.ts +9 -0
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/catalog.js +15 -0
- package/dist/errors/catalog.js.map +1 -1
- package/dist/grants/index.d.ts +2 -4
- package/dist/grants/index.d.ts.map +1 -1
- package/dist/grants/index.js +1 -2
- package/dist/grants/index.js.map +1 -1
- package/dist/keys/index.d.ts +1 -2
- package/dist/keys/index.d.ts.map +1 -1
- package/dist/keys/index.js +1 -2
- package/dist/keys/index.js.map +1 -1
- package/dist/keys/server-account.d.ts +5 -9
- package/dist/keys/server-account.d.ts.map +1 -1
- package/dist/keys/server-account.js +1 -47
- package/dist/keys/server-account.js.map +1 -1
- package/dist/logger/index.d.ts +6 -2
- package/dist/logger/index.d.ts.map +1 -1
- package/dist/logger/index.js +2 -6
- package/dist/logger/index.js.map +1 -1
- package/dist/logging/access-log.d.ts +0 -1
- package/dist/logging/access-log.d.ts.map +1 -1
- package/dist/logging/access-log.js +1 -24
- package/dist/logging/access-log.js.map +1 -1
- package/dist/logging/access-reader.d.ts +0 -5
- package/dist/logging/access-reader.d.ts.map +1 -1
- package/dist/logging/access-reader.js +1 -49
- package/dist/logging/access-reader.js.map +1 -1
- package/dist/mcp/activity.d.ts +68 -0
- package/dist/mcp/activity.d.ts.map +1 -0
- package/dist/mcp/activity.js +111 -0
- package/dist/mcp/activity.js.map +1 -0
- package/dist/mcp/builder-registration.d.ts +24 -0
- package/dist/mcp/builder-registration.d.ts.map +1 -0
- package/dist/mcp/builder-registration.js +89 -0
- package/dist/mcp/builder-registration.js.map +1 -0
- package/dist/mcp/connection-api.d.ts +170 -0
- package/dist/mcp/connection-api.d.ts.map +1 -0
- package/dist/mcp/connection-api.js +379 -0
- package/dist/mcp/connection-api.js.map +1 -0
- package/dist/mcp/grantee.d.ts +52 -0
- package/dist/mcp/grantee.d.ts.map +1 -0
- package/dist/mcp/grantee.js +91 -0
- package/dist/mcp/grantee.js.map +1 -0
- package/dist/mcp/index.d.ts +10 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +10 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/read-client.d.ts +136 -0
- package/dist/mcp/read-client.d.ts.map +1 -0
- package/dist/mcp/read-client.js +306 -0
- package/dist/mcp/read-client.js.map +1 -0
- package/dist/mcp/resources.d.ts +37 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +114 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/search/index.d.ts +34 -0
- package/dist/mcp/search/index.d.ts.map +1 -0
- package/dist/mcp/search/index.js +69 -0
- package/dist/mcp/search/index.js.map +1 -0
- package/dist/mcp/server.d.ts +53 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +308 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/store.d.ts +13 -0
- package/dist/mcp/store.d.ts.map +1 -0
- package/dist/mcp/store.js +98 -0
- package/dist/mcp/store.js.map +1 -0
- package/dist/mcp/tools.d.ts +60 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +1058 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp/types.d.ts +97 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +24 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/payment/index.d.ts +2 -0
- package/dist/payment/index.d.ts.map +1 -0
- package/dist/payment/index.js +2 -0
- package/dist/payment/index.js.map +1 -0
- package/dist/payment/x402.d.ts +155 -0
- package/dist/payment/x402.d.ts.map +1 -0
- package/dist/payment/x402.js +402 -0
- package/dist/payment/x402.js.map +1 -0
- package/dist/policy/data-read.d.ts +15 -0
- package/dist/policy/data-read.d.ts.map +1 -0
- package/dist/policy/data-read.js +84 -0
- package/dist/policy/data-read.js.map +1 -0
- package/dist/policy/index.d.ts +2 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +2 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/ports/index.d.ts +95 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +7 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/schemas/server-config.d.ts +12 -0
- package/dist/schemas/server-config.d.ts.map +1 -1
- package/dist/schemas/server-config.js +34 -4
- package/dist/schemas/server-config.js.map +1 -1
- package/dist/signing/index.d.ts +0 -1
- package/dist/signing/index.d.ts.map +1 -1
- package/dist/signing/index.js +0 -1
- package/dist/signing/index.js.map +1 -1
- package/dist/signing/request-signer.d.ts +8 -2
- package/dist/signing/request-signer.d.ts.map +1 -1
- package/dist/signing/request-signer.js +5 -31
- package/dist/signing/request-signer.js.map +1 -1
- package/dist/signing/signer.d.ts +20 -2
- package/dist/signing/signer.d.ts.map +1 -1
- package/dist/signing/signer.js +23 -13
- package/dist/signing/signer.js.map +1 -1
- package/dist/storage/adapters/index.d.ts +2 -1
- package/dist/storage/adapters/index.d.ts.map +1 -1
- package/dist/storage/adapters/index.js +2 -1
- package/dist/storage/adapters/index.js.map +1 -1
- package/dist/storage/adapters/interface.d.ts +10 -0
- package/dist/storage/adapters/interface.d.ts.map +1 -1
- package/dist/storage/adapters/sdk.d.ts +23 -0
- package/dist/storage/adapters/sdk.d.ts.map +1 -0
- package/dist/storage/adapters/sdk.js +73 -0
- package/dist/storage/adapters/sdk.js.map +1 -0
- package/dist/storage/adapters/vana.d.ts +7 -30
- package/dist/storage/adapters/vana.d.ts.map +1 -1
- package/dist/storage/adapters/vana.js +37 -92
- package/dist/storage/adapters/vana.js.map +1 -1
- package/dist/storage/blocks/build.d.ts +20 -0
- package/dist/storage/blocks/build.d.ts.map +1 -0
- package/dist/storage/blocks/build.js +378 -0
- package/dist/storage/blocks/build.js.map +1 -0
- package/dist/storage/blocks/cursor.d.ts +33 -0
- package/dist/storage/blocks/cursor.d.ts.map +1 -0
- package/dist/storage/blocks/cursor.js +142 -0
- package/dist/storage/blocks/cursor.js.map +1 -0
- package/dist/storage/blocks/errors.d.ts +6 -0
- package/dist/storage/blocks/errors.d.ts.map +1 -0
- package/dist/storage/blocks/errors.js +9 -0
- package/dist/storage/blocks/errors.js.map +1 -0
- package/dist/storage/blocks/index.d.ts +5 -0
- package/dist/storage/blocks/index.d.ts.map +1 -0
- package/dist/storage/blocks/index.js +4 -0
- package/dist/storage/blocks/index.js.map +1 -0
- package/dist/storage/blocks/types.d.ts +49 -0
- package/dist/storage/blocks/types.d.ts.map +1 -0
- package/dist/storage/blocks/types.js +2 -0
- package/dist/{grants → storage/blocks}/types.js.map +1 -1
- package/dist/storage/hierarchy/index.d.ts +0 -1
- package/dist/storage/hierarchy/index.d.ts.map +1 -1
- package/dist/storage/hierarchy/index.js +0 -1
- package/dist/storage/hierarchy/index.js.map +1 -1
- package/dist/storage/hierarchy/manager.d.ts +0 -14
- package/dist/storage/hierarchy/manager.d.ts.map +1 -1
- package/dist/storage/hierarchy/manager.js +1 -59
- package/dist/storage/hierarchy/manager.js.map +1 -1
- package/dist/storage/hierarchy/paths.d.ts.map +1 -1
- package/dist/storage/hierarchy/paths.js +11 -4
- package/dist/storage/hierarchy/paths.js.map +1 -1
- package/dist/storage/index/index.d.ts +2 -3
- package/dist/storage/index/index.d.ts.map +1 -1
- package/dist/storage/index/index.js +1 -2
- package/dist/storage/index/index.js.map +1 -1
- package/dist/storage/index/manager.d.ts +26 -6
- package/dist/storage/index/manager.d.ts.map +1 -1
- package/dist/storage/index/manager.js +1 -131
- package/dist/storage/index/manager.js.map +1 -1
- package/dist/storage/index/schema.d.ts +1 -3
- package/dist/storage/index/schema.d.ts.map +1 -1
- package/dist/storage/index/schema.js +1 -26
- package/dist/storage/index/schema.js.map +1 -1
- package/dist/storage/index/types.d.ts +16 -0
- package/dist/storage/index/types.d.ts.map +1 -1
- package/dist/storage/preview.d.ts +12 -0
- package/dist/storage/preview.d.ts.map +1 -0
- package/dist/storage/preview.js +239 -0
- package/dist/storage/preview.js.map +1 -0
- package/dist/sync/cursor.d.ts +5 -7
- package/dist/sync/cursor.d.ts.map +1 -1
- package/dist/sync/cursor.js +1 -18
- package/dist/sync/cursor.js.map +1 -1
- package/dist/sync/engine/sync-manager.d.ts +17 -0
- package/dist/sync/engine/sync-manager.d.ts.map +1 -1
- package/dist/sync/engine/sync-manager.js +104 -43
- package/dist/sync/engine/sync-manager.js.map +1 -1
- package/dist/sync/index.d.ts +4 -2
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/sync/index.js.map +1 -1
- package/dist/sync/issues.d.ts +55 -0
- package/dist/sync/issues.d.ts.map +1 -0
- package/dist/sync/issues.js +168 -0
- package/dist/sync/issues.js.map +1 -0
- package/dist/sync/retry-memory.d.ts +33 -0
- package/dist/sync/retry-memory.d.ts.map +1 -0
- package/dist/sync/retry-memory.js +68 -0
- package/dist/sync/retry-memory.js.map +1 -0
- package/dist/sync/types.d.ts +9 -24
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/sync/workers/delete.d.ts +42 -0
- package/dist/sync/workers/delete.d.ts.map +1 -0
- package/dist/sync/workers/delete.js +40 -0
- package/dist/sync/workers/delete.js.map +1 -0
- package/dist/sync/workers/download.d.ts +64 -18
- package/dist/sync/workers/download.d.ts.map +1 -1
- package/dist/sync/workers/download.js +396 -54
- package/dist/sync/workers/download.js.map +1 -1
- package/dist/sync/workers/upload.d.ts +29 -18
- package/dist/sync/workers/upload.d.ts.map +1 -1
- package/dist/sync/workers/upload.js +163 -46
- package/dist/sync/workers/upload.js.map +1 -1
- package/dist/test-utils/wallet.d.ts +1 -0
- package/dist/test-utils/wallet.d.ts.map +1 -1
- package/dist/test-utils/wallet.js +9 -31
- package/dist/test-utils/wallet.js.map +1 -1
- package/package.json +51 -27
- package/dist/auth/web3-signed.d.ts +0 -48
- package/dist/auth/web3-signed.d.ts.map +0 -1
- package/dist/auth/web3-signed.js +0 -110
- package/dist/auth/web3-signed.js.map +0 -1
- package/dist/config/loader.d.ts +0 -8
- package/dist/config/loader.d.ts.map +0 -1
- package/dist/config/loader.js +0 -38
- package/dist/config/loader.js.map +0 -1
- package/dist/gateway/client.d.ts +0 -98
- package/dist/gateway/client.d.ts.map +0 -1
- package/dist/gateway/client.js +0 -171
- package/dist/gateway/client.js.map +0 -1
- package/dist/grants/eip712.d.ts +0 -28
- package/dist/grants/eip712.d.ts.map +0 -1
- package/dist/grants/eip712.js +0 -30
- package/dist/grants/eip712.js.map +0 -1
- package/dist/grants/types.d.ts +0 -29
- package/dist/grants/types.d.ts.map +0 -1
- package/dist/grants/types.js +0 -6
- package/dist/grants/verify.d.ts +0 -24
- package/dist/grants/verify.d.ts.map +0 -1
- package/dist/grants/verify.js +0 -71
- package/dist/grants/verify.js.map +0 -1
- package/dist/keys/derive.d.ts +0 -18
- package/dist/keys/derive.d.ts.map +0 -1
- package/dist/keys/derive.js +0 -43
- package/dist/keys/derive.js.map +0 -1
- package/dist/schemas/data-file.d.ts +0 -20
- package/dist/schemas/data-file.d.ts.map +0 -1
- package/dist/schemas/data-file.js +0 -23
- package/dist/schemas/data-file.js.map +0 -1
- package/dist/scopes/index.d.ts +0 -3
- package/dist/scopes/index.d.ts.map +0 -1
- package/dist/scopes/index.js +0 -3
- package/dist/scopes/index.js.map +0 -1
- package/dist/scopes/match.d.ts +0 -13
- package/dist/scopes/match.d.ts.map +0 -1
- package/dist/scopes/match.js +0 -23
- package/dist/scopes/match.js.map +0 -1
- package/dist/scopes/parse.d.ts +0 -12
- package/dist/scopes/parse.d.ts.map +0 -1
- package/dist/scopes/parse.js +0 -29
- package/dist/scopes/parse.js.map +0 -1
- package/dist/signing/eip712.d.ts +0 -69
- package/dist/signing/eip712.d.ts.map +0 -1
- package/dist/signing/eip712.js +0 -68
- package/dist/signing/eip712.js.map +0 -1
- package/dist/storage/encryption/decrypt.d.ts +0 -10
- package/dist/storage/encryption/decrypt.d.ts.map +0 -1
- package/dist/storage/encryption/decrypt.js +0 -19
- package/dist/storage/encryption/decrypt.js.map +0 -1
- package/dist/storage/encryption/encrypt.d.ts +0 -10
- package/dist/storage/encryption/encrypt.d.ts.map +0 -1
- package/dist/storage/encryption/encrypt.js +0 -19
- package/dist/storage/encryption/encrypt.js.map +0 -1
- package/dist/storage/encryption/index.d.ts +0 -3
- package/dist/storage/encryption/index.d.ts.map +0 -1
- package/dist/storage/encryption/index.js +0 -3
- package/dist/storage/encryption/index.js.map +0 -1
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* X402 payment challenge / verification for builder reads.
|
|
3
|
+
*
|
|
4
|
+
* The personal server speaks an x402-style payment dance to builders on
|
|
5
|
+
* GET /v1/data/:scope. When a request arrives without (or with an invalid)
|
|
6
|
+
* X-PAYMENT header the server issues a 402 challenge: a server-signed
|
|
7
|
+
* RECORD_DATA_ACCESS attestation plus the canonical GenericPayment message
|
|
8
|
+
* the builder must EIP-712 sign. The builder retries with the signed
|
|
9
|
+
* message in X-PAYMENT; the server validates locally, then forwards to
|
|
10
|
+
* `POST /v1/escrow/pay` on the gateway. On 2xx the read proceeds; on
|
|
11
|
+
* 4xx/5xx the server responds with a fresh challenge.
|
|
12
|
+
*
|
|
13
|
+
* This module is wire-format only — it doesn't talk to the gateway or the
|
|
14
|
+
* storage layer. Callers in `api/index.ts` glue it to `gateway.getGrant`
|
|
15
|
+
* (for fee discovery), `IndexEntry.dataPointId/version` (for accessRecord
|
|
16
|
+
* binding), and a direct `fetch` to the gateway for payment forwarding.
|
|
17
|
+
*/
|
|
18
|
+
import { GENERIC_PAYMENT_TYPES, RECORD_DATA_ACCESS_TYPES, dataRegistryDomain, escrowPaymentDomain, } from "@opendatalabs/vana-sdk/browser";
|
|
19
|
+
import { recoverTypedDataAddress } from "viem";
|
|
20
|
+
// Per-event recordId on the access attestation. 32 cryptographically random
|
|
21
|
+
// bytes — collision-resistant under the DataRegistryV2 `_usedRecordIds`
|
|
22
|
+
// set the contract pins per access event.
|
|
23
|
+
export function generateRecordId() {
|
|
24
|
+
const bytes = new Uint8Array(32);
|
|
25
|
+
crypto.getRandomValues(bytes);
|
|
26
|
+
return ("0x" +
|
|
27
|
+
Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join(""));
|
|
28
|
+
}
|
|
29
|
+
// Build a fresh paymentNonce: high 32 bits = Date.now() (ms-monotonic), low
|
|
30
|
+
// 32 bits = cryptographic randomness (within-ms collision avoidance). Yields
|
|
31
|
+
// a strictly-increasing uint256 across ms ticks while keeping per-ms
|
|
32
|
+
// collision probability negligible. Serialized as a decimal string on the
|
|
33
|
+
// wire so the gateway's `^[1-9]\d*$` regex accepts it.
|
|
34
|
+
//
|
|
35
|
+
// Caveat: server-clock regressions can break monotonicity; the gateway
|
|
36
|
+
// rejects out-of-order nonces with 409 and the builder retries.
|
|
37
|
+
export function nextPaymentNonce() {
|
|
38
|
+
const rand = new Uint32Array(1);
|
|
39
|
+
crypto.getRandomValues(rand);
|
|
40
|
+
return (BigInt(Date.now()) << 32n) + BigInt(rand[0]);
|
|
41
|
+
}
|
|
42
|
+
// Recover the millisecond timestamp encoded in the high 32 bits of a nonce
|
|
43
|
+
// generated by `nextPaymentNonce`. Used for the optional freshness check
|
|
44
|
+
// during X-PAYMENT validation.
|
|
45
|
+
export function paymentNonceIssueTimeMs(nonce) {
|
|
46
|
+
return nonce >> 32n;
|
|
47
|
+
}
|
|
48
|
+
const CHALLENGE_TTL_SECONDS = 300; // 5 min — challenges are stateless; this
|
|
49
|
+
// is purely advisory for clients.
|
|
50
|
+
const NONCE_FRESHNESS_MS = 600_000; // accept paymentNonces issued within
|
|
51
|
+
// the last 10 minutes (or up to 1 min in the future — clock skew tolerance).
|
|
52
|
+
const NONCE_FUTURE_SKEW_MS = 60_000;
|
|
53
|
+
const BYTES32_REGEX = /^0x[0-9a-fA-F]{64}$/;
|
|
54
|
+
const ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
|
|
55
|
+
const SIGNATURE_REGEX = /^0x[0-9a-fA-F]{130}$/;
|
|
56
|
+
const POSITIVE_DECIMAL_INT_REGEX = /^[1-9]\d*$/;
|
|
57
|
+
const NON_NEGATIVE_DECIMAL_INT_REGEX = /^(0|[1-9]\d*)$/;
|
|
58
|
+
export async function buildChallenge(input) {
|
|
59
|
+
const now = input.now?.() ?? new Date();
|
|
60
|
+
const expiresAt = Math.floor(now.getTime() / 1000) + CHALLENGE_TTL_SECONDS;
|
|
61
|
+
const generateNonce = input.generateNonce ?? nextPaymentNonce;
|
|
62
|
+
const generateRecord = input.generateRecordIdFn ?? generateRecordId;
|
|
63
|
+
// The canary `totalDue` already accounts for paymentStatus (registration
|
|
64
|
+
// is omitted when grant.paymentStatus === 'paid'). SDK comment: "snapshot
|
|
65
|
+
// — clients shouldn't cache across requests", so the caller re-fetches.
|
|
66
|
+
const amount = input.grant.fee.totalDue;
|
|
67
|
+
const registrationOwed = input.grant.paymentStatus !== "paid";
|
|
68
|
+
const asset = input.grant.fee.asset;
|
|
69
|
+
let accessRecord;
|
|
70
|
+
if (input.serverSigner &&
|
|
71
|
+
input.serverOwner &&
|
|
72
|
+
input.entry &&
|
|
73
|
+
input.entry.dataPointId !== null) {
|
|
74
|
+
const recordId = generateRecord();
|
|
75
|
+
const version = BigInt(input.entry.version);
|
|
76
|
+
const signature = await input.serverSigner.signRecordDataAccess({
|
|
77
|
+
ownerAddress: input.serverOwner,
|
|
78
|
+
scope: input.entry.scope,
|
|
79
|
+
version,
|
|
80
|
+
accessor: input.builder,
|
|
81
|
+
recordId,
|
|
82
|
+
});
|
|
83
|
+
accessRecord = {
|
|
84
|
+
dataPointId: input.entry.dataPointId,
|
|
85
|
+
version: version.toString(),
|
|
86
|
+
accessor: input.builder,
|
|
87
|
+
recordId,
|
|
88
|
+
signature,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const message = {
|
|
92
|
+
payerAddress: input.builder,
|
|
93
|
+
opType: "grant",
|
|
94
|
+
opId: input.grantId,
|
|
95
|
+
asset,
|
|
96
|
+
amount,
|
|
97
|
+
paymentNonce: generateNonce().toString(),
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
x402Version: 1,
|
|
101
|
+
error: "PAYMENT_REQUIRED",
|
|
102
|
+
accepts: [
|
|
103
|
+
{
|
|
104
|
+
scheme: "vana-escrow-grant",
|
|
105
|
+
network: input.network,
|
|
106
|
+
asset,
|
|
107
|
+
amount,
|
|
108
|
+
domain: escrowPaymentDomain(input.gatewayConfig),
|
|
109
|
+
types: GENERIC_PAYMENT_TYPES,
|
|
110
|
+
message,
|
|
111
|
+
breakdown: {
|
|
112
|
+
registrationFee: registrationOwed
|
|
113
|
+
? input.grant.fee.registrationFee
|
|
114
|
+
: "0",
|
|
115
|
+
dataAccessFee: input.grant.fee.dataAccessFee,
|
|
116
|
+
registrationOwed,
|
|
117
|
+
},
|
|
118
|
+
...(accessRecord ? { accessRecord } : {}),
|
|
119
|
+
expiresAt,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// Decode base64 to UTF-8. Tolerates standard + url-safe alphabets so clients
|
|
125
|
+
// can use either. Uses the universally-available `atob` + Web text codecs
|
|
126
|
+
// rather than Node's Buffer so this module remains browser-safe (consumed
|
|
127
|
+
// by ps-lite as well as the Node server).
|
|
128
|
+
function base64decode(input) {
|
|
129
|
+
let s = input.replace(/-/g, "+").replace(/_/g, "/");
|
|
130
|
+
const pad = (4 - (s.length % 4)) % 4;
|
|
131
|
+
s += "=".repeat(pad);
|
|
132
|
+
const binString = atob(s);
|
|
133
|
+
const bytes = Uint8Array.from(binString, (c) => c.codePointAt(0) ?? 0);
|
|
134
|
+
return new TextDecoder().decode(bytes);
|
|
135
|
+
}
|
|
136
|
+
function base64encode(input) {
|
|
137
|
+
const bytes = new TextEncoder().encode(input);
|
|
138
|
+
let binString = "";
|
|
139
|
+
for (const b of bytes)
|
|
140
|
+
binString += String.fromCodePoint(b);
|
|
141
|
+
return btoa(binString);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Parse the X-PAYMENT header value. Returns `null` if missing/malformed —
|
|
145
|
+
* the caller should treat that as "no payment provided" and issue a 402.
|
|
146
|
+
*/
|
|
147
|
+
export function parsePaymentHeader(headerValue) {
|
|
148
|
+
if (!headerValue)
|
|
149
|
+
return null;
|
|
150
|
+
let decoded;
|
|
151
|
+
try {
|
|
152
|
+
decoded = base64decode(headerValue.trim());
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
let parsed;
|
|
158
|
+
try {
|
|
159
|
+
parsed = JSON.parse(decoded);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
if (!parsed || typeof parsed !== "object")
|
|
165
|
+
return null;
|
|
166
|
+
const obj = parsed;
|
|
167
|
+
if (obj["x402Version"] !== 1)
|
|
168
|
+
return null;
|
|
169
|
+
if (obj["scheme"] !== "vana-escrow-grant")
|
|
170
|
+
return null;
|
|
171
|
+
if (typeof obj["network"] !== "string")
|
|
172
|
+
return null;
|
|
173
|
+
const payload = obj["payload"];
|
|
174
|
+
if (!payload || typeof payload !== "object")
|
|
175
|
+
return null;
|
|
176
|
+
const p = payload;
|
|
177
|
+
const message = p["message"];
|
|
178
|
+
if (!message || typeof message !== "object")
|
|
179
|
+
return null;
|
|
180
|
+
const m = message;
|
|
181
|
+
if (typeof m["payerAddress"] !== "string" ||
|
|
182
|
+
!ADDRESS_REGEX.test(m["payerAddress"]) ||
|
|
183
|
+
typeof m["opType"] !== "string" ||
|
|
184
|
+
typeof m["opId"] !== "string" ||
|
|
185
|
+
!BYTES32_REGEX.test(m["opId"]) ||
|
|
186
|
+
typeof m["asset"] !== "string" ||
|
|
187
|
+
!ADDRESS_REGEX.test(m["asset"]) ||
|
|
188
|
+
typeof m["amount"] !== "string" ||
|
|
189
|
+
!NON_NEGATIVE_DECIMAL_INT_REGEX.test(m["amount"]) ||
|
|
190
|
+
typeof m["paymentNonce"] !== "string" ||
|
|
191
|
+
!POSITIVE_DECIMAL_INT_REGEX.test(m["paymentNonce"])) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
if (typeof p["signature"] !== "string" ||
|
|
195
|
+
!SIGNATURE_REGEX.test(p["signature"])) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
const accessRecordRaw = p["accessRecord"];
|
|
199
|
+
let accessRecord;
|
|
200
|
+
if (accessRecordRaw !== undefined) {
|
|
201
|
+
if (!accessRecordRaw || typeof accessRecordRaw !== "object")
|
|
202
|
+
return null;
|
|
203
|
+
const ar = accessRecordRaw;
|
|
204
|
+
if (typeof ar["dataPointId"] !== "string" ||
|
|
205
|
+
!BYTES32_REGEX.test(ar["dataPointId"]) ||
|
|
206
|
+
typeof ar["version"] !== "string" ||
|
|
207
|
+
!POSITIVE_DECIMAL_INT_REGEX.test(ar["version"]) ||
|
|
208
|
+
typeof ar["accessor"] !== "string" ||
|
|
209
|
+
!ADDRESS_REGEX.test(ar["accessor"]) ||
|
|
210
|
+
typeof ar["recordId"] !== "string" ||
|
|
211
|
+
!BYTES32_REGEX.test(ar["recordId"]) ||
|
|
212
|
+
typeof ar["signature"] !== "string" ||
|
|
213
|
+
!SIGNATURE_REGEX.test(ar["signature"])) {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
accessRecord = {
|
|
217
|
+
dataPointId: ar["dataPointId"],
|
|
218
|
+
version: ar["version"],
|
|
219
|
+
accessor: ar["accessor"],
|
|
220
|
+
recordId: ar["recordId"],
|
|
221
|
+
signature: ar["signature"],
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
return {
|
|
225
|
+
x402Version: 1,
|
|
226
|
+
scheme: "vana-escrow-grant",
|
|
227
|
+
network: obj["network"],
|
|
228
|
+
payload: {
|
|
229
|
+
message: {
|
|
230
|
+
payerAddress: m["payerAddress"],
|
|
231
|
+
opType: m["opType"],
|
|
232
|
+
opId: m["opId"],
|
|
233
|
+
asset: m["asset"],
|
|
234
|
+
amount: m["amount"],
|
|
235
|
+
paymentNonce: m["paymentNonce"],
|
|
236
|
+
},
|
|
237
|
+
signature: p["signature"],
|
|
238
|
+
...(accessRecord ? { accessRecord } : {}),
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Encode an X402Payment back to a base64 header value. Useful for client
|
|
244
|
+
* code (the personal server only decodes here; this is exported for tests
|
|
245
|
+
* and downstream builders that want a shared serializer).
|
|
246
|
+
*/
|
|
247
|
+
export function encodePaymentHeader(payment) {
|
|
248
|
+
return base64encode(JSON.stringify(payment));
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Validate a parsed X-PAYMENT against the live grant + entry state. On
|
|
252
|
+
* success the caller forwards the payment verbatim to the gateway. Any
|
|
253
|
+
* failure should result in a fresh 402 challenge.
|
|
254
|
+
*
|
|
255
|
+
* Replay defense is layered: gateway enforces per-(payer, opType, nonce)
|
|
256
|
+
* uniqueness via DB constraint and per-recordId uniqueness via the on-chain
|
|
257
|
+
* `_usedRecordIds` set. Local checks here catch obvious malformed echoes
|
|
258
|
+
* before they reach the gateway.
|
|
259
|
+
*/
|
|
260
|
+
export async function verifyPayment(input) {
|
|
261
|
+
const { payment, grant, builder } = input;
|
|
262
|
+
const msg = payment.payload.message;
|
|
263
|
+
// Builder identity: the payment must claim the authenticated signer.
|
|
264
|
+
// Recovery below cryptographically pins this.
|
|
265
|
+
if (msg.payerAddress.toLowerCase() !== builder.toLowerCase()) {
|
|
266
|
+
return {
|
|
267
|
+
ok: false,
|
|
268
|
+
reason: "payerAddress does not match authenticated builder",
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
if (msg.opType !== "grant") {
|
|
272
|
+
return { ok: false, reason: `Unsupported opType: ${msg.opType}` };
|
|
273
|
+
}
|
|
274
|
+
if (msg.opId.toLowerCase() !== input.grantId.toLowerCase()) {
|
|
275
|
+
return { ok: false, reason: "opId does not match the request's grantId" };
|
|
276
|
+
}
|
|
277
|
+
// Amount + asset must match the gateway's canonical values. Re-fetched
|
|
278
|
+
// per request, so a builder echoing stale amounts gets rejected here
|
|
279
|
+
// before we hit the gateway.
|
|
280
|
+
if (msg.asset.toLowerCase() !== grant.fee.asset.toLowerCase()) {
|
|
281
|
+
return { ok: false, reason: "asset does not match grant fee asset" };
|
|
282
|
+
}
|
|
283
|
+
if (msg.amount !== grant.fee.totalDue) {
|
|
284
|
+
return {
|
|
285
|
+
ok: false,
|
|
286
|
+
reason: `amount ${msg.amount} != grant.fee.totalDue ${grant.fee.totalDue}`,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
// Stateless freshness check: extract the issue-time from the high 32 bits
|
|
290
|
+
// of paymentNonce and require it within the last ~10 minutes. Cheap; no
|
|
291
|
+
// server state. Catches replays of captured X-PAYMENTs far in the past.
|
|
292
|
+
let nonceBig;
|
|
293
|
+
try {
|
|
294
|
+
nonceBig = BigInt(msg.paymentNonce);
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
return { ok: false, reason: "paymentNonce is not a valid uint256" };
|
|
298
|
+
}
|
|
299
|
+
const issueMs = paymentNonceIssueTimeMs(nonceBig);
|
|
300
|
+
const nowMs = BigInt(input.nowMs?.() ?? Date.now());
|
|
301
|
+
if (issueMs > nowMs + BigInt(NONCE_FUTURE_SKEW_MS)) {
|
|
302
|
+
return { ok: false, reason: "paymentNonce timestamp is in the future" };
|
|
303
|
+
}
|
|
304
|
+
if (nowMs - issueMs > BigInt(NONCE_FRESHNESS_MS)) {
|
|
305
|
+
return {
|
|
306
|
+
ok: false,
|
|
307
|
+
reason: "paymentNonce is older than the freshness window",
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
// GenericPayment signature recovery — must recover to the builder.
|
|
311
|
+
let recoveredPayer;
|
|
312
|
+
try {
|
|
313
|
+
recoveredPayer = await recoverTypedDataAddress({
|
|
314
|
+
domain: escrowPaymentDomain(input.gatewayConfig),
|
|
315
|
+
types: GENERIC_PAYMENT_TYPES,
|
|
316
|
+
primaryType: "GenericPayment",
|
|
317
|
+
message: {
|
|
318
|
+
payerAddress: msg.payerAddress,
|
|
319
|
+
opType: msg.opType,
|
|
320
|
+
opId: msg.opId,
|
|
321
|
+
asset: msg.asset,
|
|
322
|
+
amount: BigInt(msg.amount),
|
|
323
|
+
paymentNonce: nonceBig,
|
|
324
|
+
},
|
|
325
|
+
signature: payment.payload.signature,
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
catch {
|
|
329
|
+
return { ok: false, reason: "GenericPayment signature recovery failed" };
|
|
330
|
+
}
|
|
331
|
+
if (recoveredPayer.toLowerCase() !== builder.toLowerCase()) {
|
|
332
|
+
return {
|
|
333
|
+
ok: false,
|
|
334
|
+
reason: "GenericPayment signer does not match authenticated builder",
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
// AccessRecord echo (when present) — verify the server actually signed it
|
|
338
|
+
// and the binding fields match the entry being served.
|
|
339
|
+
if (payment.payload.accessRecord) {
|
|
340
|
+
const ar = payment.payload.accessRecord;
|
|
341
|
+
if (!input.entry) {
|
|
342
|
+
return {
|
|
343
|
+
ok: false,
|
|
344
|
+
reason: "accessRecord supplied but no entry to bind it to",
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
if (input.entry.dataPointId === null) {
|
|
348
|
+
return {
|
|
349
|
+
ok: false,
|
|
350
|
+
reason: "accessRecord supplied but entry has no dataPointId yet",
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
if (ar.dataPointId.toLowerCase() !== input.entry.dataPointId.toLowerCase()) {
|
|
354
|
+
return {
|
|
355
|
+
ok: false,
|
|
356
|
+
reason: "accessRecord.dataPointId does not match entry",
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
if (ar.version !== String(input.entry.version)) {
|
|
360
|
+
return { ok: false, reason: "accessRecord.version does not match entry" };
|
|
361
|
+
}
|
|
362
|
+
if (ar.accessor.toLowerCase() !== builder.toLowerCase()) {
|
|
363
|
+
return {
|
|
364
|
+
ok: false,
|
|
365
|
+
reason: "accessRecord.accessor does not match authenticated builder",
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (!input.serverOwner) {
|
|
369
|
+
return {
|
|
370
|
+
ok: false,
|
|
371
|
+
reason: "serverOwner required to verify accessRecord signature",
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
let recoveredServer;
|
|
375
|
+
try {
|
|
376
|
+
recoveredServer = await recoverTypedDataAddress({
|
|
377
|
+
domain: dataRegistryDomain(input.gatewayConfig),
|
|
378
|
+
types: RECORD_DATA_ACCESS_TYPES,
|
|
379
|
+
primaryType: "RecordDataAccess",
|
|
380
|
+
message: {
|
|
381
|
+
ownerAddress: input.serverOwner,
|
|
382
|
+
scope: input.entry.scope,
|
|
383
|
+
version: BigInt(ar.version),
|
|
384
|
+
accessor: ar.accessor,
|
|
385
|
+
recordId: ar.recordId,
|
|
386
|
+
},
|
|
387
|
+
signature: ar.signature,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
return { ok: false, reason: "accessRecord signature recovery failed" };
|
|
392
|
+
}
|
|
393
|
+
if (recoveredServer.toLowerCase() !== input.serverAddress.toLowerCase()) {
|
|
394
|
+
return {
|
|
395
|
+
ok: false,
|
|
396
|
+
reason: "accessRecord signer is not this personal server",
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return { ok: true, payment };
|
|
401
|
+
}
|
|
402
|
+
//# sourceMappingURL=x402.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x402.js","sourceRoot":"","sources":["../../src/payment/x402.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GatewayGrantResponse } from "@opendatalabs/vana-sdk/browser";
|
|
2
|
+
import { type AuthSessionVerifierPort, type GrantVerifierPort, type RuntimeAvailabilityPort } from "../ports/index.js";
|
|
3
|
+
export interface DataReadPolicyInput {
|
|
4
|
+
signer: `0x${string}`;
|
|
5
|
+
grantId?: string;
|
|
6
|
+
requestedScope: string;
|
|
7
|
+
fileId?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DataReadPolicyPorts {
|
|
10
|
+
authSessionVerifier: AuthSessionVerifierPort;
|
|
11
|
+
grantVerifier: GrantVerifierPort;
|
|
12
|
+
runtimeAvailability?: RuntimeAvailabilityPort;
|
|
13
|
+
}
|
|
14
|
+
export declare function verifyDataReadPolicy(input: DataReadPolicyInput, ports: DataReadPolicyPorts): Promise<GatewayGrantResponse>;
|
|
15
|
+
//# sourceMappingURL=data-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-read.d.ts","sourceRoot":"","sources":["../../src/policy/data-read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAW3E,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC7B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IAGvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,mBAAmB,EAAE,uBAAuB,CAAC;IAC7C,aAAa,EAAE,iBAAiB,CAAC;IAKjC,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;CAC/C;AAcD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CA4E/B"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { scopeCoveredByGrant } from "@opendatalabs/vana-sdk/browser";
|
|
2
|
+
import { GrantExpiredError, GrantRequiredError, GrantRevokedError, InvalidSignatureError, PsUnavailableError, ScopeMismatchError, UnregisteredBuilderError, } from "../errors/catalog.js";
|
|
3
|
+
function parseExpiresAtSeconds(value) {
|
|
4
|
+
if (value === null || value === undefined || value === "0")
|
|
5
|
+
return 0;
|
|
6
|
+
if (typeof value === "number")
|
|
7
|
+
return Number.isFinite(value) ? value : null;
|
|
8
|
+
if (typeof value !== "string")
|
|
9
|
+
return null;
|
|
10
|
+
const numeric = Number(value);
|
|
11
|
+
if (Number.isFinite(numeric))
|
|
12
|
+
return numeric;
|
|
13
|
+
const millis = Date.parse(value);
|
|
14
|
+
return Number.isNaN(millis) ? null : Math.floor(millis / 1000);
|
|
15
|
+
}
|
|
16
|
+
export async function verifyDataReadPolicy(input, ports) {
|
|
17
|
+
const available = await ports.runtimeAvailability?.isAvailable();
|
|
18
|
+
if (available === false) {
|
|
19
|
+
throw new PsUnavailableError();
|
|
20
|
+
}
|
|
21
|
+
const builder = await ports.authSessionVerifier.getBuilder(input.signer);
|
|
22
|
+
if (!builder) {
|
|
23
|
+
throw new UnregisteredBuilderError();
|
|
24
|
+
}
|
|
25
|
+
if (!input.grantId) {
|
|
26
|
+
throw new GrantRequiredError({
|
|
27
|
+
reason: "No grantId in authorization payload",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const grant = await ports.grantVerifier.getGrant(input.grantId);
|
|
31
|
+
if (!grant) {
|
|
32
|
+
throw new GrantRequiredError({
|
|
33
|
+
reason: "Grant not found",
|
|
34
|
+
grantId: input.grantId,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
if (grant.revokedAt !== null) {
|
|
38
|
+
throw new GrantRevokedError({ grantId: grant.id });
|
|
39
|
+
}
|
|
40
|
+
// Canary GatewayGrantResponse is flat — scopes is a top-level string[]
|
|
41
|
+
// and expiresAt is a decimal-string uint256 (`null` = perpetual). The
|
|
42
|
+
// legacy signed `grant` JSON blob and `fileIds` pinning are gone.
|
|
43
|
+
if (!grant.scopes || grant.scopes.length === 0) {
|
|
44
|
+
throw new ScopeMismatchError({
|
|
45
|
+
requestedScope: input.requestedScope,
|
|
46
|
+
reason: "Grant has no scopes",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (grant.expiresAt !== null && grant.expiresAt !== undefined) {
|
|
50
|
+
// DPv2 may surface either the legacy uint256-seconds string or the
|
|
51
|
+
// current gateway ISO timestamp. Parse both so the policy stays aligned
|
|
52
|
+
// with the gateway response shape.
|
|
53
|
+
const expiresAtSec = parseExpiresAtSeconds(grant.expiresAt);
|
|
54
|
+
if (expiresAtSec === null) {
|
|
55
|
+
throw new ScopeMismatchError({
|
|
56
|
+
requestedScope: input.requestedScope,
|
|
57
|
+
reason: "Grant expiry is invalid",
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (expiresAtSec > 0) {
|
|
61
|
+
const nowSec = Math.floor(Date.now() / 1000);
|
|
62
|
+
if (expiresAtSec < nowSec) {
|
|
63
|
+
throw new GrantExpiredError({
|
|
64
|
+
expiresAt: expiresAtSec,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (!scopeCoveredByGrant(input.requestedScope, grant.scopes)) {
|
|
70
|
+
throw new ScopeMismatchError({
|
|
71
|
+
requestedScope: input.requestedScope,
|
|
72
|
+
grantedScopes: grant.scopes,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (builder.id.toLowerCase() !== grant.granteeId.toLowerCase()) {
|
|
76
|
+
throw new InvalidSignatureError({
|
|
77
|
+
reason: "Request signer is not the grant builder",
|
|
78
|
+
expected: grant.granteeId,
|
|
79
|
+
actual: input.signer,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return grant;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=data-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-read.js","sourceRoot":"","sources":["../../src/policy/data-read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/policy/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,GAGrB,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Builder, DataFileEnvelope, DataPointListResult, DataPointRecord, GatewayGrantResponse, ListDataPointsOptions, Schema, ServerInfo } from "@opendatalabs/vana-sdk/browser";
|
|
2
|
+
import type { WriteResult } from "../storage/hierarchy/index.js";
|
|
3
|
+
import type { DataBlockManifest, DataScopeBlock, ReadScopeBlocksResponse } from "../storage/blocks/index.js";
|
|
4
|
+
import type { IndexEntry, NewIndexEntry, ScopeSummary } from "../storage/index/types.js";
|
|
5
|
+
export interface ProtocolGatewayPort {
|
|
6
|
+
getBuilder(address: string): Promise<Builder | null>;
|
|
7
|
+
getGrant(grantId: string): Promise<GatewayGrantResponse | null>;
|
|
8
|
+
getSchemaForScope(scope: string): Promise<Schema | null>;
|
|
9
|
+
getServer(address: string): Promise<ServerInfo | null>;
|
|
10
|
+
getDataPoint(dataPointId: string): Promise<DataPointRecord | null>;
|
|
11
|
+
listDataPointsByOwner(owner: string, cursor: string | null, options?: ListDataPointsOptions): Promise<DataPointListResult>;
|
|
12
|
+
}
|
|
13
|
+
export interface GrantVerifierPort {
|
|
14
|
+
getGrant(grantId: string): Promise<GatewayGrantResponse | null>;
|
|
15
|
+
}
|
|
16
|
+
export interface AuthSessionVerifierPort {
|
|
17
|
+
getBuilder(address: string): Promise<Builder | null>;
|
|
18
|
+
}
|
|
19
|
+
export interface FileRegistrySyncRegistryPort {
|
|
20
|
+
getDataPoint(dataPointId: string): Promise<DataPointRecord | null>;
|
|
21
|
+
listDataPointsByOwner(owner: string, cursor: string | null, options?: ListDataPointsOptions): Promise<DataPointListResult>;
|
|
22
|
+
}
|
|
23
|
+
export interface PlatformCryptoPort {
|
|
24
|
+
randomBytes(length: number): Uint8Array;
|
|
25
|
+
}
|
|
26
|
+
export interface RuntimeStoragePort {
|
|
27
|
+
kind: "node-fs-sqlite" | "browser-indexeddb-opfs" | "custom";
|
|
28
|
+
}
|
|
29
|
+
export interface DataStorageListOptions {
|
|
30
|
+
limit?: number;
|
|
31
|
+
offset?: number;
|
|
32
|
+
}
|
|
33
|
+
export interface DataStorageScopeListOptions extends DataStorageListOptions {
|
|
34
|
+
scopePrefix?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface DataStorageEntryLookup {
|
|
37
|
+
scope: string;
|
|
38
|
+
fileId?: string;
|
|
39
|
+
at?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface DataStorageEnvelopePreview {
|
|
42
|
+
text: string;
|
|
43
|
+
truncated: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface DataStoragePort extends RuntimeStoragePort {
|
|
46
|
+
listScopes(options: DataStorageScopeListOptions): {
|
|
47
|
+
scopes: ScopeSummary[];
|
|
48
|
+
total: number;
|
|
49
|
+
};
|
|
50
|
+
listVersions(scope: string, options: DataStorageListOptions): IndexEntry[];
|
|
51
|
+
countVersions(scope: string): number;
|
|
52
|
+
findEntry(lookup: DataStorageEntryLookup): IndexEntry | undefined;
|
|
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;
|
|
56
|
+
findUnsynced(options?: {
|
|
57
|
+
limit?: number;
|
|
58
|
+
}): IndexEntry[];
|
|
59
|
+
readEnvelope(scope: string, collectedAt: string): Promise<DataFileEnvelope>;
|
|
60
|
+
readEnvelopePreview?(scope: string, collectedAt: string, options: {
|
|
61
|
+
maxBytes: number;
|
|
62
|
+
}): Promise<DataStorageEnvelopePreview>;
|
|
63
|
+
readScopeBlocks?(scope: string, collectedAt: string, options: {
|
|
64
|
+
cursor?: string;
|
|
65
|
+
maxBytes: number;
|
|
66
|
+
}): Promise<ReadScopeBlocksResponse>;
|
|
67
|
+
hasScopeBlocks?(scope: string, collectedAt: string): boolean | Promise<boolean>;
|
|
68
|
+
canReadScopeBlocks?(scope: string, collectedAt: string): boolean | Promise<boolean>;
|
|
69
|
+
writeEnvelope(envelope: DataFileEnvelope): Promise<WriteResult>;
|
|
70
|
+
writeBlockManifest?(scope: string, collectedAt: string, manifest: DataBlockManifest, blocks: DataScopeBlock[]): Promise<void>;
|
|
71
|
+
insertEntry(entry: NewIndexEntry): IndexEntry | Promise<IndexEntry>;
|
|
72
|
+
updateFileId(path: string, fileId: string): boolean | Promise<boolean>;
|
|
73
|
+
/** Highest stored DPv2 `version` for a scope; 0 if none. */
|
|
74
|
+
findLatestVersionByScope(scope: string): number | Promise<number>;
|
|
75
|
+
/** Stamps the DPv2 dataPointId on an entry after registerDataPoint. */
|
|
76
|
+
updateDataPointId(path: string, dataPointId: string): boolean | Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Rewrites the DPv2 `version` on an entry. Used when the upload worker
|
|
79
|
+
* rebases a registration onto the registry's live version after a
|
|
80
|
+
* stale-expectedVersion conflict — the blob key embeds the version, so
|
|
81
|
+
* the local row must follow the registered one.
|
|
82
|
+
*/
|
|
83
|
+
updateEntryVersion(path: string, version: number): boolean | Promise<boolean>;
|
|
84
|
+
deleteScope(scope: string): Promise<number>;
|
|
85
|
+
/**
|
|
86
|
+
* Delete a single version (index entry + its local blob) by its gateway fileId.
|
|
87
|
+
* Returns true if a local copy existed and was removed, false if none was present (no-op).
|
|
88
|
+
* Used by sync delete-reconciliation to drop a copy the gateway reports as deleted.
|
|
89
|
+
*/
|
|
90
|
+
deleteByFileId(fileId: string): Promise<boolean>;
|
|
91
|
+
}
|
|
92
|
+
export interface RuntimeAvailabilityPort {
|
|
93
|
+
isAvailable(): boolean | Promise<boolean>;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ports/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,MAAM,EACN,UAAU,EACX,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,YAAY,EACb,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,mBAAmB;IAClC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;IAChE,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACvD,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACnE,qBAAqB,CACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,4BAA4B;IAC3C,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACnE,qBAAqB,CACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CAAC;CACzC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,gBAAgB,GAAG,wBAAwB,GAAG,QAAQ,CAAC;CAC9D;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,2BAA4B,SAAQ,sBAAsB;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,kBAAkB;IACzD,UAAU,CAAC,OAAO,EAAE,2BAA2B,GAAG;QAChD,MAAM,EAAE,YAAY,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,UAAU,EAAE,CAAC;IAC3E,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,SAAS,CAAC,MAAM,EAAE,sBAAsB,GAAG,UAAU,GAAG,SAAS,CAAC;IAClE,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACrD,qFAAqF;IACrF,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC/D,YAAY,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,EAAE,CAAC;IACzD,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC5E,mBAAmB,CAAC,CAClB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAC5B,OAAO,CAAC,0BAA0B,CAAC,CAAC;IACvC,eAAe,CAAC,CACd,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAC7C,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACpC,cAAc,CAAC,CACb,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,kBAAkB,CAAC,CACjB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAChE,kBAAkB,CAAC,CACjB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,MAAM,EAAE,cAAc,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACpE,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvE,4DAA4D;IAC5D,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAClE,uEAAuE;IACvE,iBAAiB,CACf,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B;;;;;OAKG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9E,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,uBAAuB;IACtC,WAAW,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3C"}
|