OrbitDocs

OrbitContract

A no_std Soroban contract with four entrypoints, persistent vault storage and no admin.

Sourcecontracts/soroban/src/lib.rs
SDKsoroban-sdk 27.0.6
Targetwasm32v1-none
Testnet IDCAZBZBUWBSQYK2RZ6WHMXVDLIQHSU5WD7ANZYL6HLNSCRUOTNYCDYQNG
AdminNone
Eventsvault_created, funds_pulled, batch_disbursed. See Events

Entrypoints

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

KeyTypeValueTTL
VaultKey { user, merchant }persistentVaultDataExtended 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_960
  • extend_to is the billing interval plus a margin of about 7 days (120_960 ledgers), with a floor of about 30 days (518_400 ledgers).
  • 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_secondsextend_toRoughly
86400 (1 day)518_400 ledgers30 days
2592000 (30 days)639_360 ledgers37 days
31536000 (365 days)6_428_160 ledgers372 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.wasm

Release profile: opt-level = "z", lto = true, overflow-checks = true, panic = "abort".

On this page