@b3dotfun/sdk 0.1.2-alpha.2 → 0.1.2-alpha.4
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/react/components/AnySpendCustomExactIn.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +110 -38
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpsideExactIn.js +2 -2
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +4 -6
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +6 -7
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +20 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +118 -15
- package/dist/cjs/anyspend/react/hooks/useRecipientAddressState.js +1 -1
- package/dist/cjs/anyspend/utils/format.js +12 -2
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +2 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.d.ts +1 -0
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +111 -39
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +2 -1
- package/dist/esm/anyspend/react/components/AnySpendStakeUpsideExactIn.js +2 -2
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +4 -6
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +6 -7
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +20 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +118 -16
- package/dist/esm/anyspend/react/hooks/useRecipientAddressState.js +1 -1
- package/dist/esm/anyspend/utils/format.js +12 -2
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +2 -0
- package/dist/types/anyspend/react/components/AnySpendCustomExactIn.d.ts +1 -0
- package/dist/types/anyspend/react/components/AnySpendStakeUpsideExactIn.d.ts +2 -1
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +20 -1
- package/dist/types/global-account/react/stores/useModalStore.d.ts +2 -0
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +125 -41
- package/src/anyspend/react/components/AnySpendStakeUpsideExactIn.tsx +3 -0
- package/src/anyspend/react/components/common/OrderDetails.tsx +4 -6
- package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +7 -6
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +140 -17
- package/src/anyspend/react/hooks/useRecipientAddressState.ts +1 -1
- package/src/anyspend/utils/format.ts +13 -2
- package/src/global-account/react/stores/useModalStore.ts +2 -0
|
@@ -6,7 +6,11 @@ const getStatusDisplay = (order) => {
|
|
|
6
6
|
const srcToken = order.metadata?.srcToken;
|
|
7
7
|
const dstToken = order.metadata?.dstToken;
|
|
8
8
|
const formattedSrcAmount = srcToken ? (0, number_1.formatTokenAmount)(BigInt(order.srcAmount), srcToken.decimals) : undefined;
|
|
9
|
-
|
|
9
|
+
// For custom orders, use payload.amount as fallback if actualDstAmount is not available
|
|
10
|
+
const actualDstAmount = order.settlement?.actualDstAmount ||
|
|
11
|
+
(order.type === "custom" || order.type === "custom_exact_in" || order.type === "deposit_first"
|
|
12
|
+
? order.payload.amount?.toString()
|
|
13
|
+
: undefined);
|
|
10
14
|
const formattedActualDstAmount = actualDstAmount && dstToken ? (0, number_1.formatTokenAmount)(BigInt(actualDstAmount), dstToken.decimals) : undefined;
|
|
11
15
|
switch (order.status) {
|
|
12
16
|
case "scanning_deposit_transaction": {
|
|
@@ -43,6 +47,7 @@ const getStatusDisplay = (order) => {
|
|
|
43
47
|
};
|
|
44
48
|
case "executed": {
|
|
45
49
|
const receivedText = formattedActualDstAmount && dstToken ? `Received ${formattedActualDstAmount} ${dstToken.symbol}` : undefined;
|
|
50
|
+
const actionText = order.metadata?.action || "Order";
|
|
46
51
|
const { text, description } = order.type === "swap"
|
|
47
52
|
? { text: receivedText || "Swap Complete", description: "Your swap has been completed successfully." }
|
|
48
53
|
: order.type === "mint_nft"
|
|
@@ -51,7 +56,12 @@ const getStatusDisplay = (order) => {
|
|
|
51
56
|
? { text: "Tournament Joined", description: "You have joined the tournament" }
|
|
52
57
|
: order.type === "fund_tournament"
|
|
53
58
|
? { text: "Tournament Funded", description: "You have funded the tournament" }
|
|
54
|
-
:
|
|
59
|
+
: order.type === "custom" || order.type === "custom_exact_in"
|
|
60
|
+
? {
|
|
61
|
+
text: receivedText || `${actionText} Complete`,
|
|
62
|
+
description: "Your order has been completed successfully.",
|
|
63
|
+
}
|
|
64
|
+
: { text: receivedText || "Order Complete", description: "Your order has been completed" };
|
|
55
65
|
return { text, status: "success", description };
|
|
56
66
|
}
|
|
57
67
|
case "refunding":
|
|
@@ -306,6 +306,8 @@ export interface AnySpendDepositUpsideProps extends BaseModalProps {
|
|
|
306
306
|
depositContractAddress: string;
|
|
307
307
|
/** Token to deposit */
|
|
308
308
|
token: components["schemas"]["Token"];
|
|
309
|
+
/** The exact amount of destination tokens to receive, in wei. This will pre-fill the output amount and switch to an exact output swap. */
|
|
310
|
+
destinationTokenAmount?: string;
|
|
309
311
|
/** Callback function called when the deposit is successful */
|
|
310
312
|
onSuccess?: () => void;
|
|
311
313
|
}
|
|
@@ -18,6 +18,7 @@ export interface AnySpendCustomExactInProps {
|
|
|
18
18
|
sourceTokenChainId?: number;
|
|
19
19
|
destinationToken: components["schemas"]["Token"];
|
|
20
20
|
destinationChainId: number;
|
|
21
|
+
destinationTokenAmount?: string;
|
|
21
22
|
onSuccess?: (amount: string) => void;
|
|
22
23
|
onOpenCustomModal?: () => void;
|
|
23
24
|
mainFooter?: React.ReactNode;
|
|
@@ -10,7 +10,7 @@ import { motion } from "motion/react";
|
|
|
10
10
|
import { useEffect, useMemo, useRef } from "react";
|
|
11
11
|
import { useSetActiveWallet } from "thirdweb/react";
|
|
12
12
|
import { B3_TOKEN } from "../../constants/index.js";
|
|
13
|
-
import { PanelView, useAnyspendFlow } from "../hooks/useAnyspendFlow.js";
|
|
13
|
+
import { generateEncodedData, PanelView, useAnyspendFlow } from "../hooks/useAnyspendFlow.js";
|
|
14
14
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper.js";
|
|
15
15
|
import { CryptoPaySection } from "./common/CryptoPaySection.js";
|
|
16
16
|
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod.js";
|
|
@@ -27,13 +27,13 @@ export function AnySpendCustomExactIn(props) {
|
|
|
27
27
|
const fingerprintConfig = getFingerprintConfig();
|
|
28
28
|
return (_jsx(AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: _jsx(AnySpendCustomExactInInner, { ...props }) }));
|
|
29
29
|
}
|
|
30
|
-
function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddress, paymentType = "crypto", sourceTokenAddress, sourceTokenChainId, destinationToken, destinationChainId, onSuccess, onOpenCustomModal, mainFooter, onTokenSelect, customUsdInputValues, preferEoa, customExactInConfig, orderType = "custom_exact_in", minDestinationAmount, header, returnToHomeUrl, customRecipientLabel, returnHomeLabel, classes, }) {
|
|
30
|
+
function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddress, paymentType = "crypto", sourceTokenAddress, sourceTokenChainId, destinationToken, destinationChainId, onSuccess, onOpenCustomModal, mainFooter, onTokenSelect, customUsdInputValues, preferEoa, customExactInConfig, destinationTokenAmount, orderType = "custom_exact_in", minDestinationAmount, header, returnToHomeUrl, customRecipientLabel, returnHomeLabel, classes, }) {
|
|
31
31
|
const actionLabel = customExactInConfig?.action ?? "Custom Execution";
|
|
32
32
|
const DESTINATION_TOKEN_DETAILS = {
|
|
33
33
|
SYMBOL: destinationToken.symbol ?? "TOKEN",
|
|
34
34
|
LOGO_URI: destinationToken.metadata?.logoURI ?? "",
|
|
35
35
|
};
|
|
36
|
-
const { activePanel, setActivePanel, orderId, setOrderId, oat, selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, selectedDstToken, selectedDstChainId, srcAmount, setSrcAmount, dstAmount, isSrcInputDirty, setIsSrcInputDirty, selectedCryptoPaymentMethod, effectiveCryptoPaymentMethod, setSelectedCryptoPaymentMethod, selectedFiatPaymentMethod, setSelectedFiatPaymentMethod, selectedRecipientAddress, setSelectedRecipientAddress, recipientName, globalAddress, hasEnoughBalance, isBalanceLoading, anyspendQuote, isLoadingAnyspendQuote, activeInputAmountInWei, geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support, createOrder, isCreatingOrder, createOnrampOrder, isCreatingOnrampOrder, } = useAnyspendFlow({
|
|
36
|
+
const { activePanel, setActivePanel, orderId, setOrderId, oat, selectedSrcChainId, setSelectedSrcChainId, selectedSrcToken, setSelectedSrcToken, selectedDstToken, selectedDstChainId, srcAmount, setSrcAmount, dstAmount, dstAmountInput, setDstAmountInput, isSrcInputDirty, setIsSrcInputDirty, tradeType, selectedCryptoPaymentMethod, effectiveCryptoPaymentMethod, setSelectedCryptoPaymentMethod, selectedFiatPaymentMethod, setSelectedFiatPaymentMethod, selectedRecipientAddress, setSelectedRecipientAddress, recipientName, globalAddress, hasEnoughBalance, isBalanceLoading, anyspendQuote, isLoadingAnyspendQuote, isQuoteLoading, activeInputAmountInWei, activeOutputAmountInWei, geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support, createOrder, isCreatingOrder, createOnrampOrder, isCreatingOnrampOrder, } = useAnyspendFlow({
|
|
37
37
|
paymentType,
|
|
38
38
|
recipientAddress,
|
|
39
39
|
loadOrder,
|
|
@@ -45,6 +45,7 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
45
45
|
slippage: SLIPPAGE_PERCENT,
|
|
46
46
|
disableUrlParamManagement: true,
|
|
47
47
|
orderType,
|
|
48
|
+
customExactInConfig,
|
|
48
49
|
});
|
|
49
50
|
const { connectedEOAWallet } = useAccountWallet();
|
|
50
51
|
const setActiveWallet = useSetActiveWallet();
|
|
@@ -59,6 +60,17 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
}, [preferEoa, connectedEOAWallet, setActiveWallet]);
|
|
63
|
+
// Prefill destination amount if provided (for EXACT_OUTPUT mode)
|
|
64
|
+
const appliedDestinationAmount = useRef(false);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (destinationTokenAmount && !appliedDestinationAmount.current) {
|
|
67
|
+
appliedDestinationAmount.current = true;
|
|
68
|
+
// Convert wei to human-readable format
|
|
69
|
+
const formattedAmount = formatUnits(destinationTokenAmount, destinationToken.decimals);
|
|
70
|
+
setDstAmountInput(formattedAmount);
|
|
71
|
+
setIsSrcInputDirty(false); // Switch to EXACT_OUTPUT mode
|
|
72
|
+
}
|
|
73
|
+
}, [destinationTokenAmount, destinationToken.decimals, setDstAmountInput, setIsSrcInputDirty]);
|
|
62
74
|
const selectedRecipientOrDefault = selectedRecipientAddress ?? recipientAddress;
|
|
63
75
|
const expectedDstAmountRaw = anyspendQuote?.data?.currencyOut?.amount ?? "0";
|
|
64
76
|
const buildCustomPayload = (_recipient) => {
|
|
@@ -83,12 +95,14 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
83
95
|
};
|
|
84
96
|
};
|
|
85
97
|
const btnInfo = useMemo(() => {
|
|
86
|
-
|
|
98
|
+
// Check for empty amount based on trade type
|
|
99
|
+
const isAmountEmpty = tradeType === "EXACT_OUTPUT" ? !dstAmountInput || dstAmountInput === "0" : activeInputAmountInWei === "0";
|
|
100
|
+
if (isAmountEmpty)
|
|
87
101
|
return { text: "Enter an amount", disable: true, error: false, loading: false };
|
|
88
102
|
if (orderType === "hype_duel" && selectedSrcToken?.address?.toLowerCase() === B3_TOKEN.address.toLowerCase()) {
|
|
89
103
|
return { text: "Convert to HYPE using B3", disable: false, error: false, loading: false };
|
|
90
104
|
}
|
|
91
|
-
if (
|
|
105
|
+
if (isQuoteLoading)
|
|
92
106
|
return { text: "Loading quote...", disable: true, error: false, loading: true };
|
|
93
107
|
if (isCreatingOrder || isCreatingOnrampOrder)
|
|
94
108
|
return { text: "Creating order...", disable: true, error: false, loading: true };
|
|
@@ -136,7 +150,7 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
136
150
|
return { text: "Continue", disable: false, error: false, loading: false };
|
|
137
151
|
}, [
|
|
138
152
|
activeInputAmountInWei,
|
|
139
|
-
|
|
153
|
+
isQuoteLoading,
|
|
140
154
|
isCreatingOrder,
|
|
141
155
|
isCreatingOnrampOrder,
|
|
142
156
|
selectedRecipientOrDefault,
|
|
@@ -151,6 +165,8 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
151
165
|
DESTINATION_TOKEN_DETAILS.SYMBOL,
|
|
152
166
|
orderType,
|
|
153
167
|
selectedSrcToken,
|
|
168
|
+
tradeType,
|
|
169
|
+
dstAmountInput,
|
|
154
170
|
]);
|
|
155
171
|
const onMainButtonClick = async () => {
|
|
156
172
|
if (orderType === "hype_duel" && selectedSrcToken?.address?.toLowerCase() === B3_TOKEN.address.toLowerCase()) {
|
|
@@ -181,9 +197,9 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
181
197
|
const headerContent = header ? (header({ anyspendPrice: anyspendQuote, isLoadingAnyspendPrice: isLoadingAnyspendQuote })) : (_jsx("div", { className: "mb-4 flex flex-col items-center gap-3 text-center", children: _jsxs("div", { children: [_jsx("h1", { className: "text-as-primary text-xl font-bold", children: actionLabel }), _jsx("p", { className: "text-as-secondary text-sm", children: "Pay from any token to execute a custom exact-in transaction." })] }) }));
|
|
182
198
|
const mainView = (_jsxs("div", { className: classes?.container ||
|
|
183
199
|
"anyspend-custom-exact-in-container mx-auto flex w-[460px] max-w-full flex-col items-center gap-2", children: [headerContent, _jsx("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: _jsxs("div", { className: "relative flex w-full max-w-[calc(100vw-32px)] flex-col gap-2", children: [paymentType === "crypto" ? (_jsx(CryptoPaySection, { selectedSrcChainId: selectedSrcChainId, setSelectedSrcChainId: setSelectedSrcChainId, selectedSrcToken: selectedSrcToken, setSelectedSrcToken: setSelectedSrcToken, srcAmount: srcAmount, setSrcAmount: setSrcAmount, isSrcInputDirty: isSrcInputDirty, setIsSrcInputDirty: setIsSrcInputDirty, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod, onSelectCryptoPaymentMethod: () => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD), anyspendQuote: anyspendQuote, onTokenSelect: onTokenSelect })) : (_jsx(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: _jsx(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: PanelView.FIAT_PAYMENT_METHOD, recipientSelectionPanelIndex: PanelView.RECIPIENT_SELECTION, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(PanelView.FEE_DETAIL), customUsdInputValues: customUsdInputValues, customRecipientLabel: customRecipientLabel }) })), _jsx("div", { className: cn("relative -my-1 flex h-0 items-center justify-center", paymentType === "fiat" && "hidden"), children: _jsx(Button, { variant: "ghost", className: classes?.swapDirectionButton ||
|
|
184
|
-
"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: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode:
|
|
200
|
+
"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: _jsx("div", { className: "relative flex items-center justify-center transition-opacity", children: _jsx(ArrowDown, { className: "text-as-primary/50 h-5 w-5" }) }) }) }), paymentType === "crypto" && (_jsx(CryptoReceiveSection, { isDepositMode: false, isBuyMode: false, effectiveRecipientAddress: selectedRecipientOrDefault, recipientName: recipientName || undefined, customRecipientLabel: customRecipientLabel, onSelectRecipient: () => setActivePanel(PanelView.RECIPIENT_SELECTION), dstAmount: isSrcInputDirty ? dstAmount : dstAmountInput, dstToken: selectedDstToken, dstTokenSymbol: DESTINATION_TOKEN_DETAILS.SYMBOL, dstTokenLogoURI: DESTINATION_TOKEN_DETAILS.LOGO_URI, selectedDstChainId: selectedDstChainId, setSelectedDstChainId: () => { }, setSelectedDstToken: () => { }, isSrcInputDirty: isSrcInputDirty, onChangeDstAmount: value => {
|
|
185
201
|
setIsSrcInputDirty(false);
|
|
186
|
-
|
|
202
|
+
setDstAmountInput(value);
|
|
187
203
|
}, anyspendQuote: anyspendQuote, onShowPointsDetail: () => setActivePanel(PanelView.POINTS_DETAIL), onShowFeeDetail: () => setActivePanel(PanelView.FEE_DETAIL) }))] }) }), _jsx(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: cn("mt-4 flex w-full max-w-[460px] flex-col gap-2"), children: _jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", disabled: btnInfo.disable, onClick: onMainButtonClick, className: (btnInfo.error && classes?.mainButtonError) ||
|
|
188
204
|
(btnInfo.disable && classes?.mainButtonDisabled) ||
|
|
189
205
|
classes?.mainButton ||
|
|
@@ -192,20 +208,49 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
192
208
|
try {
|
|
193
209
|
invariant(anyspendQuote, "Relay price is not found");
|
|
194
210
|
invariant(selectedRecipientOrDefault, "Recipient address is not found");
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
211
|
+
if (tradeType === "EXACT_OUTPUT") {
|
|
212
|
+
// EXACT_OUTPUT mode: create a custom order (like AnySpendStakeUpside)
|
|
213
|
+
const srcAmountFromQuote = anyspendQuote.data?.currencyIn?.amount;
|
|
214
|
+
invariant(srcAmountFromQuote, "Source amount from quote is not found");
|
|
215
|
+
const expectedDstAmount = anyspendQuote.data?.currencyOut?.amount ?? "0";
|
|
216
|
+
const encodedData = generateEncodedData(customExactInConfig, activeOutputAmountInWei);
|
|
217
|
+
createOrder({
|
|
218
|
+
recipientAddress: selectedRecipientOrDefault,
|
|
219
|
+
orderType: "custom",
|
|
220
|
+
srcChain: selectedSrcChainId,
|
|
221
|
+
dstChain: selectedDstChainId,
|
|
222
|
+
srcToken: selectedSrcToken,
|
|
223
|
+
dstToken: selectedDstToken,
|
|
224
|
+
srcAmount: srcAmountFromQuote,
|
|
225
|
+
expectedDstAmount,
|
|
226
|
+
creatorAddress: globalAddress,
|
|
227
|
+
payload: {
|
|
228
|
+
amount: activeOutputAmountInWei,
|
|
229
|
+
data: encodedData,
|
|
230
|
+
to: customExactInConfig ? normalizeAddress(customExactInConfig.to) : undefined,
|
|
231
|
+
spenderAddress: customExactInConfig?.spenderAddress
|
|
232
|
+
? normalizeAddress(customExactInConfig.spenderAddress)
|
|
233
|
+
: undefined,
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// EXACT_INPUT mode: create custom_exact_in order (original behavior)
|
|
239
|
+
const srcAmountBigInt = BigInt(activeInputAmountInWei);
|
|
240
|
+
const payload = buildCustomPayload(selectedRecipientOrDefault);
|
|
241
|
+
createOrder({
|
|
242
|
+
recipientAddress: selectedRecipientOrDefault,
|
|
243
|
+
orderType,
|
|
244
|
+
srcChain: selectedSrcChainId,
|
|
245
|
+
dstChain: selectedDstChainId,
|
|
246
|
+
srcToken: selectedSrcToken,
|
|
247
|
+
dstToken: selectedDstToken,
|
|
248
|
+
srcAmount: srcAmountBigInt.toString(),
|
|
249
|
+
expectedDstAmount: expectedDstAmountRaw,
|
|
250
|
+
creatorAddress: globalAddress,
|
|
251
|
+
payload,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
209
254
|
}
|
|
210
255
|
catch (err) {
|
|
211
256
|
console.error(err);
|
|
@@ -241,23 +286,50 @@ function AnySpendCustomExactInInner({ loadOrder, mode = "modal", recipientAddres
|
|
|
241
286
|
toast.error("Please select a payment method");
|
|
242
287
|
return;
|
|
243
288
|
}
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
289
|
+
const onrampOptions = {
|
|
290
|
+
vendor,
|
|
291
|
+
paymentMethod: paymentMethodString,
|
|
292
|
+
country: geoData?.country || "US",
|
|
293
|
+
redirectUrl: window.location.origin,
|
|
294
|
+
};
|
|
295
|
+
if (tradeType === "EXACT_OUTPUT") {
|
|
296
|
+
// EXACT_OUTPUT mode: create a custom order (like AnySpendStakeUpside)
|
|
297
|
+
const expectedDstAmount = anyspendQuote.data?.currencyOut?.amount ?? "0";
|
|
298
|
+
const encodedData = generateEncodedData(customExactInConfig, activeOutputAmountInWei);
|
|
299
|
+
createOnrampOrder({
|
|
300
|
+
recipientAddress: selectedRecipientOrDefault,
|
|
301
|
+
orderType: "custom",
|
|
302
|
+
dstChain: selectedDstChainId,
|
|
303
|
+
dstToken: selectedDstToken,
|
|
304
|
+
srcFiatAmount: srcAmount,
|
|
305
|
+
onramp: onrampOptions,
|
|
306
|
+
expectedDstAmount,
|
|
307
|
+
creatorAddress: globalAddress,
|
|
308
|
+
payload: {
|
|
309
|
+
amount: activeOutputAmountInWei,
|
|
310
|
+
data: encodedData,
|
|
311
|
+
to: customExactInConfig ? normalizeAddress(customExactInConfig.to) : undefined,
|
|
312
|
+
spenderAddress: customExactInConfig?.spenderAddress
|
|
313
|
+
? normalizeAddress(customExactInConfig.spenderAddress)
|
|
314
|
+
: undefined,
|
|
315
|
+
},
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
// EXACT_INPUT mode: create custom_exact_in order (original behavior)
|
|
320
|
+
const payload = buildCustomPayload(selectedRecipientOrDefault);
|
|
321
|
+
createOnrampOrder({
|
|
322
|
+
recipientAddress: selectedRecipientOrDefault,
|
|
323
|
+
orderType,
|
|
324
|
+
dstChain: selectedDstChainId,
|
|
325
|
+
dstToken: selectedDstToken,
|
|
326
|
+
srcFiatAmount: srcAmount,
|
|
327
|
+
onramp: onrampOptions,
|
|
328
|
+
expectedDstAmount: expectedDstAmountRaw,
|
|
329
|
+
creatorAddress: globalAddress,
|
|
330
|
+
payload,
|
|
331
|
+
});
|
|
332
|
+
}
|
|
261
333
|
}
|
|
262
334
|
catch (err) {
|
|
263
335
|
console.error(err);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { components } from "../../../anyspend/types/api";
|
|
2
|
-
export declare function AnySpendStakeUpsideExactIn({ loadOrder, mode, recipientAddress, sourceTokenAddress, sourceTokenChainId, stakingContractAddress, token, onSuccess, }: {
|
|
2
|
+
export declare function AnySpendStakeUpsideExactIn({ loadOrder, mode, recipientAddress, sourceTokenAddress, sourceTokenChainId, destinationTokenAmount, stakingContractAddress, token, onSuccess, }: {
|
|
3
3
|
loadOrder?: string;
|
|
4
4
|
mode?: "modal" | "page";
|
|
5
5
|
recipientAddress: string;
|
|
@@ -7,5 +7,6 @@ export declare function AnySpendStakeUpsideExactIn({ loadOrder, mode, recipientA
|
|
|
7
7
|
sourceTokenChainId?: number;
|
|
8
8
|
stakingContractAddress: string;
|
|
9
9
|
token: components["schemas"]["Token"];
|
|
10
|
+
destinationTokenAmount?: string;
|
|
10
11
|
onSuccess?: (amount: string) => void;
|
|
11
12
|
}): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -14,7 +14,7 @@ const STAKE_FOR_FUNCTION_ABI = JSON.stringify([
|
|
|
14
14
|
outputs: [],
|
|
15
15
|
},
|
|
16
16
|
]);
|
|
17
|
-
export function AnySpendStakeUpsideExactIn({ loadOrder, mode = "modal", recipientAddress, sourceTokenAddress, sourceTokenChainId, stakingContractAddress, token, onSuccess, }) {
|
|
17
|
+
export function AnySpendStakeUpsideExactIn({ loadOrder, mode = "modal", recipientAddress, sourceTokenAddress, sourceTokenChainId, destinationTokenAmount, stakingContractAddress, token, onSuccess, }) {
|
|
18
18
|
if (!recipientAddress)
|
|
19
19
|
return null;
|
|
20
20
|
const header = () => (_jsx(_Fragment, { children: _jsx("div", { className: "from-b3-react-background to-as-on-surface-1 w-full rounded-t-lg bg-gradient-to-t", children: _jsx("div", { className: "mb-1 flex w-full flex-col items-center gap-2", children: _jsxs("span", { className: "font-sf-rounded text-2xl font-semibold", children: ["Swap & Stake ", token.symbol, " (Exact In)"] }) }) }) }));
|
|
@@ -26,5 +26,5 @@ export function AnySpendStakeUpsideExactIn({ loadOrder, mode = "modal", recipien
|
|
|
26
26
|
spenderAddress: stakingContractAddress,
|
|
27
27
|
action: `stake ${token.symbol}`,
|
|
28
28
|
};
|
|
29
|
-
return (_jsx(AnySpendCustomExactIn, { loadOrder: loadOrder, mode: mode, recipientAddress: recipientAddress, sourceTokenAddress: sourceTokenAddress, sourceTokenChainId: sourceTokenChainId, destinationToken: token, destinationChainId: base.id, customExactInConfig: customExactInConfig, header: header, onSuccess: onSuccess }));
|
|
29
|
+
return (_jsx(AnySpendCustomExactIn, { loadOrder: loadOrder, mode: mode, recipientAddress: recipientAddress, sourceTokenAddress: sourceTokenAddress, sourceTokenChainId: sourceTokenChainId, destinationToken: token, destinationChainId: base.id, destinationTokenAmount: destinationTokenAmount, customExactInConfig: customExactInConfig, header: header, onSuccess: onSuccess }));
|
|
30
30
|
}
|
|
@@ -348,13 +348,11 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
348
348
|
if (!srcToken || !dstToken) {
|
|
349
349
|
return _jsx("div", { children: "Loading..." });
|
|
350
350
|
}
|
|
351
|
-
const expectedDstAmount = order.type === "mint_nft" ||
|
|
352
|
-
order.type === "join_tournament" ||
|
|
353
|
-
order.type === "fund_tournament" ||
|
|
354
|
-
order.type === "custom" ||
|
|
355
|
-
order.type === "deposit_first"
|
|
351
|
+
const expectedDstAmount = order.type === "mint_nft" || order.type === "join_tournament" || order.type === "fund_tournament"
|
|
356
352
|
? "0"
|
|
357
|
-
: order.
|
|
353
|
+
: order.type === "custom" || order.type === "deposit_first"
|
|
354
|
+
? order.payload.amount?.toString() || "0"
|
|
355
|
+
: order.payload.expectedDstAmount.toString();
|
|
358
356
|
const formattedExpectedDstAmount = formatTokenAmount(BigInt(expectedDstAmount), dstToken.decimals);
|
|
359
357
|
const actualDstAmount = order.settlement?.actualDstAmount;
|
|
360
358
|
const formattedActualDstAmount = actualDstAmount
|
|
@@ -16,13 +16,12 @@ export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({ o
|
|
|
16
16
|
const showOrderDetails = isOpen !== undefined ? isOpen : internalOpen;
|
|
17
17
|
const setShowOrderDetails = onOpenChange || setInternalOpen;
|
|
18
18
|
// Calculate expected amount if not provided
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
order.type === "fund_tournament" ||
|
|
22
|
-
order.type === "custom" ||
|
|
23
|
-
order.type === "deposit_first"
|
|
19
|
+
// For custom orders, use payload.amount as the expected destination amount
|
|
20
|
+
const expectedDstAmount = order.type === "mint_nft" || order.type === "join_tournament" || order.type === "fund_tournament"
|
|
24
21
|
? "0"
|
|
25
|
-
: order.
|
|
22
|
+
: order.type === "custom" || order.type === "deposit_first"
|
|
23
|
+
? order.payload.amount?.toString() || "0"
|
|
24
|
+
: order.payload.expectedDstAmount.toString();
|
|
26
25
|
const finalFormattedExpectedDstAmount = formattedExpectedDstAmount || formatTokenAmount(BigInt(expectedDstAmount), dstToken.decimals);
|
|
27
26
|
return (_jsx("div", { className: cn(classes?.container ||
|
|
28
27
|
"order-details-collapsible bg-as-surface-secondary border-as-border-secondary rounded-xl border px-4 py-2", className), children: showOrderDetails ? (_jsx(motion.div, { className: "order-details-expanded w-full", 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: _jsxs("div", { className: "order-details-content flex w-full flex-col items-center gap-3 whitespace-nowrap py-2 text-sm", children: [_jsxs("div", { className: "order-details-recipient-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-recipient-label text-as-tertiarry", children: "Recipient" }), _jsxs("div", { className: "order-details-recipient-info flex flex-col items-end gap-1", children: [recipientName && (_jsx("div", { className: "order-details-recipient-name text-as-primary font-semibold", children: recipientName })), _jsx(CopyToClipboard, { text: order.recipientAddress, onCopy: () => {
|
|
@@ -40,5 +39,5 @@ export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({ o
|
|
|
40
39
|
? order.metadata.action
|
|
41
40
|
? capitalizeFirstLetter(order.metadata.action)
|
|
42
41
|
: "Contract execution"
|
|
43
|
-
: "" }), _jsxs("div", { className: "order-details-expected-value flex flex-wrap items-center justify-end gap-2", children: [order.type === "swap" || order.type === "deposit_first" ? (_jsx("span", { className: "order-details-amount-text", children: `~${finalFormattedExpectedDstAmount} ${dstToken.symbol}` })) : order.type === "mint_nft" ? (_jsxs("div", { className: "order-details-nft-info flex items-center gap-2", children: [_jsx("img", { src: nft?.imageUrl, alt: nft?.name || "NFT", className: "order-details-nft-image h-5 w-5" }), _jsx("div", { className: "order-details-nft-name", children: nft?.name || "NFT" })] })) : order.type === "join_tournament" || order.type === "fund_tournament" ? (_jsxs("div", { className: "order-details-tournament-info flex items-center gap-2", children: [_jsx("img", { src: tournament?.imageUrl, alt: tournament?.name || "Tournament", className: "order-details-tournament-image h-5 w-5" }), _jsx("div", { className: "order-details-tournament-name", children: tournament?.name || "Tournament" })] })) : order.type === "hype_duel" ? (_jsx("div", { className: "order-details-hype-info flex items-center gap-2", children: _jsxs("div", { className: "order-details-hype-amount", children: [formatTokenAmount(BigInt(order.payload.expectedDstAmount), dstToken.decimals), " HYPE"] }) })) : null, _jsxs("div", { className: "order-details-chain-info text-as-primary/50 flex items-center gap-2", children: [_jsxs("span", { className: "order-details-chain-text", children: ["on ", order.dstChain !== b3.id && getChainName(order.dstChain)] }), _jsx("img", { src: ALL_CHAINS[order.dstChain].logoUrl, alt: getChainName(order.dstChain), className: cn("order-details-chain-logo h-3", order.dstChain !== b3.id && "w-3 rounded-full", order.dstChain === b3.id && "h-4") })] })] })] }), points !== undefined && points !== null && (_jsxs(_Fragment, { children: [_jsx("div", { className: "order-details-divider divider w-full" }), _jsxs("div", { className: "order-details-points-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-points-label text-as-tertiarry", children: "Points" }), _jsxs("div", { className: "order-details-points-value text-as-brand font-semibold", children: ["+", formatNumber(points), " pts"] })] })] })), _jsx("div", { className: "order-details-divider divider w-full" }), _jsxs("div", { className: "order-details-id-total-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-id-total-label text-as-tertiarry", children: showTotal ? "Total (included fee)" : "Order ID" }), _jsx("div", { className: "order-details-id-total-value text-as-primary overflow-hidden text-ellipsis whitespace-nowrap", children: showTotal && totalAmount ? totalAmount : order.id })] })] }) })) : (_jsxs("div", { className: "order-details-collapsed flex w-full items-center", children: [_jsx("div", { className: "order-details-collapsed-divider divider w-full" }), _jsx("button", { className: "order-details-collapsed-button whitespace-nowrap text-sm", onClick: () => setShowOrderDetails(true), children: "Order Details" }), _jsx(ChevronDown, { className: "order-details-collapsed-chevron text-as-primary mx-1 h-4 min-h-4 w-4 min-w-4" }), _jsx("div", { className: "order-details-collapsed-divider divider w-full" })] })) }));
|
|
42
|
+
: "" }), _jsxs("div", { className: "order-details-expected-value flex flex-wrap items-center justify-end gap-2", children: [order.type === "swap" || order.type === "deposit_first" ? (_jsx("span", { className: "order-details-amount-text", children: `~${finalFormattedExpectedDstAmount} ${dstToken.symbol}` })) : order.type === "mint_nft" ? (_jsxs("div", { className: "order-details-nft-info flex items-center gap-2", children: [_jsx("img", { src: nft?.imageUrl, alt: nft?.name || "NFT", className: "order-details-nft-image h-5 w-5" }), _jsx("div", { className: "order-details-nft-name", children: nft?.name || "NFT" })] })) : order.type === "join_tournament" || order.type === "fund_tournament" ? (_jsxs("div", { className: "order-details-tournament-info flex items-center gap-2", children: [_jsx("img", { src: tournament?.imageUrl, alt: tournament?.name || "Tournament", className: "order-details-tournament-image h-5 w-5" }), _jsx("div", { className: "order-details-tournament-name", children: tournament?.name || "Tournament" })] })) : order.type === "hype_duel" ? (_jsx("div", { className: "order-details-hype-info flex items-center gap-2", children: _jsxs("div", { className: "order-details-hype-amount", children: [formatTokenAmount(BigInt(order.payload.expectedDstAmount), dstToken.decimals), " HYPE"] }) })) : order.type === "custom" || order.type === "custom_exact_in" ? (_jsx("span", { className: "order-details-amount-text", children: `~${finalFormattedExpectedDstAmount} ${dstToken.symbol}` })) : null, _jsxs("div", { className: "order-details-chain-info text-as-primary/50 flex items-center gap-2", children: [_jsxs("span", { className: "order-details-chain-text", children: ["on ", order.dstChain !== b3.id && getChainName(order.dstChain)] }), _jsx("img", { src: ALL_CHAINS[order.dstChain].logoUrl, alt: getChainName(order.dstChain), className: cn("order-details-chain-logo h-3", order.dstChain !== b3.id && "w-3 rounded-full", order.dstChain === b3.id && "h-4") })] })] })] }), points !== undefined && points !== null && (_jsxs(_Fragment, { children: [_jsx("div", { className: "order-details-divider divider w-full" }), _jsxs("div", { className: "order-details-points-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-points-label text-as-tertiarry", children: "Points" }), _jsxs("div", { className: "order-details-points-value text-as-brand font-semibold", children: ["+", formatNumber(points), " pts"] })] })] })), _jsx("div", { className: "order-details-divider divider w-full" }), _jsxs("div", { className: "order-details-id-total-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-id-total-label text-as-tertiarry", children: showTotal ? "Total (included fee)" : "Order ID" }), _jsx("div", { className: "order-details-id-total-value text-as-primary overflow-hidden text-ellipsis whitespace-nowrap", children: showTotal && totalAmount ? totalAmount : order.id })] })] }) })) : (_jsxs("div", { className: "order-details-collapsed flex w-full items-center", children: [_jsx("div", { className: "order-details-collapsed-divider divider w-full" }), _jsx("button", { className: "order-details-collapsed-button whitespace-nowrap text-sm", onClick: () => setShowOrderDetails(true), children: "Order Details" }), _jsx(ChevronDown, { className: "order-details-collapsed-chevron text-as-primary mx-1 h-4 min-h-4 w-4 min-w-4" }), _jsx("div", { className: "order-details-collapsed-divider divider w-full" })] })) }));
|
|
44
43
|
});
|
|
@@ -11,6 +11,19 @@ export declare enum PanelView {
|
|
|
11
11
|
POINTS_DETAIL = 6,
|
|
12
12
|
FEE_DETAIL = 7
|
|
13
13
|
}
|
|
14
|
+
export type CustomExactInConfig = {
|
|
15
|
+
functionAbi: string;
|
|
16
|
+
functionName: string;
|
|
17
|
+
functionArgs: string[];
|
|
18
|
+
to: string;
|
|
19
|
+
spenderAddress?: string;
|
|
20
|
+
action?: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Generates encoded function data for custom contract calls.
|
|
24
|
+
* Handles amount placeholder replacement and BigInt conversion.
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateEncodedData(config: CustomExactInConfig | undefined, amountInWei: string): string | undefined;
|
|
14
27
|
interface UseAnyspendFlowProps {
|
|
15
28
|
paymentType?: "crypto" | "fiat";
|
|
16
29
|
recipientAddress?: string;
|
|
@@ -25,8 +38,9 @@ interface UseAnyspendFlowProps {
|
|
|
25
38
|
slippage?: number;
|
|
26
39
|
disableUrlParamManagement?: boolean;
|
|
27
40
|
orderType?: "hype_duel" | "custom_exact_in" | "swap";
|
|
41
|
+
customExactInConfig?: CustomExactInConfig;
|
|
28
42
|
}
|
|
29
|
-
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, destinationTokenAddress, destinationTokenChainId, slippage, disableUrlParamManagement, orderType, }: UseAnyspendFlowProps): {
|
|
43
|
+
export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrder, onOrderSuccess, onTransactionSuccess, sourceTokenAddress, sourceTokenChainId, destinationTokenAddress, destinationTokenChainId, slippage, disableUrlParamManagement, orderType, customExactInConfig, }: UseAnyspendFlowProps): {
|
|
30
44
|
activePanel: PanelView;
|
|
31
45
|
setActivePanel: import("react").Dispatch<import("react").SetStateAction<PanelView>>;
|
|
32
46
|
orderId: string | undefined;
|
|
@@ -91,8 +105,11 @@ export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrd
|
|
|
91
105
|
setSrcAmount: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
92
106
|
dstAmount: string;
|
|
93
107
|
setDstAmount: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
108
|
+
dstAmountInput: string;
|
|
109
|
+
setDstAmountInput: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
94
110
|
isSrcInputDirty: boolean;
|
|
95
111
|
setIsSrcInputDirty: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
112
|
+
tradeType: string;
|
|
96
113
|
cryptoPaymentMethod: CryptoPaymentMethodType;
|
|
97
114
|
setCryptoPaymentMethod: (method: CryptoPaymentMethodType) => void;
|
|
98
115
|
selectedCryptoPaymentMethod: CryptoPaymentMethodType;
|
|
@@ -176,8 +193,10 @@ export declare function useAnyspendFlow({ paymentType, recipientAddress, loadOrd
|
|
|
176
193
|
statusCode: number;
|
|
177
194
|
} | undefined;
|
|
178
195
|
isLoadingAnyspendQuote: boolean;
|
|
196
|
+
isQuoteLoading: boolean;
|
|
179
197
|
getAnyspendQuoteError: Error | null;
|
|
180
198
|
activeInputAmountInWei: string;
|
|
199
|
+
activeOutputAmountInWei: string;
|
|
181
200
|
geoData: import("../../../anyspend/react").GeoData | undefined;
|
|
182
201
|
coinbaseAvailablePaymentMethods: {
|
|
183
202
|
id?: string;
|