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 { useToast } from 'components/shared/Toast';
import { useGQLClient } from '../../../context/GQLClientContext';
import IFrame from './IFrame';
import EnvironmentVariablesForm from 'pages/org-slug/projects/id/settings/EnvironmentVariablesForm';
import { EnvironmentVariablesFormValues } from 'types/types';
import IFrame from './IFrame';
import { useWalletConnectClient } from 'context/WalletConnectContext';
import { VITE_LACONICD_CHAIN_ID } from 'utils/constants';
type ConfigureDeploymentFormValues = {
@ -39,8 +38,6 @@ type ConfigureFormValues = ConfigureDeploymentFormValues &
const DEFAULT_MAX_PRICE = '10000';
const Configure = () => {
const { signClient, session } = useWalletConnectClient();
const [isLoading, setIsLoading] = useState(false);
const [deployers, setDeployers] = useState<Deployer[]>([]);
const [selectedAccount, setSelectedAccount] = useState<string>();
@ -49,8 +46,6 @@ const Configure = () => {
const [isPaymentLoading, setIsPaymentLoading] = useState(false);
const [isPaymentDone, setIsPaymentDone] = useState(false);
const [isFrameVisible, setIsFrameVisible] = useState(false);
const [txHashr, setTxHash] = useState<string | null>(null);
const [isTransactionPending, setIsTransactionPending] = useState<boolean>(false);
const [searchParams] = useSearchParams();
const templateId = searchParams.get('templateId');
@ -188,7 +183,7 @@ const Configure = () => {
let amount: string;
let senderAddress: string;
let txHash: string;
let txHash;
if (createFormData.option === 'LRN' && !deployer?.minimumPayment) {
toast({
id: 'no-payment-required',
@ -202,7 +197,7 @@ const Configure = () => {
} else {
if (!selectedAccount) return;
senderAddress = selectedAccount.split(':')[2];
senderAddress = selectedAccount;
if (createFormData.option === 'LRN') {
amount = deployer?.minimumPayment!;
@ -214,30 +209,10 @@ const Configure = () => {
const amountToBePaid = amount.replace(/\D/g, '').toString();
await cosmosSendTokensHandler(
selectedAccount,
txHash = await cosmosSendTokensHandler(
senderAddress,
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(
@ -256,7 +231,7 @@ const Configure = () => {
createFormData,
environmentVariables,
senderAddress,
txHash,
txHash!,
);
await client.getEnvironmentVariables(projectId);
@ -264,19 +239,19 @@ const Configure = () => {
if (templateId) {
createFormData.option === 'Auction'
? navigate(
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
)
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
)
: navigate(
`/${orgSlug}/projects/create/template/deploy?projectId=${projectId}&templateId=${templateId}`,
);
`/${orgSlug}/projects/create/template/deploy?projectId=${projectId}&templateId=${templateId}`,
);
} else {
createFormData.option === 'Auction'
? navigate(
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
)
`/${orgSlug}/projects/create/success/${projectId}?isAuction=true`,
)
: navigate(
`/${orgSlug}/projects/create/deploy?projectId=${projectId}`,
);
`/${orgSlug}/projects/create/deploy?projectId=${projectId}`,
);
}
} catch (error) {
console.error(error);
@ -332,27 +307,72 @@ const Configure = () => {
onDismiss: dismiss,
});
await requestTx(senderAddress, snowballAddress, amount)
await requestTx(senderAddress, snowballAddress, amount);
await new Promise((resolve) => setTimeout(resolve, 10000));
return;
} catch (error: any) {
console.error('Error sending tokens', error);
const txHash = await new Promise<string>((resolve, reject) => {
const handleTxStatus = async (event: MessageEvent) => {
if (event.origin !== 'http://localhost:3001') return;
toast({
id: 'error-sending-tokens',
title: 'Error sending tokens',
variant: 'error',
onDismiss: dismiss,
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({
id: 'payment-successful',
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',
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,
});
}
window.removeEventListener('message', handleTxStatus);
};
window.addEventListener('message', handleTxStatus);
// Set a timeout, consider unsuccessful after 1 min
setTimeout(() => {
reject(new Error('Transaction timeout'));
window.removeEventListener('message', handleTxStatus);
}, 60000);
});
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?
return txHash;
} catch (error) {
console.error('Error in transaction:', error);
return;
} finally {
setIsPaymentLoading(false);
}
},
[session, signClient, toast],
[client, dismiss, toast],
);
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(() => {
fetchDeployers();
}, []);