# Token Factories

### Token Metadata

All token launches require metadata:

```typescript
type TokenMetadata = {
  name: string;        // Token name (e.g., "My Token")
  symbol: string;      // Token symbol (e.g., "MTK")
  decimals?: number;   // Number of decimals (default: 9)
  uri?: string;        // Optional URI to JSON metadata
};
```

#### Creating Token Metadata Helper

The SDK provides a `createTokenMetadata()` helper function that validates and formats your token metadata:

```typescript
import { createTokenMetadata } from "@vertigo-amm/vertigo-sdk";

// Create and validate token metadata
const metadata = createTokenMetadata(
  "My Amazing Token",                        // name (max 32 characters)
  "MAT",                                     // symbol (max 10 characters)
  "https://example.com/token-metadata.json"  // URI to off-chain metadata
);
```

The helper automatically:

* ✅ Validates name length (1-32 characters)
* ✅ Validates symbol length (1-10 characters)
* ✅ Trims whitespace from all fields
* ✅ Uppercases the symbol
* ✅ Ensures URI is provided
* ✅ Throws clear error messages if validation fails

**Example with factory:**

```typescript
import { Vertigo, createTokenMetadata } from "@vertigo-amm/vertigo-sdk";

const vertigo = await Vertigo.load({ connection, wallet });

// Create validated metadata
const metadata = createTokenMetadata(
  "My Launch Token",
  "MLT",
  "https://example.com/metadata.json"
);

// Use with token factory
const result = await vertigo.factory.launchTokenWithPool({
  metadata,
  supply: 1_000_000_000,
  initialMarketCap: 50 * LAMPORTS_PER_SOL,
  royaltiesBps: 250,
});
```

### Example: Launch a simple token

Create a token without a pool:

```typescript
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

async function main() {
  const connection = new Connection("https://api.devnet.solana.com", "confirmed");
  const walletKeypair = anchor.Wallet.local();

  const vertigo = await Vertigo.load({
    connection,
    wallet: walletKeypair,
    network: "devnet",
  });

  // Launch a standard SPL token
  const { signature, mintAddress } = await vertigo.factory.launchToken({
    metadata: {
      name: "My Token",
      symbol: "MTK",
      decimals: 9,
      uri: "https://example.com/token-metadata.json", // Optional
    },
    supply: 1_000_000, // 1 million tokens (will be multiplied by 10^decimals)
    useToken2022: false, // Use SPL token (default)
  });

  console.log(`Token created: ${mintAddress.toBase58()}`);
  console.log(`Transaction: ${signature}`);
}

main();
```

### Example: Launch a Token-2022 token

The same API works for Token-2022:

```typescript
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

async function main() {
  const connection = new Connection("https://api.devnet.solana.com", "confirmed");
  const walletKeypair = anchor.Wallet.local();

  const vertigo = await Vertigo.load({
    connection,
    wallet: walletKeypair,
    network: "devnet",
  });

  // Launch a Token-2022 token
  const { signature, mintAddress } = await vertigo.factory.launchToken({
    metadata: {
      name: "My Token 2022",
      symbol: "MT22",
      decimals: 6,
    },
    supply: 10_000_000, // 10 million tokens
    useToken2022: true, // Use Token-2022 program
  });

  console.log(`Token-2022 created: ${mintAddress.toBase58()}`);
  console.log(`Transaction: ${signature}`);
}

main();
```

### Example: Launch token with liquidity pool

Create a token and pool in one operation:

```typescript
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

async function main() {
  const connection = new Connection("https://api.devnet.solana.com", "confirmed");
  const walletKeypair = anchor.Wallet.local();

  const vertigo = await Vertigo.load({
    connection,
    wallet: walletKeypair,
    network: "devnet",
  });

  // Launch token with liquidity pool
  const result = await vertigo.factory.launchTokenWithPool({
    metadata: {
      name: "My Launch Token",
      symbol: "MLT",
      decimals: 9,
      uri: "https://example.com/metadata.json",
    },
    supply: 1_000_000_000, // 1 billion tokens
    initialMarketCap: 50 * LAMPORTS_PER_SOL, // 50 SOL market cap
    royaltiesBps: 250, // 2.5% trading fees
    useToken2022: false,
  });

  console.log(`Token created: ${result.mintAddress.toBase58()}`);
  console.log(`Pool created: ${result.poolAddress.toBase58()}`);
  console.log(`Token transaction: ${result.tokenSignature}`);
  console.log(`Pool transaction: ${result.poolSignature}`);
}

main();
```

### Example: Launch with custom timing

Schedule a launch for a specific time:

```typescript
import { Vertigo } from "@vertigo-amm/vertigo-sdk";
import { Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";
import * as anchor from "@coral-xyz/anchor";

async function main() {
  const connection = new Connection("https://api.devnet.solana.com", "confirmed");
  const walletKeypair = anchor.Wallet.local();

  const vertigo = await Vertigo.load({
    connection,
    wallet: walletKeypair,
    network: "devnet",
  });

  // Launch 24 hours from now
  const launchTime = new anchor.BN(Math.floor(Date.now() / 1000) + 86400);

  const result = await vertigo.factory.launchTokenWithPool({
    metadata: {
      name: "Scheduled Launch Token",
      symbol: "SLT",
      decimals: 9,
    },
    supply: 1_000_000_000,
    initialMarketCap: 100 * LAMPORTS_PER_SOL,
    royaltiesBps: 100, // 1% fees
    launchTime, // Unix timestamp
  });

  console.log(`Token will launch at: ${new Date(launchTime.toNumber() * 1000)}`);
  console.log(`Pool address: ${result.poolAddress.toBase58()}`);
}

main();
```

### Parameters Reference

#### LaunchTokenParams

* **metadata** - Token metadata object
  * **name** - Token display name
  * **symbol** - Token symbol/ticker
  * **decimals** - Number of decimals (default: 9)
  * **uri** - Optional metadata URI
* **supply** - Total token supply in whole units
* **useToken2022** - Use Token-2022 instead of SPL (default: false)

#### LaunchTokenWithPoolParams

All of `LaunchTokenParams`, plus:

* **initialMarketCap** - Starting market cap in lamports
* **royaltiesBps** - Trading fee in basis points (e.g., 250 = 2.5%)
* **launchTime** - Optional Unix timestamp for scheduled launch

### Migration from v1

#### v1 (Old) - SPL Token Factory

```typescript
// Initialize factory
await vertigo.SPLTokenFactory.initialize({
  payer,
  owner,
  mintA: NATIVE_MINT,
  params: {
    shift: new anchor.BN(100 * LAMPORTS_PER_SOL),
    initialTokenReserves: new anchor.BN(1_000_000_000),
    feeParams: { /* ... */ },
    tokenParams: { /* ... */ },
    nonce: 0,
  },
});

// Launch from factory
await vertigo.SPLTokenFactory.launch({
  payer,
  owner,
  mintA: NATIVE_MINT,
  mintB,
  mintBAuthority,
  tokenProgramA: TOKEN_PROGRAM_ID,
  params: { /* ... */ },
});
```

#### v2 (New) - Unified Factory

```typescript
// No initialization needed - just launch!
const result = await vertigo.factory.launchTokenWithPool({
  metadata: {
    name: "My Token",
    symbol: "MTK",
    decimals: 9,
  },
  supply: 1_000_000_000,
  initialMarketCap: 50 * LAMPORTS_PER_SOL,
  royaltiesBps: 250,
});
```

### Key Improvements in v2

1. **No initialization required** - Just launch directly
2. **Simplified parameters** - No need to specify token programs, authorities, etc.
3. **Unified interface** - Same API for SPL and Token-2022
4. **Automatic handling** - Token accounts, minting, etc. handled automatically
5. **Better error messages** - Clear, actionable error messages
6. **Type safety** - Full TypeScript support with IntelliSense

### Advanced: Pool Authority Client

For advanced pool management and custom configurations, use the Pool Authority Client:

```typescript
import { PoolAuthority } from "@vertigo-amm/vertigo-sdk";

const poolAuth = await PoolAuthority.load({
  connection,
  wallet,
});

// Create pools with custom authority settings
// Note: This is for advanced use cases
```

{% hint style="warning" %}
The Pool Authority Client is for advanced users who need fine-grained control over pool creation. Most users should use the standard Factory Client's `launchTokenWithPool()` method.
{% endhint %}

### Custom Token Factories

While Vertigo provides default factories, you can build custom factories for your specific launchpad needs:

1. Use the Factory Client as a starting point
2. Extend functionality with custom validation
3. Add custom metadata or launch mechanics
4. Integrate with your own smart contracts

For guidance on building custom factories, see [Designing Token Factories](/designing-token-factories.md).

### Error Handling

```typescript
try {
  const result = await vertigo.factory.launchTokenWithPool({
    metadata: { name: "My Token", symbol: "MTK" },
    supply: 1_000_000,
    initialMarketCap: 50 * LAMPORTS_PER_SOL,
    royaltiesBps: 250,
  });
  console.log(`Success: ${result.poolAddress.toBase58()}`);
} catch (error) {
  if (error.message.includes("Wallet not connected")) {
    console.error("Please connect a wallet first");
  } else if (error.message.includes("Insufficient funds")) {
    console.error("Not enough SOL to create token and pool");
  } else {
    console.error(`Launch failed: ${error.message}`);
  }
}
```

### Tips

* The initial supply is minted to your wallet's associated token account
* Market cap is the initial virtual SOL backing the pool
* Royalties are trading fees that accrue to the pool owner
* Always test on devnet before launching on mainnet
* Consider using `launchTime` for coordinated launches
* Token-2022 offers advanced features but requires compatible wallets
* Use the `createTokenMetadata()` helper to ensure metadata is properly validated


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.vertigo.sh/sdk-v2/token-factories.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
