Metadata-Version: 2.4
Name: mosaic-sdk
Version: 0.1.0
Summary: Python SDK for Mosaic bounty contracts on Base — transactions, signing, events, and metadata
Author-email: Mosaic <hello@usemosaic.xyz>
License-Expression: MIT
Project-URL: Homepage, https://github.com/usemosaicxyz/mosaic-sdk
Project-URL: Repository, https://github.com/usemosaicxyz/mosaic-sdk
Project-URL: Issues, https://github.com/usemosaicxyz/mosaic-sdk/issues
Keywords: mosaic,bounty,base,ethereum,usdc,sdk,python
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: eth-abi>=5.2.0
Requires-Dist: eth-account>=0.13.7
Requires-Dist: eth-hash[pycryptodome]>=0.8.0
Requires-Dist: eth-utils>=5.3.0
Requires-Dist: httpx>=0.28.1
Requires-Dist: loguru>=0.7.3
Dynamic: license-file

# mosaic-sdk

Python SDK for [Mosaic](https://usemosaic.xyz) bounty contracts on Base. Build and sign on-chain transactions, decode contract events, and load bounty metadata from Arweave or HTTP.

This package complements the TypeScript SDK ([`usemosaicxyz/ts-sdk`](https://github.com/usemosaicxyz/ts-sdk)), which also integrates the Mortar read API. The Python SDK focuses on wallet/RPC workflows and log indexing.

## Requirements

- Python **3.12+**
- An RPC endpoint for Base mainnet (chain id `8453`)
- A deployed Mosaic bounties contract address
- A private key only when you need to **sign and broadcast** transactions via `MosaicClient.send`

## Install

From a clone of this repository:

```bash
uv sync
# or: pip install -e .
```

Dependencies are declared in `pyproject.toml` (`eth-account`, `eth-abi`, `httpx`, `loguru`, etc.).

## Quick start

### Build transactions (no private key)

Use `MosaicClient` to assemble unsigned transaction dicts (`chainId`, `to`, `data`, `value`). Pass them to your own signer or hardware wallet.

```python
import asyncio
from mosaic_sdk import MosaicClient, canonical_metadata_hash

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

metadata = {"version": 1, "title": "Fix login redirect", "brief": "..."}
metadata_hash = canonical_metadata_hash(metadata)
metadata_uri = "ar://your-tx-id"  # or any URI your deployment accepts

approve_tx = client.approve_usdc(50_000_000)  # 50 USDC (6 decimals)
create_tx = client.create_bounty(
    metadata_uri=metadata_uri,
    metadata_hash=metadata_hash,
    reward_amount=25_000_000,
    duration=86_400,
)
```

### Sign and broadcast

Provide `private_key` when calling `send`. **Never commit keys**; load from environment variables or a secret manager in your application.

```python
import os
import asyncio

client = MosaicClient(
    rpc_url=os.environ["RPC_URL"],
    contract_address=os.environ["CONTRACT_ADDRESS"],
    private_key=os.environ["PRIVATE_KEY"],
)

async def main():
    tx_hash = await client.send(client.create_bounty(...))
    print(tx_hash)

asyncio.run(main())
```

### Decode events

```python
from mosaic_sdk import decode_event

# `log` is an Ethereum log object (e.g. from `eth_getLogs`)
event = decode_event(log)
# {"name": "BountyCreated", "bountyId": 1, "poster": "0x...", ...}
```

### Load and verify metadata

```python
import asyncio
from mosaic_sdk import load_metadata, canonical_metadata_hash

async def main():
    metadata = await load_metadata(
        "ar://your-tx-id",
        expected_hash=canonical_metadata_hash({...}),
    )

asyncio.run(main())
```

`load_metadata` resolves `ar://` URIs via the Arweave gateway (default `https://arweave.net`) and checks the canonical JSON hash when `expected_hash` is set.

## Defaults (Base mainnet)

| Constant | Value |
|----------|--------|
| `BASE_CHAIN_ID` | `8453` |
| `BASE_USDC` | Base native USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`) |

`MosaicClient` enforces Base + native USDC for v1. Override is not supported until a future version documents other networks.

## API surface

**`MosaicClient`** — transaction builders and RPC sender:

- `approve_usdc`, `create_bounty`, `submit`, `dispute`
- `finalize`, `advance_review_cursor`, `refund_submission_bond`, `refund_expired`
- `resolve_dispute`, `cancel_resolved_dispute`
- `withdraw`, `withdraw_to`
- Admin: `set_config`, `set_allowed_duration`, `set_grout`, `set_admin`
- `send(tx)` — estimate gas, sign, and broadcast (requires `private_key`)

**`decode_event(log)`** — decode Mosaic bounty contract logs.

**`canonical_metadata_hash(metadata)`** — keccak256 of canonical JSON (`sort_keys`, compact separators).

**`load_metadata(uri, expected_hash?, gateway?)`** — fetch JSON metadata and optionally verify hash.

## Configuration and secrets

Keep sensitive values out of source control:

| Variable | Purpose |
|----------|---------|
| `RPC_URL` | Base JSON-RPC URL (may include provider API keys in the path) |
| `CONTRACT_ADDRESS` | Mosaic bounties contract |
| `PRIVATE_KEY` | Hex-encoded key for `send` only |

See `.env.example` for a template. Copy to `.env` locally (gitignored).

## Related projects

- [Mosaic](https://usemosaic.xyz) — on-chain bounties settled in USDC on Base
- [`usemosaicxyz/ts-sdk`](https://github.com/usemosaicxyz/ts-sdk) — TypeScript SDK + Mortar API client

## License

MIT
