Skip to content

Commit d4e6ebc

Browse files
authored
Merge pull request #1 from KitHat/renaming
Add verify functionality for libindy
2 parents 5be018d + a73f5bc commit d4e6ebc

File tree

5 files changed

+305
-4
lines changed

5 files changed

+305
-4
lines changed

libindy/src/api/payments.rs

Lines changed: 149 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ pub type BuildGetTxnFeesReqCB = extern fn(command_handle: i32,
257257
///
258258
/// # Params
259259
/// command_handle: command handle to map callback to context
260-
/// payment_method: payment method to use
261260
/// resp_json: response for Indy request for getting fees
262261
///
263262
/// # Return
@@ -273,6 +272,47 @@ pub type ParseGetTxnFeesResponseCB = extern fn(command_handle: i32,
273272
err: ErrorCode,
274273
fees_json: *const c_char) -> ErrorCode>) -> ErrorCode;
275274

275+
/// Builds Indy request for information to verify the receipt
276+
///
277+
/// # Params
278+
/// command_handle
279+
/// wallet_handle
280+
/// submitter_did
281+
/// receipt -- receipt to verify
282+
///
283+
/// # Return
284+
/// verify_txn_json -- request to be sent to ledger
285+
286+
pub type BuildVerifyReqCB = extern fn(command_handle: i32,
287+
wallet_handle: i32,
288+
submitter_did: *const c_char,
289+
receipt: *const c_char,
290+
cb: Option<extern fn(command_handle_: i32,
291+
err: ErrorCode,
292+
verify_txn_json: *const c_char) -> ErrorCode>) -> ErrorCode;
293+
294+
/// Parses Indy response with information to verify receipt
295+
///
296+
/// # Params
297+
/// command_handle
298+
/// resp_json -- response of the ledger for verify txn
299+
///
300+
/// # Return
301+
/// txn_json: {
302+
/// sources: [<str>, ]
303+
/// receipts: [ {
304+
/// recipient: <str>, // payment address of recipient
305+
/// receipt: <str>, // receipt that can be used for payment referencing and verification
306+
/// amount: <int>, // amount
307+
/// }, ]
308+
/// extra: <str>, //optional data
309+
/// }
310+
pub type ParseVerifyResponseCB = extern fn(command_handle: i32,
311+
resp_json: *const c_char,
312+
cb: Option<extern fn(command_handle_: i32,
313+
err: ErrorCode,
314+
txn_json: *const c_char) -> ErrorCode>) -> ErrorCode;
315+
276316
/// Register custom payment implementation.
277317
///
278318
/// It allows library user to provide custom payment method implementation as set of handlers.
@@ -303,6 +343,8 @@ pub extern fn indy_register_payment_method(command_handle: i32,
303343
build_set_txn_fees_req: Option<BuildSetTxnFeesReqCB>,
304344
build_get_txn_fees_req: Option<BuildGetTxnFeesReqCB>,
305345
parse_get_txn_fees_response: Option<ParseGetTxnFeesResponseCB>,
346+
build_verify_req: Option<BuildVerifyReqCB>,
347+
parse_verify_response: Option<ParseVerifyResponseCB>,
306348
cb: Option<extern fn(command_handle_: i32,
307349
err: ErrorCode)>) -> ErrorCode {
308350
trace!("indy_register_payment_method: >>> payment_method: {:?}", payment_method);
@@ -319,7 +361,9 @@ pub extern fn indy_register_payment_method(command_handle: i32,
319361
check_useful_c_callback!(build_set_txn_fees_req, ErrorCode::CommonInvalidParam11);
320362
check_useful_c_callback!(build_get_txn_fees_req, ErrorCode::CommonInvalidParam12);
321363
check_useful_c_callback!(parse_get_txn_fees_response, ErrorCode::CommonInvalidParam13);
322-
check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam14);
364+
check_useful_c_callback!(build_verify_req, ErrorCode::CommonInvalidParam14);
365+
check_useful_c_callback!(parse_verify_response, ErrorCode::CommonInvalidParam15);
366+
check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam16);
323367

324368
trace!("indy_register_payment_method: entities >>> payment_method: {:?}", payment_method);
325369

@@ -334,7 +378,9 @@ pub extern fn indy_register_payment_method(command_handle: i32,
334378
build_mint_req,
335379
build_set_txn_fees_req,
336380
build_get_txn_fees_req,
337-
parse_get_txn_fees_response
381+
parse_get_txn_fees_response,
382+
build_verify_req,
383+
parse_verify_response,
338384
);
339385
let result =
340386
CommandExecutor::instance().send(
@@ -1014,4 +1060,104 @@ pub extern fn indy_parse_get_txn_fees_response(command_handle: i32,
10141060
trace!("indy_parse_get_txn_fees_response: <<< res: {:?}", res);
10151061

10161062
res
1063+
}
1064+
1065+
/// Builds Indy request for information to verify the receipt
1066+
///
1067+
/// # Params
1068+
/// command_handle
1069+
/// wallet_handle
1070+
/// submitter_did
1071+
/// receipt -- receipt to verify
1072+
///
1073+
/// # Return
1074+
/// verify_txn_json -- request to be sent to ledger
1075+
/// payment_method
1076+
#[no_mangle]
1077+
pub extern fn indy_build_verify_req(command_handle: i32,
1078+
wallet_handle: i32,
1079+
submitter_did: *const c_char,
1080+
receipt: *const c_char,
1081+
cb: Option<extern fn(command_handle_: i32,
1082+
err: ErrorCode,
1083+
verify_txn_json: *const c_char,
1084+
payment_method: *const c_char)>) -> ErrorCode {
1085+
trace!("indy_build_verify_req: >>> wallet_handle {:?}, submitter_did: {:?}, receipt: {:?}", wallet_handle, submitter_did, receipt);
1086+
check_useful_c_str!(submitter_did, ErrorCode::CommonInvalidParam3);
1087+
check_useful_c_str!(receipt, ErrorCode::CommonInvalidParam4);
1088+
check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam5);
1089+
1090+
trace!("indy_build_verify_req: entities >>> wallet_handle {:?}, submitter_did: {:?}, receipt: {:?}", wallet_handle, submitter_did, receipt);
1091+
1092+
let result = CommandExecutor::instance()
1093+
.send(Command::Payments(
1094+
PaymentsCommand::BuildVerifyReq(
1095+
wallet_handle,
1096+
submitter_did,
1097+
receipt,
1098+
Box::new(move |result| {
1099+
let (err, verify_txn_json, payment_method) = result_to_err_code_2!(result, String::new(), String::new());
1100+
trace!("indy_build_verify_req: verify_txn_json: {:?}, payment_method: {:?}", verify_txn_json, payment_method);
1101+
let verify_txn_json = CStringUtils::string_to_cstring(verify_txn_json);
1102+
let payment_method = CStringUtils::string_to_cstring(payment_method);
1103+
cb(command_handle, err, verify_txn_json.as_ptr(), payment_method.as_ptr());
1104+
})
1105+
)));
1106+
1107+
let result = result_to_err_code!(result);
1108+
1109+
trace!("indy_build_verify_req: <<< result: {:?}", result);
1110+
1111+
result
1112+
}
1113+
1114+
/// Parses Indy response with information to verify receipt
1115+
///
1116+
/// # Params
1117+
/// command_handle
1118+
/// payment_method
1119+
/// resp_json -- response of the ledger for verify txn
1120+
///
1121+
/// # Return
1122+
/// txn_json: {
1123+
/// sources: [<str>, ]
1124+
/// receipts: [ {
1125+
/// recipient: <str>, // payment address of recipient
1126+
/// receipt: <str>, // receipt that can be used for payment referencing and verification
1127+
/// amount: <int>, // amount
1128+
/// }, ]
1129+
/// extra: <str>, //optional data
1130+
/// }
1131+
#[no_mangle]
1132+
pub extern fn indy_parse_verify_response(command_handle: i32,
1133+
payment_method: *const c_char,
1134+
resp_json: *const c_char,
1135+
cb: Option<extern fn(command_handle_: i32,
1136+
err: ErrorCode,
1137+
txn_json: *const c_char)>) -> ErrorCode {
1138+
trace!("indy_parse_payment_response: >>> resp_json: {:?}", resp_json);
1139+
check_useful_c_str!(payment_method, ErrorCode::CommonInvalidParam2);
1140+
check_useful_c_str!(resp_json, ErrorCode::CommonInvalidParam3);
1141+
check_useful_c_callback!(cb, ErrorCode::CommonInvalidParam4);
1142+
1143+
trace!("indy_parse_payment_response: entities >>> resp_json: {:?}", resp_json);
1144+
1145+
let result = CommandExecutor::instance()
1146+
.send(Command::Payments(
1147+
PaymentsCommand::ParseVerifyResponse(
1148+
payment_method,
1149+
resp_json,
1150+
Box::new(move |result| {
1151+
let (err, txn_json) = result_to_err_code_1!(result, String::new());
1152+
trace!("indy_build_verify_req: txn_json: {:?}", txn_json);
1153+
let txn_json = CStringUtils::string_to_cstring(txn_json);
1154+
cb(command_handle, err, txn_json.as_ptr());
1155+
})
1156+
)));
1157+
1158+
let result = result_to_err_code!(result);
1159+
1160+
trace!("indy_parse_payment_response: <<< result: {:?}", result);
1161+
1162+
result
10171163
}

libindy/src/commands/payments.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ pub enum PaymentsCommand {
112112
String, //response
113113
Box<Fn(Result<String, IndyError>) + Send>),
114114
ParseGetTxnFeesResponseAck(
115+
i32,
116+
Result<String, PaymentsError>),
117+
BuildVerifyReq(
118+
i32, //wallet_handle
119+
String, //submitter_did
120+
String, //receipt
121+
Box<Fn(Result<(String, String), IndyError>) + Send>),
122+
BuildVerifyReqAck(
123+
i32,
124+
Result<String, PaymentsError>),
125+
ParseVerifyResponse(
126+
String, //payment_method
127+
String, //resp_json
128+
Box<Fn(Result<String, IndyError>) + Send>),
129+
ParseVerifyResponseAck(
115130
i32,
116131
Result<String, PaymentsError>)
117132
}
@@ -231,6 +246,22 @@ impl PaymentsCommandExecutor {
231246
info!(target: "payments_command_executor", "ParseGetTxnFeesResponseAck command received");
232247
self.parse_get_txn_fees_response_ack(cmd_handle, result);
233248
}
249+
PaymentsCommand::BuildVerifyReq(wallet_handle, submitter_did, receipt, cb) => {
250+
info!(target: "payments_command_executor", "BuildVerifyReq command received");
251+
self.build_verify_request(wallet_handle, &submitter_did, &receipt, cb);
252+
}
253+
PaymentsCommand::BuildVerifyReqAck(command_handle, result) => {
254+
info!(target: "payments_command_executor", "BuildVerifyReqAck command received");
255+
self.build_verify_request_ack(command_handle, result);
256+
}
257+
PaymentsCommand::ParseVerifyResponse(payment_method, resp_json, cb) => {
258+
info!(target: "payments_command_executor", "ParseVerifyResponse command received");
259+
self.parse_verify_response(&payment_method, &resp_json, cb);
260+
}
261+
PaymentsCommand::ParseVerifyResponseAck(command_handle, result) => {
262+
info!(target: "payments_command_executor", "ParseVerifyResponseAck command received");
263+
self.parse_verify_response_ack(command_handle, result);
264+
}
234265
}
235266
}
236267

@@ -541,6 +572,50 @@ impl PaymentsCommandExecutor {
541572
trace!("parse_get_txn_fees_response_ack <<<");
542573
}
543574

575+
fn build_verify_request(&self, wallet_handle: i32, submitter_did: &str, receipt: &str, cb: Box<Fn(Result<(String, String), IndyError>) + Send>) {
576+
trace!("build_verify_request >>> wallet_handle: {:?}, submitter_did: {:?}, receipt: {:?}", wallet_handle, submitter_did, receipt);
577+
match self.crypto_service.validate_did(submitter_did).map_err(map_err_err!()) {
578+
Err(err) => return cb(Err(IndyError::from(err))),
579+
_ => ()
580+
}
581+
match self.wallet_service.check(wallet_handle).map_err(map_err_err!()) {
582+
Err(err) => return cb(Err(IndyError::from(err))),
583+
_ => (),
584+
};
585+
586+
let method = match self.payments_service.parse_method_from_payment_address(receipt) {
587+
Ok(method) => method,
588+
Err(err) => {
589+
cb(Err(IndyError::from(err)));
590+
return;
591+
}
592+
};
593+
let method_copy = method.to_string();
594+
self._process_method(
595+
Box::new(move |get_sources_txn_json| cb(get_sources_txn_json.map(|s| (s, method.to_string())))),
596+
&|i| self.payments_service.build_verify_req(i, &method_copy, wallet_handle, &submitter_did, receipt)
597+
);
598+
trace!("build_get_payment_sources_request <<<");
599+
}
600+
601+
fn build_verify_request_ack(&self, cmd_handle: i32, result: Result<String, PaymentsError>) {
602+
trace!("build_verify_request_ack >>> result: {:?}", result);
603+
self._common_ack_payments(cmd_handle, result, "BuildVerifyRequestAck");
604+
trace!("build_verify_request_ack <<<");
605+
}
606+
607+
fn parse_verify_response(&self, type_: &str, resp_json: &str, cb: Box<Fn(Result<String, IndyError>) + Send>) {
608+
trace!("parse_verify_response >>> response: {:?}", resp_json);
609+
self._process_method(cb, &|i| self.payments_service.parse_verify_response(i, type_, resp_json));
610+
trace!("parse_verify_response <<<");
611+
}
612+
613+
fn parse_verify_response_ack(&self, cmd_handle: i32, result: Result<String, PaymentsError>) {
614+
trace!("parse_verify_response_ack >>> result: {:?}", result);
615+
self._common_ack_payments(cmd_handle, result, "ParseVerifyResponseAck");
616+
trace!("parse_verify_response_ack <<<");
617+
}
618+
544619
// HELPERS
545620

546621
fn _process_method(&self, cb: Box<Fn(Result<String, IndyError>) + Send>,

libindy/src/services/payments.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub struct PaymentsMethod {
2929
build_set_txn_fees_req: BuildSetTxnFeesReqCB,
3030
build_get_txn_fees_req: BuildGetTxnFeesReqCB,
3131
parse_get_txn_fees_response: ParseGetTxnFeesResponseCB,
32+
build_verify_req: BuildVerifyReqCB,
33+
parse_verify_response: ParseVerifyResponseCB,
3234
}
3335

3436
pub type PaymentsMethodCBs = PaymentsMethod;
@@ -44,7 +46,9 @@ impl PaymentsMethodCBs {
4446
build_mint_req: BuildMintReqCB,
4547
build_set_txn_fees_req: BuildSetTxnFeesReqCB,
4648
build_get_txn_fees_req: BuildGetTxnFeesReqCB,
47-
parse_get_txn_fees_response: ParseGetTxnFeesResponseCB) -> Self {
49+
parse_get_txn_fees_response: ParseGetTxnFeesResponseCB,
50+
build_verify_req: BuildVerifyReqCB,
51+
parse_verify_response: ParseVerifyResponseCB) -> Self {
4852
PaymentsMethodCBs {
4953
create_address,
5054
add_request_fees,
@@ -57,6 +61,8 @@ impl PaymentsMethodCBs {
5761
build_set_txn_fees_req,
5862
build_get_txn_fees_req,
5963
parse_get_txn_fees_response,
64+
build_verify_req,
65+
parse_verify_response,
6066
}
6167
}
6268
}
@@ -282,6 +288,39 @@ impl PaymentsService {
282288
res
283289
}
284290

291+
pub fn build_verify_req(&self, cmd_handle: i32, type_: &str, wallet_handle: i32, submitter_did: &str, receipt: &str) -> Result<(), PaymentsError> {
292+
trace!("build_verify_req >>> type_: {:?}, wallet_handle: {:?}, submitter_did: {:?}, receipt: {:?}", type_, wallet_handle, submitter_did, receipt);
293+
let build_verify_req: BuildVerifyReqCB = self.methods.borrow().get(type_)
294+
.ok_or(PaymentsError::UnknownType(format!("Unknown payment method {}", type_)))?.build_verify_req;
295+
296+
let submitter_did = CString::new(submitter_did)?;
297+
let receipt = CString::new(receipt)?;
298+
299+
let err = build_verify_req(cmd_handle, wallet_handle, submitter_did.as_ptr(), receipt.as_ptr(), cbs::build_verify_req(cmd_handle));
300+
301+
let res = PaymentsService::consume_result(err);
302+
303+
trace!("build_verify_req <<< result: {:?}", res);
304+
305+
res
306+
}
307+
308+
pub fn parse_verify_response(&self, cmd_handle: i32, type_: &str, resp_json: &str) -> Result<(), PaymentsError> {
309+
trace!("parse_verify_response >>> type_: {:?}, resp_json: {:?}", type_, resp_json);
310+
let parse_verify_response: ParseVerifyResponseCB = self.methods.borrow().get(type_)
311+
.ok_or(PaymentsError::UnknownType(format!("Unknown payment method {}", type_)))?.parse_verify_response;
312+
313+
let resp_json = CString::new(resp_json)?;
314+
315+
let err = parse_verify_response(cmd_handle, resp_json.as_ptr(), cbs::parse_verify_response(cmd_handle));
316+
317+
let res = PaymentsService::consume_result(err);
318+
319+
trace!("parse_verify_response <<< result: {:?}", res);
320+
321+
res
322+
}
323+
285324
pub fn parse_method_from_inputs(&self, inputs: &str) -> Result<String, PaymentsError> {
286325
trace!("parse_method_from_inputs >>> inputs: {:?}", inputs);
287326
let inputs: Vec<&str> = serde_json::from_str(inputs).map_err(|_| PaymentsError::CommonError(CommonError::InvalidStructure("Unable to parse inputs".to_string())))?;
@@ -475,6 +514,18 @@ mod cbs {
475514
send_ack(cmd_handle, Box::new(move |cmd_handle, result| PaymentsCommand::ParseGetTxnFeesResponseAck(cmd_handle, result)))
476515
}
477516

517+
pub fn build_verify_req(cmd_handle: i32) -> Option<extern fn(command_handle: i32,
518+
err: ErrorCode,
519+
c_str: *const c_char) -> ErrorCode> {
520+
send_ack(cmd_handle, Box::new(move |cmd_handle, result| PaymentsCommand::BuildVerifyReqAck(cmd_handle, result)))
521+
}
522+
523+
pub fn parse_verify_response(cmd_handle: i32) -> Option<extern fn(command_handle: i32,
524+
err: ErrorCode,
525+
c_str: *const c_char) -> ErrorCode> {
526+
send_ack(cmd_handle, Box::new(move |cmd_handle, result| PaymentsCommand::ParseVerifyResponseAck(cmd_handle, result)))
527+
}
528+
478529
fn send_ack(cmd_handle: i32, builder: Box<Fn(i32, Result<String, PaymentsError>) -> PaymentsCommand + Send>) -> Option<extern fn(command_handle: i32,
479530
err: ErrorCode,
480531
c_str: *const c_char) -> ErrorCode> {

0 commit comments

Comments
 (0)