@unifold/ui-react 0.1.43 → 0.1.45
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.d.mts +42 -46
- package/dist/index.d.ts +42 -46
- package/dist/index.js +138 -119
- package/dist/index.mjs +132 -111
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -567,46 +567,6 @@ declare function useAddressBalance(params: {
|
|
|
567
567
|
enabled?: boolean;
|
|
568
568
|
}): _tanstack_react_query.UseQueryResult<AddressBalanceResult | null, Error>;
|
|
569
569
|
|
|
570
|
-
type DetectedWallet = {
|
|
571
|
-
name: string;
|
|
572
|
-
address: string;
|
|
573
|
-
} & ({
|
|
574
|
-
chainFamily: "evm";
|
|
575
|
-
provider: EvmWalletProvider;
|
|
576
|
-
} | {
|
|
577
|
-
chainFamily: "solana";
|
|
578
|
-
provider: SolanaWalletProvider;
|
|
579
|
-
});
|
|
580
|
-
declare function sendEvmWithdraw(params: {
|
|
581
|
-
provider: EvmWalletProvider;
|
|
582
|
-
fromAddress: string;
|
|
583
|
-
depositWalletAddress: string;
|
|
584
|
-
sourceTokenAddress: string;
|
|
585
|
-
sourceChainId: string;
|
|
586
|
-
amountBaseUnit: string;
|
|
587
|
-
}): Promise<string>;
|
|
588
|
-
declare function sendSolanaWithdraw(params: {
|
|
589
|
-
provider: SolanaWalletProvider;
|
|
590
|
-
fromAddress: string;
|
|
591
|
-
depositWalletAddress: string;
|
|
592
|
-
sourceTokenAddress: string;
|
|
593
|
-
amountBaseUnit: string;
|
|
594
|
-
publishableKey: string;
|
|
595
|
-
}): Promise<string>;
|
|
596
|
-
declare const HYPERCORE_CHAIN_ID = "1337";
|
|
597
|
-
declare function isHypercoreChain(chainId: string): boolean;
|
|
598
|
-
declare function sendHypercoreWithdraw(params: {
|
|
599
|
-
provider: EvmWalletProvider;
|
|
600
|
-
fromAddress: string;
|
|
601
|
-
depositWalletAddress: string;
|
|
602
|
-
sourceTokenAddress: string;
|
|
603
|
-
amount: string;
|
|
604
|
-
tokenSymbol: string;
|
|
605
|
-
publishableKey: string;
|
|
606
|
-
}): Promise<void>;
|
|
607
|
-
|
|
608
|
-
declare function detectBrowserWallet(chainType: string, senderAddress?: string): Promise<DetectedWallet | null>;
|
|
609
|
-
|
|
610
570
|
interface WithdrawFormProps {
|
|
611
571
|
publishableKey: string;
|
|
612
572
|
externalUserId: string;
|
|
@@ -621,13 +581,9 @@ interface WithdrawFormProps {
|
|
|
621
581
|
estimatedProcessingTime: number | null;
|
|
622
582
|
maxSlippagePercent: number | null;
|
|
623
583
|
priceImpactPercent: number | null;
|
|
624
|
-
|
|
625
|
-
detectedWallet: DetectedWallet | null;
|
|
584
|
+
senderAddress: string;
|
|
626
585
|
sourceChainId: string;
|
|
627
586
|
sourceTokenAddress: string;
|
|
628
|
-
isWalletMatch: boolean;
|
|
629
|
-
connectedWalletName: string | null;
|
|
630
|
-
canWithdraw: boolean;
|
|
631
587
|
onWithdraw?: (txInfo: WithdrawTransactionInfo) => void | Promise<void>;
|
|
632
588
|
onWithdrawError?: (error: {
|
|
633
589
|
message: string;
|
|
@@ -649,7 +605,7 @@ interface WithdrawFormProps {
|
|
|
649
605
|
/** Optional element rendered on the left side of the footer row (e.g. tracker link) */
|
|
650
606
|
footerLeft?: React.ReactNode;
|
|
651
607
|
}
|
|
652
|
-
declare function WithdrawForm({ publishableKey, externalUserId, sourceChainType, selectedToken, selectedChain, sourceTokenSymbol, recipientAddressProp, balanceData, isLoadingBalance, minimumWithdrawAmountUsd, estimatedProcessingTime, maxSlippagePercent, priceImpactPercent,
|
|
608
|
+
declare function WithdrawForm({ publishableKey, externalUserId, sourceChainType, selectedToken, selectedChain, sourceTokenSymbol, recipientAddressProp, balanceData, isLoadingBalance, minimumWithdrawAmountUsd, estimatedProcessingTime, maxSlippagePercent, priceImpactPercent, senderAddress, sourceChainId, sourceTokenAddress, onWithdraw, onWithdrawError, onDepositWalletCreation, onWithdrawSubmitted, footerLeft, }: WithdrawFormProps): react_jsx_runtime.JSX.Element;
|
|
653
609
|
|
|
654
610
|
interface WithdrawExecutionItemProps {
|
|
655
611
|
execution: AutoSwapResponse;
|
|
@@ -665,6 +621,46 @@ interface WithdrawConfirmingViewProps {
|
|
|
665
621
|
}
|
|
666
622
|
declare function WithdrawConfirmingView({ txInfo, executions, onClose, onViewTracker, }: WithdrawConfirmingViewProps): react_jsx_runtime.JSX.Element;
|
|
667
623
|
|
|
624
|
+
type DetectedWallet = {
|
|
625
|
+
name: string;
|
|
626
|
+
address: string;
|
|
627
|
+
} & ({
|
|
628
|
+
chainFamily: "evm";
|
|
629
|
+
provider: EvmWalletProvider;
|
|
630
|
+
} | {
|
|
631
|
+
chainFamily: "solana";
|
|
632
|
+
provider: SolanaWalletProvider;
|
|
633
|
+
});
|
|
634
|
+
declare function sendEvmWithdraw(params: {
|
|
635
|
+
provider: EvmWalletProvider;
|
|
636
|
+
fromAddress: string;
|
|
637
|
+
depositWalletAddress: string;
|
|
638
|
+
sourceTokenAddress: string;
|
|
639
|
+
sourceChainId: string;
|
|
640
|
+
amountBaseUnit: string;
|
|
641
|
+
}): Promise<string>;
|
|
642
|
+
declare function sendSolanaWithdraw(params: {
|
|
643
|
+
provider: SolanaWalletProvider;
|
|
644
|
+
fromAddress: string;
|
|
645
|
+
depositWalletAddress: string;
|
|
646
|
+
sourceTokenAddress: string;
|
|
647
|
+
amountBaseUnit: string;
|
|
648
|
+
publishableKey: string;
|
|
649
|
+
}): Promise<string>;
|
|
650
|
+
declare const HYPERCORE_CHAIN_ID = "1337";
|
|
651
|
+
declare function isHypercoreChain(chainId: string): boolean;
|
|
652
|
+
declare function sendHypercoreWithdraw(params: {
|
|
653
|
+
provider: EvmWalletProvider;
|
|
654
|
+
fromAddress: string;
|
|
655
|
+
depositWalletAddress: string;
|
|
656
|
+
sourceTokenAddress: string;
|
|
657
|
+
amount: string;
|
|
658
|
+
tokenSymbol: string;
|
|
659
|
+
publishableKey: string;
|
|
660
|
+
}): Promise<void>;
|
|
661
|
+
|
|
662
|
+
declare function detectBrowserWallet(chainType: string, senderAddress?: string): Promise<DetectedWallet | null>;
|
|
663
|
+
|
|
668
664
|
interface CurrencyListItemProps {
|
|
669
665
|
currency: FiatCurrency;
|
|
670
666
|
isSelected: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -567,46 +567,6 @@ declare function useAddressBalance(params: {
|
|
|
567
567
|
enabled?: boolean;
|
|
568
568
|
}): _tanstack_react_query.UseQueryResult<AddressBalanceResult | null, Error>;
|
|
569
569
|
|
|
570
|
-
type DetectedWallet = {
|
|
571
|
-
name: string;
|
|
572
|
-
address: string;
|
|
573
|
-
} & ({
|
|
574
|
-
chainFamily: "evm";
|
|
575
|
-
provider: EvmWalletProvider;
|
|
576
|
-
} | {
|
|
577
|
-
chainFamily: "solana";
|
|
578
|
-
provider: SolanaWalletProvider;
|
|
579
|
-
});
|
|
580
|
-
declare function sendEvmWithdraw(params: {
|
|
581
|
-
provider: EvmWalletProvider;
|
|
582
|
-
fromAddress: string;
|
|
583
|
-
depositWalletAddress: string;
|
|
584
|
-
sourceTokenAddress: string;
|
|
585
|
-
sourceChainId: string;
|
|
586
|
-
amountBaseUnit: string;
|
|
587
|
-
}): Promise<string>;
|
|
588
|
-
declare function sendSolanaWithdraw(params: {
|
|
589
|
-
provider: SolanaWalletProvider;
|
|
590
|
-
fromAddress: string;
|
|
591
|
-
depositWalletAddress: string;
|
|
592
|
-
sourceTokenAddress: string;
|
|
593
|
-
amountBaseUnit: string;
|
|
594
|
-
publishableKey: string;
|
|
595
|
-
}): Promise<string>;
|
|
596
|
-
declare const HYPERCORE_CHAIN_ID = "1337";
|
|
597
|
-
declare function isHypercoreChain(chainId: string): boolean;
|
|
598
|
-
declare function sendHypercoreWithdraw(params: {
|
|
599
|
-
provider: EvmWalletProvider;
|
|
600
|
-
fromAddress: string;
|
|
601
|
-
depositWalletAddress: string;
|
|
602
|
-
sourceTokenAddress: string;
|
|
603
|
-
amount: string;
|
|
604
|
-
tokenSymbol: string;
|
|
605
|
-
publishableKey: string;
|
|
606
|
-
}): Promise<void>;
|
|
607
|
-
|
|
608
|
-
declare function detectBrowserWallet(chainType: string, senderAddress?: string): Promise<DetectedWallet | null>;
|
|
609
|
-
|
|
610
570
|
interface WithdrawFormProps {
|
|
611
571
|
publishableKey: string;
|
|
612
572
|
externalUserId: string;
|
|
@@ -621,13 +581,9 @@ interface WithdrawFormProps {
|
|
|
621
581
|
estimatedProcessingTime: number | null;
|
|
622
582
|
maxSlippagePercent: number | null;
|
|
623
583
|
priceImpactPercent: number | null;
|
|
624
|
-
|
|
625
|
-
detectedWallet: DetectedWallet | null;
|
|
584
|
+
senderAddress: string;
|
|
626
585
|
sourceChainId: string;
|
|
627
586
|
sourceTokenAddress: string;
|
|
628
|
-
isWalletMatch: boolean;
|
|
629
|
-
connectedWalletName: string | null;
|
|
630
|
-
canWithdraw: boolean;
|
|
631
587
|
onWithdraw?: (txInfo: WithdrawTransactionInfo) => void | Promise<void>;
|
|
632
588
|
onWithdrawError?: (error: {
|
|
633
589
|
message: string;
|
|
@@ -649,7 +605,7 @@ interface WithdrawFormProps {
|
|
|
649
605
|
/** Optional element rendered on the left side of the footer row (e.g. tracker link) */
|
|
650
606
|
footerLeft?: React.ReactNode;
|
|
651
607
|
}
|
|
652
|
-
declare function WithdrawForm({ publishableKey, externalUserId, sourceChainType, selectedToken, selectedChain, sourceTokenSymbol, recipientAddressProp, balanceData, isLoadingBalance, minimumWithdrawAmountUsd, estimatedProcessingTime, maxSlippagePercent, priceImpactPercent,
|
|
608
|
+
declare function WithdrawForm({ publishableKey, externalUserId, sourceChainType, selectedToken, selectedChain, sourceTokenSymbol, recipientAddressProp, balanceData, isLoadingBalance, minimumWithdrawAmountUsd, estimatedProcessingTime, maxSlippagePercent, priceImpactPercent, senderAddress, sourceChainId, sourceTokenAddress, onWithdraw, onWithdrawError, onDepositWalletCreation, onWithdrawSubmitted, footerLeft, }: WithdrawFormProps): react_jsx_runtime.JSX.Element;
|
|
653
609
|
|
|
654
610
|
interface WithdrawExecutionItemProps {
|
|
655
611
|
execution: AutoSwapResponse;
|
|
@@ -665,6 +621,46 @@ interface WithdrawConfirmingViewProps {
|
|
|
665
621
|
}
|
|
666
622
|
declare function WithdrawConfirmingView({ txInfo, executions, onClose, onViewTracker, }: WithdrawConfirmingViewProps): react_jsx_runtime.JSX.Element;
|
|
667
623
|
|
|
624
|
+
type DetectedWallet = {
|
|
625
|
+
name: string;
|
|
626
|
+
address: string;
|
|
627
|
+
} & ({
|
|
628
|
+
chainFamily: "evm";
|
|
629
|
+
provider: EvmWalletProvider;
|
|
630
|
+
} | {
|
|
631
|
+
chainFamily: "solana";
|
|
632
|
+
provider: SolanaWalletProvider;
|
|
633
|
+
});
|
|
634
|
+
declare function sendEvmWithdraw(params: {
|
|
635
|
+
provider: EvmWalletProvider;
|
|
636
|
+
fromAddress: string;
|
|
637
|
+
depositWalletAddress: string;
|
|
638
|
+
sourceTokenAddress: string;
|
|
639
|
+
sourceChainId: string;
|
|
640
|
+
amountBaseUnit: string;
|
|
641
|
+
}): Promise<string>;
|
|
642
|
+
declare function sendSolanaWithdraw(params: {
|
|
643
|
+
provider: SolanaWalletProvider;
|
|
644
|
+
fromAddress: string;
|
|
645
|
+
depositWalletAddress: string;
|
|
646
|
+
sourceTokenAddress: string;
|
|
647
|
+
amountBaseUnit: string;
|
|
648
|
+
publishableKey: string;
|
|
649
|
+
}): Promise<string>;
|
|
650
|
+
declare const HYPERCORE_CHAIN_ID = "1337";
|
|
651
|
+
declare function isHypercoreChain(chainId: string): boolean;
|
|
652
|
+
declare function sendHypercoreWithdraw(params: {
|
|
653
|
+
provider: EvmWalletProvider;
|
|
654
|
+
fromAddress: string;
|
|
655
|
+
depositWalletAddress: string;
|
|
656
|
+
sourceTokenAddress: string;
|
|
657
|
+
amount: string;
|
|
658
|
+
tokenSymbol: string;
|
|
659
|
+
publishableKey: string;
|
|
660
|
+
}): Promise<void>;
|
|
661
|
+
|
|
662
|
+
declare function detectBrowserWallet(chainType: string, senderAddress?: string): Promise<DetectedWallet | null>;
|
|
663
|
+
|
|
668
664
|
interface CurrencyListItemProps {
|
|
669
665
|
currency: FiatCurrency;
|
|
670
666
|
isSelected: boolean;
|
package/dist/index.js
CHANGED
|
@@ -13589,6 +13589,7 @@ function WithdrawDoubleInput({
|
|
|
13589
13589
|
// src/components/withdrawals/WithdrawForm.tsx
|
|
13590
13590
|
var import_react21 = require("react");
|
|
13591
13591
|
var import_lucide_react25 = require("lucide-react");
|
|
13592
|
+
var import_core33 = require("@unifold/core");
|
|
13592
13593
|
|
|
13593
13594
|
// src/hooks/use-verify-recipient-address.ts
|
|
13594
13595
|
var import_react_query15 = require("@tanstack/react-query");
|
|
@@ -13792,6 +13793,7 @@ async function sendHypercoreWithdraw(params) {
|
|
|
13792
13793
|
async function detectBrowserWallet(chainType, senderAddress) {
|
|
13793
13794
|
const win = typeof window !== "undefined" ? window : null;
|
|
13794
13795
|
if (!win || !senderAddress) return null;
|
|
13796
|
+
if (getUserDisconnectedWallet()) return null;
|
|
13795
13797
|
const anyWin = win;
|
|
13796
13798
|
if (chainType === "solana") {
|
|
13797
13799
|
const solProviders = [];
|
|
@@ -13825,28 +13827,44 @@ async function detectBrowserWallet(chainType, senderAddress) {
|
|
|
13825
13827
|
evmProviders.push({ provider: p, name });
|
|
13826
13828
|
}
|
|
13827
13829
|
};
|
|
13828
|
-
|
|
13829
|
-
|
|
13830
|
-
add(anyWin.trustwallet?.ethereum, "Trust Wallet");
|
|
13831
|
-
add(anyWin.okxwallet, "OKX Wallet");
|
|
13832
|
-
if (anyWin.__eip6963Providers) {
|
|
13833
|
-
for (const detail of anyWin.__eip6963Providers) {
|
|
13834
|
-
const rdns = detail.info?.rdns || "";
|
|
13835
|
-
let name = detail.info?.name || "Wallet";
|
|
13836
|
-
if (rdns.includes("metamask")) name = "MetaMask";
|
|
13837
|
-
else if (rdns.includes("rabby")) name = "Rabby";
|
|
13838
|
-
else if (rdns.includes("rainbow")) name = "Rainbow";
|
|
13839
|
-
add(detail.provider, name);
|
|
13840
|
-
}
|
|
13830
|
+
if (!anyWin.__eip6963Providers) {
|
|
13831
|
+
anyWin.__eip6963Providers = [];
|
|
13841
13832
|
}
|
|
13842
|
-
|
|
13843
|
-
const
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
|
|
13847
|
-
|
|
13848
|
-
|
|
13849
|
-
|
|
13833
|
+
const handleAnnouncement = (event) => {
|
|
13834
|
+
const { detail } = event;
|
|
13835
|
+
if (!detail?.info || !detail?.provider) return;
|
|
13836
|
+
const exists = anyWin.__eip6963Providers.some((p) => p.info.uuid === detail.info.uuid);
|
|
13837
|
+
if (!exists) anyWin.__eip6963Providers.push(detail);
|
|
13838
|
+
};
|
|
13839
|
+
win.addEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
13840
|
+
win.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
13841
|
+
win.removeEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
13842
|
+
for (const detail of anyWin.__eip6963Providers) {
|
|
13843
|
+
const rdns = detail.info?.rdns || "";
|
|
13844
|
+
let name = detail.info?.name || "Wallet";
|
|
13845
|
+
if (rdns.includes("metamask")) name = "MetaMask";
|
|
13846
|
+
else if (rdns.includes("phantom")) name = "Phantom";
|
|
13847
|
+
else if (rdns.includes("coinbase")) name = "Coinbase";
|
|
13848
|
+
else if (rdns.includes("rabby")) name = "Rabby";
|
|
13849
|
+
else if (rdns.includes("rainbow")) name = "Rainbow";
|
|
13850
|
+
else if (rdns.includes("okx")) name = "OKX Wallet";
|
|
13851
|
+
else if (rdns.includes("trust")) name = "Trust Wallet";
|
|
13852
|
+
add(detail.provider, name);
|
|
13853
|
+
}
|
|
13854
|
+
if (evmProviders.length === 0) {
|
|
13855
|
+
add(anyWin.phantom?.ethereum, "Phantom");
|
|
13856
|
+
add(anyWin.coinbaseWalletExtension, "Coinbase");
|
|
13857
|
+
add(anyWin.trustwallet?.ethereum, "Trust Wallet");
|
|
13858
|
+
add(anyWin.okxwallet, "OKX Wallet");
|
|
13859
|
+
if (evmProviders.length === 0 && win.ethereum) {
|
|
13860
|
+
const eth = win.ethereum;
|
|
13861
|
+
let name = "Wallet";
|
|
13862
|
+
if (eth.isMetaMask && !eth.isPhantom && !eth.isRabby) name = "MetaMask";
|
|
13863
|
+
else if (eth.isRabby) name = "Rabby";
|
|
13864
|
+
else if (eth.isRainbow) name = "Rainbow";
|
|
13865
|
+
else if (eth.isCoinbaseWallet) name = "Coinbase";
|
|
13866
|
+
add(eth, name);
|
|
13867
|
+
}
|
|
13850
13868
|
}
|
|
13851
13869
|
for (const { provider, name } of evmProviders) {
|
|
13852
13870
|
try {
|
|
@@ -13902,12 +13920,9 @@ function WithdrawForm({
|
|
|
13902
13920
|
estimatedProcessingTime,
|
|
13903
13921
|
maxSlippagePercent,
|
|
13904
13922
|
priceImpactPercent,
|
|
13905
|
-
|
|
13923
|
+
senderAddress,
|
|
13906
13924
|
sourceChainId,
|
|
13907
13925
|
sourceTokenAddress,
|
|
13908
|
-
isWalletMatch,
|
|
13909
|
-
connectedWalletName,
|
|
13910
|
-
canWithdraw,
|
|
13911
13926
|
onWithdraw,
|
|
13912
13927
|
onWithdrawError,
|
|
13913
13928
|
onDepositWalletCreation,
|
|
@@ -14042,12 +14057,43 @@ function WithdrawForm({
|
|
|
14042
14057
|
destinationTokenAddress: selectedChain.token_address,
|
|
14043
14058
|
recipientAddress: trimmedAddress
|
|
14044
14059
|
});
|
|
14045
|
-
|
|
14060
|
+
let amountBaseUnit = computeBaseUnit(
|
|
14046
14061
|
balanceData.balanceBaseUnit,
|
|
14047
14062
|
parseFloat(amount),
|
|
14048
14063
|
inputUnit === "crypto" ? balanceCrypto : balanceUsdNum
|
|
14049
14064
|
);
|
|
14050
|
-
|
|
14065
|
+
let humanAmount = toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
|
|
14066
|
+
if (isHypercoreChain(sourceChainId)) {
|
|
14067
|
+
try {
|
|
14068
|
+
const check = await (0, import_core33.checkHypercoreActivation)(
|
|
14069
|
+
{
|
|
14070
|
+
source_address: senderAddress,
|
|
14071
|
+
recipient_address: depositWallet.address
|
|
14072
|
+
},
|
|
14073
|
+
publishableKey
|
|
14074
|
+
);
|
|
14075
|
+
if (!check.user_exists) {
|
|
14076
|
+
const fee = check.activation_fee;
|
|
14077
|
+
const maxSendable = balanceCrypto - fee;
|
|
14078
|
+
if (maxSendable <= 0) {
|
|
14079
|
+
throw new Error(
|
|
14080
|
+
`Insufficient balance. A ${fee} USDC activation fee is required for the first transfer to this address.`
|
|
14081
|
+
);
|
|
14082
|
+
}
|
|
14083
|
+
const requestedAmount = parseFloat(humanAmount);
|
|
14084
|
+
if (requestedAmount > maxSendable) {
|
|
14085
|
+
humanAmount = toSafeDecimalString(maxSendable, sourceDecimals);
|
|
14086
|
+
amountBaseUnit = computeBaseUnit(
|
|
14087
|
+
balanceData.balanceBaseUnit,
|
|
14088
|
+
maxSendable,
|
|
14089
|
+
balanceCrypto
|
|
14090
|
+
);
|
|
14091
|
+
}
|
|
14092
|
+
}
|
|
14093
|
+
} catch (e) {
|
|
14094
|
+
if (e instanceof Error && e.message.includes("activation fee")) throw e;
|
|
14095
|
+
}
|
|
14096
|
+
}
|
|
14051
14097
|
const txInfo = {
|
|
14052
14098
|
sourceChainType,
|
|
14053
14099
|
sourceChainId,
|
|
@@ -14062,43 +14108,67 @@ function WithdrawForm({
|
|
|
14062
14108
|
withdrawIntentAddress: depositWallet.address,
|
|
14063
14109
|
recipientAddress: trimmedAddress
|
|
14064
14110
|
};
|
|
14065
|
-
|
|
14066
|
-
|
|
14067
|
-
|
|
14068
|
-
|
|
14069
|
-
|
|
14070
|
-
|
|
14071
|
-
|
|
14111
|
+
const wallet = await detectBrowserWallet(sourceChainType, senderAddress);
|
|
14112
|
+
console.log("browser wallet", wallet);
|
|
14113
|
+
if (wallet) {
|
|
14114
|
+
try {
|
|
14115
|
+
if (wallet.chainFamily === "evm" && isHypercoreChain(sourceChainId)) {
|
|
14116
|
+
await sendHypercoreWithdraw({
|
|
14117
|
+
provider: wallet.provider,
|
|
14118
|
+
fromAddress: wallet.address,
|
|
14119
|
+
depositWalletAddress: depositWallet.address,
|
|
14120
|
+
sourceTokenAddress,
|
|
14121
|
+
amount: humanAmount,
|
|
14122
|
+
tokenSymbol,
|
|
14123
|
+
publishableKey
|
|
14124
|
+
});
|
|
14125
|
+
} else if (wallet.chainFamily === "evm") {
|
|
14126
|
+
await sendEvmWithdraw({
|
|
14127
|
+
provider: wallet.provider,
|
|
14128
|
+
fromAddress: wallet.address,
|
|
14129
|
+
depositWalletAddress: depositWallet.address,
|
|
14130
|
+
sourceTokenAddress,
|
|
14131
|
+
sourceChainId,
|
|
14132
|
+
amountBaseUnit
|
|
14133
|
+
});
|
|
14134
|
+
} else if (wallet.chainFamily === "solana") {
|
|
14135
|
+
await sendSolanaWithdraw({
|
|
14136
|
+
provider: wallet.provider,
|
|
14137
|
+
fromAddress: wallet.address,
|
|
14138
|
+
depositWalletAddress: depositWallet.address,
|
|
14139
|
+
sourceTokenAddress,
|
|
14140
|
+
amountBaseUnit,
|
|
14141
|
+
publishableKey
|
|
14142
|
+
});
|
|
14143
|
+
}
|
|
14144
|
+
} catch (walletErr) {
|
|
14145
|
+
console.error("[Unifold] Browser wallet send failed:", walletErr, {
|
|
14146
|
+
wallet: `${wallet.name} (${wallet.chainFamily})`,
|
|
14147
|
+
sourceChainId,
|
|
14072
14148
|
amount: humanAmount,
|
|
14073
|
-
|
|
14074
|
-
|
|
14149
|
+
amountBaseUnit,
|
|
14150
|
+
depositWallet: depositWallet.address
|
|
14075
14151
|
});
|
|
14076
|
-
|
|
14077
|
-
|
|
14078
|
-
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
|
|
14152
|
+
throw walletErr;
|
|
14153
|
+
}
|
|
14154
|
+
} else if (onWithdraw) {
|
|
14155
|
+
try {
|
|
14156
|
+
await onWithdraw(txInfo);
|
|
14157
|
+
} catch (callbackErr) {
|
|
14158
|
+
console.error("[Unifold] onWithdraw callback failed:", callbackErr, {
|
|
14082
14159
|
sourceChainId,
|
|
14083
|
-
|
|
14084
|
-
});
|
|
14085
|
-
} else if (detectedWallet.chainFamily === "solana") {
|
|
14086
|
-
await sendSolanaWithdraw({
|
|
14087
|
-
provider: detectedWallet.provider,
|
|
14088
|
-
fromAddress: detectedWallet.address,
|
|
14089
|
-
depositWalletAddress: depositWallet.address,
|
|
14090
|
-
sourceTokenAddress,
|
|
14160
|
+
amount: humanAmount,
|
|
14091
14161
|
amountBaseUnit,
|
|
14092
|
-
|
|
14162
|
+
depositWallet: depositWallet.address
|
|
14093
14163
|
});
|
|
14164
|
+
throw callbackErr;
|
|
14094
14165
|
}
|
|
14095
|
-
} else if (onWithdraw) {
|
|
14096
|
-
await onWithdraw(txInfo);
|
|
14097
14166
|
} else {
|
|
14098
14167
|
throw new Error("No withdrawal method available. Please connect a wallet.");
|
|
14099
14168
|
}
|
|
14100
14169
|
onWithdrawSubmitted?.(txInfo);
|
|
14101
14170
|
} catch (err) {
|
|
14171
|
+
console.error("[Unifold] Withdrawal failed:", err);
|
|
14102
14172
|
const raw = err instanceof Error ? err.message : "Withdrawal failed. Please try again.";
|
|
14103
14173
|
setSubmitError(raw.length > 120 ? "Withdrawal failed. Please try again." : raw);
|
|
14104
14174
|
onWithdrawError?.({
|
|
@@ -14109,7 +14179,7 @@ function WithdrawForm({
|
|
|
14109
14179
|
} finally {
|
|
14110
14180
|
setIsSubmitting(false);
|
|
14111
14181
|
}
|
|
14112
|
-
}, [selectedToken, selectedChain, isFormValid, cryptoAmountFromInput, sourceDecimals, trimmedAddress, publishableKey, onWithdraw,
|
|
14182
|
+
}, [selectedToken, selectedChain, isFormValid, cryptoAmountFromInput, sourceDecimals, trimmedAddress, publishableKey, onWithdraw, sourceChainType, senderAddress, sourceTokenAddress, sourceChainId, onWithdrawError, onDepositWalletCreation, onWithdrawSubmitted, amount, inputUnit, balanceCrypto, balanceUsdNum, balanceData]);
|
|
14113
14183
|
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
|
|
14114
14184
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { children: [
|
|
14115
14185
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
@@ -14320,23 +14390,12 @@ function WithdrawForm({
|
|
|
14320
14390
|
] })
|
|
14321
14391
|
] })
|
|
14322
14392
|
] }),
|
|
14323
|
-
|
|
14324
|
-
"div",
|
|
14325
|
-
{
|
|
14326
|
-
className: "uf-flex uf-items-start uf-gap-2.5 uf-p-3 uf-rounded-xl",
|
|
14327
|
-
style: { backgroundColor: colors2.card, border: `1px solid ${colors2.border}` },
|
|
14328
|
-
children: [
|
|
14329
|
-
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react25.Wallet, { className: "uf-w-4 uf-h-4 uf-flex-shrink-0 uf-mt-0.5", style: { color: colors2.warning } }),
|
|
14330
|
-
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "No connected wallet detected. Please connect a wallet that matches your account to withdraw." })
|
|
14331
|
-
]
|
|
14332
|
-
}
|
|
14333
|
-
),
|
|
14334
|
-
isWalletMatch && connectedWalletName ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
14393
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
14335
14394
|
"button",
|
|
14336
14395
|
{
|
|
14337
14396
|
type: "button",
|
|
14338
14397
|
onClick: handleWithdraw,
|
|
14339
|
-
disabled: !isFormValid ||
|
|
14398
|
+
disabled: !isFormValid || isSubmitting || !selectedToken || !selectedChain,
|
|
14340
14399
|
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed uf-flex uf-items-center uf-justify-center uf-gap-2",
|
|
14341
14400
|
style: {
|
|
14342
14401
|
backgroundColor: colors2.primary,
|
|
@@ -14350,29 +14409,9 @@ function WithdrawForm({
|
|
|
14350
14409
|
"Processing..."
|
|
14351
14410
|
] }) : isOverBalance ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_jsx_runtime54.Fragment, { children: "Insufficient balance" }) : isBelowMinimum ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_jsx_runtime54.Fragment, { children: "Minimum amount not met" }) : submitError ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_jsx_runtime54.Fragment, { children: "Withdrawal failed. Try again" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
|
|
14352
14411
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react25.Wallet, { className: "uf-w-4 uf-h-4" }),
|
|
14353
|
-
|
|
14354
|
-
connectedWalletName
|
|
14412
|
+
t8.withdraw
|
|
14355
14413
|
] })
|
|
14356
14414
|
}
|
|
14357
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
|
|
14358
|
-
"button",
|
|
14359
|
-
{
|
|
14360
|
-
type: "button",
|
|
14361
|
-
onClick: handleWithdraw,
|
|
14362
|
-
disabled: !isFormValid || !canWithdraw || isSubmitting || !selectedToken || !selectedChain,
|
|
14363
|
-
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
|
|
14364
|
-
style: {
|
|
14365
|
-
backgroundColor: colors2.primary,
|
|
14366
|
-
color: colors2.primaryForeground,
|
|
14367
|
-
fontFamily: fonts.medium,
|
|
14368
|
-
borderRadius: components.button.borderRadius,
|
|
14369
|
-
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
14370
|
-
},
|
|
14371
|
-
children: isSubmitting ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2", children: [
|
|
14372
|
-
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(import_lucide_react25.Loader2, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
|
|
14373
|
-
"Processing..."
|
|
14374
|
-
] }) : isOverBalance ? "Insufficient balance" : isBelowMinimum ? "Minimum amount not met" : submitError ? "Withdrawal failed. Try again" : t8.withdraw
|
|
14375
|
-
}
|
|
14376
14415
|
),
|
|
14377
14416
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "uf-flex uf-items-center uf-justify-between uf-text-xs uf-pt-1", children: [
|
|
14378
14417
|
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { children: footerLeft }),
|
|
@@ -14390,14 +14429,14 @@ function WithdrawForm({
|
|
|
14390
14429
|
|
|
14391
14430
|
// src/components/withdrawals/WithdrawExecutionItem.tsx
|
|
14392
14431
|
var import_lucide_react26 = require("lucide-react");
|
|
14393
|
-
var
|
|
14432
|
+
var import_core34 = require("@unifold/core");
|
|
14394
14433
|
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
14395
14434
|
function WithdrawExecutionItem({
|
|
14396
14435
|
execution,
|
|
14397
14436
|
onClick
|
|
14398
14437
|
}) {
|
|
14399
14438
|
const { colors: colors2, fonts, components } = useTheme();
|
|
14400
|
-
const isPending = execution.status ===
|
|
14439
|
+
const isPending = execution.status === import_core34.ExecutionStatus.PENDING || execution.status === import_core34.ExecutionStatus.WAITING || execution.status === import_core34.ExecutionStatus.DELAYED;
|
|
14401
14440
|
const formatDateTime = (timestamp) => {
|
|
14402
14441
|
try {
|
|
14403
14442
|
const date = new Date(timestamp);
|
|
@@ -14444,7 +14483,7 @@ function WithdrawExecutionItem({
|
|
|
14444
14483
|
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
14445
14484
|
"img",
|
|
14446
14485
|
{
|
|
14447
|
-
src: execution.destination_token_metadata?.icon_url || (0,
|
|
14486
|
+
src: execution.destination_token_metadata?.icon_url || (0, import_core34.getIconUrl)("/icons/tokens/svg/usdc.svg"),
|
|
14448
14487
|
alt: "Token",
|
|
14449
14488
|
width: 36,
|
|
14450
14489
|
height: 36,
|
|
@@ -14703,7 +14742,7 @@ function WithdrawConfirmingView({
|
|
|
14703
14742
|
}
|
|
14704
14743
|
|
|
14705
14744
|
// src/components/withdrawals/WithdrawModal.tsx
|
|
14706
|
-
var
|
|
14745
|
+
var import_core35 = require("@unifold/core");
|
|
14707
14746
|
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
14708
14747
|
var t9 = i18n.withdrawModal;
|
|
14709
14748
|
var getChainKey5 = (chainId, chainType) => `${chainType}:${chainId}`;
|
|
@@ -14764,22 +14803,6 @@ function WithdrawModal({
|
|
|
14764
14803
|
});
|
|
14765
14804
|
const [selectedToken, setSelectedToken] = (0, import_react23.useState)(null);
|
|
14766
14805
|
const [selectedChain, setSelectedChain] = (0, import_react23.useState)(null);
|
|
14767
|
-
const [detectedWallet, setDetectedWallet] = (0, import_react23.useState)(null);
|
|
14768
|
-
const connectedWalletName = detectedWallet?.name ?? null;
|
|
14769
|
-
const isWalletMatch = !!detectedWallet;
|
|
14770
|
-
(0, import_react23.useEffect)(() => {
|
|
14771
|
-
if (!senderAddress || !open) {
|
|
14772
|
-
setDetectedWallet(null);
|
|
14773
|
-
return;
|
|
14774
|
-
}
|
|
14775
|
-
let cancelled = false;
|
|
14776
|
-
detectBrowserWallet(sourceChainType, senderAddress).then((wallet) => {
|
|
14777
|
-
if (!cancelled) setDetectedWallet(wallet);
|
|
14778
|
-
});
|
|
14779
|
-
return () => {
|
|
14780
|
-
cancelled = true;
|
|
14781
|
-
};
|
|
14782
|
-
}, [senderAddress, sourceChainType, open]);
|
|
14783
14806
|
const [view, setView] = (0, import_react23.useState)("form");
|
|
14784
14807
|
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = (0, import_react23.useState)();
|
|
14785
14808
|
const [selectedExecution, setSelectedExecution] = (0, import_react23.useState)(null);
|
|
@@ -14793,24 +14816,24 @@ function WithdrawModal({
|
|
|
14793
14816
|
onWithdrawError
|
|
14794
14817
|
});
|
|
14795
14818
|
const { data: allWithdrawalsData } = useExecutions(externalUserId, publishableKey, {
|
|
14796
|
-
actionType:
|
|
14819
|
+
actionType: import_core35.ActionType.Withdraw,
|
|
14797
14820
|
enabled: open,
|
|
14798
14821
|
refetchInterval: view === "tracker" || view === "detail" ? 5e3 : 15e3
|
|
14799
14822
|
});
|
|
14800
14823
|
const allWithdrawals = allWithdrawalsData?.data ?? [];
|
|
14801
14824
|
const handleDepositWalletCreation = (0, import_react23.useCallback)(async (params) => {
|
|
14802
|
-
const { data: wallets } = await (0,
|
|
14825
|
+
const { data: wallets } = await (0, import_core35.createDepositAddress)(
|
|
14803
14826
|
{
|
|
14804
14827
|
external_user_id: externalUserId,
|
|
14805
14828
|
destination_chain_type: params.destinationChainType,
|
|
14806
14829
|
destination_chain_id: params.destinationChainId,
|
|
14807
14830
|
destination_token_address: params.destinationTokenAddress,
|
|
14808
14831
|
recipient_address: params.recipientAddress,
|
|
14809
|
-
action_type:
|
|
14832
|
+
action_type: import_core35.ActionType.Withdraw
|
|
14810
14833
|
},
|
|
14811
14834
|
publishableKey
|
|
14812
14835
|
);
|
|
14813
|
-
const depositWallet = (0,
|
|
14836
|
+
const depositWallet = (0, import_core35.getWalletByChainType)(wallets, sourceChainType);
|
|
14814
14837
|
if (!depositWallet) {
|
|
14815
14838
|
throw new Error(`No deposit wallet available for ${sourceChainType}`);
|
|
14816
14839
|
}
|
|
@@ -14872,7 +14895,6 @@ function WithdrawModal({
|
|
|
14872
14895
|
if (chain) setSelectedChain(chain);
|
|
14873
14896
|
}, [selectedToken]);
|
|
14874
14897
|
const isSourceSupported = sourceValidation?.isSupported ?? null;
|
|
14875
|
-
const canWithdraw = !!onWithdraw || isWalletMatch;
|
|
14876
14898
|
const isAnyLoading = tokensLoading || isCheckingSourceToken;
|
|
14877
14899
|
const withdrawPoweredByFooter = /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "uf-pt-3", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(PoweredByUnifold, { color: colors2.foregroundMuted, className: "uf-flex uf-justify-center uf-shrink-0" }) });
|
|
14878
14900
|
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Dialog, { open: hideOverlay || open, onOpenChange: hideOverlay ? void 0 : handleClose, modal: !hideOverlay, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
@@ -14903,7 +14925,7 @@ function WithdrawModal({
|
|
|
14903
14925
|
/* ---------- Tracker view: execution list ---------- */
|
|
14904
14926
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
|
|
14905
14927
|
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(DepositHeader, { title: "Withdrawal History", showBack: true, showClose: !hideOverlay, onBack: () => setView("form"), onClose: handleClose }),
|
|
14906
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "uf-
|
|
14928
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "uf-flex uf-flex-col uf-gap-2", children: allWithdrawals.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-8", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uf-text-sm", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "No withdrawals to track yet" }) }) : allWithdrawals.map((ex) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
14907
14929
|
WithdrawExecutionItem,
|
|
14908
14930
|
{
|
|
14909
14931
|
execution: ex,
|
|
@@ -14913,7 +14935,7 @@ function WithdrawModal({
|
|
|
14913
14935
|
}
|
|
14914
14936
|
},
|
|
14915
14937
|
ex.id
|
|
14916
|
-
)) }),
|
|
14938
|
+
)) }) }),
|
|
14917
14939
|
withdrawPoweredByFooter
|
|
14918
14940
|
] })
|
|
14919
14941
|
) : (
|
|
@@ -14953,12 +14975,9 @@ function WithdrawModal({
|
|
|
14953
14975
|
estimatedProcessingTime: sourceValidation?.estimatedProcessingTime ?? null,
|
|
14954
14976
|
maxSlippagePercent: sourceValidation?.maxSlippagePercent ?? null,
|
|
14955
14977
|
priceImpactPercent: sourceValidation?.priceImpactPercent ?? null,
|
|
14956
|
-
|
|
14978
|
+
senderAddress,
|
|
14957
14979
|
sourceChainId,
|
|
14958
14980
|
sourceTokenAddress,
|
|
14959
|
-
isWalletMatch,
|
|
14960
|
-
connectedWalletName,
|
|
14961
|
-
canWithdraw,
|
|
14962
14981
|
onWithdraw,
|
|
14963
14982
|
onWithdrawError,
|
|
14964
14983
|
onDepositWalletCreation: handleDepositWalletCreation,
|
package/dist/index.mjs
CHANGED
|
@@ -13592,6 +13592,9 @@ import {
|
|
|
13592
13592
|
ShieldCheck as ShieldCheck3,
|
|
13593
13593
|
Wallet as Wallet3
|
|
13594
13594
|
} from "lucide-react";
|
|
13595
|
+
import {
|
|
13596
|
+
checkHypercoreActivation
|
|
13597
|
+
} from "@unifold/core";
|
|
13595
13598
|
|
|
13596
13599
|
// src/hooks/use-verify-recipient-address.ts
|
|
13597
13600
|
import { useQuery as useQuery15 } from "@tanstack/react-query";
|
|
@@ -13800,6 +13803,7 @@ async function sendHypercoreWithdraw(params) {
|
|
|
13800
13803
|
async function detectBrowserWallet(chainType, senderAddress) {
|
|
13801
13804
|
const win = typeof window !== "undefined" ? window : null;
|
|
13802
13805
|
if (!win || !senderAddress) return null;
|
|
13806
|
+
if (getUserDisconnectedWallet()) return null;
|
|
13803
13807
|
const anyWin = win;
|
|
13804
13808
|
if (chainType === "solana") {
|
|
13805
13809
|
const solProviders = [];
|
|
@@ -13833,28 +13837,44 @@ async function detectBrowserWallet(chainType, senderAddress) {
|
|
|
13833
13837
|
evmProviders.push({ provider: p, name });
|
|
13834
13838
|
}
|
|
13835
13839
|
};
|
|
13836
|
-
|
|
13837
|
-
|
|
13838
|
-
add(anyWin.trustwallet?.ethereum, "Trust Wallet");
|
|
13839
|
-
add(anyWin.okxwallet, "OKX Wallet");
|
|
13840
|
-
if (anyWin.__eip6963Providers) {
|
|
13841
|
-
for (const detail of anyWin.__eip6963Providers) {
|
|
13842
|
-
const rdns = detail.info?.rdns || "";
|
|
13843
|
-
let name = detail.info?.name || "Wallet";
|
|
13844
|
-
if (rdns.includes("metamask")) name = "MetaMask";
|
|
13845
|
-
else if (rdns.includes("rabby")) name = "Rabby";
|
|
13846
|
-
else if (rdns.includes("rainbow")) name = "Rainbow";
|
|
13847
|
-
add(detail.provider, name);
|
|
13848
|
-
}
|
|
13840
|
+
if (!anyWin.__eip6963Providers) {
|
|
13841
|
+
anyWin.__eip6963Providers = [];
|
|
13849
13842
|
}
|
|
13850
|
-
|
|
13851
|
-
const
|
|
13852
|
-
|
|
13853
|
-
|
|
13854
|
-
|
|
13855
|
-
|
|
13856
|
-
|
|
13857
|
-
|
|
13843
|
+
const handleAnnouncement = (event) => {
|
|
13844
|
+
const { detail } = event;
|
|
13845
|
+
if (!detail?.info || !detail?.provider) return;
|
|
13846
|
+
const exists = anyWin.__eip6963Providers.some((p) => p.info.uuid === detail.info.uuid);
|
|
13847
|
+
if (!exists) anyWin.__eip6963Providers.push(detail);
|
|
13848
|
+
};
|
|
13849
|
+
win.addEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
13850
|
+
win.dispatchEvent(new Event("eip6963:requestProvider"));
|
|
13851
|
+
win.removeEventListener("eip6963:announceProvider", handleAnnouncement);
|
|
13852
|
+
for (const detail of anyWin.__eip6963Providers) {
|
|
13853
|
+
const rdns = detail.info?.rdns || "";
|
|
13854
|
+
let name = detail.info?.name || "Wallet";
|
|
13855
|
+
if (rdns.includes("metamask")) name = "MetaMask";
|
|
13856
|
+
else if (rdns.includes("phantom")) name = "Phantom";
|
|
13857
|
+
else if (rdns.includes("coinbase")) name = "Coinbase";
|
|
13858
|
+
else if (rdns.includes("rabby")) name = "Rabby";
|
|
13859
|
+
else if (rdns.includes("rainbow")) name = "Rainbow";
|
|
13860
|
+
else if (rdns.includes("okx")) name = "OKX Wallet";
|
|
13861
|
+
else if (rdns.includes("trust")) name = "Trust Wallet";
|
|
13862
|
+
add(detail.provider, name);
|
|
13863
|
+
}
|
|
13864
|
+
if (evmProviders.length === 0) {
|
|
13865
|
+
add(anyWin.phantom?.ethereum, "Phantom");
|
|
13866
|
+
add(anyWin.coinbaseWalletExtension, "Coinbase");
|
|
13867
|
+
add(anyWin.trustwallet?.ethereum, "Trust Wallet");
|
|
13868
|
+
add(anyWin.okxwallet, "OKX Wallet");
|
|
13869
|
+
if (evmProviders.length === 0 && win.ethereum) {
|
|
13870
|
+
const eth = win.ethereum;
|
|
13871
|
+
let name = "Wallet";
|
|
13872
|
+
if (eth.isMetaMask && !eth.isPhantom && !eth.isRabby) name = "MetaMask";
|
|
13873
|
+
else if (eth.isRabby) name = "Rabby";
|
|
13874
|
+
else if (eth.isRainbow) name = "Rainbow";
|
|
13875
|
+
else if (eth.isCoinbaseWallet) name = "Coinbase";
|
|
13876
|
+
add(eth, name);
|
|
13877
|
+
}
|
|
13858
13878
|
}
|
|
13859
13879
|
for (const { provider, name } of evmProviders) {
|
|
13860
13880
|
try {
|
|
@@ -13910,12 +13930,9 @@ function WithdrawForm({
|
|
|
13910
13930
|
estimatedProcessingTime,
|
|
13911
13931
|
maxSlippagePercent,
|
|
13912
13932
|
priceImpactPercent,
|
|
13913
|
-
|
|
13933
|
+
senderAddress,
|
|
13914
13934
|
sourceChainId,
|
|
13915
13935
|
sourceTokenAddress,
|
|
13916
|
-
isWalletMatch,
|
|
13917
|
-
connectedWalletName,
|
|
13918
|
-
canWithdraw,
|
|
13919
13936
|
onWithdraw,
|
|
13920
13937
|
onWithdrawError,
|
|
13921
13938
|
onDepositWalletCreation,
|
|
@@ -14050,12 +14067,43 @@ function WithdrawForm({
|
|
|
14050
14067
|
destinationTokenAddress: selectedChain.token_address,
|
|
14051
14068
|
recipientAddress: trimmedAddress
|
|
14052
14069
|
});
|
|
14053
|
-
|
|
14070
|
+
let amountBaseUnit = computeBaseUnit(
|
|
14054
14071
|
balanceData.balanceBaseUnit,
|
|
14055
14072
|
parseFloat(amount),
|
|
14056
14073
|
inputUnit === "crypto" ? balanceCrypto : balanceUsdNum
|
|
14057
14074
|
);
|
|
14058
|
-
|
|
14075
|
+
let humanAmount = toSafeDecimalString(cryptoAmountFromInput, sourceDecimals);
|
|
14076
|
+
if (isHypercoreChain(sourceChainId)) {
|
|
14077
|
+
try {
|
|
14078
|
+
const check = await checkHypercoreActivation(
|
|
14079
|
+
{
|
|
14080
|
+
source_address: senderAddress,
|
|
14081
|
+
recipient_address: depositWallet.address
|
|
14082
|
+
},
|
|
14083
|
+
publishableKey
|
|
14084
|
+
);
|
|
14085
|
+
if (!check.user_exists) {
|
|
14086
|
+
const fee = check.activation_fee;
|
|
14087
|
+
const maxSendable = balanceCrypto - fee;
|
|
14088
|
+
if (maxSendable <= 0) {
|
|
14089
|
+
throw new Error(
|
|
14090
|
+
`Insufficient balance. A ${fee} USDC activation fee is required for the first transfer to this address.`
|
|
14091
|
+
);
|
|
14092
|
+
}
|
|
14093
|
+
const requestedAmount = parseFloat(humanAmount);
|
|
14094
|
+
if (requestedAmount > maxSendable) {
|
|
14095
|
+
humanAmount = toSafeDecimalString(maxSendable, sourceDecimals);
|
|
14096
|
+
amountBaseUnit = computeBaseUnit(
|
|
14097
|
+
balanceData.balanceBaseUnit,
|
|
14098
|
+
maxSendable,
|
|
14099
|
+
balanceCrypto
|
|
14100
|
+
);
|
|
14101
|
+
}
|
|
14102
|
+
}
|
|
14103
|
+
} catch (e) {
|
|
14104
|
+
if (e instanceof Error && e.message.includes("activation fee")) throw e;
|
|
14105
|
+
}
|
|
14106
|
+
}
|
|
14059
14107
|
const txInfo = {
|
|
14060
14108
|
sourceChainType,
|
|
14061
14109
|
sourceChainId,
|
|
@@ -14070,43 +14118,67 @@ function WithdrawForm({
|
|
|
14070
14118
|
withdrawIntentAddress: depositWallet.address,
|
|
14071
14119
|
recipientAddress: trimmedAddress
|
|
14072
14120
|
};
|
|
14073
|
-
|
|
14074
|
-
|
|
14075
|
-
|
|
14076
|
-
|
|
14077
|
-
|
|
14078
|
-
|
|
14079
|
-
|
|
14121
|
+
const wallet = await detectBrowserWallet(sourceChainType, senderAddress);
|
|
14122
|
+
console.log("browser wallet", wallet);
|
|
14123
|
+
if (wallet) {
|
|
14124
|
+
try {
|
|
14125
|
+
if (wallet.chainFamily === "evm" && isHypercoreChain(sourceChainId)) {
|
|
14126
|
+
await sendHypercoreWithdraw({
|
|
14127
|
+
provider: wallet.provider,
|
|
14128
|
+
fromAddress: wallet.address,
|
|
14129
|
+
depositWalletAddress: depositWallet.address,
|
|
14130
|
+
sourceTokenAddress,
|
|
14131
|
+
amount: humanAmount,
|
|
14132
|
+
tokenSymbol,
|
|
14133
|
+
publishableKey
|
|
14134
|
+
});
|
|
14135
|
+
} else if (wallet.chainFamily === "evm") {
|
|
14136
|
+
await sendEvmWithdraw({
|
|
14137
|
+
provider: wallet.provider,
|
|
14138
|
+
fromAddress: wallet.address,
|
|
14139
|
+
depositWalletAddress: depositWallet.address,
|
|
14140
|
+
sourceTokenAddress,
|
|
14141
|
+
sourceChainId,
|
|
14142
|
+
amountBaseUnit
|
|
14143
|
+
});
|
|
14144
|
+
} else if (wallet.chainFamily === "solana") {
|
|
14145
|
+
await sendSolanaWithdraw({
|
|
14146
|
+
provider: wallet.provider,
|
|
14147
|
+
fromAddress: wallet.address,
|
|
14148
|
+
depositWalletAddress: depositWallet.address,
|
|
14149
|
+
sourceTokenAddress,
|
|
14150
|
+
amountBaseUnit,
|
|
14151
|
+
publishableKey
|
|
14152
|
+
});
|
|
14153
|
+
}
|
|
14154
|
+
} catch (walletErr) {
|
|
14155
|
+
console.error("[Unifold] Browser wallet send failed:", walletErr, {
|
|
14156
|
+
wallet: `${wallet.name} (${wallet.chainFamily})`,
|
|
14157
|
+
sourceChainId,
|
|
14080
14158
|
amount: humanAmount,
|
|
14081
|
-
|
|
14082
|
-
|
|
14159
|
+
amountBaseUnit,
|
|
14160
|
+
depositWallet: depositWallet.address
|
|
14083
14161
|
});
|
|
14084
|
-
|
|
14085
|
-
|
|
14086
|
-
|
|
14087
|
-
|
|
14088
|
-
|
|
14089
|
-
|
|
14162
|
+
throw walletErr;
|
|
14163
|
+
}
|
|
14164
|
+
} else if (onWithdraw) {
|
|
14165
|
+
try {
|
|
14166
|
+
await onWithdraw(txInfo);
|
|
14167
|
+
} catch (callbackErr) {
|
|
14168
|
+
console.error("[Unifold] onWithdraw callback failed:", callbackErr, {
|
|
14090
14169
|
sourceChainId,
|
|
14091
|
-
|
|
14092
|
-
});
|
|
14093
|
-
} else if (detectedWallet.chainFamily === "solana") {
|
|
14094
|
-
await sendSolanaWithdraw({
|
|
14095
|
-
provider: detectedWallet.provider,
|
|
14096
|
-
fromAddress: detectedWallet.address,
|
|
14097
|
-
depositWalletAddress: depositWallet.address,
|
|
14098
|
-
sourceTokenAddress,
|
|
14170
|
+
amount: humanAmount,
|
|
14099
14171
|
amountBaseUnit,
|
|
14100
|
-
|
|
14172
|
+
depositWallet: depositWallet.address
|
|
14101
14173
|
});
|
|
14174
|
+
throw callbackErr;
|
|
14102
14175
|
}
|
|
14103
|
-
} else if (onWithdraw) {
|
|
14104
|
-
await onWithdraw(txInfo);
|
|
14105
14176
|
} else {
|
|
14106
14177
|
throw new Error("No withdrawal method available. Please connect a wallet.");
|
|
14107
14178
|
}
|
|
14108
14179
|
onWithdrawSubmitted?.(txInfo);
|
|
14109
14180
|
} catch (err) {
|
|
14181
|
+
console.error("[Unifold] Withdrawal failed:", err);
|
|
14110
14182
|
const raw = err instanceof Error ? err.message : "Withdrawal failed. Please try again.";
|
|
14111
14183
|
setSubmitError(raw.length > 120 ? "Withdrawal failed. Please try again." : raw);
|
|
14112
14184
|
onWithdrawError?.({
|
|
@@ -14117,7 +14189,7 @@ function WithdrawForm({
|
|
|
14117
14189
|
} finally {
|
|
14118
14190
|
setIsSubmitting(false);
|
|
14119
14191
|
}
|
|
14120
|
-
}, [selectedToken, selectedChain, isFormValid, cryptoAmountFromInput, sourceDecimals, trimmedAddress, publishableKey, onWithdraw,
|
|
14192
|
+
}, [selectedToken, selectedChain, isFormValid, cryptoAmountFromInput, sourceDecimals, trimmedAddress, publishableKey, onWithdraw, sourceChainType, senderAddress, sourceTokenAddress, sourceChainId, onWithdrawError, onDepositWalletCreation, onWithdrawSubmitted, amount, inputUnit, balanceCrypto, balanceUsdNum, balanceData]);
|
|
14121
14193
|
return /* @__PURE__ */ jsxs47(Fragment11, { children: [
|
|
14122
14194
|
/* @__PURE__ */ jsxs47("div", { children: [
|
|
14123
14195
|
/* @__PURE__ */ jsx54(
|
|
@@ -14328,23 +14400,12 @@ function WithdrawForm({
|
|
|
14328
14400
|
] })
|
|
14329
14401
|
] })
|
|
14330
14402
|
] }),
|
|
14331
|
-
|
|
14332
|
-
"div",
|
|
14333
|
-
{
|
|
14334
|
-
className: "uf-flex uf-items-start uf-gap-2.5 uf-p-3 uf-rounded-xl",
|
|
14335
|
-
style: { backgroundColor: colors2.card, border: `1px solid ${colors2.border}` },
|
|
14336
|
-
children: [
|
|
14337
|
-
/* @__PURE__ */ jsx54(Wallet3, { className: "uf-w-4 uf-h-4 uf-flex-shrink-0 uf-mt-0.5", style: { color: colors2.warning } }),
|
|
14338
|
-
/* @__PURE__ */ jsx54("div", { className: "uf-text-xs", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "No connected wallet detected. Please connect a wallet that matches your account to withdraw." })
|
|
14339
|
-
]
|
|
14340
|
-
}
|
|
14341
|
-
),
|
|
14342
|
-
isWalletMatch && connectedWalletName ? /* @__PURE__ */ jsx54(
|
|
14403
|
+
/* @__PURE__ */ jsx54(
|
|
14343
14404
|
"button",
|
|
14344
14405
|
{
|
|
14345
14406
|
type: "button",
|
|
14346
14407
|
onClick: handleWithdraw,
|
|
14347
|
-
disabled: !isFormValid ||
|
|
14408
|
+
disabled: !isFormValid || isSubmitting || !selectedToken || !selectedChain,
|
|
14348
14409
|
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed uf-flex uf-items-center uf-justify-center uf-gap-2",
|
|
14349
14410
|
style: {
|
|
14350
14411
|
backgroundColor: colors2.primary,
|
|
@@ -14358,29 +14419,9 @@ function WithdrawForm({
|
|
|
14358
14419
|
"Processing..."
|
|
14359
14420
|
] }) : isOverBalance ? /* @__PURE__ */ jsx54(Fragment11, { children: "Insufficient balance" }) : isBelowMinimum ? /* @__PURE__ */ jsx54(Fragment11, { children: "Minimum amount not met" }) : submitError ? /* @__PURE__ */ jsx54(Fragment11, { children: "Withdrawal failed. Try again" }) : /* @__PURE__ */ jsxs47(Fragment11, { children: [
|
|
14360
14421
|
/* @__PURE__ */ jsx54(Wallet3, { className: "uf-w-4 uf-h-4" }),
|
|
14361
|
-
|
|
14362
|
-
connectedWalletName
|
|
14422
|
+
t8.withdraw
|
|
14363
14423
|
] })
|
|
14364
14424
|
}
|
|
14365
|
-
) : /* @__PURE__ */ jsx54(
|
|
14366
|
-
"button",
|
|
14367
|
-
{
|
|
14368
|
-
type: "button",
|
|
14369
|
-
onClick: handleWithdraw,
|
|
14370
|
-
disabled: !isFormValid || !canWithdraw || isSubmitting || !selectedToken || !selectedChain,
|
|
14371
|
-
className: "uf-w-full uf-py-3 uf-text-sm uf-font-medium uf-transition-colors disabled:uf-opacity-50 disabled:uf-cursor-not-allowed",
|
|
14372
|
-
style: {
|
|
14373
|
-
backgroundColor: colors2.primary,
|
|
14374
|
-
color: colors2.primaryForeground,
|
|
14375
|
-
fontFamily: fonts.medium,
|
|
14376
|
-
borderRadius: components.button.borderRadius,
|
|
14377
|
-
border: `${components.button.borderWidth}px solid ${components.button.borderColor}`
|
|
14378
|
-
},
|
|
14379
|
-
children: isSubmitting ? /* @__PURE__ */ jsxs47("span", { className: "uf-flex uf-items-center uf-justify-center uf-gap-2", children: [
|
|
14380
|
-
/* @__PURE__ */ jsx54(Loader26, { className: "uf-w-4 uf-h-4 uf-animate-spin" }),
|
|
14381
|
-
"Processing..."
|
|
14382
|
-
] }) : isOverBalance ? "Insufficient balance" : isBelowMinimum ? "Minimum amount not met" : submitError ? "Withdrawal failed. Try again" : t8.withdraw
|
|
14383
|
-
}
|
|
14384
14425
|
),
|
|
14385
14426
|
/* @__PURE__ */ jsxs47("div", { className: "uf-flex uf-items-center uf-justify-between uf-text-xs uf-pt-1", children: [
|
|
14386
14427
|
/* @__PURE__ */ jsx54("div", { children: footerLeft }),
|
|
@@ -14779,22 +14820,6 @@ function WithdrawModal({
|
|
|
14779
14820
|
});
|
|
14780
14821
|
const [selectedToken, setSelectedToken] = useState32(null);
|
|
14781
14822
|
const [selectedChain, setSelectedChain] = useState32(null);
|
|
14782
|
-
const [detectedWallet, setDetectedWallet] = useState32(null);
|
|
14783
|
-
const connectedWalletName = detectedWallet?.name ?? null;
|
|
14784
|
-
const isWalletMatch = !!detectedWallet;
|
|
14785
|
-
useEffect27(() => {
|
|
14786
|
-
if (!senderAddress || !open) {
|
|
14787
|
-
setDetectedWallet(null);
|
|
14788
|
-
return;
|
|
14789
|
-
}
|
|
14790
|
-
let cancelled = false;
|
|
14791
|
-
detectBrowserWallet(sourceChainType, senderAddress).then((wallet) => {
|
|
14792
|
-
if (!cancelled) setDetectedWallet(wallet);
|
|
14793
|
-
});
|
|
14794
|
-
return () => {
|
|
14795
|
-
cancelled = true;
|
|
14796
|
-
};
|
|
14797
|
-
}, [senderAddress, sourceChainType, open]);
|
|
14798
14823
|
const [view, setView] = useState32("form");
|
|
14799
14824
|
const [withdrawDepositWalletId, setWithdrawDepositWalletId] = useState32();
|
|
14800
14825
|
const [selectedExecution, setSelectedExecution] = useState32(null);
|
|
@@ -14887,7 +14912,6 @@ function WithdrawModal({
|
|
|
14887
14912
|
if (chain) setSelectedChain(chain);
|
|
14888
14913
|
}, [selectedToken]);
|
|
14889
14914
|
const isSourceSupported = sourceValidation?.isSupported ?? null;
|
|
14890
|
-
const canWithdraw = !!onWithdraw || isWalletMatch;
|
|
14891
14915
|
const isAnyLoading = tokensLoading || isCheckingSourceToken;
|
|
14892
14916
|
const withdrawPoweredByFooter = /* @__PURE__ */ jsx57("div", { className: "uf-pt-3", children: /* @__PURE__ */ jsx57(PoweredByUnifold, { color: colors2.foregroundMuted, className: "uf-flex uf-justify-center uf-shrink-0" }) });
|
|
14893
14917
|
return /* @__PURE__ */ jsx57(PortalContainerProvider, { value: hideOverlay ? containerEl : null, children: /* @__PURE__ */ jsx57(Dialog, { open: hideOverlay || open, onOpenChange: hideOverlay ? void 0 : handleClose, modal: !hideOverlay, children: /* @__PURE__ */ jsx57(
|
|
@@ -14918,7 +14942,7 @@ function WithdrawModal({
|
|
|
14918
14942
|
/* ---------- Tracker view: execution list ---------- */
|
|
14919
14943
|
/* @__PURE__ */ jsxs50(Fragment13, { children: [
|
|
14920
14944
|
/* @__PURE__ */ jsx57(DepositHeader, { title: "Withdrawal History", showBack: true, showClose: !hideOverlay, onBack: () => setView("form"), onClose: handleClose }),
|
|
14921
|
-
/* @__PURE__ */ jsx57("div", { className: "uf-
|
|
14945
|
+
/* @__PURE__ */ jsx57("div", { className: "uf-h-[460px] uf-overflow-y-auto [scrollbar-width:none] [&::-webkit-scrollbar]:uf-hidden", children: /* @__PURE__ */ jsx57("div", { className: "uf-flex uf-flex-col uf-gap-2", children: allWithdrawals.length === 0 ? /* @__PURE__ */ jsx57("div", { className: "uf-flex uf-items-center uf-justify-center uf-py-8", children: /* @__PURE__ */ jsx57("p", { className: "uf-text-sm", style: { color: colors2.foregroundMuted, fontFamily: fonts.regular }, children: "No withdrawals to track yet" }) }) : allWithdrawals.map((ex) => /* @__PURE__ */ jsx57(
|
|
14922
14946
|
WithdrawExecutionItem,
|
|
14923
14947
|
{
|
|
14924
14948
|
execution: ex,
|
|
@@ -14928,7 +14952,7 @@ function WithdrawModal({
|
|
|
14928
14952
|
}
|
|
14929
14953
|
},
|
|
14930
14954
|
ex.id
|
|
14931
|
-
)) }),
|
|
14955
|
+
)) }) }),
|
|
14932
14956
|
withdrawPoweredByFooter
|
|
14933
14957
|
] })
|
|
14934
14958
|
) : (
|
|
@@ -14968,12 +14992,9 @@ function WithdrawModal({
|
|
|
14968
14992
|
estimatedProcessingTime: sourceValidation?.estimatedProcessingTime ?? null,
|
|
14969
14993
|
maxSlippagePercent: sourceValidation?.maxSlippagePercent ?? null,
|
|
14970
14994
|
priceImpactPercent: sourceValidation?.priceImpactPercent ?? null,
|
|
14971
|
-
|
|
14995
|
+
senderAddress,
|
|
14972
14996
|
sourceChainId,
|
|
14973
14997
|
sourceTokenAddress,
|
|
14974
|
-
isWalletMatch,
|
|
14975
|
-
connectedWalletName,
|
|
14976
|
-
canWithdraw,
|
|
14977
14998
|
onWithdraw,
|
|
14978
14999
|
onWithdrawError,
|
|
14979
15000
|
onDepositWalletCreation: handleDepositWalletCreation,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unifold/ui-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45",
|
|
4
4
|
"description": "Unifold UI React - Deposit and onramp components for React applications",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"lucide-react": "^0.454.0",
|
|
44
44
|
"qr-code-styling": "^1.6.0-rc.1",
|
|
45
45
|
"tailwind-merge": "^2.0.0",
|
|
46
|
-
"@unifold/core": "0.1.
|
|
46
|
+
"@unifold/core": "0.1.45"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@solana/spl-token": "^0.3.8",
|