TypeScript SDK
TypeScript helpers for Mosaic wallet transactions, quotes, metadata, and indexed reads.
@usemosiac/ts-sdk exports transaction builders. Each builder returns an unsigned WalletTx.
Install
npm install @usemosiac/ts-sdkpnpm add @usemosiac/ts-sdkyarn add @usemosiac/ts-sdkbun add @usemosiac/ts-sdkImport
import {
canonicalJson,
createMosaicApiClient,
createMosaicSdk,
metadataToDataUri,
quoteCreateAmount,
} from "@usemosiac/ts-sdk";Configure
const mosaicAddress = "0x0c7fad7C9bBaD0BE62aAc867c6069d7Aad7Cb361" as const;
const sdk = createMosaicSdk({
contractAddress: mosaicAddress,
});Defaults:
| Field | Value |
|---|---|
chainId | 8453 |
usdcAddress | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
Create Bounty
import { keccak256, stringToBytes } from "viem";
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 funding = quoteCreateAmount(50_000_000n);
const approve = sdk.approveUsdc(funding.totalAmount);
const create = sdk.createBounty({
metadataUri: metadataToDataUri(metadata),
metadataHash,
rewardAmount: funding.rewardAmount,
duration: 86_400,
});Send approve before create. The contract pulls reward plus post fee during createBounty.
Submit Work
const submit = sdk.submit({
bountyId: 1n,
metadataUri: "ar://submission-json",
metadataHash: "0x1111111111111111111111111111111111111111111111111111111111111111",
});The contract pulls the bounty submission bond during submit.
Dispute Work
const dispute = sdk.dispute({
submissionId: 4n,
metadataUri: "ar://dispute-json",
metadataHash: "0x2222222222222222222222222222222222222222222222222222222222222222",
});The contract pulls the dispute bond during dispute. The caller must be a whitelisted grout.
Transaction Result
Every transaction helper returns:
type WalletTx = {
chainId: number;
to: `0x${string}`;
data: `0x${string}`;
value: `0x${string}`;
};value is always 0x0.
Transaction Helpers
| Helper | Contract Call |
|---|---|
approveUsdc(amount) | USDC approve(contractAddress, amount) |
createBounty(input) | createBounty(string,bytes32,uint256,uint64) |
submit(input) | submit(uint256,string,bytes32) |
dispute(input) | dispute(uint256,string,bytes32) |
finalize(bountyId) | finalize(uint256) |
advanceReviewCursor(bountyId) | advanceReviewCursor(uint256) |
refundExpired(bountyId) | refundExpired(uint256) |
refundSubmissionBond(submissionId) | refundSubmissionBond(uint256) |
cancelResolvedDispute(challengeId) | cancelResolvedDispute(uint256) |
withdraw() | withdraw() |
withdrawTo(recipient) | withdrawTo(address) |
Read API Client
const api = createMosaicApiClient({ baseUrl: "https://api.example" });
const bounties = await api.listBounties();
const bounty = await api.getBounty(1);
const submissions = await api.listSubmissions(1);
const disputes = await api.listDisputes();| Method | HTTP Request |
|---|---|
listBounties() | GET /bounties |
getBounty(bountyId) | GET /bounties/{bountyId} |
listSubmissions() | GET /submissions |
listSubmissions(bountyId) | GET /submissions?bounty_id=... |
listDisputes() | GET /disputes |
listDisputes(submissionId) | GET /disputes?submission_id=... |
The client throws mortar request failed {status} when the HTTP response is not OK.
The published TypeScript client exposes the methods above. Paginated and overview reads are Mortar HTTP routes documented in Reference.
Metadata Helpers
| Helper | Return |
|---|---|
canonicalJson(value) | JSON string with sorted object keys and no undefined fields. |
metadataToDataUri(metadata) | data:application/json,... URI containing canonical JSON. |
parseMetadataUri(uri) | Parsed inline JSON or null. |
quoteCreateAmount(rewardAmount, config?) | Reward, submission bond, post fee, and total poster funding. |
Validation Errors
invalid address: address must match0xplus 40 hex characters.bytes32 value must be 32 bytes: hash must be 32 bytes.number must be a safe uint: usebigintor a decimal string for large values.uint{bits} value out of range: unsigned integer exceeds the ABI type width.
