mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-22 14:47:58 +00:00
feat(web): Add mobile bridge support for P2P WebView integration
- Add mobile-bridge.ts utility for native app communication - Add useMobileBridge.ts React hook - Update AuthContext to detect and use native wallet - Update PezkuwiContext to connect mobile wallet automatically - Update WalletContext to sign transactions via native bridge Mobile app can now seamlessly use web P2P features with native wallet.
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Mobile Bridge Utility
|
||||
*
|
||||
* Handles communication between the web app and native mobile app (React Native WebView).
|
||||
* When running inside the Pezkuwi mobile app, this bridge enables:
|
||||
* - Native wallet integration (address, signing)
|
||||
* - Platform detection
|
||||
* - Native navigation
|
||||
*/
|
||||
|
||||
// Type definitions for the native bridge
|
||||
declare global {
|
||||
interface Window {
|
||||
PEZKUWI_MOBILE?: boolean;
|
||||
PEZKUWI_PLATFORM?: 'ios' | 'android';
|
||||
PEZKUWI_ADDRESS?: string;
|
||||
PEZKUWI_ACCOUNT_NAME?: string;
|
||||
ReactNativeWebView?: {
|
||||
postMessage: (message: string) => void;
|
||||
};
|
||||
PezkuwiNativeBridge?: {
|
||||
signTransaction: (extrinsicHex: string, callback: (signature: string | null, error: string | null) => void) => void;
|
||||
connectWallet: () => void;
|
||||
goBack: () => void;
|
||||
isWalletConnected: () => boolean;
|
||||
getAddress: () => string | null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface MobileBridgeState {
|
||||
isMobile: boolean;
|
||||
platform: 'ios' | 'android' | 'web';
|
||||
walletAddress: string | null;
|
||||
accountName: string | null;
|
||||
isWalletConnected: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if running inside mobile WebView
|
||||
*/
|
||||
export function isMobileApp(): boolean {
|
||||
return typeof window !== 'undefined' && window.PEZKUWI_MOBILE === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current platform
|
||||
*/
|
||||
export function getPlatform(): 'ios' | 'android' | 'web' {
|
||||
if (!isMobileApp()) return 'web';
|
||||
return window.PEZKUWI_PLATFORM || 'android';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get native wallet address (if connected in mobile app)
|
||||
*/
|
||||
export function getNativeWalletAddress(): string | null {
|
||||
if (!isMobileApp()) return null;
|
||||
return window.PEZKUWI_ADDRESS || window.PezkuwiNativeBridge?.getAddress() || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get native account name
|
||||
*/
|
||||
export function getNativeAccountName(): string | null {
|
||||
if (!isMobileApp()) return null;
|
||||
return window.PEZKUWI_ACCOUNT_NAME || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if native wallet is connected
|
||||
*/
|
||||
export function isNativeWalletConnected(): boolean {
|
||||
if (!isMobileApp()) return false;
|
||||
return window.PezkuwiNativeBridge?.isWalletConnected() || !!window.PEZKUWI_ADDRESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request wallet connection from native app
|
||||
*/
|
||||
export function requestNativeWalletConnection(): void {
|
||||
if (!isMobileApp()) return;
|
||||
window.PezkuwiNativeBridge?.connectWallet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign transaction using native wallet
|
||||
* Returns a promise that resolves with the signature or rejects with error
|
||||
*/
|
||||
export function signTransactionNative(extrinsicHex: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!isMobileApp() || !window.PezkuwiNativeBridge) {
|
||||
reject(new Error('Native bridge not available'));
|
||||
return;
|
||||
}
|
||||
|
||||
window.PezkuwiNativeBridge.signTransaction(extrinsicHex, (signature, error) => {
|
||||
if (error) {
|
||||
reject(new Error(error));
|
||||
} else if (signature) {
|
||||
resolve(signature);
|
||||
} else {
|
||||
reject(new Error('No signature returned'));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate back in native app
|
||||
*/
|
||||
export function navigateBackNative(): void {
|
||||
if (!isMobileApp()) return;
|
||||
window.PezkuwiNativeBridge?.goBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send message to native app
|
||||
*/
|
||||
export function sendMessageToNative(type: string, payload?: unknown): void {
|
||||
if (!isMobileApp() || !window.ReactNativeWebView) return;
|
||||
|
||||
window.ReactNativeWebView.postMessage(JSON.stringify({ type, payload }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current mobile bridge state
|
||||
*/
|
||||
export function getMobileBridgeState(): MobileBridgeState {
|
||||
const isMobile = isMobileApp();
|
||||
return {
|
||||
isMobile,
|
||||
platform: getPlatform(),
|
||||
walletAddress: getNativeWalletAddress(),
|
||||
accountName: getNativeAccountName(),
|
||||
isWalletConnected: isNativeWalletConnected(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Log to native console (for debugging)
|
||||
*/
|
||||
export function logToNative(message: string, data?: unknown): void {
|
||||
if (!isMobileApp()) {
|
||||
console.log(message, data);
|
||||
return;
|
||||
}
|
||||
|
||||
sendMessageToNative('CONSOLE_LOG', { message, data });
|
||||
}
|
||||
|
||||
// Export a singleton for easy access
|
||||
export const mobileBridge = {
|
||||
isMobileApp,
|
||||
getPlatform,
|
||||
getNativeWalletAddress,
|
||||
getNativeAccountName,
|
||||
isNativeWalletConnected,
|
||||
requestNativeWalletConnection,
|
||||
signTransactionNative,
|
||||
navigateBackNative,
|
||||
sendMessageToNative,
|
||||
getMobileBridgeState,
|
||||
logToNative,
|
||||
};
|
||||
|
||||
export default mobileBridge;
|
||||
Reference in New Issue
Block a user