Skip to content

Commit 8e0a3ce

Browse files
authored
Integrate Pay Modal with TransactionButton, disable Pay Modal for gasless (#2933)
1 parent 86105c9 commit 8e0a3ce

File tree

4 files changed

+115
-11
lines changed

4 files changed

+115
-11
lines changed

.changeset/tender-ghosts-enjoy.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
"thirdweb": patch
3+
---
4+
5+
### Integrate Pay Modal with TransactionButton
6+
7+
By default, the Pay Modal is integrated with the `TransactionButton` component. If the user performs a transaction and does not have enough funds to execute it and if [thirdweb pay](https://portal.thirdweb.com/connect/pay/buy-with-crypto) is available for that blockchain, the Pay Modal will be displayed to allow user to buy the required amount of tokens
8+
9+
A new prop `payModal` is added to the `TransactionButton` component customize the Pay Modal UI or disable it entirely
10+
11+
Example: Disable Pay Modal
12+
13+
```tsx
14+
<TransactionButton payModal={false}> Example 1 </TransactionButton>
15+
```
16+
17+
Example: Customize Pay Modal UI
18+
19+
```tsx
20+
<TransactionButton
21+
payModal={{
22+
theme: "light",
23+
}}
24+
>
25+
Example 2
26+
</TransactionButton>
27+
```
28+
29+
### Disable Pay Modal for certain configurations in `useSendTransaction` hook
30+
31+
If `useSendTransaction` hook is passed `gasless: true` configuration or if current active wallet is a smart wallet with `sponsorGas: true` configuration - the Pay Modal will be disabled

packages/thirdweb/src/exports/react.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export { useReadContract } from "../react/core/hooks/contract/useReadContract.js
6161
export {
6262
useSendTransaction,
6363
type SendTransactionConfig,
64+
type SendTransactionPayModalConfig,
6465
} from "../react/web/hooks/useSendTransaction.js";
6566
export { useSendBatchTransaction } from "../react/core/hooks/contract/useSendBatchTransaction.js";
6667
export { useSendAndConfirmTransaction } from "../react/core/hooks/contract/useSendAndConfirmTransaction.js";

packages/thirdweb/src/react/web/hooks/useSendTransaction.tsx

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { useContext, useState } from "react";
22
import type { ThirdwebClient } from "../../../client/client.js";
33
import type { GaslessOptions } from "../../../transaction/actions/gasless/types.js";
44
import type { PreparedTransaction } from "../../../transaction/prepare-transaction.js";
5+
import type { Wallet } from "../../../wallets/interfaces/wallet.js";
56
import { useSendTransactionCore } from "../../core/hooks/contract/useSendTransaction.js";
7+
import { useActiveWallet } from "../../core/hooks/wallets/wallet-hooks.js";
68
import { SetRootElementContext } from "../../core/providers/RootElementContext.js";
79
import {
810
type SupportedTokens,
@@ -17,6 +19,34 @@ import type { Theme } from "../ui/design-system/index.js";
1719
import type { LocaleId } from "../ui/types.js";
1820
import { LoadingScreen } from "../wallets/shared/LoadingScreen.js";
1921

22+
/**
23+
* Configuration for the "Pay Modal" that opens when the user doesn't have enough funds to send a transaction.
24+
* Set `payModal: false` to disable the "Pay Modal" popup
25+
*
26+
* This configuration object includes the following properties to configure the "Pay Modal" UI:
27+
*
28+
* ### `locale`
29+
* The language to use for the "Pay Modal" UI. Defaults to `"en_US"`.
30+
*
31+
* ### `supportedTokens`
32+
* An object of type [`SupportedTokens`](https://portal.thirdweb.com/references/typescript/v5/SupportedTokens) to configure the tokens to show for a chain.
33+
*
34+
* ### `theme`
35+
* The theme to use for the "Pay Modal" UI. Defaults to `"dark"`.
36+
*
37+
* It can be set to `"light"` or `"dark"` or an object of type [`Theme`](https://portal.thirdweb.com/references/typescript/v5/Theme) for a custom theme.
38+
*
39+
* Refer to [`lightTheme`](https://portal.thirdweb.com/references/typescript/v5/lightTheme)
40+
* or [`darkTheme`](https://portal.thirdweb.com/references/typescript/v5/darkTheme) helper functions to use the default light or dark theme and customize it.
41+
*/
42+
export type SendTransactionPayModalConfig =
43+
| {
44+
locale?: LocaleId;
45+
supportedTokens?: SupportedTokens;
46+
theme?: Theme | "light" | "dark";
47+
}
48+
| false;
49+
2050
/**
2151
* Configuration for the `useSendTransaction` hook.
2252
*/
@@ -41,14 +71,7 @@ export type SendTransactionConfig = {
4171
* Refer to [`lightTheme`](https://portal.thirdweb.com/references/typescript/v5/lightTheme)
4272
* or [`darkTheme`](https://portal.thirdweb.com/references/typescript/v5/darkTheme) helper functions to use the default light or dark theme and customize it.
4373
*/
44-
payModal?:
45-
| {
46-
locale?: LocaleId;
47-
supportedTokens?: SupportedTokens;
48-
theme?: Theme | "light" | "dark";
49-
}
50-
| false;
51-
74+
payModal?: SendTransactionPayModalConfig;
5275
/**
5376
* Configuration for gasless transactions.
5477
* Refer to [`GaslessOptions`](https://portal.thirdweb.com/references/typescript/v5/GaslessOptions) for more details.
@@ -73,11 +96,31 @@ export type SendTransactionConfig = {
7396
* @transaction
7497
*/
7598
export function useSendTransaction(config: SendTransactionConfig = {}) {
99+
const activeWallet = useActiveWallet();
76100
const payModal = config.payModal;
77101

102+
let payModalEnabled = true;
103+
104+
if (payModal === false || config.gasless) {
105+
payModalEnabled = false;
106+
}
107+
108+
// if active wallet is smart wallet with gasless enabled, don't show the pay modal
109+
if (activeWallet && activeWallet.id === "smart") {
110+
const options = (activeWallet as Wallet<"smart">).getConfig();
111+
112+
if ("sponsorGas" in options && options.sponsorGas === true) {
113+
payModalEnabled = false;
114+
}
115+
116+
if ("gasless" in options && options.gasless === true) {
117+
payModalEnabled = false;
118+
}
119+
}
120+
78121
const setRootEl = useContext(SetRootElementContext);
79122
return useSendTransactionCore(
80-
payModal === false
123+
!payModalEnabled || payModal === false
81124
? undefined
82125
: (data) => {
83126
setRootEl(

packages/thirdweb/src/react/web/ui/TransactionButton/index.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@ import {
77
} from "../../../../transaction/actions/wait-for-tx-receipt.js";
88
import type { PreparedTransaction } from "../../../../transaction/prepare-transaction.js";
99
import type { TransactionReceipt } from "../../../../transaction/types.js";
10-
import { useSendTransactionCore } from "../../../core/hooks/contract/useSendTransaction.js";
1110
import {
1211
useActiveAccount,
1312
useActiveWallet,
1413
useSwitchActiveWalletChain,
1514
} from "../../../core/hooks/wallets/wallet-hooks.js";
15+
import {
16+
type SendTransactionPayModalConfig,
17+
useSendTransaction,
18+
} from "../../hooks/useSendTransaction.js";
1619
import { Spinner } from "../components/Spinner.js";
1720
import { Button } from "../components/buttons.js";
1821

@@ -72,6 +75,28 @@ export type TransactionButtonProps = {
7275
* The button's disabled state
7376
*/
7477
disabled?: boolean;
78+
79+
/**
80+
* Configuration for the "Pay Modal" that opens when the user doesn't have enough funds to send a transaction.
81+
* Set `payModal: false` to disable the "Pay Modal" popup
82+
*
83+
* This configuration object includes the following properties to configure the "Pay Modal" UI:
84+
*
85+
* ### `locale`
86+
* The language to use for the "Pay Modal" UI. Defaults to `"en_US"`.
87+
*
88+
* ### `supportedTokens`
89+
* An object of type [`SupportedTokens`](https://portal.thirdweb.com/references/typescript/v5/SupportedTokens) to configure the tokens to show for a chain.
90+
*
91+
* ### `theme`
92+
* The theme to use for the "Pay Modal" UI. Defaults to `"dark"`.
93+
*
94+
* It can be set to `"light"` or `"dark"` or an object of type [`Theme`](https://portal.thirdweb.com/references/typescript/v5/Theme) for a custom theme.
95+
*
96+
* Refer to [`lightTheme`](https://portal.thirdweb.com/references/typescript/v5/lightTheme)
97+
* or [`darkTheme`](https://portal.thirdweb.com/references/typescript/v5/darkTheme) helper functions to use the default light or dark theme and customize it.
98+
*/
99+
payModal?: SendTransactionPayModalConfig;
75100
};
76101

77102
/**
@@ -100,6 +125,7 @@ export function TransactionButton(props: TransactionButtonProps) {
100125
onError,
101126
onClick,
102127
gasless,
128+
payModal,
103129
disabled,
104130
...buttonProps
105131
} = props;
@@ -108,7 +134,10 @@ export function TransactionButton(props: TransactionButtonProps) {
108134
const [isPending, setIsPending] = useState(false);
109135
const switchChain = useSwitchActiveWalletChain();
110136

111-
const sendTransaction = useSendTransactionCore(undefined, gasless);
137+
const sendTransaction = useSendTransaction({
138+
gasless,
139+
payModal,
140+
});
112141

113142
return (
114143
<Button

0 commit comments

Comments
 (0)