From 928d5ed24f8926de68e5decc5bcb794b0362368e Mon Sep 17 00:00:00 2001 From: Nasr Date: Thu, 8 Aug 2024 15:55:31 -0400 Subject: [PATCH 1/2] feat: add more starknet functions --- src/wasm/mod.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/wasm/mod.rs b/src/wasm/mod.rs index b6def64..203c659 100644 --- a/src/wasm/mod.rs +++ b/src/wasm/mod.rs @@ -13,7 +13,7 @@ use starknet::accounts::{ }; use starknet::core::crypto::Signature; 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}; @@ -658,7 +658,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; @@ -746,6 +746,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 Client { #[wasm_bindgen(js_name = getEntities)] From 798796354d355b02df34c8be70301f68afac3efc Mon Sep 17 00:00:00 2001 From: Nasr Date: Thu, 8 Aug 2024 16:03:38 -0400 Subject: [PATCH 2/2] feat: add to native platforms --- dojo.h | 8 ++++++++ dojo.hpp | 8 ++++++++ src/c/mod.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 2 deletions(-) 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 9ca70b8..7e05d45 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() {