UNPKG

@pushchain/ui-kit

Version:
384 lines 18.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WalletContextProvider = exports.WalletContext = void 0; const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const core_1 = require("@pushchain/core"); const progress_hook_types_1 = require("@pushchain/core/src/lib/progress-hook/progress-hook.types"); const types_1 = require("../types"); const constants_1 = require("../constants"); const WalletProviderRegistry_1 = require("../providers/walletProviders/WalletProviderRegistry"); const PushWalletToast_1 = require("../components/PushWalletToast"); const LoginModal_1 = require("../components/LoginModal"); const WalletContextMap_1 = require("./WalletContextMap"); exports.WalletContext = (0, react_1.createContext)(null); const WalletContextProvider = ({ children, config, app, themeMode = constants_1.PushUI.CONSTANTS.THEME.DARK, themeOverrides, }) => { const [universalAccount, setUniversalAccount] = (0, react_1.useState)(null); const iframeRef = (0, react_1.useRef)(null); const [isWalletVisible, setWalletVisibility] = (0, react_1.useState)(false); // to display the iframe as connect button is clicked const [isWalletMinimised, setMinimiseWallet] = (0, react_1.useState)(false); // to display/hide minimized wallet modal const [isIframeLoading, setIframeLoading] = (0, react_1.useState)(true); const [connectionStatus, setConnectionStatus] = (0, react_1.useState)(types_1.ConnectionStatus.NOT_CONNECTED); const [externalWallet, setExternalWallet] = (0, react_1.useState)(null); // to connect with external wallet const [progress, setProgress] = (0, react_1.useState)(null); const signatureResolverRef = (0, react_1.useRef)(null); const [modalAppData, setModalAppData] = (0, react_1.useState)(app ? { title: app === null || app === void 0 ? void 0 : app.title, logoURL: app === null || app === void 0 ? void 0 : app.logoUrl, description: app === null || app === void 0 ? void 0 : app.description, } : undefined); const [walletAppData, setWalletAppData] = (0, react_1.useState)(app ? { title: app === null || app === void 0 ? void 0 : app.title, logoURL: app === null || app === void 0 ? void 0 : app.logoUrl, description: app === null || app === void 0 ? void 0 : app.description, } : undefined); const toggleButtonRef = (0, react_1.useRef)(null); const updateModalAppData = (newData) => { setModalAppData((prevData) => (Object.assign(Object.assign({}, prevData), newData))); }; const updateWalletAppData = (newData) => { setWalletAppData((prevData) => (Object.assign(Object.assign({}, prevData), newData))); }; const handleConnectToPushWallet = () => { setWalletVisibility(true); setConnectionStatus(types_1.ConnectionStatus.CONNECTING); }; // sending wallet config to the Push wallet const sendWalletConfig = () => { const walletConfig = { loginDefaults: config.login, themeMode, appMetadata: walletAppData, themeOverrides: themeOverrides || {}, }; sendMessageToPushWallet({ type: constants_1.APP_TO_WALLET_ACTION.WALLET_CONFIG, data: Object.assign({}, walletConfig), }); }; const handleUserLogOutEvent = () => { setConnectionStatus(types_1.ConnectionStatus.NOT_CONNECTED); setUniversalAccount(null); setMinimiseWallet(false); setWalletVisibility(false); setIframeLoading(true); }; // sending events to wallet from dapp const sendMessageToPushWallet = (message) => { var _a; if ((_a = iframeRef === null || iframeRef === void 0 ? void 0 : iframeRef.current) === null || _a === void 0 ? void 0 : _a.contentWindow) { try { iframeRef.current.contentWindow.postMessage(message, constants_1.WALLET_CONFIG_URL[config.network]); } catch (error) { console.error('Error sending message to push wallet tab:', error); } } }; // response when the wallet sends logged in action const handleIsLoggedInAction = () => { handleNewConnectionRequest(); // setExternalWallet(null); }; // sending a new connection request as soon as wallet gets connected const handleNewConnectionRequest = () => { setConnectionStatus(types_1.ConnectionStatus.AUTHENTICATING); sendMessageToPushWallet({ type: constants_1.APP_TO_WALLET_ACTION.NEW_CONNECTION_REQUEST, }); }; const handleAppConnectionSuccess = (response) => { setConnectionStatus(types_1.ConnectionStatus.CONNECTED); setMinimiseWallet(true); if (response.account) { setUniversalAccount(response.account); } }; const handleAppConnectionRejection = () => { setConnectionStatus(types_1.ConnectionStatus.RETRY); setUniversalAccount(null); }; // Connect external wallet const handleExternalWalletConnection = (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { try { const providerReceived = WalletProviderRegistry_1.walletRegistry.getProvider(data.provider); if (!providerReceived) { return; } const walletInfo = yield providerReceived.connect(data.chain); console.log('@@@@@@@ walletInfo', walletInfo); console.log('#######', core_1.PushChain.utils.account); console.log('$$$$$$', core_1.PushChain.utils.account.fromChainAgnostic); setConnectionStatus(types_1.ConnectionStatus.CONNECTED); setMinimiseWallet(true); const result = core_1.PushChain.utils.account.fromChainAgnostic(walletInfo.caipAddress); setUniversalAccount(result); const connectedWallet = { address: walletInfo.caipAddress, providerName: data.provider, chainType: data.chain, }; setExternalWallet(connectedWallet); sendMessageToPushWallet({ type: constants_1.APP_TO_WALLET_ACTION.CONNECTION_STATUS, data: Object.assign({ status: 'successful' }, connectedWallet), }); } catch (error) { console.log('Failed to connect to provider', error); sendMessageToPushWallet({ type: constants_1.APP_TO_WALLET_ACTION.CONNECTION_STATUS, data: { status: 'rejected', }, }); throw new Error('Failed to connect to provider'); } }); // handles external wallet signature request const handleExternalWalletSignRequest = (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { if (!externalWallet) { throw new Error('No External wallet connected'); } try { const providerReceived = WalletProviderRegistry_1.walletRegistry.getProvider(externalWallet.providerName); if (!providerReceived) { throw new Error('Provider not found'); } const signature = yield providerReceived.signMessage(data); return signature; } catch (error) { console.log('Error in generating signature', error); throw new Error('Signature request failed'); } }); const handleExternalWalletSignTransactionRequest = (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { if (!externalWallet) { throw new Error('No External wallet connected'); } try { const providerReceived = WalletProviderRegistry_1.walletRegistry.getProvider(externalWallet.providerName); if (!providerReceived) { throw new Error('Provider not found'); } const signature = yield providerReceived.signAndSendTransaction(data); return signature; } catch (error) { console.log('Error in generating signature', error); throw new Error('Signature request failed'); } }); const handleExternalWalletSignTypedDataRequest = (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { if (!externalWallet) { throw new Error('No External wallet connected'); } try { const providerReceived = WalletProviderRegistry_1.walletRegistry.getProvider(externalWallet.providerName); if (!providerReceived) { throw new Error('Provider not found'); } const signature = yield providerReceived.signTypedData(data); return signature; } catch (error) { console.log('Error in generating signature', error); throw new Error('Signature request failed'); } }); // handles Push wallet signature request const handleSendSignRequestToPushWallet = (data) => { return new Promise((resolve, reject) => { if (signatureResolverRef.current) { reject(new Error('Another sign request is already in progress')); return; } signatureResolverRef.current = { success: (response) => { resolve(response.signature); signatureResolverRef.current = null; // Clean up }, error: (response) => { signatureResolverRef.current = null; // Clean up reject(new Error('Signature request failed')); }, }; // Send the sign request to the wallet tab sendMessageToPushWallet({ type: constants_1.APP_TO_WALLET_ACTION.SIGN_MESSAGE, data, }); }); }; const handleSendSignTransactionRequestToPushWallet = (data) => { return new Promise((resolve, reject) => { if (signatureResolverRef.current) { reject(new Error('Another sign request is already in progress')); return; } signatureResolverRef.current = { success: (response) => { resolve(response.signature); signatureResolverRef.current = null; // Clean up }, error: (response) => { signatureResolverRef.current = null; // Clean up reject(new Error('Signature request failed')); }, }; // Send the sign request to the wallet tab sendMessageToPushWallet({ type: constants_1.APP_TO_WALLET_ACTION.SIGN_TRANSACTION, data, }); }); }; const handleSendSignTypedDataRequestToPushWallet = (data) => { return new Promise((resolve, reject) => { if (signatureResolverRef.current) { reject(new Error('Another sign request is already in progress')); return; } signatureResolverRef.current = { success: (response) => { resolve(response.signature); signatureResolverRef.current = null; // Clean up }, error: (response) => { signatureResolverRef.current = null; // Clean up reject(new Error('Signature request failed')); }, }; // Send the sign request to the wallet tab sendMessageToPushWallet({ type: constants_1.APP_TO_WALLET_ACTION.SIGN_TYPED_DATA, data, }); }); }; // sending Message sign request to wallet based on which wallet is connected (external or pushwallet) const handleSignMessage = (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { let signature; if (externalWallet) { signature = yield handleExternalWalletSignRequest(data); } else { signature = yield handleSendSignRequestToPushWallet(data); } return signature; }); const handleSignAndSendTransaction = (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { let signature; if (externalWallet) { signature = yield handleExternalWalletSignTransactionRequest(data); } else { signature = yield handleSendSignTransactionRequestToPushWallet(data); } return signature; }); const handleSignTypedData = (data) => tslib_1.__awaiter(void 0, void 0, void 0, function* () { let signature; if (externalWallet) { signature = yield handleExternalWalletSignTypedDataRequest(data); } else { signature = yield handleSendSignTypedDataRequestToPushWallet(data); } return signature; }); // eslint-disable-next-line @typescript-eslint/no-empty-function const handleCloseIFrame = (0, react_1.useCallback)(() => { }, [universalAccount]); (0, react_1.useEffect)(() => { const messageHandler = (event) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j; if (((_a = iframeRef.current) === null || _a === void 0 ? void 0 : _a.contentWindow) !== event.source) return; switch (event.data.type) { case constants_1.WALLET_TO_APP_ACTION.CONNECT_EXTERNAL_WALLET: console.log('External wallet connection req'); handleExternalWalletConnection(event.data.data); break; case constants_1.WALLET_TO_APP_ACTION.IS_LOGGED_IN: console.log('wallet connected successfully', event.data); handleIsLoggedInAction(); break; case constants_1.WALLET_TO_APP_ACTION.APP_CONNECTION_SUCCESS: handleAppConnectionSuccess(event.data.data); break; case constants_1.WALLET_TO_APP_ACTION.APP_CONNECTION_REJECTED: handleAppConnectionRejection(); break; case constants_1.WALLET_TO_APP_ACTION.SIGN_MESSAGE: if (signatureResolverRef.current) { (_c = (_b = signatureResolverRef === null || signatureResolverRef === void 0 ? void 0 : signatureResolverRef.current) === null || _b === void 0 ? void 0 : _b.success) === null || _c === void 0 ? void 0 : _c.call(_b, event.data.data); } break; case constants_1.WALLET_TO_APP_ACTION.SIGN_TRANSACTION: if (signatureResolverRef.current) { (_e = (_d = signatureResolverRef === null || signatureResolverRef === void 0 ? void 0 : signatureResolverRef.current) === null || _d === void 0 ? void 0 : _d.success) === null || _e === void 0 ? void 0 : _e.call(_d, event.data.data); } break; case constants_1.WALLET_TO_APP_ACTION.SIGN_TYPED_DATA: if (signatureResolverRef.current) { (_g = (_f = signatureResolverRef === null || signatureResolverRef === void 0 ? void 0 : signatureResolverRef.current) === null || _f === void 0 ? void 0 : _f.success) === null || _g === void 0 ? void 0 : _g.call(_f, event.data.data); } break; case constants_1.WALLET_TO_APP_ACTION.IS_LOGGED_OUT: handleUserLogOutEvent(); break; case constants_1.WALLET_TO_APP_ACTION.ERROR: (_j = (_h = signatureResolverRef === null || signatureResolverRef === void 0 ? void 0 : signatureResolverRef.current) === null || _h === void 0 ? void 0 : _h.error) === null || _j === void 0 ? void 0 : _j.call(_h, event.data.data); break; case constants_1.WALLET_TO_APP_ACTION.CLOSE_IFRAME: if (universalAccount) setMinimiseWallet(true); else handleUserLogOutEvent(); break; default: console.warn('Unknown message type:', event.data.type); } }; window.addEventListener('message', messageHandler); return () => window.removeEventListener('message', messageHandler); }, [universalAccount]); const WalletContext = (0, WalletContextMap_1.getWalletContext)((config === null || config === void 0 ? void 0 : config.uid) || 'default'); const dummyProgress = { id: progress_hook_types_1.PROGRESS_HOOK.SEND_TX_99_01, title: 'Push Chain Tx Success', message: '', level: 'SUCCESS', response: null, timestamp: '', }; return ((0, jsx_runtime_1.jsxs)(WalletContext.Provider, { value: { app, config, connectionStatus, universalAccount, isWalletMinimised, modalAppData, themeMode, themeOverrides: {}, updateModalAppData, walletAppData, updateWalletAppData, setMinimiseWallet, handleConnectToPushWallet, handleUserLogOutEvent, handleSignMessage, handleSignAndSendTransaction, handleSignTypedData, toggleButtonRef, setProgress, }, children: [(0, jsx_runtime_1.jsx)(LoginModal_1.LoginModal, { iframeRef: iframeRef, themeMode: themeMode, modalAppData: modalAppData, isWalletVisible: isWalletVisible, isIframeLoading: isIframeLoading, setIframeLoading: setIframeLoading, sendWalletConfig: sendWalletConfig, config: config, universalAccount: universalAccount, isWalletMinimised: isWalletMinimised, setMinimiseWallet: setMinimiseWallet, handleUserLogOutEvent: handleUserLogOutEvent, toggleButtonRef: toggleButtonRef, sendMessageToPushWallet: sendMessageToPushWallet }), progress && ((0, jsx_runtime_1.jsx)(PushWalletToast_1.PushWalletToast, { progress: progress, setProgress: setProgress })), children] })); }; exports.WalletContextProvider = WalletContextProvider; //# sourceMappingURL=WalletContext.js.map