use std::sync::mpsc::{channel}; use std::ffi::{CString}; use indy::api::signus::{ indy_sign, indy_create_and_store_my_did, indy_store_their_did, indy_replace_keys, indy_verify_signature }; use indy::api::ErrorCode; use utils::callback::CallbackUtils; use utils::timeout::TimeoutUtils; pub struct SignusUtils {} impl SignusUtils { pub fn sign(wallet_handle: i32, their_did: &str, msg: &str) -> Result { let (sender, receiver) = channel(); let cb = Box::new(move |err, signature| { sender.send((err, signature)).unwrap(); }); let (command_handle, cb) = CallbackUtils::closure_to_sign_cb(cb); let their_did = CString::new(their_did).unwrap(); let msg = CString::new(msg).unwrap(); let err = indy_sign(command_handle, wallet_handle, their_did.as_ptr(), msg.as_ptr(), cb); if err != ErrorCode::Success { return Err(err); } let (err, signature) = receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); if err != ErrorCode::Success { return Err(err); } Ok(signature) } pub fn create_and_store_my_did(wallet_handle: i32, seed: Option<&str>) -> Result<(String, String, String), ErrorCode> { let (create_and_store_my_did_sender, create_and_store_my_did_receiver) = channel(); let create_and_store_my_did_cb = Box::new(move |err, did, verkey, public_key| { create_and_store_my_did_sender.send((err, did, verkey, public_key)).unwrap(); }); let (create_and_store_my_did_command_handle, create_and_store_my_did_callback) = CallbackUtils::closure_to_create_and_store_my_did_cb(create_and_store_my_did_cb); let my_did_json = seed.map_or("{}".to_string(), |seed| format!("{{\"seed\":\"{}\" }}", seed)); let my_did_json = CString::new(my_did_json).unwrap(); let err = indy_create_and_store_my_did(create_and_store_my_did_command_handle, wallet_handle, my_did_json.as_ptr(), create_and_store_my_did_callback); if err != ErrorCode::Success { return Err(err); } let (err, my_did, my_verkey, my_pk) = create_and_store_my_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); if err != ErrorCode::Success { return Err(err); } Ok((my_did, my_verkey, my_pk)) } pub fn create_my_did(wallet_handle: i32, my_did_json: &str) -> Result<(String, String, String), ErrorCode> { let (sender, receiver) = channel(); let cb = Box::new(move |err, did, verkey, public_key| { sender.send((err, did, verkey, public_key)).unwrap(); }); let (command_handle, cb) = CallbackUtils::closure_to_create_and_store_my_did_cb(cb); let my_did_json = CString::new(my_did_json).unwrap(); let err = indy_create_and_store_my_did(command_handle, wallet_handle, my_did_json.as_ptr(), cb); if err != ErrorCode::Success { return Err(err); } let (err, my_did, my_verkey, my_pk) = receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); if err != ErrorCode::Success { return Err(err); } Ok((my_did, my_verkey, my_pk)) } pub fn store_their_did(wallet_handle: i32, identity_json: &str) -> Result<(), ErrorCode> { let (sender, receiver) = channel(); let cb = Box::new(move |err| { sender.send((err)).unwrap(); }); let (command_handle, cb) = CallbackUtils::closure_to_store_their_did_cb(cb); let identity_json = CString::new(identity_json).unwrap(); let err = indy_store_their_did(command_handle, wallet_handle, identity_json.as_ptr(), cb); if err != ErrorCode::Success { return Err(err); } let err = receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); if err != ErrorCode::Success { return Err(err); } Ok(()) } pub fn store_their_did_from_parts(wallet_handle: i32, their_did: &str, their_pk: &str, their_verkey: &str, endpoint: &str) -> Result<(), ErrorCode> { let (store_their_did_sender, store_their_did_receiver) = channel(); let store_their_did_cb = Box::new(move |err| { store_their_did_sender.send((err)).unwrap(); }); let (store_their_did_command_handle, store_their_did_callback) = CallbackUtils::closure_to_store_their_did_cb(store_their_did_cb); let their_identity_json = format!("{{\"did\":\"{}\",\ \"pk\":\"{}\",\ \"verkey\":\"{}\",\ \"endpoint\":\"{}\"\ }}", their_did, their_pk, their_verkey, endpoint); let their_identity_json = CString::new(their_identity_json).unwrap(); let err = indy_store_their_did(store_their_did_command_handle, wallet_handle, their_identity_json.as_ptr(), store_their_did_callback); if err != ErrorCode::Success { return Err(err); } let err = store_their_did_receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); if err != ErrorCode::Success { return Err(err); } Ok(()) } pub fn replace_keys(wallet_handle: i32, did: &str, identity_json: &str) -> Result<(String, String), ErrorCode> { let (sender, receiver) = channel(); let cb = Box::new(move |err, verkey, public_key| { sender.send((err, verkey, public_key)).unwrap(); }); let (command_handle, cb) = CallbackUtils::closure_to_replace_keys_cb(cb); let did = CString::new(did).unwrap(); let identity_json = CString::new(identity_json).unwrap(); let err = indy_replace_keys(command_handle, wallet_handle, did.as_ptr(), identity_json.as_ptr(), cb); if err != ErrorCode::Success { return Err(err); } let (err, my_verkey, my_pk) = receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); if err != ErrorCode::Success { return Err(err); } Ok((my_verkey, my_pk)) } pub fn verify(wallet_handle: i32, pool_handle: i32, did: &str, signed_msg: &str) -> Result { let (sender, receiver) = channel(); let cb = Box::new(move |err, valid| { sender.send((err, valid)).unwrap(); }); let (command_handle, cb) = CallbackUtils::closure_to_verify_signature_cb(cb); let did = CString::new(did).unwrap(); let signed_msg = CString::new(signed_msg).unwrap(); let err = indy_verify_signature(command_handle, wallet_handle, pool_handle, did.as_ptr(), signed_msg.as_ptr(), cb); if err != ErrorCode::Success { return Err(err); } let (err, valid) = receiver.recv_timeout(TimeoutUtils::long_timeout()).unwrap(); if err != ErrorCode::Success { return Err(err); } Ok(valid) } }