@b3dotfun/sdk 0.0.65-alpha.0 → 0.0.65-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/anyspend/react/components/AnySpend.js +38 -24
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +22 -9
- package/dist/cjs/anyspend/react/components/AnySpendCustomExactIn.js +7 -7
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +5 -5
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +2 -10
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +5 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +16 -10
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +7 -5
- package/dist/cjs/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +13 -9
- package/dist/cjs/anyspend/react/hooks/useCryptoPaymentMethodState.d.ts +42 -0
- package/dist/cjs/anyspend/react/hooks/useCryptoPaymentMethodState.js +51 -0
- package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +6 -14
- package/dist/esm/anyspend/react/components/AnySpend.js +38 -24
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +22 -9
- package/dist/esm/anyspend/react/components/AnySpendCustomExactIn.js +7 -7
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +5 -5
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +2 -10
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +5 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +16 -10
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +7 -5
- package/dist/esm/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.js +13 -9
- package/dist/esm/anyspend/react/hooks/useCryptoPaymentMethodState.d.ts +42 -0
- package/dist/esm/anyspend/react/hooks/useCryptoPaymentMethodState.js +48 -0
- package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +6 -14
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +5 -1
- package/dist/types/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.d.ts +7 -5
- package/dist/types/anyspend/react/hooks/useCryptoPaymentMethodState.d.ts +42 -0
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +50 -29
- package/src/anyspend/react/components/AnySpendCustom.tsx +28 -15
- package/src/anyspend/react/components/AnySpendCustomExactIn.tsx +8 -7
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +5 -4
- package/src/anyspend/react/components/common/OrderTokenAmount.tsx +2 -13
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +24 -12
- package/src/anyspend/react/hooks/useAutoSelectCryptoPaymentMethod.ts +20 -12
- package/src/anyspend/react/hooks/useCryptoPaymentMethodState.ts +71 -0
- package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +6 -12
|
@@ -33,6 +33,7 @@ import { base, mainnet } from "viem/chains";
|
|
|
33
33
|
import { components } from "../../types/api";
|
|
34
34
|
import { useAutoSelectCryptoPaymentMethod } from "../hooks/useAutoSelectCryptoPaymentMethod";
|
|
35
35
|
import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi";
|
|
36
|
+
import { useCryptoPaymentMethodState } from "../hooks/useCryptoPaymentMethodState";
|
|
36
37
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
|
|
37
38
|
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
|
|
38
39
|
import { CryptoPaySection } from "./common/CryptoPaySection";
|
|
@@ -174,11 +175,17 @@ function AnySpendInner({
|
|
|
174
175
|
setActivePanel(targetPanel);
|
|
175
176
|
}, [activePanel]);
|
|
176
177
|
const [customRecipients, setCustomRecipients] = useState<RecipientOption[]>([]);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
178
|
+
|
|
179
|
+
// Payment method state with dual-state system (auto + explicit user selection)
|
|
180
|
+
const {
|
|
181
|
+
cryptoPaymentMethod,
|
|
182
|
+
setCryptoPaymentMethod,
|
|
183
|
+
selectedCryptoPaymentMethod,
|
|
184
|
+
setSelectedCryptoPaymentMethod,
|
|
185
|
+
effectiveCryptoPaymentMethod,
|
|
186
|
+
resetPaymentMethods,
|
|
187
|
+
} = useCryptoPaymentMethodState();
|
|
188
|
+
|
|
182
189
|
const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState<FiatPaymentMethod>(FiatPaymentMethod.NONE);
|
|
183
190
|
// const [newRecipientAddress, setNewRecipientAddress] = useState("");
|
|
184
191
|
// const recipientInputRef = useRef<HTMLInputElement>(null);
|
|
@@ -197,7 +204,7 @@ function AnySpendInner({
|
|
|
197
204
|
});
|
|
198
205
|
const [selectedSrcToken, setSelectedSrcToken] = useState<components["schemas"]["Token"]>(srcTokenFromUrl);
|
|
199
206
|
const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
|
|
200
|
-
const [srcAmount, setSrcAmount] = useState<string>(searchParams.get("fromAmount") || "0
|
|
207
|
+
const [srcAmount, setSrcAmount] = useState<string>(searchParams.get("fromAmount") || "0");
|
|
201
208
|
|
|
202
209
|
// State for onramp amount
|
|
203
210
|
const [srcAmountOnRamp, setSrcAmountOnRamp] = useState<string>(searchParams.get("fromAmount") || "5");
|
|
@@ -467,8 +474,9 @@ function AnySpendInner({
|
|
|
467
474
|
// Auto-select crypto payment method based on available wallets and balance
|
|
468
475
|
useAutoSelectCryptoPaymentMethod({
|
|
469
476
|
paymentType: activeTab,
|
|
477
|
+
cryptoPaymentMethod,
|
|
478
|
+
setCryptoPaymentMethod,
|
|
470
479
|
selectedCryptoPaymentMethod,
|
|
471
|
-
setSelectedCryptoPaymentMethod,
|
|
472
480
|
hasEnoughBalance,
|
|
473
481
|
isBalanceLoading,
|
|
474
482
|
});
|
|
@@ -602,9 +610,9 @@ function AnySpendInner({
|
|
|
602
610
|
// Add orderId and payment method to URL for persistence
|
|
603
611
|
const params = new URLSearchParams(searchParams.toString()); // Preserve existing params
|
|
604
612
|
params.set("orderId", orderId);
|
|
605
|
-
if (
|
|
606
|
-
console.log("Setting cryptoPaymentMethod in URL:",
|
|
607
|
-
params.set("cryptoPaymentMethod",
|
|
613
|
+
if (effectiveCryptoPaymentMethod !== CryptoPaymentMethodType.NONE) {
|
|
614
|
+
console.log("Setting cryptoPaymentMethod in URL:", effectiveCryptoPaymentMethod);
|
|
615
|
+
params.set("cryptoPaymentMethod", effectiveCryptoPaymentMethod);
|
|
608
616
|
} else {
|
|
609
617
|
console.log("Payment method is NONE, not setting in URL");
|
|
610
618
|
}
|
|
@@ -672,7 +680,7 @@ function AnySpendInner({
|
|
|
672
680
|
// For crypto: check payment method first, then recipient
|
|
673
681
|
|
|
674
682
|
// If no payment method selected, show "Choose payment method"
|
|
675
|
-
if (
|
|
683
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
676
684
|
return { text: "Choose payment method", disable: false, error: false, loading: false };
|
|
677
685
|
}
|
|
678
686
|
|
|
@@ -681,12 +689,12 @@ function AnySpendInner({
|
|
|
681
689
|
|
|
682
690
|
// If payment method selected, show appropriate action
|
|
683
691
|
if (
|
|
684
|
-
|
|
685
|
-
|
|
692
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
693
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
|
|
686
694
|
) {
|
|
687
695
|
return { text: "Swap", disable: false, error: false, loading: false };
|
|
688
696
|
}
|
|
689
|
-
if (
|
|
697
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO) {
|
|
690
698
|
return { text: "Continue to payment", disable: false, error: false, loading: false };
|
|
691
699
|
}
|
|
692
700
|
}
|
|
@@ -701,7 +709,7 @@ function AnySpendInner({
|
|
|
701
709
|
isCreatingOnrampOrder,
|
|
702
710
|
anyspendQuote,
|
|
703
711
|
activeTab,
|
|
704
|
-
|
|
712
|
+
effectiveCryptoPaymentMethod,
|
|
705
713
|
selectedFiatPaymentMethod,
|
|
706
714
|
]);
|
|
707
715
|
|
|
@@ -735,7 +743,7 @@ function AnySpendInner({
|
|
|
735
743
|
// For crypto: check payment method first, then recipient
|
|
736
744
|
|
|
737
745
|
// If no payment method selected, show payment method selection
|
|
738
|
-
if (
|
|
746
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
739
747
|
console.log("No payment method selected, showing selection panel");
|
|
740
748
|
navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward");
|
|
741
749
|
return;
|
|
@@ -751,12 +759,12 @@ function AnySpendInner({
|
|
|
751
759
|
|
|
752
760
|
// If payment method is selected, create order with payment method info
|
|
753
761
|
if (
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
762
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
763
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ||
|
|
764
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO
|
|
757
765
|
) {
|
|
758
|
-
console.log("Creating crypto order with payment method:",
|
|
759
|
-
await handleCryptoSwap(
|
|
766
|
+
console.log("Creating crypto order with payment method:", effectiveCryptoPaymentMethod);
|
|
767
|
+
await handleCryptoSwap(effectiveCryptoPaymentMethod);
|
|
760
768
|
return;
|
|
761
769
|
}
|
|
762
770
|
}
|
|
@@ -962,13 +970,17 @@ function AnySpendInner({
|
|
|
962
970
|
relayTxs={oat.data.relayTxs}
|
|
963
971
|
executeTx={oat.data.executeTx}
|
|
964
972
|
refundTxs={oat.data.refundTxs}
|
|
965
|
-
selectedCryptoPaymentMethod={
|
|
966
|
-
onPaymentMethodChange={
|
|
973
|
+
selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod}
|
|
974
|
+
onPaymentMethodChange={method => {
|
|
975
|
+
// When user explicitly changes payment method, set it as selected
|
|
976
|
+
setSelectedCryptoPaymentMethod(method);
|
|
977
|
+
}}
|
|
967
978
|
points={oat.data.points || undefined}
|
|
968
979
|
onBack={() => {
|
|
969
980
|
setOrderId(undefined);
|
|
970
981
|
navigateBack();
|
|
971
|
-
|
|
982
|
+
// Reset payment methods when going back
|
|
983
|
+
resetPaymentMethods();
|
|
972
984
|
}}
|
|
973
985
|
/>
|
|
974
986
|
)}
|
|
@@ -1000,7 +1012,12 @@ function AnySpendInner({
|
|
|
1000
1012
|
{/* Tab section */}
|
|
1001
1013
|
<TabSection
|
|
1002
1014
|
activeTab={activeTab}
|
|
1003
|
-
setActiveTab={
|
|
1015
|
+
setActiveTab={tab => {
|
|
1016
|
+
setActiveTab(tab);
|
|
1017
|
+
// Reset payment methods when switching tabs
|
|
1018
|
+
resetPaymentMethods();
|
|
1019
|
+
setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE);
|
|
1020
|
+
}}
|
|
1004
1021
|
setSelectedCryptoPaymentMethod={setSelectedCryptoPaymentMethod}
|
|
1005
1022
|
setSelectedFiatPaymentMethod={setSelectedFiatPaymentMethod}
|
|
1006
1023
|
/>
|
|
@@ -1017,7 +1034,7 @@ function AnySpendInner({
|
|
|
1017
1034
|
setSrcAmount={setSrcAmount}
|
|
1018
1035
|
isSrcInputDirty={isSrcInputDirty}
|
|
1019
1036
|
setIsSrcInputDirty={setIsSrcInputDirty}
|
|
1020
|
-
selectedCryptoPaymentMethod={
|
|
1037
|
+
selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod}
|
|
1021
1038
|
onSelectCryptoPaymentMethod={() => navigateToPanel(PanelView.CRYPTO_PAYMENT_METHOD, "forward")}
|
|
1022
1039
|
anyspendQuote={anyspendQuote}
|
|
1023
1040
|
onTokenSelect={onTokenSelect}
|
|
@@ -1120,7 +1137,7 @@ function AnySpendInner({
|
|
|
1120
1137
|
anyspendQuote={anyspendQuote}
|
|
1121
1138
|
onShowPointsDetail={() => navigateToPanel(PanelView.POINTS_DETAIL, "forward")}
|
|
1122
1139
|
onShowFeeDetail={() => navigateToPanel(PanelView.FEE_DETAIL, "forward")}
|
|
1123
|
-
selectedCryptoPaymentMethod={
|
|
1140
|
+
selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod}
|
|
1124
1141
|
/>
|
|
1125
1142
|
)}
|
|
1126
1143
|
</div>
|
|
@@ -1209,11 +1226,15 @@ function AnySpendInner({
|
|
|
1209
1226
|
<CryptoPaymentMethod
|
|
1210
1227
|
globalAddress={globalAddress}
|
|
1211
1228
|
globalWallet={globalWallet}
|
|
1212
|
-
selectedPaymentMethod={
|
|
1213
|
-
setSelectedPaymentMethod={
|
|
1229
|
+
selectedPaymentMethod={effectiveCryptoPaymentMethod}
|
|
1230
|
+
setSelectedPaymentMethod={method => {
|
|
1231
|
+
// When user explicitly selects a payment method, save it
|
|
1232
|
+
setSelectedCryptoPaymentMethod(method);
|
|
1233
|
+
}}
|
|
1214
1234
|
isCreatingOrder={isCreatingOrder}
|
|
1215
1235
|
onBack={navigateBack}
|
|
1216
1236
|
onSelectPaymentMethod={(method: CryptoPaymentMethodType) => {
|
|
1237
|
+
// When user explicitly selects a payment method, save it and go back
|
|
1217
1238
|
setSelectedCryptoPaymentMethod(method);
|
|
1218
1239
|
navigateBack();
|
|
1219
1240
|
}}
|
|
@@ -45,6 +45,7 @@ import { toast } from "sonner";
|
|
|
45
45
|
import { base } from "viem/chains";
|
|
46
46
|
import { useFeatureFlags } from "../contexts/FeatureFlagsContext";
|
|
47
47
|
import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi";
|
|
48
|
+
import { useCryptoPaymentMethodState } from "../hooks/useCryptoPaymentMethodState";
|
|
48
49
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
|
|
49
50
|
import { CryptoPaymentMethod, CryptoPaymentMethodType } from "./common/CryptoPaymentMethod";
|
|
50
51
|
import { FeeBreakDown } from "./common/FeeBreakDown";
|
|
@@ -250,10 +251,11 @@ function AnySpendCustomInner({
|
|
|
250
251
|
);
|
|
251
252
|
const [activeTab, setActiveTab] = useState<"crypto" | "fiat">(activeTabProps);
|
|
252
253
|
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
254
|
+
// Payment method state with dual-state system (auto + explicit user selection)
|
|
255
|
+
// Note: AnySpendCustom doesn't use auto-selection, only explicit user selection
|
|
256
|
+
const { setSelectedCryptoPaymentMethod, effectiveCryptoPaymentMethod, resetPaymentMethods } =
|
|
257
|
+
useCryptoPaymentMethodState();
|
|
258
|
+
|
|
257
259
|
const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState<FiatPaymentMethod>(FiatPaymentMethod.NONE);
|
|
258
260
|
|
|
259
261
|
// Get current user's wallet
|
|
@@ -550,7 +552,7 @@ function AnySpendCustomInner({
|
|
|
550
552
|
}
|
|
551
553
|
|
|
552
554
|
// Check payment method selection for crypto tab
|
|
553
|
-
if (activeTab === "crypto" &&
|
|
555
|
+
if (activeTab === "crypto" && effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
554
556
|
setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD);
|
|
555
557
|
return;
|
|
556
558
|
}
|
|
@@ -693,12 +695,17 @@ function AnySpendCustomInner({
|
|
|
693
695
|
relayTxs={oat.data.relayTxs}
|
|
694
696
|
executeTx={oat.data.executeTx}
|
|
695
697
|
refundTxs={oat.data.refundTxs}
|
|
696
|
-
cryptoPaymentMethod={activeTab === "fiat" ? CryptoPaymentMethodType.NONE :
|
|
697
|
-
selectedCryptoPaymentMethod={
|
|
698
|
-
onPaymentMethodChange={
|
|
698
|
+
cryptoPaymentMethod={activeTab === "fiat" ? CryptoPaymentMethodType.NONE : effectiveCryptoPaymentMethod}
|
|
699
|
+
selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod}
|
|
700
|
+
onPaymentMethodChange={method => {
|
|
701
|
+
// When user explicitly changes payment method, set it as selected
|
|
702
|
+
setSelectedCryptoPaymentMethod(method);
|
|
703
|
+
}}
|
|
699
704
|
onBack={() => {
|
|
700
705
|
setOrderId(undefined);
|
|
701
706
|
setActivePanel(PanelView.CONFIRM_ORDER);
|
|
707
|
+
// Reset payment methods when going back
|
|
708
|
+
resetPaymentMethods();
|
|
702
709
|
// Remove orderId from URL when canceling
|
|
703
710
|
const params = new URLSearchParams(searchParams.toString());
|
|
704
711
|
params.delete("orderId");
|
|
@@ -832,7 +839,8 @@ function AnySpendCustomInner({
|
|
|
832
839
|
)}
|
|
833
840
|
onClick={() => {
|
|
834
841
|
setActiveTab("crypto");
|
|
835
|
-
|
|
842
|
+
// Reset payment methods when switching tabs
|
|
843
|
+
resetPaymentMethods();
|
|
836
844
|
setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE);
|
|
837
845
|
}}
|
|
838
846
|
>
|
|
@@ -846,7 +854,8 @@ function AnySpendCustomInner({
|
|
|
846
854
|
)}
|
|
847
855
|
onClick={() => {
|
|
848
856
|
setActiveTab("fiat");
|
|
849
|
-
|
|
857
|
+
// Reset payment methods when switching tabs
|
|
858
|
+
resetPaymentMethods();
|
|
850
859
|
setSelectedFiatPaymentMethod(FiatPaymentMethod.NONE);
|
|
851
860
|
}}
|
|
852
861
|
>
|
|
@@ -902,7 +911,7 @@ function AnySpendCustomInner({
|
|
|
902
911
|
className="text-as-tertiarry flex h-7 items-center gap-2 text-sm transition-colors hover:text-blue-700"
|
|
903
912
|
onClick={() => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD)}
|
|
904
913
|
>
|
|
905
|
-
{
|
|
914
|
+
{effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ? (
|
|
906
915
|
<>
|
|
907
916
|
{connectedAddress ? (
|
|
908
917
|
<>
|
|
@@ -915,7 +924,7 @@ function AnySpendCustomInner({
|
|
|
915
924
|
)}
|
|
916
925
|
<ChevronRight className="h-4 w-4" />
|
|
917
926
|
</>
|
|
918
|
-
) :
|
|
927
|
+
) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
|
|
919
928
|
<>
|
|
920
929
|
Transfer crypto
|
|
921
930
|
<ChevronRight className="h-4 w-4" />
|
|
@@ -1043,7 +1052,7 @@ function AnySpendCustomInner({
|
|
|
1043
1052
|
</div>
|
|
1044
1053
|
) : !recipientAddress ? (
|
|
1045
1054
|
"Select recipient"
|
|
1046
|
-
) :
|
|
1055
|
+
) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE ? (
|
|
1047
1056
|
"Choose payment method"
|
|
1048
1057
|
) : anyspendQuote ? (
|
|
1049
1058
|
<>
|
|
@@ -1239,11 +1248,15 @@ function AnySpendCustomInner({
|
|
|
1239
1248
|
<CryptoPaymentMethod
|
|
1240
1249
|
globalAddress={currentWallet?.wallet?.address}
|
|
1241
1250
|
globalWallet={currentWallet?.wallet}
|
|
1242
|
-
selectedPaymentMethod={
|
|
1243
|
-
setSelectedPaymentMethod={
|
|
1251
|
+
selectedPaymentMethod={effectiveCryptoPaymentMethod}
|
|
1252
|
+
setSelectedPaymentMethod={method => {
|
|
1253
|
+
// When user explicitly selects a payment method, save it
|
|
1254
|
+
setSelectedCryptoPaymentMethod(method);
|
|
1255
|
+
}}
|
|
1244
1256
|
isCreatingOrder={isCreatingOrder}
|
|
1245
1257
|
onBack={() => setActivePanel(PanelView.CONFIRM_ORDER)}
|
|
1246
1258
|
onSelectPaymentMethod={(method: CryptoPaymentMethodType) => {
|
|
1259
|
+
// When user explicitly selects a payment method, save it and go back
|
|
1247
1260
|
setSelectedCryptoPaymentMethod(method);
|
|
1248
1261
|
setActivePanel(PanelView.CONFIRM_ORDER);
|
|
1249
1262
|
}}
|
|
@@ -108,6 +108,7 @@ function AnySpendCustomExactInInner({
|
|
|
108
108
|
isSrcInputDirty,
|
|
109
109
|
setIsSrcInputDirty,
|
|
110
110
|
selectedCryptoPaymentMethod,
|
|
111
|
+
effectiveCryptoPaymentMethod,
|
|
111
112
|
setSelectedCryptoPaymentMethod,
|
|
112
113
|
selectedFiatPaymentMethod,
|
|
113
114
|
setSelectedFiatPaymentMethod,
|
|
@@ -184,13 +185,13 @@ function AnySpendCustomExactInInner({
|
|
|
184
185
|
return { text: "Get quote error", disable: true, error: true, loading: false };
|
|
185
186
|
|
|
186
187
|
if (paymentType === "crypto") {
|
|
187
|
-
if (
|
|
188
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
188
189
|
return { text: "Choose payment method", disable: false, error: false, loading: false };
|
|
189
190
|
}
|
|
190
191
|
if (
|
|
191
192
|
!hasEnoughBalance &&
|
|
192
193
|
!isBalanceLoading &&
|
|
193
|
-
|
|
194
|
+
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
194
195
|
) {
|
|
195
196
|
return { text: "Insufficient balance", disable: true, error: true, loading: false };
|
|
196
197
|
}
|
|
@@ -213,7 +214,7 @@ function AnySpendCustomExactInInner({
|
|
|
213
214
|
selectedRecipientOrDefault,
|
|
214
215
|
anyspendQuote,
|
|
215
216
|
paymentType,
|
|
216
|
-
|
|
217
|
+
effectiveCryptoPaymentMethod,
|
|
217
218
|
selectedFiatPaymentMethod,
|
|
218
219
|
hasEnoughBalance,
|
|
219
220
|
isBalanceLoading,
|
|
@@ -229,7 +230,7 @@ function AnySpendCustomExactInInner({
|
|
|
229
230
|
}
|
|
230
231
|
|
|
231
232
|
if (paymentType === "crypto") {
|
|
232
|
-
if (
|
|
233
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
233
234
|
setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD);
|
|
234
235
|
return;
|
|
235
236
|
}
|
|
@@ -270,7 +271,7 @@ function AnySpendCustomExactInInner({
|
|
|
270
271
|
setSrcAmount={setSrcAmount}
|
|
271
272
|
isSrcInputDirty={isSrcInputDirty}
|
|
272
273
|
setIsSrcInputDirty={setIsSrcInputDirty}
|
|
273
|
-
selectedCryptoPaymentMethod={
|
|
274
|
+
selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod}
|
|
274
275
|
onSelectCryptoPaymentMethod={() => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD)}
|
|
275
276
|
anyspendQuote={anyspendQuote}
|
|
276
277
|
onTokenSelect={onTokenSelect}
|
|
@@ -465,8 +466,8 @@ function AnySpendCustomExactInInner({
|
|
|
465
466
|
relayTxs={oat.data.relayTxs}
|
|
466
467
|
executeTx={oat.data.executeTx}
|
|
467
468
|
refundTxs={oat.data.refundTxs}
|
|
468
|
-
cryptoPaymentMethod={paymentType === "fiat" ? CryptoPaymentMethodType.NONE :
|
|
469
|
-
selectedCryptoPaymentMethod={
|
|
469
|
+
cryptoPaymentMethod={paymentType === "fiat" ? CryptoPaymentMethodType.NONE : effectiveCryptoPaymentMethod}
|
|
470
|
+
selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod}
|
|
470
471
|
onPaymentMethodChange={setSelectedCryptoPaymentMethod}
|
|
471
472
|
onBack={() => {
|
|
472
473
|
setOrderId(undefined);
|
|
@@ -87,6 +87,7 @@ function AnySpendDepositHypeInner({
|
|
|
87
87
|
isSrcInputDirty,
|
|
88
88
|
setIsSrcInputDirty,
|
|
89
89
|
selectedCryptoPaymentMethod,
|
|
90
|
+
effectiveCryptoPaymentMethod,
|
|
90
91
|
setSelectedCryptoPaymentMethod,
|
|
91
92
|
selectedFiatPaymentMethod,
|
|
92
93
|
setSelectedFiatPaymentMethod,
|
|
@@ -153,7 +154,7 @@ function AnySpendDepositHypeInner({
|
|
|
153
154
|
}
|
|
154
155
|
|
|
155
156
|
if (paymentType === "crypto") {
|
|
156
|
-
if (
|
|
157
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
157
158
|
return { text: "Choose payment method", disable: false, error: false, loading: false };
|
|
158
159
|
}
|
|
159
160
|
return { text: "Continue to deposit", disable: false, error: false, loading: false };
|
|
@@ -169,6 +170,7 @@ function AnySpendDepositHypeInner({
|
|
|
169
170
|
return { text: "Continue to deposit", disable: false, error: false, loading: false };
|
|
170
171
|
}, [
|
|
171
172
|
activeInputAmountInWei,
|
|
173
|
+
effectiveCryptoPaymentMethod,
|
|
172
174
|
isLoadingAnyspendQuote,
|
|
173
175
|
isCreatingOrder,
|
|
174
176
|
isCreatingOnrampOrder,
|
|
@@ -176,7 +178,6 @@ function AnySpendDepositHypeInner({
|
|
|
176
178
|
anyspendQuote,
|
|
177
179
|
dstAmount,
|
|
178
180
|
paymentType,
|
|
179
|
-
selectedCryptoPaymentMethod,
|
|
180
181
|
selectedFiatPaymentMethod,
|
|
181
182
|
]);
|
|
182
183
|
|
|
@@ -189,7 +190,7 @@ function AnySpendDepositHypeInner({
|
|
|
189
190
|
}
|
|
190
191
|
|
|
191
192
|
if (paymentType === "crypto") {
|
|
192
|
-
if (
|
|
193
|
+
if (effectiveCryptoPaymentMethod === CryptoPaymentMethodType.NONE) {
|
|
193
194
|
setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD);
|
|
194
195
|
return;
|
|
195
196
|
}
|
|
@@ -227,7 +228,7 @@ function AnySpendDepositHypeInner({
|
|
|
227
228
|
setSrcAmount={setSrcAmount}
|
|
228
229
|
isSrcInputDirty={isSrcInputDirty}
|
|
229
230
|
setIsSrcInputDirty={setIsSrcInputDirty}
|
|
230
|
-
selectedCryptoPaymentMethod={
|
|
231
|
+
selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod}
|
|
231
232
|
onSelectCryptoPaymentMethod={() => setActivePanel(PanelView.CRYPTO_PAYMENT_METHOD)}
|
|
232
233
|
anyspendQuote={anyspendQuote}
|
|
233
234
|
onTokenSelect={onTokenSelect}
|
|
@@ -53,8 +53,6 @@ export function OrderTokenAmount({
|
|
|
53
53
|
}) {
|
|
54
54
|
// Track previous token to detect changes
|
|
55
55
|
const prevTokenRef = useRef<string>(token.address);
|
|
56
|
-
// Track if initial balance has been set
|
|
57
|
-
const initialBalanceSetRef = useRef(false);
|
|
58
56
|
|
|
59
57
|
// Only get token balance when context is "from" (for setting max amount)
|
|
60
58
|
const { rawBalance } = useTokenBalance({
|
|
@@ -62,23 +60,15 @@ export function OrderTokenAmount({
|
|
|
62
60
|
address: context === "from" && walletAddress ? walletAddress : undefined,
|
|
63
61
|
});
|
|
64
62
|
|
|
65
|
-
// Reset balance ref when token address or chain changes
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
initialBalanceSetRef.current = false;
|
|
68
|
-
}, [token.address, token.chainId]);
|
|
69
|
-
|
|
70
63
|
useEffect(() => {
|
|
71
64
|
// Only handle "from" context
|
|
72
65
|
if (context !== "from") return;
|
|
73
66
|
|
|
74
67
|
// Check if token changed or if this is the initial load with balance
|
|
75
68
|
const isTokenChanged = prevTokenRef.current !== token.address;
|
|
76
|
-
const isInitialLoad = !initialBalanceSetRef.current && rawBalance;
|
|
77
69
|
|
|
78
|
-
if (
|
|
79
|
-
console.log(
|
|
80
|
-
`Setting max balance - Token: ${token.address}, Changed: ${isTokenChanged}, Initial: ${isInitialLoad}`,
|
|
81
|
-
);
|
|
70
|
+
if (isTokenChanged && rawBalance) {
|
|
71
|
+
console.log(`Setting max balance - Token: ${token.address}, Changed: ${isTokenChanged}`);
|
|
82
72
|
|
|
83
73
|
// Calculate max amount with gas reserve for native tokens
|
|
84
74
|
let maxAmount: bigint;
|
|
@@ -97,7 +87,6 @@ export function OrderTokenAmount({
|
|
|
97
87
|
|
|
98
88
|
// Update refs
|
|
99
89
|
prevTokenRef.current = token.address;
|
|
100
|
-
initialBalanceSetRef.current = true;
|
|
101
90
|
}
|
|
102
91
|
}, [token.address, token.chainId, token.decimals, chainId, context, onChangeInput, rawBalance]);
|
|
103
92
|
|
|
@@ -19,12 +19,13 @@ import { useEffect, useMemo, useState } from "react";
|
|
|
19
19
|
import { toast } from "sonner";
|
|
20
20
|
import { parseUnits } from "viem";
|
|
21
21
|
import { base, mainnet } from "viem/chains";
|
|
22
|
-
import { useAccount } from "wagmi";
|
|
23
22
|
import { components } from "../../types/api";
|
|
24
23
|
import { CryptoPaymentMethodType } from "../components/common/CryptoPaymentMethod";
|
|
25
24
|
import { FiatPaymentMethod } from "../components/common/FiatPaymentMethod";
|
|
26
25
|
import { useAutoSelectCryptoPaymentMethod } from "./useAutoSelectCryptoPaymentMethod";
|
|
27
26
|
import { useAutoSetActiveWalletFromWagmi } from "./useAutoSetActiveWalletFromWagmi";
|
|
27
|
+
import { useConnectedWalletDisplay } from "./useConnectedWalletDisplay";
|
|
28
|
+
import { useCryptoPaymentMethodState } from "./useCryptoPaymentMethodState";
|
|
28
29
|
|
|
29
30
|
export enum PanelView {
|
|
30
31
|
MAIN,
|
|
@@ -85,22 +86,28 @@ export function useAnyspendFlow({
|
|
|
85
86
|
const defaultDstToken = B3_TOKEN; // Default destination token
|
|
86
87
|
const [selectedSrcToken, setSelectedSrcToken] = useState<components["schemas"]["Token"]>(defaultSrcToken);
|
|
87
88
|
const [selectedDstToken, setSelectedDstToken] = useState<components["schemas"]["Token"]>(defaultDstToken);
|
|
88
|
-
const [srcAmount, setSrcAmount] = useState<string>(paymentType === "fiat" ? "5" : "0
|
|
89
|
+
const [srcAmount, setSrcAmount] = useState<string>(paymentType === "fiat" ? "5" : "0");
|
|
89
90
|
const [dstAmount, setDstAmount] = useState<string>("");
|
|
90
91
|
const [isSrcInputDirty, setIsSrcInputDirty] = useState(true);
|
|
91
92
|
|
|
92
93
|
// Derive destination chain ID from token or prop (cannot change)
|
|
93
94
|
const selectedDstChainId = destinationTokenChainId || selectedDstToken.chainId;
|
|
94
95
|
|
|
95
|
-
// Payment method state
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
// Payment method state with dual-state system (auto + explicit user selection)
|
|
97
|
+
const {
|
|
98
|
+
cryptoPaymentMethod,
|
|
99
|
+
setCryptoPaymentMethod,
|
|
100
|
+
selectedCryptoPaymentMethod,
|
|
101
|
+
setSelectedCryptoPaymentMethod,
|
|
102
|
+
effectiveCryptoPaymentMethod,
|
|
103
|
+
resetPaymentMethods,
|
|
104
|
+
} = useCryptoPaymentMethodState();
|
|
105
|
+
|
|
99
106
|
const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState<FiatPaymentMethod>(FiatPaymentMethod.NONE);
|
|
100
107
|
|
|
101
108
|
// Recipient state
|
|
102
109
|
const { address: globalAddress } = useAccountWallet();
|
|
103
|
-
const {
|
|
110
|
+
const { walletAddress } = useConnectedWalletDisplay(effectiveCryptoPaymentMethod);
|
|
104
111
|
const [selectedRecipientAddress, setSelectedRecipientAddress] = useState<string | undefined>(recipientAddress);
|
|
105
112
|
const recipientProfile = useProfile({ address: selectedRecipientAddress, fresh: true });
|
|
106
113
|
const recipientName = recipientProfile.data?.name;
|
|
@@ -118,7 +125,7 @@ export function useAnyspendFlow({
|
|
|
118
125
|
// Check token balance for crypto payments
|
|
119
126
|
const { rawBalance, isLoading: isBalanceLoading } = useTokenBalance({
|
|
120
127
|
token: selectedSrcToken,
|
|
121
|
-
address:
|
|
128
|
+
address: walletAddress,
|
|
122
129
|
});
|
|
123
130
|
|
|
124
131
|
// Check if user has enough balance
|
|
@@ -135,8 +142,9 @@ export function useAnyspendFlow({
|
|
|
135
142
|
// Auto-select crypto payment method based on available wallets and balance
|
|
136
143
|
useAutoSelectCryptoPaymentMethod({
|
|
137
144
|
paymentType,
|
|
145
|
+
cryptoPaymentMethod,
|
|
146
|
+
setCryptoPaymentMethod,
|
|
138
147
|
selectedCryptoPaymentMethod,
|
|
139
|
-
setSelectedCryptoPaymentMethod,
|
|
140
148
|
hasEnoughBalance,
|
|
141
149
|
isBalanceLoading,
|
|
142
150
|
});
|
|
@@ -248,9 +256,9 @@ export function useAnyspendFlow({
|
|
|
248
256
|
if (!disableUrlParamManagement) {
|
|
249
257
|
const params = new URLSearchParams(searchParams.toString()); // Preserve existing params
|
|
250
258
|
params.set("orderId", newOrderId);
|
|
251
|
-
if (
|
|
252
|
-
console.log("Setting cryptoPaymentMethod in URL:",
|
|
253
|
-
params.set("cryptoPaymentMethod",
|
|
259
|
+
if (effectiveCryptoPaymentMethod !== CryptoPaymentMethodType.NONE) {
|
|
260
|
+
console.log("Setting cryptoPaymentMethod in URL:", effectiveCryptoPaymentMethod);
|
|
261
|
+
params.set("cryptoPaymentMethod", effectiveCryptoPaymentMethod);
|
|
254
262
|
} else {
|
|
255
263
|
console.log("Payment method is NONE, not setting in URL");
|
|
256
264
|
}
|
|
@@ -316,8 +324,12 @@ export function useAnyspendFlow({
|
|
|
316
324
|
isSrcInputDirty,
|
|
317
325
|
setIsSrcInputDirty,
|
|
318
326
|
// Payment methods
|
|
327
|
+
cryptoPaymentMethod,
|
|
328
|
+
setCryptoPaymentMethod,
|
|
319
329
|
selectedCryptoPaymentMethod,
|
|
320
330
|
setSelectedCryptoPaymentMethod,
|
|
331
|
+
effectiveCryptoPaymentMethod,
|
|
332
|
+
resetPaymentMethods,
|
|
321
333
|
selectedFiatPaymentMethod,
|
|
322
334
|
setSelectedFiatPaymentMethod,
|
|
323
335
|
// Recipient
|
|
@@ -5,10 +5,12 @@ import { useConnectedWalletDisplay } from "./useConnectedWalletDisplay";
|
|
|
5
5
|
interface UseAutoSelectCryptoPaymentMethodParams {
|
|
6
6
|
/** Current payment type (crypto or fiat) */
|
|
7
7
|
paymentType?: "crypto" | "fiat";
|
|
8
|
-
/**
|
|
8
|
+
/** Auto-selected payment method based on balance (not used in hook logic, but part of state management) */
|
|
9
|
+
cryptoPaymentMethod: CryptoPaymentMethodType;
|
|
10
|
+
/** Function to update the auto-selected payment method */
|
|
11
|
+
setCryptoPaymentMethod: (method: CryptoPaymentMethodType) => void;
|
|
12
|
+
/** User explicitly selected payment method (NONE means no explicit selection) */
|
|
9
13
|
selectedCryptoPaymentMethod: CryptoPaymentMethodType;
|
|
10
|
-
/** Function to update the selected payment method */
|
|
11
|
-
setSelectedCryptoPaymentMethod: (method: CryptoPaymentMethodType) => void;
|
|
12
14
|
/** Whether user has enough balance to pay */
|
|
13
15
|
hasEnoughBalance: boolean;
|
|
14
16
|
/** Whether balance is still loading */
|
|
@@ -20,7 +22,7 @@ interface UseAutoSelectCryptoPaymentMethodParams {
|
|
|
20
22
|
* based on available wallets and balance.
|
|
21
23
|
*
|
|
22
24
|
* Auto-selection logic:
|
|
23
|
-
* - Only auto-selects when
|
|
25
|
+
* - Only auto-selects when selectedCryptoPaymentMethod is NONE (user hasn't explicitly chosen)
|
|
24
26
|
* - If EOA/Wagmi wallet connected + has balance → CONNECT_WALLET
|
|
25
27
|
* - If EOA/Wagmi wallet connected + insufficient balance → TRANSFER_CRYPTO
|
|
26
28
|
* - If only Global wallet available → GLOBAL_WALLET
|
|
@@ -28,8 +30,9 @@ interface UseAutoSelectCryptoPaymentMethodParams {
|
|
|
28
30
|
*/
|
|
29
31
|
export function useAutoSelectCryptoPaymentMethod({
|
|
30
32
|
paymentType = "crypto",
|
|
33
|
+
cryptoPaymentMethod: _cryptoPaymentMethod,
|
|
34
|
+
setCryptoPaymentMethod,
|
|
31
35
|
selectedCryptoPaymentMethod,
|
|
32
|
-
setSelectedCryptoPaymentMethod,
|
|
33
36
|
hasEnoughBalance,
|
|
34
37
|
isBalanceLoading,
|
|
35
38
|
}: UseAutoSelectCryptoPaymentMethodParams) {
|
|
@@ -37,8 +40,13 @@ export function useAutoSelectCryptoPaymentMethod({
|
|
|
37
40
|
const { suggestedPaymentMethod } = useConnectedWalletDisplay(selectedCryptoPaymentMethod);
|
|
38
41
|
|
|
39
42
|
useEffect(() => {
|
|
40
|
-
// Only auto-select when on crypto payment type
|
|
41
|
-
if (paymentType !== "crypto"
|
|
43
|
+
// Only auto-select when on crypto payment type
|
|
44
|
+
if (paymentType !== "crypto") {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Only auto-switch if user hasn't explicitly selected a payment method
|
|
49
|
+
if (selectedCryptoPaymentMethod !== CryptoPaymentMethodType.NONE) {
|
|
42
50
|
return;
|
|
43
51
|
}
|
|
44
52
|
|
|
@@ -48,25 +56,25 @@ export function useAutoSelectCryptoPaymentMethod({
|
|
|
48
56
|
// Otherwise, default to TRANSFER_CRYPTO if balance is insufficient
|
|
49
57
|
if (!isBalanceLoading) {
|
|
50
58
|
if (hasEnoughBalance && suggestedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
51
|
-
|
|
59
|
+
setCryptoPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
52
60
|
} else if (!hasEnoughBalance && suggestedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
53
61
|
// Wallet connected but insufficient balance - suggest transfer
|
|
54
|
-
|
|
62
|
+
setCryptoPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
|
|
55
63
|
} else {
|
|
56
64
|
// Use suggested method (e.g., GLOBAL_WALLET)
|
|
57
|
-
|
|
65
|
+
setCryptoPaymentMethod(suggestedPaymentMethod);
|
|
58
66
|
}
|
|
59
67
|
} else {
|
|
60
68
|
// Balance still loading, use suggested method
|
|
61
|
-
|
|
69
|
+
setCryptoPaymentMethod(suggestedPaymentMethod);
|
|
62
70
|
}
|
|
63
71
|
}
|
|
64
72
|
}, [
|
|
65
73
|
paymentType,
|
|
74
|
+
setCryptoPaymentMethod,
|
|
66
75
|
selectedCryptoPaymentMethod,
|
|
67
76
|
suggestedPaymentMethod,
|
|
68
77
|
hasEnoughBalance,
|
|
69
78
|
isBalanceLoading,
|
|
70
|
-
setSelectedCryptoPaymentMethod,
|
|
71
79
|
]);
|
|
72
80
|
}
|