mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-24 20:07:55 +00:00
feat: add XCM teleport and CI/CD deployment workflow
Features: - Add XCMTeleportModal for cross-chain HEZ transfers - Support Asset Hub and People Chain teleports - Add "Fund Fees" button with user-friendly tooltips - Use correct XCM V3 format with teyrchain junction Fixes: - Fix PEZ transfer to use Asset Hub API - Silence unnecessary pallet availability warnings - Fix transaction loading performance (10 blocks limit) - Remove Supabase admin_roles dependency CI/CD: - Add auto-deploy to VPS on main branch push - Add version bumping on deploy - Upload build artifacts for deployment
This commit is contained in:
@@ -134,23 +134,10 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
||||
return true;
|
||||
}
|
||||
|
||||
// SECONDARY: Check Supabase admin_roles (if wallet not in whitelist)
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
if (user) {
|
||||
const { data, error } = await supabase
|
||||
.from('admin_roles')
|
||||
.select('role')
|
||||
.eq('user_id', user.id)
|
||||
.maybeSingle();
|
||||
// SECONDARY: Supabase admin_roles check disabled (table may not exist)
|
||||
// Admin access is primarily wallet-based via the whitelist above
|
||||
|
||||
if (!error && data && ['admin', 'super_admin'].includes(data.role)) {
|
||||
if (import.meta.env.DEV) console.log('✅ Admin access granted (Supabase-based)');
|
||||
setIsAdmin(true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (import.meta.env.DEV) console.log('❌ Admin access denied');
|
||||
if (import.meta.env.DEV) console.log('❌ Admin access denied (wallet not in whitelist)');
|
||||
setIsAdmin(false);
|
||||
return false;
|
||||
} catch (err) {
|
||||
|
||||
@@ -5,14 +5,17 @@ import type { InjectedAccountWithMeta } from '@pezkuwi/extension-inject/types';
|
||||
import { DEFAULT_ENDPOINT } from '../../../shared/blockchain/pezkuwi';
|
||||
import { isMobileApp, getNativeWalletAddress, getNativeAccountName } from '@/lib/mobile-bridge';
|
||||
|
||||
// Asset Hub endpoint for PEZ token queries
|
||||
// Parachain endpoints
|
||||
const ASSET_HUB_ENDPOINT = 'wss://asset-hub-rpc.pezkuwichain.io';
|
||||
const PEOPLE_CHAIN_ENDPOINT = 'wss://people-rpc.pezkuwichain.io';
|
||||
|
||||
interface PezkuwiContextType {
|
||||
api: ApiPromise | null;
|
||||
assetHubApi: ApiPromise | null;
|
||||
peopleApi: ApiPromise | null;
|
||||
isApiReady: boolean;
|
||||
isAssetHubReady: boolean;
|
||||
isPeopleReady: boolean;
|
||||
isConnected: boolean;
|
||||
accounts: InjectedAccountWithMeta[];
|
||||
selectedAccount: InjectedAccountWithMeta | null;
|
||||
@@ -36,8 +39,10 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
||||
}) => {
|
||||
const [api, setApi] = useState<ApiPromise | null>(null);
|
||||
const [assetHubApi, setAssetHubApi] = useState<ApiPromise | null>(null);
|
||||
const [peopleApi, setPeopleApi] = useState<ApiPromise | null>(null);
|
||||
const [isApiReady, setIsApiReady] = useState(false);
|
||||
const [isAssetHubReady, setIsAssetHubReady] = useState(false);
|
||||
const [isPeopleReady, setIsPeopleReady] = useState(false);
|
||||
const [accounts, setAccounts] = useState<InjectedAccountWithMeta[]>([]);
|
||||
const [selectedAccount, setSelectedAccount] = useState<InjectedAccountWithMeta | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
@@ -105,6 +110,17 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
||||
|
||||
if (import.meta.env.DEV) console.log(`📡 Chain: ${chain}`);
|
||||
if (import.meta.env.DEV) console.log(`🖥️ Node: ${nodeName} v${nodeVersion}`);
|
||||
|
||||
// Debug: Check Junction type definition
|
||||
try {
|
||||
const junctionType = apiInstance.createType('XcmV3Junction');
|
||||
console.log('🔍 XCM Junction type keys:', (junctionType as any).defKeys || Object.keys(junctionType.toJSON() || {}));
|
||||
// Expose api for console debugging
|
||||
(window as any).__PEZKUWI_API__ = apiInstance;
|
||||
console.log('💡 API exposed as window.__PEZKUWI_API__ for debugging');
|
||||
} catch (e) {
|
||||
console.log('⚠️ Could not check Junction type:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch sudo key from blockchain
|
||||
@@ -168,8 +184,43 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize People Chain API for identity/citizenship
|
||||
const initPeopleApi = async () => {
|
||||
try {
|
||||
if (import.meta.env.DEV) {
|
||||
console.log('🔗 Connecting to People Chain:', PEOPLE_CHAIN_ENDPOINT);
|
||||
}
|
||||
|
||||
const provider = new WsProvider(PEOPLE_CHAIN_ENDPOINT);
|
||||
const peopleApiInstance = await ApiPromise.create({
|
||||
provider,
|
||||
signedExtensions: {
|
||||
AuthorizeCall: {
|
||||
extrinsic: {},
|
||||
payload: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await peopleApiInstance.isReady;
|
||||
|
||||
setPeopleApi(peopleApiInstance);
|
||||
setIsPeopleReady(true);
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
console.log('✅ Connected to People Chain for identity');
|
||||
}
|
||||
} catch (err) {
|
||||
if (import.meta.env.DEV) {
|
||||
console.error('❌ Failed to connect to People Chain:', err);
|
||||
}
|
||||
// Don't set error - Identity features just won't work
|
||||
}
|
||||
};
|
||||
|
||||
initApi();
|
||||
initAssetHubApi();
|
||||
initPeopleApi();
|
||||
|
||||
return () => {
|
||||
if (api) {
|
||||
@@ -178,6 +229,9 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
||||
if (assetHubApi) {
|
||||
assetHubApi.disconnect();
|
||||
}
|
||||
if (peopleApi) {
|
||||
peopleApi.disconnect();
|
||||
}
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [endpoint]);
|
||||
@@ -357,8 +411,10 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({
|
||||
const value: PezkuwiContextType = {
|
||||
api,
|
||||
assetHubApi,
|
||||
peopleApi,
|
||||
isApiReady,
|
||||
isAssetHubReady,
|
||||
isPeopleReady,
|
||||
isConnected: isApiReady, // Alias for backward compatibility
|
||||
accounts,
|
||||
selectedAccount,
|
||||
|
||||
@@ -53,15 +53,10 @@ export const WebSocketProvider: React.FC<{ children: React.ReactNode }> = ({ chi
|
||||
const connectionAttempts = useRef(0);
|
||||
|
||||
const connect = useCallback((endpointIndex: number = 0) => {
|
||||
// If we've tried all endpoints, show error once and stop
|
||||
// If we've tried all endpoints, stop silently (WebSocket is optional)
|
||||
if (endpointIndex >= ENDPOINTS.length) {
|
||||
if (!hasShownFinalError.current) {
|
||||
if (import.meta.env.DEV) console.error('❌ All WebSocket endpoints failed');
|
||||
toast({
|
||||
title: "Real-time Connection Unavailable",
|
||||
description: "Could not connect to WebSocket server. Live updates will be disabled.",
|
||||
variant: "destructive",
|
||||
});
|
||||
// WebSocket service is optional - fail silently
|
||||
hasShownFinalError.current = true;
|
||||
}
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user