API Interaction
How the game server communicates with Monsuta Core for off-chain to on-chain settlement.
Purpose
The API interaction layer defines how a game server submits gameplay results to the blockchain. It exists because:
- Game servers must not interact with smart contracts directly from gameplay code
- There must be a standardized interface between off-chain game logic and on-chain settlement
- The communication model must handle failures, retries, and authorization
- Multiple games using Monsuta Core need a consistent integration pattern
Communication Model
┌──────────────────────────────────────────────────────────────┐
│ GAME SERVER │
│ │
│ ┌────────────┐ ┌────────────┐ ┌─────────────────────────┐ │
│ │ Match │ │ Reward │ │ Monsuta Core │ │
│ │ Engine │──►│ Calculator │──►│ API Client │ │
│ │ │ │ │ │ │ │
│ │ gameplay │ │ determines │ │ • signs requests │ │
│ │ logic │ │ who earned │ │ • batches transactions │ │
│ │ │ │ what │ │ • handles retries │ │
│ └────────────┘ └────────────┘ │ • tracks tx status │ │
│ └──────────┬──────────────┘ │
└─────────────────────────────────────────────┼────────────────┘
│
signed API requests
│
┌────────────▼────────────┐
│ Monsuta Core Gateway │
│ (optional middleware) │
│ │
│ • validates signatures │
│ • rate limiting │
│ • queue management │
│ • nonce management │
└────────────┬────────────┘
│
smart contract calls
│
┌────────────▼────────────┐
│ AVALANCHE C-CHAIN │
│ │
│ Prize Pool Contract │
│ Identity Contract │
│ Crafting Contract │
│ THC Token Contract │
└─────────────────────────┘
Interaction Patterns
Pattern 1: Server-Signed, Player-Submitted
The server generates a signed attestation. The player submits the transaction.
Server signs attestation:
"Player 0x1234 won match #567 and earned 100 THC"
│
▼
Signature sent to player's game client
│
▼
Player submits claim() transaction with signature
│
▼
Contract verifies server signature, processes claim
When to use:
- Player claims rewards
- Player crafts items
- Player mints achievements
Advantages:
- Player pays gas (server has no gas costs)
- Player controls timing of claim
- No server-to-chain dependency for routine claims
Disadvantages:
- Player needs AVAX for gas
- Claim UX requires wallet interaction
Pattern 2: Server-Submitted (Push)
The server submits transactions directly.
Server detects economic event (season end, tournament complete)
│
▼
Server submits transaction to contract
│
▼
Contract processes event (distributes rewards, mints NFTs)
When to use:
- Season finalization (submitting final rankings)
- Tournament result submission
- Batch operations affecting many players
Advantages:
- Players don't need gas
- Immediate finality
- Suitable for batch operations
Disadvantages:
- Server pays gas
- Server key must be funded and secured
- Server downtime blocks settlements
Pattern 3: Hybrid (Server Signs, Relayer Submits)
Server signs payload
│
▼
Payload stored (database or queue)
│
▼
Relayer service picks up pending payloads
│
▼
Relayer submits transactions to chain
│
▼
Relayer monitors confirmations
When to use:
- High-volume operations
- When separating signing authority from gas payment
- When using a third-party relayer service (e.g., OpenZeppelin Defender, Gelato)
API Endpoints
Result Submission
POST /api/v1/results/submit
Authorization: Bearer <server_api_key>
Body:
{
"competition_id": "season_1",
"competition_type": "season", // "season" | "tournament" | "event"
"results": [
{
"player": "0x1234...",
"rank": 1,
"stats": {
"wins": 87,
"losses": 23,
"elo": 2150
}
},
{
"player": "0x5678...",
"rank": 2,
"stats": {
"wins": 80,
"losses": 30,
"elo": 2050
}
}
],
"timestamp": 1777420800,
"nonce": 42
}
Response:
{
"tx_hash": "0xABCD...",
"status": "pending",
"confirmation_url": "/api/v1/tx/0xABCD..."
}
Reward Claim Generation
POST /api/v1/claims/generate
Authorization: Bearer <server_api_key>
Body:
{
"player": "0x1234...",
"reward_type": "season_thc",
"amount": 5000,
"season_id": 1,
"nonce": 12345
}
Response:
{
"claim_data": {
"player": "0x1234...",
"amount": 5000,
"nonce": 12345,
"expiry": 1778020800
},
"signature": "0x9876...ABCD",
"contract": "0xTHC_CONTRACT...",
"method": "claim(address,uint256,uint256,uint256,bytes)"
}
Achievement Minting
POST /api/v1/achievements/mint
Authorization: Bearer <server_api_key>
Body:
{
"player": "0x1234...",
"achievement_type_id": 42,
"season_id": 1,
"competition_id": 0,
"metadata": {
"league": "Diamond",
"final_rank": 3,
"wins": 87,
"win_rate": "79%"
}
}
Response:
{
"mint_data": { ... },
"signature": "0xSIG...",
"token_id": null, // assigned on mint
"status": "ready_to_mint"
}
Crafting Authorization
POST /api/v1/crafting/authorize
Authorization: Bearer <server_api_key>
Body:
{
"player": "0x1234...",
"recipe_id": 1,
"input_nft_ids": [101, 102], // if recipe requires NFT inputs
"materials_verified": true, // server confirms off-chain material balance
"thc_amount": 500,
"nonce": 67890
}
Response:
{
"craft_data": { ... },
"signature": "0xCRAFTSIG...",
"contract": "0xCRAFTING...",
"method": "craft(uint256,uint256[],uint256,bytes)"
}
Transaction Status
GET /api/v1/tx/{tx_hash}
Response:
{
"tx_hash": "0xABCD...",
"status": "confirmed", // "pending" | "confirmed" | "failed" | "reverted"
"block_number": 12345678,
"confirmations": 5,
"gas_used": 125000,
"error": null // populated on failure/revert
}
Authorization Model
Server API Key
- Used for server-to-gateway authentication
- Not a blockchain key — just an API key
- Rotatable without affecting on-chain state
Server Signing Key
- EVM private key used to sign attestations
- Must be registered in on-chain contracts as an authorized signer
- Should be stored in a KMS, not in application config
- Rotation requires updating contract registrations
Separation of Concerns
┌────────────┐ ┌──────────┐ ┌──────────────┐
│ API Key │ │ Signing │ │ Gas Wallet │
│ │ │ Key │ │ │
│ authenticates │ signs │ │ pays for │
│ server to │ │ payload │ │ transactions │
│ gateway │ │ data │ │ │
│ │ │ │ │ │
│ not on-chain│ │ registered│ │ funded with │
│ │ │ on-chain │ │ AVAX │
└────────────┘ └──────────┘ └──────────────┘
Error Handling
Retry Strategy
| Error Type | Retry? | Strategy |
|---|---|---|
| Network timeout | Yes | Exponential backoff (1s, 2s, 4s, 8s, 16s) |
| Nonce too low | Yes | Fetch current nonce, resubmit |
| Gas price spike | Yes | Wait for gas price to stabilize |
| Contract revert | No | Log error, investigate root cause |
| Signature invalid | No | Signing key mismatch, investigate |
| Already claimed | No | Skip — claim was already processed |
Idempotency
All API calls must be idempotent. The nonce field prevents replay:
First call: nonce=42 → success → claim processed
Replay: nonce=42 → contract reverts "already used"
Queue Management
For high-volume operations (season end, batch minting):
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ Game Server │ │ Transaction │ │ Blockchain │
│ │ │ Queue │ │ │
│ enqueues │────►│ │────►│ transactions │
│ 500 reward │ │ • priority │ │ submitted │
│ claims │ │ • rate limit │ │ sequentially │
│ │ │ • nonce mgmt │ │ │
│ │ │ • retry │ │ │
└─────────────┘ └──────────────┘ └──────────────┘
Why a queue? Submitting 500 transactions simultaneously causes nonce conflicts and gas price bidding wars. A queue serializes submissions with proper nonce management and gas estimation.
Integration Guide for Other Games
Step 1: Choose Your Pattern
| Your Situation | Recommended Pattern |
|---|---|
| Players have wallets and AVAX for gas | Server-signed, player-submitted |
| Players should not pay gas | Server-submitted (push) |
| High volume, need reliability | Hybrid with relayer |
| Mixed: some player-submitted, some push | Multiple patterns in parallel |
Step 2: Implement the API Client
- Wrap your on-chain interactions in an API client module
- Handle signing, nonce management, and retries
- Log all transactions for audit
Step 3: Secure Your Keys
- API keys in environment variables
- Signing keys in KMS (AWS KMS, GCP KMS, HashiCorp Vault)
- Gas wallet funded with monitoring alerts
- Key rotation plan documented
Step 4: Test on Testnet
- Deploy contracts on Avalanche Fuji
- Run all API flows end-to-end
- Simulate failure cases (network timeout, gas spikes, double-submit)
- Verify idempotency
Step 5: Monitor in Production
- Track pending transactions and confirmation times
- Alert on failed submissions or reverts
- Monitor gas wallet balance
- Log all signed payloads for audit and debugging