Hartii developer docs

Games

Integrate

Read a wallet's claimable ranked winnings

No wallet signature needed — this is a pure read.

js
const res = await fetch(`https://hartiigames.com/api/claimable/${walletAddress}`);
const { pools, totalQuai } = await res.json();
// pools: [{ game, pool, wei, quai }] — nonzero claimableBalances(wallet) per pool

Claim a ranked payout on-chain

The API never moves funds — claiming is always the winner's own transaction against the game's pool contract.

js
import { quais } from 'quais';

const POOL_ABI = [
  'function claimPayout() external',
  'function claimableBalances(address) view returns (uint256)',
];

async function claimPrize(signer, poolAddress) {
  const pool = new quais.Contract(quais.getAddress(poolAddress.toLowerCase()), POOL_ABI, signer);
  const owed = await pool.claimableBalances(await signer.getAddress());
  if (owed === 0n) return null;
  const tx = await pool.claimPayout();
  return tx.wait();
}

Enter ranked play (currently hash-wars only, and gated by a global kill switch)

Step 1 — pay the pool on-chain:

js
const POOL_ENTER_ABI = ['function enterRanked() external payable'];

async function payEntry(signer, poolAddress, tierQuoteWei) {
  const pool = new quais.Contract(quais.getAddress(poolAddress.toLowerCase()), POOL_ENTER_ABI, signer);
  const tx = await pool.enterRanked({ value: tierQuoteWei });
  const receipt = await tx.wait();
  return receipt.hash;
}

Step 2 — hand the tx hash to the API to get a run seed:

js
async function enterRanked({ gameId, tier, wallet, txHash }) {
  const res = await fetch('https://hartiigames.com/api/ranked/enter', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ gameId, tier, wallet, txHash, ack: true }),
  });
  if (!res.ok) throw new Error((await res.json()).error);
  return res.json(); // { runId, seed, gameId, tier }
}

Step 3 — play the deterministic sim against seed, then submit for verification:

js
async function submitRun({ runId, score, inputLog }) {
  const res = await fetch('https://hartiigames.com/api/ranked/submit', {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ runId, score, inputLog }),
  });
  return res.json(); // { accepted, reason?, replayScore? } or a promotion result on success
}

Read the current gas/QUAI-price quote before building a tx

js
const [gas, price] = await Promise.all([
  fetch('https://hartiigames.com/api/gas').then((r) => r.json()),
  fetch('https://hartiigames.com/api/quai-price').then((r) => r.json()),
]);
// gas.usd.entry / gas.usd.claim — measured USD cost per action, gas.elevated flags a fee spike

Buy HARTII

js
const SALE_ABI = ['function buy() external payable', 'function quote(uint256) view returns (uint256)'];

async function buyHartii(signer, saleAddress, quaiInWei) {
  const sale = new quais.Contract(quais.getAddress(saleAddress.toLowerCase()), SALE_ABI, signer);
  const tx = await sale.buy({ value: quaiInWei });
  return tx.wait();
}

Biome — read cross-product stats (no auth, no wallet)

js
const [chain, prices, ecosystem] = await Promise.all([
  fetch('https://hartiibiome.com/api/chain').then((r) => r.json()),
  fetch('https://hartiibiome.com/api/prices').then((r) => r.json()),
  fetch('https://hartiibiome.com/api/ecosystem').then((r) => r.json()),
]);
Quai Network mainnet · chain 9 · Cyprus-1. Figures marked "read on" a date were read from the chain that day; re-read before relying on them.