ic_agent/identity/
delegated.rsuse candid::Principal;
use crate::{agent::EnvelopeContent, Signature};
use super::{Delegation, Identity, SignedDelegation};
pub struct DelegatedIdentity {
to: Box<dyn Identity>,
chain: Vec<SignedDelegation>,
from_key: Vec<u8>,
}
impl DelegatedIdentity {
pub fn new(from_key: Vec<u8>, to: Box<dyn Identity>, chain: Vec<SignedDelegation>) -> Self {
Self {
to,
from_key,
chain,
}
}
fn chain_signature(&self, mut sig: Signature) -> Signature {
sig.public_key = self.public_key();
sig.delegations
.get_or_insert(vec![])
.extend(self.chain.iter().cloned());
sig
}
}
impl Identity for DelegatedIdentity {
fn sender(&self) -> Result<Principal, String> {
Ok(Principal::self_authenticating(&self.from_key))
}
fn public_key(&self) -> Option<Vec<u8>> {
Some(self.from_key.clone())
}
fn sign(&self, content: &EnvelopeContent) -> Result<Signature, String> {
self.to.sign(content).map(|sig| self.chain_signature(sig))
}
fn sign_delegation(&self, content: &Delegation) -> Result<Signature, String> {
self.to
.sign_delegation(content)
.map(|sig| self.chain_signature(sig))
}
fn sign_arbitrary(&self, content: &[u8]) -> Result<Signature, String> {
self.to
.sign_arbitrary(content)
.map(|sig| self.chain_signature(sig))
}
fn delegation_chain(&self) -> Vec<SignedDelegation> {
let mut chain = self.to.delegation_chain();
chain.extend(self.chain.iter().cloned());
chain
}
}