use bitcoin::hashes::Hash; use crate::{env, Timestamp}; pub const UTXO_STORAGE_KEY_TAG: &str = "@"; /// Maximum expected byte length of a JSON-serialized `bool` promise result (`true`/`false`). pub const MAX_BOOL_RESULT: usize = 10; /// Maximum expected byte length of a JSON-serialized `U128` promise result (e.g. from `ft_on_transfer`). pub const MAX_FT_TRANSFER_CALL_RESULT: usize = 50; /// Maximum expected byte length of a JSON-serialized `near_sdk::PublicKey` promise result. pub const MAX_PUBLIC_KEY_RESULT: usize = 200; /// Maximum expected byte length of a JSON-serialized `SignatureResponse` promise result. pub const MAX_SIGNATURE_RESULT: usize = 300; pub fn generate_utxo_storage_key(txid: String, vout: u32) -> String { format!( "{}{}{}", txid, UTXO_STORAGE_KEY_TAG, vout.to_string().as_str() ) } pub fn to_nano(sec: u32) -> Timestamp { Timestamp::from(sec) * 10u64.pow(9) } pub fn nano_to_sec(nano: u64) -> u32 { u32::try_from(nano / 10u64.pow(9)) .unwrap_or_else(|_| env::panic_str("Timestamp overflow when converting nano to sec")) } pub mod u64_dec_format { use near_sdk::serde::de; use near_sdk::serde::{Deserialize, Deserializer, Serializer}; pub fn serialize(num: &u64, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&num.to_string()) } pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { String::deserialize(deserializer)? .parse() .map_err(de::Error::custom) } } pub mod u128_dec_format { use near_sdk::serde::de; use near_sdk::serde::{Deserialize, Deserializer, Serializer}; pub fn serialize(num: &u128, serializer: S) -> Result where S: Serializer, { serializer.serialize_str(&num.to_string()) } pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { String::deserialize(deserializer)? .parse() .map_err(de::Error::custom) } } pub mod u128_dec_format_option { use near_sdk::serde::de; use near_sdk::serde::{Deserialize, Deserializer, Serializer}; pub fn serialize(value: &Option, serializer: S) -> Result where S: Serializer, { match value { Some(num) => serializer.serialize_some(&num.to_string()), None => serializer.serialize_none(), } } pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { let s: Option = Option::deserialize(deserializer)?; match s { Some(s) => s.parse().map(Some).map_err(de::Error::custom), None => Ok(None), } } } pub fn verify_secp256k1_signature(public_key: &Vec, message: &str, signature: &[u8]) -> bool { let mut recovery_id = signature[0]; if recovery_id >= 31 { recovery_id -= 31; } else { recovery_id -= 27; } let msg_hash = bitcoin::sign_message::signed_msg_hash(message).to_byte_array(); let recovered_pk = env::ecrecover(&msg_hash, &signature[1..65], recovery_id, true) .unwrap() .to_vec(); &recovered_pk == public_key }