Developers

Create tokens on Livo programmatically

Overview

Token creation on Livo is a two-step process: call a Livo factory contract on-chain to deploy the token, then submit metadata (name, image, socials) to the Livo API keyed by the transaction hash.

Step 1: Authenticate

All API calls require a JWT Bearer token. Obtain one by signing a message with your wallet. Tokens expire after 7 days.

POST /api/auth/wallet
Content-Type: application/json

{
  "address": "0xYourWalletAddress",
  "signature": "<signature>",
  "message": "Sign in to Livo\nTimestamp: <unix_ms>"
}

// Response:
{ "token": "eyJhbGci..." }

The message must contain Timestamp: <unix_ms> where the timestamp is within the last 5 minutes.

Step 2: Call the Factory Contract

Token creation goes through one of three factory contracts depending on configuration:

if (buyTax > 0 || sellTax > 0):
    use factoryTaxV4   (LivoFactoryTaxToken)
else if (creatorLPFeeShare):
    use factoryV4      (LivoFactoryBase)
else:
    use factoryV2      (LivoFactoryBase)

Contract addresses are maintained in the contracts repo. All contracts are verified on Etherscan — fetch ABIs from there.

Function Signatures

createToken (no tax)

function createToken(
    string name,
    string symbol,
    address feeReceiver,  // usually msg.sender
    bytes32 salt          // vanity salt (address must end in 1110)
) returns (address token)

createToken (with tax)

function createToken(
    string name,
    string symbol,
    address feeReceiver,
    bytes32 salt,
    uint16 buyTaxBps,           // max 500 (5%)
    uint16 sellTaxBps,          // max 500 (5%)
    uint32 taxDurationSeconds   // max 1209600 (14 days)
) returns (address token)

createTokenWithFeeSplit (multiple fee recipients)

function createTokenWithFeeSplit(
    string name,
    string symbol,
    address[] recipients,
    uint256[] sharesBps,  // must sum to 10000
    bytes32 salt
) returns (address token, address feeSplitter)

Vanity Salt

The factory uses CREATE2. Livo requires the deployed token address to end in 1110. You must brute-force a salt that produces a matching address.

import { keccak256, concat, toBytes } from "viem";

const PROXY_PREFIX = "0x3d602d80600a3d3981f3363d3d373d3d3d363d73";
const PROXY_SUFFIX = "0x5af43d82803e903d91602b57fd5bf3";

function findVanitySalt(factoryAddress, tokenImplementation) {
  const initcodeHash = keccak256(
    concat([PROXY_PREFIX, tokenImplementation, PROXY_SUFFIX])
  );
  const buffer = new Uint8Array(85);
  buffer[0] = 0xff;
  buffer.set(toBytes(factoryAddress), 1);
  buffer.set(toBytes(initcodeHash), 53);

  const salt = crypto.getRandomValues(new Uint8Array(32));
  for (;;) {
    buffer.set(salt, 21);
    const hash = keccak256(buffer);
    if (hash.endsWith("1110")) {
      const saltHex = "0x" + Array.from(salt,
        (b) => b.toString(16).padStart(2, "0")).join("");
      return { salt: saltHex, tokenAddress: "0x" + hash.slice(26) };
    }
    for (let i = 31; i >= 0; i--) {
      if (salt[i] < 255) { salt[i]++; break; }
      salt[i] = 0;
    }
  }
}

Step 3: Submit Metadata

After broadcasting the transaction and obtaining the txHash, submit token metadata via multipart form data.

POST /api/tokens/create
Authorization: Bearer <jwt_token>
Content-Type: multipart/form-data
txHashrequired
0x-prefixed, 66-character hex string
namerequired
Token name, max 32 characters
symbolrequired
Uppercase alphanumeric, max 15 characters
chainIdrequired
1 (mainnet) or 11155111 (sepolia)
description
Max 250 characters
telegram
Valid t.me URL
twitter
Valid x.com or twitter.com URL
website
Valid http/https URL
image
JPEG, PNG, GIF, or WebP, max 5MB

Response:

{
  "success": true,
  "txHash": "0x...",
  "imageUrl": "https://..."
}

Validation Rules

name
1-32 characters, non-empty
symbol
1-15 characters, uppercase alphanumeric only (A-Z, 0-9)
buyTaxBps
0-500 (0%-5%)
sellTaxBps
0-500 (0%-5%)
taxDurationSeconds
86400-1209600 (1-14 days)
feeSplitShares
Must sum to 10000, no duplicate addresses

Key Events

After token creation, the factory emits:

event TokenCreated(
    address indexed token,
    string name,
    string symbol,
    address tokenOwner,
    address launchpad,
    address graduator,
    address feeHandler,
    address feeReceiver
)

The launchpad emits:

event TokenLaunched(
    address indexed token,
    uint256 graduationThreshold,
    uint256 maxExcessOverThreshold
)

Parse the TokenLaunched event from the transaction receipt to get the created token address.

Notes

  • Token creation is free (no ETH cost beyond gas).
  • Tokens start on a bonding curve. Once ~3.5 ETH is collected, the token automatically graduates to Uniswap.
  • The image field should be a raw file upload (not a URL). The API uploads it to IPFS via Pinata.