1use crate::types::identifiers::{AuthorityId, ChannelId, ContextId};
8use crate::Hash32;
9use async_trait::async_trait;
10use serde::{Deserialize, Serialize};
11
12pub const MAX_AMP_CIPHERTEXT_BYTES: usize = 65_536;
13pub const MAX_AMP_PLAINTEXT_BYTES: usize = 65_536;
14
15#[derive(Debug, thiserror::Error, Serialize, Deserialize, Clone, PartialEq, Eq)]
17pub enum AmpChannelError {
18 #[error("channel not found")]
19 NotFound,
20 #[error("context not found")]
21 ContextNotFound,
22 #[error("invalid state: {0}")]
23 InvalidState(String),
24 #[error("authorization failed")]
25 Unauthorized,
26 #[error("storage error: {0}")]
27 Storage(String),
28 #[error("crypto error: {0}")]
29 Crypto(String),
30 #[error("internal error: {0}")]
31 Internal(String),
32}
33
34impl crate::ProtocolErrorCode for AmpChannelError {
35 fn code(&self) -> &'static str {
36 match self {
37 AmpChannelError::NotFound => "not_found",
38 AmpChannelError::ContextNotFound => "not_found",
39 AmpChannelError::InvalidState(_) => "invalid_state",
40 AmpChannelError::Unauthorized => "unauthorized",
41 AmpChannelError::Storage(_) => "storage",
42 AmpChannelError::Crypto(_) => "crypto",
43 AmpChannelError::Internal(_) => "internal",
44 }
45 }
46}
47
48#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
50pub struct AmpHeader {
51 pub context: ContextId,
52 pub channel: ChannelId,
53 pub chan_epoch: u64,
54 pub ratchet_gen: u64,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
59pub struct AmpCiphertext {
60 pub header: AmpHeader,
61 pub ciphertext: Vec<u8>,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
66pub struct ChannelBootstrapPackage {
67 pub bootstrap_id: Hash32,
68 pub key: Vec<u8>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
73pub struct ChannelCreateParams {
74 pub context: ContextId,
75 pub channel: Option<ChannelId>,
77 pub skip_window: Option<u32>,
79 pub topic: Option<String>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
85pub struct ChannelCloseParams {
86 pub context: ContextId,
87 pub channel: ChannelId,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
92pub struct ChannelJoinParams {
93 pub context: ContextId,
94 pub channel: ChannelId,
95 pub participant: AuthorityId,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
101pub struct ChannelLeaveParams {
102 pub context: ContextId,
103 pub channel: ChannelId,
104 pub participant: AuthorityId,
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
110pub struct ChannelSendParams {
111 pub context: ContextId,
112 pub channel: ChannelId,
113 pub sender: AuthorityId,
114 pub plaintext: Vec<u8>,
116 pub reply_to: Option<Vec<u8>>, }
118
119#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
120#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
121pub trait AmpChannelEffects: Send + Sync {
122 async fn create_channel(
124 &self,
125 params: ChannelCreateParams,
126 ) -> Result<ChannelId, AmpChannelError>;
127
128 async fn close_channel(&self, params: ChannelCloseParams) -> Result<(), AmpChannelError>;
130
131 async fn join_channel(&self, params: ChannelJoinParams) -> Result<(), AmpChannelError>;
133
134 async fn leave_channel(&self, params: ChannelLeaveParams) -> Result<(), AmpChannelError>;
136
137 async fn send_message(
139 &self,
140 params: ChannelSendParams,
141 ) -> Result<AmpCiphertext, AmpChannelError>;
142}
143
144#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
146#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
147impl<T: AmpChannelEffects + ?Sized> AmpChannelEffects for std::sync::Arc<T> {
148 async fn create_channel(
149 &self,
150 params: ChannelCreateParams,
151 ) -> Result<ChannelId, AmpChannelError> {
152 (**self).create_channel(params).await
153 }
154
155 async fn close_channel(&self, params: ChannelCloseParams) -> Result<(), AmpChannelError> {
156 (**self).close_channel(params).await
157 }
158
159 async fn join_channel(&self, params: ChannelJoinParams) -> Result<(), AmpChannelError> {
160 (**self).join_channel(params).await
161 }
162
163 async fn leave_channel(&self, params: ChannelLeaveParams) -> Result<(), AmpChannelError> {
164 (**self).leave_channel(params).await
165 }
166
167 async fn send_message(
168 &self,
169 params: ChannelSendParams,
170 ) -> Result<AmpCiphertext, AmpChannelError> {
171 (**self).send_message(params).await
172 }
173}