# Token List Authoring Guide

**Based on**: [Uniswap Token Lists Specification](https://github.com/Uniswap/token-lists#authoring-token-lists)  
**Schema**: [https://uniswap.org/tokenlist.schema.json](https://uniswap.org/tokenlist.schema.json)  
**Network**: ChainID 138 (SMOM-DBIS-138)

---

## 📋 Overview

This guide explains how to create and maintain token lists that conform to the Uniswap Token Lists specification. Token lists are JSON files that contain metadata about ERC20 tokens for use in dApp interfaces like MetaMask, Uniswap, and other DeFi applications.

---

## 📁 File Structure

Our token list files:

- **`token-lists/lists/dbis-138.tokenlist.json`** - Main token list file (production)
- **`docs/METAMASK_TOKEN_LIST.json`** - Legacy location (deprecated, kept for backward compatibility)
- **`token-list.json`** - Public-facing token list (deployed version)

The `.tokenlist.json` extension enables automatic JSON schema validation in editors like VSCode and IntelliJ.

**Note**: The token list has been migrated to `token-lists/lists/dbis-138.tokenlist.json` for better organization and CI/CD integration.

---

## 📝 Token List Structure

### Required Fields

Every token list must include:

```json
{
  "name": "SMOM-DBIS-138 Token List",
  "version": {
    "major": 1,
    "minor": 0,
    "patch": 0
  },
  "timestamp": "2025-12-22T17:45:00.000Z",
  "tokens": [
    // Array of token objects
  ]
}
```

### Optional Fields

Recommended fields for better compatibility:

- **`logoURI`** (string): Logo URL for the token list itself
- **`tags`** (object): Tag definitions for categorizing tokens
- **`tokenMap`** (object): Optional map for quick token lookups

### Token Object Structure

Each token in the `tokens` array must have:

**Required:**
- `chainId` (number): Chain ID (138 for SMOM-DBIS-138)
- `address` (string): Ethereum address (0x-prefixed, 40 hex chars)
- `name` (string): Human-readable token name
- `symbol` (string): Token symbol (e.g., "WETH", "ETH-USD")
- `decimals` (number): Number of decimals (0-255)

**Optional:**
- `logoURI` (string): URL to token logo image
- `tags` (array of strings): Array of tag identifiers

---

## 🎨 Example Token List

```json
{
  "name": "SMOM-DBIS-138 Token List",
  "version": {
    "major": 1,
    "minor": 1,
    "patch": 0
  },
  "timestamp": "2025-12-22T17:45:00.000Z",
  "logoURI": "https://example.com/logo.png",
  "tokens": [
    {
      "chainId": 138,
      "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
      "name": "Wrapped Ether",
      "symbol": "WETH",
      "decimals": 18,
      "logoURI": "https://example.com/weth.png",
      "tags": ["defi", "wrapped"]
    }
  ],
  "tags": {
    "defi": {
      "name": "DeFi",
      "description": "Decentralized Finance tokens"
    },
    "wrapped": {
      "name": "Wrapped",
      "description": "Wrapped tokens representing native assets"
    }
  }
}
```

---

## ✅ Validation

### Using the Validation Script

We provide enhanced validation scripts in `token-lists/scripts/`:

```bash
# Validate the token list (schema, checksums, duplicates, chain ID)
node token-lists/scripts/validate-token-list.js token-lists/lists/dbis-138.tokenlist.json

# Validate address checksums
node token-lists/scripts/checksum-addresses.js token-lists/lists/dbis-138.tokenlist.json

# Fix checksummed addresses
node token-lists/scripts/checksum-addresses.js token-lists/lists/dbis-138.tokenlist.json --fix

# Validate logos
node token-lists/scripts/validate-logos.js token-lists/lists/dbis-138.tokenlist.json

# Verify on-chain contracts
node token-lists/scripts/verify-on-chain.js token-lists/lists/dbis-138.tokenlist.json
```

The script will:
1. Fetch the official Uniswap schema
2. Validate the JSON structure
3. Check all required fields
4. Validate token addresses format
5. Verify decimals are in valid range (0-255)
6. Display token list information

### Manual Validation

For manual validation, you can:

1. **Use an editor with JSON Schema support** (VSCode, IntelliJ, etc.)
   - Files with `.tokenlist.json` extension automatically get schema validation
   - The schema is registered in SchemaStore

2. **Use online validators**:
   - [JSON Schema Validator](https://www.jsonschemavalidator.net/)
   - Schema URL: `https://uniswap.org/tokenlist.schema.json`

3. **Use command-line tools**:
   ```bash
   # Basic JSON validation
   jq empty docs/METAMASK_TOKEN_LIST.json

   # Validate against schema (requires ajv-cli)
   ajv validate -s tokenlist.schema.json -d docs/METAMASK_TOKEN_LIST.json
   ```

---

## 🔄 Semantic Versioning

Token list versions follow [semantic versioning](https://semver.org/) rules:

### Version Increment Rules

- **Major version** (1.0.0 → 2.0.0):
  - When tokens are **removed** from the list
  - When token addresses or chain IDs change (considered remove + add)

- **Minor version** (1.0.0 → 1.1.0):
  - When tokens are **added** to the list

- **Patch version** (1.0.0 → 1.0.1):
  - When **existing tokens** have minor details changed:
    - Name changes
    - Symbol changes
    - Logo URL updates
    - Decimals changes
    - Tag additions/removals

### Example Version Changes

```json
// Version 1.0.0 → 1.0.1 (patch)
// Changed logo URL for WETH
{
  "version": { "major": 1, "minor": 0, "patch": 1 },
  "tokens": [
    { "symbol": "WETH", "logoURI": "https://new-logo.png" }
  ]
}

// Version 1.0.0 → 1.1.0 (minor)
// Added new token
{
  "version": { "major": 1, "minor": 1, "patch": 0 },
  "tokens": [
    { "symbol": "WETH", ... },
    { "symbol": "USDC", ... }  // New token
  ]
}

// Version 1.0.0 → 2.0.0 (major)
// Removed token
{
  "version": { "major": 2, "minor": 0, "patch": 0 },
  "tokens": [
    { "symbol": "WETH", ... }
    // USDC removed
  ]
}
```

---

## 🛠️ Authoring Methods

### Manual Authoring

**Recommended for**: Small lists, occasional updates

1. **Use an editor with JSON Schema support**:
   - VSCode (recommended)
   - IntelliJ IDEA
   - Other editors from [SchemaStore](https://www.schemastore.org/json/)

2. **Open the `.tokenlist.json` file**:
   ```bash
   code docs/METAMASK_TOKEN_LIST.tokenlist.json
   ```

3. **The editor will provide**:
   - Autocomplete for valid fields
   - Validation errors in real-time
   - Schema-aware formatting

4. **Make your changes** and save

5. **Validate before committing**:
   ```bash
   node token-lists/scripts/validate-token-list.js token-lists/lists/dbis-138.tokenlist.json
   ```

### Automated Authoring

**Recommended for**: Large lists, frequent updates, pulling from contracts

You can use the `@uniswap/token-lists` npm package:

```javascript
import { TokenList, schema } from '@uniswap/token-lists'
import Ajv from 'ajv'
import addFormats from 'ajv-formats'

// Generate your token list
const myList: TokenList = {
  name: "SMOM-DBIS-138 Token List",
  version: { major: 1, minor: 0, patch: 0 },
  timestamp: new Date().toISOString(),
  tokens: [
    // Your tokens
  ]
}

// Validate against schema
const ajv = new Ajv({ allErrors: true, verbose: true })
addFormats(ajv)
const validator = ajv.compile(schema)
const valid = validator(myList)

if (!valid) {
  console.error('Validation errors:', validator.errors)
} else {
  // Print JSON
  console.log(JSON.stringify(myList, null, 2))
}
```

---

## 📤 Deploying Token Lists

### Release Process

For production releases, use the release script:

```bash
# Bump version (patch, minor, or major)
cd token-lists
./scripts/release.sh patch

# Sign the token list
./scripts/sign-list.sh sign

# Create git tag and push (triggers GitHub Actions release workflow)
git tag -a v1.2.0 -m "Release v1.2.0"
git push --tags
```

The GitHub Actions release workflow will automatically:
- Validate the token list
- Verify on-chain contracts
- Generate checksums
- Sign the token list
- Create a GitHub Release

For manual hosting, you can use the hosting script:

```bash
# Prepare for GitHub Pages
./scripts/host-token-list.sh github

# Prepare for IPFS
./scripts/host-token-list.sh ipfs

# Get instructions for custom hosting
./scripts/host-token-list.sh local
```

See [METAMASK_TOKEN_LIST_HOSTING.md](./METAMASK_TOKEN_LIST_HOSTING.md) for detailed deployment instructions.

### Hosting Requirements

- **HTTPS required**: MetaMask and other dApps require HTTPS
- **CORS headers**: Must include `Access-Control-Allow-Origin: *`
- **Content-Type**: Should be `application/json`

---

## 🔍 Current Token List Contents

Our token list currently includes:

1. **WETH9** (`0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`)
   - Wrapped Ether (18 decimals)
   - Tags: `defi`, `wrapped`

2. **WETH10** (`0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f`)
   - Wrapped Ether v10 (18 decimals)
   - Tags: `defi`, `wrapped`

3. **ETH/USD Price Feed** (`0x3304b747e565a97ec8ac220b0b6a1f6ffdb837e6`)
   - Oracle price feed (8 decimals)
   - Tags: `oracle`, `price-feed`

---

## 📚 Best Practices

1. **Always validate** before deploying
   ```bash
   node scripts/validate-token-list.js docs/METAMASK_TOKEN_LIST.json
   ```

2. **Update timestamp** when making changes
   ```json
   "timestamp": "2025-12-22T17:45:00.000Z"
   ```

3. **Use checksummed addresses** (mixed case)
   - Use tools like [ethsum.netlify.app](https://ethsum.netlify.app/)
   - Or use ethers.js: `ethers.getAddress(address)`

4. **Provide logo URLs** for better UX
   - Use reliable CDNs (GitHub, IPFS, etc.)
   - Recommended format: PNG or SVG
   - Recommended size: 256x256 or larger

5. **Use tags** to categorize tokens
   - Makes filtering easier for users
   - Define tag descriptions in the `tags` object

6. **Follow versioning rules** strictly
   - Helps users understand what changed
   - Prevents breaking changes

7. **Test in MetaMask** after updates
   - Add the token list URL to MetaMask
   - Verify tokens appear correctly
   - Check metadata (name, symbol, decimals, logo)

---

## 🔗 Related Documentation

- [Token Lists README](/docs/01-getting-started/README.md) - Main token lists documentation
- [Token List Policy](../token-lists/docs/TOKEN_LIST_POLICY.md) - Inclusion and delisting policy
- [Integration Guide](../token-lists/docs/INTEGRATION_GUIDE.md) - Integration instructions
- [Uniswap Token Lists Specification](https://github.com/Uniswap/token-lists)
- [JSON Schema](https://uniswap.org/tokenlist.schema.json)
- [MetaMask Token List Guide](./METAMASK_ADD_TOKEN_LIST_GUIDE.md)
- [Token List Hosting Guide](./METAMASK_TOKEN_LIST_HOSTING.md)
- [MetaMask Integration Requirements](./METAMASK_FULL_INTEGRATION_REQUIREMENTS.md)

---

## 🐛 Troubleshooting

### Validation Errors

**Error: "Missing or invalid address"**
- Ensure address is 0x-prefixed with 40 hex characters
- Use checksummed (mixed case) addresses

**Error: "Invalid decimals"**
- Decimals must be a number between 0 and 255

**Error: "Invalid chainId"**
- Chain ID must be a number
- For SMOM-DBIS-138, use 138

### Schema Validation Fails

If AJV validation fails but basic validation passes:

1. Install dependencies:
   ```bash
   npm install ajv ajv-formats
   ```

2. Run validation again:
   ```bash
   node scripts/validate-token-list.js docs/METAMASK_TOKEN_LIST.json
   ```

3. Check specific errors in the output

---

**Last Updated**: 2025-12-22  
**Maintainer**: DBIS Team

