Spark for developers and trading bots
Spark is a memecoin launchpad on Lighter EVM. Tokens trade on a bonding curve, then graduate into a pool whose liquidity is locked forever. Everything a bot, a terminal or an aggregator needs is open: verified contracts, Uniswap V2 compatible pools, a read API, a JavaScript SDK and a share of the fee on every trade you route.
How a token trades
- Supply 1,000,000,000 tokens, 18 decimals, EIP-2612 permit (domain
"Spark Meme", version"1"). No transfer fee, no blacklist, no owner functions. - Curve while
getCurve(token).graduatedis false:buy/sell(orsellWithPermit) on its launchpad. Fee 0 to 5% set by the creator (1% default); the first 60 s after launch carry a higher fee falling to normal. - Pool after graduation: a constant-product pool with a 0.3% fee against the pair's quote token, LP locked forever. Trade it through the launchpad's router or directly on the pool.
- Pairs one launchpad per pair. ETH memes are bought with ETH. Memes on leveraged pairs (ETH3x, BTC2x, SOL, ...) are priced in that vault's share. The USDC zap buys them with plain USDC in one transaction.
Contracts devnet
Live from /v1/pads. Sources are verified on the explorer. Launchpads marked current take new launches; the others still trade their tokens.
| Pair | Launchpad | Router (V2) |
|---|---|---|
| Loading… | ||
As a Uniswap V2 fork
Pools and routers of the current launchpads use Uniswap V2's interfaces unchanged: getReserves() with the timestamp,
swap(amount0Out, amount1Out, to, data) with flash swaps (uniswapV2Call), price accumulators,
factory.getPair / allPairs / PairCreated, and the router's WETH(),
getAmountsOut, swapExact… and …SupportingFeeOnTransferTokens functions. Fee: 0.3% (997/1000).
Pool address: CREATE2(factory, keccak256(token0, token1), INIT_CODE_PAIR_HASH), where
factory.INIT_CODE_PAIR_HASH() returns the hash (the same for every factory):
loading…
Launchpad events
event TokenCreated(address indexed token, address indexed creator, string name, string symbol, string uri)
event Trade(address indexed token, address indexed trader, bool isBuy, uint256 ethAmount, uint256 tokenAmount,
uint256 fee, uint256 vEth, uint256 vTok) // price = vEth / vTok (quote per token)
event Graduated(address indexed token, address indexed pair, uint256 ethToPool, uint256 tokensToPool, uint256 fee)
Launchpad functions
function quoteBuy(address token, uint256 amountIn) view returns (uint256 tokensOut, uint256 fee, uint256 refund)
function quoteSell(address token, uint256 amountIn) view returns (uint256 ethOut, uint256 fee)
function buy(address token, uint256 minTokensOut, uint256 deadline, address referrer) payable // ETH pairs
function buyQuoted(address token, uint256 amountIn, uint256 minTokensOut, uint256 deadline, address referrer) // vault pairs
function sellWithPermit(address token, uint256 amountIn, uint256 minOut, uint256 deadline, address referrer,
uint8 v, bytes32 r, bytes32 s)
function getCurve(address token) view returns (Curve) // .graduated, .pair, .feeBps, .snipeDuration, ...
function currentFeeBps(address token) view returns (uint256)
USDC on vault pairs
// UsdcZap: the vault mints shares from the buyer's USDC at once, the zap buys the meme with them
function buyWithUsdcPermit(address launchpad, address token, uint256 usdcIn, uint256 minTokensOut, uint256 deadline,
address referrer, uint8 v, bytes32 r, bytes32 s) returns (uint256 tokensOut)
// sells into a redemption in the seller's name; the vault pays the USDC after its round (seconds)
function sellForUsdc(address launchpad, address token, uint256 amountIn, uint256 minSharesOut, uint256 deadline,
address referrer, uint8 v, bytes32 r, bytes32 s) returns (uint256 shares, uint64 round)
The launchpad records the zap as the trader of these trades; the wallet is the transaction's sender. The API already shows the wallet.
JavaScript SDK
One file, spark.js, ethers v6 as its only dependency. It loads the addresses from the API, so it keeps working through redeploys.
import { ethers } from "ethers";
import { Spark } from "./spark.js";
const provider = new ethers.JsonRpcProvider(Spark.DEVNET.rpc);
const spark = await Spark.connect({ signer: new ethers.Wallet(KEY, provider), referrer: MY_ADDRESS });
// new tokens and trades on every pair, straight from the chain (~1 s blocks)
spark.watchLaunches((t) => console.log("launch", t.symbol, t.token, t.quote.symbol));
spark.watchTrades((t) => console.log(t.isBuy ? "buy" : "sell", t.token, t.quoteAmount));
await spark.buy(token, ethers.parseEther("0.01")); // curve or pool, ETH or the pair's quote
await spark.sell(token, amount); // permit + one transaction
await spark.buyWithUsdc(token, 10_000_000n); // 10 USDC on a vault pair
await spark.sellForUsdc(token, amount); // USDC arrives after the vault's round
Open API
Read-only, any origin, no key: spark-api.gamemrkt.online/v1. Tokens with prices and risk metrics (holders, top 10, dev, snipers, bundles), trades, candles, holders, live quotes with the transaction to send, and every launchpad's contracts.
| Endpoint | What |
|---|---|
| /v1/pads | every launchpad, its router, factory, quote token, USDC zap |
| /v1/all | tokens and latest trades of every pair in one answer |
| /v1/token/{address} | one token, whichever pair it is on |
| /v1/tokens/{address}/quote?side=buy&amount=… | a live quote with the transaction to send |
| /v1/tokens/{address}/candles?tf=60 | OHLCV candles |
| /v1/contracts?pad=… | addresses and human-readable ABIs (ethers / viem) |
The API is indexed about once a minute. For sniping and live feeds, read the chain events above (or use the SDK's watchers).
Earn on the trades you route
Every curve trade takes a referrer. Pass your bot's or your users' address and that address earns part of Spark's fee on each trade (the referrer's share of Spark's part, in basis points: launch.defaults.refShareBps in
/v1). Earnings accrue in the launchpad; collect them with claim().
Contracts are BUSL-1.1: free to read, audit, test and integrate with; not to run as a competing launchpad. Not audited yet; devnet only.