diff --git a/packages/bridge-ui/src/components/Bridge/FungibleBridgeComponents/ImportStep/ImportStep.svelte b/packages/bridge-ui/src/components/Bridge/FungibleBridgeComponents/ImportStep/ImportStep.svelte index 7a86cff725..b928cf206c 100644 --- a/packages/bridge-ui/src/components/Bridge/FungibleBridgeComponents/ImportStep/ImportStep.svelte +++ b/packages/bridge-ui/src/components/Bridge/FungibleBridgeComponents/ImportStep/ImportStep.svelte @@ -1,7 +1,7 @@ + +
+ {#if small} +
+ {$t('destOwner.title')} + {#if displayedDestOwner} + {shortenAddress(displayedDestOwner, 8, 10)} + {#if displayedDestOwner !== $account?.address} + | {$t('common.customized')} + {/if} + {:else} + {$t('destOwner.placeholder')} + {/if} +
+ {:else} +
+
+ {$t('destOwner.title')} + +

{$t('destOwner.tooltip_title')}

+ {$t('destOwner.tooltip')} +
+
+ {#if !disabled} + + {/if} +
+ + + {#if displayedDestOwner} + {shortenAddress(displayedDestOwner, 15, 13)} + {#if displayedDestOwner !== $account?.address} + | {$t('common.customized')} + {/if} + {:else} + {$t('recipient.placeholder')} + {/if} + + + + + + {/if} +
diff --git a/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/Recipient.svelte b/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/Recipient.svelte index 75756392c9..86786da693 100644 --- a/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/Recipient.svelte +++ b/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/Recipient.svelte @@ -2,14 +2,15 @@ import { t } from 'svelte-i18n'; import type { Address } from 'viem'; - import { recipientAddress } from '$components/Bridge/state'; + import { destNetwork, destOwnerAddress, recipientAddress } from '$components/Bridge/state'; import { ActionButton, CloseButton } from '$components/Button'; import { Tooltip } from '$components/Tooltip'; + import { isSmartContract } from '$libs/util/isSmartContract'; import { shortenAddress } from '$libs/util/shortenAddress'; - import { uid } from '$libs/util/uid'; import { account } from '$stores/account'; import AddressInput from '../AddressInput/AddressInput.svelte'; + // import Alert from '$components/Alert/Alert.svelte'; // Public API export const clearRecipient = () => { @@ -20,13 +21,18 @@ export let small = false; export let disabled = false; - let dialogId = `dialog-${uid()}`; + let dialogId = `dialog-${crypto.randomUUID()}`; let addressInput: AddressInput; + let destOwnerAddressInput: AddressInput; let modalOpen = false; - let invalidAddress = false; + let invalidRecipient = false; + let invalidDestOwner = false; let prevRecipientAddress: Maybe
= null; + let recipientIsSmartContract = false; + // let destOwnerIsSmartContract = false; + function closeModal() { modalOpen = false; } @@ -40,6 +46,7 @@ function cancelModal() { // Revert change of recipient address $recipientAddress = prevRecipientAddress; + $destOwnerAddress = recipientIsSmartContract ? $account?.address : null; removeEscKeyListener(); closeModal(); } @@ -51,16 +58,46 @@ } } - function onAddressValidation(event: CustomEvent<{ isValidEthereumAddress: boolean; addr: Address }>) { + async function onRecipientValidation(event: CustomEvent<{ isValidEthereumAddress: boolean; addr: Address }>) { const { isValidEthereumAddress, addr } = event.detail; + if (isValidEthereumAddress) { - $recipientAddress = addr; - invalidAddress = false; + validateRecipient(addr); } else { - invalidAddress = true; + invalidRecipient = true; } } + const validateRecipient = async (addr: Address) => { + $recipientAddress = addr; + invalidRecipient = false; + if ($destNetwork?.id && (await isSmartContract(addr, $destNetwork.id))) { + recipientIsSmartContract = true; + } else { + recipientIsSmartContract = false; + } + }; + + async function onDestOwnerValidation(event: CustomEvent<{ isValidEthereumAddress: boolean; addr: Address }>) { + const { isValidEthereumAddress, addr } = event.detail; + if (isValidEthereumAddress) { + validateDestOwner(addr); + } else { + invalidDestOwner = true; + } + } + + const validateDestOwner = async (addr: Address) => { + $destOwnerAddress = addr; + invalidDestOwner = false; + // if ($destNetwork?.id && (await isSmartContract(addr, $destNetwork.id))) { + // destOwnerIsSmartContract = true; + // // invalidDestOwner = true; + // } else { + // destOwnerIsSmartContract = false; + // } + }; + let escKeyListener: (event: KeyboardEvent) => void; const addEscKeyListener = () => { @@ -79,6 +116,7 @@ $: modalOpenChange(modalOpen); $: ethereumAddressBinding = $recipientAddress || undefined; + $: destOwnerAddressBinding = $destOwnerAddress || undefined; $: displayedRecipient = $recipientAddress || $account?.address; @@ -134,17 +172,40 @@ + on:addressvalidation={onRecipientValidation} + onDialog + resettable /> + {#if recipientIsSmartContract} +

+ You are sending funds to a smart contract. Please provide an alternate address that can manually claim the + funds if the relayer doesn't or you configured it that way. Ensure this is an address you control, as you + cannot claim the funds as the smart contract directly. +

+
+ + +
+ {/if} +
{$t('common.cancel')} {$t('common.confirm')} diff --git a/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/RecipientStep.svelte b/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/RecipientStep.svelte index 143e1626eb..e187ec9b20 100644 --- a/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/RecipientStep.svelte +++ b/packages/bridge-ui/src/components/Bridge/SharedBridgeComponents/RecipientStep/RecipientStep.svelte @@ -4,7 +4,10 @@ import { Alert } from '$components/Alert'; import { ProcessingFee, Recipient } from '$components/Bridge/SharedBridgeComponents'; + import DestOwner from './DestOwner.svelte'; + let recipientComponent: Recipient; + let destOwnerComponent: DestOwner; let processingFeeComponent: ProcessingFee; export let hasEnoughEth: boolean = false; @@ -18,6 +21,7 @@
+
diff --git a/packages/bridge-ui/src/components/Bridge/state.ts b/packages/bridge-ui/src/components/Bridge/state.ts index f6089db261..c55af63702 100644 --- a/packages/bridge-ui/src/components/Bridge/state.ts +++ b/packages/bridge-ui/src/components/Bridge/state.ts @@ -29,6 +29,7 @@ export const processingFee = writable(BigInt(0)); export const gasLimitZero = writable(false); export const processingFeeMethod = writable(ProcessingFeeMethod.RECOMMENDED); export const recipientAddress = writable>(null); +export const destOwnerAddress = writable>(null); // Loading state export const bridging = writable(false); diff --git a/packages/bridge-ui/src/components/ChainSelectors/ChainPill/ChainPill.svelte b/packages/bridge-ui/src/components/ChainSelectors/ChainPill/ChainPill.svelte index e4a8e6f496..6d2d882cba 100644 --- a/packages/bridge-ui/src/components/ChainSelectors/ChainPill/ChainPill.svelte +++ b/packages/bridge-ui/src/components/ChainSelectors/ChainPill/ChainPill.svelte @@ -8,7 +8,6 @@ import { DesktopOrLarger } from '$components/DesktopOrLarger'; import { classNames } from '$libs/util/classNames'; import { truncateString } from '$libs/util/truncateString'; - import { uid } from '$libs/util/uid'; import { account } from '$stores'; export let value: Maybe | null = null; @@ -26,8 +25,8 @@ let iconSize = 'min-w-5 max-w-5 min-h-5 max-h-5'; - let buttonId = `button-${uid()}`; - let dialogId = `dialog-${uid()}`; + let buttonId = `button-${crypto.randomUUID()}`; + let dialogId = `dialog-${crypto.randomUUID()}`; let modalOpen = false; const handlePillClick = () => { diff --git a/packages/bridge-ui/src/components/ChainSelectors/SelectorDialogs/ChainsDialog.svelte b/packages/bridge-ui/src/components/ChainSelectors/SelectorDialogs/ChainsDialog.svelte index 6317de54fa..126631bdc6 100644 --- a/packages/bridge-ui/src/components/ChainSelectors/SelectorDialogs/ChainsDialog.svelte +++ b/packages/bridge-ui/src/components/ChainSelectors/SelectorDialogs/ChainsDialog.svelte @@ -9,7 +9,6 @@ import { ActionButton } from '$components/Button'; import { chains } from '$libs/chain'; import { closeOnEscapeOrOutsideClick } from '$libs/customActions'; - import { uid } from '$libs/util/uid'; import { connectedSourceChain } from '$stores/network'; export let isOpen = false; @@ -17,7 +16,7 @@ export let switchWallet = false; let modalOpen = false; - const dialogId = `dialog-${uid()}`; + const dialogId = `dialog-${crypto.randomUUID()}`; const dispatch = createEventDispatcher(); diff --git a/packages/bridge-ui/src/components/Dialogs/ClaimDialog/ClaimDialog.svelte b/packages/bridge-ui/src/components/Dialogs/ClaimDialog/ClaimDialog.svelte index 146c838754..649a5d42d5 100644 --- a/packages/bridge-ui/src/components/Dialogs/ClaimDialog/ClaimDialog.svelte +++ b/packages/bridge-ui/src/components/Dialogs/ClaimDialog/ClaimDialog.svelte @@ -24,7 +24,6 @@ } from '$libs/error'; import type { NFT } from '$libs/token'; import { getLogger } from '$libs/util/logger'; - import { uid } from '$libs/util/uid'; import { connectedSourceChain } from '$stores/network'; import { pendingTransactions } from '$stores/pendingTransactions'; @@ -37,7 +36,7 @@ const log = getLogger('ClaimDialog'); - const dialogId = `dialog-${uid()}`; + const dialogId = `dialog-${crypto.randomUUID()}`; const dispatch = createEventDispatcher(); export let dialogOpen = false; diff --git a/packages/bridge-ui/src/components/Dialogs/ReleaseDialog/ReleaseDialog.svelte b/packages/bridge-ui/src/components/Dialogs/ReleaseDialog/ReleaseDialog.svelte index bf461a0c19..b09be8da5e 100644 --- a/packages/bridge-ui/src/components/Dialogs/ReleaseDialog/ReleaseDialog.svelte +++ b/packages/bridge-ui/src/components/Dialogs/ReleaseDialog/ReleaseDialog.svelte @@ -18,7 +18,6 @@ RetryError, } from '$libs/error'; import { getLogger } from '$libs/util/logger'; - import { uid } from '$libs/util/uid'; import { connectedSourceChain } from '$stores/network'; import { pendingTransactions } from '$stores/pendingTransactions'; @@ -32,7 +31,7 @@ const log = getLogger('ReleaseDialog'); - const dialogId = `dialog-${uid()}`; + const dialogId = `dialog-${crypto.randomUUID()}`; const dispatch = createEventDispatcher(); export let bridgeTx: BridgeTransaction; diff --git a/packages/bridge-ui/src/components/Dialogs/RetryDialog/RetryDialog.svelte b/packages/bridge-ui/src/components/Dialogs/RetryDialog/RetryDialog.svelte index 3a90c0a662..ef60ee478b 100644 --- a/packages/bridge-ui/src/components/Dialogs/RetryDialog/RetryDialog.svelte +++ b/packages/bridge-ui/src/components/Dialogs/RetryDialog/RetryDialog.svelte @@ -12,7 +12,6 @@ import type { BridgeTransaction } from '$libs/bridge'; import { closeOnEscapeOrOutsideClick } from '$libs/customActions'; import { getLogger } from '$libs/util/logger'; - import { uid } from '$libs/util/uid'; import { pendingTransactions } from '$stores/pendingTransactions'; import Claim from '../Claim.svelte'; @@ -35,7 +34,7 @@ const log = getLogger('RetryDialog'); const dispatch = createEventDispatcher(); - const dialogId = `dialog-${uid()}`; + const dialogId = `dialog-${crypto.randomUUID()}`; let canContinue = false; let retrying: boolean; diff --git a/packages/bridge-ui/src/components/Dialogs/Shared/ClaimPreCheck.svelte b/packages/bridge-ui/src/components/Dialogs/Shared/ClaimPreCheck.svelte index 3351c040dc..8004aef57c 100644 --- a/packages/bridge-ui/src/components/Dialogs/Shared/ClaimPreCheck.svelte +++ b/packages/bridge-ui/src/components/Dialogs/Shared/ClaimPreCheck.svelte @@ -104,8 +104,11 @@ $: hasPaidProcessingFee = tx.processingFee > 0; $: differentRecipient = false; - $: if (tx.message?.destOwner && $account?.address) { - if (getAddress(tx.message.destOwner) === getAddress($account?.address)) { + $: if (tx.message?.to && $account?.address && tx.message.destOwner) { + if ( + getAddress(tx.message.to) === getAddress($account.address) || + getAddress($account.address) === getAddress(tx.message.destOwner) + ) { differentRecipient = false; } else { differentRecipient = true; diff --git a/packages/bridge-ui/src/components/Dialogs/Shared/ReviewStep.svelte b/packages/bridge-ui/src/components/Dialogs/Shared/ReviewStep.svelte index 69f40fab2c..48b6f3b41f 100644 --- a/packages/bridge-ui/src/components/Dialogs/Shared/ReviewStep.svelte +++ b/packages/bridge-ui/src/components/Dialogs/Shared/ReviewStep.svelte @@ -58,7 +58,7 @@
{$t('common.recipient')}
{shortenAddress(tx.message?.destOwner, 5, 5)} + >{shortenAddress(tx.message?.to, 5, 5)}
{/if} diff --git a/packages/bridge-ui/src/components/NFTs/NFTInfoDialog.svelte b/packages/bridge-ui/src/components/NFTs/NFTInfoDialog.svelte index 668e817aba..d44164a01c 100644 --- a/packages/bridge-ui/src/components/NFTs/NFTInfoDialog.svelte +++ b/packages/bridge-ui/src/components/NFTs/NFTInfoDialog.svelte @@ -11,10 +11,9 @@ import type { NFT } from '$libs/token'; import { getTokenAddresses } from '$libs/token/getTokenAddresses'; import { shortenAddress } from '$libs/util/shortenAddress'; - import { uid } from '$libs/util/uid'; import { connectedSourceChain } from '$stores/network'; - const dialogId = `dialog-${uid()}`; + const dialogId = `dialog-${crypto.randomUUID()}`; const placeholderUrl = '/placeholder.svg'; diff --git a/packages/bridge-ui/src/components/NotificationToast/NotificationToast.svelte b/packages/bridge-ui/src/components/NotificationToast/NotificationToast.svelte index 34e7f0c8f8..ce60f9c22c 100644 --- a/packages/bridge-ui/src/components/NotificationToast/NotificationToast.svelte +++ b/packages/bridge-ui/src/components/NotificationToast/NotificationToast.svelte @@ -2,7 +2,6 @@ import { toast } from '@zerodevx/svelte-toast'; import { toastConfig } from '$config'; - import { uid } from '$libs/util/uid'; import ItemToast from './ItemToast.svelte'; import type { TypeToast } from './types'; @@ -28,7 +27,7 @@ } export function notify(notificationType: NotificationType) { - const id = Number(uid()); + const id = Number(crypto.randomUUID()); const close = () => toast.pop(id); const { title, message, type = 'unknown', closeManually = getDefaultCloseBehaviour(type) } = notificationType; diff --git a/packages/bridge-ui/src/components/TokenDropdown/AddCustomERC20.svelte b/packages/bridge-ui/src/components/TokenDropdown/AddCustomERC20.svelte index e9fd751376..9c72342e64 100644 --- a/packages/bridge-ui/src/components/TokenDropdown/AddCustomERC20.svelte +++ b/packages/bridge-ui/src/components/TokenDropdown/AddCustomERC20.svelte @@ -17,7 +17,6 @@ import { getTokenAddresses } from '$libs/token/getTokenAddresses'; import { getTokenWithInfoFromAddress } from '$libs/token/getTokenWithInfoFromAddress'; import { getLogger } from '$libs/util/logger'; - import { uid } from '$libs/util/uid'; import { config } from '$libs/wagmi'; import { account } from '$stores/account'; import { connectedSourceChain } from '$stores/network'; @@ -27,7 +26,7 @@ const dispatch = createEventDispatcher(); const log = getLogger('component:AddCustomERC20'); - const dialogId = `dialog-${uid()}`; + const dialogId = `dialog-${crypto.randomUUID()}`; export let modalOpen = false; export let loadingTokenDetails = false; diff --git a/packages/bridge-ui/src/components/TokenDropdown/TokenDropdown.svelte b/packages/bridge-ui/src/components/TokenDropdown/TokenDropdown.svelte index a39082eba1..27f734c21e 100644 --- a/packages/bridge-ui/src/components/TokenDropdown/TokenDropdown.svelte +++ b/packages/bridge-ui/src/components/TokenDropdown/TokenDropdown.svelte @@ -22,7 +22,6 @@ import { getTokenAddresses } from '$libs/token/getTokenAddresses'; import { getLogger } from '$libs/util/logger'; import { truncateString } from '$libs/util/truncateString'; - import { uid } from '$libs/util/uid'; import { type Account, account } from '$stores/account'; import { connectedSourceChain } from '$stores/network'; @@ -44,7 +43,7 @@ let customTokenModalOpen = false; - let id = `menu-${uid()}`; + let id = `menu-${crypto.randomUUID()}`; $: menuOpen = false; let activeTab: TabTypes = TabTypes.TOKEN; diff --git a/packages/bridge-ui/src/components/Tooltip/Tooltip.svelte b/packages/bridge-ui/src/components/Tooltip/Tooltip.svelte index cf779ef53a..f69ca24573 100644 --- a/packages/bridge-ui/src/components/Tooltip/Tooltip.svelte +++ b/packages/bridge-ui/src/components/Tooltip/Tooltip.svelte @@ -4,12 +4,11 @@ import { Icon } from '$components/Icon'; import { classNames } from '$libs/util/classNames'; import { positionElementByTarget } from '$libs/util/positionElementByTarget'; - import { uid } from '$libs/util/uid'; export let position: Position = 'top'; export let tooltipOpen = false; - let tooltipId = `tooltip-${uid()}`; + let tooltipId = `tooltip-${crypto.randomUUID()}`; let tooltipClass = `block dialog-tooltip`; let classes = classNames('flex z-10 ', $$props.class || 'relative'); diff --git a/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDialog.svelte b/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDialog.svelte index b4a3827c85..4ed183dd43 100644 --- a/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDialog.svelte +++ b/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDialog.svelte @@ -3,11 +3,10 @@ import { ActionButton, CloseButton } from '$components/Button'; import { MessageStatus } from '$libs/bridge'; - import { uid } from '$libs/util/uid'; export let selectedStatus: MessageStatus | null = null; - let dialogId = `dialog-${uid()}`; + let dialogId = `dialog-${crypto.randomUUID()}`; export let menuOpen = false; diff --git a/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDropdown.svelte b/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDropdown.svelte index f2445651a8..4faea34358 100644 --- a/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDropdown.svelte +++ b/packages/bridge-ui/src/components/Transactions/Filter/StatusFilterDropdown.svelte @@ -5,13 +5,12 @@ import { MessageStatus } from '$libs/bridge'; import { closeOnEscapeOrOutsideClick } from '$libs/customActions'; import { classNames } from '$libs/util/classNames'; - import { uid } from '$libs/util/uid'; export let selectedStatus: MessageStatus | null = null; let flipped = false; let menuOpen = false; - let uuid = `dropdown-${uid()}`; + let uuid = `dropdown-${crypto.randomUUID()}`; let iconFlipperComponent: IconFlipper; diff --git a/packages/bridge-ui/src/components/Transactions/InsufficientFunds.svelte b/packages/bridge-ui/src/components/Transactions/InsufficientFunds.svelte index 8e78a5189b..afcd8c4f20 100644 --- a/packages/bridge-ui/src/components/Transactions/InsufficientFunds.svelte +++ b/packages/bridge-ui/src/components/Transactions/InsufficientFunds.svelte @@ -5,11 +5,10 @@ import { Icon } from '$components/Icon'; import { PUBLIC_GUIDE_URL } from '$env/static/public'; import { closeOnEscapeOrOutsideClick } from '$libs/customActions'; - import { uid } from '$libs/util/uid'; export let modalOpen = false; - let dialogId = `dialog-${uid()}`; + let dialogId = `dialog-${crypto.randomUUID()}`; function closeModal() { modalOpen = false; diff --git a/packages/bridge-ui/src/components/Transactions/MobileDetailsDialog.svelte b/packages/bridge-ui/src/components/Transactions/MobileDetailsDialog.svelte index 6968d9431a..e07aaaadb0 100644 --- a/packages/bridge-ui/src/components/Transactions/MobileDetailsDialog.svelte +++ b/packages/bridge-ui/src/components/Transactions/MobileDetailsDialog.svelte @@ -13,7 +13,6 @@ import { getTokenAddresses } from '$libs/token/getTokenAddresses'; import { noop } from '$libs/util/noop'; import { shortenAddress } from '$libs/util/shortenAddress'; - import { uid } from '$libs/util/uid'; import { connectedSourceChain } from '$stores/network'; import ChainSymbolName from './ChainSymbolName.svelte'; @@ -34,7 +33,7 @@ const openToolTip = () => { tooltipOpen = !tooltipOpen; }; - let dialogId = `dialog-${uid()}`; + let dialogId = `dialog-${crypto.randomUUID()}`; const handleStatusDialog = () => { openStatusDialog = !openStatusDialog; diff --git a/packages/bridge-ui/src/components/Transactions/Status/StatusInfoDialog.svelte b/packages/bridge-ui/src/components/Transactions/Status/StatusInfoDialog.svelte index 3dc7f7245b..672480a605 100644 --- a/packages/bridge-ui/src/components/Transactions/Status/StatusInfoDialog.svelte +++ b/packages/bridge-ui/src/components/Transactions/Status/StatusInfoDialog.svelte @@ -3,13 +3,12 @@ import { CloseButton } from '$components/Button'; import { Icon } from '$components/Icon'; - import { uid } from '$libs/util/uid'; export let modalOpen = false; export let noIcon = false; - const dialogId = `dialog-${uid()}`; + const dialogId = `dialog-${crypto.randomUUID()}`; const closeModal = () => (modalOpen = false); diff --git a/packages/bridge-ui/src/i18n/en.json b/packages/bridge-ui/src/i18n/en.json index 824bb73d6b..460f98ee46 100644 --- a/packages/bridge-ui/src/i18n/en.json +++ b/packages/bridge-ui/src/i18n/en.json @@ -250,6 +250,7 @@ "not_available_short": "N/A", "ok": "Okay", "recipient": "Recipient", + "reset_to_wallet": "Reset to current address", "review": "Review", "search_token": "Search token", "see_results": "See results", @@ -266,6 +267,16 @@ "custom_recipient": { "placeholder": "Add custom recipient" }, + "destOwner": { + "alerts": { + "smartContract": "You cannot set the destination owner to a contract address" + }, + "description": "You can set a custom address that should be able to claim the transaction on the destination chain, for example if the recipient is a smart contract that cannot manually claim.", + "placeholder": "add address that should be able to manually claim...", + "title": "Destination owner", + "tooltip": "Defaults to your address. You can specify a different address that should be able to claim this transaction.", + "tooltip_title": "What is Destination Owner?" + }, "faucet": { "button": { "checking": "Checking mintability", diff --git a/packages/bridge-ui/src/libs/bridge/ERC1155Bridge.ts b/packages/bridge-ui/src/libs/bridge/ERC1155Bridge.ts index bdc64eab28..94f9931e82 100644 --- a/packages/bridge-ui/src/libs/bridge/ERC1155Bridge.ts +++ b/packages/bridge-ui/src/libs/bridge/ERC1155Bridge.ts @@ -4,7 +4,7 @@ import { getContract, UserRejectedRequestError } from 'viem'; import { bridgeAbi, erc1155Abi, erc1155VaultAbi } from '$abi'; import { routingContractsMap } from '$bridgeConfig'; -import { gasLimitZero } from '$components/Bridge/state'; +import { destOwnerAddress, gasLimitZero } from '$components/Bridge/state'; import { gasLimitConfig } from '$config'; import { ApproveError, @@ -223,7 +223,7 @@ export class ERC1155Bridge extends Bridge { const sendERC1155Args: NFTBridgeTransferOp = { destChainId: BigInt(destChainId), to, - destOwner: to, + destOwner: get(destOwnerAddress) || to, token, gasLimit: Number(gasLimit), fee, diff --git a/packages/bridge-ui/src/libs/bridge/ERC20Bridge.ts b/packages/bridge-ui/src/libs/bridge/ERC20Bridge.ts index f1c06c0324..e3023d9307 100644 --- a/packages/bridge-ui/src/libs/bridge/ERC20Bridge.ts +++ b/packages/bridge-ui/src/libs/bridge/ERC20Bridge.ts @@ -4,7 +4,7 @@ import { getContract, UserRejectedRequestError } from 'viem'; import { bridgeAbi, erc20Abi, erc20VaultAbi } from '$abi'; import { routingContractsMap } from '$bridgeConfig'; -import { gasLimitZero } from '$components/Bridge/state'; +import { destOwnerAddress, gasLimitZero } from '$components/Bridge/state'; import { gasLimitConfig } from '$config'; import { ApproveError, @@ -75,7 +75,7 @@ export class ERC20Bridge extends Bridge { const sendERC20Args = { destChainId: BigInt(destChainId), - destOwner: to, + destOwner: get(destOwnerAddress) || to, to, token, amount, diff --git a/packages/bridge-ui/src/libs/bridge/ERC721Bridge.ts b/packages/bridge-ui/src/libs/bridge/ERC721Bridge.ts index 294bdb6990..45c5f6968b 100644 --- a/packages/bridge-ui/src/libs/bridge/ERC721Bridge.ts +++ b/packages/bridge-ui/src/libs/bridge/ERC721Bridge.ts @@ -4,7 +4,7 @@ import { getContract, UserRejectedRequestError } from 'viem'; import { bridgeAbi, erc721Abi, erc721VaultAbi } from '$abi'; import { routingContractsMap } from '$bridgeConfig'; -import { gasLimitZero } from '$components/Bridge/state'; +import { destOwnerAddress, gasLimitZero } from '$components/Bridge/state'; import { gasLimitConfig } from '$config'; import { ApproveError, @@ -235,7 +235,7 @@ export class ERC721Bridge extends Bridge { const sendERC721Args: NFTBridgeTransferOp = { destChainId: BigInt(destChainId), to, - destOwner: to, + destOwner: get(destOwnerAddress) || to, token, gasLimit: Number(gasLimit), fee, diff --git a/packages/bridge-ui/src/libs/bridge/ETHBridge.ts b/packages/bridge-ui/src/libs/bridge/ETHBridge.ts index 5cbae26530..b81911ec2c 100644 --- a/packages/bridge-ui/src/libs/bridge/ETHBridge.ts +++ b/packages/bridge-ui/src/libs/bridge/ETHBridge.ts @@ -3,7 +3,7 @@ import { get } from 'svelte/store'; import { getContract, UserRejectedRequestError } from 'viem'; import { bridgeAbi } from '$abi'; -import { gasLimitZero } from '$components/Bridge/state'; +import { destOwnerAddress, gasLimitZero } from '$components/Bridge/state'; import { BridgePausedError, SendMessageError } from '$libs/error'; import type { BridgeProver } from '$libs/proof'; import { isBridgePaused } from '$libs/util/checkForPausedContracts'; @@ -55,7 +55,7 @@ export class ETHBridge extends Bridge { srcOwner: owner, from: owner, - destOwner: to, + destOwner: get(destOwnerAddress) || to, srcChainId: BigInt(srcChainId), destChainId: BigInt(destChainId), diff --git a/packages/bridge-ui/src/libs/util/isSmartContractWallet.test.ts b/packages/bridge-ui/src/libs/util/isSmartContract.test.ts similarity index 79% rename from packages/bridge-ui/src/libs/util/isSmartContractWallet.test.ts rename to packages/bridge-ui/src/libs/util/isSmartContract.test.ts index ba9be467ff..64d9d99658 100644 --- a/packages/bridge-ui/src/libs/util/isSmartContractWallet.test.ts +++ b/packages/bridge-ui/src/libs/util/isSmartContract.test.ts @@ -4,7 +4,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { config } from '$libs/wagmi'; import { L1_CHAIN_ID } from '$mocks'; -import { isSmartContractWallet } from './isSmartContractWallet'; +import { isSmartContract } from './isSmartContract'; // Mock wagmi core vi.mock('@wagmi/core'); @@ -13,7 +13,7 @@ vi.mock('$customToken'); vi.mock('$libs/token'); -describe('isSmartContractWallet', () => { +describe('isSmartContract', () => { const mockWalletAddress = '0x1234567890abcdef1234567890abcdef12345678'; const mockChainId = L1_CHAIN_ID; const mockClient = { @@ -30,7 +30,7 @@ describe('isSmartContractWallet', () => { mockClient.getBytecode.mockResolvedValueOnce('0x6000600055'); // When - const result = await isSmartContractWallet(mockWalletAddress, mockChainId); + const result = await isSmartContract(mockWalletAddress, mockChainId); // Then expect(result).toBe(true); @@ -43,7 +43,7 @@ describe('isSmartContractWallet', () => { mockClient.getBytecode.mockResolvedValueOnce('0x'); // When - const result = await isSmartContractWallet(mockWalletAddress, mockChainId); + const result = await isSmartContract(mockWalletAddress, mockChainId); // Then expect(result).toBe(false); @@ -56,6 +56,6 @@ describe('isSmartContractWallet', () => { vi.mocked(getPublicClient).mockReturnValueOnce(null); // When/Then - await expect(isSmartContractWallet(mockWalletAddress, mockChainId)).rejects.toThrow('No public client found'); + await expect(isSmartContract(mockWalletAddress, mockChainId)).rejects.toThrow('No public client found'); }); }); diff --git a/packages/bridge-ui/src/libs/util/isSmartContractWallet.ts b/packages/bridge-ui/src/libs/util/isSmartContract.ts similarity index 70% rename from packages/bridge-ui/src/libs/util/isSmartContractWallet.ts rename to packages/bridge-ui/src/libs/util/isSmartContract.ts index 53c49bf1e3..9bbc18e233 100644 --- a/packages/bridge-ui/src/libs/util/isSmartContractWallet.ts +++ b/packages/bridge-ui/src/libs/util/isSmartContract.ts @@ -5,9 +5,9 @@ import { config } from '$libs/wagmi'; import { getLogger } from './logger'; -const log = getLogger('util:isSmartContractWallet'); +const log = getLogger('util:isSmartContract'); -export const isSmartContractWallet = async (walletAddress: Address, chainId: number) => { +export const isSmartContract = async (walletAddress: Address, chainId: number) => { const publicClient = getPublicClient(config, { chainId }); if (!publicClient) throw new Error('No public client found'); @@ -18,6 +18,6 @@ export const isSmartContractWallet = async (walletAddress: Address, chainId: num if (byteCode !== '0x' && byteCode !== undefined) { isSmartContract = true; } - log('isSmartContractWallet', isSmartContract, walletAddress, chainId); + log('isSmartContract', isSmartContract, walletAddress, chainId); return isSmartContract; }; diff --git a/packages/bridge-ui/src/libs/util/uid.test.ts b/packages/bridge-ui/src/libs/util/uid.test.ts deleted file mode 100644 index 44ee4aa327..0000000000 --- a/packages/bridge-ui/src/libs/util/uid.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { uid } from './uid'; - -describe('uid', () => { - it('should always return a unique id', () => { - const generatedIds = new Set(); - - // Is this unique enough? 😅 - for (let i = 0; i < 1000; i++) { - generatedIds.add(uid()); - } - - expect(generatedIds.size).toBe(1000); - }); -}); diff --git a/packages/bridge-ui/src/libs/util/uid.ts b/packages/bridge-ui/src/libs/util/uid.ts deleted file mode 100644 index 62cb3175f1..0000000000 --- a/packages/bridge-ui/src/libs/util/uid.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function uid() { - return Math.floor(Math.random() * Date.now()).toString(16); -} diff --git a/packages/bridge-ui/src/libs/wagmi/watcher.ts b/packages/bridge-ui/src/libs/wagmi/watcher.ts index 3523b253dd..31fe27791c 100644 --- a/packages/bridge-ui/src/libs/wagmi/watcher.ts +++ b/packages/bridge-ui/src/libs/wagmi/watcher.ts @@ -3,13 +3,14 @@ import { watchAccount } from '@wagmi/core'; import { chains, isSupportedChain } from '$libs/chain'; import { refreshUserBalance } from '$libs/util/balance'; import { checkForPausedContracts } from '$libs/util/checkForPausedContracts'; -import { isSmartContractWallet } from '$libs/util/isSmartContractWallet'; +import { isSmartContract } from '$libs/util/isSmartContract'; import { getLogger } from '$libs/util/logger'; import { account, connectedSmartContractWallet } from '$stores/account'; import { switchChainModal } from '$stores/modal'; import { connectedSourceChain } from '$stores/network'; import { config } from './client'; + const log = getLogger('wagmi:watcher'); let isWatching = false; @@ -23,6 +24,7 @@ export async function startWatching() { async onChange(data) { await checkForPausedContracts(); log('Account changed', data); + account.set(data); refreshUserBalance(); const { chainId, address } = data; @@ -30,7 +32,7 @@ export async function startWatching() { if (chainId && address) { let smartWallet = false; try { - smartWallet = (await isSmartContractWallet(address, Number(chainId))) || false; + smartWallet = (await isSmartContract(address, Number(chainId))) || false; } catch (error) { console.error('Error checking for smart contract wallet', error); } finally { @@ -49,10 +51,8 @@ export async function startWatching() { // the source chain. const srcChain = chains.find((c) => c.id === Number(chainId)); if (srcChain) connectedSourceChain.set(srcChain); - refreshUserBalance(); } - account.set(data); }, });