/** * Builder-side client for encrypted Gateway jobs. * * @remarks * This Node-only client fetches an owner's sealed enclave identity, signs and * seals raw-read work, submits it to the Gateway, polls builder-visible state, * and decrypts the bound result with the builder private key. * * @category Protocol */ import { type Address, type Hex, type LocalAccount } from "viem"; import type { ECIESProvider } from "../crypto/ecies/interface.js"; import { type JobResult, type JobState, type JobQuote, type JobStatus, type ResultHandle } from "./jobs.js"; import { type WriteSignerSource } from "./write-signer.js"; /** A viem local account that exposes the public key required by job requests. */ export type JobsBuilderAccount = Extract; /** Configuration captured by {@link createJobsClient}. */ export interface JobsClientOptions { /** Gateway base URL; its origin is the Web3Signed audience. */ gatewayUrl: string; /** Vana chain ID used by the owner identity lookup. */ chainId: number; /** Raw builder private key, used for signing and result decryption. */ builderPrivateKey?: Hex; /** * viem local account used for signing. Its public key supports submission, * but without `builderPrivateKey` this client cannot decrypt results: * `openResult` and `readRaw` reject while submit/status/wait remain usable. */ builderAccount?: JobsBuilderAccount; /** HTTP implementation; defaults to `globalThis.fetch`. */ fetch?: typeof fetch; /** ECIES implementation; defaults to the Node provider. */ ecies?: ECIESProvider; /** Clock used when constructing a job deadline. */ now?: () => Date; /** * `DataPortabilityEscrow` address for the payment signature's EIP-712 domain. * Defaults to the deployment this SDK ships for `chainId`; override only when * pointing at a non-canonical escrow. */ escrowContract?: Address; } /** Parameters for one encrypted raw-read submission. */ export interface SubmitRawReadParams { /** Owner whose enclave executes the read. */ owner: Address; /** Owner-issued builder grant. */ grantId: Hex; /** Data scope to read. */ scope: string; /** Exact record version to require, or `null` for an unpinned read. */ pinnedVersion?: string | null; /** Requested deadline offset, clamped to the protocol maximum. */ deadlineSeconds?: number; /** Gateway inline-wait seconds, clamped to `0..MAX_WAIT_SECONDS`. */ wait?: number; /** * The most this read may cost, uint256 decimal. A quote above it is refused * before anything is signed. Omit to accept whatever the chain's FeeRegistry * says at submission time. */ maxPrice?: string; /** * Reuse a job id across attempts instead of minting one. * * @remarks * A charged read reserves escrow when the Gateway first accepts the job, so a * response lost in transit is ambiguous: retrying with a fresh id would * reserve a second time. Supply the id (and {@link idempotencyKey}) from * durable storage and a resubmission replays the original job and reserves * nothing. `JobTransportError.details` carries both back when a submission * fails mid-flight. */ jobId?: string; idempotencyKey?: string; } /** Result of submitting an encrypted raw-read job. */ export interface SubmitRawReadResult { /** Client-generated job UUID. */ jobId: string; /** Current Gateway state. */ state: JobState; /** Full status when the Gateway returned an inline 200 response. */ job?: JobStatus; } /** Polling controls for {@link JobsClient.waitForJob}. */ export interface WaitForJobOptions { /** Total polling budget in milliseconds. */ timeoutMs?: number; /** Delay between reads; values below `CLAIM_POLL_FLOOR_MS` are raised. */ pollMs?: number; } /** Expected plaintext bindings for {@link JobsClient.openResult}. */ export interface OpenJobResultOptions { /** Bind the plaintext to this job id. */ expect: { jobId: string; scope?: string; version?: string | null; }; } /** Parameters for the submit, wait, and decrypt convenience flow. */ export interface ReadRawParams extends SubmitRawReadParams, WaitForJobOptions { } /** Builder operations exposed by {@link createJobsClient}. */ export interface JobsClient { /** * Encrypt and submit a raw-read job. * * @param params - Owner, grant, scope, deadline, and inline-wait controls. * @returns The job id and current state, plus inline status on HTTP 200. * @throws {OwnerNotReadyError} When the owner identity is not sealed. * @throws {JobsClientError} When the Gateway or transport rejects the call. */ submitRawRead(params: SubmitRawReadParams): Promise; /** * Ask what one read costs on this chain before committing to it. * * @returns The chain's `data_access` fee, its asset, and whether the Gateway * enforces it today. * @throws {JobsClientError} When the Gateway or transport rejects the call. * * @remarks * Optional: {@link JobsClient.submitRawRead} signs the quote the Gateway * returns with its 402, so a builder that does not care about the price ahead * of time never needs this call. */ quoteJob(): Promise; /** * Read one builder-visible job status. * * @param jobId - Client-generated job UUID. * @returns The current job status. * @throws {JobNotFoundError} When the job is absent or belongs to another builder. * @throws {JobsClientError} For other Gateway or transport failures. */ getJob(jobId: string): Promise; /** * Poll until a job completes, fails, expires, or is cancelled. * * @param jobId - Job UUID to poll. * @param options - Timeout and poll cadence. * @returns The terminal job status. * @throws {JobTimeoutError} When the caller or job deadline is exhausted. */ waitForJob(jobId: string, options?: WaitForJobOptions): Promise; /** * Fetch, decrypt, and validate a job result from object storage. * * @param handle - Object-storage location and integrity metadata. * @param options - Expected plaintext job, scope, and version bindings. * @returns The validated plaintext job result. * @remarks Decryption requires `builderPrivateKey`; `builderAccount` alone * only supports submission, status reads, and waiting. * @throws {JobRejectedError} When a raw private key is unavailable. * @throws {JobTransportError} When fetching the result object fails. * @throws {JobResultIntegrityError} When the fetched bytes mismatch the handle. * @throws {JobEnvelopeError} When decrypted protocol fields or bindings differ. */ openResult(handle: ResultHandle, options: OpenJobResultOptions): Promise; /** * Submit, wait for, and decrypt one raw read. * * @param params - Raw-read request plus polling controls. * @returns The decrypted, binding-checked job result. * @remarks This convenience flow decrypts the result and therefore requires * `builderPrivateKey`; a client configured only with `builderAccount` * cannot call `readRaw`. * @throws {JobsClientError} When submission, polling, or decryption setup fails. * @throws {JobEnvelopeError} When decrypted result bindings differ. * * @example * ```typescript * const result = await client.readRaw({ * owner, * grantId, * scope: "profile.email", * wait: 25, * }); * ``` */ readRaw(params: ReadRawParams): Promise; } /** * Create a reusable Node builder client for encrypted Gateway jobs. * * @param options - Gateway, chain, builder signer, and injectable adapters. * @returns A client bound to the configured builder and Gateway. * @throws {JobRejectedError} When configuration or signer shape is invalid. * * @remarks * This client is Node-only. `builderPrivateKey` supports the complete flow; * `builderAccount` alone supports submit/status/wait but cannot decrypt, so * `openResult` and `readRaw` require the raw private key. * * @example * ```typescript * const client = createJobsClient({ * gatewayUrl: "https://gateway.example.com", * chainId: 14800, * builderPrivateKey: process.env.BUILDER_PRIVATE_KEY as Hex, * }); * const result = await client.readRaw({ owner, grantId, scope: "profile" }); * ``` */ export declare function createJobsClient(options: JobsClientOptions): JobsClient;