openzeppelin_relayer/models/notification/
webhook_notification.rs1use crate::{
2 domain::SwapResult,
3 jobs::NotificationSend,
4 models::{
5 RelayerRepoModel, RelayerResponse, SignAndSendTransactionResult, SignTransactionResult,
6 TransactionRepoModel, TransactionResponse, TransferTransactionResult,
7 },
8};
9use chrono::Utc;
10use serde::{Deserialize, Serialize};
11use uuid::Uuid;
12
13#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
14pub struct WebhookNotification {
15 pub id: String,
16 pub event: String,
17 pub payload: WebhookPayload,
18 pub timestamp: String,
19}
20
21impl WebhookNotification {
22 pub fn new(event: String, payload: WebhookPayload) -> Self {
23 Self {
24 id: Uuid::new_v4().to_string(),
25 event,
26 payload,
27 timestamp: Utc::now().to_rfc3339(),
28 }
29 }
30}
31
32#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
33pub struct TransactionFailurePayload {
34 pub transaction: TransactionResponse,
35 pub failure_reason: String,
36}
37
38#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
39pub struct RelayerDisabledPayload {
40 pub relayer: RelayerResponse,
41 pub disable_reason: String,
42}
43#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
44pub struct SolanaDexPayload {
45 pub swap_results: Vec<SwapResult>,
46}
47
48#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
49#[serde(rename_all = "lowercase")]
50#[serde(tag = "payload_type")]
51pub enum WebhookPayload {
52 Transaction(TransactionResponse),
53 #[serde(rename = "transaction_failure")]
54 TransactionFailure(TransactionFailurePayload),
55 #[serde(rename = "relayer_disabled")]
56 RelayerDisabled(Box<RelayerDisabledPayload>),
57 #[serde(rename = "solana_rpc")]
58 SolanaRpc(SolanaWebhookRpcPayload),
59 #[serde(rename = "solana_dex")]
60 SolanaDex(SolanaDexPayload),
61}
62
63#[derive(Debug, Serialize, Deserialize, Clone)]
64pub struct WebhookResponse {
65 pub status: String,
66 pub message: Option<String>,
67}
68
69pub fn produce_transaction_update_notification_payload(
70 notification_id: &str,
71 transaction: &TransactionRepoModel,
72) -> NotificationSend {
73 let tx_payload: TransactionResponse = transaction.clone().into();
74 NotificationSend::new(
75 notification_id.to_string(),
76 WebhookNotification::new(
77 "transaction_update".to_string(),
78 WebhookPayload::Transaction(tx_payload),
79 ),
80 )
81}
82
83pub fn produce_relayer_disabled_payload(
84 notification_id: &str,
85 relayer: &RelayerRepoModel,
86 reason: &str,
87) -> NotificationSend {
88 let relayer_response: RelayerResponse = relayer.clone().into();
89 let payload = RelayerDisabledPayload {
90 relayer: relayer_response,
91 disable_reason: reason.to_string(),
92 };
93 NotificationSend::new(
94 notification_id.to_string(),
95 WebhookNotification::new(
96 "relayer_state_update".to_string(),
97 WebhookPayload::RelayerDisabled(Box::new(payload)),
98 ),
99 )
100}
101
102#[allow(clippy::enum_variant_names)]
103#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
104#[serde(untagged)]
105pub enum SolanaWebhookRpcPayload {
106 SignAndSendTransaction(SignAndSendTransactionResult),
107 SignTransaction(SignTransactionResult),
108 TransferTransaction(TransferTransactionResult),
109}
110
111pub fn produce_solana_rpc_webhook_payload(
113 notification_id: &str,
114 event: String,
115 payload: SolanaWebhookRpcPayload,
116) -> NotificationSend {
117 NotificationSend::new(
118 notification_id.to_string(),
119 WebhookNotification::new(event, WebhookPayload::SolanaRpc(payload)),
120 )
121}
122
123pub fn produce_solana_dex_webhook_payload(
124 notification_id: &str,
125 event: String,
126 payload: SolanaDexPayload,
127) -> NotificationSend {
128 NotificationSend::new(
129 notification_id.to_string(),
130 WebhookNotification::new(event, WebhookPayload::SolanaDex(payload)),
131 )
132}