/** * Derivative lineage: which data points a record was derived from, and which * records were derived from it. * * @remarks * A data point is addressed by `keccak256(abi.encode(address owner, string * scope))` ({@link deriveDataPointId}). A builder writing a derivative names * its sources through the `lineage` option of {@link writeData}; the Personal * Server stores them under the reserved `$lineage` key and both the Personal * Server (`GET /v1/data/:scope/lineage[/:version]`) and the gateway * (`GET /v1/data/:dataPointId/lineage[/:version]`) answer the resulting view. * Nodes the caller holds no grant for come back as exactly * `{ redacted: true }`: no id, scope or version, because the id is * `keccak256(owner, scope)` and a grantee who knows the owner could recover * the scope from it with a small dictionary. Order and count are preserved, * so a redacted node is still identified by its position. A source that no * longer resolves comes back with `version: "0"`. * * A derived scope must not share its first dot-segment with any source scope * (a grant on `chatgpt.*` must never read a derivative of * `chatgpt.conversations`): see {@link assertDerivedScopeNaming}. * * @category Protocol */ import { type Address, type Hex } from "viem"; import { z } from "zod"; import { type ResolveWriteSignerOptions, type WriteSignerSource } from "./write-signer.js"; /** `true` when `value` is a 32-byte hex data point id. */ export declare function isDataPointId(value: unknown): value is Hex; /** * Derive the DataRegistryV2 data point id for an owner and scope: * `keccak256(abi.encode(address ownerAddress, string scope))`. * * @param ownerAddress - The data owner (the Personal Server owner). * @param scope - The scope the data point is stored under. * @returns The 32-byte id, lowercase hex. * @throws Error when `ownerAddress` is not an EVM address. */ export declare function deriveDataPointId(ownerAddress: Address, scope: string): Hex; /** First dot-segment of a scope (`chatgpt` for `chatgpt.conversations`). */ export declare function scopeNamespace(scope: string): string; /** * The naming rule: a derived scope and a source scope must not share their * first dot-segment, because a `prefix.*` grant would then cover both and * leak across the lineage edge. Mirrors the Personal Server's check * (`LINEAGE_SCOPE_UNDER_SOURCE_PREFIX`). */ export declare function derivedScopeViolatesNaming(derivedScope: string, sourceScope: string): boolean; /** * Throw when `derivedScope` shares its first dot-segment with any source * scope (see {@link derivedScopeViolatesNaming}). * * @throws {WriteRequestError} Naming the offending source scope in `details`. */ export declare function assertDerivedScopeNaming(derivedScope: string, sourceScopes: readonly string[]): void; export declare const LineageNodeSchema: z.ZodObject<{ dataPointId: z.ZodPipe>; scope: z.ZodString; version: z.ZodPipe, z.ZodTransform>; deletedAt: z.ZodNullable; redacted: z.ZodOptional; }, z.core.$strip>; /** * A redacted node is exactly `{ redacted: true }`. Any other key on it would * leak what the redaction hides, so the schema is strict: a view carrying a * redacted node with an id (or anything else) is refused rather than passed * through. */ export declare const RedactedLineageNodeSchema: z.ZodObject<{ redacted: z.ZodLiteral; }, z.core.$strict>; export declare const LineageEntrySchema: z.ZodUnion; }, z.core.$strict>, z.ZodObject<{ dataPointId: z.ZodPipe>; scope: z.ZodString; version: z.ZodPipe, z.ZodTransform>; deletedAt: z.ZodNullable; redacted: z.ZodOptional; }, z.core.$strip>]>; export declare const LineageGraphSchema: z.ZodObject<{ dataPointId: z.ZodPipe>; ownerAddress: z.ZodOptional; scope: z.ZodString; version: z.ZodPipe, z.ZodTransform>; deletedAt: z.ZodNullable; sources: z.ZodArray; }, z.core.$strict>, z.ZodObject<{ dataPointId: z.ZodPipe>; scope: z.ZodString; version: z.ZodPipe, z.ZodTransform>; deletedAt: z.ZodNullable; redacted: z.ZodOptional; }, z.core.$strip>]>>; derivatives: z.ZodArray; }, z.core.$strict>, z.ZodObject<{ dataPointId: z.ZodPipe>; scope: z.ZodString; version: z.ZodPipe, z.ZodTransform>; deletedAt: z.ZodNullable; redacted: z.ZodOptional; }, z.core.$strip>]>>; derivativesTruncated: z.ZodOptional; }, z.core.$strip>; /** A lineage node the caller is allowed to see. */ export type LineageNode = z.infer; /** A lineage node the caller holds no grant for: nothing but its position. */ export type RedactedLineageNode = z.infer; /** One entry of a lineage graph. Narrow with {@link isRedactedLineageNode}. */ export type LineageEntry = z.infer; /** The lineage view of one data point (the `data` of the response). */ export type LineageGraph = z.infer; /** A lineage read: the view plus the gateway's attestation over it. */ export interface LineageReadResult extends LineageGraph { /** * The gateway `proof` (`GatewayAttestation` over the served view, so a * redacted view verifies on its own). Passed through as received; absent * when the server sent none. */ proof?: Record; } /** `true` when the entry was redacted (the caller holds no grant for it). */ export declare function isRedactedLineageNode(entry: LineageEntry): entry is RedactedLineageNode; /** * The Personal Server lineage path: `/v1/data/:scope/lineage[/:version]`. * The version is a path segment (a query string is refused by the server), * so the signed `uri` covers the whole request. */ export declare function personalServerLineagePath(scope: string, version?: string | number): string; /** * The gateway lineage path: `/v1/data//lineage[/:version]`, * what the request is signed over and sent to. The grant view is the signed * `grantId` claim, never a query parameter. */ export declare function gatewayLineagePath(dataPointId: Hex, version?: string | number): string; interface LineageRequestOptions { /** * Read the lineage as of this version (a positive decimal integer); * omitted = the current version, or the last version that carried lineage * when the current one is a tombstone. */ version?: string | number; /** `fetch` to use; defaults to `globalThis.fetch`. */ fetch?: typeof fetch; /** Extra request headers. */ headers?: HeadersInit; } /** Lineage read against the Personal Server holding the record. */ export interface PersonalServerLineageParams extends LineageRequestOptions { /** Personal Server origin, e.g. `https://ps.example.com`. */ personalServerUrl: string; /** The scope whose lineage to read. */ scope: string; /** A grant covering the scope, sent as the signed `grantId` claim. */ grantId: string; /** Builder key: a viem `LocalAccount`, `WalletClient`, or `{ signMessage }`. */ signer: WriteSignerSource; /** Account for a viem wallet client without a hoisted account. */ account?: ResolveWriteSignerOptions["account"]; /** Web3Signed audience; defaults to `personalServerUrl`. */ audience?: string; } /** Lineage read against the gateway, by data point id. */ export interface GatewayLineageParams extends LineageRequestOptions { /** Gateway origin, e.g. `https://dp-rpc.vana.org`. */ gatewayUrl: string; /** The data point whose lineage to read (see {@link deriveDataPointId}). */ dataPointId: Hex; /** * The key the request is signed with (Web3Signed, audience = the gateway * origin). The signer decides the view: the owner or one of its servers * gets the full view; a registered builder holding a live grant covering * the data point's scope gets that grant's view; anyone else is refused. */ signer: WriteSignerSource; /** Account for a viem wallet client without a hoisted account. */ account?: ResolveWriteSignerOptions["account"]; /** * The grant whose view to read, sent lowercased as the signed `grantId` * claim (never as a query parameter). An owner or server uses it to fetch * the view a builder's grant sees; a builder needs it to see anything. */ grantId?: string; } export type GetLineageParams = PersonalServerLineageParams | GatewayLineageParams; /** * Read a scope's lineage from the Personal Server that stores it. * * @remarks * Sends `GET /v1/data/:scope/lineage[/:version]` with a Web3Signed * `Authorization` header carrying `grantId`, the same authentication a data * read uses; the signed `uri` is the full path, version segment included. * The server resolves the data point id, fetches the view the grant sees * from the gateway and returns the gateway's `data` + `proof`. * * @returns The lineage view, with redacted entries for nodes the grant does * not cover, plus the gateway attestation. * @throws {LineageReadError} On a non-2xx answer (`errorCode`: read errors, * `INVALID_VERSION`, `NOT_FOUND` when the scope or version is not * registered at the gateway, `LINEAGE_FORBIDDEN`, `LINEAGE_GATEWAY_ERROR`, * `LINEAGE_UNAVAILABLE`), an unreadable body, a bad `version`, or a * transport failure. */ export declare function getPersonalServerLineage(params: PersonalServerLineageParams): Promise; /** * Read a data point's lineage from the gateway. * * @remarks * Sends `GET /v1/data/:dataPointId/lineage[/:version]` with a Web3Signed * `Authorization` header: `aud` = the gateway origin, `uri` = * {@link gatewayLineagePath} (lowercase id, version segment included), * empty-body `bodyHash`, and the lowercased `grantId` claim when given. The * gateway answers a uniform 404 for an unknown data point and for a signer * it will not serve, so the two cannot be told apart from outside. * * @returns The lineage view, with redacted entries for nodes the caller's * grant does not cover, plus the gateway attestation. * @throws {LineageReadError} On a malformed `dataPointId` or `version`, a * non-2xx answer (400 malformed request, 401 `LINEAGE_SIGNATURE_REQUIRED` * / `LINEAGE_SIGNATURE_INVALID`, 404 unknown or not served), an unreadable * body, or a transport failure. */ export declare function getGatewayLineage(params: GatewayLineageParams): Promise; /** * Read a lineage view from either the Personal Server (by scope) or the * gateway (by data point id), chosen by the params shape. * * @example * ```typescript * const fromPs = await getLineage({ personalServerUrl, scope, grantId, signer }); * const fromGateway = await getLineage({ gatewayUrl, dataPointId, grantId, signer }); * ``` */ export declare function getLineage(params: GetLineageParams): Promise; export {};