Skip to content

This site describes solve-engine as it is on main: 2.43.0, which npm does not have yet. npm installs 2.40.0, so a page may show an answer that version does not give yet.

CurrencyExchangeService

Defined in: packages/engine/src/uom/CurrencyExchange.ts:97

Caches exchange rates fetched from an external source.

Rates are global market data rather than per-engine configuration, which is why one instance is shared. Two engines with private copies would fetch the same endpoint twice and could disagree about one pair at one moment. See engine/EngineContext.ts.

new CurrencyExchangeService(): CurrencyExchangeService;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:237

CurrencyExchangeService

clearRates(): void;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:425

Drop every cached/primed rate table.

Mainly for test isolation: sharedCurrencyExchange is a module-level singleton, so a rate primed or fetched by one test can silently leak into a later test in the same file. Also usable in production if a caller ever wants to force a full re-fetch.

void


convert(
value,
from,
to
): Promise<number>;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:479

Convert value from from to to using a freshly-fetched live rate (see getRate).

ParameterType
valuenumber
fromstring
tostring

Promise<number>


convertSync(
value,
from,
to
): number | null;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:520

Synchronous conversion using cached rates only Returns null if rate not in cache

ParameterType
valuenumber
fromstring
tostring

number | null


getAllRates(): Record<string, number> | null;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:493

Get all currently cached fresh rates, keyed “FROM:TO”.

Where two fresh tables for one base give a rate for the same code, the one stored most recently is listed, the rate a conversion through that base would use.

Record<string, number> | null

Snapshot of fresh live rates, or null when none are cached.


getRate(
from,
to,
signal?
): Promise<number>;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:263

Fetch the live exchange rate for converting 1 unit of from into to.

Routes cryptocurrency codes (see CRYPTO_IDS) to CoinGecko and everything else to Frankfurter (ECB reference rates, fiat-only). On success, caches the whole returned rate table for from so subsequent lookups, including cross-pairs via triangulation, can be served synchronously by getRateSync within the freshness window.

ParameterType
fromstring
tostring
signal?AbortSignal

Promise<number>

If the currency code is unrecognized or the fetch fails/times out.


getRateSync(from, to): number | null;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:439

Synchronous rate lookup: 1 for same-currency pairs, a cached LIVE rate if one was fetched within RATE_FRESHNESS_MS, otherwise null, callers fall through to the async fetch path and the expression shows Pending until real data arrives.

There is deliberately no hardcoded fallback table: a stale made-up rate presented as a real conversion is worse than a Pending state.

ParameterType
fromstring
tostring

number | null


hasRates(): boolean;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:512

Check whether any fresh live rates are currently cached.

boolean


isCurrency(code): boolean;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:547

Check whether code is a recognized currency code: any active ISO 4217 code, or one of the cryptocurrencies in CRYPTO_IDS.

This used to be a hand-written list of forty-six codes, which meant $100 in UAH returned an unconverted hundred dollars rather than saying it could not convert. Answering from the standard rather than from whichever codes happened to get added is what stops that class of bug.

Recognising a code is not the same as having a rate for it. That is answered later, by the exchange provider; conflating the two is what produced the silent failure.

Remembered per spelling (see currencyAnswers), because the VM asks on every unit-bearing instruction and the answer for a spelling never changes.

ParameterType
codestring

boolean


primeRates(
base,
rates,
options?
): void;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:408

Seed a base rate table without a network fetch.

Intended for tests and for a host’s own offline rates; the engine’s own live data comes from getRate. Seeded rates obey the same freshness window as fetched ones.

A conversion through a primed table records it as a primed source (see vm/Provenance.ts), named by options.provider so a host can say whose rates they are. The table sits beside the engine’s own live tables rather than replacing them, and a live fetch for the same base does not replace it (#649); priming the same provider and base again does.

ParameterTypeDescription
basestringBase currency code (e.g. “USD”).
ratesRecord<string, number>Map of currency code → rate relative to the base.
optionsPrimeRatesOptionsThe provider’s name and when its rates were published.

void


rateSourcesSync(from, to):
| readonly ValueSource[]
| undefined;

Defined in: packages/engine/src/uom/CurrencyExchange.ts:463

Where the rate getRateSync would use for this pair came from.

The same lookup, in the same order, so the record always describes the table that actually served the conversion. undefined for a same-currency pair (no rate is involved) and for a pair no fresh table covers (the conversion has no rate either, and reports that itself).

The list for one pair from one table is built once and handed out again, so converting the same pair on every keystroke allocates nothing.

ParameterType
fromstring
tostring

| readonly ValueSource[] | undefined

A one-record list naming the provider, how the rate was obtained, when, and the pair as FROM/TO.