@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
|
@@ -22,6 +22,7 @@ export function AnySpendStakeUpsideExactIn({
|
|
|
22
22
|
recipientAddress,
|
|
23
23
|
sourceTokenAddress,
|
|
24
24
|
sourceTokenChainId,
|
|
25
|
+
destinationTokenAmount,
|
|
25
26
|
stakingContractAddress,
|
|
26
27
|
token,
|
|
27
28
|
onSuccess,
|
|
@@ -33,6 +34,7 @@ export function AnySpendStakeUpsideExactIn({
|
|
|
33
34
|
sourceTokenChainId?: number;
|
|
34
35
|
stakingContractAddress: string;
|
|
35
36
|
token: components["schemas"]["Token"];
|
|
37
|
+
destinationTokenAmount?: string;
|
|
36
38
|
onSuccess?: (amount: string) => void;
|
|
37
39
|
}) {
|
|
38
40
|
if (!recipientAddress) return null;
|
|
@@ -65,6 +67,7 @@ export function AnySpendStakeUpsideExactIn({
|
|
|
65
67
|
sourceTokenChainId={sourceTokenChainId}
|
|
66
68
|
destinationToken={token}
|
|
67
69
|
destinationChainId={base.id}
|
|
70
|
+
destinationTokenAmount={destinationTokenAmount}
|
|
68
71
|
customExactInConfig={customExactInConfig}
|
|
69
72
|
header={header}
|
|
70
73
|
onSuccess={onSuccess}
|
|
@@ -498,13 +498,11 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
498
498
|
}
|
|
499
499
|
|
|
500
500
|
const expectedDstAmount =
|
|
501
|
-
order.type === "mint_nft" ||
|
|
502
|
-
order.type === "join_tournament" ||
|
|
503
|
-
order.type === "fund_tournament" ||
|
|
504
|
-
order.type === "custom" ||
|
|
505
|
-
order.type === "deposit_first"
|
|
501
|
+
order.type === "mint_nft" || order.type === "join_tournament" || order.type === "fund_tournament"
|
|
506
502
|
? "0"
|
|
507
|
-
: order.
|
|
503
|
+
: order.type === "custom" || order.type === "deposit_first"
|
|
504
|
+
? order.payload.amount?.toString() || "0"
|
|
505
|
+
: order.payload.expectedDstAmount.toString();
|
|
508
506
|
const formattedExpectedDstAmount = formatTokenAmount(BigInt(expectedDstAmount), dstToken.decimals);
|
|
509
507
|
|
|
510
508
|
const actualDstAmount = order.settlement?.actualDstAmount;
|
|
@@ -57,14 +57,13 @@ export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({
|
|
|
57
57
|
const setShowOrderDetails = onOpenChange || setInternalOpen;
|
|
58
58
|
|
|
59
59
|
// Calculate expected amount if not provided
|
|
60
|
+
// For custom orders, use payload.amount as the expected destination amount
|
|
60
61
|
const expectedDstAmount =
|
|
61
|
-
order.type === "mint_nft" ||
|
|
62
|
-
order.type === "join_tournament" ||
|
|
63
|
-
order.type === "fund_tournament" ||
|
|
64
|
-
order.type === "custom" ||
|
|
65
|
-
order.type === "deposit_first"
|
|
62
|
+
order.type === "mint_nft" || order.type === "join_tournament" || order.type === "fund_tournament"
|
|
66
63
|
? "0"
|
|
67
|
-
: order.
|
|
64
|
+
: order.type === "custom" || order.type === "deposit_first"
|
|
65
|
+
? order.payload.amount?.toString() || "0"
|
|
66
|
+
: order.payload.expectedDstAmount.toString();
|
|
68
67
|
|
|
69
68
|
const finalFormattedExpectedDstAmount =
|
|
70
69
|
formattedExpectedDstAmount || formatTokenAmount(BigInt(expectedDstAmount), dstToken.decimals);
|
|
@@ -149,6 +148,8 @@ export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({
|
|
|
149
148
|
{formatTokenAmount(BigInt(order.payload.expectedDstAmount), dstToken.decimals)} HYPE
|
|
150
149
|
</div>
|
|
151
150
|
</div>
|
|
151
|
+
) : order.type === "custom" || order.type === "custom_exact_in" ? (
|
|
152
|
+
<span className="order-details-amount-text">{`~${finalFormattedExpectedDstAmount} ${dstToken.symbol}`}</span>
|
|
152
153
|
) : null}
|
|
153
154
|
|
|
154
155
|
<div className="order-details-chain-info text-as-primary/50 flex items-center gap-2">
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
useGeoOnrampOptions,
|
|
8
8
|
} from "@b3dotfun/sdk/anyspend/react";
|
|
9
9
|
import { anyspendService } from "@b3dotfun/sdk/anyspend/services/anyspend";
|
|
10
|
+
import { normalizeAddress } from "@b3dotfun/sdk/anyspend/utils";
|
|
10
11
|
import {
|
|
11
12
|
toast,
|
|
12
13
|
useAccountWallet,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
import { formatTokenAmount, formatUnits } from "@b3dotfun/sdk/shared/utils/number";
|
|
19
20
|
import { useEffect, useMemo, useState } from "react";
|
|
20
21
|
|
|
21
|
-
import { parseUnits } from "viem";
|
|
22
|
+
import { encodeFunctionData, parseUnits } from "viem";
|
|
22
23
|
import { base, mainnet } from "viem/chains";
|
|
23
24
|
import { components } from "../../types/api";
|
|
24
25
|
import { GetQuoteRequest } from "../../types/api_req_res";
|
|
@@ -40,6 +41,59 @@ export enum PanelView {
|
|
|
40
41
|
FEE_DETAIL,
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
export type CustomExactInConfig = {
|
|
45
|
+
functionAbi: string;
|
|
46
|
+
functionName: string;
|
|
47
|
+
functionArgs: string[];
|
|
48
|
+
to: string;
|
|
49
|
+
spenderAddress?: string;
|
|
50
|
+
action?: string;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Generates encoded function data for custom contract calls.
|
|
55
|
+
* Handles amount placeholder replacement and BigInt conversion.
|
|
56
|
+
*/
|
|
57
|
+
export function generateEncodedData(config: CustomExactInConfig | undefined, amountInWei: string): string | undefined {
|
|
58
|
+
if (!config || !config.functionAbi || !config.functionName || !config.functionArgs) {
|
|
59
|
+
console.warn("customExactInConfig missing required fields for encoding:", {
|
|
60
|
+
hasConfig: !!config,
|
|
61
|
+
hasFunctionAbi: !!config?.functionAbi,
|
|
62
|
+
hasFunctionName: !!config?.functionName,
|
|
63
|
+
hasFunctionArgs: !!config?.functionArgs,
|
|
64
|
+
});
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const abi = JSON.parse(config.functionAbi);
|
|
70
|
+
const processedArgs = config.functionArgs.map(arg => {
|
|
71
|
+
// Replace amount placeholders ({{dstAmount}}, {{amount_out}}, etc.)
|
|
72
|
+
if (arg === "{{dstAmount}}" || arg === "{{amount_out}}") {
|
|
73
|
+
return BigInt(amountInWei);
|
|
74
|
+
}
|
|
75
|
+
// Convert numeric strings to BigInt for uint256 args
|
|
76
|
+
if (/^\d+$/.test(arg)) {
|
|
77
|
+
return BigInt(arg);
|
|
78
|
+
}
|
|
79
|
+
return arg;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return encodeFunctionData({
|
|
83
|
+
abi,
|
|
84
|
+
functionName: config.functionName,
|
|
85
|
+
args: processedArgs,
|
|
86
|
+
});
|
|
87
|
+
} catch (e) {
|
|
88
|
+
console.error("Failed to encode function data:", e, {
|
|
89
|
+
functionAbi: config.functionAbi,
|
|
90
|
+
functionName: config.functionName,
|
|
91
|
+
functionArgs: config.functionArgs,
|
|
92
|
+
});
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
43
97
|
interface UseAnyspendFlowProps {
|
|
44
98
|
paymentType?: "crypto" | "fiat";
|
|
45
99
|
recipientAddress?: string;
|
|
@@ -54,6 +108,7 @@ interface UseAnyspendFlowProps {
|
|
|
54
108
|
slippage?: number;
|
|
55
109
|
disableUrlParamManagement?: boolean;
|
|
56
110
|
orderType?: "hype_duel" | "custom_exact_in" | "swap";
|
|
111
|
+
customExactInConfig?: CustomExactInConfig;
|
|
57
112
|
}
|
|
58
113
|
|
|
59
114
|
// This hook serves for order hype_duel and custom_exact_in
|
|
@@ -70,6 +125,7 @@ export function useAnyspendFlow({
|
|
|
70
125
|
slippage = 0,
|
|
71
126
|
disableUrlParamManagement = false,
|
|
72
127
|
orderType = "hype_duel",
|
|
128
|
+
customExactInConfig,
|
|
73
129
|
}: UseAnyspendFlowProps) {
|
|
74
130
|
const searchParams = useSearchParamsSSR();
|
|
75
131
|
const router = useRouter();
|
|
@@ -89,6 +145,8 @@ export function useAnyspendFlow({
|
|
|
89
145
|
const [selectedDstToken, setSelectedDstToken] = useState<components["schemas"]["Token"]>(defaultDstToken);
|
|
90
146
|
const [srcAmount, setSrcAmount] = useState<string>(paymentType === "fiat" ? "5" : "0");
|
|
91
147
|
const [dstAmount, setDstAmount] = useState<string>("");
|
|
148
|
+
const [dstAmountInput, setDstAmountInput] = useState<string>(""); // User input for destination amount (EXACT_OUTPUT mode)
|
|
149
|
+
const [debouncedDstAmountInput, setDebouncedDstAmountInput] = useState<string>(""); // Debounced version for quote requests
|
|
92
150
|
const [isSrcInputDirty, setIsSrcInputDirty] = useState(true);
|
|
93
151
|
|
|
94
152
|
// Derive destination chain ID from token or prop (cannot change)
|
|
@@ -183,6 +241,20 @@ export function useAnyspendFlow({
|
|
|
183
241
|
fetchDestinationToken();
|
|
184
242
|
}, [destinationTokenAddress, destinationTokenChainId]);
|
|
185
243
|
|
|
244
|
+
// Check if destination token is ready (matches the expected address from props)
|
|
245
|
+
// This is important for EXACT_OUTPUT mode where we need correct decimals
|
|
246
|
+
const isDestinationTokenReady =
|
|
247
|
+
!destinationTokenAddress || selectedDstToken.address.toLowerCase() === destinationTokenAddress.toLowerCase();
|
|
248
|
+
|
|
249
|
+
// Debounce destination amount input for quote requests (500ms delay)
|
|
250
|
+
useEffect(() => {
|
|
251
|
+
const timer = setTimeout(() => {
|
|
252
|
+
setDebouncedDstAmountInput(dstAmountInput);
|
|
253
|
+
}, 500);
|
|
254
|
+
|
|
255
|
+
return () => clearTimeout(timer);
|
|
256
|
+
}, [dstAmountInput]);
|
|
257
|
+
|
|
186
258
|
// Helper function for onramp vendor mapping
|
|
187
259
|
const getOnrampVendor = (paymentMethod: FiatPaymentMethod): "coinbase" | "stripe" | "stripe-web2" | undefined => {
|
|
188
260
|
switch (paymentMethod) {
|
|
@@ -197,8 +269,18 @@ export function useAnyspendFlow({
|
|
|
197
269
|
|
|
198
270
|
// Get quote
|
|
199
271
|
// For fiat payments, always use USDC decimals (6) regardless of selectedSrcToken
|
|
200
|
-
const
|
|
201
|
-
const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""),
|
|
272
|
+
const effectiveSrcDecimals = paymentType === "fiat" ? USDC_BASE.decimals : selectedSrcToken.decimals;
|
|
273
|
+
const activeInputAmountInWei = parseUnits(srcAmount.replace(/,/g, ""), effectiveSrcDecimals).toString();
|
|
274
|
+
|
|
275
|
+
// Calculate output amount in wei for EXACT_OUTPUT mode
|
|
276
|
+
// Only calculate when destination token is ready (has correct decimals)
|
|
277
|
+
// Use debounced value to reduce quote API calls
|
|
278
|
+
const activeOutputAmountInWei = isDestinationTokenReady
|
|
279
|
+
? parseUnits(debouncedDstAmountInput.replace(/,/g, "") || "0", selectedDstToken.decimals).toString()
|
|
280
|
+
: "0";
|
|
281
|
+
|
|
282
|
+
// Determine trade type based on which input was last edited
|
|
283
|
+
const tradeType = isSrcInputDirty ? "EXACT_INPUT" : "EXACT_OUTPUT";
|
|
202
284
|
|
|
203
285
|
// Build quote request based on order type
|
|
204
286
|
const quoteRequest: GetQuoteRequest = (() => {
|
|
@@ -215,8 +297,8 @@ export function useAnyspendFlow({
|
|
|
215
297
|
return {
|
|
216
298
|
...baseParams,
|
|
217
299
|
type: "swap" as const,
|
|
218
|
-
tradeType: "EXACT_INPUT"
|
|
219
|
-
amount: activeInputAmountInWei,
|
|
300
|
+
tradeType: tradeType as "EXACT_INPUT" | "EXACT_OUTPUT",
|
|
301
|
+
amount: tradeType === "EXACT_INPUT" ? activeInputAmountInWei : activeOutputAmountInWei,
|
|
220
302
|
};
|
|
221
303
|
} else if (orderType === "hype_duel") {
|
|
222
304
|
return {
|
|
@@ -225,6 +307,23 @@ export function useAnyspendFlow({
|
|
|
225
307
|
amount: activeInputAmountInWei,
|
|
226
308
|
};
|
|
227
309
|
} else {
|
|
310
|
+
// custom_exact_in - for EXACT_OUTPUT, use custom type to get the quote
|
|
311
|
+
if (tradeType === "EXACT_OUTPUT") {
|
|
312
|
+
const encodedData = generateEncodedData(customExactInConfig, activeOutputAmountInWei);
|
|
313
|
+
|
|
314
|
+
return {
|
|
315
|
+
...baseParams,
|
|
316
|
+
type: "custom" as const,
|
|
317
|
+
payload: {
|
|
318
|
+
amount: activeOutputAmountInWei,
|
|
319
|
+
data: encodedData || "",
|
|
320
|
+
to: customExactInConfig ? normalizeAddress(customExactInConfig.to) : "",
|
|
321
|
+
spenderAddress: customExactInConfig?.spenderAddress
|
|
322
|
+
? normalizeAddress(customExactInConfig.spenderAddress)
|
|
323
|
+
: undefined,
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
}
|
|
228
327
|
return {
|
|
229
328
|
...baseParams,
|
|
230
329
|
type: "custom_exact_in" as const,
|
|
@@ -235,26 +334,45 @@ export function useAnyspendFlow({
|
|
|
235
334
|
|
|
236
335
|
const { anyspendQuote, isLoadingAnyspendQuote, getAnyspendQuoteError } = useAnyspendQuote(quoteRequest);
|
|
237
336
|
|
|
337
|
+
// Combined loading state: includes debounce waiting period and actual quote fetching
|
|
338
|
+
// For EXACT_OUTPUT mode, also check if we're waiting for debounce
|
|
339
|
+
const isDebouncingDstAmount = tradeType === "EXACT_OUTPUT" && dstAmountInput !== debouncedDstAmountInput;
|
|
340
|
+
const isQuoteLoading = isLoadingAnyspendQuote || isDebouncingDstAmount;
|
|
341
|
+
|
|
238
342
|
// Get geo options for fiat
|
|
239
343
|
const { geoData, coinbaseAvailablePaymentMethods, stripeWeb2Support } = useGeoOnrampOptions(
|
|
240
344
|
paymentType === "fiat" ? formatUnits(activeInputAmountInWei, USDC_BASE.decimals) : "0",
|
|
241
345
|
);
|
|
242
346
|
|
|
243
|
-
// Update
|
|
347
|
+
// Update amounts when quote changes based on trade type
|
|
244
348
|
useEffect(() => {
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
349
|
+
if (isSrcInputDirty) {
|
|
350
|
+
// EXACT_INPUT mode: update destination amount from quote
|
|
351
|
+
if (anyspendQuote?.data?.currencyOut?.amount && anyspendQuote.data.currencyOut.currency?.decimals) {
|
|
352
|
+
const amount = anyspendQuote.data.currencyOut.amount;
|
|
353
|
+
const decimals = anyspendQuote.data.currencyOut.currency.decimals;
|
|
354
|
+
|
|
355
|
+
// Apply slippage (0-100) - reduce amount by slippage percentage
|
|
356
|
+
const amountWithSlippage = (BigInt(amount) * BigInt(100 - slippage)) / BigInt(100);
|
|
357
|
+
|
|
358
|
+
const formattedAmount = formatTokenAmount(amountWithSlippage, decimals, 6, false);
|
|
359
|
+
setDstAmount(formattedAmount);
|
|
360
|
+
} else {
|
|
361
|
+
setDstAmount("");
|
|
362
|
+
}
|
|
254
363
|
} else {
|
|
255
|
-
|
|
364
|
+
// EXACT_OUTPUT mode: update source amount from quote
|
|
365
|
+
if (anyspendQuote?.data?.currencyIn?.amount && anyspendQuote.data.currencyIn.currency?.decimals) {
|
|
366
|
+
const amount = anyspendQuote.data.currencyIn.amount;
|
|
367
|
+
const decimals = anyspendQuote.data.currencyIn.currency.decimals;
|
|
368
|
+
|
|
369
|
+
const formattedAmount = formatTokenAmount(BigInt(amount), decimals, 6, false);
|
|
370
|
+
setSrcAmount(formattedAmount);
|
|
371
|
+
}
|
|
372
|
+
// Also set the display destination amount from the user input
|
|
373
|
+
setDstAmount(dstAmountInput);
|
|
256
374
|
}
|
|
257
|
-
}, [anyspendQuote, slippage]);
|
|
375
|
+
}, [anyspendQuote, slippage, isSrcInputDirty, dstAmountInput]);
|
|
258
376
|
|
|
259
377
|
// Update useEffect for URL parameter to not override loadOrder
|
|
260
378
|
useEffect(() => {
|
|
@@ -344,8 +462,11 @@ export function useAnyspendFlow({
|
|
|
344
462
|
setSrcAmount,
|
|
345
463
|
dstAmount,
|
|
346
464
|
setDstAmount,
|
|
465
|
+
dstAmountInput,
|
|
466
|
+
setDstAmountInput,
|
|
347
467
|
isSrcInputDirty,
|
|
348
468
|
setIsSrcInputDirty,
|
|
469
|
+
tradeType,
|
|
349
470
|
// Payment methods
|
|
350
471
|
cryptoPaymentMethod,
|
|
351
472
|
setCryptoPaymentMethod,
|
|
@@ -366,8 +487,10 @@ export function useAnyspendFlow({
|
|
|
366
487
|
// Quote data
|
|
367
488
|
anyspendQuote,
|
|
368
489
|
isLoadingAnyspendQuote,
|
|
490
|
+
isQuoteLoading, // Combined loading state (includes debounce + quote fetching)
|
|
369
491
|
getAnyspendQuoteError,
|
|
370
492
|
activeInputAmountInWei,
|
|
493
|
+
activeOutputAmountInWei, // User's destination amount input in wei (for EXACT_OUTPUT mode)
|
|
371
494
|
// Geo/onramp data
|
|
372
495
|
geoData,
|
|
373
496
|
coinbaseAvailablePaymentMethods,
|
|
@@ -62,7 +62,7 @@ export function useRecipientAddressState({
|
|
|
62
62
|
|
|
63
63
|
// The effective recipient address, derived on each render, respecting priority.
|
|
64
64
|
const effectiveRecipientAddress =
|
|
65
|
-
|
|
65
|
+
selectedRecipientAddress || recipientAddressFromProps || walletAddress || globalAddress;
|
|
66
66
|
|
|
67
67
|
// Helper function to reset user's manual selection.
|
|
68
68
|
const resetRecipientAddress = () => {
|
|
@@ -7,7 +7,12 @@ export const getStatusDisplay = (
|
|
|
7
7
|
const srcToken = order.metadata?.srcToken;
|
|
8
8
|
const dstToken = order.metadata?.dstToken;
|
|
9
9
|
const formattedSrcAmount = srcToken ? formatTokenAmount(BigInt(order.srcAmount), srcToken.decimals) : undefined;
|
|
10
|
-
|
|
10
|
+
// For custom orders, use payload.amount as fallback if actualDstAmount is not available
|
|
11
|
+
const actualDstAmount =
|
|
12
|
+
order.settlement?.actualDstAmount ||
|
|
13
|
+
(order.type === "custom" || order.type === "custom_exact_in" || order.type === "deposit_first"
|
|
14
|
+
? order.payload.amount?.toString()
|
|
15
|
+
: undefined);
|
|
11
16
|
const formattedActualDstAmount =
|
|
12
17
|
actualDstAmount && dstToken ? formatTokenAmount(BigInt(actualDstAmount), dstToken.decimals) : undefined;
|
|
13
18
|
|
|
@@ -51,6 +56,7 @@ export const getStatusDisplay = (
|
|
|
51
56
|
case "executed": {
|
|
52
57
|
const receivedText =
|
|
53
58
|
formattedActualDstAmount && dstToken ? `Received ${formattedActualDstAmount} ${dstToken.symbol}` : undefined;
|
|
59
|
+
const actionText = (order.metadata as { action?: string })?.action || "Order";
|
|
54
60
|
const { text, description } =
|
|
55
61
|
order.type === "swap"
|
|
56
62
|
? { text: receivedText || "Swap Complete", description: "Your swap has been completed successfully." }
|
|
@@ -60,7 +66,12 @@ export const getStatusDisplay = (
|
|
|
60
66
|
? { text: "Tournament Joined", description: "You have joined the tournament" }
|
|
61
67
|
: order.type === "fund_tournament"
|
|
62
68
|
? { text: "Tournament Funded", description: "You have funded the tournament" }
|
|
63
|
-
:
|
|
69
|
+
: order.type === "custom" || order.type === "custom_exact_in"
|
|
70
|
+
? {
|
|
71
|
+
text: receivedText || `${actionText} Complete`,
|
|
72
|
+
description: "Your order has been completed successfully.",
|
|
73
|
+
}
|
|
74
|
+
: { text: receivedText || "Order Complete", description: "Your order has been completed" };
|
|
64
75
|
return { text, status: "success", description };
|
|
65
76
|
}
|
|
66
77
|
|
|
@@ -323,6 +323,8 @@ export interface AnySpendDepositUpsideProps extends BaseModalProps {
|
|
|
323
323
|
depositContractAddress: string;
|
|
324
324
|
/** Token to deposit */
|
|
325
325
|
token: components["schemas"]["Token"];
|
|
326
|
+
/** The exact amount of destination tokens to receive, in wei. This will pre-fill the output amount and switch to an exact output swap. */
|
|
327
|
+
destinationTokenAmount?: string;
|
|
326
328
|
/** Callback function called when the deposit is successful */
|
|
327
329
|
onSuccess?: () => void;
|
|
328
330
|
}
|