thirdweb 5.87.4 → 5.88.0
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/client/client.js +2 -1
- package/dist/cjs/client/client.js.map +1 -1
- package/dist/cjs/contract/deployment/zksync/zkDeployContract.js +4 -2
- package/dist/cjs/contract/deployment/zksync/zkDeployContract.js.map +1 -1
- package/dist/cjs/pay/buyWithCrypto/getQuote.js +1 -24
- package/dist/cjs/pay/buyWithCrypto/getQuote.js.map +1 -1
- package/dist/cjs/pay/buyWithCrypto/getTransfer.js +1 -13
- package/dist/cjs/pay/buyWithCrypto/getTransfer.js.map +1 -1
- package/dist/cjs/pay/buyWithFiat/getQuote.js.map +1 -1
- package/dist/cjs/pay/utils/commonTypes.js +2 -0
- package/dist/cjs/pay/utils/commonTypes.js.map +1 -1
- package/dist/cjs/react/core/utils/storage.js +2 -1
- package/dist/cjs/react/core/utils/storage.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +50 -200
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +111 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/PostOnRampSwap.js +30 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/PostOnRampSwap.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/Providers.js +24 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/fiat/Providers.js.map +1 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js +2 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +18 -6
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js +37 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js.map +1 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +165 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +33 -6
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/nativeToken.js +8 -0
- package/dist/cjs/react/web/ui/ConnectWallet/screens/nativeToken.js.map +1 -1
- package/dist/cjs/react/web/utils/errors.js +16 -0
- package/dist/cjs/react/web/utils/errors.js.map +1 -0
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/smart/index.js +27 -0
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/cjs/wallets/smart/types.js.map +1 -1
- package/dist/esm/client/client.js +2 -1
- package/dist/esm/client/client.js.map +1 -1
- package/dist/esm/contract/deployment/zksync/zkDeployContract.js +4 -2
- package/dist/esm/contract/deployment/zksync/zkDeployContract.js.map +1 -1
- package/dist/esm/pay/buyWithCrypto/getQuote.js +1 -24
- package/dist/esm/pay/buyWithCrypto/getQuote.js.map +1 -1
- package/dist/esm/pay/buyWithCrypto/getTransfer.js +1 -13
- package/dist/esm/pay/buyWithCrypto/getTransfer.js.map +1 -1
- package/dist/esm/pay/buyWithFiat/getQuote.js.map +1 -1
- package/dist/esm/pay/utils/commonTypes.js +1 -1
- package/dist/esm/pay/utils/commonTypes.js.map +1 -1
- package/dist/esm/react/core/utils/storage.js +1 -0
- package/dist/esm/react/core/utils/storage.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js +50 -200
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js +108 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.js.map +1 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/PostOnRampSwap.js +30 -2
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/PostOnRampSwap.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/Providers.js +21 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/fiat/Providers.js.map +1 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js +2 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +18 -6
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js +34 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.js.map +1 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js +162 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.js.map +1 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +33 -6
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js +7 -0
- package/dist/esm/react/web/ui/ConnectWallet/screens/nativeToken.js.map +1 -1
- package/dist/esm/react/web/utils/errors.js +12 -0
- package/dist/esm/react/web/utils/errors.js.map +1 -0
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/smart/index.js +27 -0
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/esm/wallets/smart/types.js.map +1 -1
- package/dist/types/client/client.d.ts.map +1 -1
- package/dist/types/contract/deployment/zksync/zkDeployContract.d.ts.map +1 -1
- package/dist/types/pay/buyWithCrypto/getQuote.d.ts +2 -2
- package/dist/types/pay/buyWithCrypto/getQuote.d.ts.map +1 -1
- package/dist/types/pay/buyWithCrypto/getTransfer.d.ts +2 -2
- package/dist/types/pay/buyWithCrypto/getTransfer.d.ts.map +1 -1
- package/dist/types/pay/buyWithFiat/getQuote.d.ts +4 -0
- package/dist/types/pay/buyWithFiat/getQuote.d.ts.map +1 -1
- package/dist/types/pay/utils/commonTypes.d.ts +2 -1
- package/dist/types/pay/utils/commonTypes.d.ts.map +1 -1
- package/dist/types/react/core/utils/storage.d.ts +1 -0
- package/dist/types/react/core/utils/storage.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.d.ts +25 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.d.ts.map +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/PostOnRampSwap.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/Providers.d.ts +9 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/fiat/Providers.d.ts.map +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/types.d.ts +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/main/types.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.d.ts +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.d.ts +11 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.d.ts.map +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.d.ts +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts +31 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.d.ts.map +1 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts +2 -0
- package/dist/types/react/web/ui/ConnectWallet/screens/nativeToken.d.ts.map +1 -1
- package/dist/types/react/web/ui/components/text.d.ts +1 -1
- package/dist/types/react/web/ui/components/text.d.ts.map +1 -1
- package/dist/types/react/web/utils/errors.d.ts +14 -0
- package/dist/types/react/web/utils/errors.d.ts.map +1 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/smart/index.d.ts.map +1 -1
- package/dist/types/wallets/smart/types.d.ts +5 -0
- package/dist/types/wallets/smart/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/client/client.test.ts +2 -2
- package/src/client/client.ts +2 -1
- package/src/contract/deployment/zksync/zkDeployContract.ts +5 -2
- package/src/pay/buyWithCrypto/getQuote.ts +2 -27
- package/src/pay/buyWithCrypto/getTransfer.ts +2 -14
- package/src/pay/buyWithFiat/getQuote.ts +5 -0
- package/src/pay/utils/commonTypes.ts +3 -1
- package/src/react/core/utils/storage.ts +1 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/BuyScreen.tsx +70 -531
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/FiatScreenContent.tsx +307 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/PostOnRampSwap.tsx +33 -1
- package/src/react/web/ui/ConnectWallet/screens/Buy/fiat/Providers.tsx +57 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/main/types.ts +1 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/BuyTokenInput.tsx +12 -2
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +21 -6
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/FiatValue.tsx +51 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapFlow.tsx +2 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/SwapScreenContent.tsx +353 -0
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.tsx +43 -6
- package/src/react/web/ui/ConnectWallet/screens/nativeToken.ts +8 -0
- package/src/react/web/ui/components/text.tsx +1 -1
- package/src/react/web/utils/errors.ts +22 -0
- package/src/version.ts +1 -1
- package/src/wallets/smart/index.ts +28 -0
- package/src/wallets/smart/smart-wallet-integration.test.ts +25 -0
- package/src/wallets/smart/types.ts +5 -0
@@ -0,0 +1,307 @@
|
|
1
|
+
import { ChevronDownIcon } from "@radix-ui/react-icons";
|
2
|
+
import { useState } from "react";
|
3
|
+
import type { Chain } from "../../../../../../../chains/types.js";
|
4
|
+
import type { ThirdwebClient } from "../../../../../../../client/client.js";
|
5
|
+
import { NATIVE_TOKEN_ADDRESS } from "../../../../../../../constants/addresses.js";
|
6
|
+
import { isSwapRequiredPostOnramp } from "../../../../../../../pay/buyWithFiat/isSwapRequiredPostOnramp.js";
|
7
|
+
import type { FiatProvider } from "../../../../../../../pay/utils/commonTypes.js";
|
8
|
+
import { formatNumber } from "../../../../../../../utils/formatNumber.js";
|
9
|
+
import {
|
10
|
+
type Theme,
|
11
|
+
iconSize,
|
12
|
+
spacing,
|
13
|
+
} from "../../../../../../core/design-system/index.js";
|
14
|
+
import type { PayUIOptions } from "../../../../../../core/hooks/connection/ConnectButtonProps.js";
|
15
|
+
import { useBuyWithFiatQuote } from "../../../../../../core/hooks/pay/useBuyWithFiatQuote.js";
|
16
|
+
import { PREFERRED_FIAT_PROVIDER_STORAGE_KEY } from "../../../../../../core/utils/storage.js";
|
17
|
+
import {
|
18
|
+
defaultMessage,
|
19
|
+
getErrorMessage,
|
20
|
+
} from "../../../../../utils/errors.js";
|
21
|
+
import {
|
22
|
+
Drawer,
|
23
|
+
DrawerOverlay,
|
24
|
+
useDrawer,
|
25
|
+
} from "../../../../components/Drawer.js";
|
26
|
+
import { Spacer } from "../../../../components/Spacer.js";
|
27
|
+
import { Spinner } from "../../../../components/Spinner.js";
|
28
|
+
import { Container } from "../../../../components/basic.js";
|
29
|
+
import { Button } from "../../../../components/buttons.js";
|
30
|
+
import { Text } from "../../../../components/text.js";
|
31
|
+
import { TokenSymbol } from "../../../../components/token/TokenSymbol.js";
|
32
|
+
import { type ERC20OrNativeToken, isNativeToken } from "../../nativeToken.js";
|
33
|
+
import { EstimatedTimeAndFees } from "../EstimatedTimeAndFees.js";
|
34
|
+
import { PayWithCreditCard } from "../PayWIthCreditCard.js";
|
35
|
+
import type { SelectedScreen } from "../main/types.js";
|
36
|
+
import { openOnrampPopup } from "../openOnRamppopup.js";
|
37
|
+
import { FiatFees } from "../swap/Fees.js";
|
38
|
+
import { addPendingTx } from "../swap/pendingSwapTx.js";
|
39
|
+
import type { PayerInfo } from "../types.js";
|
40
|
+
import { Providers } from "./Providers.js";
|
41
|
+
import type { CurrencyMeta } from "./currencies.js";
|
42
|
+
|
43
|
+
export function FiatScreenContent(props: {
|
44
|
+
setScreen: (screen: SelectedScreen) => void;
|
45
|
+
tokenAmount: string;
|
46
|
+
toToken: ERC20OrNativeToken;
|
47
|
+
toChain: Chain;
|
48
|
+
selectedCurrency: CurrencyMeta;
|
49
|
+
showCurrencySelector: () => void;
|
50
|
+
payOptions: PayUIOptions;
|
51
|
+
theme: "light" | "dark" | Theme;
|
52
|
+
client: ThirdwebClient;
|
53
|
+
onDone: () => void;
|
54
|
+
isEmbed: boolean;
|
55
|
+
payer: PayerInfo;
|
56
|
+
setTokenAmount: (amount: string) => void;
|
57
|
+
setHasEditedAmount: (hasEdited: boolean) => void;
|
58
|
+
}) {
|
59
|
+
const {
|
60
|
+
toToken,
|
61
|
+
tokenAmount,
|
62
|
+
payer,
|
63
|
+
client,
|
64
|
+
setScreen,
|
65
|
+
toChain,
|
66
|
+
showCurrencySelector,
|
67
|
+
selectedCurrency,
|
68
|
+
} = props;
|
69
|
+
const defaultRecipientAddress = (
|
70
|
+
props.payOptions as Extract<PayUIOptions, { mode: "direct_payment" }>
|
71
|
+
)?.paymentInfo?.sellerAddress;
|
72
|
+
const receiverAddress =
|
73
|
+
defaultRecipientAddress || props.payer.account.address;
|
74
|
+
const { drawerRef, drawerOverlayRef, isOpen, setIsOpen } = useDrawer();
|
75
|
+
const [drawerScreen, setDrawerScreen] = useState<"fees" | "providers">(
|
76
|
+
"fees",
|
77
|
+
);
|
78
|
+
|
79
|
+
const buyWithFiatOptions = props.payOptions.buyWithFiat;
|
80
|
+
const [preferredProvider, setPreferredProvider] = useState<
|
81
|
+
FiatProvider | undefined
|
82
|
+
>(
|
83
|
+
buyWithFiatOptions !== false
|
84
|
+
? buyWithFiatOptions?.preferredProvider ||
|
85
|
+
((localStorage.getItem(
|
86
|
+
PREFERRED_FIAT_PROVIDER_STORAGE_KEY,
|
87
|
+
) as FiatProvider | null) ??
|
88
|
+
undefined)
|
89
|
+
: undefined,
|
90
|
+
);
|
91
|
+
|
92
|
+
const fiatQuoteQuery = useBuyWithFiatQuote(
|
93
|
+
buyWithFiatOptions !== false && tokenAmount
|
94
|
+
? {
|
95
|
+
fromCurrencySymbol: selectedCurrency.shorthand,
|
96
|
+
toChainId: toChain.id,
|
97
|
+
toAddress: receiverAddress,
|
98
|
+
toTokenAddress: isNativeToken(toToken)
|
99
|
+
? NATIVE_TOKEN_ADDRESS
|
100
|
+
: toToken.address,
|
101
|
+
toAmount: tokenAmount,
|
102
|
+
client,
|
103
|
+
isTestMode: buyWithFiatOptions?.testMode,
|
104
|
+
purchaseData: props.payOptions.purchaseData,
|
105
|
+
fromAddress: payer.account.address,
|
106
|
+
preferredProvider: preferredProvider,
|
107
|
+
}
|
108
|
+
: undefined,
|
109
|
+
);
|
110
|
+
|
111
|
+
function handleSubmit() {
|
112
|
+
if (!fiatQuoteQuery.data) {
|
113
|
+
return;
|
114
|
+
}
|
115
|
+
|
116
|
+
const hasTwoSteps = isSwapRequiredPostOnramp(fiatQuoteQuery.data);
|
117
|
+
let openedWindow: Window | null = null;
|
118
|
+
|
119
|
+
if (!hasTwoSteps) {
|
120
|
+
openedWindow = openOnrampPopup(
|
121
|
+
fiatQuoteQuery.data.onRampLink,
|
122
|
+
typeof props.theme === "string" ? props.theme : props.theme.type,
|
123
|
+
);
|
124
|
+
|
125
|
+
addPendingTx({
|
126
|
+
type: "fiat",
|
127
|
+
intentId: fiatQuoteQuery.data.intentId,
|
128
|
+
});
|
129
|
+
}
|
130
|
+
|
131
|
+
setScreen({
|
132
|
+
id: "fiat-flow",
|
133
|
+
quote: fiatQuoteQuery.data,
|
134
|
+
openedWindow,
|
135
|
+
});
|
136
|
+
}
|
137
|
+
|
138
|
+
function showFees() {
|
139
|
+
if (!fiatQuoteQuery.data) {
|
140
|
+
return;
|
141
|
+
}
|
142
|
+
|
143
|
+
setDrawerScreen("fees");
|
144
|
+
setIsOpen(true);
|
145
|
+
}
|
146
|
+
|
147
|
+
function showProviders() {
|
148
|
+
setDrawerScreen("providers");
|
149
|
+
setIsOpen(true);
|
150
|
+
}
|
151
|
+
|
152
|
+
const disableSubmit = !fiatQuoteQuery.data;
|
153
|
+
|
154
|
+
const errorMsg =
|
155
|
+
!fiatQuoteQuery.isLoading && fiatQuoteQuery.error
|
156
|
+
? getErrorMessage(fiatQuoteQuery.error)
|
157
|
+
: undefined;
|
158
|
+
|
159
|
+
return (
|
160
|
+
<Container flex="column" gap="md" animate="fadein">
|
161
|
+
{isOpen && (
|
162
|
+
<>
|
163
|
+
<DrawerOverlay ref={drawerOverlayRef} />
|
164
|
+
<Drawer ref={drawerRef} close={() => setIsOpen(false)}>
|
165
|
+
{drawerScreen === "fees" && fiatQuoteQuery.data && (
|
166
|
+
<div>
|
167
|
+
<Text size="lg" color="primaryText">
|
168
|
+
Fees
|
169
|
+
</Text>
|
170
|
+
|
171
|
+
<Spacer y="lg" />
|
172
|
+
<FiatFees quote={fiatQuoteQuery.data} />
|
173
|
+
</div>
|
174
|
+
)}
|
175
|
+
{drawerScreen === "providers" && (
|
176
|
+
<div>
|
177
|
+
<Text size="lg" color="primaryText">
|
178
|
+
Providers
|
179
|
+
</Text>
|
180
|
+
<Spacer y="lg" />
|
181
|
+
<Providers
|
182
|
+
preferredProvider={
|
183
|
+
preferredProvider || fiatQuoteQuery.data?.provider
|
184
|
+
}
|
185
|
+
onSelect={(provider) => {
|
186
|
+
setPreferredProvider(provider);
|
187
|
+
// save the pref in local storage
|
188
|
+
localStorage.setItem(
|
189
|
+
PREFERRED_FIAT_PROVIDER_STORAGE_KEY,
|
190
|
+
provider,
|
191
|
+
);
|
192
|
+
setIsOpen(false);
|
193
|
+
}}
|
194
|
+
/>
|
195
|
+
</div>
|
196
|
+
)}
|
197
|
+
</Drawer>
|
198
|
+
</>
|
199
|
+
)}
|
200
|
+
|
201
|
+
<div>
|
202
|
+
<PayWithCreditCard
|
203
|
+
isLoading={fiatQuoteQuery.isLoading}
|
204
|
+
value={fiatQuoteQuery.data?.fromCurrencyWithFees.amount}
|
205
|
+
client={client}
|
206
|
+
currency={selectedCurrency}
|
207
|
+
onSelectCurrency={showCurrencySelector}
|
208
|
+
/>
|
209
|
+
<Container
|
210
|
+
bg="tertiaryBg"
|
211
|
+
flex="row"
|
212
|
+
borderColor="borderColor"
|
213
|
+
style={{
|
214
|
+
paddingLeft: spacing.md,
|
215
|
+
justifyContent: "space-between",
|
216
|
+
alignItems: "center",
|
217
|
+
borderWidth: "1px",
|
218
|
+
borderStyle: "solid",
|
219
|
+
borderBottom: "none",
|
220
|
+
}}
|
221
|
+
>
|
222
|
+
<Text size="xs" color="secondaryText">
|
223
|
+
Provider
|
224
|
+
</Text>
|
225
|
+
<Button variant="ghost" onClick={showProviders}>
|
226
|
+
<Container flex="row" center="y" gap="xxs" color="secondaryText">
|
227
|
+
<Text size="xs">
|
228
|
+
{preferredProvider
|
229
|
+
? `${preferredProvider.charAt(0).toUpperCase() + preferredProvider.slice(1).toLowerCase()}`
|
230
|
+
: fiatQuoteQuery.data?.provider
|
231
|
+
? `${fiatQuoteQuery.data?.provider.charAt(0).toUpperCase() + fiatQuoteQuery.data?.provider.slice(1).toLowerCase()}`
|
232
|
+
: ""}
|
233
|
+
</Text>
|
234
|
+
<ChevronDownIcon width={iconSize.sm} height={iconSize.sm} />
|
235
|
+
</Container>
|
236
|
+
</Button>
|
237
|
+
</Container>
|
238
|
+
{/* Estimated time + View fees button */}
|
239
|
+
<EstimatedTimeAndFees
|
240
|
+
quoteIsLoading={fiatQuoteQuery.isLoading}
|
241
|
+
estimatedSeconds={fiatQuoteQuery.data?.estimatedDurationSeconds}
|
242
|
+
onViewFees={showFees}
|
243
|
+
/>
|
244
|
+
<Spacer y="md" />
|
245
|
+
</div>
|
246
|
+
|
247
|
+
{/* Error message */}
|
248
|
+
{errorMsg && (
|
249
|
+
<div>
|
250
|
+
{errorMsg.data?.minimumAmountEth ? (
|
251
|
+
<Text color="danger" size="sm" center multiline>
|
252
|
+
Minimum amount is{" "}
|
253
|
+
{formatNumber(Number(errorMsg.data.minimumAmountEth), 6)}{" "}
|
254
|
+
<TokenSymbol
|
255
|
+
token={toToken}
|
256
|
+
chain={toChain}
|
257
|
+
size="sm"
|
258
|
+
inline
|
259
|
+
color="danger"
|
260
|
+
/>
|
261
|
+
</Text>
|
262
|
+
) : (
|
263
|
+
<Text color="danger" size="sm" center multiline>
|
264
|
+
{errorMsg.message || defaultMessage}
|
265
|
+
</Text>
|
266
|
+
)}
|
267
|
+
</div>
|
268
|
+
)}
|
269
|
+
|
270
|
+
{errorMsg?.data?.minimumAmountEth ? (
|
271
|
+
<Button
|
272
|
+
variant="accent"
|
273
|
+
fullWidth
|
274
|
+
onClick={() => {
|
275
|
+
props.setTokenAmount(
|
276
|
+
formatNumber(
|
277
|
+
Number(errorMsg.data?.minimumAmountEth),
|
278
|
+
6,
|
279
|
+
).toString(),
|
280
|
+
);
|
281
|
+
props.setHasEditedAmount(true);
|
282
|
+
}}
|
283
|
+
>
|
284
|
+
Set Minimum
|
285
|
+
</Button>
|
286
|
+
) : (
|
287
|
+
<Button
|
288
|
+
variant={disableSubmit ? "outline" : "accent"}
|
289
|
+
data-disabled={disableSubmit}
|
290
|
+
disabled={disableSubmit}
|
291
|
+
fullWidth
|
292
|
+
onClick={handleSubmit}
|
293
|
+
gap="xs"
|
294
|
+
>
|
295
|
+
{fiatQuoteQuery.isLoading ? (
|
296
|
+
<>
|
297
|
+
Getting price quote
|
298
|
+
<Spinner size="sm" color="accentText" />
|
299
|
+
</>
|
300
|
+
) : (
|
301
|
+
"Continue"
|
302
|
+
)}
|
303
|
+
</Button>
|
304
|
+
)}
|
305
|
+
</Container>
|
306
|
+
);
|
307
|
+
}
|
@@ -1,6 +1,9 @@
|
|
1
1
|
import { useQuery } from "@tanstack/react-query";
|
2
2
|
import { useEffect, useState } from "react";
|
3
|
+
import { getCachedChain } from "../../../../../../../chains/utils.js";
|
3
4
|
import type { ThirdwebClient } from "../../../../../../../client/client.js";
|
5
|
+
import { getContract } from "../../../../../../../contract/contract.js";
|
6
|
+
import { allowance } from "../../../../../../../extensions/erc20/__generated__/IERC20/read/allowance.js";
|
4
7
|
import type { BuyWithCryptoQuote } from "../../../../../../../pay/buyWithCrypto/getQuote.js";
|
5
8
|
import type { BuyWithCryptoStatus } from "../../../../../../../pay/buyWithCrypto/getStatus.js";
|
6
9
|
import { getPostOnRampQuote } from "../../../../../../../pay/buyWithFiat/getPostOnRampQuote.js";
|
@@ -43,11 +46,38 @@ export function PostOnRampSwap(props: {
|
|
43
46
|
refetchOnWindowFocus: false,
|
44
47
|
});
|
45
48
|
|
49
|
+
const allowanceQuery = useQuery({
|
50
|
+
queryKey: [
|
51
|
+
"allowance",
|
52
|
+
props.payer.account.address,
|
53
|
+
postOnRampQuoteQuery.data?.approvalData,
|
54
|
+
],
|
55
|
+
queryFn: () => {
|
56
|
+
if (!postOnRampQuoteQuery.data?.approvalData) {
|
57
|
+
return null;
|
58
|
+
}
|
59
|
+
return allowance({
|
60
|
+
contract: getContract({
|
61
|
+
client: props.client,
|
62
|
+
address: postOnRampQuoteQuery.data.swapDetails.fromToken.tokenAddress,
|
63
|
+
chain: getCachedChain(
|
64
|
+
postOnRampQuoteQuery.data.swapDetails.fromToken.chainId,
|
65
|
+
),
|
66
|
+
}),
|
67
|
+
spender: postOnRampQuoteQuery.data.approvalData.spenderAddress,
|
68
|
+
owner: props.payer.account.address,
|
69
|
+
});
|
70
|
+
},
|
71
|
+
enabled: !!postOnRampQuoteQuery.data?.approvalData,
|
72
|
+
refetchOnMount: true,
|
73
|
+
});
|
74
|
+
|
46
75
|
useEffect(() => {
|
47
76
|
if (
|
48
77
|
postOnRampQuoteQuery.data &&
|
49
78
|
!lockedOnRampQuote &&
|
50
|
-
!postOnRampQuoteQuery.isRefetching
|
79
|
+
!postOnRampQuoteQuery.isRefetching &&
|
80
|
+
!allowanceQuery.isLoading
|
51
81
|
) {
|
52
82
|
setLockedOnRampQuote(postOnRampQuoteQuery.data);
|
53
83
|
}
|
@@ -55,6 +85,7 @@ export function PostOnRampSwap(props: {
|
|
55
85
|
postOnRampQuoteQuery.data,
|
56
86
|
lockedOnRampQuote,
|
57
87
|
postOnRampQuoteQuery.isRefetching,
|
88
|
+
allowanceQuery.isLoading,
|
58
89
|
]);
|
59
90
|
|
60
91
|
if (postOnRampQuoteQuery.isError) {
|
@@ -133,6 +164,7 @@ export function PostOnRampSwap(props: {
|
|
133
164
|
transactionMode={props.transactionMode}
|
134
165
|
isEmbed={props.isEmbed}
|
135
166
|
onSuccess={props.onSuccess}
|
167
|
+
approvalAmount={allowanceQuery.data ?? undefined}
|
136
168
|
/>
|
137
169
|
);
|
138
170
|
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import {
|
2
|
+
type FiatProvider,
|
3
|
+
FiatProviders,
|
4
|
+
} from "../../../../../../../pay/utils/commonTypes.js";
|
5
|
+
import { Container } from "../../../../components/basic.js";
|
6
|
+
import { Button } from "../../../../components/buttons.js";
|
7
|
+
import { Link } from "../../../../components/text.js";
|
8
|
+
/**
|
9
|
+
* @internal
|
10
|
+
*/
|
11
|
+
export function Providers(props: {
|
12
|
+
preferredProvider?: FiatProvider;
|
13
|
+
onSelect: (provider: FiatProvider) => void;
|
14
|
+
}) {
|
15
|
+
return (
|
16
|
+
<Container
|
17
|
+
expand
|
18
|
+
flex="column"
|
19
|
+
gap="sm"
|
20
|
+
style={{
|
21
|
+
alignItems: "flex-start",
|
22
|
+
}}
|
23
|
+
>
|
24
|
+
{FiatProviders.map((provider) => {
|
25
|
+
return (
|
26
|
+
<Container
|
27
|
+
key={provider}
|
28
|
+
flex="row"
|
29
|
+
expand
|
30
|
+
style={{
|
31
|
+
justifyContent: "space-between",
|
32
|
+
}}
|
33
|
+
>
|
34
|
+
<Button
|
35
|
+
fullWidth
|
36
|
+
onClick={() => props.onSelect(provider)}
|
37
|
+
variant={"link"}
|
38
|
+
>
|
39
|
+
<Link
|
40
|
+
color={
|
41
|
+
props.preferredProvider === provider
|
42
|
+
? "primaryText"
|
43
|
+
: "secondaryText"
|
44
|
+
}
|
45
|
+
size="sm"
|
46
|
+
hoverColor="primaryText"
|
47
|
+
>
|
48
|
+
{provider.charAt(0).toUpperCase() +
|
49
|
+
provider.slice(1).toLowerCase()}
|
50
|
+
</Link>
|
51
|
+
</Button>
|
52
|
+
</Container>
|
53
|
+
);
|
54
|
+
})}
|
55
|
+
</Container>
|
56
|
+
);
|
57
|
+
}
|
@@ -19,6 +19,7 @@ import { Text } from "../../../../components/text.js";
|
|
19
19
|
import { TokenSymbol } from "../../../../components/token/TokenSymbol.js";
|
20
20
|
import type { ERC20OrNativeToken } from "../../nativeToken.js";
|
21
21
|
import { getBuyTokenAmountFontSize } from "../utils.js";
|
22
|
+
import { FiatValue } from "./FiatValue.js";
|
22
23
|
|
23
24
|
/**
|
24
25
|
* @internal
|
@@ -35,7 +36,6 @@ export function BuyTokenInput(props: {
|
|
35
36
|
freezeChainAndToken?: boolean;
|
36
37
|
}) {
|
37
38
|
const { name } = useChainName(props.chain);
|
38
|
-
|
39
39
|
const getWidth = () => {
|
40
40
|
let chars = props.value.replace(".", "").length;
|
41
41
|
const hasDot = props.value.includes(".");
|
@@ -122,9 +122,19 @@ export function BuyTokenInput(props: {
|
|
122
122
|
</Container>
|
123
123
|
</div>
|
124
124
|
|
125
|
+
<Container flex="row" center="both">
|
126
|
+
<FiatValue
|
127
|
+
tokenAmount={props.value}
|
128
|
+
token={props.token}
|
129
|
+
chain={props.chain}
|
130
|
+
client={props.client}
|
131
|
+
size="md"
|
132
|
+
/>
|
133
|
+
</Container>
|
134
|
+
|
125
135
|
{!props.hideTokenSelector && (
|
126
136
|
<>
|
127
|
-
<Spacer y="
|
137
|
+
<Spacer y="md" />
|
128
138
|
|
129
139
|
{/* Token / Chain selector */}
|
130
140
|
<Container flex="row" center="x">
|
@@ -3,6 +3,8 @@ import { useState } from "react";
|
|
3
3
|
import { trackPayEvent } from "../../../../../../../analytics/track/pay.js";
|
4
4
|
import type { Chain } from "../../../../../../../chains/types.js";
|
5
5
|
import type { ThirdwebClient } from "../../../../../../../client/client.js";
|
6
|
+
import { getContract } from "../../../../../../../contract/contract.js";
|
7
|
+
import { approve } from "../../../../../../../extensions/erc20/write/approve.js";
|
6
8
|
import type { BuyWithCryptoQuote } from "../../../../../../../pay/buyWithCrypto/getQuote.js";
|
7
9
|
import { sendTransaction } from "../../../../../../../transaction/actions/send-transaction.js";
|
8
10
|
import { waitForReceipt } from "../../../../../../../transaction/actions/wait-for-tx-receipt.js";
|
@@ -51,9 +53,13 @@ export function SwapConfirmationScreen(props: {
|
|
51
53
|
fromTokenSymbol: string;
|
52
54
|
isFiatFlow: boolean;
|
53
55
|
payer: PayerInfo;
|
56
|
+
preApprovedAmount?: bigint;
|
54
57
|
}) {
|
55
|
-
const
|
56
|
-
|
58
|
+
const needsApproval =
|
59
|
+
props.quote.approvalData &&
|
60
|
+
props.preApprovedAmount !== undefined &&
|
61
|
+
props.preApprovedAmount < BigInt(props.quote.approvalData.amountWei);
|
62
|
+
const initialStep = needsApproval ? "approval" : "swap";
|
57
63
|
|
58
64
|
const [step, setStep] = useState<"approval" | "swap">(initialStep);
|
59
65
|
const [status, setStatus] = useState<
|
@@ -136,7 +142,7 @@ export function SwapConfirmationScreen(props: {
|
|
136
142
|
<Spacer y="xl" />
|
137
143
|
|
138
144
|
{/* Show 2 steps - Approve and confirm */}
|
139
|
-
{
|
145
|
+
{needsApproval && (
|
140
146
|
<>
|
141
147
|
<Spacer y="sm" />
|
142
148
|
<Container
|
@@ -187,7 +193,7 @@ export function SwapConfirmationScreen(props: {
|
|
187
193
|
fullWidth
|
188
194
|
disabled={status === "pending"}
|
189
195
|
onClick={async () => {
|
190
|
-
if (step === "approval" && props.quote.
|
196
|
+
if (step === "approval" && props.quote.approvalData) {
|
191
197
|
try {
|
192
198
|
setStatus("pending");
|
193
199
|
|
@@ -204,13 +210,22 @@ export function SwapConfirmationScreen(props: {
|
|
204
210
|
dstChainId: props.quote.swapDetails.toToken.chainId,
|
205
211
|
});
|
206
212
|
|
213
|
+
const transaction = approve({
|
214
|
+
contract: getContract({
|
215
|
+
client: props.client,
|
216
|
+
address: props.quote.swapDetails.fromToken.tokenAddress,
|
217
|
+
chain: props.fromChain,
|
218
|
+
}),
|
219
|
+
spender: props.quote.approvalData.spenderAddress,
|
220
|
+
amountWei: BigInt(props.quote.approvalData.amountWei),
|
221
|
+
});
|
222
|
+
|
207
223
|
const tx = await sendTransaction({
|
208
224
|
account: props.payer.account,
|
209
|
-
transaction
|
225
|
+
transaction,
|
210
226
|
});
|
211
227
|
|
212
228
|
await waitForReceipt({ ...tx, maxBlocksWaitTime: 50 });
|
213
|
-
// props.onQuoteFinalized(props.quote);
|
214
229
|
|
215
230
|
trackPayEvent({
|
216
231
|
event: "swap_approval_success",
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
2
|
+
import type { Chain } from "../../../../../../../chains/types.js";
|
3
|
+
import type { ThirdwebClient } from "../../../../../../../client/client.js";
|
4
|
+
import { convertCryptoToFiat } from "../../../../../../../pay/convert/cryptoToFiat.js";
|
5
|
+
import { formatNumber } from "../../../../../../../utils/formatNumber.js";
|
6
|
+
import { fontSize } from "../../../../../../core/design-system/index.js";
|
7
|
+
import { Skeleton } from "../../../../components/Skeleton.js";
|
8
|
+
import { Text } from "../../../../components/text.js";
|
9
|
+
import type { TextProps } from "../../../../components/text.js";
|
10
|
+
import { useDebouncedValue } from "../../../../hooks/useDebouncedValue.js";
|
11
|
+
import type { ERC20OrNativeToken } from "../../nativeToken.js";
|
12
|
+
import { getTokenAddress } from "../../nativeToken.js";
|
13
|
+
|
14
|
+
export function FiatValue(
|
15
|
+
props: {
|
16
|
+
tokenAmount: string;
|
17
|
+
token: ERC20OrNativeToken;
|
18
|
+
chain: Chain;
|
19
|
+
client: ThirdwebClient;
|
20
|
+
} & TextProps,
|
21
|
+
) {
|
22
|
+
const deferredTokenAmount = useDebouncedValue(props.tokenAmount, 500);
|
23
|
+
const cryptoToFiatQuery = useQuery({
|
24
|
+
queryKey: [
|
25
|
+
"cryptoToFiat",
|
26
|
+
props.chain.id,
|
27
|
+
getTokenAddress(props.token),
|
28
|
+
deferredTokenAmount,
|
29
|
+
],
|
30
|
+
queryFn: () =>
|
31
|
+
convertCryptoToFiat({
|
32
|
+
client: props.client,
|
33
|
+
chain: props.chain,
|
34
|
+
fromTokenAddress: getTokenAddress(props.token),
|
35
|
+
fromAmount: Number(deferredTokenAmount),
|
36
|
+
to: "USD",
|
37
|
+
}),
|
38
|
+
});
|
39
|
+
|
40
|
+
if (cryptoToFiatQuery.isLoading) {
|
41
|
+
return <Skeleton width={"50px"} height={fontSize.lg} />;
|
42
|
+
}
|
43
|
+
|
44
|
+
return (
|
45
|
+
<Text {...props}>
|
46
|
+
{cryptoToFiatQuery.data?.result
|
47
|
+
? `$${formatNumber(cryptoToFiatQuery.data.result, 2)}`
|
48
|
+
: "$0.00"}
|
49
|
+
</Text>
|
50
|
+
);
|
51
|
+
}
|
@@ -22,6 +22,7 @@ type SwapFlowProps = {
|
|
22
22
|
transactionMode: boolean;
|
23
23
|
isEmbed: boolean;
|
24
24
|
onSuccess: ((status: BuyWithCryptoStatus) => void) | undefined;
|
25
|
+
approvalAmount?: bigint;
|
25
26
|
};
|
26
27
|
|
27
28
|
export function SwapFlow(props: SwapFlowProps) {
|
@@ -109,6 +110,7 @@ export function SwapFlow(props: SwapFlowProps) {
|
|
109
110
|
quote={quote}
|
110
111
|
isFiatFlow={props.isFiatFlow}
|
111
112
|
payer={props.payer}
|
113
|
+
preApprovedAmount={props.approvalAmount}
|
112
114
|
/>
|
113
115
|
);
|
114
116
|
}
|