mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-06-13 21:31:01 +00:00
fix: fetch collators from parachains and restrict CORS to production domains
- NetworkStats now queries Asset Hub and People Chain for collator data instead of relay chain (where collatorSelection doesn't exist) - Restrict Edge Functions CORS to app.pezkuwichain.io domains only - Add Access-Control-Allow-Credentials header for secure cross-origin requests
This commit is contained in:
@@ -5,7 +5,7 @@ import { Badge } from '@/components/ui/badge';
|
|||||||
import { Activity, Wifi, WifiOff, Users, Box, TrendingUp } from 'lucide-react';
|
import { Activity, Wifi, WifiOff, Users, Box, TrendingUp } from 'lucide-react';
|
||||||
|
|
||||||
export const NetworkStats: React.FC = () => {
|
export const NetworkStats: React.FC = () => {
|
||||||
const { api, isApiReady, error } = usePezkuwi();
|
const { api, assetHubApi, peopleApi, isApiReady, isAssetHubReady, isPeopleReady, error } = usePezkuwi();
|
||||||
const [blockNumber, setBlockNumber] = useState<number>(0);
|
const [blockNumber, setBlockNumber] = useState<number>(0);
|
||||||
const [blockHash, setBlockHash] = useState<string>('');
|
const [blockHash, setBlockHash] = useState<string>('');
|
||||||
const [finalizedBlock, setFinalizedBlock] = useState<number>(0);
|
const [finalizedBlock, setFinalizedBlock] = useState<number>(0);
|
||||||
@@ -52,17 +52,31 @@ export const NetworkStats: React.FC = () => {
|
|||||||
if (import.meta.env.DEV) console.warn('Failed to fetch validators', err);
|
if (import.meta.env.DEV) console.warn('Failed to fetch validators', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Fetch Collators (Invulnerables)
|
// 2. Fetch Collators from Parachains (Asset Hub + People Chain)
|
||||||
let cCount = 0;
|
let cCount = 0;
|
||||||
|
|
||||||
|
// Fetch from Asset Hub
|
||||||
try {
|
try {
|
||||||
if (api.query.collatorSelection?.invulnerables) {
|
if (isAssetHubReady && assetHubApi?.query.collatorSelection?.invulnerables) {
|
||||||
const invulnerables = await api.query.collatorSelection.invulnerables();
|
const assetHubCollators = await assetHubApi.query.collatorSelection.invulnerables();
|
||||||
if (invulnerables) {
|
if (assetHubCollators) {
|
||||||
cCount = invulnerables.length;
|
cCount += assetHubCollators.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (import.meta.env.DEV) console.warn('Failed to fetch collators', err);
|
if (import.meta.env.DEV) console.warn('Failed to fetch Asset Hub collators', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch from People Chain
|
||||||
|
try {
|
||||||
|
if (isPeopleReady && peopleApi?.query.collatorSelection?.invulnerables) {
|
||||||
|
const peopleCollators = await peopleApi.query.collatorSelection.invulnerables();
|
||||||
|
if (peopleCollators) {
|
||||||
|
cCount += peopleCollators.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (import.meta.env.DEV) console.warn('Failed to fetch People Chain collators', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Count Nominators
|
// 3. Count Nominators
|
||||||
@@ -103,7 +117,7 @@ export const NetworkStats: React.FC = () => {
|
|||||||
if (unsubscribeFinalizedHeads) unsubscribeFinalizedHeads();
|
if (unsubscribeFinalizedHeads) unsubscribeFinalizedHeads();
|
||||||
if (intervalId) clearInterval(intervalId);
|
if (intervalId) clearInterval(intervalId);
|
||||||
};
|
};
|
||||||
}, [api, isApiReady]);
|
}, [api, assetHubApi, peopleApi, isApiReady, isAssetHubReady, isPeopleReady]);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -7,9 +7,20 @@ import { createClient } from 'npm:@supabase/supabase-js@2'
|
|||||||
import { ApiPromise, WsProvider, Keyring } from 'npm:@pezkuwi/api@16.5.11'
|
import { ApiPromise, WsProvider, Keyring } from 'npm:@pezkuwi/api@16.5.11'
|
||||||
import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.11'
|
import { cryptoWaitReady } from 'npm:@pezkuwi/util-crypto@14.0.11'
|
||||||
|
|
||||||
const corsHeaders = {
|
// Allowed origins for CORS
|
||||||
'Access-Control-Allow-Origin': '*',
|
const ALLOWED_ORIGINS = [
|
||||||
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
'https://app.pezkuwichain.io',
|
||||||
|
'https://www.pezkuwichain.io',
|
||||||
|
'https://pezkuwichain.io',
|
||||||
|
]
|
||||||
|
|
||||||
|
function getCorsHeaders(origin: string | null) {
|
||||||
|
const allowedOrigin = origin && ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0]
|
||||||
|
return {
|
||||||
|
'Access-Control-Allow-Origin': allowedOrigin,
|
||||||
|
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
||||||
|
'Access-Control-Allow-Credentials': 'true',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform hot wallet address
|
// Platform hot wallet address
|
||||||
@@ -167,6 +178,8 @@ async function sendTokens(
|
|||||||
}
|
}
|
||||||
|
|
||||||
serve(async (req) => {
|
serve(async (req) => {
|
||||||
|
const corsHeaders = getCorsHeaders(req.headers.get('Origin'))
|
||||||
|
|
||||||
// Handle CORS preflight
|
// Handle CORS preflight
|
||||||
if (req.method === 'OPTIONS') {
|
if (req.method === 'OPTIONS') {
|
||||||
return new Response(null, { headers: corsHeaders })
|
return new Response(null, { headers: corsHeaders })
|
||||||
|
|||||||
@@ -177,10 +177,20 @@ async function processWithdrawal(
|
|||||||
* Main handler
|
* Main handler
|
||||||
*/
|
*/
|
||||||
serve(async (req: Request) => {
|
serve(async (req: Request) => {
|
||||||
// CORS headers
|
// Allowed origins for CORS
|
||||||
|
const ALLOWED_ORIGINS = [
|
||||||
|
'https://app.pezkuwichain.io',
|
||||||
|
'https://www.pezkuwichain.io',
|
||||||
|
'https://pezkuwichain.io',
|
||||||
|
]
|
||||||
|
|
||||||
|
const requestOrigin = req.headers.get('Origin')
|
||||||
|
const allowedOrigin = requestOrigin && ALLOWED_ORIGINS.includes(requestOrigin) ? requestOrigin : ALLOWED_ORIGINS[0]
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
"Access-Control-Allow-Origin": "*",
|
"Access-Control-Allow-Origin": allowedOrigin,
|
||||||
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
|
||||||
|
"Access-Control-Allow-Credentials": "true",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,20 @@ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
|
|||||||
import { createClient } from 'npm:@supabase/supabase-js@2'
|
import { createClient } from 'npm:@supabase/supabase-js@2'
|
||||||
import { ApiPromise, WsProvider } from 'npm:@pezkuwi/api@16.5.11'
|
import { ApiPromise, WsProvider } from 'npm:@pezkuwi/api@16.5.11'
|
||||||
|
|
||||||
const corsHeaders = {
|
// Allowed origins for CORS
|
||||||
'Access-Control-Allow-Origin': '*',
|
const ALLOWED_ORIGINS = [
|
||||||
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
'https://app.pezkuwichain.io',
|
||||||
|
'https://www.pezkuwichain.io',
|
||||||
|
'https://pezkuwichain.io',
|
||||||
|
]
|
||||||
|
|
||||||
|
function getCorsHeaders(origin: string | null) {
|
||||||
|
const allowedOrigin = origin && ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0]
|
||||||
|
return {
|
||||||
|
'Access-Control-Allow-Origin': allowedOrigin,
|
||||||
|
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
||||||
|
'Access-Control-Allow-Credentials': 'true',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform hot wallet address (PRODUCTION) - Treasury_3
|
// Platform hot wallet address (PRODUCTION) - Treasury_3
|
||||||
@@ -213,6 +224,8 @@ async function verifyTransactionOnChain(
|
|||||||
}
|
}
|
||||||
|
|
||||||
serve(async (req) => {
|
serve(async (req) => {
|
||||||
|
const corsHeaders = getCorsHeaders(req.headers.get('Origin'))
|
||||||
|
|
||||||
// Handle CORS preflight
|
// Handle CORS preflight
|
||||||
if (req.method === 'OPTIONS') {
|
if (req.method === 'OPTIONS') {
|
||||||
return new Response(null, { headers: corsHeaders })
|
return new Response(null, { headers: corsHeaders })
|
||||||
|
|||||||
Reference in New Issue
Block a user