Skip to content

Launch a coin

Example

This is an example. Every value in it (names, amounts, addresses) is there to show you how; change any of them to suit you. It’s launch.mjs from developers/examples, as it is. Anything that sends waits for SEND=1: there is no testnet, so a sent transaction spends real ETH.

launch.mjs
// Launch a coin on Doppler, Clanker, Pools.trade, Flap or Pons from your own wallet. The API stores its details, builds the
// launch and simulates it; your key signs each step. Without SEND=1 it only builds and prints the steps.
// PRIVATE_KEY=0x… LAUNCHPAD=clanker NAME="Example Coin" SYMBOL=EXMPL IMAGE=./logo.png SEND=1 node launch.mjs
import { readFile } from 'node:fs/promises';
import { JsonRpcProvider, Wallet } from 'ethers';
const API = process.env.UPRALLY_API ?? 'https://uprally.co/api/v1';
const chain = await (await fetch(`${API}/chain`)).json();
const wallet = new Wallet(process.env.PRIVATE_KEY, new JsonRpcProvider(chain.rpc, chain.chainId));
const ok = async (res) => {
const json = await res.json();
if (!res.ok) throw new Error(`${json.error.code}: ${json.error.message} ${json.error.fix ?? ''}`);
return json;
};
// What each launchpad takes and costs (Flap needs a picture; Pons charges a small launch fee).
const options = await ok(await fetch(`${API}/launch`));
const launchpad = process.env.LAUNCHPAD ?? 'clanker';
console.log(launchpad, JSON.stringify(options.launchpads[launchpad].fees));
// A picture, if there is one: the raw bytes, its type in the header.
let image;
if (process.env.IMAGE) {
const type = process.env.IMAGE.endsWith('.png') ? 'image/png' : 'image/jpeg';
({ image } = await ok(await fetch(`${API}/media/image`, { method: 'POST', headers: { 'content-type': type }, body: await readFile(process.env.IMAGE) })));
}
const built = await ok(await fetch(`${API}/launch`, {
method: 'POST', headers: { 'content-type': 'application/json' },
body: JSON.stringify({ launchpad, creator: wallet.address, name: process.env.NAME ?? 'Example Coin', symbol: process.env.SYMBOL ?? 'EXMPL', description: 'Launched from the Uprally API.', image, firstBuyEth: Number(process.env.FIRST_BUY_ETH ?? 0) }),
}));
console.log(`coin ${built.token}: ${built.steps.length} step(s): ${built.steps.map((s) => s.step).join(', ')}`);
if (process.env.SEND !== '1') { console.log('RESULT built'); process.exit(0); }
// In order, each confirmed before the next.
for (const s of built.steps) {
const sent = await wallet.sendTransaction({ to: s.tx.to, data: s.tx.data, value: BigInt(s.tx.value), gasLimit: s.tx.gas ? BigInt(s.tx.gas) : undefined, chainId: s.tx.chainId });
const r = await sent.wait();
if (r.status !== 1) throw new Error(`${s.step} reverted: ${chain.explorer}/tx/${sent.hash}`);
console.log(s.step, sent.hash);
}
console.log(`live: ${built.page}`);
console.log(`RESULT ${built.token}`);