Skip to content

Project: Set Up a Liquidity Pool ​

A complete, runnable project doing the admin-side setup for a new Uniswap V2 pool on Celo: register both assets, create the pool, fund it, and confirm reserves — the prerequisite for AMM Trading to work. See the Admin API for the endpoint reference.

Celo logo Celo only

Uniswap V2 pools are a Celo-specific mechanism — there's no chain selector on this page because Stellar's AMM (see Stellar AMM) is a completely separate native protocol-level mechanism with no equivalent create/fund flow.

▸API ConfigurationNot configured

What you'll build ​

A setup.js script that registers two assets, creates the pool between them, funds it with real reserves, and confirms it's live — everything AMM Trading needs to actually execute a swap.

Prerequisites ​

  • Node.js 18+ (for global fetch)
  • A running comet-engine with a service token — pool creation/funding are platform-wide admin actions, not tenant-scoped, so this uses X-Service-Token rather than a tenant API key/secret

Project setup ​

bash
mkdir pool-setup && cd pool-setup && npm init -y && npm install dotenv

.env:

env
COMET_BASE_URL=http://localhost:8100
COMET_SERVICE_TOKEN=your-service-token

Create setup.js with this shared helper at the top — every step below adds to the same file:

js
import 'dotenv/config';

const base = process.env.COMET_BASE_URL;
const headers = {
  'Content-Type': 'application/json',
  'X-Service-Token': process.env.COMET_SERVICE_TOKEN,
};

async function comet(method, path, body) {
  const res = await fetch(base + path, { method, headers, body: body ? JSON.stringify(body) : undefined });
  const data = await res.json();
  if (!res.ok) throw new Error(`${method} ${path} -> ${res.status}: ${JSON.stringify(data)}`);
  return data;
}

Step 1: Register both assets ​

Register USDT

🔒 Admin operation — always requires a Service Token, regardless of the panel above.

curl -X POST "http://localhost:8100/api/v1/admin/assets/USDT/register?chain=celo" \
  -H "Content-Type: application/json" \
  -H "X-Service-Token: YOUR_SERVICE_TOKEN" \
  -d '{
  "contract": "0x3C8EB6c8DF02B43a7bae71314917aCBdd60edDDF",
  "decimals": 6,
  "name": "Tether USD"
}'
Response200
{
  "message": "asset USDT registered on celo",
  "asset": {
    "symbol": "USDT",
    "contract": "0x3C8E...DDDF"
  }
}
Register IMC

🔒 Admin operation — always requires a Service Token, regardless of the panel above.

curl -X POST "http://localhost:8100/api/v1/admin/assets/IMC/register?chain=celo" \
  -H "Content-Type: application/json" \
  -H "X-Service-Token: YOUR_SERVICE_TOKEN" \
  -d '{
  "contract": "0x1D1aA006f66A191fc04e7d1cab8D62B0c81d9221",
  "decimals": 6,
  "name": "ImpalaCoin",
  "type": "airtime",
  "backing": "airtime"
}'
Response200
{
  "message": "asset IMC registered on celo",
  "asset": {
    "symbol": "IMC",
    "contract": "0xF150...d5A2"
  }
}

Step 2: Create the pool ​

Create Pool

🔒 Admin operation — always requires a Service Token, regardless of the panel above.

curl -X POST "http://localhost:8100/api/v1/admin/pools/create" \
  -H "Content-Type: application/json" \
  -H "X-Service-Token: YOUR_SERVICE_TOKEN" \
  -d '{
  "tokenA": "USDT",
  "tokenB": "IMC",
  "chain": "celo"
}'
Response200
{
  "pair": "0xfE6A7492c21DE2C196B465A814A1FAf9B2564082",
  "chain": "celo"
}

Step 3: Fund it with real reserves ​

Fund Pool (500 USDT + 1000 IMC)

🔒 Admin operation — always requires a Service Token, regardless of the panel above.

curl -X POST "http://localhost:8100/api/v1/admin/pools/fund" \
  -H "Content-Type: application/json" \
  -H "X-Service-Token: YOUR_SERVICE_TOKEN" \
  -d '{
  "pair": "0xfE6A7492c21DE2C196B465A814A1FAf9B2564082",
  "amountA": 500000000,
  "amountB": 1000000000,
  "chain": "celo"
}'
Response200
{
  "status": "success",
  "txHash": "0x...",
  "reserveA": "500000000",
  "reserveB": "1000000000"
}

Step 4: Confirm it's live ​

List Pools
curl -X GET "http://localhost:8100/api/v1/swap/pools" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "X-API-Secret: YOUR_API_SECRET"
Response200
{
  "pools": [
    {
      "pair": "0xfE6A7492c21DE2C196B465A814A1FAf9B2564082",
      "token0": "USDT",
      "token1": "IMC",
      "reserve0": "500000000",
      "reserve1": "1000000000"
    }
  ],
  "count": 1
}

Step 5: Run the whole setup as one script ​

Add main() to setup.js:

js
async function main() {
  await comet('POST', '/api/v1/admin/assets/USDT/register?chain=celo', {
    contract: '0x3C8EB6c8DF02B43a7bae71314917aCBdd60edDDF', decimals: 6, name: 'Tether USD',
  });
  await comet('POST', '/api/v1/admin/assets/IMC/register?chain=celo', {
    contract: '0x1D1aA006f66A191fc04e7d1cab8D62B0c81d9221', decimals: 6, name: 'ImpalaCoin', type: 'airtime', backing: 'airtime',
  });
  console.log('assets registered');

  const pool = await comet('POST', '/api/v1/admin/pools/create', { tokenA: 'USDT', tokenB: 'IMC', chain: 'celo' });
  console.log('pool created:', pool.pair);

  const funded = await comet('POST', '/api/v1/admin/pools/fund', {
    pair: pool.pair, amountA: 500000000, amountB: 1000000000, chain: 'celo',
  });
  console.log('pool funded:', funded.txHash);

  const pools = await comet('GET', '/api/v1/swap/pools');
  console.log('pools now live:', pools.pools);
}

main().catch((e) => { console.error(e); process.exit(1); });
bash
node setup.js

What you built ​

  • A real, funded Uniswap V2 pool on Celo — not a testnet placeholder, actual reserves an actual swap can draw against.
  • The full admin lifecycle: register, create, fund, verify.

Next steps: head to AMM Trading to actually swap against this pool, or repeat Step 1–3 for another asset pair.

Released under the MIT License.