@funkit/connect 9.0.0 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @funkit/connect
2
2
 
3
+ ## 9.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 7506ab8: feat(connect): swapped statsig step events
8
+ - 0e2bc9d: feat(connect): swapped iframe event metadata
9
+ - c1fed6a: fix: swapped box paddings
10
+ - 9b87e81: replace postmessage wildcard origin for swapped
11
+ - c5d7c00: feat: resolve css variable values before sending theme to swapped
12
+ - f863de4: feat(connect): add timeout error logs
13
+
3
14
  ## 9.0.0
4
15
 
5
16
  ### Major Changes
@@ -32,6 +32,8 @@ export declare enum CheckoutModalEvent {
32
32
  READY_TRANSFER_TOKEN = "fc::ready::transfer_token",
33
33
  READY_LOADING_ACCOUNT = "fc::ready::loading_account",
34
34
  READY_SWAPPED_IFRAME = "fc::ready::swapped_iframe",
35
+ SOURCE_CHANGE_CRYPTO_TAB = "fc::source_change::crypto_tab",
36
+ SOURCE_CHANGE_CASH_TAB = "fc::source_change::cash_tab",
35
37
  QUERY_FROG_SUB_ACCOUNTS = "fc::query::frog_sub_accounts",
36
38
  QUERY_UDA_ADDRESS = "fc::query::uda_address",
37
39
  QUERY_WALLET_ASSETS = "fc::query::wallet_assets",
@@ -44,6 +46,10 @@ export declare enum CheckoutModalEvent {
44
46
  BLUVO_WITHDRAWAL_COMPLETED = "fc::success::bluvo_withdrawal_completed",
45
47
  QUICK_OPTION_SELECTED = "fc::input_amount::quick_option_selected",
46
48
  SWAPPED_IFRAME_NAVIGATION = "fc::swapped_iframe::navigation",
49
+ SWAPPED_IFRAME_NAVIGATION_INITIAL = "fc::swapped_iframe::navigation::initial",
50
+ SWAPPED_IFRAME_NAVIGATION_KYC = "fc::swapped_iframe::navigation::kyc",
51
+ SWAPPED_IFRAME_NAVIGATION_PAYMENT = "fc::swapped_iframe::navigation::payment",
52
+ SWAPPED_IFRAME_NAVIGATION_CONFIRMATION = "fc::swapped_iframe::navigation::confirmation",
47
53
  SWAPPED_IFRAME_COMPLETE = "fc::swapped_iframe::complete",
48
54
  SWAPPED_IFRAME_ERROR = "fc::swapped_iframe::error",
49
55
  SWAPPED_IFRAME_BACK = "fc::swapped_iframe::back",
package/dist/index.js CHANGED
@@ -2354,7 +2354,7 @@ function setFunkitConnectVersion({ version }) {
2354
2354
  localStorage.setItem(storageKey, version);
2355
2355
  }
2356
2356
  function getCurrentSdkVersion() {
2357
- return "9.0.0";
2357
+ return "9.0.1";
2358
2358
  }
2359
2359
  function useFingerprint() {
2360
2360
  const fingerprint = useCallback3(() => {
@@ -7346,6 +7346,18 @@ var flagConfig = {
7346
7346
  }
7347
7347
  ],
7348
7348
  value: JSON.stringify(QR_CODE_WITH_MONAD)
7349
+ },
7350
+ {
7351
+ if_any: [
7352
+ {
7353
+ key: "apiKey",
7354
+ type: "isAnyOf",
7355
+ values: [VENTUALS_API_KEY]
7356
+ }
7357
+ ],
7358
+ // Relay does not support Bitcoin to Hyperliquid USDH route (https://fun-xyz.slack.com/archives/C0AKC3U55FC)
7359
+ // If we want to enable other chains for Ventuals, please remember to exclude Bitcoin
7360
+ value: JSON.stringify(QR_CODE_WITH_SOLANA)
7349
7361
  }
7350
7362
  ]
7351
7363
  },
@@ -20505,6 +20517,14 @@ var getSavedFormOfPaymentIcon = (fop) => {
20505
20517
  const cardBrandInfo = SWAPPED_CARD_BRANDS[cardBrand];
20506
20518
  return cardBrandInfo?.iconImageUrl ?? fop.iconImageUrl;
20507
20519
  };
20520
+ function getSwappedOrigin(url) {
20521
+ try {
20522
+ const { origin } = new URL(url);
20523
+ return isSwappedOrigin(origin) ? origin : null;
20524
+ } catch {
20525
+ return null;
20526
+ }
20527
+ }
20508
20528
  function isSwappedOrigin(origin) {
20509
20529
  try {
20510
20530
  const { hostname } = new URL(origin);
@@ -20513,38 +20533,77 @@ function isSwappedOrigin(origin) {
20513
20533
  return false;
20514
20534
  }
20515
20535
  }
20516
- function buildSwappedTheme(activeTheme, customFontFamily) {
20536
+ function resolveCssValue(value) {
20537
+ if (typeof value !== "string" || !value.startsWith("var(")) {
20538
+ return value;
20539
+ }
20540
+ if (typeof document === "undefined") {
20541
+ return value;
20542
+ }
20543
+ try {
20544
+ const prop = value.slice(4, -1).split(",")[0]?.trim();
20545
+ if (!prop) {
20546
+ return value;
20547
+ }
20548
+ const resolved = getComputedStyle(document.documentElement).getPropertyValue(prop).trim();
20549
+ return resolved || value;
20550
+ } catch {
20551
+ return value;
20552
+ }
20553
+ }
20554
+ function resolveObjectCssVars(obj) {
20555
+ if (!obj || typeof obj !== "object") {
20556
+ return obj;
20557
+ }
20558
+ const result = {};
20559
+ for (const key in obj) {
20560
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
20561
+ const val = obj[key];
20562
+ if (typeof val === "string") {
20563
+ result[key] = resolveCssValue(val);
20564
+ } else if (val && typeof val === "object" && !Array.isArray(val)) {
20565
+ result[key] = resolveObjectCssVars(val);
20566
+ } else {
20567
+ result[key] = val;
20568
+ }
20569
+ }
20570
+ }
20571
+ return result;
20572
+ }
20573
+ function buildSwappedTheme(theme) {
20574
+ const { customFontFamily } = theme;
20517
20575
  const toFontSlug = (name) => name.toLowerCase().replace(/ /g, "-");
20518
- return {
20576
+ const swappedTheme = {
20519
20577
  colors: {
20520
- ...activeTheme.colors,
20521
- buttonDisabled: activeTheme.colors.buttonBackgroundDisabled,
20522
- headerButtonBackground: activeTheme.colors.modalTopbarIconBackground,
20523
- inputBorder: activeTheme.colors.inputBorderBase,
20524
- secondaryButtonBg: activeTheme.colors.modalTopbarIconBackground,
20525
- secondaryButtonText: activeTheme.colors.modalTopbarIcon,
20526
- secondaryButtonHover: activeTheme.colors.modalTopbarIconBackgroundHover,
20527
- secondaryButtonTextHover: activeTheme.colors.modalTopbarIcon,
20528
- inputBorderFocused: activeTheme.colors.secondaryText,
20529
- inputBorderActive: activeTheme.colors.secondaryText,
20530
- inputPlaceholder: activeTheme.colors.secondaryText
20578
+ ...theme.colors,
20579
+ buttonDisabled: theme.colors.buttonBackgroundDisabled,
20580
+ headerButtonBackground: theme.colors.modalTopbarIconBackground,
20581
+ inputBorder: theme.colors.inputBorderBase,
20582
+ secondaryButtonBg: theme.colors.modalTopbarIconBackground,
20583
+ secondaryButtonText: theme.colors.modalTopbarIcon,
20584
+ secondaryButtonHover: theme.colors.modalTopbarIconBackgroundHover,
20585
+ secondaryButtonTextHover: theme.colors.modalTopbarIcon,
20586
+ inputBorderFocused: theme.colors.secondaryText,
20587
+ inputBorderActive: theme.colors.secondaryText,
20588
+ inputPlaceholder: theme.colors.secondaryText
20531
20589
  },
20532
20590
  radii: {
20533
- ...activeTheme.radii,
20534
- otpInput: activeTheme.radii.actionButton,
20535
- calculatorInput: activeTheme.radii.actionButton,
20536
- amountPill: activeTheme.radii.actionButton
20537
- },
20538
- headerHeight: activeTheme.dimensions.modalTopBarHeight,
20539
- headerFontWeight: activeTheme.fontWeight.modalTopbarTitle,
20540
- topbarIconColor: activeTheme.colors.modalTopbarIcon,
20541
- topbarTextFontSize: activeTheme.fontSize.modalTopbarTitle.fontSize,
20542
- headerIconWrapperSize: activeTheme.dimensions.modalTopbarIconWrapperSize,
20543
- headerIconSize: activeTheme.dimensions.modalTopbarIconSize,
20544
- buttonFontWeight: activeTheme.fontWeight.modalBottomBarButtonText,
20545
- modalBottomBarButtonHeight: activeTheme.dimensions.modalBottomBarButtonHeight,
20546
- iframeBackground: activeTheme.colors.modalBackground,
20591
+ ...theme.radii,
20592
+ otpInput: theme.radii.actionButton,
20593
+ calculatorInput: theme.radii.actionButton,
20594
+ amountPill: theme.radii.actionButton
20595
+ },
20596
+ headerHeight: theme.dimensions.modalTopBarHeight,
20597
+ headerFontWeight: theme.fontWeight.modalTopbarTitle,
20598
+ topbarIconColor: theme.colors.modalTopbarIcon,
20599
+ topbarTextFontSize: theme.fontSize.modalTopbarTitle.fontSize,
20600
+ headerIconWrapperSize: theme.dimensions.modalTopbarIconWrapperSize,
20601
+ headerIconSize: theme.dimensions.modalTopbarIconSize,
20602
+ buttonFontWeight: theme.fontWeight.modalBottomBarButtonText,
20603
+ modalBottomBarButtonHeight: theme.dimensions.modalBottomBarButtonHeight,
20604
+ iframeBackground: theme.colors.modalBackground,
20547
20605
  boxPaddingY: "16px",
20606
+ boxPaddingX: "16px",
20548
20607
  paddingPrimary: "20px",
20549
20608
  paddingSecondary: "12px",
20550
20609
  paddingTertiary: "20px",
@@ -20555,6 +20614,21 @@ function buildSwappedTheme(activeTheme, customFontFamily) {
20555
20614
  secondaryFont: toFontSlug(customFontFamily.secondary)
20556
20615
  }
20557
20616
  };
20617
+ return resolveObjectCssVars(swappedTheme);
20618
+ }
20619
+ function buildSwappedThemeQueryParams(activeTheme) {
20620
+ const toRawHex = (color) => resolveCssValue(color).replace(/^#/, "");
20621
+ return {
20622
+ iframeBackground: toRawHex(activeTheme.colors.modalBackground),
20623
+ widgetBackground: toRawHex(activeTheme.colors.modalBackground),
20624
+ textColor: toRawHex(activeTheme.colors.primaryText),
20625
+ spinnerColor: toRawHex(activeTheme.colors.spinnerIndicator),
20626
+ modalRadii: resolveCssValue(activeTheme.radii.modal),
20627
+ skeletonColor: toRawHex(activeTheme.colors.inputBorderHover),
20628
+ skeletonSecondaryColor: toRawHex(activeTheme.colors.offBackground),
20629
+ height: String(DIALOG_HEIGHT),
20630
+ width: String(Number.parseInt(DIALOG_WIDTH_WIDE))
20631
+ };
20558
20632
  }
20559
20633
 
20560
20634
  // src/components/FunBadge/BridgeCustomerStatusBadge.tsx
@@ -25030,7 +25104,7 @@ import React239 from "react";
25030
25104
  import {
25031
25105
  useCallback as useCallback48,
25032
25106
  useEffect as useEffect59,
25033
- useRef as useRef33,
25107
+ useRef as useRef34,
25034
25108
  useState as useState71
25035
25109
  } from "react";
25036
25110
 
@@ -35060,7 +35134,7 @@ import {
35060
35134
  } from "@funkit/api-base";
35061
35135
  import { LIGHTER_CHAIN_ID as LIGHTER_CHAIN_ID3 } from "@funkit/chains";
35062
35136
  import { noop as noop9 } from "@funkit/utils";
35063
- import React221, { useEffect as useEffect55, useState as useState63 } from "react";
35137
+ import React221, { useEffect as useEffect55, useRef as useRef31, useState as useState63 } from "react";
35064
35138
  import { createPortal as createPortal20 } from "react-dom";
35065
35139
 
35066
35140
  // src/hooks/queries/useFops.ts
@@ -35156,7 +35230,6 @@ var useSwappedDefaultCurrency = () => {
35156
35230
  };
35157
35231
 
35158
35232
  // src/hooks/queries/useFops.ts
35159
- var stripHash = (color) => color.replace(/^#/, "");
35160
35233
  function validateFormOfPayments(res) {
35161
35234
  const isValid = (data) => {
35162
35235
  if (!data.iconImageUrl || !isValidUrl(data.embeddedFlowUrl)) {
@@ -35198,19 +35271,10 @@ var useFops = () => {
35198
35271
  } = useSwappedDefaultCurrency();
35199
35272
  const { checkoutItem } = useCheckoutContext();
35200
35273
  const { transferInit, isLoading: isTransferInitLoading } = useCheckoutTransferInit();
35201
- const themeConfig = useMemo47(() => {
35202
- return {
35203
- iframeBackground: stripHash(activeTheme.colors.modalBackground),
35204
- widgetBackground: stripHash(activeTheme.colors.modalBackground),
35205
- textColor: stripHash(activeTheme.colors.primaryText),
35206
- spinnerColor: stripHash(activeTheme.colors.spinnerIndicator),
35207
- modalRadii: activeTheme.radii.modal,
35208
- skeletonColor: stripHash(activeTheme.colors.inputBorderHover),
35209
- skeletonSecondaryColor: stripHash(activeTheme.colors.offBackground),
35210
- height: String(DIALOG_HEIGHT),
35211
- width: String(Number.parseInt(DIALOG_WIDTH_WIDE))
35212
- };
35213
- }, [activeTheme.colors, activeTheme.radii.modal]);
35274
+ const themeConfig = useMemo47(
35275
+ () => buildSwappedThemeQueryParams(activeTheme),
35276
+ [activeTheme]
35277
+ );
35214
35278
  const targetAsset = checkoutItem?.initSettings.config.targetAsset;
35215
35279
  const targetChain = checkoutItem?.initSettings.config.targetChain;
35216
35280
  const recipientAddress = getDepositAddressForChain(
@@ -35409,7 +35473,10 @@ function SwappedProvider({ children }) {
35409
35473
  const activeCallbacksRef = useRef30(null);
35410
35474
  const loadDelayTimeoutRef = useRef30(void 0);
35411
35475
  const swappedTheme = useMemo48(
35412
- () => buildSwappedTheme(activeTheme, uiCustomizations.customFontFamily),
35476
+ () => buildSwappedTheme({
35477
+ ...activeTheme,
35478
+ customFontFamily: uiCustomizations.customFontFamily
35479
+ }),
35413
35480
  [activeTheme, uiCustomizations.customFontFamily]
35414
35481
  );
35415
35482
  const setActiveCallbacks = useCallback43(
@@ -35428,11 +35495,13 @@ function SwappedProvider({ children }) {
35428
35495
  },
35429
35496
  [pool.activeUrlRef, pool.getRef]
35430
35497
  );
35431
- const sendThemeToWindow = useEffectEvent((contentWindow) => {
35432
- const msg = { type: "SWAPPED_THEME", data: swappedTheme };
35433
- contentWindow.postMessage(msg, "*");
35434
- logger.info("swapped-provider:sendTheme", { postMessage: msg });
35435
- });
35498
+ const sendThemeToWindow = useEffectEvent(
35499
+ (contentWindow, targetOrigin) => {
35500
+ const msg = { type: "SWAPPED_THEME", data: swappedTheme };
35501
+ contentWindow.postMessage(msg, targetOrigin);
35502
+ logger.info("swapped-provider:sendTheme", { postMessage: msg });
35503
+ }
35504
+ );
35436
35505
  const onIframeReady = useEffectEvent((source) => {
35437
35506
  const url = pool.urls.find((u) => pool.getRef(u)?.contentWindow === source);
35438
35507
  if (url) {
@@ -35448,9 +35517,10 @@ function SwappedProvider({ children }) {
35448
35517
  });
35449
35518
  const handleIframeElementLoaded = useCallback43(
35450
35519
  (url) => {
35520
+ const targetOrigin = getSwappedOrigin(url);
35451
35521
  const contentWindow = pool.getRef(url)?.contentWindow;
35452
- if (contentWindow) {
35453
- sendThemeToWindow(contentWindow);
35522
+ if (contentWindow && targetOrigin) {
35523
+ sendThemeToWindow(contentWindow, targetOrigin);
35454
35524
  }
35455
35525
  },
35456
35526
  [pool.getRef, sendThemeToWindow]
@@ -35460,13 +35530,17 @@ function SwappedProvider({ children }) {
35460
35530
  }, []);
35461
35531
  useEffect53(() => {
35462
35532
  for (const url of pool.urls) {
35533
+ const targetOrigin = getSwappedOrigin(url);
35463
35534
  const contentWindow = pool.getRef(url)?.contentWindow;
35464
- if (contentWindow) {
35465
- const msg = { type: "SWAPPED_THEME", data: swappedTheme };
35466
- contentWindow.postMessage(msg, "*");
35535
+ const isLoaded = pool.loadedUrlsRef.current.includes(url);
35536
+ if (contentWindow && targetOrigin && isLoaded) {
35537
+ contentWindow.postMessage(
35538
+ { type: "SWAPPED_THEME", data: swappedTheme },
35539
+ targetOrigin
35540
+ );
35467
35541
  }
35468
35542
  }
35469
- }, [swappedTheme, pool.urls, pool.getRef]);
35543
+ }, [swappedTheme, pool.urls, pool.getRef, pool.loadedUrlsRef]);
35470
35544
  useEffect53(() => {
35471
35545
  function handleMessage(event) {
35472
35546
  if (!isSwappedOrigin(event.origin)) {
@@ -35478,7 +35552,7 @@ function SwappedProvider({ children }) {
35478
35552
  }
35479
35553
  if (messageType === "SWAPPED_READY") {
35480
35554
  if (event.source && "postMessage" in event.source) {
35481
- sendThemeToWindow(event.source);
35555
+ sendThemeToWindow(event.source, event.origin);
35482
35556
  onIframeReady(event.source);
35483
35557
  }
35484
35558
  }
@@ -35486,9 +35560,6 @@ function SwappedProvider({ children }) {
35486
35560
  return;
35487
35561
  }
35488
35562
  switch (messageType) {
35489
- case "SWAPPED_READY":
35490
- activeCallbacksRef.current.onReady();
35491
- break;
35492
35563
  case "SWAPPED_COMPLETE":
35493
35564
  activeCallbacksRef.current.onComplete();
35494
35565
  break;
@@ -36011,6 +36082,7 @@ function SourceChange({
36011
36082
  setModalState
36012
36083
  }) {
36013
36084
  const bluvo = useBluvo();
36085
+ const { logEvent } = useTrack();
36014
36086
  const connectionStatus = useConnectionStatus();
36015
36087
  const bottomSectionRef = useBottomSectionRef();
36016
36088
  const { t } = useFunkitTranslation();
@@ -36119,6 +36191,22 @@ function SourceChange({
36119
36191
  setModalState((state) => ({ ...state, showWalletOptions: true }));
36120
36192
  }
36121
36193
  };
36194
+ const lastObservedTabRef = useRef31(void 0);
36195
+ const sendPaymentMethodTabEvent = useEffectEvent((tab) => {
36196
+ if (lastObservedTabRef.current === tab) {
36197
+ return;
36198
+ }
36199
+ lastObservedTabRef.current = tab;
36200
+ logEvent(
36201
+ trackEventForTabChange(
36202
+ checkoutItem ?? { id: modalState.checkoutId },
36203
+ tab
36204
+ )
36205
+ );
36206
+ });
36207
+ useEffect55(() => {
36208
+ sendPaymentMethodTabEvent(paymentMethodTab);
36209
+ }, [paymentMethodTab, sendPaymentMethodTabEvent]);
36122
36210
  const handleNewSourceContinue = async (newSource2, isConfirmed = false) => {
36123
36211
  setConnectedSource(null);
36124
36212
  setNewSource(newSource2);
@@ -36317,10 +36405,21 @@ function SourceChange({
36317
36405
  bottomSectionRef
36318
36406
  ));
36319
36407
  }
36408
+ function trackEventForTabChange(checkoutItem, tab) {
36409
+ return {
36410
+ eventName: tab === "crypto" ? "fc::source_change::crypto_tab" /* SOURCE_CHANGE_CRYPTO_TAB */ : "fc::source_change::cash_tab" /* SOURCE_CHANGE_CASH_TAB */,
36411
+ metadata: {
36412
+ ...checkoutItem,
36413
+ // alias 'id' to 'checkoutId' for better readability / consistency with other events
36414
+ id: void 0,
36415
+ checkoutId: checkoutItem.id
36416
+ }
36417
+ };
36418
+ }
36320
36419
 
36321
36420
  // src/modals/CheckoutModal/SwappedIframe/SwappedIframe.tsx
36322
36421
  import { useQueryClient as useQueryClient3 } from "@tanstack/react-query";
36323
- import React222, { useEffect as useEffect56, useRef as useRef31, useState as useState64 } from "react";
36422
+ import React222, { useEffect as useEffect56, useRef as useRef32, useState as useState64 } from "react";
36324
36423
  var SwappedIframeInfo = {
36325
36424
  Component: SwappedIframe,
36326
36425
  onBack: (state, prevState) => {
@@ -36354,7 +36453,8 @@ function SwappedIframe({
36354
36453
  const { t } = useFunkitTranslation();
36355
36454
  const queryClient = useQueryClient3();
36356
36455
  const [error, setError] = useState64(null);
36357
- const timeoutRef = useRef31(void 0);
36456
+ const timeoutRef = useRef32(void 0);
36457
+ const { checkoutItem } = useCheckoutContext();
36358
36458
  const {
36359
36459
  activateIframe,
36360
36460
  deactivateIframe,
@@ -36366,73 +36466,122 @@ function SwappedIframe({
36366
36466
  const { selectedPaymentOption } = modalState;
36367
36467
  const iframeUrl = selectedPaymentOption.embeddedFlowUrl || "";
36368
36468
  const loaded = loadedIframeUrls.includes(iframeUrl);
36469
+ const getTrackEvent = useEffectEvent(
36470
+ (event, extras) => trackEventForFormOfPayment(
36471
+ selectedPaymentOption,
36472
+ checkoutItem ?? { id: modalState.checkoutId },
36473
+ event,
36474
+ extras
36475
+ )
36476
+ );
36369
36477
  useEffect56(() => {
36370
36478
  startMeasuredEvent("fc::ready::swapped_iframe" /* READY_SWAPPED_IFRAME */);
36371
36479
  }, [startMeasuredEvent]);
36480
+ useEffect56(() => {
36481
+ if (loaded) {
36482
+ const event = getTrackEvent("fc::ready::swapped_iframe" /* READY_SWAPPED_IFRAME */);
36483
+ logger.info("swapped-iframe:ready", event.metadata);
36484
+ logMeasuredEvent(event);
36485
+ }
36486
+ }, [getTrackEvent, loaded, logMeasuredEvent]);
36372
36487
  useEffect56(() => {
36373
36488
  setActiveCallbacks({
36374
- onReady: () => {
36375
- logger.info("swapped-iframe:ready");
36376
- },
36377
36489
  onComplete: () => {
36378
- logger.info("swapped-iframe:complete");
36379
- logEvent({
36380
- eventName: "fc::swapped_iframe::complete" /* SWAPPED_IFRAME_COMPLETE */,
36381
- metadata: {
36382
- paymentOptionType: selectedPaymentOption.fopType
36383
- }
36384
- });
36490
+ const event = getTrackEvent("fc::swapped_iframe::complete" /* SWAPPED_IFRAME_COMPLETE */);
36491
+ logger.info("swapped-iframe:complete", event.metadata);
36492
+ logEvent(event);
36385
36493
  queryClient.invalidateQueries({ queryKey: ["fops"] });
36386
36494
  onNext({ success: true });
36387
36495
  },
36388
36496
  onBack: () => {
36389
- logger.info("swapped-iframe:back");
36390
- logEvent({
36391
- eventName: "fc::swapped_iframe::back" /* SWAPPED_IFRAME_BACK */
36392
- });
36497
+ const event = getTrackEvent("fc::swapped_iframe::back" /* SWAPPED_IFRAME_BACK */);
36498
+ logger.info("swapped-iframe:back", event.metadata);
36499
+ logEvent(event);
36393
36500
  queryClient.invalidateQueries({ queryKey: ["fops"] });
36394
36501
  onBack();
36395
36502
  },
36396
36503
  onNewDeposit: () => {
36397
- logger.info("swapped-iframe:back_and_new_deposit");
36398
- logEvent({
36399
- eventName: "fc::swapped_iframe::new_deposit_back" /* SWAPPED_IFRAME_NEW_DEPOSIT_BACK */
36400
- });
36504
+ const event = getTrackEvent(
36505
+ "fc::swapped_iframe::new_deposit_back" /* SWAPPED_IFRAME_NEW_DEPOSIT_BACK */
36506
+ );
36507
+ logger.info("swapped-iframe:back_and_new_deposit", event.metadata);
36508
+ logEvent(event);
36401
36509
  queryClient.invalidateQueries({ queryKey: ["fops"] });
36402
36510
  onBack();
36403
36511
  },
36404
36512
  onExit: () => {
36405
- logger.info("swapped-iframe:exit");
36406
- logEvent({
36407
- eventName: "fc::swapped_iframe::exit" /* SWAPPED_IFRAME_EXIT */
36408
- });
36513
+ const event = getTrackEvent("fc::swapped_iframe::exit" /* SWAPPED_IFRAME_EXIT */);
36514
+ logger.info("swapped-iframe:exit", event.metadata);
36515
+ logEvent(event);
36409
36516
  queryClient.invalidateQueries({ queryKey: ["fops"] });
36410
36517
  onClose();
36411
36518
  },
36412
36519
  onError: (message) => {
36413
- logger.error("swapped-iframe:error", { message });
36414
- logEvent({
36415
- eventName: "fc::swapped_iframe::error" /* SWAPPED_IFRAME_ERROR */,
36416
- metadata: { message }
36520
+ const event = getTrackEvent("fc::swapped_iframe::error" /* SWAPPED_IFRAME_ERROR */, {
36521
+ message
36417
36522
  });
36523
+ logger.error("swapped-iframe:error", event.metadata);
36524
+ logEvent(event);
36418
36525
  setError(t("checkoutConfirmation.genericErrorMessage"));
36419
36526
  },
36420
36527
  onNavigation: (step) => {
36421
- logger.info("swapped-iframe:navigation", { step });
36422
- logEvent({
36423
- eventName: "fc::swapped_iframe::navigation" /* SWAPPED_IFRAME_NAVIGATION */,
36424
- metadata: { step }
36425
- });
36528
+ switch (step) {
36529
+ // that's the initial step with the amount input
36530
+ case "EMPTY": {
36531
+ const event = getTrackEvent(
36532
+ "fc::swapped_iframe::navigation::initial" /* SWAPPED_IFRAME_NAVIGATION_INITIAL */
36533
+ );
36534
+ logger.info("swapped-iframe:navigation:initial", event.metadata);
36535
+ logEvent(event);
36536
+ break;
36537
+ }
36538
+ case "KYC_IDENTITY": {
36539
+ const event = getTrackEvent(
36540
+ "fc::swapped_iframe::navigation::kyc" /* SWAPPED_IFRAME_NAVIGATION_KYC */
36541
+ );
36542
+ logger.info("swapped-iframe:navigation:kyc", event.metadata);
36543
+ logEvent(event);
36544
+ break;
36545
+ }
36546
+ case "PAYMENT": {
36547
+ const event = getTrackEvent(
36548
+ "fc::swapped_iframe::navigation::payment" /* SWAPPED_IFRAME_NAVIGATION_PAYMENT */
36549
+ );
36550
+ logger.info("swapped-iframe:navigation:payment", event.metadata);
36551
+ logEvent(event);
36552
+ break;
36553
+ }
36554
+ case "ORDER_CONFIRMATION": {
36555
+ const event = getTrackEvent(
36556
+ "fc::swapped_iframe::navigation::confirmation" /* SWAPPED_IFRAME_NAVIGATION_CONFIRMATION */
36557
+ );
36558
+ logger.info(
36559
+ "swapped-iframe:navigation:confirmation",
36560
+ event.metadata
36561
+ );
36562
+ logEvent(event);
36563
+ break;
36564
+ }
36565
+ default: {
36566
+ const event = getTrackEvent(
36567
+ "fc::swapped_iframe::navigation" /* SWAPPED_IFRAME_NAVIGATION */,
36568
+ { step }
36569
+ );
36570
+ logger.info("swapped-iframe:navigation", event.metadata);
36571
+ logEvent(event);
36572
+ break;
36573
+ }
36574
+ }
36426
36575
  }
36427
36576
  });
36428
36577
  return () => setActiveCallbacks(null);
36429
36578
  }, [
36579
+ getTrackEvent,
36430
36580
  setActiveCallbacks,
36431
36581
  logEvent,
36432
36582
  onBack,
36433
36583
  onClose,
36434
36584
  onNext,
36435
- selectedPaymentOption.fopType,
36436
36585
  t,
36437
36586
  queryClient
36438
36587
  ]);
@@ -36447,16 +36596,12 @@ function SwappedIframe({
36447
36596
  }
36448
36597
  timeoutRef.current = setTimeout(() => {
36449
36598
  setError(t("common.pleaseTryAgainLater"));
36599
+ logger.error("swapped-iframe:timeout", {
36600
+ message: "Unable to load swapped iframe. Max timeout error"
36601
+ });
36450
36602
  }, TIMEOUT_ERROR);
36451
36603
  return () => clearTimeout(timeoutRef.current);
36452
36604
  }, [loaded, t]);
36453
- useEffect56(() => {
36454
- if (loaded) {
36455
- logMeasuredEvent({
36456
- eventName: "fc::ready::swapped_iframe" /* READY_SWAPPED_IFRAME */
36457
- });
36458
- }
36459
- }, [loaded, logMeasuredEvent]);
36460
36605
  if (error) {
36461
36606
  return /* @__PURE__ */ React222.createElement(React222.Fragment, null, /* @__PURE__ */ React222.createElement(Dialog.Content, null, /* @__PURE__ */ React222.createElement(
36462
36607
  Box,
@@ -36590,10 +36735,26 @@ function SwappedIframe({
36590
36735
  }
36591
36736
  return null;
36592
36737
  }
36738
+ function trackEventForFormOfPayment(fop, checkoutItem, eventName, extras) {
36739
+ return {
36740
+ eventName,
36741
+ metadata: {
36742
+ ...checkoutItem,
36743
+ ...extras,
36744
+ fopMetadata: fop.metadata,
36745
+ fopName: fop.name,
36746
+ fopType: fop.fopType,
36747
+ fopUrl: fop.embeddedFlowUrl,
36748
+ // alias 'id' to 'checkoutId' for better readability / consistency with other events
36749
+ id: void 0,
36750
+ checkoutId: checkoutItem.id
36751
+ }
36752
+ };
36753
+ }
36593
36754
 
36594
36755
  // src/modals/CheckoutModal/TransferToken/TransferToken.tsx
36595
36756
  import { motion as motion16, useAnimationControls as useAnimationControls3 } from "motion/react";
36596
- import React232, { useRef as useRef32, useState as useState68 } from "react";
36757
+ import React232, { useRef as useRef33, useState as useState68 } from "react";
36597
36758
  import { createPortal as createPortal21 } from "react-dom";
36598
36759
 
36599
36760
  // src/components/CopyAddress/CopyInputDisplayedAddress.tsx
@@ -37312,7 +37473,7 @@ function TransferToken({
37312
37473
  const { checkoutItem } = useCheckoutContext();
37313
37474
  const checkoutConfig = checkoutItem?.initSettings.config;
37314
37475
  const { transferToken } = modalState;
37315
- const disclaimerTextWrapperRef = useRef32(null);
37476
+ const disclaimerTextWrapperRef = useRef33(null);
37316
37477
  const { transferInit } = useCheckoutTransferInit();
37317
37478
  const {
37318
37479
  assets,
@@ -38221,7 +38382,7 @@ function useCheckoutModalTransition(checkoutItem, onClose) {
38221
38382
  );
38222
38383
  const { animation, animate } = useAnimatedNavigation(void 0);
38223
38384
  const [stateHistory, setHistory] = useState71([]);
38224
- const prevStep = useRef33(null);
38385
+ const prevStep = useRef34(null);
38225
38386
  const hasHistoryEntry = stateHistory.length > 1;
38226
38387
  const onNext = useCallback48(
38227
38388
  (payload) => {
@@ -38392,7 +38553,7 @@ function useCheckoutModalTitle(depositAddress, defaultTitle) {
38392
38553
  import { IN_PROGRESS_CHECKOUT_STATES as IN_PROGRESS_CHECKOUT_STATES2 } from "@funkit/api-base";
38393
38554
  import { formatTimestampToDate, fullMonthNames } from "@funkit/utils";
38394
38555
  import clsx23 from "clsx";
38395
- import React248, { useEffect as useEffect60, useMemo as useMemo51, useRef as useRef34, useState as useState73 } from "react";
38556
+ import React248, { useEffect as useEffect60, useMemo as useMemo51, useRef as useRef35, useState as useState73 } from "react";
38396
38557
  import { Virtuoso } from "react-virtuoso";
38397
38558
 
38398
38559
  // src/components/Icons/GreenRoundCheckmark.tsx
@@ -38925,8 +39086,8 @@ function Home({
38925
39086
  }) {
38926
39087
  const { t } = useFunkitTranslation();
38927
39088
  const [selectedView, setSelectedView] = useState73(defaultHomeTab);
38928
- const checkoutsListRef = useRef34(null);
38929
- const virtuosoParentRef = useRef34(null);
39089
+ const checkoutsListRef = useRef35(null);
39090
+ const virtuosoParentRef = useRef35(null);
38930
39091
  const account = useAccount();
38931
39092
  useCheckoutHistoryListener();
38932
39093
  const { userInfo, handleLogout } = useGeneralWallet();
@@ -39684,7 +39845,7 @@ function ChainModal({ onClose, open }) {
39684
39845
  // src/modals/CheckoutModal/FunCheckoutModal.tsx
39685
39846
  import { FUNKIT_CONNECT_SUPPORTED_CHECKOUT_CHAINS_INFO_LIST as FUNKIT_CONNECT_SUPPORTED_CHECKOUT_CHAINS_INFO_LIST3 } from "@funkit/chains";
39686
39847
  import { LogLevel as LogLevel2, initializeRelayClient } from "@funkit/fun-relay";
39687
- import React267, { useRef as useRef35 } from "react";
39848
+ import React267, { useRef as useRef36 } from "react";
39688
39849
 
39689
39850
  // src/components/FunConnectOptions/FunConnectOptions.tsx
39690
39851
  import React264, { useCallback as useCallback51, useMemo as useMemo52, useState as useState77 } from "react";
@@ -40379,8 +40540,8 @@ function FunCheckoutModalInner({
40379
40540
  depositAddress
40380
40541
  });
40381
40542
  };
40382
- const animationCallbackRef = useRef35(null);
40383
- const tooltipAnchorRef = useRef35(null);
40543
+ const animationCallbackRef = useRef36(null);
40544
+ const tooltipAnchorRef = useRef36(null);
40384
40545
  const handleAnimationCompleteRegister = (cb) => {
40385
40546
  animationCallbackRef.current = cb;
40386
40547
  };
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type SwappedTheme } from '../utils/swapped';
3
3
  export interface SwappedIframeCallbacks {
4
- onReady: () => void;
5
4
  onComplete: () => void;
6
5
  onBack: () => void;
7
6
  onExit: () => void;
@@ -90,6 +90,13 @@ export declare const flagConfig: {
90
90
  readonly values: ["clDebbfo9edXq1GydZ0CahSAfSimPj616lFa9p8e"];
91
91
  }];
92
92
  readonly value: string;
93
+ }, {
94
+ readonly if_any: [{
95
+ readonly key: "apiKey";
96
+ readonly type: "isAnyOf";
97
+ readonly values: ["5UzOrcAE2F3rcuMX2EeIlaYv5VUcDe6Lyh0PeZX2"];
98
+ }];
99
+ readonly value: string;
93
100
  }];
94
101
  };
95
102
  readonly withdrawal_chains_and_assets: {
@@ -1,9 +1,8 @@
1
1
  import type { SavedFormOfPayment, SwappedFormOfPayment } from '@funkit/api-base';
2
2
  import type { ThemeVars } from '../css/sprinkles.css';
3
- export declare const isSavedFormOfPaymentType: (fop: SwappedFormOfPayment) => fop is SavedFormOfPayment;
4
- export declare const getSavedFormOfPaymentDisplayName: (fop: SavedFormOfPayment) => string;
5
- export declare const getSavedFormOfPaymentIcon: (fop: SavedFormOfPayment) => string;
6
- export declare function isSwappedOrigin(origin: string): boolean;
3
+ /**
4
+ * Ref: https://www.notion.so/Fun-Parameter-Styling-Guide-312966ea6e398011bbc6c14e976e281d#63dcdd77ea2d488084a980cda4c63d08
5
+ */
7
6
  export interface SwappedTheme {
8
7
  colors: Record<string, string>;
9
8
  radii: Record<string, string>;
@@ -12,7 +11,9 @@ export interface SwappedTheme {
12
11
  buttonFontWeight: string;
13
12
  modalBottomBarButtonHeight: string;
14
13
  iframeBackground: string;
15
- paddingPrimary: string;
14
+ paddingPrimary?: string;
15
+ paddingPrimaryX?: string;
16
+ paddingPrimaryY?: string;
16
17
  paddingSecondary: string;
17
18
  paddingTertiary: string;
18
19
  baseFont?: string;
@@ -23,8 +24,19 @@ export interface SwappedTheme {
23
24
  topbarTextFontSize?: string;
24
25
  contentPadding?: string;
25
26
  boxPaddingY?: string;
27
+ boxPaddingX?: string;
26
28
  }
27
- export declare function buildSwappedTheme(activeTheme: ThemeVars, customFontFamily?: {
28
- primary?: string;
29
- secondary?: string;
29
+ export declare const isSavedFormOfPaymentType: (fop: SwappedFormOfPayment) => fop is SavedFormOfPayment;
30
+ export declare const getSavedFormOfPaymentDisplayName: (fop: SavedFormOfPayment) => string;
31
+ export declare const getSavedFormOfPaymentIcon: (fop: SavedFormOfPayment) => string;
32
+ export declare function getSwappedOrigin(url: string): string | null;
33
+ export declare function isSwappedOrigin(origin: string): boolean;
34
+ export declare function resolveCssValue(value: string): string;
35
+ export declare function resolveObjectCssVars<T extends object>(obj: T): T;
36
+ export declare function buildSwappedTheme(theme: ThemeVars & {
37
+ customFontFamily?: {
38
+ primary?: string;
39
+ secondary?: string;
40
+ };
30
41
  }): SwappedTheme;
42
+ export declare function buildSwappedThemeQueryParams(activeTheme: ThemeVars): Record<string, string>;
@@ -5,6 +5,9 @@ import {
5
5
  import {
6
6
  zealWallet
7
7
  } from "./chunk-HE2LMIPD.js";
8
+ import {
9
+ tahoWallet
10
+ } from "./chunk-4BMUFNMT.js";
8
11
  import {
9
12
  talismanWallet
10
13
  } from "./chunk-6MFOL6EB.js";
@@ -14,18 +17,15 @@ import {
14
17
  import {
15
18
  tokenaryWallet
16
19
  } from "./chunk-34LO6Q7A.js";
17
- import {
18
- safeheronWallet
19
- } from "./chunk-4R4AARTG.js";
20
20
  import {
21
21
  trustWallet
22
22
  } from "./chunk-KO56HCTI.js";
23
- import {
24
- walletConnectWallet
25
- } from "./chunk-J34FG3W4.js";
26
23
  import {
27
24
  uniswapWallet
28
25
  } from "./chunk-NHLG5PVD.js";
26
+ import {
27
+ walletConnectWallet
28
+ } from "./chunk-J34FG3W4.js";
29
29
  import {
30
30
  xdefiWallet
31
31
  } from "./chunk-O7RSASRH.js";
@@ -44,6 +44,9 @@ import {
44
44
  import {
45
45
  safeWallet
46
46
  } from "./chunk-YKVWTGU7.js";
47
+ import {
48
+ safeheronWallet
49
+ } from "./chunk-4R4AARTG.js";
47
50
  import {
48
51
  safepalWallet
49
52
  } from "./chunk-IICWJWGZ.js";
@@ -51,11 +54,8 @@ import {
51
54
  subWallet
52
55
  } from "./chunk-XBLHZICW.js";
53
56
  import {
54
- tahoWallet
55
- } from "./chunk-4BMUFNMT.js";
56
- import {
57
- ledgerWallet
58
- } from "./chunk-WKCCLGHJ.js";
57
+ metaMaskWallet
58
+ } from "./chunk-HETS3KKI.js";
59
59
  import {
60
60
  mewWallet
61
61
  } from "./chunk-HKVDCVCG.js";
@@ -78,8 +78,8 @@ import {
78
78
  phantomWallet
79
79
  } from "./chunk-XMNVOYSJ.js";
80
80
  import {
81
- foxWallet
82
- } from "./chunk-53VYSPXK.js";
81
+ enkryptWallet
82
+ } from "./chunk-W6TXXLCO.js";
83
83
  import {
84
84
  frameWallet
85
85
  } from "./chunk-WDTNOIMF.js";
@@ -99,8 +99,8 @@ import {
99
99
  kresusWallet
100
100
  } from "./chunk-G4V5B6YC.js";
101
101
  import {
102
- metaMaskWallet
103
- } from "./chunk-HETS3KKI.js";
102
+ ledgerWallet
103
+ } from "./chunk-WKCCLGHJ.js";
104
104
  import {
105
105
  bybitWallet
106
106
  } from "./chunk-6UCI7GM6.js";
@@ -123,14 +123,14 @@ import {
123
123
  desigWallet
124
124
  } from "./chunk-JYVLYSH3.js";
125
125
  import {
126
- enkryptWallet
127
- } from "./chunk-W6TXXLCO.js";
128
- import {
129
- bifrostWallet
130
- } from "./chunk-EKJHJFRN.js";
126
+ foxWallet
127
+ } from "./chunk-53VYSPXK.js";
131
128
  import {
132
129
  argentWallet
133
130
  } from "./chunk-VUOAIUZE.js";
131
+ import {
132
+ bifrostWallet
133
+ } from "./chunk-EKJHJFRN.js";
134
134
  import {
135
135
  bitgetWallet
136
136
  } from "./chunk-HOPH3TQ3.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funkit/connect",
3
- "version": "9.0.0",
3
+ "version": "9.0.1",
4
4
  "description": "Funkit Connect SDK elevates DeFi apps via web2 sign-ins and one-click checkouts.",
5
5
  "files": [
6
6
  "dist",
@@ -102,10 +102,10 @@
102
102
  "ua-parser-js": "^1.0.37",
103
103
  "use-debounce": "^10.0.5",
104
104
  "uuid": "^9.0.1",
105
- "@funkit/chains": "1.1.0",
106
105
  "@funkit/api-base": "2.3.1",
107
- "@funkit/utils": "1.2.3",
108
- "@funkit/fun-relay": "2.6.1"
106
+ "@funkit/chains": "1.1.0",
107
+ "@funkit/fun-relay": "2.6.1",
108
+ "@funkit/utils": "1.2.3"
109
109
  },
110
110
  "repository": {
111
111
  "type": "git",