Allowance vaults
How Orbit bills on a schedule without ever holding the subscriber's funds.
An allowance vault is made of two pieces of onchain state that work together:
| Piece | Lives in | Set by | Controls |
|---|---|---|---|
| Token allowance | The token's SAC | Subscriber, via approve | How much Orbit can move in total, and until which ledger |
VaultData | Orbit contract storage | Subscriber, via create_vault | How often the merchant can pull, and how much per pull |
Tokens only move when both agree.
Lifecycle
Pull eligibility
A pull succeeds only when all of these hold:
now >= last_pull + interval_seconds OR last_pull = 0amount_per_interval <= allowance(user, orbit) AND amount_per_interval <= balance(user)The first condition is checked by Orbit. The second is enforced by the token contract inside transfer_from.
Storage
#[contracttype]
pub struct VaultKey {
pub user: Address,
pub merchant: Address,
}
#[contracttype]
pub struct VaultData {
pub token: Address,
pub amount_per_interval: i128,
pub interval_seconds: u64,
pub last_pull_timestamp: u64,
}- There is one vault per
(user, merchant)pair, stored in persistent storage. - A subscriber can hold vaults with any number of merchants, each with its own terms.
- Calling
create_vaultagain for the same pair overwrites the terms and setslast_pull_timestampback to0.
Sizing the allowance
Approve amount_per_interval x cycles and choose a live_until_ledger that covers them:
cycles = 12
amount = 290000000 # 29 USDC
allowance = 3480000000 # 348 USDC
ledgers per cycle ~ 2592000 / 5 = 518400A short allowance that you top up on renewal gives subscribers more control than one large, long-lived allowance. The dashboard can prompt for re-approval when the allowance is about to run out.
Cancelling
Subscribers cancel on the token, not on Orbit:
stellar contract invoke --id $TOKEN --source subscriber --network testnet -- \
approve --from $SUBSCRIBER --spender $ORBIT --amount 0 --live_until_ledger 0After this, every pull_funds for that subscriber fails inside the SAC, whatever vault terms are stored.