Skip to main content

alloy_rpc_types_beacon/
withdrawals.rs

1use alloy_eips::eip4895::Withdrawal;
2use alloy_primitives::Address;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use serde_with::{serde_as, DeserializeAs, DisplayFromStr, SerializeAs};
5
6/// Same as [Withdrawal] but respects the Beacon API format which uses snake-case and quoted
7/// decimals.
8#[serde_as]
9#[derive(Serialize, Deserialize, Clone)]
10pub(crate) struct BeaconWithdrawal {
11    #[serde_as(as = "DisplayFromStr")]
12    index: u64,
13    #[serde_as(as = "DisplayFromStr")]
14    validator_index: u64,
15    address: Address,
16    #[serde_as(as = "DisplayFromStr")]
17    amount: u64,
18}
19
20impl SerializeAs<Withdrawal> for BeaconWithdrawal {
21    fn serialize_as<S>(source: &Withdrawal, serializer: S) -> Result<S::Ok, S::Error>
22    where
23        S: Serializer,
24    {
25        beacon_withdrawals::serialize(source, serializer)
26    }
27}
28
29impl<'de> DeserializeAs<'de, Withdrawal> for BeaconWithdrawal {
30    fn deserialize_as<D>(deserializer: D) -> Result<Withdrawal, D::Error>
31    where
32        D: Deserializer<'de>,
33    {
34        beacon_withdrawals::deserialize(deserializer)
35    }
36}
37
38/// A helper serde module to convert from/to the Beacon API which uses quoted decimals rather than
39/// big-endian hex.
40pub mod beacon_withdrawals {
41    use super::*;
42
43    /// Serialize the payload attributes for the beacon API.
44    pub fn serialize<S>(payload_attributes: &Withdrawal, serializer: S) -> Result<S::Ok, S::Error>
45    where
46        S: Serializer,
47    {
48        let withdrawal = BeaconWithdrawal {
49            index: payload_attributes.index,
50            validator_index: payload_attributes.validator_index,
51            address: payload_attributes.address,
52            amount: payload_attributes.amount,
53        };
54        withdrawal.serialize(serializer)
55    }
56
57    /// Deserialize the payload attributes for the beacon API.
58    pub fn deserialize<'de, D>(deserializer: D) -> Result<Withdrawal, D::Error>
59    where
60        D: Deserializer<'de>,
61    {
62        let withdrawal = BeaconWithdrawal::deserialize(deserializer)?;
63        Ok(Withdrawal {
64            index: withdrawal.index,
65            validator_index: withdrawal.validator_index,
66            address: withdrawal.address,
67            amount: withdrawal.amount,
68        })
69    }
70}