blueprint_tangle_extra/extract/
caller.rs

1use blueprint_core::{
2    __composite_rejection as composite_rejection, __define_rejection as define_rejection,
3};
4use blueprint_core::{FromJobCallParts, job::call::Parts as JobCallParts};
5use tangle_subxt::subxt::utils::AccountId32;
6
7/// Extracts the current caller from the job call.
8#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
9pub struct Caller(pub AccountId32);
10
11impl Caller {
12    pub const METADATA_KEY: &'static str = "X-TANGLE-CALLER-ID";
13}
14
15blueprint_core::__impl_deref!(Caller: AccountId32);
16blueprint_core::__impl_from!(AccountId32, Caller);
17
18define_rejection! {
19  #[body = "No Caller found in the metadata"]
20  /// A Rejection type for [`Caller`] when it is missing from the Metadata.
21  pub struct MissingCaller;
22}
23
24define_rejection! {
25  #[body = "The caller id in the metadata is not a valid AccountId32"]
26  /// A Rejection type for [`Caller`] when it is not a valid AccountId32.
27  pub struct InvalidCaller;
28}
29
30composite_rejection! {
31    /// Rejection used for [`Caller`].
32    ///
33    /// Contains one variant for each way the [`Caller`] extractor
34    /// can fail.
35    pub enum CallerRejection {
36        MissingCaller,
37        InvalidCaller,
38    }
39}
40
41impl TryFrom<&mut JobCallParts> for Caller {
42    type Error = CallerRejection;
43
44    fn try_from(parts: &mut JobCallParts) -> Result<Self, Self::Error> {
45        let caller_id_raw = parts
46            .metadata
47            .get(Self::METADATA_KEY)
48            .ok_or(MissingCaller)?;
49        let caller_id_bytes: [u8; 32] = caller_id_raw
50            .as_bytes()
51            .try_into()
52            .map_err(|_| InvalidCaller)?;
53        let caller_id = AccountId32::from(caller_id_bytes);
54        Ok(Caller(caller_id))
55    }
56}
57
58impl<Ctx> FromJobCallParts<Ctx> for Caller
59where
60    Ctx: Send + Sync,
61{
62    type Rejection = CallerRejection;
63
64    async fn from_job_call_parts(
65        parts: &mut JobCallParts,
66        _: &Ctx,
67    ) -> Result<Self, Self::Rejection> {
68        Caller::try_from(parts)
69    }
70}