From dbce3a736b812b70ceeceeb0fb529055346c4c2a Mon Sep 17 00:00:00 2001 From: George Mulhearn Date: Tue, 26 Sep 2023 18:17:28 +1000 Subject: [PATCH] docco Signed-off-by: George Mulhearn --- .../formats/holder/hyperledger_indy.rs | 13 +++- .../issuance_v2/formats/holder/mod.rs | 2 + .../formats/issuer/hyperledger_indy.rs | 13 +++- .../issuance_v2/formats/issuer/mod.rs | 2 + .../src/protocols/issuance_v2/issuer/mod.rs | 76 +++++++++++++++++++ 5 files changed, 104 insertions(+), 2 deletions(-) diff --git a/aries_vcx/src/protocols/issuance_v2/formats/holder/hyperledger_indy.rs b/aries_vcx/src/protocols/issuance_v2/formats/holder/hyperledger_indy.rs index a8fea5c61b..cbbb82220f 100644 --- a/aries_vcx/src/protocols/issuance_v2/formats/holder/hyperledger_indy.rs +++ b/aries_vcx/src/protocols/issuance_v2/formats/holder/hyperledger_indy.rs @@ -21,7 +21,18 @@ use crate::{ }, }; -// https://github.com/hyperledger/aries-rfcs/blob/b3a3942ef052039e73cd23d847f42947f8287da2/features/0592-indy-attachments/README.md#cred-filter-format +/// Structure which implements [HolderCredentialIssuanceFormat] functionality for the `hlindy/...` +/// family of issue-credential-v2 attachment formats. +/// +/// This implementation expects and creates attachments of the following types: +/// * [ProposeCredentialAttachmentFormatType::HyperledgerIndyCredentialFilter2_0] +/// * [RequestCredentialAttachmentFormatType::HyperledgerIndyCredentialRequest2_0] +/// * [OfferCredentialAttachmentFormatType::HyperledgerIndyCredentialAbstract2_0] +/// * [IssueCredentialAttachmentFormatType::HyperledgerIndyCredential2_0] +/// +/// This is done in accordance to the Aries RFC 0592 Spec: +/// +/// https://github.com/hyperledger/aries-rfcs/blob/b3a3942ef052039e73cd23d847f42947f8287da2/features/0592-indy-attachments/README.md pub struct HyperledgerIndyHolderCredentialIssuanceFormat<'a> { _data: &'a PhantomData<()>, } diff --git a/aries_vcx/src/protocols/issuance_v2/formats/holder/mod.rs b/aries_vcx/src/protocols/issuance_v2/formats/holder/mod.rs index 653e7cf792..f4cae17c26 100644 --- a/aries_vcx/src/protocols/issuance_v2/formats/holder/mod.rs +++ b/aries_vcx/src/protocols/issuance_v2/formats/holder/mod.rs @@ -15,6 +15,8 @@ use crate::{ pub mod hyperledger_indy; pub mod ld_proof_vc; +/// Trait representing some issue-credential-v2 format family, containing methods required by an +/// holder of this format to create attachments of this format. #[async_trait] pub trait HolderCredentialIssuanceFormat { type CreateProposalInput; diff --git a/aries_vcx/src/protocols/issuance_v2/formats/issuer/hyperledger_indy.rs b/aries_vcx/src/protocols/issuance_v2/formats/issuer/hyperledger_indy.rs index 0d01c80e85..f6368bbd4c 100644 --- a/aries_vcx/src/protocols/issuance_v2/formats/issuer/hyperledger_indy.rs +++ b/aries_vcx/src/protocols/issuance_v2/formats/issuer/hyperledger_indy.rs @@ -17,7 +17,18 @@ use crate::{ utils::openssl::encode, }; -// https://github.com/hyperledger/aries-rfcs/blob/b3a3942ef052039e73cd23d847f42947f8287da2/features/0592-indy-attachments/README.md#cred-filter-format +/// Structure which implements [IssuerCredentialIssuanceFormat] functionality for the `hlindy/...` +/// family of issue-credential-v2 attachment formats. +/// +/// This implementation expects and creates attachments of the following types: +/// * [ProposeCredentialAttachmentFormatType::HyperledgerIndyCredentialFilter2_0] +/// * [RequestCredentialAttachmentFormatType::HyperledgerIndyCredentialRequest2_0] +/// * [OfferCredentialAttachmentFormatType::HyperledgerIndyCredentialAbstract2_0] +/// * [IssueCredentialAttachmentFormatType::HyperledgerIndyCredential2_0] +/// +/// This is done in accordance to the Aries RFC 0592 Spec: +/// +/// https://github.com/hyperledger/aries-rfcs/blob/b3a3942ef052039e73cd23d847f42947f8287da2/features/0592-indy-attachments/README.md pub struct HyperledgerIndyIssuerCredentialIssuanceFormat<'a> { _marker: &'a PhantomData<()>, diff --git a/aries_vcx/src/protocols/issuance_v2/formats/issuer/mod.rs b/aries_vcx/src/protocols/issuance_v2/formats/issuer/mod.rs index 2cc2cb37c4..9a054291d9 100644 --- a/aries_vcx/src/protocols/issuance_v2/formats/issuer/mod.rs +++ b/aries_vcx/src/protocols/issuance_v2/formats/issuer/mod.rs @@ -15,6 +15,8 @@ use crate::{ handlers::util::{extract_attachment_as_base64, get_attachment_with_id}, }; +/// Trait representing some issue-credential-v2 format family, containing methods required by an +/// issuer of this format to create attachments of this format. #[async_trait] pub trait IssuerCredentialIssuanceFormat { type ProposalDetails; diff --git a/aries_vcx/src/protocols/issuance_v2/issuer/mod.rs b/aries_vcx/src/protocols/issuance_v2/issuer/mod.rs index 6e01f37b0a..81761b7e7e 100644 --- a/aries_vcx/src/protocols/issuance_v2/issuer/mod.rs +++ b/aries_vcx/src/protocols/issuance_v2/issuer/mod.rs @@ -219,6 +219,16 @@ impl IssuerV2> { Ok((details, preview)) } + /// Respond to a proposal by preparing a new offer. This API can be used repeatedly to negotiate + /// the offer with the holder until an agreement is reached. + /// + /// An offer is prepared in the format of [IssuerCredentialIssuanceFormat], using the provided + /// input data to create it. Additionally, a [CredentialPreviewV2] is attached to give further + /// details to the holder about the offer. + /// + /// In the event of failure, an error is returned which contains the reason for failure + /// and the state machine before any transitions. Consumers should decide whether the failure + /// is terminal, in which case they should prepare a problem report. pub async fn prepare_offer( self, input_data: &T::CreateOfferInput, @@ -256,6 +266,11 @@ impl IssuerV2> { } impl IssuerV2> { + /// Initiate a new [IssuerV2] by preparing a offer message from the provided input for + /// creating a offer with the choosen [IssuerCredentialIssuanceFormat]. + /// + /// Additionally, a [CredentialPreviewV2] is provided to attach more credential information + /// in the offer message payload. pub async fn with_offer( input_data: &T::CreateOfferInput, preview: CredentialPreviewV2, @@ -284,10 +299,20 @@ impl IssuerV2> { }) } + /// Get the prepared offer message which should be sent to the holder. pub fn get_offer(&self) -> &OfferCredentialV2 { &self.state.offer } + /// Receive an incoming [ProposeCredentialV2] message for this protocol. On success, the + /// [IssuerV2] transitions into the [ProposalReceived] state. + /// + /// This API should only be used for proposals which are in response to an ongoing [IssuerV2] + /// protocol thread. New proposals should be received via [IssuerV2::from_proposal]. + /// + /// In the event of failure, an error is returned which contains the reason for failure + /// and the state machine before any transitions. Consumers should decide whether the failure + /// is terminal, in which case they should prepare a problem report. pub fn receive_proposal( self, proposal: ProposeCredentialV2, @@ -315,6 +340,15 @@ impl IssuerV2> { }) } + /// Receive a request in response to an offer that was sent to the holder. + /// + /// This API should only be used for requests that are in response to an ongoing [IssuerV2] + /// protocol thread. To receive new standalone requests, [IssuerV2::from_request] should be + /// used. + /// + /// In the event of failure, an error is returned which contains the reason for failure + /// and the state machine before any transitions. Consumers should decide whether the failure + /// is terminal, in which case they should prepare a problem report. pub fn receive_request( self, request: RequestCredentialV2, @@ -344,6 +378,16 @@ impl IssuerV2> { } impl IssuerV2> { + /// Initialize an [IssuerV2] by receiving a standalone request message from a holder. This API + /// should only be used for standalone requests not in response to an ongoing protocol thread. + /// + /// To receive a request in response to an ongoing protocol thread, the + /// [IssuerV2::receive_request] method should be used. + /// + /// The request should contain an attachment in the suitable [IssuerCredentialIssuanceFormat] + /// format, and the [IssuerCredentialIssuanceFormat] MUST support receiving standalone requests + /// for this function to succeed. Some formats (such as hlindy or anoncreds) do not + /// support this. pub fn from_request(request: RequestCredentialV2) -> VcxResult { if !T::supports_request_independent_of_offer() { return Err(AriesVcxError::from_msg( @@ -365,6 +409,19 @@ impl IssuerV2> { }) } + /// Prepare a credential message in response to a received request. The prepared credential will + /// be in the [IssuerCredentialIssuanceFormat] format, and will be created using the associated + /// input data. + /// + /// Additionally other flags can be attached to the prepared message for the holder. Notably: + /// * `please_ack` - whether the holder should acknowledge that they receive the credential + /// * `replacement_id` - a unique ID which can be used across credential issuances to indicate + /// that this credential should effectively 'replace' the last credential that this issuer + /// issued to them with the same `replacement_id`. + /// + /// In the event of failure, an error is returned which contains the reason for failure + /// and the state machine before any transitions. Consumers should decide whether the failure + /// is terminal, in which case they should prepare a problem report. pub async fn prepare_credential( self, input_data: &T::CreateCredentialInput, @@ -416,18 +473,29 @@ impl IssuerV2> { } impl IssuerV2> { + /// Get the prepared credential message which should be sent to the holder. pub fn get_credential(&self) -> &IssueCredentialV2 { &self.state.credential } + /// Get details about the credential that was prepared. + /// The details are specific to the [IssuerCredentialIssuanceFormat] being used. pub fn get_credential_creation_metadata(&self) -> &T::CreatedCredentialMetadata { &self.state.credential_metadata } + /// Whether or not this [IssuerV2] is expecting an Ack message to complete. pub fn is_expecting_ack(&self) -> bool { self.state.please_ack } + /// Transition into a completed state without receiving an ack message from the holder. + /// + /// In the case where the [IssuerV2] was expecting an ack, this method will fail. + /// + /// In the event of failure, an error is returned which contains the reason for failure + /// and the state machine before any transitions. Consumers should decide whether the failure + /// is terminal, in which case they should prepare a problem report. pub fn complete_without_ack(self) -> VcxSMTransitionResult>, Self> { if self.is_expecting_ack() { return Err(RecoveredSMError { @@ -450,6 +518,11 @@ impl IssuerV2> { }) } + /// Transition into a completed state by receiving an incoming ack message from the holder. + /// + /// In the event of failure, an error is returned which contains the reason for failure + /// and the state machine before any transitions. Consumers should decide whether the failure + /// is terminal, in which case they should prepare a problem report. pub fn complete_with_ack( self, ack: AckCredentialV2, @@ -475,12 +548,15 @@ impl IssuerV2> { } impl IssuerV2 { + /// Get the prepared [CredIssuanceProblemReportV2] to be sent to the holder to report a failure. pub fn get_problem_report(&self) -> &CredIssuanceProblemReportV2 { &self.state.problem_report } } impl IssuerV2 { + /// Transition into the [Failed] state by preparing a problem report message for the holder. + /// The problem report message is generated by using details from the provided [Error]. pub fn prepare_problem_report_with_error(self, err: &E) -> IssuerV2 where E: Error,