@b3dotfun/sdk 0.0.63-test.0 → 0.0.63-test.0-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.
Files changed (66) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
  2. package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +275 -0
  3. package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
  4. package/dist/cjs/anyspend/react/components/AnySpendStakeB3ExactIn.js +288 -0
  5. package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
  6. package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.js +33 -0
  7. package/dist/cjs/anyspend/react/components/common/OrderDetails.js +10 -2
  8. package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
  9. package/dist/cjs/anyspend/react/components/index.d.ts +5 -1
  10. package/dist/cjs/anyspend/react/components/index.js +11 -3
  11. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
  12. package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +30 -8
  13. package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
  14. package/dist/cjs/anyspend/react/hooks/useAnyspendQuote.js +1 -1
  15. package/dist/cjs/anyspend/types/api.d.ts +665 -3
  16. package/dist/cjs/anyspend/utils/orderPayload.js +4 -0
  17. package/dist/cjs/global-account/react/components/B3DynamicModal.js +10 -1
  18. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
  19. package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +2 -2
  20. package/dist/cjs/global-account/react/hooks/useAuthentication.js +7 -2
  21. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +31 -1
  22. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
  23. package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +269 -0
  24. package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
  25. package/dist/esm/anyspend/react/components/AnySpendStakeB3ExactIn.js +285 -0
  26. package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
  27. package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.js +30 -0
  28. package/dist/esm/anyspend/react/components/common/OrderDetails.js +10 -2
  29. package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +2 -3
  30. package/dist/esm/anyspend/react/components/index.d.ts +5 -1
  31. package/dist/esm/anyspend/react/components/index.js +5 -1
  32. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
  33. package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +30 -8
  34. package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
  35. package/dist/esm/anyspend/react/hooks/useAnyspendQuote.js +1 -1
  36. package/dist/esm/anyspend/types/api.d.ts +665 -3
  37. package/dist/esm/anyspend/utils/orderPayload.js +4 -0
  38. package/dist/esm/global-account/react/components/B3DynamicModal.js +11 -2
  39. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStep.js +2 -2
  40. package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +2 -2
  41. package/dist/esm/global-account/react/hooks/useAuthentication.js +7 -2
  42. package/dist/esm/global-account/react/stores/useModalStore.d.ts +31 -1
  43. package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +34 -0
  44. package/dist/types/anyspend/react/components/AnySpendStakeB3ExactIn.d.ts +9 -0
  45. package/dist/types/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +11 -0
  46. package/dist/types/anyspend/react/components/index.d.ts +5 -1
  47. package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +25 -3
  48. package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +116 -0
  49. package/dist/types/anyspend/types/api.d.ts +665 -3
  50. package/dist/types/global-account/react/hooks/useAuthentication.d.ts +2 -2
  51. package/dist/types/global-account/react/stores/useModalStore.d.ts +31 -1
  52. package/package.json +3 -3
  53. package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +595 -0
  54. package/src/anyspend/react/components/AnySpendStakeB3ExactIn.tsx +522 -0
  55. package/src/anyspend/react/components/AnySpendStakeUpsideExactIn.tsx +73 -0
  56. package/src/anyspend/react/components/common/OrderDetails.tsx +10 -2
  57. package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +2 -3
  58. package/src/anyspend/react/components/index.ts +5 -1
  59. package/src/anyspend/react/hooks/useAnyspendFlow.ts +38 -8
  60. package/src/anyspend/react/hooks/useAnyspendQuote.ts +1 -1
  61. package/src/anyspend/types/api.ts +669 -1
  62. package/src/anyspend/utils/orderPayload.ts +5 -1
  63. package/src/global-account/react/components/B3DynamicModal.tsx +11 -1
  64. package/src/global-account/react/components/SignInWithB3/steps/LoginStep.tsx +2 -2
  65. package/src/global-account/react/hooks/useAuthentication.ts +10 -2
  66. package/src/global-account/react/stores/useModalStore.ts +34 -0
@@ -0,0 +1,34 @@
1
+ import { components } from "../../../anyspend/types/api";
2
+ import { GetQuoteResponse } from "../../../anyspend/types/api_req_res";
3
+ type CustomExactInConfig = {
4
+ functionAbi: string;
5
+ functionName: string;
6
+ functionArgs: string[];
7
+ to: string;
8
+ spenderAddress?: string;
9
+ action?: string;
10
+ };
11
+ export interface AnySpendCustomExactInProps {
12
+ loadOrder?: string;
13
+ mode?: "modal" | "page";
14
+ recipientAddress: string;
15
+ paymentType?: "crypto" | "fiat";
16
+ sourceTokenAddress?: string;
17
+ sourceTokenChainId?: number;
18
+ destinationToken: components["schemas"]["Token"];
19
+ destinationChainId: number;
20
+ onSuccess?: (amount: string) => void;
21
+ mainFooter?: React.ReactNode;
22
+ onTokenSelect?: (token: components["schemas"]["Token"], event: {
23
+ preventDefault: () => void;
24
+ }) => void;
25
+ customUsdInputValues?: string[];
26
+ preferEoa?: boolean;
27
+ customExactInConfig: CustomExactInConfig;
28
+ header?: ({ anyspendPrice, isLoadingAnyspendPrice, }: {
29
+ anyspendPrice: GetQuoteResponse | undefined;
30
+ isLoadingAnyspendPrice: boolean;
31
+ }) => React.JSX.Element;
32
+ }
33
+ export declare function AnySpendCustomExactIn(props: AnySpendCustomExactInProps): import("react/jsx-runtime").JSX.Element;
34
+ export {};
@@ -0,0 +1,275 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AnySpendCustomExactIn = AnySpendCustomExactIn;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const utils_1 = require("../../../anyspend/utils");
9
+ const react_1 = require("../../../global-account/react");
10
+ const cn_1 = require("../../../shared/utils/cn");
11
+ const invariant_1 = __importDefault(require("invariant"));
12
+ const lucide_react_1 = require("lucide-react");
13
+ const react_2 = require("motion/react");
14
+ const react_3 = require("react");
15
+ const sonner_1 = require("sonner");
16
+ const react_4 = require("thirdweb/react");
17
+ const utils_2 = require("../../utils");
18
+ const useAnyspendFlow_1 = require("../hooks/useAnyspendFlow");
19
+ const AnySpendFingerprintWrapper_1 = require("./AnySpendFingerprintWrapper");
20
+ const CryptoPaySection_1 = require("./common/CryptoPaySection");
21
+ const CryptoPaymentMethod_1 = require("./common/CryptoPaymentMethod");
22
+ const CryptoReceiveSection_1 = require("./common/CryptoReceiveSection");
23
+ const FeeDetailPanel_1 = require("./common/FeeDetailPanel");
24
+ const FiatPaymentMethod_1 = require("./common/FiatPaymentMethod");
25
+ const OrderDetails_1 = require("./common/OrderDetails");
26
+ const PanelOnramp_1 = require("./common/PanelOnramp");
27
+ const PointsDetailPanel_1 = require("./common/PointsDetailPanel");
28
+ const RecipientSelection_1 = require("./common/RecipientSelection");
29
+ const SLIPPAGE_PERCENT = 3;
30
+ function AnySpendCustomExactIn(props) {
31
+ const fingerprintConfig = (0, AnySpendFingerprintWrapper_1.getFingerprintConfig)();
32
+ return ((0, jsx_runtime_1.jsx)(AnySpendFingerprintWrapper_1.AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: (0, jsx_runtime_1.jsx)(AnySpendCustomExactInInner, { ...props }) }));
33
+ }
34
+ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddress, paymentType = "crypto", sourceTokenAddress, sourceTokenChainId, destinationToken, destinationChainId, onSuccess, mainFooter, onTokenSelect, customUsdInputValues, preferEoa, customExactInConfig, header, }) {
35
+ const actionLabel = customExactInConfig.action ?? "Custom Execution";
36
+ const DESTINATION_TOKEN_DETAILS = {
37
+ SYMBOL: destinationToken.symbol ?? "TOKEN",
38
+ LOGO_URI: destinationToken.metadata?.logoURI ?? "",
39
+ };
40
+ const { activePanel, setActivePanel, orderId, setOrderId, oat, selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, selectedDstToken, selectedDstChainId, srcAmount, setSrcAmount, dstAmount, isSrcInputDirty, setIsSrcInputDirty, selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod, selectedFiatPaymentMethod, setSelectedFiatPaymentMethod, selectedRecipientAddress, setSelectedRecipientAddress, recipientName, globalAddress, hasEnoughBalance, isBalanceLoading, anyspendQuote, isLoadingAnyspendQuote, activeInputAmountInWei, geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support, createOrder, isCreatingOrder, createOnrampOrder, isCreatingOnrampOrder, } = (0, useAnyspendFlow_1.useAnyspendFlow)({
41
+ paymentType,
42
+ recipientAddress,
43
+ loadOrder,
44
+ isDepositMode: true,
45
+ onTransactionSuccess: onSuccess,
46
+ sourceTokenAddress,
47
+ sourceTokenChainId,
48
+ destinationTokenAddress: destinationToken.address,
49
+ destinationTokenChainId: destinationChainId,
50
+ slippage: SLIPPAGE_PERCENT,
51
+ disableUrlParamManagement: true,
52
+ orderType: "custom_exact_in",
53
+ });
54
+ const { connectedEOAWallet } = (0, react_1.useAccountWallet)();
55
+ const setActiveWallet = (0, react_4.useSetActiveWallet)();
56
+ const activeWallet = (0, react_4.useActiveWallet)();
57
+ const setGlobalAccountWallet = (0, utils_2.useGlobalWalletState)(state => state.setGlobalAccountWallet);
58
+ const appliedPreferEoa = (0, react_3.useRef)(false);
59
+ (0, react_3.useEffect)(() => {
60
+ if (preferEoa && !appliedPreferEoa.current) {
61
+ if (connectedEOAWallet) {
62
+ appliedPreferEoa.current = true;
63
+ setGlobalAccountWallet(activeWallet);
64
+ setActiveWallet(connectedEOAWallet);
65
+ }
66
+ }
67
+ }, [preferEoa, connectedEOAWallet, setActiveWallet, activeWallet, setGlobalAccountWallet]);
68
+ const selectedRecipientOrDefault = selectedRecipientAddress ?? recipientAddress;
69
+ const expectedDstAmountRaw = anyspendQuote?.data?.currencyOut?.amount ?? "0";
70
+ const buildCustomPayload = (_recipient) => {
71
+ return {
72
+ amount: expectedDstAmountRaw,
73
+ expectedDstAmount: expectedDstAmountRaw,
74
+ functionAbi: customExactInConfig.functionAbi,
75
+ functionName: customExactInConfig.functionName,
76
+ functionArgs: customExactInConfig.functionArgs,
77
+ to: (0, utils_1.normalizeAddress)(customExactInConfig.to),
78
+ spenderAddress: customExactInConfig.spenderAddress
79
+ ? (0, utils_1.normalizeAddress)(customExactInConfig.spenderAddress)
80
+ : undefined,
81
+ action: customExactInConfig.action,
82
+ };
83
+ };
84
+ const btnInfo = (0, react_3.useMemo)(() => {
85
+ if (activeInputAmountInWei === "0")
86
+ return { text: "Enter an amount", disable: true, error: false, loading: false };
87
+ if (isLoadingAnyspendQuote)
88
+ return { text: "Loading quote...", disable: true, error: false, loading: true };
89
+ if (isCreatingOrder || isCreatingOnrampOrder)
90
+ return { text: "Creating order...", disable: true, error: false, loading: true };
91
+ if (!selectedRecipientOrDefault)
92
+ return { text: "Select recipient", disable: false, error: false, loading: false };
93
+ if (!anyspendQuote || !anyspendQuote.success)
94
+ return { text: "Get quote error", disable: true, error: true, loading: false };
95
+ if (paymentType === "crypto") {
96
+ if (selectedCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.NONE) {
97
+ return { text: "Choose payment method", disable: false, error: false, loading: false };
98
+ }
99
+ if (!hasEnoughBalance &&
100
+ !isBalanceLoading &&
101
+ selectedCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.CONNECT_WALLET) {
102
+ return { text: "Insufficient balance", disable: true, error: true, loading: false };
103
+ }
104
+ return { text: `Execute ${actionLabel}`, disable: false, error: false, loading: false };
105
+ }
106
+ if (paymentType === "fiat") {
107
+ if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.NONE) {
108
+ return { text: "Select payment method", disable: false, error: false, loading: false };
109
+ }
110
+ return { text: "Buy", disable: false, error: false, loading: false };
111
+ }
112
+ return { text: "Continue", disable: false, error: false, loading: false };
113
+ }, [
114
+ activeInputAmountInWei,
115
+ isLoadingAnyspendQuote,
116
+ isCreatingOrder,
117
+ isCreatingOnrampOrder,
118
+ selectedRecipientOrDefault,
119
+ anyspendQuote,
120
+ paymentType,
121
+ selectedCryptoPaymentMethod,
122
+ selectedFiatPaymentMethod,
123
+ hasEnoughBalance,
124
+ isBalanceLoading,
125
+ actionLabel,
126
+ ]);
127
+ const onMainButtonClick = async () => {
128
+ if (btnInfo.disable)
129
+ return;
130
+ if (!selectedRecipientOrDefault) {
131
+ setActivePanel(useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION);
132
+ return;
133
+ }
134
+ if (paymentType === "crypto") {
135
+ if (selectedCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.NONE) {
136
+ setActivePanel(useAnyspendFlow_1.PanelView.CRYPTO_PAYMENT_METHOD);
137
+ return;
138
+ }
139
+ await handleCryptoOrder();
140
+ }
141
+ else if (paymentType === "fiat") {
142
+ if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.NONE) {
143
+ setActivePanel(useAnyspendFlow_1.PanelView.FIAT_PAYMENT_METHOD);
144
+ return;
145
+ }
146
+ await handleFiatOrder();
147
+ }
148
+ };
149
+ const headerContent = header ? (header({ anyspendPrice: anyspendQuote, isLoadingAnyspendPrice: isLoadingAnyspendQuote })) : ((0, jsx_runtime_1.jsx)("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-as-primary text-xl font-bold", children: actionLabel }), (0, jsx_runtime_1.jsx)("p", { className: "text-as-secondary text-sm", children: "Pay from any token to execute a custom exact-in transaction." })] }) }));
150
+ const mainView = ((0, jsx_runtime_1.jsxs)("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [headerContent, (0, jsx_runtime_1.jsx)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? ((0, jsx_runtime_1.jsx)(CryptoPaySection_1.CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: selectedCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(useAnyspendFlow_1.PanelView.CRYPTO_PAYMENT_METHOD), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : ((0, jsx_runtime_1.jsx)(react_2.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" }, children: (0, jsx_runtime_1.jsx)(PanelOnramp_1.PanelOnramp, { srcAmountOnRamp: srcAmount, setSrcAmountOnRamp: setSrcAmount, selectedPaymentMethod: selectedFiatPaymentMethod, setActivePanel: setActivePanel, _recipientAddress: selectedRecipientOrDefault, destinationToken: selectedDstToken, destinationChainId: selectedDstChainId, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, hideDstToken: true, destinationAmount: dstAmount, onDestinationTokenChange: () => { }, onDestinationChainChange: () => { }, fiatPaymentMethodIndex: useAnyspendFlow_1.PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL), customUsdInputValues: customUsdInputValues }) })), (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("relative -my-1 flex h-0 items-center justify-center", paymentType === "fiat" && "hidden"), children: (0, jsx_runtime_1.jsx)(react_1.Button, { variant: "ghost", className: (0, cn_1.cn)("swap-direction-button border-as-stroke bg-as-surface-primary z-10 h-10 w-10 cursor-default rounded-xl border-2 sm:h-8 sm:w-8 sm:rounded-xl"), children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex items-center justify-center transition-opacity", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && ((0, jsx_runtime_1.jsx)(CryptoReceiveSection_1.CryptoReceiveSection, { isDepositMode: false, isBuyMode: true, selectedRecipientAddress: selectedRecipientOrDefault, recipientName: recipientName || undefined, onSelectRecipient: () => setActivePanel(useAnyspendFlow_1.PanelView.RECIPIENT_SELECTION), dstAmount: dstAmount, dstToken: selectedDstToken, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, dstTokenLogoURI: DESTINATION_TOKEN_DETAILS.LOGO_URI, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: () => { }, setSelectedDstToken: () => { }, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
151
+ setIsSrcInputDirty(false);
152
+ setSrcAmount(value);
153
+ }, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(useAnyspendFlow_1.PanelView.FEE_DETAIL) }))] }) }), (0, jsx_runtime_1.jsx)(react_2.motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: (0, cn_1.cn)("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: (0, jsx_runtime_1.jsx)(react_1.ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (0, cn_1.cn)("as-main-button relative w-full", btnInfo.error ? "!bg-as-red" : btnInfo.disable ? "!bg-as-on-surface-2" : "!bg-as-brand"), textClassName: (0, cn_1.cn)(btnInfo.error ? "text-white" : btnInfo.disable ? "text-as-secondary" : "text-white"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [btnInfo.loading && (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-4 w-4 animate-spin" }), btnInfo.text] }) }) }), mainFooter ? mainFooter : null] }));
154
+ const handleCryptoOrder = async () => {
155
+ try {
156
+ (0, invariant_1.default)(anyspendQuote, "Relay price is not found");
157
+ (0, invariant_1.default)(selectedRecipientOrDefault, "Recipient address is not found");
158
+ const srcAmountBigInt = BigInt(activeInputAmountInWei);
159
+ const payload = buildCustomPayload(selectedRecipientOrDefault);
160
+ createOrder({
161
+ recipientAddress: selectedRecipientOrDefault,
162
+ orderType: "custom_exact_in",
163
+ srcChain: selectedSrcChainId,
164
+ dstChain: selectedDstChainId,
165
+ srcToken: selectedSrcToken,
166
+ dstToken: selectedDstToken,
167
+ srcAmount: srcAmountBigInt.toString(),
168
+ expectedDstAmount: expectedDstAmountRaw,
169
+ creatorAddress: globalAddress,
170
+ payload,
171
+ });
172
+ }
173
+ catch (err) {
174
+ console.error(err);
175
+ sonner_1.toast.error("Failed to create order: " + err.message);
176
+ }
177
+ };
178
+ const handleFiatOrder = async () => {
179
+ try {
180
+ (0, invariant_1.default)(anyspendQuote, "Relay price is not found");
181
+ (0, invariant_1.default)(selectedRecipientOrDefault, "Recipient address is not found");
182
+ if (!srcAmount || parseFloat(srcAmount) <= 0) {
183
+ sonner_1.toast.error("Please enter a valid amount");
184
+ return;
185
+ }
186
+ let vendor;
187
+ let paymentMethodString = "";
188
+ if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.COINBASE_PAY) {
189
+ if (coinbaseAvailablePaymentMethods.length === 0) {
190
+ sonner_1.toast.error("Coinbase Pay not available");
191
+ return;
192
+ }
193
+ vendor = "coinbase";
194
+ paymentMethodString = coinbaseAvailablePaymentMethods[0]?.id || "";
195
+ }
196
+ else if (selectedFiatPaymentMethod === FiatPaymentMethod_1.FiatPaymentMethod.STRIPE) {
197
+ if (!stripeWeb2Support || !stripeWeb2Support.isSupport) {
198
+ sonner_1.toast.error("Stripe not available");
199
+ return;
200
+ }
201
+ vendor = "stripe-web2";
202
+ }
203
+ else {
204
+ sonner_1.toast.error("Please select a payment method");
205
+ return;
206
+ }
207
+ const payload = buildCustomPayload(selectedRecipientOrDefault);
208
+ createOnrampOrder({
209
+ recipientAddress: selectedRecipientOrDefault,
210
+ orderType: "custom_exact_in",
211
+ dstChain: selectedDstChainId,
212
+ dstToken: selectedDstToken,
213
+ srcFiatAmount: srcAmount,
214
+ onramp: {
215
+ vendor,
216
+ paymentMethod: paymentMethodString,
217
+ country: geoData?.country || "US",
218
+ redirectUrl: window.location.origin,
219
+ },
220
+ expectedDstAmount: expectedDstAmountRaw,
221
+ creatorAddress: globalAddress,
222
+ payload,
223
+ });
224
+ }
225
+ catch (err) {
226
+ console.error(err);
227
+ sonner_1.toast.error("Failed to create order: " + err.message);
228
+ }
229
+ };
230
+ const orderDetailsView = ((0, jsx_runtime_1.jsx)("div", { className: "mx-auto w-[460px] max-w-full", children: (0, jsx_runtime_1.jsx)("div", { className: "relative flex flex-col gap-4", children: oat && ((0, jsx_runtime_1.jsx)(OrderDetails_1.OrderDetails, { mode: mode, order: oat.data.order, depositTxs: oat.data.depositTxs, relayTxs: oat.data.relayTxs, executeTx: oat.data.executeTx, refundTxs: oat.data.refundTxs, cryptoPaymentMethod: paymentType === "fiat" ? CryptoPaymentMethod_1.CryptoPaymentMethodType.NONE : selectedCryptoPaymentMethod, selectedCryptoPaymentMethod: selectedCryptoPaymentMethod, onPaymentMethodChange: setSelectedCryptoPaymentMethod, onBack: () => {
231
+ setOrderId(undefined);
232
+ setActivePanel(useAnyspendFlow_1.PanelView.MAIN);
233
+ }, disableUrlParamManagement: true, points: oat.data.points || undefined })) }) }));
234
+ const loadingView = ((0, jsx_runtime_1.jsx)("div", { className: "mx-auto flex w-full flex-col items-center gap-4 p-5", children: (0, jsx_runtime_1.jsx)("div", { className: "text-as-primary", children: "Loading order details..." }) }));
235
+ const recipientSelectionView = ((0, jsx_runtime_1.jsx)(RecipientSelection_1.RecipientSelection, { initialValue: selectedRecipientOrDefault || "", onBack: () => setActivePanel(useAnyspendFlow_1.PanelView.MAIN), onConfirm: address => {
236
+ setSelectedRecipientAddress(address);
237
+ setActivePanel(useAnyspendFlow_1.PanelView.MAIN);
238
+ } }));
239
+ const cryptoPaymentMethodView = ((0, jsx_runtime_1.jsx)(CryptoPaymentMethod_1.CryptoPaymentMethod, { globalAddress: globalAddress, globalWallet: undefined, selectedPaymentMethod: selectedCryptoPaymentMethod, setSelectedPaymentMethod: setSelectedCryptoPaymentMethod, isCreatingOrder: isCreatingOrder, onBack: () => setActivePanel(useAnyspendFlow_1.PanelView.MAIN), onSelectPaymentMethod: (method) => {
240
+ setSelectedCryptoPaymentMethod(method);
241
+ setActivePanel(useAnyspendFlow_1.PanelView.MAIN);
242
+ } }));
243
+ const fiatPaymentMethodView = ((0, jsx_runtime_1.jsx)(FiatPaymentMethod_1.FiatPaymentMethodComponent, { selectedPaymentMethod: selectedFiatPaymentMethod, setSelectedPaymentMethod: setSelectedFiatPaymentMethod, onBack: () => setActivePanel(useAnyspendFlow_1.PanelView.MAIN), onSelectPaymentMethod: (method) => {
244
+ setSelectedFiatPaymentMethod(method);
245
+ setActivePanel(useAnyspendFlow_1.PanelView.MAIN);
246
+ }, srcAmountOnRamp: srcAmount }));
247
+ const pointsDetailView = ((0, jsx_runtime_1.jsx)(PointsDetailPanel_1.PointsDetailPanel, { pointsAmount: anyspendQuote?.data?.pointsAmount || 0, onBack: () => setActivePanel(useAnyspendFlow_1.PanelView.MAIN) }));
248
+ const feeDetailView = anyspendQuote?.data?.fee ? ((0, jsx_runtime_1.jsx)(FeeDetailPanel_1.FeeDetailPanel, { fee: anyspendQuote.data.fee, transactionAmountUsd: paymentType === "fiat"
249
+ ? parseFloat(srcAmount)
250
+ : anyspendQuote.data.currencyIn?.amountUsd
251
+ ? Number(anyspendQuote.data.currencyIn.amountUsd)
252
+ : undefined, onBack: () => setActivePanel(useAnyspendFlow_1.PanelView.MAIN) })) : null;
253
+ return ((0, jsx_runtime_1.jsx)(react_1.StyleRoot, { children: (0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("anyspend-container font-inter bg-as-surface-primary mx-auto w-full max-w-[460px] p-6", mode === "page" && "border-as-border-secondary overflow-hidden rounded-2xl border shadow-xl"), children: (0, jsx_runtime_1.jsx)(react_1.TransitionPanel, { activeIndex: orderId
254
+ ? oat
255
+ ? useAnyspendFlow_1.PanelView.ORDER_DETAILS
256
+ : useAnyspendFlow_1.PanelView.LOADING
257
+ : activePanel === useAnyspendFlow_1.PanelView.ORDER_DETAILS
258
+ ? useAnyspendFlow_1.PanelView.MAIN
259
+ : activePanel, className: (0, cn_1.cn)("rounded-2xl", {
260
+ "mt-0": mode === "modal",
261
+ }), variants: {
262
+ enter: { x: 300, opacity: 0 },
263
+ center: { x: 0, opacity: 1 },
264
+ exit: { x: -300, opacity: 0 },
265
+ }, transition: { type: "spring", stiffness: 300, damping: 30 }, children: [
266
+ (0, jsx_runtime_1.jsx)("div", { children: mainView }, "main-view"),
267
+ (0, jsx_runtime_1.jsx)("div", { children: cryptoPaymentMethodView }, "crypto-payment-method-view"),
268
+ (0, jsx_runtime_1.jsx)("div", { children: fiatPaymentMethodView }, "fiat-payment-method-view"),
269
+ (0, jsx_runtime_1.jsx)("div", { children: recipientSelectionView }, "recipient-selection-view"),
270
+ (0, jsx_runtime_1.jsx)("div", { children: orderDetailsView }, "order-details-view"),
271
+ (0, jsx_runtime_1.jsx)("div", { children: loadingView }, "loading-view"),
272
+ (0, jsx_runtime_1.jsx)("div", { children: pointsDetailView }, "points-detail-view"),
273
+ (0, jsx_runtime_1.jsx)("div", { children: feeDetailView }, "fee-detail-view"),
274
+ ] }) }) }));
275
+ }
@@ -0,0 +1,9 @@
1
+ export declare function AnySpendStakeB3ExactIn({ loadOrder, mode, sourceTokenAddress, sourceTokenChainId, recipientAddress, stakeAmount, onSuccess, }: {
2
+ loadOrder?: string;
3
+ mode?: "modal" | "page";
4
+ sourceTokenAddress?: string;
5
+ sourceTokenChainId?: number;
6
+ recipientAddress: string;
7
+ stakeAmount?: string;
8
+ onSuccess?: (amount: string) => void;
9
+ }): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,288 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AnySpendStakeB3ExactIn = AnySpendStakeB3ExactIn;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const anyspend_1 = require("../../../anyspend");
6
+ const utils_1 = require("../../../anyspend/utils");
7
+ const react_1 = require("../../../global-account/react");
8
+ const constants_1 = require("../../../shared/constants");
9
+ const number_1 = require("../../../shared/utils/number");
10
+ const lucide_react_1 = require("lucide-react");
11
+ const react_2 = require("motion/react");
12
+ const react_3 = require("react");
13
+ const sonner_1 = require("sonner");
14
+ const viem_1 = require("viem");
15
+ const chains_1 = require("viem/chains");
16
+ const wagmi_1 = require("wagmi");
17
+ const AnySpendCustomExactIn_1 = require("./AnySpendCustomExactIn");
18
+ const EthIcon_1 = require("./icons/EthIcon");
19
+ const SolIcon_1 = require("./icons/SolIcon");
20
+ const USDCIcon_1 = require("./icons/USDCIcon");
21
+ const basePublicClient = (0, viem_1.createPublicClient)({
22
+ chain: chains_1.base,
23
+ transport: (0, viem_1.http)(constants_1.PUBLIC_BASE_RPC_URL),
24
+ });
25
+ const ERC20Staking = "0xbf04200be3cbf371467a539706393c81c470f523";
26
+ const STAKE_FUNCTION_ABI = JSON.stringify([
27
+ {
28
+ name: "stake",
29
+ type: "function",
30
+ stateMutability: "nonpayable",
31
+ inputs: [
32
+ { name: "amount", type: "uint256" },
33
+ { name: "beneficiary", type: "address" },
34
+ ],
35
+ outputs: [],
36
+ },
37
+ ]);
38
+ function AnySpendStakeB3ExactIn({ loadOrder, mode = "modal", sourceTokenAddress, sourceTokenChainId, recipientAddress, stakeAmount, onSuccess, }) {
39
+ const hasMounted = (0, react_1.useHasMounted)();
40
+ const { setB3ModalOpen } = (0, react_1.useModalStore)();
41
+ // Wagmi hooks for direct staking
42
+ const { address } = (0, wagmi_1.useAccount)();
43
+ const { switchChainAndExecute, isSwitchingOrExecuting } = (0, react_1.useUnifiedChainSwitchAndExecute)();
44
+ // Fetch B3 token balance
45
+ const { data: simBalance, isLoading: isBalanceLoading } = (0, react_1.useSimBalance)(address, [chains_1.base.id]);
46
+ const b3RawBalanceStr = simBalance?.balances.find(b => (0, anyspend_1.eqci)(b.address, anyspend_1.B3_TOKEN.address))?.amount || "0";
47
+ const b3RawBalance = BigInt(b3RawBalanceStr);
48
+ const b3Balance = (0, number_1.formatTokenAmount)(b3RawBalance, anyspend_1.B3_TOKEN.decimals);
49
+ // State for direct staking flow
50
+ const [isStaking, setIsStaking] = (0, react_3.useState)(false);
51
+ const [stakingTxHash, setStakingTxHash] = (0, react_3.useState)("");
52
+ const [showSuccessModal, setShowSuccessModal] = (0, react_3.useState)(false);
53
+ // Wait for transaction confirmation
54
+ const { isLoading: isTxPending, isSuccess: isTxSuccess } = (0, wagmi_1.useWaitForTransactionReceipt)({
55
+ hash: stakingTxHash,
56
+ query: {
57
+ structuralSharing: false, // Disable to avoid BigInt serialization issues
58
+ },
59
+ });
60
+ // Show success modal when transaction is confirmed
61
+ (0, react_3.useEffect)(() => {
62
+ if (isTxSuccess && stakingTxHash) {
63
+ setShowAmountPrompt(false);
64
+ setShowSuccessModal(true);
65
+ setIsStaking(false);
66
+ }
67
+ }, [isTxSuccess, stakingTxHash]);
68
+ const [userStakeAmount, setUserStakeAmount] = (0, react_3.useState)(stakeAmount || "");
69
+ const [showAmountPrompt, setShowAmountPrompt] = (0, react_3.useState)(!stakeAmount);
70
+ const [isAmountValid, setIsAmountValid] = (0, react_3.useState)(!!stakeAmount);
71
+ const [validationError, setValidationError] = (0, react_3.useState)("");
72
+ // Store display amount for UI
73
+ const [displayAmount, setDisplayAmount] = (0, react_3.useState)("");
74
+ // Debounced state for balance checks and messaging
75
+ const [debouncedAmount, setDebouncedAmount] = (0, react_3.useState)("");
76
+ const [debouncedUserStakeAmount, setDebouncedUserStakeAmount] = (0, react_3.useState)("");
77
+ // Debounce the amount for balance checks
78
+ (0, react_3.useEffect)(() => {
79
+ const timer = setTimeout(() => {
80
+ setDebouncedAmount(displayAmount);
81
+ setDebouncedUserStakeAmount(userStakeAmount);
82
+ }, 500);
83
+ return () => clearTimeout(timer);
84
+ }, [displayAmount, userStakeAmount]);
85
+ (0, react_3.useEffect)(() => {
86
+ if (stakeAmount) {
87
+ setUserStakeAmount(stakeAmount);
88
+ setShowAmountPrompt(false);
89
+ setIsAmountValid(true);
90
+ }
91
+ }, [stakeAmount]);
92
+ if (!recipientAddress)
93
+ return null;
94
+ const validateAndSetAmount = (value) => {
95
+ // Allow decimal input by validating against a pattern
96
+ // This regex allows numbers with up to 18 decimal places
97
+ const isValidFormat = /^(\d+\.?\d{0,18}|\.\d{1,18})$/.test(value) || value === "";
98
+ if (!isValidFormat && value !== "") {
99
+ return;
100
+ }
101
+ setDisplayAmount(value);
102
+ try {
103
+ if (value === "" || value === ".") {
104
+ setUserStakeAmount("");
105
+ setIsAmountValid(false);
106
+ setValidationError("");
107
+ return;
108
+ }
109
+ // For UI validation - check if it's a positive number
110
+ const numValue = parseFloat(value);
111
+ if (isNaN(numValue) || numValue <= 0) {
112
+ setIsAmountValid(false);
113
+ setUserStakeAmount("");
114
+ setValidationError("Please enter a valid positive number");
115
+ return;
116
+ }
117
+ // Check minimum stake amount (50 B3)
118
+ if (numValue < 50) {
119
+ setIsAmountValid(false);
120
+ setUserStakeAmount("");
121
+ setValidationError("Minimum stake amount is 50 B3");
122
+ return;
123
+ }
124
+ // Convert to wei (multiply by 10^18)
125
+ // Handle decimal places correctly by removing the decimal point
126
+ let fullAmount;
127
+ if (value.includes(".")) {
128
+ const [whole, fraction = ""] = value.split(".");
129
+ // Pad with zeros to 18 decimal places
130
+ const paddedFraction = fraction.padEnd(18, "0");
131
+ fullAmount = whole + paddedFraction;
132
+ }
133
+ else {
134
+ fullAmount = value + "000000000000000000"; // Add 18 zeros
135
+ }
136
+ // Remove leading zeros
137
+ fullAmount = fullAmount.replace(/^0+/, "") || "0";
138
+ // Set the full amount for the actual transaction
139
+ setUserStakeAmount(fullAmount);
140
+ setIsAmountValid(true);
141
+ setValidationError("");
142
+ }
143
+ catch (error) {
144
+ setIsAmountValid(false);
145
+ setUserStakeAmount("");
146
+ setValidationError("Please enter a valid amount");
147
+ }
148
+ };
149
+ const handleDirectStaking = async () => {
150
+ if (!address || !basePublicClient || !userStakeAmount)
151
+ return;
152
+ try {
153
+ setIsStaking(true);
154
+ // Check current allowance
155
+ const allowance = await basePublicClient.readContract({
156
+ address: anyspend_1.B3_TOKEN.address,
157
+ abi: viem_1.erc20Abi,
158
+ functionName: "allowance",
159
+ args: [address, ERC20Staking],
160
+ });
161
+ // If allowance is insufficient, request approval first
162
+ if (allowance < BigInt(userStakeAmount)) {
163
+ sonner_1.toast.info("Approving B3 spending...");
164
+ const approvalData = (0, viem_1.encodeFunctionData)({
165
+ abi: viem_1.erc20Abi,
166
+ functionName: "approve",
167
+ args: [ERC20Staking, BigInt(userStakeAmount)],
168
+ });
169
+ const approvalHash = await switchChainAndExecute(chains_1.base.id, {
170
+ to: anyspend_1.B3_TOKEN.address,
171
+ data: approvalData,
172
+ value: BigInt(0),
173
+ });
174
+ if (!approvalHash) {
175
+ sonner_1.toast.error("Approval failed. Please try again.");
176
+ return;
177
+ }
178
+ const approvalReceipt = await basePublicClient.waitForTransactionReceipt({
179
+ hash: approvalHash,
180
+ confirmations: 1,
181
+ });
182
+ if (approvalReceipt?.status !== "success") {
183
+ sonner_1.toast.error("Approval failed. Please try again.");
184
+ return;
185
+ }
186
+ }
187
+ // Execute the stake
188
+ sonner_1.toast.info("Staking B3...");
189
+ const stakeData = (0, viem_1.encodeFunctionData)({
190
+ abi: anyspend_1.ABI_ERC20_STAKING,
191
+ functionName: "stake",
192
+ args: [BigInt(userStakeAmount), recipientAddress],
193
+ });
194
+ const stakeHash = await switchChainAndExecute(chains_1.base.id, {
195
+ to: ERC20Staking,
196
+ data: stakeData,
197
+ value: BigInt(0),
198
+ });
199
+ if (stakeHash) {
200
+ setStakingTxHash(stakeHash);
201
+ sonner_1.toast.success("Staking transaction submitted!");
202
+ }
203
+ }
204
+ catch (error) {
205
+ console.error("@@b3-stake-custom-exact-in:error:", error);
206
+ sonner_1.toast.error("Staking failed. Please try again.");
207
+ setShowSuccessModal(false); // Ensure modal doesn't show on error
208
+ }
209
+ finally {
210
+ setIsStaking(false);
211
+ }
212
+ };
213
+ const confirmAmount = () => {
214
+ if (!isAmountValid) {
215
+ sonner_1.toast.error("Please enter a valid amount to stake");
216
+ return;
217
+ }
218
+ // Check if user has sufficient B3 balance for direct staking
219
+ const hasEnoughBalance = b3RawBalance && BigInt(userStakeAmount) <= b3RawBalance;
220
+ if (hasEnoughBalance) {
221
+ // User has enough B3, proceed with direct staking
222
+ handleDirectStaking();
223
+ }
224
+ else {
225
+ // User needs more B3, proceed to AnySpend conversion flow
226
+ setShowAmountPrompt(false);
227
+ }
228
+ };
229
+ const header = () => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: "relative mx-auto size-32", children: (0, jsx_runtime_1.jsx)("img", { alt: "b3 coin", className: "size-full", src: "https://cdn.b3.fun/b3-coin-3d.png" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "from-b3-react-background to-as-on-surface-1 mt-[-60px] w-full rounded-t-lg bg-gradient-to-t", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-[60px] w-full" }), (0, jsx_runtime_1.jsx)("div", { className: "mb-1 flex w-full flex-col items-center gap-2 p-5", children: (0, jsx_runtime_1.jsxs)("span", { className: "font-sf-rounded text-2xl font-semibold", children: ["Swap & Stake ", userStakeAmount ? (0, number_1.formatTokenAmount)(BigInt(userStakeAmount), 18) : "", " B3 (Exact In)"] }) })] })] }));
230
+ const onFocusStakeAmountInput = () => {
231
+ window.scrollTo(0, 0);
232
+ document.body.scrollTop = 0;
233
+ };
234
+ const customExactInConfig = {
235
+ functionAbi: STAKE_FUNCTION_ABI,
236
+ functionName: "stake",
237
+ functionArgs: ["{{amount_out}}", (0, utils_1.normalizeAddress)(recipientAddress)],
238
+ to: ERC20Staking,
239
+ spenderAddress: ERC20Staking,
240
+ action: "stake B3",
241
+ };
242
+ // Render amount input prompt if no stake amount is provided
243
+ if (showAmountPrompt) {
244
+ return ((0, jsx_runtime_1.jsx)(react_1.StyleRoot, { children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-b3-react-background flex w-full flex-col items-center", children: [(0, jsx_runtime_1.jsxs)("div", { className: "w-full px-4", children: [(0, jsx_runtime_1.jsx)(react_2.motion.div, { initial: false, animate: {
245
+ opacity: hasMounted ? 1 : 0,
246
+ y: hasMounted ? 0 : 20,
247
+ filter: hasMounted ? "blur(0px)" : "blur(10px)",
248
+ }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "relative mx-auto size-48", children: (0, jsx_runtime_1.jsx)("video", { autoPlay: true, muted: true, playsInline: true, className: "size-full", src: "https://cdn.b3.fun/b3-sphere-to-coin.mp4" }) }), (0, jsx_runtime_1.jsx)(react_2.motion.div, { initial: false, animate: {
249
+ opacity: hasMounted ? 1 : 0,
250
+ y: hasMounted ? 0 : 20,
251
+ filter: hasMounted ? "blur(0px)" : "blur(10px)",
252
+ }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, children: (0, jsx_runtime_1.jsx)("h2", { className: "font-sf-rounded font-neue-montreal-medium mb-1 text-center text-2xl font-semibold", children: (() => {
253
+ const hasEnoughBalance = b3RawBalance && BigInt(debouncedUserStakeAmount || "0") <= b3RawBalance;
254
+ return hasEnoughBalance || !debouncedAmount ? "Stake B3" : "Swap & Stake B3";
255
+ })() }) })] }), (0, jsx_runtime_1.jsxs)(react_2.motion.div, { initial: false, animate: {
256
+ opacity: hasMounted ? 1 : 0,
257
+ y: hasMounted ? 0 : 20,
258
+ filter: hasMounted ? "blur(0px)" : "blur(10px)",
259
+ }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: "bg-b3-react-background w-full p-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "mb-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("p", { className: "text-as-primary/70 text-sm font-medium", children: "I want to stake" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-as-primary/50 flex items-center gap-1 text-sm", children: ["Available: ", isBalanceLoading ? (0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-3 w-3 animate-spin" }) : `${b3Balance} B3`] })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(react_1.Input, { onFocus: onFocusStakeAmountInput, type: "text", placeholder: "0.00", value: displayAmount, onChange: e => validateAndSetAmount(e.target.value), className: `h-14 px-4 text-lg ${!isAmountValid && displayAmount ? "border-as-red" : "border-b3-react-border"}` }), (0, jsx_runtime_1.jsx)("div", { className: "font-pack absolute right-4 top-1/2 -translate-y-1/2 text-lg font-medium text-blue-500/70", children: "B3" })] }), !isAmountValid && displayAmount && (0, jsx_runtime_1.jsx)("p", { className: "text-as-red mt-2 text-sm", children: validationError }), (0, jsx_runtime_1.jsx)("div", { className: "mt-4", children: (() => {
260
+ const hasEnoughBalance = b3RawBalance && BigInt(debouncedUserStakeAmount || "0") <= b3RawBalance;
261
+ if (!hasEnoughBalance || !debouncedAmount) {
262
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "bg-as-brand/10 flex flex-col items-center gap-2 rounded-lg p-4 pb-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-primary text-sm font-semibold", children: "Swap & stake from any token" }), (0, jsx_runtime_1.jsxs)(react_1.TextLoop, { children: [(0, jsx_runtime_1.jsx)(EthIcon_1.EthIcon, { className: "h-8 w-8" }), (0, jsx_runtime_1.jsx)(SolIcon_1.SolIcon, { className: "h-8 w-8" }), (0, jsx_runtime_1.jsx)(USDCIcon_1.UsdcIcon, { className: "h-8 w-8" })] }), (0, jsx_runtime_1.jsx)(lucide_react_1.ArrowRight, { className: "text-as-primary h-4 w-4" }), (0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3-coin-3d.png", className: "h-7 w-7", alt: "B3 Token" })] }), (0, jsx_runtime_1.jsx)("p", { className: "text-as-primary/50 text-sm font-medium", children: debouncedAmount
263
+ ? `No problem, we'll help you swap to ${debouncedAmount} B3!`
264
+ : "Not enough B3? We'll help you swap from other coins." })] }));
265
+ }
266
+ })() }), (0, jsx_runtime_1.jsx)(react_1.Button, { onClick: confirmAmount, disabled: !isAmountValid || !displayAmount || isStaking || isTxPending || isSwitchingOrExecuting, className: "bg-as-brand hover:bg-as-brand/90 text-as-primary mt-4 h-14 w-full rounded-xl text-lg font-medium", children: isStaking || isSwitchingOrExecuting ? "Staking..." : isTxPending ? "Confirming..." : "Continue" })] })] }) }));
267
+ }
268
+ // Success Modal for Direct Staking
269
+ if (showSuccessModal) {
270
+ return ((0, jsx_runtime_1.jsx)(react_1.StyleRoot, { children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-b3-react-background flex w-full flex-col items-center", children: [(0, jsx_runtime_1.jsxs)("div", { className: "w-full p-4", children: [(0, jsx_runtime_1.jsxs)(react_2.motion.div, { initial: false, animate: {
271
+ opacity: hasMounted ? 1 : 0,
272
+ y: hasMounted ? 0 : 20,
273
+ filter: hasMounted ? "blur(0px)" : "blur(10px)",
274
+ }, transition: { duration: 0.3, delay: 0, ease: "easeInOut" }, className: "relative mx-auto mb-4 size-[120px]", children: [(0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 scale-95 rounded-[50%] bg-black/30 blur-md" }), (0, jsx_runtime_1.jsxs)(react_1.GlareCardRounded, { className: "overflow-hidden rounded-full border-none", children: [(0, jsx_runtime_1.jsx)("img", { alt: "b3 coin", loading: "lazy", width: "64", height: "64", decoding: "async", "data-nimg": "1", className: "size-full shrink-0 bg-transparent text-transparent", src: "https://cdn.b3.fun/b3-coin-3d.png" }), (0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 rounded-[50%] border border-white/10" })] })] }), (0, jsx_runtime_1.jsx)(react_2.motion.div, { initial: false, animate: {
275
+ opacity: hasMounted ? 1 : 0,
276
+ y: hasMounted ? 0 : 20,
277
+ filter: hasMounted ? "blur(0px)" : "blur(10px)",
278
+ }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, children: (0, jsx_runtime_1.jsxs)("h2", { className: "font-sf-rounded mb-1 text-center text-2xl font-semibold", children: ["Staked ", (0, number_1.formatTokenAmount)(BigInt(userStakeAmount), 18), " B3"] }) })] }), (0, jsx_runtime_1.jsxs)(react_2.motion.div, { initial: false, animate: {
279
+ opacity: hasMounted ? 1 : 0,
280
+ y: hasMounted ? 0 : 20,
281
+ filter: hasMounted ? "blur(0px)" : "blur(10px)",
282
+ }, transition: { duration: 0.3, delay: 0.2, ease: "easeInOut" }, className: "bg-b3-react-background w-full p-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "mb-6", children: (0, jsx_runtime_1.jsx)("a", { href: `https://basescan.org/tx/${stakingTxHash}`, target: "_blank", rel: "noopener noreferrer", className: "text-as-primary/70 hover:text-as-primary block break-all text-center font-mono text-sm underline transition-colors", children: "View transaction" }) }), (0, jsx_runtime_1.jsx)(react_1.Button, { onClick: () => {
283
+ setB3ModalOpen(false);
284
+ onSuccess?.((0, number_1.formatTokenAmount)(BigInt(userStakeAmount), 18) ?? "");
285
+ }, className: "bg-as-brand hover:bg-as-brand/90 text-as-primary h-14 w-full rounded-xl text-lg font-medium", children: "Done" })] })] }) }));
286
+ }
287
+ return ((0, jsx_runtime_1.jsx)(AnySpendCustomExactIn_1.AnySpendCustomExactIn, { loadOrder: loadOrder, mode: mode, recipientAddress: recipientAddress, sourceTokenAddress: sourceTokenAddress, sourceTokenChainId: sourceTokenChainId, destinationToken: anyspend_1.B3_TOKEN, destinationChainId: chains_1.base.id, customExactInConfig: customExactInConfig, header: header, onSuccess: onSuccess }));
288
+ }
@@ -0,0 +1,11 @@
1
+ import { components } from "../../../anyspend/types/api";
2
+ export declare function AnySpendStakeUpsideExactIn({ loadOrder, mode, recipientAddress, sourceTokenAddress, sourceTokenChainId, stakingContractAddress, token, onSuccess, }: {
3
+ loadOrder?: string;
4
+ mode?: "modal" | "page";
5
+ recipientAddress: string;
6
+ sourceTokenAddress?: string;
7
+ sourceTokenChainId?: number;
8
+ stakingContractAddress: string;
9
+ token: components["schemas"]["Token"];
10
+ onSuccess?: (amount: string) => void;
11
+ }): import("react/jsx-runtime").JSX.Element | null;