mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-25 07:27:54 +00:00
refactor(core): Apply various updates and fixes across components
This commit is contained in:
@@ -96,42 +96,75 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
// Check active sessions and sets the user
|
||||
supabase.auth.getSession().then(({ data: { session } }) => {
|
||||
setUser(session?.user ?? null);
|
||||
if (session?.user) {
|
||||
checkAdminStatus();
|
||||
}
|
||||
checkAdminStatus(); // Check admin status regardless of Supabase session
|
||||
setLoading(false);
|
||||
}).catch(() => {
|
||||
// If Supabase is not available, continue without auth
|
||||
// If Supabase is not available, still check wallet-based admin
|
||||
checkAdminStatus();
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
// Listen for changes on auth state
|
||||
const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => {
|
||||
setUser(session?.user ?? null);
|
||||
if (session?.user) {
|
||||
checkAdminStatus();
|
||||
}
|
||||
checkAdminStatus(); // Check admin status on auth change
|
||||
setLoading(false);
|
||||
});
|
||||
|
||||
return () => subscription.unsubscribe();
|
||||
// Listen for wallet changes (from PolkadotContext)
|
||||
const handleWalletChange = () => {
|
||||
checkAdminStatus();
|
||||
};
|
||||
window.addEventListener('walletChanged', handleWalletChange);
|
||||
|
||||
return () => {
|
||||
subscription.unsubscribe();
|
||||
window.removeEventListener('walletChanged', handleWalletChange);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const checkAdminStatus = async () => {
|
||||
// Admin wallet whitelist (blockchain-based auth)
|
||||
const ADMIN_WALLETS = [
|
||||
'5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', // Founder (original)
|
||||
'5DFwqK698vL4gXHEcanaewnAqhxJ2rjhAogpSTHw3iwGDwd3', // Founder delegate (initial KYC member)
|
||||
'5GgTgG9sRmPQAYU1RsTejZYnZRjwzKZKWD3awtuqjHioki45', // Founder (current dev wallet)
|
||||
];
|
||||
|
||||
try {
|
||||
// PRIMARY: Check wallet-based admin (blockchain auth)
|
||||
const connectedWallet = localStorage.getItem('selectedWallet');
|
||||
console.log('🔍 Admin check - Connected wallet:', connectedWallet);
|
||||
console.log('🔍 Admin check - Whitelist:', ADMIN_WALLETS);
|
||||
|
||||
if (connectedWallet && ADMIN_WALLETS.includes(connectedWallet)) {
|
||||
console.log('✅ Admin access granted (wallet-based)');
|
||||
setIsAdmin(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
// SECONDARY: Check Supabase admin_roles (if wallet not in whitelist)
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
if (!user) return false;
|
||||
if (user) {
|
||||
const { data, error } = await supabase
|
||||
.from('admin_roles')
|
||||
.select('role')
|
||||
.eq('user_id', user.id)
|
||||
.maybeSingle();
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('admin_roles')
|
||||
.select('role')
|
||||
.eq('user_id', user.id)
|
||||
.maybeSingle();
|
||||
if (!error && data && ['admin', 'super_admin'].includes(data.role)) {
|
||||
console.log('✅ Admin access granted (Supabase-based)');
|
||||
setIsAdmin(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const adminStatus = !error && data && ['admin', 'super_admin'].includes(data.role);
|
||||
setIsAdmin(adminStatus);
|
||||
return adminStatus;
|
||||
} catch {
|
||||
console.log('❌ Admin access denied');
|
||||
setIsAdmin(false);
|
||||
return false;
|
||||
} catch (err) {
|
||||
console.error('Admin check error:', err);
|
||||
setIsAdmin(false);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -33,6 +33,19 @@ export const PolkadotProvider: React.FC<PolkadotProviderProps> = ({
|
||||
const [selectedAccount, setSelectedAccount] = useState<InjectedAccountWithMeta | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
// Wrapper to trigger events when wallet changes
|
||||
const handleSetSelectedAccount = (account: InjectedAccountWithMeta | null) => {
|
||||
setSelectedAccount(account);
|
||||
if (account) {
|
||||
localStorage.setItem('selectedWallet', account.address);
|
||||
console.log('💾 Wallet saved:', account.address);
|
||||
window.dispatchEvent(new Event('walletChanged'));
|
||||
} else {
|
||||
localStorage.removeItem('selectedWallet');
|
||||
window.dispatchEvent(new Event('walletChanged'));
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize Polkadot API
|
||||
useEffect(() => {
|
||||
const initApi = async () => {
|
||||
@@ -76,35 +89,73 @@ export const PolkadotProvider: React.FC<PolkadotProviderProps> = ({
|
||||
};
|
||||
}, [endpoint]);
|
||||
|
||||
// Auto-restore wallet on page load
|
||||
useEffect(() => {
|
||||
const restoreWallet = async () => {
|
||||
const savedAddress = localStorage.getItem('selectedWallet');
|
||||
if (!savedAddress) return;
|
||||
|
||||
try {
|
||||
// Enable extension
|
||||
const extensions = await web3Enable('PezkuwiChain');
|
||||
if (extensions.length === 0) return;
|
||||
|
||||
// Get accounts
|
||||
const allAccounts = await web3Accounts();
|
||||
if (allAccounts.length === 0) return;
|
||||
|
||||
// Find saved account
|
||||
const savedAccount = allAccounts.find(acc => acc.address === savedAddress);
|
||||
if (savedAccount) {
|
||||
setAccounts(allAccounts);
|
||||
handleSetSelectedAccount(savedAccount);
|
||||
console.log('✅ Wallet restored:', savedAddress.slice(0, 8) + '...');
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Failed to restore wallet:', err);
|
||||
}
|
||||
};
|
||||
|
||||
restoreWallet();
|
||||
}, []);
|
||||
|
||||
// Connect wallet (Polkadot.js extension)
|
||||
const connectWallet = async () => {
|
||||
try {
|
||||
setError(null);
|
||||
|
||||
|
||||
// Enable extension
|
||||
const extensions = await web3Enable('PezkuwiChain');
|
||||
|
||||
|
||||
if (extensions.length === 0) {
|
||||
setError('Please install Polkadot.js extension');
|
||||
window.open('https://polkadot.js.org/extension/', '_blank');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
console.log('✅ Polkadot.js extension enabled');
|
||||
|
||||
|
||||
// Get accounts
|
||||
const allAccounts = await web3Accounts();
|
||||
|
||||
|
||||
if (allAccounts.length === 0) {
|
||||
setError('No accounts found. Please create an account in Polkadot.js extension');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setAccounts(allAccounts);
|
||||
setSelectedAccount(allAccounts[0]); // Auto-select first account
|
||||
|
||||
|
||||
// Try to restore previously selected account, otherwise use first
|
||||
const savedAddress = localStorage.getItem('selectedWallet');
|
||||
const accountToSelect = savedAddress
|
||||
? allAccounts.find(acc => acc.address === savedAddress) || allAccounts[0]
|
||||
: allAccounts[0];
|
||||
|
||||
// Use wrapper to trigger events
|
||||
handleSetSelectedAccount(accountToSelect);
|
||||
|
||||
console.log(`✅ Found ${allAccounts.length} account(s)`);
|
||||
|
||||
|
||||
} catch (err) {
|
||||
console.error('❌ Wallet connection failed:', err);
|
||||
setError('Failed to connect wallet');
|
||||
@@ -114,7 +165,7 @@ export const PolkadotProvider: React.FC<PolkadotProviderProps> = ({
|
||||
// Disconnect wallet
|
||||
const disconnectWallet = () => {
|
||||
setAccounts([]);
|
||||
setSelectedAccount(null);
|
||||
handleSetSelectedAccount(null);
|
||||
console.log('🔌 Wallet disconnected');
|
||||
};
|
||||
|
||||
@@ -124,7 +175,7 @@ export const PolkadotProvider: React.FC<PolkadotProviderProps> = ({
|
||||
isConnected: isApiReady, // Alias for backward compatibility
|
||||
accounts,
|
||||
selectedAccount,
|
||||
setSelectedAccount,
|
||||
setSelectedAccount: handleSetSelectedAccount,
|
||||
connectWallet,
|
||||
disconnectWallet,
|
||||
error,
|
||||
|
||||
@@ -38,9 +38,10 @@ export const WebSocketProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
||||
const connectionAttempts = useRef(0);
|
||||
|
||||
const ENDPOINTS = [
|
||||
'wss://ws.pezkuwichain.io', // Production WebSocket
|
||||
'ws://localhost:9944', // Local development node
|
||||
'ws://127.0.0.1:9944', // Alternative local address
|
||||
'ws://localhost:8082', // Local Vite dev server
|
||||
'ws://127.0.0.1:9944', // Local development node (primary)
|
||||
'ws://localhost:9944', // Local development node (alternative)
|
||||
'wss://ws.pezkuwichain.io', // Production WebSocket (fallback)
|
||||
];
|
||||
|
||||
const connect = useCallback((endpointIndex: number = 0) => {
|
||||
|
||||
Reference in New Issue
Block a user