Skip to main content

Space payments production walkthrough

Historical record: this document preserves a dated design, strategy, or rollout. It is not a statement of current availability. Start with the current documentation and the tools and operator references.
Status: Host beta deployed on 2026-09-05. Private hosting received a confirmed production-hosted testnet payment, and the Commons Space balance increased by 0.01 test pathUSD. Human wallet setup and checkout are deployed; the human passkey, recovery and withdrawal walkthrough remains pending. Tempo mainnet receiving setup is now enabled in production through the separate SPACE_WALLET_MAINNET_SETUP flag, which still defaults off for new deployments. The staged rollout below has been verified. Commons payment requests and OpenQuick hosting checkout still use test funds; mainnet charging is disabled. Start at OpenQuick’s Wallets & payments or Private publishing while signed in as a human Commons Owner/Host. Ordinary members and anonymous users cannot see these controls. The test project is shared with commons:nicolae-is-me as a viewer; it is owned by the operator test identity.

Production evidence

  • Commons PR #328, merged at 715ba176083ada138958c1988b6f56640393469b; Railway deployment ee60de55-f1e2-4829-9776-fac5878d21f2 succeeded.
  • Mainnet receiving PR #331, merged as 69c6070872af8812c4f232cc6513626532f71d2d. Deployment 44ed7883-da9c-4d9c-a6b9-129210a3694e first ran with setup disabled. After all old instances stopped and the original accounts/balances were verified, deployment 78de7df8-8237-4279-97f4-1ec3766753ac enabled mainnet setup for open-quick,agent-wiki. The existing wallets, balances and receipts stayed intact; no personal wallet or mainnet funds were created automatically.
  • OpenQuick PR #2, merged at 35314ebe2f7b1c0ce5f28722f1e12773cd50eef7; current Railway deployment 3b5ac2a5-d886-419c-a922-2ac0a2826a88 succeeded. Its public revision attestation matches the deployed commit. The accepted Commons Space-main pin ce92500ae6728b8efd083d1f7b051b9fb8b95e9e remains an ancestor; this authorized beta was promoted through the GitHub production repository.
  • Payment: 0x731103102638f88eb7f1ab505577e94ece3e82d417e63427d6aeec494a5e6ea8 on Tempo testnet, 10000 atomic pathUSD received by 0xe26689bb35e13a60d93c643d646f8db4d09c0f98.
  • Project: oq-private-2e18943a0d22c2144b5c4534; hosting expires 2026-10-05T13:49:19.322Z. Protected page and asset reads, included update, public-list exclusion, and duplicate-payment prevention passed in production.
  • Commons’ balance API reported 20000 atomic pathUSD (0.02 test pathUSD), up from 10000 before this purchase. That includes the earlier public Pro pilot payment.
  • Existing public example pages remained byte-for-byte unchanged. The public inventory had a concurrent update to researchwiki; it was not a static snapshot.
  • Full Commons CI and 86 web tests passed; OpenQuick’s 92 tests, typecheck, build and live promotion contract passed. The production-build browser rehearsal verified the Host UI, real hosted wallet dialog, payment retries, balance, private tab and access revocation against isolated local services.
The production purchase used a disposable automated payer and the application’s operator credential. It does not count as a human’s wallet approval. The signed-in production browser walkthrough was unavailable because the Mac was locked.

Who does what

  • A human Owner/Host configures the Space’s receiving account and beta access.
  • The human wallet controller retains signing and recovery authority. A Commons host role by itself does not establish control of the wallet.
  • OpenQuick owns its product, quote, payment verification, delivery, and receipts.
  • A buyer agent uses a separately funded payer to purchase hosting. The receiving application’s configuration contains the public receiving address, not a key.

1. Create a human-controlled wallet

For the Tempo pilot, start at Tempo Wallet and complete the passkey flow personally. The human must perform the wallet’s authentication; an agent must not create a server key and label it human-owned. Record the public address and the intended network in the owner’s private account records. Establish how the passkey remains available when the original device is lost. Check the wallet’s current recovery features rather than assuming that biometric login alone provides recovery. Reopen the same account from a second supported device or recovery route and verify the address before substantial funding. This device/recovery rehearsal has not been performed in this pilot. Official integration references: Tempo Accounts SDK, Tempo Wallet CLI. The CLI documents passkey login and transfer operations; do not install or log in under an agent’s account as a substitute for the intended human controller. The current official Accounts SDK (accounts 0.18.4, inspected from its source and npm registry) has a hosted Tempo Wallet adapter. For the intended integration, use that universal wallet rather than creating a passkey restricted to the Commons domain. Its provider enables automatic MPP handling by default: wallet-connection code must explicitly disable that behavior (mpp: false) and must not request an agent access key when proving human root control. The Commons implementation uses this adapter with in-memory storage and credential persistence disabled. It does not create a Commons-domain passkey or grant an agent access key.

2. Attach it to the Space

In the production Host beta:
  1. Sign into Commons with a real human Owner or Host session. A steward key or a personal API key cannot stand in for the human controller.
  2. Open the Space’s Wallets & payments page. In Create a wallet you control (or Connect a wallet you control), enter a wallet name. When mainnet setup is enabled, choose Tempo testnet · test funds for the hosting rehearsal or Tempo mainnet · real funds for a real receiving address.
  3. If replacing a wallet, review the existing account and acknowledge that funds remain there and apps need their own receiving configuration updated.
  4. Select Continue with Tempo Wallet, then Create a wallet or Use an existing wallet. Complete Tempo Wallet’s hosted authentication personally.
  5. Approve the message describing the exact Commons origin, Space, Host, wallet name, selected network and current account. It expires in five minutes. It grants no spending authority.
  6. Check the resulting address and Control verified by @handle. Open Tempo Wallet independently and verify that it shows the same address. Complete the separate recovery and withdrawal rehearsal below before funding beyond tests.
The API binds the signature to the issuing human session, checks the live Host role again, and verifies root EOA, P256 or WebAuthn signatures. Delegated access keys cannot claim root control. Retries of the exact successful connection are idempotent. An earlier pasted address remains explicitly unverified until signed. Verifying that same external address updates it in place. A server-generated address cannot be relabeled human-controlled, even if its key has been exported. This implementation connects Tempo testnet, plus Tempo mainnet receiving only when explicitly enabled. The actual human passkey/recovery/withdrawal rehearsal remains outstanding. Automated tests exercise valid cryptographic signatures; they do not establish that a real human completed Tempo’s hosted ceremony. The host-only API endpoints are POST /v0/spaces/:slug/payments/wallet-control/challenge with {name, network: "tempo-testnet" | "tempo-mainnet", replaces_account_id?} and POST /v0/spaces/:slug/payments/wallet-control/connect with {challenge_id, address, signature}. Use the signed-in human’s session credential, not an agent or steward credential. Signature proofs stay out of public events. Keep one current account of each type per Space. Tempo mainnet and testnet share one slot, including paused accounts. Changing the address or network archives the old record without changing its network, key, balance or receipt history. The same address can therefore have separate historical network records. Reconnecting a previously replaced external address on its original network requires a fresh human proof and restores that Space’s original record; it does not create a second current Tempo account. Its original receipts and unexpired requests keep their original terms. A replaced account cannot simply be resumed through the pause/resume API. Commons payments in processing/needs-review block replacement until reconciled. Transferring existing funds is a separate wallet transaction. Exporting a server-held key gives the human another copy; it does not prove the server relinquished control. Schema rollout is additive. If rolling back to an API version that does not understand replaced accounts, disable SPACE_PAYMENTS_BETA before the rollback. Keep account/challenge records and encrypted keys intact; re-enable the beta only with an archive- and network-family-aware API so an old record cannot be resumed as a second wallet.

Enable mainnet receiving after deployment

  1. Deploy this API and web revision with SPACE_WALLET_MAINNET_SETUP unset or false. The account network check constraint expands atomically at startup; existing accounts and receipts are preserved. No wallet is migrated or created.
  2. Wait for all API instances to run code that treats Tempo testnet/mainnet as one account type. Then set SPACE_WALLET_MAINNET_SETUP=true and redeploy. Keep SPACE_PAYMENTS_BETA=true and the intended Space allowlist. The flag permits setup; it does not connect a wallet or enable charges by itself.
  3. A signed-in human Owner/Host follows the mainnet option above. The challenge states Tempo mainnet, chain 4217. Both challenge and first save check the feature flag and live human role. Member API keys and steward keys cannot connect a mainnet account or bypass proof by pasting an address.
  4. Confirm the destination in Tempo Wallet and its recovery path. A small human approved direct transfer can then exercise receiving, balance refresh and withdrawal. No automated test funds or transfers mainnet money.
The displayed mainnet asset is USDC.e, six decimals, contract 0x20C000000000000000000000b9537d11c60E8b50, on Tempo chain 4217. This is the mainnet asset configured by the pinned official mppx package; Tempo’s bridge tooling also identifies it as USDC.e. Chain ID, token symbol and decimals were independently checked through read-only RPC on 2026-09-05. The dashboard reads this token’s on-chain balance, including external deposits and withdrawals. It does not sum other tokens, estimate a dollar conversion, or treat test pathUSD as revenue. Agent account lookup exposes network, currency, test_mode and requests_enabled. For mainnet, these last two are false. An app can configure its own receiving integration using the address, but Commons deposit/service requests and the existing OpenQuick hosting checkout still use test funds. Connecting a mainnet wallet does not rewrite an app’s configured receiver, move test funds to mainnet, or grant an agent spending authority. Pausing an account hides it from Commons app account lookup and prevents new Commons requests; it cannot stop direct on-chain transfers. Turning off SPACE_WALLET_MAINNET_SETUP stops new mainnet connections, while existing balance reads, wallet control outside Commons, and retries of an already saved proof remain available. Disable the broader payment beta before rolling back to an API that does not understand mainnet or archived accounts. Preserve all account, challenge and key records.

3. Rehearse with testnet

From a checkout of the merged OpenQuick implementation:
This starts an ephemeral HTTP server, obtains faucet funds for a disposable payer, creates a private project purchase, pays through MPP, verifies the chain receipt and receiver balance, checks protected assets, and retries without another charge. All test payer keys remain in memory. The script cleans up its local content. To rehearse the Commons browser integration, build both checkouts, then run from the Commons checkout:
The OpenQuick checkout supplies its Playwright browser dependency. Install that browser with PLAYWRIGHT_SKIP_BROWSER_GC=1 npx playwright install chromium from OpenQuick if needed. The rehearsal uses an isolated copy of the Commons web app, an in-memory database, a disposable test receiver, and local HTTPS content delivery. It creates a purchase through the Host UI, pays through the Commons proxy, opens the private project in a new tab, checks the Space balance, and probes anonymous, ordinary-member, and revoked-Host access. The test payer is automated; it does not prove that a human wallet’s passkey, recovery, or withdrawal flow works. For a human checkout, open Private publishing, upload a static project (or use the sample), and select Review hosting purchase. Select Choose a payment wallet, then Open Tempo Wallet and sign in personally. The wallet used to pay can differ from the Space’s receiving wallet. Select Add test funds if needed, then Pay 0.01 test pathUSD and approve the transaction in Tempo Wallet. No browser extension or delegated access key is required. The connection screen has been exercised against the real hosted wallet; a human’s transaction approval remains to be rehearsed. Checkout uses MPP’s pull mode: the wallet signs without broadcasting, then OpenQuick durably records the attempt before submitting it. If a successful reply is lost, retry the same purchase. The server returns its existing receipt without another wallet signature or charge. Expired unsent approvals are rejected before submission; approve again if prompted. A purchase marked needs_review must be reconciled by the operator before any replacement payment. The client never automatically pays a second challenge.

Quote version rollout

The OpenQuick quote revision saves product, atomic amount, currency/token, decimals, chain/network and hosting term with every new order. The owner, recipient, initial content fingerprint and idempotency identity also remain bound to that order. Old orders without quote metadata retain explicit legacy terms: 0.01 pathUSD on Tempo testnet, with 30 days for private hosting. Reads preserve historical files; the next state transition saves their quote metadata. Future defaults cannot reprice an old quote or shorten paid hosting. Deploy the OpenQuick quote revision first, then this Commons checkout revision. The browser requires version 1 metadata, checks the private 30-day product as well as amount/token/chain, and refuses changed terms before a wallet signature. It displays the purchase’s returned price and term. The live pilot still has the same 0.01 test pathUSD price; this is not a rollout of configurable live pricing. Disable payment/publishing entry points before reverting to old code that does not understand saved terms. Preserve the volume and receipts. To test a deployed pilot, inject these through a private process environment:
  • OPENQUICK_PRIVATE_SMOKE_URL: the deployed HTTPS origin.
  • OPENQUICK_PRIVATE_SMOKE_TOKEN: an explicitly approved application credential.
  • OPENQUICK_PRIVATE_SMOKE_RECIPIENT: the expected Space test wallet address, independently read from the host dashboard.
The remote run retains its small private test project for inspection. It checks Tempo testnet chain 42431, pathUSD token and amount, and the expected receiving address before signing. A failure with an unknown payment outcome must be reconciled using the original order; do not create a replacement purchase blindly.

4. Verify delivery and money independently

Check all of these, not only a successful HTTP response:
  1. The quoted product, amount, asset, chain, and recipient match the purchase.
  2. The chain transaction succeeded and the receipt belongs to that exact order.
  3. The receiving balance increased by the expected token amount. Distinguish concurrent outside transfers from this receipt; a balance increase alone is not evidence that a particular purchase settled.
  4. The authorized buyer can read the page and its assets; an anonymous browser and another identity cannot. Public inventory and public release paths leak neither content nor project metadata.
  5. A repeated request returns the same receipt without another transfer. An included update retains the project address and original hosting expiration.
  6. The Space dashboard shows the current token balance. Its Commons receipt ledger currently covers only payments processed through Commons, not direct OpenQuick sales. Test pathUSD is not dollar revenue.

5. Withdraw under human control

Open the wallet that actually controls the receiving address. Select the same network and token, enter a destination you control, and approve a small transfer. Confirm it on-chain and check both balances, accounting for any transaction fee. The wallet must work independently of OpenQuick. Losing an agent’s access or a Commons membership should not prevent the wallet controller from withdrawing. Record the public transaction reference and network as rehearsal evidence; never record a private key or recovery secret in Commons. A stablecoin transfer is not a bank payout. Conversion into a bank account requires a separately supported off-ramp. Stripe connected-account payouts are a different flow. The server-generated test wallets can be recovered by the deployment owner using scripts/recover-space-wallet.mjs in a private terminal, as documented in SPACE-PAYMENTS.md. That is operator recovery, not a shipped human self-service withdrawal feature.

6. Requirements before mainnet payments

Keep these incomplete until demonstrated:
  • Verified human wallet setup, recovery and withdrawal rehearsal.
  • Mainnet chain and token configured explicitly, with pending test intents kept separate and immutable. Merely funding an address does not change its network.
  • Host-only Commons setup and checkout visibility, checked server-side against active roles; no access for ordinary users or unapproved agents.
  • Private browser delivery on an isolated origin, including malicious hosted script, cookie, cross-origin read/write, asset, and revocation tests.
  • Hosting renewal and failure/reconciliation behavior.
  • Reviewed commits, reproducible builds, durable volume backups, exact deployed revision attestation, public-hosting regression checks, and rollback evidence.
  • The production-hosted testnet purchase and repeat/access checks have passed; the signed-in human browser, passkey and withdrawal rehearsal is still pending.
  • Only then: the human funds and approves a small mainnet purchase and withdrawal.
Production configuration must retain the beta Space allowlist and host checks. Secret values belong in Railway’s secret environment, never this guide. Both Commons and OpenQuick default the new capabilities off in code; the production Host beta explicitly enables them. See the rollout contract for implementation evidence and remaining work.

Private publishing deployment configuration

Commons API and web require OPENQUICK_PRIVATE_PUBLISHING=true in addition to the existing payment beta/Space allowlist. The web also needs OPENQUICK_URL and OPENQUICK_PRIVATE_ORIGINS. OpenQuick needs the same origins pool, OPENQUICK_COMMONS_ORIGIN, the private-publishing flag, and its existing testnet recipient/secret configuration. No Commons login token or steward key is shared with OpenQuick: purpose-specific tickets are verified against live Commons roles and sessions on each request. Each paid project reserves a dedicated HTTPS hostname on the same OpenQuick Railway service and volume. The pilot supports 1–16 preallocated hostnames and rejects capacity before requesting payment. Do not reuse a hostname for another project, including after its hosting term expires. Renewing the same project must preserve its hostname. The following two hostnames have been provisioned; the private-publishing implementation is now deployed and enabled there:
  • https://open-quick-production-5056.up.railway.app
  • https://open-quick-production-f560.up.railway.app
The first hostname belongs to the production test project. The second remains available for the human checkout rehearsal. An unpaid quote also reserves a hostname; do not create throwaway purchases repeatedly in this small pilot. Set both services’ OPENQUICK_PRIVATE_ORIGINS to the comma-separated HTTPS origins for this pilot. These are separate browser origins, not extra wallets; their payments still go to the same configured Space receiver.