use crate::account::Signature;
use crate::client::http::body;
use crate::client::network::Network;
use crate::utils::address::Address;
use crate::utils::sign::eip712::{Domain, Field, TypedStruct};
use crate::utils::sign::keccak::Keccak256;
use crate::utils::sign::msgpack::Map;
#[must_use]
pub fn connection_id(msgpack: &[u8], nonce: u64, vault: Option<Address>) -> [u8; 32] {
let sponge = Keccak256::new().chain(msgpack).chain(&nonce.to_be_bytes());
match vault {
Some(vault) => sponge.chain(&[0x01]).chain(vault.bytes()),
None => sponge.chain(&[0x00]),
}
.finalize()
}
#[must_use]
pub fn phantom_agent(connection_id: [u8; 32], network: Network) -> TypedStruct<'static> {
TypedStruct::new("Agent")
.field("source", Field::String(network.agent_source()))
.field("connectionId", Field::Bytes32(connection_id))
}
#[must_use]
pub fn l1_digest(msgpack: &[u8], nonce: u64, vault: Option<Address>, network: Network) -> [u8; 32] {
phantom_agent(connection_id(msgpack, nonce, vault), network).digest(&Domain::EXCHANGE)
}
pub trait L1Action {
fn action(&self) -> Map;
#[must_use]
fn msgpack(&self) -> Vec<u8> {
self.action().to_msgpack()
}
#[must_use]
fn wire(&self) -> String {
self.action().to_json().compact()
}
#[must_use]
fn connection_id(&self, nonce: u64, vault: Option<Address>) -> [u8; 32] {
connection_id(&self.msgpack(), nonce, vault)
}
#[must_use]
fn typed(&self, nonce: u64, vault: Option<Address>, network: Network) -> TypedStruct<'static> {
phantom_agent(self.connection_id(nonce, vault), network)
}
#[must_use]
fn digest(&self, nonce: u64, vault: Option<Address>, network: Network) -> [u8; 32] {
self.typed(nonce, vault, network).digest(&Domain::EXCHANGE)
}
#[must_use]
fn wallet_json(&self, nonce: u64, vault: Option<Address>, network: Network) -> String {
self.typed(nonce, vault, network).wallet_json(&Domain::EXCHANGE)
}
#[must_use]
fn body(&self, nonce: u64, signature: &Signature, vault: Option<Address>) -> String {
body::l1(&self.action(), nonce, signature, vault)
}
}
impl L1Action for Map {
fn action(&self) -> Map {
self.clone()
}
}
#[cfg(test)]
#[path = "tests/l1.rs"]
mod tests;