@opendatalabs/vana-sdk
Version:
A TypeScript library for interacting with Vana Network smart contracts.
91 lines (90 loc) • 3.46 kB
TypeScript
/**
* OAuth 2.0 Authorization Code + PKCE client orchestration.
*
* @remarks
* Drives the full authorize → callback → token-exchange → refresh dance on top
* of the {@link TokenStore} and PKCE primitives that ship with this package.
* Implements RFC 6749 §4.1 with the RFC 7636 PKCE extension (S256 only).
*
* @category Auth
* @module auth/oauth-client
*/
import { type TokenRecord, type TokenStore } from "./token-store";
/**
* Constructor options for {@link OAuthClient}.
*/
export interface OAuthClientConfig {
/** Authorization endpoint, e.g. `https://account.vana.org/oauth/authorize`. */
authorizationEndpoint: string;
/** Token endpoint, e.g. `https://account.vana.org/oauth/token`. */
tokenEndpoint: string;
/** OAuth `client_id` (public; PKCE protects the flow). */
clientId: string;
/** Redirect URI registered with the authorization server. */
redirectUri: string;
/** Default scope; can be overridden per call. */
scope?: string;
/**
* Where to persist access + refresh tokens and the in-flight code verifier
* between `authorize` → `callback`. Defaults to a fresh
* {@link InMemoryTokenStore}. Use IndexedDB/localStorage-backed
* implementations for browser apps where the user navigates away during the
* dance.
*/
tokenStore?: TokenStore;
/** Override the global `fetch` (e.g. for tests). Defaults to `globalThis.fetch`. */
fetchImpl?: typeof fetch;
/**
* Override the random-state generator (mostly for tests). Must return a
* URL-safe string of >= 16 bytes of entropy.
*/
generateState?: () => string;
}
/**
* Result of {@link OAuthClient.buildAuthorizationUrl}.
*/
export interface AuthorizationUrlResult {
/** The full authorize URL to redirect / `window.open` to. */
url: string;
/** The `state` value the auth server will echo back; used for CSRF check. */
state: string;
}
/**
* OAuth 2.0 Authorization Code + PKCE client.
*
* @remarks
* Storage layout under the supplied {@link TokenStore} (all keys namespaced):
* - `oauth:tokens:{clientId}` → access token record
* - `oauth:refresh:{clientId}` → refresh token record (no expiry)
* - `oauth:verifier:{state}` → in-flight PKCE verifier (10 min TTL)
*
* @category Auth
*/
export declare class OAuthClient {
#private;
constructor(config: OAuthClientConfig);
/** Build the authorize URL and persist the PKCE verifier keyed by `state`. */
buildAuthorizationUrl(opts?: {
state?: string;
scope?: string;
extraParams?: Record<string, string>;
}): Promise<AuthorizationUrlResult>;
/**
* Handle the redirect-callback URL. Validates `state`, retrieves the saved
* verifier, exchanges the authorization code + verifier for tokens, and
* persists them. Returns the access {@link TokenRecord}.
*/
handleCallback(callbackUrl: string): Promise<TokenRecord>;
/**
* Exchange a stored refresh token for a fresh access token. Throws if no
* refresh token is available.
*/
refresh(): Promise<TokenRecord>;
/**
* Get the current access token if valid (refreshing first if expired and a
* refresh token is available). Returns `null` when no usable token exists.
*/
getAccessToken(): Promise<string | null>;
/** Forget tokens (logout). Does NOT call any remote revocation endpoint. */
signOut(): Promise<void>;
}