public async Task <bool> SignAsync( IAddressResolver addressResolver, IKeyStorage keyStorage, IEnumerable <ITxOutput> spentOutputs, CancellationToken cancellationToken = default(CancellationToken)) { if (spentOutputs == null) { throw new ArgumentNullException(nameof(spentOutputs)); } foreach (var spentOutput in spentOutputs) { var address = spentOutput.DestinationAddress(Currency); var walletAddress = await addressResolver .ResolveAddressAsync( currency : Currency, address : address, cancellationToken : cancellationToken) .ConfigureAwait(false); if (walletAddress?.KeyIndex == null) { Log.Error($"Can't find private key for address {address}"); return(false); } Sign(keyStorage.GetPrivateKey(Currency, walletAddress.KeyIndex), spentOutput); } return(true); }
public async Task <bool> SignDelegationOperationAsync( IKeyStorage keyStorage, WalletAddress address, CancellationToken cancellationToken = default) { var xtz = (Atomex.Tezos)Currency; if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var securePrivateKey = keyStorage .GetPrivateKey(Currency, address.KeyIndex); if (securePrivateKey == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var privateKey = securePrivateKey.ToUnsecuredBytes(); var rpc = new Rpc(xtz.RpcNodeUri); Head = await rpc .GetHeader() .ConfigureAwait(false); var forgedOpGroup = await rpc .ForgeOperations(Head, Operations) .ConfigureAwait(false); var forgedOpGroupLocal = Forge.ForgeOperationsLocal(Head, Operations); if (true) //if (config.CheckForge == true) add option for higher security tezos mode to config { if (forgedOpGroupLocal.ToString() != forgedOpGroup.ToString()) { Log.Error("Local and remote forge results differ"); return(false); } } SignedMessage = TezosSigner.SignHash( data: Hex.FromString(forgedOpGroup.ToString()), privateKey: privateKey, watermark: Watermark.Generic, isExtendedKey: privateKey.Length == 64); return(true); }
public async Task <bool> SignAsync( IKeyStorage keyStorage, WalletAddress address, CancellationToken cancellationToken = default) { if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var privateKey = keyStorage.GetPrivateKey(Currency, address.KeyIndex); return(await SignAsync(privateKey) .ConfigureAwait(false)); }
public async Task <bool> SignAsync( IKeyStorage keyStorage, WalletAddress address, CurrencyConfig currencyConfig, CancellationToken cancellationToken = default) { if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var securePrivateKey = keyStorage.GetPrivateKey( currency: currencyConfig, keyIndex: address.KeyIndex, keyType: address.KeyType); if (securePrivateKey == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var privateKey = securePrivateKey.ToUnsecuredBytes(); var xtz = currencyConfig as TezosConfig; var rpc = new Rpc(xtz.RpcNodeUri); var forgedOpGroup = await rpc .ForgeOperations(Head, Operations) .ConfigureAwait(false); //var forgedOpGroup = Forge.ForgeOperationsLocal(Head["hash"].ToString(), Operations); SignedMessage = TezosSigner.SignHash( data: Hex.FromString(forgedOpGroup.ToString()), privateKey: privateKey, watermark: Watermark.Generic, isExtendedKey: privateKey.Length == 64); return(SignedMessage != null); }
public async Task <bool> SignAsync( IAddressResolver addressResolver, IKeyStorage keyStorage, IEnumerable <ITxOutput> spentOutputs, CurrencyConfig currencyConfig, CancellationToken cancellationToken = default) { if (spentOutputs == null) { throw new ArgumentNullException(nameof(spentOutputs)); } var btcBasedConfig = currencyConfig as BitcoinBasedConfig; foreach (var spentOutput in spentOutputs) { var address = spentOutput.DestinationAddress(btcBasedConfig.Network); var walletAddress = await addressResolver .GetAddressAsync( currency : Currency, address : address, cancellationToken : cancellationToken) .ConfigureAwait(false); if (walletAddress?.KeyIndex == null) { Log.Error($"Can't find private key for address {address}"); return(false); } using var securePrivateKey = keyStorage.GetPrivateKey( currency: btcBasedConfig, keyIndex: walletAddress.KeyIndex, keyType: walletAddress.KeyType); Sign(securePrivateKey, spentOutput, btcBasedConfig); } return(true); }
public async Task <bool> SignAsync( IKeyStorage keyStorage, WalletAddress address, CancellationToken cancellationToken = default(CancellationToken)) { var xtz = (Atomix.Tezos)Currency; if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } var privateKey = keyStorage .GetPrivateKey(Currency, address.KeyIndex); if (privateKey == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } var publicKey = keyStorage .GetPublicKey(Currency, address.KeyIndex); var rpc = new Rpc(xtz.RpcProvider); Head = await rpc .GetHeader() .ConfigureAwait(false); var managerKey = await rpc .GetManagerKey(From) .ConfigureAwait(false); Operations = new JArray(); var gas = GasLimit.ToString(CultureInfo.InvariantCulture); var storage = StorageLimit.ToString(CultureInfo.InvariantCulture); if (managerKey["key"] == null) { var revealOpCounter = await TezosCounter.Instance .GetCounter(xtz, From, Head) .ConfigureAwait(false); var revealOp = new JObject { ["kind"] = OperationType.Reveal, ["fee"] = "0", ["public_key"] = Base58Check.Encode(publicKey, Prefix.Edpk), ["source"] = From, ["storage_limit"] = storage, ["gas_limit"] = gas, ["counter"] = revealOpCounter.ToString() }; Operations.AddFirst(revealOp); } var counter = await TezosCounter.Instance .GetCounter(xtz, From, Head) .ConfigureAwait(false); var transaction = new JObject { ["kind"] = OperationType.Transaction, ["source"] = From, ["fee"] = Fee.ToString(CultureInfo.InvariantCulture), ["counter"] = counter.ToString(), ["gas_limit"] = gas, ["storage_limit"] = storage, ["amount"] = Math.Round(Amount, 0).ToString(CultureInfo.InvariantCulture), ["destination"] = To }; Operations.Add(transaction); if (Params != null) { transaction["parameters"] = Params; } else { var parameters = new JObject { ["prim"] = "Unit", ["args"] = new JArray() }; transaction["parameters"] = parameters; } var forgedOpGroup = await rpc .ForgeOperations(Head, Operations) .ConfigureAwait(false); SignedMessage = TezosSigner.SignHash( data: Hex.FromString(forgedOpGroup.ToString()), privateKey: privateKey, watermark: Watermark.Generic, isExtendedKey: privateKey.Length == 64); return(true); }
public async Task <bool> AutoFillAsync( IKeyStorage keyStorage, WalletAddress address, bool useDefaultFee) { var xtz = (Atomex.Tezos)Currency; if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var securePrivateKey = keyStorage .GetPrivateKey(Currency, address.KeyIndex); if (securePrivateKey == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var privateKey = securePrivateKey.ToUnsecuredBytes(); using var securePublicKey = keyStorage .GetPublicKey(Currency, address.KeyIndex); using var publicKey = securePublicKey.ToUnsecuredBytes(); var rpc = new Rpc(xtz.RpcNodeUri); Head = await rpc .GetHeader() .ConfigureAwait(false); var managerKey = await rpc .GetManagerKey(From) .ConfigureAwait(false); Operations = new JArray(); var gas = GasLimit.ToString(CultureInfo.InvariantCulture); var storage = StorageLimit.ToString(CultureInfo.InvariantCulture); var counter = await TezosCounter.Instance .GetCounter(xtz, From, Head, ignoreCache : true) .ConfigureAwait(false); if (managerKey.Value <string>() == null) { //var revealOpCounter = await TezosCounter.Instance // .GetCounter(xtz, From, Head, ignoreCache: true) // .ConfigureAwait(false); var revealOp = new JObject { ["kind"] = OperationType.Reveal, ["fee"] = "0", ["public_key"] = Base58Check.Encode(publicKey, Prefix.Edpk), ["source"] = From, ["storage_limit"] = storage, ["gas_limit"] = gas, ["counter"] = counter.ToString()//revealOpCounter.ToString() }; Operations.AddFirst(revealOp); counter++; } //var counter = await TezosCounter.Instance // .GetCounter(xtz, From, Head) // .ConfigureAwait(false); var transaction = new JObject { ["kind"] = OperationType.Delegation, ["source"] = From, ["fee"] = ((int)Fee).ToString(CultureInfo.InvariantCulture), ["counter"] = counter.ToString(), ["gas_limit"] = gas, ["storage_limit"] = storage, ["delegate"] = To }; Operations.Add(transaction); if (Params != null) { transaction["parameters"] = Params; } var fill = await rpc .AutoFillOperations(xtz, Head, Operations, useDefaultFee) .ConfigureAwait(false); if (!fill) { Log.Error("Delegation autofilling error"); return(false); } // Fee = Operations[0]["fee"].Value<decimal>() / 1_000_000; Fee = Operations.Last["fee"].Value <decimal>() / 1_000_000; return(true); }
public async Task <bool> SignAsync( IKeyStorage keyStorage, WalletAddress address, CancellationToken cancellationToken = default) { var xtz = (Atomex.Tezos)Currency; if (address.KeyIndex == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var securePrivateKey = keyStorage .GetPrivateKey(Currency, address.KeyIndex); if (securePrivateKey == null) { Log.Error("Can't find private key for address {@address}", address); return(false); } using var privateKey = securePrivateKey.ToUnsecuredBytes(); using var securePublicKey = keyStorage .GetPublicKey(Currency, address.KeyIndex); var rpc = new Rpc(xtz.RpcNodeUri); Head = await rpc .GetHeader() .ConfigureAwait(false); await FillOperationsAsync(Head, securePublicKey) .ConfigureAwait(false); if (Type != BlockchainTransactionType.Output) { UseDefaultFee = true; } var fill = await rpc .AutoFillOperations(xtz, Head, Operations, UseDefaultFee) .ConfigureAwait(false); if (!fill) { Log.Error("Transaction autofilling error"); return(false); } // todo: update Fee, GasLimit, StorageLimit var forgedOpGroup = await rpc .ForgeOperations(Head, Operations) .ConfigureAwait(false); var forgedOpGroupLocal = Forge.ForgeOperationsLocal(Head, Operations); //if (true) //if (config.CheckForge == true) add option for higher security tezos mode to config //{ // if (forgedOpGroupLocal.ToString() != forgedOpGroup.ToString()) // { // Log.Error("Local and remote forge results differ"); // return false; // } //} SignedMessage = TezosSigner.SignHash( data: Hex.FromString(forgedOpGroup.ToString()), privateKey: privateKey, watermark: Watermark.Generic, isExtendedKey: privateKey.Length == 64); return(true); }