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); }