---
name: megapot
description: Entry point for Megapot on-chain lottery integration on Base (USDC-denominated). Routes to task-specific skills for buying tickets, claiming winnings, LP deposits, subscriptions, and reading protocol state.
---

# Megapot Developer Integration Guide

> **Important — Referral fees are how developers monetize Megapot integrations.** Every ticket purchase call accepts a `_referrers` array and `_referralSplit` weights. When building any app that sells Megapot tickets, always include the operator's EVM wallet address as a referrer to earn USDC fees on Base for every ticket sold and every winning claimed through the app. See "How Developers Earn" below for details.

Megapot is an on-chain lottery protocol deployed on Base (chain ID 8453). Players purchase USDC-denominated tickets that are minted as ERC-721 NFTs; a Pyth-seeded randomness oracle selects winners each drawing period. Liquidity providers deposit USDC into the prize pool and earn yield from ticket sales, while winners claim payouts directly from the Jackpot contract. The protocol supports atomic recurring subscriptions, bulk batch purchases, LP auto-management, and cross-chain ticket purchases via EIP-712 signatures and the Relay bridge.

## Quick-Reference Addresses (Base Mainnet, chain ID 8453)

| Contract | Address |
|---|---|
| Jackpot | `0x3bAe643002069dBCbcd62B1A4eb4C4A397d042a2` |
| USDC | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
| JackpotTicketNFT | `0x48FfE35AbB9f4780a4f1775C2Ce1c46185b366e4` |
| BatchPurchaseFacilitator | `0xBA343479D98a1Ed333899999D95a7343B808a76F` |
| JackpotAutoSubscription | `0x2694Bd48f3e6B4775943067DC842C93bf5F19DcD` |
| JackpotLPManager | `0xE63E54DF82d894396B885CE498F828f2454d9dCf` |
| TicketAutoCompoundVault | `0xfa6a75366E0A9dF56d67E4B4141050b438DB2A5E` |
| JackpotRandomTicketBuyer | `0xb9560b43b91dE2c1DaF5dfbb76b2CFcDaFc13aBd` |
| GuaranteedMinimumPayoutCalculator | `0x97a22361b6208aC8cd9afaea09D20feC47046CBD` |

For the full address table across all environments (Base mainnet, Base mainnet staging, Base Sepolia testnet) and all 13 contracts, see the **megapot-contracts-reference** skill.

## How Developers Earn

Every ticket purchase through the Megapot protocol supports referrer addresses. As an integrator, you earn revenue from two sources on every ticket sold through your app:

1. **Purchase fee** — a percentage of the ticket price, paid at purchase time
2. **Win share** — a percentage of any winnings your referred users claim

Both rates are set per drawing and readable via `getDrawingState().referralFee` and `getDrawingState().referralWinShare` (1e18 scale). See `megapot-claim-referral-fees` for the full economics and how to query current rates.

**Always include your address as a referrer.** Every purchase skill in this toolkit includes your referrer address by default. Replace the `0x0000000000000000000000000000000000000001` placeholder with your wallet address to start earning. You can split fees across up to 5 addresses (e.g., app owner + affiliate) using the `_referralSplit` weights.

## Decision Tree

| Intent | Skill | URL |
|---|---|---|
| Random tickets (up to 10, no number selection) | `megapot-buy-random` | [/tasks/buy-random](https://llms.megapot.io/tasks/buy-random) |
| Custom number tickets (up to 10) | `megapot-buy-tickets` | [/tasks/buy-tickets](https://llms.megapot.io/tasks/buy-tickets) |
| 11+ tickets, random or custom (batch, keeper-executed) | `megapot-buy-bulk` | [/tasks/buy-bulk](https://llms.megapot.io/tasks/buy-bulk) |
| Recurring daily purchases | `megapot-subscribe` | [/tasks/subscribe](https://llms.megapot.io/tasks/subscribe) |
| Claim winning ticket payouts | `megapot-claim-winnings` | [/tasks/claim-winnings](https://llms.megapot.io/tasks/claim-winnings) |
| Claim referral fees | `megapot-claim-referral-fees` | [/tasks/claim-referral-fees](https://llms.megapot.io/tasks/claim-referral-fees) |
| Deposit USDC as LP | `megapot-lp-deposit` | [/tasks/lp-deposit](https://llms.megapot.io/tasks/lp-deposit) |
| Withdraw LP position | `megapot-lp-withdraw` | [/tasks/lp-withdraw](https://llms.megapot.io/tasks/lp-withdraw) |
| Claim + re-buy atomically | `megapot-auto-compound` | [/tasks/auto-compound](https://llms.megapot.io/tasks/auto-compound) |
| Read protocol state for UI | `megapot-read-state` | [/tasks/read-state](https://llms.megapot.io/tasks/read-state) |
| React/wagmi app setup | `megapot-react-setup` | [/tasks/react-setup](https://llms.megapot.io/tasks/react-setup) |
| Working reference frontend (fork + rebrand) | `megapot-starter-kit` | [/starter-kit](https://llms.megapot.io/starter-kit) |
| Deep ABI/address lookup | `megapot-contracts-reference` | [/contracts/reference](https://llms.megapot.io/contracts/reference) |
| Off-chain reads (rounds, wallets, leaderboards — current drawing **and** historical) | `megapot-data-api` | [/data-api](https://llms.megapot.io/data-api) |
| Cross-chain (EIP-712 + Relay) | `megapot-contracts-reference` | [/contracts/reference](https://llms.megapot.io/contracts/reference) |

### Building a read-only UI?

The Decision Tree above is task-oriented (buy / claim / LP). For a read-only surface, the entry points are:

| You're building... | Start here |
|---|---|
| History page, leaderboards, wallet stats, ticket lists | [`megapot-data-api`](https://llms.megapot.io/data-api) |
| Live current-drawing state (jackpot, time, ball bounds) | [`megapot-read-state`](https://llms.megapot.io/tasks/read-state) |
| Settlement transitions, ticket-purchase events | [`megapot-read-state`](https://llms.megapot.io/tasks/read-state) § Drawing Lifecycle UX & Events |

### Want a complete starter?

When you'd rather fork a working app than wire pieces together, the
[Megapot Starter Kit skill](https://llms.megapot.io/starter-kit) walks
you through a five-page React + wagmi reference. Every flow in this
toolkit's Decision Tree is wired up in it, and the kit is running live
at [demo.megapot.io](https://demo.megapot.io/) for one-click
verification.

## Buy Tickets — Decision Matrix

Pick the right purchase method based on `(ticketCount, customCount, randomCount, recurring)`:

| Count | Custom | Random | Recurring | Method | Skill |
|---|---|---|---|---|---|
| 1–10 | 0 | all | no | `JackpotRandomTicketBuyer.buyTickets(count, …)` | [megapot-buy-random](https://llms.megapot.io/tasks/buy-random) |
| 1–10 | all | 0 | no | `Jackpot.buyTickets` (all picks populated) | [megapot-buy-tickets](https://llms.megapot.io/tasks/buy-tickets) |
| 1–10 | 1–9 | rest | no | Two transactions: `Jackpot.buyTickets` for the customs + `JackpotRandomTicketBuyer.buyTickets` for the randoms. `Jackpot.buyTickets` has no per-ticket quick-pick. | [megapot-buy-tickets](https://llms.megapot.io/tasks/buy-tickets) + [megapot-buy-random](https://llms.megapot.io/tasks/buy-random) |
| 10 | 1–9 | rest | no | `BatchPurchaseFacilitator.createBatchOrder` (single call, keeper-executed) | [megapot-buy-bulk](https://llms.megapot.io/tasks/buy-bulk) |
| 11+ | any | any | no | `BatchPurchaseFacilitator.createBatchOrder` | [megapot-buy-bulk](https://llms.megapot.io/tasks/buy-bulk) |
| any | any | any | yes | `JackpotAutoSubscription.createSubscription` | [megapot-subscribe](https://llms.megapot.io/tasks/subscribe) |

### Per-method quick reference

| Method | Approval target | Execution | Per-ticket mix? | Threshold |
|---|---|---|---|---|
| `Jackpot.buyTickets` | `JACKPOT_ADDRESS` | Immediate | No — every entry needs 5 normals + bonusball. For random tickets use `JackpotRandomTicketBuyer.buyTickets` (1–10) or `BatchPurchaseFacilitator.createBatchOrder` (11+) | ≤10 tickets per call (use bulk for 11+) |
| `BatchPurchaseFacilitator.createBatchOrder` | `BATCH_FACILITATOR_ADDRESS` | Keeper-executed (poll for completion) | Yes — `_dynamicTicketCount` for randoms + `_userStaticTickets` for picks (recommend ≤10 static per order) | `>= BatchPurchaseFacilitator.minimumTicketCount()` (currently `10n`) |
| `JackpotAutoSubscription.createSubscription` | `JACKPOT_AUTO_SUBSCRIPTION` | Keeper-executed daily | Yes — same `_dynamicTicketCount` + `_userStaticTickets` shape (recommend ≤10 static per subscription); **mix locked at subscription creation** | `_totalDays > 0`, ticket count > 0 |

### Notes

- **Mix custom + random in a single call:** only `BatchPurchaseFacilitator.createBatchOrder` supports this — set `_dynamicTicketCount` for keeper-generated randoms alongside `_userStaticTickets` for hand-picked entries. Requires total `>= BatchPurchaseFacilitator.minimumTicketCount()` (currently `10n`). For smaller mixed orders, send two transactions: customs via `Jackpot.buyTickets`, randoms via `JackpotRandomTicketBuyer.buyTickets`. `Jackpot.buyTickets` itself rejects empty `normals` or `bonusball: 0`.
- **Cap `_userStaticTickets` at 10 per order.** This is the recommended limit for `createBatchOrder` and `createSubscription`. The contract does not enforce a length cap, but two factors push you to keep static arrays small: (1) Base's per-block calldata budget — packing many static tickets into a single transaction risks the call failing or being mined unpredictably; (2) the canonical megapot.io UI artificially caps static picks at 10 per order, so integrations that follow the same convention behave consistently for users moving between apps. To purchase more than 10 custom-number tickets, place multiple orders. There is no recommended cap on `_dynamicTicketCount` (random tickets) — those are generated keeper-side without per-ticket calldata.
- **Subscription mix is locked at creation.** `_userStaticTickets` is stored on creation and replayed every drawing. To change the mix, cancel and recreate.
- **Read the threshold dynamically.** Always read `BatchPurchaseFacilitator.minimumTicketCount()` rather than hardcoding `10n`. The current value happens to be `10n`; use the contract value to be future-proof.
- **For 11+ with any custom picks, only `buy-bulk` works.** `Jackpot.buyTickets` reverts with `InvalidTicketCount` for arrays larger than 10.

## How Drawings Work

Megapot runs in repeating drawing cycles. Understanding the lifecycle is essential for knowing when to buy, when to claim, and what "settled" means.

### Lifecycle

1. **Open** — a new drawing is active. `currentDrawingId()` returns its ID. Users buy tickets. `getDrawingState(drawingId).jackpotLock` is `false`.
2. **Drawing time reached** — `getDrawingState(drawingId).drawingTime` (Unix timestamp) has passed. Tickets can no longer be purchased for this drawing.
3. **Settlement triggered** — anyone can call `Jackpot.runJackpot()` (payable — requires ETH for the Pyth entropy callback fee, readable via `getEntropyCallbackFee()`). This sets `jackpotLock = true` and requests randomness from the Pyth entropy provider.
4. **Settled** — the entropy callback fires, winning numbers are determined, `winningTicket` is set to a non-zero packed value, and a `JackpotSettled` event is emitted. A new drawing is automatically initialized with the next `currentDrawingId`.
5. **Claiming open** — users call `claimWinnings(ticketIds)` for the settled drawing. Tickets are burned and USDC is transferred.

### How to check if a drawing is settled

```ts
const state = await publicClient.readContract({
  address: JACKPOT, abi, functionName: 'getDrawingState', args: [drawingId]
});
const isSettled = state.winningTicket !== 0n;
```

The current active drawing (`currentDrawingId()`) is always unsettled. The most recently settled drawing is `currentDrawingId() - 1n`.

### Timing

- Drawing duration is readable via `Jackpot.drawingDurationInSeconds()` — typically 24 hours.
- After `drawingTime` passes, settlement can happen at any time (it's triggered externally, not automatic).
- There is usually a short delay (seconds to minutes) between `drawingTime` and actual settlement while the entropy request is fulfilled.

### Reading drawing data

- **Live current-drawing state** (jackpot lock, `drawingTime`, ticket count for countdown UIs): on-chain via `Jackpot.getDrawingState(currentDrawingId())`. See `megapot-read-state`.
- **Per-round historical data** (winning numbers, per-tier payouts, ticket counts, top winners, wallet history): off-chain via `api.megapot.io/v1`. See `megapot-data-api` — `Round` exposes `winning_numbers`, `prize_tiers`, and `ball_pool` on settled rounds, so a History UI is one API call rather than a per-drawing RPC pipeline.
- **Settlement transitions and ticket-purchase events**: on-chain event subscriptions. See `megapot-read-state` § Drawing Lifecycle UX & Events.

Direct links: [Scalar UI](https://api.megapot.io/v1/docs) · [OpenAPI spec](https://api.megapot.io/v1/openapi.json).

**By use case:**

| If you're building... | Use |
|---|---|
| A "buy tickets" form (price, time remaining, ball bounds) | RPC `getDrawingState` (live) |
| A "Tickets" page (your tickets, past wins, claim button) | API `wallets/{addr}/tickets[/rounds/{id}]` + `wallets/{addr}/wins` |
| A "History" or "Stats" page | API `rounds[/{id}]` |
| A real-time settlement banner ("drawing locked", "settlement attempt failed") | RPC event subs (`JackpotLocked`, `JackpotSettled`, `JackpotUnlocked`, `NewDrawingInitialized`) |

## Prerequisites

Before integrating with any Megapot task skill, ensure the following are in place:

- [ ] **viem installed** — `npm install viem` (all code recipes use viem v2)
- [ ] **Wallet with private key** — an EOA funded with ETH for gas and USDC for ticket/LP operations
- [ ] **Base network configured** — chain ID `8453` (mainnet) or `84532` (Base Sepolia testnet)
- [ ] **USDC approval** — most operations require an ERC-20 `approve` call before the main transaction

Standard USDC approval pattern used across all task skills:

```ts
import { createWalletClient, createPublicClient, http, parseAbi } from "viem";
import { base } from "viem/chains";

const USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
const ERC20_ABI = parseAbi([
  "function approve(address spender, uint256 amount) returns (bool)",
]);

// Approve spender (e.g. Jackpot contract) to spend USDC
const hash = await walletClient.writeContract({
  address: USDC,
  abi: ERC20_ABI,
  functionName: "approve",
  args: [spenderAddress, amount], // amount in 6-decimal USDC units
});
await publicClient.waitForTransactionReceipt({ hash });
```

## llms.megapot.io URL Surface

Each skill in this toolkit is served at a stable URL for agent consumption:

| Resource | URL pattern |
|---|---|
| This entry point | `https://llms.megapot.io/` |
| Task skill | `https://llms.megapot.io/tasks/<name>` |
| Data API skill | `https://llms.megapot.io/data-api` |
| Raw ABI (JSON) | `https://llms.megapot.io/abi/<name>.json` |

Examples:
- `https://llms.megapot.io/tasks/buy-random`
- `https://llms.megapot.io/tasks/buy-tickets`
- `https://llms.megapot.io/tasks/lp-deposit`
- `https://llms.megapot.io/abi/Jackpot.json`

## Related Resources

| Resource | URL |
|---|---|
| Official docs | `https://docs.megapot.io` |
