@unifold/ui-web 0.1.45 → 0.1.47

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 +76 -343
  2. package/dist/index.mjs +76 -343
  3. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -43351,6 +43351,9 @@ function getOnrampSessionStartUrl(request, publishableKey) {
43351
43351
  if (request.subdivision_code) {
43352
43352
  params.append("subdivision_code", request.subdivision_code);
43353
43353
  }
43354
+ if (request.external_id) {
43355
+ params.append("external_id", request.external_id);
43356
+ }
43354
43357
  return `${API_BASE_URL}/v1/public/onramps/sessions/start?${params.toString()}`;
43355
43358
  }
43356
43359
  async function getDefaultOnrampToken(params, publishableKey) {
@@ -43674,52 +43677,38 @@ async function getDepositQuote(request, publishableKey) {
43674
43677
  const json = await response.json();
43675
43678
  return json.data;
43676
43679
  }
43677
- async function buildHypercoreTransaction(request, publishableKey) {
43678
- const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43679
- validatePublishableKey(pk);
43680
- const response = await fetch(
43681
- `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
43682
- {
43683
- method: "POST",
43684
- headers: {
43685
- accept: "application/json",
43686
- "x-publishable-key": pk,
43687
- "Content-Type": "application/json"
43688
- },
43689
- body: JSON.stringify(request)
43680
+ function generatePrefixedKSUID(prefix) {
43681
+ const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
43682
+ const KSUID_EPOCH = 14e8;
43683
+ const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
43684
+ const payload = new Uint8Array(20);
43685
+ payload[0] = timestampSeconds >>> 24 & 255;
43686
+ payload[1] = timestampSeconds >>> 16 & 255;
43687
+ payload[2] = timestampSeconds >>> 8 & 255;
43688
+ payload[3] = timestampSeconds & 255;
43689
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
43690
+ crypto.getRandomValues(payload.subarray(4));
43691
+ } else {
43692
+ for (let i = 4; i < 20; i++) {
43693
+ payload[i] = Math.floor(Math.random() * 256);
43690
43694
  }
43691
- );
43692
- if (!response.ok) {
43693
- const error = await response.json().catch(() => ({ message: response.statusText }));
43694
- throw new Error(
43695
- `Failed to build HyperCore transaction: ${error.message || response.statusText}`
43696
- );
43697
43695
  }
43698
- return response.json();
43699
- }
43700
- async function sendHypercoreTransaction(request, publishableKey) {
43701
- const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43702
- validatePublishableKey(pk);
43703
- const response = await fetch(
43704
- `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
43705
- {
43706
- method: "POST",
43707
- headers: {
43708
- accept: "application/json",
43709
- "x-publishable-key": pk,
43710
- "Content-Type": "application/json"
43711
- },
43712
- body: JSON.stringify(request)
43713
- }
43714
- );
43715
- if (!response.ok) {
43716
- const error = await response.json().catch(() => ({ message: response.statusText }));
43717
- throw new Error(
43718
- `Failed to send HyperCore transaction: ${error.message || response.statusText}`
43719
- );
43696
+ let value = 0n;
43697
+ for (const byte of payload) {
43698
+ value = value << 8n | BigInt(byte);
43720
43699
  }
43721
- return response.json();
43700
+ let encoded = "";
43701
+ while (value > 0n) {
43702
+ encoded = BASE62[Number(value % 62n)] + encoded;
43703
+ value = value / 62n;
43704
+ }
43705
+ encoded = encoded.padStart(27, "0");
43706
+ return `${prefix}_${encoded}`;
43722
43707
  }
43708
+ var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
43709
+ DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
43710
+ return DepositEventType2;
43711
+ })(DepositEventType || {});
43723
43712
  var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
43724
43713
  var use = React25[" use ".trim().toString()];
43725
43714
  function isPromiseLike(value) {
@@ -50053,6 +50042,7 @@ function BuyWithCard({
50053
50042
  destinationTokenAddress,
50054
50043
  onDepositSuccess,
50055
50044
  onDepositError,
50045
+ onEvent,
50056
50046
  themeClass = "",
50057
50047
  wallets: externalWallets,
50058
50048
  assetCdnUrl,
@@ -50406,6 +50396,7 @@ function BuyWithCard({
50406
50396
  setQuotesError("Wallet address not available");
50407
50397
  return;
50408
50398
  }
50399
+ const externalId = generatePrefixedKSUID("orsext");
50409
50400
  const sessionRequest = {
50410
50401
  service_provider: selectedProvider.service_provider,
50411
50402
  country_code: selectedProvider.country_code.toUpperCase() || "US",
@@ -50414,7 +50405,8 @@ function BuyWithCard({
50414
50405
  destination_currency: selectedProvider.destination_currency,
50415
50406
  destination_network: selectedProvider.destination_network,
50416
50407
  wallet_address: wallet.address,
50417
- subdivision_code: userIpInfo?.state || void 0
50408
+ subdivision_code: userIpInfo?.state || void 0,
50409
+ external_id: externalId
50418
50410
  };
50419
50411
  const sessionStartUrl = getOnrampSessionStartUrl(
50420
50412
  sessionRequest,
@@ -50424,7 +50416,14 @@ function BuyWithCard({
50424
50416
  provider: selectedProvider,
50425
50417
  sourceCurrency: currency,
50426
50418
  sourceAmount: amount,
50427
- sessionUrl: sessionStartUrl
50419
+ sessionUrl: sessionStartUrl,
50420
+ externalId
50421
+ });
50422
+ onEvent?.({
50423
+ id: generatePrefixedKSUID("sevt"),
50424
+ type: DepositEventType.ONRAMP_SESSION_CREATED,
50425
+ created: Math.floor(Date.now() / 1e3),
50426
+ data: { object: { externalId } }
50428
50427
  });
50429
50428
  window.open(sessionStartUrl, "_blank");
50430
50429
  handleViewChange("onramp");
@@ -57895,10 +57894,11 @@ function BrowserWalletModal({
57895
57894
  const chainType = depositWallet.chain_type;
57896
57895
  const recipientAddress = depositWallet.address;
57897
57896
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
57898
- const { executions: depositExecutions, isPolling } = useDepositPolling({
57897
+ const { executions: depositExecutions, isPolling, handleIveDeposited } = useDepositPolling({
57899
57898
  userId,
57900
57899
  publishableKey,
57901
57900
  clientSecret,
57901
+ depositWalletId: depositWallet.id,
57902
57902
  enabled: open && hasSignedTransaction,
57903
57903
  onDepositSuccess,
57904
57904
  onDepositError
@@ -58149,6 +58149,7 @@ function BrowserWalletModal({
58149
58149
  }
58150
58150
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
58151
58151
  setHasSignedTransaction(true);
58152
+ handleIveDeposited();
58152
58153
  setIsConfirming(false);
58153
58154
  setStep("confirming");
58154
58155
  onSuccess?.(txHash);
@@ -59185,6 +59186,7 @@ function DepositModal({
59185
59186
  hideDisplayDescription = false,
59186
59187
  onDepositSuccess,
59187
59188
  onDepositError,
59189
+ onEvent,
59188
59190
  theme = "dark",
59189
59191
  hideOverlay = false,
59190
59192
  initialScreen = "main",
@@ -59699,6 +59701,7 @@ function DepositModal({
59699
59701
  destinationTokenAddress,
59700
59702
  onDepositSuccess,
59701
59703
  onDepositError,
59704
+ onEvent,
59702
59705
  themeClass,
59703
59706
  wallets,
59704
59707
  assetCdnUrl: projectConfig?.asset_cdn_url,
@@ -59882,6 +59885,10 @@ function CheckoutModal({
59882
59885
  publishableKey,
59883
59886
  modalTitle,
59884
59887
  enableConnectWallet = false,
59888
+ defaultSourceChainType,
59889
+ defaultSourceChainId,
59890
+ defaultSourceTokenAddress,
59891
+ defaultSourceSymbol,
59885
59892
  theme = "dark",
59886
59893
  onCheckoutSuccess,
59887
59894
  onCheckoutError
@@ -60379,6 +60386,10 @@ function CheckoutModal({
60379
60386
  destinationChainType: paymentIntent.destination_chain_type,
60380
60387
  destinationChainId: paymentIntent.destination_chain_id,
60381
60388
  destinationTokenAddress: paymentIntent.destination_token_address,
60389
+ defaultSourceChainType,
60390
+ defaultSourceChainId,
60391
+ defaultSourceTokenAddress,
60392
+ defaultSourceSymbol,
60382
60393
  depositConfirmationMode: "auto_ui",
60383
60394
  wallets,
60384
60395
  onSourceTokenChange: setSelectedSource,
@@ -60880,249 +60891,10 @@ function useVerifyRecipientAddress(params) {
60880
60891
  refetchOnWindowFocus: false
60881
60892
  });
60882
60893
  }
60883
- async function sendEvmWithdraw(params) {
60884
- const {
60885
- provider,
60886
- fromAddress,
60887
- depositWalletAddress,
60888
- sourceTokenAddress,
60889
- sourceChainId,
60890
- amountBaseUnit
60891
- } = params;
60892
- const currentChainIdHex = await provider.request({
60893
- method: "eth_chainId",
60894
- params: []
60895
- });
60896
- const currentChainId = parseInt(currentChainIdHex, 16).toString();
60897
- if (currentChainId !== sourceChainId) {
60898
- const requiredHex = "0x" + parseInt(sourceChainId).toString(16);
60899
- try {
60900
- await provider.request({
60901
- method: "wallet_switchEthereumChain",
60902
- params: [{ chainId: requiredHex }]
60903
- });
60904
- const newHex = await provider.request({ method: "eth_chainId", params: [] });
60905
- if (parseInt(newHex, 16).toString() !== sourceChainId) {
60906
- throw new Error(`Failed to switch to chain ${sourceChainId}. Please switch manually.`);
60907
- }
60908
- } catch (err) {
60909
- if (err && typeof err === "object" && "code" in err) {
60910
- const e = err;
60911
- if (e.code === 4902) throw new Error(`Chain ${sourceChainId} is not configured in your wallet.`);
60912
- if (e.code === 4001) throw new Error("You must approve the network switch to withdraw.");
60913
- }
60914
- throw err;
60915
- }
60916
- }
60917
- const isNative = sourceTokenAddress === "native" || sourceTokenAddress === "0x0000000000000000000000000000000000000000" || sourceTokenAddress === "";
60918
- const amountBig = BigInt(amountBaseUnit);
60919
- const txParams = isNative ? { from: fromAddress, to: depositWalletAddress, value: "0x" + amountBig.toString(16) } : {
60920
- from: fromAddress,
60921
- to: sourceTokenAddress,
60922
- data: "0xa9059cbb" + depositWalletAddress.slice(2).padStart(64, "0") + amountBig.toString(16).padStart(64, "0")
60923
- };
60924
- let gasEstimate;
60925
- try {
60926
- const hex = await provider.request({ method: "eth_estimateGas", params: [txParams] });
60927
- gasEstimate = BigInt(hex);
60928
- } catch {
60929
- gasEstimate = isNative ? BigInt(21e3) : BigInt(65e3);
60930
- }
60931
- const gasPrice = BigInt(await provider.request({ method: "eth_gasPrice", params: [] }));
60932
- const gasWithBuffer = gasEstimate * BigInt(120) / BigInt(100);
60933
- const gasCost = gasWithBuffer * gasPrice;
60934
- const ethBalance = BigInt(
60935
- await provider.request({ method: "eth_getBalance", params: [fromAddress, "latest"] })
60936
- );
60937
- const totalRequired = isNative ? gasCost + amountBig : gasCost;
60938
- if (ethBalance < totalRequired) {
60939
- const gasFmt = (Number(gasCost) / 1e18).toFixed(6);
60940
- if (isNative) {
60941
- throw new Error(`Insufficient balance. Need ${(Number(totalRequired) / 1e18).toFixed(6)} ETH (amount + ~${gasFmt} gas).`);
60942
- }
60943
- throw new Error(`Insufficient ETH for gas. Need ~${gasFmt} ETH for fees.`);
60944
- }
60945
- const txHash = await provider.request({ method: "eth_sendTransaction", params: [txParams] });
60946
- return txHash;
60947
- }
60948
- async function sendSolanaWithdraw(params) {
60949
- const {
60950
- provider,
60951
- fromAddress,
60952
- depositWalletAddress,
60953
- sourceTokenAddress,
60954
- amountBaseUnit,
60955
- publishableKey
60956
- } = params;
60957
- if (!provider.publicKey) {
60958
- await provider.connect();
60959
- }
60960
- const buildResponse = await buildSolanaTransaction(
60961
- {
60962
- chain_id: "mainnet",
60963
- token_address: sourceTokenAddress === "" ? "native" : sourceTokenAddress,
60964
- source_address: fromAddress,
60965
- destination_address: depositWalletAddress,
60966
- amount: amountBaseUnit
60967
- },
60968
- publishableKey
60969
- );
60970
- const { VersionedTransaction } = await import(
60971
- /* @vite-ignore */
60972
- "@solana/web3.js"
60973
- );
60974
- const binaryString = atob(buildResponse.transaction);
60975
- const bytes = new Uint8Array(binaryString.length);
60976
- for (let i = 0; i < binaryString.length; i++) {
60977
- bytes[i] = binaryString.charCodeAt(i);
60978
- }
60979
- const transaction = VersionedTransaction.deserialize(bytes);
60980
- const signedTransaction = await provider.signTransaction(transaction);
60981
- const serialized = signedTransaction.serialize();
60982
- let binaryStr = "";
60983
- for (let i = 0; i < serialized.length; i++) {
60984
- binaryStr += String.fromCharCode(serialized[i]);
60985
- }
60986
- const sendResponse = await sendSolanaTransaction(
60987
- { chain_id: "mainnet", signed_transaction: btoa(binaryStr) },
60988
- publishableKey
60989
- );
60990
- return sendResponse.signature;
60991
- }
60992
60894
  var HYPERCORE_CHAIN_ID = "1337";
60993
- var HYPERCORE_SPOT_USDC_ADDRESS = "0x6d1e7cde53ba9467b783cb7c530ce054";
60994
60895
  function isHypercoreChain(chainId) {
60995
60896
  return chainId === HYPERCORE_CHAIN_ID;
60996
60897
  }
60997
- async function sendHypercoreWithdraw(params) {
60998
- const {
60999
- provider,
61000
- fromAddress,
61001
- depositWalletAddress,
61002
- sourceTokenAddress,
61003
- amount,
61004
- tokenSymbol,
61005
- publishableKey
61006
- } = params;
61007
- const isSpot = sourceTokenAddress.toLowerCase() === HYPERCORE_SPOT_USDC_ADDRESS;
61008
- const currentChainHex = await provider.request({
61009
- method: "eth_chainId",
61010
- params: []
61011
- });
61012
- const activeChainId = String(parseInt(currentChainHex, 16));
61013
- const buildResult = await buildHypercoreTransaction(
61014
- {
61015
- action_type: isSpot ? "spot_send" : "usd_send",
61016
- signature_chain_type: "ethereum",
61017
- signature_chain_id: activeChainId,
61018
- recipient_address: depositWalletAddress,
61019
- token_address: sourceTokenAddress,
61020
- token_symbol: tokenSymbol || void 0,
61021
- amount
61022
- },
61023
- publishableKey
61024
- );
61025
- const signature = await provider.request({
61026
- method: "eth_signTypedData_v4",
61027
- params: [fromAddress, JSON.stringify(buildResult.typed_data)]
61028
- });
61029
- await sendHypercoreTransaction(
61030
- {
61031
- action_payload: buildResult.action_payload,
61032
- signature,
61033
- nonce: buildResult.nonce
61034
- },
61035
- publishableKey
61036
- );
61037
- }
61038
- async function detectBrowserWallet(chainType, senderAddress) {
61039
- const win = typeof window !== "undefined" ? window : null;
61040
- if (!win || !senderAddress) return null;
61041
- if (getUserDisconnectedWallet()) return null;
61042
- const anyWin = win;
61043
- if (chainType === "solana") {
61044
- const solProviders = [];
61045
- if (win.phantom?.solana) solProviders.push({ provider: win.phantom.solana, name: "Phantom" });
61046
- if (anyWin.solflare) solProviders.push({ provider: anyWin.solflare, name: "Solflare" });
61047
- if (anyWin.backpack) solProviders.push({ provider: anyWin.backpack, name: "Backpack" });
61048
- if (anyWin.trustwallet?.solana) solProviders.push({ provider: anyWin.trustwallet.solana, name: "Trust Wallet" });
61049
- for (const { provider, name } of solProviders) {
61050
- if (!provider) continue;
61051
- try {
61052
- let addr;
61053
- if (provider.isConnected && provider.publicKey) {
61054
- addr = provider.publicKey.toString();
61055
- } else {
61056
- const resp = await provider.connect({ onlyIfTrusted: true });
61057
- if (resp?.publicKey) addr = resp.publicKey.toString();
61058
- }
61059
- if (addr && addr === senderAddress) {
61060
- return { chainFamily: "solana", provider, name, address: addr };
61061
- }
61062
- } catch {
61063
- }
61064
- }
61065
- }
61066
- if (chainType === "ethereum") {
61067
- const evmProviders = [];
61068
- const seen = /* @__PURE__ */ new Set();
61069
- const add = (p, name) => {
61070
- if (p && typeof p.request === "function" && !seen.has(p)) {
61071
- seen.add(p);
61072
- evmProviders.push({ provider: p, name });
61073
- }
61074
- };
61075
- if (!anyWin.__eip6963Providers) {
61076
- anyWin.__eip6963Providers = [];
61077
- }
61078
- const handleAnnouncement = (event) => {
61079
- const { detail } = event;
61080
- if (!detail?.info || !detail?.provider) return;
61081
- const exists = anyWin.__eip6963Providers.some((p) => p.info.uuid === detail.info.uuid);
61082
- if (!exists) anyWin.__eip6963Providers.push(detail);
61083
- };
61084
- win.addEventListener("eip6963:announceProvider", handleAnnouncement);
61085
- win.dispatchEvent(new Event("eip6963:requestProvider"));
61086
- win.removeEventListener("eip6963:announceProvider", handleAnnouncement);
61087
- for (const detail of anyWin.__eip6963Providers) {
61088
- const rdns = detail.info?.rdns || "";
61089
- let name = detail.info?.name || "Wallet";
61090
- if (rdns.includes("metamask")) name = "MetaMask";
61091
- else if (rdns.includes("phantom")) name = "Phantom";
61092
- else if (rdns.includes("coinbase")) name = "Coinbase";
61093
- else if (rdns.includes("rabby")) name = "Rabby";
61094
- else if (rdns.includes("rainbow")) name = "Rainbow";
61095
- else if (rdns.includes("okx")) name = "OKX Wallet";
61096
- else if (rdns.includes("trust")) name = "Trust Wallet";
61097
- add(detail.provider, name);
61098
- }
61099
- if (evmProviders.length === 0) {
61100
- add(anyWin.phantom?.ethereum, "Phantom");
61101
- add(anyWin.coinbaseWalletExtension, "Coinbase");
61102
- add(anyWin.trustwallet?.ethereum, "Trust Wallet");
61103
- add(anyWin.okxwallet, "OKX Wallet");
61104
- if (evmProviders.length === 0 && win.ethereum) {
61105
- const eth = win.ethereum;
61106
- let name = "Wallet";
61107
- if (eth.isMetaMask && !eth.isPhantom && !eth.isRabby) name = "MetaMask";
61108
- else if (eth.isRabby) name = "Rabby";
61109
- else if (eth.isRainbow) name = "Rainbow";
61110
- else if (eth.isCoinbaseWallet) name = "Coinbase";
61111
- add(eth, name);
61112
- }
61113
- }
61114
- for (const { provider, name } of evmProviders) {
61115
- try {
61116
- const accounts = await provider.request({ method: "eth_accounts" });
61117
- if (accounts?.length > 0 && accounts[0].toLowerCase() === senderAddress.toLowerCase()) {
61118
- return { chainFamily: "evm", provider, name, address: accounts[0] };
61119
- }
61120
- } catch {
61121
- }
61122
- }
61123
- }
61124
- return null;
61125
- }
61126
60898
  var t8 = i18n2.withdrawModal;
61127
60899
  var tCrypto = i18n2.transferCrypto;
61128
60900
  function formatProcessingTime2(seconds) {
@@ -61270,8 +61042,8 @@ function WithdrawForm({
61270
61042
  setAmount(fiat.toFixed(2));
61271
61043
  setInputUnit("fiat");
61272
61044
  } else {
61273
- const crypto = val / exchangeRate;
61274
- setAmount(crypto.toFixed(sourceDecimals > 6 ? 6 : sourceDecimals));
61045
+ const crypto2 = val / exchangeRate;
61046
+ setAmount(crypto2.toFixed(sourceDecimals > 6 ? 6 : sourceDecimals));
61275
61047
  setInputUnit("crypto");
61276
61048
  }
61277
61049
  }, [amount, inputUnit, exchangeRate, sourceDecimals]);
@@ -61293,6 +61065,9 @@ function WithdrawForm({
61293
61065
  setIsSubmitting(true);
61294
61066
  setSubmitError(null);
61295
61067
  try {
61068
+ if (!onWithdraw) {
61069
+ throw new Error("No withdrawal method available. Please provide an onWithdraw handler.");
61070
+ }
61296
61071
  const depositWallet = await onDepositWalletCreation({
61297
61072
  destinationChainType: selectedChain.chain_type,
61298
61073
  destinationChainId: selectedChain.chain_id,
@@ -61350,63 +61125,16 @@ function WithdrawForm({
61350
61125
  withdrawIntentAddress: depositWallet.address,
61351
61126
  recipientAddress: trimmedAddress
61352
61127
  };
61353
- const wallet = await detectBrowserWallet(sourceChainType, senderAddress);
61354
- console.log("browser wallet", wallet);
61355
- if (wallet) {
61356
- try {
61357
- if (wallet.chainFamily === "evm" && isHypercoreChain(sourceChainId)) {
61358
- await sendHypercoreWithdraw({
61359
- provider: wallet.provider,
61360
- fromAddress: wallet.address,
61361
- depositWalletAddress: depositWallet.address,
61362
- sourceTokenAddress,
61363
- amount: humanAmount,
61364
- tokenSymbol,
61365
- publishableKey
61366
- });
61367
- } else if (wallet.chainFamily === "evm") {
61368
- await sendEvmWithdraw({
61369
- provider: wallet.provider,
61370
- fromAddress: wallet.address,
61371
- depositWalletAddress: depositWallet.address,
61372
- sourceTokenAddress,
61373
- sourceChainId,
61374
- amountBaseUnit
61375
- });
61376
- } else if (wallet.chainFamily === "solana") {
61377
- await sendSolanaWithdraw({
61378
- provider: wallet.provider,
61379
- fromAddress: wallet.address,
61380
- depositWalletAddress: depositWallet.address,
61381
- sourceTokenAddress,
61382
- amountBaseUnit,
61383
- publishableKey
61384
- });
61385
- }
61386
- } catch (walletErr) {
61387
- console.error("[Unifold] Browser wallet send failed:", walletErr, {
61388
- wallet: `${wallet.name} (${wallet.chainFamily})`,
61389
- sourceChainId,
61390
- amount: humanAmount,
61391
- amountBaseUnit,
61392
- depositWallet: depositWallet.address
61393
- });
61394
- throw walletErr;
61395
- }
61396
- } else if (onWithdraw) {
61397
- try {
61398
- await onWithdraw(txInfo);
61399
- } catch (callbackErr) {
61400
- console.error("[Unifold] onWithdraw callback failed:", callbackErr, {
61401
- sourceChainId,
61402
- amount: humanAmount,
61403
- amountBaseUnit,
61404
- depositWallet: depositWallet.address
61405
- });
61406
- throw callbackErr;
61407
- }
61408
- } else {
61409
- throw new Error("No withdrawal method available. Please connect a wallet.");
61128
+ try {
61129
+ await onWithdraw(txInfo);
61130
+ } catch (callbackErr) {
61131
+ console.error("[Unifold] onWithdraw callback failed:", callbackErr, {
61132
+ sourceChainId,
61133
+ amount: humanAmount,
61134
+ amountBaseUnit,
61135
+ depositWallet: depositWallet.address
61136
+ });
61137
+ throw callbackErr;
61410
61138
  }
61411
61139
  onWithdrawSubmitted?.(txInfo);
61412
61140
  } catch (err) {
@@ -62512,6 +62240,10 @@ function UnifoldProvider2({
62512
62240
  clientSecret: checkoutConfig.clientSecret,
62513
62241
  publishableKey,
62514
62242
  enableConnectWallet: config?.enableConnectWallet,
62243
+ defaultSourceChainType: checkoutConfig.defaultSourceChainType,
62244
+ defaultSourceChainId: checkoutConfig.defaultSourceChainId,
62245
+ defaultSourceTokenAddress: checkoutConfig.defaultSourceTokenAddress,
62246
+ defaultSourceSymbol: checkoutConfig.defaultSourceSymbol,
62515
62247
  theme: resolvedTheme,
62516
62248
  onCheckoutSuccess: handleCheckoutSuccess,
62517
62249
  onCheckoutError: handleCheckoutError
@@ -62562,6 +62294,7 @@ function UnifoldProvider2({
62562
62294
  enablePayWithExchange: config?.enablePayWithExchange,
62563
62295
  onDepositSuccess: handleDepositSuccess,
62564
62296
  onDepositError: handleDepositError,
62297
+ onEvent: depositConfig.onEvent,
62565
62298
  theme: resolvedTheme,
62566
62299
  initialScreen: depositConfig.initialScreen ?? config?.defaultInitialScreen,
62567
62300
  transferCryptoTitle: config?.transferCryptoTitle,
package/dist/index.mjs CHANGED
@@ -43338,6 +43338,9 @@ function getOnrampSessionStartUrl(request, publishableKey) {
43338
43338
  if (request.subdivision_code) {
43339
43339
  params.append("subdivision_code", request.subdivision_code);
43340
43340
  }
43341
+ if (request.external_id) {
43342
+ params.append("external_id", request.external_id);
43343
+ }
43341
43344
  return `${API_BASE_URL}/v1/public/onramps/sessions/start?${params.toString()}`;
43342
43345
  }
43343
43346
  async function getDefaultOnrampToken(params, publishableKey) {
@@ -43661,52 +43664,38 @@ async function getDepositQuote(request, publishableKey) {
43661
43664
  const json = await response.json();
43662
43665
  return json.data;
43663
43666
  }
43664
- async function buildHypercoreTransaction(request, publishableKey) {
43665
- const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43666
- validatePublishableKey(pk);
43667
- const response = await fetch(
43668
- `${API_BASE_URL}/v1/public/transactions/hypercore/build`,
43669
- {
43670
- method: "POST",
43671
- headers: {
43672
- accept: "application/json",
43673
- "x-publishable-key": pk,
43674
- "Content-Type": "application/json"
43675
- },
43676
- body: JSON.stringify(request)
43667
+ function generatePrefixedKSUID(prefix) {
43668
+ const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
43669
+ const KSUID_EPOCH = 14e8;
43670
+ const timestampSeconds = Math.floor(Date.now() / 1e3) - KSUID_EPOCH;
43671
+ const payload = new Uint8Array(20);
43672
+ payload[0] = timestampSeconds >>> 24 & 255;
43673
+ payload[1] = timestampSeconds >>> 16 & 255;
43674
+ payload[2] = timestampSeconds >>> 8 & 255;
43675
+ payload[3] = timestampSeconds & 255;
43676
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
43677
+ crypto.getRandomValues(payload.subarray(4));
43678
+ } else {
43679
+ for (let i = 4; i < 20; i++) {
43680
+ payload[i] = Math.floor(Math.random() * 256);
43677
43681
  }
43678
- );
43679
- if (!response.ok) {
43680
- const error = await response.json().catch(() => ({ message: response.statusText }));
43681
- throw new Error(
43682
- `Failed to build HyperCore transaction: ${error.message || response.statusText}`
43683
- );
43684
43682
  }
43685
- return response.json();
43686
- }
43687
- async function sendHypercoreTransaction(request, publishableKey) {
43688
- const pk = publishableKey || DEFAULT_PUBLISHABLE_KEY;
43689
- validatePublishableKey(pk);
43690
- const response = await fetch(
43691
- `${API_BASE_URL}/v1/public/transactions/hypercore/send`,
43692
- {
43693
- method: "POST",
43694
- headers: {
43695
- accept: "application/json",
43696
- "x-publishable-key": pk,
43697
- "Content-Type": "application/json"
43698
- },
43699
- body: JSON.stringify(request)
43700
- }
43701
- );
43702
- if (!response.ok) {
43703
- const error = await response.json().catch(() => ({ message: response.statusText }));
43704
- throw new Error(
43705
- `Failed to send HyperCore transaction: ${error.message || response.statusText}`
43706
- );
43683
+ let value = 0n;
43684
+ for (const byte of payload) {
43685
+ value = value << 8n | BigInt(byte);
43707
43686
  }
43708
- return response.json();
43687
+ let encoded = "";
43688
+ while (value > 0n) {
43689
+ encoded = BASE62[Number(value % 62n)] + encoded;
43690
+ value = value / 62n;
43691
+ }
43692
+ encoded = encoded.padStart(27, "0");
43693
+ return `${prefix}_${encoded}`;
43709
43694
  }
43695
+ var DepositEventType = /* @__PURE__ */ ((DepositEventType2) => {
43696
+ DepositEventType2["ONRAMP_SESSION_CREATED"] = "onramp_session.created";
43697
+ return DepositEventType2;
43698
+ })(DepositEventType || {});
43710
43699
  var REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for("react.lazy");
43711
43700
  var use = React25[" use ".trim().toString()];
43712
43701
  function isPromiseLike(value) {
@@ -50040,6 +50029,7 @@ function BuyWithCard({
50040
50029
  destinationTokenAddress,
50041
50030
  onDepositSuccess,
50042
50031
  onDepositError,
50032
+ onEvent,
50043
50033
  themeClass = "",
50044
50034
  wallets: externalWallets,
50045
50035
  assetCdnUrl,
@@ -50393,6 +50383,7 @@ function BuyWithCard({
50393
50383
  setQuotesError("Wallet address not available");
50394
50384
  return;
50395
50385
  }
50386
+ const externalId = generatePrefixedKSUID("orsext");
50396
50387
  const sessionRequest = {
50397
50388
  service_provider: selectedProvider.service_provider,
50398
50389
  country_code: selectedProvider.country_code.toUpperCase() || "US",
@@ -50401,7 +50392,8 @@ function BuyWithCard({
50401
50392
  destination_currency: selectedProvider.destination_currency,
50402
50393
  destination_network: selectedProvider.destination_network,
50403
50394
  wallet_address: wallet.address,
50404
- subdivision_code: userIpInfo?.state || void 0
50395
+ subdivision_code: userIpInfo?.state || void 0,
50396
+ external_id: externalId
50405
50397
  };
50406
50398
  const sessionStartUrl = getOnrampSessionStartUrl(
50407
50399
  sessionRequest,
@@ -50411,7 +50403,14 @@ function BuyWithCard({
50411
50403
  provider: selectedProvider,
50412
50404
  sourceCurrency: currency,
50413
50405
  sourceAmount: amount,
50414
- sessionUrl: sessionStartUrl
50406
+ sessionUrl: sessionStartUrl,
50407
+ externalId
50408
+ });
50409
+ onEvent?.({
50410
+ id: generatePrefixedKSUID("sevt"),
50411
+ type: DepositEventType.ONRAMP_SESSION_CREATED,
50412
+ created: Math.floor(Date.now() / 1e3),
50413
+ data: { object: { externalId } }
50415
50414
  });
50416
50415
  window.open(sessionStartUrl, "_blank");
50417
50416
  handleViewChange("onramp");
@@ -57882,10 +57881,11 @@ function BrowserWalletModal({
57882
57881
  const chainType = depositWallet.chain_type;
57883
57882
  const recipientAddress = depositWallet.address;
57884
57883
  const supportedChainType = chainType === "algorand" || chainType === "xrpl" ? "ethereum" : chainType;
57885
- const { executions: depositExecutions, isPolling } = useDepositPolling({
57884
+ const { executions: depositExecutions, isPolling, handleIveDeposited } = useDepositPolling({
57886
57885
  userId,
57887
57886
  publishableKey,
57888
57887
  clientSecret,
57888
+ depositWalletId: depositWallet.id,
57889
57889
  enabled: open && hasSignedTransaction,
57890
57890
  onDepositSuccess,
57891
57891
  onDepositError
@@ -58136,6 +58136,7 @@ function BrowserWalletModal({
58136
58136
  }
58137
58137
  setReceivedUsdAtSubmission(checkoutReceivedUsd ?? "0");
58138
58138
  setHasSignedTransaction(true);
58139
+ handleIveDeposited();
58139
58140
  setIsConfirming(false);
58140
58141
  setStep("confirming");
58141
58142
  onSuccess?.(txHash);
@@ -59172,6 +59173,7 @@ function DepositModal({
59172
59173
  hideDisplayDescription = false,
59173
59174
  onDepositSuccess,
59174
59175
  onDepositError,
59176
+ onEvent,
59175
59177
  theme = "dark",
59176
59178
  hideOverlay = false,
59177
59179
  initialScreen = "main",
@@ -59686,6 +59688,7 @@ function DepositModal({
59686
59688
  destinationTokenAddress,
59687
59689
  onDepositSuccess,
59688
59690
  onDepositError,
59691
+ onEvent,
59689
59692
  themeClass,
59690
59693
  wallets,
59691
59694
  assetCdnUrl: projectConfig?.asset_cdn_url,
@@ -59869,6 +59872,10 @@ function CheckoutModal({
59869
59872
  publishableKey,
59870
59873
  modalTitle,
59871
59874
  enableConnectWallet = false,
59875
+ defaultSourceChainType,
59876
+ defaultSourceChainId,
59877
+ defaultSourceTokenAddress,
59878
+ defaultSourceSymbol,
59872
59879
  theme = "dark",
59873
59880
  onCheckoutSuccess,
59874
59881
  onCheckoutError
@@ -60366,6 +60373,10 @@ function CheckoutModal({
60366
60373
  destinationChainType: paymentIntent.destination_chain_type,
60367
60374
  destinationChainId: paymentIntent.destination_chain_id,
60368
60375
  destinationTokenAddress: paymentIntent.destination_token_address,
60376
+ defaultSourceChainType,
60377
+ defaultSourceChainId,
60378
+ defaultSourceTokenAddress,
60379
+ defaultSourceSymbol,
60369
60380
  depositConfirmationMode: "auto_ui",
60370
60381
  wallets,
60371
60382
  onSourceTokenChange: setSelectedSource,
@@ -60867,249 +60878,10 @@ function useVerifyRecipientAddress(params) {
60867
60878
  refetchOnWindowFocus: false
60868
60879
  });
60869
60880
  }
60870
- async function sendEvmWithdraw(params) {
60871
- const {
60872
- provider,
60873
- fromAddress,
60874
- depositWalletAddress,
60875
- sourceTokenAddress,
60876
- sourceChainId,
60877
- amountBaseUnit
60878
- } = params;
60879
- const currentChainIdHex = await provider.request({
60880
- method: "eth_chainId",
60881
- params: []
60882
- });
60883
- const currentChainId = parseInt(currentChainIdHex, 16).toString();
60884
- if (currentChainId !== sourceChainId) {
60885
- const requiredHex = "0x" + parseInt(sourceChainId).toString(16);
60886
- try {
60887
- await provider.request({
60888
- method: "wallet_switchEthereumChain",
60889
- params: [{ chainId: requiredHex }]
60890
- });
60891
- const newHex = await provider.request({ method: "eth_chainId", params: [] });
60892
- if (parseInt(newHex, 16).toString() !== sourceChainId) {
60893
- throw new Error(`Failed to switch to chain ${sourceChainId}. Please switch manually.`);
60894
- }
60895
- } catch (err) {
60896
- if (err && typeof err === "object" && "code" in err) {
60897
- const e = err;
60898
- if (e.code === 4902) throw new Error(`Chain ${sourceChainId} is not configured in your wallet.`);
60899
- if (e.code === 4001) throw new Error("You must approve the network switch to withdraw.");
60900
- }
60901
- throw err;
60902
- }
60903
- }
60904
- const isNative = sourceTokenAddress === "native" || sourceTokenAddress === "0x0000000000000000000000000000000000000000" || sourceTokenAddress === "";
60905
- const amountBig = BigInt(amountBaseUnit);
60906
- const txParams = isNative ? { from: fromAddress, to: depositWalletAddress, value: "0x" + amountBig.toString(16) } : {
60907
- from: fromAddress,
60908
- to: sourceTokenAddress,
60909
- data: "0xa9059cbb" + depositWalletAddress.slice(2).padStart(64, "0") + amountBig.toString(16).padStart(64, "0")
60910
- };
60911
- let gasEstimate;
60912
- try {
60913
- const hex = await provider.request({ method: "eth_estimateGas", params: [txParams] });
60914
- gasEstimate = BigInt(hex);
60915
- } catch {
60916
- gasEstimate = isNative ? BigInt(21e3) : BigInt(65e3);
60917
- }
60918
- const gasPrice = BigInt(await provider.request({ method: "eth_gasPrice", params: [] }));
60919
- const gasWithBuffer = gasEstimate * BigInt(120) / BigInt(100);
60920
- const gasCost = gasWithBuffer * gasPrice;
60921
- const ethBalance = BigInt(
60922
- await provider.request({ method: "eth_getBalance", params: [fromAddress, "latest"] })
60923
- );
60924
- const totalRequired = isNative ? gasCost + amountBig : gasCost;
60925
- if (ethBalance < totalRequired) {
60926
- const gasFmt = (Number(gasCost) / 1e18).toFixed(6);
60927
- if (isNative) {
60928
- throw new Error(`Insufficient balance. Need ${(Number(totalRequired) / 1e18).toFixed(6)} ETH (amount + ~${gasFmt} gas).`);
60929
- }
60930
- throw new Error(`Insufficient ETH for gas. Need ~${gasFmt} ETH for fees.`);
60931
- }
60932
- const txHash = await provider.request({ method: "eth_sendTransaction", params: [txParams] });
60933
- return txHash;
60934
- }
60935
- async function sendSolanaWithdraw(params) {
60936
- const {
60937
- provider,
60938
- fromAddress,
60939
- depositWalletAddress,
60940
- sourceTokenAddress,
60941
- amountBaseUnit,
60942
- publishableKey
60943
- } = params;
60944
- if (!provider.publicKey) {
60945
- await provider.connect();
60946
- }
60947
- const buildResponse = await buildSolanaTransaction(
60948
- {
60949
- chain_id: "mainnet",
60950
- token_address: sourceTokenAddress === "" ? "native" : sourceTokenAddress,
60951
- source_address: fromAddress,
60952
- destination_address: depositWalletAddress,
60953
- amount: amountBaseUnit
60954
- },
60955
- publishableKey
60956
- );
60957
- const { VersionedTransaction } = await import(
60958
- /* @vite-ignore */
60959
- "@solana/web3.js"
60960
- );
60961
- const binaryString = atob(buildResponse.transaction);
60962
- const bytes = new Uint8Array(binaryString.length);
60963
- for (let i = 0; i < binaryString.length; i++) {
60964
- bytes[i] = binaryString.charCodeAt(i);
60965
- }
60966
- const transaction = VersionedTransaction.deserialize(bytes);
60967
- const signedTransaction = await provider.signTransaction(transaction);
60968
- const serialized = signedTransaction.serialize();
60969
- let binaryStr = "";
60970
- for (let i = 0; i < serialized.length; i++) {
60971
- binaryStr += String.fromCharCode(serialized[i]);
60972
- }
60973
- const sendResponse = await sendSolanaTransaction(
60974
- { chain_id: "mainnet", signed_transaction: btoa(binaryStr) },
60975
- publishableKey
60976
- );
60977
- return sendResponse.signature;
60978
- }
60979
60881
  var HYPERCORE_CHAIN_ID = "1337";
60980
- var HYPERCORE_SPOT_USDC_ADDRESS = "0x6d1e7cde53ba9467b783cb7c530ce054";
60981
60882
  function isHypercoreChain(chainId) {
60982
60883
  return chainId === HYPERCORE_CHAIN_ID;
60983
60884
  }
60984
- async function sendHypercoreWithdraw(params) {
60985
- const {
60986
- provider,
60987
- fromAddress,
60988
- depositWalletAddress,
60989
- sourceTokenAddress,
60990
- amount,
60991
- tokenSymbol,
60992
- publishableKey
60993
- } = params;
60994
- const isSpot = sourceTokenAddress.toLowerCase() === HYPERCORE_SPOT_USDC_ADDRESS;
60995
- const currentChainHex = await provider.request({
60996
- method: "eth_chainId",
60997
- params: []
60998
- });
60999
- const activeChainId = String(parseInt(currentChainHex, 16));
61000
- const buildResult = await buildHypercoreTransaction(
61001
- {
61002
- action_type: isSpot ? "spot_send" : "usd_send",
61003
- signature_chain_type: "ethereum",
61004
- signature_chain_id: activeChainId,
61005
- recipient_address: depositWalletAddress,
61006
- token_address: sourceTokenAddress,
61007
- token_symbol: tokenSymbol || void 0,
61008
- amount
61009
- },
61010
- publishableKey
61011
- );
61012
- const signature = await provider.request({
61013
- method: "eth_signTypedData_v4",
61014
- params: [fromAddress, JSON.stringify(buildResult.typed_data)]
61015
- });
61016
- await sendHypercoreTransaction(
61017
- {
61018
- action_payload: buildResult.action_payload,
61019
- signature,
61020
- nonce: buildResult.nonce
61021
- },
61022
- publishableKey
61023
- );
61024
- }
61025
- async function detectBrowserWallet(chainType, senderAddress) {
61026
- const win = typeof window !== "undefined" ? window : null;
61027
- if (!win || !senderAddress) return null;
61028
- if (getUserDisconnectedWallet()) return null;
61029
- const anyWin = win;
61030
- if (chainType === "solana") {
61031
- const solProviders = [];
61032
- if (win.phantom?.solana) solProviders.push({ provider: win.phantom.solana, name: "Phantom" });
61033
- if (anyWin.solflare) solProviders.push({ provider: anyWin.solflare, name: "Solflare" });
61034
- if (anyWin.backpack) solProviders.push({ provider: anyWin.backpack, name: "Backpack" });
61035
- if (anyWin.trustwallet?.solana) solProviders.push({ provider: anyWin.trustwallet.solana, name: "Trust Wallet" });
61036
- for (const { provider, name } of solProviders) {
61037
- if (!provider) continue;
61038
- try {
61039
- let addr;
61040
- if (provider.isConnected && provider.publicKey) {
61041
- addr = provider.publicKey.toString();
61042
- } else {
61043
- const resp = await provider.connect({ onlyIfTrusted: true });
61044
- if (resp?.publicKey) addr = resp.publicKey.toString();
61045
- }
61046
- if (addr && addr === senderAddress) {
61047
- return { chainFamily: "solana", provider, name, address: addr };
61048
- }
61049
- } catch {
61050
- }
61051
- }
61052
- }
61053
- if (chainType === "ethereum") {
61054
- const evmProviders = [];
61055
- const seen = /* @__PURE__ */ new Set();
61056
- const add = (p, name) => {
61057
- if (p && typeof p.request === "function" && !seen.has(p)) {
61058
- seen.add(p);
61059
- evmProviders.push({ provider: p, name });
61060
- }
61061
- };
61062
- if (!anyWin.__eip6963Providers) {
61063
- anyWin.__eip6963Providers = [];
61064
- }
61065
- const handleAnnouncement = (event) => {
61066
- const { detail } = event;
61067
- if (!detail?.info || !detail?.provider) return;
61068
- const exists = anyWin.__eip6963Providers.some((p) => p.info.uuid === detail.info.uuid);
61069
- if (!exists) anyWin.__eip6963Providers.push(detail);
61070
- };
61071
- win.addEventListener("eip6963:announceProvider", handleAnnouncement);
61072
- win.dispatchEvent(new Event("eip6963:requestProvider"));
61073
- win.removeEventListener("eip6963:announceProvider", handleAnnouncement);
61074
- for (const detail of anyWin.__eip6963Providers) {
61075
- const rdns = detail.info?.rdns || "";
61076
- let name = detail.info?.name || "Wallet";
61077
- if (rdns.includes("metamask")) name = "MetaMask";
61078
- else if (rdns.includes("phantom")) name = "Phantom";
61079
- else if (rdns.includes("coinbase")) name = "Coinbase";
61080
- else if (rdns.includes("rabby")) name = "Rabby";
61081
- else if (rdns.includes("rainbow")) name = "Rainbow";
61082
- else if (rdns.includes("okx")) name = "OKX Wallet";
61083
- else if (rdns.includes("trust")) name = "Trust Wallet";
61084
- add(detail.provider, name);
61085
- }
61086
- if (evmProviders.length === 0) {
61087
- add(anyWin.phantom?.ethereum, "Phantom");
61088
- add(anyWin.coinbaseWalletExtension, "Coinbase");
61089
- add(anyWin.trustwallet?.ethereum, "Trust Wallet");
61090
- add(anyWin.okxwallet, "OKX Wallet");
61091
- if (evmProviders.length === 0 && win.ethereum) {
61092
- const eth = win.ethereum;
61093
- let name = "Wallet";
61094
- if (eth.isMetaMask && !eth.isPhantom && !eth.isRabby) name = "MetaMask";
61095
- else if (eth.isRabby) name = "Rabby";
61096
- else if (eth.isRainbow) name = "Rainbow";
61097
- else if (eth.isCoinbaseWallet) name = "Coinbase";
61098
- add(eth, name);
61099
- }
61100
- }
61101
- for (const { provider, name } of evmProviders) {
61102
- try {
61103
- const accounts = await provider.request({ method: "eth_accounts" });
61104
- if (accounts?.length > 0 && accounts[0].toLowerCase() === senderAddress.toLowerCase()) {
61105
- return { chainFamily: "evm", provider, name, address: accounts[0] };
61106
- }
61107
- } catch {
61108
- }
61109
- }
61110
- }
61111
- return null;
61112
- }
61113
60885
  var t8 = i18n2.withdrawModal;
61114
60886
  var tCrypto = i18n2.transferCrypto;
61115
60887
  function formatProcessingTime2(seconds) {
@@ -61257,8 +61029,8 @@ function WithdrawForm({
61257
61029
  setAmount(fiat.toFixed(2));
61258
61030
  setInputUnit("fiat");
61259
61031
  } else {
61260
- const crypto = val / exchangeRate;
61261
- setAmount(crypto.toFixed(sourceDecimals > 6 ? 6 : sourceDecimals));
61032
+ const crypto2 = val / exchangeRate;
61033
+ setAmount(crypto2.toFixed(sourceDecimals > 6 ? 6 : sourceDecimals));
61262
61034
  setInputUnit("crypto");
61263
61035
  }
61264
61036
  }, [amount, inputUnit, exchangeRate, sourceDecimals]);
@@ -61280,6 +61052,9 @@ function WithdrawForm({
61280
61052
  setIsSubmitting(true);
61281
61053
  setSubmitError(null);
61282
61054
  try {
61055
+ if (!onWithdraw) {
61056
+ throw new Error("No withdrawal method available. Please provide an onWithdraw handler.");
61057
+ }
61283
61058
  const depositWallet = await onDepositWalletCreation({
61284
61059
  destinationChainType: selectedChain.chain_type,
61285
61060
  destinationChainId: selectedChain.chain_id,
@@ -61337,63 +61112,16 @@ function WithdrawForm({
61337
61112
  withdrawIntentAddress: depositWallet.address,
61338
61113
  recipientAddress: trimmedAddress
61339
61114
  };
61340
- const wallet = await detectBrowserWallet(sourceChainType, senderAddress);
61341
- console.log("browser wallet", wallet);
61342
- if (wallet) {
61343
- try {
61344
- if (wallet.chainFamily === "evm" && isHypercoreChain(sourceChainId)) {
61345
- await sendHypercoreWithdraw({
61346
- provider: wallet.provider,
61347
- fromAddress: wallet.address,
61348
- depositWalletAddress: depositWallet.address,
61349
- sourceTokenAddress,
61350
- amount: humanAmount,
61351
- tokenSymbol,
61352
- publishableKey
61353
- });
61354
- } else if (wallet.chainFamily === "evm") {
61355
- await sendEvmWithdraw({
61356
- provider: wallet.provider,
61357
- fromAddress: wallet.address,
61358
- depositWalletAddress: depositWallet.address,
61359
- sourceTokenAddress,
61360
- sourceChainId,
61361
- amountBaseUnit
61362
- });
61363
- } else if (wallet.chainFamily === "solana") {
61364
- await sendSolanaWithdraw({
61365
- provider: wallet.provider,
61366
- fromAddress: wallet.address,
61367
- depositWalletAddress: depositWallet.address,
61368
- sourceTokenAddress,
61369
- amountBaseUnit,
61370
- publishableKey
61371
- });
61372
- }
61373
- } catch (walletErr) {
61374
- console.error("[Unifold] Browser wallet send failed:", walletErr, {
61375
- wallet: `${wallet.name} (${wallet.chainFamily})`,
61376
- sourceChainId,
61377
- amount: humanAmount,
61378
- amountBaseUnit,
61379
- depositWallet: depositWallet.address
61380
- });
61381
- throw walletErr;
61382
- }
61383
- } else if (onWithdraw) {
61384
- try {
61385
- await onWithdraw(txInfo);
61386
- } catch (callbackErr) {
61387
- console.error("[Unifold] onWithdraw callback failed:", callbackErr, {
61388
- sourceChainId,
61389
- amount: humanAmount,
61390
- amountBaseUnit,
61391
- depositWallet: depositWallet.address
61392
- });
61393
- throw callbackErr;
61394
- }
61395
- } else {
61396
- throw new Error("No withdrawal method available. Please connect a wallet.");
61115
+ try {
61116
+ await onWithdraw(txInfo);
61117
+ } catch (callbackErr) {
61118
+ console.error("[Unifold] onWithdraw callback failed:", callbackErr, {
61119
+ sourceChainId,
61120
+ amount: humanAmount,
61121
+ amountBaseUnit,
61122
+ depositWallet: depositWallet.address
61123
+ });
61124
+ throw callbackErr;
61397
61125
  }
61398
61126
  onWithdrawSubmitted?.(txInfo);
61399
61127
  } catch (err) {
@@ -62499,6 +62227,10 @@ function UnifoldProvider2({
62499
62227
  clientSecret: checkoutConfig.clientSecret,
62500
62228
  publishableKey,
62501
62229
  enableConnectWallet: config?.enableConnectWallet,
62230
+ defaultSourceChainType: checkoutConfig.defaultSourceChainType,
62231
+ defaultSourceChainId: checkoutConfig.defaultSourceChainId,
62232
+ defaultSourceTokenAddress: checkoutConfig.defaultSourceTokenAddress,
62233
+ defaultSourceSymbol: checkoutConfig.defaultSourceSymbol,
62502
62234
  theme: resolvedTheme,
62503
62235
  onCheckoutSuccess: handleCheckoutSuccess,
62504
62236
  onCheckoutError: handleCheckoutError
@@ -62549,6 +62281,7 @@ function UnifoldProvider2({
62549
62281
  enablePayWithExchange: config?.enablePayWithExchange,
62550
62282
  onDepositSuccess: handleDepositSuccess,
62551
62283
  onDepositError: handleDepositError,
62284
+ onEvent: depositConfig.onEvent,
62552
62285
  theme: resolvedTheme,
62553
62286
  initialScreen: depositConfig.initialScreen ?? config?.defaultInitialScreen,
62554
62287
  transferCryptoTitle: config?.transferCryptoTitle,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifold/ui-web",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
4
4
  "description": "Unifold UI Web - Framework-agnostic deposit widget",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -27,10 +27,10 @@
27
27
  "@types/react-dom": "^19.0.0",
28
28
  "tsup": "^8.0.0",
29
29
  "typescript": "^5.0.0",
30
- "@unifold/connect-react": "0.1.45",
31
- "@unifold/core": "0.1.45",
32
- "@unifold/react-provider": "0.1.45",
33
- "@unifold/ui-react": "0.1.45"
30
+ "@unifold/connect-react": "0.1.47",
31
+ "@unifold/core": "0.1.47",
32
+ "@unifold/ui-react": "0.1.47",
33
+ "@unifold/react-provider": "0.1.47"
34
34
  },
35
35
  "keywords": [
36
36
  "unifold",