public async Task <object> TestingTransfer(string from, string privateKey, string to, IAsset asset, decimal amount)
        {
            var nodeHttp    = new NodeHttp(_nemUrl);
            var networkType = await nodeHttp.GetNetworkType();

            var networkTime    = (int)(await nodeHttp.GetExtendedNodeInfo()).NisInfo.CurrentTime;
            var toAddressParts = to.Split(AddressSeparator);
            var message        = toAddressParts.Length > 1
                ? PlainMessage.Create(toAddressParts[1]) as IMessage
                : EmptyMessage.Create();
            var mosaic = Mosaic.CreateFromIdentifier(asset.AssetId, (ulong)asset.ToBaseUnit(amount));
            var fee    = await TransferTransaction.CalculateFee(networkType, message, new[] { mosaic }, new NamespaceMosaicHttp(_nemUrl));

            var tx = TransferTransaction.Create(
                networkType,
                new Deadline(networkTime + _expiresInSeconds),
                fee.fee,
                Address.CreateFromEncoded(toAddressParts[0]),
                new List <Mosaic> {
                mosaic
            },
                message,
                networkTime);
            var signed = tx.SignWith(KeyPair.CreateFromPrivateKey(privateKey));
            var result = await new TransactionHttp(_nemUrl).Announce(signed);

            return(result);
        }
 /// <summary>
 ///     Initializes a new instance of the <see cref="SiriusClient" /> class.
 /// </summary>
 /// <param name="host">The network host</param>
 public SiriusClient(string host = @"http://localhost:3000")
 {
     Host            = host;
     NetworkHttp     = new NetworkHttp(host);
     AccountHttp     = new AccountHttp(host, NetworkHttp);
     BlockHttp       = new BlockHttp(host, NetworkHttp);
     ChainHttp       = new ChainHttp(host, NetworkHttp);
     MetadataHttp    = new MetadataHttp(host, NetworkHttp);
     MosaicHttp      = new MosaicHttp(host, NetworkHttp);
     NamespaceHttp   = new NamespaceHttp(host, NetworkHttp);
     TransactionHttp = new TransactionHttp(host, NetworkHttp);
     NodeHttp        = new NodeHttp(host, NetworkHttp);
 }
        public async Task <(string transactionContext, decimal fee, long expiration)> BuildTransactionAsync(Guid operationId,
                                                                                                            IAsset asset, IReadOnlyList <IOperationAction> actions, bool includeFee)
        {
            // from one side NEM supports single sender and single receiver per transaction,
            // from the other side we support single asset per transaction,
            // finally only single transfers are allowed

            if (actions.Count != 1)
            {
                throw new ArgumentException("Transaction must contain a single transfer only");
            }

            var nodeHttp    = new NodeHttp(_nemUrl);
            var networkType = await nodeHttp.GetNetworkType();

            var action         = actions[0];
            var toAddressParts = action.To.Split(AddressSeparator);
            var toAddress      = toAddressParts[0];
            var memo           = toAddressParts.Length > 1
                ? toAddressParts[1]
                : "";
            var message = !string.IsNullOrEmpty(memo)
                ? PlainMessage.Create(memo) as IMessage
                : EmptyMessage.Create();
            var mosaic = Mosaic.CreateFromIdentifier(asset.AssetId, (ulong)asset.ToBaseUnit(action.Amount));
            var fee    = await TransferTransaction.CalculateFee(networkType, message, new[] { mosaic }, new NamespaceMosaicHttp(_nemUrl));

            if (includeFee)
            {
                try
                {
                    checked
                    {
                        if (mosaic.NamespaceName == Xem.NamespaceName &&
                            mosaic.MosaicName == Xem.MosaicName)
                        {
                            mosaic.Amount -= fee.fee;
                        }

                        // only single transfers are supported,
                        // so there must be single levy

                        var levy = fee.levies.SingleOrDefault();

                        if (levy != null &&
                            mosaic.NamespaceName == levy.NamespaceName &&
                            mosaic.MosaicName == levy.MosaicName)
                        {
                            mosaic.Amount -= levy.Amount;
                        }
                    }
                }
                catch (OverflowException)
                {
                    throw new BlockchainException(BlockchainErrorCode.AmountIsTooSmall, "Amount is less than fee");
                }
            }

            // check balances of FromAddress for all required assets

            var fromAddress = action.From.Split(AddressSeparator)[0];
            var owned       = await new AccountHttp(_nemUrl).MosaicsOwned(Address.CreateFromEncoded(fromAddress));
            var required    = fee.levies
                              .Append(Xem.CreateAbsolute(fee.fee))
                              .Append(mosaic)
                              .GroupBy(m => new { m.NamespaceName, m.MosaicName })
                              .Select(g => new Mosaic(g.Key.NamespaceName, g.Key.MosaicName, g.Aggregate(0UL, (v, m) => v += m.Amount)))
                              .ToList();

            foreach (var req in required)
            {
                var own = owned.FirstOrDefault(m => m.NamespaceName == req.NamespaceName && m.MosaicName == req.MosaicName)?.Amount ?? 0UL;
                if (own < req.Amount)
                {
                    throw new BlockchainException(BlockchainErrorCode.NotEnoughBalance,
                                                  $"Not enough {req.NamespaceName}:{req.MosaicName}");
                }
            }

            var networkTime = (int)(await nodeHttp.GetExtendedNodeInfo()).NisInfo.CurrentTime;

            var tx = TransferTransaction.Create(
                networkType,
                new Deadline(networkTime + _expiresInSeconds),
                fee.fee,
                Address.CreateFromEncoded(toAddress),
                new List <Mosaic> {
                mosaic
            },
                message,
                networkTime);

            return(
                tx.ToJson(),
                Convert.ToDecimal(fee.fee * 1e-6),
                tx.Deadline.GetInstant()
                );
        }
Exemple #4
0
 public NodeHttpTests() : base()
 {
     _nodeHttp = new NodeHttp(BaseUrl);
 }