Skip to content

Managed Space wager sessions

Managed Space wagers escrow API points for one creator-operated game session. Arinova owns wallet accounting and conservation; the creator owns game rules, randomness, cards, and hand-history generation. API points have no cash value, cannot be withdrawn, and never become creator-wallet revenue through wagers.

Only a confidential OAuth app bound to an active Space package may obtain a client_credentials service token with the wager scope. The token is hashed at rest, snapshots one space_id, and expires within one hour. Rotation or app-secret changes revoke all outstanding service tokens.

Exchange credentials at canonical POST /api/v1/oauth/token. The legacy POST /oauth/token path is an equivalent alias retained for existing SDK releases; both paths invoke the same handler and rate-limit class.

The same least-privilege service token can read the package’s current version through GET /api/v1/wager/space/version. Its response is {spaceId, activeVersionId, version}, allowing a game host to open sessions without storing a creator-wide API key.

POST /api/v1/wager/sessions fixes these values for the session lifetime:

  • spaceVersionId;
  • minimum and maximum buy-in, with a hard per-buy-in maximum of 1,000,000;
  • rake basis points, from 0 through 500;
  • initial expiry.

There is no update endpoint for those economic parameters. Heartbeat may only extend expiresAt within the server’s total extension ceiling. A creator must open a new session to change version, buy-in range, or rake.

GET /api/v1/wager/sessions/{sessionId} returns the immutable session fields, the current potPoints, and stakes: [{userId, amountPoints, status}]. The session and stake rows are read from one repeatable-read snapshot, so a concurrent buy-in cannot produce a response assembled from two database moments.

An opaque runtime requests arinova:wager-buyin-request. The first-party parent verifies the exact iframe source and fragment-bound bridge token, loads the authoritative session, shows native localized confirmation, and creates a host idempotency key. The iframe cannot choose a hidden price or call the session-authenticated debit directly. Two consecutive cancellations for one Space produce a 60-second host cooldown.

The debit accepts only paid and won API points, spending won first. Bonus points are never wagerable. A Space owner cannot sit at their own table. Daily admitted stake is capped at 1,000,000 points per user using a guarded wager_daily_stakes update. The day boundary is always UTC. Partial settlement, final settlement, cancellation, expiry refund, and force-void release the corresponding cap usage; retries cannot release it twice.

OperationSession statePackage statusCredential
Opennewactive onlySpace service token
Buy inopenactive runtime entitlement and exact active versionWeb session through native bridge
Heartbeatopen or lockedactive, suspended, or rejectedSpace service token
Lockopenactive, suspended, or rejectedSpace service token
Partial settleopen or lockedactive, suspended, or rejectedSpace service token
Final settlelocked onlyactive, suspended, or rejectedSpace service token
Cancelopen or lockedactive, suspended, or rejectedSpace service token

The status relaxation applies only to closing an existing liability. A suspended or rejected package cannot open another table. Downlisting locks active tables, while owner deletion and user purge refund them before the Space row can cascade.

Every wallet or state mutation acquires the session advisory lock and then re-reads status. Multi-user wallet writes run in user-ID order. Consequently a concurrent settle, cancellation, reaper, or admin force-void has one serialized winner and cannot double-credit or double-refund.

Partial settlement lets a departing player carry away their reported chip value immediately. Final settlement is accepted only after lock. The platform derives total stake from its own rows and validates:

  • payout users are active stakers;
  • all amounts are non-negative and rake is within the immutable snapshot;
  • cumulative partial distributions never exceed total stake;
  • cumulative payout plus rake equals total stake at final settlement.

Payouts and the creator’s rake credit the non-withdrawable won pool in the same transaction. Rake is 100% creator-owned won points; platform rake is zero. The session has no pending state, finalizer, dispute window, or delayed credit. Settlement idempotency is checked before session-state validation: an exact sequence replay remains successful after final settlement (including an older partial replay), while a changed payload conflicts and a new sequence after final settlement is invalid. Reporter-token rotation is ignored only for the comparison; the original unmodified payload remains stored for audit.

Admin relief records a unique settlement-reversal decision and audit reason, then claws payout and rake back from available won balances. A shortfall does not erase evidence: it creates a wager_session_anomalies record for manual recovery. Reversing a final settlement voids the session and refunds exactly the escrow left after finalized partial payouts and rake. Refund allocation is deterministic and weighted by principal not already recovered through partial payouts, so the operation remains globally conservative even when a partial winner previously received more than their own stake.

Expired sessions are voided by the reaper in earliest-expiry order. Heartbeat resets retry backoff. Repeated failures use exponential backoff and leave the session visible to the admin force-void surface after the retry ceiling.

Version 1 is a disclosure-and-evidence contract, not a poker engine. The Terms of Use require the creator to retain enough hand history and outcome evidence to support every reported settlement. Arinova persists the exact creator-reported settlement payload, token attribution, payouts, rake, immutable wallet transactions, reversal decision, and any anomaly. Operators can inspect these records from the admin wager detail surface.

Arinova does not parse or attest cards, RNG, per-bet actions, or creator hand history in v1. A future v2 may define a signed hand-history schema, retention period, player export, and automated consistency checks. Until that contract is implemented, no client or creator may describe platform accounting evidence as platform verification of gameplay fairness.

Wager stakes, settlement payouts, operations, and their four wallet sources are accounting evidence. User erasure repoints retained user references to the canonical tombstone and deletes the non-evidentiary daily-cap row. Session and settlement rows survive so historical conservation can still be reproduced. Deleting an owning Space is different: all active sessions must first be voided and refunded, after which terminal Space-linked rows may cascade.

The real-database lifecycle test covers open, native-equivalent buy-ins, partial settlement, re-buy, heartbeat, lock, final settlement, won-pool balances, admin final reversal, zero reconciliation anomalies, settle versus force-void serialization, and owner purge with an active table. It self-skips without a test database and runs with the backend database integration lane:

Terminal window
TEST_DATABASE_URL=postgres://... cargo test --test bucket_economy space_commerce_integration_tests::managed_wager_full_lifecycle -- --test-threads=1

Build a7f47a5ca54ddcf7806cd48b81ce1b9827042766