@funkit/connect 9.7.2-next.1 → 9.9.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 (112) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/dist/__generated__/default_configs.d.ts +1 -1
  3. package/dist/__generated__/default_feature_gates.d.ts +2 -0
  4. package/dist/clients/chunk-LMEQD56M.js +289 -0
  5. package/dist/clients/fanatics.css +1 -1
  6. package/dist/clients/fanatics.js +55 -329
  7. package/dist/clients/lighter.css +4775 -4775
  8. package/dist/clients/lighter.d.ts +30 -34
  9. package/dist/clients/lighter.js +163 -69
  10. package/dist/components/ApprovalMethodToggle/ApprovalMethodToggle.d.ts +19 -0
  11. package/dist/components/Dropdown/BaseActiveDropdownItem.d.ts +2 -1
  12. package/dist/components/Dropdown/BaseDropdown.d.ts +11 -23
  13. package/dist/components/Dropdown/BaseDropdown.utils.d.ts +23 -0
  14. package/dist/components/Dropdown/ChainDropdown.d.ts +2 -1
  15. package/dist/components/Dropdown/TokenAndChainDropdown.d.ts +9 -3
  16. package/dist/components/Dropdown/TokenDropdown.d.ts +7 -3
  17. package/dist/domains/asset.d.ts +0 -1
  18. package/dist/domains/quote.d.ts +9 -1
  19. package/dist/domains/quoteMode/exactOut.d.ts +2 -1
  20. package/dist/domains/quoteMode/resolveQuoteMode.d.ts +3 -1
  21. package/dist/hooks/queries/useWithdrawalQuote.d.ts +2 -8
  22. package/dist/hooks/useCheckoutDirectExecution.d.ts +8 -1
  23. package/dist/hooks/useIsStablecoin.d.ts +2 -0
  24. package/dist/hooks/useTokenAndChainDropdown.d.ts +13 -7
  25. package/dist/hooks/useTokenTransfer.d.ts +2 -2
  26. package/dist/index.css +99 -99
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +5847 -4800
  29. package/dist/modals/CheckoutModal/SourceChange/CryptoCashToggle.d.ts +2 -1
  30. package/dist/modals/CheckoutModal/TransferToken/useTransferTokenTracking.d.ts +2 -2
  31. package/dist/modals/WithdrawalModal/WithdrawalContent.d.ts +11 -1
  32. package/dist/modals/WithdrawalModal/useWithdrawal.d.ts +5 -1
  33. package/dist/providers/FunkitCheckoutContext/index.d.ts +1 -0
  34. package/dist/providers/FunkitCheckoutContext/types.d.ts +60 -2
  35. package/dist/providers/FunkitHistoryContext.d.ts +2 -2
  36. package/dist/providers/FunkitQuoteContext.d.ts +6 -0
  37. package/dist/utils/withdrawal.d.ts +6 -1
  38. package/dist/wallets/Wallet.d.ts +11 -0
  39. package/dist/wallets/walletConnectors/bifrostWallet/bifrostWallet.js +2 -2
  40. package/dist/wallets/walletConnectors/bitgetWallet/bitgetWallet.js +2 -2
  41. package/dist/wallets/walletConnectors/bybitWallet/bybitWallet.js +2 -2
  42. package/dist/wallets/walletConnectors/clvWallet/clvWallet.js +2 -2
  43. package/dist/wallets/walletConnectors/coin98Wallet/coin98Wallet.js +2 -2
  44. package/dist/wallets/walletConnectors/coreWallet/coreWallet.js +2 -2
  45. package/dist/wallets/walletConnectors/foxWallet/foxWallet.js +2 -2
  46. package/dist/wallets/walletConnectors/frontierWallet/frontierWallet.js +2 -2
  47. package/dist/wallets/walletConnectors/gateWallet/gateWallet.js +2 -2
  48. package/dist/wallets/walletConnectors/index.js +45 -45
  49. package/dist/wallets/walletConnectors/metaMaskWallet/metaMaskWallet.js +2 -2
  50. package/dist/wallets/walletConnectors/okxWallet/okxWallet.js +2 -2
  51. package/dist/wallets/walletConnectors/rainbowWallet/rainbowWallet.js +2 -2
  52. package/dist/wallets/walletConnectors/roninWallet/roninWallet.js +2 -2
  53. package/dist/wallets/walletConnectors/safepalWallet/safepalWallet.js +2 -2
  54. package/dist/wallets/walletConnectors/subWallet/subWallet.js +2 -2
  55. package/dist/wallets/walletConnectors/tokenPocketWallet/tokenPocketWallet.js +2 -2
  56. package/dist/wallets/walletConnectors/trustWallet/trustWallet.js +2 -2
  57. package/dist/wallets/walletConnectors/zerionWallet/zerionWallet.js +2 -2
  58. package/package.json +6 -5
  59. package/dist/chunk-64NZSUGQ.js +0 -368
  60. package/dist/chunk-B2B6HDIE.js +0 -238
  61. package/dist/chunk-OQNN7EMQ.js +0 -238
  62. package/dist/chunk-S65TG73G.js +0 -247
  63. package/dist/chunk-VLAOBEJN.js +0 -247
  64. package/dist/clients/chunk-3LSYVQXK.js +0 -289
  65. package/dist/clients/chunk-SBQ2UUPK.js +0 -214
  66. package/dist/clients/chunk-V526Q43Z.js +0 -271
  67. package/dist/components/Dropdown/TokenAndChainDropdown.css.d.ts +0 -1
  68. package/dist/hooks/track/CheckoutTrackingContext.d.ts +0 -60
  69. package/dist/hooks/useTokenChain.d.ts +0 -21
  70. package/dist/modals/CheckoutModal/SwappedIframe/SwappedIframeContainer.d.ts +0 -17
  71. package/dist/modals/WithdrwalModal/WithdrawalCallbackSuccess.d.ts +0 -10
  72. package/dist/modals/WithdrwalModal/WithdrawalContent.d.ts +0 -11
  73. package/dist/modals/WithdrwalModal/WithdrawalModal.d.ts +0 -9
  74. package/dist/modals/WithdrwalModal/WithdrawalSuccess.d.ts +0 -15
  75. package/dist/modals/WithdrwalModal/types.d.ts +0 -5
  76. package/dist/modals/WithdrwalModal/useWithdrawal.d.ts +0 -24
  77. package/dist/wallets/walletConnectors/chunk-34HACM5U.js +0 -110
  78. package/dist/wallets/walletConnectors/chunk-4C7ER452.js +0 -93
  79. package/dist/wallets/walletConnectors/chunk-53VYSPXK.js +0 -66
  80. package/dist/wallets/walletConnectors/chunk-5TN5Z2WY.js +0 -87
  81. package/dist/wallets/walletConnectors/chunk-6DRCY52E.js +0 -69
  82. package/dist/wallets/walletConnectors/chunk-6UCI7GM6.js +0 -98
  83. package/dist/wallets/walletConnectors/chunk-6YO27XOM.js +0 -96
  84. package/dist/wallets/walletConnectors/chunk-7OARWILZ.js +0 -92
  85. package/dist/wallets/walletConnectors/chunk-7V33VJAL.js +0 -218
  86. package/dist/wallets/walletConnectors/chunk-APHCF4DT.js +0 -103
  87. package/dist/wallets/walletConnectors/chunk-CJJT7LMT.js +0 -96
  88. package/dist/wallets/walletConnectors/chunk-DEFRRPXB.js +0 -98
  89. package/dist/wallets/walletConnectors/chunk-EKJHJFRN.js +0 -69
  90. package/dist/wallets/walletConnectors/chunk-FG2LDVXL.js +0 -92
  91. package/dist/wallets/walletConnectors/chunk-GH4M6FTK.js +0 -95
  92. package/dist/wallets/walletConnectors/chunk-GSHSWVEG.js +0 -70
  93. package/dist/wallets/walletConnectors/chunk-GVOQTORD.js +0 -87
  94. package/dist/wallets/walletConnectors/chunk-HETS3KKI.js +0 -218
  95. package/dist/wallets/walletConnectors/chunk-HOPH3TQ3.js +0 -99
  96. package/dist/wallets/walletConnectors/chunk-HRDPUW3V.js +0 -94
  97. package/dist/wallets/walletConnectors/chunk-HXWUH73P.js +0 -93
  98. package/dist/wallets/walletConnectors/chunk-IICWJWGZ.js +0 -110
  99. package/dist/wallets/walletConnectors/chunk-KO56HCTI.js +0 -106
  100. package/dist/wallets/walletConnectors/chunk-KWX2SYU2.js +0 -100
  101. package/dist/wallets/walletConnectors/chunk-LCIPVVH5.js +0 -70
  102. package/dist/wallets/walletConnectors/chunk-LI6QY2B5.js +0 -94
  103. package/dist/wallets/walletConnectors/chunk-PKMAPNN6.js +0 -92
  104. package/dist/wallets/walletConnectors/chunk-T4ROGPMF.js +0 -106
  105. package/dist/wallets/walletConnectors/chunk-TTHM3WUR.js +0 -100
  106. package/dist/wallets/walletConnectors/chunk-UDTBQV4Q.js +0 -96
  107. package/dist/wallets/walletConnectors/chunk-V6UOWTEZ.js +0 -95
  108. package/dist/wallets/walletConnectors/chunk-VJZWNQOF.js +0 -92
  109. package/dist/wallets/walletConnectors/chunk-XBLHZICW.js +0 -103
  110. package/dist/wallets/walletConnectors/chunk-XVBSJCW5.js +0 -96
  111. package/dist/wallets/walletConnectors/chunk-YIEASHLS.js +0 -99
  112. package/dist/wallets/walletConnectors/chunk-ZPSPK6LH.js +0 -66
@@ -13,39 +13,39 @@
13
13
  * Both callbacks conform to CustomWithdrawalConfig.withdrawCallback; the
14
14
  * caller provides the actual on-chain implementation.
15
15
  */
16
- import { type LighterAccountIndex } from '@funkit/api-base';
17
- import type { Address } from 'viem';
16
+ import type { LighterAccountIndex } from '@funkit/api-base';
18
17
  import type { CustomWithdrawalConfig, MultiMethodWithdrawalConfig } from '../providers/FunkitCheckoutContext/types';
19
- /** Arbitrum USDC the source token shown on the Fast withdrawal screen. */
20
- export declare const ARBITRUM_USDC: Address;
21
- /** Ethereum mainnet USDC — the source token shown on the Secure withdrawal screen. */
22
- export declare const MAINNET_USDC: Address;
23
- export interface LighterFastWithdrawalCallbackParams {
24
- /** The UDA address to receive the withdrawn funds on the source chain. */
25
- udaAddress: Address;
26
- /** Amount in base units (from the quote). */
27
- amountBaseUnit: bigint;
28
- }
29
- type LighterFastWithdrawalExec = (params: LighterFastWithdrawalCallbackParams) => Promise<void>;
30
- export interface LighterFastWithdrawalConfig {
31
- userId: string;
32
- modalTitle?: string;
33
- disableConnectedWallet?: boolean;
34
- iconSrc?: string;
35
- /**
36
- * Submit the Fast withdrawal on Lighter targeting the UDA. Routed through
37
- * Fun + Relay so the destination can be any supported chain/token.
38
- */
39
- sendLighterFastWithdrawal: LighterFastWithdrawalExec;
40
- }
18
+ export type LighterTransferParams = {
19
+ toAccountIndex: number;
20
+ assetIndex: number;
21
+ fromRouteType: number;
22
+ toRouteType: number;
23
+ amount: number;
24
+ usdcFee: number;
25
+ memo: string;
26
+ ethSigner?: {
27
+ signMessage: (message: string) => Promise<string>;
28
+ };
29
+ nonce?: number;
30
+ };
31
+ export type LighterTransaction = {
32
+ hash: string;
33
+ status: number | 'pending' | 'confirmed' | 'failed';
34
+ block_height?: number;
35
+ message?: string;
36
+ };
37
+ export type LighterSigner = {
38
+ transfer: (params: LighterTransferParams) => Promise<[unknown, string, string | null]>;
39
+ };
41
40
  export interface LighterWithdrawalConfig {
42
- userId: string;
41
+ accountIndex: string;
43
42
  /** Title shown on the selection screen. Defaults to "Withdraw". */
44
43
  modalTitle?: string;
45
44
  disableConnectedWallet?: boolean;
46
45
  fastIconSrc?: string;
47
46
  secureIconSrc?: string;
48
- sendLighterFastWithdrawal: LighterFastWithdrawalExec;
47
+ /** Pre-built Lighter signer. l1Address and accountIndex are resolved internally. */
48
+ signerClient: LighterSigner;
49
49
  sendLighterSecureWithdrawal: LighterSecureWithdrawalExec;
50
50
  /**
51
51
  * Returns the minimum Secure withdrawal amount in token units for the given symbol.
@@ -64,7 +64,7 @@ export interface LighterSecureWithdrawalCallbackParams {
64
64
  }
65
65
  type LighterSecureWithdrawalExec = (params: LighterSecureWithdrawalCallbackParams) => Promise<string>;
66
66
  export interface LighterSecureWithdrawalConfig {
67
- userId: string;
67
+ accountIndex: string;
68
68
  modalTitle?: string;
69
69
  disableConnectedWallet?: boolean;
70
70
  iconSrc?: string;
@@ -99,12 +99,10 @@ export declare function useLighterWithdrawalBalances({ accountIndex, }: {
99
99
  };
100
100
  /** Single-method config for Lighter's Secure withdrawal (bridge to Ethereum). */
101
101
  export declare function createLighterSecureWithdrawalConfig(config: LighterSecureWithdrawalConfig): CustomWithdrawalConfig;
102
- /** Single-method config for Lighter's Fast withdrawal. */
103
- export declare function createLighterFastWithdrawalConfig(config: LighterFastWithdrawalConfig): CustomWithdrawalConfig;
104
102
  /**
105
103
  * Hook version of {@link createLighterWithdrawalConfig}.
106
104
  *
107
- * Fetches all Lighter asset balances for `config.userId` and injects them as
105
+ * Fetches all Lighter asset balances for `config.accountIndex` and injects them as
108
106
  * `withdrawalSourceTokenBalance` into each method's config so the withdrawal
109
107
  * form displays and validates against the real Lighter account balance.
110
108
  *
@@ -113,8 +111,7 @@ export declare function createLighterFastWithdrawalConfig(config: LighterFastWit
113
111
  *
114
112
  * ```tsx
115
113
  * const withdrawalConfig = useLighterWithdrawalConfig({
116
- * userId,
117
- * sendLighterFastWithdrawal: ...,
114
+ * accountIndex,
118
115
  * sendLighterSecureWithdrawal: ...,
119
116
  * })
120
117
  * <WithdrawalModal config={withdrawalConfig} ... />
@@ -128,8 +125,7 @@ export declare function useLighterWithdrawalConfig(config: LighterWithdrawalConf
128
125
  * Usage:
129
126
  * ```ts
130
127
  * const withdrawalConfig = createLighterWithdrawalConfig({
131
- * userId: walletAddress,
132
- * sendLighterFastWithdrawal: async ({ udaAddress, amountBaseUnit }) => { ... },
128
+ * accountIndex: '0',
133
129
  * sendLighterSecureWithdrawal: async ({ amountTokenUnits, assetIndex }) => { ... },
134
130
  * })
135
131
  * ```
@@ -3,20 +3,15 @@ import {
3
3
  AsyncImage,
4
4
  Box,
5
5
  useFunkitTranslation
6
- } from "./chunk-3LSYVQXK.js";
7
- import {
8
- generateClientMetadataForTokenTransfer
9
- } from "./chunk-V526Q43Z.js";
6
+ } from "./chunk-LMEQD56M.js";
10
7
  import {
11
8
  logger
12
9
  } from "./chunk-H6F75ULR.js";
13
10
 
14
11
  // src/clients/lighter.tsx
15
- import {
16
- LIGHTERXYZ_API_KEY as LIGHTERXYZ_API_KEY2,
17
- initializeCheckoutTokenTransferAddress
18
- } from "@funkit/api-base";
19
12
  import { SOLANA_MAINNET_CHAIN_ID } from "@funkit/chains";
13
+ import { RELAY_LIGHTER_CHAIN_ID } from "@funkit/fun-relay";
14
+ import { retry } from "@lifeomic/attempt";
20
15
  import i18next from "i18next";
21
16
  import React2, { useEffect, useMemo as useMemo2 } from "react";
22
17
  import { arbitrum, base, bsc, mainnet as mainnet2, optimism } from "viem/chains";
@@ -281,8 +276,132 @@ function useLighterAccount(lookup, options) {
281
276
  }
282
277
 
283
278
  // src/clients/lighter.tsx
284
- var ARBITRUM_USDC = "0xaf88d065e77c8cC2239327C5EDb3A432268e5831";
279
+ var LIGHTER_USDC_PERPS_ADDRESS = "0x0000000000000000000000000000000000000000";
285
280
  var MAINNET_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
281
+ var LIGHTER_API_BASE = "https://mainnet.zklighter.elliot.ai";
282
+ var LIGHTER_TX_STATUS = {
283
+ PENDING: 0,
284
+ QUEUED: 1,
285
+ COMMITTED: 2,
286
+ EXECUTED: 3,
287
+ FAILED: 4,
288
+ REJECTED: 5
289
+ };
290
+ function coerceLighterStatus(status) {
291
+ if (typeof status === "number") {
292
+ return status;
293
+ }
294
+ switch (status) {
295
+ case "confirmed":
296
+ return LIGHTER_TX_STATUS.EXECUTED;
297
+ case "failed":
298
+ return LIGHTER_TX_STATUS.FAILED;
299
+ default:
300
+ return LIGHTER_TX_STATUS.PENDING;
301
+ }
302
+ }
303
+ var LighterTerminalError = class extends Error {
304
+ };
305
+ async function pollLighterTransaction(txHash, options) {
306
+ const { pollIntervalMs, maxAttempts, waitFor } = options;
307
+ return retry(
308
+ async () => {
309
+ const resp = await fetch(
310
+ `${LIGHTER_API_BASE}/api/v1/tx?by=hash&value=${txHash}`
311
+ );
312
+ if (!resp.ok) {
313
+ throw new Error(`Lighter API error ${resp.status} for tx ${txHash}`);
314
+ }
315
+ const tx = await resp.json();
316
+ if (!tx.hash) {
317
+ throw new Error(`Lighter tx ${txHash} not found yet`);
318
+ }
319
+ const status = coerceLighterStatus(tx.status ?? LIGHTER_TX_STATUS.PENDING);
320
+ if (status === LIGHTER_TX_STATUS.FAILED || status === LIGHTER_TX_STATUS.REJECTED) {
321
+ const label = status === LIGHTER_TX_STATUS.FAILED ? "failed" : "rejected";
322
+ throw new LighterTerminalError(
323
+ `Lighter transaction ${label}: ${tx.message ?? "unknown error"}`
324
+ );
325
+ }
326
+ if (waitFor === "findable") {
327
+ return tx;
328
+ }
329
+ if (status === LIGHTER_TX_STATUS.COMMITTED || status === LIGHTER_TX_STATUS.EXECUTED) {
330
+ return tx;
331
+ }
332
+ throw new Error(
333
+ `Lighter transaction ${txHash} did not reach '${waitFor}' after ${maxAttempts} attempts`
334
+ );
335
+ },
336
+ {
337
+ maxAttempts,
338
+ delay: pollIntervalMs,
339
+ factor: 1,
340
+ jitter: false,
341
+ handleError: (err, context) => {
342
+ if (err instanceof LighterTerminalError) {
343
+ context.abort();
344
+ }
345
+ }
346
+ }
347
+ );
348
+ }
349
+ function createLighterAdaptedWallet({
350
+ signerClient,
351
+ accountIndex
352
+ }) {
353
+ async function handleSendTransactionStep(_chainId, stepItem) {
354
+ const action = stepItem.data?.action;
355
+ if (!action || action.type !== "transfer") {
356
+ throw new Error(
357
+ `Unsupported Lighter action: ${action?.type ?? "undefined"}`
358
+ );
359
+ }
360
+ const p = action.parameters;
361
+ logger.info("lighter:wallet:transfer", p);
362
+ const [, txHash, error] = await signerClient.transfer({
363
+ toAccountIndex: p.toAccountIndex,
364
+ assetIndex: p.assetIndex,
365
+ fromRouteType: p.fromRouteType,
366
+ toRouteType: p.toRouteType,
367
+ amount: p.amount,
368
+ usdcFee: p.usdcFee,
369
+ memo: p.memo
370
+ });
371
+ if (error) {
372
+ throw new Error(`Lighter transfer failed: ${error}`);
373
+ }
374
+ if (!txHash) {
375
+ throw new Error("Lighter transfer returned no transaction hash");
376
+ }
377
+ logger.info("lighter:wallet:transfer:done", { txHash });
378
+ return txHash;
379
+ }
380
+ return {
381
+ vmType: "lvm",
382
+ getChainId: async () => Number(RELAY_LIGHTER_CHAIN_ID),
383
+ address: async () => accountIndex.toString(),
384
+ handleSignMessageStep: async () => {
385
+ throw new Error("Message signing not implemented for Lighter");
386
+ },
387
+ handleSendTransactionStep,
388
+ handleConfirmTransactionStep: async (txHash) => {
389
+ const tx = await pollLighterTransaction(txHash, {
390
+ pollIntervalMs: 2e3,
391
+ maxAttempts: 60,
392
+ waitFor: "findable"
393
+ });
394
+ return {
395
+ txHash: tx.hash,
396
+ blockHeight: tx.block_height ?? 0,
397
+ status: tx.status
398
+ };
399
+ },
400
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: Lighter is single-chain — no switching needed
401
+ switchChain: async () => {
402
+ }
403
+ };
404
+ }
286
405
  function freeBalance(balance, lockedBalance) {
287
406
  return String(Math.max(0, Number(balance) - Number(lockedBalance)));
288
407
  }
@@ -388,63 +507,41 @@ function createLighterSecureWithdrawalConfig(config) {
388
507
  getMinWithdrawalAmount: config.getMinWithdrawalAmount
389
508
  };
390
509
  }
391
- function buildFastWithdrawalCallback({
392
- userId,
393
- exec
510
+ function buildLighterFastWalletWithdrawalConfig({
511
+ signerClient,
512
+ accountIndex,
513
+ modalTitle,
514
+ disableConnectedWallet,
515
+ iconSrc
394
516
  }) {
395
- return async (param) => {
396
- const { targetAssetAddress, targetChainId, destinationAddress, funQuote } = param;
397
- logger.info("lighter:withdrawal:fast:start", {
398
- targetChainId,
399
- targetAssetAddress,
400
- destinationAddress,
401
- quoteId: param.quoteId
402
- });
403
- const transferInit = await initializeCheckoutTokenTransferAddress({
404
- apiKey: LIGHTERXYZ_API_KEY2,
405
- userId,
406
- recipientAddr: destinationAddress,
407
- toChainId: targetChainId.toString(),
408
- toTokenAddress: targetAssetAddress,
409
- logger,
410
- clientMetadata: {
411
- ...generateClientMetadataForTokenTransfer(),
412
- isWithdrawal: true
413
- }
414
- });
415
- const udaAddress = transferInit.depositAddr;
416
- const quote = funQuote;
417
- const amountStr = quote?.baseQuote?.estTotalFromAmountBaseUnit;
418
- if (!amountStr) {
419
- logger.error(
420
- "lighter:withdrawal:fast:missingAmountInQuote",
421
- new Error("Missing withdrawal amount in quote"),
422
- { quote, udaAddress, targetChainId, targetAssetAddress }
423
- );
424
- return;
517
+ const adaptedWallet = createLighterAdaptedWallet({
518
+ signerClient,
519
+ accountIndex
520
+ });
521
+ const wallet = {
522
+ _type: "lighter",
523
+ adaptedWallet,
524
+ address: () => String(accountIndex),
525
+ getChainId: async () => Number(RELAY_LIGHTER_CHAIN_ID),
526
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: no-op — Lighter has no EVM chain switching
527
+ switchChain: async () => {
528
+ },
529
+ sendTransaction: async () => {
530
+ throw new Error("Use adaptedWallet for Lighter execution");
531
+ },
532
+ confirmTransaction: async () => {
533
+ throw new Error("Use adaptedWallet for Lighter execution");
425
534
  }
426
- await exec({ udaAddress, amountBaseUnit: BigInt(amountStr) });
427
- logger.info("lighter:withdrawal:fast:submitted", {
428
- udaAddress,
429
- amountBaseUnit: amountStr
430
- });
431
535
  };
432
- }
433
- function createLighterFastWithdrawalConfig(config) {
434
536
  return {
435
- modalTitle: config.modalTitle ?? i18next.t("withdrawal.withdraw"),
436
- disableConnectedWallet: config.disableConnectedWallet,
437
- withdrawCallback: buildFastWithdrawalCallback({
438
- userId: config.userId,
439
- exec: config.sendLighterFastWithdrawal
440
- }),
441
- // Fast withdrawals source USDC out of Lighter Perps; Relay takes over
442
- // on Arbitrum and routes to any supported destination token/chain.
443
- sourceChainId: arbitrum.id.toString(),
537
+ modalTitle: modalTitle ?? i18next.t("withdrawal.withdraw"),
538
+ disableConnectedWallet,
539
+ wallet,
540
+ sourceChainId: RELAY_LIGHTER_CHAIN_ID,
444
541
  sourceTokenSymbol: "USDC",
445
542
  defaultReceiveToken: "USDC",
446
- sourceTokenAddress: ARBITRUM_USDC,
447
- iconSrc: config.iconSrc ?? "https://sdk-cdn.fun.xyz/images/logos/lighter.png",
543
+ sourceTokenAddress: LIGHTER_USDC_PERPS_ADDRESS,
544
+ iconSrc: iconSrc ?? "https://sdk-cdn.fun.xyz/images/logos/lighter.png",
448
545
  getMinWithdrawalUSD: () => 4
449
546
  };
450
547
  }
@@ -484,15 +581,15 @@ function buildLighterMultiMethodConfig({
484
581
  t,
485
582
  withBalance
486
583
  }) {
487
- const fastConfig = createLighterFastWithdrawalConfig({
488
- userId: config.userId,
584
+ const fastConfig = buildLighterFastWalletWithdrawalConfig({
585
+ signerClient: config.signerClient,
586
+ accountIndex: Number(config.accountIndex),
489
587
  modalTitle: config.modalTitle,
490
588
  disableConnectedWallet: config.disableConnectedWallet,
491
- iconSrc: config.fastIconSrc,
492
- sendLighterFastWithdrawal: config.sendLighterFastWithdrawal
589
+ iconSrc: config.fastIconSrc
493
590
  });
494
591
  const secureConfig = createLighterSecureWithdrawalConfig({
495
- userId: config.userId,
592
+ accountIndex: config.accountIndex,
496
593
  modalTitle: config.modalTitle,
497
594
  disableConnectedWallet: config.disableConnectedWallet,
498
595
  iconSrc: config.secureIconSrc,
@@ -534,7 +631,7 @@ function buildLighterMultiMethodConfig({
534
631
  function useLighterWithdrawalConfig(config) {
535
632
  const { t } = useFunkitTranslation();
536
633
  const { balances } = useLighterWithdrawalBalances({
537
- accountIndex: asLighterAccountIndex(config.userId)
634
+ accountIndex: asLighterAccountIndex(config.accountIndex)
538
635
  });
539
636
  return useMemo2(
540
637
  () => buildLighterMultiMethodConfig({
@@ -552,9 +649,6 @@ function createLighterWithdrawalConfig(config) {
552
649
  });
553
650
  }
554
651
  export {
555
- ARBITRUM_USDC,
556
- MAINNET_USDC,
557
- createLighterFastWithdrawalConfig,
558
652
  createLighterSecureWithdrawalConfig,
559
653
  createLighterWithdrawalConfig,
560
654
  freeBalance,
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import type { ApprovalMethod } from '../../providers/FunkitQuoteContext';
3
+ interface ApprovalMethodToggleProps {
4
+ value: ApprovalMethod;
5
+ onChange: (next: ApprovalMethod) => void;
6
+ disabled?: boolean;
7
+ testId?: string;
8
+ }
9
+ /**
10
+ * A small dropdown selector for the user's preferred source-side
11
+ * authorization method ("Approve transaction" vs "Signed message").
12
+ *
13
+ * Pure presentation: state lives in `useApprovalMethodSelection`. The
14
+ * component is screen-agnostic so it can be mounted on either
15
+ * `ConfirmationStep` (non-native flow) or `InputAmount` (native flow,
16
+ * future) without changes.
17
+ */
18
+ export declare function ApprovalMethodToggle({ value, onChange, disabled, testId, }: ApprovalMethodToggleProps): React.JSX.Element;
19
+ export {};
@@ -14,9 +14,10 @@ export interface BaseActiveDropdownItemProps {
14
14
  color?: BoxProps['color'];
15
15
  arrowColor?: BoxProps['color'];
16
16
  background?: BoxProps['background'];
17
+ labelStyle?: React.CSSProperties;
17
18
  }
18
19
  /**
19
20
  * Represents the component used to open the dropdown, usually displayed all the time.
20
21
  */
21
- declare function BaseActiveDropdownItem({ iconComponent, label, isOpened, onClick, horizontalIconGap, alwaysVisibleLabel, tagComponent, tagPosition, size, color, arrowColor, background, }: BaseActiveDropdownItemProps): React.JSX.Element;
22
+ declare function BaseActiveDropdownItem({ iconComponent, label, isOpened, onClick, horizontalIconGap, alwaysVisibleLabel, tagComponent, tagPosition, size, color, arrowColor, background, labelStyle, }: BaseActiveDropdownItemProps): React.JSX.Element;
22
23
  export default BaseActiveDropdownItem;
@@ -2,36 +2,22 @@ import React from 'react';
2
2
  import { type BoxProps } from '../Box/Box';
3
3
  import { type BaseActiveDropdownItemProps } from './BaseActiveDropdownItem';
4
4
  import './BaseDropdownAnimation.css';
5
+ import { type BaseDropdownGroup, type BaseDropdownOption } from './BaseDropdown.utils';
6
+ export type { BaseDropdownGroup, BaseDropdownOption, } from './BaseDropdown.utils';
7
+ export { NO_SELECTION_VALUE } from './BaseDropdown.utils';
5
8
  /** gap between the icon and the label of the item */
6
9
  export declare const HORIZONTAL_ICON_GAP = "4";
7
10
  /** safe spacing, ie. padding, on the left & right of the active item and dropdown item */
8
11
  export declare const HORIZONTAL_OUTER_PADDING_X = "12";
9
- export declare const NO_SELECTION_VALUE = "";
10
- export interface BaseDropdownOption<T = string, G extends string = never> {
11
- label: string;
12
- value: T;
13
- /**
14
- * For grouped dropdowns, this is the {@link BaseDropdownGroup.key} of the group this option belongs to.
15
- *
16
- * If omitted, or if no group has the key, the option is treated as ungrouped.
17
- *
18
- * _See {@link BaseDropdownProps.groups} and {@link BaseDropdownProps.showOthersGroup}_
19
- */
20
- group?: G;
21
- }
22
- export interface BaseDropdownGroup<G extends string> {
23
- key: G;
24
- label: string;
25
- }
26
12
  export interface BaseDropdownProps<T = string, G extends string = never> {
27
13
  value: string;
28
- activeItemProps?: Partial<Pick<BaseActiveDropdownItemProps, 'iconComponent' | 'label' | 'color' | 'alwaysVisibleLabel' | 'tagComponent' | 'tagPosition' | 'background'>>;
14
+ activeItemProps?: Partial<Pick<BaseActiveDropdownItemProps, 'iconComponent' | 'label' | 'color' | 'alwaysVisibleLabel' | 'tagComponent' | 'tagPosition' | 'background' | 'labelStyle'>>;
29
15
  /**
30
16
  * List of groups to show and the corresponding labels, in the expected order.
31
17
  *
32
18
  * _Defaults to ungrouped dropdown behavior_
33
19
  */
34
- groups?: BaseDropdownGroup<G>[];
20
+ groups?: BaseDropdownGroup<T, G>[];
35
21
  /**
36
22
  * Additional group displayed after configured groups (only if there are non-empty groups).
37
23
  * - "all": display all options (grouped options will effectively be shown twice in total)
@@ -56,10 +42,10 @@ export interface BaseDropdownProps<T = string, G extends string = never> {
56
42
  * Label for {@link allowUnselect}
57
43
  */
58
44
  unselectLabel?: string;
59
- options: BaseDropdownOption<T, G>[];
45
+ options: BaseDropdownOption<T>[];
60
46
  onOpen?: () => void;
61
- onOptionSelected?: (item: BaseDropdownOption<T, G>) => void;
62
- renderDropdownOption: (item: BaseDropdownOption<T, G>, isSelected: boolean) => React.ReactNode;
47
+ onOptionSelected?: (item: BaseDropdownOption<T>) => void;
48
+ renderDropdownOption: (item: BaseDropdownOption<T>, isSelected: boolean) => React.ReactNode;
63
49
  searchableOptions?: boolean;
64
50
  searchPlaceholder?: string;
65
51
  placeholder?: string;
@@ -79,7 +65,9 @@ export interface BaseDropdownProps<T = string, G extends string = never> {
79
65
  * This values should be set so that the last dropdown item is partially visible to indicate that there are more options.
80
66
  */
81
67
  maxDropdownHeight?: number;
68
+ dropdownWidth?: number;
69
+ dropdownAlign?: 'start' | 'center' | 'end';
82
70
  testId?: string;
83
71
  }
84
- declare function BaseDropdown<T extends string = string, G extends string = never>({ activeItemProps, value, options, groups, additionalGroup, additionalGroupLabel, allowUnselect, unselectLabel, onOptionSelected, onOpen, renderDropdownOption, searchableOptions, searchPlaceholder, placeholder, resetSearchOnClose, openToTopOnMobile, alwaysOpenToTop, openDropdownFullWidth, isLoading, preloadIconUrls, horizontalIconGap, openDropdownBackgroundColor, size, label, maxDropdownHeight, testId, }: BaseDropdownProps<T, G>): React.JSX.Element;
72
+ declare function BaseDropdown<T extends string = string, G extends string = never>({ activeItemProps, value, options, groups, additionalGroup, additionalGroupLabel, allowUnselect, unselectLabel, onOptionSelected, onOpen, renderDropdownOption, searchableOptions, searchPlaceholder, placeholder, resetSearchOnClose, openToTopOnMobile, alwaysOpenToTop, openDropdownFullWidth, isLoading, preloadIconUrls, horizontalIconGap, openDropdownBackgroundColor, size, label, maxDropdownHeight, dropdownWidth, dropdownAlign, testId, }: BaseDropdownProps<T, G>): React.JSX.Element;
85
73
  export default BaseDropdown;
@@ -0,0 +1,23 @@
1
+ export declare const NO_SELECTION_VALUE = "";
2
+ export declare const ADDITIONAL_GROUP_KEY = "__additional__";
3
+ export interface BaseDropdownOption<T = string> {
4
+ label: string;
5
+ value: T;
6
+ }
7
+ export interface BaseDropdownGroup<T = string, G extends string = never> {
8
+ key: G;
9
+ label: string;
10
+ values: T[];
11
+ }
12
+ export interface OrganizedDropdownGroup<T, G extends string> {
13
+ key: G | typeof ADDITIONAL_GROUP_KEY | typeof NO_SELECTION_VALUE;
14
+ label: string | undefined;
15
+ options: BaseDropdownOption<T>[];
16
+ }
17
+ export interface OrganizeDropdownGroupsResult<T, G extends string> {
18
+ organizedGroups: OrganizedDropdownGroup<T, G>[];
19
+ organizedOptions: BaseDropdownOption<T>[];
20
+ }
21
+ export declare function buildAllOptions<T extends string>(options: BaseDropdownOption<T>[], allowUnselect: boolean, unselectLabel?: string): BaseDropdownOption<T>[];
22
+ export declare function filterOptions<T extends string>(allOptions: BaseDropdownOption<T>[], searchInput: string): BaseDropdownOption<T>[];
23
+ export declare function organizeDropdownGroups<T extends string, G extends string>(filteredOptions: BaseDropdownOption<T>[], groups: BaseDropdownGroup<T, G>[] | undefined, additionalGroup: 'all' | 'others', additionalGroupLabel: string | undefined): OrganizeDropdownGroupsResult<T, G>;
@@ -23,7 +23,8 @@ interface ChainDropdownProps {
23
23
  alwaysOpenToTop?: BaseDropdownProps['alwaysOpenToTop'];
24
24
  maxDropdownHeight?: BaseDropdownProps['maxDropdownHeight'];
25
25
  tagComponent?: (value: string) => React.ReactNode;
26
+ placeholder?: string;
26
27
  testId?: string;
27
28
  }
28
- export declare const ChainDropdown: ({ assets, chainIdSortOrder, selectedChainId: propSelectedChainId, selectedToken, allowUnselect, onChainSelected, activeItemProps, size, openDropdownBackgroundColor, openDropdownFullWidth, isLoading, alwaysOpenToTop, maxDropdownHeight, tagComponent, testId, }: ChainDropdownProps) => React.JSX.Element;
29
+ export declare const ChainDropdown: ({ assets, chainIdSortOrder, selectedChainId: propSelectedChainId, selectedToken, allowUnselect, onChainSelected, activeItemProps, size, openDropdownBackgroundColor, openDropdownFullWidth, isLoading, alwaysOpenToTop, maxDropdownHeight, tagComponent, placeholder, testId, }: ChainDropdownProps) => React.JSX.Element;
29
30
  export {};
@@ -3,8 +3,8 @@ import type { TokenTransferSourceChainsAndAssets } from '../../modals/CheckoutMo
3
3
  import type { BaseDropdownProps } from './BaseDropdown';
4
4
  interface TokenAndChainDropdownProps {
5
5
  isLoading: boolean;
6
- selectedToken: string;
7
- selectedChainId: number;
6
+ selectedToken: string | undefined;
7
+ selectedChainId: number | undefined;
8
8
  assets: TokenTransferSourceChainsAndAssets;
9
9
  /**
10
10
  * Callback fired after token selection
@@ -16,6 +16,10 @@ interface TokenAndChainDropdownProps {
16
16
  onChainSelected: (chainId?: number, autoUpdate?: boolean) => void;
17
17
  tokenLabel?: string;
18
18
  chainLabel?: string;
19
+ /** Placeholder shown in the token dropdown when no token is selected */
20
+ tokenPlaceholder?: string;
21
+ /** Placeholder shown in the chain dropdown when no chain is selected */
22
+ chainPlaceholder?: string;
19
23
  chainLabelAddon?: ReactNode;
20
24
  alwaysOpenToTop?: boolean;
21
25
  maxTokenDropdownHeight?: BaseDropdownProps['maxDropdownHeight'];
@@ -26,11 +30,13 @@ interface TokenAndChainDropdownProps {
26
30
  * Override to hide the new token badge
27
31
  */
28
32
  hideNewTokenBadge?: boolean;
33
+ /** Token symbols to show in a separate "Popular" group */
34
+ popularTokenSymbols?: string[];
29
35
  /** Token symbols to prioritize at top of dropdown */
30
36
  priorityTokenSymbols?: string[];
31
37
  /** Determines the chain display order */
32
38
  chainIdSortOrder?: number[];
33
39
  }
34
40
  /** Combines together chain and token dropdowns */
35
- export declare const TokenAndChainDropdown: ({ isLoading, selectedToken, selectedChainId, assets, onTokenSelected, onChainSelected, tokenLabel, chainLabel, chainLabelAddon, alwaysOpenToTop, maxTokenDropdownHeight, maxChainDropdownHeight, openChainDropdownFullWidth, chainTagComponent, hideNewTokenBadge, priorityTokenSymbols, chainIdSortOrder, }: TokenAndChainDropdownProps) => React.JSX.Element;
41
+ export declare const TokenAndChainDropdown: ({ isLoading, selectedToken, selectedChainId, assets, onTokenSelected, onChainSelected, tokenLabel, chainLabel, tokenPlaceholder, chainPlaceholder, chainLabelAddon, alwaysOpenToTop, maxTokenDropdownHeight, maxChainDropdownHeight, openChainDropdownFullWidth, chainTagComponent, hideNewTokenBadge, popularTokenSymbols, priorityTokenSymbols, chainIdSortOrder, }: TokenAndChainDropdownProps) => React.JSX.Element;
36
42
  export {};
@@ -2,14 +2,14 @@ import React from 'react';
2
2
  import type { TokenTransferSourceChainsAndAssets } from '../../modals/CheckoutModal/TransferToken/TransferToken';
3
3
  import { type BaseDropdownProps } from './BaseDropdown';
4
4
  interface TokenDropdownProps {
5
- selectedChainId: number;
5
+ selectedChainId: number | undefined;
6
6
  assets: TokenTransferSourceChainsAndAssets;
7
7
  onTokenSelected: (token: string, chainId?: number,
8
8
  /**
9
9
  * If true, it will trigger automatic updates for the matching chain in the parent component.
10
10
  */
11
11
  autoUpdate?: boolean) => void;
12
- selectedToken?: string;
12
+ selectedToken: string | undefined;
13
13
  isLoading?: BaseDropdownProps['isLoading'];
14
14
  alwaysOpenToTop?: BaseDropdownProps['alwaysOpenToTop'];
15
15
  maxDropdownHeight?: BaseDropdownProps['maxDropdownHeight'];
@@ -17,12 +17,16 @@ interface TokenDropdownProps {
17
17
  * Override to hide the new token badge
18
18
  */
19
19
  hideNewTokenBadge?: boolean;
20
+ /** Token symbols to show in a separate "Popular" group */
21
+ popularTokenSymbols?: string[];
20
22
  /** Token symbols to prioritize at top of dropdown */
21
23
  priorityTokenSymbols?: string[];
24
+ /** Placeholder shown when no token is selected */
25
+ placeholder?: string;
22
26
  /**
23
27
  * Test ID for the token dropdown
24
28
  */
25
29
  testId?: string;
26
30
  }
27
- export declare const TokenDropdown: ({ assets, selectedChainId, selectedToken, onTokenSelected, isLoading, alwaysOpenToTop, maxDropdownHeight, hideNewTokenBadge, priorityTokenSymbols, testId, }: TokenDropdownProps) => React.JSX.Element;
31
+ export declare const TokenDropdown: ({ assets, selectedChainId, selectedToken, onTokenSelected, isLoading, alwaysOpenToTop, maxDropdownHeight, hideNewTokenBadge, popularTokenSymbols, priorityTokenSymbols, placeholder, testId, }: TokenDropdownProps) => React.JSX.Element;
28
32
  export {};
@@ -8,7 +8,6 @@ import { PaymentMethod } from '../domains/paymentMethods';
8
8
  * Accounts for the customer's configured minimum deposit and a global floor.
9
9
  */
10
10
  export declare function getMinValueThreshold(config: FunkitCheckoutConfig | undefined, minUsdRequired?: number): number;
11
- export declare const isStablecoin: (symbol: string) => boolean;
12
11
  export declare function isPreferredChain(chainId: number, additionalChains?: number[]): boolean;
13
12
  export declare function isNativeTokenAddress(address: Address): boolean;
14
13
  export declare function isDefaultToken(asset: AssetHoldingsItem, checkoutConfig: FunkitCheckoutConfig): boolean;
@@ -13,7 +13,15 @@ export interface FunkitCheckoutQuoteResult extends Omit<ApiFunkitCheckoutQuoteRe
13
13
  finalSpreadUsd: string;
14
14
  finalFeesBreakdown: CheckoutFees;
15
15
  }
16
- export declare function getCheckoutBaseQuote(checkoutItem: FunkitActiveCheckoutItem, userId: string, walletAddress: Address, apiKey: string, wagmiConfig: Config, directExecutionInfo: FunkitDirectExecutionInfo, senderAddress?: Address, isWithdrawal?: boolean, quoteBuilder?: QuoteBuilder): Promise<CheckoutQuoteResponse>;
16
+ export declare function getCheckoutBaseQuote(checkoutItem: FunkitActiveCheckoutItem, userId: string, walletAddress: Address, apiKey: string, wagmiConfig: Config, directExecutionInfo: FunkitDirectExecutionInfo, senderAddress?: Address, isWithdrawal?: boolean, quoteBuilder?: QuoteBuilder,
17
+ /**
18
+ * User-driven preference for the source-side authorization step. Forwarded
19
+ * to the direct-execution branch (`getDirectExecutionQuote` →
20
+ * `getCheckoutQuoteV2`) where Relay's `usePermit` flag actually flows. The
21
+ * legacy `getApiCheckoutQuote` branch ignores this; the permit toggle is
22
+ * scoped to Wallet (Relay direct-execution) only.
23
+ */
24
+ usePermit?: boolean): Promise<CheckoutQuoteResponse>;
17
25
  export declare function getQuoteFinalEstimation(baseQuote: CheckoutQuoteResponse, checkoutItem: FunkitActiveCheckoutItem, newPaymentMethodInfo: PaymentMethodInfo, wagmiConfig: Config, apiKey: string, loginType: LoginType, isWithdrawal?: boolean, brokerageQuote?: BluvoBrokerageQuote): Promise<{
18
26
  finalEstimation: FunkitCheckoutQuoteResult;
19
27
  brokerage?: BrokerageDetails;
@@ -1,2 +1,3 @@
1
+ import type { IsStablecoinFn } from '../../hooks/useIsStablecoin';
1
2
  import { type QuoteBuilder } from './types';
2
- export declare function createExactOutBuilder(): QuoteBuilder;
3
+ export declare function createExactOutBuilder(isStablecoin: IsStablecoinFn): QuoteBuilder;
@@ -1,7 +1,9 @@
1
+ import type { IsStablecoinFn } from '../../hooks/useIsStablecoin';
1
2
  import { type QuoteBuilder } from './types';
2
3
  export interface ResolveQuoteBuilderParams {
3
4
  hasPostAction: boolean | undefined;
4
5
  isExactInEnabled: boolean;
6
+ isStablecoin: IsStablecoinFn;
5
7
  providerSupportsExactInWithActions?: boolean;
6
8
  }
7
9
  /**
@@ -17,4 +19,4 @@ export interface ResolveQuoteBuilderParams {
17
19
  * Note: ONE_TO_ONE (subsidized routes) is not yet auto-detected.
18
20
  * It will be enabled in a future phase when subsidy detection is implemented.
19
21
  */
20
- export declare function resolveQuoteBuilder({ hasPostAction, isExactInEnabled, providerSupportsExactInWithActions, }: ResolveQuoteBuilderParams): QuoteBuilder;
22
+ export declare function resolveQuoteBuilder({ hasPostAction, isExactInEnabled, isStablecoin, providerSupportsExactInWithActions, }: ResolveQuoteBuilderParams): QuoteBuilder;