Skip to main content

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.

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.
TypeScript
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.
TypeScript
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.
TypeScript
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.
TypeScript
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

ActionRequired phaseRequired state
resolveMarketawaitingResolveActive or Closed, past closeTime
flagResolutionpendingResolutionPendingResolution (4), not disputed
finalizeResolutionawaitingFinalizePendingResolution (4), not disputed, window elapsed
adminOverrideResolutiondisputedPendingResolution (4), disputed