use df_hyperliquid_core::client::evm::BadAmount;
use df_hyperliquid_core::client::evm::rlp;
use crate::bridge::message::{Message, MessageKind};
use crate::client::{Call, Method, Network};
use crate::utils::{Address, Dec, keccak256, wei};
use crate::{B256, U256};
pub const DEPOSIT_ETH: Method = Method::new("depositEth()", "uint256");
pub const DEPOSIT_TX: u8 = 0x64;
pub fn deposit(network: Network, amount: Dec) -> Result<Call, BadAmount> {
if !amount.is_positive() {
return Err(BadAmount::NotPositive(amount));
}
Ok(deposit_wei(network, wei(amount)?))
}
#[must_use]
pub fn deposit_wei(network: Network, value: U256) -> Call {
Call { to: Some(network.contracts().inbox), value, data: DEPOSIT_ETH.calldata(&[]) }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Deposit {
pub message_number: U256,
pub from: Address,
pub to: Address,
pub value: U256,
}
impl Deposit {
#[must_use]
pub fn from_message(message: &Message) -> Option<Deposit> {
if message.kind != MessageKind::EthDeposit {
return None;
}
let data = message.data.as_deref()?;
let (to, value) = data.split_first_chunk::<20>()?;
let value: &[u8; 32] = value.try_into().ok()?;
Some(Deposit {
message_number: message.number,
from: message.sender,
to: Address::from_bytes(*to),
value: U256::from_be_bytes(*value),
})
}
#[must_use]
pub fn tx_hash(&self, chain_id: u64) -> B256 {
let fields = [
rlp::uint(u128::from(chain_id)),
rlp::bytes(&self.message_number.to_be_bytes()),
rlp::bytes(self.from.bytes()),
rlp::bytes(self.to.bytes()),
rlp::u256(self.value),
];
let mut typed = vec![DEPOSIT_TX];
typed.extend(rlp::list(&fields));
B256(keccak256(&typed))
}
}
#[cfg(test)]
#[path = "tests/deposit.rs"]
mod tests;