outofbandv2

package
v0.1.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2022 License: Apache-2.0 Imports: 6 Imported by: 13

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

View Source
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 New

func New(p Provider) (*Client, error)

New returns a new Client for the Out-Of-Band protocol.

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.

type Provider

type Provider interface {
	ServiceEndpoint() string
	Service(id string) (interface{}, error)
	KMS() kms.KeyManager
	KeyType() kms.KeyType
	KeyAgreementType() kms.KeyType
	MediaTypeProfiles() []string
}

Provider provides the dependencies for the client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL