/// <inheritdoc />
        public virtual async Task <(byte[], string)> PrepareRouteAsync(Wallet wallet, byte[] message, string endpointUri)
        {
            var records = await _registrationService.GetAllCloudAgentAsync(wallet);

            int counter = 0;

            while (records.Count > 0)
            {
                counter++;
                var record = _registrationService.getRandomCloudAgent(records);
                message = await CryptoUtils.PackAsync(wallet, record.TheirVk, new ForwardMessage { Message = message.GetUTF8String(), To = endpointUri });

                endpointUri = record.Endpoint.ServiceEndpoint;
            }
            return(message, endpointUri);
        }
        /// <inheritdoc />
        public virtual async Task <(ConnectionInvitationMessage, ConnectionRecord)> CreateInvitationAsync(IAgentContext agentContext,
                                                                                                          InviteConfiguration config = null)
        {
            var connectionId = !string.IsNullOrEmpty(config?.ConnectionId)
                ? config.ConnectionId
                : Guid.NewGuid().ToString();

            config = config ?? new InviteConfiguration();

            Logger.LogInformation(LoggingEvents.CreateInvitation, "ConnectionId {0}", connectionId);

            var connectionKey = await Crypto.CreateKeyAsync(agentContext.Wallet, "{}");

            var connection = new ConnectionRecord {
                Id = connectionId
            };

            connection.SetTag(TagConstants.ConnectionKey, connectionKey);

            //if (config.AutoAcceptConnection)
            connection.SetTag(TagConstants.AutoAcceptConnection, "true");

            connection.MultiPartyInvitation = config.MultiPartyInvitation;

            if (!config.MultiPartyInvitation)
            {
                connection.Alias = config.TheirAlias;
                if (!string.IsNullOrEmpty(config.TheirAlias.Name))
                {
                    connection.SetTag(TagConstants.Alias, config.TheirAlias.Name);
                }
            }

            foreach (var tag in config.Tags)
            {
                connection.SetTag(tag.Key, tag.Value);
            }

            var provisioning = await ProvisioningService.GetProvisioningAsync(agentContext.Wallet);

            string uri = "";

            if (string.IsNullOrEmpty(provisioning.Endpoint.Uri))
            {
                var records = await CloudAgentRegistrationService.GetAllCloudAgentAsync(agentContext.Wallet);

                if (records.Count > 0)
                {
                    var record = CloudAgentRegistrationService.getRandomCloudAgent(records);
                    uri = record.Endpoint.ResponseEndpoint + "/" + record.MyConsumerId;
                }
                else
                {
                    throw new AgentFrameworkException(ErrorCode.RecordInInvalidState, "No Cloud Agent Registered");
                }
            }

            await RecordService.AddAsync(agentContext.Wallet, connection);

            return(new ConnectionInvitationMessage
            {
                ServiceEndpoint = uri,
                RoutingKeys = null,        //provisioning.Endpoint.Verkey != null ? new[] {provisioning.Endpoint.Verkey} : null,
                RecipientKeys = new[] { connectionKey },
                Label = config.MyAlias.Name ?? provisioning.Owner.Name,
                ImageUrl = config.MyAlias.ImageUrl ?? provisioning.Owner.ImageUrl
            }, connection);
        }