Skip to main content
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)

ParameterTypeDescription
vaultIdbytes32Links to source vault
senderHashbytes20Controls pause/cancel
recipientHashbytes20Fixed payment recipient (immutable)
amountPerIntervalintSatoshis or FT per payment
intervalSecondsintSeconds between payments
totalAmountintTotal pool cap. 0 = unlimited.
startTimestampintWhen first payment can occur. 0 = immediate.
endTimestampintHard expiry. 0 = no expiry.

NFT State (40 bytes)

[0]:    status
[1]:    flags
[2-9]:  total_paid (uint64)
[10-17]: payment_count (uint64)
[18-22]: next_payment_timestamp (5 bytes)
[23-27]: pause_start (5 bytes, 0 if not paused)
[28-39]: reserved

Transaction Structure

All entrypoints spend stream state from tx.inputs[0].
FunctionRequired outputsNotes
paytx.outputs[0] recipient payout, tx.outputs[1] updated stream UTXOPermissionless; locktime gates interval execution.
pausetx.outputs[0] updated stream UTXOStores pause_start = tx.locktime.
resumetx.outputs[0] updated stream UTXOSets next_payment_timestamp = tx.locktime + intervalSeconds.
cancelFor capped streams (totalAmount > 0): tx.outputs[0] sender payoutFor 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 pay recipientHash with amountPerInterval (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 COMPLETED only when capped stream reaches totalAmount

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.