@coinbase/cdp-sdk
Version:
SDK for interacting with the Coinbase Developer Platform Wallet API
174 lines • 6.43 kB
TypeScript
import type { Network } from "@x402/core/types";
/**
* An asset identifier — typically an ERC-20 contract address or a Solana SPL mint address.
*/
export type Asset = string;
/**
* A wallet address. Normalization (e.g. lower-casing EVM addresses) is handled in `./normalize.ts`.
*/
export type Address = string;
/**
* A payment amount in base units (the smallest denomination for the asset),
* optionally scoped to a specific asset.
*
* - `atomic` is a non-negative integer. Strings are accepted for convenience.
* - `asset` is optional but recommended. When set, caps and totals are scoped to that asset.
*
* @example
* ```ts
* const cap: Amount = {
* atomic: 1_000_000n,
* asset: "0x036cbd53842c5426634e7929541ec2318f3dcf7e",
* };
* ```
*/
export type Amount = {
atomic: bigint | string;
asset?: Asset;
};
/**
* A duration expressed as either a number of milliseconds or one of the
* shorthand strings: `"500ms"`, `"30s"`, `"5m"`, `"1h"`, `"24h"`, `"7d"`.
*/
export type Duration = number | string;
/**
* Typed string constants for every {@link SpendControlErrorCode} value.
*/
export declare const SpendControlErrorCodes: {
readonly PER_PAYMENT_CAP: "per_payment_cap";
readonly CUMULATIVE_CAP: "cumulative_cap";
readonly ALREADY_APPLIED: "already_applied";
readonly CONFIGURATION_INVALID: "configuration_invalid";
readonly LEDGER_CAPACITY_EXCEEDED: "ledger_capacity_exceeded";
readonly NETWORK_NOT_ALLOWED: "network_not_allowed";
readonly ASSET_NOT_ALLOWED: "asset_not_allowed";
readonly PAYEE_NOT_ALLOWED: "payee_not_allowed";
readonly AMOUNT_UNPARSEABLE: "amount_unparseable";
readonly MALFORMED_REQUIREMENT: "malformed_requirement";
readonly MAX_TIMEOUT_EXCEEDED: "max_timeout_exceeded";
};
/**
* Error code for {@link SpendControlError}.
*/
export type SpendControlErrorCode = (typeof SpendControlErrorCodes)[keyof typeof SpendControlErrorCodes];
/**
* Structured context attached to a {@link SpendControlError}.
*/
export type SpendControlErrorDetails = {
attempted?: string;
limit?: string;
asset?: Asset;
network?: Network | string;
payTo?: Address;
input?: unknown;
};
/**
* Thrown when a payment is blocked by the configured spend controls.
*/
export declare class SpendControlError extends Error {
/** - Identifies the type of violation. */
readonly code: SpendControlErrorCode;
/** - Structured context for the error (always defined, may be empty). */
readonly details: SpendControlErrorDetails;
/**
* Creates a SpendControlError with the given code and message.
*
* @param code - The error code identifying the violation type.
* @param message - Human-readable error message.
* @param details - Optional structured context for the error.
*/
constructor(code: SpendControlErrorCode, message: string, details?: SpendControlErrorDetails);
}
/**
* A single recorded payment in the spend ledger.
*/
export type SpendLedgerEntry = {
atomicAmount: bigint;
asset: Asset;
network: Network;
payTo: Address;
at: number;
};
/**
* Storage interface for the spend ledger.
*
* **The default implementation is in-memory and process-local.** For
* production workloads where the cap must be enforced across restarts or
* replicas, implement this interface against a shared durable backend (Redis,
* Postgres, DynamoDB, etc.) and pass an instance via {@link SpendControls.store}.
*/
export interface SpendStore {
/** - Optional: return the current entry count. */
size?(): Promise<number>;
/** - Returns all entries currently held by the store. */
load(): Promise<SpendLedgerEntry[]>;
/** - Adds a single entry to the store. */
append(entry: SpendLedgerEntry): Promise<void>;
/** - Optional: drop entries older than `olderThanMs`. */
prune?(olderThanMs: number): Promise<void>;
/** - Optional: drop the oldest `n` entries. */
dropOldest?(n: number): Promise<void>;
/** - Optional: remove a specific entry by its field values. */
removeEntry?(entry: SpendLedgerEntry): Promise<void>;
}
/**
* Configuration for spend controls. All fields are optional.
*
* @example
* ```ts
* const USDC_BASE = "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913";
* const controls: SpendControls = {
* maxAmountPerPayment: { atomic: 10_000n, asset: USDC_BASE },
* maxCumulativeSpend: { atomic: 50_000n, asset: USDC_BASE },
* maxCumulativeSpendWindow: "24h",
* allowedNetworks: ["eip155:8453"],
* };
* ```
*/
export type SpendControls = {
/**
* Hard per-payment cap. If `asset` is set the cap only applies to payments in
* that asset — payments in any other asset are left uncapped by this field
* (atomic units are not comparable across assets with different decimals).
* Omit `asset` to cap every payment by raw atomic amount.
*/
maxAmountPerPayment?: Amount;
/**
* Rolling cumulative cap. Unlike `maxAmountPerPayment`, `asset` is required
* (enforced when spend controls are applied) because cross-asset atomic units
* cannot be summed.
*/
maxCumulativeSpend?: Amount;
maxCumulativeSpendWindow?: Duration;
allowedNetworks?: Network[];
allowedAssets?: Asset[];
allowedPayees?: Address[];
onApproachingLimit?: (spent: Amount, limit: Amount) => void;
approachingLimitThresholds?: number[];
maxLedgerEntries?: number;
store?: SpendStore;
};
/**
* Converts a {@link Duration} to milliseconds.
*
* Accepts a non-negative number (already in milliseconds) or a shorthand
* string: `"500ms"`, `"30s"`, `"5m"`, `"1h"`, `"24h"`, `"7d"`.
*
* @param input - The duration value to parse.
* @returns The duration in milliseconds.
* @throws {SpendControlError} `"amount_unparseable"` if the input can't be parsed.
*/
export declare function parseDuration(input: Duration): number;
/**
* Parses an amount into `{ atomic: bigint; asset?: string }`.
*
* @param value - The amount value to parse (bigint, string, or Amount object).
* @param asset - Optional asset identifier to scope the amount.
* @returns Parsed amount with atomic bigint value and optional asset.
* @throws {SpendControlError} `"amount_unparseable"` on bad input.
*/
export declare function parseAmount(value: bigint | string | Amount, asset?: Asset): {
atomic: bigint;
asset?: string;
};
//# sourceMappingURL=types.d.ts.map