AGENT RING - open and settle a duel in the pit (instructions for an AI agent) ============================================================================ What you are doing ------------------ Running a 1v1 duel for the user in Agent Ring's Arena. Both players stake play credits; the winner takes 90% of the pot and 10% goes to the treasury. Nothing is paid in BNB here. Chain: BNB Smart Chain (chain 56). Read https://demo2.zk0x.app/config.js first. If `arena` is empty the contract is not deployed: say so and stop. Send nothing. Moves ----- STRIKE (1) beats FEINT (3) FEINT (3) beats GUARD (2) GUARD (2) beats STRIKE (1) Same move = tie: the higher identity level wins, then the lower identity tokenId. There is no randomness in the result. Anyone can recompute it with `outcome(uint8,uint8)` selector 0xff6cd08c, so do not describe a duel as luck. Contracts and selectors ----------------------- Arena.openMatch(uint256 identityId, uint256 stake, bytes32 commit) 0x31116f1f Arena.joinMatch(uint256 matchId, uint256 identityId, bytes32 commit) 0x7468437a Arena.reveal(uint256 matchId, uint8 move, bytes32 salt) 0x9a42f3aa (see below) Arena.settleExpired(uint256 matchId) 0x87641eb2 Arena.cancelOpen(uint256 matchId) 0x806762a0 Arena.revealWindow() 0x863d22c7 CreditShop.balanceOf(address) 0x70a08231 The reveal selector is 0x9a42f3aa - read it from the contract yourself if this file ever looks stale. Step 1 - ask the user --------------------- Ask three things and wait: which identity tokenId they fight with, how many credits they want to stake, and their move. Check the balance first (`balanceOf` on the shop); never stake more than the wallet holds. Two players stake the same amount, so the stake must fit both. Step 2 - commit, do not reveal yet ---------------------------------- commit = keccak256(abi.encode(uint8 move, bytes32 salt, address player)) Use a random 32-byte salt and keep it. The commit hides the move from the opponent, which is the only thing that makes the duel fair. Show the user the calldata and gas estimate, wait for approval, then send `openMatch` (or `joinMatch` with the matchId the user is joining). Step 3 - reveal --------------- After the opponent joins: Arena.reveal(matchId, move, salt) 0x9a42f3aa If both players have revealed, the duel settles inside that same transaction. If the opponent does not reveal before `revealWindow()` seconds pass: Arena.settleExpired(matchId) 0x87641eb2 The player who revealed takes the pot. If neither revealed, both stakes come back and no rake is taken. If the match was never joined, the opener can call `cancelOpen` for a refund. Step 4 - report --------------- Transaction hashes, the winner, the prize (90% of the pot), the rake (10%), and the credit balance after. Never report a win before the settle transaction exists. Guardrails ---------- Never send a transaction the user has not approved. Never reveal a move before the opponent's commit exists - that hands them the win. Never guess a stake, a matchId or a salt. Credits are a game balance: no transfer, no withdrawal. A duel stake is a spend, not an investment, and a lost stake is gone. If the chain contradicts this file, trust the chain and tell the user.