@funkit/connect 9.9.0 → 9.11.0-next.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/chunk-64NZSUGQ.js +368 -0
  3. package/dist/chunk-B2B6HDIE.js +238 -0
  4. package/dist/chunk-OQNN7EMQ.js +238 -0
  5. package/dist/chunk-S65TG73G.js +247 -0
  6. package/dist/chunk-VLAOBEJN.js +247 -0
  7. package/dist/clients/chunk-3LSYVQXK.js +289 -0
  8. package/dist/clients/chunk-5HU2XDR2.js +289 -0
  9. package/dist/clients/chunk-DKWYHSW3.js +225 -0
  10. package/dist/clients/chunk-IPK5DVIL.js +229 -0
  11. package/dist/clients/chunk-PVOHWTSR.js +289 -0
  12. package/dist/clients/chunk-SBQ2UUPK.js +214 -0
  13. package/dist/clients/fanatics.css +1 -1
  14. package/dist/clients/fanatics.js +1 -1
  15. package/dist/clients/lighter.css +1 -1
  16. package/dist/clients/lighter.d.ts +35 -28
  17. package/dist/clients/lighter.js +122 -26
  18. package/dist/clients/rolly.d.ts +42 -0
  19. package/dist/clients/rolly.js +91 -0
  20. package/dist/components/Dropdown/TokenAndChainDropdown.css.d.ts +1 -0
  21. package/dist/hooks/queries/useSwappedExchanges.d.ts +14 -0
  22. package/dist/hooks/statsig/checkFeatureGate.d.ts +19 -0
  23. package/dist/hooks/track/CheckoutTrackingContext.d.ts +60 -0
  24. package/dist/hooks/useExchangeOptions.d.ts +10 -0
  25. package/dist/hooks/useTokenChain.d.ts +21 -0
  26. package/dist/index.css +10 -10
  27. package/dist/index.js +97 -60
  28. package/dist/modals/CheckoutModal/SwappedIframe/SwappedIframeContainer.d.ts +17 -0
  29. package/dist/modals/WithdrwalModal/WithdrawalCallbackSuccess.d.ts +10 -0
  30. package/dist/modals/WithdrwalModal/WithdrawalContent.d.ts +11 -0
  31. package/dist/modals/WithdrwalModal/WithdrawalModal.d.ts +9 -0
  32. package/dist/modals/WithdrwalModal/WithdrawalSuccess.d.ts +15 -0
  33. package/dist/modals/WithdrwalModal/types.d.ts +5 -0
  34. package/dist/modals/WithdrwalModal/useWithdrawal.d.ts +24 -0
  35. package/dist/utils/openExternalFlowPopup.d.ts +21 -0
  36. package/dist/utils/polymarket.d.ts +6 -0
  37. package/dist/wallets/walletConnectors/chunk-34HACM5U.js +110 -0
  38. package/dist/wallets/walletConnectors/chunk-4C7ER452.js +93 -0
  39. package/dist/wallets/walletConnectors/chunk-53VYSPXK.js +66 -0
  40. package/dist/wallets/walletConnectors/chunk-5TN5Z2WY.js +87 -0
  41. package/dist/wallets/walletConnectors/chunk-6DRCY52E.js +69 -0
  42. package/dist/wallets/walletConnectors/chunk-6UCI7GM6.js +98 -0
  43. package/dist/wallets/walletConnectors/chunk-6YO27XOM.js +96 -0
  44. package/dist/wallets/walletConnectors/chunk-7OARWILZ.js +92 -0
  45. package/dist/wallets/walletConnectors/chunk-7V33VJAL.js +218 -0
  46. package/dist/wallets/walletConnectors/chunk-APHCF4DT.js +103 -0
  47. package/dist/wallets/walletConnectors/chunk-CJJT7LMT.js +96 -0
  48. package/dist/wallets/walletConnectors/chunk-DEFRRPXB.js +98 -0
  49. package/dist/wallets/walletConnectors/chunk-EKJHJFRN.js +69 -0
  50. package/dist/wallets/walletConnectors/chunk-FG2LDVXL.js +92 -0
  51. package/dist/wallets/walletConnectors/chunk-GH4M6FTK.js +95 -0
  52. package/dist/wallets/walletConnectors/chunk-GSHSWVEG.js +70 -0
  53. package/dist/wallets/walletConnectors/chunk-GVOQTORD.js +87 -0
  54. package/dist/wallets/walletConnectors/chunk-HETS3KKI.js +218 -0
  55. package/dist/wallets/walletConnectors/chunk-HOPH3TQ3.js +99 -0
  56. package/dist/wallets/walletConnectors/chunk-HRDPUW3V.js +94 -0
  57. package/dist/wallets/walletConnectors/chunk-HXWUH73P.js +93 -0
  58. package/dist/wallets/walletConnectors/chunk-IICWJWGZ.js +110 -0
  59. package/dist/wallets/walletConnectors/chunk-KO56HCTI.js +106 -0
  60. package/dist/wallets/walletConnectors/chunk-KWX2SYU2.js +100 -0
  61. package/dist/wallets/walletConnectors/chunk-LCIPVVH5.js +70 -0
  62. package/dist/wallets/walletConnectors/chunk-LI6QY2B5.js +94 -0
  63. package/dist/wallets/walletConnectors/chunk-PKMAPNN6.js +92 -0
  64. package/dist/wallets/walletConnectors/chunk-T4ROGPMF.js +106 -0
  65. package/dist/wallets/walletConnectors/chunk-TTHM3WUR.js +100 -0
  66. package/dist/wallets/walletConnectors/chunk-UDTBQV4Q.js +96 -0
  67. package/dist/wallets/walletConnectors/chunk-V6UOWTEZ.js +95 -0
  68. package/dist/wallets/walletConnectors/chunk-VJZWNQOF.js +92 -0
  69. package/dist/wallets/walletConnectors/chunk-XBLHZICW.js +103 -0
  70. package/dist/wallets/walletConnectors/chunk-XVBSJCW5.js +96 -0
  71. package/dist/wallets/walletConnectors/chunk-YIEASHLS.js +99 -0
  72. package/dist/wallets/walletConnectors/chunk-ZPSPK6LH.js +66 -0
  73. package/dist/wallets/walletConnectors/index.js +61 -61
  74. package/package.json +3 -3
  75. /package/dist/clients/{chunk-LMEQD56M.js → chunk-GCAV3VTB.js} +0 -0
@@ -14,6 +14,7 @@
14
14
  * caller provides the actual on-chain implementation.
15
15
  */
16
16
  import type { LighterAccountIndex } from '@funkit/api-base';
17
+ import type { Address } from 'viem';
17
18
  import type { CustomWithdrawalConfig, MultiMethodWithdrawalConfig } from '../providers/FunkitCheckoutContext/types';
18
19
  export type LighterTransferParams = {
19
20
  toAccountIndex: number;
@@ -38,13 +39,18 @@ export type LighterSigner = {
38
39
  transfer: (params: LighterTransferParams) => Promise<[unknown, string, string | null]>;
39
40
  };
40
41
  export interface LighterWithdrawalConfig {
41
- accountIndex: string;
42
+ /**
43
+ * The connected user's L1 address. The hook resolves the Lighter account
44
+ * index from this internally — get it from `useFunkitUserInfo` (or your
45
+ * own wallet hook) in the caller and pass it through.
46
+ */
47
+ l1Address: Address;
42
48
  /** Title shown on the selection screen. Defaults to "Withdraw". */
43
49
  modalTitle?: string;
44
50
  disableConnectedWallet?: boolean;
45
51
  fastIconSrc?: string;
46
52
  secureIconSrc?: string;
47
- /** Pre-built Lighter signer. l1Address and accountIndex are resolved internally. */
53
+ /** Pre-built Lighter signer. */
48
54
  signerClient: LighterSigner;
49
55
  sendLighterSecureWithdrawal: LighterSecureWithdrawalExec;
50
56
  /**
@@ -54,8 +60,14 @@ export interface LighterWithdrawalConfig {
54
60
  * getSecureMinWithdrawalAmount: (symbol) => ({ USDC: 1, ETH: 0.001 }[symbol] ?? 0)
55
61
  * ```
56
62
  */
57
- getSecureMinWithdrawalAmount?: (symbol: string) => number;
63
+ getSecureMinWithdrawalAmount?: (symbol: string) => number | undefined;
58
64
  }
65
+ /**
66
+ * Default minimum Secure-withdrawal amounts (token units) for known Lighter
67
+ * assets. Used as a fallback when `LighterWithdrawalConfig.getSecureMinWithdrawalAmount`
68
+ * is omitted or returns `undefined` for a symbol.
69
+ */
70
+ export declare const LIGHTER_DEFAULT_SECURE_MIN_WITHDRAWAL_AMOUNTS: Record<string, number>;
59
71
  export interface LighterSecureWithdrawalCallbackParams {
60
72
  /** Withdrawal amount in token units (e.g. "1.5" for 1.5 ETH). */
61
73
  amountTokenUnits: string;
@@ -100,35 +112,30 @@ export declare function useLighterWithdrawalBalances({ accountIndex, }: {
100
112
  /** Single-method config for Lighter's Secure withdrawal (bridge to Ethereum). */
101
113
  export declare function createLighterSecureWithdrawalConfig(config: LighterSecureWithdrawalConfig): CustomWithdrawalConfig;
102
114
  /**
103
- * Hook version of {@link createLighterWithdrawalConfig}.
115
+ * The single React entry point for Lighter withdrawals. Returns a
116
+ * `MultiMethodWithdrawalConfig` ready to hand to the withdrawal modal, or
117
+ * `null` while the inputs aren't ready yet.
104
118
  *
105
- * Fetches all Lighter asset balances for `config.accountIndex` and injects them as
106
- * `withdrawalSourceTokenBalance` into each method's config so the withdrawal
107
- * form displays and validates against the real Lighter account balance.
119
+ * The hook owns every Lighter-specific concern that requires React context:
120
+ * - the user's Lighter account index (resolved from `config.l1Address`)
121
+ * - all Lighter asset balances (so the form validates against the real
122
+ * account)
123
+ * - the live Secure-withdrawal delay (`/api/v1/withdrawalDelay`)
124
+ * - the active locale (so the disclaimer renders correctly)
108
125
  *
109
- * Drop-in replacement for `createLighterWithdrawalConfig` call it in any
110
- * React component/hook and pass the result directly to the withdrawal modal:
126
+ * Pass `null` while prerequisites (wallet, signer, etc.) aren't ready — the
127
+ * hook always invokes its inner hooks (Rules of Hooks) and returns `null`
128
+ * until you supply a real config and the account resolves:
111
129
  *
112
130
  * ```tsx
113
- * const withdrawalConfig = useLighterWithdrawalConfig({
114
- * accountIndex,
115
- * sendLighterSecureWithdrawal: ...,
116
- * })
117
- * <WithdrawalModal config={withdrawalConfig} ... />
118
- * ```
119
- */
120
- export declare function useLighterWithdrawalConfig(config: LighterWithdrawalConfig): MultiMethodWithdrawalConfig;
121
- /**
122
- * Creates a full {@link MultiMethodWithdrawalConfig} for Lighter that renders
123
- * the Fast vs Secure selection screen before the standard withdrawal flow.
124
- *
125
- * Usage:
126
- * ```ts
127
- * const withdrawalConfig = createLighterWithdrawalConfig({
128
- * accountIndex: '0',
129
- * sendLighterSecureWithdrawal: async ({ amountTokenUnits, assetIndex }) => { ... },
130
- * })
131
+ * const { address: l1Address } = useFunkitUserInfo()
132
+ * const lighter = useLighterWithdrawalConfig(
133
+ * userId && walletClient
134
+ * ? { l1Address, signerClient, sendLighterSecureWithdrawal, ... }
135
+ * : null,
136
+ * )
137
+ * if (!lighter) return { ready: false, disabledReason: '...' }
131
138
  * ```
132
139
  */
133
- export declare function createLighterWithdrawalConfig(config: LighterWithdrawalConfig): MultiMethodWithdrawalConfig;
140
+ export declare function useLighterWithdrawalConfig(config: LighterWithdrawalConfig | null): MultiMethodWithdrawalConfig | null;
134
141
  export {};
@@ -3,7 +3,7 @@ import {
3
3
  AsyncImage,
4
4
  Box,
5
5
  useFunkitTranslation
6
- } from "./chunk-LMEQD56M.js";
6
+ } from "./chunk-GCAV3VTB.js";
7
7
  import {
8
8
  logger
9
9
  } from "./chunk-H6F75ULR.js";
@@ -12,6 +12,7 @@ import {
12
12
  import { SOLANA_MAINNET_CHAIN_ID } from "@funkit/chains";
13
13
  import { RELAY_LIGHTER_CHAIN_ID } from "@funkit/fun-relay";
14
14
  import { retry } from "@lifeomic/attempt";
15
+ import { useQuery as useQuery2 } from "@tanstack/react-query";
15
16
  import i18next from "i18next";
16
17
  import React2, { useEffect, useMemo as useMemo2 } from "react";
17
18
  import { arbitrum, base, bsc, mainnet as mainnet2, optimism } from "viem/chains";
@@ -238,6 +239,16 @@ function useFunkitConfig() {
238
239
  }
239
240
 
240
241
  // src/utils/customer.ts
242
+ async function getLighterAccountsByL1Address(address) {
243
+ const response = await fetch(
244
+ `https://mainnet.zklighter.elliot.ai/api/v1/accountsByL1Address?l1_address=${address}`
245
+ );
246
+ if (!response.ok) {
247
+ throw new Error(`Failed to fetch lighter accounts: ${response.statusText}`);
248
+ }
249
+ const data = await response.json();
250
+ return data;
251
+ }
241
252
  async function getLighterAccount(lookup, activeOnly) {
242
253
  const params = new URLSearchParams({
243
254
  by: lookup.by,
@@ -274,11 +285,75 @@ function useLighterAccount(lookup, options) {
274
285
  account: query.data?.accounts?.[0]
275
286
  };
276
287
  }
288
+ function useLighterAccounts({
289
+ address
290
+ }) {
291
+ const { apiKey } = useFunkitConfig();
292
+ const isLighter = isLighterxyzCustomer(apiKey);
293
+ const enabled = !!address && address !== "0x" && isLighter;
294
+ const query = useQuery({
295
+ queryKey: ["lighterAccounts", address],
296
+ queryFn: () => getLighterAccountsByL1Address(address),
297
+ enabled,
298
+ staleTime: Number.POSITIVE_INFINITY,
299
+ gcTime: Number.POSITIVE_INFINITY,
300
+ retry: false,
301
+ // allows us to always refetch the data but return the previous data until the new data is fetched
302
+ refetchOnMount: "always"
303
+ });
304
+ return {
305
+ ...query,
306
+ mainAccountIndex: query.data?.sub_accounts?.[0]?.index?.toString(),
307
+ subAccounts: query.data?.sub_accounts
308
+ };
309
+ }
310
+
311
+ // src/utils/timeFormat.ts
312
+ import { formatSecondsToReadableForm } from "@funkit/utils";
313
+ function formatSecondsTranslated(seconds, t, specifyUnderMinute = false, omitSeconds = false) {
314
+ return formatSecondsToReadableForm(seconds, specifyUnderMinute, omitSeconds, {
315
+ lessThanOneMin: t("time.lessThanOneMin"),
316
+ seconds: (count) => t("time.seconds", { count }),
317
+ minutes: (count) => t("time.minutes", { count }),
318
+ hours: (count) => t("time.hours", { count }),
319
+ secondsShort: (count) => t("time.secondsShort", { count })
320
+ });
321
+ }
277
322
 
278
323
  // src/clients/lighter.tsx
279
324
  var LIGHTER_USDC_PERPS_ADDRESS = "0x0000000000000000000000000000000000000000";
280
325
  var MAINNET_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
281
326
  var LIGHTER_API_BASE = "https://mainnet.zklighter.elliot.ai";
327
+ async function getLighterWithdrawalDelay() {
328
+ const response = await fetch(`${LIGHTER_API_BASE}/api/v1/withdrawalDelay`);
329
+ if (!response.ok) {
330
+ throw new Error(
331
+ `Failed to fetch Lighter withdrawal delay: ${response.statusText}`
332
+ );
333
+ }
334
+ return response.json();
335
+ }
336
+ function useLighterSecureDelayText() {
337
+ const { t } = useFunkitTranslation();
338
+ const query = useQuery2({
339
+ queryKey: ["lighterWithdrawalDelay"],
340
+ queryFn: getLighterWithdrawalDelay,
341
+ staleTime: 6e4,
342
+ retry: 2
343
+ });
344
+ const seconds = query.data?.seconds;
345
+ if (seconds === void 0 || !Number.isFinite(seconds) || seconds <= 0) {
346
+ return void 0;
347
+ }
348
+ return formatSecondsTranslated(
349
+ seconds,
350
+ t,
351
+ /*specifyUnderMinutes*/
352
+ false,
353
+ /*omitSeconds*/
354
+ true
355
+ );
356
+ }
282
357
  var LIGHTER_TX_STATUS = {
283
358
  PENDING: 0,
284
359
  QUEUED: 1,
@@ -402,15 +477,20 @@ function createLighterAdaptedWallet({
402
477
  }
403
478
  };
404
479
  }
480
+ var LIGHTER_DEFAULT_SECURE_MIN_WITHDRAWAL_AMOUNTS = {
481
+ USDC: 1,
482
+ ETH: 1e-3,
483
+ LIT: 1,
484
+ LINK: 0.1,
485
+ UNI: 0.2,
486
+ AAVE: 0.01,
487
+ SKY: 20,
488
+ LDO: 2,
489
+ AZTEC: 100
490
+ };
405
491
  function freeBalance(balance, lockedBalance) {
406
492
  return String(Math.max(0, Number(balance) - Number(lockedBalance)));
407
493
  }
408
- function asLighterAccountIndex(s) {
409
- if (!/^\d+$/.test(s)) {
410
- throw new Error(`Invalid LighterAccountIndex: ${s}`);
411
- }
412
- return s;
413
- }
414
494
  function useLighterWithdrawalBalances({
415
495
  accountIndex
416
496
  }) {
@@ -578,23 +658,31 @@ var LIGHTER_FAST_PREVIEW_CHAIN_IDS = [
578
658
  var LIGHTER_SECURE_PREVIEW_CHAIN_IDS = [mainnet2.id];
579
659
  function buildLighterMultiMethodConfig({
580
660
  config,
661
+ accountIndex,
581
662
  t,
582
- withBalance
663
+ withBalance,
664
+ secureDelayText
583
665
  }) {
584
666
  const fastConfig = buildLighterFastWalletWithdrawalConfig({
585
667
  signerClient: config.signerClient,
586
- accountIndex: Number(config.accountIndex),
668
+ accountIndex: Number(accountIndex),
587
669
  modalTitle: config.modalTitle,
588
670
  disableConnectedWallet: config.disableConnectedWallet,
589
671
  iconSrc: config.fastIconSrc
590
672
  });
591
673
  const secureConfig = createLighterSecureWithdrawalConfig({
592
- accountIndex: config.accountIndex,
674
+ accountIndex,
593
675
  modalTitle: config.modalTitle,
594
676
  disableConnectedWallet: config.disableConnectedWallet,
595
677
  iconSrc: config.secureIconSrc,
596
678
  sendLighterSecureWithdrawal: config.sendLighterSecureWithdrawal,
597
- getMinWithdrawalAmount: config.getSecureMinWithdrawalAmount
679
+ getMinWithdrawalAmount: (symbol) => {
680
+ const userMin = config.getSecureMinWithdrawalAmount?.(symbol);
681
+ if (userMin !== void 0) {
682
+ return userMin;
683
+ }
684
+ return LIGHTER_DEFAULT_SECURE_MIN_WITHDRAWAL_AMOUNTS[symbol.toUpperCase()] ?? 0;
685
+ }
598
686
  });
599
687
  const fast = {
600
688
  id: "lighter-fast",
@@ -612,7 +700,12 @@ function buildLighterMultiMethodConfig({
612
700
  const secure = {
613
701
  id: "lighter-secure",
614
702
  keyText: t("withdrawal.methodSecure"),
615
- subtitleText: t("withdrawal.secureDisclaimer"),
703
+ subtitleText: t("withdrawal.secureDisclaimer", {
704
+ // Until the live value loads, show the localized "60+ minutes"
705
+ // historical estimate. The "+" lives in the per-locale fallback string
706
+ // so it doesn't bleed into live values, which are exact.
707
+ delay: secureDelayText ?? t("withdrawal.secureFallbackDelay")
708
+ }),
616
709
  icon: /* @__PURE__ */ React2.createElement(EvmWallet, { size: 20 }),
617
710
  valueIcon: /* @__PURE__ */ React2.createElement(ChainIconStack, { chainIds: LIGHTER_SECURE_PREVIEW_CHAIN_IDS }),
618
711
  config: withBalance ? {
@@ -630,27 +723,30 @@ function buildLighterMultiMethodConfig({
630
723
  }
631
724
  function useLighterWithdrawalConfig(config) {
632
725
  const { t } = useFunkitTranslation();
726
+ const { mainAccountIndex } = useLighterAccounts({
727
+ address: config?.l1Address
728
+ });
729
+ const accountIndex = mainAccountIndex && /^\d+$/.test(mainAccountIndex) ? mainAccountIndex : void 0;
633
730
  const { balances } = useLighterWithdrawalBalances({
634
- accountIndex: asLighterAccountIndex(config.accountIndex)
731
+ accountIndex
635
732
  });
636
- return useMemo2(
637
- () => buildLighterMultiMethodConfig({
733
+ const secureDelayText = useLighterSecureDelayText();
734
+ return useMemo2(() => {
735
+ if (!config || !accountIndex) {
736
+ return null;
737
+ }
738
+ return buildLighterMultiMethodConfig({
638
739
  config,
740
+ accountIndex,
639
741
  t,
640
- withBalance: (symbol) => () => balances[symbol.toUpperCase()] ?? "0"
641
- }),
642
- [config, balances, t]
643
- );
644
- }
645
- function createLighterWithdrawalConfig(config) {
646
- return buildLighterMultiMethodConfig({
647
- config,
648
- t: i18next.t.bind(i18next)
649
- });
742
+ withBalance: (symbol) => () => balances[symbol.toUpperCase()] ?? "0",
743
+ secureDelayText
744
+ });
745
+ }, [config, accountIndex, balances, t, secureDelayText]);
650
746
  }
651
747
  export {
748
+ LIGHTER_DEFAULT_SECURE_MIN_WITHDRAWAL_AMOUNTS,
652
749
  createLighterSecureWithdrawalConfig,
653
- createLighterWithdrawalConfig,
654
750
  freeBalance,
655
751
  useLighterWithdrawalBalances,
656
752
  useLighterWithdrawalConfig
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Rolly deposit via VaultDepositor.
3
+ *
4
+ * Deposit flow wraps Rolly's `depositToken()` call inside the VaultDepositor
5
+ * proxy so it composes with EXACT_INPUT quoting:
6
+ * 1. approve(USDT, VAULT_DEPOSITOR[mainnet], MAX)
7
+ * 2. VAULT_DEPOSITOR[mainnet].deposit(USDT, ROLLY_VAULT,
8
+ * depositToken(recipient, AMOUNT_PLACEHOLDER), 0)
9
+ * VaultDepositor pulls the msg.sender's full USDT balance at exec time and
10
+ * substitutes AMOUNT_PLACEHOLDER with the actual amount before calling
11
+ * Rolly.depositToken, so the arrival amount doesn't need to be known at quote
12
+ * time.
13
+ */
14
+ import { type Address } from 'viem';
15
+ import type { FunkitCheckoutActionParams } from '../providers/FunkitCheckoutContext/types';
16
+ /** Rolly rollup deposit contract on Ethereum mainnet (UUPS proxy). */
17
+ export declare const ROLLY_VAULT_ADDRESS: `0x${string}`;
18
+ /** Ethereum mainnet USDT — Rolly's source deposit token. */
19
+ export declare const MAINNET_USDT: `0x${string}`;
20
+ /** VaultDepositor on Ethereum mainnet — same address used by other VaultDepositor flows. */
21
+ export declare const VAULT_DEPOSITOR_MAINNET: `0x${string}`;
22
+ /** Sentinel value the VaultDepositor replaces with the actual deposit amount at exec time. */
23
+ export declare const AMOUNT_PLACEHOLDER = 115792089237316195423570985008687907853269984665640564039457584007912570601199n;
24
+ export interface RollyDepositActionsConfig {
25
+ /** Address credited on the Rolly rollup (typically the connected wallet). */
26
+ recipientAddress: Address | undefined;
27
+ }
28
+ /**
29
+ * Builds the `generateActionsParams` callback for a Rolly deposit routed
30
+ * through VaultDepositor.
31
+ *
32
+ * Usage:
33
+ * ```ts
34
+ * const checkoutConfig: FunkitCheckoutConfig = {
35
+ * // ...
36
+ * generateActionsParams: createRollyDepositActions({
37
+ * recipientAddress: walletAddress,
38
+ * }),
39
+ * }
40
+ * ```
41
+ */
42
+ export declare function createRollyDepositActions(config: RollyDepositActionsConfig): () => Promise<FunkitCheckoutActionParams[]>;
@@ -0,0 +1,91 @@
1
+ "use client";
2
+
3
+ // src/clients/rolly.tsx
4
+ import {
5
+ encodeFunctionData,
6
+ erc20Abi,
7
+ getAddress,
8
+ maxUint256
9
+ } from "viem";
10
+ var ROLLY_VAULT_ADDRESS = getAddress(
11
+ "0x6e6B003F801c4532350858431d893B04317734C4"
12
+ );
13
+ var MAINNET_USDT = getAddress(
14
+ "0xdAC17F958D2ee523a2206206994597C13D831ec7"
15
+ );
16
+ var VAULT_DEPOSITOR_MAINNET = getAddress(
17
+ "0x64Aa32cd125FB32F4286d2bAC3a7346edFffEe2A"
18
+ );
19
+ var AMOUNT_PLACEHOLDER = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeadbeefn;
20
+ var ROLLY_VAULT_ABI = [
21
+ {
22
+ name: "depositToken",
23
+ type: "function",
24
+ stateMutability: "nonpayable",
25
+ inputs: [
26
+ { name: "to", type: "address" },
27
+ { name: "amount", type: "uint256" }
28
+ ],
29
+ outputs: []
30
+ }
31
+ ];
32
+ var VAULT_DEPOSITOR_ABI = [
33
+ {
34
+ name: "deposit",
35
+ type: "function",
36
+ stateMutability: "nonpayable",
37
+ inputs: [
38
+ { name: "token", type: "address" },
39
+ { name: "vault", type: "address" },
40
+ { name: "callData", type: "bytes" },
41
+ { name: "minAmountOut", type: "uint256" }
42
+ ],
43
+ outputs: [{ name: "returnData", type: "bytes" }]
44
+ }
45
+ ];
46
+ function createRollyDepositActions(config) {
47
+ const { recipientAddress } = config;
48
+ return async () => {
49
+ if (!recipientAddress) {
50
+ throw new Error(
51
+ "Please connect your wallet before starting a Rolly deposit"
52
+ );
53
+ }
54
+ const depositCalldata = encodeFunctionData({
55
+ abi: ROLLY_VAULT_ABI,
56
+ functionName: "depositToken",
57
+ args: [recipientAddress, AMOUNT_PLACEHOLDER]
58
+ });
59
+ return [
60
+ // Step 1: Reset USDT approval
61
+ {
62
+ contractAbi: erc20Abi,
63
+ contractAddress: MAINNET_USDT,
64
+ functionName: "approve",
65
+ functionArgs: [VAULT_DEPOSITOR_MAINNET, 0n]
66
+ },
67
+ // Step 2: Approve USDT to VaultDepositor (infinite)
68
+ {
69
+ contractAbi: erc20Abi,
70
+ contractAddress: MAINNET_USDT,
71
+ functionName: "approve",
72
+ functionArgs: [VAULT_DEPOSITOR_MAINNET, maxUint256]
73
+ },
74
+ // Step 3: VaultDepositor pulls USDT, swaps placeholder, forwards to
75
+ // Rolly.depositToken → credits recipient on the rollup
76
+ {
77
+ contractAbi: VAULT_DEPOSITOR_ABI,
78
+ contractAddress: VAULT_DEPOSITOR_MAINNET,
79
+ functionName: "deposit",
80
+ functionArgs: [MAINNET_USDT, ROLLY_VAULT_ADDRESS, depositCalldata, 0n]
81
+ }
82
+ ];
83
+ };
84
+ }
85
+ export {
86
+ AMOUNT_PLACEHOLDER,
87
+ MAINNET_USDT,
88
+ ROLLY_VAULT_ADDRESS,
89
+ VAULT_DEPOSITOR_MAINNET,
90
+ createRollyDepositActions
91
+ };
@@ -0,0 +1 @@
1
+ export declare const hideOnXsmallScreenSize: string;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Fetches Swapped exchange options by calling /fops with a CRYPTO_TO_CRYPTO
3
+ * rail config. The rail config is what causes the backend to return exchange
4
+ * FOPs (e.g. Bybit); however, this hook does not guard against the backend
5
+ * returning non-Swapped or non-exchange FOPs in the future — callers should
6
+ * be aware that the response may evolve as the BE adds rail types.
7
+ *
8
+ * Gated by the `enable-swapped-exchanges` Statsig feature gate — when off,
9
+ * the query is disabled and the response is empty.
10
+ */
11
+ export declare const useSwappedExchanges: () => import("@tanstack/react-query").UseQueryResult<{
12
+ genericFormsOfPayments: import("@funkit/api-base").GenericFormOfPayment[];
13
+ savedFormsOfPayments: never[];
14
+ }, Error>;
@@ -0,0 +1,19 @@
1
+ import fallbackFeatureGates from '../../__generated__/default_feature_gates';
2
+ type FeatureGateName = keyof typeof fallbackFeatureGates;
3
+ /**
4
+ * Synchronous, non-hook variant of {@link useFeatureGate}. Reads the gate
5
+ * value directly from the connect package's Statsig client singleton.
6
+ *
7
+ * Use this from non-React contexts (event handlers, async callbacks created
8
+ * outside render) where calling a hook is not possible. Behavior:
9
+ * - Returns the live gate value once `FunkitStatsigProvider`'s async init
10
+ * has resolved (typical case for event-driven calls — by the time a user
11
+ * clicks a button, init has long since completed).
12
+ * - Returns the bundled default if called before init completes or if the
13
+ * provider has not been mounted (graceful fallback rather than throw).
14
+ *
15
+ * For render-time consumers, prefer {@link useFeatureGate} so the consumer
16
+ * re-renders when values update mid-session.
17
+ */
18
+ export declare function checkFeatureGate(name: FeatureGateName): boolean;
19
+ export {};
@@ -0,0 +1,60 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import type { FunCheckoutStep } from '../../modals/CheckoutModal/FunCheckoutStep';
3
+ /**
4
+ * Read-only per-session metadata auto-attached by {@link useTrack} to every
5
+ * Statsig event emitted inside the checkout modal tree. All three fields
6
+ * already exist on the state machine — this context just surfaces them:
7
+ *
8
+ * - `checkoutId` — `modalState.checkoutId` (client-generated UUID from
9
+ * `initNewCheckout`). Joins Statsig events to
10
+ * `analytics.checkouts` in Redshift.
11
+ * - `step` — `modalState.step` (current `FunCheckoutStep`).
12
+ * - `modalOpenedAt` — `checkoutItem.startTimestampMs`. `useTrack` derives
13
+ * `time_since_modal_ms` = `Date.now() - modalOpenedAt`
14
+ * at emission time.
15
+ *
16
+ * Outside the provider (e.g. `useTrack` called from a non-checkout surface)
17
+ * every field is `null` and `useTrack` elides the attachment.
18
+ */
19
+ export interface CheckoutTrackingContextValue {
20
+ checkoutId: string | null;
21
+ step: FunCheckoutStep | null;
22
+ modalOpenedAt: number | null;
23
+ }
24
+ interface CheckoutTrackingProviderProps extends CheckoutTrackingContextValue {
25
+ children: ReactNode;
26
+ }
27
+ /**
28
+ * Root provider. Memoizes `value` against the three primitive fields so
29
+ * consumers only re-render when one of them actually changes (not on
30
+ * every parent render). The three fields are already-derived state owned
31
+ * by `FunCheckoutModal` / `useCheckoutModalTransition`; we surface them
32
+ * here rather than duplicating storage.
33
+ */
34
+ export declare function CheckoutTrackingProvider({ children, checkoutId, step, modalOpenedAt, }: CheckoutTrackingProviderProps): React.JSX.Element;
35
+ export declare function useCheckoutTrackingContext(): CheckoutTrackingContextValue;
36
+ /**
37
+ * Build the shared-metadata fields (`checkoutId`, `step`,
38
+ * `time_since_modal_ms`) inline at emission sites that run *outside* this
39
+ * provider and therefore can't use `useTrack`'s auto-attach.
40
+ *
41
+ * Those sites are:
42
+ * - `FunkitCheckoutContext.initNewCheckout` — modal not mounted yet
43
+ * - `FunkitCheckoutContext.confirmCheckout` — app-level, above the modal
44
+ * - `useCheckoutModalTransition.{trackNextState,onBack,onCloseWrapper}` —
45
+ * the hook that *produces* the provider's value; it cannot also
46
+ * consume it
47
+ *
48
+ * Keep this as a pure helper — no hooks. The three fields mirror the
49
+ * contract in {@link CheckoutTrackingContextValue}; any new auto-attached
50
+ * field should be added to both in the same commit.
51
+ */
52
+ export declare function buildCheckoutSessionMetadata(checkoutItem: {
53
+ id: string;
54
+ startTimestampMs: number;
55
+ }, step: FunCheckoutStep): {
56
+ checkoutId: string;
57
+ step: FunCheckoutStep;
58
+ time_since_modal_ms: string;
59
+ };
60
+ export {};
@@ -0,0 +1,10 @@
1
+ import { type BrokerageOption } from '../consts/bluvo';
2
+ /**
3
+ * Unified brokerage list combining static Bluvo exchanges and dynamic
4
+ * Swapped Connect FOPs (CRYPTO_TO_CRYPTO). Used by SelectBrokerage and the
5
+ * payment-method preview row. Live entries come first; ComingSoon (and
6
+ * FOPs that came back without an embeddedFlowUrl) follow.
7
+ */
8
+ export declare function useExchangeOptions({ iconSize, }: {
9
+ iconSize: number;
10
+ }): BrokerageOption[];
@@ -0,0 +1,21 @@
1
+ import type { CheckoutInitTokenTransferResponse } from '@funkit/api-base';
2
+ import type { TokenTransferSourceChainsAndAssets } from '../modals/CheckoutModal/TransferToken/TransferToken';
3
+ export type TransferTokenDefault = {
4
+ token: string;
5
+ chainId: number;
6
+ };
7
+ interface UseTokenChainResult {
8
+ assets: TokenTransferSourceChainsAndAssets;
9
+ selectedChainId: number;
10
+ handleChainChange: (chainId?: number, autoUpdate?: boolean) => void;
11
+ selectedToken: string;
12
+ selectedChainName: string;
13
+ handleTokenChange: (token: string, chainId?: number, autoUpdate?: boolean) => void;
14
+ }
15
+ /**
16
+ * Semi reusable hook (tied into token transfer configuration)
17
+ * ensures token&chain dropdown preselection logic is reusable
18
+ * @param transferInit - used for chain&token solana filtering, can be omitted if not needed
19
+ */
20
+ export declare const useTokenAndChainSelection: (transferInit: CheckoutInitTokenTransferResponse | undefined, defaultValues?: TransferTokenDefault, isWithdrawal?: boolean) => UseTokenChainResult;
21
+ export {};