Skip to content

v1.8 Advanced Billing Features (Active)

Started: 2026-04-15 | Phases: 3 (45–47) | Plans: 47 | Status: Phase 46 complete, Phase 47 in progress

The most ambitious milestone by plans per phase (47 across 3 phases). v1.8 builds the three major billing features that v1.7's infrastructure was designed to support: streaming payments, plan upgrades with multi-token, and a webhook SDK with staging acceptance testing.

Scope

Phase 45: Streaming Engine (COMPLETE)

The first net-new billing primitive since v1.0's periodic pulls.

  • StreamMandate PDA — A new mandate type for continuous payment streams
    • authorized_max_rate — Rate-per-second authorization (not a fixed amount)
    • 56-byte reserved tail for future extensions
  • 6 streaming instructions:
    • create_stream — Establish a payment stream between payer and payee
    • execute_stream — Pull-based settlement at the authorized rate
    • pause_stream / resume_stream — Temporary stream suspension
    • update_stream_rate — Change the authorized rate on an active stream
    • cancel_stream — Permanently end a stream with final settlement
  • Settle-then-mutate invariant — All stream operations settle accrued amounts before modifying state, enforced by a pub(crate) helper
  • Transfer hook streaming branch — Slot 3 in the ExtraAccountMetaList stays PullApproval-compatible; the hook dispatches from the owner account discriminator
  • SDK builders — TypeScript instruction builders for all streaming operations
  • Error codes 6700–6711 — Reserved for stream-specific validation and authorization failures
  • 128-case proptest suite — Math property testing for stream calculations
  • LiteSVM edge-case suite — Full E2E testing including clock regression

Phase 46: Plan Upgrades + Multi-Token Activation (COMPLETE)

Plan modification and multi-currency billing.

  • Proration math — Calculate prorated amounts when subscribers switch plans mid-cycle
  • Mandate v3 inline pending_upgrade — Upgrade state lives inline on the mandate using v1.7's reserved space (no separate UpgradeIntent PDA)
  • TokenConfig end-to-end activation — Multi-token billing fully wired from Phase 41's TokenConfig registry
    • Per-mint billing rails
    • Decimal handling across different tokens
    • Oracle configuration for USD display
  • Browser-safe SDK boundary — SDK works in browser environments for plan upgrade flows
  • 16 plans executed, 24 requirements covered

Phase 47: Webhook SDK + Staging Closure (IN PROGRESS)

Typed webhook events and staging environment acceptance.

  • @vela/webhook package — Workspace package inside vela-sdk monorepo (NOT a separate repo)
    • Typed wrappers around raw Helius webhook payloads
    • NOT a new Vela-emitted event feed — wraps existing events
  • HMAC verifier — Cryptographic verification of webhook authenticity
  • DLQ (Dead Letter Queue) — Reliable handling of failed webhook deliveries
  • Staging E2E acceptance — Closing v1.5 tech debt:
    • Real Resend delivery verification
    • Hosted invoice visual QA
    • Queue/DLQ timing measurement
    • Live wallet acceptance testing
    • Pricing table accessibility sweep
  • 18 plans scoped

Key Design Decisions

Streaming Is a Distinct Primitive

Streaming is NOT "periodic billing with period=1 second." It's a fundamentally different billing model:

  • Pull-based — The payee pulls at the authorized rate, not the payer pushes
  • Rate-per-second authorization — Not a fixed amount per period
  • Continuous accrual — Amount owed grows continuously, settled on pull
  • Settle-then-mutate — Any state change (pause, rate change, cancel) settles accrued amount first

This distinction matters for regulatory compliance (streaming vs periodic), accounting treatment, and the transfer hook validation path.

Pull-Based Streaming with Rate-per-Second Authorization

The stream authorizes a rate (tokens per second), not an amount. The keeper pulls whenever it wants, and the settled amount is calculated from rate × elapsed_time. This means:

  • No fixed billing intervals — Settlement can happen at any cadence
  • Rate changes mid-stream — Update the rate without restarting the stream
  • Graceful pauses — Pause stops accrual, resume continues from zero accrued

Settle-Then-Mutate Invariant

Every stream operation that modifies state must first settle any accrued amount:

fn settle_accrued_in_place(stream: &mut StreamMandate, clock: &Clock) -> u64 {
    let accrued = stream.authorized_max_rate * (clock.slot - stream.last_settlement_slot);
    stream.accrued += accrued;
    stream.last_settlement_slot = clock.slot;
    accrued
}

This invariant is enforced by a pub(crate) helper that all mutating instructions call. It's kept crate-private so future handlers share one trust boundary.

Upgrade State Inline on Mandate v3

Plan upgrades use v1.7's reserved space on the Mandate v3 account:

  • pending_upgrade stored in the 64-byte reserved area
  • No separate UpgradeIntent PDA needed
  • Upgrade state is co-located with the mandate, reducing account lookups

Multi-Token from Day One

Multi-token support was designed into v1.8 from the start, not retrofitted:

  • Phase 45 streaming is multi-token-aware (rate denominated in the mandate's mint)
  • Phase 46 upgrade proration handles multi-token decimals
  • TokenConfig registry from v1.7 Phase 41 is fully activated

@vela/webhook as Workspace Package

The webhook SDK is a workspace package inside the vela-sdk monorepo, not a separate repository:

  • Shares types with the SDK
  • Same build and publish pipeline
  • Wraps raw Helius payloads — not a new Vela-emitted event feed

Oracle Lookup Is Client-Side

USD display values (for plans denominated in various tokens) use a client-side SDK helper with 60-second TTL cache. Plans are token-denominated on-chain. The oracle is a display concern, not a billing concern.

Sequencing Rationale

The three phases were sequenced A → B+C (merged) → D+E (merged):

  1. Streaming first — The only net-new primitive and highest review risk. Needed to land before anything depends on it.
  2. Upgrades + Multi-Token merged — Both touch SDK builders, dashboard UI, and webhook event tagging. Upgrade proration already must handle multi-token decimals, so they share work.
  3. Webhook SDK + Staging merged — Webhook SDK consumes stabilized events from Phases 45+46. Staging E2E (Playwright + Mailpit) naturally validates webhook delivery. Cross-phase dependencies resolve since 47 is last.

The original plan was 5 phases (A→B→C→D with E parallel). The 3-phase aggressive merge reduced overhead while maintaining strict serial execution.

Phase 45 Design Decisions (Detailed)

The streaming engine required several lockable decisions during execution:

  • Freeze the canonical stream schema at state/stream_mandate.rs with authorized_max_rate and 56-byte reserved tail
  • Retire the Plan 45-01 stream-proto path so downstream plans only target the final schema
  • Error codes 6700–6711 reserved for stream-specific failures
  • settle_accrued_in_place kept pub(crate) and re-exported from instructions/mod.rs
  • Fail closed on non-stream discriminators with WrongAccountType while reusing existing IncorrectProgramId owner check
  • Source-module test harness for direct helper testing (Rust integration tests can't call pub(crate))
  • execute_stream on the approved GO path — slot 3 stays PullApproval-compatible
  • Short-circuit zero-amount transfers — No transfer_checked CPI when settle_accrued_in_place returns zero
  • Either keeper or merchant can settle — Without reintroducing plan-account dependencies
  • Reuse execute_stream transfer path for pause, cancel, and rate updates (no duplicated CPI hook plumbing)
  • resume_stream free of settlement references — So no-back-accrual invariant stays grep-checkable
  • 128 proptest cases for math properties (clears under 60-second verification budget)
  • Concurrent settle+update modeled as single transaction, accepting only old-rate linearization or full rejection

Status

PhasePlansStatus
45 Streaming Engine12COMPLETE
46 Plan Upgrades + Multi-Token16COMPLETE
47 Webhook SDK + Staging Closure18IN PROGRESS

v1.8 progress: 28/47+ plans complete (Phases 45–46 done, Phase 47 executing)

Internal knowledge base for the Vela Labs workspace.