Example #1
0
        public async Task <Result <decimal> > GetFa12AllowanceAsync(
            string holderAddress,
            string spenderAddress,
            string callingAddress,
            SecureBytes securePublicKey,
            CancellationToken cancellationToken = default)
        {
            var tokenConfig = _currency as Fa12Config;

            try
            {
                var rpc = new Rpc(_rpcNodeUri);

                var tx = new TezosTransaction
                {
                    Currency     = tokenConfig.Name,
                    From         = callingAddress,
                    To           = tokenConfig.TokenContractAddress,
                    Fee          = 0,      //token.GetAllowanceFee,
                    GasLimit     = tokenConfig.GetAllowanceGasLimit,
                    StorageLimit = 0,      //token.GetAllowanceStorageLimit,
                    Params       = CreateGetAllowanceParams(holderAddress, spenderAddress, tokenConfig.ViewContractAddress),

                    UseRun            = false,
                    UseOfflineCounter = false
                };

                _ = await tx
                    .FillOperationsAsync(
                    securePublicKey : securePublicKey,
                    tezosConfig : tokenConfig,
                    cancellationToken : cancellationToken)
                    .ConfigureAwait(false);

                var runResults = await rpc
                                 .RunOperations(tx.Head, tx.Operations)
                                 .ConfigureAwait(false);

                return(runResults
                    ?["contents"]
                       ?.LastOrDefault()
                    ?["metadata"]
                    ?["internal_operation_results"]
                    ?[0]
                    ?["result"]
                    ?["errors"]
                    ?[1]
                    ?["with"]
                    ?["args"]
                    ?[0]
                    ?["args"]
                    ?[0]
                    ?["int"]
                       ?.Value <decimal>() ?? 0);
            }
            catch (Exception e)
            {
                return(new Error(Errors.RequestError, e.Message));
            }
        }
Example #2
0
        private Result <TezosTransaction> ParseFA12Params(TezosTransaction tx, JObject transaction)
        {
            var tokenContractAddress = (_currency as TezosTokens.FA12).TokenContractAddress;

            if (transaction["target"]?["address"]?.ToString() != tokenContractAddress)
            {
                Log.Error(
                    "Error while parsing token transactions {@Id}",
                    transaction["hash"].ToString());
                return(null);
            }

            //if (transaction["hasInternals"].Value<bool>())
            //    return null;

            tx.Fee          = transaction["bakerFee"].Value <decimal>();
            tx.GasLimit     = transaction["gasLimit"].Value <decimal>();
            tx.StorageLimit = transaction["storageLimit"].Value <decimal>();

            var parameters = transaction.ContainsKey("parameters")
                ? JObject.Parse(transaction["parameters"].Value <string>())
                : null;

            if (parameters?["entrypoint"]?.ToString() == "approve")
            {
                tx.Type   = BlockchainTransactionType.TokenApprove;
                tx.From   = transaction["sender"]?["address"]?.ToString();
                tx.To     = transaction["target"]?["address"]?.ToString();
                tx.Amount = 0;
            }
            else if (parameters?["entrypoint"]?.ToString() == "transfer")
            {
                if (parameters?["value"]?["args"]?[0]?["string"] != null)
                {
                    tx.From = parameters?["value"]?["args"]?[0]?["string"]?.ToString();
                    tx.To   = parameters?["value"]?["args"]?[1]?["args"]?[0]?["string"]?.ToString();
                }
                else
                {
                    tx.From = Unforge.UnforgeAddress(parameters?["value"]?["args"]?[0]?["bytes"]?.ToString());
                    tx.To   = Unforge.UnforgeAddress(parameters?["value"]?["args"]?[1]?["args"]?[0]?["bytes"]?.ToString());
                }
                tx.Amount = parameters?["value"]?["args"]?[1]?["args"]?[1]?["int"]?.Value <decimal>() ?? 0;
            }
            else
            {
                Log.Error(
                    "Error while parsing FA12 token transactions {@Id}",
                    transaction["hash"].ToString());
                return(null);
            }

            tx.Params = parameters;

            return(tx);
        }
Example #3
0
        public override async Task <Result <IBlockchainTransaction> > GetTransactionAsync(
            string txId,
            CancellationToken cancellationToken = default)
        {
            var transaction     = new TezosTransaction();
            var isParentTxValid = false;

            var requestUri = $"operations/transactions/{txId}?micheline=2";

            return(await HttpHelper
                   .GetAsyncResult <IBlockchainTransaction>(
                       baseUri : _baseUri,
                       requestUri : requestUri,
                       headers : _headers,
                       responseHandler : (response, content) =>
            {
                var txResult = ParseTxs(JsonConvert.DeserializeObject <JArray>(content));

                if (txResult.HasError)
                {
                    return txResult.Error;
                }

                if (!txResult.Value.Any())
                {
                    return null;
                }

                var internalTxs = new List <TezosTransaction>();

                foreach (var tx in txResult.Value)
                {
                    if (!tx.IsInternal)
                    {
                        transaction = tx;
                        isParentTxValid = true;
                    }
                    else
                    {
                        internalTxs.Add(tx);
                    }
                }

                transaction.InternalTxs = internalTxs;

                // replace non valid parent tx by internal tx
                if (isParentTxValid == false && internalTxs.Count == 1)
                {
                    transaction = internalTxs.First();
                }

                return transaction;
            },
                       cancellationToken : cancellationToken)
                   .ConfigureAwait(false));
        }
Example #4
0
        public async Task <Result <decimal> > GetTokenAllowanceAsync(
            string holderAddress,
            string spenderAddress,
            string callingAddress,
            SecureBytes securePublicKey,
            CancellationToken cancellationToken = default)
        {
            var token = _currency as TezosTokens.FA12;

            try
            {
                var rpc = new Rpc(_rpcNodeUri);

                var head = await rpc
                           .GetHeader()
                           .ConfigureAwait(false);

                var tx = new TezosTransaction
                {
                    Currency     = token,
                    From         = callingAddress,
                    To           = token.TokenContractAddress,
                    Fee          = 0, //token.GetAllowanceFee,
                    GasLimit     = token.GetAllowanceGasLimit,
                    StorageLimit = 0, //token.GetAllowanceStorageLimit,
                    Params       = GetAllowanceParams(holderAddress, spenderAddress, token.ViewContractAddress),
                };

                await tx.FillOperationsAsync(
                    head : head,
                    securePublicKey : securePublicKey,
                    incrementCounter : false,
                    cancellationToken : cancellationToken)
                .ConfigureAwait(false);

                var runResults = await rpc
                                 .RunOperations(head, tx.Operations)
                                 .ConfigureAwait(false);

                Log.Debug("getTokenAllowance result {@result}", runResults);

                return(runResults?["contents"]?.LastOrDefault()?["metadata"]?["internal_operation_results"]?[0]?["result"]?["errors"]?[1]?["with"]?["args"]?[0]?["args"]?[0]?["int"]?.Value <decimal>());
            }
            catch (Exception e)
            {
                return(new Error(Errors.RequestError, e.Message));
            }
        }
        public TezosTransaction Clone()
        {
            var resTx = new TezosTransaction()
            {
                Id           = Id,
                Currency     = Currency,
                State        = State,
                Type         = Type,
                CreationTime = CreationTime,

                From         = From,
                To           = To,
                Amount       = Amount,
                Fee          = Fee,
                GasLimit     = GasLimit,
                GasUsed      = GasUsed,
                StorageLimit = StorageLimit,
                Burn         = Burn,
                Alias        = Alias,

                Params        = Params,
                IsInternal    = IsInternal,
                InternalIndex = InternalIndex,
                InternalTxs   = new List <TezosTransaction>(),

                BlockInfo = (BlockInfo)(BlockInfo?.Clone() ?? null)
            };

            if (InternalTxs != null)
            {
                foreach (var intTx in InternalTxs)
                {
                    resTx.InternalTxs.Add(intTx.Clone());
                }
            }

            return(resTx);
        }
Example #6
0
        public TezosTransaction Clone()
        {
            var resTx = new TezosTransaction()
            {
                Id           = this.Id,
                Currency     = this.Currency,
                State        = this.State,
                Type         = this.Type,
                CreationTime = this.CreationTime,

                From         = this.From,
                To           = this.To,
                Amount       = this.Amount,
                Fee          = this.Fee,
                GasLimit     = this.GasLimit,
                GasUsed      = this.GasUsed,
                StorageLimit = this.StorageLimit,
                Burn         = this.Burn,

                Params        = this.Params,
                IsInternal    = this.IsInternal,
                InternalIndex = this.InternalIndex,
                InternalTxs   = new List <TezosTransaction>(),

                BlockInfo = (BlockInfo)(this.BlockInfo?.Clone() ?? null)
            };

            if (this.InternalTxs != null)
            {
                foreach (var intTx in this.InternalTxs)
                {
                    resTx.InternalTxs.Add(intTx.Clone());
                }
            }

            return(resTx);
        }
Example #7
0
        private Result <IEnumerable <TezosTransaction> > ParseTxs(JArray data)
        {
            var result = new List <TezosTransaction>();

            foreach (var op in data)
            {
                if (!(op is JObject transaction))
                {
                    return(new Error(Errors.NullOperation, "Null operation in response"));
                }

                var state = StateFromStatus(transaction["status"].Value <string>());

                var tx = new TezosTransaction()
                {
                    Id           = transaction["hash"].ToString(),
                    Currency     = _currency,
                    State        = state,
                    Type         = BlockchainTransactionType.Unknown,
                    CreationTime = DateTime.SpecifyKind(DateTime.Parse(transaction["timestamp"].ToString()), DateTimeKind.Utc),

                    GasUsed = transaction["gasUsed"].Value <decimal>(),
                    Burn    = transaction["storageFee"].Value <decimal>() +
                              transaction["allocationFee"].Value <decimal>(),

                    IsInternal = transaction.ContainsKey("nonce"),
                    //tx.IsInternal = tx.From == ((TezosTokens.FA12) _currency).SwapContractAddress;
                    InternalIndex = transaction["nonce"]?.Value <int>() ?? 0,

                    BlockInfo = new BlockInfo
                    {
                        Confirmations = state == BlockchainTransactionState.Failed ? 0 : 1,
                        BlockHash     = null,
                        BlockHeight   = transaction["level"].Value <long>(),
                        BlockTime     = DateTime.SpecifyKind(DateTime.Parse(transaction["timestamp"].ToString()), DateTimeKind.Utc),
                        FirstSeen     = DateTime.SpecifyKind(DateTime.Parse(transaction["timestamp"].ToString()), DateTimeKind.Utc)
                    }
                };

                if (_currency.Name != Tezos)
                {
                    if (_currency.Name == NYX)
                    {
                        tx = ParseNYXParams(tx, transaction).Value;
                    }
                    else if (_currency.Name == FA2)
                    {
                        tx = ParseFA2Params(tx, transaction).Value;
                    }
                    else
                    {
                        tx = ParseFA12Params(tx, transaction).Value;
                    }
                }
                else
                {
                    tx.From   = transaction["sender"]?["address"]?.ToString();
                    tx.To     = transaction["target"]?["address"]?.ToString();
                    tx.Amount = transaction["amount"].Value <decimal>();

                    if (tx.IsInternal)
                    {
                        tx.InternalIndex = transaction["nonce"]?.Value <int>() ?? 0;
                    }
                    else
                    {
                        var txParameters = transaction.ContainsKey("parameters")
                            ? JObject.Parse(transaction["parameters"].Value <string>())
                            : null;

                        tx.Params       = txParameters;
                        tx.Fee          = transaction["bakerFee"].Value <decimal>();
                        tx.GasLimit     = transaction["gasLimit"].Value <decimal>();
                        tx.StorageLimit = transaction["storageLimit"].Value <decimal>();
                    }
                }

                if (tx != null)
                {
                    result.Add(tx);
                }
            }

            return(result);
        }