OrbitContract
A no_std Soroban contract with four entrypoints, persistent vault storage and no admin.
| Source | contracts/soroban/src/lib.rs |
| SDK | soroban-sdk 27.0.6 |
| Target | wasm32v1-none |
| Testnet ID | CAZBZBUWBSQYK2RZ6WHMXVDLIQHSU5WD7ANZYL6HLNSCRUOTNYCDYQNG |
| Admin | None |
| Events | vault_created, funds_pulled, batch_disbursed. See Events |
Entrypoints
create_vault
Subscriber sets the billing terms for one merchant.
get_vault
Anyone reads the terms and last pull time. Read-only.
pull_funds
Merchant collects one cycle.
batch_disburse
Sender pays many recipients atomically.
Types
#[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,
}
#[contracttype]
pub struct PaymentSplit {
pub recipient: Address,
pub amount: i128,
}Storage
| Key | Type | Value | TTL |
|---|---|---|---|
VaultKey { user, merchant } | persistent | VaultData | Extended by create_vault and pull_funds |
TTL extension
create_vault and every successful pull_funds extend the TTL of both the vault entry and the contract instance, so a vault stays live between pulls without anyone paying to bump it by hand.
interval_ledgers = interval_seconds / 5 // about 5 seconds per ledger
extend_to = max(interval_ledgers + 120_960, 518_400)
threshold = 120_960extend_tois the billing interval plus a margin of about 7 days (120_960ledgers), with a floor of about 30 days (518_400ledgers).- The extension only happens when the remaining TTL is below
threshold(about 7 days), so a call made while the entry already has plenty of TTL left does not extend it again.
interval_seconds | extend_to | Roughly |
|---|---|---|
86400 (1 day) | 518_400 ledgers | 30 days |
2592000 (30 days) | 639_360 ledgers | 37 days |
31536000 (365 days) | 6_428_160 ledgers | 372 days |
Preview. TTL extension is in the contract source on main but not yet in the testnet deployment CAZBZBUW...CDYQNG. Vaults on the current deployment keep the network default TTL until the next redeploy.
get_vault does not extend the TTL. A vault that is never pulled for longer than extend_to can still be archived and has to be restored before the next pull.
Token model
Orbit is always the spender, never the holder:
token::Client::new(&env, &token).transfer_from(
&env.current_contract_address(), // spender: Orbit
&from, // user or sender
&to, // merchant or recipient
&amount,
);Any SEP-41 token works: a Stellar Asset Contract (USDC, XLM) or a custom Soroban token that implements approve and transfer_from.
Build and test
cd contracts/soroban
cargo test
stellar contract build
# target/wasm32v1-none/release/orbit_contract.wasmRelease profile: opt-level = "z", lto = true, overflow-checks = true, panic = "abort".