diff --git a/dojo.h b/dojo.h index d4c1f18..315986f 100644 --- a/dojo.h +++ b/dojo.h @@ -547,8 +547,6 @@ struct ResultToriiClient client_new(const char *torii_url, const struct KeysClause *entities, uintptr_t entities_len); -void client_run_relay(struct ToriiClient *client); - struct Resultbool client_on_message(struct ToriiClient *client, void (*callback)(const char *propagation_source, const char *source, @@ -570,8 +568,6 @@ struct ResultCArrayEntity client_entities(struct ToriiClient *client, const stru struct CArrayKeysClause client_subscribed_models(struct ToriiClient *client); -struct Resultbool client_start_subscription(struct ToriiClient *client); - struct WorldMetadata client_metadata(struct ToriiClient *client); struct Resultbool client_add_models_to_sync(struct ToriiClient *client, diff --git a/src/libc.rs b/src/libc.rs index 378cab5..b914572 100644 --- a/src/libc.rs +++ b/src/libc.rs @@ -16,7 +16,6 @@ use starknet_crypto::FieldElement; use std::ffi::{c_void, CStr, CString}; use std::ops::Deref; use std::os::raw::c_char; -use std::thread; use tokio_stream::StreamExt; use torii_client::client::Client as TClient; @@ -47,43 +46,40 @@ pub unsafe extern "C" fn client_new( Some(entities) }; - let world = FieldElement::from_hex_be(world.as_str()); - - if let Err(e) = world { - return Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }); - } - let world = world.unwrap(); + let world = match FieldElement::from_hex_be(world.as_str()) { + Ok(world) => world, + Err(e) => return Result::Err(e.into()), + }; let client_future = TClient::new(torii_url, rpc_url, libp2p_relay_url, world, some_entities); let runtime = tokio::runtime::Runtime::new().unwrap(); - let client = runtime.block_on(client_future).map_err(|e| Error { - message: CString::new(e.to_string()).unwrap().into_raw(), + let client = match runtime.block_on(client_future) { + Ok(client) => client, + Err(e) => return Result::Err(e.into()), + }; + + // Run relay + let relay_runner = client.relay_client_runner(); + runtime.spawn(async move { + relay_runner.lock().await.run().await; }); - if let Err(e) = client { - return Result::Err(e); + // Start subscription + let result = runtime.block_on(client.start_subscription()); + match result { + Ok(sub) => { + runtime.spawn(sub); + } + Err(e) => return Result::Err(e.into()), } - let client = client.unwrap(); Result::Ok(Box::into_raw(Box::new(ToriiClient { inner: client, runtime, }))) } -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn client_run_relay(client: *mut ToriiClient) { - let relay_runner = (*client).inner.relay_client_runner(); - - (*client).runtime.spawn(async move { - relay_runner.lock().await.run().await; - }); -} - #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn client_on_message( @@ -125,13 +121,9 @@ pub unsafe extern "C" fn client_subscribe_topic( let client_future = unsafe { (*client).inner.subscribe_topic(topic) }; - let result = (*client).runtime.block_on(client_future); - - match result { + match (*client).runtime.block_on(client_future) { Ok(_) => Result::Ok(true), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -145,13 +137,9 @@ pub unsafe extern "C" fn client_unsubscribe_topic( let client_future = unsafe { (*client).inner.unsubscribe_topic(topic) }; - let result = (*client).runtime.block_on(client_future); - - match result { + match (*client).runtime.block_on(client_future) { Ok(_) => Result::Ok(true), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -167,13 +155,9 @@ pub unsafe extern "C" fn client_publish_message( let client_future = unsafe { (*client).inner.publish_message(topic.as_str(), data) }; - let result = (*client).runtime.block_on(client_future); - - match result { - Ok(_) => Result::Ok(result.unwrap().into()), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + match (*client).runtime.block_on(client_future) { + Ok(data) => Result::Ok(data.into()), + Err(e) => Result::Err(e.into()), } } @@ -186,9 +170,7 @@ pub unsafe extern "C" fn client_model( let keys = (&keys.clone()).into(); let entity_future = unsafe { (*client).inner.model(&keys) }; - let result = (*client).runtime.block_on(entity_future); - - match result { + match (*client).runtime.block_on(entity_future) { Ok(ty) => { if let Some(ty) = ty { Result::Ok(COption::Some(Box::into_raw(Box::new((&ty).into())))) @@ -196,9 +178,7 @@ pub unsafe extern "C" fn client_model( Result::Ok(COption::None) } } - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -212,17 +192,13 @@ pub unsafe extern "C" fn client_entities( let entities_future = unsafe { (*client).inner.entities(query) }; - let result = (*client).runtime.block_on(entities_future); - - match result { + match (*client).runtime.block_on(entities_future) { Ok(entities) => { let entities: Vec = entities.into_iter().map(|e| (&e).into()).collect(); Result::Ok(entities.into()) } - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -238,23 +214,6 @@ pub unsafe extern "C" fn client_subscribed_models(client: *mut ToriiClient) -> C entities.into() } -#[no_mangle] -#[allow(clippy::missing_safety_doc)] -pub unsafe extern "C" fn client_start_subscription(client: *mut ToriiClient) -> Result { - let client_future = unsafe { (*client).inner.start_subscription() }; - let result = (*client).runtime.block_on(client_future); - - match result { - Ok(sub) => { - (*client).runtime.spawn(sub); - Result::Ok(true) - } - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), - } -} - #[no_mangle] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn client_metadata(client: *mut ToriiClient) -> WorldMetadata { @@ -276,13 +235,9 @@ pub unsafe extern "C" fn client_add_models_to_sync( .add_models_to_sync(models.iter().map(|e| e.into()).collect()) }; - let result = (*client).runtime.block_on(client_future); - - match result { + match (*client).runtime.block_on(client_future) { Ok(_) => Result::Ok(true), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -296,18 +251,15 @@ pub unsafe extern "C" fn client_on_sync_model_update( let model: torii_grpc::types::KeysClause = (&model).into(); let storage = (*client).inner.storage(); - let rcv = storage.add_listener( + let mut rcv = match storage.add_listener( cairo_short_string_to_felt(model.model.as_str()).unwrap(), model.keys.as_slice(), - ); - if let Err(e) = rcv { - return Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }); - } - let mut rcv = rcv.unwrap(); + ) { + Ok(rcv) => rcv, + Err(e) => return Result::Err(e.into()), + }; - thread::spawn(move || loop { + (*client).runtime.spawn(async move { if let Ok(Some(_)) = rcv.try_next() { callback(); } @@ -329,13 +281,10 @@ pub unsafe extern "C" fn client_on_entity_state_update( let entities = entities.iter().map(|e| (&e.clone()).into()).collect(); let entity_stream = unsafe { (*client).inner.on_entity_updated(entities) }; - let result = (*client).runtime.block_on(entity_stream); - if let Err(e) = result { - return Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }); - } - let mut rcv = result.unwrap(); + let mut rcv = match (*client).runtime.block_on(entity_stream) { + Ok(rcv) => rcv, + Err(e) => return Result::Err(e.into()), + }; (*client).runtime.spawn(async move { while let Some(Ok(entity)) = rcv.next().await { @@ -363,13 +312,9 @@ pub unsafe extern "C" fn client_remove_models_to_sync( .remove_models_to_sync(models.iter().map(|e| e.into()).collect()) }; - let result = (*client).runtime.block_on(client_future); - - match result { + match (*client).runtime.block_on(client_future) { Ok(_) => Result::Ok(true), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -391,9 +336,7 @@ pub unsafe extern "C" fn signing_key_sign( match sig { Ok(sig) => Result::Ok((&sig).into()), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -421,9 +364,7 @@ pub unsafe extern "C" fn verifying_key_verify( match verifying_key.verify(hash, signature) { Ok(result) => Result::Ok(result), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + Err(e) => Result::Err(e.into()), } } @@ -431,13 +372,10 @@ pub unsafe extern "C" fn verifying_key_verify( #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn jsonrpc_client_new(rpc_url: *const c_char) -> Result<*mut CJsonRpcClient> { let rpc_url = unsafe { CStr::from_ptr(rpc_url).to_string_lossy() }; - let rpc_url = url::Url::parse(rpc_url.deref()); - if let Err(e) = rpc_url { - return Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }); - } - let rpc_url = rpc_url.unwrap(); + let rpc_url = match url::Url::parse(rpc_url.deref()) { + Ok(url) => url, + Err(e) => return Result::Err(e.into()), + }; let rpc = JsonRpcClient::new(HttpTransport::new(rpc_url)); @@ -452,27 +390,24 @@ pub unsafe extern "C" fn account_new( address: *const c_char, ) -> Result<*mut Account> { let address = unsafe { CStr::from_ptr(address).to_string_lossy() }; - let address = FieldElement::from_hex_be(address.deref()); - if let Err(e) = address { - return Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }); - } - - let address = address.unwrap(); + let address = match FieldElement::from_hex_be(address.deref()) { + Ok(address) => address, + Err(e) => return Result::Err(e.into()), + }; - let chain_id = tokio::runtime::Runtime::new() - .unwrap() - .block_on((*rpc).0.chain_id()) - .unwrap(); + let chain_id = match tokio::runtime::Runtime::new() { + Ok(runtime) => match runtime.block_on((*rpc).0.chain_id()) { + Ok(chain_id) => chain_id, + Err(e) => return Result::Err(e.into()), + }, + Err(e) => return Result::Err(e.into()), + }; let signer = LocalWallet::from_signing_key(SigningKey::from_secret_scalar((&private_key).into())); let account = SingleOwnerAccount::new(&(*rpc).0, signer, address, chain_id, ExecutionEncoding::New); - // account.set_block_id(starknet::core::types::BlockId::Tag(starknet::core::types::BlockTag::Pending)); - Result::Ok(Box::into_raw(Box::new(Account(account)))) } @@ -515,34 +450,22 @@ pub unsafe extern "C" fn account_deploy_burner( selector: get_selector_from_name("deployContract").unwrap(), }]); - let result = tokio::runtime::Runtime::new().map_err(|e| Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }); - if let Err(e) = result { - return Result::Err(e); - } - - let result = result.unwrap().block_on(exec.send()); - - if let Err(e) = result { - return Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }); - } + let runtime = match tokio::runtime::Runtime::new() { + Ok(runtime) => runtime, + Err(e) => return Result::Err(e.into()), + }; - let result = result.unwrap(); + let result = match runtime.block_on(exec.send()) { + Ok(result) => result, + Err(e) => return Result::Err(e.into()), + }; - if let Err(e) = tokio::runtime::Runtime::new() - .unwrap() - .block_on(watch_tx(&(*provider).0, result.transaction_hash)) - .map_err(|e| Error { + match runtime.block_on(watch_tx(&(*provider).0, result.transaction_hash)) { + Ok(_) => Result::Ok(Box::into_raw(Box::new(Account(account)))), + Err(e) => Result::Err(Error { message: CString::new(e.to_string()).unwrap().into_raw(), - }) - { - return Result::Err(e); + }), } - - Result::Ok(Box::into_raw(Box::new(Account(account)))) } #[no_mangle] @@ -578,15 +501,12 @@ pub unsafe extern "C" fn account_execute_raw( .collect::>(); let call = (*account).0.execute(calldata); - let result = tokio::runtime::Runtime::new() - .unwrap() - .block_on(call.send()); - - match result { - Ok(res) => Result::Ok((&res.transaction_hash).into()), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + match tokio::runtime::Runtime::new() { + Ok(runtime) => match runtime.block_on(call.send()) { + Ok(result) => Result::Ok((&result.transaction_hash).into()), + Err(e) => Result::Err(e.into()), + }, + Err(e) => Result::Err(e.into()), } } @@ -597,15 +517,14 @@ pub unsafe extern "C" fn wait_for_transaction( txn_hash: types::FieldElement, ) -> Result { let txn_hash = (&txn_hash).into(); - let result = tokio::runtime::Runtime::new() - .unwrap() - .block_on(watch_tx(&(*rpc).0, txn_hash)); - - match result { - Ok(_) => Result::Ok(true), - Err(e) => Result::Err(Error { - message: CString::new(e.to_string()).unwrap().into_raw(), - }), + match tokio::runtime::Runtime::new() { + Ok(runtime) => match runtime.block_on(watch_tx(&(*rpc).0, txn_hash)) { + Ok(_) => Result::Ok(true), + Err(e) => Result::Err(Error { + message: CString::new(e.to_string()).unwrap().into_raw(), + }), + }, + Err(e) => Result::Err(e.into()), } } diff --git a/src/libwasm.rs b/src/libwasm.rs index ea007dd..4a322e8 100644 --- a/src/libwasm.rs +++ b/src/libwasm.rs @@ -330,13 +330,8 @@ pub async unsafe fn account_new( let chain_id = chain_id.unwrap(); let signer = LocalWallet::from_signing_key(SigningKey::from_secret_scalar(private_key)); - let account = SingleOwnerAccount::new( - &(*rpc).0, - signer, - address, - chain_id, - ExecutionEncoding::New, - ); + let account = + SingleOwnerAccount::new(&(*rpc).0, signer, address, chain_id, ExecutionEncoding::New); Result::Ok(Box::into_raw(Box::new(Account(account)))) } diff --git a/src/types.rs b/src/types.rs index 5c240e4..45ef425 100644 --- a/src/types.rs +++ b/src/types.rs @@ -174,6 +174,18 @@ pub struct Error { pub message: *mut c_char, } +// Implement conversion from std::error::Error to Error +impl From for Error +where + T: std::error::Error, +{ + fn from(val: T) -> Self { + Error { + message: CString::new(val.to_string()).unwrap().into_raw(), + } + } +} + #[derive(Clone, Debug)] #[repr(C)] pub struct FieldElement {