Spark

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.

V2 compatible poolsAdd Spark as a Uniswap V2 fork: factory, router and one init code hash.
Live launchesEvery new token is an event on chain the second it exists. No indexer delay.
Earn on every tradePass your address as the referrer and keep part of Spark's fee.

How a token trades

Contracts devnet

Live from /v1/pads. Sources are verified on the explorer. Launchpads marked current take new launches; the others still trade their tokens.

PairLaunchpadRouter (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.

EndpointWhat
/v1/padsevery launchpad, its router, factory, quote token, USDC zap
/v1/alltokens 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=60OHLCV 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.