public BeneficiarySession( VaspContractInfo beneficiaryVaspContractInfo, VaspInformation beneficiaryVasp, string sessionId, string counterpartyTopic, string counterPartyPubSigningKey, string sharedKey, string privateSigningKey, IWhisperRpc whisperRpc, IVaspMessageHandler vaspMessageHandler, ITransportClient transportClient, ISignService signService) : base( beneficiaryVaspContractInfo, beneficiaryVasp, counterPartyPubSigningKey, sharedKey, privateSigningKey, whisperRpc, transportClient, signService) { this.SessionId = sessionId; this.CounterPartyTopic = counterpartyTopic; this._vaspMessageHandler = vaspMessageHandler; _messageHandlerResolverBuilder.AddHandler(typeof(TransferRequestMessage), new TransferRequestMessageHandler( async(message, cancellationToken) => { await _vaspMessageHandler.TransferRequestHandlerAsync(message, this); })); _messageHandlerResolverBuilder.AddHandler(typeof(TransferDispatchMessage), new TransferDispatchMessageHandler( async(message, cancellationToken) => { await _vaspMessageHandler.TransferDispatchHandlerAsync(message, this); })); _messageHandlerResolverBuilder.AddHandler(typeof(TerminationMessage), new TerminationMessageHandler(async(message, token) => { _hasReceivedTerminationMessage = true; await TerminateAsync(message.GetMessageCode()); })); }
/// <summary> /// Run listener which would process incoming messages. /// </summary> /// <param name="messageHandler">Handler which authorizes originator's Vasp and processes Transfer Request and Transfer Dispatch Messages</param> public void RunListener(IVaspMessageHandler messageHandler) { lock (_lock) { if (!_hasStartedListening) { _hasStartedListening = true; var token = _cancellationTokenSource.Token; var taskFactory = new TaskFactory(_cancellationTokenSource.Token); this._listener = taskFactory.StartNew(async(_) => { var privateKeyId = await _whisperRpc.RegisterKeyPairAsync(this._handshakeKey.PrivateKey); string messageFilter = await _whisperRpc.CreateMessageFilterAsync(topicHex: _vaspContractInfo.VaspCode.Code, privateKeyId); do { var sessionRequestMessages = await _transportClient.GetSessionMessagesAsync(messageFilter); if (sessionRequestMessages != null && sessionRequestMessages.Count != 0) { foreach (var message in sessionRequestMessages) { var sessionRequestMessage = message.Message as SessionRequestMessage; if (sessionRequestMessage == null) { continue; } var isAuthorized = await messageHandler.AuthorizeSessionRequestAsync(sessionRequestMessage.VASP); if (!isAuthorized) { continue; } var originatorVaspContractInfo = await _ethereumRpc.GetVaspContractInfoAync(sessionRequestMessage.VASP .VaspIdentity); if (!_signService.VerifySign(message.Payload, message.Signature, originatorVaspContractInfo.SigningKey)) { continue; } var sharedSecret = this._handshakeKey.GenerateSharedSecretHex(sessionRequestMessage.HandShake .EcdhPubKey); var session = new BeneficiarySession( originatorVaspContractInfo, this.VaspInfo, sessionRequestMessage.Message.SessionId, sessionRequestMessage.HandShake.TopicA, originatorVaspContractInfo.SigningKey, sharedSecret, this._signatureKey, this._whisperRpc, messageHandler, _transportClient, _signService); this.NotifySessionCreated(session); session.OnSessionTermination += this.ProcessSessionTermination; if (_beneficiarySessionsDict.TryAdd(session.SessionId, session)) { await session.StartAsync(); } else { await session.TerminateAsync(TerminationMessage.TerminationMessageCode .SessionClosedTransferDeclinedByBeneficiaryVasp); } } continue; } await Task.Delay(5000, token); } while (!token.IsCancellationRequested); }, token, TaskCreationOptions.LongRunning); } else { throw new Exception("You can start observation only once."); } } }