pub type CanisterId = candid::Principal; pub type CanisterIdHex = String;
pub type UserId = candid::Principal; pub type UserIdHex = String;
pub type CallerId = candid::Principal;
pub type SubAccount = [u8; 32];
pub type AccountIdentifier = [u8; 32]; pub type AccountIdentifierHex = String;
#[inline]
pub fn caller() -> CallerId {
ic_cdk::api::caller()
}
#[inline]
pub fn self_canister_id() -> CanisterId {
ic_cdk::api::id()
}
fn to_array(vec: &Vec<u8>) -> [u8; 32] {
assert!(vec.len() == 32);
let mut array: [u8; 32] = [0; 32];
for i in 0..32 {
array[i] = vec[i];
}
array
}
pub fn to_account_identifier(account: &Vec<u8>) -> AccountIdentifier {
assert!(account.len() == 32, "Invalid Account");
to_array(&account)
}
pub fn unwrap_account_identifier_hex(
account_identifier: AccountIdentifierHex,
) -> AccountIdentifier {
let vec = hex::decode(&account_identifier).unwrap();
assert!(vec.len() == 32, "Invalid Account Id");
to_array(&vec)
}
pub fn wrap_account_identifier(account_identifier: &AccountIdentifier) -> AccountIdentifierHex {
hex::encode(&account_identifier)
}
pub fn parse_account_identifier(
user_id: &UserId,
sub_account: &Option<SubAccount>,
) -> AccountIdentifier {
let sub_account: [u8; 32] = sub_account.clone().unwrap_or_else(|| [0; 32]);
assert!(sub_account.len() == 32, "Invalid SubAccount");
use sha2::Digest;
let mut hasher = sha2::Sha224::new(); hasher.update(b"\x0Aaccount-id");
hasher.update(user_id.as_slice());
hasher.update(&sub_account[..]);
let hash: [u8; 28] = hasher.finalize().into();
let mut hasher = crc32fast::Hasher::new();
hasher.update(&hash);
let crc32_bytes = hasher.finalize().to_be_bytes();
let mut result: [u8; 32] = [0u8; 32];
result[0..4].copy_from_slice(&crc32_bytes[..]); result[4..32].copy_from_slice(hash.as_ref());
result
}
pub fn parse_account_identifier_hex(
user_id: &UserId,
sub_account: &Option<SubAccount>,
) -> AccountIdentifierHex {
wrap_account_identifier(&parse_account_identifier(user_id, sub_account))
}
pub fn parse_u64_to_sub_account(sub_account: u64) -> SubAccount {
let mut list: [u8; 32] = [0; 32];
for i in 0..8 {
list[24 + i] = ((sub_account >> 8 * (7 - i)) & 0xff) as u8
}
list
}
pub fn parse_account_identifier_by_vec(
user_id: &UserId,
sub_account: &Option<Vec<u8>>,
) -> AccountIdentifier {
if let Some(vec) = sub_account {
assert!(vec.len() == 32, "Invalid SubAccount");
}
let sub_account = if let Some(vec) = sub_account {
Some(to_array(vec))
} else {
None
};
parse_account_identifier(user_id, &sub_account)
}
pub fn parse_account_identifier_hex_by_vec(
user_id: &UserId,
sub_account: &Option<Vec<u8>>,
) -> AccountIdentifierHex {
wrap_account_identifier(&parse_account_identifier_by_vec(user_id, sub_account))
}