@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.
- package/dist/index.js +76 -343
- package/dist/index.mjs +76 -343
- 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
|
-
|
|
43678
|
-
const
|
|
43679
|
-
|
|
43680
|
-
const
|
|
43681
|
-
|
|
43682
|
-
|
|
43683
|
-
|
|
43684
|
-
|
|
43685
|
-
|
|
43686
|
-
|
|
43687
|
-
|
|
43688
|
-
|
|
43689
|
-
|
|
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
|
-
|
|
43699
|
-
|
|
43700
|
-
|
|
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
|
-
|
|
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
|
|
61274
|
-
setAmount(
|
|
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
|
-
|
|
61354
|
-
|
|
61355
|
-
|
|
61356
|
-
|
|
61357
|
-
|
|
61358
|
-
|
|
61359
|
-
|
|
61360
|
-
|
|
61361
|
-
|
|
61362
|
-
|
|
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
|
-
|
|
43665
|
-
const
|
|
43666
|
-
|
|
43667
|
-
const
|
|
43668
|
-
|
|
43669
|
-
|
|
43670
|
-
|
|
43671
|
-
|
|
43672
|
-
|
|
43673
|
-
|
|
43674
|
-
|
|
43675
|
-
|
|
43676
|
-
|
|
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
|
-
|
|
43686
|
-
|
|
43687
|
-
|
|
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
|
-
|
|
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
|
|
61261
|
-
setAmount(
|
|
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
|
-
|
|
61341
|
-
|
|
61342
|
-
|
|
61343
|
-
|
|
61344
|
-
|
|
61345
|
-
|
|
61346
|
-
|
|
61347
|
-
|
|
61348
|
-
|
|
61349
|
-
|
|
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.
|
|
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.
|
|
31
|
-
"@unifold/core": "0.1.
|
|
32
|
-
"@unifold/react
|
|
33
|
-
"@unifold/
|
|
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",
|