@b3dotfun/sdk 0.0.43 → 0.0.44-alpha.1
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/AnySpend.js +82 -24
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +2 -7
- package/dist/cjs/anyspend/react/components/common/OrderHistoryItem.js +1 -6
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +3 -3
- package/dist/cjs/anyspend/react/hooks/useAnyspendOrderAndTransactions.d.ts +2 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +48 -0
- package/dist/cjs/anyspend/types/api.d.ts +15 -20
- package/dist/cjs/anyspend/utils/orderPayload.js +0 -4
- package/dist/cjs/shared/react/hooks/useCurrencyConversion.d.ts +1 -1
- package/dist/cjs/shared/react/hooks/useCurrencyConversion.js +30 -12
- package/dist/esm/anyspend/react/components/AnySpend.js +82 -24
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +2 -7
- package/dist/esm/anyspend/react/components/common/OrderHistoryItem.js +1 -6
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +3 -3
- package/dist/esm/anyspend/react/hooks/useAnyspendOrderAndTransactions.d.ts +2 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +48 -0
- package/dist/esm/anyspend/types/api.d.ts +15 -20
- package/dist/esm/anyspend/utils/orderPayload.js +0 -4
- package/dist/esm/shared/react/hooks/useCurrencyConversion.d.ts +1 -1
- package/dist/esm/shared/react/hooks/useCurrencyConversion.js +30 -12
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/useAnyspendOrderAndTransactions.d.ts +2 -0
- package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +48 -0
- package/dist/types/anyspend/types/api.d.ts +15 -20
- package/dist/types/shared/react/hooks/useCurrencyConversion.d.ts +1 -1
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +93 -28
- package/src/anyspend/react/components/common/OrderDetails.tsx +3 -9
- package/src/anyspend/react/components/common/OrderHistoryItem.tsx +1 -7
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +3 -3
- package/src/anyspend/types/api.ts +15 -20
- package/src/anyspend/utils/orderPayload.ts +0 -4
- package/src/shared/react/hooks/useCurrencyConversion.ts +39 -12
|
@@ -140,6 +140,11 @@ function AnySpendInner({
|
|
|
140
140
|
// Track if onSuccess has been called for the current order
|
|
141
141
|
const onSuccessCalled = useRef(false);
|
|
142
142
|
|
|
143
|
+
// Track animation direction for TransitionPanel
|
|
144
|
+
const animationDirection = useRef<"forward" | "back" | null>(null);
|
|
145
|
+
// Track previous panel for proper back navigation
|
|
146
|
+
const previousPanel = useRef<PanelView>(PanelView.MAIN);
|
|
147
|
+
|
|
143
148
|
const [activeTab, setActiveTab] = useState<"crypto" | "fiat">(defaultActiveTab);
|
|
144
149
|
|
|
145
150
|
const [orderId, setOrderId] = useState<string | undefined>(loadOrder);
|
|
@@ -147,6 +152,23 @@ function AnySpendInner({
|
|
|
147
152
|
!!getOrderAndTransactionsError && console.log("getOrderAndTransactionsError", getOrderAndTransactionsError);
|
|
148
153
|
|
|
149
154
|
const [activePanel, setActivePanel] = useState<PanelView>(loadOrder ? PanelView.ORDER_DETAILS : PanelView.MAIN);
|
|
155
|
+
|
|
156
|
+
// Helper functions to navigate with animation direction
|
|
157
|
+
const navigateToPanel = useCallback(
|
|
158
|
+
(panel: PanelView, direction: "forward" | "back" = "forward") => {
|
|
159
|
+
previousPanel.current = activePanel;
|
|
160
|
+
animationDirection.current = direction;
|
|
161
|
+
setActivePanel(panel);
|
|
162
|
+
},
|
|
163
|
+
[activePanel],
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
const navigateBack = useCallback(() => {
|
|
167
|
+
animationDirection.current = "back";
|
|
168
|
+
// Navigate back to previous panel or default to MAIN
|
|
169
|
+
const targetPanel = previousPanel.current !== activePanel ? previousPanel.current : PanelView.MAIN;
|
|
170
|
+
setActivePanel(targetPanel);
|
|
171
|
+
}, [activePanel]);
|
|
150
172
|
const [customRecipients, setCustomRecipients] = useState<RecipientOption[]>([]);
|
|
151
173
|
// Add state for selected payment method
|
|
152
174
|
const [selectedCryptoPaymentMethod, setSelectedCryptoPaymentMethod] = useState<CryptoPaymentMethodType>(
|
|
@@ -544,7 +566,7 @@ function AnySpendInner({
|
|
|
544
566
|
const orderId = data.data.id;
|
|
545
567
|
setOrderId(orderId);
|
|
546
568
|
// setNewRecipientAddress("");
|
|
547
|
-
|
|
569
|
+
navigateToPanel(PanelView.ORDER_DETAILS, "forward");
|
|
548
570
|
|
|
549
571
|
// Debug: Check payment method before setting URL
|
|
550
572
|
console.log("Creating order - selectedCryptoPaymentMethod:", selectedCryptoPaymentMethod);
|
|
@@ -572,7 +594,7 @@ function AnySpendInner({
|
|
|
572
594
|
onSuccess: data => {
|
|
573
595
|
const orderId = data.data.id;
|
|
574
596
|
setOrderId(orderId);
|
|
575
|
-
|
|
597
|
+
navigateToPanel(PanelView.ORDER_DETAILS, "forward");
|
|
576
598
|
|
|
577
599
|
// Add orderId and payment method to URL for persistence
|
|
578
600
|
const params = new URLSearchParams(searchParams.toString());
|
|
@@ -638,7 +660,7 @@ function AnySpendInner({
|
|
|
638
660
|
if (btnInfo.disable) return;
|
|
639
661
|
|
|
640
662
|
if (!recipientAddress) {
|
|
641
|
-
|
|
663
|
+
navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward");
|
|
642
664
|
return;
|
|
643
665
|
}
|
|
644
666
|
|
|
@@ -649,7 +671,7 @@ function AnySpendInner({
|
|
|
649
671
|
if (activeTab === "fiat") {
|
|
650
672
|
// If no fiat payment method selected, show payment method selection
|
|
651
673
|
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
652
|
-
|
|
674
|
+
navigateToPanel(PanelView.FIAT_PAYMENT_METHOD, "forward");
|
|
653
675
|
return;
|
|
654
676
|
}
|
|
655
677
|
// If payment method is selected, create order directly
|
|
@@ -661,7 +683,7 @@ function AnySpendInner({
|
|
|
661
683
|
// If no payment method selected, show payment method selection
|
|
662
684
|
if (selectedCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
663
685
|
console.log("No payment method selected, showing selection panel");
|
|
664
|
-
|
|
686
|
+
navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward");
|
|
665
687
|
return;
|
|
666
688
|
}
|
|
667
689
|
|
|
@@ -684,7 +706,7 @@ function AnySpendInner({
|
|
|
684
706
|
|
|
685
707
|
const onClickHistory = () => {
|
|
686
708
|
setOrderId(undefined);
|
|
687
|
-
|
|
709
|
+
navigateToPanel(PanelView.HISTORY, "forward");
|
|
688
710
|
// Remove orderId and paymentMethod from URL when going back to history
|
|
689
711
|
const params = new URLSearchParams(searchParams.toString());
|
|
690
712
|
params.delete("orderId");
|
|
@@ -807,8 +829,8 @@ function AnySpendInner({
|
|
|
807
829
|
}, [searchParams, loadOrder]);
|
|
808
830
|
|
|
809
831
|
const onSelectOrder = (selectedOrderId: string) => {
|
|
810
|
-
setActivePanel(PanelView.MAIN);
|
|
811
832
|
setOrderId(selectedOrderId);
|
|
833
|
+
navigateToPanel(PanelView.ORDER_DETAILS, "forward");
|
|
812
834
|
// Update URL with the new orderId and preserve existing parameters
|
|
813
835
|
const params = new URLSearchParams(searchParams.toString());
|
|
814
836
|
params.set("orderId", selectedOrderId);
|
|
@@ -830,9 +852,40 @@ function AnySpendInner({
|
|
|
830
852
|
window.scrollTo({ top: 0, behavior: "smooth" });
|
|
831
853
|
}, [activePanel]);
|
|
832
854
|
|
|
855
|
+
// Handle browser back button for recipient selection and payment method views
|
|
856
|
+
useEffect(() => {
|
|
857
|
+
// Push a new history state when navigating to specific panels
|
|
858
|
+
if (activePanel === PanelView.RECIPIENT_SELECTION) {
|
|
859
|
+
window.history.pushState({ panel: "recipient-selection" }, "");
|
|
860
|
+
} else if (activePanel === PanelView.CRYPTO_PAYMENT_METHOD) {
|
|
861
|
+
window.history.pushState({ panel: "crypto-payment-method" }, "");
|
|
862
|
+
} else if (activePanel === PanelView.FIAT_PAYMENT_METHOD) {
|
|
863
|
+
window.history.pushState({ panel: "fiat-payment-method" }, "");
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// Listen for popstate event (browser back button)
|
|
867
|
+
const handlePopState = (event: PopStateEvent) => {
|
|
868
|
+
if (
|
|
869
|
+
activePanel === PanelView.RECIPIENT_SELECTION ||
|
|
870
|
+
activePanel === PanelView.CRYPTO_PAYMENT_METHOD ||
|
|
871
|
+
activePanel === PanelView.FIAT_PAYMENT_METHOD
|
|
872
|
+
) {
|
|
873
|
+
// User pressed back while on these panels
|
|
874
|
+
event.preventDefault();
|
|
875
|
+
navigateBack();
|
|
876
|
+
}
|
|
877
|
+
};
|
|
878
|
+
|
|
879
|
+
window.addEventListener("popstate", handlePopState);
|
|
880
|
+
|
|
881
|
+
return () => {
|
|
882
|
+
window.removeEventListener("popstate", handlePopState);
|
|
883
|
+
};
|
|
884
|
+
}, [activePanel, navigateBack]);
|
|
885
|
+
|
|
833
886
|
const historyView = (
|
|
834
887
|
<div className={"mx-auto flex w-[560px] max-w-full flex-col items-center"}>
|
|
835
|
-
<OrderHistory mode={mode} onBack={
|
|
888
|
+
<OrderHistory mode={mode} onBack={navigateBack} onSelectOrder={onSelectOrder} />
|
|
836
889
|
</div>
|
|
837
890
|
);
|
|
838
891
|
|
|
@@ -851,7 +904,7 @@ function AnySpendInner({
|
|
|
851
904
|
onPaymentMethodChange={setSelectedCryptoPaymentMethod}
|
|
852
905
|
onBack={() => {
|
|
853
906
|
setOrderId(undefined);
|
|
854
|
-
|
|
907
|
+
navigateBack();
|
|
855
908
|
setSelectedCryptoPaymentMethod(CryptoPaymentMethodType.NONE); // Reset payment method when going back
|
|
856
909
|
}}
|
|
857
910
|
/>
|
|
@@ -901,7 +954,7 @@ function AnySpendInner({
|
|
|
901
954
|
setSrcAmount={setSrcAmount}
|
|
902
955
|
setIsSrcInputDirty={setIsSrcInputDirty}
|
|
903
956
|
selectedCryptoPaymentMethod={selectedCryptoPaymentMethod}
|
|
904
|
-
onSelectCryptoPaymentMethod={() =>
|
|
957
|
+
onSelectCryptoPaymentMethod={() => navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward")}
|
|
905
958
|
anyspendQuote={anyspendQuote}
|
|
906
959
|
onTokenSelect={onTokenSelect}
|
|
907
960
|
/>
|
|
@@ -915,7 +968,15 @@ function AnySpendInner({
|
|
|
915
968
|
srcAmountOnRamp={srcAmountOnRamp}
|
|
916
969
|
setSrcAmountOnRamp={setSrcAmountOnRamp}
|
|
917
970
|
selectedPaymentMethod={selectedFiatPaymentMethod}
|
|
918
|
-
setActivePanel={
|
|
971
|
+
setActivePanel={(panelIndex: number) => {
|
|
972
|
+
// Map panel index to navigation with direction
|
|
973
|
+
const panelsWithForwardNav = [PanelView.FIAT_PAYMENT_METHOD, PanelView.RECIPIENT_SELECTION];
|
|
974
|
+
if (panelsWithForwardNav.includes(panelIndex)) {
|
|
975
|
+
navigateToPanel(panelIndex, "forward");
|
|
976
|
+
} else {
|
|
977
|
+
setActivePanel(panelIndex);
|
|
978
|
+
}
|
|
979
|
+
}}
|
|
919
980
|
_recipientAddress={recipientAddress}
|
|
920
981
|
destinationToken={selectedDstToken}
|
|
921
982
|
destinationChainId={selectedDstChainId}
|
|
@@ -926,7 +987,7 @@ function AnySpendInner({
|
|
|
926
987
|
recipientSelectionPanelIndex={PanelView.RECIPIENT_SELECTION}
|
|
927
988
|
hideDstToken={isBuyMode}
|
|
928
989
|
anyspendQuote={anyspendQuote}
|
|
929
|
-
onShowPointsDetail={() =>
|
|
990
|
+
onShowPointsDetail={() => navigateToPanel(PanelView.POINTS_DETAIL, "forward")}
|
|
930
991
|
customUsdInputValues={customUsdInputValues}
|
|
931
992
|
/>
|
|
932
993
|
</motion.div>
|
|
@@ -976,7 +1037,7 @@ function AnySpendInner({
|
|
|
976
1037
|
isBuyMode={isBuyMode}
|
|
977
1038
|
selectedRecipientAddress={recipientAddress}
|
|
978
1039
|
recipientName={recipientName || undefined}
|
|
979
|
-
onSelectRecipient={() =>
|
|
1040
|
+
onSelectRecipient={() => navigateToPanel(PanelView.RECIPIENT_SELECTION, "forward")}
|
|
980
1041
|
dstAmount={dstAmount}
|
|
981
1042
|
dstToken={selectedDstToken}
|
|
982
1043
|
selectedDstChainId={selectedDstChainId}
|
|
@@ -987,7 +1048,7 @@ function AnySpendInner({
|
|
|
987
1048
|
setDstAmount(value);
|
|
988
1049
|
}}
|
|
989
1050
|
anyspendQuote={anyspendQuote}
|
|
990
|
-
onShowPointsDetail={() =>
|
|
1051
|
+
onShowPointsDetail={() => navigateToPanel(PanelView.POINTS_DETAIL, "forward")}
|
|
991
1052
|
/>
|
|
992
1053
|
)}
|
|
993
1054
|
</div>
|
|
@@ -1042,7 +1103,7 @@ function AnySpendInner({
|
|
|
1042
1103
|
globalAddress={globalAddress}
|
|
1043
1104
|
onOrderCreated={orderId => {
|
|
1044
1105
|
setOrderId(orderId);
|
|
1045
|
-
|
|
1106
|
+
navigateToPanel(PanelView.ORDER_DETAILS, "forward");
|
|
1046
1107
|
// Add orderId and payment method to URL for persistence
|
|
1047
1108
|
const params = new URLSearchParams(searchParams.toString()); // Preserve existing params
|
|
1048
1109
|
params.set("orderId", orderId);
|
|
@@ -1054,7 +1115,7 @@ function AnySpendInner({
|
|
|
1054
1115
|
}
|
|
1055
1116
|
router.push(`${window.location.pathname}?${params.toString()}`);
|
|
1056
1117
|
}}
|
|
1057
|
-
onBack={
|
|
1118
|
+
onBack={navigateBack}
|
|
1058
1119
|
recipientEnsName={globalWallet?.ensName}
|
|
1059
1120
|
recipientImageUrl={globalWallet?.meta?.icon}
|
|
1060
1121
|
/>
|
|
@@ -1063,10 +1124,10 @@ function AnySpendInner({
|
|
|
1063
1124
|
const recipientSelectionView = (
|
|
1064
1125
|
<RecipientSelection
|
|
1065
1126
|
initialValue={recipientAddress || ""}
|
|
1066
|
-
onBack={
|
|
1127
|
+
onBack={navigateBack}
|
|
1067
1128
|
onConfirm={address => {
|
|
1068
1129
|
setRecipientAddress(address);
|
|
1069
|
-
|
|
1130
|
+
navigateBack();
|
|
1070
1131
|
}}
|
|
1071
1132
|
/>
|
|
1072
1133
|
);
|
|
@@ -1078,10 +1139,10 @@ function AnySpendInner({
|
|
|
1078
1139
|
selectedPaymentMethod={selectedCryptoPaymentMethod}
|
|
1079
1140
|
setSelectedPaymentMethod={setSelectedCryptoPaymentMethod}
|
|
1080
1141
|
isCreatingOrder={isCreatingOrder}
|
|
1081
|
-
onBack={
|
|
1142
|
+
onBack={navigateBack}
|
|
1082
1143
|
onSelectPaymentMethod={(method: CryptoPaymentMethodType) => {
|
|
1083
1144
|
setSelectedCryptoPaymentMethod(method);
|
|
1084
|
-
|
|
1145
|
+
navigateBack();
|
|
1085
1146
|
}}
|
|
1086
1147
|
/>
|
|
1087
1148
|
);
|
|
@@ -1090,20 +1151,17 @@ function AnySpendInner({
|
|
|
1090
1151
|
<FiatPaymentMethodComponent
|
|
1091
1152
|
selectedPaymentMethod={selectedFiatPaymentMethod}
|
|
1092
1153
|
setSelectedPaymentMethod={setSelectedFiatPaymentMethod}
|
|
1093
|
-
onBack={
|
|
1154
|
+
onBack={navigateBack}
|
|
1094
1155
|
onSelectPaymentMethod={(method: FiatPaymentMethod) => {
|
|
1095
1156
|
setSelectedFiatPaymentMethod(method);
|
|
1096
|
-
|
|
1157
|
+
navigateBack(); // Go back to main panel to show updated pricing
|
|
1097
1158
|
}}
|
|
1098
1159
|
srcAmountOnRamp={srcAmountOnRamp}
|
|
1099
1160
|
/>
|
|
1100
1161
|
);
|
|
1101
1162
|
|
|
1102
1163
|
const pointsDetailView = (
|
|
1103
|
-
<PointsDetailPanel
|
|
1104
|
-
pointsAmount={anyspendQuote?.data?.pointsAmount || 0}
|
|
1105
|
-
onBack={() => setActivePanel(PanelView.MAIN)}
|
|
1106
|
-
/>
|
|
1164
|
+
<PointsDetailPanel pointsAmount={anyspendQuote?.data?.pointsAmount || 0} onBack={navigateBack} />
|
|
1107
1165
|
);
|
|
1108
1166
|
|
|
1109
1167
|
// Add tabs to the main component when no order is loaded
|
|
@@ -1129,10 +1187,17 @@ function AnySpendInner({
|
|
|
1129
1187
|
className={cn("rounded-2xl", {
|
|
1130
1188
|
"mt-0": mode === "modal",
|
|
1131
1189
|
})}
|
|
1190
|
+
custom={animationDirection.current}
|
|
1132
1191
|
variants={{
|
|
1133
|
-
enter:
|
|
1192
|
+
enter: direction => ({
|
|
1193
|
+
x: direction === "back" ? -300 : 300,
|
|
1194
|
+
opacity: 0,
|
|
1195
|
+
}),
|
|
1134
1196
|
center: { x: 0, opacity: 1 },
|
|
1135
|
-
exit:
|
|
1197
|
+
exit: direction => ({
|
|
1198
|
+
x: direction === "back" ? 300 : -300,
|
|
1199
|
+
opacity: 0,
|
|
1200
|
+
}),
|
|
1136
1201
|
}}
|
|
1137
1202
|
transition={{ type: "spring", stiffness: 300, damping: 30 }}
|
|
1138
1203
|
>
|
|
@@ -391,13 +391,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
391
391
|
: order.payload.expectedDstAmount.toString();
|
|
392
392
|
const formattedExpectedDstAmount = formatTokenAmount(BigInt(expectedDstAmount), dstToken.decimals);
|
|
393
393
|
|
|
394
|
-
const actualDstAmount =
|
|
395
|
-
order.type === "mint_nft" ||
|
|
396
|
-
order.type === "join_tournament" ||
|
|
397
|
-
order.type === "fund_tournament" ||
|
|
398
|
-
order.type === "custom"
|
|
399
|
-
? undefined
|
|
400
|
-
: order.payload.actualDstAmount;
|
|
394
|
+
const actualDstAmount = order.settlement?.actualDstAmount;
|
|
401
395
|
const formattedActualDstAmount = actualDstAmount
|
|
402
396
|
? formatTokenAmount(BigInt(actualDstAmount), dstToken.decimals)
|
|
403
397
|
: undefined;
|
|
@@ -987,8 +981,8 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
987
981
|
</AccordionItem>
|
|
988
982
|
</Accordion>
|
|
989
983
|
|
|
990
|
-
{/* Show payment UI
|
|
991
|
-
{!depositEnoughAmount && order.status
|
|
984
|
+
{/* Show payment UI for insufficient deposit while scanning for transaction */}
|
|
985
|
+
{depositTxs?.length > 0 && !depositEnoughAmount && order.status === "scanning_deposit_transaction" && (
|
|
992
986
|
<InsufficientDepositPayment
|
|
993
987
|
order={order}
|
|
994
988
|
srcToken={srcToken}
|
|
@@ -18,13 +18,7 @@ export function OrderHistoryItem({ order, onSelectOrder, mode }: OrderHistoryIte
|
|
|
18
18
|
const tournament =
|
|
19
19
|
order.type === "join_tournament" || order.type === "fund_tournament" ? order.metadata.tournament : undefined;
|
|
20
20
|
const dstToken = order.metadata.dstToken;
|
|
21
|
-
const actualDstAmount =
|
|
22
|
-
order.type === "mint_nft" ||
|
|
23
|
-
order.type === "join_tournament" ||
|
|
24
|
-
order.type === "fund_tournament" ||
|
|
25
|
-
order.type === "custom"
|
|
26
|
-
? undefined
|
|
27
|
-
: order.payload.actualDstAmount;
|
|
21
|
+
const actualDstAmount = order.settlement?.actualDstAmount;
|
|
28
22
|
const expectedDstAmount =
|
|
29
23
|
order.type === "mint_nft" ||
|
|
30
24
|
order.type === "join_tournament" ||
|
|
@@ -247,8 +247,8 @@ export function useAnyspendFlow({
|
|
|
247
247
|
// Handle order completion
|
|
248
248
|
useEffect(() => {
|
|
249
249
|
if (oat?.data?.order.status === "executed") {
|
|
250
|
-
// get the actualDstAmount if available from
|
|
251
|
-
const amount =
|
|
250
|
+
// get the actualDstAmount if available from settlement
|
|
251
|
+
const amount = oat.data.order.settlement?.actualDstAmount;
|
|
252
252
|
const formattedActualDstAmount = amount
|
|
253
253
|
? formatTokenAmount(BigInt(amount), oat.data.order.metadata.dstToken.decimals)
|
|
254
254
|
: undefined;
|
|
@@ -256,7 +256,7 @@ export function useAnyspendFlow({
|
|
|
256
256
|
}
|
|
257
257
|
}, [
|
|
258
258
|
oat?.data?.order.status,
|
|
259
|
-
oat?.data?.order.
|
|
259
|
+
oat?.data?.order.settlement?.actualDstAmount,
|
|
260
260
|
onTransactionSuccess,
|
|
261
261
|
oat?.data?.order.metadata.dstToken.decimals,
|
|
262
262
|
]);
|
|
@@ -435,6 +435,11 @@ export interface paths {
|
|
|
435
435
|
executeTx: components["schemas"]["ExecuteTx"] | null;
|
|
436
436
|
/** @description Refund transactions if order failed */
|
|
437
437
|
refundTxs: components["schemas"]["RefundTx"][];
|
|
438
|
+
/**
|
|
439
|
+
* @description Points awarded for this order (only present when order status is executed)
|
|
440
|
+
* @example 100
|
|
441
|
+
*/
|
|
442
|
+
points: number | null;
|
|
438
443
|
};
|
|
439
444
|
/** @example 200 */
|
|
440
445
|
statusCode: number;
|
|
@@ -1119,16 +1124,6 @@ export interface components {
|
|
|
1119
1124
|
* @example 990000
|
|
1120
1125
|
*/
|
|
1121
1126
|
expectedDstAmount: string;
|
|
1122
|
-
/**
|
|
1123
|
-
* @description Actual received amount (null for new orders)
|
|
1124
|
-
* @example 990000
|
|
1125
|
-
*/
|
|
1126
|
-
actualDstAmount: string | null;
|
|
1127
|
-
/**
|
|
1128
|
-
* @description Amount in after fee
|
|
1129
|
-
* @example 990000
|
|
1130
|
-
*/
|
|
1131
|
-
amountInAfterFee: string | null;
|
|
1132
1127
|
};
|
|
1133
1128
|
/** @description HypeDuel-specific payload */
|
|
1134
1129
|
HypeDuelPayload: {
|
|
@@ -1137,16 +1132,6 @@ export interface components {
|
|
|
1137
1132
|
* @example 990000
|
|
1138
1133
|
*/
|
|
1139
1134
|
expectedDstAmount: string;
|
|
1140
|
-
/**
|
|
1141
|
-
* @description Actual received amount (null for new orders)
|
|
1142
|
-
* @example 990000
|
|
1143
|
-
*/
|
|
1144
|
-
actualDstAmount: string | null;
|
|
1145
|
-
/**
|
|
1146
|
-
* @description Amount in after fee
|
|
1147
|
-
* @example 990000
|
|
1148
|
-
*/
|
|
1149
|
-
amountInAfterFee: string | null;
|
|
1150
1135
|
};
|
|
1151
1136
|
/** @description Custom execution payload */
|
|
1152
1137
|
CustomPayload: {
|
|
@@ -1324,6 +1309,8 @@ export interface components {
|
|
|
1324
1309
|
* @example 1752506694679
|
|
1325
1310
|
*/
|
|
1326
1311
|
expiredAt: number;
|
|
1312
|
+
/** @description Timestamp when the order was filled/executed */
|
|
1313
|
+
filledAt: number | null;
|
|
1327
1314
|
/**
|
|
1328
1315
|
* @description Optional creator address
|
|
1329
1316
|
* @example 0xb34facb90a200251318e8841c05102366f2158cf
|
|
@@ -1340,6 +1327,14 @@ export interface components {
|
|
|
1340
1327
|
* @example pi_3Rko0sJnoDg53PsP0PDLsHkR
|
|
1341
1328
|
*/
|
|
1342
1329
|
stripePaymentIntentId: string | null;
|
|
1330
|
+
/** @description Settlement information for executed orders */
|
|
1331
|
+
settlement: {
|
|
1332
|
+
/**
|
|
1333
|
+
* @description Actual received amount after execution
|
|
1334
|
+
* @example 990000
|
|
1335
|
+
*/
|
|
1336
|
+
actualDstAmount: string | null;
|
|
1337
|
+
} | null;
|
|
1343
1338
|
};
|
|
1344
1339
|
SwapOrder: components["schemas"]["BaseOrder"] & {
|
|
1345
1340
|
/**
|
|
@@ -17,8 +17,6 @@ export const buildPayload = (orderType: components["schemas"]["Order"]["type"],
|
|
|
17
17
|
case "swap":
|
|
18
18
|
return {
|
|
19
19
|
expectedDstAmount,
|
|
20
|
-
actualDstAmount: null,
|
|
21
|
-
amountInAfterFee: null,
|
|
22
20
|
};
|
|
23
21
|
case "mint_nft":
|
|
24
22
|
if (nft?.type === "erc1155") {
|
|
@@ -53,8 +51,6 @@ export const buildPayload = (orderType: components["schemas"]["Order"]["type"],
|
|
|
53
51
|
case "hype_duel":
|
|
54
52
|
return {
|
|
55
53
|
expectedDstAmount,
|
|
56
|
-
actualDstAmount: null,
|
|
57
|
-
amountInAfterFee: null,
|
|
58
54
|
};
|
|
59
55
|
default:
|
|
60
56
|
throw new Error(`Invalid order type: ${orderType}`);
|
|
@@ -1,7 +1,33 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useQuery } from "@tanstack/react-query";
|
|
2
2
|
import { formatDisplayNumber } from "@b3dotfun/sdk/shared/utils/number";
|
|
3
3
|
import { CURRENCY_SYMBOLS, useCurrencyStore } from "../stores/currencyStore";
|
|
4
4
|
|
|
5
|
+
const COINBASE_API_URL = "https://api.coinbase.com/v2/exchange-rates";
|
|
6
|
+
const REFETCH_INTERVAL_MS = 30000;
|
|
7
|
+
|
|
8
|
+
interface CoinbaseExchangeRatesResponse {
|
|
9
|
+
data: {
|
|
10
|
+
currency: string;
|
|
11
|
+
rates: Record<string, string>;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Fetches all exchange rates for a given base currency from Coinbase API.
|
|
17
|
+
*/
|
|
18
|
+
async function fetchAllExchangeRates(baseCurrency: string): Promise<Record<string, number>> {
|
|
19
|
+
const response = await fetch(`${COINBASE_API_URL}?currency=${baseCurrency}`);
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
throw new Error(`Failed to fetch exchange rates for ${baseCurrency}: ${response.status}`);
|
|
22
|
+
}
|
|
23
|
+
const data: CoinbaseExchangeRatesResponse = await response.json();
|
|
24
|
+
const rates: Record<string, number> = {};
|
|
25
|
+
for (const [currency, rate] of Object.entries(data.data.rates)) {
|
|
26
|
+
rates[currency] = parseFloat(rate);
|
|
27
|
+
}
|
|
28
|
+
return rates;
|
|
29
|
+
}
|
|
30
|
+
|
|
5
31
|
/**
|
|
6
32
|
* Hook for currency conversion and formatting with real-time exchange rates.
|
|
7
33
|
*
|
|
@@ -22,17 +48,19 @@ export function useCurrencyConversion() {
|
|
|
22
48
|
const selectedCurrency = useCurrencyStore(state => state.selectedCurrency);
|
|
23
49
|
const baseCurrency = useCurrencyStore(state => state.baseCurrency);
|
|
24
50
|
|
|
25
|
-
//
|
|
26
|
-
const {
|
|
27
|
-
baseCurrency,
|
|
28
|
-
|
|
51
|
+
// Fetch all exchange rates for the base currency
|
|
52
|
+
const { data: exchangeRates } = useQuery({
|
|
53
|
+
queryKey: ["exchangeRates", baseCurrency],
|
|
54
|
+
queryFn: () => fetchAllExchangeRates(baseCurrency),
|
|
55
|
+
refetchInterval: REFETCH_INTERVAL_MS,
|
|
56
|
+
staleTime: REFETCH_INTERVAL_MS / 2,
|
|
57
|
+
retry: 3,
|
|
58
|
+
retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, REFETCH_INTERVAL_MS),
|
|
29
59
|
});
|
|
30
60
|
|
|
31
|
-
//
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
quoteCurrency: "USD",
|
|
35
|
-
});
|
|
61
|
+
// Extract specific rates from the full rates object
|
|
62
|
+
const exchangeRate = exchangeRates?.[selectedCurrency];
|
|
63
|
+
const usdRate = exchangeRates?.["USD"];
|
|
36
64
|
|
|
37
65
|
/**
|
|
38
66
|
* Formats a numeric value as a currency string with proper conversion and formatting.
|
|
@@ -83,8 +111,7 @@ export function useCurrencyConversion() {
|
|
|
83
111
|
return `${formatted} ${baseCurrency}`;
|
|
84
112
|
}
|
|
85
113
|
|
|
86
|
-
// If
|
|
87
|
-
// incorrect values with wrong currency symbols during rate fetching
|
|
114
|
+
// If showing base currency, no conversion needed
|
|
88
115
|
if (selectedCurrency === baseCurrency || !exchangeRate) {
|
|
89
116
|
const formatted = formatDisplayNumber(value, {
|
|
90
117
|
significantDigits: baseCurrency === "B3" ? 6 : 8,
|