public void VaanIsCorrectTest()
        {
            string expectedVaan             = "bb428798524ee3fb082809d3";
            VirtualAssetsAccountNumber vaan = VirtualAssetsAccountNumber.Create("bb428798", "524ee3fb082809");

            Assert.Equal(expectedVaan, vaan.Vaan);
        }
        public async Task <string> CreateSessionAsync(Originator originator, VirtualAssetsAccountNumber beneficiaryVaan)
        {
            var originatorSession = await _vaspClient.CreateSessionAsync(originator, beneficiaryVaan, _originatorVaspCallbacks);

            _originatorSessions[originatorSession.SessionId] = originatorSession;

            return(originatorSession.SessionId);
        }
        public VirtualAssetsAccountNumber CreateVirtualAssetsAccountNumber(string beneficiaryVaan)
        {
            var sanitizedBeneficiaryVaan          = beneficiaryVaan.Replace(" ", "");
            var beneficiaryVaspCode               = sanitizedBeneficiaryVaan.Substring(0, 8);
            var beneficiaryCustomerSpecificNumber = sanitizedBeneficiaryVaan.Substring(8, 14);

            return(VirtualAssetsAccountNumber.Create(beneficiaryVaspCode, beneficiaryCustomerSpecificNumber));
        }
Example #4
0
        public static Originator CreateOriginatorForNaturalPerson(
            string originatorName,
            VirtualAssetsAccountNumber vaan,
            PostalAddress postalAddress,
            PlaceOfBirth placeOfBirth,
            NaturalPersonId[] naturalPersonIds)
        {
            var originator = new Originator(originatorName, vaan.Vaan, postalAddress, placeOfBirth, naturalPersonIds, null, null);

            return(originator);
        }
        /// <summary>
        /// Create a session and send a request session message to beneficiary Vasp.
        /// </summary>
        /// <param name="originator">Information about a client who sends a transfer</param>
        /// <param name="beneficiaryVaan">Information about a receiver of the transfer</param>
        /// <returns>OriginatorSession through which transfer request and transfer dispatch should be requested.</returns>
        public async Task <OriginatorSession> CreateSessionAsync(
            Originator originator,
            VirtualAssetsAccountNumber beneficiaryVaan,
            IOriginatorVaspCallbacks _originatorVaspCallbacks)
        {
            string counterPartyVaspContractAddress = await _ensProvider.GetContractAddressByVaspCodeAsync(beneficiaryVaan.VaspCode);

            var contractInfo = await _ethereumRpc.GetVaspContractInfoAync(counterPartyVaspContractAddress);

            var sessionKey = ECDH_Key.GenerateKey();
            var sharedKey  = sessionKey.GenerateSharedSecretHex(contractInfo.HandshakeKey);

            var session = new OriginatorSession(
                originator,
                this._vaspContractInfo,
                this.VaspInfo,
                beneficiaryVaan,
                contractInfo.SigningKey,
                contractInfo.HandshakeKey,
                sharedKey,
                sessionKey.PublicKey,
                this._signatureKey,
                _whisperRpc,
                _transportClient,
                _signService,
                _originatorVaspCallbacks);

            if (_originatorSessionsDict.TryAdd(session.SessionId, session))
            {
                this.NotifySessionCreated(session);
                session.OnSessionTermination += this.ProcessSessionTermination;
                await session.StartAsync();

                return(session);
            }

            await session.TerminateAsync(TerminationMessage.TerminationMessageCode
                                         .SessionClosedTransferCancelledByOriginator);

            //TODO: process it as exception or retry
            return(null);
        }
Example #6
0
        public async Task <Transaction> RegisterOutgoingTransactionAsync(
            Transaction transaction,
            VirtualAssetsAccountNumber virtualAssetsAccountNumber)
        {
            transaction.Status = TransactionStatus.Created;

            var originatorSession = await _vaspClient.CreateOriginatorSessionAsync(virtualAssetsAccountNumber.VaspCode);

            _originatorSessionsDict.TryAdd(originatorSession.Id, originatorSession);

            transaction.SessionId = originatorSession.Id;

            await _transactionsRepository.CreateAsync(transaction);

            await _sessionsRepository.CreateAsync(originatorSession.SessionInfo);

            await originatorSession.SessionRequestAsync(_vaspInformation);

            transaction.Status = TransactionStatus.SessionRequested;

            await _transactionsRepository.UpdateAsync(transaction);

            return(transaction);
        }
Example #7
0
        public OriginatorSession(
            Originator originator,
            VaspContractInfo originatorVaspContractInfo,
            VaspInformation originatorVasp,
            VirtualAssetsAccountNumber beneficiaryVaan,
            string beneficiaryPubSigningKey,
            string beneficiaryPubHandshakeKey,
            string sharedEncryptionKey,
            string pubEncryptionKey,
            string privateSigningKey,
            IWhisperRpc whisperRpc,
            ITransportClient transportClient,
            ISignService signService,
            IOriginatorVaspCallbacks originatorVaspCallbacks)
        //IEnsProvider ensProvider)
            : base(
                originatorVaspContractInfo,
                originatorVasp,
                beneficiaryPubSigningKey,
                sharedEncryptionKey,
                privateSigningKey,
                whisperRpc,
                transportClient,
                signService)
        {
            this._beneficiaryVaan            = beneficiaryVaan;
            this.SessionId                   = Guid.NewGuid().ToString();
            this._beneficiaryPubHandshakeKey = beneficiaryPubHandshakeKey;
            this._pubEncryptionKey           = pubEncryptionKey;
            this._originatorVaspCallbacks    = originatorVaspCallbacks;
            //this._ensProvider = ensProvider;
            this._originator = originator;

            _messageHandlerResolverBuilder.AddHandler(typeof(SessionReplyMessage),
                                                      new SessionReplyMessageHandler((sessionReplyMessage, token) =>
            {
                this.CounterPartyTopic = sessionReplyMessage.HandShake.TopicB;
                return(_originatorVaspCallbacks.SessionReplyMessageHandlerAsync(sessionReplyMessage, this));
            }));

            _messageHandlerResolverBuilder.AddHandler(typeof(TransferReplyMessage),
                                                      new TransferReplyMessageHandler((transferReplyMessage, token) =>
            {
                return(_originatorVaspCallbacks.TransferReplyMessageHandlerAsync(transferReplyMessage, this));
            }));

            _messageHandlerResolverBuilder.AddHandler(typeof(TransferConfirmationMessage),
                                                      new TransferConfirmationMessageHandler((transferDispatchMessage, token) =>
            {
                return(_originatorVaspCallbacks.TransferConfirmationMessageHandlerAsync(transferDispatchMessage,
                                                                                        this));
            }));

            _messageHandlerResolverBuilder.AddHandler(typeof(TerminationMessage),
                                                      new TerminationMessageHandler(async(message, token) =>
            {
                _hasReceivedTerminationMessage = true;

                await TerminateAsync(message.GetMessageCode());
            }));
        }
Example #8
0
        public async Task <Core.Models.Transaction> CreateOutgoingTransactionAsync(
            string originatorFullName,
            string originatorVaan,
            Core.Models.PlaceOfBirth originatorPlaceOfBirth,
            Core.Models.PostalAddress originatorPostalAddress,
            string beneficiaryFullName,
            string beneficiaryVaan,
            VirtualAssetType asset,
            decimal amount)
        {
            var sanitizedBeneficiaryVaan          = beneficiaryVaan.Replace(" ", "");
            var sanitizedOriginatorVaan           = originatorVaan.Replace(" ", "");
            var beneficiaryVaspCode               = sanitizedBeneficiaryVaan.Substring(0, 8);
            var beneficiaryCustomerSpecificNumber = sanitizedBeneficiaryVaan.Substring(8, 14);

            var transaction = new Core.Models.Transaction
            {
                Status = TransactionStatus.Created,
                OriginatorPostalAddress = originatorPostalAddress,
                OriginatorPlaceOfBirth  = originatorPlaceOfBirth,
                Amount              = amount,
                Asset               = asset,
                Id                  = Guid.NewGuid().ToString(),
                CreationDateTime    = DateTime.UtcNow,
                BeneficiaryVaan     = sanitizedBeneficiaryVaan,
                OriginatorVaan      = sanitizedOriginatorVaan,
                OriginatorFullName  = originatorFullName,
                BeneficiaryFullName = beneficiaryFullName,
                SessionId           = await _vaspSessionsManager.CreateSessionAsync(
                    new Originator(
                        originatorFullName,
                        originatorVaan,
                        new OpenVASP.Messaging.Messages.Entities.PostalAddress
                        (
                            originatorPostalAddress.Street,
                            originatorPostalAddress.Building,
                            originatorPostalAddress.AddressLine,
                            originatorPostalAddress.PostCode,
                            originatorPostalAddress.Town,
                            originatorPostalAddress.Country
                        ),
                        new OpenVASP.Messaging.Messages.Entities.PlaceOfBirth
                        (
                            originatorPlaceOfBirth.Date,
                            originatorPlaceOfBirth.Town,
                            originatorPlaceOfBirth.Country
                        ),
                        null,
                        null,
                        null
                        ),
                    VirtualAssetsAccountNumber.Create(beneficiaryVaspCode, beneficiaryCustomerSpecificNumber))
            };

            transaction.Status = TransactionStatus.SessionRequested;

            lock (_outgoingTransactions)
            {
                _outgoingTransactions.Add(transaction);
            }

            return(transaction);
        }
        public async Task CreateSessionBetweenVASPs()
        {
            int sessionTerminationCounter = 0;
            SessionTermination sessionTerminationDelegate = @event => { sessionTerminationCounter++; };

            (VaspInformation vaspInfoPerson, VaspContractInfo vaspContractInfoPerson) = await VaspInformationBuilder.CreateForNaturalPersonAsync(
                NodeClient.EthereumRpc,
                Settings.VaspSmartContractAddressPerson,
                Settings.NaturalPersonIds,
                Settings.PlaceOfBirth);

            VaspClient originator = VaspClient.Create(
                vaspInfoPerson,
                vaspContractInfoPerson,
                Settings.PersonHandshakePrivateKeyHex,
                Settings.PersonSignaturePrivateKeyHex,
                NodeClient.EthereumRpc,
                NodeClient.WhisperRpc,
                _fakeEnsProvider,
                _signService,
                NodeClient.TransportClient);

            (VaspInformation vaspInfoJuridical, VaspContractInfo vaspContractInfoJuridical) = await VaspInformationBuilder.CreateForJuridicalPersonAsync(
                NodeClient.EthereumRpc,
                Settings.VaspSmartContractAddressJuridical,
                Settings.JuridicalIds);

            VaspClient beneficiary = VaspClient.Create(
                vaspInfoJuridical,
                vaspContractInfoJuridical,
                Settings.JuridicalHandshakePrivateKeyHex,
                Settings.JuridicalSignaturePrivateKeyHex,
                NodeClient.EthereumRpc,
                NodeClient.WhisperRpc,
                _fakeEnsProvider,
                _signService,
                NodeClient.TransportClient);

            var a = vaspInfoPerson.GetVaspCode();
            var b = vaspInfoJuridical.GetVaspCode();

            var originatorVaan  = VirtualAssetsAccountNumber.Create(vaspInfoPerson.GetVaspCode(), "524ee3fb082809");
            var beneficiaryVaan = VirtualAssetsAccountNumber.Create(vaspInfoJuridical.GetVaspCode(), "524ee3fb082809");

            IVaspMessageHandler messageHandler = new VaspMessageHandlerCallbacks(
                (vaspInfo) =>
            {
                return(Task.FromResult(true));
            },
                (request, currentSession) =>
            {
                var message = new TransferReplyMessage(currentSession.SessionId, TransferReplyMessage.TransferReplyMessageCode.TransferAccepted,
                                                       request.Originator,
                                                       new Beneficiary("Mr. Test", request.Beneficiary.VAAN),
                                                       new TransferReply(
                                                           request.Transfer.VirtualAssetType,
                                                           request.Transfer.TransferType,
                                                           request.Transfer.Amount,
                                                           "0x0"),
                                                       request.VASP);

                return(Task.FromResult(message));
            },
                (dispatch, currentSession) =>
            {
                var message = new TransferConfirmationMessage(currentSession.SessionId,
                                                              TransferConfirmationMessage.TransferConfirmationMessageCode.TransferConfirmed,
                                                              dispatch.Originator,
                                                              dispatch.Beneficiary,
                                                              dispatch.Transfer,
                                                              dispatch.Transaction,
                                                              dispatch.VASP);

                return(Task.FromResult(message));
            });

            beneficiary.RunListener(messageHandler);

            originator.SessionTerminated  += sessionTerminationDelegate;
            beneficiary.SessionTerminated += sessionTerminationDelegate;

            // change enum to string and add constants
            //beneficiary.TransferRequest += request => new TransferReply(VirtualAssetType.ETH, TransferType.BlockchainTransfer, "10", "1223");
            //beneficiary.TransferDispatch += message => new TransferConfirmationMessage();

            var originatorDoc = Originator.CreateOriginatorForNaturalPerson(
                "Test van der Test",
                originatorVaan,
                new PostalAddress(
                    "StreetX",
                    44,
                    "AddressLineX",
                    "510051",
                    "TownX",
                    Country.List["DE"]),
                new PlaceOfBirth(DateTime.Today.AddYears(-30), "TownX", Country.List["DE"]),
                new NaturalPersonId[]
            {
                new NaturalPersonId("Id", NaturalIdentificationType.NationalIdentityNumber, Country.List["DE"]),
            });

            var session = await originator.CreateSessionAsync(
                originatorDoc, beneficiaryVaan, new OriginatorVaspCallbacks(
                    (message, originatorSession) =>
            {
                return(originatorSession.TransferRequestAsync(new TransferInstruction()
                {
                    VirtualAssetTransfer = new VirtualAssetTransfer()
                    {
                        TransferType = TransferType.BlockchainTransfer,
                        VirtualAssetType = VirtualAssetType.ETH,
                        TransferAmount = "1000000000000000000"
                    }
                }));
            },
                    (message, originatorSession) =>
            {
                return(originatorSession.TransferDispatchAsync(message.Transfer,
                                                               new Transaction("0xtxhash", DateTime.UtcNow, "0x0...a")));
            },
                    async(message, originatorSession) =>
            {
                await originatorSession.TerminateAsync(TerminationMessage.TerminationMessageCode.SessionClosedTransferOccured);
                originatorSession.Wait();
                originator.Dispose();
                beneficiary.Dispose();
            }));

            Assert.Equal(1, originator.GetActiveSessions().Count);
            Assert.True(originator.GetActiveSessions().First() is OriginatorSession);

            Assert.Equal(1, beneficiary.GetActiveSessions().Count);
            Assert.True(beneficiary.GetActiveSessions().First() is BeneficiarySession);

            Assert.Equal(2, sessionTerminationCounter);

            _testOutputHelper.WriteLine("End of test");
        }