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.
Immutable session contract
Section titled “Immutable session contract”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.
Player buy-in boundary
Section titled “Player buy-in boundary”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.
State and credential matrix
Section titled “State and credential matrix”| Operation | Session state | Package status | Credential |
|---|---|---|---|
| Open | new | active only | Space service token |
| Buy in | open | active runtime entitlement and exact active version | Web session through native bridge |
| Heartbeat | open or locked | active, suspended, or rejected | Space service token |
| Lock | open | active, suspended, or rejected | Space service token |
| Partial settle | open or locked | active, suspended, or rejected | Space service token |
| Final settle | locked only | active, suspended, or rejected | Space service token |
| Cancel | open or locked | active, suspended, or rejected | Space 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.
Settlement and immediate relief
Section titled “Settlement and immediate relief”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.
Hand-history v1 evidence
Section titled “Hand-history v1 evidence”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.
Tombstones and retention
Section titled “Tombstones and retention”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.
Verification
Section titled “Verification”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:
TEST_DATABASE_URL=postgres://... cargo test --test bucket_economy space_commerce_integration_tests::managed_wager_full_lifecycle -- --test-threads=1Build a7f47a5ca54ddcf7806cd48b81ce1b9827042766