Running it
Environments, storage, retries, tracing, and what self-hosting actually involves.
Environments
https://api.generalliquidity.com # live
https://sandbox.api.generalliquidity.com # test networksSame surface, same decisions, same refusals. Build against the sandbox and change one line. A refusal in the sandbox reads exactly like a refusal in production, which is the thing you actually want to test.
Storage
The reference store is in-memory and dies with the process, which is correct for tests and wrong for everything else. Two durable backends carry mandates, the hash-linked record, settlement history and the idempotency records that stop a retried payment settling twice.
- SQLite
- Synchronous, no npm dependencies, the default for a single node.
- Postgres
- Against an injected client, so no driver is a hard dependency. Promise-returning, because the network is.
Retries
Idempotency is enforced server side, keyed on the instruction's own key. Send the same key twice and you get the original answer rather than a second payment.
- Retry timeouts, rate limits and server errors, with the same key.
- Never retry a refusal. It is deterministic and the answer will not change.
- A payment waiting for a person is not a failure. Park it.
Tracing
The tracing seam in the core depends on nothing. Two ways to get spans out: hand them to an OpenTelemetry setup you already run, or post them straight to a collector with no OpenTelemetry package installed anywhere.
Request authentication
Bearer credentials with sender-constrained proof of possession are supported, so a captured token is not enough on its own. The issuing and verifying sides share one implementation, which is what stops them drifting apart.
Self-hosting
The whole thing runs in your own infrastructure, with the record staying on your side. The composition root is a single place where the concrete pieces are wired together, so what your deployment is actually running is inspectable rather than implied.
The server holds the only settle primitive and never holds a rail credential: those live inside the rail implementations you supply. That boundary is the reason self-hosting does not weaken any of the properties described elsewhere in these docs.