github.com/hyperledger/aries-framework-go@v0.3.2/pkg/didcomm/protocol/outofbandv2/service_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package outofbandv2 8 9 import ( 10 "crypto/elliptic" 11 "encoding/base64" 12 "encoding/json" 13 "errors" 14 "fmt" 15 "testing" 16 "time" 17 18 "github.com/btcsuite/btcutil/base58" 19 "github.com/golang/mock/gomock" 20 "github.com/google/uuid" 21 "github.com/stretchr/testify/require" 22 23 "github.com/hyperledger/aries-framework-go/pkg/crypto" 24 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 25 "github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher" 26 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator" 27 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/mediator" 28 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/messagepickup" 29 "github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/presentproof" 30 "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport" 31 "github.com/hyperledger/aries-framework-go/pkg/doc/did" 32 "github.com/hyperledger/aries-framework-go/pkg/doc/util/jwkkid" 33 vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr" 34 mockkms "github.com/hyperledger/aries-framework-go/pkg/internal/gomocks/kms" 35 "github.com/hyperledger/aries-framework-go/pkg/kms" 36 "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol" 37 mockmediator "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/protocol/mediator" 38 mocksvc "github.com/hyperledger/aries-framework-go/pkg/mock/didcomm/service" 39 mockdiddoc "github.com/hyperledger/aries-framework-go/pkg/mock/diddoc" 40 mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 41 mockvdr "github.com/hyperledger/aries-framework-go/pkg/mock/vdr" 42 ) 43 44 func TestNew(t *testing.T) { 45 t.Run("returns the service", func(t *testing.T) { 46 s, err := New(testProvider(t)) 47 require.NoError(t, err) 48 require.NotNil(t, s) 49 }) 50 t.Run("wraps error thrown from protocol state store when it cannot be opened", func(t *testing.T) { 51 expected := errors.New("test") 52 provider := testProvider(t) 53 provider.ProtocolStateStoreProvider = &mockstore.MockStoreProvider{ 54 ErrOpenStoreHandle: expected, 55 } 56 _, err := New(provider) 57 require.Error(t, err) 58 require.True(t, errors.Is(err, expected)) 59 }) 60 t.Run("wraps error thrown from protocol state store when setting its store config", func(t *testing.T) { 61 expected := errors.New("test") 62 provider := testProvider(t) 63 provider.ProtocolStateStoreProvider = &mockstore.MockStoreProvider{ 64 ErrSetStoreConfig: expected, 65 } 66 _, err := New(provider) 67 require.Error(t, err) 68 require.True(t, errors.Is(err, expected)) 69 }) 70 } 71 72 func TestService_Initialize(t *testing.T) { 73 t.Run("success", func(t *testing.T) { 74 prov := testProvider(t) 75 svc := Service{} 76 77 err := svc.Initialize(prov) 78 require.NoError(t, err) 79 80 // second init is no-op 81 err = svc.Initialize(prov) 82 require.NoError(t, err) 83 }) 84 85 t.Run("failure, not given a valid provider", func(t *testing.T) { 86 svc := Service{} 87 88 err := svc.Initialize("not a provider") 89 require.Error(t, err) 90 require.Contains(t, err.Error(), "expected provider of type") 91 }) 92 } 93 94 func TestName(t *testing.T) { 95 s, err := New(testProvider(t)) 96 require.NoError(t, err) 97 require.Equal(t, s.Name(), Name) 98 } 99 100 func TestAccept(t *testing.T) { 101 t.Run("accepts out-of-band/2.0 invitation messages", func(t *testing.T) { 102 s, err := New(testProvider(t)) 103 require.NoError(t, err) 104 require.True(t, s.Accept("https://didcomm.org/out-of-band/2.0/invitation")) 105 }) 106 t.Run("rejects unsupported messages", func(t *testing.T) { 107 s, err := New(testProvider(t)) 108 require.NoError(t, err) 109 require.False(t, s.Accept("unsupported")) 110 }) 111 } 112 113 func TestHandleOutbound(t *testing.T) { 114 t.Run("out-of-band Outbound not supported", func(t *testing.T) { 115 s := newAutoService(t, testProvider(t)) 116 _, err := s.HandleOutbound(nil, "", "") 117 require.EqualError(t, err, "oob/2.0 not implemented") 118 }) 119 } 120 121 func TestHandleInbound(t *testing.T) { 122 t.Run("accepts out-of-band invitation messages", func(t *testing.T) { 123 s := newAutoService(t, testProvider(t)) 124 _, err := s.HandleInbound(service.NewDIDCommMsgMap(newInvitation()), service.EmptyDIDCommContext()) 125 require.NoError(t, err) 126 }) 127 t.Run("nil out-of-band invitation messages", func(t *testing.T) { 128 s := newAutoService(t, testProvider(t)) 129 _, err := s.HandleInbound(nil, service.EmptyDIDCommContext()) 130 require.EqualError(t, err, "oob/2.0 cannot handle nil inbound message") 131 }) 132 t.Run("rejects unsupported message types", func(t *testing.T) { 133 s, err := New(testProvider(t)) 134 require.NoError(t, err) 135 req := newInvitation() 136 req.Type = "invalid" 137 _, err = s.HandleInbound(service.NewDIDCommMsgMap(req), service.EmptyDIDCommContext()) 138 require.Error(t, err) 139 }) 140 } 141 142 func TestListener(t *testing.T) { 143 t.Run("invokes handleReqFunc", func(t *testing.T) { 144 invoked := make(chan struct{}) 145 callbacks := make(chan *callback) 146 handleReqFunc := func(*callback) error { 147 invoked <- struct{}{} 148 return nil 149 } 150 go listener(callbacks, handleReqFunc)() 151 152 callbacks <- &callback{ 153 msg: service.NewDIDCommMsgMap(newInvitation()), 154 } 155 156 select { 157 case <-invoked: 158 case <-time.After(1 * time.Second): 159 t.Error("timeout") 160 } 161 }) 162 } 163 164 func TestAcceptInvitation(t *testing.T) { 165 t.Run("error if invitation has invalid accept values", func(t *testing.T) { 166 provider := testProvider(t) 167 s := newAutoService(t, provider) 168 inv := newInvitation() 169 inv.Body.Accept = []string{"INVALID"} 170 connID, err := s.AcceptInvitation(inv) 171 require.Error(t, err) 172 require.Contains(t, err.Error(), "no acceptable media type profile found in invitation") 173 require.Empty(t, connID) 174 }) 175 t.Run("error if invitation has invalid Type values", func(t *testing.T) { 176 provider := testProvider(t) 177 s := newAutoService(t, provider) 178 inv := newInvitation() 179 inv.Type = "invalidType" 180 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 181 connID, err := s.AcceptInvitation(inv) 182 require.EqualError(t, err, "oob/2.0 failed to accept invitation : unsupported message type: invalidType") 183 require.Empty(t, connID) 184 }) 185 t.Run("error if invitation empty From field", func(t *testing.T) { 186 provider := testProvider(t) 187 s := newAutoService(t, provider) 188 inv := newInvitation() 189 inv.From = "" 190 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 191 connID, err := s.AcceptInvitation(inv) 192 require.EqualError(t, err, "oob/2.0 does not have from field") 193 require.Empty(t, connID) 194 }) 195 t.Run("error if invitation with invalid signing key", func(t *testing.T) { 196 provider := testProvider(t) 197 ctrl := gomock.NewController(t) 198 defer ctrl.Finish() 199 200 km := mockkms.NewMockKeyManager(ctrl) 201 km.EXPECT().CreateAndExportPubKeyBytes(gomock.Any()).MaxTimes(1).Return("", nil, fmt.Errorf("signing key error")) 202 203 provider.CustomKMS = km 204 205 s := newAutoService(t, provider) 206 inv := newInvitation() 207 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 208 connID, err := s.AcceptInvitation(inv) 209 require.EqualError(t, err, "oob/2.0 AcceptInvitation: creating new keys and VMS for DID document failed:"+ 210 " createSigningVM: signing key error") 211 require.Empty(t, connID) 212 }) 213 t.Run("invitation valid accept values", func(t *testing.T) { 214 provider := testProvider(t) 215 ed25519RawKey, p384KeyMarshalled := createAuthenticationAndAgreementKeys(t, provider) 216 217 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 218 CreateAndExportPubKeyBytes(provider.KeyTypeValue).Return("", ed25519RawKey, nil) 219 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 220 CreateAndExportPubKeyBytes(provider.KeyAgreementTypeValue).Return("", p384KeyMarshalled, nil) 221 222 s := newAutoService(t, provider) 223 inv := newInvitation() 224 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 225 226 s.vdrRegistry = &mockvdr.MockVDRegistry{ 227 ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) { 228 return &did.DocResolution{ 229 DIDDocument: mockdiddoc.GetMockDIDDoc(t, true), 230 }, nil 231 }, 232 } 233 234 connID, err := s.AcceptInvitation(inv) 235 require.NoError(t, err) 236 require.NotEmpty(t, connID) 237 }) 238 239 t.Run("invitation success with mediator connections", func(t *testing.T) { 240 provider := testProvider(t) 241 ed25519RawKey, p384KeyMarshalled := createAuthenticationAndAgreementKeys(t, provider) 242 243 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 244 CreateAndExportPubKeyBytes(provider.KeyTypeValue).Return("", ed25519RawKey, nil) 245 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 246 CreateAndExportPubKeyBytes(provider.KeyAgreementTypeValue).Return("", p384KeyMarshalled, nil) 247 248 testKey := "did:test:foo#key" 249 250 provider.ServiceMap[mediator.Coordination] = &mockmediator.MockMediatorSvc{ 251 RouterEndpoint: "mock.endpoint", 252 RoutingKeys: []string{testKey}, 253 ConfigErr: nil, 254 } 255 256 s := newAutoService(t, provider) 257 inv := newInvitation() 258 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 259 260 var createdDoc *did.Doc 261 262 s.vdrRegistry = &mockvdr.MockVDRegistry{ 263 CreateFunc: func(s string, doc *did.Doc, option ...vdrapi.DIDMethodOption) (*did.DocResolution, error) { 264 createdDoc = doc 265 266 return &did.DocResolution{DIDDocument: doc}, nil 267 }, 268 ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) { 269 return &did.DocResolution{ 270 DIDDocument: mockdiddoc.GetMockDIDDoc(t, true), 271 }, nil 272 }, 273 } 274 275 connID, err := s.AcceptInvitation(inv, WithRouterConnections([]string{"foo"})) 276 require.NoError(t, err) 277 require.NotEmpty(t, connID) 278 279 require.NotNil(t, createdDoc) 280 docSvc, ok := did.LookupService(createdDoc, vdrapi.DIDCommV2ServiceType) 281 require.True(t, ok) 282 283 routingKeys, err := docSvc.ServiceEndpoint.RoutingKeys() 284 require.NoError(t, err) 285 286 require.Len(t, routingKeys, 1) 287 require.Equal(t, testKey, routingKeys[0]) 288 }) 289 290 t.Run("error fetching mediator config", func(t *testing.T) { 291 provider := testProvider(t) 292 ed25519RawKey, p384KeyMarshalled := createAuthenticationAndAgreementKeys(t, provider) 293 294 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 295 CreateAndExportPubKeyBytes(provider.KeyTypeValue).Return("", ed25519RawKey, nil) 296 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 297 CreateAndExportPubKeyBytes(provider.KeyAgreementTypeValue).Return("", p384KeyMarshalled, nil) 298 299 expectedErr := fmt.Errorf("expected error") 300 301 provider.ServiceMap[mediator.Coordination] = &mockmediator.MockMediatorSvc{ 302 ConfigErr: expectedErr, 303 } 304 305 s := newAutoService(t, provider) 306 inv := newInvitation() 307 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 308 309 _, err := s.AcceptInvitation(inv, WithRouterConnections([]string{"foo"})) 310 require.ErrorIs(t, err, expectedErr) 311 require.Contains(t, err.Error(), "fetch router config") 312 }) 313 314 t.Run("fail to add new keys from peer DID to router", func(t *testing.T) { 315 provider := testProvider(t) 316 ed25519RawKey, p384KeyMarshalled := createAuthenticationAndAgreementKeys(t, provider) 317 318 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 319 CreateAndExportPubKeyBytes(provider.KeyTypeValue).Return("", ed25519RawKey, nil) 320 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 321 CreateAndExportPubKeyBytes(provider.KeyAgreementTypeValue).Return("", p384KeyMarshalled, nil) 322 323 testKey := "did:test:foo#key" 324 325 expectedErr := fmt.Errorf("expected error") 326 327 provider.ServiceMap[mediator.Coordination] = &mockmediator.MockMediatorSvc{ 328 RouterEndpoint: "mock.endpoint", 329 RoutingKeys: []string{testKey}, 330 ConfigErr: nil, 331 AddKeyErr: expectedErr, 332 } 333 334 s := newAutoService(t, provider) 335 inv := newInvitation() 336 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 337 338 s.vdrRegistry = &mockvdr.MockVDRegistry{ 339 CreateFunc: func(s string, doc *did.Doc, option ...vdrapi.DIDMethodOption) (*did.DocResolution, error) { 340 return &did.DocResolution{DIDDocument: doc}, nil 341 }, 342 ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) { 343 return &did.DocResolution{ 344 DIDDocument: mockdiddoc.GetMockDIDDoc(t, true), 345 }, nil 346 }, 347 } 348 349 _, err := s.AcceptInvitation(inv, WithRouterConnections([]string{"foo"})) 350 require.ErrorIs(t, err, expectedErr) 351 require.Contains(t, err.Error(), "add key to the router") 352 }) 353 354 t.Run("invitation accept values with a valid presentproof V3 target code", func(t *testing.T) { 355 msg := service.NewDIDCommMsgMap(presentproof.PresentationV3{ 356 Type: presentproof.RequestPresentationMsgTypeV3, 357 Attachments: []decorator.AttachmentV2{{ 358 Data: decorator.AttachmentData{ 359 Base64: base64.StdEncoding.EncodeToString([]byte(`{}`)), 360 }, 361 }}, 362 }) 363 364 provider := testProvider(t) 365 s := newAutoService(t, provider) 366 ed25519RawKey, p384KeyMarshalled := createAuthenticationAndAgreementKeys(t, provider) 367 368 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 369 CreateAndExportPubKeyBytes(provider.KeyTypeValue).Return("", ed25519RawKey, nil) 370 provider.CustomKMS.(*mockkms.MockKeyManager).EXPECT(). 371 CreateAndExportPubKeyBytes(provider.KeyAgreementTypeValue).Return("", p384KeyMarshalled, nil) 372 373 inv := newInvitation() 374 inv.Body.Goal = "propose a present-proof V3.0" 375 inv.Body.GoalCode = "present-proof/3.0/propose-presentation" 376 inv.Body.Accept = []string{transport.MediaTypeDIDCommV2Profile} 377 inv.Requests = []*decorator.AttachmentV2{ 378 { 379 ID: uuid.New().String(), 380 Description: "PresentProof V3 propose presentation request", 381 FileName: "presentproofv3.json", 382 MediaType: "application/json", 383 LastModTime: time.Time{}, 384 Data: decorator.AttachmentData{ 385 JSON: msg, 386 }, 387 }, 388 } 389 390 s.vdrRegistry = &mockvdr.MockVDRegistry{ 391 ResolveFunc: func(id string, _ ...vdrapi.DIDMethodOption) (*did.DocResolution, error) { 392 return &did.DocResolution{ 393 DIDDocument: mockdiddoc.GetMockDIDDoc(t, true), 394 }, nil 395 }, 396 } 397 398 connID, err := s.AcceptInvitation(inv) 399 require.NoError(t, err) 400 require.NotEmpty(t, connID) 401 }) 402 } 403 404 func TestSaveInvitation(t *testing.T) { 405 t.Run("success", func(t *testing.T) { 406 provider := testProvider(t) 407 408 inv := newInvitation() 409 410 s, err := New(provider) 411 require.NoError(t, err) 412 413 err = s.SaveInvitation(inv) 414 require.NoError(t, err) 415 }) 416 417 t.Run("failure", func(t *testing.T) { 418 provider := testProvider(t) 419 420 expectErr := fmt.Errorf("expected store error") 421 422 provider.StoreProvider = mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 423 ErrPut: expectErr, 424 }) 425 426 inv := newInvitation() 427 428 s, err := New(provider) 429 require.NoError(t, err) 430 431 err = s.SaveInvitation(inv) 432 require.ErrorIs(t, err, expectErr) 433 }) 434 } 435 436 func createAuthenticationAndAgreementKeys(t *testing.T, provider *protocol.MockProvider) ([]byte, []byte) { 437 ed25519RawKey := base58.Decode("B12NYF8RrR3h41TDCTJojY59usg3mbtbjnFs7Eud1Y6u") 438 p384RawKey := base58.Decode("7xunFyusHxhJS3tbNWcX7xHCLRPnsScaBJJQUWw8KPpTTPfUSw9RbdyQYCBaLopw6eVQJv1G4ZD4EWgnE" + 439 "3zmkuiGHTq5y1KAwPAUv9Q4XXBricnzAxKamSHJiX29uQqGtbux") 440 x, y := elliptic.Unmarshal(elliptic.P384(), p384RawKey) 441 442 p384Key := crypto.PublicKey{ 443 X: x.Bytes(), 444 Y: y.Bytes(), 445 Curve: elliptic.P384().Params().Name, 446 Type: "EC", 447 } 448 449 p384KeyMarshalled, err := json.Marshal(p384Key) 450 require.NoError(t, err) 451 452 p384KID, err := jwkkid.CreateKID(p384KeyMarshalled, provider.KeyAgreementTypeValue) 453 require.NoError(t, err) 454 455 p384Key.KID = p384KID 456 457 p384KeyMarshalled, err = json.Marshal(p384Key) 458 require.NoError(t, err) 459 460 return ed25519RawKey, p384KeyMarshalled 461 } 462 463 func testProvider(t *testing.T) *protocol.MockProvider { 464 ctrl := gomock.NewController(t) 465 defer ctrl.Finish() 466 467 p := &protocol.MockProvider{ 468 StoreProvider: mockstore.NewMockStoreProvider(), 469 ProtocolStateStoreProvider: mockstore.NewMockStoreProvider(), 470 CustomMessenger: &mocksvc.MockMessenger{}, 471 KeyTypeValue: kms.ED25519, 472 KeyAgreementTypeValue: kms.NISTP384ECDHKWType, 473 } 474 475 km := mockkms.NewMockKeyManager(ctrl) 476 477 ppf, err := presentproof.New(p) 478 require.NoError(t, err) 479 480 // auto service for presentproof 481 events := make(chan service.DIDCommAction) 482 require.NoError(t, ppf.RegisterActionEvent(events)) 483 484 go service.AutoExecuteActionEvent(events) 485 486 messagePickupService, err := messagepickup.New(p) 487 require.NoError(t, err) 488 489 p.ServiceMap = map[string]interface{}{ 490 messagepickup.MessagePickup: messagePickupService, 491 } 492 493 mediatorSvc, err := mediator.New(p) 494 require.NoError(t, err) 495 496 // auto service for message pickup 497 events = make(chan service.DIDCommAction) 498 require.NoError(t, messagePickupService.RegisterActionEvent(events)) 499 500 go service.AutoExecuteActionEvent(events) 501 502 return &protocol.MockProvider{ 503 StoreProvider: mockstore.NewMockStoreProvider(), 504 ProtocolStateStoreProvider: mockstore.NewMockStoreProvider(), 505 CustomKMS: km, 506 KeyTypeValue: p.KeyTypeValue, 507 KeyAgreementTypeValue: p.KeyAgreementTypeValue, 508 MsgTypeServicesTargets: []dispatcher.MessageTypeTarget{ 509 { 510 Target: "present-proof/2.0/propose-presentation", 511 MsgType: "https://didcomm.org/present-proof/2.0/propose-presentation", 512 }, 513 { 514 Target: "present-proof/2.0/request-presentation", 515 MsgType: "https://didcomm.org/present-proof/2.0/request-presentation", 516 }, 517 { 518 Target: "present-proof/2.0/presentation", 519 MsgType: "https://didcomm.org/present-proof/2.0/presentation", 520 }, 521 { 522 Target: "present-proof/2.0/ack", 523 MsgType: "https://didcomm.org/present-proof/2.0/ack", 524 }, 525 { 526 Target: "present-proof/3.0/propose-presentation", 527 MsgType: "https://didcomm.org/present-proof/3.0/propose-presentation", 528 }, 529 { 530 Target: "present-proof/3.0/request-presentation", 531 MsgType: "https://didcomm.org/present-proof/3.0/request-presentation", 532 }, 533 { 534 Target: "present-proof/3.0/presentation", 535 MsgType: "https://didcomm.org/present-proof/3.0/presentation", 536 }, 537 { 538 Target: "present-proof/3.0/ack", 539 MsgType: "https://didcomm.org/present-proof/3.0/ack", 540 }, 541 { 542 Target: "messagepickup/1.0/status", 543 MsgType: "https://didcomm.org/messagepickup/1.0/status", 544 }, 545 { 546 Target: "messagepickup/1.0/status-request", 547 MsgType: "https://didcomm.org/messagepickup/1.0/status-request", 548 }, 549 }, 550 AllProtocolServices: []dispatcher.ProtocolService{ 551 ppf, 552 messagePickupService, 553 mediatorSvc, 554 }, 555 ServiceMap: map[string]interface{}{ 556 messagepickup.MessagePickup: messagePickupService, 557 presentproof.Name: ppf, 558 mediator.Coordination: mediatorSvc, 559 }, 560 } 561 } 562 563 func newInvitation() *Invitation { 564 return &Invitation{ 565 ID: uuid.New().String(), 566 Type: InvitationMsgType, 567 Label: "test", 568 From: "did:example:alice", 569 Body: &InvitationBody{ 570 Goal: "test", 571 GoalCode: "test", 572 Accept: []string{transport.MediaTypeDIDCommV2Profile}, 573 }, 574 Requests: []*decorator.AttachmentV2{ 575 { 576 ID: uuid.New().String(), 577 Description: "test", 578 FileName: "dont_open_this.exe", 579 Data: decorator.AttachmentData{ 580 JSON: map[string]interface{}{ 581 "id": "123", 582 "type": "test-type", 583 }, 584 }, 585 }, 586 }, 587 } 588 } 589 590 func newAutoService(t *testing.T, provider *protocol.MockProvider) *Service { 591 s, err := New(provider) 592 require.NoError(t, err) 593 594 events := make(chan service.DIDCommAction) 595 require.NoError(t, s.RegisterActionEvent(events)) 596 597 go service.AutoExecuteActionEvent(events) 598 599 return s 600 }