Read a subscription by id.
fn get(env: soroban_sdk::Env, id: u64) -> Subscription
Pause all payment triggers and new subscription creation. Owner only.
The Paused flag lives in persistent storage and its TTL is bumped
on every toggle so a prolonged pause window cannot silently expire.
fn pause(env: soroban_sdk::Env)
Cancel a subscription. Only the subscriber can cancel.
fn cancel(env: soroban_sdk::Env, id: u64)
Create a new recurring subscription.
token MUST be a SEP-41-compliant contract address. Passing a non-compliant
address will not fail at creation time — it will cause trigger to panic when
transfer_from is invoked. The caller is responsible for verifying the token.
interval is in seconds and must be in 1..=MAX_INTERVAL (10 years).
The subscriber must call token.approve(this_contract_address, amount) before
each payment cycle, or once with a sufficiently large allowance.
After calling cancel, the subscriber MUST also call
token.approve(this_contract_address, 0) to revoke the allowance.
fn create(
env: soroban_sdk::Env,
subscriber: soroban_sdk::Address,
token: soroban_sdk::Address,
recipient: soroban_sdk::Address,
amount: i128,
interval: u64,
) -> u64
Trigger the next payment for subscription id.
Permissionless: anyone (keeper, bot, recipient, subscriber) may call this once the payment is due. Safety derives from:
allowance (subscriber's consent to pull funds), andrecipient being fixed at creation (no third party can redirect).The token is pulled from the subscriber via transfer_from, so the
subscriber must have granted a sufficient allowance to this contract
address beforehand.
fn trigger(env: soroban_sdk::Env, id: u64)
Resume normal operation. Owner only.
fn unpause(env: soroban_sdk::Env)
Hot-swap the contract WASM. Owner only. Use to patch bugs without
draining user allowances; always couple with pause + off-chain review
of new_wasm_hash before calling.
fn upgrade(env: soroban_sdk::Env, new_wasm_hash: soroban_sdk::BytesN<32>)
Batch-catch up to count consecutive due cycles in a single tx.
The contract processes min(count, due_cycles) where
due_cycles = (now - next_payment) / interval + 1, advances
next_payment by the corresponding amount of intervals (no drift),
and pulls cycles_processed * amount from the subscriber in a single
transfer_from. Useful for keepers/recipients catching up after a
pause window or downtime.
Like trigger, this is permissionless — the subscriber's allowance
(which must cover the total amount) is the consent.
fn trigger_n(env: soroban_sdk::Env, id: u64, count: u32)
Atomic constructor — invoked exactly once by the Soroban runtime
at contract deployment. This eliminates the front-running window that a
two-step deploy + initialize flow would expose.
fn __constructor(env: soroban_sdk::Env, owner: soroban_sdk::Address)
Atomically transfer ownership. The transaction must carry signatures from BOTH the current owner and the new owner — this rules out transferring to a wrong or unresponsive address (the wrong key cannot sign) without requiring a separate acceptance step.
fn transfer_ownership(env: soroban_sdk::Env, new_owner: soroban_sdk::Address)