RecurringPaymentCovenant enforces fixed-interval payments to a fixed recipient. The pay() function is permissionless.
Contract path: contracts/core/streaming/RecurringPaymentCovenant.cash
CashScript version: ^0.13.0
Constructor Parameters (Bytecode-Embedded)
| Parameter | Type | Description |
|---|---|---|
vaultId | bytes32 | Links to source vault |
senderHash | bytes20 | Controls pause/cancel |
recipientHash | bytes20 | Fixed payment recipient (immutable) |
amountPerInterval | int | Satoshis or FT per payment |
intervalSeconds | int | Seconds between payments |
totalAmount | int | Total pool cap. 0 = unlimited. |
startTimestamp | int | When first payment can occur. 0 = immediate. |
endTimestamp | int | Hard expiry. 0 = no expiry. |
NFT State (40 bytes)
Transaction Structure
All entrypoints spend stream state fromtx.inputs[0].
| Function | Required outputs | Notes |
|---|---|---|
pay | tx.outputs[0] recipient payout, tx.outputs[1] updated stream UTXO | Permissionless; locktime gates interval execution. |
pause | tx.outputs[0] updated stream UTXO | Stores pause_start = tx.locktime. |
resume | tx.outputs[0] updated stream UTXO | Sets next_payment_timestamp = tx.locktime + intervalSeconds. |
cancel | For capped streams (totalAmount > 0): tx.outputs[0] sender payout | For uncapped (totalAmount == 0), contract does not enforce a specific payout output. |
Functions
pay()
Permissionless. Releases amountPerInterval to recipientHash. Advances next_payment_timestamp by intervalSeconds.
Validates: status == ACTIVE, tx.locktime >= next_payment_timestamp, time window constraints, newTotalPaid <= totalAmount (if capped)
Auto-completes when newTotalPaid >= totalAmount
Output rules
tx.outputs[0]must payrecipientHashwithamountPerInterval(BCH or FT mode by flag bit2).tx.outputs[1]must preserve covenant bytecode/token category and encode:- updated
total_paid - updated
payment_count - updated
next_payment_timestamp pause_start = 0- status
COMPLETEDonly when capped stream reachestotalAmount
- updated
pause(sig senderSig, pubkey senderPubkey)
Sender-only. Requires FLAG_CANCELABLE. Records pause_start.
resume(sig senderSig, pubkey senderPubkey)
Sender-only. Resets next_payment_timestamp = tx.locktime + intervalSeconds. No backdated intervals.
cancel(sig senderSig, pubkey senderPubkey)
Sender-only. Requires FLAG_CANCELABLE. Returns entire remaining pool to sender.
For unlimited streams (totalAmount == 0), this contract path authorizes cancellation but does not enforce a specific sender-refund output shape.
