laconic-wallet-web/src/hooks/useGetOrCreateAccounts.ts
shreerang 36208870ab Add component to support signing cosmos tx with custom messages (#27)
Part of https://www.notion.so/Stage0-onboarding-flow-1e4a6b22d47280aba3b5da3ed1154ff5

Co-authored-by: Shreerang Kale <shreerangkale@gmail.com>
Reviewed-on: #27
Co-authored-by: shreerang <shreerang@noreply.git.vdb.to>
Co-committed-by: shreerang <shreerang@noreply.git.vdb.to>
2025-05-06 13:19:54 +00:00

92 lines
3.0 KiB
TypeScript

import { useEffect, useCallback } from "react";
import { createWallet } from "../utils/accounts";
import { sendMessage } from "../utils/misc";
import useAccountsData from "./useAccountsData";
import { useNetworks } from "../context/NetworksContext";
import { useAccounts } from "../context/AccountsContext";
import { REQUEST_CREATE_OR_GET_ACCOUNTS, WALLET_ACCOUNTS_DATA } from "../utils/constants";
const REACT_APP_ALLOWED_URLS = process.env.REACT_APP_ALLOWED_URLS;
const useGetOrCreateAccounts = () => {
const { networksData } = useNetworks();
const { getAccountsData } = useAccountsData();
const { setAccounts } = useAccounts();
// Wrap the function in useCallback to prevent recreation on each render
const getOrCreateAccountsForChain = useCallback(async (chainId: string) => {
let accountsData = await getAccountsData(chainId);
if (accountsData.length === 0) {
console.log("Accounts not found, creating wallet...");
await createWallet(networksData);
accountsData = await getAccountsData(chainId);
}
// Update the AccountsContext with the new accounts
setAccounts(accountsData);
return accountsData;
}, [networksData, getAccountsData, setAccounts]);
useEffect(() => {
const handleCreateAccounts = async (event: MessageEvent) => {
if (event.data.type !== REQUEST_CREATE_OR_GET_ACCOUNTS) return;
if (!REACT_APP_ALLOWED_URLS) {
console.log('Allowed URLs are not set');
return;
}
const allowedUrls = REACT_APP_ALLOWED_URLS.split(',').map(url => url.trim());
if (!allowedUrls.includes(event.origin)) {
console.log('Unauthorized app.');
return;
}
const accountsData = await getOrCreateAccountsForChain(event.data.chainId);
const accountsAddressList = accountsData.map(account => account.address);
console.log('Sending WALLET_ACCOUNTS_DATA accounts:', accountsAddressList);
sendMessage(
event.source as Window, WALLET_ACCOUNTS_DATA,
accountsAddressList,
event.origin
);
};
const autoCreateAccounts = async () => {
const defaultChainId = networksData[0]?.chainId;
if (!defaultChainId) {
console.log('useGetOrCreateAccounts: No default chainId found');
return;
}
const accounts = await getOrCreateAccountsForChain(defaultChainId);
// Only notify Android when we actually have accounts
if (accounts.length > 0 && window.Android?.onAccountsReady) {
window.Android.onAccountsReady();
} else {
console.log('No accounts created or Android bridge not available');
}
};
window.addEventListener('message', handleCreateAccounts);
const isAndroidWebView = !!(window.Android);
if (isAndroidWebView) {
autoCreateAccounts();
}
return () => {
window.removeEventListener('message', handleCreateAccounts);
};
}, [networksData, getAccountsData, getOrCreateAccountsForChain]);
};
export default useGetOrCreateAccounts;