diff --git a/.changeset/old-bats-love.md b/.changeset/old-bats-love.md
new file mode 100644
index 00000000000..a6d8628e0a6
--- /dev/null
+++ b/.changeset/old-bats-love.md
@@ -0,0 +1,5 @@
+---
+"thirdweb": patch
+---
+
+A number of important fixes for payment widgets
diff --git a/packages/thirdweb/src/bridge/Onramp.ts b/packages/thirdweb/src/bridge/Onramp.ts
index e56aba9b738..582ef5337be 100644
--- a/packages/thirdweb/src/bridge/Onramp.ts
+++ b/packages/thirdweb/src/bridge/Onramp.ts
@@ -1,4 +1,5 @@
import type { Address as ox__Address } from "ox";
+import { defineChain } from "../chains/utils.js";
import type { ThirdwebClient } from "../client/client.js";
import { getThirdwebBaseUrl } from "../utils/domains.js";
import { getClientFetch } from "../utils/fetch.js";
@@ -237,6 +238,8 @@ export async function prepare(
originAmount: BigInt(step.originAmount),
transactions: step.transactions.map((tx) => ({
...tx,
+ chain: defineChain(tx.chainId),
+ client,
value: tx.value ? BigInt(tx.value) : undefined,
})),
}));
diff --git a/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts b/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts
index 2f7dc0648c1..a5851030826 100644
--- a/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts
+++ b/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts
@@ -326,7 +326,7 @@ export async function getBuyWithFiatQuote(
maxSteps: 2,
onramp: onrampProvider,
onrampChainId: params.onrampChainId,
- onrampTokenAddress: params.onrampTokenAddress ?? NATIVE_TOKEN_ADDRESS,
+ onrampTokenAddress: params.onrampTokenAddress,
paymentLinkId: params.paymentLinkId,
purchaseData: params.purchaseData,
receiver: params.toAddress, // force onramp to native token to avoid missing gas issues
diff --git a/packages/thirdweb/src/react/core/hooks/useStepExecutor.ts b/packages/thirdweb/src/react/core/hooks/useStepExecutor.ts
index 53bad596148..4754b1aae13 100644
--- a/packages/thirdweb/src/react/core/hooks/useStepExecutor.ts
+++ b/packages/thirdweb/src/react/core/hooks/useStepExecutor.ts
@@ -237,6 +237,7 @@ export function useStepExecutor(
if (tx.action === "approval" || tx.action === "fee") {
// don't poll status for approval transactions, just wait for confirmation
await waitForReceipt(result);
+ await new Promise((resolve) => setTimeout(resolve, 1000)); // Add an extra second delay for RPC to catch up to new state
return;
}
diff --git a/packages/thirdweb/src/react/web/ui/Bridge/QuoteLoader.tsx b/packages/thirdweb/src/react/web/ui/Bridge/QuoteLoader.tsx
index e71cc1ca6f7..fe2603a01e2 100644
--- a/packages/thirdweb/src/react/web/ui/Bridge/QuoteLoader.tsx
+++ b/packages/thirdweb/src/react/web/ui/Bridge/QuoteLoader.tsx
@@ -4,7 +4,6 @@ import { useEffect } from "react";
import { trackPayEvent } from "../../../../analytics/track/pay.js";
import type { Token } from "../../../../bridge/types/Token.js";
import type { ThirdwebClient } from "../../../../client/client.js";
-import { NATIVE_TOKEN_ADDRESS } from "../../../../constants/addresses.js";
import { toUnits } from "../../../../utils/units.js";
import {
type BridgePrepareRequest,
@@ -191,7 +190,6 @@ function getBridgeParams(args: {
currency: paymentMethod.currency,
enabled: !!(destinationToken && amount && client),
onramp: paymentMethod.onramp || "coinbase",
- onrampTokenAddress: NATIVE_TOKEN_ADDRESS,
paymentLinkId: args.paymentLinkId,
purchaseData: args.purchaseData,
receiver,
diff --git a/packages/thirdweb/src/react/web/ui/Bridge/StepRunner.tsx b/packages/thirdweb/src/react/web/ui/Bridge/StepRunner.tsx
index 0e5690fb70f..c0c5266271a 100644
--- a/packages/thirdweb/src/react/web/ui/Bridge/StepRunner.tsx
+++ b/packages/thirdweb/src/react/web/ui/Bridge/StepRunner.tsx
@@ -322,7 +322,8 @@ export function StepRunner({
- TEST
+ {request.onramp.slice(0, 1).toUpperCase() +
+ request.onramp.slice(1)}
{getStepStatusText(onrampStatus)}
diff --git a/packages/thirdweb/src/react/web/ui/Bridge/payment-details/PaymentDetails.tsx b/packages/thirdweb/src/react/web/ui/Bridge/payment-details/PaymentDetails.tsx
index b15b369b28a..9ce301eb502 100644
--- a/packages/thirdweb/src/react/web/ui/Bridge/payment-details/PaymentDetails.tsx
+++ b/packages/thirdweb/src/react/web/ui/Bridge/payment-details/PaymentDetails.tsx
@@ -1,9 +1,11 @@
"use client";
import { useQuery } from "@tanstack/react-query";
+import { useMemo } from "react";
import { trackPayEvent } from "../../../../../analytics/track/pay.js";
import type { ThirdwebClient } from "../../../../../client/client.js";
import { useCustomTheme } from "../../../../core/design-system/CustomThemeProvider.js";
import { radius, spacing } from "../../../../core/design-system/index.js";
+import { useChainsQuery } from "../../../../core/hooks/others/useChainQuery.js";
import type { BridgePrepareResult } from "../../../../core/hooks/useBridgePrepare.js";
import type { PaymentMethod } from "../../../../core/machines/paymentMachine.js";
import {
@@ -102,6 +104,15 @@ export function PaymentDetails({
queryKey: ["payment_details", preparedQuote.type],
});
+ const chainsQuery = useChainsQuery(
+ preparedQuote.steps.flatMap((s) => s.transactions.map((t) => t.chain)),
+ 10,
+ );
+ const chainsMetadata = useMemo(
+ () => chainsQuery.map((c) => c.data),
+ [chainsQuery],
+ ).filter((c) => !!c);
+
// Extract common data based on quote type
const getDisplayData = () => {
switch (preparedQuote.type) {
@@ -321,12 +332,48 @@ export function PaymentDetails({
>
- {step.originToken.symbol} →{" "}
- {step.destinationToken.symbol}
+ {step.destinationToken.chainId !==
+ step.originToken.chainId ? (
+ <>
+ Bridge{" "}
+ {step.originToken.symbol ===
+ step.destinationToken.symbol
+ ? step.originToken.symbol
+ : `${step.originToken.symbol} to ${step.destinationToken.symbol}`}
+ >
+ ) : (
+ <>
+ Swap {step.originToken.symbol} to{" "}
+ {step.destinationToken.symbol}
+ >
+ )}
- {step.originToken.name} to{" "}
- {step.destinationToken.name}
+ {step.originToken.chainId !==
+ step.destinationToken.chainId ? (
+ <>
+ {
+ chainsMetadata.find(
+ (c) => c.chainId === step.originToken.chainId,
+ )?.name
+ }{" "}
+ to{" "}
+ {
+ chainsMetadata.find(
+ (c) =>
+ c.chainId === step.destinationToken.chainId,
+ )?.name
+ }
+ >
+ ) : (
+ <>
+ {
+ chainsMetadata.find(
+ (c) => c.chainId === step.originToken.chainId,
+ )?.name
+ }
+ >
+ )}
diff --git a/packages/thirdweb/src/react/web/ui/Bridge/payment-selection/FiatProviderSelection.tsx b/packages/thirdweb/src/react/web/ui/Bridge/payment-selection/FiatProviderSelection.tsx
index c9107df5fbf..d76b27717fd 100644
--- a/packages/thirdweb/src/react/web/ui/Bridge/payment-selection/FiatProviderSelection.tsx
+++ b/packages/thirdweb/src/react/web/ui/Bridge/payment-selection/FiatProviderSelection.tsx
@@ -71,6 +71,16 @@ export function FiatProviderSelection({
return quoteQueries.map((q) => q.data).filter((q) => !!q);
}, [quoteQueries]);
+ if (quoteQueries.every((q) => q.isError)) {
+ return (
+
+
+ No quotes available
+
+
+ );
+ }
+
// TODO: add a "remember my choice" checkbox
return (