import { OnChainBtcPubkey } from '../../eth/types'; import { BearerTokenProvider, JsonRpcClient } from '../json-rpc-client'; import { ServerIdentityResponse } from './serverIdentity'; /** * Wire response shape of `auth_createDepositorToken`. */ export interface CreateDepositorTokenResponse { /** Base64url-encoded COSE Sign1 CWT bearer token. */ token: string; /** Unix timestamp at which the token expires. */ expires_at: number; /** Server identity proof bundled with every token response. */ server_identity: ServerIdentityResponse; } export interface VpTokenProviderConfig { client: JsonRpcClient; /** Per-vault depositor-signed PegIn tx id. NOT shared across sibling vaults in a batch. */ peginTxid: string; /** 64-char hex of the 32-byte OP_RETURN auth-anchor preimage. */ authAnchorHex: string; /** Pinned VP pubkey from the on-chain registry; branded so indexer mirrors can't substitute. */ pinnedServerPubkey: OnChainBtcPubkey; /** * Depositor x-only pubkey (32-byte hex). Asserted against every * issued token's CWT `aud` claim so a token minted for a different * depositor — or mis-issued by a buggy/compromised VP — is rejected * before it can authenticate a mutation. */ expectedAudienceXOnlyPubkey: string; /** * Methods that need a JSON-RPC-subject bearer (minted via * `auth_createDepositorToken`). Forwarded over plain HTTP JSON-RPC by * the proxy. `getToken` returns `null` for any method outside this and * {@link grpcGatedMethods}. */ authGatedMethods: ReadonlySet; /** * Methods that need a gRPC-subject bearer (minted via * `auth_createDepositorTokenGrpc`). The proxy translates these into * gRPC calls to vaultd; the JSON-RPC bearer is rejected with a * `Subject` mismatch. */ grpcGatedMethods: ReadonlySet; /** Default {@link DEFAULT_REFRESH_SKEW_SECS}. */ refreshSkewSecs?: number; /** Clock source for testability. */ now?: () => number; } /** * Acquire, cache, and refresh VP bearer tokens. * * Implements {@link BearerTokenProvider}. Safe to pass directly into * `JsonRpcClient` as `tokenProvider`. */ export declare class VpTokenProvider implements BearerTokenProvider { private client; private readonly peginTxid; private readonly authAnchorHex; private readonly pinnedServerPubkey; private readonly expectedAudienceXOnlyPubkey; private readonly authGatedMethods; private readonly grpcGatedMethods; private readonly refreshSkewSecs; private readonly now; /** Cached JSON-RPC-subject bearer (auth_createDepositorToken). */ private cachedJsonRpc; private inFlightJsonRpc; /** Cached gRPC-subject bearer (auth_createDepositorTokenGrpc). */ private cachedGrpc; private inFlightGrpc; constructor(config: VpTokenProviderConfig); /** * Return a bearer token for `method`, or `null` if `method` is not * auth-gated. * * Routes by subject: `authGatedMethods` → JSON-RPC bearer (issued via * `auth_createDepositorToken`); `grpcGatedMethods` → gRPC bearer * (`auth_createDepositorTokenGrpc`). Either path acquires lazily and * single-flights concurrent callers; the two cache slots are * independent. * * Both token-issuing methods are hard-exempted from the gate — if * either were ever included in the gated sets (caller misconfiguration) * the provider would recurse into `acquireSingleFlight` from inside the * JSON-RPC header builder before `inFlight` is assigned, defeating the * single-flight guard. Returning `null` here breaks that recursion * deterministically. */ getToken(method: string): Promise; /** * Drop both cached tokens. Next `getToken` call re-acquires the slot * that's actually needed. Called by `JsonRpcClient` on wire * `auth_expired` responses; the client doesn't tell us which subject * expired, so we evict both to stay correct under either. * * Worst case is one extra round-trip on the slot that was still fresh, * which is cheaper than carrying a `Subject` argument through * `BearerTokenProvider`. */ invalidate(): void; private getTokenForSubject; /** * Swap in a different transport for subsequent token-issuing calls. * Used by the registry when a later caller registers the same * `peginTxid` against a different `baseUrl` — the cached token * (bound to identity, not transport) stays valid, but future * refreshes hit the new URL. An in-flight acquire keeps using the * old client (it captured the reference); next call uses the new. */ setClient(client: JsonRpcClient): void; private acquireSingleFlight; } //# sourceMappingURL=tokenProvider.d.ts.map