A Next.js-based Web3 resource management middleware layer that provides static configuration APIs for chains, wallets, and tokens. Supports multi-chain, multi-wallet, and multi-token configurations.
- Only deploy to Cloudflare Pages.
- Only use edge runtime for API routes.
edge runtime is required for Cloudflare Pages deployment. Node.js runtime is not supported. docs: https://nextjs.org/docs/app/api-reference/edge#unsupported-apis
- ✅ Multi-chain support with CAIP-2 format chainId (e.g.,
eip155:1) - ✅ Multi-wallet configuration
- ✅ Multi-token configuration with chain-specific organization
- ✅ RESTful API endpoints for querying configurations
- ✅ Filter by chainId support
- ✅ Cloudflare Workers deployment ready
- ✅ Organized directory structure for easy PR submissions
src/
├── assets/ # Configuration and icon files (follows proximity principle)
│ ├── chains/
│ │ └── eip155-1/
│ │ ├── index.ts # Chain configuration
│ │ └── icon.svg # Chain icon
│ ├── wallets/
│ │ └── metamask/
│ │ ├── index.ts # Wallet configuration
│ │ └── icon.svg # Wallet icon
│ └── tokens/
│ └── eip155-1/
│ └── 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48/ # Token directory (address lowercase)
│ ├── index.ts # Token configuration
│ └── icon.svg # Token icon
├── app/
│ └── api/
│ ├── chains/route.ts # GET /api/chains
│ ├── wallets/route.ts # GET /api/wallets
│ └── tokens/route.ts # GET /api/tokens
├── lib/
│ └── config-loader.ts # Configuration loading utilities
└── types/
├── chain.ts # Chain type definitions
├── wallet.ts # Wallet type definitions
└── token.ts # Token type definitions
GET /api/chainsResponse:
{
"success": true,
"data": [
{
"chainId": "eip155:1",
"name": "Ethereum",
"icon": "/_next/static/media/icon.XXXX.svg" // example URL
}
],
"count": 1
}GET /api/chains?chainId=eip155:1GET /api/walletsResponse:
{
"success": true,
"data": [
{
"id": "metamask",
"name": "MetaMask",
"icon": "/_next/static/media/icon.XXXX.svg" // example URL
}
],
"count": 1
}GET /api/tokensGET /api/tokens?chainId=eip155:1Response:
{
"success": true,
"data": [
{
"chainId": "eip155:1",
"address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"name": "USD Coin",
"symbol": "USDC",
"decimals": 6,
"icon": "/_next/static/media/icon.XXXX.svg" // example URL
}
],
"count": 1
}- Create directory:
src/assets/chains/eip155-{chainId}/ - Add
icon.svgin the same directory - Create
index.ts:
import type { ChainConfig } from "@/types/chain";
import iconUrl from "./icon.svg";
export const chainName: ChainConfig = {
chainId: "eip155:1",
name: "Chain Name",
icon: iconUrl,
};- Export in
src/assets/chains/index.ts:
export { chainName } from "./eip155-1";- Create directory:
src/assets/wallets/{wallet-id}/ - Add
icon.svgin the same directory - Create
index.ts:
import type { WalletConfig } from "@/types/wallet";
import iconUrl from "./icon.svg";
export const walletName: WalletConfig = {
id: "wallet-id",
name: "Wallet Name",
icon: iconUrl,
};- Export in
src/assets/wallets/index.ts
- Create directory:
src/assets/tokens/eip155-{chainId}/{address-lowercase}/- Example:
src/assets/tokens/eip155-1/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48/
- Example:
- Add
icon.svgin the same directory - Create
index.ts:
import type { TokenConfig } from "@/types/token";
import iconUrl from "./icon.svg";
export const tokenName: TokenConfig = {
chainId: "eip155:1",
address: "0x...", // lowercase
name: "Token Name",
symbol: "SYMBOL",
decimals: 18,
icon: iconUrl,
};- Export in
src/assets/tokens/eip155-{chainId}/index.ts
# Install dependencies
pnpm install
# Run development server
pnpm dev
# Build for production
pnpm build
# Preview with Cloudflare adapter
pnpm preview
# Deploy to Cloudflare Workers
pnpm deployThis project is configured for deployment to Cloudflare Workers using the OpenNext adapter.
wrangler.jsonc- Cloudflare Workers configurationopen-next.config.ts- OpenNext adapter configuration
The build process:
- Next.js Turbopack automatically processes SVG imports as static assets
- Builds the Next.js application with all assets bundled
- Prepares for Cloudflare Workers deployment via OpenNext adapter
Note: Icons are imported directly in configuration files using ES6 import syntax (e.g., import iconUrl from './icon.svg'). Next.js Turbopack handles the asset processing and URL generation automatically - no additional configuration needed.
This project is designed so that all sensitive deployment information is provided via environment variables, not hard-coded in the repository.
-
Next.js environment variables
- Use
.env.localfor local development (never commit this file). - Use
NEXT_PUBLIC_*variables only for non-sensitive values that can be exposed to the browser. - Server-only secrets (API keys, private endpoints, etc.) should be plain (non-
NEXT_PUBLIC_) variables and accessed viaprocess.env.MY_SECRET.
- Use
-
Cloudflare Workers secrets
- Configure secrets using
wrangler(for example:wrangler secret put MY_SECRET). - Reference them in Workers runtime via the environment bindings configured in
wrangler.jsonc/wrangler.toml. - Do not commit any secret values to Git; only commit the names and usage in code.
- Configure secrets using
When adding new chains, wallets, or tokens that require external services (RPC endpoints, indexer APIs, etc.), always:
- Put sensitive URLs/keys into environment variables.
- Reference them from code via
process.envor Cloudflare env bindings.
This project uses the CAIP-2 (Chain Agnostic Improvement Proposal) format for chainId:
- Format:
{namespace}:{reference} - Example:
eip155:1(Ethereum Mainnet) - Reference: https://chainagnostic.org/
MIT