thirdweb 5.108.15 → 5.109.1-nightly-b1a780832ed97d80399a650beab537a89c628278-20251018000336
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/exports/react.js.map +1 -1
- package/dist/cjs/extensions/erc20/read/getCurrencyMetadata.js +31 -7
- package/dist/cjs/extensions/erc20/read/getCurrencyMetadata.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js +19 -6
- package/dist/cjs/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js +4 -1
- package/dist/cjs/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/FundWallet.js +8 -22
- package/dist/cjs/react/web/ui/Bridge/FundWallet.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/bridge-widget/bridge-widget.js +12 -0
- package/dist/cjs/react/web/ui/Bridge/bridge-widget/bridge-widget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/SearchInput.js +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/SearchInput.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/SwapWidget.js +4 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/SwapWidget.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/select-token-ui.js +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/select-token-ui.js.map +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/swap-ui.js +1 -1
- package/dist/cjs/react/web/ui/Bridge/swap-widget/swap-ui.js.map +1 -1
- package/dist/cjs/react/web/ui/components/Modal.js +3 -1
- package/dist/cjs/react/web/ui/components/Modal.js.map +1 -1
- package/dist/cjs/script-exports/bridge-widget-script.js.map +1 -1
- package/dist/cjs/stories/Bridge/BridgeWidget/bridge-widget-script.stories.js +13 -13
- package/dist/cjs/stories/Bridge/BridgeWidget/bridge-widget-script.stories.js.map +1 -1
- package/dist/cjs/stories/Bridge/Swap/SwapWidget.Prefill.stories.js +14 -9
- package/dist/cjs/stories/Bridge/Swap/SwapWidget.Prefill.stories.js.map +1 -1
- package/dist/cjs/stories/Bridge/Swap/SwapWidget.stories.js +12 -12
- package/dist/cjs/stories/Bridge/Swap/SwapWidget.stories.js.map +1 -1
- package/dist/cjs/stories/BuyWidget.stories.js +6 -4
- package/dist/cjs/stories/BuyWidget.stories.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/esm/exports/react.js.map +1 -1
- package/dist/esm/extensions/erc20/read/getCurrencyMetadata.js +31 -7
- package/dist/esm/extensions/erc20/read/getCurrencyMetadata.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js +20 -7
- package/dist/esm/react/web/ui/Bridge/BuyWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js +4 -1
- package/dist/esm/react/web/ui/Bridge/CheckoutWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/FundWallet.js +8 -22
- package/dist/esm/react/web/ui/Bridge/FundWallet.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/bridge-widget/bridge-widget.js +12 -0
- package/dist/esm/react/web/ui/Bridge/bridge-widget/bridge-widget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/SearchInput.js +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/SearchInput.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/SwapWidget.js +4 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/SwapWidget.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/select-token-ui.js +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/select-token-ui.js.map +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/swap-ui.js +1 -1
- package/dist/esm/react/web/ui/Bridge/swap-widget/swap-ui.js.map +1 -1
- package/dist/esm/react/web/ui/components/Modal.js +3 -1
- package/dist/esm/react/web/ui/components/Modal.js.map +1 -1
- package/dist/esm/script-exports/bridge-widget-script.js.map +1 -1
- package/dist/esm/stories/Bridge/BridgeWidget/bridge-widget-script.stories.js +15 -15
- package/dist/esm/stories/Bridge/BridgeWidget/bridge-widget-script.stories.js.map +1 -1
- package/dist/esm/stories/Bridge/Swap/SwapWidget.Prefill.stories.js +16 -11
- package/dist/esm/stories/Bridge/Swap/SwapWidget.Prefill.stories.js.map +1 -1
- package/dist/esm/stories/Bridge/Swap/SwapWidget.stories.js +14 -14
- package/dist/esm/stories/Bridge/Swap/SwapWidget.stories.js.map +1 -1
- package/dist/esm/stories/BuyWidget.stories.js +6 -4
- package/dist/esm/stories/BuyWidget.stories.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/scripts/bridge-widget.d.ts +185 -3
- package/dist/scripts/bridge-widget.js +101 -101
- package/dist/types/exports/react.d.ts +3 -0
- package/dist/types/exports/react.d.ts.map +1 -1
- package/dist/types/extensions/erc20/read/getCurrencyMetadata.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts +5 -1
- package/dist/types/react/web/ui/Bridge/BuyWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/CheckoutWidget.d.ts +5 -1
- package/dist/types/react/web/ui/Bridge/CheckoutWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/FundWallet.d.ts +15 -5
- package/dist/types/react/web/ui/Bridge/FundWallet.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/bridge-widget/bridge-widget.d.ts +9 -2
- package/dist/types/react/web/ui/Bridge/bridge-widget/bridge-widget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/swap-widget/SearchInput.d.ts +1 -0
- package/dist/types/react/web/ui/Bridge/swap-widget/SearchInput.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/swap-widget/SwapWidget.d.ts +5 -1
- package/dist/types/react/web/ui/Bridge/swap-widget/SwapWidget.d.ts.map +1 -1
- package/dist/types/react/web/ui/Bridge/swap-widget/swap-ui.d.ts.map +1 -1
- package/dist/types/react/web/ui/components/Modal.d.ts +1 -0
- package/dist/types/react/web/ui/components/Modal.d.ts.map +1 -1
- package/dist/types/script-exports/bridge-widget-script.d.ts +9 -2
- package/dist/types/script-exports/bridge-widget-script.d.ts.map +1 -1
- package/dist/types/stories/Bridge/BridgeWidget/bridge-widget-script.stories.d.ts.map +1 -1
- package/dist/types/stories/Bridge/Swap/SwapWidget.Prefill.stories.d.ts +0 -3
- package/dist/types/stories/Bridge/Swap/SwapWidget.Prefill.stories.d.ts.map +1 -1
- package/dist/types/stories/Bridge/Swap/SwapWidget.stories.d.ts.map +1 -1
- package/dist/types/stories/BuyWidget.stories.d.ts +0 -3
- package/dist/types/stories/BuyWidget.stories.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/exports/react.ts +3 -2
- package/src/extensions/erc20/read/getCurrencyMetadata.test.ts +39 -0
- package/src/extensions/erc20/read/getCurrencyMetadata.ts +34 -7
- package/src/extensions/erc7702/account/sessionkey.test.ts +4 -2
- package/src/react/web/ui/Bridge/BuyWidget.tsx +34 -8
- package/src/react/web/ui/Bridge/CheckoutWidget.tsx +8 -2
- package/src/react/web/ui/Bridge/FundWallet.tsx +17 -33
- package/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx +22 -2
- package/src/react/web/ui/Bridge/swap-widget/SearchInput.tsx +2 -0
- package/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx +8 -2
- package/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx +1 -0
- package/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx +1 -0
- package/src/react/web/ui/components/Modal.tsx +10 -1
- package/src/script-exports/bridge-widget-script.tsx +9 -2
- package/src/stories/Bridge/BridgeWidget/bridge-widget-script.stories.tsx +25 -18
- package/src/stories/Bridge/Swap/SwapWidget.Prefill.stories.tsx +26 -10
- package/src/stories/Bridge/Swap/SwapWidget.stories.tsx +24 -17
- package/src/stories/BuyWidget.stories.tsx +8 -4
- package/src/version.ts +1 -1
- package/src/wallets/in-app/web/lib/in-app-integration.test.ts +2 -1
- package/src/wallets/smart/smart-wallet-integration-v07.test.ts +2 -1
- package/src/wallets/smart/smart-wallet-integration.test.ts +2 -1
|
@@ -6,6 +6,7 @@ import { trackPayEvent } from "../../../../analytics/track/pay.js";
|
|
|
6
6
|
import type { TokenWithPrices } from "../../../../bridge/index.js";
|
|
7
7
|
import type { Chain } from "../../../../chains/types.js";
|
|
8
8
|
import type { ThirdwebClient } from "../../../../client/client.js";
|
|
9
|
+
import { NATIVE_TOKEN_ADDRESS } from "../../../../constants/addresses.js";
|
|
9
10
|
import type { SupportedFiatCurrency } from "../../../../pay/convert/type.js";
|
|
10
11
|
import type { PurchaseData } from "../../../../pay/types.js";
|
|
11
12
|
import type { Address } from "../../../../utils/address.js";
|
|
@@ -28,7 +29,11 @@ import connectLocaleEn from "../ConnectWallet/locale/en.js";
|
|
|
28
29
|
import { EmbedContainer } from "../ConnectWallet/Modal/ConnectEmbed.js";
|
|
29
30
|
import { DynamicHeight } from "../components/DynamicHeight.js";
|
|
30
31
|
import { ErrorBanner } from "./ErrorBanner.js";
|
|
31
|
-
import {
|
|
32
|
+
import {
|
|
33
|
+
type AmountSelection,
|
|
34
|
+
FundWallet,
|
|
35
|
+
type SelectedToken,
|
|
36
|
+
} from "./FundWallet.js";
|
|
32
37
|
import { PaymentDetails } from "./payment-details/PaymentDetails.js";
|
|
33
38
|
import { PaymentSelection } from "./payment-selection/PaymentSelection.js";
|
|
34
39
|
import { SuccessScreen } from "./payment-success/SuccessScreen.js";
|
|
@@ -158,7 +163,10 @@ export type BuyWidgetProps = {
|
|
|
158
163
|
/**
|
|
159
164
|
* Callback triggered when the purchase is successful.
|
|
160
165
|
*/
|
|
161
|
-
onSuccess?: (
|
|
166
|
+
onSuccess?: (data: {
|
|
167
|
+
quote: BuyOrOnrampPrepareResult;
|
|
168
|
+
statuses: CompletedStatusResult[];
|
|
169
|
+
}) => void;
|
|
162
170
|
|
|
163
171
|
/**
|
|
164
172
|
* Callback triggered when the purchase encounters an error.
|
|
@@ -454,6 +462,22 @@ function BridgeWidgetContent(
|
|
|
454
462
|
[props.onCancel],
|
|
455
463
|
);
|
|
456
464
|
|
|
465
|
+
const [amountSelection, setAmountSelection] = useState<AmountSelection>({
|
|
466
|
+
type: "token",
|
|
467
|
+
value: props.amount ?? "",
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
const [selectedToken, setSelectedToken] = useState<SelectedToken>(() => {
|
|
471
|
+
if (!props.chain?.id) {
|
|
472
|
+
return undefined;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
return {
|
|
476
|
+
chainId: props.chain.id,
|
|
477
|
+
tokenAddress: props.tokenAddress || NATIVE_TOKEN_ADDRESS,
|
|
478
|
+
};
|
|
479
|
+
});
|
|
480
|
+
|
|
457
481
|
if (screen.id === "1:buy-ui" || !activeWalletInfo) {
|
|
458
482
|
return (
|
|
459
483
|
<FundWallet
|
|
@@ -479,11 +503,10 @@ function BridgeWidgetContent(
|
|
|
479
503
|
}}
|
|
480
504
|
buttonLabel={props.buttonLabel}
|
|
481
505
|
currency={props.currency}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}}
|
|
506
|
+
selectedToken={selectedToken}
|
|
507
|
+
setSelectedToken={setSelectedToken}
|
|
508
|
+
amountSelection={amountSelection}
|
|
509
|
+
setAmountSelection={setAmountSelection}
|
|
487
510
|
/>
|
|
488
511
|
);
|
|
489
512
|
}
|
|
@@ -616,7 +639,10 @@ function BridgeWidgetContent(
|
|
|
616
639
|
screen.preparedQuote.type === "buy" ||
|
|
617
640
|
screen.preparedQuote.type === "onramp"
|
|
618
641
|
) {
|
|
619
|
-
props.onSuccess?.(
|
|
642
|
+
props.onSuccess?.({
|
|
643
|
+
quote: screen.preparedQuote,
|
|
644
|
+
statuses: completedStatuses,
|
|
645
|
+
});
|
|
620
646
|
}
|
|
621
647
|
setScreen({
|
|
622
648
|
id: "6:success",
|
|
@@ -170,7 +170,10 @@ export type CheckoutWidgetProps = {
|
|
|
170
170
|
/**
|
|
171
171
|
* Callback triggered when the purchase is successful.
|
|
172
172
|
*/
|
|
173
|
-
onSuccess?: (
|
|
173
|
+
onSuccess?: (data: {
|
|
174
|
+
quote: BridgePrepareResult;
|
|
175
|
+
statuses: CompletedStatusResult[];
|
|
176
|
+
}) => void;
|
|
174
177
|
|
|
175
178
|
/**
|
|
176
179
|
* Callback triggered when the purchase encounters an error.
|
|
@@ -660,7 +663,10 @@ function CheckoutWidgetContent(
|
|
|
660
663
|
handleCancel(screen.preparedQuote);
|
|
661
664
|
}}
|
|
662
665
|
onComplete={(completedStatuses) => {
|
|
663
|
-
props.onSuccess?.(
|
|
666
|
+
props.onSuccess?.({
|
|
667
|
+
quote: screen.preparedQuote,
|
|
668
|
+
statuses: completedStatuses,
|
|
669
|
+
});
|
|
664
670
|
setScreen({
|
|
665
671
|
id: "6:success",
|
|
666
672
|
preparedQuote: screen.preparedQuote,
|
|
@@ -4,7 +4,6 @@ import { ArrowDownIcon } from "@radix-ui/react-icons";
|
|
|
4
4
|
import { useState } from "react";
|
|
5
5
|
import type { TokenWithPrices } from "../../../../bridge/types/Token.js";
|
|
6
6
|
import type { ThirdwebClient } from "../../../../client/client.js";
|
|
7
|
-
import { NATIVE_TOKEN_ADDRESS } from "../../../../constants/addresses.js";
|
|
8
7
|
import {
|
|
9
8
|
getFiatSymbol,
|
|
10
9
|
type SupportedFiatCurrency,
|
|
@@ -86,11 +85,10 @@ type FundWalletProps = {
|
|
|
86
85
|
*/
|
|
87
86
|
showThirdwebBranding: boolean;
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
};
|
|
88
|
+
selectedToken: SelectedToken | undefined;
|
|
89
|
+
setSelectedToken: (token: SelectedToken | undefined) => void;
|
|
90
|
+
amountSelection: AmountSelection;
|
|
91
|
+
setAmountSelection: (amountSelection: AmountSelection) => void;
|
|
94
92
|
|
|
95
93
|
/**
|
|
96
94
|
* The currency to use for the payment.
|
|
@@ -116,14 +114,14 @@ type FundWalletProps = {
|
|
|
116
114
|
};
|
|
117
115
|
};
|
|
118
116
|
|
|
119
|
-
type SelectedToken =
|
|
117
|
+
export type SelectedToken =
|
|
120
118
|
| {
|
|
121
119
|
chainId: number;
|
|
122
120
|
tokenAddress: string;
|
|
123
121
|
}
|
|
124
122
|
| undefined;
|
|
125
123
|
|
|
126
|
-
type AmountSelection =
|
|
124
|
+
export type AmountSelection =
|
|
127
125
|
| {
|
|
128
126
|
type: "usd";
|
|
129
127
|
value: string;
|
|
@@ -134,10 +132,6 @@ type AmountSelection =
|
|
|
134
132
|
};
|
|
135
133
|
|
|
136
134
|
export function FundWallet(props: FundWalletProps) {
|
|
137
|
-
const [amountSelection, setAmountSelection] = useState<AmountSelection>({
|
|
138
|
-
type: "token",
|
|
139
|
-
value: props.initialSelection.amount ?? "",
|
|
140
|
-
});
|
|
141
135
|
const theme = useCustomTheme();
|
|
142
136
|
const activeWalletInfo = useActiveWalletInfo();
|
|
143
137
|
const receiver =
|
|
@@ -154,20 +148,9 @@ export function FundWallet(props: FundWalletProps) {
|
|
|
154
148
|
checksumAddress(activeWalletInfo?.activeAccount?.address)
|
|
155
149
|
: true);
|
|
156
150
|
|
|
157
|
-
const [selectedToken, setSelectedToken] = useState<SelectedToken>(() => {
|
|
158
|
-
if (!props.initialSelection.chainId) {
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
chainId: props.initialSelection.chainId,
|
|
164
|
-
tokenAddress: props.initialSelection.tokenAddress || NATIVE_TOKEN_ADDRESS,
|
|
165
|
-
};
|
|
166
|
-
});
|
|
167
|
-
|
|
168
151
|
const tokenQuery = useTokenQuery({
|
|
169
|
-
tokenAddress: selectedToken?.tokenAddress,
|
|
170
|
-
chainId: selectedToken?.chainId,
|
|
152
|
+
tokenAddress: props.selectedToken?.tokenAddress,
|
|
153
|
+
chainId: props.selectedToken?.chainId,
|
|
171
154
|
client: props.client,
|
|
172
155
|
});
|
|
173
156
|
|
|
@@ -175,8 +158,8 @@ export function FundWallet(props: FundWalletProps) {
|
|
|
175
158
|
tokenQuery.data?.type === "success" ? tokenQuery.data.token : undefined;
|
|
176
159
|
|
|
177
160
|
const tokenBalanceQuery = useTokenBalance({
|
|
178
|
-
chainId: selectedToken?.chainId,
|
|
179
|
-
tokenAddress: selectedToken?.tokenAddress,
|
|
161
|
+
chainId: props.selectedToken?.chainId,
|
|
162
|
+
tokenAddress: props.selectedToken?.tokenAddress,
|
|
180
163
|
client: props.client,
|
|
181
164
|
walletAddress: activeWalletInfo?.activeAccount?.address,
|
|
182
165
|
});
|
|
@@ -222,14 +205,15 @@ export function FundWallet(props: FundWalletProps) {
|
|
|
222
205
|
transform: "none",
|
|
223
206
|
}}
|
|
224
207
|
setOpen={(v) => setIsTokenSelectionOpen(v)}
|
|
208
|
+
autoFocusCrossIcon={false}
|
|
225
209
|
>
|
|
226
210
|
<SelectToken
|
|
227
211
|
activeWalletInfo={activeWalletInfo}
|
|
228
212
|
onClose={() => setIsTokenSelectionOpen(false)}
|
|
229
213
|
client={props.client}
|
|
230
|
-
selectedToken={selectedToken}
|
|
214
|
+
selectedToken={props.selectedToken}
|
|
231
215
|
setSelectedToken={(token) => {
|
|
232
|
-
setSelectedToken(token);
|
|
216
|
+
props.setSelectedToken(token);
|
|
233
217
|
setIsTokenSelectionOpen(false);
|
|
234
218
|
}}
|
|
235
219
|
/>
|
|
@@ -240,11 +224,11 @@ export function FundWallet(props: FundWalletProps) {
|
|
|
240
224
|
<TokenSection
|
|
241
225
|
title={actionLabel}
|
|
242
226
|
presetOptions={props.presetOptions}
|
|
243
|
-
amountSelection={amountSelection}
|
|
244
|
-
setAmount={setAmountSelection}
|
|
227
|
+
amountSelection={props.amountSelection}
|
|
228
|
+
setAmount={props.setAmountSelection}
|
|
245
229
|
activeWalletInfo={activeWalletInfo}
|
|
246
230
|
selectedToken={
|
|
247
|
-
selectedToken
|
|
231
|
+
props.selectedToken
|
|
248
232
|
? {
|
|
249
233
|
data:
|
|
250
234
|
tokenQuery.data?.type === "success"
|
|
@@ -310,7 +294,7 @@ export function FundWallet(props: FundWalletProps) {
|
|
|
310
294
|
|
|
311
295
|
const fiatPricePerToken = destinationToken.prices[props.currency];
|
|
312
296
|
const { tokenValue } = getAmounts(
|
|
313
|
-
amountSelection,
|
|
297
|
+
props.amountSelection,
|
|
314
298
|
fiatPricePerToken,
|
|
315
299
|
);
|
|
316
300
|
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
1
2
|
import { useState } from "react";
|
|
3
|
+
import { trackPayEvent } from "../../../../../analytics/track/pay.js";
|
|
2
4
|
import { defineChain } from "../../../../../chains/utils.js";
|
|
3
5
|
import type { ThirdwebClient } from "../../../../../client/client.js";
|
|
4
6
|
import type { SupportedFiatCurrency } from "../../../../../pay/convert/type.js";
|
|
@@ -13,6 +15,7 @@ import {
|
|
|
13
15
|
spacing,
|
|
14
16
|
type Theme,
|
|
15
17
|
} from "../../../../core/design-system/index.js";
|
|
18
|
+
import type { CompletedStatusResult } from "../../../../core/hooks/useStepExecutor.js";
|
|
16
19
|
import { EmbedContainer } from "../../ConnectWallet/Modal/ConnectEmbed.js";
|
|
17
20
|
import { Container } from "../../components/basic.js";
|
|
18
21
|
import { Button } from "../../components/buttons.js";
|
|
@@ -82,7 +85,10 @@ export type BridgeWidgetProps = {
|
|
|
82
85
|
/** Optional style overrides applied to the Swap tab content container. */
|
|
83
86
|
style?: React.CSSProperties;
|
|
84
87
|
/** Callback invoked when a swap is successful. */
|
|
85
|
-
onSuccess?: (
|
|
88
|
+
onSuccess?: (data: {
|
|
89
|
+
quote: SwapPreparedQuote;
|
|
90
|
+
statuses: CompletedStatusResult[];
|
|
91
|
+
}) => void;
|
|
86
92
|
/** Callback invoked when an error occurs during swapping. */
|
|
87
93
|
onError?: (error: Error, quote: SwapPreparedQuote) => void;
|
|
88
94
|
/** Callback invoked when the user cancels the swap. */
|
|
@@ -172,7 +178,10 @@ export type BridgeWidgetProps = {
|
|
|
172
178
|
quote: BuyOrOnrampPrepareResult | undefined,
|
|
173
179
|
) => void;
|
|
174
180
|
/** Callback triggered when the purchase is successful. */
|
|
175
|
-
onSuccess?: (
|
|
181
|
+
onSuccess?: (data: {
|
|
182
|
+
quote: BuyOrOnrampPrepareResult;
|
|
183
|
+
statuses: CompletedStatusResult[];
|
|
184
|
+
}) => void;
|
|
176
185
|
/** Optional class name applied to the Buy tab content container. */
|
|
177
186
|
className?: string;
|
|
178
187
|
/** The user's ISO 3166 alpha-2 country code. Used to determine onramp provider support. */
|
|
@@ -242,6 +251,17 @@ export type BridgeWidgetProps = {
|
|
|
242
251
|
export function BridgeWidget(props: BridgeWidgetProps) {
|
|
243
252
|
const [tab, setTab] = useState<"swap" | "buy">("swap");
|
|
244
253
|
|
|
254
|
+
useQuery({
|
|
255
|
+
queryFn: () => {
|
|
256
|
+
trackPayEvent({
|
|
257
|
+
client: props.client,
|
|
258
|
+
event: "ub:ui:bridge_widget:render",
|
|
259
|
+
});
|
|
260
|
+
return true;
|
|
261
|
+
},
|
|
262
|
+
queryKey: ["bridge_widget:render"],
|
|
263
|
+
});
|
|
264
|
+
|
|
245
265
|
return (
|
|
246
266
|
<CustomThemeProvider theme={props.theme}>
|
|
247
267
|
<EmbedContainer
|
|
@@ -11,6 +11,7 @@ export function SearchInput(props: {
|
|
|
11
11
|
value: string;
|
|
12
12
|
onChange: (value: string) => void;
|
|
13
13
|
placeholder: string;
|
|
14
|
+
autoFocus?: boolean;
|
|
14
15
|
}) {
|
|
15
16
|
return (
|
|
16
17
|
<div
|
|
@@ -41,6 +42,7 @@ export function SearchInput(props: {
|
|
|
41
42
|
paddingLeft: "44px",
|
|
42
43
|
}}
|
|
43
44
|
onChange={(e) => props.onChange(e.target.value)}
|
|
45
|
+
autoFocus={props.autoFocus}
|
|
44
46
|
/>
|
|
45
47
|
</div>
|
|
46
48
|
);
|
|
@@ -145,7 +145,10 @@ export type SwapWidgetProps = {
|
|
|
145
145
|
/**
|
|
146
146
|
* Callback to be called when the swap is successful.
|
|
147
147
|
*/
|
|
148
|
-
onSuccess?: (
|
|
148
|
+
onSuccess?: (data: {
|
|
149
|
+
quote: SwapPreparedQuote;
|
|
150
|
+
statuses: CompletedStatusResult[];
|
|
151
|
+
}) => void;
|
|
149
152
|
/**
|
|
150
153
|
* Callback to be called when user encounters an error when swapping.
|
|
151
154
|
*/
|
|
@@ -465,7 +468,10 @@ function SwapWidgetContent(
|
|
|
465
468
|
}}
|
|
466
469
|
onCancel={() => props.onCancel?.(screen.preparedQuote)}
|
|
467
470
|
onComplete={(completedStatuses) => {
|
|
468
|
-
props.onSuccess?.(
|
|
471
|
+
props.onSuccess?.({
|
|
472
|
+
quote: screen.preparedQuote,
|
|
473
|
+
statuses: completedStatuses,
|
|
474
|
+
});
|
|
469
475
|
setScreen({
|
|
470
476
|
...screen,
|
|
471
477
|
id: "4:success",
|
|
@@ -41,6 +41,7 @@ export const Modal: React.FC<{
|
|
|
41
41
|
title: string;
|
|
42
42
|
hide?: boolean;
|
|
43
43
|
crossContainerStyles?: React.CSSProperties;
|
|
44
|
+
autoFocusCrossIcon?: boolean;
|
|
44
45
|
}> = (props) => {
|
|
45
46
|
const [open, setOpen] = useState(props.open);
|
|
46
47
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
@@ -143,7 +144,15 @@ export const Modal: React.FC<{
|
|
|
143
144
|
}}
|
|
144
145
|
>
|
|
145
146
|
<Dialog.Close asChild>
|
|
146
|
-
<IconButton
|
|
147
|
+
<IconButton
|
|
148
|
+
aria-label="Close"
|
|
149
|
+
autoFocus={
|
|
150
|
+
props.autoFocusCrossIcon === undefined
|
|
151
|
+
? true
|
|
152
|
+
: props.autoFocusCrossIcon
|
|
153
|
+
}
|
|
154
|
+
type="button"
|
|
155
|
+
>
|
|
147
156
|
<Cross2Icon
|
|
148
157
|
height={iconSize.md}
|
|
149
158
|
style={{
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type Theme,
|
|
8
8
|
type ThemeOverrides,
|
|
9
9
|
} from "../react/core/design-system/index.js";
|
|
10
|
+
import type { CompletedStatusResult } from "../react/core/hooks/useStepExecutor.js";
|
|
10
11
|
import type { BuyOrOnrampPrepareResult } from "../react/web/ui/Bridge/BuyWidget.js";
|
|
11
12
|
import { BridgeWidget } from "../react/web/ui/Bridge/bridge-widget/bridge-widget.js";
|
|
12
13
|
import type { SwapPreparedQuote } from "../react/web/ui/Bridge/swap-widget/types.js";
|
|
@@ -23,7 +24,10 @@ export type BridgeWidgetScriptProps = {
|
|
|
23
24
|
swap?: {
|
|
24
25
|
className?: string;
|
|
25
26
|
style?: React.CSSProperties;
|
|
26
|
-
onSuccess?: (
|
|
27
|
+
onSuccess?: (data: {
|
|
28
|
+
quote: SwapPreparedQuote;
|
|
29
|
+
statuses: CompletedStatusResult[];
|
|
30
|
+
}) => void;
|
|
27
31
|
onError?: (error: Error, quote: SwapPreparedQuote) => void;
|
|
28
32
|
onCancel?: (quote: SwapPreparedQuote) => void;
|
|
29
33
|
onDisconnect?: () => void;
|
|
@@ -51,7 +55,10 @@ export type BridgeWidgetScriptProps = {
|
|
|
51
55
|
error: Error,
|
|
52
56
|
quote: BuyOrOnrampPrepareResult | undefined,
|
|
53
57
|
) => void;
|
|
54
|
-
onSuccess?: (
|
|
58
|
+
onSuccess?: (data: {
|
|
59
|
+
quote: BuyOrOnrampPrepareResult;
|
|
60
|
+
statuses: CompletedStatusResult[];
|
|
61
|
+
}) => void;
|
|
55
62
|
className?: string;
|
|
56
63
|
country?: string;
|
|
57
64
|
presetOptions?: [number, number, number];
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
import type { Meta } from "@storybook/react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BridgeWidgetScript,
|
|
4
|
+
type BridgeWidgetScriptProps,
|
|
5
|
+
} from "../../../script-exports/bridge-widget-script.js";
|
|
3
6
|
import { storyClient } from "../../utils.js";
|
|
4
7
|
|
|
5
8
|
const meta: Meta<typeof BridgeWidgetScript> = {
|
|
6
9
|
title: "Bridge/BridgeWidgetScript",
|
|
7
|
-
parameters: {
|
|
8
|
-
layout: "centered",
|
|
9
|
-
},
|
|
10
|
-
decorators: [
|
|
11
|
-
(Story) => {
|
|
12
|
-
return (
|
|
13
|
-
<div>
|
|
14
|
-
<Story />
|
|
15
|
-
</div>
|
|
16
|
-
);
|
|
17
|
-
},
|
|
18
|
-
],
|
|
19
10
|
};
|
|
20
11
|
export default meta;
|
|
21
12
|
|
|
22
13
|
export function BasicUsage() {
|
|
23
14
|
return (
|
|
24
|
-
<
|
|
15
|
+
<Variant
|
|
25
16
|
clientId={storyClient.clientId}
|
|
26
17
|
buy={{ chainId: 8453, amount: "0.1" }}
|
|
27
18
|
/>
|
|
@@ -30,7 +21,7 @@ export function BasicUsage() {
|
|
|
30
21
|
|
|
31
22
|
export function LightTheme() {
|
|
32
23
|
return (
|
|
33
|
-
<
|
|
24
|
+
<Variant
|
|
34
25
|
clientId={storyClient.clientId}
|
|
35
26
|
theme="light"
|
|
36
27
|
buy={{ chainId: 8453, amount: "0.1" }}
|
|
@@ -40,7 +31,7 @@ export function LightTheme() {
|
|
|
40
31
|
|
|
41
32
|
export function CurrencySet() {
|
|
42
33
|
return (
|
|
43
|
-
<
|
|
34
|
+
<Variant
|
|
44
35
|
clientId={storyClient.clientId}
|
|
45
36
|
currency="JPY"
|
|
46
37
|
buy={{ chainId: 8453, amount: "0.1" }}
|
|
@@ -50,7 +41,7 @@ export function CurrencySet() {
|
|
|
50
41
|
|
|
51
42
|
export function NoThirdwebBranding() {
|
|
52
43
|
return (
|
|
53
|
-
<
|
|
44
|
+
<Variant
|
|
54
45
|
clientId={storyClient.clientId}
|
|
55
46
|
theme="light"
|
|
56
47
|
buy={{ chainId: 8453, amount: "0.1" }}
|
|
@@ -61,7 +52,7 @@ export function NoThirdwebBranding() {
|
|
|
61
52
|
|
|
62
53
|
export function CustomTheme() {
|
|
63
54
|
return (
|
|
64
|
-
<
|
|
55
|
+
<Variant
|
|
65
56
|
clientId={storyClient.clientId}
|
|
66
57
|
buy={{ chainId: 8453, amount: "0.1" }}
|
|
67
58
|
theme={{
|
|
@@ -77,3 +68,19 @@ export function CustomTheme() {
|
|
|
77
68
|
/>
|
|
78
69
|
);
|
|
79
70
|
}
|
|
71
|
+
|
|
72
|
+
function Variant(props: BridgeWidgetScriptProps) {
|
|
73
|
+
return (
|
|
74
|
+
<div
|
|
75
|
+
style={{
|
|
76
|
+
display: "flex",
|
|
77
|
+
flexDirection: "column",
|
|
78
|
+
gap: "40px",
|
|
79
|
+
alignItems: "center",
|
|
80
|
+
}}
|
|
81
|
+
>
|
|
82
|
+
<BridgeWidgetScript {...props} theme="dark" />
|
|
83
|
+
<BridgeWidgetScript {...props} theme="light" />
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import type { Meta } from "@storybook/react-vite";
|
|
2
2
|
import { NATIVE_TOKEN_ADDRESS } from "../../../constants/addresses.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
SwapWidget,
|
|
5
|
+
type SwapWidgetProps,
|
|
6
|
+
} from "../../../react/web/ui/Bridge/swap-widget/SwapWidget.js";
|
|
4
7
|
import { storyClient } from "../../utils.js";
|
|
5
8
|
|
|
6
9
|
const meta = {
|
|
7
|
-
parameters: {
|
|
8
|
-
layout: "centered",
|
|
9
|
-
},
|
|
10
10
|
title: "Bridge/Swap/SwapWidget/Prefill",
|
|
11
11
|
} satisfies Meta<typeof SwapWidget>;
|
|
12
12
|
export default meta;
|
|
13
13
|
|
|
14
14
|
export function Buy_NativeToken() {
|
|
15
15
|
return (
|
|
16
|
-
<
|
|
16
|
+
<Variant
|
|
17
17
|
client={storyClient}
|
|
18
18
|
prefill={{
|
|
19
19
|
buyToken: {
|
|
@@ -26,7 +26,7 @@ export function Buy_NativeToken() {
|
|
|
26
26
|
|
|
27
27
|
export function Buy_Base_USDC() {
|
|
28
28
|
return (
|
|
29
|
-
<
|
|
29
|
+
<Variant
|
|
30
30
|
client={storyClient}
|
|
31
31
|
prefill={{
|
|
32
32
|
buyToken: {
|
|
@@ -40,7 +40,7 @@ export function Buy_Base_USDC() {
|
|
|
40
40
|
|
|
41
41
|
export function Buy_NativeToken_With_Amount() {
|
|
42
42
|
return (
|
|
43
|
-
<
|
|
43
|
+
<Variant
|
|
44
44
|
client={storyClient}
|
|
45
45
|
prefill={{
|
|
46
46
|
buyToken: {
|
|
@@ -55,7 +55,7 @@ export function Buy_NativeToken_With_Amount() {
|
|
|
55
55
|
|
|
56
56
|
export function Sell_NativeToken() {
|
|
57
57
|
return (
|
|
58
|
-
<
|
|
58
|
+
<Variant
|
|
59
59
|
client={storyClient}
|
|
60
60
|
prefill={{
|
|
61
61
|
sellToken: {
|
|
@@ -82,7 +82,7 @@ export function Sell_Base_USDC() {
|
|
|
82
82
|
|
|
83
83
|
export function Sell_NativeToken_With_Amount() {
|
|
84
84
|
return (
|
|
85
|
-
<
|
|
85
|
+
<Variant
|
|
86
86
|
client={storyClient}
|
|
87
87
|
prefill={{
|
|
88
88
|
sellToken: {
|
|
@@ -97,7 +97,7 @@ export function Sell_NativeToken_With_Amount() {
|
|
|
97
97
|
|
|
98
98
|
export function Buy_And_Sell_NativeToken() {
|
|
99
99
|
return (
|
|
100
|
-
<
|
|
100
|
+
<Variant
|
|
101
101
|
client={storyClient}
|
|
102
102
|
prefill={{
|
|
103
103
|
// base native token
|
|
@@ -114,3 +114,19 @@ export function Buy_And_Sell_NativeToken() {
|
|
|
114
114
|
/>
|
|
115
115
|
);
|
|
116
116
|
}
|
|
117
|
+
|
|
118
|
+
function Variant(props: SwapWidgetProps) {
|
|
119
|
+
return (
|
|
120
|
+
<div
|
|
121
|
+
style={{
|
|
122
|
+
display: "flex",
|
|
123
|
+
flexDirection: "column",
|
|
124
|
+
gap: "40px",
|
|
125
|
+
alignItems: "center",
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
<SwapWidget {...props} theme="dark" />
|
|
129
|
+
<SwapWidget {...props} theme="light" />
|
|
130
|
+
</div>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
@@ -1,22 +1,13 @@
|
|
|
1
1
|
import type { Meta } from "@storybook/react";
|
|
2
2
|
import { lightTheme } from "../../../react/core/design-system/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
SwapWidget,
|
|
5
|
+
type SwapWidgetProps,
|
|
6
|
+
} from "../../../react/web/ui/Bridge/swap-widget/SwapWidget.js";
|
|
4
7
|
import { storyClient } from "../../utils.js";
|
|
5
8
|
|
|
6
9
|
const meta: Meta<typeof SwapWidget> = {
|
|
7
|
-
parameters: {
|
|
8
|
-
layout: "centered",
|
|
9
|
-
},
|
|
10
10
|
title: "Bridge/Swap/SwapWidget",
|
|
11
|
-
decorators: [
|
|
12
|
-
(Story) => {
|
|
13
|
-
return (
|
|
14
|
-
<div>
|
|
15
|
-
<Story />
|
|
16
|
-
</div>
|
|
17
|
-
);
|
|
18
|
-
},
|
|
19
|
-
],
|
|
20
11
|
};
|
|
21
12
|
export default meta;
|
|
22
13
|
|
|
@@ -26,7 +17,7 @@ export function BasicUsage() {
|
|
|
26
17
|
|
|
27
18
|
export function CurrencySet() {
|
|
28
19
|
return (
|
|
29
|
-
<
|
|
20
|
+
<Variant
|
|
30
21
|
client={storyClient}
|
|
31
22
|
currency="JPY"
|
|
32
23
|
persistTokenSelections={false}
|
|
@@ -36,7 +27,7 @@ export function CurrencySet() {
|
|
|
36
27
|
|
|
37
28
|
export function LightMode() {
|
|
38
29
|
return (
|
|
39
|
-
<
|
|
30
|
+
<Variant
|
|
40
31
|
client={storyClient}
|
|
41
32
|
currency="JPY"
|
|
42
33
|
theme="light"
|
|
@@ -47,7 +38,7 @@ export function LightMode() {
|
|
|
47
38
|
|
|
48
39
|
export function NoThirdwebBranding() {
|
|
49
40
|
return (
|
|
50
|
-
<
|
|
41
|
+
<Variant
|
|
51
42
|
client={storyClient}
|
|
52
43
|
currency="JPY"
|
|
53
44
|
showThirdwebBranding={false}
|
|
@@ -58,7 +49,7 @@ export function NoThirdwebBranding() {
|
|
|
58
49
|
|
|
59
50
|
export function CustomTheme() {
|
|
60
51
|
return (
|
|
61
|
-
<
|
|
52
|
+
<Variant
|
|
62
53
|
client={storyClient}
|
|
63
54
|
currency="JPY"
|
|
64
55
|
persistTokenSelections={false}
|
|
@@ -74,3 +65,19 @@ export function CustomTheme() {
|
|
|
74
65
|
/>
|
|
75
66
|
);
|
|
76
67
|
}
|
|
68
|
+
|
|
69
|
+
function Variant(props: SwapWidgetProps) {
|
|
70
|
+
return (
|
|
71
|
+
<div
|
|
72
|
+
style={{
|
|
73
|
+
display: "flex",
|
|
74
|
+
flexDirection: "column",
|
|
75
|
+
gap: "40px",
|
|
76
|
+
alignItems: "center",
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
<SwapWidget {...props} theme="dark" />
|
|
80
|
+
<SwapWidget {...props} theme="light" />
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
@@ -9,9 +9,6 @@ import {
|
|
|
9
9
|
import { storyClient } from "./utils.js";
|
|
10
10
|
|
|
11
11
|
const meta = {
|
|
12
|
-
parameters: {
|
|
13
|
-
layout: "centered",
|
|
14
|
-
},
|
|
15
12
|
title: "Bridge/Buy/BuyWidget",
|
|
16
13
|
} satisfies Meta<typeof BuyWidget>;
|
|
17
14
|
export default meta;
|
|
@@ -143,7 +140,14 @@ export function LargeAmount() {
|
|
|
143
140
|
|
|
144
141
|
function Variant(props: BuyWidgetProps) {
|
|
145
142
|
return (
|
|
146
|
-
<div
|
|
143
|
+
<div
|
|
144
|
+
style={{
|
|
145
|
+
display: "flex",
|
|
146
|
+
flexDirection: "column",
|
|
147
|
+
gap: "40px",
|
|
148
|
+
alignItems: "center",
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
147
151
|
<BuyWidget {...props} theme="dark" />
|
|
148
152
|
<BuyWidget {...props} theme="light" />
|
|
149
153
|
</div>
|