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

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package aries
     8  
     9  import (
    10  	"fmt"
    11  	"strings"
    12  
    13  	"github.com/google/uuid"
    14  	jsonld "github.com/piprate/json-gold/ld"
    15  
    16  	"github.com/hyperledger/aries-framework-go/pkg/crypto"
    17  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/middleware"
    18  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service"
    19  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher"
    20  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher/inbound"
    21  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher/outbound"
    22  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/messenger"
    23  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packager"
    24  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/packer"
    25  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/protocol/decorator"
    26  	"github.com/hyperledger/aries-framework-go/pkg/didcomm/transport"
    27  	"github.com/hyperledger/aries-framework-go/pkg/doc/ld"
    28  	"github.com/hyperledger/aries-framework-go/pkg/doc/ldcontext/remote"
    29  	"github.com/hyperledger/aries-framework-go/pkg/framework/aries/api"
    30  	vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr"
    31  	"github.com/hyperledger/aries-framework-go/pkg/framework/context"
    32  	"github.com/hyperledger/aries-framework-go/pkg/kms"
    33  	"github.com/hyperledger/aries-framework-go/pkg/secretlock"
    34  	"github.com/hyperledger/aries-framework-go/pkg/store/did"
    35  	ldstore "github.com/hyperledger/aries-framework-go/pkg/store/ld"
    36  	"github.com/hyperledger/aries-framework-go/pkg/store/verifiable"
    37  	"github.com/hyperledger/aries-framework-go/pkg/vdr"
    38  	"github.com/hyperledger/aries-framework-go/pkg/vdr/key"
    39  	"github.com/hyperledger/aries-framework-go/pkg/vdr/peer"
    40  	"github.com/hyperledger/aries-framework-go/spi/storage"
    41  )
    42  
    43  const (
    44  	defaultEndpoint     = "didcomm:transport/queue"
    45  	defaultMasterKeyURI = "local-lock://default/master/key/"
    46  )
    47  
    48  // Aries provides access to the context being managed by the framework. The context can be used to create aries clients.
    49  type Aries struct {
    50  	storeProvider              storage.Provider
    51  	protocolStateStoreProvider storage.Provider
    52  	protocolSvcCreators        []api.ProtocolSvcCreator
    53  	services                   []dispatcher.ProtocolService
    54  	servicesMsgTypeTargets     []dispatcher.MessageTypeTarget
    55  	msgSvcProvider             api.MessageServiceProvider
    56  	outboundDispatcher         dispatcher.Outbound
    57  	messenger                  service.MessengerHandler
    58  	outboundTransports         []transport.OutboundTransport
    59  	inboundTransports          []transport.InboundTransport
    60  	kms                        kms.KeyManager
    61  	kmsCreator                 kms.Creator
    62  	secretLock                 secretlock.Service
    63  	crypto                     crypto.Crypto
    64  	packagerCreator            packager.Creator
    65  	packager                   transport.Packager
    66  	packerCreator              packer.Creator
    67  	packerCreators             []packer.Creator
    68  	primaryPacker              packer.Packer
    69  	packers                    []packer.Packer
    70  	vdrRegistry                vdrapi.Registry
    71  	vdr                        []vdrapi.VDR
    72  	verifiableStore            verifiable.Store
    73  	didConnectionStore         did.ConnectionStore
    74  	contextStore               ldstore.ContextStore
    75  	remoteProviderStore        ldstore.RemoteProviderStore
    76  	documentLoader             jsonld.DocumentLoader
    77  	contextProviderURLs        []string
    78  	transportReturnRoute       string
    79  	id                         string
    80  	keyType                    kms.KeyType
    81  	keyAgreementType           kms.KeyType
    82  	mediaTypeProfiles          []string
    83  	inboundEnvelopeHandler     inbound.MessageHandler
    84  	didRotator                 middleware.DIDCommMessageMiddleware
    85  }
    86  
    87  // Option configures the framework.
    88  type Option func(opts *Aries) error
    89  
    90  // New initializes the Aries framework based on the set of options provided. This function returns a framework
    91  // which can be used to manage Aries clients by getting the framework context.
    92  func New(opts ...Option) (*Aries, error) {
    93  	frameworkOpts := &Aries{}
    94  
    95  	// generate framework configs from options
    96  	for _, option := range opts {
    97  		err := option(frameworkOpts)
    98  		if err != nil {
    99  			closeErr := frameworkOpts.Close()
   100  			return nil, fmt.Errorf("close err: %v Error in option passed to New: %w", closeErr, err)
   101  		}
   102  	}
   103  
   104  	// generate a random framework ID
   105  	frameworkOpts.id = uuid.New().String()
   106  
   107  	// get the default framework options
   108  	err := defFrameworkOpts(frameworkOpts)
   109  	if err != nil {
   110  		return nil, fmt.Errorf("default option initialization failed: %w", err)
   111  	}
   112  
   113  	// TODO: https://github.com/hyperledger/aries-framework-go/issues/212
   114  	//  Define clear relationship between framework and context.
   115  	//  Details - The code creates context without protocolServices. The protocolServicesCreators are dependent
   116  	//  on the context. The inbound transports require ctx.MessageHandler(), which in-turn depends on
   117  	//  protocolServices. At the moment, there is a looping issue among these.
   118  
   119  	return initializeServices(frameworkOpts)
   120  }
   121  
   122  func initializeServices(frameworkOpts *Aries) (*Aries, error) {
   123  	// Order of initializing service is important
   124  	// Create kms
   125  	if e := createKMS(frameworkOpts); e != nil {
   126  		return nil, e
   127  	}
   128  
   129  	// Create vdr
   130  	if e := createVDR(frameworkOpts); e != nil {
   131  		return nil, e
   132  	}
   133  
   134  	// create packers and packager (must be done after KMS and connection store)
   135  	if err := createPackersAndPackager(frameworkOpts); err != nil {
   136  		return nil, err
   137  	}
   138  
   139  	// Create DID connection store
   140  	if err := createDIDConnectionStore(frameworkOpts); err != nil {
   141  		return nil, err
   142  	}
   143  
   144  	// Create DID rotator
   145  	if err := createDIDRotator(frameworkOpts); err != nil {
   146  		return nil, err
   147  	}
   148  
   149  	// Create outbound dispatcher
   150  	if err := createOutboundDispatcher(frameworkOpts); err != nil {
   151  		return nil, err
   152  	}
   153  
   154  	// Create messenger handler
   155  	if err := createMessengerHandler(frameworkOpts); err != nil {
   156  		return nil, err
   157  	}
   158  
   159  	// Load services
   160  	if err := loadServices(frameworkOpts); err != nil {
   161  		return nil, err
   162  	}
   163  
   164  	// Start inbound/outbound transports
   165  	if err := startTransports(frameworkOpts); err != nil {
   166  		return nil, err
   167  	}
   168  
   169  	return frameworkOpts, nil
   170  }
   171  
   172  // WithMessengerHandler injects a messenger handler to the Aries framework.
   173  func WithMessengerHandler(mh service.MessengerHandler) Option {
   174  	return func(opts *Aries) error {
   175  		opts.messenger = mh
   176  		return nil
   177  	}
   178  }
   179  
   180  // WithOutboundTransports injects an outbound transports to the Aries framework.
   181  func WithOutboundTransports(outboundTransports ...transport.OutboundTransport) Option {
   182  	return func(opts *Aries) error {
   183  		opts.outboundTransports = append(opts.outboundTransports, outboundTransports...)
   184  		return nil
   185  	}
   186  }
   187  
   188  // WithInboundTransport injects an inbound transport to the Aries framework.
   189  func WithInboundTransport(inboundTransport ...transport.InboundTransport) Option {
   190  	return func(opts *Aries) error {
   191  		opts.inboundTransports = append(opts.inboundTransports, inboundTransport...)
   192  		return nil
   193  	}
   194  }
   195  
   196  // WithTransportReturnRoute injects transport return route option to the Aries framework. Acceptable values - "none",
   197  // "all" or "thread". RFC - https://github.com/hyperledger/aries-rfcs/tree/master/features/0092-transport-return-route.
   198  // Currently, framework supports "all" and "none" option with WebSocket transport ("thread" is not supported).
   199  func WithTransportReturnRoute(transportReturnRoute string) Option {
   200  	return func(opts *Aries) error {
   201  		//  "thread" option is not supported at the moment.
   202  		if transportReturnRoute != decorator.TransportReturnRouteNone &&
   203  			transportReturnRoute != decorator.TransportReturnRouteAll {
   204  			return fmt.Errorf("invalid transport return route option : %s", transportReturnRoute)
   205  		}
   206  
   207  		opts.transportReturnRoute = transportReturnRoute
   208  
   209  		return nil
   210  	}
   211  }
   212  
   213  // WithStoreProvider injects a storage provider to the Aries framework.
   214  func WithStoreProvider(prov storage.Provider) Option {
   215  	return func(opts *Aries) error {
   216  		opts.storeProvider = prov
   217  		return nil
   218  	}
   219  }
   220  
   221  // WithProtocolStateStoreProvider injects a protocol state storage provider to the Aries framework.
   222  func WithProtocolStateStoreProvider(prov storage.Provider) Option {
   223  	return func(opts *Aries) error {
   224  		opts.protocolStateStoreProvider = prov
   225  		return nil
   226  	}
   227  }
   228  
   229  // WithProtocols injects a protocol service to the Aries framework.
   230  func WithProtocols(protocolSvcCreator ...api.ProtocolSvcCreator) Option {
   231  	return func(opts *Aries) error {
   232  		opts.protocolSvcCreators = append(opts.protocolSvcCreators, protocolSvcCreator...)
   233  		return nil
   234  	}
   235  }
   236  
   237  // WithSecretLock injects a SecretLock service to the Aries framework.
   238  func WithSecretLock(s secretlock.Service) Option {
   239  	return func(opts *Aries) error {
   240  		opts.secretLock = s
   241  		return nil
   242  	}
   243  }
   244  
   245  // WithKMS injects a KMS service to the Aries framework.
   246  func WithKMS(k kms.Creator) Option {
   247  	return func(opts *Aries) error {
   248  		opts.kmsCreator = k
   249  		return nil
   250  	}
   251  }
   252  
   253  // WithCrypto injects a crypto service to the Aries framework.
   254  func WithCrypto(c crypto.Crypto) Option {
   255  	return func(opts *Aries) error {
   256  		opts.crypto = c
   257  		return nil
   258  	}
   259  }
   260  
   261  // WithVDR injects a VDR service to the Aries framework.
   262  func WithVDR(v vdrapi.VDR) Option {
   263  	return func(opts *Aries) error {
   264  		opts.vdr = append(opts.vdr, v)
   265  		return nil
   266  	}
   267  }
   268  
   269  // WithMessageServiceProvider injects a message service provider to the Aries framework.
   270  // Message service provider returns list of message services which can be used to provide custom handle
   271  // functionality based on incoming messages type and purpose.
   272  func WithMessageServiceProvider(msv api.MessageServiceProvider) Option {
   273  	return func(opts *Aries) error {
   274  		opts.msgSvcProvider = msv
   275  		return nil
   276  	}
   277  }
   278  
   279  // WithPacker injects at least one Packer service into the Aries framework,
   280  // with the primary Packer being used for inbound/outbound communication
   281  // and the additional packers being available for unpacking inbound messages.
   282  func WithPacker(primary packer.Creator, additionalPackers ...packer.Creator) Option {
   283  	return func(opts *Aries) error {
   284  		opts.packerCreator = primary
   285  		opts.packerCreators = append(opts.packerCreators, additionalPackers...)
   286  
   287  		return nil
   288  	}
   289  }
   290  
   291  // WithVerifiableStore injects a verifiable credential store.
   292  func WithVerifiableStore(store verifiable.Store) Option {
   293  	return func(opts *Aries) error {
   294  		opts.verifiableStore = store
   295  		return nil
   296  	}
   297  }
   298  
   299  // WithDIDConnectionStore injects a DID connection store.
   300  func WithDIDConnectionStore(store did.ConnectionStore) Option {
   301  	return func(opts *Aries) error {
   302  		opts.didConnectionStore = store
   303  		return nil
   304  	}
   305  }
   306  
   307  // WithJSONLDContextStore injects a JSON-LD context store.
   308  func WithJSONLDContextStore(store ldstore.ContextStore) Option {
   309  	return func(opts *Aries) error {
   310  		opts.contextStore = store
   311  		return nil
   312  	}
   313  }
   314  
   315  // WithJSONLDRemoteProviderStore injects a JSON-LD remote provider store.
   316  func WithJSONLDRemoteProviderStore(store ldstore.RemoteProviderStore) Option {
   317  	return func(opts *Aries) error {
   318  		opts.remoteProviderStore = store
   319  		return nil
   320  	}
   321  }
   322  
   323  // WithJSONLDDocumentLoader injects a JSON-LD document loader.
   324  func WithJSONLDDocumentLoader(loader jsonld.DocumentLoader) Option {
   325  	return func(opts *Aries) error {
   326  		opts.documentLoader = loader
   327  		return nil
   328  	}
   329  }
   330  
   331  // WithJSONLDContextProviderURL injects URLs of the remote JSON-LD context providers.
   332  func WithJSONLDContextProviderURL(url ...string) Option {
   333  	return func(opts *Aries) error {
   334  		opts.contextProviderURLs = append(opts.contextProviderURLs, url...)
   335  		return nil
   336  	}
   337  }
   338  
   339  // WithKeyType injects a default signing key type.
   340  func WithKeyType(keyType kms.KeyType) Option {
   341  	return func(opts *Aries) error {
   342  		opts.keyType = keyType
   343  		return nil
   344  	}
   345  }
   346  
   347  // WithKeyAgreementType injects a default encryption key type.
   348  func WithKeyAgreementType(keyAgreementType kms.KeyType) Option {
   349  	return func(opts *Aries) error {
   350  		opts.keyAgreementType = keyAgreementType
   351  		return nil
   352  	}
   353  }
   354  
   355  // WithMediaTypeProfiles injects a default media types profile.
   356  func WithMediaTypeProfiles(mediaTypeProfiles []string) Option {
   357  	return func(opts *Aries) error {
   358  		opts.mediaTypeProfiles = make([]string, len(mediaTypeProfiles))
   359  		copy(opts.mediaTypeProfiles, mediaTypeProfiles)
   360  
   361  		return nil
   362  	}
   363  }
   364  
   365  // WithServiceMsgTypeTargets injects service msg type to target mappings in the context.
   366  func WithServiceMsgTypeTargets(msgTypeTargets ...dispatcher.MessageTypeTarget) Option {
   367  	return func(opts *Aries) error {
   368  		opts.servicesMsgTypeTargets = msgTypeTargets
   369  		return nil
   370  	}
   371  }
   372  
   373  // Context provides a handle to the framework context.
   374  func (a *Aries) Context() (*context.Provider, error) {
   375  	return context.New(
   376  		context.WithOutboundDispatcher(a.outboundDispatcher),
   377  		context.WithMessengerHandler(a.messenger),
   378  		context.WithOutboundTransports(a.outboundTransports...),
   379  		context.WithProtocolServices(a.services...),
   380  		context.WithKMS(a.kms),
   381  		context.WithSecretLock(a.secretLock),
   382  		context.WithCrypto(a.crypto),
   383  		context.WithServiceEndpoint(serviceEndpoint(a)),
   384  		context.WithRouterEndpoint(routingEndpoint(a)),
   385  		context.WithStorageProvider(a.storeProvider),
   386  		context.WithProtocolStateStorageProvider(a.protocolStateStoreProvider),
   387  		context.WithPacker(a.primaryPacker, a.packers...),
   388  		context.WithPackager(a.packager),
   389  		context.WithVDRegistry(a.vdrRegistry),
   390  		context.WithTransportReturnRoute(a.transportReturnRoute),
   391  		context.WithAriesFrameworkID(a.id),
   392  		context.WithMessageServiceProvider(a.msgSvcProvider),
   393  		context.WithVerifiableStore(a.verifiableStore),
   394  		context.WithDIDConnectionStore(a.didConnectionStore),
   395  		context.WithJSONLDContextStore(a.contextStore),
   396  		context.WithJSONLDRemoteProviderStore(a.remoteProviderStore),
   397  		context.WithJSONLDDocumentLoader(a.documentLoader),
   398  		context.WithKeyType(a.keyType),
   399  		context.WithKeyAgreementType(a.keyAgreementType),
   400  		context.WithMediaTypeProfiles(a.mediaTypeProfiles),
   401  		context.WithServiceMsgTypeTargets(a.servicesMsgTypeTargets...),
   402  		context.WithDIDRotator(&a.didRotator),
   403  		context.WithInboundEnvelopeHandler(&a.inboundEnvelopeHandler),
   404  	)
   405  }
   406  
   407  // Messenger returns messenger for sending messages through this agent framework
   408  // TODO should use dedicated messenger interface instead of Outbound dispatcher [Issue #1058].
   409  func (a *Aries) Messenger() service.Messenger {
   410  	return a.messenger
   411  }
   412  
   413  // Close frees resources being maintained by the framework.
   414  func (a *Aries) Close() error {
   415  	if a.storeProvider != nil {
   416  		err := a.storeProvider.Close()
   417  		if err != nil {
   418  			return fmt.Errorf("failed to close the store: %w", err)
   419  		}
   420  	}
   421  
   422  	if a.protocolStateStoreProvider != nil {
   423  		err := a.protocolStateStoreProvider.Close()
   424  		if err != nil {
   425  			return fmt.Errorf("failed to close the store: %w", err)
   426  		}
   427  	}
   428  
   429  	for _, inbound := range a.inboundTransports {
   430  		if err := inbound.Stop(); err != nil {
   431  			return fmt.Errorf("inbound transport close failed: %w", err)
   432  		}
   433  	}
   434  
   435  	return a.closeVDR()
   436  }
   437  
   438  func (a *Aries) closeVDR() error {
   439  	if a.vdrRegistry != nil {
   440  		if err := a.vdrRegistry.Close(); err != nil {
   441  			return fmt.Errorf("vdr registry close failed: %w", err)
   442  		}
   443  	}
   444  
   445  	return nil
   446  }
   447  
   448  type kmsProvider struct {
   449  	kmsStore          kms.Store
   450  	secretLockService secretlock.Service
   451  }
   452  
   453  func (k *kmsProvider) StorageProvider() kms.Store {
   454  	return k.kmsStore
   455  }
   456  
   457  func (k *kmsProvider) SecretLock() secretlock.Service {
   458  	return k.secretLockService
   459  }
   460  
   461  func createKMS(frameworkOpts *Aries) error {
   462  	ariesProviderKMSStoreWrapper, err := kms.NewAriesProviderWrapper(frameworkOpts.storeProvider)
   463  	if err != nil {
   464  		return fmt.Errorf("create Aries provider KMS store wrapper failed: %w", err)
   465  	}
   466  
   467  	kmsProv := &kmsProvider{
   468  		kmsStore:          ariesProviderKMSStoreWrapper,
   469  		secretLockService: frameworkOpts.secretLock,
   470  	}
   471  
   472  	frameworkOpts.kms, err = frameworkOpts.kmsCreator(kmsProv)
   473  	if err != nil {
   474  		return fmt.Errorf("create KMS failed: %w", err)
   475  	}
   476  
   477  	return nil
   478  }
   479  
   480  func createVDR(frameworkOpts *Aries) error {
   481  	ctx, err := context.New(
   482  		context.WithKMS(frameworkOpts.kms),
   483  		context.WithCrypto(frameworkOpts.crypto),
   484  		context.WithStorageProvider(frameworkOpts.storeProvider),
   485  		context.WithServiceEndpoint(serviceEndpoint(frameworkOpts)),
   486  	)
   487  	if err != nil {
   488  		return fmt.Errorf("create context failed: %w", err)
   489  	}
   490  
   491  	var opts []vdr.Option
   492  	for _, v := range frameworkOpts.vdr {
   493  		opts = append(opts, vdr.WithVDR(v))
   494  	}
   495  
   496  	p, err := peer.New(ctx.StorageProvider())
   497  	if err != nil {
   498  		return fmt.Errorf("create new vdr peer failed: %w", err)
   499  	}
   500  
   501  	dst := vdrapi.DIDCommServiceType
   502  
   503  	for _, mediaType := range frameworkOpts.mediaTypeProfiles {
   504  		if mediaType == transport.MediaTypeDIDCommV2Profile || mediaType == transport.MediaTypeAIP2RFC0587Profile {
   505  			dst = vdrapi.DIDCommV2ServiceType
   506  			break
   507  		}
   508  	}
   509  
   510  	opts = append(opts,
   511  		vdr.WithVDR(p),
   512  		vdr.WithDefaultServiceType(dst),
   513  		vdr.WithDefaultServiceEndpoint(ctx.ServiceEndpoint()),
   514  	)
   515  
   516  	k := key.New()
   517  	opts = append(opts, vdr.WithVDR(k))
   518  
   519  	frameworkOpts.vdrRegistry = vdr.New(opts...)
   520  
   521  	return nil
   522  }
   523  
   524  func createMessengerHandler(frameworkOpts *Aries) error {
   525  	if frameworkOpts.messenger != nil {
   526  		return nil
   527  	}
   528  
   529  	ctx, err := context.New(
   530  		context.WithOutboundDispatcher(frameworkOpts.outboundDispatcher),
   531  		context.WithStorageProvider(frameworkOpts.storeProvider),
   532  	)
   533  	if err != nil {
   534  		return fmt.Errorf("context creation failed: %w", err)
   535  	}
   536  
   537  	frameworkOpts.messenger, err = messenger.NewMessenger(ctx)
   538  
   539  	return err
   540  }
   541  
   542  func createDIDRotator(frameworkOpts *Aries) error {
   543  	ctx, err := context.New(
   544  		context.WithKMS(frameworkOpts.kms),
   545  		context.WithCrypto(frameworkOpts.crypto),
   546  		context.WithVDRegistry(frameworkOpts.vdrRegistry),
   547  		context.WithStorageProvider(frameworkOpts.storeProvider),
   548  		context.WithProtocolStateStorageProvider(frameworkOpts.protocolStateStoreProvider),
   549  		context.WithDIDConnectionStore(frameworkOpts.didConnectionStore),
   550  	)
   551  	if err != nil {
   552  		return fmt.Errorf("context creation failed: %w", err)
   553  	}
   554  
   555  	dr, err := middleware.New(ctx)
   556  	if err != nil {
   557  		return fmt.Errorf("failed to init did rotator: %w", err)
   558  	}
   559  
   560  	frameworkOpts.didRotator = *dr
   561  
   562  	return nil
   563  }
   564  
   565  func createOutboundDispatcher(frameworkOpts *Aries) error {
   566  	ctx, err := context.New(
   567  		context.WithKMS(frameworkOpts.kms),
   568  		context.WithCrypto(frameworkOpts.crypto),
   569  		context.WithOutboundTransports(frameworkOpts.outboundTransports...),
   570  		context.WithPackager(frameworkOpts.packager),
   571  		context.WithTransportReturnRoute(frameworkOpts.transportReturnRoute),
   572  		context.WithVDRegistry(frameworkOpts.vdrRegistry),
   573  		context.WithStorageProvider(frameworkOpts.storeProvider),
   574  		context.WithProtocolStateStorageProvider(frameworkOpts.protocolStateStoreProvider),
   575  		context.WithMediaTypeProfiles(frameworkOpts.mediaTypeProfiles),
   576  		context.WithKeyAgreementType(frameworkOpts.keyAgreementType),
   577  		context.WithDIDRotator(&frameworkOpts.didRotator),
   578  	)
   579  	if err != nil {
   580  		return fmt.Errorf("context creation failed: %w", err)
   581  	}
   582  
   583  	frameworkOpts.outboundDispatcher, err = outbound.NewOutbound(ctx)
   584  	if err != nil {
   585  		return fmt.Errorf("failed to init outbound dispatcher: %w", err)
   586  	}
   587  
   588  	return nil
   589  }
   590  
   591  func createDIDConnectionStore(frameworkOpts *Aries) error {
   592  	if frameworkOpts.didConnectionStore != nil {
   593  		return nil
   594  	}
   595  
   596  	ctx, err := context.New(
   597  		context.WithStorageProvider(frameworkOpts.storeProvider),
   598  		context.WithVDRegistry(frameworkOpts.vdrRegistry),
   599  	)
   600  	if err != nil {
   601  		return fmt.Errorf("context creation failed: %w", err)
   602  	}
   603  
   604  	frameworkOpts.didConnectionStore, err = did.NewConnectionStore(ctx)
   605  
   606  	return err
   607  }
   608  
   609  func createJSONLDContextStore(frameworkOpts *Aries) error {
   610  	if frameworkOpts.contextStore != nil {
   611  		return nil
   612  	}
   613  
   614  	s, err := ldstore.NewContextStore(frameworkOpts.storeProvider)
   615  	if err != nil {
   616  		return fmt.Errorf("failed to init JSON-LD context store: %w", err)
   617  	}
   618  
   619  	frameworkOpts.contextStore = s
   620  
   621  	return nil
   622  }
   623  
   624  func createJSONLDRemoteProviderStore(frameworkOpts *Aries) error {
   625  	if frameworkOpts.remoteProviderStore != nil {
   626  		return nil
   627  	}
   628  
   629  	s, err := ldstore.NewRemoteProviderStore(frameworkOpts.storeProvider)
   630  	if err != nil {
   631  		return fmt.Errorf("failed to init JSON-LD remote provider store: %w", err)
   632  	}
   633  
   634  	frameworkOpts.remoteProviderStore = s
   635  
   636  	return nil
   637  }
   638  
   639  func createJSONLDDocumentLoader(frameworkOpts *Aries) error {
   640  	if frameworkOpts.documentLoader != nil {
   641  		return nil
   642  	}
   643  
   644  	ctx, err := context.New(
   645  		context.WithJSONLDContextStore(frameworkOpts.contextStore),
   646  		context.WithJSONLDRemoteProviderStore(frameworkOpts.remoteProviderStore),
   647  	)
   648  	if err != nil {
   649  		return fmt.Errorf("context creation failed: %w", err)
   650  	}
   651  
   652  	var loaderOpts []ld.DocumentLoaderOpts
   653  
   654  	if len(frameworkOpts.contextProviderURLs) > 0 {
   655  		for _, url := range frameworkOpts.contextProviderURLs {
   656  			loaderOpts = append(loaderOpts, ld.WithRemoteProvider(remote.NewProvider(url)))
   657  		}
   658  	}
   659  
   660  	documentLoader, err := ld.NewDocumentLoader(ctx, loaderOpts...)
   661  	if err != nil {
   662  		return fmt.Errorf("document loader creation failed: %w", err)
   663  	}
   664  
   665  	frameworkOpts.documentLoader = documentLoader
   666  
   667  	return nil
   668  }
   669  
   670  func startTransports(frameworkOpts *Aries) error {
   671  	ctx, err := context.New(
   672  		context.WithCrypto(frameworkOpts.crypto),
   673  		context.WithPackager(frameworkOpts.packager),
   674  		context.WithProtocolServices(frameworkOpts.services...),
   675  		context.WithAriesFrameworkID(frameworkOpts.id),
   676  		context.WithMessageServiceProvider(frameworkOpts.msgSvcProvider),
   677  		context.WithMessengerHandler(frameworkOpts.messenger),
   678  		context.WithDIDConnectionStore(frameworkOpts.didConnectionStore),
   679  		context.WithKeyType(frameworkOpts.keyType),
   680  		context.WithKeyAgreementType(frameworkOpts.keyAgreementType),
   681  		context.WithMediaTypeProfiles(frameworkOpts.mediaTypeProfiles),
   682  		context.WithInboundEnvelopeHandler(&frameworkOpts.inboundEnvelopeHandler),
   683  	)
   684  	if err != nil {
   685  		return fmt.Errorf("context creation failed: %w", err)
   686  	}
   687  
   688  	for _, inbound := range frameworkOpts.inboundTransports {
   689  		// Start the inbound transport
   690  		if err = inbound.Start(ctx); err != nil {
   691  			return fmt.Errorf("inbound transport start failed: %w", err)
   692  		}
   693  	}
   694  
   695  	// Start the outbound transport
   696  	for _, outbound := range frameworkOpts.outboundTransports {
   697  		if err = outbound.Start(ctx); err != nil {
   698  			return fmt.Errorf("outbound transport start failed: %w", err)
   699  		}
   700  	}
   701  
   702  	return nil
   703  }
   704  
   705  func loadServices(frameworkOpts *Aries) error { // nolint:funlen
   706  	// uninitialized
   707  	frameworkOpts.inboundEnvelopeHandler = inbound.MessageHandler{}
   708  
   709  	ctx, err := context.New(
   710  		context.WithOutboundDispatcher(frameworkOpts.outboundDispatcher),
   711  		context.WithMessengerHandler(frameworkOpts.messenger),
   712  		context.WithStorageProvider(frameworkOpts.storeProvider),
   713  		context.WithProtocolStateStorageProvider(frameworkOpts.protocolStateStoreProvider),
   714  		context.WithKMS(frameworkOpts.kms),
   715  		context.WithCrypto(frameworkOpts.crypto),
   716  		context.WithPackager(frameworkOpts.packager),
   717  		context.WithServiceEndpoint(serviceEndpoint(frameworkOpts)),
   718  		context.WithRouterEndpoint(routingEndpoint(frameworkOpts)),
   719  		context.WithVDRegistry(frameworkOpts.vdrRegistry),
   720  		context.WithVerifiableStore(frameworkOpts.verifiableStore),
   721  		context.WithDIDConnectionStore(frameworkOpts.didConnectionStore),
   722  		context.WithMessageServiceProvider(frameworkOpts.msgSvcProvider),
   723  		context.WithJSONLDDocumentLoader(frameworkOpts.documentLoader),
   724  		context.WithKeyType(frameworkOpts.keyType),
   725  		context.WithKeyAgreementType(frameworkOpts.keyAgreementType),
   726  		context.WithMediaTypeProfiles(frameworkOpts.mediaTypeProfiles),
   727  		context.WithInboundEnvelopeHandler(&frameworkOpts.inboundEnvelopeHandler),
   728  		context.WithServiceMsgTypeTargets(frameworkOpts.servicesMsgTypeTargets...),
   729  		context.WithDIDRotator(&frameworkOpts.didRotator),
   730  	)
   731  	if err != nil {
   732  		return fmt.Errorf("create context failed: %w", err)
   733  	}
   734  
   735  	for i, v := range frameworkOpts.protocolSvcCreators {
   736  		svc, svcErr := v.Create(ctx)
   737  		if svcErr != nil {
   738  			return fmt.Errorf("new protocol service failed: %w", svcErr)
   739  		}
   740  
   741  		frameworkOpts.services = append(frameworkOpts.services, svc)
   742  		// after service was successfully created we need to add it to the context
   743  		// since the introduce protocol depends on did-exchange
   744  		if e := context.WithProtocolServices(frameworkOpts.services...)(ctx); e != nil {
   745  			return e
   746  		}
   747  
   748  		frameworkOpts.protocolSvcCreators[i].ServicePointer = svc
   749  	}
   750  
   751  	// after adding all protocol services to the context, we can initialize the handler properly.
   752  	frameworkOpts.inboundEnvelopeHandler.Initialize(ctx)
   753  
   754  	for _, v := range frameworkOpts.protocolSvcCreators {
   755  		if init := v.Init; init != nil {
   756  			if e := init(v.ServicePointer, ctx); e != nil {
   757  				return e
   758  			}
   759  		} else {
   760  			if e := v.ServicePointer.Initialize(ctx); e != nil {
   761  				return e
   762  			}
   763  		}
   764  	}
   765  
   766  	return nil
   767  }
   768  
   769  func createPackersAndPackager(frameworkOpts *Aries) error {
   770  	ctx, err := context.New(
   771  		context.WithCrypto(frameworkOpts.crypto),
   772  		context.WithStorageProvider(frameworkOpts.storeProvider),
   773  		context.WithKMS(frameworkOpts.kms),
   774  		context.WithVDRegistry(frameworkOpts.vdrRegistry),
   775  	)
   776  	if err != nil {
   777  		return fmt.Errorf("create packer context failed: %w", err)
   778  	}
   779  
   780  	frameworkOpts.primaryPacker, err = frameworkOpts.packerCreator(ctx)
   781  	if err != nil {
   782  		return fmt.Errorf("create packer failed: %w", err)
   783  	}
   784  
   785  	for _, pC := range frameworkOpts.packerCreators {
   786  		if pC == nil {
   787  			continue
   788  		}
   789  
   790  		p, e := pC(ctx)
   791  		if e != nil {
   792  			return fmt.Errorf("create packer failed: %w", e)
   793  		}
   794  
   795  		frameworkOpts.packers = append(frameworkOpts.packers, p)
   796  	}
   797  
   798  	ctx, err = context.New(context.WithPacker(frameworkOpts.primaryPacker, frameworkOpts.packers...),
   799  		context.WithStorageProvider(frameworkOpts.storeProvider), context.WithVDRegistry(frameworkOpts.vdrRegistry))
   800  	if err != nil {
   801  		return fmt.Errorf("create packager context failed: %w", err)
   802  	}
   803  
   804  	frameworkOpts.packager, err = frameworkOpts.packagerCreator(ctx)
   805  	if err != nil {
   806  		return fmt.Errorf("create packager failed: %w", err)
   807  	}
   808  
   809  	return nil
   810  }
   811  
   812  func serviceEndpoint(frameworkOpts *Aries) string {
   813  	return fetchEndpoint(frameworkOpts, "ws")
   814  }
   815  
   816  func routingEndpoint(frameworkOpts *Aries) string {
   817  	return fetchEndpoint(frameworkOpts, "http")
   818  }
   819  
   820  func fetchEndpoint(frameworkOpts *Aries, defaultScheme string) string {
   821  	// TODO https://github.com/hyperledger/aries-framework-go/issues/1161 Select Service and Router
   822  	//  endpoint from Multiple Inbound Transports
   823  	for _, inbound := range frameworkOpts.inboundTransports {
   824  		if strings.HasPrefix(inbound.Endpoint(), defaultScheme) {
   825  			return inbound.Endpoint()
   826  		}
   827  	}
   828  
   829  	if len(frameworkOpts.inboundTransports) > 0 {
   830  		return frameworkOpts.inboundTransports[0].Endpoint()
   831  	}
   832  
   833  	return defaultEndpoint
   834  }