Documentation

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.

Package: npm · GitHub

Install

npm install @usemosiac/ts-sdk
pnpm add @usemosiac/ts-sdk
yarn add @usemosiac/ts-sdk
bun add @usemosiac/ts-sdk

Import

import {
  canonicalJson,
  createMosaicApiClient,
  createMosaicSdk,
  metadataToDataUri,
  quoteCreateAmount,
} from "@usemosiac/ts-sdk";

Configure

const GIWA_SEPOLIA_CHAIN_ID = 91342;
const MOSAIC_ADDRESS = "0x7ebC4d9EfA037dFaAfBB80025A09B249eCFf4F84" as const;
const TEST_USDC_ADDRESS = "0x25ceeBa0a118DA5C346a5328D7cC5f26aa331d17" as const;

const sdk = createMosaicSdk({
  chainId: GIWA_SEPOLIA_CHAIN_ID,
  contractAddress: MOSAIC_ADDRESS,
  usdcAddress: TEST_USDC_ADDRESS,
});

Active values:

FieldValue
chainId91342
contractAddress0x7ebC4d9EfA037dFaAfBB80025A09B249eCFf4F84
usdcAddress0x25ceeBa0a118DA5C346a5328D7cC5f26aa331d17

Explicit configuration above is required for the active deployment and uses the package's public API.

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

HelperContract 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 deployment = "chain_id=91342&contract_address=0x7ebC4d9EfA037dFaAfBB80025A09B249eCFf4F84";
const bounty = await fetch(`https://api.example/bounties/1?${deployment}`).then((response) => response.json());
const submissions = await fetch(`https://api.example/submissions?bounty_id=1&${deployment}`).then((response) => response.json());
const disputes = await fetch(`https://api.example/disputes?submission_id=1&${deployment}`).then((response) => response.json());
MethodHTTP 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 0.1.0 TypeScript client does not qualify requests by deployment. Use direct Mortar requests with both chain_id and contract_address for collision-safe reads until 0.2.0 is published. Paginated and overview routes are documented in Reference.

Metadata Helpers

HelperReturn
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 match 0x plus 40 hex characters.
  • bytes32 value must be 32 bytes: hash must be 32 bytes.
  • number must be a safe uint: use bigint or a decimal string for large values.
  • uint{bits} value out of range: unsigned integer exceeds the ABI type width.

On this page