github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/protocol/didexchange/states_test.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package didexchange
     8  
     9  import (
    10  	"encoding/base64"
    11  	"encoding/json"
    12  	"errors"
    13  	"fmt"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/google/uuid"
    18  	"github.com/stretchr/testify/require"
    19  
    20  	"github.com/hyperledger/aries-framework-go/component/storageutil/mem"
    21  	commonmodel "github.com/hyperledger/aries-framework-go/pkg/common/model"
    22  	"github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto"
    23  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/model"
    24  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    25  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    26  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator"
    27  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
    28  	diddoc "github.com/hyperledger/aries-framework-go/pkg/doc/did"
    29  	vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
    30  	"github.com/hyperledger/aries-framework-go/pkg/kms"
    31  	mockcrypto "github.com/hyperledger/aries-framework-go/pkg/mock/crypto"
    32  	mockdispatcher "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/dispatcher"
    33  	"github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol"
    34  	mockroute "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator"
    35  	mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc"
    36  	mockkms "github.com/hyperledger/aries-framework-go/pkg/mock/kms"
    37  	mockstorage "github.com/hyperledger/aries-framework-go/pkg/mock/storage"
    38  	mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr"
    39  	"github.com/hyperledger/aries-framework-go/pkg/store/connection"
    40  	didstore "github.com/hyperledger/aries-framework-go/pkg/store/did"
    41  	"github.com/hyperledger/aries-framework-go/pkg/vdr/fingerprint"
    42  )
    43  
    44  func TestNoopState(t *testing.T) {
    45  	noop := &noOp{}
    46  	require.Equal(t, "noop", noop.Name())
    47  
    48  	t.Run("must not transition to any state", func(t *testing.T) {
    49  		all := []state{&null{}, &invited{}, &requested{}, &responded{}, &completed{}}
    50  		for _, s := range all {
    51  			require.False(t, noop.CanTransitionTo(s))
    52  		}
    53  	})
    54  }
    55  
    56  // null state can transition to invited state or requested state.
    57  func TestNullState(t *testing.T) {
    58  	nul := &null{}
    59  	require.Equal(t, "null", nul.Name())
    60  	require.False(t, nul.CanTransitionTo(nul))
    61  	require.True(t, nul.CanTransitionTo(&invited{}))
    62  	require.True(t, nul.CanTransitionTo(&requested{}))
    63  	require.False(t, nul.CanTransitionTo(&responded{}))
    64  	require.False(t, nul.CanTransitionTo(&completed{}))
    65  }
    66  
    67  // invited can only transition to requested state.
    68  func TestInvitedState(t *testing.T) {
    69  	inv := &invited{}
    70  	require.Equal(t, "invited", inv.Name())
    71  	require.False(t, inv.CanTransitionTo(&null{}))
    72  	require.False(t, inv.CanTransitionTo(inv))
    73  	require.True(t, inv.CanTransitionTo(&requested{}))
    74  	require.False(t, inv.CanTransitionTo(&responded{}))
    75  	require.False(t, inv.CanTransitionTo(&completed{}))
    76  }
    77  
    78  // requested can only transition to responded state.
    79  func TestRequestedState(t *testing.T) {
    80  	req := &requested{}
    81  	require.Equal(t, "requested", req.Name())
    82  	require.False(t, req.CanTransitionTo(&null{}))
    83  	require.False(t, req.CanTransitionTo(&invited{}))
    84  	require.False(t, req.CanTransitionTo(req))
    85  	require.True(t, req.CanTransitionTo(&responded{}))
    86  	require.False(t, req.CanTransitionTo(&completed{}))
    87  }
    88  
    89  // responded can only transition to completed state.
    90  func TestRespondedState(t *testing.T) {
    91  	res := &responded{}
    92  	require.Equal(t, "responded", res.Name())
    93  	require.False(t, res.CanTransitionTo(&null{}))
    94  	require.False(t, res.CanTransitionTo(&invited{}))
    95  	require.False(t, res.CanTransitionTo(&requested{}))
    96  	require.False(t, res.CanTransitionTo(res))
    97  	require.True(t, res.CanTransitionTo(&completed{}))
    98  }
    99  
   100  // completed is an end state.
   101  func TestCompletedState(t *testing.T) {
   102  	comp := &completed{}
   103  	require.Equal(t, "completed", comp.Name())
   104  	require.False(t, comp.CanTransitionTo(&null{}))
   105  	require.False(t, comp.CanTransitionTo(&invited{}))
   106  	require.False(t, comp.CanTransitionTo(&requested{}))
   107  	require.False(t, comp.CanTransitionTo(&responded{}))
   108  	require.False(t, comp.CanTransitionTo(&abandoned{}))
   109  	require.False(t, comp.CanTransitionTo(comp))
   110  }
   111  
   112  func TestAbandonedState(t *testing.T) {
   113  	ab := &abandoned{}
   114  	require.Equal(t, StateIDAbandoned, ab.Name())
   115  	require.False(t, ab.CanTransitionTo(&null{}))
   116  	require.False(t, ab.CanTransitionTo(&invited{}))
   117  	require.False(t, ab.CanTransitionTo(&requested{}))
   118  	require.False(t, ab.CanTransitionTo(&responded{}))
   119  	require.False(t, ab.CanTransitionTo(&completed{}))
   120  	connRec, _, _, err := ab.ExecuteInbound(&stateMachineMsg{}, "", &context{})
   121  	require.Error(t, err)
   122  	require.Contains(t, err.Error(), "not implemented")
   123  	require.Nil(t, connRec)
   124  }
   125  
   126  func TestStateFromMsgType(t *testing.T) {
   127  	t.Run("invited", func(t *testing.T) {
   128  		expected := &invited{}
   129  		actual, err := stateFromMsgType(InvitationMsgType)
   130  		require.NoError(t, err)
   131  		require.Equal(t, expected.Name(), actual.Name())
   132  	})
   133  	t.Run("requested", func(t *testing.T) {
   134  		expected := &requested{}
   135  		actual, err := stateFromMsgType(RequestMsgType)
   136  		require.NoError(t, err)
   137  		require.Equal(t, expected.Name(), actual.Name())
   138  	})
   139  	t.Run("responded", func(t *testing.T) {
   140  		expected := &responded{}
   141  		actual, err := stateFromMsgType(ResponseMsgType)
   142  		require.NoError(t, err)
   143  		require.Equal(t, expected.Name(), actual.Name())
   144  	})
   145  	t.Run("completed", func(t *testing.T) {
   146  		expected := &completed{}
   147  		actual, err := stateFromMsgType(AckMsgType)
   148  		require.NoError(t, err)
   149  		require.Equal(t, expected.Name(), actual.Name())
   150  	})
   151  	t.Run("invalid", func(t *testing.T) {
   152  		actual, err := stateFromMsgType("invalid")
   153  		require.Nil(t, actual)
   154  		require.Error(t, err)
   155  		require.Contains(t, err.Error(), "unrecognized msgType: invalid")
   156  	})
   157  }
   158  
   159  func TestStateFromName(t *testing.T) {
   160  	t.Run("noop", func(t *testing.T) {
   161  		expected := &noOp{}
   162  		actual, err := stateFromName(expected.Name())
   163  		require.NoError(t, err)
   164  		require.Equal(t, expected.Name(), actual.Name())
   165  	})
   166  	t.Run("null", func(t *testing.T) {
   167  		expected := &null{}
   168  		actual, err := stateFromName(expected.Name())
   169  		require.NoError(t, err)
   170  		require.Equal(t, expected.Name(), actual.Name())
   171  	})
   172  	t.Run("invited", func(t *testing.T) {
   173  		expected := &invited{}
   174  		actual, err := stateFromName(expected.Name())
   175  		require.NoError(t, err)
   176  		require.Equal(t, expected.Name(), actual.Name())
   177  	})
   178  	t.Run("requested", func(t *testing.T) {
   179  		expected := &requested{}
   180  		actual, err := stateFromName(expected.Name())
   181  		require.NoError(t, err)
   182  		require.Equal(t, expected.Name(), actual.Name())
   183  	})
   184  	t.Run("responded", func(t *testing.T) {
   185  		expected := &responded{}
   186  		actual, err := stateFromName(expected.Name())
   187  		require.NoError(t, err)
   188  		require.Equal(t, expected.Name(), actual.Name())
   189  	})
   190  	t.Run("completed", func(t *testing.T) {
   191  		expected := &completed{}
   192  		actual, err := stateFromName(expected.Name())
   193  		require.NoError(t, err)
   194  		require.Equal(t, expected.Name(), actual.Name())
   195  	})
   196  	t.Run("abandoned", func(t *testing.T) {
   197  		expected := &abandoned{}
   198  		actual, err := stateFromName(expected.Name())
   199  		require.NoError(t, err)
   200  		require.Equal(t, expected.Name(), actual.Name())
   201  	})
   202  	t.Run("undefined", func(t *testing.T) {
   203  		actual, err := stateFromName("undefined")
   204  		require.Nil(t, actual)
   205  		require.Error(t, err)
   206  		require.Contains(t, err.Error(), "invalid state name")
   207  	})
   208  }
   209  
   210  // noOp.ExecuteInbound() returns nil, error.
   211  func TestNoOpState_Execute(t *testing.T) {
   212  	_, followup, _, err := (&noOp{}).ExecuteInbound(&stateMachineMsg{}, "", &context{})
   213  	require.Error(t, err)
   214  	require.Contains(t, err.Error(), "cannot execute no-op")
   215  	require.Nil(t, followup)
   216  }
   217  
   218  // null.ExecuteInbound() is a no-op.
   219  func TestNullState_Execute(t *testing.T) {
   220  	_, followup, _, err := (&null{}).ExecuteInbound(&stateMachineMsg{}, "", &context{})
   221  	require.NoError(t, err)
   222  	require.IsType(t, &noOp{}, followup)
   223  }
   224  
   225  func TestInvitedState_Execute(t *testing.T) {
   226  	t.Run("rejects msgs other than invitations", func(t *testing.T) {
   227  		others := []service.DIDCommMsg{
   228  			service.NewDIDCommMsgMap(Request{Type: RequestMsgType}),
   229  			service.NewDIDCommMsgMap(Response{Type: ResponseMsgType}),
   230  			service.NewDIDCommMsgMap(model.Ack{Type: AckMsgType}),
   231  		}
   232  		for _, msg := range others {
   233  			_, _, _, err := (&invited{}).ExecuteInbound(&stateMachineMsg{
   234  				DIDCommMsg: msg,
   235  			}, "", &context{})
   236  			require.Error(t, err)
   237  			require.Contains(t, err.Error(), "illegal msg type")
   238  		}
   239  	})
   240  	t.Run("followup to 'requested' on inbound invitations", func(t *testing.T) {
   241  		invitationPayloadBytes, err := json.Marshal(&Invitation{
   242  			Type:            InvitationMsgType,
   243  			ID:              randomString(),
   244  			Label:           "Bob",
   245  			RecipientKeys:   []string{"8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"},
   246  			ServiceEndpoint: "https://localhost:8090",
   247  			RoutingKeys:     []string{"8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"},
   248  		})
   249  		require.NoError(t, err)
   250  		connRec, followup, _, err := (&invited{}).ExecuteInbound(
   251  			&stateMachineMsg{
   252  				DIDCommMsg: bytesToDIDCommMsg(t, invitationPayloadBytes),
   253  				connRecord: &connection.Record{},
   254  			},
   255  			"",
   256  			&context{})
   257  		require.NoError(t, err)
   258  		require.Equal(t, &requested{}, followup)
   259  		require.NotNil(t, connRec)
   260  	})
   261  	t.Run("followup to 'requested' on inbound oobinvitations", func(t *testing.T) {
   262  		connRec, followup, action, err := (&invited{}).ExecuteInbound(
   263  			&stateMachineMsg{
   264  				DIDCommMsg: service.NewDIDCommMsgMap(&OOBInvitation{Type: oobMsgType}),
   265  				connRecord: &connection.Record{},
   266  			},
   267  			"",
   268  			&context{},
   269  		)
   270  		require.NoError(t, err)
   271  		require.Equal(t, &requested{}, followup)
   272  		require.NotNil(t, connRec)
   273  		require.NotNil(t, action)
   274  	})
   275  }
   276  
   277  //nolint:gocognit,gocyclo
   278  func TestRequestedState_Execute(t *testing.T) {
   279  	prov := getProvider(t)
   280  	// Alice receives an invitation from Bob
   281  	invitationPayloadBytes, err := json.Marshal(&Invitation{
   282  		Type:            InvitationMsgType,
   283  		ID:              randomString(),
   284  		Label:           "Bob",
   285  		RecipientKeys:   []string{"8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"},
   286  		ServiceEndpoint: "https://localhost:8090",
   287  		RoutingKeys:     []string{"8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"},
   288  	})
   289  	require.NoError(t, err)
   290  
   291  	mtps := []string{
   292  		transport.MediaTypeDIDCommV2Profile,
   293  		transport.MediaTypeRFC0019EncryptedEnvelope,
   294  		transport.MediaTypeProfileDIDCommAIP1,
   295  	}
   296  
   297  	for _, mtp := range mtps {
   298  		var didServiceType string
   299  
   300  		switch mtp {
   301  		case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
   302  			didServiceType = vdrapi.DIDCommV2ServiceType
   303  		default:
   304  			didServiceType = vdrapi.DIDCommServiceType
   305  		}
   306  
   307  		t.Run("rejects messages other than invitations or requests", func(t *testing.T) {
   308  			others := []service.DIDCommMsg{
   309  				service.NewDIDCommMsgMap(Response{Type: ResponseMsgType}),
   310  				service.NewDIDCommMsgMap(model.Ack{Type: AckMsgType}),
   311  			}
   312  			for _, msg := range others {
   313  				_, _, _, e := (&requested{}).ExecuteInbound(&stateMachineMsg{
   314  					DIDCommMsg: msg,
   315  				}, "", &context{})
   316  				require.Error(t, e)
   317  				require.Contains(t, e.Error(), "illegal msg type")
   318  			}
   319  		})
   320  		t.Run("handle inbound invitations", func(t *testing.T) {
   321  			tests := []struct {
   322  				name string
   323  				ctx  *context
   324  			}{
   325  				{
   326  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   327  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   328  				},
   329  				{
   330  					name: "using context with P-256 main VM and P-256 keyAgreement",
   331  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   332  				},
   333  				{
   334  					name: "using context with P-384 main VM and P-384 keyAgreement",
   335  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   336  				},
   337  				{
   338  					name: "using context with P-521 main VM and P-521 keyAgreement",
   339  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   340  				},
   341  				{
   342  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   343  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   344  				},
   345  			}
   346  
   347  			for _, tt := range tests {
   348  				tc := tt
   349  				t.Run(tc.name, func(t *testing.T) {
   350  					msg, e := service.ParseDIDCommMsgMap(invitationPayloadBytes)
   351  					require.NoError(t, e)
   352  					thid, e := msg.ThreadID()
   353  					require.NoError(t, e)
   354  					connRec, _, _, e := (&requested{}).ExecuteInbound(&stateMachineMsg{
   355  						DIDCommMsg: msg,
   356  						connRecord: &connection.Record{},
   357  					}, thid, tc.ctx)
   358  					require.NoError(t, e)
   359  					require.NotNil(t, connRec.MyDID)
   360  				})
   361  			}
   362  		})
   363  		t.Run("handle inbound oob invitations", func(t *testing.T) {
   364  			tests := []struct {
   365  				name string
   366  				ctx  *context
   367  			}{
   368  				{
   369  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   370  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   371  				},
   372  				{
   373  					name: "using context with P-256 main VM and P-256 keyAgreement",
   374  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   375  				},
   376  				{
   377  					name: "using context with P-384 main VM and P-384 keyAgreement",
   378  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   379  				},
   380  				{
   381  					name: "using context with P-521 main VM and P-521 keyAgreement",
   382  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   383  				},
   384  				{
   385  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   386  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   387  				},
   388  			}
   389  
   390  			for _, tt := range tests {
   391  				tc := tt
   392  				t.Run(tc.name, func(t *testing.T) {
   393  					connRec, followup, action, e := (&requested{}).ExecuteInbound(&stateMachineMsg{
   394  						DIDCommMsg: service.NewDIDCommMsgMap(&OOBInvitation{
   395  							ID:         uuid.New().String(),
   396  							Type:       oobMsgType,
   397  							ThreadID:   uuid.New().String(),
   398  							TheirLabel: "test",
   399  							Target: &diddoc.Service{
   400  								ID:              uuid.New().String(),
   401  								Type:            didServiceType,
   402  								Priority:        0,
   403  								RecipientKeys:   []string{"key"},
   404  								ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
   405  							},
   406  						}),
   407  						connRecord: &connection.Record{},
   408  					}, "", tc.ctx)
   409  					require.NoError(t, e)
   410  					require.NotEmpty(t, connRec.MyDID)
   411  					require.Equal(t, &noOp{}, followup)
   412  					require.NotNil(t, action)
   413  				})
   414  			}
   415  		})
   416  		t.Run("handle inbound oob invitations", func(t *testing.T) {
   417  			tests := []struct {
   418  				name string
   419  				ctx  *context
   420  			}{
   421  				{
   422  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   423  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   424  				},
   425  				{
   426  					name: "using context with P-256 main VM and P-256 keyAgreement",
   427  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   428  				},
   429  				{
   430  					name: "using context with P-384 main VM and P-384 keyAgreement",
   431  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   432  				},
   433  				{
   434  					name: "using context with P-521 main VM and P-521 keyAgreement",
   435  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   436  				},
   437  				{
   438  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   439  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   440  				},
   441  			}
   442  
   443  			for _, tt := range tests {
   444  				tc := tt
   445  				t.Run(tc.name, func(t *testing.T) {
   446  					connRec, followup, action, e := (&requested{}).ExecuteInbound(&stateMachineMsg{
   447  						DIDCommMsg: service.NewDIDCommMsgMap(&OOBInvitation{
   448  							ID:         uuid.New().String(),
   449  							Type:       oobMsgType,
   450  							ThreadID:   uuid.New().String(),
   451  							TheirLabel: "test",
   452  							Target: &diddoc.Service{
   453  								ID:              uuid.New().String(),
   454  								Type:            didServiceType,
   455  								Priority:        0,
   456  								RecipientKeys:   []string{"key"},
   457  								ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
   458  							},
   459  						}),
   460  						connRecord: &connection.Record{},
   461  					}, "", tc.ctx)
   462  					require.NoError(t, e)
   463  					require.NotEmpty(t, connRec.MyDID)
   464  					require.Equal(t, &noOp{}, followup)
   465  					require.NotNil(t, action)
   466  				})
   467  			}
   468  		})
   469  		t.Run("handle inbound oob invitations with label", func(t *testing.T) {
   470  			expected := "my test label"
   471  			dispatched := false
   472  			tests := []struct {
   473  				name string
   474  				ctx  *context
   475  			}{
   476  				{
   477  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   478  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   479  				},
   480  				{
   481  					name: "using context with P-256 main VM and P-256 keyAgreement",
   482  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   483  				},
   484  				{
   485  					name: "using context with P-384 main VM and P-384 keyAgreement",
   486  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   487  				},
   488  				{
   489  					name: "using context with P-521 main VM and P-521 keyAgreement",
   490  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   491  				},
   492  				{
   493  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   494  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   495  				},
   496  			}
   497  
   498  			for _, tt := range tests {
   499  				tc := tt
   500  				t.Run(tc.name, func(t *testing.T) {
   501  					tc.ctx.outboundDispatcher = &mockdispatcher.MockOutbound{
   502  						ValidateSend: func(msg interface{}, _ string, _ *service.Destination) error {
   503  							dispatched = true
   504  							result, ok := msg.(*Request)
   505  							require.True(t, ok)
   506  							require.Equal(t, expected, result.Label)
   507  							return nil
   508  						},
   509  					}
   510  
   511  					_, encKey := newSigningAndEncryptionDIDKeys(t, tc.ctx)
   512  
   513  					inv := newOOBInvite(tc.ctx.mediaTypeProfiles, newServiceBlock([]string{encKey}, []string{encKey},
   514  						didServiceType))
   515  					inv.MyLabel = expected
   516  					_, _, action, e := (&requested{}).ExecuteInbound(&stateMachineMsg{
   517  						DIDCommMsg: service.NewDIDCommMsgMap(inv),
   518  						connRecord: &connection.Record{},
   519  					}, "", tc.ctx)
   520  					require.NoError(t, e)
   521  					require.NotNil(t, action)
   522  					err = action()
   523  					require.NoError(t, err)
   524  					require.True(t, dispatched)
   525  				})
   526  			}
   527  		})
   528  		t.Run("handle inbound oob invitations - register recipient keys in router", func(t *testing.T) {
   529  			registered := false
   530  			tests := []struct {
   531  				name string
   532  				ctx  *context
   533  			}{
   534  				{
   535  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   536  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   537  				},
   538  				{
   539  					name: "using context with P-256 main VM and P-256 keyAgreement",
   540  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   541  				},
   542  				{
   543  					name: "using context with P-384 main VM and P-384 keyAgreement",
   544  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   545  				},
   546  				{
   547  					name: "using context with P-521 main VM and P-521 keyAgreement",
   548  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   549  				},
   550  				{
   551  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   552  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   553  				},
   554  			}
   555  
   556  			for _, tt := range tests {
   557  				tc := tt
   558  				t.Run(tc.name, func(t *testing.T) {
   559  					_, expected := newSigningAndEncryptionDIDKeys(t, tc.ctx)
   560  					_, encKey := newSigningAndEncryptionDIDKeys(t, tc.ctx)
   561  
   562  					doc := createDIDDoc(t, tc.ctx)
   563  
   564  					if didServiceType == vdrapi.DIDCommV2ServiceType {
   565  						expected = doc.KeyAgreement[0].VerificationMethod.ID
   566  
   567  						doc.Service = []diddoc.Service{{
   568  							Type: didServiceType,
   569  							ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{
   570  								{URI: "http://test.com", Accept: []string{"didcomm/v2"}},
   571  							}),
   572  							RecipientKeys: []string{expected},
   573  						}}
   574  					} else {
   575  						doc.Service = []diddoc.Service{{
   576  							Type:            didServiceType,
   577  							ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
   578  							RecipientKeys:   []string{expected},
   579  						}}
   580  					}
   581  
   582  					tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{
   583  						CreateValue: doc,
   584  					}
   585  
   586  					tc.ctx.routeSvc = &mockroute.MockMediatorSvc{
   587  						Connections:    []string{"xyz"},
   588  						RoutingKeys:    []string{expected},
   589  						RouterEndpoint: "http://blah.com",
   590  						AddKeyFunc: func(result string) error {
   591  							require.Equal(t, expected, result)
   592  							registered = true
   593  							return nil
   594  						},
   595  					}
   596  					_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
   597  						options: &options{routerConnections: []string{"xyz"}},
   598  						DIDCommMsg: service.NewDIDCommMsgMap(newOOBInvite(
   599  							tc.ctx.mediaTypeProfiles,
   600  							newServiceBlock([]string{encKey}, []string{encKey}, didServiceType))),
   601  						connRecord: &connection.Record{},
   602  					}, "", tc.ctx)
   603  					require.NoError(t, err)
   604  					require.True(t, registered)
   605  				})
   606  			}
   607  		})
   608  		t.Run("handle inbound oob invitations - use routing info to create my did", func(t *testing.T) {
   609  			expected := mediator.NewConfig("http://test.com", []string{"my-test-key"})
   610  			created := false
   611  			tests := []struct {
   612  				name string
   613  				ctx  *context
   614  			}{
   615  				{
   616  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   617  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   618  				},
   619  				{
   620  					name: "using context with P-256 main VM and P-256 keyAgreement",
   621  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   622  				},
   623  				{
   624  					name: "using context with P-384 main VM and P-384 keyAgreement",
   625  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   626  				},
   627  				{
   628  					name: "using context with P-521 main VM and P-521 keyAgreement",
   629  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   630  				},
   631  				{
   632  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   633  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   634  				},
   635  			}
   636  
   637  			for _, tt := range tests {
   638  				tc := tt
   639  				t.Run(tc.name, func(t *testing.T) {
   640  					_, encKey := newSigningAndEncryptionDIDKeys(t, tc.ctx)
   641  
   642  					tc.ctx.routeSvc = &mockroute.MockMediatorSvc{
   643  						Connections:    []string{"xyz"},
   644  						RouterEndpoint: expected.Endpoint(),
   645  						RoutingKeys:    expected.Keys(),
   646  					}
   647  
   648  					docResolution := createDIDDoc(t, tc.ctx)
   649  					tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{
   650  						CreateFunc: func(_ string, didDoc *diddoc.Doc,
   651  							options ...vdrapi.DIDMethodOption) (*diddoc.DocResolution, error) {
   652  							created = true
   653  
   654  							uri, e := didDoc.Service[0].ServiceEndpoint.URI()
   655  							require.NoError(t, e)
   656  							require.Equal(t, expected.Endpoint(), uri)
   657  							return &diddoc.DocResolution{DIDDocument: docResolution}, nil
   658  						},
   659  						ResolveValue: docResolution,
   660  					}
   661  
   662  					oobInvite := newOOBInvite(tc.ctx.mediaTypeProfiles, newServiceBlock(
   663  						[]string{encKey}, []string{encKey}, didServiceType))
   664  					_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
   665  						options:    &options{routerConnections: []string{"xyz"}},
   666  						DIDCommMsg: service.NewDIDCommMsgMap(oobInvite),
   667  						connRecord: &connection.Record{},
   668  					}, "", tc.ctx)
   669  					require.NoError(t, err)
   670  					require.True(t, created)
   671  
   672  					// try with target as string
   673  					oobInvite.Target = docResolution.ID
   674  					_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
   675  						options:    &options{routerConnections: []string{"xyz"}},
   676  						DIDCommMsg: service.NewDIDCommMsgMap(oobInvite),
   677  						connRecord: &connection.Record{},
   678  					}, "", tc.ctx)
   679  					require.NoError(t, err)
   680  					require.True(t, created)
   681  				})
   682  			}
   683  		})
   684  		t.Run("handling invitations fails if my diddoc does not have a valid didcomm service", func(t *testing.T) {
   685  			msg, e := service.ParseDIDCommMsgMap(invitationPayloadBytes)
   686  			require.NoError(t, e)
   687  			tests := []struct {
   688  				name string
   689  				ctx  *context
   690  			}{
   691  				{
   692  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   693  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   694  				},
   695  				{
   696  					name: "using context with P-256 main VM and P-256 keyAgreement",
   697  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   698  				},
   699  				{
   700  					name: "using context with P-384 main VM and P-384 keyAgreement",
   701  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   702  				},
   703  				{
   704  					name: "using context with P-521 main VM and P-521 keyAgreement",
   705  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   706  				},
   707  				{
   708  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   709  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   710  				},
   711  			}
   712  
   713  			for _, tt := range tests {
   714  				tc := tt
   715  				t.Run(tc.name, func(t *testing.T) {
   716  					myDoc := createDIDDoc(t, tc.ctx)
   717  					myDoc.Service = []diddoc.Service{{
   718  						ID:              uuid.New().String(),
   719  						Type:            "invalid",
   720  						Priority:        0,
   721  						RecipientKeys:   nil,
   722  						ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{{}}),
   723  					}}
   724  					tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
   725  					_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
   726  						DIDCommMsg: msg,
   727  						connRecord: &connection.Record{},
   728  					}, "", tc.ctx)
   729  					require.Error(t, err)
   730  				})
   731  			}
   732  		})
   733  		t.Run("handling OOB invitations fails if my diddoc does not have a valid didcomm service", func(t *testing.T) {
   734  			tests := []struct {
   735  				name string
   736  				ctx  *context
   737  			}{
   738  				{
   739  					name: "using context with ED25519 main VM and X25519 keyAgreement",
   740  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   741  				},
   742  				{
   743  					name: "using context with P-256 main VM and P-256 keyAgreement",
   744  					ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   745  				},
   746  				{
   747  					name: "using context with P-384 main VM and P-384 keyAgreement",
   748  					ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   749  				},
   750  				{
   751  					name: "using context with P-521 main VM and P-521 keyAgreement",
   752  					ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   753  				},
   754  				{
   755  					name: "using context with ED25519 main VM and P-384 keyAgreement",
   756  					ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   757  				},
   758  			}
   759  
   760  			for _, tt := range tests {
   761  				tc := tt
   762  				t.Run(tc.name, func(t *testing.T) {
   763  					myDoc := createDIDDoc(t, tc.ctx)
   764  					myDoc.Service = []diddoc.Service{{
   765  						ID:              uuid.New().String(),
   766  						Type:            "invalid",
   767  						Priority:        0,
   768  						RecipientKeys:   nil,
   769  						ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{{}}),
   770  					}}
   771  					tc.ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
   772  					_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
   773  						DIDCommMsg: service.NewDIDCommMsgMap(&OOBInvitation{
   774  							ID:         uuid.New().String(),
   775  							Type:       oobMsgType,
   776  							ThreadID:   uuid.New().String(),
   777  							TheirLabel: "test",
   778  							Target: &diddoc.Service{
   779  								ID:              uuid.New().String(),
   780  								Type:            didServiceType,
   781  								Priority:        0,
   782  								RecipientKeys:   []string{"key"},
   783  								ServiceEndpoint: commonmodel.NewDIDCommV1Endpoint("http://test.com"),
   784  							},
   785  						}),
   786  						connRecord: &connection.Record{},
   787  					}, "", tc.ctx)
   788  					require.EqualError(t, err, "failed to handle inbound oob invitation : getting recipient key:"+
   789  						" recipientKeyAsDIDKey: invalid DID Doc service type: 'invalid'")
   790  				})
   791  			}
   792  		})
   793  		t.Run("inbound oob request error", func(t *testing.T) {
   794  			_, _, _, err = (&requested{}).ExecuteInbound(&stateMachineMsg{
   795  				DIDCommMsg: service.DIDCommMsgMap{
   796  					"@type": oobMsgType,
   797  					"@id":   map[int]int{},
   798  				},
   799  				connRecord: &connection.Record{},
   800  			}, "", &context{})
   801  			require.Error(t, err)
   802  			require.Contains(t, err.Error(), "failed to decode oob invitation: 1 error(s) decoding")
   803  		})
   804  		t.Run("inbound request unmarshalling error", func(t *testing.T) {
   805  			_, followup, _, err := (&requested{}).ExecuteInbound(&stateMachineMsg{
   806  				DIDCommMsg: service.DIDCommMsgMap{
   807  					"@type": InvitationMsgType,
   808  					"@id":   map[int]int{},
   809  				},
   810  			}, "", &context{})
   811  			require.Error(t, err)
   812  			require.Contains(t, err.Error(), "JSON unmarshalling of invitation")
   813  			require.Nil(t, followup)
   814  		})
   815  		t.Run("create DID error", func(t *testing.T) {
   816  			ctx2 := &context{
   817  				outboundDispatcher: prov.OutboundDispatcher(),
   818  				vdRegistry:         &mockvdr.MockVDRegistry{CreateErr: fmt.Errorf("create DID error")},
   819  			}
   820  			didDoc, err := ctx2.vdRegistry.Create(testMethod, nil)
   821  			require.Error(t, err)
   822  			require.Contains(t, err.Error(), "create DID error")
   823  			require.Nil(t, didDoc)
   824  		})
   825  	}
   826  }
   827  
   828  func TestRespondedState_Execute(t *testing.T) {
   829  	mtps := []string{transport.MediaTypeDIDCommV2Profile, transport.MediaTypeRFC0019EncryptedEnvelope}
   830  
   831  	for _, mtp := range mtps {
   832  		prov := getProvider(t)
   833  		tests := []struct {
   834  			name string
   835  			ctx  *context
   836  		}{
   837  			{
   838  				name: fmt.Sprintf("using context with ED25519 main VM and X25519 keyAgreement with profile %s", mtp),
   839  				ctx:  getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp),
   840  			},
   841  			{
   842  				name: fmt.Sprintf("using context with P-256 main VM and P-256 keyAgreement with profile %s", mtp),
   843  				ctx:  getContext(t, &prov, kms.ECDSAP256TypeIEEEP1363, kms.NISTP256ECDHKWType, mtp),
   844  			},
   845  			{
   846  				name: fmt.Sprintf("using context with P-384 main VM and P-384 keyAgreement with profile %s", mtp),
   847  				ctx:  getContext(t, &prov, kms.ECDSAP384TypeIEEEP1363, kms.NISTP384ECDHKWType, mtp),
   848  			},
   849  			{
   850  				name: fmt.Sprintf("using context with P-521 main VM and P-521 keyAgreement with profile %s", mtp),
   851  				ctx:  getContext(t, &prov, kms.ECDSAP521TypeIEEEP1363, kms.NISTP521ECDHKWType, mtp),
   852  			},
   853  			{
   854  				name: fmt.Sprintf("using context with ED25519 main VM and P-384 keyAgreement with profile %s", mtp),
   855  				ctx:  getContext(t, &prov, kms.ED25519Type, kms.NISTP384ECDHKWType, mtp),
   856  			},
   857  		}
   858  
   859  		for _, tt := range tests {
   860  			tc := tt
   861  			t.Run(tc.name, func(t *testing.T) {
   862  				request, err := createRequest(t, tc.ctx, false, mtp)
   863  				require.NoError(t, err)
   864  				requestPayloadBytes, err := json.Marshal(request)
   865  				require.NoError(t, err)
   866  				response, err := createResponse(request, tc.ctx)
   867  				require.NoErrorf(t, err, fmt.Sprintf("for %s", tc.name))
   868  				responsePayloadBytes, err := json.Marshal(response)
   869  				require.NoError(t, err)
   870  
   871  				t.Run("rejects messages other than requests and responses", func(t *testing.T) {
   872  					others := []service.DIDCommMsg{
   873  						service.NewDIDCommMsgMap(Invitation{Type: InvitationMsgType}),
   874  						service.NewDIDCommMsgMap(model.Ack{Type: AckMsgType}),
   875  					}
   876  					for _, msg := range others {
   877  						_, _, _, e := (&responded{}).ExecuteInbound(&stateMachineMsg{
   878  							DIDCommMsg: msg,
   879  						}, "", &context{})
   880  						require.Error(t, e)
   881  						require.Contains(t, e.Error(), "illegal msg type")
   882  					}
   883  				})
   884  				t.Run("no followup for inbound requests", func(t *testing.T) {
   885  					connRec, followup, _, e := (&responded{}).ExecuteInbound(&stateMachineMsg{
   886  						DIDCommMsg: bytesToDIDCommMsg(t, requestPayloadBytes),
   887  						connRecord: &connection.Record{},
   888  					}, "", tc.ctx)
   889  					require.NoError(t, e)
   890  					require.NotNil(t, connRec)
   891  					require.IsType(t, &noOp{}, followup)
   892  				})
   893  				t.Run("followup to 'completed' on inbound responses", func(t *testing.T) {
   894  					connRec := &connection.Record{
   895  						State:        (&responded{}).Name(),
   896  						ThreadID:     request.ID,
   897  						ConnectionID: "123",
   898  						Namespace:    findNamespace(ResponseMsgType),
   899  					}
   900  					err = tc.ctx.connectionRecorder.SaveConnectionRecordWithMappings(connRec)
   901  					require.NoError(t, err)
   902  					connRec, followup, _, e := (&responded{}).ExecuteInbound(
   903  						&stateMachineMsg{
   904  							DIDCommMsg: bytesToDIDCommMsg(t, responsePayloadBytes),
   905  							connRecord: connRec,
   906  						}, "", tc.ctx)
   907  					require.NoError(t, e)
   908  					require.NotNil(t, connRec)
   909  					require.Equal(t, (&completed{}).Name(), followup.Name())
   910  				})
   911  
   912  				t.Run("handle inbound request unmarshalling error", func(t *testing.T) {
   913  					_, followup, _, err := (&responded{}).ExecuteInbound(&stateMachineMsg{
   914  						DIDCommMsg: service.DIDCommMsgMap{"@id": map[int]int{}, "@type": RequestMsgType},
   915  					}, "", &context{})
   916  					require.Error(t, err)
   917  					require.Contains(t, err.Error(), "JSON unmarshalling of request")
   918  					require.Nil(t, followup)
   919  				})
   920  
   921  				t.Run("fails if my did has an invalid didcomm service entry", func(t *testing.T) {
   922  					ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
   923  					myDoc := createDIDDoc(t, ctx)
   924  					myDoc.Service = []diddoc.Service{{
   925  						ID:              uuid.New().String(),
   926  						Type:            "invalid",
   927  						Priority:        0,
   928  						RecipientKeys:   nil,
   929  						ServiceEndpoint: commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{{}}),
   930  					}}
   931  					ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: myDoc}
   932  					_, _, _, err := (&responded{}).ExecuteInbound(&stateMachineMsg{
   933  						DIDCommMsg: bytesToDIDCommMsg(t, requestPayloadBytes),
   934  						connRecord: &connection.Record{},
   935  					}, "", ctx)
   936  					require.Error(t, err)
   937  				})
   938  			})
   939  		}
   940  	}
   941  }
   942  
   943  func TestAbandonedState_Execute(t *testing.T) {
   944  	t.Run("execute abandon state", func(t *testing.T) {
   945  		connRec, _, _, err := (&abandoned{}).ExecuteInbound(&stateMachineMsg{
   946  			DIDCommMsg: service.NewDIDCommMsgMap(Response{Type: ResponseMsgType}),
   947  		}, "", &context{})
   948  		require.Error(t, err)
   949  		require.Contains(t, err.Error(), "not implemented")
   950  		require.Nil(t, connRec)
   951  	})
   952  }
   953  
   954  // completed is an end state.
   955  func TestCompletedState_Execute(t *testing.T) {
   956  	prov := getProvider(t)
   957  	customKMS := newKMS(t, prov.StoreProvider)
   958  	ctx := &context{
   959  		crypto:           &tinkcrypto.Crypto{},
   960  		kms:              customKMS,
   961  		keyType:          kms.ED25519Type,
   962  		keyAgreementType: kms.X25519ECDHKWType,
   963  	}
   964  	pubKey, encKey := newSigningAndEncryptionDIDKeys(t, ctx)
   965  	connRec, err := connection.NewRecorder(&prov)
   966  
   967  	require.NoError(t, err)
   968  	require.NotNil(t, connRec)
   969  
   970  	ctx.connectionRecorder = connRec
   971  
   972  	newDIDDoc := createDIDDocWithKey(pubKey, encKey, transport.MediaTypeRFC0019EncryptedEnvelope)
   973  
   974  	invitation, err := createMockInvitation(pubKey, ctx)
   975  	require.NoError(t, err)
   976  
   977  	didKey, err := ctx.getVerKey(invitation.ID)
   978  	require.NoError(t, err)
   979  
   980  	docAttach, err := ctx.didDocAttachment(newDIDDoc, didKey)
   981  	require.NoError(t, err)
   982  
   983  	response := &Response{
   984  		Type:      ResponseMsgType,
   985  		ID:        randomString(),
   986  		DocAttach: docAttach,
   987  		DID:       newDIDDoc.ID,
   988  		Thread: &decorator.Thread{
   989  			ID: "test",
   990  		},
   991  	}
   992  	responsePayloadBytes, err := json.Marshal(response)
   993  	require.NoError(t, err)
   994  
   995  	t.Run("no followup for inbound responses", func(t *testing.T) {
   996  		connRec := &connection.Record{
   997  			State:         (&responded{}).Name(),
   998  			ThreadID:      response.Thread.ID,
   999  			ConnectionID:  "123",
  1000  			MyDID:         "did:peer:123456789abcdefghi#inbox",
  1001  			Namespace:     myNSPrefix,
  1002  			InvitationID:  invitation.ID,
  1003  			RecipientKeys: []string{pubKey},
  1004  		}
  1005  		err = ctx.connectionRecorder.SaveConnectionRecordWithMappings(connRec)
  1006  		require.NoError(t, err)
  1007  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: mockdiddoc.GetMockDIDDoc(t, false)}
  1008  		require.NoError(t, err)
  1009  		_, followup, _, e := (&completed{}).ExecuteInbound(&stateMachineMsg{
  1010  			DIDCommMsg: bytesToDIDCommMsg(t, responsePayloadBytes),
  1011  			connRecord: connRec,
  1012  		}, "", ctx)
  1013  		require.NoError(t, e)
  1014  		require.IsType(t, &noOp{}, followup)
  1015  	})
  1016  	t.Run("no followup for inbound acks", func(t *testing.T) {
  1017  		connRec := &connection.Record{
  1018  			State:         (&responded{}).Name(),
  1019  			ThreadID:      response.Thread.ID,
  1020  			ConnectionID:  "123",
  1021  			Namespace:     findNamespace(AckMsgType),
  1022  			RecipientKeys: []string{pubKey},
  1023  		}
  1024  		err = ctx.connectionRecorder.SaveConnectionRecordWithMappings(connRec)
  1025  		require.NoError(t, err)
  1026  		ack := &model.Ack{
  1027  			Type:   AckMsgType,
  1028  			ID:     randomString(),
  1029  			Status: ackStatusOK,
  1030  			Thread: &decorator.Thread{
  1031  				ID: response.Thread.ID,
  1032  			},
  1033  		}
  1034  		ackPayloadBytes, e := json.Marshal(ack)
  1035  		require.NoError(t, e)
  1036  		_, followup, _, e := (&completed{}).ExecuteInbound(&stateMachineMsg{
  1037  			DIDCommMsg: bytesToDIDCommMsg(t, ackPayloadBytes),
  1038  		}, "", ctx)
  1039  		require.NoError(t, e)
  1040  		require.IsType(t, &noOp{}, followup)
  1041  	})
  1042  	t.Run("no followup for inbound complete", func(t *testing.T) {
  1043  		connRec := &connection.Record{
  1044  			State:         (&responded{}).Name(),
  1045  			ThreadID:      response.Thread.ID,
  1046  			ConnectionID:  "123",
  1047  			Namespace:     findNamespace(AckMsgType),
  1048  			RecipientKeys: []string{pubKey},
  1049  		}
  1050  		err = ctx.connectionRecorder.SaveConnectionRecordWithMappings(connRec)
  1051  		require.NoError(t, err)
  1052  		complete := &Complete{
  1053  			Type: CompleteMsgType,
  1054  			ID:   randomString(),
  1055  			Thread: &decorator.Thread{
  1056  				ID: response.Thread.ID,
  1057  			},
  1058  		}
  1059  		// without connection record
  1060  		payloadBytes, e := json.Marshal(complete)
  1061  		require.NoError(t, e)
  1062  		_, followup, _, e := (&completed{}).ExecuteInbound(&stateMachineMsg{
  1063  			DIDCommMsg: bytesToDIDCommMsg(t, payloadBytes),
  1064  		}, "", ctx)
  1065  		require.NoError(t, e)
  1066  		require.IsType(t, &noOp{}, followup)
  1067  		// with connection record
  1068  		connRec.TheirDID = "did:abc:test123"
  1069  		_, followup, _, e = (&completed{}).ExecuteInbound(&stateMachineMsg{
  1070  			DIDCommMsg: bytesToDIDCommMsg(t, payloadBytes),
  1071  			connRecord: connRec,
  1072  		}, "", ctx)
  1073  		require.NoError(t, e)
  1074  		require.IsType(t, &noOp{}, followup)
  1075  		// with connection record with sov interop fix
  1076  		connRec.TheirDID = "test123"
  1077  		ctx.doACAPyInterop = true
  1078  		_, followup, _, e = (&completed{}).ExecuteInbound(&stateMachineMsg{
  1079  			DIDCommMsg: bytesToDIDCommMsg(t, payloadBytes),
  1080  			connRecord: connRec,
  1081  		}, "", ctx)
  1082  		require.NoError(t, e)
  1083  		require.IsType(t, &noOp{}, followup)
  1084  		ctx.doACAPyInterop = false
  1085  	})
  1086  	t.Run("rejects messages other than responses, acks, and completes", func(t *testing.T) {
  1087  		others := []service.DIDCommMsg{
  1088  			service.NewDIDCommMsgMap(Invitation{Type: InvitationMsgType}),
  1089  			service.NewDIDCommMsgMap(Request{Type: RequestMsgType}),
  1090  		}
  1091  
  1092  		for _, msg := range others {
  1093  			_, _, _, err = (&completed{}).ExecuteInbound(&stateMachineMsg{
  1094  				DIDCommMsg: msg,
  1095  			}, "", &context{})
  1096  			require.Error(t, err)
  1097  			require.Contains(t, err.Error(), "illegal msg type")
  1098  		}
  1099  	})
  1100  	t.Run("no followup for inbound responses unmarshalling error", func(t *testing.T) {
  1101  		_, followup, _, err := (&completed{}).ExecuteInbound(&stateMachineMsg{
  1102  			DIDCommMsg: service.DIDCommMsgMap{"@id": map[int]int{}, "@type": ResponseMsgType},
  1103  		}, "", &context{})
  1104  		require.Error(t, err)
  1105  		require.Contains(t, err.Error(), "JSON unmarshalling of response")
  1106  		require.Nil(t, followup)
  1107  	})
  1108  	t.Run("inbound completes unmarshalling error", func(t *testing.T) {
  1109  		_, followup, _, err := (&completed{}).ExecuteInbound(&stateMachineMsg{
  1110  			DIDCommMsg: service.DIDCommMsgMap{"@id": map[int]int{}, "@type": CompleteMsgType},
  1111  		}, "", &context{})
  1112  		require.Error(t, err)
  1113  		require.Contains(t, err.Error(), "JSON unmarshalling of complete")
  1114  		require.Nil(t, followup)
  1115  	})
  1116  	t.Run("execute inbound handle inbound response  error", func(t *testing.T) {
  1117  		response.DID = ""
  1118  		responsePayloadBytes, err := json.Marshal(response)
  1119  		require.NoError(t, err)
  1120  		_, followup, _, err := (&completed{}).ExecuteInbound(&stateMachineMsg{
  1121  			DIDCommMsg: bytesToDIDCommMsg(t, responsePayloadBytes),
  1122  		}, "", ctx)
  1123  		require.Error(t, err)
  1124  		require.Contains(t, err.Error(), "handle inbound response")
  1125  		require.Nil(t, followup)
  1126  	})
  1127  }
  1128  
  1129  func TestNewRequestFromInvitation(t *testing.T) {
  1130  	invitation := &Invitation{
  1131  		Type:            InvitationMsgType,
  1132  		ID:              randomString(),
  1133  		Label:           "Bob",
  1134  		RecipientKeys:   []string{"8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"},
  1135  		ServiceEndpoint: "https://localhost:8090",
  1136  		RoutingKeys:     []string{"8HH5gYEeNc3z7PYXmd54d4x6qAfCNrqQqEB3nS7Zfu7K"},
  1137  	}
  1138  
  1139  	t.Run("successful new request from invitation", func(t *testing.T) {
  1140  		prov := getProvider(t)
  1141  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1142  		_, connRec, err := ctx.handleInboundInvitation(invitation, invitation.ID, &options{}, &connection.Record{})
  1143  		require.NoError(t, err)
  1144  		require.NotNil(t, connRec.MyDID)
  1145  	})
  1146  	t.Run("successful response to invitation with public did", func(t *testing.T) {
  1147  		prov := getProvider(t)
  1148  		ctx := &context{
  1149  			kms:               prov.CustomKMS,
  1150  			keyType:           kms.ED25519Type,
  1151  			keyAgreementType:  kms.X25519ECDHKWType,
  1152  			mediaTypeProfiles: []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  1153  		}
  1154  		doc := createDIDDoc(t, ctx)
  1155  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1156  		require.NoError(t, err)
  1157  		didConnStore, err := didstore.NewConnectionStore(&protocol.MockProvider{})
  1158  		require.NoError(t, err)
  1159  
  1160  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc}
  1161  		ctx.connectionRecorder = connRec
  1162  		ctx.connectionStore = didConnStore
  1163  
  1164  		_, connRecord, err := ctx.handleInboundInvitation(invitation, invitation.ID, &options{publicDID: doc.ID},
  1165  			&connection.Record{})
  1166  		require.NoError(t, err)
  1167  		require.NotNil(t, connRecord.MyDID)
  1168  		require.Equal(t, connRecord.MyDID, doc.ID)
  1169  	})
  1170  	t.Run("successful response to invitation with public did using P-384 key type", func(t *testing.T) {
  1171  		prov := getProvider(t)
  1172  		ctx := &context{
  1173  			kms:               prov.CustomKMS,
  1174  			keyType:           kms.ECDSAP384TypeIEEEP1363,
  1175  			keyAgreementType:  kms.NISTP384ECDHKWType,
  1176  			mediaTypeProfiles: []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  1177  		}
  1178  
  1179  		doc := createDIDDoc(t, ctx)
  1180  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1181  		require.NoError(t, err)
  1182  		didConnStore, err := didstore.NewConnectionStore(&protocol.MockProvider{})
  1183  		require.NoError(t, err)
  1184  
  1185  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc}
  1186  		ctx.connectionRecorder = connRec
  1187  		ctx.connectionStore = didConnStore
  1188  
  1189  		_, connRecord, err := ctx.handleInboundInvitation(invitation, invitation.ID, &options{publicDID: doc.ID},
  1190  			&connection.Record{})
  1191  		require.NoError(t, err)
  1192  		require.NotNil(t, connRecord.MyDID)
  1193  		require.Equal(t, connRecord.MyDID, doc.ID)
  1194  	})
  1195  	t.Run("unsuccessful new request from invitation ", func(t *testing.T) {
  1196  		prov := protocol.MockProvider{}
  1197  
  1198  		customKMS := newKMS(t, mem.NewProvider())
  1199  
  1200  		ctx := &context{
  1201  			kms:                customKMS,
  1202  			outboundDispatcher: prov.OutboundDispatcher(),
  1203  			routeSvc:           &mockroute.MockMediatorSvc{},
  1204  			vdRegistry:         &mockvdr.MockVDRegistry{CreateErr: fmt.Errorf("create DID error")},
  1205  			keyType:            kms.ED25519Type,
  1206  			keyAgreementType:   kms.X25519ECDHKWType,
  1207  			mediaTypeProfiles:  []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  1208  		}
  1209  		_, connRec, err := ctx.handleInboundInvitation(invitation, invitation.ID, &options{}, &connection.Record{})
  1210  		require.Error(t, err)
  1211  		require.Contains(t, err.Error(), "create DID error")
  1212  		require.Nil(t, connRec)
  1213  	})
  1214  	t.Run("unsuccessful new request from invitation with P-384 key as KW", func(t *testing.T) {
  1215  		prov := protocol.MockProvider{}
  1216  		customKMS := newKMS(t, mem.NewProvider())
  1217  
  1218  		ctx := &context{
  1219  			kms:                customKMS,
  1220  			outboundDispatcher: prov.OutboundDispatcher(),
  1221  			routeSvc:           &mockroute.MockMediatorSvc{},
  1222  			vdRegistry:         &mockvdr.MockVDRegistry{CreateErr: fmt.Errorf("create DID error")},
  1223  			keyType:            kms.ED25519Type,
  1224  			keyAgreementType:   kms.NISTP384ECDHKWType,
  1225  			mediaTypeProfiles:  []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  1226  		}
  1227  		_, connRec, err := ctx.handleInboundInvitation(invitation, invitation.ID, &options{}, &connection.Record{})
  1228  		require.Error(t, err)
  1229  		require.Contains(t, err.Error(), "create DID error")
  1230  		require.Nil(t, connRec)
  1231  	})
  1232  	t.Run("unsuccessful new request from invitation (creating did doc attachment for request)", func(t *testing.T) {
  1233  		prov := getProvider(t)
  1234  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1235  
  1236  		ctx.doACAPyInterop = true
  1237  		ctx.crypto = &mockcrypto.Crypto{
  1238  			SignErr: fmt.Errorf("sign error"),
  1239  		}
  1240  
  1241  		_, _, err := ctx.handleInboundInvitation(invitation, invitation.ID, &options{}, &connection.Record{})
  1242  		require.Error(t, err)
  1243  		require.Contains(t, err.Error(), "creating did doc attachment for request")
  1244  	})
  1245  }
  1246  
  1247  func TestNewResponseFromRequest(t *testing.T) {
  1248  	prov := getProvider(t)
  1249  	store := mockstorage.NewMockStoreProvider()
  1250  	k := newKMS(t, store)
  1251  
  1252  	t.Run("successful new response from request", func(t *testing.T) {
  1253  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1254  		request, err := createRequest(t, ctx, false, ctx.mediaTypeProfiles[0])
  1255  		require.NoError(t, err)
  1256  		_, connRec, err := ctx.handleInboundRequest(request, &options{}, &connection.Record{})
  1257  		require.NoError(t, err)
  1258  		require.NotNil(t, connRec.MyDID)
  1259  		require.NotNil(t, connRec.TheirDID)
  1260  	})
  1261  
  1262  	t.Run("unsuccessful new response from request due to resolve DID error", func(t *testing.T) {
  1263  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1264  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1265  		require.NoError(t, err)
  1266  
  1267  		request.DID = ""
  1268  
  1269  		_, connRec, err := ctx.handleInboundRequest(request, &options{}, &connection.Record{})
  1270  		require.Error(t, err)
  1271  		require.Contains(t, err.Error(), "resolve did doc from exchange request")
  1272  		require.Nil(t, connRec)
  1273  	})
  1274  
  1275  	t.Run("unsuccessful new response from request due to create did error", func(t *testing.T) {
  1276  		didDoc := mockdiddoc.GetMockDIDDoc(t, false)
  1277  		ctx := &context{
  1278  			vdRegistry: &mockvdr.MockVDRegistry{
  1279  				CreateErr:    fmt.Errorf("create DID error"),
  1280  				ResolveValue: mockdiddoc.GetMockDIDDoc(t, false),
  1281  			},
  1282  			routeSvc: &mockroute.MockMediatorSvc{},
  1283  		}
  1284  		request := &Request{
  1285  			DID:       didDoc.ID,
  1286  			DocAttach: signedDocAttach(t, didDoc),
  1287  		}
  1288  		_, connRec, err := ctx.handleInboundRequest(request, &options{}, &connection.Record{})
  1289  		require.Error(t, err)
  1290  		require.Contains(t, err.Error(), "create DID error")
  1291  		require.Nil(t, connRec)
  1292  	})
  1293  
  1294  	t.Run("unsuccessful new response from request due to get did doc error", func(t *testing.T) {
  1295  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1296  		ctx.connectionStore = &mockConnectionStore{saveDIDFromDocErr: fmt.Errorf("save did error")}
  1297  
  1298  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1299  		require.NoError(t, err)
  1300  		_, connRec, err := ctx.handleInboundRequest(request, &options{}, &connection.Record{})
  1301  		require.Error(t, err)
  1302  		require.Contains(t, err.Error(), "get response did doc and connection")
  1303  		require.Nil(t, connRec)
  1304  	})
  1305  
  1306  	t.Run("unsuccessful new response from request due to sign error", func(t *testing.T) {
  1307  		connRec, err := connection.NewRecorder(&prov)
  1308  		require.NoError(t, err)
  1309  		require.NotNil(t, connRec)
  1310  
  1311  		didConnStore, err := didstore.NewConnectionStore(&prov)
  1312  		require.NoError(t, err)
  1313  		require.NotNil(t, didConnStore)
  1314  
  1315  		ctx := &context{
  1316  			vdRegistry:         &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
  1317  			crypto:             &mockcrypto.Crypto{SignErr: errors.New("sign error")},
  1318  			connectionRecorder: connRec,
  1319  			connectionStore:    didConnStore,
  1320  			routeSvc:           &mockroute.MockMediatorSvc{},
  1321  			kms:                prov.CustomKMS,
  1322  			keyType:            kms.ED25519Type,
  1323  			keyAgreementType:   kms.X25519ECDHKWType,
  1324  			doACAPyInterop:     true,
  1325  		}
  1326  
  1327  		request, err := createRequest(t, ctx, true, transport.MediaTypeRFC0019EncryptedEnvelope)
  1328  		require.NoError(t, err)
  1329  
  1330  		_, connRecord, err := ctx.handleInboundRequest(request, &options{}, &connection.Record{})
  1331  
  1332  		require.Error(t, err)
  1333  		require.Contains(t, err.Error(), "sign error")
  1334  		require.Nil(t, connRecord)
  1335  	})
  1336  
  1337  	t.Run("unsuccessful new response from request due to resolve public did from request error", func(t *testing.T) {
  1338  		ctx := &context{vdRegistry: &mockvdr.MockVDRegistry{ResolveErr: errors.New("resolver error")}}
  1339  		request := &Request{DID: "did:sidetree:abc"}
  1340  		_, _, err := ctx.handleInboundRequest(request, &options{}, &connection.Record{})
  1341  		require.Error(t, err)
  1342  		require.Contains(t, err.Error(), "resolver error")
  1343  	})
  1344  
  1345  	t.Run("unsuccessful new response from request due to invalid did for creating destination", func(t *testing.T) {
  1346  		mockDoc := newPeerDID(t, k)
  1347  		mockDoc.Service = nil
  1348  
  1349  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1350  
  1351  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1352  		require.NoError(t, err)
  1353  
  1354  		request.DID = mockDoc.ID
  1355  		request.DocAttach = unsignedDocAttach(t, mockDoc)
  1356  
  1357  		_, _, err = ctx.handleInboundRequest(request, &options{}, &connection.Record{})
  1358  		require.Error(t, err)
  1359  		require.Contains(t, err.Error(), "missing DID doc service")
  1360  	})
  1361  }
  1362  
  1363  func TestPrepareResponse(t *testing.T) {
  1364  	prov := getProvider(t)
  1365  
  1366  	t.Run("successful new response from request", func(t *testing.T) {
  1367  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1368  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1369  		require.NoError(t, err)
  1370  
  1371  		_, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
  1372  		require.NoError(t, err)
  1373  	})
  1374  
  1375  	t.Run("successful new response from request, in interop mode", func(t *testing.T) {
  1376  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1377  		ctx.doACAPyInterop = true
  1378  
  1379  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1380  		require.NoError(t, err)
  1381  
  1382  		_, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
  1383  		require.NoError(t, err)
  1384  	})
  1385  
  1386  	t.Run("wraps error from connection store", func(t *testing.T) {
  1387  		expected := errors.New("test")
  1388  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1389  		ctx.doACAPyInterop = true
  1390  
  1391  		pr := testProvider()
  1392  		pr.StoreProvider = &mockstorage.MockStoreProvider{
  1393  			Store: &mockstorage.MockStore{
  1394  				Store:  make(map[string]mockstorage.DBEntry),
  1395  				ErrGet: expected,
  1396  			},
  1397  		}
  1398  
  1399  		ctx.connectionRecorder = connRecorder(t, pr)
  1400  
  1401  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1402  		require.NoError(t, err)
  1403  
  1404  		_, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
  1405  		require.Error(t, err)
  1406  		require.True(t, errors.Is(err, expected))
  1407  	})
  1408  
  1409  	t.Run("failed fetch of doc signing key", func(t *testing.T) {
  1410  		expected := errors.New("test")
  1411  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1412  		ctx.doACAPyInterop = true
  1413  
  1414  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1415  		require.NoError(t, err)
  1416  
  1417  		ctx.kms = &mockkms.KeyManager{GetKeyErr: expected}
  1418  
  1419  		_, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
  1420  		require.Error(t, err)
  1421  		require.True(t, errors.Is(err, expected))
  1422  	})
  1423  
  1424  	t.Run("failed doc signing", func(t *testing.T) {
  1425  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1426  		ctx.doACAPyInterop = true
  1427  
  1428  		request, err := createRequest(t, ctx, false, transport.MediaTypeRFC0019EncryptedEnvelope)
  1429  		require.NoError(t, err)
  1430  
  1431  		// fails to do ed25519 sign with wrong type of key
  1432  		mockKey, err := mockkms.CreateMockAESGCMKeyHandle()
  1433  		require.NoError(t, err)
  1434  
  1435  		ctx.kms = &mockkms.KeyManager{GetKeyValue: mockKey}
  1436  
  1437  		_, err = ctx.prepareResponse(request, mockdiddoc.GetMockDIDDoc(t, false))
  1438  		require.Error(t, err)
  1439  	})
  1440  }
  1441  
  1442  func TestContext_DIDDocAttachment(t *testing.T) {
  1443  	prov := getProvider(t)
  1444  
  1445  	t.Run("successful new did doc attachment without signing", func(t *testing.T) {
  1446  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1447  
  1448  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1449  
  1450  		att, err := ctx.didDocAttachment(doc, "")
  1451  		require.NoError(t, err)
  1452  
  1453  		attData, err := att.Data.Fetch()
  1454  		require.NoError(t, err)
  1455  
  1456  		checkDoc, err := diddoc.ParseDocument(attData)
  1457  		require.NoError(t, err)
  1458  		require.NotNil(t, checkDoc)
  1459  
  1460  		require.Equal(t, checkDoc.ID, doc.ID)
  1461  	})
  1462  
  1463  	t.Run("successful new did doc attachment with signing", func(t *testing.T) {
  1464  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1465  		ctx.doACAPyInterop = true
  1466  
  1467  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1468  
  1469  		_, pub, err := ctx.kms.CreateAndExportPubKeyBytes(kms.ED25519Type)
  1470  		require.NoError(t, err)
  1471  
  1472  		didKey, _ := fingerprint.CreateDIDKey(pub)
  1473  
  1474  		att, err := ctx.didDocAttachment(doc, didKey)
  1475  		require.NoError(t, err)
  1476  
  1477  		attData, err := att.Data.Fetch()
  1478  		require.NoError(t, err)
  1479  
  1480  		checkDoc, err := diddoc.ParseDocument(attData)
  1481  		require.NoError(t, err)
  1482  		require.NotNil(t, checkDoc)
  1483  
  1484  		require.Equal(t, checkDoc.ID, doc.ID)
  1485  	})
  1486  
  1487  	t.Run("fail to create did doc attachment, invalid key", func(t *testing.T) {
  1488  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1489  		ctx.doACAPyInterop = true
  1490  
  1491  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1492  
  1493  		_, err := ctx.didDocAttachment(doc, "did:key:not a did key")
  1494  		require.Error(t, err)
  1495  		require.Contains(t, err.Error(), "failed to extract pubKeyBytes")
  1496  	})
  1497  
  1498  	t.Run("fail to create did doc attachment, can't create KID", func(t *testing.T) {
  1499  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1500  		ctx.doACAPyInterop = true
  1501  
  1502  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1503  
  1504  		didKey, _ := fingerprint.CreateDIDKey([]byte{})
  1505  
  1506  		_, err := ctx.didDocAttachment(doc, didKey)
  1507  		require.Error(t, err)
  1508  		require.Contains(t, err.Error(), "failed to generate KID from public key")
  1509  	})
  1510  }
  1511  
  1512  func TestResolvePublicKey(t *testing.T) {
  1513  	prov := getProvider(t)
  1514  
  1515  	t.Run("resolve key from did:key", func(t *testing.T) {
  1516  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1517  
  1518  		keyBytes := []byte("12345678123456781234567812345678")
  1519  		didKey, _ := fingerprint.CreateDIDKey(keyBytes)
  1520  
  1521  		pub, err := ctx.resolvePublicKey(didKey)
  1522  		require.NoError(t, err)
  1523  		require.EqualValues(t, keyBytes, pub)
  1524  	})
  1525  
  1526  	t.Run("resolve key reference from doc in vdr", func(t *testing.T) {
  1527  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1528  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1529  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc}
  1530  
  1531  		vm := doc.VerificationMethod[0]
  1532  
  1533  		pub, err := ctx.resolvePublicKey(vm.ID)
  1534  		require.NoError(t, err)
  1535  		require.EqualValues(t, vm.Value, pub)
  1536  	})
  1537  
  1538  	t.Run("fail to resolve public key from unknown kid", func(t *testing.T) {
  1539  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1540  
  1541  		_, err := ctx.resolvePublicKey("something something")
  1542  		require.Error(t, err)
  1543  		require.Contains(t, err.Error(), "failed to resolve public key value from kid")
  1544  	})
  1545  
  1546  	t.Run("fail to resolve public key from invalid did:key", func(t *testing.T) {
  1547  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1548  
  1549  		_, err := ctx.resolvePublicKey("did:key:not a did key")
  1550  		require.Error(t, err)
  1551  		require.Contains(t, err.Error(), "failed to extract pubKeyBytes")
  1552  	})
  1553  
  1554  	t.Run("fail to resolve doc for key reference", func(t *testing.T) {
  1555  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1556  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1557  
  1558  		vm := doc.VerificationMethod[0]
  1559  
  1560  		_, err := ctx.resolvePublicKey(vm.ID)
  1561  		require.Error(t, err)
  1562  		require.Contains(t, err.Error(), "failed to resolve public did")
  1563  	})
  1564  
  1565  	t.Run("fail to find key in resolved doc", func(t *testing.T) {
  1566  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1567  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1568  		ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: doc}
  1569  
  1570  		kid := doc.VerificationMethod[0].ID
  1571  
  1572  		doc.VerificationMethod[0].ID = "wrong-key-id"
  1573  
  1574  		_, err := ctx.resolvePublicKey(kid)
  1575  		require.Error(t, err)
  1576  		require.Contains(t, err.Error(), "failed to lookup public key")
  1577  	})
  1578  }
  1579  
  1580  func TestResolveDIDDocFromMessage(t *testing.T) {
  1581  	prov := getProvider(t)
  1582  	mtps := []string{transport.MediaTypeDIDCommV2Profile, transport.MediaTypeRFC0019EncryptedEnvelope}
  1583  
  1584  	for _, mtp := range mtps {
  1585  		t.Run(fmt.Sprintf("success with media type profile: %s", mtp), func(t *testing.T) {
  1586  			ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1587  			docIn := mockdiddoc.GetMockDIDDoc(t, false)
  1588  
  1589  			att, err := ctx.didDocAttachment(docIn, "")
  1590  			require.NoError(t, err)
  1591  
  1592  			doc, err := ctx.resolveDidDocFromMessage(docIn.ID, att)
  1593  			require.NoError(t, err)
  1594  
  1595  			require.Equal(t, docIn.ID, doc.ID)
  1596  		})
  1597  
  1598  		t.Run(fmt.Sprintf("success - public resolution with media type profile: %s", mtp), func(t *testing.T) {
  1599  			ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1600  			docIn := mockdiddoc.GetMockDIDDoc(t, false)
  1601  			docIn.ID = "did:remote:abc"
  1602  
  1603  			ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveValue: docIn}
  1604  
  1605  			doc, err := ctx.resolveDidDocFromMessage(docIn.ID, nil)
  1606  			require.NoError(t, err)
  1607  
  1608  			require.Equal(t, docIn.ID, doc.ID)
  1609  		})
  1610  
  1611  		t.Run(fmt.Sprintf("failure - can't do public resolution with media type profile: %s", mtp),
  1612  			func(t *testing.T) {
  1613  				ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1614  				docIn := mockdiddoc.GetMockDIDDoc(t, false)
  1615  				docIn.ID = "did:remote:abc"
  1616  
  1617  				ctx.vdRegistry = &mockvdr.MockVDRegistry{ResolveErr: fmt.Errorf("resolve error")}
  1618  
  1619  				_, err := ctx.resolveDidDocFromMessage(docIn.ID, nil)
  1620  				require.Error(t, err)
  1621  				require.Contains(t, err.Error(), "failed to resolve public did")
  1622  			})
  1623  
  1624  		t.Run(fmt.Sprintf("failure - can't parse did with media type profile: %s", mtp), func(t *testing.T) {
  1625  			ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1626  			_, err := ctx.resolveDidDocFromMessage("blah blah", nil)
  1627  			require.Error(t, err)
  1628  			require.Contains(t, err.Error(), "failed to parse did")
  1629  		})
  1630  
  1631  		t.Run(fmt.Sprintf("failure - missing attachment for private did with media type profile: %s", mtp),
  1632  			func(t *testing.T) {
  1633  				ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1634  				_, err := ctx.resolveDidDocFromMessage("did:peer:abcdefg", nil)
  1635  				require.Error(t, err)
  1636  				require.Contains(t, err.Error(), "missing did_doc~attach")
  1637  			})
  1638  
  1639  		t.Run(fmt.Sprintf("failure - bad base64 data in attachment with media type profile: %s", mtp),
  1640  			func(t *testing.T) {
  1641  				ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1642  
  1643  				att := decorator.Attachment{Data: decorator.AttachmentData{Base64: "!@#$%^&*"}}
  1644  
  1645  				_, err := ctx.resolveDidDocFromMessage("did:peer:abcdefg", &att)
  1646  				require.Error(t, err)
  1647  				require.Contains(t, err.Error(), "failed to parse base64 attachment data")
  1648  			})
  1649  
  1650  		t.Run(fmt.Sprintf("failure - attachment contains encoded broken document with media type profile: %s",
  1651  			mtp), func(t *testing.T) {
  1652  			ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1653  
  1654  			att := decorator.Attachment{
  1655  				Data: decorator.AttachmentData{
  1656  					Base64: base64.StdEncoding.EncodeToString([]byte("abcdefg")),
  1657  				},
  1658  			}
  1659  
  1660  			_, err := ctx.resolveDidDocFromMessage("did:peer:abcdefg", &att)
  1661  			require.Error(t, err)
  1662  			require.Contains(t, err.Error(), "failed to parse did document")
  1663  		})
  1664  
  1665  		t.Run(fmt.Sprintf("success - interop mode with media type profile: %s", mtp), func(t *testing.T) {
  1666  			ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1667  
  1668  			docIn := mockdiddoc.GetMockDIDDoc(t, false)
  1669  			docIn.ID = "did:sov:abcdefg"
  1670  
  1671  			att, err := ctx.didDocAttachment(docIn, "")
  1672  			require.NoError(t, err)
  1673  
  1674  			ctx.doACAPyInterop = true
  1675  
  1676  			doc, err := ctx.resolveDidDocFromMessage(docIn.ID, att)
  1677  			require.NoError(t, err)
  1678  
  1679  			require.Equal(t, docIn.ID, doc.ID)
  1680  		})
  1681  
  1682  		t.Run(fmt.Sprintf("failure - can't store document locally with media type profile: %s", mtp),
  1683  			func(t *testing.T) {
  1684  				ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, mtp)
  1685  
  1686  				ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateErr: fmt.Errorf("create error")}
  1687  
  1688  				docIn := mockdiddoc.GetMockDIDDoc(t, false)
  1689  
  1690  				att, err := ctx.didDocAttachment(docIn, "")
  1691  				require.NoError(t, err)
  1692  
  1693  				_, err = ctx.resolveDidDocFromMessage(docIn.ID, att)
  1694  				require.Error(t, err)
  1695  				require.Contains(t, err.Error(), "failed to store provided did document")
  1696  			})
  1697  	}
  1698  }
  1699  
  1700  func TestHandleInboundResponse(t *testing.T) {
  1701  	prov := getProvider(t)
  1702  	ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1703  	_, encKey := newSigningAndEncryptionDIDKeys(t, ctx)
  1704  
  1705  	_, err := createMockInvitation(encKey, ctx)
  1706  	require.NoError(t, err)
  1707  
  1708  	t.Run("handle inbound responses get connection record error", func(t *testing.T) {
  1709  		response := &Response{Thread: &decorator.Thread{ID: "test"}}
  1710  		_, connRec, e := ctx.handleInboundResponse(response)
  1711  		require.Error(t, e)
  1712  		require.Contains(t, e.Error(), "get connection record")
  1713  		require.Nil(t, connRec)
  1714  	})
  1715  	t.Run("handle inbound responses get connection record error", func(t *testing.T) {
  1716  		response := &Response{Thread: &decorator.Thread{ID: ""}}
  1717  		_, connRec, e := ctx.handleInboundResponse(response)
  1718  		require.Error(t, e)
  1719  		require.Contains(t, e.Error(), "empty bytes")
  1720  		require.Nil(t, connRec)
  1721  	})
  1722  }
  1723  
  1724  func TestGetInvitationRecipientKey(t *testing.T) {
  1725  	prov := getProvider(t)
  1726  	ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1727  
  1728  	t.Run("successfully getting invitation recipient key", func(t *testing.T) {
  1729  		invitation := &Invitation{
  1730  			Type:            InvitationMsgType,
  1731  			ID:              randomString(),
  1732  			Label:           "Bob",
  1733  			RecipientKeys:   []string{"test"},
  1734  			ServiceEndpoint: "http://alice.agent.example.com:8081",
  1735  		}
  1736  		recKey, err := ctx.getInvitationRecipientKey(invitation)
  1737  		require.NoError(t, err)
  1738  		require.Equal(t, invitation.RecipientKeys[0], recKey)
  1739  	})
  1740  	t.Run("failed to get invitation recipient key", func(t *testing.T) {
  1741  		doc := mockdiddoc.GetMockDIDDoc(t, false)
  1742  		_, ok := diddoc.LookupService(doc, "did-communication")
  1743  		require.True(t, ok)
  1744  		ctx := context{vdRegistry: &mockvdr.MockVDRegistry{ResolveValue: doc}}
  1745  		invitation := &Invitation{
  1746  			Type: InvitationMsgType,
  1747  			ID:   randomString(),
  1748  			DID:  doc.ID,
  1749  		}
  1750  		recKey, err := ctx.getInvitationRecipientKey(invitation)
  1751  		require.NoError(t, err)
  1752  		// TODO fix hardcode base58 https://github.com/hyperledger/aries-framework-go/issues/1207
  1753  		require.Equal(t, doc.Service[0].RecipientKeys[0], recKey)
  1754  	})
  1755  	t.Run("failed to get invitation recipient key", func(t *testing.T) {
  1756  		invitation := &Invitation{
  1757  			Type: InvitationMsgType,
  1758  			ID:   randomString(),
  1759  			DID:  "test",
  1760  		}
  1761  		_, err := ctx.getInvitationRecipientKey(invitation)
  1762  		require.Error(t, err)
  1763  		require.Contains(t, err.Error(), "get invitation recipient key: DID does not exist")
  1764  	})
  1765  }
  1766  
  1767  func TestGetPublicKey(t *testing.T) {
  1768  	k := newKMS(t, mockstorage.NewMockStoreProvider())
  1769  	t.Run("successfully getting public key by id", func(t *testing.T) {
  1770  		prov := protocol.MockProvider{CustomKMS: k}
  1771  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1772  		doc, err := ctx.vdRegistry.Create(testMethod, nil)
  1773  		require.NoError(t, err)
  1774  		pubkey, ok := diddoc.LookupPublicKey(doc.DIDDocument.VerificationMethod[0].ID, doc.DIDDocument)
  1775  		require.True(t, ok)
  1776  		require.NotNil(t, pubkey)
  1777  	})
  1778  	t.Run("failed to get public key", func(t *testing.T) {
  1779  		prov := protocol.MockProvider{CustomKMS: k}
  1780  		ctx := getContext(t, &prov, kms.ED25519Type, kms.X25519ECDHKWType, transport.MediaTypeRFC0019EncryptedEnvelope)
  1781  		doc, err := ctx.vdRegistry.Create(testMethod, nil)
  1782  		require.NoError(t, err)
  1783  		pubkey, ok := diddoc.LookupPublicKey("invalid-key", doc.DIDDocument)
  1784  		require.False(t, ok)
  1785  		require.Nil(t, pubkey)
  1786  	})
  1787  }
  1788  
  1789  func TestGetDIDDocAndConnection(t *testing.T) {
  1790  	k := newKMS(t, mockstorage.NewMockStoreProvider())
  1791  	ctx := &context{
  1792  		kms:               k,
  1793  		keyType:           kms.ED25519Type,
  1794  		keyAgreementType:  kms.X25519ECDHKWType,
  1795  		mediaTypeProfiles: []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  1796  	}
  1797  
  1798  	t.Run("successfully getting did doc and connection for public did", func(t *testing.T) {
  1799  		doc := createDIDDoc(t, ctx)
  1800  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1801  		require.NoError(t, err)
  1802  		didConnStore, err := didstore.NewConnectionStore(&protocol.MockProvider{})
  1803  		require.NoError(t, err)
  1804  		ctx := context{
  1805  			vdRegistry:         &mockvdr.MockVDRegistry{ResolveValue: doc},
  1806  			connectionRecorder: connRec,
  1807  			connectionStore:    didConnStore,
  1808  		}
  1809  		didDoc, err := ctx.getMyDIDDoc(doc.ID, nil, "")
  1810  		require.NoError(t, err)
  1811  		require.NotNil(t, didDoc)
  1812  	})
  1813  	t.Run("error getting public did doc from resolver", func(t *testing.T) {
  1814  		ctx := context{
  1815  			vdRegistry: &mockvdr.MockVDRegistry{ResolveErr: errors.New("resolver error")},
  1816  		}
  1817  		didDoc, err := ctx.getMyDIDDoc("did-id", nil, "")
  1818  		require.Error(t, err)
  1819  		require.Contains(t, err.Error(), "resolver error")
  1820  		require.Nil(t, didDoc)
  1821  	})
  1822  	t.Run("error creating peer did", func(t *testing.T) {
  1823  		customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
  1824  		ctx := context{
  1825  			kms:              customKMS,
  1826  			vdRegistry:       &mockvdr.MockVDRegistry{CreateErr: errors.New("creator error")},
  1827  			routeSvc:         &mockroute.MockMediatorSvc{},
  1828  			keyType:          kms.ED25519Type,
  1829  			keyAgreementType: kms.X25519ECDHKWType,
  1830  		}
  1831  		didDoc, err := ctx.getMyDIDDoc("", nil, didCommServiceType)
  1832  		require.Error(t, err)
  1833  		require.Contains(t, err.Error(), "creator error")
  1834  		require.Nil(t, didDoc)
  1835  	})
  1836  	t.Run("successfully created peer did", func(t *testing.T) {
  1837  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1838  		require.NoError(t, err)
  1839  		didConnStore, err := didstore.NewConnectionStore(&protocol.MockProvider{})
  1840  		require.NoError(t, err)
  1841  		customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
  1842  		ctx := context{
  1843  			kms:                customKMS,
  1844  			vdRegistry:         &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
  1845  			connectionRecorder: connRec,
  1846  			connectionStore:    didConnStore,
  1847  			routeSvc:           &mockroute.MockMediatorSvc{},
  1848  			keyType:            kms.ED25519Type,
  1849  			keyAgreementType:   kms.X25519ECDHKWType,
  1850  		}
  1851  		didDoc, err := ctx.getMyDIDDoc("", nil, didCommV2ServiceType)
  1852  		require.NoError(t, err)
  1853  		require.NotNil(t, didDoc)
  1854  	})
  1855  
  1856  	t.Run("successfully created peer did with didcomm V2 service bloc", func(t *testing.T) {
  1857  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1858  		require.NoError(t, err)
  1859  		didConnStore, err := didstore.NewConnectionStore(&protocol.MockProvider{})
  1860  		require.NoError(t, err)
  1861  		customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
  1862  		ctx := context{
  1863  			kms:                customKMS,
  1864  			vdRegistry:         &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDocWithDIDCommV2Bloc(t, "bob")},
  1865  			connectionRecorder: connRec,
  1866  			connectionStore:    didConnStore,
  1867  			routeSvc:           &mockroute.MockMediatorSvc{},
  1868  			keyType:            kms.ED25519Type,
  1869  			keyAgreementType:   kms.X25519ECDHKWType,
  1870  		}
  1871  		didDoc, err := ctx.getMyDIDDoc("", []string{"did:peer:bob"}, didCommV2ServiceType)
  1872  		require.NoError(t, err)
  1873  		require.NotNil(t, didDoc)
  1874  	})
  1875  	t.Run("test create did doc - router service config error", func(t *testing.T) {
  1876  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1877  		require.NoError(t, err)
  1878  		customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
  1879  		ctx := context{
  1880  			kms:                customKMS,
  1881  			vdRegistry:         &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
  1882  			connectionRecorder: connRec,
  1883  			routeSvc: &mockroute.MockMediatorSvc{
  1884  				Connections: []string{"xyz"},
  1885  				ConfigErr:   errors.New("router config error"),
  1886  			},
  1887  		}
  1888  		didDoc, err := ctx.getMyDIDDoc("", []string{"xyz"}, "")
  1889  		require.Error(t, err)
  1890  		require.Contains(t, err.Error(), "did doc - fetch router config")
  1891  		require.Nil(t, didDoc)
  1892  	})
  1893  
  1894  	t.Run("test create did doc - router service config error", func(t *testing.T) {
  1895  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1896  		require.NoError(t, err)
  1897  		customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
  1898  		ctx := context{
  1899  			kms:                customKMS,
  1900  			vdRegistry:         &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
  1901  			connectionRecorder: connRec,
  1902  			routeSvc: &mockroute.MockMediatorSvc{
  1903  				Connections: []string{"xyz"},
  1904  				AddKeyErr:   errors.New("router add key error"),
  1905  			},
  1906  			keyType:          kms.ED25519Type,
  1907  			keyAgreementType: kms.X25519ECDHKWType,
  1908  		}
  1909  		didDoc, err := ctx.getMyDIDDoc("", []string{"xyz"}, "")
  1910  		require.Error(t, err)
  1911  		require.Contains(t, err.Error(), "did doc - add key to the router")
  1912  		require.Nil(t, didDoc)
  1913  	})
  1914  
  1915  	t.Run("error - invalid service type", func(t *testing.T) {
  1916  		connRec, err := connection.NewRecorder(&protocol.MockProvider{})
  1917  		require.NoError(t, err)
  1918  		didConnStore, err := didstore.NewConnectionStore(&protocol.MockProvider{})
  1919  		require.NoError(t, err)
  1920  		customKMS := newKMS(t, mockstorage.NewMockStoreProvider())
  1921  		ctx := context{
  1922  			kms:                customKMS,
  1923  			vdRegistry:         &mockvdr.MockVDRegistry{CreateValue: mockdiddoc.GetMockDIDDoc(t, false)},
  1924  			connectionRecorder: connRec,
  1925  			connectionStore:    didConnStore,
  1926  			routeSvc:           &mockroute.MockMediatorSvc{},
  1927  			keyType:            kms.ED25519Type,
  1928  			keyAgreementType:   kms.X25519ECDHKWType,
  1929  		}
  1930  		didDoc, err := ctx.getMyDIDDoc("", nil, "")
  1931  		require.Error(t, err)
  1932  		require.Nil(t, didDoc)
  1933  		require.Contains(t, err.Error(), "getMyDIDDoc: invalid DID Doc service type: ''")
  1934  	})
  1935  }
  1936  
  1937  const sovDoc = `{
  1938    "@context": "https://www.w3.org/2019/did/v1",
  1939    "id": "did:sov:17hRTxZFuRqqwFPxXnnuLj",
  1940    "service": [
  1941      {
  1942        "type": "endpoint",
  1943        "serviceEndpoint": "http://172.17.0.1:9031"
  1944      }
  1945    ],
  1946    "authentication": [
  1947      {
  1948        "type": "Ed25519SignatureAuthentication2018",
  1949        "publicKey": [
  1950          "did:sov:17hRTxZFuRqqwFPxXnnuLj#key-1"
  1951        ]
  1952      }
  1953    ],
  1954    "publicKey": [
  1955      {
  1956        "id": "did:sov:17hRTxZFuRqqwFPxXnnuLj#key-1",
  1957        "type": "Ed25519VerificationKey2018",
  1958        "publicKeyBase58": "14ehnBh9oevUhQUADCRk5dmMCk3cmLukZcKNCTxLGiic"
  1959      }
  1960    ]
  1961  }`
  1962  
  1963  func TestGetServiceBlock(t *testing.T) {
  1964  	doc, err := diddoc.ParseDocument([]byte(sovDoc))
  1965  	require.NoError(t, err)
  1966  
  1967  	v := &mockvdr.MockVDRegistry{ResolveValue: doc}
  1968  
  1969  	t.Run("success: get service block from public sov did", func(t *testing.T) {
  1970  		ctx := &context{
  1971  			doACAPyInterop: true,
  1972  			vdRegistry:     v,
  1973  		}
  1974  
  1975  		inv := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, doc.ID)
  1976  
  1977  		svc, err := ctx.getServiceBlock(inv)
  1978  		require.NoError(t, err)
  1979  		require.Len(t, svc.RecipientKeys, 1)
  1980  	})
  1981  
  1982  	t.Run("failure: get service block from public sov did, not in interop mode", func(t *testing.T) {
  1983  		ctx := &context{
  1984  			vdRegistry: v,
  1985  		}
  1986  
  1987  		inv := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, doc.ID)
  1988  
  1989  		svc, err := ctx.getServiceBlock(inv)
  1990  		require.Error(t, err)
  1991  		require.Nil(t, svc)
  1992  		require.Contains(t, err.Error(), "no valid service block found")
  1993  	})
  1994  
  1995  	t.Run("failure: get service block from public sov did, doc does not have endpoint service", func(t *testing.T) {
  1996  		doc2, err := diddoc.ParseDocument([]byte(sovDoc))
  1997  		require.NoError(t, err)
  1998  
  1999  		doc2.Service = nil
  2000  
  2001  		ctx := &context{
  2002  			vdRegistry:     &mockvdr.MockVDRegistry{ResolveValue: doc2},
  2003  			doACAPyInterop: true,
  2004  		}
  2005  
  2006  		inv := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, doc.ID)
  2007  
  2008  		svc, err := ctx.getServiceBlock(inv)
  2009  		require.Error(t, err)
  2010  		require.Nil(t, svc)
  2011  		require.Contains(t, err.Error(), "failed to get interop doc service")
  2012  	})
  2013  }
  2014  
  2015  func TestGetVerKey(t *testing.T) {
  2016  	k := newKMS(t, mockstorage.NewMockStoreProvider())
  2017  	ctx := &context{
  2018  		kms:               k,
  2019  		keyType:           kms.ED25519Type,
  2020  		keyAgreementType:  kms.X25519ECDHKWType,
  2021  		mediaTypeProfiles: []string{transport.MediaTypeRFC0019EncryptedEnvelope},
  2022  	}
  2023  
  2024  	_, encKey := newSigningAndEncryptionDIDKeys(t, ctx)
  2025  
  2026  	t.Run("returns verkey from explicit oob invitation", func(t *testing.T) {
  2027  		expected := newServiceBlock([]string{encKey}, []string{encKey}, didCommServiceType)
  2028  		invitation := newOOBInvite(expected.Accept, expected)
  2029  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2030  
  2031  		err := ctx.connectionRecorder.SaveInvitation(invitation.ThreadID, invitation)
  2032  		require.NoError(t, err)
  2033  
  2034  		result, err := ctx.getVerKey(invitation.ThreadID)
  2035  		require.NoError(t, err)
  2036  		require.Equal(t, expected.RecipientKeys[0], result)
  2037  
  2038  		expected = newServiceBlock([]string{encKey}, []string{encKey}, didCommV2ServiceType)
  2039  		accept, err := expected.ServiceEndpoint.Accept()
  2040  		require.NoError(t, err)
  2041  		invitation = newOOBInvite(accept, expected)
  2042  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2043  
  2044  		err = ctx.connectionRecorder.SaveInvitation(invitation.ThreadID, invitation)
  2045  		require.NoError(t, err)
  2046  
  2047  		result, err = ctx.getVerKey(invitation.ThreadID)
  2048  		require.NoError(t, err)
  2049  		require.Equal(t, expected.RecipientKeys[0], result)
  2050  	})
  2051  	t.Run("returns verkey from implicit oob invitation", func(t *testing.T) {
  2052  		publicDID := createDIDDoc(t, ctx)
  2053  		invitation := newOOBInvite([]string{ctx.mediaTypeProfiles[0]}, publicDID.ID)
  2054  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2055  		ctx.vdRegistry = &mockvdr.MockVDRegistry{
  2056  			ResolveValue: publicDID,
  2057  		}
  2058  
  2059  		err := ctx.connectionRecorder.SaveInvitation(invitation.ThreadID, invitation)
  2060  		require.NoError(t, err)
  2061  
  2062  		result, err := ctx.getVerKey(invitation.ThreadID)
  2063  		require.NoError(t, err)
  2064  		require.Equal(t, publicDID.Service[0].RecipientKeys[0], result)
  2065  	})
  2066  
  2067  	t.Run("returns verkey from implicit (interop) oob invitation", func(t *testing.T) {
  2068  		publicDID, err := diddoc.ParseDocument([]byte(sovDoc))
  2069  		require.NoError(t, err)
  2070  		invitation := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope}, publicDID.ID)
  2071  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2072  		ctx.vdRegistry = &mockvdr.MockVDRegistry{
  2073  			ResolveValue: publicDID,
  2074  		}
  2075  		ctx.doACAPyInterop = true
  2076  
  2077  		err = ctx.connectionRecorder.SaveInvitation(invitation.ThreadID, invitation)
  2078  		require.NoError(t, err)
  2079  
  2080  		result, err := ctx.getVerKey(invitation.ThreadID)
  2081  		require.NoError(t, err)
  2082  		require.Equal(t, publicDID.Service[0].RecipientKeys[0], result)
  2083  
  2084  		ctx.doACAPyInterop = false
  2085  	})
  2086  
  2087  	t.Run("returns verkey from explicit didexchange invitation", func(t *testing.T) {
  2088  		expected := newServiceBlock([]string{encKey}, []string{encKey}, didCommServiceType)
  2089  		invitation := newDidExchangeInvite(t, "", expected)
  2090  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2091  
  2092  		err := ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
  2093  		require.NoError(t, err)
  2094  
  2095  		result, err := ctx.getVerKey(invitation.ID)
  2096  		require.NoError(t, err)
  2097  		require.Equal(t, expected.RecipientKeys[0], result)
  2098  
  2099  		expected = newServiceBlock([]string{encKey}, []string{encKey}, didCommV2ServiceType)
  2100  		invitation = newDidExchangeInvite(t, "", expected)
  2101  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2102  
  2103  		err = ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
  2104  		require.NoError(t, err)
  2105  
  2106  		result, err = ctx.getVerKey(invitation.ID)
  2107  		require.NoError(t, err)
  2108  		require.Equal(t, expected.RecipientKeys[0], result)
  2109  	})
  2110  
  2111  	t.Run("returns verkey from implicit didexchange invitation", func(t *testing.T) {
  2112  		publicDID := createDIDDoc(t, ctx)
  2113  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2114  		ctx.vdRegistry = &mockvdr.MockVDRegistry{
  2115  			ResolveValue: publicDID,
  2116  		}
  2117  
  2118  		svc, found := diddoc.LookupService(publicDID, "did-communication")
  2119  		require.True(t, found)
  2120  
  2121  		result, err := ctx.getVerKey(publicDID.ID)
  2122  		require.NoError(t, err)
  2123  		require.Equal(t, svc.RecipientKeys[0], result)
  2124  	})
  2125  
  2126  	t.Run("fails for oob invitation with no target", func(t *testing.T) {
  2127  		invalid := newOOBInvite(nil, nil)
  2128  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2129  
  2130  		err := ctx.connectionRecorder.SaveInvitation(invalid.ThreadID, invalid)
  2131  		require.NoError(t, err)
  2132  
  2133  		_, err = ctx.getVerKey(invalid.ThreadID)
  2134  		require.Error(t, err)
  2135  	})
  2136  
  2137  	t.Run("wraps error from store", func(t *testing.T) {
  2138  		expected := errors.New("test")
  2139  		pr := testProvider()
  2140  		pr.StoreProvider = &mockstorage.MockStoreProvider{
  2141  			Store: &mockstorage.MockStore{
  2142  				Store:  make(map[string]mockstorage.DBEntry),
  2143  				ErrGet: expected,
  2144  			},
  2145  		}
  2146  		ctx.connectionRecorder = connRecorder(t, pr)
  2147  
  2148  		invitation := newOOBInvite([]string{transport.MediaTypeRFC0019EncryptedEnvelope},
  2149  			newServiceBlock([]string{encKey}, []string{encKey}, didCommServiceType))
  2150  		err := ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
  2151  		require.NoError(t, err)
  2152  
  2153  		invitation = newOOBInvite([]string{transport.MediaTypeDIDCommV2Profile},
  2154  			newServiceBlock([]string{encKey}, []string{encKey}, didCommV2ServiceType))
  2155  		err = ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
  2156  		require.NoError(t, err)
  2157  
  2158  		_, err = ctx.getVerKey(invitation.ID)
  2159  		require.Error(t, err)
  2160  	})
  2161  
  2162  	t.Run("wraps error from vdr resolution", func(t *testing.T) {
  2163  		expected := errors.New("test")
  2164  		ctx.connectionRecorder = connRecorder(t, testProvider())
  2165  		ctx.vdRegistry = &mockvdr.MockVDRegistry{
  2166  			ResolveErr: expected,
  2167  		}
  2168  
  2169  		_, err := ctx.getVerKey("did:example:123")
  2170  		require.Error(t, err)
  2171  		require.True(t, errors.Is(err, expected))
  2172  	})
  2173  }
  2174  
  2175  func createDIDDoc(t *testing.T, ctx *context) *diddoc.Doc {
  2176  	t.Helper()
  2177  
  2178  	verDIDKey, encDIDKey := newSigningAndEncryptionDIDKeys(t, ctx)
  2179  
  2180  	return createDIDDocWithKey(verDIDKey, encDIDKey, ctx.mediaTypeProfiles[0])
  2181  }
  2182  
  2183  func createDIDDocWithKey(verDIDKey, encDIDKey, mediaTypeProfile string) *diddoc.Doc {
  2184  	const (
  2185  		didFormat    = "did:%s:%s"
  2186  		didPKID      = "%s#keys-%d"
  2187  		didServiceID = "%s#endpoint-%d"
  2188  		method       = "test"
  2189  	)
  2190  
  2191  	id := fmt.Sprintf(didFormat, method, verDIDKey[:16])
  2192  	pubKeyID := fmt.Sprintf(didPKID, id, 1)
  2193  	verPubKeyVM := diddoc.VerificationMethod{
  2194  		ID:         pubKeyID,
  2195  		Type:       "Ed25519VerificationKey2018",
  2196  		Controller: id,
  2197  		Value:      []byte(verDIDKey),
  2198  	}
  2199  
  2200  	encPubKeyID := fmt.Sprintf(didPKID, id, 2)
  2201  	encKeyV := diddoc.Verification{
  2202  		VerificationMethod: diddoc.VerificationMethod{
  2203  			ID:         encPubKeyID,
  2204  			Type:       "X25519KeyAgreementKey2019",
  2205  			Controller: id,
  2206  			Value:      []byte(encDIDKey),
  2207  		},
  2208  		Relationship: diddoc.KeyAgreement,
  2209  	}
  2210  
  2211  	var (
  2212  		didCommService string
  2213  		recKey         string
  2214  		sp             commonmodel.Endpoint
  2215  	)
  2216  
  2217  	switch mediaTypeProfile {
  2218  	case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
  2219  		didCommService = vdrapi.DIDCommV2ServiceType
  2220  		recKey = verDIDKey
  2221  		sp = commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{
  2222  			{URI: "http://localhost:58416", Accept: []string{mediaTypeProfile}},
  2223  		})
  2224  	default:
  2225  		didCommService = vdrapi.DIDCommServiceType
  2226  		recKey = encPubKeyID
  2227  		sp = commonmodel.NewDIDCommV1Endpoint("http://localhost:58416")
  2228  	}
  2229  
  2230  	services := []diddoc.Service{
  2231  		{
  2232  			ID:              fmt.Sprintf(didServiceID, id, 1),
  2233  			Type:            didCommService,
  2234  			ServiceEndpoint: sp,
  2235  			Priority:        0,
  2236  			RecipientKeys:   []string{recKey},
  2237  		},
  2238  	}
  2239  
  2240  	switch mediaTypeProfile {
  2241  	case transport.MediaTypeDIDCommV2Profile, transport.MediaTypeAIP2RFC0587Profile:
  2242  	default: // set DIDComm V1 Accept field.
  2243  		services[0].Accept = []string{mediaTypeProfile}
  2244  	}
  2245  
  2246  	createdTime := time.Now()
  2247  	didDoc := &diddoc.Doc{
  2248  		Context:            []string{diddoc.ContextV1},
  2249  		ID:                 id,
  2250  		VerificationMethod: []diddoc.VerificationMethod{verPubKeyVM, encKeyV.VerificationMethod},
  2251  		KeyAgreement:       []diddoc.Verification{encKeyV},
  2252  		Service:            services,
  2253  		Created:            &createdTime,
  2254  		Updated:            &createdTime,
  2255  	}
  2256  
  2257  	return didDoc
  2258  }
  2259  
  2260  func getProvider(t *testing.T) protocol.MockProvider {
  2261  	t.Helper()
  2262  
  2263  	store := &mockstorage.MockStore{Store: make(map[string]mockstorage.DBEntry)}
  2264  	sProvider := mockstorage.NewCustomMockStoreProvider(store)
  2265  	customKMS := newKMS(t, sProvider)
  2266  
  2267  	return protocol.MockProvider{
  2268  		StoreProvider: sProvider,
  2269  		CustomKMS:     customKMS,
  2270  	}
  2271  }
  2272  
  2273  func getContext(t *testing.T, prov *protocol.MockProvider, keyType, keyAgreementType kms.KeyType,
  2274  	mediaTypeProfile string) *context {
  2275  	t.Helper()
  2276  
  2277  	ctx := &context{
  2278  		outboundDispatcher: prov.OutboundDispatcher(),
  2279  		crypto:             &tinkcrypto.Crypto{},
  2280  		routeSvc:           &mockroute.MockMediatorSvc{},
  2281  		kms:                prov.KMS(),
  2282  		keyType:            keyType,
  2283  		keyAgreementType:   keyAgreementType,
  2284  		mediaTypeProfiles:  []string{mediaTypeProfile},
  2285  	}
  2286  
  2287  	pubKey, encKey := newSigningAndEncryptionDIDKeys(t, ctx)
  2288  	connRec, err := connection.NewRecorder(prov)
  2289  	require.NoError(t, err)
  2290  
  2291  	didConnStore, err := didstore.NewConnectionStore(prov)
  2292  	require.NoError(t, err)
  2293  
  2294  	ctx.vdRegistry = &mockvdr.MockVDRegistry{CreateValue: createDIDDocWithKey(pubKey, encKey, mediaTypeProfile)}
  2295  	ctx.connectionRecorder = connRec
  2296  	ctx.connectionStore = didConnStore
  2297  
  2298  	return ctx
  2299  }
  2300  
  2301  func createRequest(t *testing.T, ctx *context, signDoc bool, mediaTypeProfile string) (*Request, error) {
  2302  	t.Helper()
  2303  
  2304  	pubKey, encKey := newSigningAndEncryptionDIDKeys(t, ctx)
  2305  
  2306  	invitation, err := createMockInvitation(pubKey, ctx)
  2307  	if err != nil {
  2308  		return nil, err
  2309  	}
  2310  
  2311  	newDidDoc := createDIDDocWithKey(pubKey, encKey, mediaTypeProfile)
  2312  
  2313  	var att *decorator.Attachment
  2314  	if signDoc {
  2315  		att = signedDocAttach(t, newDidDoc)
  2316  	} else {
  2317  		att = unsignedDocAttach(t, newDidDoc)
  2318  	}
  2319  
  2320  	// Prepare did-exchange inbound request
  2321  	request := &Request{
  2322  		Type:  RequestMsgType,
  2323  		ID:    randomString(),
  2324  		Label: "Bob",
  2325  		Thread: &decorator.Thread{
  2326  			PID: invitation.ID,
  2327  		},
  2328  
  2329  		DID:       newDidDoc.ID,
  2330  		DocAttach: att,
  2331  	}
  2332  
  2333  	return request, nil
  2334  }
  2335  
  2336  func createResponse(request *Request, ctx *context) (*Response, error) {
  2337  	doc, err := ctx.vdRegistry.Create(testMethod, nil)
  2338  	if err != nil {
  2339  		return nil, err
  2340  	}
  2341  
  2342  	didKey, err := ctx.getVerKey(request.Thread.PID)
  2343  	if err != nil {
  2344  		return nil, err
  2345  	}
  2346  
  2347  	docAttach, err := ctx.didDocAttachment(doc.DIDDocument, didKey)
  2348  	if err != nil {
  2349  		return nil, err
  2350  	}
  2351  
  2352  	response := &Response{
  2353  		Type: ResponseMsgType,
  2354  		ID:   randomString(),
  2355  		Thread: &decorator.Thread{
  2356  			ID: request.ID,
  2357  		},
  2358  		DocAttach: docAttach,
  2359  	}
  2360  
  2361  	return response, nil
  2362  }
  2363  
  2364  func createMockInvitation(pubKey string, ctx *context) (*Invitation, error) {
  2365  	invitation := &Invitation{
  2366  		Type:            InvitationMsgType,
  2367  		ID:              randomString(),
  2368  		Label:           "Bob",
  2369  		RecipientKeys:   []string{pubKey},
  2370  		ServiceEndpoint: "http://alice.agent.example.com:8081",
  2371  	}
  2372  
  2373  	err := ctx.connectionRecorder.SaveInvitation(invitation.ID, invitation)
  2374  	if err != nil {
  2375  		return nil, err
  2376  	}
  2377  
  2378  	return invitation, nil
  2379  }
  2380  
  2381  func toDIDCommMsg(t *testing.T, v interface{}) service.DIDCommMsgMap {
  2382  	msg, err := service.ParseDIDCommMsgMap(toBytes(t, v))
  2383  	require.NoError(t, err)
  2384  
  2385  	return msg
  2386  }
  2387  
  2388  func bytesToDIDCommMsg(t *testing.T, v []byte) service.DIDCommMsg {
  2389  	msg, err := service.ParseDIDCommMsgMap(v)
  2390  	require.NoError(t, err)
  2391  
  2392  	return msg
  2393  }
  2394  
  2395  func toBytes(t *testing.T, data interface{}) []byte {
  2396  	t.Helper()
  2397  
  2398  	src, err := json.Marshal(data)
  2399  	require.NoError(t, err)
  2400  
  2401  	return src
  2402  }
  2403  
  2404  func newDidExchangeInvite(t *testing.T, publicDID string, svc *diddoc.Service) *Invitation {
  2405  	t.Helper()
  2406  
  2407  	i := &Invitation{
  2408  		ID:   uuid.New().String(),
  2409  		Type: InvitationMsgType,
  2410  		DID:  publicDID,
  2411  	}
  2412  
  2413  	if svc != nil {
  2414  		if svc.Type == didCommV2ServiceType {
  2415  			i.RecipientKeys = svc.RecipientKeys
  2416  			uri, err := svc.ServiceEndpoint.URI()
  2417  			require.NoError(t, err)
  2418  
  2419  			i.ServiceEndpoint = uri
  2420  
  2421  			routingKeys, err := svc.ServiceEndpoint.RoutingKeys()
  2422  			require.NoError(t, err)
  2423  
  2424  			i.RoutingKeys = routingKeys
  2425  		} else {
  2426  			var err error
  2427  
  2428  			i.RecipientKeys = svc.RecipientKeys
  2429  			i.ServiceEndpoint, err = svc.ServiceEndpoint.URI()
  2430  			require.NoError(t, err)
  2431  			i.RoutingKeys = svc.RoutingKeys
  2432  		}
  2433  	}
  2434  
  2435  	return i
  2436  }
  2437  
  2438  func newOOBInvite(accept []string, target interface{}) *OOBInvitation {
  2439  	return &OOBInvitation{
  2440  		ID:                uuid.New().String(),
  2441  		Type:              oobMsgType,
  2442  		ThreadID:          uuid.New().String(),
  2443  		TheirLabel:        "test",
  2444  		Target:            target,
  2445  		MediaTypeProfiles: accept,
  2446  	}
  2447  }
  2448  
  2449  func newServiceBlock(recKeys, routingKeys []string, didCommServiceVType string) *diddoc.Service {
  2450  	var (
  2451  		sp                   commonmodel.Endpoint
  2452  		didCommV1RoutingKeys []string
  2453  	)
  2454  
  2455  	switch didCommServiceVType {
  2456  	case didCommV2ServiceType:
  2457  		sp = commonmodel.NewDIDCommV2Endpoint([]commonmodel.DIDCommV2Endpoint{
  2458  			{URI: "http://test.com", Accept: []string{transport.MediaTypeDIDCommV2Profile}, RoutingKeys: routingKeys},
  2459  		})
  2460  	default:
  2461  		sp = commonmodel.NewDIDCommV1Endpoint("http://test.com")
  2462  		didCommV1RoutingKeys = routingKeys
  2463  	}
  2464  
  2465  	svc := &diddoc.Service{
  2466  		ID:              uuid.New().String(),
  2467  		Type:            didCommServiceVType,
  2468  		RecipientKeys:   recKeys,
  2469  		ServiceEndpoint: sp,
  2470  	}
  2471  
  2472  	if didCommServiceVType == didCommServiceType {
  2473  		svc.Accept = []string{transport.MediaTypeRFC0019EncryptedEnvelope}
  2474  		svc.RoutingKeys = didCommV1RoutingKeys
  2475  	}
  2476  
  2477  	return svc
  2478  }
  2479  
  2480  func connRecorder(t *testing.T, p provider) *connection.Recorder {
  2481  	s, err := connection.NewRecorder(p)
  2482  	require.NoError(t, err)
  2483  
  2484  	return s
  2485  }