321 lines
8.2 KiB
Markdown
321 lines
8.2 KiB
Markdown
|
|
# Token List Integration Guide
|
||
|
|
|
||
|
|
**Network**: ChainID 138 (DBIS Chain)
|
||
|
|
**Token List**: DBIS Chain 138 Token List
|
||
|
|
**Last Updated**: 2025-12-22
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
This guide explains how to integrate the DBIS Chain 138 Token List into various applications, wallets, and services.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Token List Endpoints
|
||
|
|
|
||
|
|
### Primary Endpoints
|
||
|
|
|
||
|
|
- **GitHub Pages**: `https://{user}.github.io/{repo}/token-lists/lists/dbis-138.tokenlist.json`
|
||
|
|
- **GitHub Raw**: `https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json`
|
||
|
|
- **DBIS Domain** (if configured): `https://tokens.d-bis.org/lists/dbis-138.tokenlist.json`
|
||
|
|
|
||
|
|
### Verification
|
||
|
|
|
||
|
|
- **Signature**: `{token-list-url}.sig`
|
||
|
|
- **Checksums**: See GitHub Releases for `SHA256SUMS`
|
||
|
|
- **Public Key**: `token-lists/minisign.pub`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## MetaMask Integration
|
||
|
|
|
||
|
|
### Method 1: Manual Addition
|
||
|
|
|
||
|
|
1. Open MetaMask
|
||
|
|
2. Go to **Settings** → **Security & Privacy** → **Token Lists**
|
||
|
|
3. Click **"Add custom token list"**
|
||
|
|
4. Enter token list URL:
|
||
|
|
```
|
||
|
|
https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json
|
||
|
|
```
|
||
|
|
5. Click **Add**
|
||
|
|
|
||
|
|
### Method 2: Programmatic Addition
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Add network first (if not already added)
|
||
|
|
await window.ethereum.request({
|
||
|
|
method: 'wallet_addEthereumChain',
|
||
|
|
params: [{
|
||
|
|
chainId: '0x8a', // 138 in hex
|
||
|
|
chainName: 'SMOM-DBIS-138',
|
||
|
|
rpcUrls: ['https://rpc-core.d-bis.org'],
|
||
|
|
nativeCurrency: {
|
||
|
|
name: 'Ether',
|
||
|
|
symbol: 'ETH',
|
||
|
|
decimals: 18
|
||
|
|
},
|
||
|
|
blockExplorerUrls: ['https://explorer.d-bis.org']
|
||
|
|
}]
|
||
|
|
});
|
||
|
|
|
||
|
|
// Token list is added via MetaMask UI (Settings → Token Lists)
|
||
|
|
// MetaMask doesn't provide API for programmatic token list addition
|
||
|
|
```
|
||
|
|
|
||
|
|
### Verifying Token List in MetaMask
|
||
|
|
|
||
|
|
1. Ensure you're connected to ChainID 138
|
||
|
|
2. Go to **Assets** tab
|
||
|
|
3. Click **"Import tokens"**
|
||
|
|
4. Tokens from the list should appear automatically
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Ledger Integration
|
||
|
|
|
||
|
|
Ledger Live doesn't directly support token lists. Use MetaMask with Ledger:
|
||
|
|
|
||
|
|
1. **Connect Ledger to MetaMask**
|
||
|
|
- Connect Ledger device
|
||
|
|
- Enable "Ethereum" app on Ledger
|
||
|
|
- In MetaMask, select "Connect Hardware Wallet" → "Ledger"
|
||
|
|
|
||
|
|
2. **Add DBIS Network**
|
||
|
|
- Follow MetaMask network addition steps above
|
||
|
|
- Network will use Ledger for signing
|
||
|
|
|
||
|
|
3. **Add Token List**
|
||
|
|
- Follow MetaMask token list addition steps above
|
||
|
|
- Tokens will be available when using Ledger with MetaMask
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## dApp Integration
|
||
|
|
|
||
|
|
### Using Web3.js
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const Web3 = require('web3');
|
||
|
|
const web3 = new Web3('https://rpc-core.d-bis.org');
|
||
|
|
|
||
|
|
// Fetch token list
|
||
|
|
async function getTokenList() {
|
||
|
|
const response = await fetch('https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json');
|
||
|
|
const tokenList = await response.json();
|
||
|
|
return tokenList.tokens;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Use token metadata
|
||
|
|
const tokens = await getTokenList();
|
||
|
|
const wethToken = tokens.find(t => t.symbol === 'WETH');
|
||
|
|
console.log(`WETH address: ${wethToken.address}`);
|
||
|
|
console.log(`WETH decimals: ${wethToken.decimals}`);
|
||
|
|
```
|
||
|
|
|
||
|
|
### Using Ethers.js
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const { ethers } = require('ethers');
|
||
|
|
const provider = new ethers.JsonRpcProvider('https://rpc-core.d-bis.org');
|
||
|
|
|
||
|
|
// Fetch token list
|
||
|
|
async function getTokenList() {
|
||
|
|
const response = await fetch('https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json');
|
||
|
|
const tokenList = await response.json();
|
||
|
|
return tokenList.tokens;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Create contract instance using token metadata
|
||
|
|
const tokens = await getTokenList();
|
||
|
|
const wethToken = tokens.find(t => t.symbol === 'WETH');
|
||
|
|
|
||
|
|
const erc20ABI = [
|
||
|
|
'function balanceOf(address) view returns (uint256)',
|
||
|
|
'function decimals() view returns (uint8)'
|
||
|
|
];
|
||
|
|
|
||
|
|
const contract = new ethers.Contract(wethToken.address, erc20ABI, provider);
|
||
|
|
const balance = await contract.balanceOf(userAddress);
|
||
|
|
const decimals = await contract.decimals();
|
||
|
|
console.log(`Balance: ${ethers.formatUnits(balance, decimals)} WETH`);
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Explorer/Indexer Integration
|
||
|
|
|
||
|
|
### Blockscout Integration
|
||
|
|
|
||
|
|
1. **Configure Token List URL**
|
||
|
|
- Add token list URL to Blockscout configuration
|
||
|
|
- Blockscout will fetch token metadata automatically
|
||
|
|
|
||
|
|
2. **Manual Token Addition**
|
||
|
|
- Use Blockscout admin interface
|
||
|
|
- Add tokens from the list manually
|
||
|
|
|
||
|
|
### Custom Indexer
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
// Fetch and cache token list
|
||
|
|
async function fetchTokenList() {
|
||
|
|
const response = await fetch('https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json');
|
||
|
|
const tokenList = await response.json();
|
||
|
|
|
||
|
|
// Create lookup map
|
||
|
|
const tokenMap = new Map();
|
||
|
|
tokenList.tokens.forEach(token => {
|
||
|
|
tokenMap.set(token.address.toLowerCase(), token);
|
||
|
|
});
|
||
|
|
|
||
|
|
return tokenMap;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Use in indexing
|
||
|
|
const tokenMap = await fetchTokenList();
|
||
|
|
const token = tokenMap.get(contractAddress.toLowerCase());
|
||
|
|
if (token) {
|
||
|
|
console.log(`Token: ${token.symbol} (${token.name})`);
|
||
|
|
console.log(`Decimals: ${token.decimals}`);
|
||
|
|
console.log(`Logo: ${token.logoURI}`);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Signature Verification
|
||
|
|
|
||
|
|
Verify token list integrity using minisign:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Install minisign (if not installed)
|
||
|
|
# macOS: brew install minisign
|
||
|
|
# Ubuntu: apt-get install minisign
|
||
|
|
|
||
|
|
# Download files
|
||
|
|
curl -O https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json
|
||
|
|
curl -O https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json.sig
|
||
|
|
curl -O https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/minisign.pub
|
||
|
|
|
||
|
|
# Verify signature
|
||
|
|
minisign -V -p minisign.pub -m dbis-138.tokenlist.json -x dbis-138.tokenlist.json.sig
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## CORS Configuration
|
||
|
|
|
||
|
|
If hosting the token list on a custom domain, ensure CORS headers are configured:
|
||
|
|
|
||
|
|
### Nginx Example
|
||
|
|
|
||
|
|
```nginx
|
||
|
|
location /lists/dbis-138.tokenlist.json {
|
||
|
|
add_header Access-Control-Allow-Origin *;
|
||
|
|
add_header Access-Control-Allow-Methods "GET, OPTIONS";
|
||
|
|
add_header Content-Type application/json;
|
||
|
|
add_header Cache-Control "public, max-age=3600";
|
||
|
|
|
||
|
|
if ($request_method = OPTIONS) {
|
||
|
|
add_header Access-Control-Allow-Origin *;
|
||
|
|
add_header Access-Control-Allow-Methods "GET, OPTIONS";
|
||
|
|
add_header Content-Length 0;
|
||
|
|
add_header Content-Type text/plain;
|
||
|
|
return 204;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Apache Example
|
||
|
|
|
||
|
|
```apache
|
||
|
|
<Location "/lists/dbis-138.tokenlist.json">
|
||
|
|
Header set Access-Control-Allow-Origin "*"
|
||
|
|
Header set Access-Control-Allow-Methods "GET, OPTIONS"
|
||
|
|
Header set Content-Type "application/json"
|
||
|
|
Header set Cache-Control "public, max-age=3600"
|
||
|
|
</Location>
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Rate Limiting
|
||
|
|
|
||
|
|
When fetching the token list:
|
||
|
|
|
||
|
|
- Use appropriate caching (recommended: 1 hour)
|
||
|
|
- Respect rate limits if using GitHub API
|
||
|
|
- Consider mirroring to CDN for high-traffic applications
|
||
|
|
|
||
|
|
### Caching Example
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
const CACHE_KEY = 'dbis-token-list-v1.1.0';
|
||
|
|
const CACHE_TTL = 3600000; // 1 hour
|
||
|
|
|
||
|
|
async function getTokenListCached() {
|
||
|
|
const cached = localStorage.getItem(CACHE_KEY);
|
||
|
|
const cachedTime = localStorage.getItem(`${CACHE_KEY}-time`);
|
||
|
|
|
||
|
|
if (cached && cachedTime && Date.now() - parseInt(cachedTime) < CACHE_TTL) {
|
||
|
|
return JSON.parse(cached);
|
||
|
|
}
|
||
|
|
|
||
|
|
const response = await fetch('https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json');
|
||
|
|
const tokenList = await response.json();
|
||
|
|
|
||
|
|
localStorage.setItem(CACHE_KEY, JSON.stringify(tokenList));
|
||
|
|
localStorage.setItem(`${CACHE_KEY}-time`, Date.now().toString());
|
||
|
|
|
||
|
|
return tokenList;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Error Handling
|
||
|
|
|
||
|
|
Always handle errors when fetching token lists:
|
||
|
|
|
||
|
|
```javascript
|
||
|
|
async function getTokenList() {
|
||
|
|
try {
|
||
|
|
const response = await fetch('https://raw.githubusercontent.com/{user}/{repo}/main/token-lists/lists/dbis-138.tokenlist.json');
|
||
|
|
|
||
|
|
if (!response.ok) {
|
||
|
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
const tokenList = await response.json();
|
||
|
|
|
||
|
|
// Validate structure
|
||
|
|
if (!tokenList.tokens || !Array.isArray(tokenList.tokens)) {
|
||
|
|
throw new Error('Invalid token list format');
|
||
|
|
}
|
||
|
|
|
||
|
|
return tokenList;
|
||
|
|
} catch (error) {
|
||
|
|
console.error('Failed to fetch token list:', error);
|
||
|
|
// Fallback to cached version or default list
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Support
|
||
|
|
|
||
|
|
For integration questions or issues:
|
||
|
|
|
||
|
|
- Create an issue in the repository
|
||
|
|
- Check existing documentation
|
||
|
|
- Contact DBIS team
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Last Updated**: 2025-12-22
|
||
|
|
|