@b3dotfun/sdk 0.0.28-alpha.0 → 0.0.28-alpha.2
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/abis/escrow.d.ts +987 -0
- package/dist/cjs/anyspend/abis/escrow.js +1275 -0
- package/dist/cjs/anyspend/react/components/AnySpend.js +10 -168
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +2 -2
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.d.ts +10 -0
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +263 -0
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +17 -0
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +53 -0
- package/dist/cjs/anyspend/react/components/common/ErrorSection.d.ts +6 -0
- package/dist/cjs/anyspend/react/components/common/ErrorSection.js +12 -0
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +2 -2
- package/dist/cjs/anyspend/react/components/common/PaySection.d.ts +20 -0
- package/dist/cjs/anyspend/react/components/common/PaySection.js +58 -0
- package/dist/cjs/anyspend/react/components/common/TabSection.d.ts +10 -0
- package/dist/cjs/anyspend/react/components/common/TabSection.js +18 -0
- package/dist/cjs/anyspend/react/components/index.d.ts +2 -0
- package/dist/cjs/anyspend/react/components/index.js +5 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +165 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +184 -0
- package/dist/cjs/anyspend/react/hooks/useSigMint.d.ts +2 -2
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +3 -0
- package/dist/cjs/global-account/react/components/custom/Button.d.ts +1 -1
- package/dist/cjs/global-account/react/components/ui/button.d.ts +1 -1
- package/dist/cjs/global-account/react/components/ui/command.d.ts +2 -2
- package/dist/cjs/global-account/react/hooks/useSiwe.native.d.ts +4 -0
- package/dist/cjs/global-account/react/hooks/useSiwe.native.js +40 -0
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +17 -1
- package/dist/cjs/shared/constants/chains/b3Chain.d.ts +1 -1
- package/dist/cjs/shared/constants/chains/supported.d.ts +3 -3
- package/dist/esm/anyspend/abis/escrow.d.ts +987 -0
- package/dist/esm/anyspend/abis/escrow.js +1272 -0
- package/dist/esm/anyspend/react/components/AnySpend.js +12 -170
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +3 -3
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.d.ts +10 -0
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +257 -0
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +17 -0
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +50 -0
- package/dist/esm/anyspend/react/components/common/ErrorSection.d.ts +6 -0
- package/dist/esm/anyspend/react/components/common/ErrorSection.js +9 -0
- package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.js +2 -2
- package/dist/esm/anyspend/react/components/common/PaySection.d.ts +20 -0
- package/dist/esm/anyspend/react/components/common/PaySection.js +55 -0
- package/dist/esm/anyspend/react/components/common/TabSection.d.ts +10 -0
- package/dist/esm/anyspend/react/components/common/TabSection.js +15 -0
- package/dist/esm/anyspend/react/components/index.d.ts +2 -0
- package/dist/esm/anyspend/react/components/index.js +2 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +165 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +180 -0
- package/dist/esm/anyspend/react/hooks/useSigMint.d.ts +2 -2
- package/dist/esm/global-account/react/components/B3DynamicModal.js +3 -0
- package/dist/esm/global-account/react/components/custom/Button.d.ts +1 -1
- package/dist/esm/global-account/react/components/ui/button.d.ts +1 -1
- package/dist/esm/global-account/react/components/ui/command.d.ts +2 -2
- package/dist/esm/global-account/react/hooks/useSiwe.native.d.ts +4 -0
- package/dist/esm/global-account/react/hooks/useSiwe.native.js +34 -0
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +17 -1
- package/dist/esm/shared/constants/chains/b3Chain.d.ts +1 -1
- package/dist/esm/shared/constants/chains/supported.d.ts +3 -3
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/abis/escrow.d.ts +987 -0
- package/dist/types/anyspend/react/components/AnyspendDepositHype.d.ts +10 -0
- package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +17 -0
- package/dist/types/anyspend/react/components/common/ErrorSection.d.ts +6 -0
- package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/types/anyspend/react/components/common/PaySection.d.ts +20 -0
- package/dist/types/anyspend/react/components/common/TabSection.d.ts +10 -0
- package/dist/types/anyspend/react/components/index.d.ts +2 -0
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +165 -0
- package/dist/types/anyspend/react/hooks/useSigMint.d.ts +2 -2
- package/dist/types/global-account/react/components/custom/Button.d.ts +1 -1
- package/dist/types/global-account/react/components/ui/button.d.ts +1 -1
- package/dist/types/global-account/react/components/ui/command.d.ts +2 -2
- package/dist/types/global-account/react/hooks/useSiwe.native.d.ts +4 -0
- package/dist/types/global-account/react/stores/useModalStore.d.ts +17 -1
- package/dist/types/shared/constants/chains/b3Chain.d.ts +1 -1
- package/dist/types/shared/constants/chains/supported.d.ts +3 -3
- package/package.json +13 -1
- package/src/anyspend/abis/escrow.ts +1272 -0
- package/src/anyspend/react/components/AnySpend.tsx +48 -389
- package/src/anyspend/react/components/AnySpendCustom.tsx +2 -10
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +525 -0
- package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +152 -0
- package/src/anyspend/react/components/common/ErrorSection.tsx +21 -0
- package/src/anyspend/react/components/common/PanelOnramp.tsx +4 -2
- package/src/anyspend/react/components/common/PaySection.tsx +222 -0
- package/src/anyspend/react/components/common/TabSection.tsx +58 -0
- package/src/anyspend/react/components/index.ts +2 -0
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +226 -0
- package/src/global-account/react/components/B3DynamicModal.tsx +3 -0
- package/src/global-account/react/hooks/useSiwe.native.tsx +40 -0
- package/src/global-account/react/stores/useModalStore.ts +19 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { formatUsername } from "../../../../shared/utils/index.js";
|
|
3
|
+
import { cn } from "../../../../shared/utils/cn.js";
|
|
4
|
+
import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
|
|
5
|
+
import { formatDisplayNumber } from "../../../../shared/utils/number.js";
|
|
6
|
+
import { ChevronRight } from "lucide-react";
|
|
7
|
+
import { motion } from "motion/react";
|
|
8
|
+
import { OrderTokenAmount } from "./OrderTokenAmount.js";
|
|
9
|
+
export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, onChangeDstAmount, anyspendQuote, }) {
|
|
10
|
+
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "receive-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex w-full items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: isDepositMode ? "Deposit" : "Receive" }), selectedRecipientAddress ? (_jsx("button", { className: cn("text-as-tertiarry flex h-7 items-center gap-2 rounded-lg"), onClick: onSelectRecipient, children: _jsxs(_Fragment, { children: [_jsx("span", { className: "text-as-tertiarry flex items-center gap-1 text-sm", children: recipientName ? formatUsername(recipientName) : shortenAddress(selectedRecipientAddress || "") }), _jsx(ChevronRight, { className: "h-4 w-4" })] }) })) : (_jsx("button", { className: "text-as-primary/70 flex items-center gap-1 rounded-lg", onClick: onSelectRecipient, children: _jsx("div", { className: "text-sm font-medium", children: "Select recipient" }) }))] }), isBuyMode || isDepositMode ? (
|
|
11
|
+
// Fixed destination token display for buy mode and deposit mode
|
|
12
|
+
_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary text-2xl font-bold", children: dstAmount || "0" }), _jsxs("div", { className: "bg-as-brand/10 border-as-brand/30 flex items-center gap-3 rounded-xl border px-4 py-3", children: [dstToken.metadata?.logoURI && (_jsx("img", { src: dstToken.metadata.logoURI, alt: dstToken.symbol, className: "h-8 w-8 rounded-full" })), _jsx("span", { className: "text-as-brand text-lg font-bold", children: dstToken.symbol })] })] })) : (
|
|
13
|
+
// Token selection for regular swap mode
|
|
14
|
+
_jsx(OrderTokenAmount, { address: selectedRecipientAddress, context: "to", inputValue: dstAmount, onChangeInput: onChangeDstAmount || (() => { }), chainId: selectedDstChainId || dstToken.chainId, setChainId: setSelectedDstChainId || (() => { }), token: dstToken, setToken: setSelectedDstToken || (() => { }) })), _jsxs("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: [formatDisplayNumber(anyspendQuote?.data?.currencyOut?.amountUsd, {
|
|
15
|
+
style: "currency",
|
|
16
|
+
fallback: "",
|
|
17
|
+
}), anyspendQuote?.data?.currencyIn?.amountUsd &&
|
|
18
|
+
anyspendQuote?.data?.currencyOut?.amountUsd &&
|
|
19
|
+
(() => {
|
|
20
|
+
const calculatePriceImpact = (inputUsd, outputUsd) => {
|
|
21
|
+
if (!inputUsd || !outputUsd) {
|
|
22
|
+
return { percentage: "0.00", isNegative: false };
|
|
23
|
+
}
|
|
24
|
+
const input = Number(inputUsd);
|
|
25
|
+
const output = Number(outputUsd);
|
|
26
|
+
// Handle edge cases
|
|
27
|
+
if (input === 0 || isNaN(input) || isNaN(output) || input <= output) {
|
|
28
|
+
return { percentage: "0.00", isNegative: false };
|
|
29
|
+
}
|
|
30
|
+
const percentageValue = ((output - input) / input) * 100;
|
|
31
|
+
// Handle the -0.00% case
|
|
32
|
+
if (percentageValue > -0.005 && percentageValue < 0) {
|
|
33
|
+
return { percentage: "0.00", isNegative: false };
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
percentage: Math.abs(percentageValue).toFixed(2),
|
|
37
|
+
isNegative: percentageValue < 0,
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const { percentage, isNegative } = calculatePriceImpact(anyspendQuote.data.currencyIn.amountUsd, anyspendQuote.data.currencyOut.amountUsd);
|
|
41
|
+
// Parse the percentage as a number for comparison
|
|
42
|
+
const percentageNum = parseFloat(percentage);
|
|
43
|
+
// Don't show if less than 1%
|
|
44
|
+
if (percentageNum < 1) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
// Using inline style to ensure color displays
|
|
48
|
+
return (_jsxs("span", { className: "ml-2", style: { color: percentageNum >= 10 ? "red" : "#FFD700" }, children: ["(", isNegative ? "-" : "", percentage, "%)"] }));
|
|
49
|
+
})()] })] }));
|
|
50
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CircleAlert } from "lucide-react";
|
|
3
|
+
export function ErrorSection({ error, message }) {
|
|
4
|
+
if (!error && !message) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
const errorMessage = message || error?.message || "An error occurred";
|
|
8
|
+
return (_jsxs("div", { className: "error-section bg-as-on-surface-1 flex w-full max-w-[460px] items-center gap-2 rounded-2xl px-4 py-2", children: [_jsx(CircleAlert, { className: "bg-as-red h-4 min-h-4 w-4 min-w-4 rounded-full p-0 text-sm font-medium text-white" }), _jsx("div", { className: "text-as-red text-sm", children: errorMessage })] }));
|
|
9
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { components } from "../../../../anyspend/types/api";
|
|
2
2
|
import { FiatPaymentMethod } from "./FiatPaymentMethod";
|
|
3
|
-
export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, }: {
|
|
3
|
+
export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, }: {
|
|
4
4
|
srcAmountOnRamp: string;
|
|
5
5
|
setSrcAmountOnRamp: (amount: string) => void;
|
|
6
6
|
selectedPaymentMethod?: FiatPaymentMethod;
|
|
@@ -11,4 +11,5 @@ export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selec
|
|
|
11
11
|
destinationAmount?: string;
|
|
12
12
|
onDestinationTokenChange?: (token: components["schemas"]["Token"]) => void;
|
|
13
13
|
onDestinationChainChange?: (chainId: number) => void;
|
|
14
|
+
fiatPaymentMethodIndex: number;
|
|
14
15
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -9,7 +9,7 @@ import { useRef } from "react";
|
|
|
9
9
|
import { toast } from "sonner";
|
|
10
10
|
import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
|
|
11
11
|
import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat.js";
|
|
12
|
-
export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, }) {
|
|
12
|
+
export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, }) {
|
|
13
13
|
// Get geo-based onramp options to access fee information
|
|
14
14
|
const { stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
|
|
15
15
|
// Helper function to get fees from API data
|
|
@@ -66,7 +66,7 @@ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPayme
|
|
|
66
66
|
const handleQuickAmount = (value) => {
|
|
67
67
|
setSrcAmountOnRamp(value);
|
|
68
68
|
};
|
|
69
|
-
return (_jsxs("div", { className: "bg-as-surface-primary flex w-full flex-col", children: [_jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary relative flex w-full flex-col rounded-2xl border p-4", children: [_jsxs("div", { className: "flex h-7 w-full items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm font-bold", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm", onClick: () => setActivePanel(
|
|
69
|
+
return (_jsxs("div", { className: "panel-onramp bg-as-surface-primary flex w-full flex-col", children: [_jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary relative flex w-full flex-col rounded-2xl border p-4", children: [_jsxs("div", { className: "flex h-7 w-full items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm font-bold", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm", onClick: () => setActivePanel(fiatPaymentMethodIndex), children: selectedPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "C" }) }), "Coinbase Pay"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedPaymentMethod === FiatPaymentMethod.STRIPE ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "S" }) }), "Stripe"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx("div", { className: "flex items-center justify-center pb-2 pt-8", children: _jsxs("div", { className: "flex gap-1", children: [_jsx("span", { className: "text-as-tertiarry text-2xl font-bold", children: "$" }), _jsx(Input, { ref: amountInputRef, type: "text", value: srcAmountOnRamp, onChange: handleAmountChange, placeholder: "5", className: "text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-3 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0", style: {
|
|
70
70
|
width: `${Math.max(50, srcAmountOnRamp.length * 34)}px`,
|
|
71
71
|
} })] }) }), _jsx("div", { className: "mx-auto mb-6 inline-grid grid-cols-4 gap-2", children: ["5", "10", "20", "25"].map(value => (_jsxs("button", { onClick: () => handleQuickAmount(value), className: `bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${srcAmountOnRamp === value
|
|
72
72
|
? "border-as-border-secondary bg-as-surface-secondary"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { components } from "../../../types/api";
|
|
2
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
3
|
+
import { FiatPaymentMethod } from "./FiatPaymentMethod";
|
|
4
|
+
interface PaySectionProps {
|
|
5
|
+
paymentType: "crypto" | "fiat";
|
|
6
|
+
selectedSrcChainId: number;
|
|
7
|
+
setSelectedSrcChainId: (chainId: number) => void;
|
|
8
|
+
selectedSrcToken: components["schemas"]["Token"];
|
|
9
|
+
setSelectedSrcToken: (token: components["schemas"]["Token"]) => void;
|
|
10
|
+
srcAmount: string;
|
|
11
|
+
setSrcAmount: (amount: string) => void;
|
|
12
|
+
setIsSrcInputDirty: (dirty: boolean) => void;
|
|
13
|
+
selectedCryptoPaymentMethod: CryptoPaymentMethodType;
|
|
14
|
+
selectedFiatPaymentMethod: FiatPaymentMethod;
|
|
15
|
+
onSelectCryptoPaymentMethod: () => void;
|
|
16
|
+
onSelectFiatPaymentMethod: () => void;
|
|
17
|
+
anyspendQuote?: any;
|
|
18
|
+
}
|
|
19
|
+
export declare function PaySection({ paymentType, selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, setIsSrcInputDirty, selectedCryptoPaymentMethod, selectedFiatPaymentMethod, onSelectCryptoPaymentMethod, onSelectFiatPaymentMethod, anyspendQuote, }: PaySectionProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Input, useAccountWallet, useTokenData } from "../../../../global-account/react/index.js";
|
|
3
|
+
import { formatUsername } from "../../../../shared/utils/index.js";
|
|
4
|
+
import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
|
|
5
|
+
import { formatDisplayNumber } from "../../../../shared/utils/number.js";
|
|
6
|
+
import { ChevronRight } from "lucide-react";
|
|
7
|
+
import { motion } from "motion/react";
|
|
8
|
+
import { useEffect, useRef } from "react";
|
|
9
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod.js";
|
|
10
|
+
import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
|
|
11
|
+
import { OrderTokenAmount } from "./OrderTokenAmount.js";
|
|
12
|
+
import { TokenBalance } from "./TokenBalance.js";
|
|
13
|
+
export function PaySection({ paymentType, selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, srcAmount, setSrcAmount, setIsSrcInputDirty, selectedCryptoPaymentMethod, selectedFiatPaymentMethod, onSelectCryptoPaymentMethod, onSelectFiatPaymentMethod, anyspendQuote, }) {
|
|
14
|
+
const { address: globalAddress, wallet: globalWallet, ensName: connectedName } = useAccountWallet();
|
|
15
|
+
const connectedAddress = globalWallet?.address;
|
|
16
|
+
const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
|
|
17
|
+
// Add ref to track if we've applied metadata
|
|
18
|
+
const appliedSrcMetadataRef = useRef(false);
|
|
19
|
+
// Update source token with metadata
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (selectedSrcToken && srcTokenMetadata && !appliedSrcMetadataRef.current) {
|
|
22
|
+
// Mark as applied
|
|
23
|
+
appliedSrcMetadataRef.current = true;
|
|
24
|
+
const enhancedToken = {
|
|
25
|
+
...selectedSrcToken,
|
|
26
|
+
decimals: srcTokenMetadata.decimals || selectedSrcToken.decimals,
|
|
27
|
+
symbol: srcTokenMetadata.symbol || selectedSrcToken.symbol,
|
|
28
|
+
name: srcTokenMetadata.name || selectedSrcToken.name,
|
|
29
|
+
metadata: {
|
|
30
|
+
...selectedSrcToken.metadata,
|
|
31
|
+
logoURI: srcTokenMetadata?.logoURI || selectedSrcToken.metadata.logoURI,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
setSelectedSrcToken(enhancedToken);
|
|
35
|
+
}
|
|
36
|
+
}, [srcTokenMetadata, selectedSrcToken, setSelectedSrcToken]);
|
|
37
|
+
// Reset source token ref when address/chain changes
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
appliedSrcMetadataRef.current = false;
|
|
40
|
+
}, [selectedSrcToken.address, selectedSrcToken.chainId]);
|
|
41
|
+
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-7 items-center text-sm", children: "Pay" }), paymentType === "crypto" ? (_jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors", onClick: onSelectCryptoPaymentMethod, children: selectedCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (_jsxs(_Fragment, { children: [globalAddress ? (_jsx("div", { className: "flex items-center gap-1", children: connectedName ? formatUsername(connectedName) : shortenAddress(connectedAddress || "") })) : ("Connect wallet"), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (_jsxs(_Fragment, { children: ["Transfer crypto", _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })) : (_jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors", onClick: onSelectFiatPaymentMethod, children: selectedFiatPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "C" }) }), "Coinbase Pay"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedFiatPaymentMethod === FiatPaymentMethod.STRIPE ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "S" }) }), "Credit/Debit Card"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) }))] }), paymentType === "crypto" ? (_jsxs(_Fragment, { children: [_jsx(OrderTokenAmount, { address: globalAddress, context: "from", inputValue: srcAmount, onChangeInput: value => {
|
|
42
|
+
setIsSrcInputDirty(true);
|
|
43
|
+
setSrcAmount(value);
|
|
44
|
+
}, chainId: selectedSrcChainId, setChainId: setSelectedSrcChainId, token: selectedSrcToken, setToken: setSelectedSrcToken }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary/50 flex h-5 items-center text-sm", children: formatDisplayNumber(anyspendQuote?.data?.currencyIn?.amountUsd, {
|
|
45
|
+
style: "currency",
|
|
46
|
+
fallback: "",
|
|
47
|
+
}) }), _jsx(TokenBalance, { token: selectedSrcToken, walletAddress: globalAddress, onChangeInput: value => {
|
|
48
|
+
setIsSrcInputDirty(true);
|
|
49
|
+
setSrcAmount(value);
|
|
50
|
+
} })] })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex items-center justify-center pb-2 pt-8", children: _jsxs("div", { className: "flex gap-1", children: [_jsx("span", { className: "text-as-tertiarry text-2xl font-bold", children: "$" }), _jsx(Input, { type: "text", value: srcAmount, onChange: e => setSrcAmount(e.target.value.replace(/[^0-9.]/g, "")), placeholder: "5", className: "text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-3 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0", style: {
|
|
51
|
+
width: `${Math.max(50, srcAmount.length * 34)}px`,
|
|
52
|
+
} })] }) }), _jsx("div", { className: "mx-auto mb-6 inline-grid grid-cols-4 gap-2", children: ["5", "10", "20", "25"].map(value => (_jsxs("button", { onClick: () => setSrcAmount(value), className: `bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${srcAmount === value
|
|
53
|
+
? "border-as-border-secondary bg-as-surface-secondary"
|
|
54
|
+
: "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) })] }))] }));
|
|
55
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
2
|
+
import { FiatPaymentMethod } from "./FiatPaymentMethod";
|
|
3
|
+
interface TabSectionProps {
|
|
4
|
+
activeTab: "crypto" | "fiat";
|
|
5
|
+
setActiveTab: (tab: "crypto" | "fiat") => void;
|
|
6
|
+
setSelectedCryptoPaymentMethod: (method: CryptoPaymentMethodType) => void;
|
|
7
|
+
setSelectedFiatPaymentMethod: (method: FiatPaymentMethod) => void;
|
|
8
|
+
}
|
|
9
|
+
export declare function TabSection({ activeTab, setActiveTab, setSelectedCryptoPaymentMethod, setSelectedFiatPaymentMethod, }: TabSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from "../../../../shared/utils/cn.js";
|
|
3
|
+
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod.js";
|
|
4
|
+
import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
|
|
5
|
+
export function TabSection({ activeTab, setActiveTab, setSelectedCryptoPaymentMethod, setSelectedFiatPaymentMethod, }) {
|
|
6
|
+
return (_jsx("div", { className: "tab-section w-full", children: _jsxs("div", { className: "bg-as-surface-secondary relative mb-4 grid h-10 grid-cols-2 rounded-xl", children: [_jsx("div", { className: cn("bg-as-brand absolute bottom-0 left-0 top-0 z-0 rounded-xl transition-transform duration-100", "h-full w-1/2", activeTab === "fiat" ? "translate-x-full" : "translate-x-0"), style: { willChange: "transform" } }), _jsx("button", { className: cn("relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100", activeTab === "crypto" ? "text-white" : "text-as-primary/70 hover:bg-as-on-surface-2 bg-transparent"), onClick: () => {
|
|
7
|
+
setActiveTab("crypto");
|
|
8
|
+
setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE); // Reset payment method when switching to crypto
|
|
9
|
+
setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE); // Reset fiat payment method when switching to crypto
|
|
10
|
+
}, children: "Pay with crypto" }), _jsx("button", { className: cn("relative z-10 h-full w-full rounded-xl px-3 text-sm font-medium transition-colors duration-100", activeTab === "fiat" ? "text-white" : "text-as-primary/70 hover:bg-as-on-surface-2 bg-transparent"), onClick: () => {
|
|
11
|
+
setActiveTab("fiat");
|
|
12
|
+
setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE); // Reset crypto payment method when switching to fiat
|
|
13
|
+
setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE); // Reset fiat payment method when switching to fiat
|
|
14
|
+
}, children: "Pay with Fiat" })] }) }));
|
|
15
|
+
}
|
|
@@ -9,6 +9,7 @@ export { AnySpendStakeB3 } from "./AnySpendStakeB3";
|
|
|
9
9
|
export { AnySpendTournament } from "./AnySpendTournament";
|
|
10
10
|
export { AnySpendNFTButton } from "./common/AnySpendNFTButton";
|
|
11
11
|
export { ChainTokenIcon } from "./common/ChainTokenIcon";
|
|
12
|
+
export { CryptoReceiveSection } from "./common/CryptoReceiveSection";
|
|
12
13
|
export { OrderDetails } from "./common/OrderDetails";
|
|
13
14
|
export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible";
|
|
14
15
|
export { OrderHistory } from "./common/OrderHistory";
|
|
@@ -16,6 +17,7 @@ export { OrderHistoryItem } from "./common/OrderHistoryItem";
|
|
|
16
17
|
export { OrderStatus } from "./common/OrderStatus";
|
|
17
18
|
export { OrderToken } from "./common/OrderToken";
|
|
18
19
|
export { OrderTokenAmount } from "./common/OrderTokenAmount";
|
|
20
|
+
export { PaySection } from "./common/PaySection";
|
|
19
21
|
export { RecipientSelection } from "./common/RecipientSelection";
|
|
20
22
|
export { StepProgress } from "./common/StepProgress";
|
|
21
23
|
export { TokenBalance } from "./common/TokenBalance";
|
|
@@ -11,6 +11,7 @@ export { AnySpendTournament } from "./AnySpendTournament.js";
|
|
|
11
11
|
export { AnySpendNFTButton } from "./common/AnySpendNFTButton.js";
|
|
12
12
|
// Common Components
|
|
13
13
|
export { ChainTokenIcon } from "./common/ChainTokenIcon.js";
|
|
14
|
+
export { CryptoReceiveSection } from "./common/CryptoReceiveSection.js";
|
|
14
15
|
export { OrderDetails } from "./common/OrderDetails.js";
|
|
15
16
|
export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible.js";
|
|
16
17
|
export { OrderHistory } from "./common/OrderHistory.js";
|
|
@@ -18,6 +19,7 @@ export { OrderHistoryItem } from "./common/OrderHistoryItem.js";
|
|
|
18
19
|
export { OrderStatus } from "./common/OrderStatus.js";
|
|
19
20
|
export { OrderToken } from "./common/OrderToken.js";
|
|
20
21
|
export { OrderTokenAmount } from "./common/OrderTokenAmount.js";
|
|
22
|
+
export { PaySection } from "./common/PaySection.js";
|
|
21
23
|
export { RecipientSelection } from "./common/RecipientSelection.js";
|
|
22
24
|
export { StepProgress } from "./common/StepProgress.js";
|
|
23
25
|
export { TokenBalance } from "./common/TokenBalance.js";
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { components } from "../../types/api";
|
|
2
|
+
import { CryptoPaymentMethodType } from "../components/common/CryptoPaymentMethod";
|
|
3
|
+
import { FiatPaymentMethod } from "../components/common/FiatPaymentMethod";
|
|
4
|
+
export declare enum PanelView {
|
|
5
|
+
MAIN = 0,
|
|
6
|
+
CRYPTO_PAYMENT_METHOD = 1,
|
|
7
|
+
FIAT_PAYMENT_METHOD = 2,
|
|
8
|
+
RECIPIENT_SELECTION = 3,
|
|
9
|
+
ORDER_DETAILS = 4,
|
|
10
|
+
LOADING = 5
|
|
11
|
+
}
|
|
12
|
+
interface UseAnyspendFlowProps {
|
|
13
|
+
paymentType?: "crypto" | "fiat";
|
|
14
|
+
recipientAddress?: string;
|
|
15
|
+
loadOrder?: string;
|
|
16
|
+
isDepositMode?: boolean;
|
|
17
|
+
onOrderSuccess?: (orderId: string) => void;
|
|
18
|
+
onTransactionSuccess?: () => void;
|
|
19
|
+
sourceTokenAddress?: string;
|
|
20
|
+
sourceTokenChainId?: number;
|
|
21
|
+
}
|
|
22
|
+
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, isDepositMode, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, }: UseAnyspendFlowProps): {
|
|
23
|
+
activePanel: PanelView;
|
|
24
|
+
setActivePanel: import("react").Dispatch<import("react").SetStateAction<PanelView>>;
|
|
25
|
+
orderId: string | undefined;
|
|
26
|
+
setOrderId: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
27
|
+
oat: {
|
|
28
|
+
success: boolean;
|
|
29
|
+
message: string;
|
|
30
|
+
data: {
|
|
31
|
+
order: components["schemas"]["Order"];
|
|
32
|
+
depositTxs: components["schemas"]["DepositTx"][] | null;
|
|
33
|
+
relayTx: components["schemas"]["RelayTx"] | null;
|
|
34
|
+
executeTx: components["schemas"]["ExecuteTx"] | null;
|
|
35
|
+
refundTxs: components["schemas"]["RefundTx"][] | null;
|
|
36
|
+
};
|
|
37
|
+
statusCode: number;
|
|
38
|
+
} | undefined;
|
|
39
|
+
selectedSrcChainId: number;
|
|
40
|
+
setSelectedSrcChainId: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
41
|
+
selectedDstChainId: number;
|
|
42
|
+
setSelectedDstChainId: import("react").Dispatch<import("react").SetStateAction<number>>;
|
|
43
|
+
selectedSrcToken: {
|
|
44
|
+
chainId: number;
|
|
45
|
+
address: string;
|
|
46
|
+
symbol: string;
|
|
47
|
+
name: string;
|
|
48
|
+
decimals: number;
|
|
49
|
+
metadata: {
|
|
50
|
+
logoURI?: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
setSelectedSrcToken: import("react").Dispatch<import("react").SetStateAction<{
|
|
54
|
+
chainId: number;
|
|
55
|
+
address: string;
|
|
56
|
+
symbol: string;
|
|
57
|
+
name: string;
|
|
58
|
+
decimals: number;
|
|
59
|
+
metadata: {
|
|
60
|
+
logoURI?: string;
|
|
61
|
+
};
|
|
62
|
+
}>>;
|
|
63
|
+
srcAmount: string;
|
|
64
|
+
setSrcAmount: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
65
|
+
dstAmount: string;
|
|
66
|
+
setDstAmount: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
67
|
+
isSrcInputDirty: boolean;
|
|
68
|
+
setIsSrcInputDirty: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
69
|
+
selectedCryptoPaymentMethod: CryptoPaymentMethodType;
|
|
70
|
+
setSelectedCryptoPaymentMethod: import("react").Dispatch<import("react").SetStateAction<CryptoPaymentMethodType>>;
|
|
71
|
+
selectedFiatPaymentMethod: FiatPaymentMethod;
|
|
72
|
+
setSelectedFiatPaymentMethod: import("react").Dispatch<import("react").SetStateAction<FiatPaymentMethod>>;
|
|
73
|
+
selectedRecipientAddress: string | undefined;
|
|
74
|
+
setSelectedRecipientAddress: import("react").Dispatch<import("react").SetStateAction<string | undefined>>;
|
|
75
|
+
recipientName: string | null | undefined;
|
|
76
|
+
globalAddress: string | undefined;
|
|
77
|
+
anyspendQuote: {
|
|
78
|
+
success: boolean;
|
|
79
|
+
message: string;
|
|
80
|
+
data: {
|
|
81
|
+
operation?: string;
|
|
82
|
+
sender?: string;
|
|
83
|
+
recipient?: string;
|
|
84
|
+
currencyIn?: {
|
|
85
|
+
currency?: {
|
|
86
|
+
chainId?: number;
|
|
87
|
+
address?: string;
|
|
88
|
+
symbol?: string;
|
|
89
|
+
name?: string;
|
|
90
|
+
decimals?: number;
|
|
91
|
+
metadata?: {
|
|
92
|
+
logoURI?: string;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
amount?: string;
|
|
96
|
+
amountFormatted?: string;
|
|
97
|
+
amountUsd?: string;
|
|
98
|
+
minimumAmount?: string;
|
|
99
|
+
};
|
|
100
|
+
currencyOut?: {
|
|
101
|
+
currency?: {
|
|
102
|
+
chainId?: number;
|
|
103
|
+
address?: string;
|
|
104
|
+
symbol?: string;
|
|
105
|
+
name?: string;
|
|
106
|
+
decimals?: number;
|
|
107
|
+
metadata?: {
|
|
108
|
+
logoURI?: string;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
amount?: string;
|
|
112
|
+
amountFormatted?: string;
|
|
113
|
+
amountUsd?: string;
|
|
114
|
+
minimumAmount?: string;
|
|
115
|
+
};
|
|
116
|
+
totalImpact?: {
|
|
117
|
+
usd?: string;
|
|
118
|
+
percent?: string;
|
|
119
|
+
};
|
|
120
|
+
swapImpact?: {
|
|
121
|
+
usd?: string;
|
|
122
|
+
percent?: string;
|
|
123
|
+
};
|
|
124
|
+
rate?: string;
|
|
125
|
+
slippageTolerance?: {
|
|
126
|
+
origin?: {
|
|
127
|
+
usd?: string;
|
|
128
|
+
value?: string;
|
|
129
|
+
percent?: string;
|
|
130
|
+
};
|
|
131
|
+
destination?: {
|
|
132
|
+
usd?: string;
|
|
133
|
+
value?: string;
|
|
134
|
+
percent?: string;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
timeEstimate?: number;
|
|
138
|
+
userBalance?: string;
|
|
139
|
+
};
|
|
140
|
+
statusCode: number;
|
|
141
|
+
} | undefined;
|
|
142
|
+
isLoadingAnyspendQuote: boolean;
|
|
143
|
+
getAnyspendQuoteError: Error | null;
|
|
144
|
+
activeInputAmountInWei: string;
|
|
145
|
+
geoData: import("../../../anyspend/react").GeoData | undefined;
|
|
146
|
+
coinbaseAvailablePaymentMethods: {
|
|
147
|
+
id?: string;
|
|
148
|
+
min?: string;
|
|
149
|
+
max?: string;
|
|
150
|
+
}[];
|
|
151
|
+
stripeWeb2Support: {
|
|
152
|
+
isSupport: false;
|
|
153
|
+
} | {
|
|
154
|
+
isSupport: true;
|
|
155
|
+
formattedTotalUsd: string;
|
|
156
|
+
formattedOnrampUsd: string;
|
|
157
|
+
formattedFeeUsd: string;
|
|
158
|
+
};
|
|
159
|
+
getOnrampVendor: (paymentMethod: FiatPaymentMethod) => "coinbase" | "stripe" | "stripe-web2" | undefined;
|
|
160
|
+
createOrder: import("@tanstack/react-query").UseMutateFunction<any, Error, import("../../../anyspend/react").CreateOrderParams, unknown>;
|
|
161
|
+
isCreatingOrder: boolean;
|
|
162
|
+
createOnrampOrder: import("@tanstack/react-query").UseMutateFunction<any, Error, import("../../../anyspend/react").CreateOnrampOrderParams, unknown>;
|
|
163
|
+
isCreatingOnrampOrder: boolean;
|
|
164
|
+
};
|
|
165
|
+
export {};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { B3_TOKEN, getDefaultToken, USDC_BASE } from "../../../anyspend/index.js";
|
|
2
|
+
import { useAnyspendCreateOnrampOrder, useAnyspendCreateOrder, useAnyspendOrderAndTransactions, useAnyspendQuote, useGeoOnrampOptions, } from "../../../anyspend/react/index.js";
|
|
3
|
+
import { anyspendService } from "../../../anyspend/services/anyspend.js";
|
|
4
|
+
import { useAccountWallet, useProfile } from "../../../global-account/react/index.js";
|
|
5
|
+
import { formatTokenAmount, formatUnits } from "../../../shared/utils/number.js";
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import { toast } from "sonner";
|
|
8
|
+
import { parseUnits } from "viem";
|
|
9
|
+
import { base, mainnet } from "viem/chains";
|
|
10
|
+
import { CryptoPaymentMethodType } from "../components/common/CryptoPaymentMethod.js";
|
|
11
|
+
import { FiatPaymentMethod } from "../components/common/FiatPaymentMethod.js";
|
|
12
|
+
export var PanelView;
|
|
13
|
+
(function (PanelView) {
|
|
14
|
+
PanelView[PanelView["MAIN"] = 0] = "MAIN";
|
|
15
|
+
PanelView[PanelView["CRYPTO_PAYMENT_METHOD"] = 1] = "CRYPTO_PAYMENT_METHOD";
|
|
16
|
+
PanelView[PanelView["FIAT_PAYMENT_METHOD"] = 2] = "FIAT_PAYMENT_METHOD";
|
|
17
|
+
PanelView[PanelView["RECIPIENT_SELECTION"] = 3] = "RECIPIENT_SELECTION";
|
|
18
|
+
PanelView[PanelView["ORDER_DETAILS"] = 4] = "ORDER_DETAILS";
|
|
19
|
+
PanelView[PanelView["LOADING"] = 5] = "LOADING";
|
|
20
|
+
})(PanelView || (PanelView = {}));
|
|
21
|
+
export function useAnyspendFlow({ paymentType = "crypto", recipientAddress, loadOrder, isDepositMode = false, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, }) {
|
|
22
|
+
// Panel and order state
|
|
23
|
+
const [activePanel, setActivePanel] = useState(loadOrder ? PanelView.ORDER_DETAILS : PanelView.MAIN);
|
|
24
|
+
const [orderId, setOrderId] = useState(loadOrder);
|
|
25
|
+
const { orderAndTransactions: oat } = useAnyspendOrderAndTransactions(orderId);
|
|
26
|
+
// Token selection state - use provided sourceTokenChainId if available
|
|
27
|
+
const [selectedSrcChainId, setSelectedSrcChainId] = useState(sourceTokenChainId || (paymentType === "fiat" ? base.id : mainnet.id));
|
|
28
|
+
const [selectedDstChainId, setSelectedDstChainId] = useState(base.id); // Default to Base for cross-chain swaps
|
|
29
|
+
const defaultSrcToken = paymentType === "fiat" ? USDC_BASE : getDefaultToken(selectedSrcChainId);
|
|
30
|
+
const [selectedSrcToken, setSelectedSrcToken] = useState(defaultSrcToken);
|
|
31
|
+
const [srcAmount, setSrcAmount] = useState(paymentType === "fiat" ? "5" : "0.1");
|
|
32
|
+
const [dstAmount, setDstAmount] = useState("");
|
|
33
|
+
const [isSrcInputDirty, setIsSrcInputDirty] = useState(true);
|
|
34
|
+
// Payment method state
|
|
35
|
+
const [selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod] = useState(CryptoPaymentMethodType.NONE);
|
|
36
|
+
const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState(FiatPaymentMethod.NONE);
|
|
37
|
+
// Recipient state
|
|
38
|
+
const { address: globalAddress } = useAccountWallet();
|
|
39
|
+
const [selectedRecipientAddress, setSelectedRecipientAddress] = useState(recipientAddress);
|
|
40
|
+
const recipientProfile = useProfile({ address: selectedRecipientAddress, fresh: true });
|
|
41
|
+
const recipientName = recipientProfile.data?.name;
|
|
42
|
+
// Set default recipient address when wallet changes
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!selectedRecipientAddress && globalAddress) {
|
|
45
|
+
setSelectedRecipientAddress(globalAddress);
|
|
46
|
+
}
|
|
47
|
+
}, [selectedRecipientAddress, globalAddress]);
|
|
48
|
+
// Fetch specific token when sourceTokenAddress and sourceTokenChainId are provided
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
const fetchSourceToken = async () => {
|
|
51
|
+
if (sourceTokenAddress && sourceTokenChainId) {
|
|
52
|
+
try {
|
|
53
|
+
const token = await anyspendService.getToken(sourceTokenChainId, sourceTokenAddress);
|
|
54
|
+
setSelectedSrcToken(token);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error("Failed to fetch source token:", error);
|
|
58
|
+
toast.error(`Failed to load token ${sourceTokenAddress} on chain ${sourceTokenChainId}`);
|
|
59
|
+
// Keep the default token on error
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
fetchSourceToken();
|
|
64
|
+
}, [sourceTokenAddress, sourceTokenChainId]);
|
|
65
|
+
// Helper function for onramp vendor mapping
|
|
66
|
+
const getOnrampVendor = (paymentMethod) => {
|
|
67
|
+
switch (paymentMethod) {
|
|
68
|
+
case FiatPaymentMethod.COINBASE_PAY:
|
|
69
|
+
return "coinbase";
|
|
70
|
+
case FiatPaymentMethod.STRIPE:
|
|
71
|
+
return "stripe-web2";
|
|
72
|
+
default:
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
// Get quote
|
|
77
|
+
const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""), selectedSrcToken.decimals).toString();
|
|
78
|
+
const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } = useAnyspendQuote({
|
|
79
|
+
srcChain: paymentType === "fiat" ? base.id : selectedSrcChainId,
|
|
80
|
+
dstChain: isDepositMode ? base.id : selectedDstChainId, // For deposits, always Base; for swaps, use selected destination
|
|
81
|
+
srcTokenAddress: paymentType === "fiat" ? USDC_BASE.address : selectedSrcToken.address,
|
|
82
|
+
dstTokenAddress: isDepositMode ? B3_TOKEN.address : selectedSrcToken.address, // For deposits, always B3
|
|
83
|
+
type: "swap",
|
|
84
|
+
tradeType: "EXACT_INPUT",
|
|
85
|
+
amount: activeInputAmountInWei,
|
|
86
|
+
onrampVendor: paymentType === "fiat" ? getOnrampVendor(selectedFiatPaymentMethod) : undefined,
|
|
87
|
+
});
|
|
88
|
+
// Get geo options for fiat
|
|
89
|
+
const { geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support } = useGeoOnrampOptions(paymentType === "fiat" ? formatUnits(activeInputAmountInWei, USDC_BASE.decimals) : "0");
|
|
90
|
+
// Update destination amount when quote changes
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (anyspendQuote?.data?.currencyOut?.amount && anyspendQuote.data.currencyOut.currency?.decimals) {
|
|
93
|
+
const amount = anyspendQuote.data.currencyOut.amount;
|
|
94
|
+
const decimals = anyspendQuote.data.currencyOut.currency.decimals;
|
|
95
|
+
const formattedAmount = formatTokenAmount(BigInt(amount), decimals, 6, false);
|
|
96
|
+
setDstAmount(formattedAmount);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
setDstAmount("");
|
|
100
|
+
}
|
|
101
|
+
}, [anyspendQuote]);
|
|
102
|
+
// Order creation hooks
|
|
103
|
+
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
|
|
104
|
+
onSuccess: data => {
|
|
105
|
+
const newOrderId = data.data.id;
|
|
106
|
+
setOrderId(newOrderId);
|
|
107
|
+
setActivePanel(PanelView.ORDER_DETAILS);
|
|
108
|
+
onOrderSuccess?.(newOrderId);
|
|
109
|
+
},
|
|
110
|
+
onError: error => {
|
|
111
|
+
console.error(error);
|
|
112
|
+
toast.error("Failed to create order: " + error.message);
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const { createOrder: createOnrampOrder, isCreatingOrder: isCreatingOnrampOrder } = useAnyspendCreateOnrampOrder({
|
|
116
|
+
onSuccess: data => {
|
|
117
|
+
const newOrderId = data.data.id;
|
|
118
|
+
setOrderId(newOrderId);
|
|
119
|
+
setActivePanel(PanelView.ORDER_DETAILS);
|
|
120
|
+
onOrderSuccess?.(newOrderId);
|
|
121
|
+
},
|
|
122
|
+
onError: error => {
|
|
123
|
+
console.error(error);
|
|
124
|
+
toast.error("Failed to create order: " + error.message);
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
// Handle order completion
|
|
128
|
+
useEffect(() => {
|
|
129
|
+
if (oat?.data?.order.status === "executed") {
|
|
130
|
+
console.log("Order executed successfully");
|
|
131
|
+
onTransactionSuccess?.();
|
|
132
|
+
}
|
|
133
|
+
}, [oat?.data?.order.status, onTransactionSuccess]);
|
|
134
|
+
return {
|
|
135
|
+
// State
|
|
136
|
+
activePanel,
|
|
137
|
+
setActivePanel,
|
|
138
|
+
orderId,
|
|
139
|
+
setOrderId,
|
|
140
|
+
oat,
|
|
141
|
+
// Token state
|
|
142
|
+
selectedSrcChainId,
|
|
143
|
+
setSelectedSrcChainId,
|
|
144
|
+
selectedDstChainId,
|
|
145
|
+
setSelectedDstChainId,
|
|
146
|
+
selectedSrcToken,
|
|
147
|
+
setSelectedSrcToken,
|
|
148
|
+
srcAmount,
|
|
149
|
+
setSrcAmount,
|
|
150
|
+
dstAmount,
|
|
151
|
+
setDstAmount,
|
|
152
|
+
isSrcInputDirty,
|
|
153
|
+
setIsSrcInputDirty,
|
|
154
|
+
// Payment methods
|
|
155
|
+
selectedCryptoPaymentMethod,
|
|
156
|
+
setSelectedCryptoPaymentMethod,
|
|
157
|
+
selectedFiatPaymentMethod,
|
|
158
|
+
setSelectedFiatPaymentMethod,
|
|
159
|
+
// Recipient
|
|
160
|
+
selectedRecipientAddress,
|
|
161
|
+
setSelectedRecipientAddress,
|
|
162
|
+
recipientName,
|
|
163
|
+
globalAddress,
|
|
164
|
+
// Quote data
|
|
165
|
+
anyspendQuote,
|
|
166
|
+
isLoadingAnyspendQuote,
|
|
167
|
+
getAnyspendQuoteError,
|
|
168
|
+
activeInputAmountInWei,
|
|
169
|
+
// Geo/onramp data
|
|
170
|
+
geoData,
|
|
171
|
+
coinbaseAvailablePaymentMethods,
|
|
172
|
+
stripeWeb2Support,
|
|
173
|
+
getOnrampVendor,
|
|
174
|
+
// Order creation
|
|
175
|
+
createOrder,
|
|
176
|
+
isCreatingOrder,
|
|
177
|
+
createOnrampOrder,
|
|
178
|
+
isCreatingOnrampOrder,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -28,10 +28,10 @@ export declare const useGenerateSigMintData: ({ recipientAddress, contractAddres
|
|
|
28
28
|
description?: string | undefined;
|
|
29
29
|
properties?: any;
|
|
30
30
|
image?: string | undefined;
|
|
31
|
+
backgroundColor?: string | undefined;
|
|
31
32
|
externalLink?: string | undefined;
|
|
32
33
|
appUri?: string | undefined;
|
|
33
34
|
attributes?: any;
|
|
34
|
-
backgroundColor?: string | undefined;
|
|
35
35
|
promptImageUrl?: string | undefined;
|
|
36
36
|
};
|
|
37
37
|
} | undefined;
|
|
@@ -48,8 +48,8 @@ export declare const useGenerateSigMintData: ({ recipientAddress, contractAddres
|
|
|
48
48
|
creatorMap?: {} | undefined;
|
|
49
49
|
chainId: number;
|
|
50
50
|
address: string;
|
|
51
|
-
title: string;
|
|
52
51
|
_id: string | {};
|
|
52
|
+
title: string;
|
|
53
53
|
};
|
|
54
54
|
} | null;
|
|
55
55
|
error: Error | null;
|