use crate::config::OperatorConfig;
use crate::error::{PricingError, Result};
use crate::pricing_engine;
use blueprint_crypto::KeyType;
use parity_scale_codec::Encode;
use tangle_subxt::subxt::utils::AccountId32;
pub type BlueprintId = u64;
pub type OperatorId = AccountId32;
#[derive(Debug, Clone)]
pub struct SignedQuote<K: KeyType> {
pub quote_details: pricing_engine::QuoteDetails,
pub signature: K::Signature,
pub operator_id: OperatorId,
pub proof_of_work: Vec<u8>,
}
pub struct OperatorSigner<K: KeyType> {
keypair: K::Secret,
operator_id: OperatorId,
}
impl<K: KeyType> OperatorSigner<K> {
pub fn new(
_config: &OperatorConfig,
keypair: K::Secret,
operator_id: OperatorId,
) -> Result<Self> {
Ok(OperatorSigner {
keypair,
operator_id,
})
}
pub fn sign_quote(
&mut self,
quote_details: pricing_engine::QuoteDetails,
proof_of_work: Vec<u8>,
) -> Result<SignedQuote<K>> {
let hash = hash_quote_details("e_details)?;
let signature = K::sign_with_secret(&mut self.keypair, &hash)
.map_err(|e| PricingError::Signing(format!("Error {e:?} signing quote hash")))?;
Ok(SignedQuote {
quote_details,
signature,
operator_id: self.operator_id.clone(),
proof_of_work,
})
}
pub fn public_key(&self) -> K::Public {
K::public_from_secret(&self.keypair)
}
pub fn operator_id(&self) -> OperatorId {
self.operator_id.clone()
}
}
pub fn hash_quote_details(quote_details: &pricing_engine::QuoteDetails) -> Result<[u8; 32]> {
let on_chain_quote = crate::utils::create_on_chain_quote_type(quote_details)?;
let serialized = on_chain_quote.encode();
let keccak_hash = sp_core::keccak_256(&serialized);
Ok(keccak_hash)
}
pub fn verify_quote<K: KeyType>(quote: &SignedQuote<K>, public_key: &K::Public) -> Result<bool> {
let hash = hash_quote_details("e.quote_details)?;
Ok(K::verify(public_key, &hash, "e.signature))
}