aleph_types/account/
mod.rs1#[cfg(feature = "account-evm")]
2mod evm;
3#[cfg(feature = "account-sol")]
4mod solana;
5
6#[cfg(feature = "account-evm")]
7pub use evm::EvmAccount;
8#[cfg(feature = "account-sol")]
9pub use solana::SolanaAccount;
10
11use crate::chain::{Address, Chain, Signature};
12use crate::item_hash::ItemHash;
13use crate::message::MessageType;
14use crate::message::pending::PendingMessage;
15use crate::message::unsigned::UnsignedMessage;
16use thiserror::Error;
17
18#[derive(Debug, Error)]
19#[non_exhaustive]
20pub enum SignError {
21 #[error("signing failed: {0}")]
22 SigningFailed(String),
23}
24
25#[derive(Debug, Error)]
26#[non_exhaustive]
27pub enum AccountError {
28 #[error("chain {0} is not supported by this account type")]
29 UnsupportedChain(Chain),
30 #[error("invalid private key: {0}")]
31 InvalidKey(String),
32}
33
34pub trait Account: Send + Sync {
35 fn chain(&self) -> Chain;
36 fn address(&self) -> &Address;
37 fn sign_raw(&self, buffer: &[u8]) -> Result<Signature, SignError>;
38}
39
40pub fn verification_buffer(
41 chain: &Chain,
42 sender: &Address,
43 message_type: MessageType,
44 item_hash: &ItemHash,
45) -> String {
46 format!("{chain}\n{sender}\n{message_type}\n{item_hash}")
47}
48
49pub fn sign_message<A: Account>(
50 account: &A,
51 unsigned: UnsignedMessage,
52) -> Result<PendingMessage, SignError> {
53 let buffer = verification_buffer(
54 &account.chain(),
55 account.address(),
56 unsigned.message_type,
57 &unsigned.item_hash,
58 );
59 let signature = account.sign_raw(buffer.as_bytes())?;
60
61 Ok(PendingMessage {
62 chain: account.chain(),
63 sender: account.address().clone(),
64 signature,
65 message_type: unsigned.message_type,
66 item_type: unsigned.item_type,
67 item_content: unsigned.item_content,
68 item_hash: unsigned.item_hash,
69 time: unsigned.time,
70 channel: unsigned.channel,
71 })
72}
73
74#[cfg(test)]
75mod tests {
76 use super::*;
77 use crate::{address, item_hash};
78
79 #[test]
80 fn test_verification_buffer_format() {
81 let chain = Chain::Ethereum;
82 let sender = address!("0xB68B9D4f3771c246233823ed1D3Add451055F9Ef");
83 let message_type = MessageType::Post;
84 let hash = item_hash!("d281eb8a69ba1f4dda2d71aaf3ded06caa92edd690ef3d0632f41aa91167762c");
85
86 let buffer = verification_buffer(&chain, &sender, message_type, &hash);
87
88 assert_eq!(
89 buffer,
90 "ETH\n\
91 0xB68B9D4f3771c246233823ed1D3Add451055F9Ef\n\
92 POST\n\
93 d281eb8a69ba1f4dda2d71aaf3ded06caa92edd690ef3d0632f41aa91167762c"
94 );
95 }
96}