1use crate::payment::{ActivityPayment, AgreementPayment};
2use crate::NodeId;
3use bigdecimal::BigDecimal;
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6
7#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
8#[serde(rename_all = "camelCase")]
9pub struct Signed<T> {
10 #[serde(flatten)]
11 pub payload: T,
12 #[serde(flatten)]
13 pub signature: Option<Signature>,
14}
15
16#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub struct Signature {
19 #[serde(with = "serde_bytes")]
20 pub signature: Vec<u8>,
21 #[serde(with = "serde_bytes")]
22 pub signed_bytes: Vec<u8>,
23}
24
25#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
26#[serde(rename_all = "camelCase")]
27pub struct Payment {
28 pub payment_id: String,
29 pub payer_id: NodeId,
30 pub payee_id: NodeId,
31 pub payer_addr: String,
32 pub payee_addr: String,
33 pub payment_platform: String,
34 pub amount: BigDecimal,
35 pub timestamp: DateTime<Utc>,
36 pub agreement_payments: Vec<AgreementPayment>,
37 pub activity_payments: Vec<ActivityPayment>,
38 pub details: String,
39}
40
41#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
42#[serde(tag = "kind")]
43pub enum DriverStatusProperty {
44 InsufficientGas {
45 driver: String,
46 network: String,
47 address: String,
48 #[serde(rename = "neededGasEst")]
49 needed_gas_est: String,
50 },
51 InsufficientToken {
52 driver: String,
53 network: String,
54 address: String,
55 #[serde(rename = "neededTokenEst")]
56 needed_token_est: String,
57 },
58 InvalidChainId {
59 driver: String,
60 #[serde(rename = "chainId")]
61 chain_id: i64,
62 },
63 CantSign {
64 driver: String,
65 network: String,
66 address: String,
67 },
68 TxStuck {
69 driver: String,
70 network: String,
71 },
72 RpcError {
73 driver: String,
74 network: String,
75 },
76}
77
78impl DriverStatusProperty {
79 pub fn driver(&self) -> &str {
80 use DriverStatusProperty::*;
81 match self {
82 InsufficientGas { driver, .. } => driver,
83 InsufficientToken { driver, .. } => driver,
84 InvalidChainId { driver, .. } => driver,
85 CantSign { driver, .. } => driver,
86 TxStuck { driver, .. } => driver,
87 RpcError { driver, .. } => driver,
88 }
89 }
90
91 pub fn network(&self) -> Option<&str> {
92 use DriverStatusProperty::*;
93 Some(match self {
94 InsufficientGas { network, .. } => network,
95 InsufficientToken { network, .. } => network,
96 InvalidChainId { .. } => None?,
97 CantSign { network, .. } => network,
98 TxStuck { network, .. } => network,
99 RpcError { network, .. } => network,
100 })
101 }
102
103 pub fn is_blocking(&self) -> bool {
105 use DriverStatusProperty::*;
106 match self {
107 InsufficientGas { .. }
108 | InsufficientToken { .. }
109 | InvalidChainId { .. }
110 | CantSign { .. }
111 | TxStuck { .. }
112 | RpcError { .. } => true,
113 }
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120 use serde_json::{from_str, json, value::to_value};
121
122 #[test]
123 fn status_prop_serialization() {
124 assert_eq!(
125 json!({
126 "address": "0xf00ba4e03254c41AFd00f530A4fDFF63E7564FE8",
127 "driver": "erc20",
128 "kind": "InsufficientGas",
129 "network": "foo",
130 "neededGasEst": "bar",
131 }),
132 to_value(DriverStatusProperty::InsufficientGas {
133 driver: "erc20".into(),
134 network: "foo".into(),
135 address: "0xf00ba4e03254c41AFd00f530A4fDFF63E7564FE8".into(),
136 needed_gas_est: "bar".into()
137 })
138 .unwrap()
139 );
140 }
141
142 #[test]
143 fn status_prop_deserialization() {
144 assert_eq!(
145 DriverStatusProperty::TxStuck {
146 driver: "erc20".into(),
147 network: "baz".into(),
148 },
149 from_str(
150 r#"{
151 "driver": "erc20",
152 "kind": "TxStuck",
153 "network": "baz"
154 }"#
155 )
156 .unwrap()
157 );
158 }
159}