@unifold/ui-web 0.1.48 → 0.1.50

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 (3) hide show
  1. package/dist/index.js +155 -160
  2. package/dist/index.mjs +155 -160
  3. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -43354,6 +43354,9 @@ function getOnrampSessionStartUrl(request, publishableKey) {
43354
43354
  if (request.external_id) {
43355
43355
  params.append("external_id", request.external_id);
43356
43356
  }
43357
+ if (request.email) {
43358
+ params.append("email", request.email);
43359
+ }
43357
43360
  return `${API_BASE_URL}/v1/public/onramps/sessions/start?${params.toString()}`;
43358
43361
  }
43359
43362
  async function getDefaultOnrampToken(params, publishableKey) {
@@ -50308,31 +50311,29 @@ function BuyWithCard({
50308
50311
  );
50309
50312
  if (manualProviderStillExists) {
50310
50313
  setSelectedProvider(manualProviderStillExists);
50311
- const bestProvider = response.data.reduce(
50312
- (best, current) => current.destination_amount > best.destination_amount ? current : best
50313
- );
50314
+ const firstProvider = response.data[0];
50314
50315
  if (!autoSelectedProvider) {
50315
- setAutoSelectedProvider(bestProvider.service_provider);
50316
+ setAutoSelectedProvider(firstProvider.service_provider);
50316
50317
  }
50317
50318
  setIsAutoSelected(
50318
50319
  manualProviderStillExists.service_provider === autoSelectedProvider
50319
50320
  );
50320
- } else {
50321
- const bestProvider = response.data.reduce(
50322
- (best, current) => current.destination_amount > best.destination_amount ? current : best
50323
- );
50324
- setSelectedProvider(bestProvider);
50325
- setAutoSelectedProvider(bestProvider.service_provider);
50321
+ } else if (response.data.length > 0) {
50322
+ const firstProvider = response.data[0];
50323
+ setSelectedProvider(firstProvider);
50324
+ setAutoSelectedProvider(firstProvider.service_provider);
50326
50325
  setIsAutoSelected(true);
50327
50326
  setHasManualSelection(false);
50327
+ } else {
50328
+ setSelectedProvider(null);
50329
+ setIsAutoSelected(false);
50330
+ setHasManualSelection(false);
50328
50331
  }
50329
50332
  } else {
50330
50333
  if (response.data.length > 0) {
50331
- const bestProvider = response.data.reduce(
50332
- (best, current) => current.destination_amount > best.destination_amount ? current : best
50333
- );
50334
- setSelectedProvider(bestProvider);
50335
- setAutoSelectedProvider(bestProvider.service_provider);
50334
+ const firstProvider = response.data[0];
50335
+ setSelectedProvider(firstProvider);
50336
+ setAutoSelectedProvider(firstProvider.service_provider);
50336
50337
  setIsAutoSelected(true);
50337
50338
  }
50338
50339
  }
@@ -50428,19 +50429,7 @@ function BuyWithCard({
50428
50429
  window.open(sessionStartUrl, "_blank");
50429
50430
  handleViewChange("onramp");
50430
50431
  };
50431
- const getProviderBadges = (quote, allQuotes) => {
50432
- const badges = [];
50433
- const maxDestination = Math.max(
50434
- ...allQuotes.map((q) => q.destination_amount)
50435
- );
50436
- if (quote.destination_amount === maxDestination) {
50437
- badges.push("Best price");
50438
- }
50439
- return badges;
50440
- };
50441
- const sortedQuotes = [...quotes].sort(
50442
- (a, b) => b.destination_amount - a.destination_amount
50443
- );
50432
+ const sortedQuotes = quotes;
50444
50433
  const currencySymbol = getCurrencySymbol(currency);
50445
50434
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
50446
50435
  "div",
@@ -50642,31 +50631,7 @@ function BuyWithCard({
50642
50631
  children: selectedProvider.service_provider_display_name
50643
50632
  }
50644
50633
  ),
50645
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: [
50646
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50647
- "span",
50648
- {
50649
- className: "uf-text-[10px] uf-font-normal",
50650
- style: {
50651
- color: colors2.success,
50652
- fontFamily: fonts.regular
50653
- },
50654
- children: "Best price"
50655
- }
50656
- ),
50657
- isAutoSelected && selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50658
- "span",
50659
- {
50660
- className: "uf-text-[10px]",
50661
- style: {
50662
- color: components.card.labelColor,
50663
- fontFamily: fonts.regular
50664
- },
50665
- children: "\u2022"
50666
- }
50667
- ),
50668
- selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" })
50669
- ] })
50634
+ selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
50670
50635
  ] }),
50671
50636
  quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50672
50637
  ChevronRight,
@@ -50730,7 +50695,6 @@ function BuyWithCard({
50730
50695
  {
50731
50696
  className: `uf-transition-all uf-duration-300 uf-min-h-[420px] uf-flex uf-flex-col ${showQuotesView && !showOnrampView ? "uf-opacity-100" : "uf-opacity-0 uf-pointer-events-none uf-absolute uf-inset-0"}`,
50732
50697
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "uf-space-y-2 uf-pt-2 uf-pb-8 uf-overflow-y-auto uf-flex-1 uf-min-h-0", children: sortedQuotes.map((quote, index2) => {
50733
- const badges = getProviderBadges(quote, sortedQuotes);
50734
50698
  const displayName = quote.service_provider_display_name;
50735
50699
  const isSelected = selectedProvider?.service_provider === quote.service_provider;
50736
50700
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
@@ -50773,39 +50737,17 @@ function BuyWithCard({
50773
50737
  children: displayName
50774
50738
  }
50775
50739
  ),
50776
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: [
50777
- badges.map((badge, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
50778
- "span",
50779
- {
50780
- className: "uf-text-[10px] uf-font-normal",
50781
- style: { color: colors2.success },
50782
- children: [
50783
- badge,
50784
- i < badges.length - 1 && ","
50785
- ]
50740
+ quote.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50741
+ "span",
50742
+ {
50743
+ className: "uf-text-[10px] uf-font-normal",
50744
+ style: {
50745
+ color: components.card.subtextRightColor,
50746
+ fontFamily: fonts.regular
50786
50747
  },
50787
- i
50788
- )),
50789
- quote.low_kyc === false && badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50790
- "span",
50791
- {
50792
- className: "uf-text-[10px]",
50793
- style: { color: components.card.subtextRightColor },
50794
- children: "\u2022"
50795
- }
50796
- ),
50797
- quote.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50798
- "span",
50799
- {
50800
- className: "uf-text-[10px] uf-font-normal",
50801
- style: {
50802
- color: components.card.subtextRightColor,
50803
- fontFamily: fonts.regular
50804
- },
50805
- children: "No document upload"
50806
- }
50807
- )
50808
- ] })
50748
+ children: "No document upload"
50749
+ }
50750
+ ) })
50809
50751
  ] })
50810
50752
  ] }),
50811
50753
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "uf-text-right", children: [
@@ -54479,14 +54421,23 @@ function useAllowedCountry(publishableKey) {
54479
54421
  let isAllowed = null;
54480
54422
  if (ipData && configData) {
54481
54423
  const blockedCodes = configData.blocked_country_codes || [];
54424
+ const blockedSubdivisions = configData.blocked_country_subdivisions || [];
54482
54425
  const userCountryUpper = ipData.alpha2.toUpperCase();
54483
- isAllowed = !blockedCodes.some(
54426
+ const userSubdivision = ipData.subdivision_code || ipData.state || "";
54427
+ const userSubdivisionUpper = userSubdivision.toUpperCase();
54428
+ const isCountryBlocked = blockedCodes.some(
54484
54429
  (code) => code.toUpperCase() === userCountryUpper
54485
54430
  );
54431
+ const isSubdivisionBlocked = blockedSubdivisions.some((entry) => {
54432
+ if (entry.country_code.toUpperCase() !== userCountryUpper) return false;
54433
+ return entry.subdivision_codes.some(
54434
+ (code) => code.toUpperCase() === userSubdivisionUpper
54435
+ );
54436
+ });
54437
+ isAllowed = !isCountryBlocked && !isSubdivisionBlocked;
54486
54438
  }
54487
54439
  return {
54488
54440
  isAllowed,
54489
- // Return lowercase for consistency with useUserIp hook
54490
54441
  alpha2: ipData?.alpha2?.toLowerCase() ?? null,
54491
54442
  country: ipData?.country ?? null,
54492
54443
  isLoading,
@@ -55421,72 +55372,72 @@ function DepositPollingUi({
55421
55372
  var getChainKey = (chainId, chainType) => {
55422
55373
  return `${chainType}:${chainId}`;
55423
55374
  };
55424
- function resolveSourceToken(supportedTokens, defaultSourceChainType, defaultSourceChainId, defaultSourceTokenAddress, defaultSourceSymbol) {
55425
- if (!supportedTokens.length) return null;
55426
- let selectedTokenData;
55427
- let selectedChainData;
55428
- const hasChainDefaults = defaultSourceChainType && defaultSourceChainId;
55429
- if (defaultSourceTokenAddress && hasChainDefaults) {
55430
- for (const t11 of supportedTokens) {
55375
+ function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
55376
+ if (!tokens.length) return null;
55377
+ let selectedToken;
55378
+ let selectedChain;
55379
+ const hasChainDefaults = defaultChainType && defaultChainId;
55380
+ if (defaultTokenAddress && hasChainDefaults) {
55381
+ for (const t11 of tokens) {
55431
55382
  const matchingChain = t11.chains.find(
55432
- (c) => c.token_address.toLowerCase() === defaultSourceTokenAddress.toLowerCase() && c.chain_type === defaultSourceChainType && c.chain_id === defaultSourceChainId
55383
+ (c) => c.token_address.toLowerCase() === defaultTokenAddress.toLowerCase() && c.chain_type === defaultChainType && c.chain_id === defaultChainId
55433
55384
  );
55434
55385
  if (matchingChain) {
55435
- selectedTokenData = t11;
55436
- selectedChainData = matchingChain;
55386
+ selectedToken = t11;
55387
+ selectedChain = matchingChain;
55437
55388
  break;
55438
55389
  }
55439
55390
  }
55440
55391
  }
55441
- if (!selectedTokenData && defaultSourceSymbol && hasChainDefaults) {
55442
- for (const t11 of supportedTokens) {
55443
- if (t11.symbol !== defaultSourceSymbol) continue;
55392
+ if (!selectedToken && defaultSymbol && hasChainDefaults) {
55393
+ for (const t11 of tokens) {
55394
+ if (t11.symbol !== defaultSymbol) continue;
55444
55395
  const matchedChain = t11.chains.find(
55445
- (c) => c.chain_type === defaultSourceChainType && c.chain_id === defaultSourceChainId
55396
+ (c) => c.chain_type === defaultChainType && c.chain_id === defaultChainId
55446
55397
  );
55447
55398
  if (matchedChain) {
55448
- selectedTokenData = t11;
55449
- selectedChainData = matchedChain;
55399
+ selectedToken = t11;
55400
+ selectedChain = matchedChain;
55450
55401
  break;
55451
55402
  }
55452
55403
  }
55453
55404
  }
55454
- if (!selectedTokenData) {
55455
- for (const t11 of supportedTokens) {
55405
+ if (!selectedToken) {
55406
+ for (const t11 of tokens) {
55456
55407
  if (t11.chains.length > 0) {
55457
- selectedTokenData = t11;
55458
- selectedChainData = t11.chains[0];
55408
+ selectedToken = t11;
55409
+ selectedChain = t11.chains[0];
55459
55410
  break;
55460
55411
  }
55461
55412
  }
55462
55413
  }
55463
- if (selectedTokenData && selectedChainData) {
55464
- return { token: selectedTokenData, chain: selectedChainData };
55414
+ if (selectedToken && selectedChain) {
55415
+ return { token: selectedToken, chain: selectedChain };
55465
55416
  }
55466
55417
  return null;
55467
55418
  }
55468
- function useDefaultSourceToken({
55469
- supportedTokens,
55470
- defaultSourceChainType,
55471
- defaultSourceChainId,
55472
- defaultSourceTokenAddress,
55473
- defaultSourceSymbol
55419
+ function useDefaultToken({
55420
+ tokens,
55421
+ defaultChainType,
55422
+ defaultChainId,
55423
+ defaultTokenAddress,
55424
+ defaultSymbol
55474
55425
  }) {
55475
55426
  const [token, setToken] = (0, import_react20.useState)(null);
55476
55427
  const [chain, setChain] = (0, import_react20.useState)(null);
55477
55428
  const [initialSelectionDone, setInitialSelectionDone] = (0, import_react20.useState)(false);
55478
55429
  const appliedDefaultsRef = (0, import_react20.useRef)("");
55479
55430
  (0, import_react20.useEffect)(() => {
55480
- if (!supportedTokens.length) return;
55481
- const defaultsKey = `${defaultSourceTokenAddress ?? ""}|${defaultSourceSymbol ?? ""}|${defaultSourceChainType ?? ""}|${defaultSourceChainId ?? ""}`;
55431
+ if (!tokens.length) return;
55432
+ const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
55482
55433
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
55483
55434
  if (initialSelectionDone && !defaultsChanged) return;
55484
- const result = resolveSourceToken(
55485
- supportedTokens,
55486
- defaultSourceChainType,
55487
- defaultSourceChainId,
55488
- defaultSourceTokenAddress,
55489
- defaultSourceSymbol
55435
+ const result = resolveToken(
55436
+ tokens,
55437
+ defaultChainType,
55438
+ defaultChainId,
55439
+ defaultTokenAddress,
55440
+ defaultSymbol
55490
55441
  );
55491
55442
  if (result) {
55492
55443
  setToken(result.token.symbol);
@@ -55495,16 +55446,16 @@ function useDefaultSourceToken({
55495
55446
  setInitialSelectionDone(true);
55496
55447
  }
55497
55448
  }, [
55498
- supportedTokens,
55499
- defaultSourceTokenAddress,
55500
- defaultSourceSymbol,
55501
- defaultSourceChainType,
55502
- defaultSourceChainId,
55449
+ tokens,
55450
+ defaultTokenAddress,
55451
+ defaultSymbol,
55452
+ defaultChainType,
55453
+ defaultChainId,
55503
55454
  initialSelectionDone
55504
55455
  ]);
55505
55456
  (0, import_react20.useEffect)(() => {
55506
- if (!supportedTokens.length || !token) return;
55507
- const currentToken = supportedTokens.find((t11) => t11.symbol === token);
55457
+ if (!tokens.length || !token) return;
55458
+ const currentToken = tokens.find((t11) => t11.symbol === token);
55508
55459
  if (!currentToken || currentToken.chains.length === 0) return;
55509
55460
  const isChainAvailable = chain && currentToken.chains.some((c) => {
55510
55461
  return getChainKey(c.chain_id, c.chain_type) === chain;
@@ -55513,9 +55464,24 @@ function useDefaultSourceToken({
55513
55464
  const firstChain = currentToken.chains[0];
55514
55465
  setChain(getChainKey(firstChain.chain_id, firstChain.chain_type));
55515
55466
  }
55516
- }, [token, supportedTokens, chain]);
55467
+ }, [token, tokens, chain]);
55517
55468
  return { token, chain, setToken, setChain, initialSelectionDone };
55518
55469
  }
55470
+ function useDefaultSourceToken({
55471
+ supportedTokens,
55472
+ defaultSourceChainType,
55473
+ defaultSourceChainId,
55474
+ defaultSourceTokenAddress,
55475
+ defaultSourceSymbol
55476
+ }) {
55477
+ return useDefaultToken({
55478
+ tokens: supportedTokens,
55479
+ defaultChainType: defaultSourceChainType,
55480
+ defaultChainId: defaultSourceChainId,
55481
+ defaultTokenAddress: defaultSourceTokenAddress,
55482
+ defaultSymbol: defaultSourceSymbol
55483
+ });
55484
+ }
55519
55485
  function DepositFooterLinks({
55520
55486
  onGlossaryClick
55521
55487
  }) {
@@ -59792,19 +59758,30 @@ function DepositModal({
59792
59758
  }
59793
59759
  ) });
59794
59760
  }
59761
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
59762
+ "succeeded",
59763
+ "expired",
59764
+ "refunded",
59765
+ "canceled"
59766
+ ]);
59795
59767
  function usePaymentIntent(params) {
59796
59768
  const {
59797
59769
  clientSecret,
59798
59770
  publishableKey,
59799
59771
  enabled = true,
59800
- pollingInterval = 5e3
59772
+ pollingInterval = 3e3
59801
59773
  } = params;
59802
59774
  return useQuery({
59803
59775
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
59804
59776
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
59805
59777
  enabled: enabled && !!clientSecret && !!publishableKey,
59806
59778
  staleTime: 0,
59807
- refetchInterval: pollingInterval || false,
59779
+ refetchInterval: (query) => {
59780
+ if (!pollingInterval) return false;
59781
+ const status = query.state.data?.status;
59782
+ if (status && TERMINAL_STATUSES.has(status)) return false;
59783
+ return pollingInterval;
59784
+ },
59808
59785
  refetchOnWindowFocus: true,
59809
59786
  retry: 3,
59810
59787
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
@@ -59928,7 +59905,7 @@ function CheckoutModal({
59928
59905
  clientSecret,
59929
59906
  publishableKey,
59930
59907
  enabled: open && !!clientSecret,
59931
- pollingInterval: 5e3
59908
+ pollingInterval: 3e3
59932
59909
  });
59933
59910
  const { projectConfig } = useProjectConfig({
59934
59911
  publishableKey,
@@ -60469,6 +60446,21 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
60469
60446
  enabled
60470
60447
  });
60471
60448
  }
60449
+ function useDefaultDestinationToken({
60450
+ destinationTokens,
60451
+ defaultDestinationChainType,
60452
+ defaultDestinationChainId,
60453
+ defaultDestinationTokenAddress,
60454
+ defaultDestinationSymbol
60455
+ }) {
60456
+ return useDefaultToken({
60457
+ tokens: destinationTokens,
60458
+ defaultChainType: defaultDestinationChainType,
60459
+ defaultChainId: defaultDestinationChainId,
60460
+ defaultTokenAddress: defaultDestinationTokenAddress,
60461
+ defaultSymbol: defaultDestinationSymbol
60462
+ });
60463
+ }
60472
60464
  function useSourceTokenValidation(params) {
60473
60465
  const {
60474
60466
  sourceChainType,
@@ -61715,6 +61707,10 @@ function WithdrawModal({
61715
61707
  sourceTokenSymbol,
61716
61708
  recipientAddress: recipientAddressProp,
61717
61709
  senderAddress,
61710
+ defaultDestinationChainType,
61711
+ defaultDestinationChainId,
61712
+ defaultDestinationTokenAddress,
61713
+ defaultDestinationSymbol,
61718
61714
  onWithdraw,
61719
61715
  onWithdrawSuccess,
61720
61716
  onWithdrawError,
@@ -61758,8 +61754,21 @@ function WithdrawModal({
61758
61754
  publishableKey,
61759
61755
  enabled: open
61760
61756
  });
61761
- const [selectedToken, setSelectedToken] = (0, import_react28.useState)(null);
61762
- const [selectedChain, setSelectedChain] = (0, import_react28.useState)(null);
61757
+ const {
61758
+ token: selectedTokenSymbol,
61759
+ chain: selectedChainKey,
61760
+ setToken: setSelectedTokenSymbol,
61761
+ setChain: setSelectedChainKey,
61762
+ initialSelectionDone
61763
+ } = useDefaultDestinationToken({
61764
+ destinationTokens,
61765
+ defaultDestinationChainType,
61766
+ defaultDestinationChainId,
61767
+ defaultDestinationTokenAddress,
61768
+ defaultDestinationSymbol
61769
+ });
61770
+ const selectedToken = selectedTokenSymbol ? destinationTokens.find((t11) => t11.symbol === selectedTokenSymbol) ?? null : null;
61771
+ const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey) ?? null : null;
61763
61772
  const [view, setView] = (0, import_react28.useState)("form");
61764
61773
  const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react28.useState)();
61765
61774
  const [selectedExecution, setSelectedExecution] = (0, import_react28.useState)(null);
@@ -61801,21 +61810,11 @@ function WithdrawModal({
61801
61810
  setSubmittedTxInfo(txInfo);
61802
61811
  setView("confirming");
61803
61812
  }, []);
61804
- (0, import_react28.useEffect)(() => {
61805
- if (!destinationTokens.length || selectedToken) return;
61806
- const first = destinationTokens[0];
61807
- if (first?.chains.length > 0) {
61808
- setSelectedToken(first);
61809
- setSelectedChain(first.chains[0]);
61810
- }
61811
- }, [destinationTokens, selectedToken]);
61812
61813
  const resetViewTimeoutRef = (0, import_react28.useRef)(null);
61813
61814
  const handleClose = (0, import_react28.useCallback)(() => {
61814
61815
  onOpenChange(false);
61815
61816
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
61816
61817
  resetViewTimeoutRef.current = setTimeout(() => {
61817
- setSelectedToken(null);
61818
- setSelectedChain(null);
61819
61818
  setView("form");
61820
61819
  setSelectedExecution(null);
61821
61820
  setSubmittedTxInfo(null);
@@ -61829,8 +61828,6 @@ function WithdrawModal({
61829
61828
  clearTimeout(resetViewTimeoutRef.current);
61830
61829
  resetViewTimeoutRef.current = null;
61831
61830
  }
61832
- setSelectedToken(null);
61833
- setSelectedChain(null);
61834
61831
  setView("form");
61835
61832
  setSelectedExecution(null);
61836
61833
  setSubmittedTxInfo(null);
@@ -61840,19 +61837,13 @@ function WithdrawModal({
61840
61837
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
61841
61838
  }, []);
61842
61839
  const handleTokenSymbolChange = (0, import_react28.useCallback)((symbol) => {
61843
- const tok = destinationTokens.find((t11) => t11.symbol === symbol);
61844
- if (tok) {
61845
- setSelectedToken(tok);
61846
- if (tok.chains.length > 0) setSelectedChain(tok.chains[0]);
61847
- }
61848
- }, [destinationTokens]);
61840
+ setSelectedTokenSymbol(symbol);
61841
+ }, [setSelectedTokenSymbol]);
61849
61842
  const handleChainKeyChange = (0, import_react28.useCallback)((chainKey) => {
61850
- if (!selectedToken) return;
61851
- const chain = selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === chainKey);
61852
- if (chain) setSelectedChain(chain);
61853
- }, [selectedToken]);
61843
+ setSelectedChainKey(chainKey);
61844
+ }, [setSelectedChainKey]);
61854
61845
  const isSourceSupported = sourceValidation?.isSupported ?? null;
61855
- const isAnyLoading = tokensLoading || isCheckingSourceToken;
61846
+ const isAnyLoading = tokensLoading || isCheckingSourceToken || destinationTokens.length > 0 && !initialSelectionDone;
61856
61847
  const withdrawPoweredByFooter = /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "uf-pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PoweredByUnifold, { color: colors2.foregroundMuted, className: "uf-flex uf-justify-center uf-shrink-0" }) });
61857
61848
  return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Dialog2, { open: hideOverlay || open, onOpenChange: hideOverlay ? void 0 : handleClose, modal: !hideOverlay, children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
61858
61849
  DialogContent2,
@@ -62262,6 +62253,10 @@ function UnifoldProvider2({
62262
62253
  sourceTokenAddress: withdrawConfig.sourceTokenAddress,
62263
62254
  sourceTokenSymbol: withdrawConfig.sourceTokenSymbol,
62264
62255
  recipientAddress: withdrawConfig.recipientAddress,
62256
+ defaultDestinationChainType: withdrawConfig.defaultDestinationChainType,
62257
+ defaultDestinationChainId: withdrawConfig.defaultDestinationChainId,
62258
+ defaultDestinationTokenAddress: withdrawConfig.defaultDestinationTokenAddress,
62259
+ defaultDestinationSymbol: withdrawConfig.defaultDestinationSymbol,
62265
62260
  senderAddress: withdrawConfig.senderAddress,
62266
62261
  onWithdraw: withdrawConfig.withdraw,
62267
62262
  onWithdrawSuccess: handleWithdrawSuccess,
package/dist/index.mjs CHANGED
@@ -43341,6 +43341,9 @@ function getOnrampSessionStartUrl(request, publishableKey) {
43341
43341
  if (request.external_id) {
43342
43342
  params.append("external_id", request.external_id);
43343
43343
  }
43344
+ if (request.email) {
43345
+ params.append("email", request.email);
43346
+ }
43344
43347
  return `${API_BASE_URL}/v1/public/onramps/sessions/start?${params.toString()}`;
43345
43348
  }
43346
43349
  async function getDefaultOnrampToken(params, publishableKey) {
@@ -50295,31 +50298,29 @@ function BuyWithCard({
50295
50298
  );
50296
50299
  if (manualProviderStillExists) {
50297
50300
  setSelectedProvider(manualProviderStillExists);
50298
- const bestProvider = response.data.reduce(
50299
- (best, current) => current.destination_amount > best.destination_amount ? current : best
50300
- );
50301
+ const firstProvider = response.data[0];
50301
50302
  if (!autoSelectedProvider) {
50302
- setAutoSelectedProvider(bestProvider.service_provider);
50303
+ setAutoSelectedProvider(firstProvider.service_provider);
50303
50304
  }
50304
50305
  setIsAutoSelected(
50305
50306
  manualProviderStillExists.service_provider === autoSelectedProvider
50306
50307
  );
50307
- } else {
50308
- const bestProvider = response.data.reduce(
50309
- (best, current) => current.destination_amount > best.destination_amount ? current : best
50310
- );
50311
- setSelectedProvider(bestProvider);
50312
- setAutoSelectedProvider(bestProvider.service_provider);
50308
+ } else if (response.data.length > 0) {
50309
+ const firstProvider = response.data[0];
50310
+ setSelectedProvider(firstProvider);
50311
+ setAutoSelectedProvider(firstProvider.service_provider);
50313
50312
  setIsAutoSelected(true);
50314
50313
  setHasManualSelection(false);
50314
+ } else {
50315
+ setSelectedProvider(null);
50316
+ setIsAutoSelected(false);
50317
+ setHasManualSelection(false);
50315
50318
  }
50316
50319
  } else {
50317
50320
  if (response.data.length > 0) {
50318
- const bestProvider = response.data.reduce(
50319
- (best, current) => current.destination_amount > best.destination_amount ? current : best
50320
- );
50321
- setSelectedProvider(bestProvider);
50322
- setAutoSelectedProvider(bestProvider.service_provider);
50321
+ const firstProvider = response.data[0];
50322
+ setSelectedProvider(firstProvider);
50323
+ setAutoSelectedProvider(firstProvider.service_provider);
50323
50324
  setIsAutoSelected(true);
50324
50325
  }
50325
50326
  }
@@ -50415,19 +50416,7 @@ function BuyWithCard({
50415
50416
  window.open(sessionStartUrl, "_blank");
50416
50417
  handleViewChange("onramp");
50417
50418
  };
50418
- const getProviderBadges = (quote, allQuotes) => {
50419
- const badges = [];
50420
- const maxDestination = Math.max(
50421
- ...allQuotes.map((q) => q.destination_amount)
50422
- );
50423
- if (quote.destination_amount === maxDestination) {
50424
- badges.push("Best price");
50425
- }
50426
- return badges;
50427
- };
50428
- const sortedQuotes = [...quotes].sort(
50429
- (a, b) => b.destination_amount - a.destination_amount
50430
- );
50419
+ const sortedQuotes = quotes;
50431
50420
  const currencySymbol = getCurrencySymbol(currency);
50432
50421
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
50433
50422
  "div",
@@ -50629,31 +50618,7 @@ function BuyWithCard({
50629
50618
  children: selectedProvider.service_provider_display_name
50630
50619
  }
50631
50620
  ),
50632
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: [
50633
- isAutoSelected && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50634
- "span",
50635
- {
50636
- className: "uf-text-[10px] uf-font-normal",
50637
- style: {
50638
- color: colors2.success,
50639
- fontFamily: fonts.regular
50640
- },
50641
- children: "Best price"
50642
- }
50643
- ),
50644
- isAutoSelected && selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50645
- "span",
50646
- {
50647
- className: "uf-text-[10px]",
50648
- style: {
50649
- color: components.card.labelColor,
50650
- fontFamily: fonts.regular
50651
- },
50652
- children: "\u2022"
50653
- }
50654
- ),
50655
- selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" })
50656
- ] })
50621
+ selectedProvider.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "uf-text-[10px] uf-text-muted-foreground uf-font-normal", children: "No document upload" }) })
50657
50622
  ] }),
50658
50623
  quotes.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50659
50624
  ChevronRight,
@@ -50717,7 +50682,6 @@ function BuyWithCard({
50717
50682
  {
50718
50683
  className: `uf-transition-all uf-duration-300 uf-min-h-[420px] uf-flex uf-flex-col ${showQuotesView && !showOnrampView ? "uf-opacity-100" : "uf-opacity-0 uf-pointer-events-none uf-absolute uf-inset-0"}`,
50719
50684
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "uf-space-y-2 uf-pt-2 uf-pb-8 uf-overflow-y-auto uf-flex-1 uf-min-h-0", children: sortedQuotes.map((quote, index2) => {
50720
- const badges = getProviderBadges(quote, sortedQuotes);
50721
50685
  const displayName = quote.service_provider_display_name;
50722
50686
  const isSelected = selectedProvider?.service_provider === quote.service_provider;
50723
50687
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
@@ -50760,39 +50724,17 @@ function BuyWithCard({
50760
50724
  children: displayName
50761
50725
  }
50762
50726
  ),
50763
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: [
50764
- badges.map((badge, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
50765
- "span",
50766
- {
50767
- className: "uf-text-[10px] uf-font-normal",
50768
- style: { color: colors2.success },
50769
- children: [
50770
- badge,
50771
- i < badges.length - 1 && ","
50772
- ]
50727
+ quote.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "uf-flex uf-items-center uf-gap-1.5 uf-mt-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50728
+ "span",
50729
+ {
50730
+ className: "uf-text-[10px] uf-font-normal",
50731
+ style: {
50732
+ color: components.card.subtextRightColor,
50733
+ fontFamily: fonts.regular
50773
50734
  },
50774
- i
50775
- )),
50776
- quote.low_kyc === false && badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50777
- "span",
50778
- {
50779
- className: "uf-text-[10px]",
50780
- style: { color: components.card.subtextRightColor },
50781
- children: "\u2022"
50782
- }
50783
- ),
50784
- quote.low_kyc === false && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
50785
- "span",
50786
- {
50787
- className: "uf-text-[10px] uf-font-normal",
50788
- style: {
50789
- color: components.card.subtextRightColor,
50790
- fontFamily: fonts.regular
50791
- },
50792
- children: "No document upload"
50793
- }
50794
- )
50795
- ] })
50735
+ children: "No document upload"
50736
+ }
50737
+ ) })
50796
50738
  ] })
50797
50739
  ] }),
50798
50740
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "uf-text-right", children: [
@@ -54466,14 +54408,23 @@ function useAllowedCountry(publishableKey) {
54466
54408
  let isAllowed = null;
54467
54409
  if (ipData && configData) {
54468
54410
  const blockedCodes = configData.blocked_country_codes || [];
54411
+ const blockedSubdivisions = configData.blocked_country_subdivisions || [];
54469
54412
  const userCountryUpper = ipData.alpha2.toUpperCase();
54470
- isAllowed = !blockedCodes.some(
54413
+ const userSubdivision = ipData.subdivision_code || ipData.state || "";
54414
+ const userSubdivisionUpper = userSubdivision.toUpperCase();
54415
+ const isCountryBlocked = blockedCodes.some(
54471
54416
  (code) => code.toUpperCase() === userCountryUpper
54472
54417
  );
54418
+ const isSubdivisionBlocked = blockedSubdivisions.some((entry) => {
54419
+ if (entry.country_code.toUpperCase() !== userCountryUpper) return false;
54420
+ return entry.subdivision_codes.some(
54421
+ (code) => code.toUpperCase() === userSubdivisionUpper
54422
+ );
54423
+ });
54424
+ isAllowed = !isCountryBlocked && !isSubdivisionBlocked;
54473
54425
  }
54474
54426
  return {
54475
54427
  isAllowed,
54476
- // Return lowercase for consistency with useUserIp hook
54477
54428
  alpha2: ipData?.alpha2?.toLowerCase() ?? null,
54478
54429
  country: ipData?.country ?? null,
54479
54430
  isLoading,
@@ -55408,72 +55359,72 @@ function DepositPollingUi({
55408
55359
  var getChainKey = (chainId, chainType) => {
55409
55360
  return `${chainType}:${chainId}`;
55410
55361
  };
55411
- function resolveSourceToken(supportedTokens, defaultSourceChainType, defaultSourceChainId, defaultSourceTokenAddress, defaultSourceSymbol) {
55412
- if (!supportedTokens.length) return null;
55413
- let selectedTokenData;
55414
- let selectedChainData;
55415
- const hasChainDefaults = defaultSourceChainType && defaultSourceChainId;
55416
- if (defaultSourceTokenAddress && hasChainDefaults) {
55417
- for (const t11 of supportedTokens) {
55362
+ function resolveToken(tokens, defaultChainType, defaultChainId, defaultTokenAddress, defaultSymbol) {
55363
+ if (!tokens.length) return null;
55364
+ let selectedToken;
55365
+ let selectedChain;
55366
+ const hasChainDefaults = defaultChainType && defaultChainId;
55367
+ if (defaultTokenAddress && hasChainDefaults) {
55368
+ for (const t11 of tokens) {
55418
55369
  const matchingChain = t11.chains.find(
55419
- (c) => c.token_address.toLowerCase() === defaultSourceTokenAddress.toLowerCase() && c.chain_type === defaultSourceChainType && c.chain_id === defaultSourceChainId
55370
+ (c) => c.token_address.toLowerCase() === defaultTokenAddress.toLowerCase() && c.chain_type === defaultChainType && c.chain_id === defaultChainId
55420
55371
  );
55421
55372
  if (matchingChain) {
55422
- selectedTokenData = t11;
55423
- selectedChainData = matchingChain;
55373
+ selectedToken = t11;
55374
+ selectedChain = matchingChain;
55424
55375
  break;
55425
55376
  }
55426
55377
  }
55427
55378
  }
55428
- if (!selectedTokenData && defaultSourceSymbol && hasChainDefaults) {
55429
- for (const t11 of supportedTokens) {
55430
- if (t11.symbol !== defaultSourceSymbol) continue;
55379
+ if (!selectedToken && defaultSymbol && hasChainDefaults) {
55380
+ for (const t11 of tokens) {
55381
+ if (t11.symbol !== defaultSymbol) continue;
55431
55382
  const matchedChain = t11.chains.find(
55432
- (c) => c.chain_type === defaultSourceChainType && c.chain_id === defaultSourceChainId
55383
+ (c) => c.chain_type === defaultChainType && c.chain_id === defaultChainId
55433
55384
  );
55434
55385
  if (matchedChain) {
55435
- selectedTokenData = t11;
55436
- selectedChainData = matchedChain;
55386
+ selectedToken = t11;
55387
+ selectedChain = matchedChain;
55437
55388
  break;
55438
55389
  }
55439
55390
  }
55440
55391
  }
55441
- if (!selectedTokenData) {
55442
- for (const t11 of supportedTokens) {
55392
+ if (!selectedToken) {
55393
+ for (const t11 of tokens) {
55443
55394
  if (t11.chains.length > 0) {
55444
- selectedTokenData = t11;
55445
- selectedChainData = t11.chains[0];
55395
+ selectedToken = t11;
55396
+ selectedChain = t11.chains[0];
55446
55397
  break;
55447
55398
  }
55448
55399
  }
55449
55400
  }
55450
- if (selectedTokenData && selectedChainData) {
55451
- return { token: selectedTokenData, chain: selectedChainData };
55401
+ if (selectedToken && selectedChain) {
55402
+ return { token: selectedToken, chain: selectedChain };
55452
55403
  }
55453
55404
  return null;
55454
55405
  }
55455
- function useDefaultSourceToken({
55456
- supportedTokens,
55457
- defaultSourceChainType,
55458
- defaultSourceChainId,
55459
- defaultSourceTokenAddress,
55460
- defaultSourceSymbol
55406
+ function useDefaultToken({
55407
+ tokens,
55408
+ defaultChainType,
55409
+ defaultChainId,
55410
+ defaultTokenAddress,
55411
+ defaultSymbol
55461
55412
  }) {
55462
55413
  const [token, setToken] = (0, import_react20.useState)(null);
55463
55414
  const [chain, setChain] = (0, import_react20.useState)(null);
55464
55415
  const [initialSelectionDone, setInitialSelectionDone] = (0, import_react20.useState)(false);
55465
55416
  const appliedDefaultsRef = (0, import_react20.useRef)("");
55466
55417
  (0, import_react20.useEffect)(() => {
55467
- if (!supportedTokens.length) return;
55468
- const defaultsKey = `${defaultSourceTokenAddress ?? ""}|${defaultSourceSymbol ?? ""}|${defaultSourceChainType ?? ""}|${defaultSourceChainId ?? ""}`;
55418
+ if (!tokens.length) return;
55419
+ const defaultsKey = `${defaultTokenAddress ?? ""}|${defaultSymbol ?? ""}|${defaultChainType ?? ""}|${defaultChainId ?? ""}`;
55469
55420
  const defaultsChanged = appliedDefaultsRef.current !== defaultsKey;
55470
55421
  if (initialSelectionDone && !defaultsChanged) return;
55471
- const result = resolveSourceToken(
55472
- supportedTokens,
55473
- defaultSourceChainType,
55474
- defaultSourceChainId,
55475
- defaultSourceTokenAddress,
55476
- defaultSourceSymbol
55422
+ const result = resolveToken(
55423
+ tokens,
55424
+ defaultChainType,
55425
+ defaultChainId,
55426
+ defaultTokenAddress,
55427
+ defaultSymbol
55477
55428
  );
55478
55429
  if (result) {
55479
55430
  setToken(result.token.symbol);
@@ -55482,16 +55433,16 @@ function useDefaultSourceToken({
55482
55433
  setInitialSelectionDone(true);
55483
55434
  }
55484
55435
  }, [
55485
- supportedTokens,
55486
- defaultSourceTokenAddress,
55487
- defaultSourceSymbol,
55488
- defaultSourceChainType,
55489
- defaultSourceChainId,
55436
+ tokens,
55437
+ defaultTokenAddress,
55438
+ defaultSymbol,
55439
+ defaultChainType,
55440
+ defaultChainId,
55490
55441
  initialSelectionDone
55491
55442
  ]);
55492
55443
  (0, import_react20.useEffect)(() => {
55493
- if (!supportedTokens.length || !token) return;
55494
- const currentToken = supportedTokens.find((t11) => t11.symbol === token);
55444
+ if (!tokens.length || !token) return;
55445
+ const currentToken = tokens.find((t11) => t11.symbol === token);
55495
55446
  if (!currentToken || currentToken.chains.length === 0) return;
55496
55447
  const isChainAvailable = chain && currentToken.chains.some((c) => {
55497
55448
  return getChainKey(c.chain_id, c.chain_type) === chain;
@@ -55500,9 +55451,24 @@ function useDefaultSourceToken({
55500
55451
  const firstChain = currentToken.chains[0];
55501
55452
  setChain(getChainKey(firstChain.chain_id, firstChain.chain_type));
55502
55453
  }
55503
- }, [token, supportedTokens, chain]);
55454
+ }, [token, tokens, chain]);
55504
55455
  return { token, chain, setToken, setChain, initialSelectionDone };
55505
55456
  }
55457
+ function useDefaultSourceToken({
55458
+ supportedTokens,
55459
+ defaultSourceChainType,
55460
+ defaultSourceChainId,
55461
+ defaultSourceTokenAddress,
55462
+ defaultSourceSymbol
55463
+ }) {
55464
+ return useDefaultToken({
55465
+ tokens: supportedTokens,
55466
+ defaultChainType: defaultSourceChainType,
55467
+ defaultChainId: defaultSourceChainId,
55468
+ defaultTokenAddress: defaultSourceTokenAddress,
55469
+ defaultSymbol: defaultSourceSymbol
55470
+ });
55471
+ }
55506
55472
  function DepositFooterLinks({
55507
55473
  onGlossaryClick
55508
55474
  }) {
@@ -59779,19 +59745,30 @@ function DepositModal({
59779
59745
  }
59780
59746
  ) });
59781
59747
  }
59748
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
59749
+ "succeeded",
59750
+ "expired",
59751
+ "refunded",
59752
+ "canceled"
59753
+ ]);
59782
59754
  function usePaymentIntent(params) {
59783
59755
  const {
59784
59756
  clientSecret,
59785
59757
  publishableKey,
59786
59758
  enabled = true,
59787
- pollingInterval = 5e3
59759
+ pollingInterval = 3e3
59788
59760
  } = params;
59789
59761
  return useQuery({
59790
59762
  queryKey: ["unifold", "paymentIntent", clientSecret, publishableKey],
59791
59763
  queryFn: () => retrievePaymentIntent(clientSecret, publishableKey),
59792
59764
  enabled: enabled && !!clientSecret && !!publishableKey,
59793
59765
  staleTime: 0,
59794
- refetchInterval: pollingInterval || false,
59766
+ refetchInterval: (query) => {
59767
+ if (!pollingInterval) return false;
59768
+ const status = query.state.data?.status;
59769
+ if (status && TERMINAL_STATUSES.has(status)) return false;
59770
+ return pollingInterval;
59771
+ },
59795
59772
  refetchOnWindowFocus: true,
59796
59773
  retry: 3,
59797
59774
  retryDelay: (attempt) => Math.min(1e3 * 2 ** attempt, 1e4)
@@ -59915,7 +59892,7 @@ function CheckoutModal({
59915
59892
  clientSecret,
59916
59893
  publishableKey,
59917
59894
  enabled: open && !!clientSecret,
59918
- pollingInterval: 5e3
59895
+ pollingInterval: 3e3
59919
59896
  });
59920
59897
  const { projectConfig } = useProjectConfig({
59921
59898
  publishableKey,
@@ -60456,6 +60433,21 @@ function useSupportedDestinationTokens(publishableKey, enabled = true) {
60456
60433
  enabled
60457
60434
  });
60458
60435
  }
60436
+ function useDefaultDestinationToken({
60437
+ destinationTokens,
60438
+ defaultDestinationChainType,
60439
+ defaultDestinationChainId,
60440
+ defaultDestinationTokenAddress,
60441
+ defaultDestinationSymbol
60442
+ }) {
60443
+ return useDefaultToken({
60444
+ tokens: destinationTokens,
60445
+ defaultChainType: defaultDestinationChainType,
60446
+ defaultChainId: defaultDestinationChainId,
60447
+ defaultTokenAddress: defaultDestinationTokenAddress,
60448
+ defaultSymbol: defaultDestinationSymbol
60449
+ });
60450
+ }
60459
60451
  function useSourceTokenValidation(params) {
60460
60452
  const {
60461
60453
  sourceChainType,
@@ -61702,6 +61694,10 @@ function WithdrawModal({
61702
61694
  sourceTokenSymbol,
61703
61695
  recipientAddress: recipientAddressProp,
61704
61696
  senderAddress,
61697
+ defaultDestinationChainType,
61698
+ defaultDestinationChainId,
61699
+ defaultDestinationTokenAddress,
61700
+ defaultDestinationSymbol,
61705
61701
  onWithdraw,
61706
61702
  onWithdrawSuccess,
61707
61703
  onWithdrawError,
@@ -61745,8 +61741,21 @@ function WithdrawModal({
61745
61741
  publishableKey,
61746
61742
  enabled: open
61747
61743
  });
61748
- const [selectedToken, setSelectedToken] = (0, import_react28.useState)(null);
61749
- const [selectedChain, setSelectedChain] = (0, import_react28.useState)(null);
61744
+ const {
61745
+ token: selectedTokenSymbol,
61746
+ chain: selectedChainKey,
61747
+ setToken: setSelectedTokenSymbol,
61748
+ setChain: setSelectedChainKey,
61749
+ initialSelectionDone
61750
+ } = useDefaultDestinationToken({
61751
+ destinationTokens,
61752
+ defaultDestinationChainType,
61753
+ defaultDestinationChainId,
61754
+ defaultDestinationTokenAddress,
61755
+ defaultDestinationSymbol
61756
+ });
61757
+ const selectedToken = selectedTokenSymbol ? destinationTokens.find((t11) => t11.symbol === selectedTokenSymbol) ?? null : null;
61758
+ const selectedChain = selectedToken && selectedChainKey ? selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === selectedChainKey) ?? null : null;
61750
61759
  const [view, setView] = (0, import_react28.useState)("form");
61751
61760
  const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react28.useState)();
61752
61761
  const [selectedExecution, setSelectedExecution] = (0, import_react28.useState)(null);
@@ -61788,21 +61797,11 @@ function WithdrawModal({
61788
61797
  setSubmittedTxInfo(txInfo);
61789
61798
  setView("confirming");
61790
61799
  }, []);
61791
- (0, import_react28.useEffect)(() => {
61792
- if (!destinationTokens.length || selectedToken) return;
61793
- const first = destinationTokens[0];
61794
- if (first?.chains.length > 0) {
61795
- setSelectedToken(first);
61796
- setSelectedChain(first.chains[0]);
61797
- }
61798
- }, [destinationTokens, selectedToken]);
61799
61800
  const resetViewTimeoutRef = (0, import_react28.useRef)(null);
61800
61801
  const handleClose = (0, import_react28.useCallback)(() => {
61801
61802
  onOpenChange(false);
61802
61803
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
61803
61804
  resetViewTimeoutRef.current = setTimeout(() => {
61804
- setSelectedToken(null);
61805
- setSelectedChain(null);
61806
61805
  setView("form");
61807
61806
  setSelectedExecution(null);
61808
61807
  setSubmittedTxInfo(null);
@@ -61816,8 +61815,6 @@ function WithdrawModal({
61816
61815
  clearTimeout(resetViewTimeoutRef.current);
61817
61816
  resetViewTimeoutRef.current = null;
61818
61817
  }
61819
- setSelectedToken(null);
61820
- setSelectedChain(null);
61821
61818
  setView("form");
61822
61819
  setSelectedExecution(null);
61823
61820
  setSubmittedTxInfo(null);
@@ -61827,19 +61824,13 @@ function WithdrawModal({
61827
61824
  if (resetViewTimeoutRef.current) clearTimeout(resetViewTimeoutRef.current);
61828
61825
  }, []);
61829
61826
  const handleTokenSymbolChange = (0, import_react28.useCallback)((symbol) => {
61830
- const tok = destinationTokens.find((t11) => t11.symbol === symbol);
61831
- if (tok) {
61832
- setSelectedToken(tok);
61833
- if (tok.chains.length > 0) setSelectedChain(tok.chains[0]);
61834
- }
61835
- }, [destinationTokens]);
61827
+ setSelectedTokenSymbol(symbol);
61828
+ }, [setSelectedTokenSymbol]);
61836
61829
  const handleChainKeyChange = (0, import_react28.useCallback)((chainKey) => {
61837
- if (!selectedToken) return;
61838
- const chain = selectedToken.chains.find((c) => getChainKey5(c.chain_id, c.chain_type) === chainKey);
61839
- if (chain) setSelectedChain(chain);
61840
- }, [selectedToken]);
61830
+ setSelectedChainKey(chainKey);
61831
+ }, [setSelectedChainKey]);
61841
61832
  const isSourceSupported = sourceValidation?.isSupported ?? null;
61842
- const isAnyLoading = tokensLoading || isCheckingSourceToken;
61833
+ const isAnyLoading = tokensLoading || isCheckingSourceToken || destinationTokens.length > 0 && !initialSelectionDone;
61843
61834
  const withdrawPoweredByFooter = /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "uf-pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PoweredByUnifold, { color: colors2.foregroundMuted, className: "uf-flex uf-justify-center uf-shrink-0" }) });
61844
61835
  return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Dialog2, { open: hideOverlay || open, onOpenChange: hideOverlay ? void 0 : handleClose, modal: !hideOverlay, children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
61845
61836
  DialogContent2,
@@ -62249,6 +62240,10 @@ function UnifoldProvider2({
62249
62240
  sourceTokenAddress: withdrawConfig.sourceTokenAddress,
62250
62241
  sourceTokenSymbol: withdrawConfig.sourceTokenSymbol,
62251
62242
  recipientAddress: withdrawConfig.recipientAddress,
62243
+ defaultDestinationChainType: withdrawConfig.defaultDestinationChainType,
62244
+ defaultDestinationChainId: withdrawConfig.defaultDestinationChainId,
62245
+ defaultDestinationTokenAddress: withdrawConfig.defaultDestinationTokenAddress,
62246
+ defaultDestinationSymbol: withdrawConfig.defaultDestinationSymbol,
62252
62247
  senderAddress: withdrawConfig.senderAddress,
62253
62248
  onWithdraw: withdrawConfig.withdraw,
62254
62249
  onWithdrawSuccess: handleWithdrawSuccess,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifold/ui-web",
3
- "version": "0.1.48",
3
+ "version": "0.1.50",
4
4
  "description": "Unifold UI Web - Framework-agnostic deposit widget",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -30,10 +30,10 @@
30
30
  "@types/react-dom": "^19.0.0",
31
31
  "tsup": "^8.0.0",
32
32
  "typescript": "^5.0.0",
33
- "@unifold/connect-react": "0.1.48",
34
- "@unifold/react-provider": "0.1.48",
35
- "@unifold/core": "0.1.48",
36
- "@unifold/ui-react": "0.1.48"
33
+ "@unifold/connect-react": "0.1.50",
34
+ "@unifold/ui-react": "0.1.50",
35
+ "@unifold/react-provider": "0.1.50",
36
+ "@unifold/core": "0.1.50"
37
37
  },
38
38
  "keywords": [
39
39
  "unifold",