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