On-chain state & transaction layout
PR #13 and #15 hinge on where outputs sit and what the covenant stores. This lesson fills that gap.
Mutable state on-chain
Offer parameters (rate, amounts, expiry) are fixed at creation. Two fields change during the loan — stored in Taproot data leaves via LendingOfferStorage:
| Slot | Field | Pending offer | After accept |
|---|---|---|---|
| 0 | is_active | false | true |
| 1 | current_debt | principal + total fee | decreases on partial repay |
new_pending sets both slots before the collateral output is created. Acceptance flips is_active; repayment reduces current_debt. The indexer infers status from spends, but the covenant enforces debt math on-chain.
Supporting covenants
LendingOffer is not alone — it delegates to smaller programs. See supporting covenants reference for detail. Summary:
- ScriptAuth — glues lender NFT to offer covenant until accept
- AssetAuth — holds principal for borrower after accept
- AssetAuthVault — holds repaid funds for lender/protocol claim
PR #13’s spike implements attach_creation for pending offers: lender NFT gets a ScriptAuth output, then metadata, then collateral locked in the main covenant.
Output index map (offer creation)
The indexer’s try_from_tx assumes a fixed layout. From simplicity-lending:
| Index | Output |
|---|---|
| 2 | Borrower NFT |
| 3 | Lender NFT (ScriptAuth-locked) |
| 4 | OP_RETURN — 50-byte creation metadata |
| 5 | Pending offer (collateral in covenant) |
Earlier outputs (0–1) come from factory issuance in the same transaction. If your code places metadata or collateral at the wrong index, the tx may confirm but the indexer will ignore it.
attach_creation produce 6+ outputs with metadata at index 4 and collateral covenant last? Does metadata encode 50 bytes (program id, principal asset, amount, expiry, rate)? Does new_pending set is_active=false and current_debt=total repayable?
Factory creation layout (PR #15)
| Index | Output |
|---|---|
| 0 | Auth NFT |
| 1 | Factory program UTXO |
| 2 | OP_RETURN — 13-byte factory metadata |
Full diagram: tx-output-layout.html.
Check your understanding
1. What does is_active=false mean for an offer?
2. Where does the indexer read offer metadata?
3. What is ScriptAuth used for in offer creation?