Skip to main content

zora-coins

Typed Python SDK for Zora Coins, plus an onchain indexer for the creator and referral rewards Zora pays on every trade.

Zora's official SDK is TypeScript-only. zora-coins covers the same public API from Python (all 30 endpoints) with typed, documented models generated from Zora's own OpenAPI spec, and adds something neither the SDK nor the API offers: how much an address has actually earned as a creator, platform referrer or trade referrer, read directly from Base.

Part of zora-coins-sdks: the same types, names and docs in Python, TypeScript, Go, Rust, C#, Java and C++, plus a GraphQL gateway over the whole API.

Unofficial and community-maintained. Not affiliated with Zora.

pip install zora-coins

Python 3.10+. Dependencies: httpx, pydantic.

Quick start

from zora_coins import ZoraCoins, ListType, eth, erc20

with ZoraCoins() as zora:                      # reads ZORA_API_KEY; or ZoraCoins(api_key="...")
    coin = zora.get_coin("0x0b8590d3c0b1ee6c797e184a4afbb15f8f58a46b")
    print(coin.name, coin.market_cap, coin.unique_holders, coin.creator_profile.handle)

    for c in zora.iter_explore(ListType.top_volume_24_h, limit=10):   # follows pagination
        print(c.symbol, c.volume24h)

    for holder in zora.iter_coin_holders(coin.address, limit=100):
        print(holder.owner_address, holder.balance)

    # Build a trade. Nothing is signed or sent: pass quote.call to your wallet library.
    quote = zora.quote_trade(eth(), erc20(coin.address), amount_in=10**15, sender="0xYourWallet")
    tx = {"to": quote.call.target, "data": quote.call.data, "value": int(quote.call.value)}

Async works the same way:

from zora_coins import AsyncZoraCoins

async with AsyncZoraCoins() as zora:
    profile = await zora.get_profile("rebelstudios")
    async for coin in zora.iter_profile_coins("rebelstudios"):
        print(coin.symbol)

What's covered

Every endpoint, with an iter_* for every paginated one (method names in every language):

Area Methods
Coins get_coin, get_coins, get_coin_holders / iter_coin_holders, get_coin_swaps / iter_coin_swaps, get_coin_comments / iter_coin_comments, get_coin_merged_comments / iter_coin_merged_comments, get_coin_price_history, get_coins_list / iter_coins_list, get_token_info
Explore explore / iter_explore (all 25 list types), search / iter_search, get_trader_leaderboard / iter_trader_leaderboard, get_featured_creators / iter_featured_creators, get_trend_coin, get_trends_by_name / iter_trends_by_name
Live get_latest_live_streams / iter_latest_live_streams, get_top_live_streams / iter_top_live_streams, get_creator_livestream_comments / iter_creator_livestream_comments
Profiles get_profile, get_profile_coins / iter_profile_coins (filter by platform_referrer), get_profile_balances / iter_profile_balances, get_profile_social, get_profile_by_social_handle, get_wallet_trade_activity / iter_wallet_trade_activity
Transactions quote_trade (buy/sell calldata with optional trade referrer), create_content_coin (creation calls + predicted address, optional platform_referrer), create_upload_jwt, pool configs, get_api_key

Every response is a documented pydantic model (zora_coins.models), and your editor shows each field's meaning on hover, units included: marketCap is a USD decimal string, but balance is an 18-decimal integer string. Rate limits (429) and 5xx responses are retried with backoff; API errors raise ZoraAPIError, whose error_type says why a quote failed (insufficient_liquidity for a pool that can't fill the trade).

Why every field is Optional: the live API omits fields its spec marks as required. For example, V4 coins have no uniswapV3PoolAddress, and zoraComments is absent unless requested. Strict models rejected real responses from 9 of 24 endpoints, so the models accept what the API actually returns. Enum fields also accept strings, so a list type Zora adds later doesn't fail validation.

GraphQL

from zora_coins.graphql import ZoraGraphQL
from zora_coins.models import Zora20Token

gql = ZoraGraphQL("http://localhost:8080/graphql")      # the zora-coins GraphQL gateway
data = gql.query('query($a: String!) { coin(address: $a) { name symbol marketCap } }', {"a": "0x…"})
coin = Zora20Token.model_validate(data["coin"])         # the same models as REST

AsyncZoraGraphQL has the same interface. The gateway is at zora-coins-sdks/graphql.

Rewards: what did an address earn?

Every trade on a Zora coin pays out to the coin's creator, the platform that launched it, the interface that routed the trade, and the protocol. On V4 coins those payouts are recorded in CoinMarketRewardsV4 events, plus CreatorCoinRewards for the creator's and protocol's shares on creator-coin trades (in a sample day on Base, nearly half of what creators earned), and none of the recipient fields are indexed. You can't ask a node for "rewards paid to my address"; you have to read every reward event and filter. zora_coins.rewards does that, keeps a local SQLite index, and only fetches blocks it hasn't seen.

zora-rewards 0xYourAddress --days 30 --html rewards.html

Real output for a busy platform-referrer address over the last 6 hours:

Zora rewards for 0x55c88bb05602da94fce8feadc1cbebf5b72c2453
291 reward events, blocks 51426603–51437322
  Platform referral          328.5866 ZORA                $2.52  (34 payouts)
  Platform referral       0.000114798 WETH                $0.28  (6 payouts)
  Platform referral            5.4734 USDC                $5.47  (98 payouts)
  Trade referral          1.07698e-07 ETH            $0.0002655  (2 payouts)
  Trade referral             136.7589 ZORA                $1.05  (143 payouts)
  Trade referral          0.000130539 WETH                $0.32  (16 payouts)
  Trade referral             0.737777 USDC                $0.74  (44 payouts)
  Total (current prices)                                     $10.39
from zora_coins.rewards import RewardsIndexer, build_report, to_text

with RewardsIndexer("rewards.sqlite", rpc_url="https://mainnet.base.org") as idx:
    idx.scan(["0xYourAddress"], days=30)            # resumable; re-runs fetch only new blocks
    report = build_report(idx.events_for(["0xYourAddress"]), ["0xYourAddress"])
print(to_text(report), report.by_role_usd())
  • Roles: creator (payoutRecipient), platform referrer, trade referrer, protocol, and Doppler.
  • Amounts: kept as exact integers, in both the backing currency (ZORA, ETH, USDC or a creator coin) and the coin itself.
  • USD values: use current token prices from the Zora API, not the price at payout time.
  • Coverage: both V4 payout events; legacy V3 coins (CoinTradeRewards) with --v3. An index built before CreatorCoinRewards was read re-scans its blocks once.
  • Speed: on the public Base RPC, six hours of blocks (about 10,800) scans in about 8 seconds. A private RPC (--rpc) is faster for long histories.

Development

python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest                    # offline tests (mocked HTTP and RPC, real recorded payloads)
.venv/bin/python scripts/validate_live.py   # every endpoint against production
./scripts/generate_models.sh        # refresh models from Zora's OpenAPI spec

License

MIT © Rebel Studios Software

Release files for zora-coins 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zora-coins 0.2.1
File Size Uploaded
zora_coins-0.2.1.tar.gz 94.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for zora-coins 0.2.1
File Interpreter ABI Platform
zora_coins-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 136.9 kB

Release files / zora_coins-0.2.1.tar.gz

Download URL zora_coins-0.2.1.tar.gz
Size 94.6 kB
Tags Source
SHA-256 checksum
How to use checksums
4cc20a0ff46ad57578509c82151e9c5ef4948528c8b599b4a4a28de3844f6e6c
BLAKE2b-256 checksum
How to use checksums
3c8fa20a618a4791255e306eeb46c5323b3fa3c6db907050444ed0fe249fc669
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

Release files / zora_coins-0.2.1-py3-none-any.whl

Download URL zora_coins-0.2.1-py3-none-any.whl
Size 42.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7f022390e3f2ae8c56b2d63f64a17c3fbb27171fc58f143637a250daa703b787
BLAKE2b-256 checksum
How to use checksums
ad3d9aff117c4035626d57453b9b3026b50b0f515219091efa104e968c85d487
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

0.2.1 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page