Automated token image fetching and serving for Euler Finance tokens across supported chains.
- π Smart Sync Process: Automatically migrates local images to S3, then fetches missing images
- π S3 Integration: Stores images in AWS S3 with rich metadata (provider, date, extension)
- π HTTP Server: Fast image serving with fallback to default image
- π Multiple Providers: Extensible system supporting CoinGecko + future providers
- π Validation: Zod validation for chainId (number) and address (Ethereum format)
- π Local Migration: Automatically uploads existing local images to S3
- π― Efficient Bulk Operations: Batch S3 checks and parallel processing
- β‘ Rate Limited: Respects API limits with intelligent batching
- Ethereum (1)
- Base (8453)
- Sonic (1923, 146)
- Bob (60808)
- zkSync (80094)
- Avalanche (43114)
- BSC (56)
- Polygon (130)
# Required for CoinGecko API access
COINGECKO_API_KEY=your_coingecko_api_key_here
# Required for Euler Finance API
EULER_API_URL=https://index-dev.euler.finance
# AWS Configuration for S3 storage
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=your_aws_access_key
AWS_SECRET_ACCESS_KEY=your_aws_secret_key
# Optional - Server port (default: 4000)
PORT=4000- Clone the repository
- Install dependencies:
bun install - Set up environment variables in
.envfile - Configure AWS credentials for S3 access
- Start the server:
bun run start
- Set environment variables in your deployment platform
- Ensure AWS S3 bucket
euler-token-imagesexists and is accessible - Deploy with your preferred method (Docker, serverless, etc.)
# Install dependencies
bun install
# Set API key (for CoinGecko API)
export COINGECKO_API_KEY=your_api_key_here
# Fetch images from Euler Finance API
bun run fetch-images
# Fetch images from static token lists
bun run fetch-static-imagesStart the image serving server:
# Start server (default port 4000)
bun run start
# Or specify custom port
PORT=3000 bun run startGET /{chainId}/{address}- Serve token image from S3 or default fallbackPOST /sync/{chainId}- Sync token images for a specific chainGET /health- Health check endpoint
Image Serving Examples:
GET /1/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48β serves USDC image from S3GET /8453/0x833589fcd6edb6e08f4c7c32d4f71b54bda02913β serves Base USDC image from S3
Sync Examples:
POST /sync/1β syncs all Ethereum mainnet tokensPOST /sync/8453β syncs all Base network tokens
The sync endpoint follows an intelligent 4-step process to efficiently manage token images:
graph LR
A[Euler API] --> B[Token List]
B --> C[chainId/address pairs]
- Fetches all tokens for the specified chainId from Euler Finance API
- Validates chainId as a positive integer
graph LR
A[Token List] --> B[Bulk S3 Check]
B --> C[Existing Images]
B --> D[Missing Images]
- Efficiently checks S3 bucket
euler-token-imagesfor existing images - Uses prefix matching:
{chainId}/{address}/image.* - Skips processing for tokens that already have images in S3
graph LR
A[Missing from S3] --> B[Check Local FS]
B --> C[Found Local] --> D[Upload to S3]
B --> E[Still Missing]
D --> F[Mark as Migrated]
- For images missing from S3, checks local filesystem first
- Uploads existing local images to S3 with metadata:
provider: "local-migration"downloadDate: ISO timestampextension: file extensionoriginalUrl: local file path
graph LR
A[Still Missing] --> B[CoinGecko API]
B --> C[Download Image]
C --> D[Upload to S3]
D --> E[Mark as Downloaded]
B --> F[Not Found] --> G[Mark as Failed]
- Only after checking S3 and local images, queries external APIs
- Currently supports CoinGecko Pro API
- Extensible provider system for adding more APIs
- Rate limited and batched to respect API limits
- Stores rich metadata in S3
{
"success": true,
"data": {
"chainId": 1,
"totalTokens": 150,
"existingImages": 120, // Already in S3
"migratedFromLocal": 15, // Uploaded from local files
"downloadedImages": 10, // Downloaded from APIs
"failedDownloads": 5, // Failed to find/download
"duration": 45000, // Process time in ms
"details": [
{
"address": "0x...",
"status": "exists|migrated|downloaded|failed",
"provider": "local-migration|coingecko"
}
]
}
}The workflow runs daily at midnight UTC or can be triggered manually.
euler-token-images/
βββ 1/ # Ethereum mainnet
β βββ 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48/
β βββ image.png # USDC image with metadata
βββ 8453/ # Base network
β βββ 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913/
β βββ image.jpg # Base USDC image
βββ {chainId}/
βββ {contractAddress}/
βββ image.{extension} # Auto-detected extension
Each image stored in S3 includes rich metadata:
{
"ContentType": "image/png",
"Metadata": {
"extension": "png",
"provider": "coingecko|local-migration",
"downloadDate": "2025-01-21T10:30:00.000Z",
"originalUrl": "https://assets.coingecko.com/..." // or local path
}
}For development and migration purposes, local images follow the same pattern:
{chainId}/
βββ {contractAddress}/
βββ image.{extension}
start- Start the HTTP server with sync endpoint and image servingfetch-images- Legacy: Fetch token images from Euler Finance API + CoinGeckofetch-static-images- Legacy: Process static token lists and download remote images
Recommended: Use the
POST /sync/{chainId}endpoint instead of legacy scripts for better efficiency and S3 integration.
graph TD
A[Euler API] --> B[Token List]
B --> C[S3 Check]
C --> D[Local Check]
D --> E[CoinGecko API]
E --> F[S3 Storage]
F --> G[Image Serving]
- Token Data: Euler Finance API (
https://index-dev.euler.finance/v1/tokens) - Image Sources:
- Local filesystem (migrated automatically)
- CoinGecko Pro API (
https://pro-api.coingecko.com/api/v3/coins) - Extensible provider system for future APIs
- Storage: AWS S3 bucket
euler-token-images - Serving: Direct from S3 with fallback to default image
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β HTTP Server β β Sync Service β β Image Providersβ
β β β β β β
β β’ Image serving βββββΊβ β’ S3 operations βββββΊβ β’ CoinGecko β
β β’ Sync endpoint β β β’ Local migrationβ β β’ Extensible β
β β’ Validation β β β’ Batch processingβ β β’ Rate limited β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β β β
βΌ βΌ βΌ
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β AWS S3 β β Local Filesystemβ β Euler Finance β
β β β β β API β
β β’ Image storage β β β’ Legacy images β β β
β β’ Rich metadata β β β’ Auto migrationβ β β’ Token lists β
β β’ Global CDN β β β’ Backup/dev β β β’ Chain data β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ