@pushchain/ui-kit
Version:
## Overview
384 lines • 18.6 kB
JavaScript
;
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