> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobula.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Detect a Token's Chain from Contract Address

> Learn how to automatically identify which blockchain a token is deployed on using just the contract address - no RPC calls needed.

## Overview

When building crypto applications, you often need to identify which blockchain a token contract belongs to. Traditional approaches require expensive RPC calls to multiple chains, which is slow and resource-intensive.

Mobula's **Universal Search** (`/api/2/fast-search`) automatically detects the chain for any contract address in **under 30ms** - no RPC calls, no chain guessing.

## Quick Start

Simply pass the contract address to the search endpoint:

```bash theme={null}
curl "https://api.mobula.io/api/2/fast-search?input=0xdAC17F958D2ee523a2206206994597C13D831ec7"
```

The response includes the `chainId` field that tells you exactly which chain the token is on:

```json theme={null}
{
  "data": [
    {
      "address": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
      "chainId": "evm:1",
      "symbol": "USDT",
      "name": "Tether USD",
      "priceUSD": 0.9999,
      ...
    }
  ]
}
```

## How It Works

When you provide a contract address to the search endpoint:

1. **Cross-chain lookup**: Mobula searches across all supported blockchains simultaneously
2. **Instant matching**: Uses indexed data instead of live RPC calls
3. **Returns chain info**: The response includes `chainId` identifying the exact blockchain

This is significantly faster than the traditional approach of making sequential RPC calls to each chain.

## Code Examples

### TypeScript / JavaScript

```typescript theme={null}
interface TokenResult {
  address: string;
  chainId: string;
  symbol: string | null;
  name: string | null;
  priceUSD: number;
  // ... many more fields
}

interface SearchResponse {
  data: TokenResult[];
}

async function detectChain(contractAddress: string): Promise<string | null> {
  const response = await fetch(
    `https://api.mobula.io/api/2/fast-search?input=${contractAddress}`,
    {
      headers: {
        'Authorization': `Bearer ${process.env.MOBULA_API_KEY}`,
      },
    }
  );
  
  const result: SearchResponse = await response.json();
  
  if (result.data.length === 0) {
    return null; // Token not found
  }
  
  return result.data[0].chainId;
}

// Usage
const chainId = await detectChain('0xdAC17F958D2ee523a2206206994597C13D831ec7');
console.log(`Token is on chain: ${chainId}`); // Output: "evm:1"
```

### Python

```python theme={null}
import requests
from typing import Optional

def detect_chain(contract_address: str, api_key: str = None) -> Optional[str]:
    """Detect which blockchain a contract address belongs to."""
    
    headers = {}
    if api_key:
        headers["Authorization"] = f"Bearer {api_key}"
    
    response = requests.get(
        f"https://api.mobula.io/api/2/fast-search?input={contract_address}",
        headers=headers
    )
    
    data = response.json()
    
    if not data.get("data"):
        return None
        
    return data["data"][0]["chainId"]


# Usage
chain_id = detect_chain("0xdAC17F958D2ee523a2206206994597C13D831ec7")
print(f"Token is on chain: {chain_id}")  # Output: "evm:1"

# Solana example
chain_id = detect_chain("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v")
print(f"Token is on chain: {chain_id}")  # Output: "solana:solana"
```

## Get Full Token Data

Once you have the chain ID, you can fetch complete token details:

```typescript theme={null}
async function getTokenWithChainDetection(contractAddress: string) {
  // Step 1: Detect chain from address
  const searchResponse = await fetch(
    `https://api.mobula.io/api/2/fast-search?input=${contractAddress}&limit=1`
  );
  const searchResult = await searchResponse.json();
  
  if (searchResult.data.length === 0) {
    throw new Error('Token not found');
  }
  
  const { chainId, address } = searchResult.data[0];
  
  // Step 2: Fetch full token details
  const detailsResponse = await fetch(
    `https://api.mobula.io/api/2/token/details?blockchain=${chainId}&address=${address}`
  );
  
  return detailsResponse.json();
}

// Usage
const tokenData = await getTokenWithChainDetection('0xdAC17F958D2ee523a2206206994597C13D831ec7');
console.log(tokenData);
```

<Info>
  The search endpoint already returns comprehensive token data including price, volume, liquidity, and trading metrics. In most cases, you won't need to make a second API call.
</Info>

## Multi-Chain Tokens

Some tokens exist on multiple chains (like USDT or USDC). The search returns all instances sorted by trading activity:

```typescript theme={null}
async function findTokenAcrossChains(contractAddress: string) {
  const response = await fetch(
    `https://api.mobula.io/api/2/fast-search?input=${contractAddress}&limit=20`
  );
  const result = await response.json();
  
  // Group by chain
  const byChain = new Map<string, any>();
  for (const token of result.data) {
    if (!byChain.has(token.chainId)) {
      byChain.set(token.chainId, token);
    }
  }
  
  return byChain;
}
```

## Chain ID Format

Mobula uses standardized chain identifiers:

| Chain    | Chain ID        |
| -------- | --------------- |
| Ethereum | `evm:1`         |
| BSC      | `evm:56`        |
| Base     | `evm:8453`      |
| Arbitrum | `evm:42161`     |
| Polygon  | `evm:137`       |
| Optimism | `evm:10`        |
| Solana   | `solana:solana` |
| Sui      | `sui:sui`       |

<Tip>
  See the [Blockchains endpoint](/rest-api-reference/endpoint/blockchains) for the complete list of supported chains and their identifiers.
</Tip>

## Performance Comparison

| Method                            | Latency     | RPC Calls |
| --------------------------------- | ----------- | --------- |
| Sequential RPC checks (10 chains) | 2-5 seconds | 10+       |
| Parallel RPC checks (10 chains)   | 500ms-1s    | 10+       |
| **Mobula Universal Search**       | **\<30ms**  | **0**     |

## Best Practices

### 1. Handle Multiple Results

When a token exists on multiple chains, the API returns all matches. Always check if your expected chain is in the results:

```typescript theme={null}
async function findTokenOnSpecificChains(
  address: string, 
  preferredChains: string[]
): Promise<TokenResult | null> {
  const response = await fetch(
    `https://api.mobula.io/api/2/fast-search?input=${address}&limit=10`
  );
  const result = await response.json();
  
  // Find token on preferred chain first
  for (const chain of preferredChains) {
    const match = result.data.find((t: TokenResult) => t.chainId === chain);
    if (match) return match;
  }
  
  // Fallback to most active (first result)
  return result.data[0] || null;
}
```

### 2. Cache Results

Chain IDs for contracts don't change. Cache the results to avoid repeated lookups:

```typescript theme={null}
const chainCache = new Map<string, string>();

async function detectChainCached(address: string): Promise<string | null> {
  const normalizedAddress = address.toLowerCase();
  
  if (chainCache.has(normalizedAddress)) {
    return chainCache.get(normalizedAddress)!;
  }
  
  const chainId = await detectChain(address);
  if (chainId) {
    chainCache.set(normalizedAddress, chainId);
  }
  
  return chainId;
}
```

### 3. Filter by Specific Chains

If you only support certain chains, filter the results:

```typescript theme={null}
const response = await fetch(
  `https://api.mobula.io/api/2/fast-search?input=${address}&filters={"blockchains":"1,8453,solana"}`
);
```

## Response Fields

Each token in the response includes:

| Field          | Type   | Description            |
| -------------- | ------ | ---------------------- |
| `address`      | string | Token contract address |
| `chainId`      | string | Blockchain identifier  |
| `symbol`       | string | Token symbol           |
| `name`         | string | Token name             |
| `priceUSD`     | number | Current price in USD   |
| `volume24hUSD` | number | 24h trading volume     |
| `liquidityUSD` | number | Total liquidity        |
| `marketCapUSD` | number | Market capitalization  |

<Info>
  The full response includes 100+ fields. See the [Universal Search API Reference](/rest-api-reference/endpoint/fast-search) for complete documentation.
</Info>

## Use Cases

* **Trading bots**: Quickly identify token chains for cross-chain arbitrage
* **Portfolio trackers**: Auto-detect chains for user-provided addresses
* **Token analytics**: Build chain-agnostic token dashboards
* **Wallet integrations**: Display correct chain info without RPC overhead

## Next Steps

* [Universal Search API Reference](/rest-api-reference/endpoint/fast-search) - Full API documentation
* [Token Details](/rest-api-reference/endpoint/token-details) - Get comprehensive token data
* [Supported Blockchains](/blockchains/intro-blockchains) - See all supported chains

## Support

Need help? Join our community:

* [Discord](https://discord.gg/JVT7xKm3AD)
* [Telegram](https://t.me/mobuladevelopers)
* Email: [contact@mobulalabs.org](mailto:contact@mobulalabs.org)
