helius_sdk/api/
webhook.rs

1use std::ops::Not;
2use serde::{Deserialize, Serialize};
3use reqwest::blocking::Response;
4use crate::{AccountWebhookEncoding, CollectionIdentifier, Helius, HeliusOptions, MintlistItem, MintlistRequest, TransactionType, TxnStatus};
5use crate::common::*;
6
7#[allow(dead_code)]
8const MAX_WEBHOOK_ADDRESSES: usize = 100_000;
9const WEBHOOK_BASE: &str = "webhooks";
10
11
12impl Helius {
13    pub fn get_all_webhooks(&self) -> reqwest::Result<Vec<Webhook>> {
14        return self.handler.get(self.get_url_v0(WEBHOOK_BASE));
15    }
16
17    pub fn get_webhook_by_id(&self, webhook_id: &str) -> reqwest::Result<Webhook> {
18        return self.handler.get(self.get_url_v0(format!("{WEBHOOK_BASE}/{webhook_id}").as_str()));
19    }
20
21    pub fn create_webhook(&self, request: &CreateWebhookRequest) -> reqwest::Result<Webhook> {
22        return self.handler.post(self.get_url_v0(WEBHOOK_BASE), request);
23    }
24
25    pub fn edit_webhook(&self, request: &EditWebhookRequest) -> reqwest::Result<Webhook> {
26        return self.handler.put(
27            self.get_url_v0(format!("{WEBHOOK_BASE}/{}", request.webhook_id).as_str()),
28            &request.data
29        );
30    }
31
32    pub fn delete_webhook(&self, webhook_id: &str) -> reqwest::Result<Response> {
33        return self.handler.delete(self.get_url_v0(format!("{WEBHOOK_BASE}/{}", webhook_id).as_str()));
34    }
35
36    pub fn append_addresses_to_webhook(&self, webhook_id: &str, new_addresses: Vec<String>) -> reqwest::Result<Webhook> {
37        let mut webhook = self.get_webhook_by_id(webhook_id)?;
38        webhook.webhook_data.account_addresses.extend(new_addresses);
39        let edit_request = EditWebhookRequest {
40            webhook_id: webhook_id.to_string(),
41            data: webhook.webhook_data,
42        };
43        return self.edit_webhook(&edit_request);
44    }
45
46    pub fn create_collection_webhook(&self, request: &CreateCollectionWebhookRequest) -> reqwest::Result<Webhook> {
47        let mint_request = MintlistRequest {
48            query: request.collection_query.clone(),
49            options: Some(HeliusOptions{limit: Some(10000), pagination_token: None}),
50        };
51        let mut mintlist = Vec::<MintlistItem>::new();
52        let mut mints = self.get_mintlist(&mint_request)?;
53
54        mintlist.extend(mints.result);
55
56        while mints.pagination_token.clone().is_empty().not() {
57            mints = self.get_mintlist(&MintlistRequest {
58                query: request.collection_query.clone(),
59                options: Some(HeliusOptions {
60                    limit: mint_request.options.clone().unwrap().limit,
61                    pagination_token: Some(mints.pagination_token)
62                })
63            })?;
64            mintlist.extend(mints.result);
65        }
66
67        let data = request.data.clone();
68        let webhook_request = CreateWebhookRequest {
69            data: WebhookData {
70                webhook_url: data.webhook_url,
71                transaction_types: data.transaction_types,
72                account_addresses: mintlist.iter().map(|item| return item.mint.clone()).collect(),
73                webhook_type: data.webhook_type,
74                auth_header: data.auth_header,
75                txn_status: data.txn_status,
76                encoding: data.encoding
77            },
78        };
79
80        return self.create_webhook(&webhook_request);
81    }
82}
83
84serializable_camel_case! {
85    pub struct Webhook {
86        #[serde(rename="webhookID")]
87        pub webhook_id: String,
88        pub wallet: String,
89        #[serde(flatten)]
90        pub webhook_data: WebhookData
91    }
92}
93
94serializable_camel_case! {
95    pub struct WebhookData {
96        #[serde(rename="webhookURL")]
97        pub webhook_url: String,
98        pub transaction_types: Vec<TransactionType>,
99        pub account_addresses: Vec<String>,
100        pub webhook_type: Option<WebhookType>,
101        pub auth_header: Option<String>,
102        pub txn_status: Option<TxnStatus>,
103        pub encoding: Option<AccountWebhookEncoding>
104    }
105}
106
107enum_serializable! {
108    pub enum WebhookType {
109        #[serde(rename="enhanced")]
110        Enhanced,
111        #[serde(rename="enhancedDevnet")]
112        EnhanvedDevnet,
113        #[serde(rename="raw")]
114        Raw,
115        #[serde(rename="rawDevnet")]
116        RawDevnet,
117        #[serde(rename="discord")]
118        Discord,
119        #[serde(rename="discordDevnet")]
120        DiscordDevnet
121    }
122}
123
124serializable! {
125    pub struct CreateWebhookRequest {
126        #[serde(flatten)]
127        pub data: WebhookData,
128    }
129}
130
131serializable_camel_case! {
132    pub struct CreateCollectionWebhookRequest {
133        #[serde(flatten)]
134        pub data: WebhookData,
135        pub collection_query: CollectionIdentifier
136    }
137}
138
139serializable! {
140    pub struct EditWebhookRequest {
141        pub webhook_id: String,
142        pub data: WebhookData,
143    }
144}