From 19f77f95be3789bbb7b3235bab7e8dfa94a21b86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoe=20Faltib=C3=A0?= Date: Mon, 26 Oct 2020 14:43:17 +0100 Subject: [PATCH 1/4] Change C bindings parameters --- .../main/java/org/lnpbp/rgbnode/Runtime.java | 9 +- rust-lib/src/lib.rs | 144 ++++++++++++------ 2 files changed, 105 insertions(+), 48 deletions(-) diff --git a/ffi/android/library/src/main/java/org/lnpbp/rgbnode/Runtime.java b/ffi/android/library/src/main/java/org/lnpbp/rgbnode/Runtime.java index 138bbfa..0f6c128 100644 --- a/ffi/android/library/src/main/java/org/lnpbp/rgbnode/Runtime.java +++ b/ffi/android/library/src/main/java/org/lnpbp/rgbnode/Runtime.java @@ -21,8 +21,8 @@ public Runtime(final String network, final String stashEndpoint, final HashMap inputs, List allocate, String invoice, String prototype_psbt, String consignment_file, String transaction_file) throws RuntimeException { final TransferArgs args = new TransferArgs(inputs, allocate, invoice, prototype_psbt, consignment_file, transaction_file); try { - final String jsonArgs = mapper.writeValueAsString(args); - rgb_node.transfer(this.runtime, jsonArgs); + final String inputsStr = mapper.writeValueAsString(inputs); + final String allocateStr = mapper.writeValueAsString(allocate); + rgb_node.transfer(this.runtime, inputsStr, allocateStr, invoice, prototype_psbt, consignment_file, transaction_file); } catch (JsonProcessingException e) { throw new RuntimeException(e); } diff --git a/rust-lib/src/lib.rs b/rust-lib/src/lib.rs index 9e50e33..4dad441 100644 --- a/rust-lib/src/lib.rs +++ b/rust-lib/src/lib.rs @@ -5,6 +5,8 @@ use std::env; use std::ffi::{CStr, CString}; use std::hash::{Hash, Hasher}; use std::os::raw::{c_char, c_void}; +use std::path; +use std::str::FromStr; use log::{info, LevelFilter}; @@ -120,35 +122,41 @@ where } } -#[derive(Debug, Deserialize)] -struct StartRgbArgs { - #[serde(with = "serde_with::rust::display_fromstr")] - network: bp::Chain, - #[serde(with = "serde_with::rust::display_fromstr")] - stash_endpoint: SocketLocator, - contract_endpoints: HashMap, +fn _start_rgb( + network: *mut c_char, + stash_endpoint: *mut c_char, + contract_endpoints: *mut c_char, threaded: bool, - datadir: String, -} + datadir: *mut c_char, +) -> Result { + let c_network = unsafe { CStr::from_ptr(network) }; + let network = bp::Chain::from_str(c_network.to_str().unwrap()).unwrap(); -fn _start_rgb(json: *mut c_char) -> Result { - let config: StartRgbArgs = - serde_json::from_str(ptr_to_string(json)?.as_str()).map_err(|e| format!("{:?}", e))?; - info!("Config: {:?}", config); + let c_stash_endpoint = unsafe { CStr::from_ptr(stash_endpoint) }; + let stash_endpoint = SocketLocator::Posix(path::PathBuf::from( + c_stash_endpoint.to_str().unwrap().to_string(), + )); + + let contract_endpoints: HashMap = + serde_json::from_str(ptr_to_string(contract_endpoints)?.as_str()) + .map_err(|e| format!("{:?}", e))?; + + let c_datadir = unsafe { CStr::from_ptr(datadir) }; + let datadir = c_datadir.to_str().unwrap().to_string(); let config = Config { - network: config.network, - stash_endpoint: config.stash_endpoint, - threaded: config.threaded, - data_dir: config.datadir, - contract_endpoints: config - .contract_endpoints + network: network, + stash_endpoint: stash_endpoint, + contract_endpoints: contract_endpoints .into_iter() .map(|(k, v)| -> Result<_, UrlError> { Ok((k, v.parse()?)) }) .collect::>() .map_err(|e| format!("{:?}", e))?, + threaded: threaded, + data_dir: datadir, }; + info!("{:?}", config); Runtime::init(config).map_err(|e| format!("{:?}", e)) } @@ -165,12 +173,25 @@ fn start_logger() { } #[no_mangle] -pub extern "C" fn start_rgb(json: *mut c_char) -> CResult { +pub extern "C" fn start_rgb( + network: *mut c_char, + stash_endpoint: *mut c_char, + contract_endpoints: *mut c_char, + threaded: bool, + datadir: *mut c_char, +) -> CResult { start_logger(); info!("Starting RGB..."); - _start_rgb(json).into() + _start_rgb( + network, + stash_endpoint, + contract_endpoints, + threaded, + datadir, + ) + .into() } #[derive(Debug, Deserialize)] @@ -214,31 +235,49 @@ pub extern "C" fn issue(runtime: &COpaqueStruct, json: *mut c_char) -> CResult { _issue(runtime, json).into() } -#[derive(Debug, Deserialize)] -struct TransferArgs { - inputs: Vec, - allocate: Vec, - #[serde(with = "serde_with::rust::display_fromstr")] - invoice: Invoice, - prototype_psbt: String, - consignment_file: String, - transaction_file: String, -} - -fn _transfer(runtime: &COpaqueStruct, json: *mut c_char) -> Result<(), String> { +fn _transfer( + runtime: &COpaqueStruct, + inputs: *mut c_char, + allocate: *mut c_char, + invoice: *mut c_char, + prototype_psbt: *mut c_char, + consignment_file: *mut c_char, + transaction_file: *mut c_char, +) -> Result<(), String> { let runtime = Runtime::from_opaque(runtime)?; - let data: TransferArgs = - serde_json::from_str(ptr_to_string(json)?.as_str()).map_err(|e| format!("{:?}", e))?; - info!("{:?}", data); + + let inputs: Vec = + serde_json::from_str(ptr_to_string(inputs)?.as_str()).map_err(|e| format!("{:?}", e))?; + + let allocate: Vec = + serde_json::from_str(ptr_to_string(allocate)?.as_str()).map_err(|e| format!("{:?}", e))?; + + let c_invoice = unsafe { CStr::from_ptr(invoice) }; + let invoice = Invoice::from_str(c_invoice.to_str().unwrap()).unwrap(); + + let c_prototype_psbt = unsafe { CStr::from_ptr(prototype_psbt) }; + let prototype_psbt = c_prototype_psbt.to_str().unwrap().to_string(); + + let c_consignment_file = unsafe { CStr::from_ptr(consignment_file) }; + let consignment_file = c_consignment_file.to_str().unwrap().to_string(); + + let c_transaction_file = unsafe { CStr::from_ptr(transaction_file) }; + let transaction_file = c_transaction_file.to_str().unwrap().to_string(); + + info!( + "TransferArgs {{ inputs: {:?}, allocate: {:?}, invoice: {:?}, prototype_psbt: {:?}, \ + consignment_file: {:?}, transaction_file: {:?} }}", + inputs, allocate, invoice, prototype_psbt, consignment_file, transaction_file + ); runtime .transfer( - data.inputs, - data.allocate, - data.invoice, - data.prototype_psbt, - data.consignment_file, - data.transaction_file, + inputs, + allocate, + invoice, + prototype_psbt, + consignment_file, + transaction_file, ) .map_err(|e| format!("{:?}", e)) .map(|_| ()) @@ -246,6 +285,23 @@ fn _transfer(runtime: &COpaqueStruct, json: *mut c_char) -> Result<(), String> { } #[no_mangle] -pub extern "C" fn transfer(runtime: &COpaqueStruct, json: *mut c_char) -> CResult { - _transfer(runtime, json).into() +pub extern "C" fn transfer( + runtime: &COpaqueStruct, + inputs: *mut c_char, + allocate: *mut c_char, + invoice: *mut c_char, + prototype_psbt: *mut c_char, + consignment_file: *mut c_char, + transaction_file: *mut c_char, +) -> CResult { + _transfer( + runtime, + inputs, + allocate, + invoice, + prototype_psbt, + consignment_file, + transaction_file, + ) + .into() } From 980244cbb3b94f6e9850ce7a066394d5a2d32db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoe=20Faltib=C3=A0?= Date: Mon, 26 Oct 2020 14:46:07 +0100 Subject: [PATCH 2/4] Fix call params on Node.js demo --- demo/nodejs/example.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/demo/nodejs/example.js b/demo/nodejs/example.js index d2c28e9..589f210 100644 --- a/demo/nodejs/example.js +++ b/demo/nodejs/example.js @@ -1,4 +1,4 @@ -const ex = require('../../ffi/nodejs/build/Release/rgb_node'); +const ex = require('../../ffi/nodejs/build/Release/rgb_node') const config = { network: "testnet", @@ -8,9 +8,21 @@ const config = { }, threaded: false, datadir: "/tmp/rgb-node/" -}; +} -ex.start_rgb(JSON.stringify(config)) +const transferData = { + inputs: ["0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4:0"], + allocate: [ + { coins: 100, vout:1, txid: "0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4" } + ], + invoice: "rgb20:outpoint1mzu8vz3jly3rzzkdpph583yahv9wktljtfcln6pe2le6n7ehqulstu967t?amount=5&asset=rgb:id1yqqqxya60n725eszngdx8yvwh3pxyk0sp9fszmzxze3nzhgm76ur4dqf2f7gy", + prototype_psbt: "cHNidP8BAFICAAAAAZ38ZijCbFiZ/hvT3DOGZb/VXXraEPYiCXPfLTht7BJ2AQAAAAD/////AfA9zR0AAAAAFgAUezoAv9wU0neVwrdJAdCdpu8TNXkAAAAATwEENYfPAto/0AiAAAAAlwSLGtBEWx7IJ1UXcnyHtOTrwYogP/oPlMAVZr046QADUbdDiH7h1A3DKmBDck8tZFmztaTXPa7I+64EcvO8Q+IM2QxqT64AAIAAAACATwEENYfPAto/0AiAAAABuQRSQnE5zXjCz/JES+NTzVhgXj5RMoXlKLQH+uP2FzUD0wpel8itvFV9rCrZp+OcFyLrrGnmaLbyZnzB1nHIPKsM2QxqT64AAIABAACAAAEBKwBlzR0AAAAAIgAgLFSGEmxJeAeagU4TcV1l82RZ5NbMre0mbQUIZFuvpjIBBUdSIQKdoSzbWyNWkrkVNq/v5ckcOrlHPY5DtTODarRWKZyIcSEDNys0I07Xz5wf6l0F1EFVeSe+lUKxYusC4ass6AIkwAtSriIGAp2hLNtbI1aSuRU2r+/lyRw6uUc9jkO1M4NqtFYpnIhxENkMak+uAACAAAAAgAAAAAAiBgM3KzQjTtfPnB/qXQXUQVV5J76VQrFi6wLhqyzoAiTACxDZDGpPrgAAgAEAAIAAAAAAACICA57/H1R6HV+S36K6evaslxpL0DukpzSwMVaiVritOh75EO3kXMUAAACAAAAAgAEAAIAA", + consignment_file: "/tmp/rgb-node/output/consignment", + transaction_file: "/tmp/rgb-node/output/transaction" +} + +ex.start_rgb(config.network, config.stash_endpoint, JSON.stringify(config.contract_endpoints), config.threaded, + config.datadir) /*.then(r => ex.issue(r, JSON.stringify({ network: "testnet", ticker: "USDT", @@ -19,14 +31,7 @@ ex.start_rgb(JSON.stringify(config)) allocations: [{ coins: 100, vout:0, txid: "0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4" }], precision: 0, })))*/ - .then(r => ex.transfer(r, JSON.stringify({ - inputs: ["0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4:0"], - allocate: [ - { coins: 100, vout:1, txid: "0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4" } - ], - invoice: "rgb20:outpoint1mzu8vz3jly3rzzkdpph583yahv9wktljtfcln6pe2le6n7ehqulstu967t?amount=5&asset=rgb:id1yqqqxya60n725eszngdx8yvwh3pxyk0sp9fszmzxze3nzhgm76ur4dqf2f7gy", - prototype_psbt: "cHNidP8BAFICAAAAAZ38ZijCbFiZ/hvT3DOGZb/VXXraEPYiCXPfLTht7BJ2AQAAAAD/////AfA9zR0AAAAAFgAUezoAv9wU0neVwrdJAdCdpu8TNXkAAAAATwEENYfPAto/0AiAAAAAlwSLGtBEWx7IJ1UXcnyHtOTrwYogP/oPlMAVZr046QADUbdDiH7h1A3DKmBDck8tZFmztaTXPa7I+64EcvO8Q+IM2QxqT64AAIAAAACATwEENYfPAto/0AiAAAABuQRSQnE5zXjCz/JES+NTzVhgXj5RMoXlKLQH+uP2FzUD0wpel8itvFV9rCrZp+OcFyLrrGnmaLbyZnzB1nHIPKsM2QxqT64AAIABAACAAAEBKwBlzR0AAAAAIgAgLFSGEmxJeAeagU4TcV1l82RZ5NbMre0mbQUIZFuvpjIBBUdSIQKdoSzbWyNWkrkVNq/v5ckcOrlHPY5DtTODarRWKZyIcSEDNys0I07Xz5wf6l0F1EFVeSe+lUKxYusC4ass6AIkwAtSriIGAp2hLNtbI1aSuRU2r+/lyRw6uUc9jkO1M4NqtFYpnIhxENkMak+uAACAAAAAgAAAAAAiBgM3KzQjTtfPnB/qXQXUQVV5J76VQrFi6wLhqyzoAiTACxDZDGpPrgAAgAEAAIAAAAAAACICA57/H1R6HV+S36K6evaslxpL0DukpzSwMVaiVritOh75EO3kXMUAAACAAAAAgAEAAIAA", - consignment_file: "/tmp/rgb-node/output/consignment", - transaction_file: "/tmp/rgb-node/output/transaction" - }))) - .catch(e => console.log(e)); + .then(r => ex.transfer(r, JSON.stringify(transferData.inputs), JSON.stringify(transferData.allocate), + transferData.invoice, transferData.prototype_psbt, transferData.consignment_file, + transferData.transaction_file)) + .catch(e => console.log(e)) From e6b699c12af72110ee94fa54ae6d7d16a60b1ea5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoe=20Faltib=C3=A0?= Date: Mon, 26 Oct 2020 14:46:35 +0100 Subject: [PATCH 3/4] Fix call params on Android demo --- .../app/src/main/java/org/lnpbp/demoapp/MainActivity.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/demo/android/app/src/main/java/org/lnpbp/demoapp/MainActivity.java b/demo/android/app/src/main/java/org/lnpbp/demoapp/MainActivity.java index 3392f91..82cd83c 100644 --- a/demo/android/app/src/main/java/org/lnpbp/demoapp/MainActivity.java +++ b/demo/android/app/src/main/java/org/lnpbp/demoapp/MainActivity.java @@ -39,7 +39,13 @@ public void onClick(View view) { final String consignment_file = getCacheDir().toString() + "/" + UUID.randomUUID().toString(); final String transaction_file = getCacheDir().toString() + "/" + UUID.randomUUID().toString(); - runtime.transfer(Arrays.asList("0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4:0"), Arrays.asList(allocation), "rgb20:outpoint1mzu8vz3jly3rzzkdpph583yahv9wktljtfcln6pe2le6n7ehqulstu967t?amount=5&asset=rgb:id1yqqqxya60n725eszngdx8yvwh3pxyk0sp9fszmzxze3nzhgm76ur4dqf2f7gy", "cHNidP8BAFICAAAAAZ38ZijCbFiZ/hvT3DOGZb/VXXraEPYiCXPfLTht7BJ2AQAAAAD/////AfA9zR0AAAAAFgAUezoAv9wU0neVwrdJAdCdpu8TNXkAAAAATwEENYfPAto/0AiAAAAAlwSLGtBEWx7IJ1UXcnyHtOTrwYogP/oPlMAVZr046QADUbdDiH7h1A3DKmBDck8tZFmztaTXPa7I+64EcvO8Q+IM2QxqT64AAIAAAACATwEENYfPAto/0AiAAAABuQRSQnE5zXjCz/JES+NTzVhgXj5RMoXlKLQH+uP2FzUD0wpel8itvFV9rCrZp+OcFyLrrGnmaLbyZnzB1nHIPKsM2QxqT64AAIABAACAAAEBKwBlzR0AAAAAIgAgLFSGEmxJeAeagU4TcV1l82RZ5NbMre0mbQUIZFuvpjIBBUdSIQKdoSzbWyNWkrkVNq/v5ckcOrlHPY5DtTODarRWKZyIcSEDNys0I07Xz5wf6l0F1EFVeSe+lUKxYusC4ass6AIkwAtSriIGAp2hLNtbI1aSuRU2r+/lyRw6uUc9jkO1M4NqtFYpnIhxENkMak+uAACAAAAAgAAAAAAiBgM3KzQjTtfPnB/qXQXUQVV5J76VQrFi6wLhqyzoAiTACxDZDGpPrgAAgAEAAIAAAAAAACICA57/H1R6HV+S36K6evaslxpL0DukpzSwMVaiVritOh75EO3kXMUAAACAAAAAgAEAAIAA", 465, "0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4:2", consignment_file, transaction_file); + runtime.transfer( + Arrays.asList("0313ba7cfcaa66029a1a63918ebc426259f00953016c461663315d1bf6b83ab4:0"), + Arrays.asList(allocation), + "rgb20:outpoint1mzu8vz3jly3rzzkdpph583yahv9wktljtfcln6pe2le6n7ehqulstu967t?amount=5&asset=rgb:id1yqqqxya60n725eszngdx8yvwh3pxyk0sp9fszmzxze3nzhgm76ur4dqf2f7gy", + "cHNidP8BAFICAAAAAZ38ZijCbFiZ/hvT3DOGZb/VXXraEPYiCXPfLTht7BJ2AQAAAAD/////AfA9zR0AAAAAFgAUezoAv9wU0neVwrdJAdCdpu8TNXkAAAAATwEENYfPAto/0AiAAAAAlwSLGtBEWx7IJ1UXcnyHtOTrwYogP/oPlMAVZr046QADUbdDiH7h1A3DKmBDck8tZFmztaTXPa7I+64EcvO8Q+IM2QxqT64AAIAAAACATwEENYfPAto/0AiAAAABuQRSQnE5zXjCz/JES+NTzVhgXj5RMoXlKLQH+uP2FzUD0wpel8itvFV9rCrZp+OcFyLrrGnmaLbyZnzB1nHIPKsM2QxqT64AAIABAACAAAEBKwBlzR0AAAAAIgAgLFSGEmxJeAeagU4TcV1l82RZ5NbMre0mbQUIZFuvpjIBBUdSIQKdoSzbWyNWkrkVNq/v5ckcOrlHPY5DtTODarRWKZyIcSEDNys0I07Xz5wf6l0F1EFVeSe+lUKxYusC4ass6AIkwAtSriIGAp2hLNtbI1aSuRU2r+/lyRw6uUc9jkO1M4NqtFYpnIhxENkMak+uAACAAAAAgAAAAAAiBgM3KzQjTtfPnB/qXQXUQVV5J76VQrFi6wLhqyzoAiTACxDZDGpPrgAAgAEAAIAAAAAAACICA57/H1R6HV+S36K6evaslxpL0DukpzSwMVaiVritOh75EO3kXMUAAACAAAAAgAEAAIAA", + consignment_file, + transaction_file); } catch (RuntimeException e) { Log.e("RGB_NODE", e.getMessage()); } From 118246ef810fd80a68b7f17dcf44b54cc3a8bdaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zoe=20Faltib=C3=A0?= Date: Wed, 28 Oct 2020 12:28:40 +0100 Subject: [PATCH 4/4] Add RequestError for better error handling --- rust-lib/Cargo.lock | 5 +- rust-lib/Cargo.toml | 3 +- rust-lib/src/lib.rs | 140 ++++++++++++++++++++++++++------------------ 3 files changed, 89 insertions(+), 59 deletions(-) diff --git a/rust-lib/Cargo.lock b/rust-lib/Cargo.lock index 9a1105b..35c5482 100644 --- a/rust-lib/Cargo.lock +++ b/rust-lib/Cargo.lock @@ -1518,6 +1518,7 @@ dependencies = [ name = "rgb" version = "0.1.0-rc.1" dependencies = [ + "amplify_derive", "android_logger", "cbindgen", "env_logger", @@ -1533,9 +1534,9 @@ dependencies = [ [[package]] name = "rgb_node" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785fc4d0353f6108d4feb0d341b95140ba68d0e16bf8af7f8865fd212e102a7" +checksum = "3b0bd790a4fa374df1adce53a014df1db0a047dbddb209e6509825f462ec8229" dependencies = [ "amplify", "amplify_derive", diff --git a/rust-lib/Cargo.toml b/rust-lib/Cargo.toml index 7983c30..dd5c7f9 100644 --- a/rust-lib/Cargo.toml +++ b/rust-lib/Cargo.toml @@ -15,8 +15,9 @@ cbindgen = "^0.14" openssl = { version = "^0.10", features = ["vendored"] } [dependencies] +amplify_derive = "~2.0.6" log = "0.4" -rgb_node = "~0.1.0" +rgb_node = "~0.1.1" serde = { version = "~1.0.111", features = ["derive"] } serde_with = "~1.5.0" serde_json = "~1.0.55" diff --git a/rust-lib/src/lib.rs b/rust-lib/src/lib.rs index 4dad441..609cb1b 100644 --- a/rust-lib/src/lib.rs +++ b/rust-lib/src/lib.rs @@ -22,14 +22,19 @@ use rgb::i9n::*; use rgb::rgbd::ContractName; use rgb::util::SealSpec; +#[macro_use] +extern crate amplify_derive; + trait CReturnType: Sized + 'static { - fn from_opaque(other: &COpaqueStruct) -> Result<&mut Self, String> { + fn from_opaque(other: &COpaqueStruct) -> Result<&mut Self, RequestError> { let mut hasher = DefaultHasher::new(); TypeId::of::().hash(&mut hasher); let ty = hasher.finish(); if other.ty != ty { - return Err(String::from("Type mismatch")); + return Err(RequestError::Runtime( + rgb::error::BootstrapError::ArgParseError("Type mismatch".to_string()), + )); } let boxed = unsafe { Box::from_raw(other.ptr.clone() as *mut Self) }; @@ -83,13 +88,8 @@ fn string_to_ptr(other: String) -> *const c_char { cstr.into_raw() } -fn ptr_to_string(ptr: *mut c_char) -> Result { - unsafe { - CStr::from_ptr(ptr) - .to_str() - .map(|s| s.into()) - .map_err(|e| format!("{:?}", e)) - } +fn ptr_to_string(ptr: *mut c_char) -> Result { + unsafe { Ok(CStr::from_ptr(ptr).to_string_lossy().into_owned()) } } #[repr(C)] @@ -122,27 +122,58 @@ where } } +#[derive(Debug, Display, From, Error)] +#[display(doc_comments)] +#[non_exhaustive] +enum RequestError { + /// Input value is not a JSON object or JSON parse error: {_0} + #[from] + Json(serde_json::Error), + + /// Invoice error: {_0} + #[from] + Invoice(rgb::fungible::InvoiceError), + + /// Input value is not a UTF8 string: {_0} + #[from] + Utf8(std::str::Utf8Error), + + /// Invalid network/chain identifier: {_0} + #[from] + ChainParse(rgb::lnpbp::bp::chain::ParseError), + + /// Bootstrap error: {_0} + #[from] + Runtime(rgb::error::BootstrapError), + + /// Url error: {_0} + #[from] + Url(UrlError), + + /// Integration error: {_0} + #[from] + Integration(rgb::i9n::Error), +} + fn _start_rgb( network: *mut c_char, stash_endpoint: *mut c_char, contract_endpoints: *mut c_char, threaded: bool, datadir: *mut c_char, -) -> Result { +) -> Result { let c_network = unsafe { CStr::from_ptr(network) }; - let network = bp::Chain::from_str(c_network.to_str().unwrap()).unwrap(); + let network = bp::Chain::from_str(c_network.to_str()?)?; let c_stash_endpoint = unsafe { CStr::from_ptr(stash_endpoint) }; - let stash_endpoint = SocketLocator::Posix(path::PathBuf::from( - c_stash_endpoint.to_str().unwrap().to_string(), - )); + let stash_endpoint = + SocketLocator::Posix(path::PathBuf::from(c_stash_endpoint.to_str()?.to_string())); let contract_endpoints: HashMap = - serde_json::from_str(ptr_to_string(contract_endpoints)?.as_str()) - .map_err(|e| format!("{:?}", e))?; + serde_json::from_str(&ptr_to_string(contract_endpoints)?)?; let c_datadir = unsafe { CStr::from_ptr(datadir) }; - let datadir = c_datadir.to_str().unwrap().to_string(); + let datadir = c_datadir.to_str()?.to_string(); let config = Config { network: network, @@ -150,14 +181,16 @@ fn _start_rgb( contract_endpoints: contract_endpoints .into_iter() .map(|(k, v)| -> Result<_, UrlError> { Ok((k, v.parse()?)) }) - .collect::>() - .map_err(|e| format!("{:?}", e))?, + .collect::>()?, threaded: threaded, data_dir: datadir, }; info!("{:?}", config); - Runtime::init(config).map_err(|e| format!("{:?}", e)) + + let runtime = Runtime::init(config)?; + + Ok(runtime) } #[cfg(target_os = "android")] @@ -210,24 +243,23 @@ struct IssueArgs { prune_seals: Vec, } -fn _issue(runtime: &COpaqueStruct, json: *mut c_char) -> Result<(), String> { +fn _issue(runtime: &COpaqueStruct, json: *mut c_char) -> Result<(), RequestError> { let runtime = Runtime::from_opaque(runtime)?; - let data: IssueArgs = - serde_json::from_str(ptr_to_string(json)?.as_str()).map_err(|e| format!("{:?}", e))?; + let data: IssueArgs = serde_json::from_str(&ptr_to_string(json)?)?; info!("{:?}", data); - runtime - .issue( - data.network, - data.ticker, - data.name, - data.description, - data.issue_structure, - data.allocations, - data.precision, - data.prune_seals, - ) - .map_err(|e| format!("{:?}", e)) + runtime.issue( + data.network, + data.ticker, + data.name, + data.description, + data.issue_structure, + data.allocations, + data.precision, + data.prune_seals, + )?; + + Ok(()) } #[no_mangle] @@ -243,26 +275,24 @@ fn _transfer( prototype_psbt: *mut c_char, consignment_file: *mut c_char, transaction_file: *mut c_char, -) -> Result<(), String> { +) -> Result<(), RequestError> { let runtime = Runtime::from_opaque(runtime)?; - let inputs: Vec = - serde_json::from_str(ptr_to_string(inputs)?.as_str()).map_err(|e| format!("{:?}", e))?; + let inputs: Vec = serde_json::from_str(&ptr_to_string(inputs)?)?; - let allocate: Vec = - serde_json::from_str(ptr_to_string(allocate)?.as_str()).map_err(|e| format!("{:?}", e))?; + let allocate: Vec = serde_json::from_str(&ptr_to_string(allocate)?)?; let c_invoice = unsafe { CStr::from_ptr(invoice) }; - let invoice = Invoice::from_str(c_invoice.to_str().unwrap()).unwrap(); + let invoice = Invoice::from_str(c_invoice.to_str()?)?; let c_prototype_psbt = unsafe { CStr::from_ptr(prototype_psbt) }; - let prototype_psbt = c_prototype_psbt.to_str().unwrap().to_string(); + let prototype_psbt = c_prototype_psbt.to_str()?.to_string(); let c_consignment_file = unsafe { CStr::from_ptr(consignment_file) }; - let consignment_file = c_consignment_file.to_str().unwrap().to_string(); + let consignment_file = c_consignment_file.to_str()?.to_string(); let c_transaction_file = unsafe { CStr::from_ptr(transaction_file) }; - let transaction_file = c_transaction_file.to_str().unwrap().to_string(); + let transaction_file = c_transaction_file.to_str()?.to_string(); info!( "TransferArgs {{ inputs: {:?}, allocate: {:?}, invoice: {:?}, prototype_psbt: {:?}, \ @@ -270,18 +300,16 @@ fn _transfer( inputs, allocate, invoice, prototype_psbt, consignment_file, transaction_file ); - runtime - .transfer( - inputs, - allocate, - invoice, - prototype_psbt, - consignment_file, - transaction_file, - ) - .map_err(|e| format!("{:?}", e)) - .map(|_| ()) - //.and_then(|r| serde_json::to_string(&r).map_err(|e| format!("{:?}", e))) + runtime.transfer( + inputs, + allocate, + invoice, + prototype_psbt, + consignment_file, + transaction_file, + )?; + + Ok(()) } #[no_mangle]