alchemy_api/api/notify/
create_webhook.rs1use super::WebhookType;
2use crate::{
3 cores::endpoint::Endpoint,
4 types::{chain::AlchemyChain, common::NftFilter},
5};
6use derive_builder::Builder;
7use ethers_core::types::Address;
8use http::Method;
9use serde::{Deserialize, Serialize};
10use serde_with::{serde_as, skip_serializing_none};
11
12#[serde_as]
14#[skip_serializing_none]
15#[derive(Builder, Default, Debug, Clone, Serialize, Deserialize)]
16#[builder(setter(into, strip_option), build_fn(validate = "Self::validate"))]
17pub struct CreateWebhook {
18 #[builder(setter(skip))]
20 network: AlchemyChain,
21 #[builder(setter)]
23 webhook_type: WebhookType,
24 #[builder(setter)]
26 webhook_url: String,
27 #[builder(default)]
29 app_id: Option<String>,
30 #[builder(default)]
32 addresses: Vec<Address>,
33 #[builder(default)]
35 nft_filters: Option<Vec<NftFilter>>,
36 #[builder(default)]
38 nft_metadata_filters: Option<Vec<NftFilter>>,
39}
40
41impl CreateWebhook {
42 pub fn builder() -> CreateWebhookBuilder {
44 CreateWebhookBuilder::default()
45 }
46}
47
48impl CreateWebhookBuilder {
49 fn validate(&self) -> Result<(), String> {
51 if let Some(whtype) = self.webhook_type {
56 match whtype {
57 WebhookType::MinedTransaction | WebhookType::DroppedTransaction
58 if self.app_id.is_none() =>
59 {
60 Err("app_id is required for mined and dropped webhooks".to_string())
61 }
62 WebhookType::AddressActivity
63 if self.addresses.is_none() || self.addresses.as_ref().unwrap().is_empty() =>
64 {
65 Err("addresses is required for address activity webhooks".to_string())
66 }
67 _ => Ok(()),
68 }
69 } else {
70 Err("webhook_type is required".to_string())
71 }
72 }
73}
74
75impl Endpoint for CreateWebhook {
76 fn method(&self) -> http::Method {
77 Method::POST
78 }
79
80 fn endpoint(&self) -> std::borrow::Cow<'static, str> {
81 "api/create-webhook".into()
82 }
83
84 fn body(&self) -> anyhow::Result<Option<(&'static str, Vec<u8>)>> {
85 let body = serde_json::to_vec(self)?;
86 Ok(Some(("application/json", body)))
87 }
88}