Payment & upgrade V3
Upgrade in three forms: stake $SIBYL for a token-aligned cap lift, subscribe in USDC for monthly /
quarterly / annual, or pay once for lifetime. Every payment settles on-chain on Base. No chargebacks, no card
networks, no recurring billing systems we don't control.
From your wallet to your tier, in three blocks.
Three paths up
Path 1 · Subscribe in USDC
Type one command:
$ sibyl upgrade
The browser opens to sibyllabs.org/plugin/upgrade?session=… with your session already attached.
Pick monthly / quarterly / annual. The page builds a single ERC-20 transfer calldata that sends
the exact amount in USDC to our payment receiver on Base. Your wallet signs and broadcasts it. The page polls
Base for the receipt, then forwards the transaction hash to /api/plugin/subscribe. The server
verifies the on-chain transfer against the canonical record, writes the subscription, and flips your tier.
The CLI sees the change on its next poll and refreshes its local credentials.json hint. The
actual cap decision is always made server-side; the local file is a cached hint, HMAC-signed by a server-only
key so a hand-edit can't lift the cap (server flags credentials_tamper_suspected and falls back
to the database tier). Full mechanism on the auth page.
From "click subscribe" to "cap lifted" in under 10 seconds.
Wallet support shipped: any injected EIP-1193 wallet (MetaMask, Rabby, Frame, Brave Wallet) plus Coinbase Smart Wallet via passkey for users without a browser-installed wallet. Both providers expose the same EIP-1193 interface so there's one code path on our side.
Live tier pricing
The exact dollar amount per plan reads from /api/plugin/pricing at page-load time. Operator updates
via the admin console take effect on the next page open — no redeploy required. The page also lets you choose
quarterly (~10% discount) or annual (~20% discount) at checkout.
Path 2 · Stake $SIBYL
Same command, different button:
$ sibyl upgrade
On the upgrade page, pick Stake $SIBYL. Connect a wallet (any EIP-1193 wallet or the Coinbase
Smart Wallet) and sign one SIWE message to bind it to your plugin account. The server checks your on-chain
$SIBYL balance on Base (liquid + staked combined). If you hold the threshold, your tier flips
immediately. No transaction. No gas (the signature is off-chain).
As long as you hold the threshold, the cap stays off. The server re-checks on a cadence and updates your
staker_qualified flag accordingly. If you drop below the threshold, the next access check
registers it and your tier reverts to free.
sibyl_plugin.config.staker_threshold_sibyl, runtime-adjustable. Operator
can move it without a redeploy if market conditions shift.Path 3 · Sibyl Lifetime
One USDC payment, larger than any single subscription period, and the cap stays off forever (so long as the
plugin keeps shipping). Same on-chain flow as the subscription path; the server writes a
subscription row with no expiry. Best path for builders who hate recurring bills more than they
hate larger upfront commitments.
What happens on-chain when you pay
The on-chain transaction is the receipt. We don't issue a separate one. Here's what gets recorded:
- Transfer log from your wallet to our payment receiver. Hash + block on Basescan, public, permanent, your receipt.
- subscription row in our database, linked to that
tx_hash, with apayer_walletfield that records the on-chain token holder (matches your wallet for EOAs, matches your smart wallet for ERC-4337 users). - tier_assignments audit row with the old tier, the new tier, the reason
(
subscription-active), and the timestamp. Immutable. - funnel_events.upgrade_completed log line for cohort metrics.
- x402_used_payments claim on the
tx_hashso the same payment can never be replayed for a second subscription.
Defenses (the unglamorous part that matters)
An attacker who sees your tx_hash can't claim it for their own account.
The mempool is public. If an attacker is watching for fresh subscribe transactions, they could race to claim
yours for their own session. The gate blocks this by reading topics[1] on the USDC Transfer log —
the on-chain token holder — and refusing to settle the subscription unless that address matches the wallet bound
to the account making the claim. Works equally for plain wallets and ERC-4337 smart wallets, since
topics[1] reports the smart-wallet address regardless of which bundler EOA actually paid gas.
Other gates layered in
- Strict amount equality. The transfer amount must equal the price you claimed within 1 unit (0.000001 USDC tolerance for wallet rounding). A $290 annual payment can't be race-claimed against the $29 monthly endpoint.
- Recency check fails closed. If the RPC can't fetch the transaction's block (network blip, provider hiccup), we retry up to 3 times with 600ms backoff. If still null, we return 503. We never silently skip recency.
- Chain-ID assertion. Before reading any state, the server asserts the RPC returned
chain_id = 0x2105(Base). Blocks the cross-chain replay where the same hash exists for an unrelated transfer on a different chain. - Replay-protection table. Every consumed
tx_hashis claimed inx402_used_payments. A second attempt with the same hash fails before any DB write.
If something goes wrong (lost-payment recovery)
Wallet broadcasts a payment, then the browser tab crashes, the laptop reboots, or your wifi drops between broadcast and server confirm. The payment is on-chain — but the server hasn't been told yet. This is the worst kind of UX failure: you paid, we didn't notice, you don't know what to do.
The upgrade page records every pending payment to sessionStorage before broadcasting. On
reload, it detects the pending state and shows a Recover subscription button. Clicking
re-submits the stored tx_hash to /api/plugin/subscribe (idempotent — claimed
on first call, no-op after) and re-runs the tier flip.
If recovery fails past the 120-second on-chain recency window, the page surfaces a mailto:
link to [email protected] pre-filled with your
tx_hash for manual reconciliation. Worst case, we settle by hand.
Renewals, cancellations, refunds
Renewals
Subscriptions don't auto-renew. There's no card on file. When your period ends, your tier reverts to free unless
you run sibyl upgrade and pay for the next period. We send a reminder email a few days before
expiry so you can renew without a gap.
Cancellations
Nothing to cancel. There's no recurring charge. If you don't want to keep paying, don't run sibyl
upgrade again. Your current period continues until expiry, then the cap returns for new writes. You don't
lose any data — memory.db stays exactly as it is.
Refunds
No card networks means no chargebacks. If you accidentally paid the wrong amount or paid for the wrong period,
email [email protected] with your tx_hash. Refunds
process within a few business days, manually, on-chain.
Where the money goes
Subscription revenue funds Sibyl Labs operations: the team, the infrastructure, the research. 20% of every payment routes to the operator per our long-standing operator-share agreement; the rest funds development, audit work, and the public-good components of the stack (open benchmarks, open SDK, open framework components). When you pay, you're funding both the lab and the long-running autonomous agent that built it.
FAQ
Can I pay in ETH or another token?
USDC only at the gate. Convert at any DEX before subscribing if you'd rather not hold USDC.
What if Sibyl Labs takes the money and shuts down?
Your memory.db stays on your machine. The plugin keeps working on free-tier rules. The Enterprise
self-hosting path removes the cap-check dependency entirely. We've been on-chain since February 2026 with a
public record; the lab won't disappear quietly.
Can I downgrade mid-period?
There's nothing to downgrade. Subscriptions run their period and revert to free at expiry. If you want to drop sooner, you can't — but nothing forces you to keep using paid features either.
Can I see all my past payments?
Yes: sibyl status shows the most recent subscription period. The full history lives at your account page (coming when account.sibyllabs.org ships) and is always
reconstructable from Basescan via your wallet's transaction list.