use candid::{CandidType, Principal};
use serde::{Deserialize, Serialize};
mod bytes;
mod cbor;
mod xid;
pub use bytes::*;
pub use cbor::*;
pub use xid::*;
#[derive(CandidType, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct Delegation {
#[serde(alias = "p")]
pub pubkey: ByteBufB64,
#[serde(alias = "e")]
pub expiration: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[serde(alias = "t")]
pub targets: Option<Vec<Principal>>,
}
#[derive(CandidType, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct SignedDelegation {
#[serde(alias = "d")]
pub delegation: Delegation,
#[serde(alias = "s")]
pub signature: ByteBufB64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct SignInResponse {
pub expiration: u64,
pub user_key: ByteBufB64,
pub seed: ByteBufB64,
}
#[derive(CandidType, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct DelegationCompact {
#[serde(rename = "p", alias = "pubkey")]
pub pubkey: ByteBufB64,
#[serde(rename = "e", alias = "expiration")]
pub expiration: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
#[serde(rename = "t", alias = "targets")]
pub targets: Option<Vec<Principal>>,
}
#[derive(CandidType, Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct SignedDelegationCompact {
#[serde(rename = "d", alias = "delegation")]
pub delegation: DelegationCompact,
#[serde(rename = "s", alias = "signature")]
pub signature: ByteBufB64,
}
impl From<DelegationCompact> for Delegation {
fn from(d: DelegationCompact) -> Self {
Self {
pubkey: d.pubkey,
expiration: d.expiration,
targets: d.targets,
}
}
}
impl From<Delegation> for DelegationCompact {
fn from(d: Delegation) -> Self {
Self {
pubkey: d.pubkey,
expiration: d.expiration,
targets: d.targets,
}
}
}
impl From<SignedDelegationCompact> for SignedDelegation {
fn from(d: SignedDelegationCompact) -> Self {
Self {
delegation: d.delegation.into(),
signature: d.signature,
}
}
}
impl From<SignedDelegation> for SignedDelegationCompact {
fn from(d: SignedDelegation) -> Self {
Self {
delegation: d.delegation.into(),
signature: d.signature,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_delegation_format() {
let d = Delegation {
pubkey: ByteBufB64(vec![1, 2, 3, 4]),
expiration: 99,
targets: Some(vec![Principal::management_canister()]),
};
let data = serde_json::to_string(&d).unwrap();
println!("{data}");
assert_eq!(
data,
r#"{"pubkey":"AQIDBA==","expiration":99,"targets":["aaaaa-aa"]}"#
);
let d1: Delegation = serde_json::from_str(&data).unwrap();
assert_eq!(d, d1);
let mut data = Vec::new();
ciborium::into_writer(&d, &mut data).unwrap();
println!("{}", hex::encode(&data));
assert_eq!(
data,
hex::decode("a3667075626b657944010203046a65787069726174696f6e186367746172676574738140")
.unwrap()
);
let d1: Delegation = ciborium::from_reader(&data[..]).unwrap();
assert_eq!(d, d1);
}
}