# @suaveplan/currency-provider-virtual - Universal in-memory virtual / game currency provider for @suaveplan/currency. Programmable rate table (setRate / removeRate / clear) with optional Clock injection for deterministic timestamps. No HTTP, no API key, no FetchLike. Throws typed CurrencyProviderError(UNKNOWN_CURRENCY) when the requested base is absent. Sibling of the @suaveplan/currency-providers slim core. In-memory, programmable virtual / game currency provider for `@suaveplan/currency`. Sibling of the `@suaveplan/currency-providers` slim plugin core. No HTTP, no API key, no `FetchLike` — purely an operator-controlled rate table backed by a nested `Map`. Use it for game economies, loyalty points, internal test rates, or any rate source you want to seed and mutate deterministically in process. ## Documentation tree - [error-codes](./src/error-codes/error-codes.md) — This module surfaces the single `CURRENCY_PROVIDER.UNKNOWN_CURRENCY` code that `@suaveplan/currency-provider-virtual` r… - [error-codes](./src/error-codes/error-codes.md) — This module surfaces the single `CURRENCY_PROVIDER.UNKNOWN_CURRENCY` code that `@suaveplan/currency-provider-virtual` r… - [provider](./src/provider/provider.md) — `VirtualCurrencyProvider` is an in-memory, programmable rate-source implementation of `@suaveplan/currency`'s `Currency… - [provider](./src/provider/provider.md) — `VirtualCurrencyProvider` is an in-memory, programmable rate-source implementation of `@suaveplan/currency`'s `Currency… ## Install ```bash bun add @suaveplan/currency-provider-virtual @suaveplan/currency-providers @suaveplan/currency ``` ## Quick start ```ts import { CurrencyConverter } from "@suaveplan/currency"; import { CurrencyProviderRegistry } from "@suaveplan/currency-providers"; import { VirtualCurrencyProvider } from "@suaveplan/currency-provider-virtual"; const virtual = new VirtualCurrencyProvider({ defaultBase: "USD", initialRates: [ { from: "USD", to: "GOLD", rate: 100 }, { from: "USD", to: "GEMS", rate: 500 }, ], }); const registry = new CurrencyProviderRegistry(); registry.register(virtual); const converter = new CurrencyConverter({ provider: registry.get("virtual-currency") }); const rate = await converter.getRate("USD", "GOLD"); // 100 // Operators can mutate at any time. virtual.setRate("USD", "GOLD", 110); virtual.removeRate("USD", "GEMS"); ``` ## Features - Programmable rate table: `setRate(from, to, rate)` (upsert), `removeRate(from, to)` (idempotent), `clear()`, `hasRate(from, to)`, `getRate(from, to)`, `listCurrencies(): readonly string[]` (sorted snapshot). - `fetchRates(options?)` returns directed rates stored under the requested `base`, optionally filtered by `options.targets`. - Typed `CurrencyProviderError(UNKNOWN_CURRENCY)` raised when the requested base has no rates stored (no triangulation; the table can be empty). - Optional `Clock` injection (`@suaveplan/types`) for deterministic `RateFetchResult.timestamp` values under `FakeClock`-driven tests. - Implements the `CurrencyProvider` contract from `@suaveplan/currency` with `supportsVirtual: true`, `supportsFiat: false`, `supportsCrypto: false`, `name: "virtual-currency"`. - Universal — runs unchanged on Node 18+, Bun, browsers, and Web Workers. Zero browser/Node/DOM APIs in production source. - `sideEffects: false` — the constructor never mutates global state (no `@suaveplan/money` `registerCurrency` integration). - Explicit named barrels; two subpath exports; 100/100/100/100 istanbul coverage. ## Modules - [`src/error-codes/error-codes.md`](./src/error-codes/error-codes.md) — `VIRTUAL_CURRENCY_PROVIDER_CODES`, `VIRTUAL_PROVIDER_NAME`, and the `makeUnknownCurrencyError(base)` helper. - [`src/provider/provider.md`](./src/provider/provider.md) — `VirtualCurrencyProvider` class + `VirtualCurrencyProviderConfig` and `VirtualRateEntry` types. ## Status `0.1.0` (pre-graduation). Sibling of the `@suaveplan/currency-providers` slim core landed on 2026-05-17. See the design proposal for the migration record. The cross-cutting architecture for the `@suaveplan/currency-provider-*` family is documented in the design document.