Skip to main content

What You Can Build

RektHub isn’t just another “token launchpad”, it’s infrastructure for the creator economy. Integrate our contracts to build:
  • Trading Interfaces: Cross-chain token trading UIs
  • Creator Dashboards: Fee tracking, analytics, community management
  • Portfolio Trackers: Multi-chain creator token portfolios
  • Trading Bots: Automated trading strategies
  • Aggregators: Cross-platform creator token discovery
Building something cool? Tag us @rekthub_io on X—we love seeing what the community creates.

Prerequisites

Before you start, make sure you have:
  • Node.js v16+ installed
  • ethers.js v6+ or viem v1+ (your choice)
  • A wallet provider (MetaMask, WalletConnect, etc.)
  • RPC endpoint for your target chain
  • Some native tokens for gas fees
Need testnet tokens? Check our Deployment Addresses page for faucet links.

Installation

npm install ethers@^6

Your First Buy Transaction

Let’s buy some creator tokens. This example shows the complete flow:
import { ethers } from 'ethers';

// Contract addresses (see deployment-addresses page)
const FACTORY_ADDRESS = '0x...'; // RektHub Factory
const TOKEN_ADDRESS = '0x...';   // Token you want to buy

// Factory ABI (minimal - just what we need)
const FACTORY_ABI = [
  'function buy(address token, uint256 minTokensOut) payable returns (uint256)',
  'function getCurve(address token) view returns (address)',
  'event TokenPurchased(address indexed token, address indexed curve, address indexed buyer, uint256 nativeIn, uint256 tokensOut, uint256 totalFee, uint256 creatorFee, uint256 platformFee, uint256 newRealNativeReserves, uint256 newRealTokenReserves, uint256 newVirtualNativeReserves, uint256 newVirtualTokenReserves)'
];

async function buyCreatorToken() {
  // 1. Connect to provider and signer
  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();

  // 2. Create factory contract instance
  const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, signer);

  // 3. Calculate amount to spend (0.1 native tokens)
  const amountToSpend = ethers.parseEther('0.1');

  // 4. Get price quote (optional but recommended)
  const curveAddress = await factory.getCurve(TOKEN_ADDRESS);
  // ... call getBuyPrice on curve for exact quote

  // 5. Set slippage protection (5% slippage tolerance)
  const expectedTokens = /* from quote */;
  const minTokensOut = expectedTokens * 95n / 100n; // 5% slippage

  // 6. Execute buy transaction
  const tx = await factory.buy(TOKEN_ADDRESS, minTokensOut, {
    value: amountToSpend
  });

  console.log('Transaction sent:', tx.hash);

  // 7. Wait for confirmation
  const receipt = await tx.wait();
  console.log('Transaction confirmed:', receipt.hash);

  // 8. Parse event to get exact amounts
  const event = receipt.logs
    .map(log => {
      try { return factory.interface.parseLog(log); }
      catch { return null; }
    })
    .find(e => e?.name === 'TokenPurchased');

  if (event) {
    console.log('Tokens received:', ethers.formatEther(event.args.tokensOut));
    console.log('Creator earned:', ethers.formatEther(event.args.creatorFee));
  }

  return receipt;
}
Always implement slippage protection. Prices move between quote and execution—use minTokensOut to protect users.

Your First Sell Transaction

Selling tokens back to the curve:
import { ethers } from 'ethers';

const FACTORY_ADDRESS = '0x...';
const TOKEN_ADDRESS = '0x...';

const FACTORY_ABI = [
  'function sell(address token, uint256 tokenAmount, uint256 minNativeOut) returns (uint256)',
  'event TokenSold(address indexed token, address indexed curve, address indexed seller, uint256 tokensIn, uint256 nativeOut, uint256 totalFee, uint256 creatorFee, uint256 platformFee, uint256 newRealNativeReserves, uint256 newRealTokenReserves, uint256 newVirtualNativeReserves, uint256 newVirtualTokenReserves)'
];

const TOKEN_ABI = [
  'function approve(address spender, uint256 amount) returns (bool)',
  'function balanceOf(address account) view returns (uint256)'
];

async function sellCreatorToken() {
  const provider = new ethers.BrowserProvider(window.ethereum);
  const signer = await provider.getSigner();

  const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, signer);
  const token = new ethers.Contract(TOKEN_ADDRESS, TOKEN_ABI, signer);

  // 1. Get user's token balance
  const balance = await token.balanceOf(await signer.getAddress());
  const amountToSell = balance / 2n; // Sell 50%

  // 2. Get curve address
  const curveAddress = await factory.getCurve(TOKEN_ADDRESS);

  // 3. Approve curve to spend tokens
  const approveTx = await token.approve(curveAddress, amountToSell);
  await approveTx.wait();
  console.log('Approval confirmed');

  // 4. Get price quote for slippage protection
  // ... call getSellPrice on curve
  const expectedNative = /* from quote */;
  const minNativeOut = expectedNative * 95n / 100n; // 5% slippage

  // 5. Execute sell transaction
  const tx = await factory.sell(TOKEN_ADDRESS, amountToSell, minNativeOut);
  console.log('Sell transaction sent:', tx.hash);

  const receipt = await tx.wait();
  console.log('Sell confirmed:', receipt.hash);

  return receipt;
}
Pro tip: Use sellPercentage() instead to sell a percentage without calculating exact amounts. Perfect for “Sell 25%” buttons.

Creating Your First Token

Launch a creator token in minutes. Here’s the complete flow from metadata to deployment:

Step 1: Prepare Your Metadata

Create a JSON file with your token info:
{
	"name": "Creator Coin",
	"symbol": "CRTR",
	"description": "Official token for [Your Community]. Join us!",
	"image": "ipfs://QmYourImageHash...",
	"external_url": "https://your-website.com",
	"social_links": {
		"twitter": "https://x.com/yourusername",
		"telegram": "https://t.me/yourchannel"
	}
}

Step 2: Upload to IPFS

// Using Pinata (or any IPFS service)
import pinataSDK from '@pinata/sdk';

const pinata = new pinataSDK(
	process.env.PINATA_API_KEY,
	process.env.PINATA_SECRET
);

// Upload metadata JSON
const upload = await pinata.pinJSONToIPFS(metadata);
const metadataURI = `ipfs://${upload.IpfsHash}`;

console.log('Metadata URI:', metadataURI);
Free IPFS Services: Pinata, NFT.Storage, or Web3.Storage all offer free tiers.

Step 3: Create the Token

import { ethers } from 'ethers';

const FACTORY_ADDRESS = '0x...';
const FACTORY_ABI = [
	'function createToken(string calldata name, string calldata symbol, string calldata tokenURI) payable returns (address, address)',
	'function getCreationFee() view returns (uint256)',
	'event TokenCreated(address indexed tokenAddress, address indexed curveAddress, address indexed creator, string name, string symbol, string uri, uint256 realNativeReserves, uint256 realTokenReserves, uint256 virtualNativeReserves, uint256 virtualTokenReserves, uint256 creationFee)',
];

async function createCreatorToken() {
	const provider = new ethers.BrowserProvider(window.ethereum);
	const signer = await provider.getSigner();

	const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, signer);

	// 1. Get creation fee
	const creationFee = await factory.getCreationFee();
	console.log('Creation fee:', ethers.formatEther(creationFee), 'ETH');

	// 2. Create token
	const tx = await factory.createToken(
		'Creator Coin', // name
		'CRTR', // symbol
		'ipfs://QmYourHash...', // tokenURI from step 2
		{ value: creationFee }
	);

	console.log('Transaction sent:', tx.hash);
	const receipt = await tx.wait();

	// 3. Get token addresses from event
	const event = receipt.logs
		.map((log) => {
			try {
				return factory.interface.parseLog(log);
			} catch {
				return null;
			}
		})
		.find((e) => e?.name === 'TokenCreated');

	console.log('✅ Token created!');
	console.log('Token address:', event.args.tokenAddress);
	console.log('Curve address:', event.args.curveAddress);
	console.log(
		'View on explorer:',
		`https://etherscan.io/token/${event.args.tokenAddress}`
	);

	return {
		token: event.args.tokenAddress,
		curve: event.args.curveAddress,
	};
}

Step 4: Verify on Block Explorer

After creation, verify your token shows up correctly:
// Check token was deployed correctly
const token = new ethers.Contract(
	tokenAddress,
	[
		'function name() view returns (string)',
		'function symbol() view returns (string)',
		'function totalSupply() view returns (uint256)',
		'function tokenURI() view returns (string)',
	],
	provider
);

const [name, symbol, supply, uri] = await Promise.all([
	token.name(),
	token.symbol(),
	token.totalSupply(),
	token.tokenURI(),
]);

console.log('Name:', name);
console.log('Symbol:', symbol);
console.log('Supply:', ethers.formatEther(supply)); // 1,000,000,000
console.log('Metadata:', uri);
Token Supply: All RektHub tokens have a fixed supply of 1 billion tokens with 18 decimals. 850M are tradeable, 150M reserved for graduation liquidity.

Bonus: Create with Vanity Address

Want a custom token address like 0x000... or 0xdead...?
// Mine a salt offchain first (this can take a while)
function mineVanitySalt(prefix, implementationAddress, factoryAddress) {
	let nonce = 0;
	while (true) {
		const salt = ethers.id(`vanity-${nonce}`);
		const predicted = ethers.getCreate2Address(
			factoryAddress,
			salt,
			ethers.keccak256(
				ethers.concat([
					'0x3d602d80600a3d3981f3363d3d373d3d3d363d73',
					implementationAddress,
					'0x5af43d82803e903d91602b57fd5bf3',
				])
			)
		);

		if (predicted.toLowerCase().startsWith(prefix.toLowerCase())) {
			return { salt, address: predicted };
		}
		nonce++;

		if (nonce % 10000 === 0) {
			console.log(`Tried ${nonce} combinations...`);
		}
	}
}

// Use the mined salt
const { salt, address } = mineVanitySalt('0x0000', tokenImpl, factoryAddress);
console.log('Found vanity address:', address);

const tx = await factory.createTokenDeterministic(
	'Vanity Token',
	'VNTY',
	metadataURI,
	salt,
	{ value: creationFee }
);
Vanity Mining: Finding addresses with specific prefixes can take hours/days depending on length. Mine offchain, then deploy with the found salt.

Listening to Events

Track real-time activity across all creator tokens:
import { ethers } from 'ethers';

const FACTORY_ADDRESS = '0x...';
const FACTORY_ABI = [
	'event TokenPurchased(address indexed token, address indexed curve, address indexed buyer, uint256 nativeIn, uint256 tokensOut, uint256 totalFee, uint256 creatorFee, uint256 platformFee, uint256 newRealNativeReserves, uint256 newRealTokenReserves, uint256 newVirtualNativeReserves, uint256 newVirtualTokenReserves)',
	'event TokenSold(address indexed token, address indexed curve, address indexed seller, uint256 tokensIn, uint256 nativeOut, uint256 totalFee, uint256 creatorFee, uint256 platformFee, uint256 newRealNativeReserves, uint256 newRealTokenReserves, uint256 newVirtualNativeReserves, uint256 newVirtualTokenReserves)',
	'event TokenCreated(address indexed tokenAddress, address indexed curveAddress, address indexed creator, string name, string symbol, string uri, uint256 realNativeReserves, uint256 realTokenReserves, uint256 virtualNativeReserves, uint256 virtualTokenReserves, uint256 creationFee)',
];

async function listenToActivity() {
	const provider = new ethers.JsonRpcProvider('YOUR_RPC_URL');
	const factory = new ethers.Contract(FACTORY_ADDRESS, FACTORY_ABI, provider);

	// Listen for new token launches
	factory.on(
		'TokenCreated',
		(tokenAddress, curveAddress, creator, name, symbol) => {
			console.log(`🚀 New token launched: ${name} (${symbol})`);
			console.log(`   Creator: ${creator}`);
			console.log(`   Token: ${tokenAddress}`);
		}
	);

	// Listen for buys
	factory.on(
		'TokenPurchased',
		(token, curve, buyer, nativeIn, tokensOut, totalFee, creatorFee) => {
			console.log(`💰 Buy: ${ethers.formatEther(tokensOut)} tokens`);
			console.log(`   Spent: ${ethers.formatEther(nativeIn)}`);
			console.log(`   Creator earned: ${ethers.formatEther(creatorFee)}`);
		}
	);

	// Listen for sells
	factory.on(
		'TokenSold',
		(token, curve, seller, tokensIn, nativeOut, totalFee, creatorFee) => {
			console.log(`📉 Sell: ${ethers.formatEther(tokensIn)} tokens`);
			console.log(`   Received: ${ethers.formatEther(nativeOut)}`);
			console.log(`   Creator earned: ${ethers.formatEther(creatorFee)}`);
		}
	);
}

Common Integration Patterns

Building Trading UIs

// Real-time price updates
async function getPriceQuote(tokenAddress, amountIn) {
	const curveAddress = await factory.getCurve(tokenAddress);
	const curve = new ethers.Contract(curveAddress, CURVE_ABI, provider);

	const [tokensOut, totalFee, creatorFee, platformFee] = await curve.getBuyPrice(
		amountIn
	);

	return {
		tokensOut,
		totalFee,
		creatorFee,
		platformFee,
		effectivePrice: amountIn / tokensOut,
	};
}

// Chart data from events
async function getTradeHistory(tokenAddress, fromBlock) {
	const filter = factory.filters.TokenPurchased(tokenAddress);
	const events = await factory.queryFilter(filter, fromBlock);

	return events.map((e) => ({
		timestamp: e.blockNumber,
		price: e.args.nativeIn / e.args.tokensOut,
		volume: e.args.tokensOut,
		buyer: e.args.buyer,
	}));
}

Building Aggregators

// Discover trending tokens
async function getTrendingTokens(fromBlock) {
	const createdFilter = factory.filters.TokenCreated();
	const tokens = await factory.queryFilter(createdFilter, fromBlock);

	// Get trade volume for each
	const withVolume = await Promise.all(
		tokens.map(async (t) => {
			const buyFilter = factory.filters.TokenPurchased(t.args.tokenAddress);
			const trades = await factory.queryFilter(buyFilter, fromBlock);

			const volume = trades.reduce((sum, trade) => sum + trade.args.nativeIn, 0n);

			return {
				address: t.args.tokenAddress,
				name: t.args.name,
				symbol: t.args.symbol,
				creator: t.args.creator,
				volume: ethers.formatEther(volume),
			};
		})
	);

	// Sort by volume
	return withVolume.sort((a, b) => parseFloat(b.volume) - parseFloat(a.volume));
}

Building Trading Bots

// Simple momentum bot example
async function momentumBot(tokenAddress, thresholds) {
	const curve = await getCurveContract(tokenAddress);

	// Monitor price changes
	factory.on('TokenPurchased', async (token, _, __, nativeIn, tokensOut) => {
		if (token !== tokenAddress) return;

		const priceImpact = calculatePriceImpact(nativeIn, tokensOut);

		if (priceImpact > thresholds.buyThreshold) {
			// Momentum detected, execute buy
			await executeBuy(tokenAddress /* amount */);
		}
	});

	// Set take-profit/stop-loss logic
	// ... your trading strategy here
}
Trading bots carry risk. Always test thoroughly on testnets and use appropriate risk management.

Next Steps

Get Help