Integrate wallet IFrame for payments #42

Merged
nabarun merged 27 commits from iv-integrate-frame into main 2024-11-13 13:32:28 +00:00
2 changed files with 73 additions and 37 deletions
Showing only changes of commit 3a087cbf8d - Show all commits

View File

@ -24,6 +24,7 @@ import EnvironmentVariablesForm from 'pages/org-slug/projects/id/settings/Enviro
import { EnvironmentVariablesFormValues } from 'types/types'; import { EnvironmentVariablesFormValues } from 'types/types';
import IFrame from './IFrame'; import IFrame from './IFrame';
import { useWalletConnectClient } from 'context/WalletConnectContext'; import { useWalletConnectClient } from 'context/WalletConnectContext';
import { VITE_LACONICD_CHAIN_ID } from 'utils/constants';
type ConfigureDeploymentFormValues = { type ConfigureDeploymentFormValues = {
option: string; option: string;
@ -48,6 +49,8 @@ const Configure = () => {
const [isPaymentLoading, setIsPaymentLoading] = useState(false); const [isPaymentLoading, setIsPaymentLoading] = useState(false);
const [isPaymentDone, setIsPaymentDone] = useState(false); const [isPaymentDone, setIsPaymentDone] = useState(false);
const [isFrameVisible, setIsFrameVisible] = useState(false); const [isFrameVisible, setIsFrameVisible] = useState(false);
const [txHashr, setTxHash] = useState<string | null>(null);
const [isTransactionPending, setIsTransactionPending] = useState<boolean>(false);
const [searchParams] = useSearchParams(); const [searchParams] = useSearchParams();
const templateId = searchParams.get('templateId'); const templateId = searchParams.get('templateId');
@ -211,17 +214,19 @@ const Configure = () => {
const amountToBePaid = amount.replace(/\D/g, '').toString(); const amountToBePaid = amount.replace(/\D/g, '').toString();
const txHashResponse = await cosmosSendTokensHandler( await cosmosSendTokensHandler(
selectedAccount, selectedAccount,
amountToBePaid, amountToBePaid,
); );
if (!txHashResponse) { await new Promise((resolve) => setTimeout(resolve, 3000));
if (!txHashr) {
console.error('Tx not successful'); console.error('Tx not successful');
return; return;
} }
txHash = txHashResponse; txHash = txHashr;
const isTxHashValid = await verifyTx( const isTxHashValid = await verifyTx(
senderAddress, senderAddress,
@ -309,12 +314,11 @@ const Configure = () => {
const cosmosSendTokensHandler = useCallback( const cosmosSendTokensHandler = useCallback(
async (selectedAccount: string, amount: string) => { async (selectedAccount: string, amount: string) => {
if (!signClient || !session || !selectedAccount) { if (!selectedAccount) {
return; return;
} }
const chainId = selectedAccount.split(':')[1]; const senderAddress = selectedAccount;
const senderAddress = selectedAccount.split(':')[2];
const snowballAddress = await client.getAddress(); const snowballAddress = await client.getAddress();
try { try {
@ -328,35 +332,10 @@ const Configure = () => {
onDismiss: dismiss, onDismiss: dismiss,
}); });
const result: { signature: string } = await signClient.request({ await requestTx(senderAddress, snowballAddress, amount)
topic: session.topic,
chainId: `cosmos:${chainId}`,
request: {
method: 'cosmos_sendTokens',
params: [
{
from: senderAddress,
to: snowballAddress,
value: amount,
},
],
},
});
if (!result) { await new Promise((resolve) => setTimeout(resolve, 10000));
throw new Error('Error completing transaction'); return;
}
toast({
id: 'payment-successful',
title: 'Payment successful',
variant: 'success',
onDismiss: dismiss,
});
setIsPaymentDone(true);
return result.signature;
} catch (error: any) { } catch (error: any) {
console.error('Error sending tokens', error); console.error('Error sending tokens', error);
@ -368,6 +347,7 @@ const Configure = () => {
}); });
setIsPaymentDone(false); setIsPaymentDone(false);
// should return the txhash but we arw checking for it in the gettxstatus useeffect.. how do i return it after it is found?
} finally { } finally {
setIsPaymentLoading(false); setIsPaymentLoading(false);
} }
@ -375,6 +355,62 @@ const Configure = () => {
[session, signClient, toast], [session, signClient, toast],
); );
const requestTx = async (sender: string, recipient: string, amount: string,) => {
const iframe = document.getElementById('walletIframe') as HTMLIFrameElement;
if (!iframe.contentWindow) {
console.error('Iframe not found or not loaded');
return;
}
iframe.contentWindow.postMessage(
{
type: 'REQUEST_TX',
chainId: VITE_LACONICD_CHAIN_ID,
fromAddress: sender,
toAddress: recipient,
amount,
},
'http://localhost:3001'
);
};
useEffect(() => {
// Define the event listener to listen for transaction status
const getTxStatus = (event: MessageEvent) => {
// Ensure you're handling the message only from the correct origin
if (event.origin !== 'http://localhost:3001') return;
if (event.data.type === 'TRANSACTION_SUCCESS') {
console.log('Transaction Success:', event.data.transactionHash);
setTxHash(event.data.transactionHash);
console.log(event.data.transactionHash)
setIsTransactionPending(false);
console.log({txHashr})
toast({
id: 'payment-successful',
title: 'Payment successful',
variant: 'success',
onDismiss: dismiss,
});
setIsPaymentDone(true);
} else if (event.data.type === 'ERROR') {
console.error('Error from wallet:', event.data.message);
setIsTransactionPending(false); // Mark the transaction as failed
}
};
// Add the event listener to listen for 'message' events
window.addEventListener('message', getTxStatus);
// Cleanup: Remove the event listener when the component unmounts
return () => {
window.removeEventListener('message', getTxStatus);
};
}, []);
useEffect(() => { useEffect(() => {
fetchDeployers(); fetchDeployers();
}, []); }, []);

View File

@ -88,7 +88,7 @@ const IFrame = ({
</Select> </Select>
</div> </div>
)} )}
<Modal open={isVisible} onClose={toggleModal}> <Modal open={isVisible} onClose={toggleModal} keepMounted>
<Box <Box
sx={{ sx={{
position: 'absolute', position: 'absolute',
@ -112,14 +112,14 @@ const IFrame = ({
></iframe> ></iframe>
</Box> </Box>
</Modal> </Modal>
<iframe {/* <iframe
onLoad={getDataFromWallet} onLoad={getDataFromWallet}
id="walletIframe" id="walletIframe"
src="http://localhost:3001" src="http://localhost:3001"
width="0" width="0"
height="0" height="0"
sandbox="allow-scripts allow-same-origin" sandbox="allow-scripts allow-same-origin"
></iframe> ></iframe> */}
</div> </div>
); );
}; };