github.com/hyperledger/aries-framework-go@v0.3.2/pkg/client/outofbandv2/client.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package outofbandv2
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"github.com/google/uuid"
    13  
    14  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    15  	oobv2 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/outofbandv2"
    16  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
    17  	"github.com/hyperledger/aries-framework-go/pkg/kms"
    18  )
    19  
    20  const (
    21  	// InvitationMsgType is the 'type' for the invitation message.
    22  	InvitationMsgType = oobv2.InvitationMsgType
    23  )
    24  
    25  // MessageOption allow you to customize the way out-of-band messages are built.
    26  type MessageOption func(*message)
    27  
    28  type message struct {
    29  	Label              string
    30  	Goal               string
    31  	GoalCode           string
    32  	From               string
    33  	RouterConnections  []string
    34  	Service            []interface{}
    35  	HandshakeProtocols []string
    36  	Attachments        []*decorator.AttachmentV2
    37  	Accept             []string
    38  }
    39  
    40  // OobService defines the outofband service.
    41  type OobService interface {
    42  	AcceptInvitation(*oobv2.Invitation, ...oobv2.AcceptOption) (string, error)
    43  	SaveInvitation(inv *oobv2.Invitation) error
    44  }
    45  
    46  // Provider provides the dependencies for the client.
    47  type Provider interface {
    48  	ServiceEndpoint() string
    49  	Service(id string) (interface{}, error)
    50  	KMS() kms.KeyManager
    51  	KeyType() kms.KeyType
    52  	KeyAgreementType() kms.KeyType
    53  	MediaTypeProfiles() []string
    54  }
    55  
    56  // Client for the Out-Of-Band protocol:
    57  // https://github.com/hyperledger/aries-rfcs/blob/master/features/0434-outofband/README.md
    58  type Client struct {
    59  	oobService        OobService
    60  	mediaTypeProfiles []string
    61  }
    62  
    63  // New returns a new Client for the Out-Of-Band protocol.
    64  func New(p Provider) (*Client, error) {
    65  	s, err := p.Service(oobv2.Name)
    66  	if err != nil {
    67  		return nil, fmt.Errorf("failed to look up service %s : %w", oobv2.Name, err)
    68  	}
    69  
    70  	oobSvc, ok := s.(OobService)
    71  	if !ok {
    72  		return nil, fmt.Errorf("failed to cast service %s as a dependency", oobv2.Name)
    73  	}
    74  
    75  	mtp := p.MediaTypeProfiles()
    76  
    77  	if len(mtp) == 0 {
    78  		mtp = []string{transport.MediaTypeDIDCommV2Profile}
    79  	}
    80  
    81  	client := &Client{
    82  		oobService:        oobSvc,
    83  		mediaTypeProfiles: mtp,
    84  	}
    85  
    86  	return client, nil
    87  }
    88  
    89  // CreateInvitation creates and saves an out-of-band/v2 invitation.
    90  func (c *Client) CreateInvitation(opts ...MessageOption) (*oobv2.Invitation, error) {
    91  	msg := &message{}
    92  
    93  	for _, opt := range opts {
    94  		opt(msg)
    95  	}
    96  
    97  	inv := &oobv2.Invitation{
    98  		ID:    uuid.New().String(),
    99  		Type:  InvitationMsgType,
   100  		Label: msg.Label,
   101  		From:  msg.From,
   102  		Body: &oobv2.InvitationBody{
   103  			Goal:     msg.Goal,
   104  			GoalCode: msg.GoalCode,
   105  			Accept:   msg.Accept,
   106  		},
   107  		Requests: msg.Attachments,
   108  	}
   109  
   110  	if len(inv.Body.Accept) == 0 {
   111  		inv.Body.Accept = c.mediaTypeProfiles
   112  	}
   113  
   114  	err := c.oobService.SaveInvitation(inv)
   115  	if err != nil {
   116  		return nil, fmt.Errorf("out-of-band/2.0 service failed to save invitation : %w", err)
   117  	}
   118  
   119  	return inv, nil
   120  }
   121  
   122  // AcceptInvitation from another agent and return the ID of the new connection records.
   123  func (c *Client) AcceptInvitation(i *oobv2.Invitation, opts ...oobv2.AcceptOption) (string, error) {
   124  	connID, err := c.oobService.AcceptInvitation(i, opts...)
   125  	if err != nil {
   126  		return "", fmt.Errorf("out-of-band/2.0 service failed to accept invitation : %w", err)
   127  	}
   128  
   129  	return connID, nil
   130  }
   131  
   132  // WithLabel allows you to specify the label on the message.
   133  func WithLabel(l string) MessageOption {
   134  	return func(m *message) {
   135  		m.Label = l
   136  	}
   137  }
   138  
   139  // WithFrom allows you to specify the sender's DID on the message.
   140  func WithFrom(f string) MessageOption {
   141  	return func(m *message) {
   142  		m.From = f
   143  	}
   144  }
   145  
   146  // WithGoal allows you to specify the `goal` and `goalCode` for the message.
   147  func WithGoal(goal, goalCode string) MessageOption {
   148  	return func(m *message) {
   149  		m.Goal = goal
   150  		m.GoalCode = goalCode
   151  	}
   152  }
   153  
   154  // WithAttachments allows you to include attachments in the Invitation.
   155  func WithAttachments(a ...*decorator.AttachmentV2) MessageOption {
   156  	return func(m *message) {
   157  		m.Attachments = a
   158  	}
   159  }
   160  
   161  // WithAccept will set the given media type profiles in the Invitation's `accept` property.
   162  // Only valid values from RFC 0044 are supported.
   163  func WithAccept(a ...string) MessageOption {
   164  	return func(m *message) {
   165  		m.Accept = a
   166  	}
   167  }