/** * @pwngh/economy-lab * * Copyright (c) Preston Neal * * This source code is licensed under the MIT license found in the * LICENSE.md file in the root directory of this source tree. * * @license MIT */ import type { EnvMap } from './env.js'; import type { Config, Secrets } from './config.js'; import type { RatesConfig } from './from-env.js'; import type { Economy } from './economy.js'; import type { FeePolicy } from './contract.js'; import type { Worker } from './worker/index.js'; import type { Anchor, Cache, Clock, Digest, Dispatcher, Ids, Logger, Meter, PayeeDirectory, Ports, Processor, Rates, Scheduler, Signer, Store } from './ports.js'; export { createEconomy } from './economy.js'; export { createSubmitCoalescer } from './batching.js'; export type { CoalescerOptions, SubmitCoalescer } from './batching.js'; export { createWorker, DEFAULT_SWEEP_LIMIT } from './worker/index.js'; export type { Worker, SweepRequest, WorkerDefaults, } from './worker/index.js'; export { createServer } from './server.js'; export type { FetchHandler, ServerOptions, ServerPorts } from './server.js'; export { systemRuntime } from './runtime.js'; export type { Ports } from './ports.js'; export { DEV_RATES } from './from-env.js'; export type { RatesConfig } from './from-env.js'; export { spendable, earned, promo, currency, SYSTEM, ownerOf, isWalletAccount, } from './accounts.js'; export { toAmount, credits, usd, decodeAmount, encodeAmount, decodeAmountWire, add, negate, zero, compare, isZero, isNegative, isAmount, convertFloor, convertCeil, SCALE, } from './money.js'; export { credit, debit } from './ledger.js'; export type { Leg } from './ports.js'; export { topUp, spend, refund, clawback, requestPayout, subscribe, cancelSubscription, grantEntitlement, revokeEntitlement, grantPromo, adjust, reverse, reversePayout, settlePayout, idempotencyKey, } from './operation.js'; export { userActor, systemActor, operatorActor } from './actor.js'; export { defaultConfig, loadConfig, mergeConfig, inspectConfig, maintenanceWindow, CONFIG_KEYS, SECRET_KEYS, DECLINE_KEYS, } from './config.js'; export type { Config, Secrets } from './config.js'; export { EconomyError, ERROR_CODES, normalizeError, statusForError, REJECTION_CODES, REJECTION_SPEC, isSuccess, isRejection, requireSuccess, } from './errors.js'; export type { ErrorCode, RejectionCode } from './errors.js'; export type { Economy } from './economy.js'; export type { EnvMap } from './env.js'; export { CAPACITY_THRESHOLDS } from './contract.js'; export type { Operation, Outcome, BatchOutcome, Success, Rejection, RejectionDetail, Transaction, Principal, Recipient, EntitlementAttributes, FeePolicy, ProveReport, HealthReport, EconomyStatus, CapacityReport, } from './contract.js'; export type { Amount, Currency } from './money.js'; export type { AccountRef } from './accounts.js'; export type { BitsetOptions } from './adapters/entitlement-bitset.js'; export type { CallOptions, Range, Statement, Checkpoint, StoredLink, Rate, } from './ports.js'; export { allInvariantsHold, proveEconomy, findByHash } from './integrity.js'; export type { ProvePorts } from './integrity.js'; export { paginate } from './paginate.js'; export { parseExport, verifyExport } from './verify-export.js'; export type { ParsedExport, VerifyReport } from './verify-export.js'; export { EXPORT_FORMAT } from './economy.js'; export type { Signer, Processor, Rates, Clock, Ids, Digest, Store, Dispatcher, Logger, Meter, Anchor, Cache, RateLimiter, RateVerdict, Scheduler, } from './ports.js'; export type { Saga, Posting, EconomyEvent } from './ports.js'; /** * Overrides for {@link openPorts} — every field optional. A port field set to `false` is an * explicit decline, which production accepts where a bare omission is an error (see the absence * policy on {@link preflight}). `rates` takes a live source or the exact integer knobs. */ export type PortsInit = { readonly store?: Store; readonly clock?: Clock; readonly ids?: Ids; readonly digest?: Digest; readonly signer?: Signer; readonly processor?: Processor; readonly rates?: Rates | RatesConfig; readonly pricing?: FeePolicy; readonly logger?: Logger; readonly meter?: Meter; readonly config?: Partial; readonly secrets?: Partial; readonly cache?: Cache | false; readonly dispatcher?: Dispatcher | false; readonly payees?: PayeeDirectory | false; readonly anchor?: Anchor | false; readonly scheduler?: Scheduler | false; }; /** Everything {@link boot} accepts: the {@link PortsInit} overrides plus the worker switch. */ export type BootInit = PortsInit & { /** Default true; false boots the API-process shape with `worker: null`. */ readonly worker?: boolean; }; /** * One {@link preflight} finding. Severity 'error' is exactly what {@link openPorts} refuses; * 'warning' is advisory and blocks nothing. */ export type PreflightIssue = { /** Stable machine code, e.g. 'secret.missing' or 'port.absent'. */ readonly code: string; /** The env name or port slot at fault, e.g. 'DATABASE_URL' or 'dispatcher'. */ readonly path: string; /** Human-readable, states the fix. */ readonly message: string; readonly severity: 'error' | 'warning'; }; /** The runtime quartet a production host wires from one signing key via {@link systemRuntime}. */ export type Runtime = Pick; /** * What {@link describeEnv} returns: the concrete adapter each env knob selects — kind and URL — * before any driver loads, plus secret presence (never values). 'declined' versus 'missing' * mirrors the production absence policy on {@link preflight}. */ export type EnvDescription = { readonly production: boolean; readonly store: { readonly kind: 'memory' | 'postgres' | 'mysql' | 'unsupported'; readonly url: string | null; }; readonly cache: { readonly kind: 'none' | 'redis'; readonly url: string | null; }; readonly dispatcher: { readonly kind: 'in-process' | 'http' | 'sqs' | 'declined' | 'missing'; readonly url: string | null; }; readonly processor: { readonly kind: 'memory' | 'http'; readonly url: string | null; }; readonly payees: 'set' | 'declined' | 'missing'; readonly anchor: 'set' | 'declined' | 'missing'; readonly secrets: { readonly webhook: 'missing' | 'set'; readonly signing: 'missing' | 'set'; readonly signingPriors: number; }; readonly velocityWindowMs: number | null; }; /** * What {@link boot} returns: the resolved ports, the economy assembled over them, and the worker * bound to that same economy — null when the init declined it with `worker: false`. */ export type Boot = { readonly ports: Ports; readonly economy: Economy; readonly worker: Worker | null; }; /** * Validates `env` plus `init` without constructing anything: every issue here with severity * 'error' is exactly what {@link openPorts} would throw on. Run it at deploy time so a bad * config fails on a health check, not on the first request. Outside production only the store * scheme and the shape of init-supplied ports are checked, since the dev defaults fill * everything else. */ export declare function preflight(env?: EnvMap, init?: PortsInit): readonly PreflightIssue[]; /** * Reports what a given env and init would wire, presence only — no secret values, no * connections. `declined` versus `missing` mirrors the production absence policy. */ export declare function describeEnv(env?: EnvMap, init?: PortsInit): EnvDescription; /** * The sole env-to-bag path: loads Config and Secrets (init wins per field, both frozen), builds * the runtime and external ports with dev stand-ins outside production, opens the store the * `DATABASE_URL` scheme names, and applies the production absence policy. Everything * {@link preflight} flags as an error throws here as one CONFIG.INVALID. * * @example * const ports = await openPorts(process.env, { * config: { platformFeeBps: 3000 }, * dispatcher: false, // this deployment runs without outbox delivery, on purpose * }); * const economy = createEconomy(ports); */ export declare function openPorts(env?: EnvMap, init?: PortsInit): Promise; /** * The day-one door: openPorts, createEconomy, and (unless `worker: false`) a worker bound to * that economy over the same bag. Anything a bad env would make {@link openPorts} throw, boot * throws too, so a misconfigured deploy dies at startup. * * @example * const { economy, worker } = await boot(process.env); * const stop = worker?.start(30_000); // payout, outbox, and checkpoint sweeps every 30s * const outcome = await economy.submit( * topUp({ idempotencyKey: 'idem_1', actor: systemActor('store'), userId: 'usr_1', * amount: credits(1_200), source: 'card' }), * ); */ export declare function boot(env?: EnvMap, init?: BootInit): Promise; /** * A finished in-memory Ports bag for tests and quickstarts: memory store, dev rates and fees, * in-memory processor, and a real Ed25519 signer seeded from `signingKey`. Sync, no env. */ export declare function memoryPorts(options: { readonly signingKey: string; readonly config?: Partial; readonly secrets?: Partial; readonly store?: Store; }): Ports;