@funkit/connect 9.13.0 → 9.15.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 +54 -0
  2. package/dist/__generated__/default_configs.d.ts +8 -11
  3. package/dist/__generated__/default_feature_gates.d.ts +3 -2
  4. package/dist/clients/aave.d.ts +92 -0
  5. package/dist/clients/aave.js +156 -0
  6. package/dist/clients/{chunk-LMEQD56M.js → chunk-PLDXBAAH.js} +2 -1
  7. package/dist/clients/fanatics.js +1 -1
  8. package/dist/clients/lighter.d.ts +33 -2
  9. package/dist/clients/lighter.js +124 -2
  10. package/dist/clients/polymarket.d.ts +30 -1
  11. package/dist/clients/polymarket.js +153 -4
  12. package/dist/components/CopyAddress/CopyInputDisplayedAddress.css.d.ts +1 -0
  13. package/dist/components/CopyAddress/CopyInputDisplayedAddress.d.ts +6 -0
  14. package/dist/components/FreeUsdcBanner/FreeUsdcBanner.d.ts +5 -0
  15. package/dist/components/FunPayments/FunPaymentMethods.d.ts +16 -0
  16. package/dist/components/Icons/CashAppIcon.d.ts +4 -0
  17. package/dist/consts/customers.d.ts +8 -0
  18. package/dist/consts/polymarket.d.ts +7 -0
  19. package/dist/domains/paymentMethods.d.ts +9 -1
  20. package/dist/domains/quote.d.ts +11 -0
  21. package/dist/hooks/usePaymentSources.d.ts +1 -0
  22. package/dist/index.css +22 -15
  23. package/dist/index.js +3017 -2395
  24. package/dist/modals/CheckoutModal/InputAmount/InputAmount.d.ts +4 -0
  25. package/dist/modals/CheckoutModal/InputAmount/aaveClient.d.ts +20 -0
  26. package/dist/modals/CheckoutModal/InputAmount/useAaveNativeSupply.d.ts +44 -0
  27. package/dist/modals/CheckoutModal/SourceChange/SourceChange.d.ts +8 -0
  28. package/dist/modals/CheckoutModal/SourceChange/SourceList.d.ts +7 -1
  29. package/dist/modals/CheckoutModal/SourceChange/buildSourceGroups.d.ts +31 -8
  30. package/dist/modals/WithdrawalModal/WithdrawAmountInput.d.ts +10 -4
  31. package/dist/modals/WithdrawalModal/WithdrawalContent.d.ts +32 -1
  32. package/dist/modals/WithdrawalModal/WithdrawalSuccess.d.ts +0 -1
  33. package/dist/modals/WithdrawalModal/useWithdrawal.d.ts +1 -2
  34. package/dist/providers/FunkitCheckoutContext/index.d.ts +8 -0
  35. package/dist/providers/FunkitCheckoutContext/types.d.ts +6 -0
  36. package/dist/providers/FunkitConfigContext.d.ts +2 -0
  37. package/dist/wagmi/actions.d.ts +1 -1
  38. package/dist/wallets/walletConnectors/bifrostWallet/bifrostWallet.js +2 -2
  39. package/dist/wallets/walletConnectors/bitgetWallet/bitgetWallet.js +2 -2
  40. package/dist/wallets/walletConnectors/bybitWallet/bybitWallet.js +2 -2
  41. package/dist/wallets/walletConnectors/clvWallet/clvWallet.js +2 -2
  42. package/dist/wallets/walletConnectors/coin98Wallet/coin98Wallet.js +2 -2
  43. package/dist/wallets/walletConnectors/coreWallet/coreWallet.js +2 -2
  44. package/dist/wallets/walletConnectors/foxWallet/foxWallet.js +2 -2
  45. package/dist/wallets/walletConnectors/frontierWallet/frontierWallet.js +2 -2
  46. package/dist/wallets/walletConnectors/gateWallet/gateWallet.js +2 -2
  47. package/dist/wallets/walletConnectors/index.js +40 -40
  48. package/dist/wallets/walletConnectors/metaMaskWallet/metaMaskWallet.js +2 -2
  49. package/dist/wallets/walletConnectors/okxWallet/okxWallet.js +2 -2
  50. package/dist/wallets/walletConnectors/rainbowWallet/rainbowWallet.js +2 -2
  51. package/dist/wallets/walletConnectors/roninWallet/roninWallet.js +2 -2
  52. package/dist/wallets/walletConnectors/safepalWallet/safepalWallet.js +2 -2
  53. package/dist/wallets/walletConnectors/subWallet/subWallet.js +2 -2
  54. package/dist/wallets/walletConnectors/tokenPocketWallet/tokenPocketWallet.js +2 -2
  55. package/dist/wallets/walletConnectors/trustWallet/trustWallet.js +2 -2
  56. package/dist/wallets/walletConnectors/zerionWallet/zerionWallet.js +2 -2
  57. package/package.json +10 -5
  58. package/dist/wallets/walletConnectors/{chunk-VMMROPXK.js → chunk-34HACM5U.js} +3 -3
  59. package/dist/wallets/walletConnectors/{chunk-3ZJN3PXP.js → chunk-5TN5Z2WY.js} +3 -3
  60. package/dist/wallets/walletConnectors/{chunk-OD6B2ISG.js → chunk-6DRCY52E.js} +3 -3
  61. package/dist/wallets/walletConnectors/{chunk-IRHK6SOW.js → chunk-7V33VJAL.js} +3 -3
  62. package/dist/wallets/walletConnectors/{chunk-ZJJWGKB6.js → chunk-APHCF4DT.js} +3 -3
  63. package/dist/wallets/walletConnectors/{chunk-7IEUTLHY.js → chunk-DEFRRPXB.js} +3 -3
  64. package/dist/wallets/walletConnectors/{chunk-OSOB6QYX.js → chunk-FG2LDVXL.js} +3 -3
  65. package/dist/wallets/walletConnectors/{chunk-ZL6XCMV5.js → chunk-HRDPUW3V.js} +3 -3
  66. package/dist/wallets/walletConnectors/{chunk-UYW6MV74.js → chunk-HXWUH73P.js} +3 -3
  67. package/dist/wallets/walletConnectors/{chunk-UFYNHHDU.js → chunk-KWX2SYU2.js} +3 -3
  68. package/dist/wallets/walletConnectors/{chunk-AZYMJ4C6.js → chunk-LCIPVVH5.js} +3 -3
  69. package/dist/wallets/walletConnectors/{chunk-FWM4KTOV.js → chunk-T4ROGPMF.js} +3 -3
  70. package/dist/wallets/walletConnectors/{chunk-J3PJOMO7.js → chunk-UDTBQV4Q.js} +3 -3
  71. package/dist/wallets/walletConnectors/{chunk-55VS2NKG.js → chunk-V6UOWTEZ.js} +3 -3
  72. package/dist/wallets/walletConnectors/{chunk-LEAZMT5Y.js → chunk-VJZWNQOF.js} +3 -3
  73. package/dist/wallets/walletConnectors/{chunk-RZQ4B4Z7.js → chunk-XVBSJCW5.js} +3 -3
  74. package/dist/wallets/walletConnectors/{chunk-IMNI4AGV.js → chunk-YIEASHLS.js} +3 -3
  75. package/dist/wallets/walletConnectors/{chunk-YGMU5VWD.js → chunk-ZPSPK6LH.js} +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # @funkit/connect
2
2
 
3
+ ## 9.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8d525fb: Add Aave deposit fast-path: same-token deposits to supported Aave reserves go directly to the protocol, skipping the quote flow.
8
+ - cc655ee: feat(connect): add Aave V3 supply actions factory + checkout config builder via VaultDepositor
9
+ - e9883ef: Add `display.collateralizationEnabled` to `createAaveSupplyCheckoutConfig`, driving the deposit modal's collateralization subtitle.
10
+ - 11a585d: Register enable-free-usdc-banner feature gate and wire stub component in WithdrawalModal and SourceChange
11
+ - 783d034: feat(api-base, connect): track Lighter Secure withdrawals as `direct_execution` rows.
12
+
13
+ - `@funkit/api-base`: add `DirectExecutionType.EXTERNALLY_FULFILLED` for flows fulfilled outside Fun — backend persists the row but never polls for status.
14
+ - `@funkit/connect`: Lighter Secure withdrawals now post a tracking-only DE row keyed off the L2 tx hash. Fire-and-forget — failures log at warn and never block the UI.
15
+
16
+ - ab5ab81: feat(connect): add createPerpsGenerateActionParams factory for Polymarket Perps deposits
17
+ - 49b653f: Route Polymarket Perps deposits to pUSD: QR/UDA transfers for the `POLYMARKET_PERPS_DEPOSIT` action now target pUSD instead of the configured target asset.
18
+
19
+ ### Patch Changes
20
+
21
+ - 650d56e: Skip the redundant approve(0) reset for Aave supply assets outside `TOKENS_REQUIRING_APPROVAL_RESET`.
22
+ - d9e78ce: test(connect): add direct execution history coverage
23
+ - 3d19a04: test(connect): add direct execution polling coverage
24
+ - 2846b98: Add unit tests for evaluateFeeBreakdown covering wallet, brokerage, card, and unsupported payment methods
25
+ - a0353b7: Show user-entered token amount (not USD) on Lighter Secure withdrawal success screen
26
+ - 86300af: test(connect): test useAmountInput
27
+ - b38e78b: test(connect): add domains/quote tests
28
+ - 8207111: test(connect): test useQuoteRefresh
29
+ - 3fd1475: Add exhaustive unit tests for the quoteMode domain builders
30
+ - 9a2c30a: Extract `SAFE_URL_PROTOCOLS` set in `sanitizeUrl`. Internal refactor, no behavior change.
31
+ - 298eec7: feat: add invoice label support on copyinput component
32
+ - 984ce0c: chore(connect): expand bundled statsig fallbacks
33
+ - Updated dependencies [8d525fb]
34
+ - Updated dependencies [783d034]
35
+ - @funkit/api-base@4.3.0
36
+
37
+ ## 9.14.0
38
+
39
+ ### Minor Changes
40
+
41
+ - c32bc92: feat(connect): Aave source-select renders Native + Use other assets sections; Native row fast-paths to InputAmount when wallet holds the target asset.
42
+ - ccd1855: Register Bitcoin on Cash App as a payment source on the crypto tab of the checkout modal.
43
+
44
+ ### Patch Changes
45
+
46
+ - bc5ce6f: test(connect): add checkout transfer init coverage
47
+ - b69e713: Fix CopyAddress button border-radius to account for parent 1px border.
48
+ - c097446: Fix withdrawal modal conflating source-token amount with USD value. No-op for
49
+ 1:1 stablecoin sources; corrects target-amount, receive-fiat, and min-amount
50
+ math for non-stable sources.
51
+ - beb12ee: test(connect): add unit test coverage
52
+ - Updated dependencies [d67a842]
53
+ - Updated dependencies [e9e960a]
54
+ - @funkit/api-base@4.2.3
55
+ - @funkit/chains@1.2.0
56
+
3
57
  ## 9.13.0
4
58
 
5
59
  ### Minor Changes
@@ -22,6 +22,8 @@ declare const _default: {
22
22
  readonly '0x881D40237659C251811CEC9c364ef91dC08D300C': "Metamask Swap Router";
23
23
  readonly '0x07d82CD44cd598ACf355Af8c8089b30b2a13B088': "Polymarket Withdrawal Block";
24
24
  readonly '2ygdTkdUtN9PhoMko12bQi6PimJrqxcKmCvQGkCG6SN7': "Polymarket Withdrawal Block";
25
+ readonly '0xd40cBF452e8D6c9dF3e8bbE24eA8b65f859Ae34b': "Polymarket Withdrawal Block";
26
+ readonly GZxiVHg1JM6gCWRG7FwhaD6gPYpcLhiJ21s4ga7Ynfus: "Polymarket Withdrawal Block";
25
27
  };
26
28
  };
27
29
  readonly blockedcountries: {
@@ -276,6 +278,9 @@ declare const _default: {
276
278
  readonly enablebitcoin: {
277
279
  readonly value: true;
278
280
  };
281
+ readonly enablebitcoinlightning: {
282
+ readonly value: false;
283
+ };
279
284
  readonly enablebluvobrokerage: {
280
285
  readonly value: true;
281
286
  };
@@ -295,6 +300,9 @@ declare const _default: {
295
300
  readonly enablesourcegrouplabels: {
296
301
  readonly value: true;
297
302
  };
303
+ readonly enableswapped: {
304
+ readonly value: false;
305
+ };
298
306
  readonly enableswappeddeposit: {
299
307
  readonly value: false;
300
308
  };
@@ -658,17 +666,6 @@ declare const _default: {
658
666
  }, {
659
667
  readonly address: "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34";
660
668
  }];
661
- }, {
662
- readonly chainId: 2741;
663
- readonly assets: readonly [{
664
- readonly address: "0x84A71ccD554Cc1b02749b35d22F684CC8ec987e1";
665
- }, {
666
- readonly address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
667
- }, {
668
- readonly address: "0x3439153EB7AF838Ad19d56E1571FBD09333C2809";
669
- }, {
670
- readonly address: "0x0709F39376dEEe2A2dfC94A58EdEb2Eb9DF012bD";
671
- }];
672
669
  }, {
673
670
  readonly chainId: 5064014;
674
671
  readonly assets: readonly [{
@@ -1,7 +1,9 @@
1
1
  declare const _default: {
2
2
  readonly 'compliance-review-blocker': false;
3
3
  readonly 'enable-across-wallet-flow': false;
4
+ readonly 'enable-add-token-to-wallet': false;
4
5
  readonly 'enable-empty-withdrawal-selection': false;
6
+ readonly 'enable-free-usdc-banner': false;
5
7
  readonly 'enable-permit-toggle': false;
6
8
  readonly 'enable-polymarket-wallet-withdrawal': false;
7
9
  readonly 'enable-swapped-exchanges': false;
@@ -9,9 +11,8 @@ declare const _default: {
9
11
  readonly 'faster-notifications': false;
10
12
  readonly 'new-token-transfer-config': false;
11
13
  readonly 'new-withdrawal-config': false;
12
- readonly 'polymarket-pusd-migration': false;
13
14
  readonly 'saved-card-defaults-to-fiat-tab': false;
14
- readonly 'test-testing-gate': false;
15
+ readonly 'test-feature-gate': false;
15
16
  readonly 'wallet-flow-enable-exact-input-with-actions': false;
16
17
  readonly 'you-receive-remove-swap-impact': false;
17
18
  };
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Aave V3 supply routed through Fun's VaultDepositor proxy.
3
+ *
4
+ * Two entry points:
5
+ * - `createAaveSupplyCheckoutConfig` — high-level; returns a full
6
+ * `FunkitCheckoutConfig` or `undefined` if the chain isn't Fun-supported.
7
+ * The `undefined` return is the canonical "is this Fun-routed?" signal.
8
+ * - `createAaveSupplyActions` — low-level; returns just the actions
9
+ * closure. Use when you need non-default modal copy.
10
+ *
11
+ * Adding a new Aave entrypoint here (e.g. `supplyWithPermit`) requires
12
+ * coordinating with backend: VaultDepositor selector-whitelists each
13
+ * forwarded call. Pool addresses, in contrast, are owned by Aave's
14
+ * registry — callers pass `poolAddress` directly.
15
+ */
16
+ import { type Address } from 'viem';
17
+ import type { FunkitCheckoutActionParams, FunkitCheckoutConfig } from '../providers/FunkitCheckoutContext/types';
18
+ /** Returns true if Fun has a VaultDepositor deployment on `chainId` ready to route Aave supplies. */
19
+ export declare function isAaveSupplySupported(chainId: number): boolean;
20
+ export interface AaveSupplyActionsConfig {
21
+ /** Address that receives the aToken receipt. Typically the connected wallet. */
22
+ onBehalfOf: Address | undefined;
23
+ /** Underlying asset to be supplied. Matches Aave's `DashboardReserve.underlyingAsset`. */
24
+ underlyingAsset: Address;
25
+ /** Aave V3 Pool contract on `chainId`. Aave maintains the registry — pass the value from `@aave-dao/aave-address-book` or your own `marketsData`. */
26
+ poolAddress: Address;
27
+ /** Chain ID — selects the Fun VaultDepositor deployment. */
28
+ chainId: number;
29
+ /** Aave referral code. Defaults to 0; partners with a registered code pass theirs. */
30
+ referralCode?: number;
31
+ }
32
+ /**
33
+ * Builds the `generateActionsParams` callback for an Aave V3 supply routed
34
+ * through VaultDepositor.
35
+ *
36
+ * Usage:
37
+ * ```ts
38
+ * const checkoutConfig: FunkitCheckoutConfig = {
39
+ * // ...
40
+ * generateActionsParams: createAaveSupplyActions({
41
+ * onBehalfOf: walletAddress,
42
+ * underlyingAsset: usdtAddress,
43
+ * poolAddress: AaveV3Ethereum.POOL,
44
+ * chainId: mainnet.id,
45
+ * }),
46
+ * }
47
+ * ```
48
+ */
49
+ export declare function createAaveSupplyActions(config: AaveSupplyActionsConfig): () => Promise<FunkitCheckoutActionParams[]>;
50
+ export interface AaveSupplyCheckoutInput {
51
+ /** Underlying asset (Aave's `DashboardReserve.underlyingAsset`). */
52
+ underlyingAsset: Address;
53
+ /** Aave V3 Pool contract on `chainId`. From Aave's own registry (`marketsData[market].addresses.LENDING_POOL` or `@aave-dao/aave-address-book`). */
54
+ poolAddress: Address;
55
+ /** Chain ID — typically resolved from Aave's `currentMarket` via `marketsData[market].chainId`. */
56
+ chainId: number;
57
+ /** Connected wallet — becomes `onBehalfOf` for the aToken receipt. Pass `undefined` if the wallet isn't connected yet; actions throw at exec time. */
58
+ walletAddress: Address | undefined;
59
+ /** Reserve metadata used for modal display. Optional, but recommended. */
60
+ display?: {
61
+ /** Token symbol (e.g. "USDT") — drives modal title "Supply USDT" and receipt ticker "aUSDT". */
62
+ symbol: string;
63
+ /** Supply APY as a display string (e.g. "2.79"). When provided, the modal subtitle includes "{apy}% APY". */
64
+ supplyAPY?: string;
65
+ /**
66
+ * Whether this supply is/will be enabled as collateral for the user —
67
+ * Aave's "usage as collateral" toggle (the `isCollateral` enablement
68
+ * concept), NOT the reserve-level "can be collateral" eligibility. When
69
+ * provided, the modal subtitle includes "Collateralization enabled" /
70
+ * "disabled".
71
+ */
72
+ collateralizationEnabled?: boolean;
73
+ /** Override modal icon. If omitted, the modal falls back to its own asset-icon resolver. */
74
+ iconSrc?: string;
75
+ };
76
+ /** Aave referral code; defaults to 0. */
77
+ referralCode?: number;
78
+ }
79
+ /**
80
+ * High-level builder for an Aave V3 supply checkout. Returns a
81
+ * `FunkitCheckoutConfig` ready to launch via Fun's checkout, or `undefined`
82
+ * if `chainId` isn't a Fun-supported chain.
83
+ *
84
+ * The `undefined` return is the canonical "is this path Fun-routed?" signal —
85
+ * callers should fall back to Aave's native supply flow when it's returned.
86
+ *
87
+ * Modal copy ("Supply {symbol}", the "{apy}% APY · Collateralization
88
+ * enabled/disabled" subtitle, "a{symbol}" receipt ticker) is owned here so it
89
+ * stays consistent across SDK consumers. Subtitle segments only appear when
90
+ * the corresponding `display` signal is provided.
91
+ */
92
+ export declare function createAaveSupplyCheckoutConfig(input: AaveSupplyCheckoutInput): FunkitCheckoutConfig | undefined;
@@ -0,0 +1,156 @@
1
+ "use client";
2
+
3
+ // src/clients/aave.tsx
4
+ import {
5
+ encodeFunctionData,
6
+ erc20Abi,
7
+ getAddress,
8
+ maxUint256
9
+ } from "viem";
10
+ import { mainnet as mainnet2 } from "viem/chains";
11
+
12
+ // src/utils/isMainnetUsdt.ts
13
+ import { isTokenEquivalent } from "@funkit/utils";
14
+ import { mainnet } from "viem/chains";
15
+ var USDT_MAINNET_ADDRESS = "0xdAC17F958D2ee523a2206206994597C13D831ec7";
16
+ function isMainnetUsdt(chainId, address) {
17
+ return isTokenEquivalent({
18
+ firstTokenAddress: address,
19
+ firstTokenChainId: chainId.toString(),
20
+ secondTokenAddress: USDT_MAINNET_ADDRESS,
21
+ secondTokenChainId: mainnet.id.toString()
22
+ });
23
+ }
24
+
25
+ // src/clients/aave.tsx
26
+ var VAULT_DEPOSITOR_BY_CHAIN_ID = {
27
+ [mainnet2.id]: getAddress("0x40b72bB73B1E9380629B205e7880Fa409ae7fcc9")
28
+ };
29
+ function isAaveSupplySupported(chainId) {
30
+ return chainId in VAULT_DEPOSITOR_BY_CHAIN_ID;
31
+ }
32
+ var AMOUNT_PLACEHOLDER = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffdeadbeefn;
33
+ var AAVE_POOL_ABI = [
34
+ {
35
+ name: "supply",
36
+ type: "function",
37
+ stateMutability: "nonpayable",
38
+ inputs: [
39
+ { name: "asset", type: "address" },
40
+ { name: "amount", type: "uint256" },
41
+ { name: "onBehalfOf", type: "address" },
42
+ { name: "referralCode", type: "uint16" }
43
+ ],
44
+ outputs: []
45
+ }
46
+ ];
47
+ var VAULT_DEPOSITOR_ABI = [
48
+ {
49
+ name: "deposit",
50
+ type: "function",
51
+ stateMutability: "nonpayable",
52
+ inputs: [
53
+ { name: "token", type: "address" },
54
+ { name: "vault", type: "address" },
55
+ { name: "callData", type: "bytes" },
56
+ { name: "minAmountOut", type: "uint256" }
57
+ ],
58
+ outputs: [{ name: "returnData", type: "bytes" }]
59
+ }
60
+ ];
61
+ function createAaveSupplyActions(config) {
62
+ const {
63
+ onBehalfOf,
64
+ underlyingAsset,
65
+ poolAddress,
66
+ chainId,
67
+ referralCode = 0
68
+ } = config;
69
+ const vaultDepositor = VAULT_DEPOSITOR_BY_CHAIN_ID[chainId];
70
+ return async () => {
71
+ if (!vaultDepositor) {
72
+ throw new Error(
73
+ `Aave supply is not yet supported on chain ${chainId}. Supported chain IDs: ${Object.keys(VAULT_DEPOSITOR_BY_CHAIN_ID).join(", ")}`
74
+ );
75
+ }
76
+ if (!onBehalfOf) {
77
+ throw new Error(
78
+ "Please connect your wallet before starting an Aave supply"
79
+ );
80
+ }
81
+ const asset = getAddress(underlyingAsset);
82
+ const supplyCalldata = encodeFunctionData({
83
+ abi: AAVE_POOL_ABI,
84
+ functionName: "supply",
85
+ args: [asset, AMOUNT_PLACEHOLDER, onBehalfOf, referralCode]
86
+ });
87
+ const needsApprovalReset = isMainnetUsdt(chainId, asset);
88
+ const resetApproval = {
89
+ contractAbi: erc20Abi,
90
+ contractAddress: asset,
91
+ functionName: "approve",
92
+ functionArgs: [vaultDepositor, 0n]
93
+ };
94
+ const maxApproval = {
95
+ contractAbi: erc20Abi,
96
+ contractAddress: asset,
97
+ functionName: "approve",
98
+ functionArgs: [vaultDepositor, maxUint256]
99
+ };
100
+ const vaultDeposit = {
101
+ contractAbi: VAULT_DEPOSITOR_ABI,
102
+ contractAddress: vaultDepositor,
103
+ functionName: "deposit",
104
+ functionArgs: [asset, poolAddress, supplyCalldata, 0n]
105
+ };
106
+ return needsApprovalReset ? [resetApproval, maxApproval, vaultDeposit] : [maxApproval, vaultDeposit];
107
+ };
108
+ }
109
+ function buildSupplyModalTitleMeta(display) {
110
+ const parts = [];
111
+ if (display?.supplyAPY !== void 0) {
112
+ parts.push(`${display.supplyAPY}% APY`);
113
+ }
114
+ if (display?.collateralizationEnabled !== void 0) {
115
+ parts.push(
116
+ `Collateralization ${display.collateralizationEnabled ? "enabled" : "disabled"}`
117
+ );
118
+ }
119
+ return parts.length > 0 ? parts.join(" \xB7 ") : void 0;
120
+ }
121
+ function createAaveSupplyCheckoutConfig(input) {
122
+ const {
123
+ underlyingAsset,
124
+ poolAddress,
125
+ chainId,
126
+ walletAddress,
127
+ display,
128
+ referralCode
129
+ } = input;
130
+ if (!isAaveSupplySupported(chainId)) {
131
+ return void 0;
132
+ }
133
+ const symbol = display?.symbol ?? "asset";
134
+ const receiptTicker = `a${symbol}`;
135
+ return {
136
+ modalTitle: `Supply ${symbol}`,
137
+ modalTitleMeta: buildSupplyModalTitleMeta(display),
138
+ targetChain: chainId.toString(),
139
+ targetAsset: underlyingAsset,
140
+ targetAssetTicker: receiptTicker,
141
+ checkoutItemTitle: receiptTicker,
142
+ iconSrc: display?.iconSrc,
143
+ generateActionsParams: createAaveSupplyActions({
144
+ onBehalfOf: walletAddress,
145
+ underlyingAsset,
146
+ poolAddress,
147
+ chainId,
148
+ referralCode
149
+ })
150
+ };
151
+ }
152
+ export {
153
+ createAaveSupplyActions,
154
+ createAaveSupplyCheckoutConfig,
155
+ isAaveSupplySupported
156
+ };
@@ -125,13 +125,14 @@ function preloadRemoteImages(...imageUrls) {
125
125
  import React2, { useMemo, useReducer as useReducer2, useState } from "react";
126
126
 
127
127
  // src/utils/sanitizeUrl.ts
128
+ var SAFE_URL_PROTOCOLS = /* @__PURE__ */ new Set(["https:", "http:"]);
128
129
  function sanitizeUrl(url) {
129
130
  if (!url) {
130
131
  return void 0;
131
132
  }
132
133
  try {
133
134
  const parsed = new URL(url);
134
- if (parsed.protocol === "https:" || parsed.protocol === "http:") {
135
+ if (SAFE_URL_PROTOCOLS.has(parsed.protocol)) {
135
136
  return parsed.href;
136
137
  }
137
138
  return void 0;
@@ -4,7 +4,7 @@ import {
4
4
  Box,
5
5
  preloadRemoteImages,
6
6
  useFunkitTranslation
7
- } from "./chunk-LMEQD56M.js";
7
+ } from "./chunk-PLDXBAAH.js";
8
8
  import "./chunk-H6F75ULR.js";
9
9
 
10
10
  // src/clients/fanatics.tsx
@@ -13,7 +13,7 @@
13
13
  * Both callbacks conform to CustomWithdrawalConfig.withdrawCallback; the
14
14
  * caller provides the actual on-chain implementation.
15
15
  */
16
- import type { Address } from 'viem';
16
+ import { type Address } from 'viem';
17
17
  import type { CustomWithdrawalConfig, MultiMethodWithdrawalConfig } from '../providers/FunkitCheckoutContext/types';
18
18
  export type LighterTransferParams = {
19
19
  toAccountIndex: number;
@@ -93,6 +93,37 @@ export interface LighterSecureWithdrawalConfig {
93
93
  */
94
94
  getMinWithdrawalAmount?: (symbol: string) => number;
95
95
  }
96
+ /**
97
+ * Records a Lighter Secure withdrawal in Fun's direct-execution table as
98
+ * `EXTERNALLY_FULFILLED` — tracking-only, since Fun is not in the execution
99
+ * path. The row is keyed off the L2 tx hash and exists purely for attribution
100
+ * and support tooling; the backend writes a one-time terminal `listenerInfo`
101
+ * and never polls for L1 settlement (see EXTERNALLY_FULFILLED design doc).
102
+ *
103
+ * Fire-and-forget: callers should not await this, and any failure here must
104
+ * not block the withdrawal success UI. Failures log at warn/error and return.
105
+ */
106
+ export declare function trackLighterSecureWithdrawal({ apiKey, userId, txHash, recipientAddr, assetIndex, mainnetTokenAddress, amountTokenUnits, withdrawalUSD, }: {
107
+ apiKey: string;
108
+ userId: string;
109
+ txHash: string;
110
+ recipientAddr: Address;
111
+ /**
112
+ * Lighter L2 asset index. Used as `fromTokenAddress`
113
+ * (`pad(toHex(assetIndex))`) and to resolve symbol + mainnet decimals from
114
+ * {@link LIGHTER_SECURE_ASSETS_BY_INDEX}.
115
+ */
116
+ assetIndex: number;
117
+ /** Mainnet ERC-20 address the L2 asset bridges to (resolved by the modal). */
118
+ mainnetTokenAddress: Address;
119
+ /** User-input amount in token units (e.g. "1.5" for 1.5 ETH). */
120
+ amountTokenUnits: string;
121
+ /**
122
+ * USD value of the withdrawal as computed by the modal (token amount × live
123
+ * spot price). Avoids a separate spot-price round-trip from this helper.
124
+ */
125
+ withdrawalUSD: string;
126
+ }): Promise<void>;
96
127
  /** Single-method config for Lighter's Secure withdrawal (bridge to Ethereum). */
97
128
  export declare function createLighterSecureWithdrawalConfig(config: LighterSecureWithdrawalConfig): CustomWithdrawalConfig;
98
129
  /**
@@ -112,7 +143,7 @@ export declare function createLighterSecureWithdrawalConfig(config: LighterSecur
112
143
  * ```tsx
113
144
  * const { address: l1Address } = useFunkitUserInfo()
114
145
  * const lighter = useLighterWithdrawalConfig(
115
- * userId && walletClient
146
+ * l1Address && walletClient
116
147
  * ? { l1Address, signerClient, sendLighterSecureWithdrawal, ... }
117
148
  * : null,
118
149
  * )
@@ -3,18 +3,25 @@ import {
3
3
  AsyncImage,
4
4
  Box,
5
5
  useFunkitTranslation
6
- } from "./chunk-LMEQD56M.js";
6
+ } from "./chunk-PLDXBAAH.js";
7
7
  import {
8
8
  logger
9
9
  } from "./chunk-H6F75ULR.js";
10
10
 
11
11
  // src/clients/lighter.tsx
12
- import { SOLANA_MAINNET_CHAIN_ID } from "@funkit/chains";
12
+ import {
13
+ DirectExecutionType,
14
+ LIGHTERXYZ_API_KEY as LIGHTERXYZ_API_KEY2,
15
+ createDirectExecution
16
+ } from "@funkit/api-base";
17
+ import { LIGHTER_CHAIN_ID, SOLANA_MAINNET_CHAIN_ID } from "@funkit/chains";
13
18
  import { RELAY_LIGHTER_CHAIN_ID } from "@funkit/fun-relay";
14
19
  import { retry } from "@lifeomic/attempt";
15
20
  import { useQuery as useQuery2 } from "@tanstack/react-query";
16
21
  import i18next from "i18next";
17
22
  import React2, { useMemo as useMemo2 } from "react";
23
+ import { v4 as uuid } from "uuid";
24
+ import { pad, parseUnits, toHex } from "viem";
18
25
  import { arbitrum, base, bsc, mainnet as mainnet2, optimism } from "viem/chains";
19
26
 
20
27
  // src/components/Icons/EvmWallet.tsx
@@ -48,6 +55,7 @@ import { useQuery } from "@tanstack/react-query";
48
55
 
49
56
  // src/consts/customers.ts
50
57
  import {
58
+ AAVE_API_KEY,
51
59
  AVANTIS_API_KEY,
52
60
  BASED_API_KEY,
53
61
  BSX_API_KEY,
@@ -82,6 +90,7 @@ var DEFAULT_TEXT_CUSTOMIZATIONS = {
82
90
  sourceMethodTitle: "Your source",
83
91
  tokensListTitle: "Your tokens",
84
92
  transferTokens: "Transfer Crypto",
93
+ bitcoinLightning: "Bitcoin on Cash App",
85
94
  receiveDropdownTitle: "",
86
95
  // Default to empty
87
96
  receiveDropdownLabel: "Asset to Receive",
@@ -165,6 +174,7 @@ function useFunkitConfig() {
165
174
  sourceMethodTitle: t("textCustomizations.sourceMethodTitle"),
166
175
  tokensListTitle: t("textCustomizations.tokensListTitle"),
167
176
  transferTokens: t("textCustomizations.transferTokens"),
177
+ bitcoinLightning: t("textCustomizations.bitcoinLightning"),
168
178
  receiveDropdownTitle: t("textCustomizations.receiveDropdownTitle"),
169
179
  receiveDropdownLabel: t("textCustomizations.receiveDropdownLabel"),
170
180
  confirmationScreen: {
@@ -288,6 +298,17 @@ function formatSecondsTranslated(seconds, t, specifyUnderMinute = false, omitSec
288
298
  // src/clients/lighter.tsx
289
299
  var LIGHTER_USDC_PERPS_ADDRESS = "0x0000000000000000000000000000000000000000";
290
300
  var MAINNET_USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
301
+ var LIGHTER_SECURE_ASSETS_BY_INDEX = {
302
+ 1: { symbol: "ETH", decimals: 18 },
303
+ 2: { symbol: "LIT", decimals: 18 },
304
+ 3: { symbol: "USDC", decimals: 6 },
305
+ 5: { symbol: "LINK", decimals: 18 },
306
+ 6: { symbol: "UNI", decimals: 18 },
307
+ 7: { symbol: "AAVE", decimals: 18 },
308
+ 8: { symbol: "SKY", decimals: 18 },
309
+ 9: { symbol: "LDO", decimals: 18 },
310
+ 10: { symbol: "AZTEC", decimals: 18 }
311
+ };
291
312
  var LIGHTER_API_BASE = "https://mainnet.zklighter.elliot.ai";
292
313
  async function getLighterWithdrawalDelay() {
293
314
  const response = await fetch(`${LIGHTER_API_BASE}/api/v1/withdrawalDelay`);
@@ -453,6 +474,86 @@ var LIGHTER_DEFAULT_SECURE_MIN_WITHDRAWAL_AMOUNTS = {
453
474
  LDO: 2,
454
475
  AZTEC: 100
455
476
  };
477
+ function truncateAmountToDecimals(amount, decimals) {
478
+ const [whole = "0", frac = ""] = amount.split(".");
479
+ if (frac.length <= decimals) {
480
+ return amount;
481
+ }
482
+ const truncated = frac.slice(0, decimals);
483
+ return truncated ? `${whole}.${truncated}` : whole;
484
+ }
485
+ async function trackLighterSecureWithdrawal({
486
+ apiKey,
487
+ userId,
488
+ txHash,
489
+ recipientAddr,
490
+ assetIndex,
491
+ mainnetTokenAddress,
492
+ amountTokenUnits,
493
+ withdrawalUSD
494
+ }) {
495
+ const assetMeta = LIGHTER_SECURE_ASSETS_BY_INDEX[assetIndex];
496
+ if (!assetMeta) {
497
+ logger.error(
498
+ "lighter:withdrawal:secure:tracking:unknownAssetIndex",
499
+ new Error(`Unknown Lighter Secure asset index: ${assetIndex}`),
500
+ { assetIndex, txHash }
501
+ );
502
+ return;
503
+ }
504
+ const { symbol, decimals } = assetMeta;
505
+ const estTotalUsd = Number(withdrawalUSD);
506
+ const safeAmount = truncateAmountToDecimals(amountTokenUnits, decimals);
507
+ const baseUnitAmount = parseUnits(safeAmount, decimals).toString();
508
+ const fromTokenAddress = pad(toHex(assetIndex), { size: 20 });
509
+ await createDirectExecution({
510
+ apiKey,
511
+ logger,
512
+ // Lighter L2 tx hashes are not 0x-prefixed EVM hashes — they're the L2's
513
+ // own format. We cast here for convenience to satisfy the DE row type;
514
+ // the backend stores the literal string and we never use it as an EVM hash.
515
+ txHash,
516
+ type: DirectExecutionType.EXTERNALLY_FULFILLED,
517
+ userId,
518
+ recipientAddr,
519
+ fromChainId: LIGHTER_CHAIN_ID.toString(),
520
+ fromTokenAddress,
521
+ toChainId: mainnet2.id.toString(),
522
+ toTokenAddress: mainnetTokenAddress,
523
+ fromAmountBaseUnit: baseUnitAmount,
524
+ toAmountBaseUnit: baseUnitAmount,
525
+ estTotalUsd,
526
+ // Secure withdrawals come out of the user's Lighter account balance; the
527
+ // L1 owner of that account is the recipient (Secure locks to connected wallet).
528
+ sourceOfFund: `balance|lighter-secure|${recipientAddr}`,
529
+ clientMetadata: {
530
+ id: uuid(),
531
+ startTimestampMs: Date.now(),
532
+ finalDollarValue: estTotalUsd,
533
+ latestQuote: null,
534
+ depositAddress: null,
535
+ initSettings: {
536
+ config: {
537
+ targetAsset: mainnetTokenAddress,
538
+ targetChain: mainnet2.id.toString(),
539
+ targetAssetTicker: symbol
540
+ }
541
+ },
542
+ selectedSourceAssetInfo: {
543
+ address: fromTokenAddress,
544
+ symbol,
545
+ chainId: LIGHTER_CHAIN_ID.toString(),
546
+ iconSrc: null
547
+ },
548
+ selectedPaymentMethodInfo: {
549
+ paymentMethod: "LIGHTER_SECURE_WITHDRAWAL",
550
+ title: "",
551
+ description: ""
552
+ },
553
+ isWithdrawal: true
554
+ }
555
+ });
556
+ }
456
557
  function buildSecureWithdrawalCallback({
457
558
  exec
458
559
  }) {
@@ -476,6 +577,7 @@ function buildSecureWithdrawalCallback({
476
577
  );
477
578
  return;
478
579
  }
580
+ const withdrawalUSD = param.withdrawalUSD ?? "0";
479
581
  logger.info("lighter:withdrawal:secure:start", {
480
582
  assetIndex,
481
583
  amountTokenUnits,
@@ -491,6 +593,25 @@ function buildSecureWithdrawalCallback({
491
593
  assetIndex,
492
594
  txHash
493
595
  });
596
+ void trackLighterSecureWithdrawal({
597
+ apiKey: LIGHTERXYZ_API_KEY2,
598
+ // Secure locks the destination to the connected wallet, so the L1
599
+ // recipient address doubles as the userId for tracking purposes.
600
+ userId: destinationAddress,
601
+ txHash,
602
+ recipientAddr: destinationAddress,
603
+ assetIndex,
604
+ mainnetTokenAddress: targetAssetAddress,
605
+ amountTokenUnits,
606
+ withdrawalUSD
607
+ }).catch((err) => {
608
+ logger.warn("lighter:withdrawal:secure:trackingFailed", {
609
+ error: err instanceof Error ? err.message : String(err),
610
+ txHash,
611
+ assetIndex,
612
+ amountTokenUnits
613
+ });
614
+ });
494
615
  return txHash;
495
616
  };
496
617
  }
@@ -655,5 +776,6 @@ function useLighterWithdrawalConfig(config) {
655
776
  export {
656
777
  LIGHTER_DEFAULT_SECURE_MIN_WITHDRAWAL_AMOUNTS,
657
778
  createLighterSecureWithdrawalConfig,
779
+ trackLighterSecureWithdrawal,
658
780
  useLighterWithdrawalConfig
659
781
  };