Exemple #1
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);
        }
        private async Task <IEnumerable <byte[]> > WriteRequestAndReadAsync <TRequest>(TRequest request) where TRequest : RequestBase
        {
            var responseData = new List <byte[]>();

            var apduChunks = request.ToAPDUChunks();

            for (var i = 0; i < apduChunks.Count; i++)
            {
                var apduCommandChunk = apduChunks[i];

                if (apduChunks.Count == 1)
                {
                    //There is only one chunk so use the argument from the request (e.g P1_SIGN)
                    apduCommandChunk[2] = request.Argument1;
                }
                else if (apduChunks.Count > 1)
                {
                    //There are multiple chunks so the assumption is that this is probably a transaction

                    if (i == 0)
                    {
                        //This is the first chunk of the transaction
                        apduCommandChunk[2] = Constants.P1_FIRST;
                    }
                    else if (i == (apduChunks.Count - 1))
                    {
                        //This is the last chunk of the transaction
                        apduCommandChunk[2] = Constants.P1_LAST;
                    }
                    else
                    {
                        //This is one of the middle chunks and there is more coming
                        apduCommandChunk[2] = Constants.P1_MORE;
                    }
                }

                var    packetIndex = 0;
                byte[] data        = null;
                using (var memoryStream = new MemoryStream(apduCommandChunk))
                {
                    do
                    {
                        data = Helpers.GetRequestDataPacket(memoryStream, packetIndex);
                        packetIndex++;
                        await LedgerHidDevice.WriteAsync(data);
                    } while (memoryStream.Position != memoryStream.Length);
                }

                var responseDataChunk = await ReadAsync();

                responseData.Add(responseDataChunk);

                var returnCode = ResponseBase.GetReturnCode(responseDataChunk);

                if (returnCode != Constants.SuccessStatusCode)
                {
                    return(responseData);
                }
            }
            return(responseData);
        }