Digital Asset Payments Infrastructure: Building for Reliability and Compliance
By Formance Staff
Guide
Embedded Finance
Loading article content
Loading table of contents
Loading author
_FORMANCE LEDGER/
Build your digital asset payments infrastructure on Formance Ledger
Build your digital asset payments infrastructure on Formance Ledger: clone it from GitHub, run it locally, and post the detection and pending-to-available transactions against your own confirmation threshold.
Digital asset payments infrastructure, often called crypto payments infrastructure, moves roughly $390 billion a year in real-economy stablecoin payments. The teams running these rails carry the reconciliation discrepancy between what the blockchain records and what their ledgers show.
The reconciliation discrepancy opens when a duplicate blockchain notification credits a customer twice, or a custody provider's update lands after the core ledger has already recorded the transfer as complete.
Now the core ledger shows one balance, the custody provider shows another, and the shared on-chain wallet shows a third. No teams can explain the difference, and the daily regulatory safeguarding reconciliation is due by end of day.
Building a reliable, compliant digital asset payments infrastructure comes down to five ledger rules, four Service Level Objectives (SLOs), and one pause rule.
Where digital asset payments infrastructure fails
Failures happen at handoffs where information moves between platforms that do not trust each other: reading events off the blockchain, taking updates from custody providers, sending transactions to the blockchain, and correcting reconciliation breaks after the fact.
Reading events off the blockchain
The ledger has to decide whether a deposit report from a node is a new event or a repeat of an old one. Nodes re-send deposit reports on restart, on reconnect, and after chain reorganizations. The ledger cannot tell a real second deposit from a repeated first one without a stored check.
Taking updates from custody providers
A webhook can arrive late, twice, or out of order compared to the on-chain event it describes. Custody providers retry webhooks until they get an acknowledgment, so the same settlement update can land before, at the same time as, and after the chain event it points to.
Sending transactions back out to the blockchain
The ledger and the blockchain are not coordinated, and a timeout between them leaves money in a state neither system can describe. The debit sits on the ledger while the chain transaction may be waiting in the mempool, already mined, or dropped, and looking at either system alone will not tell you which.
Correcting reconciliation breaks after the fact
A person or a script "fixes" a break by writing a posting nobody can explain later. Manual fixes made under pressure to close the daily reconciliation are the hardest thing to audit, because they carry no link to the event that caused the break.
Each of the four handoffs needs rules to be enforced in the ledger database.
Five ledger invariants that enforce reliability and compliance at every boundary
Five ledger rules enforced at the database layer (a posting state machine, idempotency keys, reorg reversal, omnibus attribution atomic, and compliance data attached to the posting) give you reliable state changes at each handoff and a full audit trail for daily reconciliation.
Formance Ledger is the open-source, programmable core ledger that provides the primitives reliable and compliant rails depend on. It unifies fiat and digital assets with regulatory-grade traceability, enforces double-entry accounting at the database layer, and provides immutability and atomic multi-posting, giving customers the foundation to build all five rules on top.
1. Posting state machine mapping pending, available, failed, and reversed to confirmation depth
The posting state machine has four states: pending, available, failed, and reversed. A deposit enters as pending as soon as a node reports it and never jumps straight to available.
The deposit moves to available once confirmation depth is reached, to failed if the transaction is dropped before depth, and to reversed if the chain invalidates it after depth. Confirmation depth is the number of blocks mined on top of a transaction before the ledger treats it as final.
Debits and credits stay balanced in every state. Pending funds sit in a real account balance (@users:48213:wallet:pending), funded from the Ethereum omnibus account. A status column on a row cannot represent a pending balance, so the pending balance is a real balance the ledger can query, sum, and reconcile.
The two Numscript blocks below record a 2,500,000 USD Coin (USDC) deposit detected on Ethereum, then the move to available once confirmation depth is reached.
// STABLECOIN_DEPOSIT_DETECTED// Event: detect a 2,500,000 USDC deposit and attribute it to the user's pending balancesend [USDC/6 2500000000000] ( source = @external:ethereum:omnibus allowing unbounded overdraft destination = @users:48213:wallet:pending)set_tx_meta("event_type", "stablecoin_deposit_detected")set_tx_meta("transfer_id", "trf48213")set_tx_meta("tx_hash", "0x3f9a...c21e")set_tx_meta("detected_block", "21480355")set_tx_meta("chain", "ethereum")// STABLECOIN_DEPOSIT_SETTLED// Event: make the deposit available after the configured confirmation depth is reachedsend [USDC/6 2500000000000] ( source = @users:48213:wallet:pending destination = @users:48213:wallet:available)set_tx_meta("event_type", "stablecoin_deposit_settled")set_tx_meta("transfer_id", "trf48213")set_tx_meta("tx_hash", "0x3f9a...c21e")set_tx_meta("confirmations_at_settlement", "12")
2. Idempotency keys spanning the ledger write and the chain broadcast
An idempotency key has to cover the ledger write and the blockchain send together, because nothing coordinates between them.
A key that only deduplicates the ledger call protects half the operation. A withdrawal debits the customer's available account and then sends a transaction to the chain.
If the send times out, the debit exists, but nobody knows what happened on-chain because the transaction may be in the mempool, mined, or dropped. A retry based only on the ledger write will send a second transaction.
Only a chain-state lookup on the key's recorded transaction hash resolves this, and the ledger has to refuse any second send-posting until that lookup returns.
3. Reorg reversal handled as an append-only counter-posting
When a reorg invalidates a posting, the fix is a reversal: a new posting that cancels the original out, not an edit of it. Editing the original erases the only evidence the credit ever existed.
The counter-posting moves the amount from @users:48213:wallet:pending, or from @users:48213:wallet:available if it had reached that state, back to @external:ethereum:omnibus.
The metadata carries the original transaction hash and the block where the chain dropped it. The original posting stays, so you can query the ledger for what it believed at any point in time.
After the chain split above, this kind of counter-posting is exactly what operators needed for every transfer stuck on the orphaned blocks.
4. Omnibus attribution atomic with deposit detection
Moving funds across the omnibus boundary and attributing them to a specific customer must happen in one atomic transaction, or you'll get a reconciliation break later. A detected deposit without a customer to attribute it to is a failed write.
The on-chain omnibus balance has to equal the sum of pending plus available across every @users:*:wallet:* account attached to it at every reconciliation point. Any difference is a discrepancy.
5. Compliance evidence bound to the posting instead of filed beside it
Attaching the Travel Rule sender and receiver information to the posting that moves the money means a query for a single transfer returns both the compliance record and the money movement together.
The Financial Action Task Force (FATF) Travel Rule requires virtual asset service providers to "obtain, hold, and transmit specific originator and beneficiary information immediately and securely" when transferring virtual assets.
The workflow enforces one rule: a transfer missing required sender or receiver information stays in pending and cannot move to available.
Four SLOs that turn ledger rules into something a team can measure
Four SLOs, including chain-event-to-posting delay, reconciliation lag, exception time-to-owner, and post-incident recovery time, turn the five ledger rules into a measurable operational framework a team can own.
1. Chain-event-to-posting delay
The time between a node reporting a deposit and the pending posting being written. If this delay grows, customers see their deposit on the chain before the ledger acknowledges it, and support tickets arrive before reconciliation spots the problem.
Own it in the ingestion service and alert when p95 crosses a threshold the team agrees on.
2. Reconciliation lag
How old the last passing balance check is between the ledger, custody, and the chain. Every hour this lag grows is another hour a discrepancy can hide. Daily safeguarding rules do not accept "we were behind" as an answer.
Run the three-way check at least hourly and treat anything beyond a two- to four-hour lag as out of tolerance, well inside the daily cut-off.
3. Exception time-to-owner
How long a flagged break waits before a named person takes it on. A break with no owner drifts, gets rediscovered a day later, and becomes a manual fix.
High-severity breaks are typically measured in minutes to owner, with lower-severity breaks measured in hours but still resolved the same day.
Own it in the exception queue, with a named on-call rotation and an alert when any break sits unowned past the agreed window.
4. Recovery time after a rail incident
How long until every queued pending posting has moved to available or failed. During an incident, pending postings pile up, and the rail is not back until each one reaches a final state.
The recovery clock starts the moment block production resumes and confirmation depth begins moving again, not when the incident is first declared resolved.
Construct an incident runbook, and issue an alert when the queue isn't cleared within the recovery target after block production resumes.
The four SLOs give you detection and recovery targets with clear ownership.
The rail-pause rule for chain finality failures
Pause the rail when a chain's finality guarantees start to fail. The Rail-pause rule exists because every rule assumes confirmation depth is advancing.
Pending postings can only move to available when new blocks land on top of them, while reorg reversals can only be trusted when the chain is progressing. Idempotency lookups on transaction hashes only return meaningful state when nodes are in sync.
When block production stalls or nodes disagree on what's final, those assumptions break, and any ledger writes become guesses about a chain state nobody can verify.
Pausing the rail keeps the infrastructure honest under those conditions. Outbound postings stop so the ledger doesn't record transactions into a chain it can't confirm. Incoming events queue as pending so no unverifiable credit reaches a customer balance. No new settlements are released until depth starts moving again.
The rail resumes when confirmation depth begins advancing at a normal rate, and that is when SLO 4's recovery clock starts.
Checklist for building reliable and compliant digital asset payments infrastructure
Building reliable and compliant digital asset rails come down to ten things: five ledger rules the database must enforce, four service-level targets, and one pause rule to activate when the chain can no longer be trusted.
Mark each item off against your own infrastructure:
1Posting state machine: pending, available, failed, and reversed states tied to confirmation depth
2Idempotency keys: one key covers both the ledger write and the on-chain broadcast
3Reorg reversal: append-only counter-postings, never edits to historical rows
4Atomic omnibus attribution: no omnibus movement without a customer account in the same write
5Compliance evidence on the posting: Travel Rule originator and beneficiary data attached to the transfer itself
6Chain-event-to-posting delay: measured in seconds, owned by the ingestion service
7Reconciliation lag: three-way check between ledger, custody, and chain runs inside the daily cut-off
8Exception time-to-owner: every open break has a named on-call owner
9Recovery time after a rail incident: clock starts when block production resumes, owned by the runbook
10Rail-pause for degraded chain finality: automatic halt when finality slips, automatic resume when depth advances again
It all starts with the ledger. Every item is either a state the ledger must represent, a query the ledger must answer, or an invariant the ledger must enforce.