Documentation

Overview

Mosaic protocol, read API, and SDK entry points.

Mosaic is a USDC bounty protocol on Base. Posters create funded bounties. Tiles submit bonded work. Whitelisted grouts dispute submitted work. Accepted tiles withdraw credited USDC.

Roles

  • Poster: creates a bounty and funds the reward plus post fee.
  • Tile: submits work and locks the submission bond.
  • Grout: whitelisted account allowed to dispute a submission during review.
  • Public caller: finalizes eligible bounties, advances the review cursor, and cleans up closed disputes.
  • Credited account: withdraws its own credited USDC.

SDK Defaults

Chain: Base mainnet (8453). Token: native Base USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913). Contract: 0x0c7fad7C9bBaD0BE62aAc867c6069d7Aad7Cb361.

Sections

Core Flow

  1. Poster approves USDC for reward plus post fee.
  2. Poster creates a bounty with metadata URI, metadata hash, reward amount, and allowed duration.
  3. Tile approves the submission bond and submits before the bounty deadline.
  4. Submission review starts at submission time.
  5. Whitelisted grout disputes during the submission review window.
  6. Mosaic review resolves pending disputes.
  7. Public caller finalizes the current review target after the bounty deadline and submission review deadline.
  8. Credited accounts call withdraw or withdrawTo.

SDK Entry Points

TypeScript exports unsigned wallet transactions via @usemosiac/ts-sdk (npm · GitHub). Python exports transaction dicts and metadata helpers.

import { canonicalJson, createMosaicSdk, metadataToDataUri } from "@usemosiac/ts-sdk";
import { keccak256, stringToBytes } from "viem";

const mosaicAddress = "0x0c7fad7C9bBaD0BE62aAc867c6069d7Aad7Cb361" as const;

const sdk = createMosaicSdk({
  contractAddress: mosaicAddress,
});

const metadata = {
  version: 1,
  title: "Find a reproducible bug",
  brief: "Submit a minimal reproduction and a fix suggestion.",
};

const metadataHash = keccak256(stringToBytes(canonicalJson(metadata)));

const post = sdk.createBounty({
  metadataUri: metadataToDataUri(metadata),
  metadataHash,
  rewardAmount: 50_000_000n,
  duration: 86_400,
});
from mosaic_sdk import MosaicClient, canonical_metadata_hash

client = MosaicClient(
    rpc_url="https://mainnet.base.org",
    contract_address="0x0c7fad7C9bBaD0BE62aAc867c6069d7Aad7Cb361",
)

metadata = {
    "version": 1,
    "title": "Find a reproducible bug",
    "brief": "Submit a minimal reproduction and a fix suggestion.",
}

post = client.create_bounty(
    metadata_uri="ar://bounty-json",
    metadata_hash=canonical_metadata_hash(metadata),
    reward_amount=50_000_000,
    duration=86_400,
)

Next Pages

On this page