How a covenant gets funded — and how it ends. A payment-first covenant is funded only after the payment, so a remittance moves through two steps: the request (the sender asks a seller to fund) and the funding (the seller locks BCH once paid). This page follows one remittance through that lifecycle.
Status: Phase 0 (testnet). The seller checks below are client-side for testing; a covenant change — an explicit floor plus an on-chain collateral check — is scheduled for v0, before Phase 0 launch (see What is not yet enforced).
Under the payment-first model the sender must not lock BCH before paying fiat. So the sender creates a covenant that is unfunded (awaiting payment), and a BCH seller funds it once the fiat payment is confirmed. Until then the covenant carries no money — the request is an offer with agreed terms.
The request’s reference is the recipient’s Cash Account (Elena#142, or the destination address if there is none). It is human-readable and it is the payment concept the seller’s notification bot uses to match a bank notification to the right covenant (see the caveat under Scale).
initialBchPriceInCents (see The floor).[FUND_COVENANT] message goes to the chosen seller over Nostr (a NIP-17 DM). It carries the reference, the seller’s ad id, fee, buffer, the pay-by window, and the sender’s initial price. (The card is the sender’s single place to watch a remittance move: requesting → funded → claimed/refunded.)Before funding, the seller’s app checks:
The price is still above the floor — funding happens only if
current ≥ initial × (1 − 1.5 %).
A rise is free (it only makes the buffer larger). A fall of more than ~1.5 % since creation means the request is already doomed → the seller does not fund and the sender recreates.
These checks stop a seller from funding a request that was set up to fail. They are client-side for testing — a buggy or hostile client could bypass them — so they are not “the guarantee”; the v0 covenant makes the important ones on-chain (below).
The sender has a pay-by window to complete the payment. Past the window the request is cancelled — but not deleted: the sender may simply have forgotten to mark it sent, so the seller keeps a window to rescue the request.
The window is method-specific, not a global constant:
payment-timing-per-method.One pending request blocks the reference for its window — a bounded wait, fine for Phase 0.
The reference (the recipient’s Cash Account) is unique per recipient, not per request, so two senders paying the same recipient serialize and share the same concept. Making the reference unique per request (e.g. a short nonce in the concept) is a durability refinement for later phases.
A covenant ends in one of five ways: claim, merchantCashout, refund, abort, sellerRecoverBuffer. When it ends, the actor tells the counterparties over Nostr with a [COVENANT_RESOLVED] message (covenantAddress, path, txid). That message is a hint, not the truth: the receiver verifies on-chain (the covenant is spent, the tx exists) before concluding. The spending transaction is the source of truth; the DM only triggers a timely look.
At expiry (8 h) the funder automatically recovers its buffer (sellerRecoverBuffer: an exact alarm, a catch-up on app/boot start, and a short retry). The sender’s refund() is manual (available any time before a claim). No stability tokens are minted at expiry — minting happens only on merchantCashout and on abort (>7 % drop). See Auto-Refund UX and Funder Principle.
The seller’s app groups its remittances into three:
🛡️ Buffer recovered, ✅ Settled (on-chain), ✅ Claimed, with the txid.Statuses surface as ✅ Claimed / ✅ Refunded / ⏱️ Expired / ✅ Settled.
initialBchPriceInCents is the floor reference, not the sale price. The seller sells BCH in advance — it holds the fiat first and delivers BCH at claim — so its sale price is the resolution price, and a stale initial shifts only where the floor sits, not the seller’s economics. The seller sizes its buffer (and, in v0, an explicit floor param) to leave headroom above the expected funding price. See Value-Guaranteed Delivery.
Honest scope, so the guarantees are not overstated:
floor constructor param, and an on-chain collateral check (V ≥ eurCents × 1e8 / floor) so the funded collateral always covers the euro amount down to the floor.[COVENANT_RESOLVED] directions are emitted — refund/abort → funder; claim and sellerRecoverBuffer → sender. The npub sources are best-effort (the listing board, contacts, DMs), and the receiver always verifies on-chain — the message is a hint, never the truth.Navigation
| 🏠 Home | ↑ The Mechanism | 📖 Glossary |
Related: How They Interact · Nostr Coordination · Payment Timing (per method) · Sender Journey · Merchant Journey