122 lines
3.9 KiB
Rust
122 lines
3.9 KiB
Rust
//! `Pubkey` Javascript interface
|
|
#![cfg(target_arch = "wasm32")]
|
|
#![allow(non_snake_case)]
|
|
use {
|
|
crate::{pubkey::*, wasm::display_to_jsvalue},
|
|
js_sys::{Array, Uint8Array},
|
|
wasm_bindgen::{prelude::*, JsCast},
|
|
};
|
|
|
|
fn js_value_to_seeds_vec(array_of_uint8_arrays: &[JsValue]) -> Result<Vec<Vec<u8>>, JsValue> {
|
|
let vec_vec_u8 = array_of_uint8_arrays
|
|
.iter()
|
|
.filter_map(|u8_array| {
|
|
u8_array
|
|
.dyn_ref::<Uint8Array>()
|
|
.map(|u8_array| u8_array.to_vec())
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
if vec_vec_u8.len() != array_of_uint8_arrays.len() {
|
|
Err("Invalid Array of Uint8Arrays".into())
|
|
} else {
|
|
Ok(vec_vec_u8)
|
|
}
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
impl Pubkey {
|
|
/// Create a new Pubkey object
|
|
///
|
|
/// * `value` - optional public key as a base58 encoded string, `Uint8Array`, `[number]`
|
|
#[wasm_bindgen(constructor)]
|
|
pub fn constructor(value: JsValue) -> Result<Pubkey, JsValue> {
|
|
if let Some(base58_str) = value.as_string() {
|
|
base58_str.parse::<Pubkey>().map_err(display_to_jsvalue)
|
|
} else if let Some(uint8_array) = value.dyn_ref::<Uint8Array>() {
|
|
Ok(Pubkey::new(&uint8_array.to_vec()))
|
|
} else if let Some(array) = value.dyn_ref::<Array>() {
|
|
let mut bytes = vec![];
|
|
let iterator = js_sys::try_iter(&array.values())?.expect("array to be iterable");
|
|
for x in iterator {
|
|
let x = x?;
|
|
|
|
if let Some(n) = x.as_f64() {
|
|
if n >= 0. && n <= 255. {
|
|
bytes.push(n as u8);
|
|
continue;
|
|
}
|
|
}
|
|
return Err(format!("Invalid array argument: {:?}", x).into());
|
|
}
|
|
Ok(Pubkey::new(&bytes))
|
|
} else if value.is_undefined() {
|
|
Ok(Pubkey::default())
|
|
} else {
|
|
Err("Unsupported argument".into())
|
|
}
|
|
}
|
|
|
|
/// Return the base58 string representation of the public key
|
|
pub fn toString(&self) -> String {
|
|
self.to_string()
|
|
}
|
|
|
|
/// Check if a `Pubkey` is on the ed25519 curve.
|
|
pub fn isOnCurve(&self) -> bool {
|
|
self.is_on_curve()
|
|
}
|
|
|
|
/// Checks if two `Pubkey`s are equal
|
|
pub fn equals(&self, other: &Pubkey) -> bool {
|
|
self == other
|
|
}
|
|
|
|
/// Return the `Uint8Array` representation of the public key
|
|
pub fn toBytes(&self) -> Box<[u8]> {
|
|
self.0.clone().into()
|
|
}
|
|
|
|
/// Derive a Pubkey from another Pubkey, string seed, and a program id
|
|
pub fn createWithSeed(base: &Pubkey, seed: &str, owner: &Pubkey) -> Result<Pubkey, JsValue> {
|
|
Pubkey::create_with_seed(base, seed, owner).map_err(display_to_jsvalue)
|
|
}
|
|
|
|
/// Derive a program address from seeds and a program id
|
|
pub fn createProgramAddress(
|
|
seeds: Box<[JsValue]>,
|
|
program_id: &Pubkey,
|
|
) -> Result<Pubkey, JsValue> {
|
|
let seeds_vec = js_value_to_seeds_vec(&seeds)?;
|
|
let seeds_slice = seeds_vec
|
|
.iter()
|
|
.map(|seed| seed.as_slice())
|
|
.collect::<Vec<_>>();
|
|
|
|
Pubkey::create_program_address(seeds_slice.as_slice(), program_id)
|
|
.map_err(display_to_jsvalue)
|
|
}
|
|
|
|
/// Find a valid program address
|
|
///
|
|
/// Returns:
|
|
/// * `[PubKey, number]` - the program address and bump seed
|
|
pub fn findProgramAddress(
|
|
seeds: Box<[JsValue]>,
|
|
program_id: &Pubkey,
|
|
) -> Result<JsValue, JsValue> {
|
|
let seeds_vec = js_value_to_seeds_vec(&seeds)?;
|
|
let seeds_slice = seeds_vec
|
|
.iter()
|
|
.map(|seed| seed.as_slice())
|
|
.collect::<Vec<_>>();
|
|
|
|
let (address, bump_seed) = Pubkey::find_program_address(seeds_slice.as_slice(), program_id);
|
|
|
|
let result = Array::new_with_length(2);
|
|
result.set(0, address.into());
|
|
result.set(1, bump_seed.into());
|
|
Ok(result.into())
|
|
}
|
|
}
|