blueprint_evm_extra/extract/
contract.rs1use alloy_primitives::Address;
9
10use blueprint_core::{
11 __composite_rejection as composite_rejection, __define_rejection as define_rejection,
12 __impl_deref as impl_deref, __impl_from as impl_from, FromJobCallParts,
13 job::call::Parts as JobCallParts,
14};
15
16#[derive(Debug, Clone, Copy)]
18pub struct ContractAddress(pub Address);
19
20impl ContractAddress {
21 pub const METADATA_KEY: &'static str = "X-EVM-CONTRACT-ADDRESS";
23}
24
25impl_deref!(ContractAddress: Address);
26impl_from!(Address, ContractAddress);
27
28define_rejection! {
29 #[body = "No contract address found in the metadata"]
30 pub struct MissingContractAddress;
32}
33
34define_rejection! {
35 #[body = "Contract address must be a valid address"]
36 pub struct InvalidContractAddress;
38}
39
40composite_rejection! {
41 pub enum ContractAddressRejection {
43 MissingContractAddress,
44 InvalidContractAddress,
45 }
46}
47
48impl TryFrom<&mut JobCallParts> for ContractAddress {
49 type Error = ContractAddressRejection;
50
51 fn try_from(parts: &mut JobCallParts) -> Result<Self, Self::Error> {
52 let address = parts
53 .metadata
54 .get(Self::METADATA_KEY)
55 .ok_or(MissingContractAddress)?;
56 let address_bytes = address.as_bytes();
57 let address = Address::try_from(address_bytes).map_err(|_| InvalidContractAddress)?;
58 Ok(ContractAddress(address))
59 }
60}
61
62impl<Ctx> FromJobCallParts<Ctx> for ContractAddress
63where
64 Ctx: Send + Sync,
65{
66 type Rejection = ContractAddressRejection;
67 async fn from_job_call_parts(
68 parts: &mut JobCallParts,
69 _: &Ctx,
70 ) -> Result<Self, Self::Rejection> {
71 Self::try_from(parts)
72 }
73}