@b3dotfun/sdk 0.1.68-alpha.3 → 0.1.68-alpha.5
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/platform/client.d.ts +35 -0
- package/dist/cjs/anyspend/platform/client.js +158 -0
- package/dist/cjs/anyspend/platform/errors.d.ts +38 -0
- package/dist/cjs/anyspend/platform/errors.js +77 -0
- package/dist/cjs/anyspend/platform/index.d.ts +87 -0
- package/dist/cjs/anyspend/platform/index.js +85 -0
- package/dist/cjs/anyspend/platform/resources/analytics.d.ts +7 -0
- package/dist/cjs/anyspend/platform/resources/analytics.js +12 -0
- package/dist/cjs/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
- package/dist/cjs/anyspend/platform/resources/checkout-sessions.js +27 -0
- package/dist/cjs/anyspend/platform/resources/customers.d.ts +19 -0
- package/dist/cjs/anyspend/platform/resources/customers.js +34 -0
- package/dist/cjs/anyspend/platform/resources/discount-codes.d.ts +29 -0
- package/dist/cjs/anyspend/platform/resources/discount-codes.js +31 -0
- package/dist/cjs/anyspend/platform/resources/events.d.ts +14 -0
- package/dist/cjs/anyspend/platform/resources/events.js +16 -0
- package/dist/cjs/anyspend/platform/resources/notifications.d.ts +18 -0
- package/dist/cjs/anyspend/platform/resources/notifications.js +27 -0
- package/dist/cjs/anyspend/platform/resources/organization.d.ts +17 -0
- package/dist/cjs/anyspend/platform/resources/organization.js +15 -0
- package/dist/cjs/anyspend/platform/resources/payment-links.d.ts +21 -0
- package/dist/cjs/anyspend/platform/resources/payment-links.js +49 -0
- package/dist/cjs/anyspend/platform/resources/products.d.ts +27 -0
- package/dist/cjs/anyspend/platform/resources/products.js +31 -0
- package/dist/cjs/anyspend/platform/resources/transactions.d.ts +11 -0
- package/dist/cjs/anyspend/platform/resources/transactions.js +25 -0
- package/dist/cjs/anyspend/platform/resources/webhooks.d.ts +14 -0
- package/dist/cjs/anyspend/platform/resources/webhooks.js +33 -0
- package/dist/cjs/anyspend/platform/resources/widgets.d.ts +38 -0
- package/dist/cjs/anyspend/platform/resources/widgets.js +31 -0
- package/dist/cjs/anyspend/platform/types.d.ts +478 -0
- package/dist/cjs/anyspend/platform/types.js +5 -0
- package/dist/cjs/anyspend/platform/utils/idempotency.d.ts +4 -0
- package/dist/cjs/anyspend/platform/utils/idempotency.js +17 -0
- package/dist/cjs/anyspend/platform/utils/pagination.d.ts +12 -0
- package/dist/cjs/anyspend/platform/utils/pagination.js +22 -0
- package/dist/cjs/anyspend/react/components/AnySpend.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/AnySpend.js +128 -11
- package/dist/cjs/anyspend/react/components/checkout/FiatCheckoutPanel.js +13 -12
- package/dist/cjs/anyspend/react/components/checkout/KycGate.d.ts +11 -0
- package/dist/cjs/anyspend/react/components/checkout/KycGate.js +181 -0
- package/dist/cjs/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/cjs/anyspend/react/hooks/index.js +1 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +9 -0
- package/dist/cjs/anyspend/react/hooks/useKycStatus.d.ts +42 -0
- package/dist/cjs/anyspend/react/hooks/useKycStatus.js +113 -0
- package/dist/cjs/anyspend/services/anyspend.d.ts +3 -1
- package/dist/cjs/anyspend/services/anyspend.js +2 -1
- package/dist/cjs/global-account/react/components/B3DynamicModal.js +1 -1
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +3 -3
- package/dist/cjs/global-account/react/hooks/useAuth.js +1 -1
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/cjs/global-account/react/stores/useModalStore.js +2 -0
- package/dist/cjs/global-account/react/utils/createWagmiConfig.d.ts +18 -0
- package/dist/cjs/global-account/react/utils/createWagmiConfig.js +17 -0
- package/dist/esm/anyspend/platform/client.d.ts +35 -0
- package/dist/esm/anyspend/platform/client.js +153 -0
- package/dist/esm/anyspend/platform/errors.d.ts +38 -0
- package/dist/esm/anyspend/platform/errors.js +67 -0
- package/dist/esm/anyspend/platform/index.d.ts +87 -0
- package/dist/esm/anyspend/platform/index.js +75 -0
- package/dist/esm/anyspend/platform/resources/analytics.d.ts +7 -0
- package/dist/esm/anyspend/platform/resources/analytics.js +8 -0
- package/dist/esm/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
- package/dist/esm/anyspend/platform/resources/checkout-sessions.js +23 -0
- package/dist/esm/anyspend/platform/resources/customers.d.ts +19 -0
- package/dist/esm/anyspend/platform/resources/customers.js +30 -0
- package/dist/esm/anyspend/platform/resources/discount-codes.d.ts +29 -0
- package/dist/esm/anyspend/platform/resources/discount-codes.js +27 -0
- package/dist/esm/anyspend/platform/resources/events.d.ts +14 -0
- package/dist/esm/anyspend/platform/resources/events.js +12 -0
- package/dist/esm/anyspend/platform/resources/notifications.d.ts +18 -0
- package/dist/esm/anyspend/platform/resources/notifications.js +23 -0
- package/dist/esm/anyspend/platform/resources/organization.d.ts +17 -0
- package/dist/esm/anyspend/platform/resources/organization.js +11 -0
- package/dist/esm/anyspend/platform/resources/payment-links.d.ts +21 -0
- package/dist/esm/anyspend/platform/resources/payment-links.js +45 -0
- package/dist/esm/anyspend/platform/resources/products.d.ts +27 -0
- package/dist/esm/anyspend/platform/resources/products.js +27 -0
- package/dist/esm/anyspend/platform/resources/transactions.d.ts +11 -0
- package/dist/esm/anyspend/platform/resources/transactions.js +21 -0
- package/dist/esm/anyspend/platform/resources/webhooks.d.ts +14 -0
- package/dist/esm/anyspend/platform/resources/webhooks.js +29 -0
- package/dist/esm/anyspend/platform/resources/widgets.d.ts +38 -0
- package/dist/esm/anyspend/platform/resources/widgets.js +27 -0
- package/dist/esm/anyspend/platform/types.d.ts +478 -0
- package/dist/esm/anyspend/platform/types.js +4 -0
- package/dist/esm/anyspend/platform/utils/idempotency.d.ts +4 -0
- package/dist/esm/anyspend/platform/utils/idempotency.js +14 -0
- package/dist/esm/anyspend/platform/utils/pagination.d.ts +12 -0
- package/dist/esm/anyspend/platform/utils/pagination.js +19 -0
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +3 -1
- package/dist/esm/anyspend/react/components/AnySpend.js +129 -12
- package/dist/esm/anyspend/react/components/checkout/FiatCheckoutPanel.js +13 -12
- package/dist/esm/anyspend/react/components/checkout/KycGate.d.ts +11 -0
- package/dist/esm/anyspend/react/components/checkout/KycGate.js +145 -0
- package/dist/esm/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/esm/anyspend/react/hooks/index.js +1 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendCreateOnrampOrder.js +9 -0
- package/dist/esm/anyspend/react/hooks/useKycStatus.d.ts +42 -0
- package/dist/esm/anyspend/react/hooks/useKycStatus.js +107 -0
- package/dist/esm/anyspend/services/anyspend.d.ts +3 -1
- package/dist/esm/anyspend/services/anyspend.js +2 -1
- package/dist/esm/global-account/react/components/B3DynamicModal.js +1 -1
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +3 -3
- package/dist/esm/global-account/react/hooks/useAuth.js +2 -2
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/esm/global-account/react/stores/useModalStore.js +2 -0
- package/dist/esm/global-account/react/utils/createWagmiConfig.d.ts +18 -0
- package/dist/esm/global-account/react/utils/createWagmiConfig.js +16 -0
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/platform/client.d.ts +35 -0
- package/dist/types/anyspend/platform/errors.d.ts +38 -0
- package/dist/types/anyspend/platform/index.d.ts +87 -0
- package/dist/types/anyspend/platform/resources/analytics.d.ts +7 -0
- package/dist/types/anyspend/platform/resources/checkout-sessions.d.ts +17 -0
- package/dist/types/anyspend/platform/resources/customers.d.ts +19 -0
- package/dist/types/anyspend/platform/resources/discount-codes.d.ts +29 -0
- package/dist/types/anyspend/platform/resources/events.d.ts +14 -0
- package/dist/types/anyspend/platform/resources/notifications.d.ts +18 -0
- package/dist/types/anyspend/platform/resources/organization.d.ts +17 -0
- package/dist/types/anyspend/platform/resources/payment-links.d.ts +21 -0
- package/dist/types/anyspend/platform/resources/products.d.ts +27 -0
- package/dist/types/anyspend/platform/resources/transactions.d.ts +11 -0
- package/dist/types/anyspend/platform/resources/webhooks.d.ts +14 -0
- package/dist/types/anyspend/platform/resources/widgets.d.ts +38 -0
- package/dist/types/anyspend/platform/types.d.ts +478 -0
- package/dist/types/anyspend/platform/utils/idempotency.d.ts +4 -0
- package/dist/types/anyspend/platform/utils/pagination.d.ts +12 -0
- package/dist/types/anyspend/react/components/AnySpend.d.ts +3 -1
- package/dist/types/anyspend/react/components/checkout/KycGate.d.ts +11 -0
- package/dist/types/anyspend/react/hooks/index.d.ts +1 -0
- package/dist/types/anyspend/react/hooks/useKycStatus.d.ts +42 -0
- package/dist/types/anyspend/services/anyspend.d.ts +3 -1
- package/dist/types/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/types/global-account/react/utils/createWagmiConfig.d.ts +18 -0
- package/package.json +7 -1
- package/src/anyspend/platform/client.ts +198 -0
- package/src/anyspend/platform/errors.ts +92 -0
- package/src/anyspend/platform/index.ts +129 -0
- package/src/anyspend/platform/resources/analytics.ts +10 -0
- package/src/anyspend/platform/resources/checkout-sessions.ts +36 -0
- package/src/anyspend/platform/resources/customers.ts +54 -0
- package/src/anyspend/platform/resources/discount-codes.ts +63 -0
- package/src/anyspend/platform/resources/events.ts +22 -0
- package/src/anyspend/platform/resources/notifications.ts +37 -0
- package/src/anyspend/platform/resources/organization.ts +24 -0
- package/src/anyspend/platform/resources/payment-links.ts +74 -0
- package/src/anyspend/platform/resources/products.ts +59 -0
- package/src/anyspend/platform/resources/transactions.ts +33 -0
- package/src/anyspend/platform/resources/webhooks.ts +47 -0
- package/src/anyspend/platform/resources/widgets.ts +63 -0
- package/src/anyspend/platform/types.ts +532 -0
- package/src/anyspend/platform/utils/idempotency.ts +15 -0
- package/src/anyspend/platform/utils/pagination.ts +32 -0
- package/src/anyspend/react/components/AnySpend.tsx +150 -13
- package/src/anyspend/react/components/checkout/FiatCheckoutPanel.tsx +16 -13
- package/src/anyspend/react/components/checkout/KycGate.tsx +351 -0
- package/src/anyspend/react/hooks/index.ts +1 -0
- package/src/anyspend/react/hooks/useAnyspendCreateOnrampOrder.ts +10 -0
- package/src/anyspend/react/hooks/useKycStatus.ts +140 -0
- package/src/anyspend/services/anyspend.ts +4 -0
- package/src/global-account/react/components/B3DynamicModal.tsx +0 -2
- package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +7 -7
- package/src/global-account/react/hooks/useAuth.ts +2 -2
- package/src/global-account/react/stores/useModalStore.ts +6 -0
- package/src/global-account/react/utils/createWagmiConfig.tsx +18 -0
|
@@ -27,6 +27,8 @@ import {
|
|
|
27
27
|
toast,
|
|
28
28
|
TransitionPanel,
|
|
29
29
|
useAccountWallet,
|
|
30
|
+
useAuth,
|
|
31
|
+
useAuthStore,
|
|
30
32
|
useB3Config,
|
|
31
33
|
useModalStore,
|
|
32
34
|
useProfile,
|
|
@@ -64,6 +66,9 @@ import { FiatPaymentMethod, FiatPaymentMethodComponent } from "./common/FiatPaym
|
|
|
64
66
|
import { GasIndicator } from "./common/GasIndicator";
|
|
65
67
|
import { OrderDetails, OrderDetailsLoadingView } from "./common/OrderDetails";
|
|
66
68
|
import { OrderHistory } from "./common/OrderHistory";
|
|
69
|
+
import { KycGate } from "./checkout/KycGate";
|
|
70
|
+
import { useWalletAuthHeaders } from "../hooks/useKycStatus";
|
|
71
|
+
import { LoginStep } from "@b3dotfun/sdk/global-account/react/components/SignInWithB3/steps/LoginStep";
|
|
67
72
|
import { PanelOnramp } from "./common/PanelOnramp";
|
|
68
73
|
import { PanelOnrampPayment } from "./common/PanelOnrampPayment";
|
|
69
74
|
import { PointsDetailPanel } from "./common/PointsDetailPanel";
|
|
@@ -94,6 +99,8 @@ export enum PanelView {
|
|
|
94
99
|
POINTS_DETAIL,
|
|
95
100
|
FEE_DETAIL,
|
|
96
101
|
DIRECT_TRANSFER_SUCCESS,
|
|
102
|
+
FIAT_KYC,
|
|
103
|
+
FIAT_AUTH,
|
|
97
104
|
}
|
|
98
105
|
|
|
99
106
|
const ANYSPEND_RECIPIENTS_KEY = "anyspend_recipients";
|
|
@@ -209,6 +216,16 @@ function AnySpendInner({
|
|
|
209
216
|
const { partnerId } = useB3Config();
|
|
210
217
|
const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
|
|
211
218
|
const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
|
|
219
|
+
const { isAuthenticated } = useAuth();
|
|
220
|
+
// KYC approval is tracked per-session so we only prompt the wallet
|
|
221
|
+
// signature when the user actually clicks Buy, not on panel mount.
|
|
222
|
+
// useRef so handleFiatOrder can read the updated value synchronously
|
|
223
|
+
// in the same frame that onStatusResolved sets it (setState is async).
|
|
224
|
+
const kycApprovedRef = useRef(false);
|
|
225
|
+
// Pre-warm wallet auth headers inside user-gesture context (button click)
|
|
226
|
+
// so the signing prompt fires before we navigate away — browsers block
|
|
227
|
+
// wallet popups triggered from async/non-gesture contexts (React Query queryFn).
|
|
228
|
+
const { getHeaders: getKycHeaders } = useWalletAuthHeaders();
|
|
212
229
|
|
|
213
230
|
// Determine if we're in "buy mode" based on whether destination token props are provided
|
|
214
231
|
const isBuyMode = !!(destinationTokenAddress && destinationTokenChainId);
|
|
@@ -236,7 +253,17 @@ function AnySpendInner({
|
|
|
236
253
|
// Track previous panel for proper back navigation
|
|
237
254
|
const previousPanel = useRef<PanelView>(PanelView.MAIN);
|
|
238
255
|
|
|
239
|
-
const [activeTab, setActiveTab] = useState<"crypto" | "fiat">(
|
|
256
|
+
const [activeTab, setActiveTab] = useState<"crypto" | "fiat">(() => {
|
|
257
|
+
if (typeof window !== "undefined") {
|
|
258
|
+
const stored = sessionStorage.getItem("anyspend_active_tab") as "crypto" | "fiat" | null;
|
|
259
|
+
if (stored === "crypto" || stored === "fiat") return stored;
|
|
260
|
+
}
|
|
261
|
+
return defaultActiveTab;
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
useEffect(() => {
|
|
265
|
+
sessionStorage.setItem("anyspend_active_tab", activeTab);
|
|
266
|
+
}, [activeTab]);
|
|
240
267
|
|
|
241
268
|
const [orderId, setOrderId] = useState<string | undefined>(loadOrder);
|
|
242
269
|
const [directTransferTxHash, setDirectTransferTxHash] = useState<string | undefined>();
|
|
@@ -273,10 +300,20 @@ function AnySpendInner({
|
|
|
273
300
|
resetPaymentMethods,
|
|
274
301
|
} = useCryptoPaymentMethodState();
|
|
275
302
|
|
|
276
|
-
const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState<FiatPaymentMethod>(
|
|
303
|
+
const [selectedFiatPaymentMethod, setSelectedFiatPaymentMethod] = useState<FiatPaymentMethod>(() => {
|
|
304
|
+
if (typeof window !== "undefined") {
|
|
305
|
+
const stored = sessionStorage.getItem("anyspend_fiat_method") as FiatPaymentMethod | null;
|
|
306
|
+
if (stored && Object.values(FiatPaymentMethod).includes(stored)) return stored;
|
|
307
|
+
}
|
|
308
|
+
return FiatPaymentMethod.NONE;
|
|
309
|
+
});
|
|
277
310
|
// const [newRecipientAddress, setNewRecipientAddress] = useState("");
|
|
278
311
|
// const recipientInputRef = useRef<HTMLInputElement>(null);
|
|
279
312
|
|
|
313
|
+
useEffect(() => {
|
|
314
|
+
sessionStorage.setItem("anyspend_fiat_method", selectedFiatPaymentMethod);
|
|
315
|
+
}, [selectedFiatPaymentMethod]);
|
|
316
|
+
|
|
280
317
|
// Get initial chain IDs from URL or defaults
|
|
281
318
|
const initialSrcChainId = sourceChainId || parseInt(searchParams.get("fromChainId") || "0") || mainnet.id;
|
|
282
319
|
const initialDstChainId =
|
|
@@ -297,11 +334,27 @@ function AnySpendInner({
|
|
|
297
334
|
const { data: srcTokenMetadata } = useTokenData(selectedSrcToken?.chainId, selectedSrcToken?.address);
|
|
298
335
|
const [srcAmount, setSrcAmount] = useState<string>(searchParams.get("fromAmount") || "0");
|
|
299
336
|
|
|
300
|
-
// State for onramp amount
|
|
301
|
-
const [srcAmountOnRamp, setSrcAmountOnRamp] = useState<string>(
|
|
337
|
+
// State for onramp amount — persisted in sessionStorage so it survives Persona KYC roundtrip
|
|
338
|
+
const [srcAmountOnRamp, setSrcAmountOnRamp] = useState<string>(() => {
|
|
339
|
+
if (typeof window !== "undefined") {
|
|
340
|
+
const stored = sessionStorage.getItem("anyspend_fiat_amount");
|
|
341
|
+
if (stored) return stored;
|
|
342
|
+
}
|
|
343
|
+
return searchParams.get("fromAmount") || "5";
|
|
344
|
+
});
|
|
302
345
|
|
|
303
|
-
|
|
304
|
-
|
|
346
|
+
useEffect(() => {
|
|
347
|
+
sessionStorage.setItem("anyspend_fiat_amount", srcAmountOnRamp);
|
|
348
|
+
}, [srcAmountOnRamp]);
|
|
349
|
+
|
|
350
|
+
// State for destination chain/token selection (sync effects come after state declarations below) — persisted in sessionStorage for Persona KYC roundtrip
|
|
351
|
+
const [selectedDstChainId, setSelectedDstChainId] = useState<number>(() => {
|
|
352
|
+
if (!isBuyMode && typeof window !== "undefined") {
|
|
353
|
+
const stored = sessionStorage.getItem("anyspend_dst_chain_id");
|
|
354
|
+
if (stored) return parseInt(stored, 10);
|
|
355
|
+
}
|
|
356
|
+
return initialDstChainId;
|
|
357
|
+
});
|
|
305
358
|
// Helper to check if address is Hyperliquid USDC (supports both 34-char and 42-char formats)
|
|
306
359
|
const isHyperliquidUSDCAddress = (address?: string) =>
|
|
307
360
|
eqci(address, HYPERLIQUID_USDC_ADDRESS) || eqci(address, ZERO_ADDRESS);
|
|
@@ -323,12 +376,29 @@ function AnySpendInner({
|
|
|
323
376
|
defaultToken: defaultDstToken,
|
|
324
377
|
prefix: "to",
|
|
325
378
|
});
|
|
326
|
-
const [selectedDstToken, setSelectedDstToken] = useState<components["schemas"]["Token"]>(
|
|
327
|
-
isBuyMode
|
|
328
|
-
|
|
379
|
+
const [selectedDstToken, setSelectedDstToken] = useState<components["schemas"]["Token"]>(() => {
|
|
380
|
+
if (!isBuyMode && typeof window !== "undefined") {
|
|
381
|
+
const stored = sessionStorage.getItem("anyspend_dst_token");
|
|
382
|
+
if (stored) {
|
|
383
|
+
try {
|
|
384
|
+
return JSON.parse(stored) as components["schemas"]["Token"];
|
|
385
|
+
} catch {}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return isBuyMode ? defaultDstToken : dstTokenFromUrl;
|
|
389
|
+
});
|
|
329
390
|
const { data: dstTokenMetadata } = useTokenData(selectedDstToken?.chainId, selectedDstToken?.address);
|
|
330
391
|
const [dstAmount, setDstAmount] = useState<string>(searchParams.get("toAmount") || "");
|
|
331
392
|
|
|
393
|
+
// Sync dst chain/token to sessionStorage so they survive Persona KYC roundtrip
|
|
394
|
+
useEffect(() => {
|
|
395
|
+
if (!isBuyMode) sessionStorage.setItem("anyspend_dst_chain_id", selectedDstChainId.toString());
|
|
396
|
+
}, [selectedDstChainId, isBuyMode]);
|
|
397
|
+
|
|
398
|
+
useEffect(() => {
|
|
399
|
+
if (!isBuyMode) sessionStorage.setItem("anyspend_dst_token", JSON.stringify(selectedDstToken));
|
|
400
|
+
}, [selectedDstToken, isBuyMode]);
|
|
401
|
+
|
|
332
402
|
const [isSrcInputDirty, setIsSrcInputDirty] = useState(true);
|
|
333
403
|
// Add refs to track if we've applied metadata
|
|
334
404
|
const appliedSrcMetadataRef = useRef(false);
|
|
@@ -728,6 +798,17 @@ function AnySpendInner({
|
|
|
728
798
|
// Call onSuccess when order is executed
|
|
729
799
|
useOnOrderSuccess({ orderData: oat, orderId, onSuccess });
|
|
730
800
|
|
|
801
|
+
// Clear all persisted selection state once an order is submitted — next open starts fresh
|
|
802
|
+
useEffect(() => {
|
|
803
|
+
if (orderId) {
|
|
804
|
+
sessionStorage.removeItem("anyspend_fiat_amount");
|
|
805
|
+
sessionStorage.removeItem("anyspend_active_tab");
|
|
806
|
+
sessionStorage.removeItem("anyspend_fiat_method");
|
|
807
|
+
sessionStorage.removeItem("anyspend_dst_chain_id");
|
|
808
|
+
sessionStorage.removeItem("anyspend_dst_token");
|
|
809
|
+
}
|
|
810
|
+
}, [orderId]);
|
|
811
|
+
|
|
731
812
|
const { createOrder, isCreatingOrder } = useAnyspendCreateOrder({
|
|
732
813
|
onSuccess: data => {
|
|
733
814
|
const orderId = data.data.id;
|
|
@@ -817,8 +898,8 @@ function AnySpendInner({
|
|
|
817
898
|
if (selectedFiatPaymentMethod === FiatPaymentMethod.NONE) {
|
|
818
899
|
return { text: "Select payment method", disable: false, error: false, loading: false };
|
|
819
900
|
}
|
|
820
|
-
// If payment method is selected, show "
|
|
821
|
-
return { text: "
|
|
901
|
+
// If payment method is selected, show "Continue"
|
|
902
|
+
return { text: "Continue", disable: false, error: false, loading: false };
|
|
822
903
|
}
|
|
823
904
|
|
|
824
905
|
if (activeTab === "crypto") {
|
|
@@ -845,7 +926,7 @@ function AnySpendInner({
|
|
|
845
926
|
}
|
|
846
927
|
}
|
|
847
928
|
|
|
848
|
-
return { text: "
|
|
929
|
+
return { text: "Continue", disable: false, error: false, loading: false };
|
|
849
930
|
}, [
|
|
850
931
|
activeInputAmountInWei,
|
|
851
932
|
isSameChainSameToken,
|
|
@@ -1028,7 +1109,22 @@ function AnySpendInner({
|
|
|
1028
1109
|
vendor = "stripe";
|
|
1029
1110
|
paymentMethodString = "";
|
|
1030
1111
|
} else if (paymentMethod === FiatPaymentMethod.STRIPE_WEB2) {
|
|
1031
|
-
// Stripe embedded payment form
|
|
1112
|
+
// Stripe embedded payment form requires authentication + KYC
|
|
1113
|
+
// Read from store directly to avoid stale closure when called from onLoginSuccess callback
|
|
1114
|
+
const currentlyAuthenticated = useAuthStore.getState().isAuthenticated;
|
|
1115
|
+
if (!currentlyAuthenticated) {
|
|
1116
|
+
navigateToPanel(PanelView.FIAT_AUTH, "forward");
|
|
1117
|
+
return;
|
|
1118
|
+
}
|
|
1119
|
+
if (!kycApprovedRef.current) {
|
|
1120
|
+
// Pre-sign the KYC auth message NOW (user-gesture context) so the
|
|
1121
|
+
// result is cached before useKycStatus fires its queryFn inside the
|
|
1122
|
+
// FIAT_KYC panel. Wallets/browsers block signing prompts from async
|
|
1123
|
+
// (non-gesture) contexts, which is exactly what React Query uses.
|
|
1124
|
+
await getKycHeaders().catch(() => {});
|
|
1125
|
+
navigateToPanel(PanelView.FIAT_KYC, "forward");
|
|
1126
|
+
return;
|
|
1127
|
+
}
|
|
1032
1128
|
if (!stripeWeb2Support.isSupport) {
|
|
1033
1129
|
toast.error("Pay with Card not available");
|
|
1034
1130
|
return;
|
|
@@ -1147,6 +1243,15 @@ function AnySpendInner({
|
|
|
1147
1243
|
};
|
|
1148
1244
|
}, [activePanel, navigateBack]);
|
|
1149
1245
|
|
|
1246
|
+
// When auth completes while on the FIAT_AUTH panel, navigate back and retry the order
|
|
1247
|
+
useEffect(() => {
|
|
1248
|
+
if (isAuthenticated && activePanel === PanelView.FIAT_AUTH) {
|
|
1249
|
+
navigateBack();
|
|
1250
|
+
handleFiatOrder(selectedFiatPaymentMethod);
|
|
1251
|
+
}
|
|
1252
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1253
|
+
}, [isAuthenticated]);
|
|
1254
|
+
|
|
1150
1255
|
const historyView = (
|
|
1151
1256
|
<div className={"mx-auto flex w-[560px] max-w-full flex-col items-center"}>
|
|
1152
1257
|
<OrderHistory mode={mode} onBack={navigateBack} onSelectOrder={onSelectOrder} />
|
|
@@ -1593,6 +1698,32 @@ function AnySpendInner({
|
|
|
1593
1698
|
</div>
|
|
1594
1699
|
);
|
|
1595
1700
|
|
|
1701
|
+
const kycView = (
|
|
1702
|
+
<div className="mx-auto flex w-full max-w-[460px] flex-col gap-4 px-5 pt-5">
|
|
1703
|
+
<KycGate
|
|
1704
|
+
enabled={activePanel === PanelView.FIAT_KYC}
|
|
1705
|
+
onStatusResolved={approved => {
|
|
1706
|
+
if (approved) {
|
|
1707
|
+
kycApprovedRef.current = true;
|
|
1708
|
+
navigateBack();
|
|
1709
|
+
handleFiatOrder(selectedFiatPaymentMethod);
|
|
1710
|
+
}
|
|
1711
|
+
}}
|
|
1712
|
+
/>
|
|
1713
|
+
</div>
|
|
1714
|
+
);
|
|
1715
|
+
|
|
1716
|
+
const authView = (
|
|
1717
|
+
<div className="mx-auto w-full max-w-[460px]">
|
|
1718
|
+
<LoginStep
|
|
1719
|
+
chain={baseChain}
|
|
1720
|
+
onSuccess={async () => {
|
|
1721
|
+
// isAuthenticated will be true at this point — the useEffect below handles navigation
|
|
1722
|
+
}}
|
|
1723
|
+
/>
|
|
1724
|
+
</div>
|
|
1725
|
+
);
|
|
1726
|
+
|
|
1596
1727
|
// Add tabs to the main component when no order is loaded
|
|
1597
1728
|
return (
|
|
1598
1729
|
<StyleRoot>
|
|
@@ -1667,6 +1798,12 @@ function AnySpendInner({
|
|
|
1667
1798
|
<div key="direct-transfer-success-view" className={cn(mode === "page" && "p-6")}>
|
|
1668
1799
|
{directTransferSuccessView}
|
|
1669
1800
|
</div>,
|
|
1801
|
+
<div key="fiat-kyc-view" className={cn(mode === "page" && "p-6")}>
|
|
1802
|
+
{kycView}
|
|
1803
|
+
</div>,
|
|
1804
|
+
<div key="fiat-auth-view" className={cn(mode === "page" && "p-6")}>
|
|
1805
|
+
{authView}
|
|
1806
|
+
</div>,
|
|
1670
1807
|
]}
|
|
1671
1808
|
</TransitionPanel>
|
|
1672
1809
|
</div>
|
|
@@ -17,6 +17,7 @@ import { Loader2, Lock } from "lucide-react";
|
|
|
17
17
|
import { AnimatePresence, motion } from "motion/react";
|
|
18
18
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
19
19
|
import type { AnySpendCheckoutClasses } from "./AnySpendCheckout";
|
|
20
|
+
import { KycGate } from "./KycGate";
|
|
20
21
|
|
|
21
22
|
interface FiatCheckoutPanelProps {
|
|
22
23
|
recipientAddress: string;
|
|
@@ -89,18 +90,6 @@ export function FiatCheckoutPanel({
|
|
|
89
90
|
return parseFloat(raw).toFixed(2);
|
|
90
91
|
}, [isStablecoin, formattedAmount, anyspendQuote]);
|
|
91
92
|
|
|
92
|
-
// Debug: log computed values for Stripe flow diagnostics
|
|
93
|
-
useEffect(() => {
|
|
94
|
-
console.log("@@fiat-checkout:debug", {
|
|
95
|
-
totalAmount,
|
|
96
|
-
formattedAmount,
|
|
97
|
-
isStablecoin,
|
|
98
|
-
isLoadingAnyspendQuote,
|
|
99
|
-
quoteAmount: anyspendQuote?.data?.currencyIn?.amount,
|
|
100
|
-
usdAmount,
|
|
101
|
-
});
|
|
102
|
-
}, [totalAmount, formattedAmount, isStablecoin, isLoadingAnyspendQuote, anyspendQuote, usdAmount]);
|
|
103
|
-
|
|
104
93
|
const {
|
|
105
94
|
geoData,
|
|
106
95
|
stripeOnrampSupport,
|
|
@@ -108,6 +97,13 @@ export function FiatCheckoutPanel({
|
|
|
108
97
|
isLoading: isLoadingGeo,
|
|
109
98
|
} = useGeoOnrampOptions(usdAmount || "0");
|
|
110
99
|
|
|
100
|
+
// KYC state
|
|
101
|
+
const [kycApproved, setKycApproved] = useState(false);
|
|
102
|
+
|
|
103
|
+
const handleKycResolved = useCallback((approved: boolean) => {
|
|
104
|
+
setKycApproved(approved);
|
|
105
|
+
}, []);
|
|
106
|
+
|
|
111
107
|
// Order state
|
|
112
108
|
const [orderId, setOrderId] = useState<string | null>(null);
|
|
113
109
|
const [stripePaymentIntentId, setStripePaymentIntentId] = useState<string | null>(null);
|
|
@@ -131,7 +127,7 @@ export function FiatCheckoutPanel({
|
|
|
131
127
|
},
|
|
132
128
|
});
|
|
133
129
|
|
|
134
|
-
// Auto-create onramp order when Stripe Web2 is supported and all data is ready
|
|
130
|
+
// Auto-create onramp order when Stripe Web2 is supported, KYC approved, and all data is ready
|
|
135
131
|
useEffect(() => {
|
|
136
132
|
if (
|
|
137
133
|
!isLoadingGeo &&
|
|
@@ -139,6 +135,7 @@ export function FiatCheckoutPanel({
|
|
|
139
135
|
usdAmount &&
|
|
140
136
|
parseFloat(usdAmount) > 0 &&
|
|
141
137
|
stripeWeb2Support?.isSupport &&
|
|
138
|
+
kycApproved &&
|
|
142
139
|
!orderCreatedRef.current &&
|
|
143
140
|
!orderId &&
|
|
144
141
|
!isCreatingOrder &&
|
|
@@ -182,6 +179,7 @@ export function FiatCheckoutPanel({
|
|
|
182
179
|
isLoadingAnyspendQuote,
|
|
183
180
|
usdAmount,
|
|
184
181
|
stripeWeb2Support,
|
|
182
|
+
kycApproved,
|
|
185
183
|
orderId,
|
|
186
184
|
isCreatingOrder,
|
|
187
185
|
orderError,
|
|
@@ -232,6 +230,11 @@ export function FiatCheckoutPanel({
|
|
|
232
230
|
);
|
|
233
231
|
}
|
|
234
232
|
|
|
233
|
+
// KYC gate — shown before order creation when verification is needed
|
|
234
|
+
if (!kycApproved) {
|
|
235
|
+
return <KycGate themeColor={themeColor} classes={classes} enabled onStatusResolved={handleKycResolved} />;
|
|
236
|
+
}
|
|
237
|
+
|
|
235
238
|
// Order creation error - show with retry
|
|
236
239
|
if (orderError) {
|
|
237
240
|
return (
|