GhostPay Protocol Specification
Version 2.0 — The complete technical specification for the GhostPay Mesh offline-first cryptographic payment protocol.
1. Overview
GhostPay Mesh is a cryptographic protocol designed for offline-first value transfer. It enables the creation, transfer, and settlement of monetary value between parties without requiring continuous internet connectivity.
At its core, the protocol revolves around Cryptographic Liquidity Promises (PLCs) — signed, verifiable digital instruments that represent a commitment to settle a specific monetary amount. PLCs can be created offline, transferred between devices via BLE, NFC, or QR codes, and settled when connectivity is restored through traditional payment rails (Pix, Boleto) or on-chain transactions.
The protocol provides:
- Offline creation and transfer of monetary value with cryptographic guarantees
- Multi-hop transfers through a mesh network of devices
- Replay protection through nonces, commitment hashes, and signature chains
- Privacy by design with zero personal data requirements
- Flexible settlement via Pix, Boleto, or on-chain methods
2. Terminology
| Term | Definition |
|---|---|
| PLC | Cryptographic Liquidity Promise. A signed digital instrument representing a commitment to settle a monetary amount. The fundamental unit of value transfer in the protocol. |
| Issuer | The entity that creates and cryptographically signs a PLC. The issuer commits to settling the PLC’s value upon redemption. |
| Bearer | The current holder of a PLC. Possession is proven via the transfer chain and signature verification. |
| Settlement | The process of converting a PLC into actual monetary value through a payment rail (Pix, Boleto, or on-chain transfer). |
| Mesh Network | The peer-to-peer network of GhostPay-enabled devices that can relay and verify PLCs without centralized infrastructure. |
| Transfer Chain | An ordered list of cryptographic signatures recording every transfer of a PLC from issuer to current bearer. |
| Commitment Hash | A SHA-256 hash that binds the PLC’s fields together, preventing tampering after issuance. |
3. PLC Structure
A PLC is a self-contained data structure that carries all information necessary for verification without network access. Every field is immutable after issuance, except transfer_chain[] and status.
| Field | Type | Description |
|---|---|---|
id |
UUID v4 | Unique identifier for this PLC instance |
amount |
Decimal | The monetary value committed (e.g., 150.00) |
currency |
ISO 4217 | Currency code (BRL, USD, EUR) |
commitment_hash |
SHA-256 | Hash binding all immutable fields: SHA-256(id + amount + currency + issuer_pubkey + created_at + expires_at + nonce) |
issuer_pubkey |
Ed25519 | The public key of the PLC issuer |
signature |
Ed25519 | Issuer’s signature over the commitment_hash |
created_at |
ISO 8601 | Timestamp of PLC creation |
expires_at |
ISO 8601 | Expiration timestamp (max 7 days from creation) |
transfer_chain |
Array | Ordered list of transfer records, each containing: from_pubkey, to_pubkey, signature, timestamp, nonce |
status |
Enum | Current lifecycle state: ISSUED, TRANSFERRED, REDEEMED, EXPIRED, CANCELLED |
"id": "plc_7f3a8b2c-4d1e-4f6a-9b3c-2e1d4f5a6b7c",
"amount": 150.00,
"currency": "BRL",
"commitment_hash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"issuer_pubkey": "ed25519:3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
"signature": "sig_ed25519:5d41402abc4b2a76b9719d911017c592...",
"created_at": "2025-01-15T10:30:00Z",
"expires_at": "2025-01-22T10:30:00Z",
"transfer_chain": [
{
"from_pubkey": "ed25519:3b6a27bc...",
"to_pubkey": "ed25519:9a4f2c1d...",
"signature": "sig_ed25519:a1b2c3d4...",
"timestamp": "2025-01-15T14:22:00Z",
"nonce": "n_8f7e6d5c4b3a2190"
}
],
"status": "TRANSFERRED"
}
4. Lifecycle
Every PLC transitions through a well-defined set of states. The state machine is designed to be deterministic and verifiable offline — any device holding a PLC can independently determine its validity.
State Definitions
- ISSUED — PLC has been created and signed by the issuer. It has not yet been transferred.
- TRANSFERRED — PLC has been transferred to one or more bearers. The
transfer_chaincontains at least one entry. - REDEEMED — PLC has been settled through a payment rail. Terminal state.
- EXPIRED — PLC has passed its
expires_attimestamp without being redeemed. Terminal state. - CANCELLED — PLC has been cancelled by the issuer before any transfer. Terminal state.
State Machine
stateDiagram-v2
[*] --> ISSUED : Create + Sign
ISSUED --> TRANSFERRED : Transfer to Bearer
ISSUED --> CANCELLED : Issuer Cancels
ISSUED --> EXPIRED : TTL Exceeded
TRANSFERRED --> TRANSFERRED : Multi-hop Transfer
TRANSFERRED --> REDEEMED : Settlement Complete
TRANSFERRED --> EXPIRED : TTL Exceeded
REDEEMED --> [*]
EXPIRED --> [*]
CANCELLED --> [*]
Transition Rules
- ISSUED → TRANSFERRED: Requires a valid transfer record signed by the current bearer (initially the issuer).
- ISSUED → CANCELLED: Only the original issuer may cancel. Must be signed by the issuer’s private key. Cannot occur after any transfer.
- TRANSFERRED → TRANSFERRED: Multi-hop transfer. Each hop adds a new entry to
transfer_chainwith the sender’s signature. - TRANSFERRED → REDEEMED: The current bearer initiates settlement. Requires connectivity to a settlement provider.
- Any → EXPIRED: Automatic transition when
expires_atis reached. Verified locally by comparing device clock.
5. Offline Transfer Protocol
The offline transfer protocol enables PLC transfers between devices without internet connectivity. Three transport mechanisms are supported:
Transport Mechanisms
| Transport | Range | Speed | Use Case |
|---|---|---|---|
| BLE 5.0 | ~100m | 2 Mbps | Proximity payments, mesh relay |
| NFC | ~4cm | 424 kbps | Tap-to-pay, POS terminals |
| QR Code | Visual | ~3KB | Cross-platform, printed receipts |
Transfer Flow
sequenceDiagram
participant A as Sender (Alice)
participant B as Receiver (Bob)
A->>A: Verify PLC is valid & not expired
A->>A: Generate transfer nonce
A->>A: Create transfer record
A->>A: Sign with private key
A->>B: Transmit PLC + transfer record (BLE/NFC/QR)
B->>B: Verify issuer signature on commitment_hash
B->>B: Verify complete transfer_chain signatures
B->>B: Verify PLC not expired
B->>B: Verify nonce uniqueness
B->>B: Accept PLC
B-->>A: Send ACK (if bidirectional channel)
Signature Verification
Upon receiving a PLC, the receiver performs the following verification steps:
- Commitment integrity: Recompute
SHA-256(id + amount + currency + issuer_pubkey + created_at + expires_at + nonce)and compare withcommitment_hash. - Issuer signature: Verify the issuer’s Ed25519 signature over the
commitment_hashusingissuer_pubkey. - Chain validation: For each entry in
transfer_chain, verify that thesignaturewas produced by thefrom_pubkeyover the concatenation ofto_pubkey + timestamp + nonce + previous_chain_hash. - Expiration check: Confirm
expires_athas not passed according to the local device clock (with configurable tolerance).
6. Settlement Protocol
Settlement converts a PLC into actual monetary value. This is the only step that requires internet connectivity. The protocol supports multiple settlement rails:
Settlement Rails
- Pix (Instant): Brazilian instant payment system. Settlement in <10 seconds. Available 24/7.
- Boleto (Batch): Brazilian payment slip. Settlement in 1-3 business days.
- On-chain: Blockchain settlement for cross-border or high-value PLCs. Supports Solana SPL transfers.
Settlement Flow
- Bearer initiates settlement request with the complete PLC payload.
- Settlement service verifies the entire PLC (commitment, signatures, chain, expiration).
- Settlement service checks for double-spend attempts against the global ledger.
- If valid, settlement service initiates the payment via the selected rail.
- PLC status transitions to
REDEEMED. The settlement transaction ID is recorded.
{
"plc_id": "plc_7f3a8b2c-4d1e-4f6a-9b3c-2e1d4f5a6b7c",
"plc_payload": "<full PLC JSON, base64-encoded>",
"settlement_rail": "pix",
"destination": {
"pix_key": "random-key-uuid"
},
"bearer_signature": "sig_ed25519:..."
}
7. Replay Protection
The protocol employs multiple layers of replay protection to prevent double-spending and replay attacks, even in offline environments:
7.1 Nonce-Based Protection
Every transfer record includes a cryptographically random nonce (128-bit). Receiving devices maintain a local nonce cache and reject any transfer containing a previously seen nonce.
7.2 Commitment Hash Binding
The commitment_hash binds all immutable PLC fields together with a unique nonce. This prevents an attacker from modifying any field (amount, currency, expiration) without invalidating the issuer’s signature.
7.3 Signature Chain
Each transfer in the transfer_chain includes a signature over the concatenation of the transfer data and the hash of the previous chain entry. This creates a Merkle-like chain where:
- Removing any intermediate transfer invalidates all subsequent signatures
- Reordering transfers invalidates the chain
- Forking the chain (double-spend) requires forging an Ed25519 signature
7.4 Server-Side Deduplication
Upon settlement, the backend verifies the PLC against a global ledger. If a PLC has already been redeemed (even partially via a different transfer chain fork), the settlement is rejected.
8. Idempotency
All API operations in the GhostPay Mesh protocol are designed to be idempotent, ensuring safe retries in unreliable network conditions.
Idempotency Keys
Clients include an Idempotency-Key header with every mutating request. The server stores the response for each key and returns the cached response on subsequent requests with the same key.
Idempotency-Key: ik_8f7e6d5c-4b3a-2190-abcd-ef0123456789
Content-Type: application/json
{
"amount": 150.00,
"currency": "BRL"
}
Idempotency Rules
- Keys are scoped to the device’s public key and expire after 24 hours.
- If a request is received while a previous request with the same key is still processing, the server returns
409 Conflict. - Idempotency keys are stored in a distributed cache with eventual consistency guarantees.
- PLC creation, transfer initiation, and settlement requests all require idempotency keys.