Documentation ¶
Overview ¶
Package outofband provides support for the Out-of-Band protocols: https://github.com/hyperledger/aries-rfcs/blob/master/features/0434-outofband/README.md.
Create your client:
ctx := getFrameworkContext() client, err := outofband.New(ctx)
if err != nil { panic(err) }
You can create requests and invitations with client.CreateRequest() and client.CreateInvitation() respectively.
You can accept out-of-band requests and invitations received via out of band channels. If you have a request or an invitation on hand you can use the client.AcceptRequest() and client.AcceptInvitation() respectively. These return the ID of the newly-created connection record.
If you're expecting to receive out-of-band invitations or requests via a DIDComm channel then you should register to the action event stream and the state event stream:
events := make(chan service.DIDCommAction) err = client.RegisterActionEvent(events)
if err != nil { panic(err) }
states := make(chan service.StateMsg) err = client.RegisterMsgEvent(states)
if err != nil { panic(err) }
for { select { case event := <-events: switch event.Message.Type() { case outofband.RequestMsgType: // inspect the request req := &outofband.Request{} err = event.Message.Decode(req) if err != nil { panic(err) } // accept the request: event.Continue(&outofband.EventOptions{Label: "Bob"}) // OR you may reject this request: // event.Stop(errors.New("rejected")) case outofband.InvitationMsgType: // inspect and handle the out-of-band invitation just like with the // request message above } case state := <-states: // the connection ID is delivered in a PostState if state.Type == service.PostState { props := state.Properties.(outofband.Event) if props.Error() != nil { panic(props.Error()) } // the connection ID connID := props.ConnectionID() } } }
Note: the ouf-of-band protocol results in the execution of other protocols. You need to subscribe to the event and state streams of those protocols as well.
Index ¶
- Constants
- type Action
- type Client
- func (c *Client) AcceptInvitation(i *Invitation, myLabel string, opts ...MessageOption) (string, error)
- func (c *Client) AcceptRequest(r *Request, myLabel string, opts ...MessageOption) (string, error)
- func (c *Client) ActionContinue(piID, label string, opts ...MessageOption) error
- func (c *Client) ActionStop(piID string, err error) error
- func (c *Client) Actions() ([]Action, error)
- func (c *Client) CreateInvitation(protocols []string, opts ...MessageOption) (*Invitation, error)
- func (c *Client) CreateRequest(attchmnts []*decorator.Attachment, opts ...MessageOption) (*Request, error)
- type Event
- type EventOptions
- type Invitation
- type MessageOption
- type OobService
- type Provider
- type Request
Examples ¶
Constants ¶
const ( // RequestMsgType is the request message's '@type'. RequestMsgType = outofband.RequestMsgType // InvitationMsgType is the '@type' for the invitation message. InvitationMsgType = outofband.InvitationMsgType )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
Client for the Out-Of-Band protocol: https://github.com/hyperledger/aries-rfcs/blob/master/features/0434-outofband/README.md
func (*Client) AcceptInvitation ¶
func (c *Client) AcceptInvitation(i *Invitation, myLabel string, opts ...MessageOption) (string, error)
AcceptInvitation from another agent and return the ID of the new connection records.
Example ¶
Example of an edge agent sending an out-of-band request to another edge agent.
{ //nolint:gocyclo,gocognit // set up the router aliceCtx := getContext(Alice) alice, err := New(aliceCtx) if err != nil { panic(err) } aliceDIDs, err := didexchange.New(aliceCtx) if err != nil { panic(err) } aliceRouting, err := mediator.New(aliceCtx) if err != nil { panic(err) } aliceEvents := makeActionsChannel(Alice) err = aliceDIDs.RegisterActionEvent(aliceEvents) if err != nil { panic(err) } err = aliceRouting.RegisterActionEvent(aliceEvents) if err != nil { panic(err) } // set up the edge agent bob, err := New(getContext(Bob)) if err != nil { panic(err) } // alice creates an outofband invitation inv, err := alice.CreateInvitation(nil, WithLabel(Alice)) if err != nil { panic(err) } fmt.Printf("%s creates an out-of-band invitation\n", Alice) // the edge agent accepts the outofband invitation bobConnID, err := bob.AcceptInvitation(inv, Bob) if err != nil { panic(err) } fmt.Printf( "%s accepts the out-of-band invitation received via an out of band channel and created connectionID %s\n", Bob, bobConnID) done := make(chan struct{}) // ends this example go func() { for event := range aliceEvents { fmt.Printf("%s received %s from %s\n", Alice, event.Message.Type(), Bob) if event.ProtocolName == didexchange.ProtocolName && event.Message.Type() == didexchange.RequestMsgType { didExchangeRequest := &didsvc.Request{} err = event.Message.Decode(didExchangeRequest) if err != nil { panic(err) } if didExchangeRequest.Label != Bob { err = fmt.Errorf( "%s expected a didexchange request from %s but got %s", Alice, Bob, didExchangeRequest.Label, ) event.Stop(err) panic(err) } props, ok := event.Properties.(didexchange.Event) if !ok { panic("failed to cast event properties (shouldn't happen)") } fmt.Printf("%s created connectionID %s\n", Alice, props.ConnectionID()) event.Continue(nil) done <- struct{}{} } } }() select { case <-done: case <-time.After(time.Second): // timeout varies in your environment panic("timeout") }
Output: Alice creates an out-of-band invitation Bob accepts the out-of-band invitation received via an out of band channel and created connectionID abcdefg Alice received https://didcomm.org/didexchange/1.0/request from Bob Alice created connectionID xyz
func (*Client) AcceptRequest ¶
AcceptRequest from another agent and return the ID of a new connection record.
Example ¶
Example of an edge agent accepting an out-of-band request from a router.
{ //nolint:gocyclo,gocognit // set up the router routerCtx := getContext(Router) router, err := New(routerCtx) if err != nil { panic(err) } routerDIDs, err := didexchange.New(routerCtx) if err != nil { panic(err) } routerClient, err := mediator.New(routerCtx) if err != nil { panic(err) } routerEvents := makeActionsChannel(Router) err = routerDIDs.RegisterActionEvent(routerEvents) if err != nil { panic(err) } err = routerClient.RegisterActionEvent(routerEvents) if err != nil { panic(err) } // set up the edge agent bobCtx := getContext(Bob) bob, err := New(bobCtx) if err != nil { panic(err) } // router creates the route-request message routeRequest, err := json.Marshal(mediator.NewRequest()) if err != nil { panic(err) } // router creates outofband request and embeds the route-request message in it req, err := router.CreateRequest( []*decorator.Attachment{{ ID: uuid.New().String(), Data: decorator.AttachmentData{ Base64: base64.StdEncoding.EncodeToString(routeRequest), }, }}, WithLabel(Router), ) if err != nil { panic(err) } fmt.Printf("%s creates an out-of-band request with an embedded route-request message\n", Router) // the edge agent accepts the outofband request bobConnID, err := bob.AcceptRequest(req, Bob) if err != nil { panic(err) } fmt.Printf( "%s accepts the out-of-band request received via an out of band channel and created connectionID %s\n", Bob, bobConnID) done := make(chan struct{}) // ends this example go func() { for event := range routerEvents { fmt.Printf("%s received %s from %s\n", Router, event.Message.Type(), Bob) switch event.ProtocolName { case didexchange.ProtocolName: if event.Message.Type() == didexchange.RequestMsgType { didExchangeRequest := &didsvc.Request{} err = event.Message.Decode(didExchangeRequest) if err != nil { panic(err) } if didExchangeRequest.Label != Bob { err = fmt.Errorf( "%s expected a didexchange request from %s but got %s", Router, Bob, didExchangeRequest.Label, ) event.Stop(err) panic(err) } props, ok := event.Properties.(didexchange.Event) if !ok { panic("failed to cast event properties (shouldn't happen)") } fmt.Printf("%s created connectionID %s\n", Router, props.ConnectionID()) event.Continue(nil) } case mediator.ProtocolName: if event.Message.Type() == mediator.RequestMsgType { event.Continue(nil) done <- struct{}{} } } } }() select { case <-done: case <-time.After(time.Second): // timeout varies in your environment panic("timeout") } bobRoutes, err := mediator.New(bobCtx) if err != nil { panic(err) } config, err := bobRoutes.GetConfig("xyz") if err != nil { panic(err) } fmt.Printf( "%s has registered a route on %s with routerEndpoint %s and routingKeys %+v\n", Bob, Router, config.Endpoint(), config.Keys())
Output: Router creates an out-of-band request with an embedded route-request message Bob accepts the out-of-band request received via an out of band channel and created connectionID xyz Router received https://didcomm.org/didexchange/1.0/request from Bob Router created connectionID xyz Router received https://didcomm.org/coordinatemediation/1.0/mediate-request from Bob Bob has registered a route on Router with routerEndpoint http://routers-r-us.com and routingKeys [key-1 key-2]
func (*Client) ActionContinue ¶ added in v0.1.4
func (c *Client) ActionContinue(piID, label string, opts ...MessageOption) error
ActionContinue allows continuing with the protocol after an action event was triggered.
func (*Client) ActionStop ¶ added in v0.1.4
ActionStop stops the protocol after an action event was triggered.
func (*Client) CreateInvitation ¶
func (c *Client) CreateInvitation(protocols []string, opts ...MessageOption) (*Invitation, error)
CreateInvitation creates and saves an out-of-band invitation. Protocols is an optional list of protocol identifier URIs that can be used to form connections. A default will be set if none are provided.
func (*Client) CreateRequest ¶
func (c *Client) CreateRequest(attchmnts []*decorator.Attachment, opts ...MessageOption) (*Request, error)
CreateRequest creates and saves an Out-Of-Band request message. At least one attachment must be provided. Service entries can be optionally provided. If none are provided then a new one will be automatically created for you.
type Event ¶
type Event interface { // ConnectionID of the connection record, once it's created. // This becomes available in a post-state event unless an error condition is encountered. ConnectionID() string // Error is non-nil if an error is encountered. Error() error }
Event is a container of out-of-band protocol-specific properties for DIDCommActions and StateMsgs.
type EventOptions ¶ added in v0.1.4
type EventOptions struct { // Label will be shared with the other agent during the subsequent did-exchange. Label string // Connections allows specifying router connections. Connections []string }
EventOptions are is a container of options that you can pass to an event's Continue function to customize the reaction to incoming out-of-band messages.
func (*EventOptions) MyLabel ¶ added in v0.1.4
func (e *EventOptions) MyLabel() string
MyLabel will be shared with the other agent during the subsequent did-exchange.
func (*EventOptions) RouterConnections ¶ added in v0.1.5
func (e *EventOptions) RouterConnections() []string
RouterConnections return router connections.
type Invitation ¶
type Invitation outofband.Invitation
Invitation is this protocol's `invitation` message.
type MessageOption ¶
type MessageOption func(*message) error
MessageOption allow you to customize the way out-of-band messages are built.
func WithGoal ¶
func WithGoal(goal, goalCode string) MessageOption
WithGoal allows you to specify the `goal` and `goalCode` for the message.
func WithLabel ¶
func WithLabel(l string) MessageOption
WithLabel allows you to specify the label on the message.
func WithRouterConnections ¶ added in v0.1.5
func WithRouterConnections(conn ...string) MessageOption
WithRouterConnections allows you to specify the router connections.
func WithServices ¶
func WithServices(svcs ...interface{}) MessageOption
WithServices allows you to specify service entries to include in the request message. Each entry must be either a valid DID (string) or a `service` object.
type OobService ¶ added in v0.1.4
type OobService interface { service.Event AcceptRequest(*outofband.Request, string, []string) (string, error) AcceptInvitation(*outofband.Invitation, string, []string) (string, error) SaveRequest(*outofband.Request) error SaveInvitation(*outofband.Invitation) error Actions() ([]outofband.Action, error) ActionContinue(string, outofband.Options) error ActionStop(string, error) error }
OobService defines the outofband service.