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, and none of that event's 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: legacy V3 coins (CoinTradeRewards) with --v3.
  • 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.0

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.0
File Size Uploaded
zora_coins-0.2.0.tar.gz 92.8 kB Details

Built distribution (wheel)

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

Total release size: 134.5 kB

Release files / zora_coins-0.2.0.tar.gz

Download URL zora_coins-0.2.0.tar.gz
Size 92.8 kB
Tags Source
SHA-256 checksum
How to use checksums
33fa6e18b62cc96642d3f9d05540a86276271d15226d4a7adb8be91a544c3aa7
BLAKE2b-256 checksum
How to use checksums
aa9d9ab766fa5a0a4f3c87068060878b144e32e2d5aa92e3d899b596241fec93
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.0-py3-none-any.whl

Download URL zora_coins-0.2.0-py3-none-any.whl
Size 41.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3cd12928ab07b312da85c9b2b68c9e3a6c2f047ace9ac84bb4ca9130b90277b7
BLAKE2b-256 checksum
How to use checksums
8c85143431a66ccc2d319edde23438181664ba74400ea179373955b332dd14df
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

0.2.1

2 release files

This release

0.2.0 This release

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