Market resolution flow
After a market's closeTime passes, the designated resolver posts the real-world outcome. Arcium's MPC nodes then decrypt the encrypted bet pool and compute payout ratios. A challenge window follows before the market becomes claimable.
Rendering diagram…
resolveMarket
Posts the real-world outcome and triggers the Arcium MPC reveal circuit. Only the wallet set as resolver at market creation can call this.
const result = await client.actions.resolveMarket({
payer: resolverPublicKey,
resolver: resolverPublicKey,
marketId: 42n,
outcomeValue: 1, // 0 = NO/Option0, 1 = YES/Option1, 2+ for multi
onProgress: ({ stage }) => console.log(stage),
});After this call the market moves to PendingResolution (state 4). The Arcium callback writes revealed pool sizes and the payout ratio. The market does not become Resolved until finalizeResolution is called (or the challenge window elapses undisputed).
Parameters
payer PublicKey required
Transaction fee payer.
resolver PublicKey required
Must match market.resolver on-chain. Any other key throws UnauthorizedResolver (error 6005).
marketId bigint | number required
Market to resolve. Must be in awaitingResolve phase (past closeTime, not yet revealed).
outcomeValue number required
Winning outcome index. For YesNo: 0 = NO, 1 = YES. For MultiOutcome: 0-(numOutcomes - 1).
computationOffset bigint
Arcium computation slot. Random by default.
timeoutMs number
Milliseconds to wait for the MPC callback. Defaults to 60_000.
onProgress ProgressCallback
Progress callback. Stages: validating → fetching-state → submitting → awaiting-callback → refetching → done.
Return value
signature string
Transaction signature.
market MarketAccount | null
Market account after the reveal callback ran. Check market.state - it will be 4 (PendingResolution) at this point.
computation ComputationResult
Arcium callback result.
flagResolution v0.2+
Flags a pending resolution as disputed during the challenge window. Permissionless - anyone can call this if they believe the outcome is wrong.
const flag = await client.actions.flagResolution({
flagger: walletPublicKey,
marketId: 42n,
});flagger PublicKey required
Caller's public key (any wallet).
marketId bigint | number required
A market in PendingResolution (state 4) that has not yet been flagged.
After flagging, the market enters a disputed state. Payouts are blocked until an admin calls adminOverrideResolution.
finalizeResolution v0.2+
Finalizes a pending resolution after the challenge window elapses undisputed. Permissionless - anyone can call this to move the market to Resolved.
const finalize = await client.actions.finalizeResolution({
caller: walletPublicKey,
marketId: 42n,
});caller PublicKey required
Any wallet (permissionless).
marketId bigint | number required
A market in PendingResolution that is not disputed and whose challengePeriod has elapsed.
After this call the market state becomes Resolved and claim_deadline is set, opening the payout window.
adminOverrideResolution v0.2+
Overrides the outcome on a disputed market. Admin-only.
const override = await client.actions.adminOverrideResolution({
admin: adminPublicKey,
marketId: 42n,
outcomeValue: 0, // corrected outcome
});admin PublicKey required
Must match globalState.admin on-chain.
marketId bigint | number required
A disputed market in PendingResolution.
outcomeValue number required
Corrected outcome index. The program recomputes payout_ratio from the already-revealed plaintext pools using this value.
After this call the market moves to Resolved and the ResolutionOverriddenEvent is emitted.
Phase gate reference
| Action | Required phase | Required state |
|---|---|---|
resolveMarket |
awaitingResolve |
Active or Closed, past closeTime |
flagResolution |
pendingResolution |
PendingResolution (4), not disputed |
finalizeResolution |
awaitingFinalize |
PendingResolution (4), not disputed, window elapsed |
adminOverrideResolution |
disputed |
PendingResolution (4), disputed |