/// <summary>
    /// Gets the signed transaction data from the Ledger wallet.
    /// </summary>
    /// <param name="transaction"> The transaction to sign. </param>
    /// <param name="path"> The path of the address to sign the transaction with. </param>
    /// <param name="onSignatureRequestSent"> Action to call once the signature request has been sent. </param>
    /// <returns> Task returning the SignedTransactionDataHolder instance. </returns>
    protected override async Task <SignedTransactionDataHolder> GetSignedTransactionData(Transaction transaction, string path, Action onSignatureRequestSent)
    {
        var ledgerManager = LedgerConnector.GetWindowsConnectedLedger();
        var address       = ledgerManager == null
            ? null
            : (await ledgerManager.GetPublicKeyResponse(Wallet.ELECTRUM_LEDGER_PATH.Replace("x", "0"), false, false).ConfigureAwait(false))?.Address;

        // Don't sign transaction if app is not Ethereum, or if the first address doesn't match the first address of the opened Ledger wallet.
        if (string.IsNullOrEmpty(address) || !address.EqualsIgnoreCase(addresses[1][0]))
        {
            return(null);
        }

        var addressIndex   = path.Count(c => c == '/') - 1;
        var derivationData = Helpers.GetDerivationPathData(path);

        var request = new EthereumAppSignTransactionRequest(derivationData.Concat(transaction.GetRLPEncoded()).ToArray());

        onSignatureRequestSent?.Invoke();

        var response = await ledgerManager.SendRequestAsync <EthereumAppSignTransactionResponse, EthereumAppSignTransactionRequest>(request).ConfigureAwait(false);

        if (!response.IsSuccess)
        {
            return(new SignedTransactionDataHolder());
        }

        return(new SignedTransactionDataHolder {
            signed = true, v = response.SignatureV, r = response.SignatureR, s = response.SignatureS
        });
    }
Exemple #2
0
        public async Task <ECDSASignature> SignAsync(byte[] hash)
        {
            var path = GetPath();

            var firstRequest = new EthereumAppSignTransactionRequest(true, path.Concat(hash).ToArray());

            var response = await LedgerManager.SendRequestAsync <EthereumAppSignTransactionResponse, EthereumAppSignTransactionRequest>(firstRequest);

            var signature = ECDSASignatureFactory.FromComponents(response.SignatureR, response.SignatureS);

            signature.V = new BigInteger(response.SignatureV).ToBytesForRLPEncoding();
            return(signature);
        }
Exemple #3
0
        public async Task <ECDSASignature> SignAsync(byte[] hash)
        {
            var ledgerManager = await GetLedger();

            ledgerManager.SetCoinNumber(60);
            var derivationData = Helpers.GetDerivationPathData(ledgerManager.CurrentCoin.App, ledgerManager.CurrentCoin.CoinNumber, 0, 0, false, ledgerManager.CurrentCoin.IsSegwit);

            // Create base class like GetPublicKeyResponseBase and make the method more like GetAddressAsync
            var firstRequest = new EthereumAppSignTransactionRequest(derivationData.Concat(hash).ToArray());

            var response = await ledgerManager.SendRequestAsync <EthereumAppSignTransactionResponse, EthereumAppSignTransactionRequest>(firstRequest);

            var signature = new ECDSASignature(new Org.BouncyCastle.Math.BigInteger(response.SignatureR), new Org.BouncyCastle.Math.BigInteger(response.SignatureS));

            signature.V = new BigInteger(response.SignatureV).ToBytesForRLPEncoding();
            return(signature);
        }