datahaven-xyz/datahaven · error
InvalidEthereumAddress
InvalidEthereumAddress
Error message
InvalidEthereumAddress
What it means
transfer_to_ethereum validates that the recipient H160 is not the zero address (recipient != H160::zero()). Sending bridged funds to the zero address on Ethereum would irrecoverably burn them, so the pallet rejects it with InvalidEthereumAddress.
Solutions
- Validate the Ethereum address is a well-formed 20-byte value and not the zero address before submission.
- Use checksummed address parsing (e.g. viem's isAddress / getAddress) in the client.
- Reject empty or placeholder inputs at the UI layer.
Example fix
// before
const recipient = recipientInput ?? '0x0000000000000000000000000000000000000000';
// after
import { isAddress } from 'viem';
if (!isAddress(recipientInput) || recipientInput === '0x0000000000000000000000000000000000000000') throw new Error('invalid recipient');
await api.tx.datahavenNativeTransfer.transferToEthereum(recipientInput, amount, fee); Defensive patterns
Strategy: validation
Validate before calling
const ZERO = '0x0000000000000000000000000000000000000000';
if (!isAddress(recipient) || recipient.toLowerCase() === ZERO) throw new Error('recipient must be a valid non-zero Ethereum address'); Type guard
const isValidRecipient = (r) => typeof r === 'string' && /^0x[0-9a-fA-F]{40}$/.test(r) && r !== '0x' + '0'.repeat(40); Try / catch
try {
await transferToEthereum(recipient, amount, fee);
} catch (e) {
if (String(e).includes('InvalidEthereumAddress')) showFormError('Enter a valid Ethereum address');
else throw e;
} Prevention
- Use checksummed address parsing libraries for all address inputs.
- Never default recipients to the zero address.
- Require explicit user confirmation of the destination address.
When it happens
Trigger: Calling transfer_to_ethereum with recipient = 0x0000000000000000000000000000000000000000.
Common situations: Unset/empty recipient fields defaulting to zero address; encoding bugs producing a zeroed H160; users pasting incomplete addresses.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
AI-assisted analysis of datahaven-xyz/datahaven@edcb13dbbc (2026-09-13).
Data as JSON: /api/errors/49f4db83488d0a8d.
Report an issue: GitHub.
Appendix: source
Thrown at operator/pallets/datahaven-native-transfer/src/lib.rs:187
/// - `fee`: The fee to incentivize relayers (in native tokens)
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::transfer_to_ethereum())]
pub fn transfer_to_ethereum(
origin: OriginFor<T>,
recipient: H160,
amount: BalanceOf<T>,
fee: BalanceOf<T>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
ensure!(!Paused::<T>::get(), Error::<T>::TransfersDisabled);
// Get the token ID - fails if not registered
let token_id = T::NativeTokenId::get().ok_or(Error::<T>::TokenNotRegistered)?;
ensure!(amount > Zero::zero(), Error::<T>::InvalidAmount);
ensure!(fee > Zero::zero(), Error::<T>::ZeroFee);
ensure!(
recipient != H160::zero(),
Error::<T>::InvalidEthereumAddress
);
// Transfer fee to recipient
T::Currency::transfer(&who, &T::FeeRecipient::get(), fee, Preservation::Preserve)?;
// Lock tokens in the sovereign account
Self::lock_tokens(&who, amount)?;
// Build and send the message
let message = Self::build_mint_message(token_id, recipient, amount, fee)?;
T::OutboundQueue::validate(&message)
.and_then(|ticket| T::OutboundQueue::deliver(ticket))
.map_err(|_| Error::<T>::SendMessageFailed)?;
Self::deposit_event(Event::TokensTransferredToEthereum {
from: who,View on GitHub (pinned to edcb13dbbc)