Skip to main content

polyester/codecs/decode/
guard_signer.rs

1//! Guard signer decoders.
2
3use crate::models::{
4    BatchSignProtectedActionsResult, CreateGuardSignerWalletResult, ExportGuardSignerWalletResult,
5    GuardApproval, GuardSignerStatus, RotateGuardSignerWalletResult,
6};
7use crate::proto::chain::guard::v1::{
8    BatchSignProtectedActionsResponse, CreateGuardSignerWalletResponse,
9    ExportGuardSignerWalletResponse, GetGuardSignerStatusResponse, GuardApproval as ProtoApproval,
10    GuardSignerStatus as ProtoStatus, RotateGuardSignerWalletResponse, SignProtectedActionResponse,
11};
12
13pub fn guard_signer_status_from_proto(msg: &ProtoStatus) -> GuardSignerStatus {
14    let status = if msg.initialized {
15        "initialized"
16    } else {
17        "uninitialized"
18    };
19    GuardSignerStatus {
20        signer_wallet: msg.signer_address.clone(),
21        status: status.into(),
22    }
23}
24
25pub fn status_from_proto(msg: &GetGuardSignerStatusResponse) -> Option<GuardSignerStatus> {
26    msg.status.as_option().map(guard_signer_status_from_proto)
27}
28
29pub fn create_wallet_from_proto(
30    msg: &CreateGuardSignerWalletResponse,
31) -> CreateGuardSignerWalletResult {
32    CreateGuardSignerWalletResult {
33        signer_wallet: msg.signer_address.clone(),
34    }
35}
36
37pub fn guard_approval_from_proto(msg: &ProtoApproval) -> GuardApproval {
38    GuardApproval {
39        approval_id: String::new(),
40        signature: hex::encode(&msg.signature),
41    }
42}
43
44pub fn sign_protected_action_from_proto(
45    msg: &SignProtectedActionResponse,
46) -> Option<GuardApproval> {
47    msg.approval.as_option().map(guard_approval_from_proto)
48}
49
50pub fn batch_sign_from_proto(
51    msg: &BatchSignProtectedActionsResponse,
52) -> BatchSignProtectedActionsResult {
53    BatchSignProtectedActionsResult {
54        approvals: msg
55            .approvals
56            .iter()
57            .map(guard_approval_from_proto)
58            .collect(),
59    }
60}
61
62pub fn rotate_wallet_from_proto(
63    msg: &RotateGuardSignerWalletResponse,
64) -> RotateGuardSignerWalletResult {
65    RotateGuardSignerWalletResult {
66        signer_wallet: msg.new_signer_address.clone(),
67    }
68}
69
70pub fn export_wallet_from_proto(
71    msg: &ExportGuardSignerWalletResponse,
72) -> ExportGuardSignerWalletResult {
73    ExportGuardSignerWalletResult {
74        encrypted_private_key: msg.private_key.clone(),
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    #[test]
83    fn status_initialized_label() {
84        let msg = GetGuardSignerStatusResponse {
85            status: ProtoStatus {
86                signer_address: "0xsigner".into(),
87                initialized: true,
88                ..Default::default()
89            }
90            .into(),
91            ..Default::default()
92        };
93        let status = status_from_proto(&msg).expect("status");
94        assert_eq!(status.signer_wallet, "0xsigner");
95        assert_eq!(status.status, "initialized");
96    }
97
98    #[test]
99    fn create_and_sign_decode() {
100        let created = create_wallet_from_proto(&CreateGuardSignerWalletResponse {
101            signer_address: "0xabc".into(),
102            ..Default::default()
103        });
104        assert_eq!(created.signer_wallet, "0xabc");
105
106        let signed = sign_protected_action_from_proto(&SignProtectedActionResponse {
107            approval: ProtoApproval {
108                signature: vec![0xde, 0xad],
109                ..Default::default()
110            }
111            .into(),
112            ..Default::default()
113        })
114        .expect("approval");
115        assert_eq!(signed.signature, "dead");
116    }
117}