UNPKG

@coin-voyage/paykit

Version:

Seamless crypto payments. Onboard users from any chain, any coin into your app with one click.

160 lines (159 loc) 6.09 kB
import { useAccount } from "@coin-voyage/crypto/hooks"; import { zPayOrder } from "@coin-voyage/shared/common"; import { ChainType, PayOrderMode } from "@coin-voyage/shared/types"; import { useResolveSuiNSName } from "@mysten/dapp-kit"; import { useCallback, useState } from "react"; import { mainnet } from "viem/chains"; import { useEnsName } from "wagmi"; import { useBackendApi } from "../components/contexts/api"; import { ROUTES } from "../types/routes"; import { usePayOrderQuotes } from "./usePayOrderQuotes"; import { usePayToAddress } from "./usePayToAddress"; import { usePayFromWallet } from "./usePayWithToken"; export function usePaymentState({ payOrder, setPayOrder, setRoute, log, }) { const api = useBackendApi(); const [connectorChainType, setConnectorChainType] = useState(); const [selectedWallet, setSelectedWallet] = useState(); const { account: senderAccount } = useAccount({ selectedWallet, chainType: connectorChainType, }); const { data: suiEnsName } = useResolveSuiNSName(senderAccount.address, { enabled: !!senderAccount.address && senderAccount.chainType === ChainType.SUI && senderAccount.isConnected, }); const { data: evmEnsName } = useEnsName({ chainId: mainnet.id, address: senderAccount.address, query: { enabled: !!senderAccount.address && senderAccount.chainType === ChainType.EVM && senderAccount.isConnected, }, }); const payOrderQuotes = usePayOrderQuotes({ payOrder, address: senderAccount.address, chainType: connectorChainType, }); const [selectedCurrencyOption, setSelectedCurrencyOption] = useState(); const [paymentMethod, setPaymentMethod] = useState(); const [payToAddressChainId, setPayToAddressChainId] = useState(); const [payToAddressCurrency, setPayToAddressCurrency] = useState(); const { payFromWallet } = usePayFromWallet({ senderAddr: senderAccount.address, payOrder, setPayOrder, chainType: connectorChainType, log, }); const { payToAddress } = usePayToAddress({ payOrder, setPayOrder, log, }); const fetchPayOrder = useCallback(async (id) => { const { data: order, error } = await api.getPayOrder(id); if (!order || error) { log(`[CHECKOUT] No order found for ${id}: ${JSON.stringify(error)}`); return undefined; } return order; }, [api, log]); const refreshOrder = useCallback(async () => { if (!payOrder?.id) return; const order = await fetchPayOrder(payOrder.id); if (order) setPayOrder(order); }, [payOrder, fetchPayOrder, setPayOrder]); const setPayOrderId = useCallback(async (payOrderId) => { if (!payOrderId || payOrder?.id === payOrderId) return; const order = await fetchPayOrder(payOrderId); if (order) setPayOrder(order); }, [payOrder, fetchPayOrder, setPayOrder]); const copyDepositPayOrder = useCallback(async () => { if (!payOrder?.id) { log(`No payOrder to copy`); return; } if (payOrder.mode !== PayOrderMode.DEPOSIT) { log(`Cannot recreate SALE order`); return; } const asset = payOrder.fulfillment.asset; const { data, error } = await api.createDepositPayOrder({ intent: { asset, amount: { ...(asset ? { token_amount: payOrder.fulfillment.amount.ui_amount } : {}), ...(payOrder.fulfillment.fiat ? { fiat: { amount: payOrder.fulfillment.amount.value_usd, unit: payOrder.fulfillment.fiat, }, } : {}), }, receiving_address: payOrder.fulfillment.receiving_address, }, metadata: payOrder.metadata, }); if (!data || error) { log(`[CHECKOUT] Error creating payOrder: ${JSON.stringify(error)}`); return; } await setPayOrderId(data.id); }, [api, payOrder, log, setPayOrderId]); const createDepositPayOrder = useCallback(async (params, onError) => { try { const result = zPayOrder.safeParse(params); if (result.error) { onError?.(`[CREATE DEPOSIT]: ${result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ")}`); return; } const { data: payOrder, error } = await api.createDepositPayOrder(params); if (!payOrder || error) { log(`[CREATE DEPOSIT] Error creating payOrder: ${JSON.stringify(error)}`); return; } setPayOrder(payOrder); } catch (e) { if (e instanceof Error) onError?.(e.message); else onError?.("Unknown error"); } }, [api, setPayOrder, log]); const clearUserSelection = useCallback(() => { setSelectedCurrencyOption(undefined); setConnectorChainType(undefined); setSelectedWallet(undefined); setRoute(ROUTES.SELECT_METHOD); }, [setRoute]); return { setPayId: setPayOrderId, createDepositPayOrder, copyDepositPayOrder, clearUserSelection, payOrder, paymentMethod, setPaymentMethod, connectorChainType, setConnectorChainType, selectedWallet, setSelectedWallet, selectedCurrencyOption, setSelectedCurrencyOption, payOrderQuotes, payFromWallet, payToAddress, refreshOrder, senderEnsName: evmEnsName ?? suiEnsName ?? undefined, payToAddressChainId, setPayToAddressChainId, payToAddressCurrency, setPayToAddressCurrency, }; }