use casper_types::{AccessRights, URef as _URef, URefAddr, UREF_ADDR_LENGTH};
use gloo_utils::format::JsValueSerdeExt;
use serde::{Deserialize, Serialize};
use std::ops::Deref;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Debug, Deserialize, Clone, Serialize, Ord, PartialOrd, Eq, PartialEq)]
pub struct URef(_URef);
impl URef {
pub fn new(uref_hex_str: &str, access_rights: u8) -> Result<Self, String> {
let bytes = match hex::decode(uref_hex_str) {
Ok(bytes) => bytes,
Err(err) => {
return Err(format!("Invalid hex string: {err:?}"));
}
};
if bytes.len() != UREF_ADDR_LENGTH {
return Err(String::from("Invalid URefAddr length"));
}
let mut array = [0u8; UREF_ADDR_LENGTH];
array.copy_from_slice(&bytes);
let uref_addr = URefAddr::from(array);
let uref = _URef::new(
uref_addr,
AccessRights::from_bits(access_rights).unwrap_or_default()
);
Ok(URef(uref))
}
pub fn from_formatted_str(formatted_str: &str) -> Result<Self, String> {
let uref = _URef::from_formatted_str(formatted_str)
.map_err(|error| format!("Failed to parse URef from formatted string: {error:?}"))?;
Ok(URef(uref))
}
}
#[wasm_bindgen]
impl URef {
#[wasm_bindgen(constructor)]
pub fn new_js_alias(uref_hex_str: &str, access_rights: u8) -> Result<URef, JsError> {
Self::new(uref_hex_str, access_rights)
.map_err(|err| JsError::new(&format!("Failed to parse URef from hex string: {err:?}")))
}
#[wasm_bindgen(js_name = "fromFormattedStr")]
pub fn from_formatted_str_js_alias(formatted_str: &str) -> Result<URef, JsError> {
Self::from_formatted_str(formatted_str).map_err(|err| {
JsError::new(&format!(
"Failed to parse URef from formatted string: {err:?}"
))
})
}
#[wasm_bindgen(js_name = "fromUint8Array")]
pub fn from_bytes(bytes: Vec<u8>, access_rights: u8) -> Result<Self, JsError> {
if bytes.len() != UREF_ADDR_LENGTH {
return Err(JsError::new(&format!(
"Expected {UREF_ADDR_LENGTH} bytes for URef address, got {}",
bytes.len()
)));
}
let mut address_array = [0u8; 32];
address_array[..bytes.len()].copy_from_slice(&bytes);
Ok(URef(_URef::new(
address_array,
AccessRights::from_bits(access_rights).unwrap_or_default()
)))
}
#[wasm_bindgen(js_name = "toFormattedString")]
pub fn to_formatted_string(&self) -> String {
self.0.to_formatted_string()
}
#[wasm_bindgen(js_name = "toJson")]
pub fn to_json(&self) -> JsValue {
JsValue::from_serde(self).unwrap_or(JsValue::null())
}
}
impl From<_URef> for URef {
fn from(uref: _URef) -> Self {
URef(uref)
}
}
impl From<URef> for _URef {
fn from(uref: URef) -> Self {
uref.0
}
}
impl Deref for URef {
type Target = _URef;
fn deref(&self) -> &Self::Target {
&self.0
}
}