Documentation ¶
Overview ¶
Package issuecredential provides support for the Issue Credential Protocol 2.0: https://github.com/hyperledger/aries-rfcs/blob/master/features/0453-issue-credential-v2/README.md.
Formalizes messages used to issue a credential. The protocol is responsible for orchestrating the message flow according to the RFC.
1. Create your client:
client, err := issuecredential.New(ctx) if err != nil { panic(err) }
2. Register an action event channel.
actions := make(chan service.DIDCommAction) client.RegisterActionEvent(actions)
3. Handle incoming actions.
for { select { case event := <-actions: piid := e.Properties.All()["piid"].(string) if event.Message.Type() == presentproof.ProposeCredentialMsgType { // If Issuer is willing to accept the proposal. client.AcceptProposalV2(piid, &OfferCredentialV2{}) // If Issuer is not willing to accept the proposal. client.DeclineProposal(piid, reason) } if event.Message.Type() == presentproof.OfferCredentialMsgType { // If Holder is willing to accept the offer. client.AcceptOfferV2(piid) // If Holder wants to counter an offer they received with a proposal. client.NegotiateProposalV2(piid, &ProposeCredentialV2{}) // If Holder is not willing to accept the offer. client.DeclineOffer(piid, reason) } if event.Message.Type() == presentproof.RequestCredentialMsgType { // If Issuer is willing to accept the request. client.AcceptRequestV2(piid, &IssueCredentialV2{}) // If Issuer is not willing to accept the request. client.DeclineRequest(piid, reason) } if event.Message.Type() == presentproof.IssueCredentialMsgType { // If Holder is willing to accept the credentials. client.AcceptCredential(piid, names) // If Holder is not willing to accept the credentials. client.DeclineCredential(piid, reason) } if event.Message.Type() == presentproof.ProblemReportMsgType { // Problem report message is triggered to notify client about the error. // In that case, there is only one option - accept it. client.AcceptProblemReport(piid) } } }
How to initiate the protocol? The protocol can be initiated by the Issuer or by the Holder. Issuer initiates the protocol.
client.SendOfferV2(&OfferCredentialV2{}, myDID, theirDID)
Holder initiates the protocol. There are two options of how to initiate the protocol.
- The Holder can begin with a proposal. client.SendProposalV2(&ProposeCredentialV2{}, myDID, theirDID)
- Holder can begin with a request. client.SendRequestV2(&RequestCredentialV2{}, myDID, theirDID)
Index ¶
- func WithFriendlyNames(names ...string) issuecredential.Opt
- func WithIssueCredential(msg *IssueCredential) issuecredential.Opt
- func WithOfferCredential(msg *OfferCredential) issuecredential.Opt
- func WithProposeCredential(msg *ProposeCredential) issuecredential.Opt
- func WithRequestCredential(msg *RequestCredential) issuecredential.Opt
- type AcceptCredentialOptions
- type Action
- type Client
- func (c *Client) AcceptCredential(piID string, options ...AcceptCredentialOptions) error
- func (c *Client) AcceptOffer(piID string, msg *RequestCredential) error
- func (c *Client) AcceptProblemReport(piID string) error
- func (c *Client) AcceptProposal(piID string, msg *OfferCredential) error
- func (c *Client) AcceptRequest(piID string, msg *IssueCredential) error
- func (c *Client) Actions() ([]Action, error)
- func (c *Client) DeclineCredential(piID, reason string) error
- func (c *Client) DeclineOffer(piID, reason string) error
- func (c *Client) DeclineProposal(piID, reason string, options ...IssuerDeclineOptions) error
- func (c *Client) DeclineRequest(piID, reason string, options ...IssuerDeclineOptions) error
- func (c *Client) NegotiateProposal(piID string, msg *ProposeCredential) error
- func (c *Client) SendOffer(offer *OfferCredential, conn *connection.Record) (string, error)
- func (c *Client) SendProposal(proposal *ProposeCredential, conn *connection.Record) (string, error)
- func (c *Client) SendRequest(request *RequestCredential, conn *connection.Record) (string, error)
- type IssueCredential
- type IssueCredentialV2
- type IssueCredentialV3
- type IssuerDeclineOptions
- type OfferCredential
- type OfferCredentialV2
- type OfferCredentialV3
- type ProposeCredential
- type ProposeCredentialV2
- type ProposeCredentialV3
- type ProtocolService
- type Provider
- type RequestCredential
- type RequestCredentialV2
- type RequestCredentialV3
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func WithFriendlyNames ¶
func WithFriendlyNames(names ...string) issuecredential.Opt
WithFriendlyNames allows providing names for the credentials. USAGE: This function should be used when the Holder receives IssueCredential message.
func WithIssueCredential ¶
func WithIssueCredential(msg *IssueCredential) issuecredential.Opt
WithIssueCredential allows providing IssueCredential message USAGE: This message should be provided after receiving a RequestCredential message.
func WithOfferCredential ¶
func WithOfferCredential(msg *OfferCredential) issuecredential.Opt
WithOfferCredential allows providing OfferCredential message USAGE: This message should be provided after receiving a ProposeCredential message.
func WithProposeCredential ¶
func WithProposeCredential(msg *ProposeCredential) issuecredential.Opt
WithProposeCredential allows providing ProposeCredential message USAGE: This message should be provided after receiving an OfferCredential message.
func WithRequestCredential ¶ added in v0.1.5
func WithRequestCredential(msg *RequestCredential) issuecredential.Opt
WithRequestCredential allows providing RequestCredential message USAGE: This message should be provided after receiving an OfferCredential message.
Types ¶
type AcceptCredentialOptions ¶ added in v0.1.8
type AcceptCredentialOptions func(opts *acceptCredentialOpts)
AcceptCredentialOptions is custom option for accepting credential in holder.
func AcceptByFriendlyNames ¶ added in v0.1.8
func AcceptByFriendlyNames(names ...string) AcceptCredentialOptions
AcceptByFriendlyNames option to provide optional friendly names for accepting credentials.
func AcceptBySkippingStorage ¶ added in v0.1.8
func AcceptBySkippingStorage() AcceptCredentialOptions
AcceptBySkippingStorage skips storing incoming credential to storage.
type Client ¶
Client enable access to issuecredential API.
func (*Client) AcceptCredential ¶
func (c *Client) AcceptCredential(piID string, options ...AcceptCredentialOptions) error
AcceptCredential is used when the Holder is willing to accept the IssueCredential. NOTE: For async usage.
func (*Client) AcceptOffer ¶
func (c *Client) AcceptOffer(piID string, msg *RequestCredential) error
AcceptOffer is used when the Holder is willing to accept the offer.
func (*Client) AcceptProblemReport ¶ added in v0.1.4
AcceptProblemReport accepts problem report action.
func (*Client) AcceptProposal ¶
func (c *Client) AcceptProposal(piID string, msg *OfferCredential) error
AcceptProposal is used when the Issuer is willing to accept the proposal. NOTE: For async usage.
func (*Client) AcceptRequest ¶
func (c *Client) AcceptRequest(piID string, msg *IssueCredential) error
AcceptRequest is used when the Issuer is willing to accept the request. NOTE: For async usage.
func (*Client) DeclineCredential ¶
DeclineCredential is used when the Holder does not want to accept the IssueCredential. NOTE: For async usage.
func (*Client) DeclineOffer ¶
DeclineOffer is used when the Holder does not want to accept the offer. NOTE: For async usage.
func (*Client) DeclineProposal ¶
func (c *Client) DeclineProposal(piID, reason string, options ...IssuerDeclineOptions) error
DeclineProposal is used when the Issuer does not want to accept the proposal. NOTE: For async usage.
func (*Client) DeclineRequest ¶
func (c *Client) DeclineRequest(piID, reason string, options ...IssuerDeclineOptions) error
DeclineRequest is used when the Issuer does not want to accept the request. NOTE: For async usage.
func (*Client) NegotiateProposal ¶
func (c *Client) NegotiateProposal(piID string, msg *ProposeCredential) error
NegotiateProposal is used when the Holder wants to negotiate about an offer he received. NOTE: For async usage. This function can be used only after receiving OfferCredential.
func (*Client) SendOffer ¶
func (c *Client) SendOffer(offer *OfferCredential, conn *connection.Record) (string, error)
SendOffer is used by the Issuer to send an offer.
Example ¶
transport := map[string]chan payload{ Alice: make(chan payload), Bob: make(chan payload), } // Alice creates client clientAlice, err := New(mockContext(Alice, transport)) if err != nil { panic(err) } // Alice registers channel for actions. actionsAlice := make(chan service.DIDCommAction) err = clientAlice.RegisterActionEvent(actionsAlice) if err != nil { panic(err) } // Bob creates client. clientBob, err := New(mockContext(Bob, transport)) if err != nil { panic(err) } // Bob registers channel for actions. actionsBob := make(chan service.DIDCommAction) err = clientBob.RegisterActionEvent(actionsBob) if err != nil { panic(err) } go func() { for { var acceptErr error select { case e := <-actionsAlice: acceptErr = clientAlice.AcceptRequest(e.Properties.All()["piid"].(string), &IssueCredential{}) case e := <-actionsBob: acceptErr = clientBob.AcceptOffer(e.Properties.All()["piid"].(string), &RequestCredential{}) } if acceptErr != nil { fmt.Println(acceptErr) } } }() // Alice. waitForAlice := waitForFn(clientAlice) // Bob. waitForBob := waitForFn(clientBob) _, err = clientAlice.SendOffer(&OfferCredential{}, &connection.Record{MyDID: Alice, TheirDID: Bob}) if err != nil { fmt.Println(err) } waitForAlice() waitForBob()
Output: Bob received https://didcomm.org/issue-credential/2.0/offer-credential from Alice Alice received https://didcomm.org/issue-credential/2.0/request-credential from Bob Bob received https://didcomm.org/issue-credential/2.0/issue-credential from Alice Alice received https://didcomm.org/issue-credential/2.0/ack from Bob
func (*Client) SendProposal ¶
func (c *Client) SendProposal(proposal *ProposeCredential, conn *connection.Record) (string, error)
SendProposal is used by the Holder to send a proposal.
Example ¶
nolint: gocyclo
transport := map[string]chan payload{ Alice: make(chan payload), Bob: make(chan payload), } // Alice creates client. clientAlice, err := New(mockContext(Alice, transport)) if err != nil { panic(err) } // Alice registers channel for actions. actionsAlice := make(chan service.DIDCommAction) err = clientAlice.RegisterActionEvent(actionsAlice) if err != nil { panic(err) } // Bob creates client. clientBob, err := New(mockContext(Bob, transport)) if err != nil { panic(err) } // Bob registers channel for actions. actionsBob := make(chan service.DIDCommAction) err = clientBob.RegisterActionEvent(actionsBob) if err != nil { panic(err) } go func() { for { var acceptErr error var e service.DIDCommAction select { case e = <-actionsAlice: case e = <-actionsBob: } piid, ok := e.Properties.All()["piid"].(string) if !ok { fmt.Println("empty piid") } if e.Message.Type() == issuecredential.ProposeCredentialMsgTypeV2 { acceptErr = clientAlice.AcceptProposal(piid, &OfferCredential{}) } if e.Message.Type() == issuecredential.RequestCredentialMsgTypeV2 { acceptErr = clientAlice.AcceptRequest(piid, &IssueCredential{}) } if e.Message.Type() == issuecredential.OfferCredentialMsgTypeV2 { acceptErr = clientBob.AcceptOffer(piid, &RequestCredential{}) } if e.Message.Type() == issuecredential.IssueCredentialMsgTypeV2 { acceptErr = clientBob.AcceptCredential(piid) } if acceptErr != nil { fmt.Println(acceptErr) } } }() // Alice. waitForAlice := waitForFn(clientAlice) // Bob. waitForBob := waitForFn(clientBob) _, err = clientBob.SendProposal(&ProposeCredential{}, &connection.Record{MyDID: Bob, TheirDID: Alice}) if err != nil { fmt.Println(err) } waitForAlice() waitForBob()
Output: Alice received https://didcomm.org/issue-credential/2.0/propose-credential from Bob Bob received https://didcomm.org/issue-credential/2.0/offer-credential from Alice Alice received https://didcomm.org/issue-credential/2.0/request-credential from Bob Bob received https://didcomm.org/issue-credential/2.0/issue-credential from Alice Alice received https://didcomm.org/issue-credential/2.0/ack from Bob
func (*Client) SendRequest ¶
func (c *Client) SendRequest(request *RequestCredential, conn *connection.Record) (string, error)
SendRequest is used by the Holder to send a request.
Example ¶
transport := map[string]chan payload{ Alice: make(chan payload), Bob: make(chan payload), } // Alice creates client. clientAlice, err := New(mockContext(Alice, transport)) if err != nil { panic(err) } // Alice registers channel for actions. actionsAlice := make(chan service.DIDCommAction) err = clientAlice.RegisterActionEvent(actionsAlice) if err != nil { panic(err) } // Bob creates client. clientBob, err := New(mockContext(Bob, transport)) if err != nil { panic(err) } // Bob registers channel for actions. actionsBob := make(chan service.DIDCommAction) err = clientBob.RegisterActionEvent(actionsBob) if err != nil { panic(err) } go func() { for { var acceptErr error select { case e := <-actionsAlice: acceptErr = clientAlice.AcceptRequest(e.Properties.All()["piid"].(string), &IssueCredential{}) case e := <-actionsBob: acceptErr = clientBob.AcceptCredential(e.Properties.All()["piid"].(string)) } if acceptErr != nil { fmt.Println(acceptErr) } } }() // Alice. waitForAlice := waitForFn(clientAlice) // Bob. waitForBob := waitForFn(clientBob) _, err = clientBob.SendRequest(&RequestCredential{}, &connection.Record{MyDID: Bob, TheirDID: Alice}) if err != nil { fmt.Println(err) } waitForAlice() waitForBob()
Output: Alice received https://didcomm.org/issue-credential/2.0/request-credential from Bob Bob received https://didcomm.org/issue-credential/2.0/issue-credential from Alice Alice received https://didcomm.org/issue-credential/2.0/ack from Bob
type IssueCredential ¶
type IssueCredential = issuecredential.IssueCredentialParams
IssueCredential contains as attached payload the credentials being issued and is sent in response to a valid Invitation Credential message.
type IssueCredentialV2 ¶ added in v0.1.8
type IssueCredentialV2 issuecredential.IssueCredentialV2 //nolint: golint
IssueCredentialV2 contains as attached payload the credentials being issued and is sent in response to a valid Invitation Credential message.
type IssueCredentialV3 ¶ added in v0.1.8
type IssueCredentialV3 issuecredential.IssueCredentialV3 //nolint: golint
IssueCredentialV3 contains as attached payload the credentials being issued and is sent in response to a valid Invitation Credential message.
type IssuerDeclineOptions ¶ added in v0.1.8
type IssuerDeclineOptions func(opts *redirectOpts)
IssuerDeclineOptions is custom option for sending web redirect options to holder. https://github.com/hyperledger/aries-rfcs/tree/main/concepts/0700-oob-through-redirect
func RequestRedirect ¶ added in v0.1.8
func RequestRedirect(url string) IssuerDeclineOptions
RequestRedirect option to provide optional redirect URL requesting holder to redirect.
type OfferCredential ¶
type OfferCredential = issuecredential.OfferCredentialParams
OfferCredential is a message sent by the Issuer to the potential Holder, describing the credential they intend to offer and possibly the price they expect to be paid.
type OfferCredentialV2 ¶ added in v0.1.8
type OfferCredentialV2 issuecredential.OfferCredentialV2
OfferCredentialV2 is a message sent by the Issuer to the potential Holder, describing the credential they intend to offer and possibly the price they expect to be paid.
type OfferCredentialV3 ¶ added in v0.1.8
type OfferCredentialV3 issuecredential.OfferCredentialV3
OfferCredentialV3 is a message sent by the Issuer to the potential Holder, describing the credential they intend to offer and possibly the price they expect to be paid.
type ProposeCredential ¶
type ProposeCredential = issuecredential.ProposeCredentialParams
ProposeCredential is an optional message sent by the potential Holder to the Issuer to initiate the protocol or in response to a offer-credential message when the Holder wants some adjustments made to the credential data offered by Issuer.
type ProposeCredentialV2 ¶ added in v0.1.8
type ProposeCredentialV2 issuecredential.ProposeCredentialV2
ProposeCredentialV2 is an optional message sent by the potential Holder to the Issuer to initiate the protocol or in response to a offer-credential message when the Holder wants some adjustments made to the credential data offered by Issuer.
type ProposeCredentialV3 ¶ added in v0.1.8
type ProposeCredentialV3 issuecredential.ProposeCredentialV3
ProposeCredentialV3 is an optional message sent by the potential Holder to the Issuer to initiate the protocol or in response to a offer-credential message when the Holder wants some adjustments made to the credential data offered by Issuer.
type ProtocolService ¶
type ProtocolService interface { service.DIDComm Actions() ([]issuecredential.Action, error) ActionContinue(piID string, opt ...issuecredential.Opt) error ActionStop(piID string, err error, opt ...issuecredential.Opt) error }
ProtocolService defines the issuecredential service.
type Provider ¶
Provider contains dependencies for the issuecredential protocol and is typically created by using aries.Context().
type RequestCredential ¶
type RequestCredential = issuecredential.RequestCredentialParams
RequestCredential is a message sent by the potential Holder to the Issuer, to request the issuance of a credential. Where circumstances do not require a preceding Offer Credential message (e.g., there is no cost to issuance that the Issuer needs to explain in advance, and there is no need for cryptographic negotiation), this message initiates the protocol.
type RequestCredentialV2 ¶ added in v0.1.8
type RequestCredentialV2 issuecredential.RequestCredentialV2
RequestCredentialV2 is a message sent by the potential Holder to the Issuer, to request the issuance of a credential. Where circumstances do not require a preceding Offer Credential message (e.g., there is no cost to issuance that the Issuer needs to explain in advance, and there is no need for cryptographic negotiation), this message initiates the protocol.
type RequestCredentialV3 ¶ added in v0.1.8
type RequestCredentialV3 issuecredential.RequestCredentialV3
RequestCredentialV3 is a message sent by the potential Holder to the Issuer, to request the issuance of a credential. Where circumstances do not require a preceding Offer Credential message (e.g., there is no cost to issuance that the Issuer needs to explain in advance, and there is no need for cryptographic negotiation), this message initiates the protocol.