SDK Reference
Complete TypeScript API reference for @ledgergate/ledgergate-sdk — every exported function, class, type, and constant.
Installation
npm install @ledgergate/ledgergate-sdk
# pnpm add @ledgergate/ledgergate-sdk
# yarn add @ledgergate/ledgergate-sdkRequires Node.js 18+. Framework packages (express, fastify) are optional peer dependencies — install only what you use.
createLedgergateSdk(config)
The main entry point. Validates config, applies defaults, and initialises the event queue.
import { createLedgergateSdk } from "@ledgergate/ledgergate-sdk";
const sdk = createLedgergateSdk({
apiKey: process.env.LEDGERGATE_API_KEY!,
});Parameters
| Param | Type | Description |
|---|---|---|
config | SdkConfigInput | SDK configuration — only apiKey is required |
Returns SdkInstance
Throws ZodError if the supplied configuration is invalid.
See Configuration for the full options reference.
SdkInstance
The object returned by createLedgergateSdk().
interface SdkInstance {
readonly config: SdkConfig;
readonly queue: EventQueue;
shutdown(): Promise<void>;
}| Member | Description |
|---|---|
config | Fully resolved configuration with all defaults applied |
queue | The in-memory event queue |
shutdown() | Flushes remaining events and tears down the queue. Idempotent. |
Adapters
createExpressMiddleware(sdk)
Returns an Express RequestHandler that wires the SDK into the request/response lifecycle.
import { createExpressMiddleware } from "@ledgergate/ledgergate-sdk";
app.use(createExpressMiddleware(sdk));After mounting, every request has an x402Context attached to res.locals.
fastifyLedgergate
Fastify plugin (Fastify 5, wrapped with fastify-plugin for global hook scope).
import { fastifyLedgergate } from "@ledgergate/ledgergate-sdk";
await app.register(fastifyLedgergate, { sdk });After registration, every request has an x402Context property on FastifyRequest.
Options: FastifyLedgergateOptions
interface FastifyLedgergateOptions {
sdk: SdkInstance;
}Event Queue
EventQueue
interface EventQueue {
enqueue(event: AnalyticsEvent): void;
flush(): Promise<void>;
shutdown(): Promise<void>;
size(): number;
}| Method | Description |
|---|---|
enqueue(event) | Adds an event to the buffer. Triggers an immediate send if batchSize is reached; otherwise schedules a timed flush. No-ops silently after shutdown(). |
flush() | Forces an immediate send of all buffered events. Awaitable. |
shutdown() | Cancels the flush timer, waits for any in-flight send, then flushes remaining events. Idempotent. |
size() | Returns the current number of events waiting in the buffer. |
Event Builders
Higher-level helpers that construct validated AnalyticsEvent objects from SDK context.
buildRequestReceivedEvent(context)
function buildRequestReceivedEvent(context: RequestContext): AnalyticsEventbuildPaymentRequiredEvent(context, payment, response)
function buildPaymentRequiredEvent(
context: RequestContext,
payment: X402Metadata,
response: ResponseData
): AnalyticsEventbuildPaymentVerifiedEvent(context, payment, response)
function buildPaymentVerifiedEvent(
context: RequestContext,
payment: X402Metadata,
response: ResponseData
): AnalyticsEventbuildPaymentFailedEvent(context, payment, response)
function buildPaymentFailedEvent(
context: RequestContext,
payment: X402Metadata,
response: ResponseData
): AnalyticsEventbuildRequestCompletedEvent(context, response, payment?)
function buildRequestCompletedEvent(
context: RequestContext,
response: ResponseData,
payment?: X402Metadata
): AnalyticsEventCore Utilities
createRequestContext(options)
function createRequestContext(options: CreateContextOptions): RequestContextBuilds an immutable per-request context: generates a UUID, starts the high-resolution timer, extracts and hashes the client IP, and redacts headers.
interface CreateContextOptions {
method: string;
path: string;
headers: Record<string, string | string[] | undefined>;
remoteAddress?: string;
redaction: RedactionConfig;
sampled: boolean;
}captureResponseData(context, statusCode)
function captureResponseData(
context: RequestContext,
statusCode: number
): ResponseDataCalculates latency from the context timer and returns a ResponseData object.
shouldSample(rate)
function shouldSample(rate: number): booleanReturns true with the given probability (0–1). Called once per request at middleware entry.
createTimer()
function createTimer(): Timer
interface Timer {
elapsed(): number; // milliseconds since timer creation
}getTimestamp()
function getTimestamp(): string // ISO 8601Privacy Utilities
extractClientIp(headers, directIp?)
function extractClientIp(
headers: Record<string, string | string[] | undefined>,
directIp?: string
): string | undefinedChecks X-Forwarded-For → X-Real-IP → directIp in order and returns the first non-empty value.
hashIp(ip, salt?)
function hashIp(ip: string, salt?: string): stringSHA-256 hashes salt + ip and returns the first 16 hex characters.
isSensitiveHeader(name)
function isSensitiveHeader(headerName: string): booleanCase-insensitive check against the built-in sensitive header list.
redactHeaders(headers, allowlist?)
function redactHeaders(
headers: Record<string, string | string[] | undefined>,
allowlist?: readonly string[]
): Record<string, string>Returns a new headers object with sensitive header values replaced by "[REDACTED]". Keys not in allowlist and matching the sensitive header list are redacted. Array values are joined with ", ".
x402 Detection
detectX402(statusCode, headers, config?, body?)
function detectX402(
statusCode: number,
headers: Record<string, string | string[] | undefined>,
config?: X402DetectionConfig,
body?: Record<string, unknown>
): X402Metadata | undefinedInspects a response for x402 payment signals. Returns X402Metadata if a 402 status code is present or any configured payment field is found; otherwise returns undefined.
isPaymentRequired(statusCode)
function isPaymentRequired(statusCode: number): booleanReturns true if statusCode === 402.
parsePaymentHeaders(headers, fieldMapping?)
function parsePaymentHeaders(
headers: Record<string, string | string[] | undefined>,
fieldMapping?: PaymentFieldMapping
): Partial<X402Metadata>parsePaymentBody(body, fieldMapping?)
function parsePaymentBody(
body: Record<string, unknown>,
fieldMapping?: PaymentFieldMapping
): Partial<X402Metadata>applyX402DetectionDefaults(input?)
function applyX402DetectionDefaults(
input?: Partial<X402DetectionConfig>
): X402DetectionConfigConfig Utilities
parseConfig(input)
function parseConfig(input: SdkConfigInput): SdkConfigValidates with Zod and applies all defaults. Throws ZodError on invalid input.
safeParseConfig(input)
function safeParseConfig(input: unknown): z.SafeParseReturnType<SdkConfigInput, SdkConfig>Non-throwing variant — returns a Zod safe-parse result.
Types
SdkConfig
interface SdkConfig {
readonly apiKey: string;
readonly endpoint: string;
readonly redaction: RedactionConfig;
readonly transport: TransportConfig;
readonly sampleRate: number;
readonly debug: boolean;
readonly x402: X402DetectionConfig;
}RedactionConfig
interface RedactionConfig {
readonly hashIp: boolean;
readonly allowedHeaders: readonly string[];
readonly ipHashSalt?: string;
}TransportConfig
interface TransportConfig {
readonly batchSize: number;
readonly flushIntervalMs: number;
readonly maxRetries: number;
readonly timeoutMs: number;
}RequestContext
interface RequestContext {
readonly id: string; // UUID v4 — shared by all events for this request
readonly timer: Timer;
readonly method: string; // uppercase HTTP method
readonly path: string; // normalised path, no query string
readonly headers: Readonly<Record<string, string>>;
readonly clientIpHash?: string;
readonly sampled: boolean;
}ResponseData
interface ResponseData {
statusCode: number;
latencyMs: number;
}AnalyticsEvent
interface AnalyticsEvent {
schemaVersion: "1.0";
eventId: string;
eventType: string;
timestamp: string;
request: {
id: string;
method: string;
path: string;
statusCode?: number;
latencyMs?: number;
clientIpHash?: string;
headers?: Record<string, string>;
};
payment?: {
isRequired: boolean;
address?: string;
amount?: string;
network?: string;
token?: string;
status?: "required" | "verified" | "failed";
};
sdk: { name: string; version: string };
}X402Metadata
interface X402Metadata {
readonly isPaymentRequired: boolean;
readonly paymentAddress?: string;
readonly paymentAmount?: string;
readonly paymentNetwork?: string;
readonly paymentToken?: string;
readonly paymentStatus?: "required" | "verified" | "failed";
}X402DetectionConfig
interface X402DetectionConfig {
readonly source: "header" | "body" | "both";
readonly fieldMapping: Required<PaymentFieldMapping>;
}PaymentFieldMapping
interface PaymentFieldMapping {
readonly address?: string; // default: "x-payment-address"
readonly amount?: string; // default: "x-payment-amount"
readonly network?: string; // default: "x-payment-network"
readonly token?: string; // default: "x-payment-token"
readonly status?: string; // default: "x-payment-status"
}EventType
const EventType = {
REQUEST_RECEIVED: "request.received",
PAYMENT_REQUIRED: "payment.required",
PAYMENT_VERIFIED: "payment.verified",
PAYMENT_FAILED: "payment.failed",
REQUEST_COMPLETED:"request.completed",
} as const;PaymentStatus
const PaymentStatus = {
REQUIRED: "required",
VERIFIED: "verified",
FAILED: "failed",
} as const;Zod Schemas
Use these to validate event data in your own tooling or tests:
| Export | Validates |
|---|---|
SdkConfigSchema | Full SDK config input |
RedactionConfigSchema | redaction sub-object |
TransportConfigSchema | transport sub-object |
X402DetectionConfigSchema | x402 sub-object |
AnalyticsEventSchema | A single analytics event |
Constants
| Export | Value | Description |
|---|---|---|
SDK_VERSION | "1.0.0" | Current SDK version |
SDK_NAME | "ledgergate-sdk" | SDK name included in every event |