openzeppelin_relayer/models/notification/
webhook_notification.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::{
    jobs::NotificationSend,
    models::{
        RelayerRepoModel, RelayerResponse, SignAndSendTransactionResult, SignTransactionResult,
        TransactionRepoModel, TransactionResponse, TransferTransactionResult,
    },
};
use chrono::Utc;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct WebhookNotification {
    pub id: String,
    pub event: String,
    pub payload: WebhookPayload,
    pub timestamp: String,
}

impl WebhookNotification {
    pub fn new(event: String, payload: WebhookPayload) -> Self {
        Self {
            id: Uuid::new_v4().to_string(),
            event,
            payload,
            timestamp: Utc::now().to_rfc3339(),
        }
    }
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct TransactionFailurePayload {
    pub transaction: TransactionResponse,
    pub failure_reason: String,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct RelayerDisabledPayload {
    pub relayer: RelayerResponse,
    pub disable_reason: String,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "lowercase")]
#[serde(tag = "payload_type")]
pub enum WebhookPayload {
    Transaction(TransactionResponse),
    #[serde(rename = "transaction_failure")]
    TransactionFailure(TransactionFailurePayload),
    #[serde(rename = "relayer_disabled")]
    RelayerDisabled(RelayerDisabledPayload),
    #[serde(rename = "solana_rpc")]
    SolanaRpc(SolanaWebhookRpcPayload),
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct WebhookResponse {
    pub status: String,
    pub message: Option<String>,
}

pub fn produce_transaction_update_notification_payload(
    notification_id: &str,
    transaction: &TransactionRepoModel,
) -> NotificationSend {
    let tx_payload: TransactionResponse = transaction.clone().into();
    NotificationSend::new(
        notification_id.to_string(),
        WebhookNotification::new(
            "transaction_update".to_string(),
            WebhookPayload::Transaction(tx_payload),
        ),
    )
}

pub fn produce_relayer_disabled_payload(
    notification_id: &str,
    relayer: &RelayerRepoModel,
    reason: &str,
) -> NotificationSend {
    let relayer_response: RelayerResponse = relayer.clone().into();
    let payload = RelayerDisabledPayload {
        relayer: relayer_response,
        disable_reason: reason.to_string(),
    };
    NotificationSend::new(
        notification_id.to_string(),
        WebhookNotification::new(
            "relayer_state_update".to_string(),
            WebhookPayload::RelayerDisabled(payload),
        ),
    )
}

#[allow(clippy::enum_variant_names)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(untagged)]
pub enum SolanaWebhookRpcPayload {
    SignAndSendTransaction(SignAndSendTransactionResult),
    SignTransaction(SignTransactionResult),
    TransferTransaction(TransferTransactionResult),
}

/// Produces a notification payload for a Solana RPC webhook event
pub fn produce_solana_rpc_webhook_payload(
    notification_id: &str,
    event: String,
    payload: SolanaWebhookRpcPayload,
) -> NotificationSend {
    NotificationSend::new(
        notification_id.to_string(),
        WebhookNotification::new(event, WebhookPayload::SolanaRpc(payload)),
    )
}