verity_ic/remittance/external_router/
mod.rsuse crate::remittance::types::{ DataModel, Event, RemittanceSubscriber, Subscriber };
use candid::{ CandidType, Principal };
use ic_cdk::{ api::call::RejectionCode, id };
use serde::Deserialize;
use serde_json::Value;
use std::{ cell::RefCell, collections::BTreeMap };
thread_local! {
pub static REMITTANCE_CANISTER: RefCell<Option<RemittanceSubscriber>> = RefCell::default();
}
pub mod permissions;
pub type SubscriberStore = BTreeMap<Principal, Subscriber>;
#[derive(Clone, Debug, CandidType, Deserialize)]
pub struct Account {
pub balance: u64,
}
pub fn set_remittance_canister(remittance_principal: Principal) {
REMITTANCE_CANISTER.with(|rc| {
let _ = rc.borrow_mut().insert(RemittanceSubscriber {
canister_principal: remittance_principal,
subscribed: false,
});
})
}
pub fn get_remittance_canister() -> RemittanceSubscriber {
REMITTANCE_CANISTER.with(|rc| rc.borrow().clone()).expect("REMITTANCE_CANISTER_NOT_INITIALIZED")
}
pub fn subscribe() {
let subscriber_principal_id = ic_cdk::caller();
let whitelisted_remittance_canister = REMITTANCE_CANISTER.with(|rc| rc.borrow().clone()).expect(
"REMITTANCE_CANISTER_NOT_INITIALIZED"
);
if whitelisted_remittance_canister.canister_principal != subscriber_principal_id {
panic!("REMITTANCE_CANISTER_NOT_WHITELISTED");
}
REMITTANCE_CANISTER.with(|rc| {
let _ = rc.borrow_mut().insert(RemittanceSubscriber {
canister_principal: subscriber_principal_id,
subscribed: true,
});
});
}
pub fn is_subscribed(canister_principal: Principal) -> bool {
let whitelisted_remittance_canister = REMITTANCE_CANISTER.with(|rc| rc.borrow().clone()).expect(
"REMITTANCE_CANISTER_NOT_INITIALIZED"
);
whitelisted_remittance_canister.canister_principal == canister_principal &&
whitelisted_remittance_canister.subscribed
}
pub async fn publish_dc_json_to_remittance(json_data: String) -> Result<(), String> {
let json_event: Value = serde_json
::from_str(&json_data[..])
.expect("JSON_DESERIALIZATION_FAILED");
let update_succesful = if let Value::Array(events) = json_event {
let mut parsed_events: Vec<DataModel> = Vec::new();
for event in events {
let json_event: Event = serde_json::from_value(event).unwrap();
let parsed_event: DataModel = json_event.into();
parsed_events.push(parsed_event);
}
let dc_canister = id();
let response = broadcast_to_remittance(&parsed_events, dc_canister).or(
Err("PUBLISH_FAILED".to_string())
);
response
} else {
Err("ERROR_PARSING_EVENT_INTO_DATAMODEL".to_string())
};
update_succesful
}
pub async fn publish_pdc_json_to_remittance(json_data: String) -> Result<(), String> {
let json_event: Value = serde_json
::from_str(&json_data[..])
.expect("JSON_DESERIALIZATION_FAILED");
let update_succesful = if let Value::Array(events) = json_event {
for event in events {
let json_event: Event = serde_json::from_value(event).unwrap();
let dc_canister: Principal = (&json_event.canister_id[..]).try_into().unwrap();
let parsed_event: DataModel = json_event.into();
let _ = broadcast_to_remittance(&vec![parsed_event], dc_canister);
}
Ok(())
} else {
Err("ERROR_PARSING_EVENT_INTO_DATAMODEL".to_string())
};
update_succesful
}
pub fn broadcast_to_remittance(
events: &Vec<DataModel>,
dc_canister: Principal
) -> Result<(), RejectionCode> {
let whitelisted_remittance_canister = get_remittance_canister();
if !whitelisted_remittance_canister.subscribed {
panic!("REMITTANCE_CANISTER_NOT_INITIALIZED");
}
let remittance_response: Result<(), RejectionCode> = ic_cdk::notify(
whitelisted_remittance_canister.canister_principal,
"update_remittance",
(&events, dc_canister)
);
remittance_response
}