Ejemplo n.º 1
0
        /// <summary>
        /// Check whether any of the destination accounts require a memo.
        ///
        /// This method implements the checks defined in
        /// <a href="https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0029.md">SEP0029</a>.
        /// It will sequantially load each destination account and check if it has the data field
        /// <c>config.memo_required</c> set to <c>"MQ=="</c>.
        /// </summary>
        /// <param name="transaction"></param>
        /// <returns></returns>
        /// <exception cref="AccountRequiresMemoException"></exception>
        public async Task CheckMemoRequired(TransactionBase transaction)
        {
            var tx = GetTransactionToCheck(transaction);

            if (tx.Memo != null && !Equals(tx.Memo, Memo.None()))
            {
                return;
            }

            var destinations = new HashSet <string>();

            foreach (var operation in tx.Operations)
            {
                if (!IsPaymentOperation(operation))
                {
                    continue;
                }

                // If it's a muxed account it already contains the memo.
                var destinationKey = PaymentOperationDestination(operation);
                if (destinationKey.IsMuxedAccount)
                {
                    continue;
                }

                var destination = destinationKey.Address;

                if (destinations.Contains(destination))
                {
                    continue;
                }

                destinations.Add(destination);

                try
                {
                    var account = await Accounts.Account(destination);

                    if (!account.Data.ContainsKey(AccountRequiresMemoKey))
                    {
                        continue;
                    }

                    if (account.Data[AccountRequiresMemoKey] == AccountRequiresMemo)
                    {
                        throw new AccountRequiresMemoException("Account requires memo", destination, operation);
                    }
                }
                catch (HttpResponseException ex)
                {
                    if (ex.StatusCode != 404)
                    {
                        throw;
                    }
                }
            }
        }
Ejemplo n.º 2
0
        public Transaction(IAccountId sourceAccount, uint fee, long sequenceNumber, Operation[] operations, Memo memo, TimeBounds timeBounds)
        {
            SourceAccount  = sourceAccount ?? throw new ArgumentNullException(nameof(sourceAccount), "sourceAccount cannot be null");
            Fee            = fee;
            SequenceNumber = sequenceNumber;
            Operations     = operations ?? throw new ArgumentNullException(nameof(operations), "operations cannot be null");

            if (operations.Length == 0)
            {
                throw new ArgumentNullException(nameof(operations), "At least one operation required");
            }

            Memo       = memo ?? Memo.None();
            TimeBounds = timeBounds;
        }
Ejemplo n.º 3
0
        private Transaction(KeyPair sourceAccount, long sequenceNumber, Operation[] operations, Memo memo, TimeBounds timeBounds)
        {
            SourceAccount  = sourceAccount ?? throw new ArgumentNullException(nameof(sourceAccount), "sourceAccount cannot be null");
            SequenceNumber = sequenceNumber;
            Operations     = operations ?? throw new ArgumentNullException(nameof(operations), "operations cannot be null");

            if (operations.Length == 0)
            {
                throw new ArgumentNullException(nameof(operations), "At least one operation required");
            }

            Fee        = operations.Length * BaseFee;
            Signatures = new List <DecoratedSignature>();
            Memo       = memo ?? Memo.None();
            TimeBounds = timeBounds;
        }
Ejemplo n.º 4
0
        public void TestTryingToAddMemoTwice()
        {
            // GBPMKIRA2OQW2XZZQUCQILI5TMVZ6JNRKM423BSAISDM7ZFWQ6KWEBC4
            var source      = KeyPair.FromSecretSeed("SCH27VUZZ6UAKB67BDNF6FA42YMBMQCBKXWGMFD5TZ6S5ZZCZFLRXKHS");
            var destination = KeyPair.FromAccountId("GDW6AUTBXTOC7FIKUO5BOO3OGLK4SF7ZPOBLMQHMZDI45J2Z6VXRB5NR");

            try
            {
                var account = new Account(source, 2908908335136768L);
                new Transaction.Builder(account)
                .AddOperation(new CreateAccountOperation.Builder(destination, "2000").Build())
                .AddMemo(Memo.None())
                .AddMemo(Memo.None());
                Assert.Fail();
            }
            catch (Exception exception)
            {
                Assert.IsTrue(exception.Message.Contains("Memo has been already added."));
            }
        }
Ejemplo n.º 5
0
        public void TestMemoNone()
        {
            var memo = Memo.None();

            Assert.AreEqual(sdkxdr.MemoType.MemoTypeEnum.MEMO_NONE, memo.ToXdr().Discriminant.InnerValue);
        }