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
Protocol
Contract roles, funding, review, dispute, and payout rules.
Lifecycle
Create, submit, dispute, finalize, refund, and withdraw paths.
Metadata
URI and hash fields for bounty, submission, and dispute records.
SDKs
TypeScript and Python transaction helpers.
Core Flow
- Poster approves USDC for reward plus post fee.
- Poster creates a bounty with metadata URI, metadata hash, reward amount, and allowed duration.
- Tile approves the submission bond and submits before the bounty deadline.
- Submission review starts at submission time.
- Whitelisted grout disputes during the submission review window.
- Mosaic review resolves pending disputes.
- Public caller finalizes the current review target after the bounty deadline and submission review deadline.
- Credited accounts call
withdraworwithdrawTo.
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,
)