public static void GenerateKeyPair(
            SecureBytes seed,
            out SecureBytes privateKey,
            out SecureBytes publicKey)
        {
            using var scopedSeed       = seed.ToUnsecuredBytes();
            using var scopedPrivateKey = new ScopedBytes(PrivateKeySize);
            using var scopedPublicKey  = new ScopedBytes(PublicKeySize);

            // copy first 32-bytes from seed to expandedPrivateKey left part ([0-31] bytes)
            Array.Copy(
                sourceArray: scopedSeed,
                sourceIndex: 0,
                destinationArray: scopedPrivateKey,
                destinationIndex: 0,
                length: PrivateKeySize);

            // use first 32-bytes from seed (private key) to generate public key
            GeneratePublicKey(
                sk: scopedSeed,
                skOff: 0,
                pk: scopedPublicKey,
                pkOff: 0);

            privateKey = new SecureBytes(scopedPrivateKey);
            publicKey  = new SecureBytes(scopedPublicKey);
        }
Exemple #2
0
        public TezosExtKey(SecureBytes seed)
        {
            using var scopedSeed = seed.ToUnsecuredBytes();
            //var masterSecret = Hashes.HMACSHA512(key: HashKey, data: seed);
            using var masterSecret = new ScopedBytes(PrivateKeyLength);

            Buffer.BlockCopy(
                src: scopedSeed,
                srcOffset: 0,
                dst: masterSecret,
                dstOffset: 0,
                count: 32);

            // check third highest bit of the last byte of kL, where
            // k = H512(masterSecret) and kL is its left 32-bytes

            while (true)
            {
                using var k = new ScopedBytes(Hashes.SHA512(masterSecret));

                if ((k[31] & 0b00100000) > 0)
                {
                    // discard current k and try to get new
                    Buffer.BlockCopy(
                        src: k,
                        srcOffset: 0,
                        dst: masterSecret,
                        dstOffset: 0,
                        count: 32);
                }
Exemple #3
0
        /// <exception cref="SerializationException">An object in the graph of type parameter <typeparamref name="T"/> is not marked as serializable.</exception>
        private T ReadObject(int len)
        {
            var data = new byte[len];

            BaseStream.Read(data, 0, len);

            //Check if we have to decrypt this data first
            if (ProtectedEncryptionKey != null)
            {
                var key = SecureBytes.Unprotect(ProtectedEncryptionKey);

                try
                {
                    var encryptedData = DecryptBytes(data, key);
                    Array.Clear(data, 0, data.Length);

                    data = encryptedData;
                }
                finally
                {
                    Array.Clear(key, 0, key.Length);
                }
            }

            using (var memoryStream = new MemoryStream(data))
            {
                var result = (T)_binaryFormatter.Deserialize(memoryStream);
                Array.Clear(data, 0, data.Length);

                return(result);
            }
        }
Exemple #4
0
        /// <exception cref="SerializationException">An object in the graph of type parameter <typeparamref name="T"/> is not marked as serializable.</exception>
        private byte[] Serialize(T obj)
        {
            try
            {
                using (var memoryStream = new MemoryStream())
                {
                    _binaryFormatter.Serialize(memoryStream, obj);

                    //Check if we should return an encrypted array of data instead
                    if (ProtectedEncryptionKey != null)
                    {
                        var key = SecureBytes.Unprotect(ProtectedEncryptionKey);

                        try
                        {
                            return(EncryptStream(memoryStream, key));
                        }
                        finally
                        {
                            Array.Clear(key, 0, key.Length);
                        }
                    }

                    return(memoryStream.ToArray());
                }
            }
            catch
            {
                //if any exception in the serialize, it will stop named pipe wrapper, so there will ignore any exception.
                return(null);
            }
        }
Exemple #5
0
        private Task <bool> SignAsync(SecureBytes privateKey)
        {
            if (privateKey == null)
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            using var scopedPrivateKey = privateKey.ToUnsecuredBytes();

            var chain = ((Atomex.Ethereum)Currency).Chain;

            RlpEncodedTx = Web3.OfflineTransactionSigner
                           .SignTransaction(
                privateKey: scopedPrivateKey,
                chain: chain,
                to: To,
                amount: Amount,
                nonce: Nonce,
                gasPrice: GasPrice,
                gasLimit: GasLimit,
                data: Input);

            From = Web3.OfflineTransactionSigner
                   .GetSenderAddress(RlpEncodedTx, chain)
                   .ToLowerInvariant();

            return(Task.FromResult(true));
        }
Exemple #6
0
        public HdKeyStorage Unlock(SecureString password)
        {
            try
            {
                using var scopedSeed = new ScopedBytes(Aes.Decrypt(
                                                           encryptedBytes: Hex.FromString(EncryptedSeed),
                                                           password: password,
                                                           keySize: AesKeySize,
                                                           saltSize: AesSaltSize,
                                                           iterations: AesRfc2898Iterations));

                Seed = new SecureBytes(scopedSeed);

                foreach (var singleKey in NonHdKeys)
                {
                    singleKey.Unlock(password);
                }
            }
            catch (Exception e)
            {
                Log.Error(e, "Unlock error");
            }

            return(this);
        }
Exemple #7
0
 public TezosKey(SecureBytes seed)
 {
     Ed25519.GenerateKeyPair(
         seed: seed,
         privateKey: out _privateKey,
         publicKey: out _publicKey);
 }
        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));
            }
        }
Exemple #9
0
        public void Sign(
            SecureBytes privateKey,
            ITxOutput[] spentOutputs,
            BitcoinBasedConfig bitcoinBasedConfig)
        {
            using var scopedPrivateKey = privateKey.ToUnsecuredBytes();

            Sign(new Key(scopedPrivateKey), spentOutputs, bitcoinBasedConfig); // todo: do not use NBitcoin.Key
        }
Exemple #10
0
        public void Lock()
        {
            Seed.Dispose();
            Seed = null;

            foreach (var singleKey in NonHdKeys)
            {
                singleKey.Lock();
            }
        }
Exemple #11
0
        public void CloneTest()
        {
            var bytes = new byte[] { 0x00, 0x01, 0x02, 0x03 };

            using var secureBytes = new SecureBytes(bytes);
            using var clone       = secureBytes.Clone();
            using var cloneBytes  = clone.ToUnsecuredBytes();

            Assert.Equal(bytes, cloneBytes);
        }
        public static void GeneratePublicKeyFromExtended(
            SecureBytes extendedPrivateKey,
            out SecureBytes publicKey)
        {
            using var scopedExtentedPrivateKey = extendedPrivateKey.ToUnsecuredBytes();
            using var scopedPublicKey          = new ScopedBytes(PointBytes);
            ScalarMultBaseEncoded(scopedExtentedPrivateKey, scopedPublicKey, 0);

            publicKey = new SecureBytes(scopedPublicKey);
        }
Exemple #13
0
 public async Task <Result <decimal> > TryGetTokenBalanceAsync(
     string address,
     string callingAddress,
     SecureBytes securePublicKey,
     int attempts           = 3,
     int attemptsIntervalMs = 1000,
     CancellationToken cancellationToken = default)
 {
     return(await ResultHelper.TryDo((c) => GetTokenBalanceAsync(address, callingAddress, securePublicKey, c), attempts, attemptsIntervalMs, cancellationToken)
            .ConfigureAwait(false) ?? new Error(Errors.RequestError, $"Connection error while getting balance after {attempts} attempts"));
 }
Exemple #14
0
        public void FromBytesArrayTest()
        {
            const string Phrase =
                "return auction present awesome blast excess receive obtain explain spider iron hip curtain recipe tent aim bonus hip cliff shrug lyrics pass right spend";

            var seed = new Mnemonic(Phrase).DeriveSeed();

            using var secureSeed = new SecureBytes(seed);
            using var scopedSeed = secureSeed.ToUnsecuredBytes();

            Assert.Equal(seed, scopedSeed);
        }
Exemple #15
0
        public HdKeyStorage(
            string mnemonic,
            Wordlist wordList       = null,
            SecureString passPhrase = null,
            Network network         = Network.MainNet)
        {
            Version = CurrentVersion;
            Network = network;

            using var scopedSeed = new ScopedBytes(new Mnemonic(mnemonic, wordList)
                                                   .DeriveSeed(passPhrase.ToUnsecuredString()));

            Seed = new SecureBytes(scopedSeed);
        }
        public static void GeneratePublicKey(
            SecureBytes privateKey,
            out SecureBytes publicKey)
        {
            using var scopedPrivateKey = privateKey.ToUnsecuredBytes();
            using var scopedPublicKey  = new ScopedBytes(PublicKeySize);

            GeneratePublicKey(
                sk: scopedPrivateKey,
                skOff: 0,
                pk: scopedPublicKey,
                pkOff: 0);

            publicKey = new SecureBytes(scopedPublicKey);
        }
Exemple #17
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 void BitcoinBasedExtKeyTest()
        {
            var messageBytes = Encoding.UTF8.GetBytes(Message);

            using var seed                 = new SecureBytes(new Mnemonic(Mnemonic).DeriveSeed());
            using var extKey               = new BitcoinBasedExtKey(seed);
            using var childKey             = extKey.Derive(new KeyPath("m/44'/0'/0'/0'"));
            using var secureChildPublicKey = childKey.GetPublicKey();
            using var childPublicKey       = secureChildPublicKey.ToUnsecuredBytes();

            var signature = childKey.SignMessage(messageBytes);

            Assert.True(childKey.VerifyMessage(messageBytes, signature));

            var address = Common.CurrenciesTestNet.Get <BitcoinConfig>("BTC").AddressFromKey(childPublicKey);

            Assert.NotNull(address);
        }
Exemple #19
0
        public void Unlock(SecureString password)
        {
            try
            {
                using var scopedSeed = new ScopedBytes(Aes.Decrypt(
                                                           encryptedBytes: Hex.FromString(EncryptedSeed),
                                                           password: password,
                                                           keySize: AesKeySize,
                                                           saltSize: AesSaltSize,
                                                           iterations: AesRfc2898Iterations));

                Seed = new SecureBytes(scopedSeed);
            }
            catch (Exception e)
            {
                Log.Error(e, "Unlock error");
            }
        }
Exemple #20
0
        private void Derive(
            byte[] chainCode,
            uint child,
            out byte[] childChainCode,
            out SecureBytes childPrivateKey,
            out SecureBytes childPublicKey)
        {
            using var scopedPublicKey  = _publicKey.ToUnsecuredBytes();
            using var scopedPrivateKey = _privateKey.ToUnsecuredBytes();

            using var data = new ScopedBytes(1 + 32 + 4);

            if (child >> 31 == 0)
            {
                data[0] = 0;
                Buffer.BlockCopy(src: scopedPublicKey, srcOffset: 0, dst: data, dstOffset: 1, count: 32);
            }
            else // hardened key (private derivation)
            {
                data[0] = 0;
                Buffer.BlockCopy(src: scopedPrivateKey, srcOffset: 0, dst: data, dstOffset: 1, count: 32);
            }

            Buffer.BlockCopy(src: IndexToBytes(child), srcOffset: 0, dst: data, dstOffset: 33, count: 4);

            using var l = new ScopedBytes(Hashes.HMACSHA512(chainCode, data));
            using var scopedChildPrivateKey = new ScopedBytes(l.Data.SubArray(start: 0, length: 32));

            childPrivateKey = new SecureBytes(scopedChildPrivateKey);

            childChainCode = new byte[ChainCodeLength];

            Buffer.BlockCopy(
                src: l,
                srcOffset: 32,
                dst: childChainCode,
                dstOffset: 0,
                count: ChainCodeLength);

            Ed25519.GeneratePublicKey(
                privateKey: childPrivateKey,
                publicKey: out childPublicKey);
        }
Exemple #21
0
        public void TezosExtKeyDerivationTest()
        {
            var messageBytes = Encoding.UTF8.GetBytes(Message);

            using var seed   = new SecureBytes(new Mnemonic(Mnemonic).DeriveSeed());
            using var extKey = new Bip32TezosExtKey(seed);

            for (var i = 0; i < 100; ++i)
            {
                using var childKey             = extKey.Derive(new KeyPath($"m/44'/1729'/0'/0/{i}"));
                using var secureChildPublicKey = childKey.GetPublicKey();
                using var childPublicKey       = secureChildPublicKey.ToUnsecuredBytes();

                var signature = childKey.SignMessage(messageBytes);
                Assert.True(childKey.VerifyMessage(messageBytes, signature));

                var address = Common.CurrenciesTestNet.Get <TezosConfig>("XTZ").AddressFromKey(childPublicKey);
                Assert.NotNull(address);
            }
        }
Exemple #22
0
        public TezosExtKey(SecureBytes seed)
        {
            using var scopedSeed     = seed.ToUnsecuredBytes();
            using var scopedHashSeed = new ScopedBytes(Hashes.HMACSHA512(HashKey, scopedSeed));
            using var secureHashSeed = new SecureBytes(scopedHashSeed);

            Ed25519.GenerateKeyPair(
                seed: secureHashSeed,
                privateKey: out _privateKey,
                publicKey: out _publicKey);

            ChainCode = new byte[ChainCodeLength];

            // copy hashSeed last 32 bytes to ChainCode
            Buffer.BlockCopy(
                src: scopedHashSeed,
                srcOffset: PrivateKeyLength,
                dst: ChainCode,
                dstOffset: 0,
                count: ChainCodeLength);
        }
Exemple #23
0
        private TezosExtKey(
            SecureBytes privateKey,
            SecureBytes publicKey,
            byte depth,
            uint child,
            byte[] chainCode,
            uint fingerPrint)
        {
            _privateKey = privateKey;
            _publicKey  = publicKey;

            Depth       = depth;
            Child       = child;
            Fingerprint = fingerPrint;
            ChainCode   = new byte[ChainCodeLength];

            Buffer.BlockCopy(
                src: chainCode,
                srcOffset: 0,
                dst: ChainCode,
                dstOffset: 0,
                count: ChainCodeLength);
        }
Exemple #24
0
 public override IExtKey CreateExtKey(SecureBytes seed)
 {
     //return new TrustWalletTezosExtKey(seed);
     return(new TezosExtKey(seed));
 }
Exemple #25
0
 public override IKey CreateKey(SecureBytes seed)
 {
     return(new TezosKey(seed));
 }
Exemple #26
0
        protected override async Task <IEnumerable <TezosTransaction> > CreatePaymentTxsAsync(
            Swap swap,
            int lockTimeSeconds,
            CancellationToken cancellationToken = default)
        {
            Log.Debug("Create payment transactions for swap {@swapId}", swap.Id);

            var fa12    = Fa12;
            var fa12Api = fa12.BlockchainApi as ITokenBlockchainApi;

            var requiredAmountInTokens = AmountHelper.QtyToAmount(swap.Side, swap.Qty, swap.Price, fa12.DigitsMultiplier);

            var refundTimeStampUtcInSec = new DateTimeOffset(swap.TimeStamp.ToUniversalTime().AddSeconds(lockTimeSeconds)).ToUnixTimeSeconds();
            var isInitTx = true;
            var rewardForRedeemInTokenDigits = swap.IsInitiator
                ? swap.PartyRewardForRedeem.ToTokenDigits(fa12.DigitsMultiplier)
                : 0;

            var unspentAddresses = (await Fa12Account
                                    .GetUnspentAddressesAsync(cancellationToken)
                                    .ConfigureAwait(false))
                                   .ToList()
                                   .SortList(new AvailableBalanceAscending());

            var transactions = new List <TezosTransaction>();

            foreach (var walletAddress in unspentAddresses)
            {
                Log.Debug("Create swap payment tx from address {@address} for swap {@swapId}",
                          walletAddress.Address,
                          swap.Id);

                var balanceInTz = (await TezosAccount
                                   .GetAddressBalanceAsync(
                                       address: walletAddress.Address,
                                       cancellationToken: cancellationToken)
                                   .ConfigureAwait(false))
                                  .Available;

                var balanceInTokens = (await Fa12Account
                                       .GetAddressBalanceAsync(
                                           address: walletAddress.Address,
                                           cancellationToken: cancellationToken)
                                       .ConfigureAwait(false))
                                      .Available;

                Log.Debug("Available balance: {@balance}", balanceInTokens);

                var balanceInMtz         = balanceInTz.ToMicroTez();
                var balanceInTokenDigits = balanceInTokens.ToTokenDigits(fa12.DigitsMultiplier);

                var isRevealed = await _account
                                 .IsRevealedSourceAsync(walletAddress.Address, cancellationToken)
                                 .ConfigureAwait(false);

                var feeAmountInMtz = fa12.ApproveFee * 2 +
                                     (isInitTx ? fa12.InitiateFee : fa12.AddFee) +
                                     (isRevealed ? 0 : fa12.RevealFee);

                var storageLimitInMtz = (fa12.ApproveStorageLimit * 2 +
                                         (isInitTx ? fa12.InitiateStorageLimit : fa12.AddStorageLimit)) *
                                        fa12.StorageFeeMultiplier;

                if (balanceInMtz - feeAmountInMtz - storageLimitInMtz - Xtz.MicroTezReserve <= 0)
                {
                    Log.Warning(
                        "Insufficient funds at {@address}. Balance: {@balance}, " +
                        "feeAmount: {@feeAmount}, storageLimit: {@storageLimit}.",
                        walletAddress.Address,
                        balanceInMtz,
                        feeAmountInMtz,
                        storageLimitInMtz);

                    continue;
                }

                var amountInTokens = requiredAmountInTokens > 0
                    ? AmountHelper.DustProofMin(balanceInTokens, requiredAmountInTokens, fa12.DigitsMultiplier, fa12.DustDigitsMultiplier)
                    : 0;

                if (amountInTokens == 0)
                {
                    break;
                }

                requiredAmountInTokens -= amountInTokens;

                using var callingAddressPublicKey = new SecureBytes((await Fa12Account.GetAddressAsync(walletAddress.Address)
                                                                     .ConfigureAwait(false))
                                                                    .PublicKeyBytes());

                var allowanceResult = await fa12Api
                                      .TryGetTokenAllowanceAsync(
                    holderAddress : walletAddress.Address,
                    spenderAddress : fa12.SwapContractAddress,
                    callingAddress : walletAddress.Address,
                    securePublicKey : callingAddressPublicKey,
                    cancellationToken : cancellationToken)
                                      .ConfigureAwait(false);

                if (allowanceResult.HasError)
                {
                    Log.Error("Error while getting token allowance for {@address} with code {@code} and description {@description}",
                              walletAddress.Address,
                              allowanceResult.Error.Code,
                              allowanceResult.Error.Description);

                    continue; // todo: maybe add approve 0
                }

                if (allowanceResult.Value > 0)
                {
                    transactions.Add(new TezosTransaction
                    {
                        Currency      = fa12,
                        CreationTime  = DateTime.UtcNow,
                        From          = walletAddress.Address,
                        To            = fa12.TokenContractAddress,
                        Fee           = fa12.ApproveFee,
                        GasLimit      = fa12.ApproveGasLimit,
                        StorageLimit  = fa12.ApproveStorageLimit,
                        Params        = ApproveParams(fa12.SwapContractAddress, 0),
                        UseDefaultFee = true,
                        Type          = BlockchainTransactionType.TokenApprove
                    });
                }

                transactions.Add(new TezosTransaction
                {
                    Currency      = fa12,
                    CreationTime  = DateTime.UtcNow,
                    From          = walletAddress.Address,
                    To            = fa12.TokenContractAddress,
                    Fee           = fa12.ApproveFee,
                    GasLimit      = fa12.ApproveGasLimit,
                    StorageLimit  = fa12.ApproveStorageLimit,
                    Params        = ApproveParams(fa12.SwapContractAddress, amountInTokens.ToTokenDigits(fa12.DigitsMultiplier)),
                    UseDefaultFee = true,
                    Type          = BlockchainTransactionType.TokenApprove
                });

                if (isInitTx)
                {
                    transactions.Add(new TezosTransaction
                    {
                        Currency      = fa12,
                        CreationTime  = DateTime.UtcNow,
                        From          = walletAddress.Address,
                        To            = fa12.SwapContractAddress,
                        Fee           = feeAmountInMtz,
                        GasLimit      = fa12.InitiateGasLimit,
                        StorageLimit  = fa12.InitiateStorageLimit,
                        Params        = InitParams(swap, fa12.TokenContractAddress, amountInTokens.ToTokenDigits(fa12.DigitsMultiplier), refundTimeStampUtcInSec, (long)rewardForRedeemInTokenDigits),
                        UseDefaultFee = true,
                        Type          = BlockchainTransactionType.Output | BlockchainTransactionType.SwapPayment
                    });
                }
                //else
                //{
                //    transactions.Add(new TezosTransaction
                //    {
                //        Currency = Xtz,
                //        CreationTime = DateTime.UtcNow,
                //        From = walletAddress.Address,
                //        To = Xtz.SwapContractAddress,
                //        Fee = feeAmountInMtz,
                //        GasLimit = Xtz.AddGasLimit,
                //        StorageLimit = Xtz.AddStorageLimit,
                //        UseDefaultFee = true,
                //        Params = AddParams(swap),
                //        Type = BlockchainTransactionType.Output | BlockchainTransactionType.SwapPayment
                //    });
                //}

                if (isInitTx)
                {
                    isInitTx = false;
                }

                if (requiredAmountInTokens <= 0)
                {
                    break;
                }
            }

            if (requiredAmountInTokens > 0)
            {
                Log.Warning("Insufficient funds (left {@requredAmount}).", requiredAmountInTokens);
                return(Enumerable.Empty <TezosTransaction>());
            }

            return(transactions);
        }
        public async Task <(bool result, bool isRunSuccess, bool hasReveal)> FillOperationsAsync(
            SecureBytes securePublicKey,
            TezosConfig tezosConfig,
            int headOffset         = 0,
            bool isAlreadyRevealed = false,
            CancellationToken cancellationToken = default)
        {
            using var publicKey = securePublicKey.ToUnsecuredBytes();

            var rpc = new Rpc(tezosConfig.RpcNodeUri);

            var managerKey = await rpc
                             .GetManagerKey(From)
                             .ConfigureAwait(false);

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

            if (Head == null)
            {
                Head = await rpc
                       .GetHeader(headOffset)
                       .ConfigureAwait(false);
            }

            Operations = new JArray();

            var gas      = GasLimit.ToString(CultureInfo.InvariantCulture);
            var storage  = StorageLimit.ToString(CultureInfo.InvariantCulture);
            var revealed = managerKey.Value <string>() != null || isAlreadyRevealed;

            UsedCounters = revealed ? 1 : 2;

            var counter = UseOfflineCounter
                ? await TezosCounter.Instance
                          .GetOfflineCounterAsync(
                address : From,
                head : actualHead["hash"].ToString(),
                rpcNodeUri : tezosConfig.RpcNodeUri,
                numberOfCounters : UsedCounters)
                          .ConfigureAwait(false)
                : await TezosCounter.Instance
                          .GetCounterAsync(
                address : From,
                head : actualHead["hash"].ToString(),
                rpcNodeUri : tezosConfig.RpcNodeUri)
                          .ConfigureAwait(false);

            if (!revealed)
            {
                var revealOp = new JObject
                {
                    ["kind"]          = Internal.OperationType.Reveal,
                    ["fee"]           = "0",
                    ["public_key"]    = Base58Check.Encode(publicKey, Prefix.Edpk),
                    ["source"]        = From,
                    ["storage_limit"] = "0",
                    ["gas_limit"]     = tezosConfig.RevealGasLimit.ToString(),
                    ["counter"]       = counter.ToString()
                };

                Operations.AddFirst(revealOp);

                counter++;
            }

            var operation = new JObject
            {
                ["kind"]          = OperationType,
                ["source"]        = From,
                ["fee"]           = ((int)Fee).ToString(CultureInfo.InvariantCulture),
                ["counter"]       = counter.ToString(),
                ["gas_limit"]     = gas,
                ["storage_limit"] = storage,
            };

            if (OperationType == Internal.OperationType.Transaction)
            {
                operation["amount"]      = Math.Round(Amount, 0).ToString(CultureInfo.InvariantCulture);
                operation["destination"] = To;
            }
            else if (OperationType == Internal.OperationType.Delegation)
            {
                operation["delegate"] = To;
            }
            else
            {
                throw new NotSupportedException($"Operation type {OperationType} not supporeted yet.");
            }

            Operations.Add(operation);

            if (Params != null)
            {
                operation["parameters"] = Params;
            }

            var isRunSuccess = false;

            if (UseRun)
            {
                var fill = await rpc
                           .AutoFillOperations(tezosConfig, Head, Operations, UseSafeStorageLimit)
                           .ConfigureAwait(false);

                if (!fill)
                {
                    Log.Warning("Operation autofilling error");
                }
                else
                {
                    Fee          = Operations.Last["fee"].Value <decimal>().ToTez();
                    isRunSuccess = true;
                }
            }

            return(
                result : true,
                isRunSuccess : isRunSuccess,
                hasReveal : !revealed
                );
        }
        public BitcoinBasedKey(SecureBytes seed)
        {
            using var scopedSeed = seed.ToUnsecuredBytes();

            Key = new Key(scopedSeed);
        }
Exemple #29
0
 public abstract IExtKey CreateExtKey(SecureBytes seed, int keyType);
Exemple #30
0
 public abstract IKey CreateKey(SecureBytes seed);