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 d862a02f92 - Show all commits

View File

@ -1,43 +1,20 @@
import { useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { Select, Option } from '@snowballtools/material-tailwind-react-fork'; import { Select, Option } from '@snowballtools/material-tailwind-react-fork';
import { VITE_LACONICD_CHAIN_ID } from 'utils/constants';
import {
VITE_LACONICD_CHAIN_ID,
} from 'utils/constants';
const IFrame = ({ const IFrame = ({
onAccountChange, onAccountChange,
}: { }: {
onAccountChange: (selectedAccount: string) => void; onAccountChange: (selectedAccount: string) => void;
}) => { }) => {
const [accounts, setAccounts] = useState<string[]>([]); const [accounts, setAccounts] = useState<string[]>([]);
useEffect(() => { useEffect(() => {
const getDataFromWallet = () => {
const iframe = document.getElementById('walletIframe') as HTMLIFrameElement;
if (!iframe.contentWindow) {
console.error('Iframe not found or not loaded');
return;
}
// Request data from wallet
iframe.contentWindow.postMessage({
type: 'REQUEST_WALLET_ACCOUNTS',
chainId: VITE_LACONICD_CHAIN_ID,
}, 'http://localhost:3001');
};
// Listen for response from wallet
const handleMessage = (event: MessageEvent) => { const handleMessage = (event: MessageEvent) => {
// Always verify origin for security
if (event.origin !== 'http://localhost:3001') return; if (event.origin !== 'http://localhost:3001') return;
if (event.data.type === 'WALLET_ACCOUNTS_DATA') { if (event.data.type === 'WALLET_ACCOUNTS_DATA') {
console.log('Received data:', event.data.data);
setAccounts(event.data.data); setAccounts(event.data.data);
// Handle the received data here
} else if (event.data.type === 'ERROR') { } else if (event.data.type === 'ERROR') {
console.error('Error from wallet:', event.data.message); console.error('Error from wallet:', event.data.message);
} }
@ -45,39 +22,55 @@ const IFrame = ({
window.addEventListener('message', handleMessage); window.addEventListener('message', handleMessage);
// Request data once iframe is loaded
const iframe = document.getElementById('walletIframe'); const iframe = document.getElementById('walletIframe');
if (iframe) { if (iframe) {
iframe.onload = getDataFromWallet; iframe.onload = getDataFromWallet;
} }
// Cleanup
return () => { return () => {
window.removeEventListener('message', handleMessage); window.removeEventListener('message', handleMessage);
}; };
}, []); }, []);
console.log({accounts}) const getDataFromWallet = useCallback(() => {
const iframe = document.getElementById('walletIframe') as HTMLIFrameElement;
if (!iframe.contentWindow) {
console.error('Iframe not found or not loaded');
return;
}
iframe.contentWindow.postMessage({
type: 'REQUEST_WALLET_ACCOUNTS',
chainId: VITE_LACONICD_CHAIN_ID,
}, 'http://localhost:3001');
}, []);
return ( return (
<div className="p-4 bg-slate-100 dark:bg-overlay3 rounded-lg mb-6"> <div className="p-6 bg-slate-100 dark:bg-overlay3 rounded-lg mb-6 shadow-md">
{accounts.length === 0 ? ( {!accounts.length ? (
<div> <div className="text-center">
no accounts.. go to 'store.laconic.com' to create wallet <p className="text-gray-700 dark:text-gray-300 mb-4">
No accounts found. Please visit{' '}
<a
href="https://store.laconic.com"
target="_blank"
rel="noopener noreferrer"
className="text-blue-600 underline dark:text-blue-400"
>
store.laconic.com
</a>{' '}
to create a wallet.
</p>
</div> </div>
) : ( ) : (
<div> <div>
<iframe
id="walletIframe"
src="http://localhost:3001/WalletEmbed"
sandbox="allow-scripts allow-same-origin"
></iframe>
<Select <Select
label="Select Account" label="Select Account"
defaultValue={accounts[0]} defaultValue={accounts[0]}
onChange={(value) => { onChange={(value) => value && onAccountChange(value)}
value && onAccountChange(value);
}}
className="dark:bg-overlay2 dark:text-foreground" className="dark:bg-overlay2 dark:text-foreground"
aria-label="Wallet Account Selector"
> >
{accounts.map((account, index) => ( {accounts.map((account, index) => (
<Option key={index} value={account}> <Option key={index} value={account}>
@ -87,6 +80,16 @@ const IFrame = ({
</Select> </Select>
</div> </div>
)} )}
<iframe
onLoad={getDataFromWallet}
id="walletIframe"
src="http://localhost:3001"
width="510"
height="300"
sandbox="allow-scripts allow-same-origin"
className="border rounded-md shadow-sm mt-4"
title="Wallet Integration"
></iframe>
</div> </div>
); );
}; };