public async Task <string> CreateConnectionAsync(string counterPartyVaspId)
        {
            var counterPartyVaspCode = counterPartyVaspId.Substring(4, 8);
            var vaspTransportKey     = await _vaspCodesService.GetTransportKeyAsync(counterPartyVaspCode);

            if (vaspTransportKey == null)
            {
                throw new InvalidOperationException($"Couldn't get TransportKey for vasp code {counterPartyVaspCode}");
            }

            var sessionKey   = ECDH_Key.GenerateKey();
            var topic        = TopicGenerator.GenerateConnectionTopic();
            var privateKeyId = await _whisperRpc.RegisterKeyPairAsync(sessionKey.PrivateKey);

            var filter = await _whisperRpc.CreateMessageFilterAsync(topic, privateKeyId);

            _activeTopics.Add(topic);

            var connection = new Connection
            {
                Id                 = Guid.NewGuid().ToString("N"),
                Filter             = filter,
                InboundTopic       = topic,
                Status             = ConnectionStatus.Active,
                CounterPartyVaspId = counterPartyVaspId,
                PrivateKey         = sessionKey.PrivateKey,
            };

            _connections[connection.Id] = connection;

            return(connection.Id);
        }
        private async Task HandleInviteMessageAsync(OpenVaspPayload payload)
        {
            var senderVaspCode   = payload.SenderVaspId.Substring(4, 8);
            var vaspTransportKey = await _vaspCodesService.GetTransportKeyAsync(senderVaspCode);

            if (vaspTransportKey == null)
            {
                _logger?.LogError($"Transport key for vasp code {senderVaspCode} cannot be found during invitation processing");
                return;
            }

            _connections.TryGetValue(payload.ConnectionId, out var connection);
            if (connection != null)
            {
                bool isSameData = connection.CounterPartyVaspId == payload.SenderVaspId &&
                                  connection.OutboundTopic == payload.ReturnTopic;
                if (isSameData)
                {
                    _logger?.LogWarning(
                        $"Received invite for already existing connectionId {payload.ConnectionId} with the same data. Skipping.");

                    await AcknowledgeMessageAsync(
                        payload,
                        null,
                        payload.EcdhPk.DecompressPublicKey().ToHex(true));
                }
                else
                {
                    _logger?.LogWarning(
                        $"Received invite for already existing connectionId {payload.ConnectionId} with the different data:{Environment.NewLine}"
                        + $"SenderVaspId: {connection.CounterPartyVaspId} - {payload.SenderVaspId},{Environment.NewLine}"
                        + $"Topic: {connection.OutboundTopic} - {payload.ReturnTopic},{Environment.NewLine}");
                }
                return;
            }

            var topic        = TopicGenerator.GenerateConnectionTopic();
            var sessionKey   = ECDH_Key.GenerateKey();
            var sharedSecret = sessionKey.GenerateSharedSecretHex(payload.EcdhPk);

            var(filter, symKeyId) = await RegisterConnectionAsync(topic, sharedSecret);

            var newConnection = new Connection
            {
                Id                         = payload.ConnectionId,
                Filter                     = filter,
                InboundTopic               = topic,
                OutboundTopic              = payload.ReturnTopic,
                Status                     = ConnectionStatus.PartiallyActive,
                CounterPartyVaspId         = payload.SenderVaspId,
                SymKeyId                   = symKeyId,
                SharedPrivateEncryptionKey = sharedSecret,
                PrivateKey                 = sessionKey.PrivateKey,
                CounterPartyPublicKey      = payload.EcdhPk,
            };

            _connections[newConnection.Id] = newConnection;

            await AcknowledgeMessageAsync(
                payload,
                null,
                payload.EcdhPk.DecompressPublicKey().ToHex(true));

            var signingKey = await _vaspCodesService.GetSigningKeyAsync(senderVaspCode);

            await TriggerAsyncEvent(TransportMessageReceived,
                                    new TransportMessageEvent
            {
                ConnectionId = payload.ConnectionId,
                SenderVaspId = payload.SenderVaspId,
                Instruction  = payload.Instruction,
                Payload      = payload.OvMessage,
                Timestamp    = DateTime.UtcNow,
                SigningKey   = signingKey
            });
        }