Documentation
¶
Overview ¶
Package outofbandv2 provides support for the Out-of-Band protocols following the DIDComm V2 spec: https://identity.foundation/didcomm-messaging/spec/#out-of-band-messages.
Create your client:
ctx := getFrameworkContext() client, err := outofbandv2.New(ctx)
if err != nil {
panic(err)
}
You can create requests and invitations with client.CreateInvitation() and client.AcceptInvitation() respectively.
Unlike other clients in the framework, this client does not trigger events since an OOB V2 messages include a target goal message in the attachment that will be triggered automatically upon the execution of the client.AcceptInvitation() function.
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 ¶
Examples ¶
Constants ¶
const ( // InvitationMsgType is the 'type' for the invitation message. InvitationMsgType = oobv2.InvitationMsgType )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
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 *oobv2.Invitation, opts ...oobv2.AcceptOption) (string, error)
AcceptInvitation from another agent and return the ID of the new connection records.
Example ¶
Example of an edge agent accepting an out-of-band invitation from a router.
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"time"
"github.com/google/uuid"
"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
"github.com/hyperledger/aries-framework-go/pkg/client/didexchange"
"github.com/hyperledger/aries-framework-go/pkg/client/mediator"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
didsvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/didexchange"
routesvc "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator"
oobv2 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
mockdidexchange "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/didexchange"
mockroute "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator"
mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider"
)
const (
// Router is a router that sends an out-of-band/2.0 invitation to the edge agent.
Router = "Router"
// Bob is an edge agent.
Bob = "Bob"
)
var agentActions = make(map[string]chan service.DIDCommAction) //nolint:gochecknoglobals
// Example of an edge agent accepting an out-of-band invitation from a router.
func main() { //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
inv, err := router.CreateInvitation(
WithLabel(Router),
WithAttachments(&decorator.AttachmentV2{
ID: uuid.New().String(),
Data: decorator.AttachmentData{
Base64: base64.StdEncoding.EncodeToString(routeRequest),
},
}),
)
if err != nil {
panic(err)
}
fmt.Printf("%s creates an out-of-band/2.0 invitation message\n", Router)
// the edge agent accepts the outofband invitation
_, err = bob.AcceptInvitation(inv)
if err != nil {
panic(err)
}
fmt.Printf("%s accepts the out-of-band/2.0 invitation received via an out of band channel and got new connID\n", Bob)
done := make(chan struct{}) // ends this example
go func() {
for event := range routerEvents {
if event.Message != nil {
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)
}
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())
}
func getContext(agent string) *mockprovider.Provider {
return &mockprovider.Provider{
KMSValue: &mockkms.KeyManager{},
StorageProviderValue: mem.NewProvider(),
ProtocolStateStorageProviderValue: mem.NewProvider(),
ServiceMap: map[string]interface{}{
oobv2.Name: &stubOOBService{
Event: nil,
acceptInvFunc: func(i *oobv2.Invitation) error {
agentActions[i.Label] <- service.DIDCommAction{
ProtocolName: didsvc.DIDExchange,
Message: service.NewDIDCommMsgMap(&didsvc.Request{
Type: didsvc.RequestMsgType,
Label: agent,
}),
Continue: func(interface{}) {
agentActions[i.Label] <- service.DIDCommAction{
ProtocolName: mediator.ProtocolName,
Message: service.NewDIDCommMsgMap(mediator.NewRequest()),
Continue: func(interface{}) {},
}
},
}
return nil
},
},
didsvc.DIDExchange: &mockdidexchange.MockDIDExchangeSvc{},
routesvc.Coordination: &mockroute.MockMediatorSvc{
RouterEndpoint: "http://routers-r-us.com",
RoutingKeys: []string{"key-1", "key-2"},
},
},
}
}
func makeActionsChannel(agent string) chan service.DIDCommAction {
c := make(chan service.DIDCommAction, 5)
agentActions[agent] = c
return c
}
Output: Router creates an out-of-band/2.0 invitation message Bob accepts the out-of-band/2.0 invitation received via an out of band channel and got new connID Router received https://didcomm.org/didexchange/1.0/request from Bob 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) CreateInvitation ¶
func (c *Client) CreateInvitation(opts ...MessageOption) (*oobv2.Invitation, error)
CreateInvitation creates and saves an out-of-band/v2 invitation.
type MessageOption ¶
type MessageOption func(*message)
MessageOption allow you to customize the way out-of-band messages are built.
func WithAccept ¶
func WithAccept(a ...string) MessageOption
WithAccept will set the given media type profiles in the Invitation's `accept` property. Only valid values from RFC 0044 are supported.
func WithAttachments ¶
func WithAttachments(a ...*decorator.AttachmentV2) MessageOption
WithAttachments allows you to include attachments in the Invitation.
func WithFrom ¶
func WithFrom(f string) MessageOption
WithFrom allows you to specify the sender's DID on the message.
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.
type OobService ¶
type OobService interface {
AcceptInvitation(*oobv2.Invitation, ...oobv2.AcceptOption) (string, error)
SaveInvitation(inv *oobv2.Invitation) error
}
OobService defines the outofband service.