@coin-voyage/paykit
Version:
Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.
79 lines (78 loc) • 3.1 kB
JavaScript
import { useAccount, useUniversalConnect } from "@coin-voyage/crypto/hooks";
import { ChainType } from "@coin-voyage/shared/types";
import { useEffect, useRef, useState } from "react";
import usePayContext from "../components/contexts/pay";
import { ROUTES } from "../types/routes";
import { useWallets } from "./useWallets";
export function useWalletConnectUri({ enabled } = { enabled: true }) {
const { log, setRoute, paymentState } = usePayContext();
const { connectorChainType } = paymentState;
const [uri, setUri] = useState();
const wallets = useWallets();
const wcWallet = wallets.find((w) => w.id === "walletConnect");
const wcConnector = wcWallet?.connectors.find((c) => c.chainType === connectorChainType)?.connector;
const { account } = useAccount({
selectedWallet: wcWallet,
chainType: connectorChainType,
});
const { connect } = useUniversalConnect({
onError: (err) => log("WC Connect Error", err),
onSuccess: () => {
setUri(undefined);
setRoute(ROUTES.SELECT_TOKEN);
},
});
const isConnectingRef = useRef(false);
const listenersAttachedRef = useRef(false);
useEffect(() => {
if (!wcConnector)
return;
const evmConnector = wcConnector;
if (!evmConnector?.emitter || listenersAttachedRef.current)
return;
listenersAttachedRef.current = true;
log("add wc listeners");
const handleMessage = (message) => {
if (message.type === "display_uri" && typeof message.data === "string") {
setUri(message.data);
}
};
const handleDisconnect = () => {
log("WC Disconnect");
isConnectingRef.current = false;
};
evmConnector.emitter.on("message", handleMessage);
evmConnector.emitter.on("disconnect", handleDisconnect);
return () => {
log("remove wc listeners");
listenersAttachedRef.current = false;
evmConnector.emitter.off("message", handleMessage);
evmConnector.emitter.off("disconnect", handleDisconnect);
};
}, [wcConnector, log]);
useEffect(() => {
if (!enabled || !wcConnector || account.isConnected || isConnectingRef.current) {
return;
}
isConnectingRef.current = true;
const connectWalletConnect = async () => {
try {
await connect({
walletConnector: {
connector: wcConnector,
chainType: connectorChainType ?? ChainType.EVM,
},
});
}
catch (error) {
isConnectingRef.current = false;
log("WC error", error);
if (error?.code === 4001) {
log("User rejected - regenerating QR");
}
}
};
connectWalletConnect();
}, [enabled, wcConnector, account.isConnected, connectorChainType, connect, log]);
return { uri };
}