Spaces:
Runtime error
Create AfricaCryptoChainx
// accx-blockchain-explorer
// Routes: api.africacryptochainx.com/*
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Content-Type": "application/json"
};
// Blockchain API endpoints
const PROVIDERS = {
ethereum: "https://eth-mainnet.g.alchemy.com/v2/demo",
bsc: "https://bsc-dataseed.binance.org",
polygon: "https://polygon-rpc.com",
bitcoin: "https://blockchain.info"
};
export default {
async fetch(request, env, ctx) {
if (request.method === "OPTIONS") {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
const url = new URL(request.url);
const path = url.pathname;
try {
// Health check
if (path === "/" || path === "/health") {
return jsonResponse({ status: "ok", service: "ACCX Blockchain Explorer", timestamp: new Date().toISOString() });
}
// === ETHEREUM ===
if (path === "/eth/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address required");
const res = await fetch(PROVIDERS.ethereum, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
});
const data = await res.json();
return jsonResponse({ address, balanceWei: data.result, balanceEth: parseInt(data.result, 16) / 1e18 });
}
if (path === "/eth/gas") {
const res = await fetch(PROVIDERS.ethereum, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_gasPrice", params: [] })
});
const data = await res.json();
return jsonResponse({ gasPriceWei: data.result, gasPriceGwei: parseInt(data.result, 16) / 1e9 });
}
if (path === "/eth/block") {
const res = await fetch(PROVIDERS.ethereum, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_blockNumber", params: [] })
});
const data = await res.json();
return jsonResponse({ blockHeight: parseInt(data.result, 16) });
}
// === BSC ===
if (path === "/bsc/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address required");
const res = await fetch(PROVIDERS.bsc, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
});
const data = await res.json();
return jsonResponse({ address, balanceWei: data.result, balanceBnb: parseInt(data.result, 16) / 1e18 });
}
if (path === "/bsc/gas") {
const res = await fetch(PROVIDERS.bsc, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_gasPrice", params: [] })
});
const data = await res.json();
return jsonResponse({ gasPriceWei: data.result, gasPriceGwei: parseInt(data.result, 16) / 1e9 });
}
// === POLYGON ===
if (path === "/polygon/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address required");
const res = await fetch(PROVIDERS.polygon, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
});
const data = await res.json();
return jsonResponse({ address, balanceWei: data.result, balanceMatic: parseInt(data.result, 16) / 1e18 });
}
// === BITCOIN ===
if (path === "/btc/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address required");
const res = await fetch(`${PROVIDERS.bitcoin}/rawaddr/${address}`);
const data = await res.json();
return jsonResponse({ address, balanceSatoshi: data.final_balance, balanceBtc: data.final_balance / 1e8, txs: data.n_tx });
}
if (path === "/btc/block") {
const res = await fetch(`${PROVIDERS.bitcoin}/latestblock`);
const data = await res.json();
return jsonResponse({ blockHeight: data.height, hash: data.hash, time: data.time });
}
// === CRYPTO PRICES ===
if (path === "/prices") {
const symbols = url.searchParams.get("symbols") || "bitcoin,ethereum,binancecoin,polygon";
const currency = url.searchParams.get("currency") || "usd";
const res = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${symbols}&vs_currencies=${currency},eur,ngn`);
const data = await res.json();
return jsonResponse(data);
}
// 404
return errorResponse("Endpoint not found. Try: /eth/balance?address=0x..., /eth/gas, /eth/block, /bsc/balance, /bsc/gas, /polygon/balance, /btc/balance, /btc/block, /prices", 404);
} catch (err) {
return errorResponse(err.message, 500);
}
}
};
function jsonResponse(data) {
return new Response(JSON.stringify(data, null, 2), { status: 200, headers: CORS_HEADERS });
}
function errorResponse(message, status = 400) {
return new Response(JSON.stringify({ error: message }, null, 2), { status, headers: CORS_HEADERS });
}
// ============================================================
// ACCX Blockchain Explorer Worker
// AfricaCryptoChainx (ACCX) Ecosystem
// Routes: api.africacryptochainx.com/*
// Network: BSC Mainnet (Chain 56)
// Token: 0xae6C2FEA44a07022177B3481B45412A2800487b5
// ============================================================
// CORS headers for cross-origin requests from dashboard
const CORS_HEADERS = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Content-Type": "application/json"
};
// Blockchain RPC endpoints and API providers
const PROVIDERS = {
ethereum: "https://eth-mainnet.g.alchemy.com/v2/demo", // Replace with actual API key
bsc: "https://bsc-dataseed.binance.org", // BNB Smart Chain
polygon: "https://polygon-rpc.com", // Polygon (Matic)
bitcoin: "https://blockchain.info" // Bitcoin explorer
};
export default {
async fetch(request, env, ctx) {
// Handle CORS preflight requests
if (request.method === "OPTIONS") {
return new Response(null, { status: 204, headers: CORS_HEADERS });
}
const url = new URL(request.url);
const path = url.pathname;
try {
// Health check endpoint
if (path === "/" || path === "/health") {
return jsonResponse({
status: "ok",
service: "ACCX Blockchain Explorer",
network: "BSC Mainnet (56)",
token: "0xae6C2FEA44a07022177B3481B45412A2800487b5",
timestamp: new Date().toISOString()
});
}
// ==================== ETHEREUM ====================
// GET /eth/balance?address=0x...
if (path === "/eth/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address parameter required");
const res = await fetch(PROVIDERS.ethereum, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
});
const data = await res.json();
return jsonResponse({
address,
balanceWei: data.result,
balanceEth: parseInt(data.result, 16) / 1e18
});
}
// GET /eth/gas - Current gas price
if (path === "/eth/gas") {
const res = await fetch(PROVIDERS.ethereum, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_gasPrice", params: [] })
});
const data = await res.json();
return jsonResponse({
gasPriceWei: data.result,
gasPriceGwei: parseInt(data.result, 16) / 1e9
});
}
// GET /eth/block - Current block number
if (path === "/eth/block") {
const res = await fetch(PROVIDERS.ethereum, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_blockNumber", params: [] })
});
const data = await res.json();
return jsonResponse({ blockHeight: parseInt(data.result, 16) });
}
// ==================== BSC (BNB Smart Chain) ====================
// GET /bsc/balance?address=0x...
if (path === "/bsc/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address parameter required");
const res = await fetch(PROVIDERS.bsc, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
});
const data = await res.json();
return jsonResponse({
address,
balanceWei: data.result,
balanceBnb: parseInt(data.result, 16) / 1e18
});
}
// GET /bsc/gas - BSC gas price
if (path === "/bsc/gas") {
const res = await fetch(PROVIDERS.bsc, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_gasPrice", params: [] })
});
const data = await res.json();
return jsonResponse({
gasPriceWei: data.result,
gasPriceGwei: parseInt(data.result, 16) / 1e9
});
}
// ==================== POLYGON ====================
// GET /polygon/balance?address=0x...
if (path === "/polygon/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address parameter required");
const res = await fetch(PROVIDERS.polygon, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
});
const data = await res.json();
return jsonResponse({
address,
balanceWei: data.result,
balanceMatic: parseInt(data.result, 16) / 1e18
});
}
// ==================== BITCOIN ====================
// GET /btc/balance?address=...
if (path === "/btc/balance") {
const address = url.searchParams.get("address");
if (!address) return errorResponse("address parameter required");
const res = await fetch(`${PROVIDERS.bitcoin}/rawaddr/${address}`);
const data = await res.json();
return jsonResponse({
address,
balanceSatoshi: data.final_balance,
balanceBtc: data.final_balance / 1e8,
transactions: data.n_tx
});
}
// GET /btc/block - Latest Bitcoin block
if (path === "/btc/block") {
const res = await fetch(`${PROVIDERS.bitcoin}/latestblock`);
const data = await res.json();
return jsonResponse({
blockHeight: data.height,
hash: data.hash,
time: data.time
});
}
// ==================== CRYPTO PRICES ====================
// GET /prices?symbols=bitcoin,binancecoin¤cy=usd
// Supports NGN (Nigerian Naira) for local pricing
if (path === "/prices") {
const symbols = url.searchParams.get("symbols") || "bitcoin,ethereum,binancecoin,polygon";
const currency = url.searchParams.get("currency") || "usd";
const res = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${symbols}&vs_currencies=${currency},eur,ngn`);
const data = await res.json();
return jsonResponse(data);
}
// 404 - Endpoint not found
return errorResponse(
"Endpoint not found. Available endpoints: /health, /eth/balance, /eth/gas, /eth/block, /bsc/balance, /bsc/gas, /polygon/balance, /btc/balance, /btc/block, /prices",
404
);
} catch (err) {
return errorResponse(err.message, 500);
}
}
};
function jsonResponse(data) {
return new Response(JSON.stringify(data, null, 2), { status: 200, headers: CORS_HEADERS });
}
function errorResponse(message, status = 400) {
return new Response(JSON.stringify({ error: message }, null, 2), { status, headers: CORS_HEADERS });
}