Files changed (1) hide show
  1. AfricaCryptoChainx +142 -0
AfricaCryptoChainx ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // accx-blockchain-explorer
2
+ // Routes: api.africacryptochainx.com/*
3
+
4
+ const CORS_HEADERS = {
5
+ "Access-Control-Allow-Origin": "*",
6
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
7
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
8
+ "Content-Type": "application/json"
9
+ };
10
+
11
+ // Blockchain API endpoints
12
+ const PROVIDERS = {
13
+ ethereum: "https://eth-mainnet.g.alchemy.com/v2/demo",
14
+ bsc: "https://bsc-dataseed.binance.org",
15
+ polygon: "https://polygon-rpc.com",
16
+ bitcoin: "https://blockchain.info"
17
+ };
18
+
19
+ export default {
20
+ async fetch(request, env, ctx) {
21
+ if (request.method === "OPTIONS") {
22
+ return new Response(null, { status: 204, headers: CORS_HEADERS });
23
+ }
24
+
25
+ const url = new URL(request.url);
26
+ const path = url.pathname;
27
+
28
+ try {
29
+ // Health check
30
+ if (path === "/" || path === "/health") {
31
+ return jsonResponse({ status: "ok", service: "ACCX Blockchain Explorer", timestamp: new Date().toISOString() });
32
+ }
33
+
34
+ // === ETHEREUM ===
35
+ if (path === "/eth/balance") {
36
+ const address = url.searchParams.get("address");
37
+ if (!address) return errorResponse("address required");
38
+ const res = await fetch(PROVIDERS.ethereum, {
39
+ method: "POST",
40
+ headers: { "Content-Type": "application/json" },
41
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
42
+ });
43
+ const data = await res.json();
44
+ return jsonResponse({ address, balanceWei: data.result, balanceEth: parseInt(data.result, 16) / 1e18 });
45
+ }
46
+
47
+ if (path === "/eth/gas") {
48
+ const res = await fetch(PROVIDERS.ethereum, {
49
+ method: "POST",
50
+ headers: { "Content-Type": "application/json" },
51
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_gasPrice", params: [] })
52
+ });
53
+ const data = await res.json();
54
+ return jsonResponse({ gasPriceWei: data.result, gasPriceGwei: parseInt(data.result, 16) / 1e9 });
55
+ }
56
+
57
+ if (path === "/eth/block") {
58
+ const res = await fetch(PROVIDERS.ethereum, {
59
+ method: "POST",
60
+ headers: { "Content-Type": "application/json" },
61
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_blockNumber", params: [] })
62
+ });
63
+ const data = await res.json();
64
+ return jsonResponse({ blockHeight: parseInt(data.result, 16) });
65
+ }
66
+
67
+ // === BSC ===
68
+ if (path === "/bsc/balance") {
69
+ const address = url.searchParams.get("address");
70
+ if (!address) return errorResponse("address required");
71
+ const res = await fetch(PROVIDERS.bsc, {
72
+ method: "POST",
73
+ headers: { "Content-Type": "application/json" },
74
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
75
+ });
76
+ const data = await res.json();
77
+ return jsonResponse({ address, balanceWei: data.result, balanceBnb: parseInt(data.result, 16) / 1e18 });
78
+ }
79
+
80
+ if (path === "/bsc/gas") {
81
+ const res = await fetch(PROVIDERS.bsc, {
82
+ method: "POST",
83
+ headers: { "Content-Type": "application/json" },
84
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_gasPrice", params: [] })
85
+ });
86
+ const data = await res.json();
87
+ return jsonResponse({ gasPriceWei: data.result, gasPriceGwei: parseInt(data.result, 16) / 1e9 });
88
+ }
89
+
90
+ // === POLYGON ===
91
+ if (path === "/polygon/balance") {
92
+ const address = url.searchParams.get("address");
93
+ if (!address) return errorResponse("address required");
94
+ const res = await fetch(PROVIDERS.polygon, {
95
+ method: "POST",
96
+ headers: { "Content-Type": "application/json" },
97
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "eth_getBalance", params: [address, "latest"] })
98
+ });
99
+ const data = await res.json();
100
+ return jsonResponse({ address, balanceWei: data.result, balanceMatic: parseInt(data.result, 16) / 1e18 });
101
+ }
102
+
103
+ // === BITCOIN ===
104
+ if (path === "/btc/balance") {
105
+ const address = url.searchParams.get("address");
106
+ if (!address) return errorResponse("address required");
107
+ const res = await fetch(`${PROVIDERS.bitcoin}/rawaddr/${address}`);
108
+ const data = await res.json();
109
+ return jsonResponse({ address, balanceSatoshi: data.final_balance, balanceBtc: data.final_balance / 1e8, txs: data.n_tx });
110
+ }
111
+
112
+ if (path === "/btc/block") {
113
+ const res = await fetch(`${PROVIDERS.bitcoin}/latestblock`);
114
+ const data = await res.json();
115
+ return jsonResponse({ blockHeight: data.height, hash: data.hash, time: data.time });
116
+ }
117
+
118
+ // === CRYPTO PRICES ===
119
+ if (path === "/prices") {
120
+ const symbols = url.searchParams.get("symbols") || "bitcoin,ethereum,binancecoin,polygon";
121
+ const currency = url.searchParams.get("currency") || "usd";
122
+ const res = await fetch(`https://api.coingecko.com/api/v3/simple/price?ids=${symbols}&vs_currencies=${currency},eur,ngn`);
123
+ const data = await res.json();
124
+ return jsonResponse(data);
125
+ }
126
+
127
+ // 404
128
+ 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);
129
+
130
+ } catch (err) {
131
+ return errorResponse(err.message, 500);
132
+ }
133
+ }
134
+ };
135
+
136
+ function jsonResponse(data) {
137
+ return new Response(JSON.stringify(data, null, 2), { status: 200, headers: CORS_HEADERS });
138
+ }
139
+
140
+ function errorResponse(message, status = 400) {
141
+ return new Response(JSON.stringify({ error: message }, null, 2), { status, headers: CORS_HEADERS });
142
+ }