Branch
Branch is a launchpad on Bags where one coin's creator fees are shared across any number of X accounts. This reference covers how a launch works end to end, the fee math, the Bags endpoints involved, and the pieces that are still marked TODO in the code.
Overview
On Bags, every coin has a creator fee: a percentage of each trade during the bonding curve and after graduation to Meteora DAMM v2. Bags' fee-share v2 program lets that fee be split among up to 100 claimers, and Bags maps social accounts (X, Kick, GitHub) to wallets. Branch combines the two: you type X handles, Branch resolves each one to its Bags wallet, and writes a fee-share config where every handle is a claimer with a percentage.
Nothing routes through Branch. Fees accrue in the on-chain program and each recipient claims directly to their own wallet, whenever they like, with no action from the launcher.
How it works
- 1Describe the coin
Name, symbol, description and an image. Branch pins the image to IPFS and asks Bags to create the token info + metadata. Bags returns the mint address.
- 2Add X handles
Each handle is resolved live through GET /token-launch/fee-share/wallet/v2. You set a percentage per handle; they must sum to 100%.
- 3Sign the config and the launch
For a new recipient set Bags returns two setup transactions (the fee-share account and the Meteora config key), then the launch transaction. Your wallet signs them in order; the initial buy is included in the launch.
- 4Everyone claims
Fees accrue on-chain. Recipients claim on Branch (Claim Fees) or on bags.fm. The launch wallet separately claims its deployer share.
Launching a coin
The Launch page is a single form split into three parts. Everything below maps one-to-one to what the API does under the hood.
Token details
| Field | Rules | Where it goes |
|---|---|---|
| Image | PNG/JPG/GIF/WebP, under 15 MB | Pinned to IPFS via Pinata, then passed to Bags as imageUrl |
| Name | required, max 32 chars | On-chain metadata |
| Symbol | required, max 10 chars, uppercased | On-chain metadata |
| Description | optional, max 1000 chars | IPFS metadata JSON (Branch fills a default if empty) |
| Website / X | optional URLs | IPFS metadata JSON |
| Initial buy | SOL, optional (default 0) | initialBuyLamports on the launch transaction |
Fee recipients
Under X Money recipients, type an X handle and press Enter or Add. Branch calls /api/resolve, which proxies Bags' wallet lookup and returns the display name, avatar and wallet. New recipients are added with an even split; edit any percentage directly or press Split evenly.
A handle that has no Bags wallet yet returns 404; that person needs to sign in to bags.fm once with X before they can be a recipient. Above 7 recipients Bags requires address lookup tables (see Roadmap).
Signing & sending
Pressing Launch runs five stages, each shown in the review panel:
- 01
POST /api/launch/token-info— image + metadata → IPFS; returns the mint. - 02
POST /api/launch/fee-share— buildsclaimersArray/basisPointsArrayand calls Bags. Any returned setup transactions are signed in order. - 03
POST /api/launch/transaction— the Meteora DBC launch transaction, partially signed by the mint keypair on Bags' side. - 04Your wallet signs and sends the launch; Branch confirms it on Helius.
- 05
POST /api/launch/record— the launch and recipients are saved so Explore, Analytics and Claim can show them.
The Bags API key never leaves the server: every Bags call happens in a route handler, and only base58 transactions travel to the browser for signing.
X Money payouts
Every recipient on Branch is an X account. When you add a handle, Branch asks Bags for the wallet that account controls (created the first time they sign in to bags.fm with X) and makes it a fee claimer. Fees are paid in SOL to that wallet; the recipient claims whenever they like, here or on bags.fm.
| X Money on Branch | |
|---|---|
| Recipients | 1 – 100 X accounts per coin |
| Identified by | X handle, resolved to a Bags wallet |
| Paid in | SOL, claimed by each recipient |
| Shares | any split, must total 100% |
| Requirement | recipient has signed in to bags.fm with X once |
Fee economics
Branch launches with Bags' default config: 2% creator fee on the bonding curve, 2% after graduation (~85 SOL).
- 01The launch wallet is registered as deployer and receives 25% of the gross claimers pool. This is separate from the shares you set.
- 02The remaining 75% is divided by your basis points.
- 03If Branch sets a partner key (roadmap), the partner share comes from Bags' platform pool, not from recipients.
| Who | Share | Receives |
|---|---|---|
| Launch wallet (deployer) | 25% of gross | 2.50 SOL |
| @recipient-a | 40% of 75% | 3.00 SOL |
| @recipient-b | 30% of 75% | 2.25 SOL |
| @recipient-c | 30% of 75% | 2.25 SOL |
Available bagsConfigType values, should you want different fee tiers:
| Config key | Fees |
|---|---|
fa29606e… | Default · 2% bonding / 2% post-graduation · ~85 SOL to graduate (what Branch uses) |
d16d3585… | 0.25% pre / 1% post |
a7c8e1f2… | 1% pre / 0.25% post |
48e26d2f… | 10% / 10% |
810faadb… | 2% flat · 85% locked · ~100 SOL |
Claiming fees
Open Claim Fees and connect the wallet that is linked to your X account on Bags. Branch calls GET /token-launch/claimable-positions and lists every coin with something owed to you. Each Claim builds transactions with POST /token-launch/claim-txs/v3; your wallet signs them in order.
Explore & analytics
Explore lists every coin launched through Branch with its recipients, split mode and lifetime fees. Filter by mode or search by coin, symbol, mint or @handle. Each coin page shows price, market cap, liquidity, 24h volume, holders and the buy/sell ratio from Birdeye, plus the fee routing with per-recipient earnings.
Analytics aggregates fees forked, coins launched and recipients paid, ranks coins by lifetime fees and estimates each person's earnings as lifetime fees × 75% × share.
Bags API reference
Base URL https://public-api-v2.bags.fm/api/v1, header x-api-key. Responses are { success, response }. Rate limit: 5 000 requests/hour per user and IP. Endpoints Branch uses or will use:
/token-launch/fee-share/wallet/v2/token-launch/fee-share/wallet/v2/bulk/token-launch/create-token-info/fee-share/config/token-launch/create-launch-transaction/token-launch/claimable-positions/token-launch/claim-txs/v3/token-launch/lifetime-fees/token-launch/creator/v3/fee-share/deployer/claimable-positions/fee-share/deployer/claim-txs/bags-payout/token/bags-payout/token/cashoutArchitecture
| Layer | What | Why |
|---|---|---|
| Framework | Next.js 16 (App Router, cache components), Tailwind v4 | Server routes keep the Bags key private; PPR shells stream fast |
| Wallet | Reown AppKit · Solana adapter | Any Solana wallet; signAndSendTransaction for base58 txs |
| RPC | Helius | Send + confirm launch and claim transactions |
| Launch rail | Bags public API → Meteora DBC → DAMM v2 | Fee-share v2 program holds recipients and shares |
| Storage | Supabase (bagsfork_tokens, bagsfork_recipients) | Explore, Analytics and recipient lookups |
| Images | Pinata (IPFS) | Stable coin art URL for Bags and for Branch |
| Market data | Birdeye | Price, mcap, liquidity, holders on coin pages |
| Avatars | /api/avatar → unavatar | Real X profile pictures, cached 24h, same-origin |
Data model
mint (pk), name, symbol, description, image_url, metadata_url, socials, creator_wallet, config_key, fee_share_authority, payout_mode, payout_handle, initial_buy_lamports, launch_signature, status, created_attoken_mint → tokens, provider, username, display_name, avatar_url, wallet, bps (1–10 000), is_creator, created_atBoth tables have RLS enabled: public read through the anon key, writes only from server routes with the service role.
Setup & environment
pnpm install
pnpm dev # http://localhost:3000
pnpm build # production build
pnpm brand:export # brand PNGs → public/brand (needs dev server)
pnpm brand:video # brand MP4 (needs dev server + ffmpeg)| Variable | Scope | Purpose |
|---|---|---|
BAGS_API_KEY | server | From dev.bags.fm → API Keys. Empty = demo mode. |
NEXT_PUBLIC_PROJECT_ID | client | Reown AppKit project ID (wallet connect). |
NEXT_PUBLIC_SOLANA_RPC_URL | client | Helius RPC used by the wallet adapter for sending + confirming. |
SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY | server | Launch + recipient records. Tables are prefixed bagsfork_. |
PINATA_JWT / NEXT_PUBLIC_PINATA_GATEWAY | server | Pins the coin image so Explore always has the real art. |
BIRDEYE_API_KEY | server | Market data on coin pages (price, mcap, liquidity, volume, holders). |
NEXT_PUBLIC_SITE_URL | client | Public URL for metadata. Defaults to https://usebranch.cash. |
Schema lives in supabase/migrations/; apply with pnpm dlx supabase@latest db query --remote=<ref> --yes -f supabase/migrations/0001_bagsfork_init.sql.
Demo mode
When BAGS_API_KEY is empty every Bags call returns a realistic mock: handles resolve to deterministic wallets, the config and launch steps return no transactions, and the launch is saved with status: "demo". Ten seeded coins with real X recipients keep Explore, Analytics and the brand kit populated. Market data for demo coins is simulated; real launches read Birdeye live.
.env and the same code path goes on-chain — no other changes.Roadmap
Each item is marked TODO(...) in the file named.
Bags needs address lookup tables above 7 claimers. Wire SDK config.getConfigCreationLookupTableTransactions() into step 2 so the launcher signs the create + extend txs first.
Create a Bags partner key for Branch (dev.bags.fm) and pass partner + partnerConfig on every config so Branch earns the 25% platform share.
Add GET /fee-share/deployer/claimable-positions and POST /fee-share/deployer/claim-txs so launchers can withdraw their 25%.
Send fee-share config bundles through Jito instead of sequentially.
Replace the simulated sparkline with GET /fee-share/token/claim-events in time mode.
Bags Payouts can convert a coin's fees to cash via Peer, but only for a single payoutCashout handle per coin. Offer it as an opt-in once Bags supports several handles.
FAQ
Does a recipient need to do anything before launch?+
They need a Bags wallet, which is created the first time they sign in to bags.fm with X. Without it, the handle lookup returns 404 and Branch won't add them.
Can I change recipients after launch?+
Bags exposes POST /fee-share/admin/update-config for the fee-share manager. Branch doesn't surface it yet; it's a natural next step after the roadmap items.
Who pays network fees?+
The launcher pays for the config + launch transactions. Claimers pay for their own claims. X Money network fees are paid by Bags.
Is Branch custodial?+
No. Recipients and shares live in the Bags fee-share program on Solana. Branch never signs for or holds funds.
Can I share with a Kick or GitHub account?+
Bags supports twitter, kick and github providers for fee claimers. Branch only exposes X today; adding a provider toggle is a small change in /api/resolve.
What happens at graduation?+
The coin migrates from the Meteora DBC bonding curve to DAMM v2 at ~85 SOL. Fees keep flowing to the same recipients (2% post-graduation).