@b3dotfun/sdk 0.0.20 → 0.0.21-alpha.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/anyspend/index.native.d.ts +0 -2
- package/dist/cjs/anyspend/index.native.js +0 -4
- package/dist/cjs/anyspend/react/components/AnySpend.d.ts +3 -3
- package/dist/cjs/anyspend/react/components/AnySpend.js +43 -55
- package/dist/cjs/anyspend/react/components/AnySpendCustom.d.ts +1 -1
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +159 -84
- package/dist/cjs/anyspend/react/components/AnySpendFingerprintWrapper.d.ts +1 -1
- package/dist/cjs/anyspend/react/components/AnySpendFingerprintWrapper.js +2 -5
- package/dist/cjs/anyspend/react/components/AnySpendNFT.js +1 -1
- package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.js +1 -1
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +4 -4
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +50 -102
- package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +1 -1
- package/dist/cjs/anyspend/react/components/common/OrderDetails.d.ts +2 -2
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +7 -9
- package/dist/cjs/anyspend/react/components/common/OrderStatus.js +2 -2
- package/dist/cjs/anyspend/react/components/common/PaymentStripeWeb2.js +1 -3
- package/dist/cjs/anyspend/react/components/common/RecipientSelection.d.ts +42 -0
- package/dist/cjs/anyspend/react/components/common/RecipientSelection.example.d.ts +7 -0
- package/dist/cjs/anyspend/react/components/common/RecipientSelection.example.js +27 -0
- package/dist/cjs/anyspend/react/components/common/RecipientSelection.js +36 -0
- package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.js +1 -1
- package/dist/cjs/anyspend/react/components/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/index.js +3 -1
- package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/hooks/index.js +1 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedUserProfile.d.ts +12 -0
- package/dist/cjs/anyspend/react/hooks/useConnectedUserProfile.js +25 -0
- package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +5 -5
- package/dist/cjs/anyspend/react/index.d.ts +1 -1
- package/dist/cjs/anyspend/react/index.js +1 -1
- package/dist/cjs/anyspend/react/providers/index.d.ts +2 -0
- package/dist/cjs/anyspend/react/providers/index.js +18 -0
- package/dist/cjs/anyspend/types/api.d.ts +35 -56
- package/dist/cjs/anyspend/utils/chain.d.ts +1 -1
- package/dist/cjs/anyspend/utils/chain.js +122 -15
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +5 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +2 -2
- package/dist/cjs/global-account/react/hooks/index.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useProfile.d.ts +2 -1
- package/dist/cjs/global-account/react/hooks/useProfile.js +9 -7
- package/dist/cjs/shared/constants/index.js +5 -3
- package/dist/cjs/shared/utils/formatUsername.d.ts +1 -1
- package/dist/cjs/shared/utils/formatUsername.js +3 -1
- package/dist/esm/anyspend/index.native.d.ts +0 -2
- package/dist/esm/anyspend/index.native.js +0 -4
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +3 -3
- package/dist/esm/anyspend/react/components/AnySpend.js +46 -58
- package/dist/esm/anyspend/react/components/AnySpendCustom.d.ts +1 -1
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +163 -88
- package/dist/esm/anyspend/react/components/AnySpendFingerprintWrapper.d.ts +1 -1
- package/dist/esm/anyspend/react/components/AnySpendFingerprintWrapper.js +2 -5
- package/dist/esm/anyspend/react/components/AnySpendNFT.js +1 -1
- package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +1 -1
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +4 -4
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +52 -104
- package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +1 -1
- package/dist/esm/anyspend/react/components/common/OrderDetails.d.ts +2 -2
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +8 -10
- package/dist/esm/anyspend/react/components/common/OrderStatus.js +2 -2
- package/dist/esm/anyspend/react/components/common/PaymentStripeWeb2.js +1 -3
- package/dist/esm/anyspend/react/components/common/RecipientSelection.d.ts +42 -0
- package/dist/esm/anyspend/react/components/common/RecipientSelection.example.d.ts +7 -0
- package/dist/esm/anyspend/react/components/common/RecipientSelection.example.js +22 -0
- package/dist/esm/anyspend/react/components/common/RecipientSelection.js +33 -0
- package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.js +1 -1
- package/dist/esm/anyspend/react/components/index.d.ts +1 -0
- package/dist/esm/anyspend/react/components/index.js +1 -0
- package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/esm/anyspend/react/hooks/index.js +1 -0
- package/dist/esm/anyspend/react/hooks/useConnectedUserProfile.d.ts +12 -0
- package/dist/esm/anyspend/react/hooks/useConnectedUserProfile.js +22 -0
- package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +5 -5
- package/dist/esm/anyspend/react/index.d.ts +1 -1
- package/dist/esm/anyspend/react/index.js +1 -1
- package/dist/esm/anyspend/react/providers/index.d.ts +2 -0
- package/dist/esm/anyspend/react/providers/index.js +2 -0
- package/dist/esm/anyspend/types/api.d.ts +35 -56
- package/dist/esm/anyspend/utils/chain.d.ts +1 -1
- package/dist/esm/anyspend/utils/chain.js +122 -15
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +5 -1
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +2 -2
- package/dist/esm/global-account/react/hooks/index.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useProfile.d.ts +2 -1
- package/dist/esm/global-account/react/hooks/useProfile.js +9 -7
- package/dist/esm/shared/constants/index.js +5 -3
- package/dist/esm/shared/utils/formatUsername.d.ts +1 -1
- package/dist/esm/shared/utils/formatUsername.js +3 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/index.native.d.ts +0 -2
- package/dist/types/anyspend/react/components/AnySpend.d.ts +3 -3
- package/dist/types/anyspend/react/components/AnySpendCustom.d.ts +1 -1
- package/dist/types/anyspend/react/components/AnySpendFingerprintWrapper.d.ts +1 -1
- package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +4 -4
- package/dist/types/anyspend/react/components/common/OrderDetails.d.ts +2 -2
- package/dist/types/anyspend/react/components/common/RecipientSelection.d.ts +42 -0
- package/dist/types/anyspend/react/components/common/RecipientSelection.example.d.ts +7 -0
- package/dist/types/anyspend/react/components/index.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/useConnectedUserProfile.d.ts +12 -0
- package/dist/types/anyspend/react/hooks/useSigMint.d.ts +5 -5
- package/dist/types/anyspend/react/index.d.ts +1 -1
- package/dist/types/anyspend/react/providers/index.d.ts +2 -0
- package/dist/types/anyspend/types/api.d.ts +35 -56
- package/dist/types/anyspend/utils/chain.d.ts +1 -1
- package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +5 -1
- package/dist/types/global-account/react/hooks/index.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useProfile.d.ts +2 -1
- package/dist/types/shared/utils/formatUsername.d.ts +1 -1
- package/package.json +2 -2
- package/src/anyspend/index.native.ts +0 -6
- package/src/anyspend/react/components/AnySpend.tsx +110 -134
- package/src/anyspend/react/components/AnySpendCustom.tsx +488 -196
- package/src/anyspend/react/components/AnySpendFingerprintWrapper.tsx +4 -8
- package/src/anyspend/react/components/AnySpendNFT.tsx +1 -1
- package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +1 -1
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +76 -108
- package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +1 -1
- package/src/anyspend/react/components/common/OrderDetails.tsx +12 -13
- package/src/anyspend/react/components/common/OrderStatus.tsx +2 -2
- package/src/anyspend/react/components/common/PaymentStripeWeb2.tsx +1 -3
- package/src/anyspend/react/components/common/RecipientSelection.example.tsx +52 -0
- package/src/anyspend/react/components/common/RecipientSelection.tsx +146 -0
- package/src/anyspend/react/components/common/TransferCryptoDetails.tsx +1 -0
- package/src/anyspend/react/components/index.ts +1 -0
- package/src/anyspend/react/hooks/index.ts +1 -0
- package/src/anyspend/react/hooks/useConnectedUserProfile.ts +26 -0
- package/src/anyspend/react/index.ts +1 -1
- package/src/anyspend/react/providers/index.ts +2 -0
- package/src/anyspend/types/api.ts +37 -58
- package/src/anyspend/utils/chain.ts +126 -18
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +6 -1
- package/src/global-account/react/hooks/index.ts +1 -1
- package/src/global-account/react/hooks/useProfile.ts +10 -5
- package/src/shared/constants/index.ts +5 -3
- package/src/shared/utils/formatUsername.ts +3 -2
|
@@ -7,23 +7,18 @@ import {
|
|
|
7
7
|
useAnyspendOrderAndTransactions,
|
|
8
8
|
useAnyspendQuote,
|
|
9
9
|
useAnyspendTokenList,
|
|
10
|
+
useConnectedUserProfile,
|
|
10
11
|
useGeoOnrampOptions,
|
|
11
12
|
} from "@b3dotfun/sdk/anyspend/react";
|
|
12
13
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
13
14
|
import { GetQuoteRequest, GetQuoteResponse } from "@b3dotfun/sdk/anyspend/types/api_req_res";
|
|
14
15
|
import {
|
|
15
16
|
Badge,
|
|
16
|
-
Button,
|
|
17
|
-
Dialog,
|
|
18
|
-
DialogContent,
|
|
19
|
-
Input,
|
|
20
17
|
ShinyButton,
|
|
21
18
|
Skeleton,
|
|
22
19
|
StyleRoot,
|
|
23
20
|
Tabs,
|
|
24
21
|
TabsContent,
|
|
25
|
-
TabsList,
|
|
26
|
-
TabTrigger,
|
|
27
22
|
TextShimmer,
|
|
28
23
|
Tooltip,
|
|
29
24
|
TooltipContent,
|
|
@@ -36,27 +31,34 @@ import {
|
|
|
36
31
|
useSearchParamsSSR,
|
|
37
32
|
useTokenBalancesByChain,
|
|
38
33
|
} from "@b3dotfun/sdk/global-account/react";
|
|
39
|
-
import { cn } from "@b3dotfun/sdk/shared/utils";
|
|
40
|
-
|
|
34
|
+
import { cn, formatUsername } from "@b3dotfun/sdk/shared/utils";
|
|
35
|
+
|
|
36
|
+
import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
|
|
41
37
|
import { formatTokenAmount, formatUnits } from "@b3dotfun/sdk/shared/utils/number";
|
|
42
38
|
import { simpleHashChainToChainName } from "@b3dotfun/sdk/shared/utils/simplehash";
|
|
43
39
|
import invariant from "invariant";
|
|
44
|
-
import { ChevronRightCircle, Loader2 } from "lucide-react";
|
|
40
|
+
import { ChevronRight, ChevronRightCircle, Loader2 } from "lucide-react";
|
|
45
41
|
import { motion } from "motion/react";
|
|
46
42
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
47
43
|
import { toast } from "sonner";
|
|
48
44
|
import { base, baseSepolia } from "viem/chains";
|
|
45
|
+
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
|
|
46
|
+
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
|
|
47
|
+
import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaymentMethod";
|
|
49
48
|
import { OrderDetails } from "./common/OrderDetails";
|
|
50
49
|
import { OrderHistory } from "./common/OrderHistory";
|
|
51
50
|
import { OrderStatus as OrderStatusDisplay } from "./common/OrderStatus";
|
|
52
51
|
import { OrderToken } from "./common/OrderToken";
|
|
53
|
-
import {
|
|
52
|
+
import { RecipientSelection } from "./common/RecipientSelection";
|
|
54
53
|
|
|
55
54
|
enum PanelView {
|
|
56
55
|
CONFIRM_ORDER,
|
|
57
56
|
HISTORY,
|
|
58
57
|
ORDER_DETAILS,
|
|
59
58
|
LOADING,
|
|
59
|
+
RECIPIENT_SELECTION,
|
|
60
|
+
CRYPTO_PAYMENT_METHOD,
|
|
61
|
+
FIAT_PAYMENT_METHOD,
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
function generateGetRelayQuoteRequest({
|
|
@@ -141,7 +143,39 @@ function generateGetRelayQuoteRequest({
|
|
|
141
143
|
}
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
export function AnySpendCustom({
|
|
146
|
+
export function AnySpendCustom(props: {
|
|
147
|
+
isMainnet?: boolean;
|
|
148
|
+
loadOrder?: string;
|
|
149
|
+
mode?: "modal" | "page";
|
|
150
|
+
recipientAddress?: string;
|
|
151
|
+
spenderAddress?: string;
|
|
152
|
+
orderType: components["schemas"]["Order"]["type"];
|
|
153
|
+
dstChainId: number;
|
|
154
|
+
dstToken: components["schemas"]["Token"];
|
|
155
|
+
dstAmount: string;
|
|
156
|
+
contractAddress: string;
|
|
157
|
+
encodedData: string;
|
|
158
|
+
metadata: any;
|
|
159
|
+
header: ({
|
|
160
|
+
anyspendPrice,
|
|
161
|
+
isLoadingAnyspendPrice,
|
|
162
|
+
}: {
|
|
163
|
+
anyspendPrice: GetQuoteResponse | undefined;
|
|
164
|
+
isLoadingAnyspendPrice: boolean;
|
|
165
|
+
}) => React.JSX.Element;
|
|
166
|
+
onSuccess?: (txHash?: string) => void;
|
|
167
|
+
showRecipient?: boolean;
|
|
168
|
+
}) {
|
|
169
|
+
const fingerprintConfig = getFingerprintConfig();
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<AnySpendFingerprintWrapper fingerprint={fingerprintConfig}>
|
|
173
|
+
<AnySpendCustomInner {...props} />
|
|
174
|
+
</AnySpendFingerprintWrapper>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function AnySpendCustomInner({
|
|
145
179
|
isMainnet = true,
|
|
146
180
|
loadOrder,
|
|
147
181
|
mode = "modal",
|
|
@@ -190,20 +224,20 @@ export function AnySpendCustom({
|
|
|
190
224
|
);
|
|
191
225
|
const [activeTab, setActiveTab] = useState<"crypto" | "fiat">("crypto");
|
|
192
226
|
|
|
227
|
+
// Add state for selected payment methods
|
|
228
|
+
const [selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod] = useState<CryptoPaymentMethodType>(
|
|
229
|
+
CryptoPaymentMethodType.NONE,
|
|
230
|
+
);
|
|
231
|
+
const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState<FiatPaymentMethod>(FiatPaymentMethod.NONE);
|
|
232
|
+
|
|
193
233
|
// Get current user's wallet
|
|
194
234
|
const currentWallet = useAccountWallet();
|
|
195
235
|
|
|
196
|
-
// Add state for recipient modal
|
|
197
|
-
const [isRecipientModalOpen, setIsRecipientModalOpen] = useState(false);
|
|
198
|
-
|
|
199
236
|
// Add state for custom recipient
|
|
200
237
|
const [customRecipientAddress, setCustomRecipientAddress] = useState<string | undefined>(recipientAddressProps);
|
|
201
238
|
|
|
202
239
|
// Update recipient logic to use custom recipient
|
|
203
240
|
const recipientAddress = customRecipientAddress || currentWallet.address;
|
|
204
|
-
const recipientPropsProfile = useProfile({ address: recipientAddress });
|
|
205
|
-
const recipientEnsName = recipientPropsProfile.data?.name?.replace(/\.b3\.fun/g, "");
|
|
206
|
-
const recipientImageUrl = recipientPropsProfile.data?.avatar || currentWallet.wallet.meta?.icon;
|
|
207
241
|
|
|
208
242
|
const [orderId, setOrderId] = useState<string | undefined>(loadOrder);
|
|
209
243
|
|
|
@@ -337,7 +371,8 @@ export function AnySpendCustom({
|
|
|
337
371
|
);
|
|
338
372
|
|
|
339
373
|
// Get geo data and onramp options (after quote is available)
|
|
340
|
-
const { geoData, isOnrampSupported } =
|
|
374
|
+
const { geoData, isOnrampSupported, coinbaseAvailablePaymentMethods, isStripeOnrampSupported, stripeWeb2Support } =
|
|
375
|
+
useGeoOnrampOptions(isMainnet, srcFiatAmount);
|
|
341
376
|
|
|
342
377
|
useEffect(() => {
|
|
343
378
|
if (oat?.data?.order.status === "executed") {
|
|
@@ -369,6 +404,10 @@ export function AnySpendCustom({
|
|
|
369
404
|
|
|
370
405
|
const isCreatingOrder = isCreatingRegularOrder || isCreatingOnrampOrder;
|
|
371
406
|
|
|
407
|
+
const { address: connectedAddress, name: connectedName, profile: connectedProfile } = useConnectedUserProfile();
|
|
408
|
+
const recipientProfile = useProfile({ address: recipientAddress });
|
|
409
|
+
const recipientName = recipientProfile.data?.name;
|
|
410
|
+
|
|
372
411
|
const handleCreateOrder = async (
|
|
373
412
|
recipientAddress: string,
|
|
374
413
|
onramp?: { paymentMethod: string; vendor: components["schemas"]["OnrampMetadata"]["vendor"] },
|
|
@@ -393,7 +432,7 @@ export function AnySpendCustom({
|
|
|
393
432
|
? {
|
|
394
433
|
type: "erc1155",
|
|
395
434
|
contractAddress: metadata.nftContract.contractAddress,
|
|
396
|
-
tokenId: metadata.nftContract.tokenId
|
|
435
|
+
tokenId: metadata.nftContract.tokenId ?? 0,
|
|
397
436
|
name: metadata.nftContract.name,
|
|
398
437
|
description: metadata.nftContract.description,
|
|
399
438
|
imageUrl: metadata.nftContract.imageUrl,
|
|
@@ -431,15 +470,20 @@ export function AnySpendCustom({
|
|
|
431
470
|
} as CreateOrderParams;
|
|
432
471
|
|
|
433
472
|
if (onramp) {
|
|
434
|
-
|
|
435
|
-
invariant(
|
|
473
|
+
const effectiveSrcToken = activeTab === "fiat" ? USDC_BASE : srcToken;
|
|
474
|
+
invariant(effectiveSrcToken.address === USDC_BASE.address, "Selected src token is not USDC");
|
|
475
|
+
invariant((activeTab === "fiat" ? base.id : srcChainId) === base.id, "Selected src chain is not base");
|
|
476
|
+
|
|
477
|
+
// Get the current geo data from the hook
|
|
478
|
+
const currentGeoData = geoData;
|
|
479
|
+
|
|
436
480
|
void createOnrampOrder({
|
|
437
481
|
...createOrderParams,
|
|
438
482
|
srcFiatAmount: srcFiatAmount,
|
|
439
483
|
onramp: {
|
|
440
484
|
vendor: onramp.vendor,
|
|
441
485
|
paymentMethod: onramp.paymentMethod,
|
|
442
|
-
country:
|
|
486
|
+
country: currentGeoData?.country || "US",
|
|
443
487
|
redirectUrl:
|
|
444
488
|
window.location.origin === "https://basement.fun"
|
|
445
489
|
? "https://basement.fun/deposit"
|
|
@@ -461,22 +505,23 @@ export function AnySpendCustom({
|
|
|
461
505
|
paymentMethod: string;
|
|
462
506
|
vendor: components["schemas"]["OnrampMetadata"]["vendor"];
|
|
463
507
|
}) => {
|
|
464
|
-
// if
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
//
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
//
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
508
|
+
// Check if recipient is selected
|
|
509
|
+
if (!recipientAddress) {
|
|
510
|
+
setActivePanel(PanelView.RECIPIENT_SELECTION);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// Check payment method selection for crypto tab
|
|
515
|
+
if (activeTab === "crypto" && selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
516
|
+
setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD);
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// Check payment method selection for fiat tab
|
|
521
|
+
if (activeTab === "fiat" && selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
522
|
+
setActivePanel(PanelView.FIAT_PAYMENT_METHOD);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
480
525
|
|
|
481
526
|
if (recipientAddress) {
|
|
482
527
|
try {
|
|
@@ -488,6 +533,50 @@ export function AnySpendCustom({
|
|
|
488
533
|
}
|
|
489
534
|
};
|
|
490
535
|
|
|
536
|
+
// Handle fiat order creation
|
|
537
|
+
const handleFiatOrder = async (paymentMethod: FiatPaymentMethod) => {
|
|
538
|
+
try {
|
|
539
|
+
invariant(anyspendQuote, "Relay price is not found");
|
|
540
|
+
invariant(recipientAddress, "Recipient address is not found");
|
|
541
|
+
|
|
542
|
+
if (!srcFiatAmount || parseFloat(srcFiatAmount) <= 0) {
|
|
543
|
+
toast.error("Please enter a valid amount");
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// Determine vendor and payment method string based on selected payment method
|
|
548
|
+
let vendor: components["schemas"]["OnrampMetadata"]["vendor"];
|
|
549
|
+
let paymentMethodString = "";
|
|
550
|
+
|
|
551
|
+
if (paymentMethod === FiatPaymentMethod.COINBASE_PAY) {
|
|
552
|
+
if (coinbaseAvailablePaymentMethods.length === 0) {
|
|
553
|
+
toast.error("Coinbase Pay not available");
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
vendor = "coinbase";
|
|
557
|
+
paymentMethodString = coinbaseAvailablePaymentMethods[0]?.id || "";
|
|
558
|
+
} else if (paymentMethod === FiatPaymentMethod.STRIPE) {
|
|
559
|
+
if (!isStripeOnrampSupported && (!stripeWeb2Support || !stripeWeb2Support.isSupport)) {
|
|
560
|
+
toast.error("Stripe not available");
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
vendor = stripeWeb2Support && stripeWeb2Support.isSupport ? "stripe-web2" : "stripe";
|
|
564
|
+
paymentMethodString = "";
|
|
565
|
+
} else {
|
|
566
|
+
toast.error("Please select a payment method");
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
await handleCreateOrder(recipientAddress, {
|
|
571
|
+
paymentMethod: paymentMethodString,
|
|
572
|
+
vendor: vendor,
|
|
573
|
+
});
|
|
574
|
+
} catch (err: any) {
|
|
575
|
+
console.error(err);
|
|
576
|
+
toast.error("Failed to create order: " + err.message);
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
|
|
491
580
|
const recipientSection = showRecipient ? (
|
|
492
581
|
<motion.div
|
|
493
582
|
initial={false}
|
|
@@ -500,7 +589,7 @@ export function AnySpendCustom({
|
|
|
500
589
|
transition={{ duration: 0.3, delay: 0.2, ease: "easeInOut" }}
|
|
501
590
|
className="flex w-full items-center justify-between gap-4"
|
|
502
591
|
>
|
|
503
|
-
<div className="text-
|
|
592
|
+
<div className="text-as-tertiarry text-sm">
|
|
504
593
|
{orderType === "swap"
|
|
505
594
|
? "Recipient"
|
|
506
595
|
: orderType === "mint_nft"
|
|
@@ -509,33 +598,35 @@ export function AnySpendCustom({
|
|
|
509
598
|
? "Join for"
|
|
510
599
|
: "Recipient"}
|
|
511
600
|
</div>
|
|
512
|
-
<div>
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
{recipientImageUrl && (
|
|
601
|
+
<div className="flex items-center gap-2">
|
|
602
|
+
{recipientAddress ? (
|
|
603
|
+
<button
|
|
604
|
+
className={cn("text-as-tertiarry flex h-7 items-center gap-2 rounded-lg")}
|
|
605
|
+
onClick={() => setActivePanel(PanelView.RECIPIENT_SELECTION)}
|
|
606
|
+
>
|
|
607
|
+
<>
|
|
608
|
+
{recipientProfile && (
|
|
521
609
|
<img
|
|
522
|
-
src={
|
|
523
|
-
alt={
|
|
524
|
-
className="bg-b3-react-foreground size-
|
|
610
|
+
src={recipientProfile.data?.avatar || ""}
|
|
611
|
+
alt={recipientProfile.data?.name || ""}
|
|
612
|
+
className="bg-b3-react-foreground size-6 rounded-full object-cover opacity-100"
|
|
525
613
|
/>
|
|
526
614
|
)}
|
|
527
|
-
<div className="
|
|
528
|
-
{
|
|
529
|
-
<span>{
|
|
615
|
+
<div className="text-as-tertiarry flex items-center gap-1 text-sm">
|
|
616
|
+
{recipientName && <span>{formatUsername(recipientName)}</span>}
|
|
617
|
+
<span>{shortenAddress(recipientAddress)}</span>
|
|
530
618
|
</div>
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
619
|
+
</>
|
|
620
|
+
</button>
|
|
621
|
+
) : (
|
|
622
|
+
<button
|
|
623
|
+
className="text-as-primary/70 flex items-center gap-1 rounded-lg"
|
|
624
|
+
onClick={() => setActivePanel(PanelView.RECIPIENT_SELECTION)}
|
|
625
|
+
>
|
|
626
|
+
<div className="text-sm font-medium">Select recipient</div>
|
|
627
|
+
</button>
|
|
628
|
+
)}
|
|
629
|
+
<ChevronRight className="h-4 w-4" />
|
|
539
630
|
</div>
|
|
540
631
|
</motion.div>
|
|
541
632
|
) : null;
|
|
@@ -561,7 +652,7 @@ export function AnySpendCustom({
|
|
|
561
652
|
<div
|
|
562
653
|
className={cn(
|
|
563
654
|
"mx-auto flex w-full flex-col items-center gap-4 p-5",
|
|
564
|
-
mode === "modal" && "bg-b3-react-background",
|
|
655
|
+
mode === "modal" && "bg-b3-react-background rounded-xl",
|
|
565
656
|
)}
|
|
566
657
|
>
|
|
567
658
|
{oat && (
|
|
@@ -575,6 +666,7 @@ export function AnySpendCustom({
|
|
|
575
666
|
relayTx={oat.data.relayTx}
|
|
576
667
|
executeTx={oat.data.executeTx}
|
|
577
668
|
refundTxs={oat.data.refundTxs}
|
|
669
|
+
cryptoPaymentMethod={activeTab === "fiat" ? CryptoPaymentMethodType.NONE : selectedCryptoPaymentMethod}
|
|
578
670
|
onBack={() => {
|
|
579
671
|
setOrderId(undefined);
|
|
580
672
|
setActivePanel(PanelView.CONFIRM_ORDER);
|
|
@@ -673,34 +765,68 @@ export function AnySpendCustom({
|
|
|
673
765
|
<div className={"relative mx-auto flex w-full flex-col items-center"}>
|
|
674
766
|
{header({ anyspendPrice: anyspendQuote, isLoadingAnyspendPrice: isLoadingAnyspendQuote })}
|
|
675
767
|
|
|
676
|
-
<div className="divider w-full" />
|
|
677
|
-
|
|
678
768
|
<Tabs
|
|
679
769
|
value={activeTab}
|
|
680
770
|
onValueChange={value => setActiveTab(value as "crypto" | "fiat")}
|
|
681
771
|
className="bg-b3-react-background max-h-[60dvh] w-full overflow-y-auto p-5"
|
|
682
772
|
>
|
|
683
|
-
<
|
|
684
|
-
<
|
|
685
|
-
<
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
773
|
+
<div className="w-full">
|
|
774
|
+
<div className="bg-as-surface-secondary relative mb-4 grid h-10 grid-cols-2 rounded-xl">
|
|
775
|
+
<div
|
|
776
|
+
className={cn(
|
|
777
|
+
"bg-as-brand absolute bottom-0 left-0 top-0 z-0 rounded-xl transition-transform duration-100",
|
|
778
|
+
"h-full w-1/2",
|
|
779
|
+
activeTab === "fiat" ? "translate-x-full" : "translate-x-0",
|
|
780
|
+
)}
|
|
781
|
+
style={{ willChange: "transform" }}
|
|
782
|
+
/>
|
|
783
|
+
<button
|
|
784
|
+
className={cn(
|
|
785
|
+
"relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100",
|
|
786
|
+
activeTab === "crypto" ? "text-white" : "text-as-primary/70 hover:bg-as-on-surface-2 bg-transparent",
|
|
787
|
+
)}
|
|
788
|
+
onClick={() => {
|
|
789
|
+
setActiveTab("crypto");
|
|
790
|
+
setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
791
|
+
setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE);
|
|
792
|
+
}}
|
|
793
|
+
>
|
|
794
|
+
Pay with crypto
|
|
795
|
+
</button>
|
|
796
|
+
{isOnrampSupported ? (
|
|
797
|
+
<button
|
|
798
|
+
className={cn(
|
|
799
|
+
"relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100",
|
|
800
|
+
activeTab === "fiat" ? "text-white" : "text-as-primary/70 hover:bg-as-on-surface-2 bg-transparent",
|
|
801
|
+
)}
|
|
802
|
+
onClick={() => {
|
|
803
|
+
setActiveTab("fiat");
|
|
804
|
+
setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
805
|
+
setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE);
|
|
806
|
+
}}
|
|
807
|
+
>
|
|
808
|
+
Pay with fiat
|
|
809
|
+
</button>
|
|
810
|
+
) : (
|
|
811
|
+
<Tooltip>
|
|
812
|
+
<TooltipTrigger asChild>
|
|
813
|
+
<button
|
|
814
|
+
className={cn(
|
|
815
|
+
"relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100",
|
|
816
|
+
"text-as-primary/50 cursor-not-allowed bg-transparent",
|
|
817
|
+
)}
|
|
818
|
+
disabled
|
|
819
|
+
>
|
|
820
|
+
Pay with fiat
|
|
821
|
+
</button>
|
|
822
|
+
</TooltipTrigger>
|
|
823
|
+
<TooltipContent>
|
|
824
|
+
<span className="text-as-primary w-[140px]">Fiat payments are not supported for this amount</span>
|
|
825
|
+
</TooltipContent>
|
|
826
|
+
</Tooltip>
|
|
827
|
+
)}
|
|
828
|
+
</div>
|
|
829
|
+
</div>
|
|
704
830
|
|
|
705
831
|
{/* Warning */}
|
|
706
832
|
{/* {srcChainId === base.id || dstChainId === base.id || activeTab === "fiat" ? (
|
|
@@ -713,8 +839,9 @@ export function AnySpendCustom({
|
|
|
713
839
|
|
|
714
840
|
{/* Crypto tab */}
|
|
715
841
|
<TabsContent value="crypto">
|
|
716
|
-
<div className="mt-2 flex flex-col gap-
|
|
717
|
-
<div className="flex flex-col gap-4">
|
|
842
|
+
<div className="mt-2 flex flex-col gap-6">
|
|
843
|
+
<div className="border-as-border-secondary bg-as-surface-secondary flex w-full flex-col gap-4 rounded-xl border p-4">
|
|
844
|
+
{/* Payment Method Selection */}
|
|
718
845
|
<motion.div
|
|
719
846
|
initial={false}
|
|
720
847
|
animate={{
|
|
@@ -725,21 +852,203 @@ export function AnySpendCustom({
|
|
|
725
852
|
transition={{ duration: 0.3, delay: 0, ease: "easeInOut" }}
|
|
726
853
|
className="relative flex w-full items-center justify-between"
|
|
727
854
|
>
|
|
728
|
-
<div className="
|
|
729
|
-
<
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
855
|
+
<div className="text-as-tertiarry flex h-7 items-center text-sm">Pay</div>
|
|
856
|
+
<button
|
|
857
|
+
className="text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors hover:text-blue-700"
|
|
858
|
+
onClick={() => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD)}
|
|
859
|
+
>
|
|
860
|
+
{selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (
|
|
861
|
+
<>
|
|
862
|
+
{connectedAddress ? (
|
|
863
|
+
<>
|
|
864
|
+
{connectedProfile?.data?.avatar && (
|
|
865
|
+
<img
|
|
866
|
+
src={connectedProfile.data?.avatar || ""}
|
|
867
|
+
alt="Connected Wallet"
|
|
868
|
+
className="bg-as-primary h-6 w-6 rounded-full"
|
|
869
|
+
/>
|
|
870
|
+
)}
|
|
871
|
+
<span className="text-as-tertiarry flex items-center gap-1">
|
|
872
|
+
{connectedName && <span>{formatUsername(connectedName)}</span>}
|
|
873
|
+
<span>{shortenAddress(connectedAddress || "")}</span>
|
|
874
|
+
</span>
|
|
875
|
+
</>
|
|
876
|
+
) : (
|
|
877
|
+
"Connect wallet"
|
|
878
|
+
)}
|
|
879
|
+
<ChevronRight className="h-4 w-4" />
|
|
880
|
+
</>
|
|
881
|
+
) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
|
|
882
|
+
<>
|
|
883
|
+
Transfer crypto
|
|
884
|
+
<ChevronRight className="h-4 w-4" />
|
|
885
|
+
</>
|
|
886
|
+
) : (
|
|
887
|
+
<>
|
|
888
|
+
Select payment method
|
|
889
|
+
<ChevronRight className="h-4 w-4" />
|
|
890
|
+
</>
|
|
891
|
+
)}
|
|
892
|
+
</button>
|
|
893
|
+
</motion.div>
|
|
894
|
+
|
|
895
|
+
<div className="divider w-full" />
|
|
896
|
+
|
|
897
|
+
{recipientSection}
|
|
898
|
+
|
|
899
|
+
<div className="divider w-full" />
|
|
900
|
+
|
|
901
|
+
<div className="flex flex-col gap-4">
|
|
902
|
+
<motion.div
|
|
903
|
+
initial={false}
|
|
904
|
+
animate={{
|
|
905
|
+
opacity: hasMounted ? 1 : 0,
|
|
906
|
+
y: hasMounted ? 0 : 20,
|
|
907
|
+
filter: hasMounted ? "blur(0px)" : "blur(10px)",
|
|
738
908
|
}}
|
|
739
|
-
|
|
740
|
-
|
|
909
|
+
transition={{ duration: 0.3, delay: 0, ease: "easeInOut" }}
|
|
910
|
+
className="relative flex w-full items-center justify-between"
|
|
911
|
+
>
|
|
912
|
+
<div className="text-as-tertiarry text-sm">Pay with</div>
|
|
913
|
+
<OrderToken
|
|
914
|
+
address={currentWallet?.wallet?.address}
|
|
915
|
+
context="from"
|
|
916
|
+
chainId={srcChainId}
|
|
917
|
+
setChainId={setSrcChainId}
|
|
918
|
+
token={srcToken}
|
|
919
|
+
setToken={token => {
|
|
920
|
+
setDirtySelectSrcToken(true);
|
|
921
|
+
setSrcToken(token);
|
|
922
|
+
}}
|
|
923
|
+
requiredAmount={srcAmount || undefined}
|
|
924
|
+
/>
|
|
925
|
+
</motion.div>
|
|
926
|
+
|
|
927
|
+
<div className="divider w-full" />
|
|
928
|
+
|
|
929
|
+
<motion.div
|
|
930
|
+
initial={false}
|
|
931
|
+
animate={{
|
|
932
|
+
opacity: hasMounted ? 1 : 0,
|
|
933
|
+
y: hasMounted ? 0 : 20,
|
|
934
|
+
filter: hasMounted ? "blur(0px)" : "blur(10px)",
|
|
935
|
+
}}
|
|
936
|
+
transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
|
|
937
|
+
className="relative flex w-full items-center justify-between"
|
|
938
|
+
>
|
|
939
|
+
<span className="text-as-tertiarry text-sm">
|
|
940
|
+
Total <span className="text-as-tertiarry">(with fee)</span>
|
|
941
|
+
</span>
|
|
942
|
+
<span className="text-as-primary font-semibold">
|
|
943
|
+
{formattedSrcAmount || "--"} {srcToken.symbol}
|
|
944
|
+
</span>
|
|
945
|
+
</motion.div>
|
|
946
|
+
</div>
|
|
947
|
+
</div>
|
|
948
|
+
|
|
949
|
+
{/* Action Buttons */}
|
|
950
|
+
<div className={cn("flex w-full flex-col items-center justify-between gap-2")}>
|
|
951
|
+
<motion.div
|
|
952
|
+
initial={false}
|
|
953
|
+
animate={{
|
|
954
|
+
opacity: hasMounted ? 1 : 0,
|
|
955
|
+
y: hasMounted ? 0 : 20,
|
|
956
|
+
filter: hasMounted ? "blur(0px)" : "blur(10px)",
|
|
957
|
+
}}
|
|
958
|
+
transition={{ duration: 0.3, delay: 0.3, ease: "easeInOut" }}
|
|
959
|
+
className="flex w-full flex-col gap-2"
|
|
960
|
+
>
|
|
961
|
+
<ShinyButton
|
|
962
|
+
accentColor={"hsl(var(--as-brand))"}
|
|
963
|
+
textColor="text-white"
|
|
964
|
+
disabled={isCreatingOrder || isLoadingAnyspendQuote || !anyspendQuote}
|
|
965
|
+
onClick={() => handleConfirmOrder()}
|
|
966
|
+
className="relative w-full"
|
|
967
|
+
>
|
|
968
|
+
{isCreatingOrder ? (
|
|
969
|
+
<div className="flex items-center gap-2">
|
|
970
|
+
<Loader2 className="size-4 animate-spin" />
|
|
971
|
+
<span>Creating order...</span>
|
|
972
|
+
</div>
|
|
973
|
+
) : isLoadingAnyspendQuote ? (
|
|
974
|
+
<div className="flex items-center gap-2">
|
|
975
|
+
<Loader2 className="size-4 animate-spin" />
|
|
976
|
+
<span>Loading quote...</span>
|
|
977
|
+
</div>
|
|
978
|
+
) : !recipientAddress ? (
|
|
979
|
+
"Select recipient"
|
|
980
|
+
) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE ? (
|
|
981
|
+
"Choose payment method"
|
|
982
|
+
) : anyspendQuote ? (
|
|
983
|
+
<>
|
|
984
|
+
<span>Checkout</span>
|
|
985
|
+
<ChevronRightCircle className="absolute right-0 top-1/2 size-6 -translate-y-1/2 opacity-70" />
|
|
986
|
+
</>
|
|
987
|
+
) : (
|
|
988
|
+
"No quote found"
|
|
989
|
+
)}
|
|
990
|
+
</ShinyButton>
|
|
991
|
+
</motion.div>
|
|
992
|
+
</div>
|
|
993
|
+
</div>
|
|
994
|
+
</TabsContent>
|
|
995
|
+
|
|
996
|
+
{/* Fiat tab */}
|
|
997
|
+
<TabsContent value="fiat">
|
|
998
|
+
<div className="mt-2 flex flex-col gap-6">
|
|
999
|
+
<div className="border-as-border-secondary bg-as-surface-secondary flex w-full flex-col gap-4 rounded-xl border p-4">
|
|
1000
|
+
{/* Fiat Payment Method Selection */}
|
|
1001
|
+
<motion.div
|
|
1002
|
+
initial={false}
|
|
1003
|
+
animate={{
|
|
1004
|
+
opacity: hasMounted ? 1 : 0,
|
|
1005
|
+
y: hasMounted ? 0 : 20,
|
|
1006
|
+
filter: hasMounted ? "blur(0px)" : "blur(10px)",
|
|
1007
|
+
}}
|
|
1008
|
+
transition={{ duration: 0.3, delay: 0, ease: "easeInOut" }}
|
|
1009
|
+
className="relative flex w-full items-center justify-between"
|
|
1010
|
+
>
|
|
1011
|
+
<div className="text-as-tertiarry flex h-7 items-center text-sm">Pay with</div>
|
|
1012
|
+
<button
|
|
1013
|
+
className="text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700"
|
|
1014
|
+
onClick={() => setActivePanel(PanelView.FIAT_PAYMENT_METHOD)}
|
|
1015
|
+
>
|
|
1016
|
+
{selectedFiatPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (
|
|
1017
|
+
<>
|
|
1018
|
+
<div className="flex items-center gap-2">
|
|
1019
|
+
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-blue-600">
|
|
1020
|
+
<span className="text-xs font-bold text-white">C</span>
|
|
1021
|
+
</div>
|
|
1022
|
+
Coinbase Pay
|
|
1023
|
+
</div>
|
|
1024
|
+
<ChevronRight className="h-4 w-4" />
|
|
1025
|
+
</>
|
|
1026
|
+
) : selectedFiatPaymentMethod === FiatPaymentMethod.STRIPE ? (
|
|
1027
|
+
<>
|
|
1028
|
+
<div className="flex items-center gap-2">
|
|
1029
|
+
<div className="flex h-5 w-5 items-center justify-center rounded-full bg-blue-600">
|
|
1030
|
+
<span className="text-xs font-bold text-white">S</span>
|
|
1031
|
+
</div>
|
|
1032
|
+
Credit/Debit Card
|
|
1033
|
+
</div>
|
|
1034
|
+
<ChevronRight className="h-4 w-4" />
|
|
1035
|
+
</>
|
|
1036
|
+
) : (
|
|
1037
|
+
<>
|
|
1038
|
+
Select payment method
|
|
1039
|
+
<ChevronRight className="h-4 w-4" />
|
|
1040
|
+
</>
|
|
1041
|
+
)}
|
|
1042
|
+
</button>
|
|
741
1043
|
</motion.div>
|
|
742
1044
|
|
|
1045
|
+
<div className="divider w-full" />
|
|
1046
|
+
|
|
1047
|
+
{recipientSection}
|
|
1048
|
+
|
|
1049
|
+
<div className="divider w-full" />
|
|
1050
|
+
|
|
1051
|
+
{/* Fiat Amount Display */}
|
|
743
1052
|
<motion.div
|
|
744
1053
|
initial={false}
|
|
745
1054
|
animate={{
|
|
@@ -750,17 +1059,13 @@ export function AnySpendCustom({
|
|
|
750
1059
|
transition={{ duration: 0.3, delay: 0.1, ease: "easeInOut" }}
|
|
751
1060
|
className="relative flex w-full items-center justify-between"
|
|
752
1061
|
>
|
|
753
|
-
<span className="
|
|
754
|
-
Total <span className="text-
|
|
1062
|
+
<span className="text-as-tertiarry text-sm">
|
|
1063
|
+
Total <span className="text-as-tertiarry">(USD)</span>
|
|
755
1064
|
</span>
|
|
756
|
-
<
|
|
757
|
-
{formattedSrcAmount || "--"} {srcToken.symbol}
|
|
758
|
-
</h2>
|
|
1065
|
+
<span className="text-as-primary text-xl font-semibold">${srcFiatAmount || "0.00"}</span>
|
|
759
1066
|
</motion.div>
|
|
760
1067
|
</div>
|
|
761
1068
|
|
|
762
|
-
{recipientSection}
|
|
763
|
-
|
|
764
1069
|
{/* Action Buttons */}
|
|
765
1070
|
<div className={cn("flex w-full flex-col items-center justify-between gap-2")}>
|
|
766
1071
|
<motion.div
|
|
@@ -776,8 +1081,14 @@ export function AnySpendCustom({
|
|
|
776
1081
|
<ShinyButton
|
|
777
1082
|
accentColor={"hsl(var(--as-brand))"}
|
|
778
1083
|
textColor="text-white"
|
|
779
|
-
disabled={isCreatingOrder || isLoadingAnyspendQuote || !anyspendQuote
|
|
780
|
-
onClick={() =>
|
|
1084
|
+
disabled={isCreatingOrder || isLoadingAnyspendQuote || !anyspendQuote}
|
|
1085
|
+
onClick={() => {
|
|
1086
|
+
if (selectedFiatPaymentMethod !== FiatPaymentMethod.NONE) {
|
|
1087
|
+
handleFiatOrder(selectedFiatPaymentMethod);
|
|
1088
|
+
} else {
|
|
1089
|
+
handleConfirmOrder();
|
|
1090
|
+
}
|
|
1091
|
+
}}
|
|
781
1092
|
className="relative w-full"
|
|
782
1093
|
>
|
|
783
1094
|
{isCreatingOrder ? (
|
|
@@ -790,80 +1101,78 @@ export function AnySpendCustom({
|
|
|
790
1101
|
<Loader2 className="size-4 animate-spin" />
|
|
791
1102
|
<span>Loading quote...</span>
|
|
792
1103
|
</div>
|
|
793
|
-
) :
|
|
1104
|
+
) : !recipientAddress ? (
|
|
1105
|
+
"Select recipient"
|
|
1106
|
+
) : selectedFiatPaymentMethod === FiatPaymentMethod.NONE ? (
|
|
1107
|
+
"Select payment method"
|
|
1108
|
+
) : anyspendQuote ? (
|
|
794
1109
|
<>
|
|
795
|
-
<span>
|
|
1110
|
+
<span>Buy</span>
|
|
796
1111
|
<ChevronRightCircle className="absolute right-0 top-1/2 size-6 -translate-y-1/2 opacity-70" />
|
|
797
1112
|
</>
|
|
798
|
-
) : recipientAddress ? (
|
|
799
|
-
"No quote found"
|
|
800
1113
|
) : (
|
|
801
|
-
"
|
|
1114
|
+
"No quote found"
|
|
802
1115
|
)}
|
|
803
1116
|
</ShinyButton>
|
|
804
1117
|
</motion.div>
|
|
805
1118
|
</div>
|
|
806
1119
|
</div>
|
|
807
1120
|
</TabsContent>
|
|
808
|
-
|
|
809
|
-
{/* Fiat tab */}
|
|
810
|
-
<TabsContent value="fiat">
|
|
811
|
-
<div className="mt-6 flex w-full flex-col gap-6">
|
|
812
|
-
<PanelOnrampPayment
|
|
813
|
-
srcAmountOnRamp={srcAmount ? formatUnits(srcAmount.toString(), USDC_BASE.decimals) : "0"}
|
|
814
|
-
recipientName={recipientEnsName}
|
|
815
|
-
recipientAddress={recipientAddress}
|
|
816
|
-
isMainnet={isMainnet}
|
|
817
|
-
isBuyMode={false}
|
|
818
|
-
selectedDstChainId={dstChainId}
|
|
819
|
-
selectedDstToken={dstToken}
|
|
820
|
-
anyspendQuote={anyspendQuote}
|
|
821
|
-
globalAddress={currentWallet?.wallet?.address}
|
|
822
|
-
onOrderCreated={(orderId: string) => setOrderId(orderId)}
|
|
823
|
-
onBack={() => setActiveTab("crypto")}
|
|
824
|
-
orderType={orderType}
|
|
825
|
-
nft={
|
|
826
|
-
metadata.type === "mint_nft"
|
|
827
|
-
? metadata.nftContract.type === "erc1155"
|
|
828
|
-
? {
|
|
829
|
-
type: "erc1155",
|
|
830
|
-
contractAddress: metadata.nftContract.contractAddress,
|
|
831
|
-
tokenId: metadata.nftContract.tokenId!,
|
|
832
|
-
imageUrl: metadata.nftContract.imageUrl,
|
|
833
|
-
name: metadata.nftContract.name,
|
|
834
|
-
description: metadata.nftContract.description,
|
|
835
|
-
price: dstAmount,
|
|
836
|
-
}
|
|
837
|
-
: {
|
|
838
|
-
type: "erc721",
|
|
839
|
-
contractAddress: metadata.nftContract.contractAddress,
|
|
840
|
-
name: metadata.nftContract.name,
|
|
841
|
-
description: metadata.nftContract.description,
|
|
842
|
-
imageUrl: metadata.nftContract.imageUrl,
|
|
843
|
-
price: dstAmount,
|
|
844
|
-
}
|
|
845
|
-
: undefined
|
|
846
|
-
}
|
|
847
|
-
payload={
|
|
848
|
-
metadata.type === "custom"
|
|
849
|
-
? {
|
|
850
|
-
...metadata,
|
|
851
|
-
amount: dstAmount,
|
|
852
|
-
data: encodedData,
|
|
853
|
-
to: contractAddress,
|
|
854
|
-
spenderAddress: spenderAddress,
|
|
855
|
-
}
|
|
856
|
-
: undefined
|
|
857
|
-
}
|
|
858
|
-
recipientEnsName={recipientEnsName}
|
|
859
|
-
recipientImageUrl={recipientImageUrl}
|
|
860
|
-
/>
|
|
861
|
-
</div>
|
|
862
|
-
</TabsContent>
|
|
863
1121
|
</Tabs>
|
|
864
1122
|
</div>
|
|
865
1123
|
);
|
|
866
1124
|
|
|
1125
|
+
// Recipient selection view
|
|
1126
|
+
const recipientSelectionView = (
|
|
1127
|
+
<div className={cn("bg-as-surface-primary mx-auto w-[460px] max-w-full rounded-xl p-4")}>
|
|
1128
|
+
<RecipientSelection
|
|
1129
|
+
initialValue={customRecipientAddress || ""}
|
|
1130
|
+
title="Add recipient address or ENS"
|
|
1131
|
+
description="Send tokens to another address"
|
|
1132
|
+
onBack={() => setActivePanel(PanelView.CONFIRM_ORDER)}
|
|
1133
|
+
onConfirm={address => {
|
|
1134
|
+
setCustomRecipientAddress(address);
|
|
1135
|
+
setActivePanel(PanelView.CONFIRM_ORDER);
|
|
1136
|
+
}}
|
|
1137
|
+
/>
|
|
1138
|
+
</div>
|
|
1139
|
+
);
|
|
1140
|
+
|
|
1141
|
+
// Crypto payment method view
|
|
1142
|
+
const cryptoPaymentMethodView = (
|
|
1143
|
+
<div className={cn("bg-as-surface-primary mx-auto w-[460px] max-w-full rounded-xl p-4")}>
|
|
1144
|
+
<CryptoPaymentMethod
|
|
1145
|
+
globalAddress={currentWallet?.wallet?.address}
|
|
1146
|
+
globalWallet={currentWallet?.wallet}
|
|
1147
|
+
selectedPaymentMethod={selectedCryptoPaymentMethod}
|
|
1148
|
+
setSelectedPaymentMethod={setSelectedCryptoPaymentMethod}
|
|
1149
|
+
isCreatingOrder={isCreatingOrder}
|
|
1150
|
+
onBack={() => setActivePanel(PanelView.CONFIRM_ORDER)}
|
|
1151
|
+
onSelectPaymentMethod={(method: CryptoPaymentMethodType) => {
|
|
1152
|
+
setSelectedCryptoPaymentMethod(method);
|
|
1153
|
+
setActivePanel(PanelView.CONFIRM_ORDER);
|
|
1154
|
+
}}
|
|
1155
|
+
/>
|
|
1156
|
+
</div>
|
|
1157
|
+
);
|
|
1158
|
+
|
|
1159
|
+
// Fiat payment method view
|
|
1160
|
+
const fiatPaymentMethodView = (
|
|
1161
|
+
<div className={cn("bg-as-surface-primary mx-auto w-[460px] max-w-full rounded-xl p-4")}>
|
|
1162
|
+
<FiatPaymentMethodComponent
|
|
1163
|
+
selectedPaymentMethod={selectedFiatPaymentMethod}
|
|
1164
|
+
setSelectedPaymentMethod={setSelectedFiatPaymentMethod}
|
|
1165
|
+
onBack={() => setActivePanel(PanelView.CONFIRM_ORDER)}
|
|
1166
|
+
onSelectPaymentMethod={(method: FiatPaymentMethod) => {
|
|
1167
|
+
setSelectedFiatPaymentMethod(method);
|
|
1168
|
+
setActivePanel(PanelView.CONFIRM_ORDER);
|
|
1169
|
+
}}
|
|
1170
|
+
srcAmountOnRamp={srcFiatAmount}
|
|
1171
|
+
isMainnet={isMainnet}
|
|
1172
|
+
/>
|
|
1173
|
+
</div>
|
|
1174
|
+
);
|
|
1175
|
+
|
|
867
1176
|
// Return the TransitionPanel with all views
|
|
868
1177
|
return (
|
|
869
1178
|
<StyleRoot>
|
|
@@ -886,7 +1195,7 @@ export function AnySpendCustom({
|
|
|
886
1195
|
transition={{ type: "spring", stiffness: 300, damping: 30 }}
|
|
887
1196
|
>
|
|
888
1197
|
{[
|
|
889
|
-
<div key="
|
|
1198
|
+
<div key="confirm-order-view" className="w-full">
|
|
890
1199
|
{confirmOrderView}
|
|
891
1200
|
</div>,
|
|
892
1201
|
<div key="history-view" className="w-full">
|
|
@@ -898,34 +1207,17 @@ export function AnySpendCustom({
|
|
|
898
1207
|
<div key="loading-view" className="w-full">
|
|
899
1208
|
{loadingView}
|
|
900
1209
|
</div>,
|
|
1210
|
+
<div key="recipient-selection-view" className="w-full">
|
|
1211
|
+
{recipientSelectionView}
|
|
1212
|
+
</div>,
|
|
1213
|
+
<div key="crypto-payment-method-view" className="w-full">
|
|
1214
|
+
{cryptoPaymentMethodView}
|
|
1215
|
+
</div>,
|
|
1216
|
+
<div key="fiat-payment-method-view" className="w-full">
|
|
1217
|
+
{fiatPaymentMethodView}
|
|
1218
|
+
</div>,
|
|
901
1219
|
]}
|
|
902
1220
|
</TransitionPanel>
|
|
903
|
-
|
|
904
|
-
{/* Add EnterRecipientModal */}
|
|
905
|
-
<Dialog open={isRecipientModalOpen} onOpenChange={setIsRecipientModalOpen}>
|
|
906
|
-
<DialogContent className="w-[420px] max-w-[calc(100vw-32px)] rounded-2xl p-3.5">
|
|
907
|
-
<div className="flex flex-col gap-3">
|
|
908
|
-
<div className="text-as-primary font-semibold">To address</div>
|
|
909
|
-
<Input
|
|
910
|
-
value={customRecipientAddress || ""}
|
|
911
|
-
onChange={e => setCustomRecipientAddress(e.target.value)}
|
|
912
|
-
placeholder="Enter address"
|
|
913
|
-
className="h-12 rounded-lg"
|
|
914
|
-
spellCheck={false}
|
|
915
|
-
/>
|
|
916
|
-
<ShinyButton
|
|
917
|
-
accentColor={"hsl(var(--as-brand))"}
|
|
918
|
-
textColor="text-white"
|
|
919
|
-
className="w-full rounded-lg"
|
|
920
|
-
onClick={() => {
|
|
921
|
-
setIsRecipientModalOpen(false);
|
|
922
|
-
}}
|
|
923
|
-
>
|
|
924
|
-
Save
|
|
925
|
-
</ShinyButton>
|
|
926
|
-
</div>
|
|
927
|
-
</DialogContent>
|
|
928
|
-
</Dialog>
|
|
929
1221
|
</StyleRoot>
|
|
930
1222
|
);
|
|
931
1223
|
}
|