/// <inheritdoc/>
        public async Task <(DidExchangeRequestMessage, ConnectionRecord)> CreateRequestAsync(IAgentContext agentContext, string did)
        {
            var key = await Did.KeyForDidAsync(await agentContext.Pool, agentContext.Wallet, did);

            var endpointResult = await _ledgerService.LookupServiceEndpointAsync(agentContext, did);

            var myDid = await Did.CreateAndStoreMyDidAsync(agentContext.Wallet, "{}");

            var connection = new ConnectionRecord
            {
                Endpoint = new AgentEndpoint {
                    Uri = endpointResult.Result.Endpoint
                },
                MyDid    = DidUtils.ConvertVerkeyToDidKey(myDid.VerKey),
                MyVk     = myDid.VerKey,
                TheirDid = did,
                TheirVk  = key,
                State    = ConnectionState.Negotiating,
            };
            await _recordService.AddAsync(agentContext.Wallet, connection);

            var provisioningRecord = await _provisioningService.GetProvisioningAsync(agentContext.Wallet);

            var didDoc = new AttachmentContent
            {
                Base64 = connection.MyDidDoc(provisioningRecord).ToJson().ToBase64Url()
            };
            await didDoc.SignWithJsonWebSignature(agentContext.Wallet, myDid.VerKey);

            var attachment = new Attachment
            {
                Id       = Guid.NewGuid().ToString(),
                MimeType = "application/json",
                Data     = didDoc
            };

            var request = new DidExchangeRequestMessage
            {
                Did    = connection.MyDid,
                Label  = provisioningRecord.Owner.Name,
                DidDoc = attachment
            };

            return(request, connection);
        }
        /// <inheritdoc/>
        public async Task <ConnectionRecord> ProcessRequestAsync(IAgentContext agentContext, DidExchangeRequestMessage requestMessage)
        {
            var myDid = await Did.CreateAndStoreMyDidAsync(agentContext.Wallet, "{}");

            DidDoc didDoc = null;

            if (requestMessage.DidDoc.Data.Base64 is { } data)
            {
                var isValidSignature = await requestMessage.DidDoc.Data.VerifyJsonWebSignature();

                if (isValidSignature == false)
                {
                    throw new AriesFrameworkException(ErrorCode.InvalidSignatureEncoding,
                                                      "The given JSON web signature is invalid");
                }

                var json = data.FromBase64Url();
                didDoc = json.ToObject <DidDoc>();
            }

            // Todo: Handle resolvable Dids
            if (didDoc == null)
            {
                throw new NotImplementedException("Request message must provide an attached did document");
            }

            if (didDoc.Keys.All(key => key.Type == DidDocExtensions.DefaultKeyType) == false)
            {
                throw new NotImplementedException($"Only {DidDocExtensions.DefaultKeyType} is supported");
            }

            var indyService = (IndyAgentDidDocService)didDoc.Services.First(service => service is IndyAgentDidDocService);

            var agentEndpoint = new AgentEndpoint(indyService.ServiceEndpoint, null, indyService.RoutingKeys.ToArray());

            var connectionRecord = new ConnectionRecord
            {
                Id    = Guid.NewGuid().ToString(),
                Alias = new ConnectionAlias {
                    Name = requestMessage.Label
                },
                MyDid    = DidUtils.ConvertVerkeyToDidKey(myDid.VerKey),
                MyVk     = myDid.VerKey,
                TheirDid = requestMessage.Did,
                TheirVk  = didDoc.Keys.FirstOrDefault(key => key.Controller == requestMessage.Did)?.PublicKeyBase58
                           ?? throw new NullReferenceException("Missing public for controller"),
                                 Endpoint = agentEndpoint,
                                 State    = ConnectionState.Negotiating
            };
            await _recordService.AddAsync(agentContext.Wallet, connectionRecord);

            _eventAggregator.Publish(
                new ServiceMessageProcessingEvent
            {
                MessageType = requestMessage.Type,
                RecordId    = connectionRecord.Id,
                ThreadId    = requestMessage.GetThreadId()
            });

            return(connectionRecord);
        }