diff --git a/dojo.h b/dojo.h index 9a4822e..4b6fd3e 100644 --- a/dojo.h +++ b/dojo.h @@ -667,6 +667,14 @@ struct Resultc_char bytearray_deserialize(const struct FieldElement *felts, uint struct FieldElement poseidon_hash(const struct FieldElement *felts, uintptr_t felts_len); +struct ResultFieldElement get_selector_from_name(const char *name); + +struct FieldElement starknet_keccak(const uint8_t *bytes, uintptr_t bytes_len); + +struct ResultFieldElement cairo_short_string_to_felt(const char *str); + +struct Resultc_char parse_cairo_short_string(struct FieldElement felt); + struct ResultFieldElement typed_data_encode(const char *typed_data, struct FieldElement address); struct FieldElement signing_key_new(void); diff --git a/dojo.hpp b/dojo.hpp index f056ac6..b248b98 100644 --- a/dojo.hpp +++ b/dojo.hpp @@ -962,6 +962,14 @@ Result bytearray_deserialize(const FieldElement *felts, uintptr_t f FieldElement poseidon_hash(const FieldElement *felts, uintptr_t felts_len); +Result get_selector_from_name(const char *name); + +FieldElement starknet_keccak(const uint8_t *bytes, uintptr_t bytes_len); + +Result cairo_short_string_to_felt(const char *str); + +Result parse_cairo_short_string(FieldElement felt); + Result typed_data_encode(const char *typed_data, FieldElement address); FieldElement signing_key_new(); diff --git a/src/c/mod.rs b/src/c/mod.rs index 47ce3b8..92be21a 100644 --- a/src/c/mod.rs +++ b/src/c/mod.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use cainome::cairo_serde::{self, ByteArray, CairoSerde}; use starknet::accounts::{Account as StarknetAccount, ExecutionEncoding, SingleOwnerAccount}; use starknet::core::types::FunctionCall; -use starknet::core::utils::{get_contract_address, get_selector_from_name}; +use starknet::core::utils::get_contract_address; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Provider as _}; use starknet::signers::{LocalWallet, SigningKey, VerifyingKey}; @@ -307,6 +307,60 @@ pub unsafe extern "C" fn poseidon_hash( (&poseidon_hash_many(&felts)).into() } +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn get_selector_from_name( + name: *const c_char, +) -> Result { + let name = unsafe { CStr::from_ptr(name).to_string_lossy().into_owned() }; + let selector = match starknet::core::utils::get_selector_from_name(name.as_str()) { + Ok(selector) => selector, + Err(e) => return Result::Err(e.into()), + }; + + Result::Ok((&selector).into()) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn starknet_keccak( + bytes: *const u8, + bytes_len: usize, +) -> types::FieldElement { + let bytes = unsafe { std::slice::from_raw_parts(bytes, bytes_len) }; + let hash = starknet::core::utils::starknet_keccak(bytes); + + (&hash).into() +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn cairo_short_string_to_felt( + str: *const c_char, +) -> Result { + let str = unsafe { CStr::from_ptr(str).to_string_lossy().into_owned() }; + let felt = match starknet::core::utils::cairo_short_string_to_felt(str.as_str()) { + Ok(felt) => felt, + Err(e) => return Result::Err(e.into()), + }; + + Result::Ok((&felt).into()) +} + +#[no_mangle] +#[allow(clippy::missing_safety_doc)] +pub unsafe extern "C" fn parse_cairo_short_string( + felt: types::FieldElement, +) -> Result<*const c_char> { + let felt = (&felt).into(); + let str = match starknet::core::utils::parse_cairo_short_string(&felt) { + Ok(str) => str, + Err(e) => return Result::Err(e.into()), + }; + + Result::Ok(CString::new(str).unwrap().into_raw()) +} + #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn typed_data_encode( @@ -491,7 +545,7 @@ pub unsafe extern "C" fn account_deploy_burner( Felt::ONE, // constructor calldata length (1) verifying_key.scalar(), // constructor calldata ], - selector: get_selector_from_name("deployContract").unwrap(), + selector: starknet::core::utils::get_selector_from_name("deployContract").unwrap(), }]); let runtime = match tokio::runtime::Runtime::new() { diff --git a/src/wasm/mod.rs b/src/wasm/mod.rs index 88e27ff..75427a6 100644 --- a/src/wasm/mod.rs +++ b/src/wasm/mod.rs @@ -14,7 +14,7 @@ use starknet::accounts::{ Account as _, ConnectedAccount as _, ExecutionEncoding, SingleOwnerAccount, }; use starknet::core::types::{Felt, FunctionCall}; -use starknet::core::utils::{get_contract_address, get_selector_from_name}; +use starknet::core::utils::get_contract_address; use starknet::providers::jsonrpc::HttpTransport; use starknet::providers::{JsonRpcClient, Provider as _}; use starknet::signers::{LocalWallet, SigningKey, VerifyingKey}; @@ -272,7 +272,7 @@ impl Account { Felt::ONE, // constructor calldata length (1) verifying_key.scalar(), // constructor calldata ], - selector: get_selector_from_name("deployContract").unwrap(), + selector: starknet::core::utils::get_selector_from_name("deployContract").unwrap(), }]); let result = exec.send().await; @@ -358,6 +358,39 @@ pub fn poseidon_hash(inputs: Vec) -> Result { Ok(format!("{:#x}", poseidon_hash_many(&inputs))) } +#[wasm_bindgen(js_name = getSelectorFromName)] +pub fn get_selector_from_name(name: &str) -> Result { + let selector = starknet::core::utils::get_selector_from_name(name) + .map_err(|e| JsValue::from(e.to_string()))?; + Ok(format!("{:#x}", selector)) +} + +#[wasm_bindgen(js_name = starknetKeccak)] +pub fn starknet_keccak(inputs: js_sys::Uint8Array) -> Result { + let inputs = inputs.to_vec(); + + let hash = starknet::core::utils::starknet_keccak(&inputs); + Ok(format!("{:#x}", hash)) +} + +#[wasm_bindgen(js_name = cairoShortStringToFelt)] +pub fn cairo_short_string_to_felt(str: &str) -> Result { + let felt = starknet::core::utils::cairo_short_string_to_felt(str) + .map_err(|e| JsValue::from(e.to_string()))?; + + Ok(format!("{:#x}", felt)) +} + +#[wasm_bindgen(js_name = parseCairoShortString)] +pub fn parse_cairo_short_string(str: &str) -> Result { + let felt = + Felt::from_str(str).map_err(|e| JsValue::from(format!("failed to parse felt: {e}")))?; + let string = starknet::core::utils::parse_cairo_short_string(&felt) + .map_err(|e| JsValue::from(format!("failed to parse cairo short string: {e}")))?; + + Ok(string) +} + #[wasm_bindgen] impl ToriiClient { #[wasm_bindgen(js_name = getEntities)]