"use client"; import { useEffect } from "react"; import type { Token } from "../../../../bridge/types/Token.js"; import type { ThirdwebClient } from "../../../../client/client.js"; import type { PurchaseData } from "../../../../pay/types.js"; import { toUnits } from "../../../../utils/units.js"; import { type BridgePrepareRequest, type BridgePrepareResult, type UseBridgePrepareParams, useBridgePrepare, } from "../../../core/hooks/useBridgePrepare.js"; import { Container } from "../components/basic.js"; import { Spacer } from "../components/Spacer.js"; import { Spinner } from "../components/Spinner.js"; import { Text } from "../components/text.js"; import type { PaymentMethod } from "./types.js"; interface QuoteLoaderProps { /** * The destination token to bridge to */ destinationToken: Token; /** * The payment method to use */ paymentMethod: PaymentMethod; /** * The amount to bridge (as string) */ amount: string; /** * The sender address */ sender: string | undefined; /** * The receiver address */ receiver: string; /** * ThirdwebClient for API calls */ client: ThirdwebClient; /** * Called when a quote is successfully received */ onQuoteReceived: ( preparedQuote: BridgePrepareResult, request: BridgePrepareRequest, ) => void; /** * Called when an error occurs */ onError: (error: Error) => void; /** * Called when user wants to go back */ onBack: (() => void) | undefined; /** * Optional purchase data for the payment */ purchaseData: PurchaseData | undefined; /** * Optional payment link ID for the payment */ paymentLinkId: string | undefined; feePayer: "sender" | "receiver" | undefined; mode: "direct_payment" | "fund_wallet" | "transaction"; } export function QuoteLoader({ destinationToken, paymentMethod, amount, sender, receiver, client, onQuoteReceived, onError, purchaseData, paymentLinkId, feePayer, mode: _mode, }: QuoteLoaderProps) { const request: BridgePrepareRequest = getBridgeParams({ amount, client, destinationToken, feePayer, paymentLinkId, paymentMethod, purchaseData, receiver, sender, }); const prepareQuery = useBridgePrepare(request); // Handle successful quote useEffect(() => { if (prepareQuery.data) { onQuoteReceived(prepareQuery.data, request); } }, [prepareQuery.data, onQuoteReceived, request]); // Handle errors useEffect(() => { if (prepareQuery.error) { onError(prepareQuery.error as Error); } }, [prepareQuery.error, onError]); return ( Finding the best route We're searching for the most efficient path for this payment. ); } function getBridgeParams(args: { paymentMethod: PaymentMethod; amount: string; destinationToken: Token; receiver: string; client: ThirdwebClient; sender?: string; feePayer?: "sender" | "receiver"; purchaseData?: PurchaseData; paymentLinkId?: string; }): UseBridgePrepareParams { const { paymentMethod, amount, destinationToken, receiver, client, sender } = args; switch (paymentMethod.type) { case "fiat": return { amount: toUnits(amount, destinationToken.decimals), chainId: destinationToken.chainId, client, currency: paymentMethod.currency, enabled: !!(destinationToken && amount && client), onramp: paymentMethod.onramp || "coinbase", paymentLinkId: args.paymentLinkId, purchaseData: args.purchaseData, receiver, sender, // always onramp to native token tokenAddress: destinationToken.address, type: "onramp", }; case "wallet": // if the origin token is the same as the destination token, use transfer type if ( paymentMethod.originToken.chainId === destinationToken.chainId && paymentMethod.originToken.address.toLowerCase() === destinationToken.address.toLowerCase() ) { return { amount: toUnits(amount, destinationToken.decimals), chainId: destinationToken.chainId, client, enabled: !!(destinationToken && amount && client), feePayer: args.feePayer || "sender", paymentLinkId: args.paymentLinkId, purchaseData: args.purchaseData, receiver, sender: sender || paymentMethod.payerWallet.getAccount()?.address || receiver, tokenAddress: destinationToken.address, type: "transfer", }; } return { amount: paymentMethod.action === "buy" ? toUnits(amount, destinationToken.decimals) : toUnits(amount, paymentMethod.originToken.decimals), client, destinationChainId: destinationToken.chainId, destinationTokenAddress: destinationToken.address, enabled: !!(destinationToken && amount && client), originChainId: paymentMethod.originToken.chainId, originTokenAddress: paymentMethod.originToken.address, paymentLinkId: args.paymentLinkId, purchaseData: args.purchaseData, receiver, sender: sender || paymentMethod.payerWallet.getAccount()?.address || receiver, type: paymentMethod.action, }; } }