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
Showing only changes of commit 6746b68793 - Show all commits

View File

@ -20,10 +20,9 @@ import { Button } from '../../shared/Button';
import { Input } from 'components/shared/Input'; import { Input } from 'components/shared/Input';
import { useToast } from 'components/shared/Toast'; import { useToast } from 'components/shared/Toast';
import { useGQLClient } from '../../../context/GQLClientContext'; import { useGQLClient } from '../../../context/GQLClientContext';
import IFrame from './IFrame';
import EnvironmentVariablesForm from 'pages/org-slug/projects/id/settings/EnvironmentVariablesForm'; import EnvironmentVariablesForm from 'pages/org-slug/projects/id/settings/EnvironmentVariablesForm';
import { EnvironmentVariablesFormValues } from 'types/types'; import { EnvironmentVariablesFormValues } from 'types/types';
import IFrame from './IFrame';
import { useWalletConnectClient } from 'context/WalletConnectContext';
import { VITE_LACONICD_CHAIN_ID } from 'utils/constants'; import { VITE_LACONICD_CHAIN_ID } from 'utils/constants';
type ConfigureDeploymentFormValues = { type ConfigureDeploymentFormValues = {
@ -39,8 +38,6 @@ type ConfigureFormValues = ConfigureDeploymentFormValues &
const DEFAULT_MAX_PRICE = '10000'; const DEFAULT_MAX_PRICE = '10000';
const Configure = () => { const Configure = () => {
const { signClient, session } = useWalletConnectClient();
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [deployers, setDeployers] = useState<Deployer[]>([]); const [deployers, setDeployers] = useState<Deployer[]>([]);
const [selectedAccount, setSelectedAccount] = useState<string>(); const [selectedAccount, setSelectedAccount] = useState<string>();
@ -49,8 +46,6 @@ 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');
@ -188,7 +183,7 @@ const Configure = () => {
let amount: string; let amount: string;
let senderAddress: string; let senderAddress: string;
let txHash: string; let txHash;
if (createFormData.option === 'LRN' && !deployer?.minimumPayment) { if (createFormData.option === 'LRN' && !deployer?.minimumPayment) {
toast({ toast({
id: 'no-payment-required', id: 'no-payment-required',
@ -202,7 +197,7 @@ const Configure = () => {
} else { } else {
if (!selectedAccount) return; if (!selectedAccount) return;
senderAddress = selectedAccount.split(':')[2]; senderAddress = selectedAccount;
if (createFormData.option === 'LRN') { if (createFormData.option === 'LRN') {
amount = deployer?.minimumPayment!; amount = deployer?.minimumPayment!;
@ -214,30 +209,10 @@ const Configure = () => {
const amountToBePaid = amount.replace(/\D/g, '').toString(); const amountToBePaid = amount.replace(/\D/g, '').toString();
await cosmosSendTokensHandler( txHash = await cosmosSendTokensHandler(
selectedAccount, senderAddress,
amountToBePaid, amountToBePaid,
); );
await new Promise((resolve) => setTimeout(resolve, 3000));
if (!txHashr) {
console.error('Tx not successful');
return;
}
txHash = txHashr;
const isTxHashValid = await verifyTx(
senderAddress,
txHash,
amountToBePaid.toString(),
);
if (isTxHashValid === false) {
console.error('Invalid Tx hash', txHash);
return;
}
} }
const environmentVariables = createFormData.variables.map( const environmentVariables = createFormData.variables.map(
@ -256,7 +231,7 @@ const Configure = () => {
createFormData, createFormData,
environmentVariables, environmentVariables,
senderAddress, senderAddress,
txHash, txHash!,
); );
await client.getEnvironmentVariables(projectId); await client.getEnvironmentVariables(projectId);
@ -332,27 +307,72 @@ const Configure = () => {
onDismiss: dismiss, onDismiss: dismiss,
}); });
await requestTx(senderAddress, snowballAddress, amount) await requestTx(senderAddress, snowballAddress, amount);
await new Promise((resolve) => setTimeout(resolve, 10000)); const txHash = await new Promise<string>((resolve, reject) => {
return; const handleTxStatus = async (event: MessageEvent) => {
} catch (error: any) { if (event.origin !== 'http://localhost:3001') return;
console.error('Error sending tokens', error);
if (event.data.type === 'TRANSACTION_SUCCESS') {
const txResponse = event.data.data;
setIsFrameVisible(false);
// Validate transaction hash
const isTxHashValid = await verifyTx(
senderAddress,
txResponse,
amount,
);
if (isTxHashValid) {
resolve(txResponse);
toast({ toast({
id: 'error-sending-tokens', id: 'payment-successful',
title: 'Error sending tokens', title: 'Payment successful',
variant: 'success',
onDismiss: dismiss,
});
} else {
reject(new Error('Invalid transaction hash'));
toast({
id: 'invalid-tx-hash',
title: 'Transaction validation failed',
variant: 'error', variant: 'error',
onDismiss: dismiss, onDismiss: dismiss,
}); });
}
} else if (event.data.type === 'ERROR') {
console.error('Error from wallet:', event.data.message);
reject(new Error('Transaction failed'));
toast({
id: 'error-transaction',
title: 'Error during transaction',
variant: 'error',
onDismiss: dismiss,
});
}
setIsPaymentDone(false); window.removeEventListener('message', handleTxStatus);
// should return the txhash but we arw checking for it in the gettxstatus useeffect.. how do i return it after it is found? };
window.addEventListener('message', handleTxStatus);
// Set a timeout, consider unsuccessful after 1 min
setTimeout(() => {
reject(new Error('Transaction timeout'));
window.removeEventListener('message', handleTxStatus);
}, 60000);
});
return txHash;
} catch (error) {
console.error('Error in transaction:', error);
return;
} finally { } finally {
setIsPaymentLoading(false); setIsPaymentLoading(false);
} }
}, },
[session, signClient, toast], [client, dismiss, toast],
); );
const requestTx = async (sender: string, recipient: string, amount: string,) => { const requestTx = async (sender: string, recipient: string, amount: string,) => {
@ -375,42 +395,6 @@ const Configure = () => {
); );
}; };
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();
}, []); }, []);