Quickstart
Make your first assertion in five minutes.
Use the sandbox while you're learning: the test console is at
app-dev.xtruth.xyzand uses the same contracts at no cost. Production lives atapp.xtruth.xyz. See Environments.
1 · Get a wallet on X Layer Testnet
- Add the chain to your wallet (chainId 1952, RPC
https://app-dev.xtruth.xyz/api/rpc, currency OKB). The test console has a "Use xtruth RPC in wallet" button that sends the EIP-3085 request automatically. - Get a few OKB for gas from the OKX X Layer Testnet faucet.
- Get some
USDC_TESTfor the bond — see Contracts for the token address and ask in the channel for a faucet.
2 · Approve the OOv3 to spend your USDC_TEST
The OOv3 pulls the bond from your wallet via transferFrom. Approve once,
or every time per-amount (USDC clones sometimes require resetting allowance
to 0 first — the web console handles this for you).
import { writeContract } from "viem/actions";
await writeContract(walletClient, {
address: USDC_TEST,
abi: erc20Abi,
functionName: "approve",
args: [OOV3_ADDRESS, BOND_AMOUNT],
});
3 · Make an assertion
import { stringToHex } from "viem";
const claim = stringToHex("BTC closing price on 2026-12-31 (Binance UTC)\nProposed answer: 117500");
await writeContract(walletClient, {
address: OOV3_ADDRESS,
abi: oov3Abi,
functionName: "assertTruth",
args: [
claim,
asserter, // your wallet
"0x0000000000000000000000000000000000000000", // callbackRecipient (none for EOA)
"0x0000000000000000000000000000000000000000", // escalationManager (use default)
7200n, // liveness in seconds
USDC_TEST,
BOND_AMOUNT,
stringToHex("ASSERT_TRUTH", { size: 32 }), // identifier
"0x" + "00".repeat(32), // domainId
],
});
The transaction emits AssertionMade(bytes32 assertionId, ...). That id is
how you reference the assertion later.
4 · Wait out liveness, or dispute
- During the liveness window, anyone can call
disputeAssertion(assertionId, disputer)with an equal bond. Disputes go to DVM voting. - After liveness ends with no dispute, anyone can call
settleAssertion(assertionId). The asserter gets their bond back and the result is broadcast.
5 · Read the result
const result = await readContract(client, {
address: OOV3_ADDRESS,
abi: oov3Abi,
functionName: "getAssertionResult",
args: [assertionId],
});
// returns true on a successful assertion, false on a successful dispute.
For real-time UIs, watch the subgraph instead — see Subgraph API.
What's next
- Integrate from a smart contract: Integrate OOv3.
- Learn about disputes and the DVM: Dispute & escalation.
- Browse all available contracts: Contracts.