Neutral Settlement Protocol
A non-custodial, geopolitically neutral settlement layer that any institution can use regardless of which side of the trade they are on - covering fiat-to-fiat, fiat-to-crypto, and crypto-to-crypto lanes.
received
→
validated
→
compliance_check
→
accepted
→
ready
→
submitted
→
confirmed
→
final
terminal:
rejected
failed
cancelled
expired
Full state machine details: Settlement Lifecycle
01Why Neutral Settlement
Traditional settlement infrastructure (SWIFT, DTCC, CLS) is centralized, slow (T+1 to T+2), and controlled by a narrow set of jurisdictions.
Single-chain solutions are fast but not jurisdictionally neutral - a single regulator can freeze or censor transactions at the protocol level.
JIL Sovereign provides a geopolitically neutral settlement layer. The protocol does not take a position on either side of a transaction.
Both counterparties submit to the same neutral state machine, governed by compliance rules in the zone matching their jurisdiction.
The settlement-api accepts instructions from any authenticated client. The settlement-engine processes them through a deterministic
9-state pipeline. The ledger-router submits finalized transactions to jil5600-core (the Rust L1 engine). Neither side gets preferential treatment.
02Three Settlement Lanes
The neutral settlement protocol supports three distinct lanes, each mapped to one or more settlement types (SIMPLE, DVP, PVP).
All three lanes share the same state machine, the same API surface, and the same compliance pipeline.
SIMPLE
Fiat-to-Fiat (FI-to-FI)
Cross-border bank settlement replacement - the institutional alternative to SWIFT and DTCC.
Single compliance check. Auto-transition from accepted to ready.
- Travel rule evaluation required (FATF Wire Transfer Rule)
- Party data: legal name, account identifier, country, address
- ISO 20022 banking fields supported (UETR, BIC, IBAN, charge bearer)
- Fees: 3-5 bps (vs 15-40 bps for SWIFT)
Example: Bank A (USD) sends to Bank B (EUR) via JIL settlement rail
SIMPLE | DVP
Fiat-to-Crypto (On-ramp)
Institutional crypto acquisition. Can be SIMPLE (single direction) or DVP (delivery vs payment) with two legs.
- DVP: fiat delivery (PAYMENT leg) against crypto delivery (ASSET leg)
- Per-leg compliance for DVP - each leg independently verified
- Travel rule evaluation applies to fiat leg
- Both legs must be attested via attest-ready (DVP only)
Example: Fund deposits USD (PAYMENT), receives JIL (ASSET) - atomically settled
DVP | PVP
Crypto-to-Crypto
Cross-chain or same-chain token swaps. PVP (payment vs payment) for concurrent asset exchange. DVP for asset-against-payment.
- PVP requires exactly 2 PAYMENT legs
- DVP requires 1 ASSET leg + 1 PAYMENT leg
- Per-leg compliance and per-leg attestation required
- Atomic: if any leg fails compliance, the entire settlement is rejected
Example: Swap jBTC for jETH atomically via PVP with two PAYMENT legs
03Settlement Type Reference
| Type |
Lane |
Legs |
Leg Requirements |
Attestation |
Compliance |
| SIMPLE |
FI-to-FI Fiat-Crypto |
0 (inline from/to/asset/amount) |
from_account, to_account, asset, amount all required |
Auto-ready (no attestation needed) |
Single compliance check |
| DVP |
Fiat-Crypto Crypto-Crypto |
Exactly 2 |
1 ASSET leg + 1 PAYMENT leg; payer + payee required |
Both legs must be attested via attest-ready |
Per-leg compliance check |
| PVP |
Crypto-Crypto |
Exactly 2 |
2 PAYMENT legs; payer + payee required |
Both legs must be attested via attest-ready |
Per-leg compliance check |
04Settlement Pipeline Flow
A client (institution, wallet, or API consumer) submits a settlement instruction to
the settlement-api. The instruction specifies the settlement type, zone, counterparties,
and either inline amounts (SIMPLE) or multi-leg definitions (DVP/PVP).
SIMPLE: Requires
from_account,
to_account,
asset,
amount.
DVP: Requires
legs[] with 1 ASSET + 1 PAYMENT leg, plus
payer and
payee.
PVP: Requires
legs[] with 2 PAYMENT legs, plus
payer and
payee.
POST /v1/settlements - single settlement
POST /v1/settlements/batch - batch of 1-100 SIMPLE settlements
The ATCE compliance gate runs at creation for all types. If denied, the settlement is immediately rejected.
On success, status is set to
received and a unique settlement ID + UETR are assigned.
Client / Institution
settlement-api :8050
compliance-api :8100
status: received
The settlement engine polls
received settlements and evaluates the FATF
Wire Transfer Rule based on the settlement zone configuration. The engine queries the compliance-api
for the zone's travel rule config - threshold amount (USD equivalent), and required fields.
Required party fields (zone-configurable, defaults):
originator_name,
originator_account,
beneficiary_name,
beneficiary_account
Extended fields (per zone):
originator_address,
originator_country,
originator_date_of_birth,
originator_national_id,
beneficiary_address,
beneficiary_country
If required travel rule fields are missing, the settlement is rejected immediately with
SETTLEMENT_REJECTED and the missing fields are listed in the failure reason.
If travel rule passes (or is not required below threshold), status transitions to
validated.
settlement-engine (poll loop)
compliance-api :8100
status: validated
The engine transitions validated settlements to
compliance_check and runs the
full compliance pipeline against the compliance-api.
SIMPLE settlements: Single compliance check on the from/to/asset/amount.
DVP/PVP settlements: Per-leg compliance - each leg is independently checked against the
compliance-api with its own from_account, to_account, asset, and amount.
Atomic rejection: If any leg is denied, the
entire settlement is rejected.
There is no partial compliance pass. The compliance receipt hash is stored for audit trail.
On compliance pass, status transitions to
accepted.
settlement-engine (poll loop)
compliance-api :8100
status: accepted
This step determines when a settlement is ready for L1 submission.
SIMPLE settlements: Auto-transition. The engine immediately moves the settlement from
accepted to
ready. No external action required.
DVP/PVP settlements: Both counterparties must independently attest that their leg is ready
by calling the attest-ready endpoint. The engine checks all legs on each tick - only when every leg has
status = 'ready' does the settlement advance to
ready.
POST /v1/settlements/:id/attest-ready
Body:
{ "party_id": "...", "leg_index": 0 | 1 }
Each attestation is recorded in the
settlement_attestations table and the corresponding
leg status is updated. The party_id must match either the payer or payee registered on the settlement.
settlement-api :8050
settlement-engine (poll loop)
status: ready
The engine submits the ready settlement to the JIL L1 ledger via ledger-router.
The ledger client calls
lab_tx RPC on ledger-router :8000, which forwards
the transaction to jil5600-core (the Rust L1 engine).
For DVP/PVP, the first leg is used as the primary submission. Both legs are atomically committed
as part of the same block.
On successful submission, the L1 returns a
tx_id and the settlement
moves to
submitted. If submission fails, the settlement moves to
failed
with the error recorded.
Timeout: If a submitted settlement receives no block inclusion within
SETTLEMENT_TIMEOUT_MS (default 60s), it is marked
failed.
settlement-engine (poll loop)
ledger-router :8000
jil5600-core (Rust L1)
status: submitted → confirmed
The engine polls submitted settlements for block inclusion via
lab_receipt RPC.
Once included in a block, the settlement moves to
confirmed with the block height,
block hash, and initial confirmation count recorded.
The engine continues polling confirmed settlements until the confirmation count reaches the
FINALITY_CONFIRMATIONS threshold (default:
6 confirmations).
At finality:
1. Fee calculation: Settlement fee is computed at the
final state (default 5 bps).
For DVP, the fee is based on the ASSET leg amount. For PVP, the fee is based on the first leg.
2. Leg settlement: For DVP/PVP, all legs are marked
settled.
3. Receipt assembly: A structured receipt is built containing the settlement ID, tx_id,
block data, fee breakdown, compliance receipt hash, and leg details (for DVP/PVP).
4. Finality proof: A proof object is stored containing the tx_id, block height, block hash,
confirmation count, and finalization timestamp.
The settlement moves to
final and a webhook is dispatched.
settlement-engine (poll loop)
ledger-router :8000
Client (webhook)
05API Endpoints
All endpoints are served by settlement-api :8050 and require API key authentication.
| Endpoint |
Method |
Purpose |
Notes |
| /v1/settlements |
POST |
Create a single settlement (SIMPLE, DVP, or PVP) |
Idempotent on (client_id, external_id) |
| /v1/settlements/batch |
POST |
Batch submit 1-100 SIMPLE settlements |
Each item validated independently; returns per-item results |
| /v1/settlements/:id |
GET |
Full settlement status with legs, parties, banking fields |
Enriched response with compliance, L1, fee data |
| /v1/settlements/:id/cancel |
POST |
Cancel a settlement |
Only from: received, validated, accepted, ready |
| /v1/settlements/:id/attest-ready |
POST |
Attest leg readiness for DVP/PVP |
Requires party_id + leg_index; idempotent |
| /v1/settlements/:id/proof |
GET |
Retrieve finality proof |
Only available when status = final |
| /v1/settlements/:id/receipt |
GET |
Retrieve settlement receipt with fee breakdown |
Only available when status = final |
| /v1/settlements/:id/parties |
GET |
Banking parties and remittance info |
ISO 20022 party fields (originator, beneficiary, agents) |
| /v1/settlements/batch/:batch_id |
GET |
Batch summary with per-settlement status |
Tracks completed, failed, pending counts |
06Settlement Type Examples
SIMPLE (Fiat-to-Fiat)
POST /v1/settlements
{
"external_id": "bank-a-txn-20260225-001",
"settlement_type": "SIMPLE",
"from_account": "acct_bank_a_usd",
"to_account": "acct_bank_b_eur",
"asset": "JIL",
"amount": "1000000",
"zone_id": "EU_ESMA",
"currency": "EUR",
"charge_bearer": "SHAR",
"originator": {
"legal_name": "Acme Bank AG",
"identifier_type": "IBAN",
"account_identifier": "DE89370400440532013000",
"bic_code": "COBADEFFXXX",
"country": "DE"
},
"beneficiary": {
"legal_name": "Summit Capital SAS",
"identifier_type": "IBAN",
"account_identifier": "FR7630006000011234567890189",
"country": "FR"
}
}
DVP (Fiat-to-Crypto)
POST /v1/settlements
{
"external_id": "fund-acq-20260225-001",
"settlement_type": "DVP",
"zone_id": "CH_FINMA",
"payer": { "party_id": "fund_alpine_capital" },
"payee": { "party_id": "otc_desk_zurich" },
"legs": [
{
"leg_type": "PAYMENT",
"from_account": "acct_alpine_usd",
"to_account": "acct_otc_usd",
"asset": "jUSDC",
"amount": "500000"
},
{
"leg_type": "ASSET",
"from_account": "acct_otc_jil",
"to_account": "acct_alpine_jil",
"asset": "JIL",
"amount": "12500000"
}
],
"controls": { "atomic_required": true }
}
After creation, both parties must call POST /v1/settlements/:id/attest-ready
with their respective party_id and leg_index before the settlement advances.
PVP (Crypto-to-Crypto)
POST /v1/settlements
{
"external_id": "swap-jbtc-jeth-001",
"settlement_type": "PVP",
"zone_id": "default",
"payer": { "party_id": "trader_alice" },
"payee": { "party_id": "trader_bob" },
"legs": [
{
"leg_type": "PAYMENT",
"from_account": "acct_alice_btc",
"to_account": "acct_bob_btc",
"asset": "jBTC",
"amount": "100000000"
},
{
"leg_type": "PAYMENT",
"from_account": "acct_bob_eth",
"to_account": "acct_alice_eth",
"asset": "jETH",
"amount": "15000000000000000000"
}
],
"controls": { "atomic_required": true, "netting_allowed": false }
}
07Fee Structure
Fees are calculated at finality, not at submission. This means a settlement that fails or is cancelled incurs zero fees.
The default fee is SETTLEMENT_FEE_BPS = 5 (5 basis points, or 0.05%).
| Settlement Type |
Fee Base |
Default bps |
Example |
| SIMPLE |
The single amount field |
5 bps |
1,000,000 JIL → 500 JIL fee |
| DVP |
The ASSET leg amount |
5 bps |
12,500,000 JIL (ASSET leg) → 6,250 JIL fee |
| PVP |
The first leg amount |
5 bps |
1.0 jBTC (leg 0) → 0.0005 jBTC fee |
08Finality Timeline Comparison
Bar widths are proportional to wall-clock settlement time. JIL achieves sub-minute finality with 6 L1 confirmations.
09Core Services
| Service |
Port |
Purpose |
| settlement-api |
8050 |
REST API for settlement submission, status, cancel, attest-ready, proof, receipt. Runs the settlement-engine poll loop internally. |
| settlement-consumer |
8051 |
Consumes settlement events from RedPanda for zone-authorized processing on validator nodes. |
| compliance-api |
8100 |
Zone-specific compliance validation (AML, sanctions, ATCE gate). Provides zone config for travel rule thresholds. |
| ledger-router |
8000 |
RPC gateway to the L1 engine. Handles lab_tx (submit) and lab_receipt (confirmation check). |
| jil5600-core |
Rust L1 |
The Rust settlement engine. Processes PaymentTx transactions and produces blocks. |
10Configuration
| Variable |
Default |
Purpose |
| PORT |
8050 |
HTTP port for settlement-api |
| LEDGER_ROUTER_URL |
http://ledger-router:8000 |
RPC endpoint for L1 transaction submission and receipt polling |
| COMPLIANCE_API_URL |
http://compliance-api:8100 |
Compliance check + zone config for travel rule |
| FINALITY_CONFIRMATIONS |
6 |
Number of L1 block confirmations required for finality |
| SETTLEMENT_FEE_BPS |
5 |
Fee in basis points, calculated at finality |
| SETTLEMENT_EXPIRY_MINUTES |
60 |
TTL for settlements before automatic expiry |
| SETTLEMENT_TIMEOUT_MS |
60000 |
Timeout for L1 block inclusion after submission |
| ENGINE_POLL_INTERVAL_MS |
2000 |
Settlement engine tick interval (processes all state transitions) |
| KAFKA_BROKERS |
redpanda:9092 |
RedPanda broker for settlement event publishing |
| JIL_NETWORK_ID |
- |
Network identifier (mainnet: jil-mainnet-1) |
11Key Source Files
| File |
Purpose |
| services/settlement-api/src/routes/settlements.ts |
POST /v1/settlements, batch, cancel, attest-ready endpoints |
| services/settlement-api/src/routes/status.ts |
GET endpoints: settlement status, proof, receipt, parties, batch summary |
| services/settlement-api/src/schemas.ts |
Zod schemas: simpleSettlementSchema, institutionalSettlementSchema, legSchema, partySchema, controlsSchema |
| services/settlement-api/src/services/settlement-engine.ts |
9-state engine: processReceived, processValidated, processAccepted, processReady, processSubmitted, processConfirmed, processExpired |
| services/settlement-api/src/services/travel-rule.ts |
FATF travel rule evaluation - zone config lookup, required field validation |
| services/settlement-api/src/services/fee-calculator.ts |
Fee calculation per settlement type (SIMPLE/DVP/PVP) |
| services/settlement-api/src/services/finality-prover.ts |
Assembles finality proof for finalized settlements |
| services/settlement-api/src/services/ledger-client.ts |
RPC calls to ledger-router: lab_tx (submit), lab_receipt (confirmation check) |
| services/settlement-api/src/services/compliance-client.ts |
HTTP client for compliance-api: ATCE gate check, zone compliance |
| services/settlement-consumer/src/index.ts |
Zone-authorized settlement event consumer for validator nodes |
| docs/openapi/settlement-router.yaml |
OpenAPI specification for settlement pipeline |