use async_graphql::Object;
use dusk_bytes::Serializable;
use dusk_core::signatures::bls::PublicKey as AccountPublicKey;
use node::archive::MoonlightGroup;
use serde::Serialize;
use translator::{IntermediateEvent, IntermediateMoonlightGroup};
pub struct MoonlightTransfers(pub Vec<MoonlightGroup>);
impl Serialize for MoonlightTransfers {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let moonlight_groups: &Vec<MoonlightGroup> = &self.0;
let mut serializable_groups: Vec<IntermediateMoonlightGroup> = vec![];
for group in moonlight_groups {
let intermediate_events: Vec<IntermediateEvent> =
group.events().iter().map(IntermediateEvent::from).collect();
serializable_groups.push(IntermediateMoonlightGroup {
events: serde_json::to_value(intermediate_events)
.unwrap_or_default(),
origin: *group.origin(),
block_height: group.block_height(),
});
}
serializable_groups.serialize(serializer)
}
}
pub struct ContractEvents(pub(super) serde_json::Value);
pub(super) struct NewAccountPublicKey(pub AccountPublicKey);
impl TryInto<NewAccountPublicKey> for String {
type Error = String;
fn try_into(self) -> Result<NewAccountPublicKey, Self::Error> {
let mut pk_bytes = [0u8; 96];
bs58::decode(self).into(&mut pk_bytes).map_err(|_| {
"Failed to decode given public key to bytes".to_string()
})?;
Ok(NewAccountPublicKey(
AccountPublicKey::from_bytes(&pk_bytes)
.map_err(|e| format!("Failed to deserialize bytes {e:?}"))?,
))
}
}
#[Object]
impl MoonlightTransfers {
pub async fn json(&self) -> serde_json::Value {
serde_json::to_value(self).unwrap_or_default()
}
}
#[Object]
impl ContractEvents {
pub async fn json(&self) -> serde_json::Value {
self.0.clone()
}
}
pub mod translator {
use dusk_core::abi::ContractId;
use dusk_core::stake::STAKE_CONTRACT;
use dusk_core::transfer::TRANSFER_CONTRACT;
use dusk_data_driver::ConvertibleContract;
use dusk_stake_contract_dd::ContractDriver as StakeContractDriver;
use dusk_transfer_contract_dd::ContractDriver as TransferContractDriver;
use node_data::events::contract::{ContractEvent, OriginHash};
use serde::{Deserialize, Serialize};
use serde_with::As;
use serde_with::hex::Hex;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub(super) struct IntermediateMoonlightGroup {
pub events: serde_json::Value,
#[serde(with = "As::<Hex>")]
pub origin: OriginHash,
pub block_height: u64,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub(super) struct IntermediateEvent {
pub target: ContractId,
pub topic: String,
pub data: serde_json::Value,
}
impl From<&ContractEvent> for IntermediateEvent {
fn from(event: &ContractEvent) -> Self {
let target = event.target;
let topic = event.topic.clone();
let data = &event.data;
let deserialized_data = match event.target {
TRANSFER_CONTRACT => {
TransferContractDriver.decode_event(&topic, data)
}
STAKE_CONTRACT => {
StakeContractDriver.decode_event(&topic, data)
}
_ => serde_json::to_value(hex::encode(data))
.map_err(dusk_data_driver::Error::from),
}
.unwrap_or_else(|e| {
tracing::warn!(
event = "Cannot decode event",
?target,
topic,
?e
);
serde_json::to_value(hex::encode(data))
.expect("String to be serialized")
});
Self {
target,
topic,
data: deserialized_data,
}
}
}
}