import { Account, Address, Chain, Abi, WalletClient, Transport, createPublicClient, ContractFunctionName, ContractFunctionArgs, ReadContractReturnType, Hash, Hex } from 'viem'; import { Z as ZeroValueAuthorization, E as EnvResolver, G as GateMiddleware, P as PricingEntry, V as Verifiability, A as Attestation, R as ReproducibleBuild, M as ManifestDefinition, T as ToolManifest, a as Access } from './index-B7CotPs_.js'; export { b as AccessRequirement, c as AccessRequirementSchema, d as AccessSchema, e as AttestationSchema, f as Eip3009UsageReporterConfig, I as InvocationEvent, g as PricingEntrySchema, h as ReproducibleBuildSchema, S as SignZeroValueAuthorizationParams, i as ToolContext, j as ToolHandlerConfig, k as ToolManifestSchema, l as VerifiabilitySchema, m as createEip3009UsageReporter, n as createToolHandler, o as defineManifest, p as findBareExtensionKeys, r as resolveManifest, s as signZeroValueAuthorization, v as validateManifest } from './index-B7CotPs_.js'; import { WalletAdapter } from '@opensea/wallet-adapters'; export { BankrAdapter, FireblocksAdapter, PrivateKeyAdapter, PrivyAdapter, PrivySvmAdapter, SvmTransactionRequest, SvmWalletAdapter, TransactionRequest, TransactionResult, TurnkeyAdapter, WALLET_PROVIDERS, WalletAdapter, WalletCapabilities, WalletProvider, WalletSelector, createWalletForProvider, createWalletFromEnv } from '@opensea/wallet-adapters'; import 'zod/v4'; type WebHandler$1 = (request: Request) => Response | Promise; interface ExpressRequest { method: string; url: string; headers: Record; hostname: string; protocol: string; body?: unknown; [key: string]: unknown; } interface ExpressResponse { status(code: number): ExpressResponse; set(name: string, value: string): ExpressResponse; json(body: unknown): void; send(body: string | Buffer): void; end(): void; [key: string]: unknown; } declare function toExpressHandler(handler: WebHandler$1): (req: ExpressRequest, res: ExpressResponse) => void; type WebHandler = (request: Request) => Response | Promise; interface VercelRequest { method: string; url?: string; headers: Record; body?: unknown; rawBody?: Buffer; [key: string]: unknown; } interface VercelResponse { status(code: number): VercelResponse; setHeader(name: string, value: string): VercelResponse; json(body: unknown): void; send(body: string | Buffer): void; end(): void; [key: string]: unknown; } declare function toVercelHandler(handler: WebHandler): (req: VercelRequest, res: VercelResponse) => Promise; interface Eip3009AuthenticatedFetchOptions extends RequestInit { account: Account; /** Restrict which `payTo` addresses the client will sign for. */ allowedRecipients?: string[]; } /** * Encode a `ZeroValueAuthorization` as an `Authorization: EIP-3009 ` * header value. The payload is base64url-encoded JSON for consistency with * the SIWE auth scheme. */ declare function createEip3009AuthHeader(authorization: ZeroValueAuthorization): string; /** * Fetch wrapper for predicate-gated tools. Sends the request; on 402, * signs an `X-Payment` header (zero-value EIP-3009 `TransferWithAuthorization`) * using the advertised `payTo` and retries once. Before signing a zero-value * challenge, it verifies that `payTo` binds the final endpoint URL to the * advertised tool ID and operator. Same-origin redirects are allowed; * cross-origin redirects fail before signing. * * This is an identity-only flow: the signed authorization always has * `value: 0`, so no USDC can move. If the challenge requests a non-zero * amount, nothing is signed and the 402 response is returned as-is — use * `paidFetch` or `paidAuthenticatedFetch` for endpoints that require real * payment. * * The challenge's `asset` must be the canonical USDC contract for a * supported network. Signing over an arbitrary verifying contract is * refused (throws), since a non-USDC contract could assign different * semantics to a zero-value `TransferWithAuthorization`. */ declare function eip3009AuthenticatedFetch(url: string, options: Eip3009AuthenticatedFetchOptions): Promise; /** * Wrap an external signing function into a viem-compatible {@link Account}. * * This lets agent wallets (Bankr, MPC, HSM) that sign via HTTP API work with * {@link authenticatedFetch} and any other viem consumer without requiring a * local private key. */ declare function createExternalSignerAccount(params: { address: Address; signMessage: (message: string) => Promise<`0x${string}`>; signTypedData?: (typedData: unknown) => Promise<`0x${string}`>; }): Account; /** * Create a viem Account backed by the Bankr wallet HTTP API. * Fetches the signer address from `/wallet/me` and signs via `/wallet/sign`. */ declare function createBankrAccount(apiKey: string): Promise; /** * Configuration for caller-side usage reporting. Unlike the server-side * reporters, this identifies the tool by its canonical endpoint URL — the * backend resolves the onchain registry coordinates automatically. */ interface CallerUsageReporterConfig { /** * URL of the OpenSea usage endpoint. * Defaults to `https://api.opensea.io/api/v2/tools/usage`. */ aggregatorUrl?: string; /** * API key sent as `x-api-key` header. When omitted the reporter * auto-provisions an instant API key via `POST /api/v2/auth/keys`. */ apiKey?: string; /** * Request timeout in milliseconds. Defaults to 5000. */ timeoutMs?: number; } /** * Outcome of a caller-side usage report. The reporters never throw; they * return one of these so callers (e.g. the `pay` CLI) can surface an accurate * status instead of assuming success. * * - `reported` — the aggregator accepted the report. * - `already-reported` — the tool's own server-side reporter recorded this * settlement first; the usage is counted, the caller's report was a duplicate. * - `skipped` — nothing was sent (failed validation, no API key, insecure URL). * - `failed` — sent but rejected, or a network/timeout error. */ type CallerUsageReportOutcome = "reported" | "already-reported" | "skipped" | "failed"; interface CallerUsageReportResult { outcome: CallerUsageReportOutcome; /** Human-readable detail, present for `skipped` and `failed`. */ detail?: string; } interface CallerX402UsageEvent { /** The tool's canonical endpoint URL (used for server-side lookup). */ toolEndpoint: string; /** Address of the caller who paid. */ callerAddress: `0x${string}`; /** Onchain settlement transaction hash. */ txHash: string; /** Chain where the settlement tx occurred. */ chainId: number; /** Tool invocation latency in milliseconds. */ latencyMs?: number; /** * ERC-8257 composite key identifying the tool onchain. Provide ALL THREE to * disambiguate when several tools are registered to the same endpoint URL — * the aggregator rejects an endpoint-only report with 400 in that case. When * present, these are sent in place of `toolEndpoint`, matching the * server-side reporter's payload. */ toolChainId?: number; toolRegistryAddress?: string; toolOnchainId?: number | string; } interface CallerEip3009UsageEvent { /** The tool's canonical endpoint URL (used for server-side lookup). */ toolEndpoint: string; /** Caller wallet address. */ callerAddress: `0x${string}`; /** EIP-3009 signature. */ signature: `0x${string}`; /** Chain ID the authorization was signed for. */ chainId: number; from: `0x${string}`; to: `0x${string}`; value: string; validAfter: string; validBefore: string; nonce: string; /** Tool invocation latency in milliseconds. */ latencyMs?: number; } /** * Reports an x402 settlement as a caller. Identifies the tool by endpoint URL * so the caller doesn't need onchain registry coordinates. Auto-provisions an * instant API key if none is configured. */ declare function reportCallerX402Usage(event: CallerX402UsageEvent, config?: CallerUsageReporterConfig): Promise; /** * Reports an EIP-3009 authorization as a caller. Identifies the tool by * endpoint URL. Auto-provisions an instant API key if none is configured. * * SECURITY: the payload contains a complete, replayable * `transferWithAuthorization` (signature plus from/to/value/nonce/validAfter/ * validBefore). Only call this AFTER the authorization is consumed onchain, or * for the zero-value identity authorizations used by predicate gates. * Reporting a non-zero authorization whose nonce is not yet consumed exposes it * to front-running if the aggregator endpoint is compromised. The aggregator * URL is required to be https for the same reason. */ declare function reportCallerEip3009Usage(event: CallerEip3009UsageEvent, config?: CallerUsageReporterConfig): Promise; interface PaidAuthenticatedFetchOptions extends RequestInit { account: Account; signer?: WalletAdapter | Account; /** @deprecated Ignored — EIP-3009 does not use expiration minutes. */ expirationMinutes?: number; maxAmount?: string; allowedRecipients?: string[]; allowedAssets?: string[]; /** * When set, sends a fire-and-forget caller-side usage report after a * successful x402 payment. The tool is identified by endpoint URL. */ reportCallerUsage?: CallerUsageReporterConfig | boolean; } /** * Combined predicate-gate + x402-paid fetch. Handles multiple 402 * challenges (predicate gate's zero-value challenge, then x402's real * payment challenge) via a retry loop. * * `body` must be a string, `ArrayBuffer`, or other re-readable type. * `ReadableStream` bodies are not supported (the body is consumed twice). */ declare function paidAuthenticatedFetch(url: string, options: PaidAuthenticatedFetchOptions): Promise; /** * Build a well-formed EIP-4361 SIWE message string. * * Uses viem's `createSiweMessage` under the hood. The returned string is * ready to be signed with `account.signMessage`. * * @deprecated Use `eip3009AuthenticatedFetch` or `signZeroValueAuthorization` * from `@opensea/tool-sdk` instead. SIWE auth is being replaced by EIP-3009 * zero-value authorizations across all tool-sdk auth flows. */ declare function createSiweMessage(params: { account: Account; domain: string; uri: string; statement?: string; expirationMinutes?: number; chainId?: number; nonce?: string; }): string; /** * Construct an `Authorization: SIWE .` header * value from a pre-signed SIWE message. Useful for agent wallets (Bankr, MPC, * HSM) that sign via an external API rather than a local viem Account. * * @deprecated Use `createEip3009AuthHeader` from `@opensea/tool-sdk` instead. */ declare function createSiweAuthHeader(message: string, signature: `0x${string}`): string; interface AuthenticatedFetchOptions extends RequestInit { account: Account; expirationMinutes?: number; chainId?: number; } /** * SIWE-authenticated fetch wrapper — the predicate-gate equivalent of * `paidFetch`. Works with both `predicateGate` (recommended) and the * deprecated `nftGate` middleware. * * Derives `domain` and `uri` from the `url` parameter, builds a SIWE message, * signs it, and sends the request with an `Authorization: SIWE ` header. * * Does NOT retry on 401/403 — SIWE auth is one-shot since the gate is * identity-based, not payment-based. * * @deprecated Use `eip3009AuthenticatedFetch` from `@opensea/tool-sdk` instead. */ declare function authenticatedFetch(url: string, options: AuthenticatedFetchOptions): Promise; declare const PAYAI_X402_FACILITATOR_URL = "https://facilitator.payai.network"; /** * Coinbase Developer Platform x402 facilitator. CDP requires JWT auth signed * with your CDP_API_KEY_SECRET. Pass `createAuthHeaders` on `cdpX402Gate` to * supply the headers; without them, verify returns 401/403 and the gate * surfaces 502. */ declare const CDP_X402_FACILITATOR_URL = "https://api.cdp.coinbase.com/platform/v2/x402"; declare const USDC_BASE_ADDRESS = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913"; declare const USDC_BASE_SEPOLIA_ADDRESS = "0x036cbd53842c5426634e7929541ec2318f3dcf7e"; declare const NETWORK_CHAIN_IDS: { readonly base: 8453; readonly "base-sepolia": 84532; }; type X402Network = keyof typeof NETWORK_CHAIN_IDS; /** * Single-use guard over payment authorizations, backed by storage you supply * (Redis, Cloudflare KV, D1, Postgres...). * * Without one, nothing stops a caller replaying one signed authorization * across N concurrent requests: the facilitator's `/verify` is stateless and * only detects a spent nonce once it is onchain, so every concurrent verify * passes, every handler runs, and only one settlement can ever land. The * others fail, having already consumed your handler, and under * `settlement: "best-effort"` they also return paid output. * * Must be backed by storage shared across every instance of your tool, and * `reserve` must be atomic (e.g. Redis `SET NX`, KV compare-and-set). An * in-process `Set` only protects a single instance and gives no protection on * serverless, where concurrent requests land in separate isolates. */ interface X402ReplayGuard { /** * Claim `key` for this request. Return `true` if the caller may proceed, * `false` if the authorization is already claimed (the gate then returns * 402 and the handler never runs). * * Back this with a TTL rather than growing the set forever, but the TTL must * cover the longest `validBefore` window you accept: the token contract * honors the authorization until then, so a key that expires first lets a * late replay claim it again. * * A reservation is held for its full TTL if the handler itself throws or * errors: the caller is not charged, but must sign a new authorization to * retry. Releasing there would let a caller who can make the handler fail * reuse one authorization to run it repeatedly, which is the amplification * this guard exists to stop. */ reserve(key: string): Promise; /** * Release a reservation when settlement failed in a way that left the nonce * unspent (a network error, or a facilitator 5xx or 429), so the caller can retry * with the same authorization. Not called when the facilitator answered * authoritatively: a spent nonce will never settle, so the key is held until * its TTL expires. Omit this and any failed settlement burns the * authorization: the caller must sign a new one. */ release?(key: string): Promise; } interface HostedX402GateConfig { recipient: `0x${string}`; /** * USDC amount as a decimal string ("0.01") or already in 6-decimal base * units ("10000"). Disambiguated by the presence of a decimal point. */ amountUsdc: string; network?: X402Network; description?: string; maxTimeoutSeconds?: number; /** * Override the resource URL advertised in the 402 response. Defaults to * the inbound request URL, which is correct for almost every deployment. */ resource?: string; /** * Override the facilitator URL. Each gate ships a sensible default; supply * this only if you are pinning to a specific facilitator instance. */ facilitatorUrl?: string; /** * Enforce that each payment authorization is used at most once. Strongly * recommended for any tool whose handler is expensive to run, see * {@link X402ReplayGuard}. Omitted by default because it needs storage the * SDK cannot provide portably. */ replayGuard?: X402ReplayGuard; } interface CdpX402GateConfig extends HostedX402GateConfig { /** * Generate auth headers for CDP /verify calls. CDP requires JWT auth signed * with your CDP_API_KEY_SECRET. A built-in helper that wraps * `@coinbase/cdp-sdk` is not yet shipped; until it lands, supply your own * callback or expect verify to return 401/403. */ createAuthHeaders?: () => Promise>; } /** * PayAI's hosted x402 facilitator. Free, no API key required. Operated by * the PayAI community (https://www.x402.org/ecosystem?filter=facilitators). * Use this for prototyping and dogfooding. For production, evaluate CDP * (`cdpX402Gate`) once you have CDP credentials. */ declare function payaiX402Gate(config: HostedX402GateConfig): GateMiddleware; /** * Coinbase Developer Platform x402 facilitator. Production-grade and * Coinbase-operated, but requires CDP authentication. Supply * `createAuthHeaders` to mint a JWT per request; without it the facilitator * rejects every verify and the gate surfaces 502. */ declare function cdpX402Gate(config: CdpX402GateConfig): GateMiddleware; /** * Build the manifest `pricing` array advertising USDC-on-Base payment via * x402. Identical regardless of which facilitator you choose at runtime, so * the advertised price and the enforced wire price stay in lockstep. */ declare function x402UsdcPricing(config: Pick): PricingEntry[]; interface ToolPaywallConfig { /** * Recipient address for USDC payments. Accepts an `EnvResolver` so the * address can be read from environment variables at request time instead * of requiring it at module-load time. */ recipient: EnvResolver<`0x${string}`>; amountUsdc: string; network?: X402Network; facilitator?: "payai" | "cdp"; /** Required when facilitator is "cdp" */ createAuthHeaders?: () => Promise>; description?: string; maxTimeoutSeconds?: number; resource?: string; facilitatorUrl?: string; /** * Enforce that each payment authorization is used at most once. See * {@link X402ReplayGuard}. */ replayGuard?: X402ReplayGuard; /** * Called after the facilitator confirms settlement. Use for telemetry, * logging, or post-payment side-effects. Errors are caught and logged * but do not affect the response. */ onSettle?: (ctx: { txHash: string; payer?: `0x${string}`; }) => void | Promise; } declare function defineToolPaywall(config: ToolPaywallConfig): { pricing: EnvResolver; gate: GateMiddleware; }; interface RawRequirements { scheme?: string; network?: string; /** x402 v1 field. */ maxAmountRequired?: string; /** x402 v2 field. */ amount?: string; payTo?: string; asset?: string; extra?: { name?: string; version?: string; }; [key: string]: unknown; } /** * Thrown when a signed x402 payment was sent but the server responded with a * 5xx error (e.g. 502 Bad Gateway, 504 Gateway Timeout). The caller should * **not** blindly retry — the payment authorization may have already been * settled on-chain even though the HTTP response indicates failure. * * Inspect {@link settled} to determine whether settlement headers were * present on the response. When `true`, the facilitator confirmed on-chain * settlement before the transport error occurred; when `false`, settlement * likely did not happen but is not guaranteed (a reverse proxy may have * dropped the response after the server settled). */ declare class X402PaymentError extends Error { readonly response: Response; readonly settled: boolean; constructor(message: string, response: Response, settled: boolean); } interface PaymentRequirements { scheme: string; /** * Network identifier. Accepts both the short names this SDK's middleware * emits (`base`, `base-sepolia`) and the CAIP-2 forms the broader x402 * ecosystem uses (`eip155:8453`). Resolved via {@link resolveNetwork}. */ network: string; maxAmountRequired: string; payTo: string; asset: string; extra?: { name?: string; version?: string; [key: string]: unknown; }; } /** * Sign an EIP-3009 `TransferWithAuthorization` for a USDC x402 payment. * Returns a base64-encoded JSON payment payload. Encode it into * `PAYMENT-SIGNATURE` (v2) or `X-PAYMENT` (v1). * * The payload envelope differs by version: * - **v1** — `{ x402Version, scheme, network, payload }` * - **v2** — `{ x402Version, payload, resource, accepted }`, where `accepted` * echoes the server's `accepts[0]` verbatim. Pass `accepted`/`resource` * from the parsed challenge so the facilitator can match the payment. */ declare function signX402Payment(params: { signer: WalletAdapter | Account; paymentRequirements: PaymentRequirements; /** * x402 protocol version to echo in the payment payload. Defaults to 1. * Pass the version advertised in the server's 402 challenge so the payload * matches what the facilitator expects. */ x402Version?: number; /** * The server's verbatim `accepts[0]` requirement, echoed in the v2 payload's * `accepted` field. Defaults to a requirement reconstructed from * `paymentRequirements` (v2 only). */ accepted?: RawRequirements; /** The server's `resource` descriptor, echoed in the v2 payload. */ resource?: unknown; }): Promise; interface PaidFetchOptions extends RequestInit { signer: WalletAdapter | Account; /** * Maximum amount (in the token's smallest unit) that may be authorized. * If the server requests more than this, `paidFetch` throws instead of * signing. Omit to accept whatever the server asks for. */ maxAmount?: string; /** * Allowlist of recipient addresses. If provided, `paidFetch` throws when * the server's `payTo` is not in this list. Addresses are compared * case-insensitively. */ allowedRecipients?: string[]; /** * Allowlist of asset contract addresses. If provided, `paidFetch` throws * when the server's `asset` is not in this list. Addresses are compared * case-insensitively. * * When omitted, defaults to the known USDC contract for the requested * network (`base` → `USDC_BASE_ADDRESS`, `base-sepolia` → * `USDC_BASE_SEPOLIA_ADDRESS`). */ allowedAssets?: string[]; /** * When set, sends a fire-and-forget caller-side usage report to the * OpenSea usage endpoint after a successful x402 payment. The tool is * identified by its endpoint URL — no onchain registry coordinates needed. */ reportCallerUsage?: CallerUsageReporterConfig | boolean; } /** * Fetch wrapper that handles x402 payment challenges automatically. * * Makes an initial request; if the server responds with 402 and an x402 * `accepts` array, signs a payment using the provided `signer` and replays * the request with an `X-Payment` header. * * **Security:** `paidFetch` trusts the server's 402 response to determine * the payment recipient, token, and amount. A compromised server can * request payment to an attacker-controlled address or for an inflated * amount. Use `maxAmount`, `allowedRecipients`, and `allowedAssets` to * constrain what gets signed. By default, `asset` is validated against * the known USDC contract address for the network, and `payTo` is * rejected if it is the zero address or a known burn address. * * `body` must be a string, `ArrayBuffer`, or other re-readable type. * `ReadableStream` bodies are not supported (the body is consumed twice). */ declare function paidFetch(url: string, options: PaidFetchOptions): Promise; /** * Extract the onchain settlement tx hash from x402 response headers. * Returns `undefined` if no settlement header is present. */ declare function extractSettlementTxHash(res: Response): string | undefined; /** * Build the x402 settlement-response header a tool server returns after it * settles a payment. The encoding is the inverse of {@link extractSettlementTxHash}: * a base64-encoded JSON settle response. The header name tracks the protocol * version — v2 uses `PAYMENT-RESPONSE`, v1 used `X-PAYMENT-RESPONSE` — matching * the request header named by {@link x402PaymentHeaderName}. */ declare function buildSettlementResponseHeader(params: { x402Version: number; transaction: string; network?: string; payer?: string; }): { name: string; value: string; }; declare class ToolHandlerError extends Error { readonly status: number; constructor(status: number, message: string); } type DataRetention = NonNullable; type SourceVisibility = NonNullable; type TeeExecution = "tee" | "e2ee"; interface VerifiabilityCommon { description?: string; dataRetention?: DataRetention; sourceVisibility?: SourceVisibility; } type SelfAttestedConfig = VerifiabilityCommon; interface HardwareAttestedConfig extends VerifiabilityCommon { execution: TeeExecution; attestation: Attestation; } interface VerifiableConfig extends VerifiabilityCommon { execution: TeeExecution; attestation: Attestation; reproducibleBuild: ReproducibleBuild; } declare function selfAttested(config?: SelfAttestedConfig): { verifiability: Verifiability; }; declare function hardwareAttested(config: HardwareAttestedConfig): { verifiability: Verifiability; }; declare function verifiable(config: VerifiableConfig): { verifiability: Verifiability; }; declare const defineVerifiability: { readonly selfAttested: typeof selfAttested; readonly hardwareAttested: typeof hardwareAttested; readonly verifiable: typeof verifiable; }; interface PredicateGateConfig { /** * Onchain tool ID. Obtained from the `ToolRegistered` event when the tool * is registered against the canonical `ToolRegistry`. */ toolId: bigint; /** * Chain where the registry is deployed. Defaults to Base. */ chain?: Chain; /** * RPC URL for read calls (registry staticcall + delegate registry). * Defaults to the chain's public RPC. */ rpcUrl?: string; /** * Optional bytes forwarded as the `data` argument to the predicate. Most * predicates ignore this; supply it only when the configured predicate * documents a use for it. */ data?: `0x${string}`; /** * Override the canonical registry address. Useful for local development * against a forked Anvil node or a custom deploy. */ registryAddress?: `0x${string}`; /** * Override the delegate.xyz DelegateRegistry address. Useful for local * development against a forked Anvil node. */ delegateRegistryAddress?: `0x${string}`; /** * Tool operator address. The gate combines this with the endpoint URL and * tool ID to derive the `payTo` recipient for the zero-value authorization. * The client verifies the same binding before signing. */ operatorAddress: `0x${string}`; /** * Absolute public URL of this endpoint. Defaults to the incoming request URL. * Set this when a reverse proxy rewrites the URL before the request reaches * the tool server. Clients always verify this audience before signing. */ audience?: string; /** * Enforce that each identity authorization is used at most once. See * {@link X402ReplayGuard}. The guard must use atomic shared storage so * concurrent requests cannot reuse one authorization to run the handler. */ replayGuard?: X402ReplayGuard; } /** * Server-side gate that delegates access decisions to the onchain * `ToolRegistry`. Uses the standard 402 + EIP-3009 flow: returns a 402 * challenge with `PaymentRequirements` when no `X-Payment` header is * present, then verifies the zero-value `TransferWithAuthorization` * signature from the `X-Payment` header to recover the caller's address * and staticcalls `tryHasAccess(toolId, caller, data)` on the registry. * * **Access results:** * - `(ok=true, granted=true)`: gate passes; sets `ctx.callerAddress`. * - `(ok=true, granted=false)`: returns `403` with the registered predicate * address in the body so the caller can self-diagnose. * - `(ok=false, *)`: returns `502` (predicate misbehaved upstream). * * **Delegated agent access:** When the request includes an * `X-Delegate-For: ` header, the gate verifies the caller * normally, then checks the delegate.xyz DelegateRegistry to confirm * the holder has delegated to the caller. If valid, the access predicate * runs against the **holder** (not the agent), and `ctx.agentAddress` is set. * * The registry is the source of truth for access policy; this middleware just * consults it. */ declare function predicateGate(config: PredicateGateConfig): GateMiddleware; interface PaidPredicateGateConfig { /** * Onchain tool ID from the `ToolRegistered` event. */ toolId: bigint; /** * Chain where the registry is deployed. Defaults to Base. */ chain?: Chain; /** * RPC URL for read calls. Defaults to the chain's public RPC. */ rpcUrl?: string; /** * Optional bytes forwarded as the `data` argument to the predicate. */ data?: `0x${string}`; /** * Override the canonical registry address. */ registryAddress?: `0x${string}`; /** * Override the delegate.xyz DelegateRegistry address. */ delegateRegistryAddress?: `0x${string}`; /** * Tool operator address. Used as both: * - The identity binding (`to` field in X-Payment must match) * - The payment recipient (`payTo` in the 402 challenge) */ operatorAddress: `0x${string}`; /** * USDC amount as a decimal string ("0.01") or in 6-decimal base units * ("10000"). Disambiguated by the presence of a decimal point. */ amountUsdc: string; /** * Network for x402 payment. Defaults to "base". */ network?: X402Network; /** * Description shown in the PaymentRequirements body. */ description?: string; /** * Maximum time (seconds) the caller has to complete the tool call after * the facilitator verifies the payment. Defaults to 60. */ maxTimeoutSeconds?: number; /** * Override the resource URL advertised in the 402 response. */ resource?: string; /** * Which facilitator to use. Defaults to "payai". */ facilitator?: "payai" | "cdp"; /** * Override the facilitator URL. */ facilitatorUrl?: string; /** * Generate auth headers for CDP /verify calls. Required when * facilitator is "cdp". */ createAuthHeaders?: () => Promise>; /** * Enforce that each payment authorization is used at most once. See * {@link X402ReplayGuard}. Without it, concurrent replays of one * authorization each pass verification and run the handler. */ replayGuard?: X402ReplayGuard; } /** * Combined predicate + x402 payment gate that resolves identity proof and * payment in a **single 402 round trip**. * * Instead of requiring two separate 402 challenges (one zero-value for * identity, one real-value for payment), this gate advertises the real * payment amount in its sole 402 response. The caller's X-Payment signature * for the real amount simultaneously proves identity (via the recovered * `from` address) AND authorizes payment (via the facilitator). * * **Flow:** * ``` * POST (bare) → 402 {payTo: operator, maxAmountRequired: "$"} * X-Payment(to=op, val=$) → verify sig → check predicate → verify payment → 200 * ``` * * **Safety:** The onchain predicate is checked BEFORE the facilitator settles * payment. If the caller does not meet the access requirement, a 403 is * returned and no funds move. */ declare function paidPredicateGate(config: PaidPredicateGateConfig): GateMiddleware; interface WellKnownHandlerOptions { /** * Environment bindings for resolving `EnvResolver` fields. On Node this * defaults to `process.env`; on Cloudflare Workers or Bun pass your * worker's `env` bindings explicitly. */ env?: Record; } /** * Creates a handler that serves the tool manifest as JSON. * * Accepts either a resolved `ToolManifest` or an unresolved * `ManifestDefinition` (returned by `defineManifest`). When a definition is * passed, `resolveManifest(definition, env)` is called once on the first * request so that `EnvResolver` fields are evaluated at request time, not at * module-load time. * * **Routing:** This handler does not perform pathname matching — mount it at * the exact well-known route in your framework (e.g. * `app.get('/.well-known/ai-tool/my-tool.json', handler)`). */ declare function createWellKnownHandler(manifestOrDefinition: ManifestDefinition | ToolManifest, options?: WellKnownHandlerOptions): (_request: Request) => Response; interface X402GateConfig { pricing: PricingEntry[]; /** * Callback to verify an x402 payment proof header. * Must return true if the payment is valid. If omitted, the gate * rejects all requests that include an X-Payment header with a * 501 "payment verification not configured" error. */ verifyPayment?: (paymentHeader: string) => Promise; } declare function x402Gate(config: X402GateConfig): GateMiddleware; declare const IToolRegistryABI: readonly [{ readonly type: "event"; readonly name: "AccessPredicateUpdated"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "newPredicate"; readonly type: "address"; readonly indexed: true; }]; }, { readonly type: "event"; readonly name: "ToolDeregistered"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }]; }, { readonly type: "event"; readonly name: "ToolMetadataUpdated"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "newURI"; readonly type: "string"; readonly indexed: false; }, { readonly name: "newHash"; readonly type: "bytes32"; readonly indexed: false; }]; }, { readonly type: "event"; readonly name: "ToolRegistered"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "creator"; readonly type: "address"; readonly indexed: true; }, { readonly name: "accessPredicate"; readonly type: "address"; readonly indexed: true; }, { readonly name: "metadataURI"; readonly type: "string"; readonly indexed: false; }, { readonly name: "manifestHash"; readonly type: "bytes32"; readonly indexed: false; }]; }, { readonly type: "error"; readonly name: "InvalidAccessPredicate"; readonly inputs: readonly [{ readonly name: "predicate"; readonly type: "address"; }]; }, { readonly type: "error"; readonly name: "InvalidManifestHash"; readonly inputs: readonly []; }, { readonly type: "error"; readonly name: "InvalidMetadataURI"; readonly inputs: readonly []; }, { readonly type: "error"; readonly name: "NotToolCreator"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "caller"; readonly type: "address"; }]; }, { readonly type: "error"; readonly name: "ToolIsDeregistered"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; }, { readonly type: "error"; readonly name: "ToolNotFound"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; }, { readonly type: "function"; readonly name: "deregisterTool"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "getToolConfig"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "tuple"; readonly components: readonly [{ readonly name: "creator"; readonly type: "address"; }, { readonly name: "metadataURI"; readonly type: "string"; }, { readonly name: "manifestHash"; readonly type: "bytes32"; }, { readonly name: "accessPredicate"; readonly type: "address"; }]; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "hasAccess"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "account"; readonly type: "address"; }, { readonly name: "data"; readonly type: "bytes"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "bool"; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "name"; readonly inputs: readonly []; readonly outputs: readonly [{ readonly name: ""; readonly type: "string"; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "registerTool"; readonly inputs: readonly [{ readonly name: "metadataURI"; readonly type: "string"; }, { readonly name: "manifestHash"; readonly type: "bytes32"; }, { readonly name: "accessPredicate"; readonly type: "address"; }]; readonly outputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "setAccessPredicate"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "newPredicate"; readonly type: "address"; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "toolCount"; readonly inputs: readonly []; readonly outputs: readonly [{ readonly name: ""; readonly type: "uint256"; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "tryHasAccess"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "account"; readonly type: "address"; }, { readonly name: "data"; readonly type: "bytes"; }]; readonly outputs: readonly [{ readonly name: "ok"; readonly type: "bool"; }, { readonly name: "granted"; readonly type: "bool"; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "updateToolMetadata"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "newURI"; readonly type: "string"; }, { readonly name: "newHash"; readonly type: "bytes32"; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "version"; readonly inputs: readonly []; readonly outputs: readonly [{ readonly name: ""; readonly type: "string"; }]; readonly stateMutability: "view"; }]; declare const IAccessPredicateABI: readonly [{ readonly type: "function"; readonly name: "hasAccess"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "account"; readonly type: "address"; }, { readonly name: "data"; readonly type: "bytes"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "bool"; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "name"; readonly inputs: readonly []; readonly outputs: readonly [{ readonly type: "string"; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "getRequirements"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: "requirements"; readonly type: "tuple[]"; readonly components: readonly [{ readonly name: "kind"; readonly type: "bytes4"; }, { readonly name: "data"; readonly type: "bytes"; }, { readonly name: "label"; readonly type: "string"; }]; }, { readonly name: "logic"; readonly type: "uint8"; }]; readonly stateMutability: "view"; }]; declare const ERC721OwnerPredicateABI: readonly [{ readonly type: "event"; readonly name: "CollectionsSet"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "collections"; readonly type: "address[]"; readonly indexed: false; }]; }, { readonly type: "function"; readonly name: "setCollections"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "collections"; readonly type: "address[]"; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "getCollections"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "address[]"; }]; readonly stateMutability: "view"; }]; declare const ERC1155OwnerPredicateABI: readonly [{ readonly type: "event"; readonly name: "CollectionTokensSet"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "entries"; readonly type: "tuple[]"; readonly indexed: false; readonly components: readonly [{ readonly name: "collection"; readonly type: "address"; }, { readonly name: "tokenIds"; readonly type: "uint256[]"; }]; }]; }, { readonly type: "function"; readonly name: "setCollectionTokens"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "entries"; readonly type: "tuple[]"; readonly components: readonly [{ readonly name: "collection"; readonly type: "address"; }, { readonly name: "tokenIds"; readonly type: "uint256[]"; }]; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "getCollectionTokens"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "tuple[]"; readonly components: readonly [{ readonly name: "collection"; readonly type: "address"; }, { readonly name: "tokenIds"; readonly type: "uint256[]"; }]; }]; readonly stateMutability: "view"; }]; declare const SubscriptionPredicateABI: readonly [{ readonly type: "event"; readonly name: "ToolGatingConfigured"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "collection"; readonly type: "address"; readonly indexed: true; }, { readonly name: "minTier"; readonly type: "uint8"; readonly indexed: false; }]; }, { readonly type: "function"; readonly name: "configureToolGating"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "collection"; readonly type: "address"; }, { readonly name: "minTier"; readonly type: "uint8"; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "getToolGatingConfig"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "tuple"; readonly components: readonly [{ readonly name: "collection"; readonly type: "address"; }, { readonly name: "minTier"; readonly type: "uint8"; }]; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "getSubscriptionStatus"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "account"; readonly type: "address"; }]; readonly outputs: readonly [{ readonly name: "hasNft"; readonly type: "bool"; }, { readonly name: "tier"; readonly type: "uint8"; }, { readonly name: "requiredTier"; readonly type: "uint8"; }, { readonly name: "expiration"; readonly type: "uint64"; }, { readonly name: "active"; readonly type: "bool"; }]; readonly stateMutability: "view"; }]; declare const CompositePredicateABI: readonly [{ readonly type: "event"; readonly name: "CompositionSet"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "op"; readonly type: "uint8"; readonly indexed: false; }, { readonly name: "terms"; readonly type: "tuple[]"; readonly indexed: false; readonly components: readonly [{ readonly name: "predicate"; readonly type: "address"; }, { readonly name: "negate"; readonly type: "bool"; }]; }]; }, { readonly type: "function"; readonly name: "setComposition"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "op"; readonly type: "uint8"; }, { readonly name: "terms"; readonly type: "tuple[]"; readonly components: readonly [{ readonly name: "predicate"; readonly type: "address"; }, { readonly name: "negate"; readonly type: "bool"; }]; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "getOp"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "uint8"; }]; readonly stateMutability: "view"; }, { readonly type: "function"; readonly name: "getTerms"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "tuple[]"; readonly components: readonly [{ readonly name: "predicate"; readonly type: "address"; }, { readonly name: "negate"; readonly type: "bool"; }]; }]; readonly stateMutability: "view"; }]; declare const TraitGatedPredicateABI: readonly [{ readonly type: "event"; readonly name: "ToolTraitConfigured"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "collection"; readonly type: "address"; readonly indexed: true; }, { readonly name: "traitsContract"; readonly type: "address"; readonly indexed: false; }, { readonly name: "traitKey"; readonly type: "bytes32"; readonly indexed: false; }, { readonly name: "allowedValues"; readonly type: "bytes32[]"; readonly indexed: false; }]; }, { readonly type: "function"; readonly name: "configureToolTrait"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "collection"; readonly type: "address"; }, { readonly name: "traitsContract"; readonly type: "address"; }, { readonly name: "traitKey"; readonly type: "bytes32"; }, { readonly name: "allowedValues"; readonly type: "bytes32[]"; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "getToolTraitConfig"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "tuple"; readonly components: readonly [{ readonly name: "collection"; readonly type: "address"; }, { readonly name: "traitsContract"; readonly type: "address"; }, { readonly name: "traitKey"; readonly type: "bytes32"; }, { readonly name: "allowedValues"; readonly type: "bytes32[]"; }]; }]; readonly stateMutability: "view"; }]; declare const ERC20BalancePredicateABI: readonly [{ readonly type: "error"; readonly name: "CallerIsNotToolCreator"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "caller"; readonly type: "address"; }]; }, { readonly type: "error"; readonly name: "ZeroToken"; readonly inputs: readonly []; }, { readonly type: "error"; readonly name: "TokenNoCode"; readonly inputs: readonly [{ readonly name: "token"; readonly type: "address"; }]; }, { readonly type: "error"; readonly name: "ZeroMinBalance"; readonly inputs: readonly []; }, { readonly type: "event"; readonly name: "ToolERC20Configured"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; readonly indexed: true; }, { readonly name: "token"; readonly type: "address"; readonly indexed: true; }, { readonly name: "minBalance"; readonly type: "uint256"; readonly indexed: false; }]; }, { readonly type: "function"; readonly name: "configureToolERC20"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }, { readonly name: "token"; readonly type: "address"; }, { readonly name: "minBalance"; readonly type: "uint256"; }]; readonly outputs: readonly []; readonly stateMutability: "nonpayable"; }, { readonly type: "function"; readonly name: "getToolERC20Config"; readonly inputs: readonly [{ readonly name: "toolId"; readonly type: "uint256"; }]; readonly outputs: readonly [{ readonly name: ""; readonly type: "tuple"; readonly components: readonly [{ readonly name: "token"; readonly type: "address"; }, { readonly name: "minBalance"; readonly type: "uint256"; }]; }]; readonly stateMutability: "view"; }]; /** * Minimal ABI for delegate.xyz's DelegateRegistry V2. * Only includes `checkDelegateForAll` which is the function we use to verify * wallet-level delegations. * @see https://docs.delegate.xyz/technical-documentation/delegate-registry/idelegateregistry.sol */ declare const IDelegateRegistryABI: readonly [{ readonly type: "function"; readonly name: "checkDelegateForAll"; readonly inputs: readonly [{ readonly name: "to"; readonly type: "address"; }, { readonly name: "from"; readonly type: "address"; }, { readonly name: "rights"; readonly type: "bytes32"; }]; readonly outputs: readonly [{ readonly name: "valid"; readonly type: "bool"; }]; readonly stateMutability: "view"; }]; interface CheckToolAccessOptions { /** Onchain tool ID to check access for. */ toolId: bigint; /** EVM account whose access is being checked. */ account: `0x${string}`; /** Chain where the registry is deployed. Defaults to Base. */ chain?: Chain; /** RPC URL for the staticcall. Defaults to the chain's public RPC. */ rpcUrl?: string; /** * Optional bytes forwarded as the `data` argument to the predicate. Most * predicates ignore this; supply it only when the configured predicate * documents a use for it. */ data?: `0x${string}`; } interface CheckToolAccessResult { /** `false` if the predicate misbehaved (out of gas, malformed return). */ ok: boolean; /** `true` if the predicate granted access. */ granted: boolean; } /** * Client-side preview of whether `account` has access to a registered tool. * Mirrors the server-side `predicateGate` decision so frontends, CLIs, and * agents can gray out "Use Tool" affordances without first invoking the tool. * * Calls `IToolRegistry.tryHasAccess` via a viem staticcall. Open-access * tools (`accessPredicate == address(0)`) return `{ ok: true, granted: true }`. */ declare function checkToolAccess(opts: CheckToolAccessOptions): Promise; interface DescribeToolAccessOptions { /** Onchain tool ID. */ toolId: bigint; /** Chain where the registry is deployed. Defaults to Base. */ chain?: Chain; /** RPC URL for the staticcall. Defaults to the chain's public RPC. */ rpcUrl?: string; } interface AccessRequirementInfo { /** ERC-165–style 4-byte selector identifying the requirement type. */ kind: `0x${string}`; /** ABI-encoded payload whose layout is determined by `kind`. */ data: `0x${string}`; /** Human-readable hint (e.g. "Chonks on Base"). */ label: string; } interface ToolAccessDescription { /** Whether the tool is open access (no predicate). */ openAccess: boolean; /** Address of the access predicate contract, if any. */ predicateAddress: `0x${string}` | null; /** Human-readable name of the predicate (from `name()`), if available. */ predicateName: string | null; /** Structured requirements from `getRequirements()`, if available. */ requirements: AccessRequirementInfo[]; /** 0 = AND, 1 = OR. How requirements combine. */ logic: "AND" | "OR"; } /** * Describes the access requirements for a registered tool in a structured * format suitable for UIs, CLIs, and agents. * * Reads the tool's predicate from the registry, then calls the predicate's * `name()` and `getRequirements(toolId)` to produce a machine-readable * description. If the predicate doesn't support those calls, the fields * degrade gracefully to `null` / empty arrays. */ declare function describeToolAccess(opts: DescribeToolAccessOptions): Promise; declare const ERC721_KIND: "0xbdf8c428"; declare const ERC1155_KIND: "0xcb429230"; declare const SUBSCRIPTION_KIND: "0x44387cc2"; declare const ERC7496_TRAIT_KIND: "0x37d8dc22"; declare const ERC20_BALANCE_KIND: "0x812b02ee"; declare const WALLET_STATE_ATTESTATION_KIND: "0x7a111640"; type DecodedERC721Requirement = { type: "erc721"; collection: `0x${string}`; }; type DecodedERC1155Requirement = { type: "erc1155"; collection: `0x${string}`; tokenId: bigint; }; type DecodedSubscriptionRequirement = { type: "subscription"; collection: `0x${string}`; minTier: number; }; type DecodedERC7496TraitRequirement = { type: "erc7496Trait"; collection: `0x${string}`; traitsContract: `0x${string}`; traitKey: `0x${string}`; allowedValues: readonly `0x${string}`[]; }; type DecodedERC20BalanceRequirement = { type: "erc20Balance"; token: `0x${string}`; minBalance: bigint; }; type DecodedWalletStateAttestationRequirement = { type: "walletStateAttestation"; issuerJwksUri: string; conditionHash: `0x${string}`; }; type DecodedUnknownRequirement = { type: "unknown"; kind: `0x${string}`; data: `0x${string}`; }; type DecodedRequirement = DecodedERC721Requirement | DecodedERC1155Requirement | DecodedSubscriptionRequirement | DecodedERC7496TraitRequirement | DecodedERC20BalanceRequirement | DecodedWalletStateAttestationRequirement | DecodedUnknownRequirement; /** * Decodes an `AccessRequirementInfo` into a typed object based on its `kind`. * Known kinds (ERC-721 holding, ERC-1155 holding, Subscription) are fully * decoded; unknown kinds are returned as-is with `type: "unknown"`. */ declare function decodeRequirement(req: AccessRequirementInfo): DecodedRequirement; /** * Canonical addresses live in packages/tool-registry/README.md. * Update both files together after every new deploy. */ /** Onchain deployment of a contract addressed via deterministic CREATE2. */ type Deployment = { /** Canonical CREATE2 address — identical on every EVM-equivalent chain. */ address: `0x${string}`; /** Chain IDs where the canonical address has been deployed. */ chains: readonly number[]; /** * Per-chain overrides for non-EVM-equivalent chains where the canonical * CREATE2 address can't be reached. Rare; most deployments have none. */ overrides?: Readonly>; }; declare const TOOL_REGISTRY: Deployment; declare const ERC721_OWNER_PREDICATE: Deployment; declare const ERC1155_OWNER_PREDICATE: Deployment; declare const SUBSCRIPTION_PREDICATE: Deployment; declare const TRAIT_GATED_PREDICATE: Deployment; declare const ERC20_BALANCE_PREDICATE: Deployment; /** * delegate.xyz DelegateRegistry V2. Deployed at the same deterministic address * on 30+ EVM chains. * @see https://docs.delegate.xyz/technical-documentation/delegate-registry/contract-addresses */ declare const DELEGATE_REGISTRY: Deployment; /** Resolve a deployment to the address active on a given chain. */ declare function deploymentAddress(d: Deployment, chainId: number): `0x${string}` | undefined; /** * Computes the ERC-8257 manifest hash: keccak256 over the JCS (RFC 8785) * canonicalization of the manifest. * * Per ERC-8257 §2, the manifest is hashed *as served*: the full JSON document * including any namespaced extension fields, with no schema stripping and no * injected defaults. Callers MUST pass the raw served/authored object (for * example the fetched response body), not a schema-stripped copy, so that an * independently computed hash agrees with this one. */ declare function computeManifestHash(manifest: object): `0x${string}`; interface PredicateClientConfig { chain?: Chain; rpcUrl?: string; walletClient?: WalletClient; predicateAddress?: `0x${string}`; } declare abstract class BasePredicateClient { protected chain: Chain; protected walletClient?: WalletClient; protected predicateAddress: `0x${string}`; protected publicClient: ReturnType; protected abi: TAbi; constructor(defaultDeployment: Deployment, contractName: string, abi: TAbi, config?: PredicateClientConfig); protected requireWalletClient(): WalletClient; /** Read a view/pure function on this predicate at the resolved address. */ protected read, const args extends ContractFunctionArgs>(functionName: fn, args: args): Promise>; /** Send a state-changing transaction to this predicate; requires a wallet. */ protected write, const args extends ContractFunctionArgs>(functionName: fn, args: args): Promise; protected openSeaChainSegment(): string | undefined; /** * Build the `links` map for a manifest requirement pointing at an asset's * OpenSea page, or `undefined` when the active chain has no OpenSea path. */ protected openSeaAssetLinks(collection: Address): Record | undefined; } declare class ERC721OwnerPredicateClient extends BasePredicateClient { constructor(config?: PredicateClientConfig); getCollections(toolId: bigint): Promise; setCollections(toolId: bigint, collections: Address[]): Promise; /** * Convenience method: reads the current list, appends the new collection, and writes back. * * **Not safe for concurrent use on the same `toolId`.** This method uses a * read-then-write pattern — if two calls race, the second transaction reads * stale state and overwrites the first. For concurrent workflows, use * {@link setCollections} directly with the full desired list. */ addCollection(toolId: bigint, collection: Address): Promise; /** * Convenience method: reads the current list, removes the collection, and writes back. * * **Not safe for concurrent use on the same `toolId`.** This method uses a * read-then-write pattern — if two calls race, the second transaction reads * stale state and overwrites the first. For concurrent workflows, use * {@link setCollections} directly with the full desired list. */ removeCollection(toolId: bigint, collection: Address): Promise; toManifestAccess(collection: Address, opts?: { label?: string; }): Access; } declare class ERC1155OwnerPredicateClient extends BasePredicateClient { constructor(config?: PredicateClientConfig); getCollectionTokens(toolId: bigint): Promise<{ collection: Address; tokenIds: bigint[]; }[]>; setCollectionTokens(toolId: bigint, entries: { collection: Address; tokenIds: bigint[]; }[]): Promise; toManifestAccess(collection: Address, tokenId: bigint, opts?: { label?: string; }): Access; } declare class SubscriptionPredicateClient extends BasePredicateClient { constructor(config?: PredicateClientConfig); getToolGatingConfig(toolId: bigint): Promise<{ collection: Address; minTier: number; }>; configureToolGating(toolId: bigint, collection: Address, minTier: number): Promise; getSubscriptionStatus(toolId: bigint, account: Address): Promise<{ hasNft: boolean; tier: number; requiredTier: number; expiration: bigint; active: boolean; }>; toManifestAccess(collection: Address, minTier: number, opts?: { label?: string; }): Access; } declare class TraitGatedPredicateClient extends BasePredicateClient { constructor(config?: PredicateClientConfig); getToolTraitConfig(toolId: bigint): Promise<{ collection: Address; traitsContract: Address; traitKey: `0x${string}`; allowedValues: readonly `0x${string}`[]; }>; configureToolTrait(toolId: bigint, collection: Address, traitsContract: Address, traitKey: `0x${string}`, allowedValues: `0x${string}`[]): Promise; toManifestAccess(collection: Address, traitsContract: Address, traitKey: `0x${string}`, allowedValues: `0x${string}`[], opts?: { label?: string; }): Access; } declare class ERC20BalancePredicateClient extends BasePredicateClient { constructor(config?: PredicateClientConfig); getToolERC20Config(toolId: bigint): Promise<{ token: Address; minBalance: bigint; }>; configureToolERC20(toolId: bigint, token: Address, minBalance: bigint): Promise; /** * Build a manifest `access` block for an ERC-20 balance gate. * * **Important:** The default label renders `minBalance` as a raw bigint * (e.g. `"1000000000000000000"`). For user-facing gates, always supply a * human-readable `opts.label` (e.g. `"Hold at least 1 USDC"`). */ toManifestAccess(token: Address, minBalance: bigint, opts?: { label?: string; }): Access; } declare enum CompositeOp { ALL = 0, ANY = 1 } interface CompositeTerm { predicate: Address; negate: boolean; } declare class CompositePredicateClient extends BasePredicateClient { constructor(config: PredicateClientConfig & { predicateAddress: `0x${string}`; }); getOp(toolId: bigint): Promise; getTerms(toolId: bigint): Promise; setComposition(toolId: bigint, op: CompositeOp, terms: CompositeTerm[]): Promise; } interface ToolConfig { creator: Address; metadataURI: string; manifestHash: Hex; accessPredicate: Address; } declare class ToolRegistryClient { private chain; private walletClient?; private registryAddress; private publicClient; constructor(config: { chain?: Chain; rpcUrl?: string; walletClient?: WalletClient; registryAddress?: `0x${string}`; }); getToolConfig(toolId: bigint): Promise; hasAccess(toolId: bigint, account: Address, data?: Hex): Promise; /** * Calls the registry's `tryHasAccess`, which distinguishes "predicate said no" * from "predicate misbehaved" (e.g. ran out of gas or returned malformed data). * * - `(ok=true, granted=true)`: the predicate granted access. * - `(ok=true, granted=false)`: the predicate denied access. * - `(ok=false, *)`: the predicate misbehaved; treat as a 5xx, not a 403. * * Open-access tools (`accessPredicate == address(0)`) return `(true, true)`. */ tryHasAccess(toolId: bigint, account: Address, data?: Hex): Promise<{ ok: boolean; granted: boolean; }>; toolCount(): Promise; name(): Promise; version(): Promise; registerTool(params: { metadataURI: string; manifest: object; accessPredicate?: Address; }): Promise<{ toolId: bigint; txHash: Hash; }>; updateToolMetadata(toolId: bigint, newURI: string, manifest: object): Promise; /** * Lists tools registered by a creator. * * When `fromBlock` is omitted, the query scans only the last 10,000 * blocks to avoid unbounded `getLogs` calls on public RPC endpoints. * Pass `fromBlock` to search further back. */ listToolsByCreator(creator: Address, options?: { fromBlock?: bigint; toBlock?: bigint; }): Promise<{ toolId: bigint; accessPredicate: Address; metadataURI: string; manifestHash: Hex; txHash: Hash; blockNumber: bigint; }[]>; setAccessPredicate(toolId: bigint, predicate: Address): Promise; } interface PredicateGateAudienceBinding { /** Absolute public URL of the predicate-gated endpoint. */ audience: string | URL; /** Onchain tool ID enforced by the gate. */ toolId: bigint; /** Operator configured by the tool server. */ operatorAddress: `0x${string}`; } /** * Normalize the endpoint URL that a free predicate-gate authorization targets. * URL fragments are client-only and never reach the server, so they are not * part of the signed audience. */ declare function normalizePredicateGateAudience(audience: string | URL): string; /** * Derive the recipient signed by free predicate-gate callers. * * EIP-3009 has no arbitrary audience field. Encoding the endpoint, tool ID, * and operator into `to` lets both the client and server verify the intended * audience without transferring funds. The address needs no private key * because the authorization value is required to be zero and is never settled. */ declare function derivePredicateGateRecipient({ audience, toolId, operatorAddress, }: PredicateGateAudienceBinding): `0x${string}`; interface X402UsageReporterConfig { /** * URL of the OpenSea usage endpoint. * Defaults to `https://api.opensea.io/api/v2/tools/usage`. */ aggregatorUrl?: string; /** * ERC-8257 composite key: chain where the tool is registered. */ toolChainId: number; /** * ERC-8257 composite key: registry contract address. */ toolRegistryAddress: string; /** * Composite key: the tool's ID in the registry. A number (for onchain * tools that fit in a JS integer) or a numeric string (for x402 tools * whose IDs exceed `Number.MAX_SAFE_INTEGER`). */ toolOnchainId: number | string; /** * API key sent as `x-api-key` header. */ apiKey: string; /** * Request timeout in milliseconds. Defaults to 5000. */ timeoutMs?: number; } interface X402UsageEvent { /** Address of the caller who paid. */ callerAddress: `0x${string}`; /** Onchain settlement transaction hash. */ txHash: string; /** Chain where the settlement tx occurred. */ chainId: number; /** Tool invocation latency in milliseconds. */ latencyMs?: number; } /** * Creates a reporter for x402 settlement-based tool usage verification. * * Use this when the tool is paid via x402 and you have the onchain * settlement transaction hash. No wallet signing is required — the * backend verifies the settlement tx directly. */ declare function createX402UsageReporter(config: X402UsageReporterConfig): (event: X402UsageEvent) => Promise; declare function deriveSlug(name: string): string; declare function walletAdapterToClient(adapter: WalletAdapter, chain: Chain, rpcUrl?: string): Promise>; export { Access, type AccessRequirementInfo, Attestation, type AuthenticatedFetchOptions, CDP_X402_FACILITATOR_URL, type CallerEip3009UsageEvent, type CallerUsageReportOutcome, type CallerUsageReportResult, type CallerUsageReporterConfig, type CallerX402UsageEvent, type CdpX402GateConfig, type CheckToolAccessOptions, type CheckToolAccessResult, CompositeOp, CompositePredicateABI, CompositePredicateClient, type CompositeTerm, DELEGATE_REGISTRY, type DecodedERC1155Requirement, type DecodedERC20BalanceRequirement, type DecodedERC721Requirement, type DecodedERC7496TraitRequirement, type DecodedRequirement, type DecodedSubscriptionRequirement, type DecodedUnknownRequirement, type DecodedWalletStateAttestationRequirement, type Deployment, type DescribeToolAccessOptions, ERC1155OwnerPredicateABI, ERC1155OwnerPredicateClient, ERC1155_KIND, ERC1155_OWNER_PREDICATE, ERC20BalancePredicateABI, ERC20BalancePredicateClient, ERC20_BALANCE_KIND, ERC20_BALANCE_PREDICATE, ERC721OwnerPredicateABI, ERC721OwnerPredicateClient, ERC721_KIND, ERC721_OWNER_PREDICATE, ERC7496_TRAIT_KIND, type Eip3009AuthenticatedFetchOptions, EnvResolver, type ExpressRequest, type ExpressResponse, GateMiddleware, type HardwareAttestedConfig, type HostedX402GateConfig, IAccessPredicateABI, IDelegateRegistryABI, IToolRegistryABI, ManifestDefinition, PAYAI_X402_FACILITATOR_URL, type PaidAuthenticatedFetchOptions, type PaidFetchOptions, type PaidPredicateGateConfig, type PaymentRequirements, type PredicateClientConfig, type PredicateGateAudienceBinding, type PredicateGateConfig, PricingEntry, ReproducibleBuild, SUBSCRIPTION_KIND, SUBSCRIPTION_PREDICATE, type SelfAttestedConfig, SubscriptionPredicateABI, SubscriptionPredicateClient, TOOL_REGISTRY, TRAIT_GATED_PREDICATE, type ToolAccessDescription, ToolHandlerError, ToolManifest, type ToolPaywallConfig, ToolRegistryClient, TraitGatedPredicateABI, TraitGatedPredicateClient, USDC_BASE_ADDRESS, USDC_BASE_SEPOLIA_ADDRESS, type VercelRequest, type VercelResponse, Verifiability, type VerifiableConfig, WALLET_STATE_ATTESTATION_KIND, type WellKnownHandlerOptions, type X402GateConfig, type X402Network, X402PaymentError, type X402ReplayGuard, type X402UsageEvent, type X402UsageReporterConfig, ZeroValueAuthorization, authenticatedFetch, buildSettlementResponseHeader, cdpX402Gate, checkToolAccess, computeManifestHash, createBankrAccount, createEip3009AuthHeader, createExternalSignerAccount, createSiweAuthHeader, createSiweMessage, createWellKnownHandler, createX402UsageReporter, decodeRequirement, defineToolPaywall, defineVerifiability, deploymentAddress, derivePredicateGateRecipient, deriveSlug, describeToolAccess, eip3009AuthenticatedFetch, extractSettlementTxHash, normalizePredicateGateAudience, paidAuthenticatedFetch, paidFetch, paidPredicateGate, payaiX402Gate, predicateGate, reportCallerEip3009Usage, reportCallerX402Usage, signX402Payment, toExpressHandler, toVercelHandler, walletAdapterToClient, x402Gate, x402UsdcPricing };