Skip to main content

Testing & Development

Best practices for testing your integration with the Web3 Identity API.


Test Environmentโ€‹

Single Environment

The Web3 Identity API uses a single production environment with a generous free tier for testing. There's no separate sandbox โ€” the free 100 calls/day is your test quota.

Why No Sandbox?โ€‹

Traditional APIsWeb3 Identity API
Separate test/prod environmentsSingle environment
Test API keysNo keys needed
Fake test dataReal blockchain data
Complex setupZero config

Benefits:

  • Test against real data (ENS, Farcaster, prices)
  • No environment mismatches
  • No test key management
  • What works in testing works in production

Free Tier for Testingโ€‹

TierDaily LimitPer MinuteCost
Anonymous100 calls30Free
SIWE200 calls60Free

100 calls is plenty for:

  • Development iteration
  • Unit tests
  • Integration tests
  • CI/CD pipelines

Testing Strategiesโ€‹

1. Use Test Addressesโ€‹

Known addresses for consistent testing:

const TEST_DATA = {
// Well-known ENS names (always exist)
ensNames: [
'vitalik.eth', // Vitalik Buterin
'nick.eth', // Nick Johnson (ENS)
'brantly.eth', // Brantly Millegan
],

// Addresses with data
addresses: [
'0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', // vitalik.eth
'0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5', // nick.eth
],

// Farcaster users
farcaster: [
{ fid: 3, username: 'dwr.eth' }, // Dan Romero
{ fid: 2, username: 'v' }, // Varun
],

// Token symbols (always have prices)
tokens: ['ETH', 'BTC', 'USDC', 'USDT'],
};

2. Mock Responses in Testsโ€‹

Don't hit the API in unit tests โ€” mock responses:

// __mocks__/api.js
export const mockENSProfile = {
name: 'test.eth',
address: '0x1234...5678',
avatar: 'https://example.com/avatar.png',
records: {
twitter: 'testuser',
github: 'testuser',
},
};

// test.js
jest.mock('./api');
import { mockENSProfile } from './__mocks__/api';

test('displays ENS profile', () => {
// Use mock data instead of real API
render(<Profile data={mockENSProfile} />);
expect(screen.getByText('test.eth')).toBeInTheDocument();
});

3. Integration Tests with Real APIโ€‹

For integration tests, use the real API sparingly:

// integration.test.js
describe('API Integration', () => {
// Run only in CI or manually
const runIntegration = process.env.CI || process.env.RUN_INTEGRATION;

(runIntegration ? test : test.skip)('resolves ENS name', async () => {
const res = await fetch('https://api.web3identity.com/api/ens/resolve/vitalik.eth');
const data = await res.json();

expect(res.status).toBe(200);
expect(data.address).toMatch(/^0x/);
});
});

4. Rate Limit Awarenessโ€‹

// Helper to track API calls
class APITracker {
constructor(dailyLimit = 100) {
this.calls = 0;
this.limit = dailyLimit;
}

async fetch(url, opts) {
if (this.calls >= this.limit) {
throw new Error(`Daily limit (${this.limit}) exceeded`);
}
this.calls++;
console.log(`API call ${this.calls}/${this.limit}`);
return fetch(url, opts);
}

remaining() {
return this.limit - this.calls;
}
}

const api = new APITracker(100);

CI/CD Integrationโ€‹

GitHub Actions Exampleโ€‹

# .github/workflows/test.yml
name: Test
on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install dependencies
run: npm ci

- name: Run unit tests
run: npm test

- name: Run integration tests
run: npm run test:integration
env:
RUN_INTEGRATION: true
# Only runs ~10 API calls per push

Cache API Responsesโ€‹

// For development/testing, cache responses locally
import fs from 'fs';
import path from 'path';

const CACHE_DIR = '.api-cache';

async function cachedFetch(url) {
const cacheKey = Buffer.from(url).toString('base64');
const cachePath = path.join(CACHE_DIR, cacheKey);

// Return cached if exists and fresh
if (fs.existsSync(cachePath)) {
const cached = JSON.parse(fs.readFileSync(cachePath));
if (Date.now() - cached.timestamp < 3600000) { // 1 hour
console.log('[CACHE HIT]', url);
return cached.data;
}
}

// Fetch and cache
console.log('[CACHE MISS]', url);
const res = await fetch(url);
const data = await res.json();

fs.mkdirSync(CACHE_DIR, { recursive: true });
fs.writeFileSync(cachePath, JSON.stringify({
timestamp: Date.now(),
data,
}));

return data;
}

Local Developmentโ€‹

Environment Setupโ€‹

# .env.local (optional - not required for basic usage)
API_BASE_URL=https://api.web3identity.com

# If using SIWE for higher limits
WALLET_PRIVATE_KEY=0x... # Test wallet only!

Development Proxyโ€‹

For local development, proxy API calls to avoid CORS:

// next.config.js (Next.js)
module.exports = {
async rewrites() {
return [
{
source: '/api/proxy/:path*',
destination: 'https://api.web3identity.com/api/:path*',
},
];
},
};
// vite.config.js (Vite)
export default {
server: {
proxy: {
'/api': {
target: 'https://api.web3identity.com',
changeOrigin: true,
},
},
},
};

Testing x402 Paymentsโ€‹

Test Wallet Setupโ€‹

  1. Create test wallet โ€” New wallet for testing only
  2. Fund on Base โ€” Get Base ETH from faucet + small USDC
  3. Test small amounts โ€” Endpoints cost $0.001-$0.05
// Test payment flow
async function testPayment() {
// 1. Make request that triggers 402
const res = await fetch('https://api.web3identity.com/api/ens/vitalik.eth');

if (res.status === 402) {
const paymentDetails = await res.json();
console.log('Payment required:', paymentDetails);

// 2. Sign payment (using SDK)
const client = new ATVClient({ signer: wallet });
const data = await client.getProfile('vitalik.eth');

console.log('Payment successful, data:', data);
}
}

Monitor Test Spendingโ€‹

// Track spending in tests
let testSpending = 0;
const MAX_TEST_SPEND = 1.00; // $1 max for tests

async function paidFetch(url, price) {
if (testSpending + price > MAX_TEST_SPEND) {
throw new Error(`Test spending limit reached: $${testSpending}`);
}
testSpending += price;
// ... make paid request
}

Debugging Toolsโ€‹

Postman Collectionโ€‹

Import our Postman collection for interactive testing:

https://api.web3identity.com/postman/Web3-Identity-API.postman_collection.json

cURL Examplesโ€‹

# Quick health check
curl https://api.web3identity.com/api/health

# Test ENS resolution
curl https://api.web3identity.com/api/ens/resolve/vitalik.eth | jq

# Check your usage
curl https://api.web3identity.com/api/usage

# Verbose output for debugging
curl -v https://api.web3identity.com/api/price/ETH

Browser DevToolsโ€‹

// Paste in browser console to test
fetch('https://api.web3identity.com/api/ens/resolve/vitalik.eth')
.then(r => r.json())
.then(console.log);

Best Practices Summaryโ€‹

DoDon't
โœ… Mock responses in unit testsโŒ Hit real API in every test
โœ… Use well-known test addressesโŒ Use random addresses
โœ… Cache responses during developmentโŒ Make duplicate requests
โœ… Track API usage in CIโŒ Ignore rate limits
โœ… Test payment flow with small amountsโŒ Test with large sums
โœ… Use batch endpointsโŒ Make many individual calls

Need More Quota?โ€‹

For extensive testing needs:

  1. SIWE Authentication โ€” 2x daily limit (200 calls)
  2. API Key Credits โ€” Purchase credits for higher volume
  3. Contact us โ€” support@web3identity.com for enterprise testing needs