Code Examples
Complete, runnable examples for different languages and use cases.
Quick Reference
Base URL
https://api.web3identity.com
Common Endpoints
| Endpoint | Description |
|---|---|
/api/ens/resolve/{name} | Resolve ENS to address |
/api/ens/{name} | Full ENS profile |
/api/ens/avatar/{name} | Avatar URL |
/api/ens/reverse/{address} | Address to ENS |
/api/farcaster/{identifier} | Farcaster profile |
/api/price/{symbol} | Token price |
/api/price/batch | Multiple prices |
JavaScript / Node.js
Basic ENS Resolution
// ens-resolve.mjs
const BASE_URL = 'https://api.web3identity.com';
// Simple address lookup
async function resolveENS(name) {
const response = await fetch(`${BASE_URL}/api/ens/resolve/${name}`);
if (!response.ok) throw new Error(`Failed: ${response.status}`);
return response.json();
}
// Full profile with records
async function getENSProfile(name) {
const response = await fetch(`${BASE_URL}/api/ens/${name}`);
if (!response.ok) throw new Error(`Failed: ${response.status}`);
return response.json();
}
// Reverse lookup (address → ENS)
async function reverseResolve(address) {
const response = await fetch(`${BASE_URL}/api/ens/reverse/${address}`);
if (!response.ok) return null; // No ENS set
return response.json();
}
// Usage
const result = await resolveENS('vitalik.eth');
console.log(result);
// { name: "vitalik.eth", address: "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" }
const profile = await getENSProfile('vitalik.eth');
console.log(profile.records.twitter); // "VitalikButerin"
const reverse = await reverseResolve('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');
console.log(reverse?.name); // "vitalik.eth"
Batch ENS Resolution
// batch-ens.mjs
const BASE_URL = 'https://api.web3identity.com';
async function batchResolve(names) {
const response = await fetch(
`${BASE_URL}/api/ens/batch?names=${names.join(',')}`
);
return response.json();
}
// Resolve multiple names in one request
const results = await batchResolve([
'vitalik.eth',
'nick.eth',
'brantly.eth',
'dwr.eth'
]);
console.log(results);
// {
// results: [
// { name: "vitalik.eth", address: "0xd8dA..." },
// { name: "nick.eth", address: "0xb8c2..." },
// ...
// ],
// count: 4
// }
Farcaster Integration
// farcaster.mjs
const BASE_URL = 'https://api.web3identity.com';
// Get user by username, FID, or connected address
async function getFarcasterUser(identifier) {
const response = await fetch(`${BASE_URL}/api/farcaster/${identifier}`);
if (!response.ok) throw new Error(`User not found: ${identifier}`);
return response.json();
}
// Get user's recent casts
async function getUserCasts(fid, limit = 10) {
const response = await fetch(
`${BASE_URL}/api/farcaster/${fid}/casts?limit=${limit}`
);
return response.json();
}
// Usage
const user = await getFarcasterUser('dwr.eth');
console.log(`${user.displayName} (@${user.username})`);
console.log(`Followers: ${user.followers.toLocaleString()}`);
const casts = await getUserCasts(user.fid, 5);
casts.casts.forEach(cast => {
console.log(`- ${cast.text.slice(0, 50)}...`);
});
Token Prices
// prices.mjs
const BASE_URL = 'https://api.web3identity.com';
// Single price
async function getPrice(symbol) {
const response = await fetch(`${BASE_URL}/api/price/${symbol}`);
return response.json();
}
// Multiple prices in one request
async function getBatchPrices(symbols) {
const response = await fetch(
`${BASE_URL}/api/price/batch?symbols=${symbols.join(',')}`
);
return response.json();
}
// Usage
const eth = await getPrice('ETH');
console.log(`ETH: $${eth.price.toFixed(2)}`);
const prices = await getBatchPrices(['ETH', 'BTC', 'USDC', 'ARB', 'OP']);
prices.forEach(p => {
console.log(`${p.symbol}: $${p.price.toFixed(2)} (${p.change24h > 0 ? '+' : ''}${p.change24h.toFixed(2)}%)`);
});
With x402 Payment Handling
// x402-fetch.mjs
import { createWalletClient, http, parseUnits } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base } from 'viem/chains';
const BASE_URL = 'https://api.web3identity.com';
async function fetchWithPayment(endpoint, wallet) {
let response = await fetch(`${BASE_URL}${endpoint}`);
if (response.status === 402) {
const paymentInfo = await response.json();
console.log(`Payment required: $${paymentInfo.priceUSD}`);
// Create payment authorization
const nonce = '0x' + [...crypto.getRandomValues(new Uint8Array(32))]
.map(b => b.toString(16).padStart(2, '0')).join('');
const signature = await wallet.signTypedData({
domain: {
name: 'USD Coin',
version: '2',
chainId: 8453,
verifyingContract: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
},
types: {
TransferWithAuthorization: [
{ name: 'from', type: 'address' },
{ name: 'to', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'validAfter', type: 'uint256' },
{ name: 'validBefore', type: 'uint256' },
{ name: 'nonce', type: 'bytes32' },
],
},
primaryType: 'TransferWithAuthorization',
message: {
from: wallet.account.address,
to: paymentInfo.recipient,
value: parseUnits(paymentInfo.priceUSD.toString(), 6),
validAfter: 0n,
validBefore: BigInt(Math.floor(Date.now() / 1000) + 300),
nonce,
},
});
const paymentHeader = btoa(JSON.stringify({ signature }));
response = await fetch(`${BASE_URL}${endpoint}`, {
headers: {
'x-payment': paymentHeader,
'payment-signature': paymentHeader,
},
});
}
return response.json();
}
// Usage
const account = privateKeyToAccount(process.env.WALLET_KEY);
const wallet = createWalletClient({
account,
chain: base,
transport: http(),
});
const profile = await fetchWithPayment('/api/ens/resolve/vitalik.eth', wallet);
cURL
Basic Requests
#!/bin/bash
# basic-requests.sh
BASE_URL="https://api.web3identity.com"
# ENS Resolution
echo "=== ENS Resolution ==="
curl -s "$BASE_URL/api/ens/resolve/vitalik.eth" | jq
# Full ENS Profile
echo -e "\n=== Full ENS Profile ==="
curl -s "$BASE_URL/api/ens/vitalik.eth" | jq '{
name: .name,
address: .address,
avatar: .avatar,
twitter: .records.twitter,
github: .records.github
}'
# Reverse Lookup
echo -e "\n=== Reverse Lookup ==="
curl -s "$BASE_URL/api/ens/reverse/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045" | jq
# Batch Resolution
echo -e "\n=== Batch Resolution ==="
curl -s "$BASE_URL/api/ens/batch?names=vitalik.eth,nick.eth,brantly.eth" | jq
Farcaster Examples
#!/bin/bash
# farcaster.sh
BASE_URL="https://api.web3identity.com"
# Get user by username
echo "=== Farcaster User ==="
curl -s "$BASE_URL/api/farcaster/dwr.eth" | jq '{
fid: .fid,
username: .username,
displayName: .displayName,
followers: .followers,
bio: .bio
}'
# Get user's casts
echo -e "\n=== Recent Casts ==="
curl -s "$BASE_URL/api/farcaster/3/casts?limit=5" | jq '.casts[] | {
text: .text[0:80],
likes: .likes,
recasts: .recasts
}'
# Search users
echo -e "\n=== Search Users ==="
curl -s "$BASE_URL/api/farcaster/search?q=ethereum&type=users&limit=5" | jq
Token Prices
#!/bin/bash
# prices.sh
BASE_URL="https://api.web3identity.com"
# Single price
echo "=== ETH Price ==="
curl -s "$BASE_URL/api/price/ETH" | jq '{
symbol: .symbol,
price: .price,
change24h: .change24h
}'
# Batch prices
echo -e "\n=== Batch Prices ==="
curl -s "$BASE_URL/api/price/batch?symbols=ETH,BTC,SOL,ARB,OP,USDC" | jq '.[] | "\(.symbol): $\(.price)"'
# Trending tokens
echo -e "\n=== Trending ==="
curl -s "$BASE_URL/api/market/trending?limit=10" | jq
Health Check
#!/bin/bash
# health.sh
BASE_URL="https://api.web3identity.com"
# API Health
curl -s "$BASE_URL/api/health" | jq
# Data sources health
curl -s "$BASE_URL/api/sources/health" | jq
Python
Complete Client Class
#!/usr/bin/env python3
"""
Web3 Identity API Client for Python
"""
import requests
from typing import Optional, List, Dict, Any
from dataclasses import dataclass
@dataclass
class ENSProfile:
name: str
address: str
avatar: Optional[str] = None
records: Dict[str, Any] = None
expiration: Optional[str] = None
class Web3IdentityClient:
"""Client for the Web3 Identity API."""
BASE_URL = "https://api.web3identity.com"
def __init__(self, api_key: Optional[str] = None):
self.session = requests.Session()
if api_key:
self.session.headers['Authorization'] = f'Bearer {api_key}'
def _get(self, endpoint: str, params: Dict = None) -> Dict:
"""Make a GET request."""
response = self.session.get(f"{self.BASE_URL}{endpoint}", params=params)
response.raise_for_status()
return response.json()
# ENS Methods
def resolve_ens(self, name: str) -> Dict:
"""Resolve ENS name to address."""
return self._get(f"/api/ens/resolve/{name}")
def get_ens_profile(self, name: str) -> ENSProfile:
"""Get full ENS profile."""
data = self._get(f"/api/ens/{name}")
return ENSProfile(
name=data['name'],
address=data['address'],
avatar=data.get('avatar'),
records=data.get('records', {}),
expiration=data.get('expiration')
)
def reverse_resolve(self, address: str) -> Optional[str]:
"""Get ENS name for address."""
try:
data = self._get(f"/api/ens/reverse/{address}")
return data.get('name')
except requests.HTTPError as e:
if e.response.status_code == 404:
return None
raise
def batch_resolve(self, names: List[str]) -> List[Dict]:
"""Resolve multiple ENS names."""
data = self._get("/api/ens/batch", params={"names": ",".join(names)})
return data['results']
def get_avatar(self, name: str) -> Optional[str]:
"""Get avatar URL for ENS name."""
data = self._get(f"/api/ens/avatar/{name}")
return data.get('avatar')
# Farcaster Methods
def get_farcaster_user(self, identifier: str) -> Dict:
"""Get Farcaster user by username, FID, or address."""
return self._get(f"/api/farcaster/{identifier}")
def get_farcaster_casts(self, fid: int, limit: int = 25) -> List[Dict]:
"""Get user's casts."""
data = self._get(f"/api/farcaster/{fid}/casts", params={"limit": limit})
return data['casts']
def get_farcaster_followers(self, fid: int, limit: int = 100) -> Dict:
"""Get user's followers."""
return self._get(f"/api/farcaster/{fid}/followers", params={"limit": limit})
# Price Methods
def get_price(self, symbol: str) -> Dict:
"""Get token price."""
return self._get(f"/api/price/{symbol}")
def get_prices(self, symbols: List[str]) -> List[Dict]:
"""Get multiple token prices."""
return self._get("/api/price/batch", params={"symbols": ",".join(symbols)})
def get_trending(self, limit: int = 10) -> List[Dict]:
"""Get trending tokens."""
return self._get("/api/market/trending", params={"limit": limit})
# Usage Example
if __name__ == "__main__":
client = Web3IdentityClient()
# ENS Resolution
print("=== ENS Resolution ===")
result = client.resolve_ens("vitalik.eth")
print(f"Address: {result['address']}")
# Full Profile
print("\n=== ENS Profile ===")
profile = client.get_ens_profile("vitalik.eth")
print(f"Name: {profile.name}")
print(f"Twitter: {profile.records.get('twitter')}")
print(f"GitHub: {profile.records.get('github')}")
# Reverse Lookup
print("\n=== Reverse Lookup ===")
name = client.reverse_resolve("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
print(f"ENS: {name}")
# Batch
print("\n=== Batch Resolution ===")
results = client.batch_resolve(["vitalik.eth", "nick.eth", "brantly.eth"])
for r in results:
print(f" {r['name']}: {r['address'][:10]}...")
# Farcaster
print("\n=== Farcaster ===")
user = client.get_farcaster_user("dwr.eth")
print(f"{user['displayName']} (@{user['username']})")
print(f"Followers: {user['followers']:,}")
# Prices
print("\n=== Token Prices ===")
prices = client.get_prices(["ETH", "BTC", "USDC"])
for p in prices:
print(f"{p['symbol']}: ${p['price']:,.2f}")
Async Python Client
#!/usr/bin/env python3
"""
Async Web3 Identity API Client
"""
import asyncio
import aiohttp
from typing import Optional, List, Dict
class AsyncWeb3IdentityClient:
"""Async client for the Web3 Identity API."""
BASE_URL = "https://api.web3identity.com"
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key
self._session: Optional[aiohttp.ClientSession] = None
async def _get_session(self) -> aiohttp.ClientSession:
if self._session is None or self._session.closed:
headers = {}
if self.api_key:
headers['Authorization'] = f'Bearer {self.api_key}'
self._session = aiohttp.ClientSession(headers=headers)
return self._session
async def close(self):
if self._session and not self._session.closed:
await self._session.close()
async def _get(self, endpoint: str, params: Dict = None) -> Dict:
session = await self._get_session()
async with session.get(f"{self.BASE_URL}{endpoint}", params=params) as resp:
resp.raise_for_status()
return await resp.json()
async def resolve_ens(self, name: str) -> Dict:
return await self._get(f"/api/ens/resolve/{name}")
async def batch_resolve(self, names: List[str]) -> List[Dict]:
data = await self._get("/api/ens/batch", params={"names": ",".join(names)})
return data['results']
async def get_farcaster_user(self, identifier: str) -> Dict:
return await self._get(f"/api/farcaster/{identifier}")
async def get_prices(self, symbols: List[str]) -> List[Dict]:
return await self._get("/api/price/batch", params={"symbols": ",".join(symbols)})
async def main():
client = AsyncWeb3IdentityClient()
try:
# Parallel requests
results = await asyncio.gather(
client.resolve_ens("vitalik.eth"),
client.resolve_ens("nick.eth"),
client.get_farcaster_user("dwr.eth"),
client.get_prices(["ETH", "BTC"]),
)
print("Vitalik:", results[0]['address'])
print("Nick:", results[1]['address'])
print("Dan Romero:", results[2]['displayName'])
print("Prices:", [(p['symbol'], p['price']) for p in results[3]])
finally:
await client.close()
if __name__ == "__main__":
asyncio.run(main())
TypeScript
Type-Safe Client
// web3identity-client.ts
const BASE_URL = 'https://api.web3identity.com';
// Types
interface ENSResolution {
name: string;
address: string;
}
interface ENSProfile {
name: string;
address: string;
avatar: string | null;
contentHash: string | null;
records: {
twitter?: string;
github?: string;
url?: string;
description?: string;
email?: string;
'com.discord'?: string;
};
expiration?: string;
registrant?: string;
controller?: string;
resolver?: string;
}
interface FarcasterUser {
fid: number;
username: string;
displayName: string;
bio: string;
pfp: string;
followers: number;
following: number;
verifications: string[];
activeStatus: string;
registeredAt: string;
}
interface FarcasterCast {
hash: string;
text: string;
timestamp: string;
likes: number;
recasts: number;
replies: number;
embeds: any[];
}
interface TokenPrice {
symbol: string;
price: number;
change24h: number;
volume24h?: number;
marketCap?: number;
}
// Client
class Web3IdentityClient {
private baseUrl: string;
private apiKey?: string;
constructor(options: { apiKey?: string; baseUrl?: string } = {}) {
this.baseUrl = options.baseUrl || BASE_URL;
this.apiKey = options.apiKey;
}
private async fetch<T>(endpoint: string, params?: Record<string, string>): Promise<T> {
const url = new URL(`${this.baseUrl}${endpoint}`);
if (params) {
Object.entries(params).forEach(([key, value]) => {
url.searchParams.set(key, value);
});
}
const headers: Record<string, string> = {};
if (this.apiKey) {
headers['Authorization'] = `Bearer ${this.apiKey}`;
}
const response = await fetch(url.toString(), { headers });
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.message || `HTTP ${response.status}`);
}
return response.json();
}
// ENS Methods
async resolveENS(name: string): Promise<ENSResolution> {
return this.fetch(`/api/ens/resolve/${name}`);
}
async getENSProfile(name: string): Promise<ENSProfile> {
return this.fetch(`/api/ens/${name}`);
}
async reverseResolve(address: string): Promise<{ name: string } | null> {
try {
return await this.fetch(`/api/ens/reverse/${address}`);
} catch {
return null;
}
}
async batchResolve(names: string[]): Promise<{ results: ENSResolution[]; count: number }> {
return this.fetch('/api/ens/batch', { names: names.join(',') });
}
async getAvatar(name: string): Promise<{ avatar: string; type: string }> {
return this.fetch(`/api/ens/avatar/${name}`);
}
// Farcaster Methods
async getFarcasterUser(identifier: string | number): Promise<FarcasterUser> {
return this.fetch(`/api/farcaster/${identifier}`);
}
async getFarcasterCasts(fid: number, limit = 25): Promise<{ casts: FarcasterCast[] }> {
return this.fetch(`/api/farcaster/${fid}/casts`, { limit: limit.toString() });
}
async getFarcasterFollowers(fid: number, limit = 100): Promise<{ users: FarcasterUser[] }> {
return this.fetch(`/api/farcaster/${fid}/followers`, { limit: limit.toString() });
}
// Price Methods
async getPrice(symbol: string): Promise<TokenPrice> {
return this.fetch(`/api/price/${symbol}`);
}
async getBatchPrices(symbols: string[]): Promise<TokenPrice[]> {
return this.fetch('/api/price/batch', { symbols: symbols.join(',') });
}
async getTrending(limit = 10): Promise<TokenPrice[]> {
return this.fetch('/api/market/trending', { limit: limit.toString() });
}
}
// Usage
const client = new Web3IdentityClient();
async function main() {
// ENS
const profile = await client.getENSProfile('vitalik.eth');
console.log(`Twitter: @${profile.records.twitter}`);
// Farcaster
const user = await client.getFarcasterUser('dwr.eth');
console.log(`${user.displayName}: ${user.followers.toLocaleString()} followers`);
// Prices
const prices = await client.getBatchPrices(['ETH', 'BTC', 'SOL']);
prices.forEach(p => console.log(`${p.symbol}: $${p.price.toFixed(2)}`));
}
main();
React Hooks
useENS Hook
// hooks/useENS.ts
import { useState, useEffect } from 'react';
const BASE_URL = 'https://api.web3identity.com';
interface ENSProfile {
name: string;
address: string;
avatar: string | null;
records: Record<string, string>;
}
interface UseENSResult {
profile: ENSProfile | null;
loading: boolean;
error: string | null;
refetch: () => void;
}
export function useENS(nameOrAddress: string | null): UseENSResult {
const [profile, setProfile] = useState<ENSProfile | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const isAddress = nameOrAddress?.startsWith('0x');
const fetchProfile = async () => {
if (!nameOrAddress) {
setProfile(null);
return;
}
setLoading(true);
setError(null);
try {
let endpoint: string;
if (isAddress) {
// Reverse resolve first
const reverseRes = await fetch(`${BASE_URL}/api/ens/reverse/${nameOrAddress}`);
if (!reverseRes.ok) {
setProfile({ name: '', address: nameOrAddress, avatar: null, records: {} });
return;
}
const { name } = await reverseRes.json();
endpoint = `/api/ens/${name}`;
} else {
endpoint = `/api/ens/${nameOrAddress}`;
}
const response = await fetch(`${BASE_URL}${endpoint}`);
if (!response.ok) {
throw new Error(response.status === 404 ? 'ENS not found' : 'Failed to fetch');
}
const data = await response.json();
setProfile({
name: data.name,
address: data.address,
avatar: data.avatar,
records: data.records || {},
});
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
setProfile(null);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchProfile();
}, [nameOrAddress]);
return { profile, loading, error, refetch: fetchProfile };
}
// Usage
function ProfileCard({ ensName }: { ensName: string }) {
const { profile, loading, error } = useENS(ensName);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!profile) return null;
return (
<div className="profile-card">
<img src={profile.avatar || '/default-avatar.png'} alt={profile.name} />
<h2>{profile.name}</h2>
<p>{profile.address.slice(0, 6)}...{profile.address.slice(-4)}</p>
{profile.records.twitter && (
<a href={`https://twitter.com/${profile.records.twitter}`}>
@{profile.records.twitter}
</a>
)}
</div>
);
}
useFarcaster Hook
// hooks/useFarcaster.ts
import { useState, useEffect } from 'react';
const BASE_URL = 'https://api.web3identity.com';
interface FarcasterUser {
fid: number;
username: string;
displayName: string;
bio: string;
pfp: string;
followers: number;
following: number;
}
export function useFarcaster(identifier: string | null) {
const [user, setUser] = useState<FarcasterUser | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
if (!identifier) {
setUser(null);
return;
}
setLoading(true);
setError(null);
fetch(`${BASE_URL}/api/farcaster/${identifier}`)
.then(res => {
if (!res.ok) throw new Error('User not found');
return res.json();
})
.then(setUser)
.catch(err => setError(err.message))
.finally(() => setLoading(false));
}, [identifier]);
return { user, loading, error };
}
useTokenPrice Hook
// hooks/useTokenPrice.ts
import { useState, useEffect } from 'react';
const BASE_URL = 'https://api.web3identity.com';
interface TokenPrice {
symbol: string;
price: number;
change24h: number;
}
export function useTokenPrice(symbol: string | null, refreshInterval = 0) {
const [price, setPrice] = useState<TokenPrice | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
if (!symbol) {
setPrice(null);
return;
}
const fetchPrice = async () => {
setLoading(true);
try {
const res = await fetch(`${BASE_URL}/api/price/${symbol}`);
if (!res.ok) throw new Error('Price not found');
setPrice(await res.json());
setError(null);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed');
} finally {
setLoading(false);
}
};
fetchPrice();
if (refreshInterval > 0) {
const interval = setInterval(fetchPrice, refreshInterval);
return () => clearInterval(interval);
}
}, [symbol, refreshInterval]);
return { price, loading, error };
}
// Usage - auto-refresh every 30 seconds
function PriceTicker({ symbol }: { symbol: string }) {
const { price, loading } = useTokenPrice(symbol, 30000);
if (loading && !price) return <span>Loading...</span>;
if (!price) return null;
return (
<span className={price.change24h >= 0 ? 'green' : 'red'}>
{symbol}: ${price.price.toFixed(2)} ({price.change24h > 0 ? '+' : ''}{price.change24h.toFixed(2)}%)
</span>
);
}
Real-World Examples
Web3 Profile Aggregator
Combine ENS + Farcaster for complete profiles:
// profile-aggregator.mjs
const BASE_URL = 'https://api.web3identity.com';
async function getAggregatedProfile(identifier) {
// Normalize identifier
const isAddress = identifier.startsWith('0x');
const isENS = identifier.includes('.eth') || identifier.includes('.xyz');
let address = isAddress ? identifier : null;
let ensName = isENS ? identifier : null;
// Step 1: Resolve address/name
if (isAddress) {
const reverse = await fetch(`${BASE_URL}/api/ens/reverse/${identifier}`).then(r => r.ok ? r.json() : null);
ensName = reverse?.name;
} else if (isENS) {
const resolve = await fetch(`${BASE_URL}/api/ens/resolve/${identifier}`).then(r => r.json());
address = resolve.address;
}
// Step 2: Fetch all data in parallel
const [ensProfile, farcasterProfile] = await Promise.allSettled([
ensName ? fetch(`${BASE_URL}/api/ens/${ensName}`).then(r => r.json()) : null,
address ? fetch(`${BASE_URL}/api/farcaster/${address}`).then(r => r.ok ? r.json() : null) : null,
]);
// Step 3: Merge profiles
const ens = ensProfile.status === 'fulfilled' ? ensProfile.value : null;
const farcaster = farcasterProfile.status === 'fulfilled' ? farcasterProfile.value : null;
return {
address,
// Primary identity
primaryName: ensName || farcaster?.username || address?.slice(0, 10),
// ENS data
ens: ens ? {
name: ens.name,
avatar: ens.avatar,
description: ens.records?.description,
twitter: ens.records?.twitter,
github: ens.records?.github,
url: ens.records?.url,
} : null,
// Farcaster data
farcaster: farcaster ? {
fid: farcaster.fid,
username: farcaster.username,
displayName: farcaster.displayName,
bio: farcaster.bio,
pfp: farcaster.pfp,
followers: farcaster.followers,
} : null,
// Merged avatar (ENS preferred)
avatar: ens?.avatar || farcaster?.pfp || null,
// Merged bio
bio: ens?.records?.description || farcaster?.bio || null,
};
}
// Usage
const profile = await getAggregatedProfile('vitalik.eth');
console.log(JSON.stringify(profile, null, 2));
Portfolio Dashboard
// portfolio.mjs
const BASE_URL = 'https://api.web3identity.com';
async function getPortfolioData(address) {
// Get ENS name
const ensRes = await fetch(`${BASE_URL}/api/ens/reverse/${address}`);
const ensName = ensRes.ok ? (await ensRes.json()).name : null;
// Get wallet balances
const balancesRes = await fetch(`${BASE_URL}/api/wallet/${address}/balances`);
const balances = balancesRes.ok ? await balancesRes.json() : { tokens: [] };
// Get current prices for held tokens
const symbols = balances.tokens.map(t => t.symbol).filter(Boolean);
const pricesRes = await fetch(`${BASE_URL}/api/price/batch?symbols=${symbols.join(',')}`);
const prices = pricesRes.ok ? await pricesRes.json() : [];
// Calculate portfolio value
const priceMap = Object.fromEntries(prices.map(p => [p.symbol, p.price]));
const portfolio = balances.tokens.map(token => ({
symbol: token.symbol,
balance: token.balance,
price: priceMap[token.symbol] || 0,
value: token.balance * (priceMap[token.symbol] || 0),
}));
const totalValue = portfolio.reduce((sum, t) => sum + t.value, 0);
return {
address,
ensName,
totalValue,
tokens: portfolio.sort((a, b) => b.value - a.value),
};
}
Discord Bot Integration
// discord-bot.mjs
import { Client, GatewayIntentBits, EmbedBuilder } from 'discord.js';
const BASE_URL = 'https://api.web3identity.com';
const client = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.MessageContent] });
client.on('messageCreate', async (message) => {
if (message.content.startsWith('!ens ')) {
const name = message.content.slice(5).trim();
try {
const res = await fetch(`${BASE_URL}/api/ens/${name}`);
if (!res.ok) {
await message.reply(`❌ ENS name "${name}" not found`);
return;
}
const profile = await res.json();
const embed = new EmbedBuilder()
.setTitle(profile.name)
.setDescription(profile.records?.description || 'No description')
.setThumbnail(profile.avatar)
.addFields(
{ name: 'Address', value: `\`${profile.address}\``, inline: false },
{ name: 'Twitter', value: profile.records?.twitter ? `@${profile.records.twitter}` : 'Not set', inline: true },
{ name: 'GitHub', value: profile.records?.github || 'Not set', inline: true },
)
.setColor(0x5865F2);
await message.reply({ embeds: [embed] });
} catch (err) {
await message.reply(`❌ Error: ${err.message}`);
}
}
});
client.login(process.env.DISCORD_TOKEN);
Download Examples
Full example files available:
Related
- Tutorials — Step-by-step guides
- SDK Documentation — Official SDK
- API Reference — Full API docs