/// <summary>Get the Extended Public Key from the device for the BIP32 path specified.</summary> /// <param name="pinChallenge">Callback that gets </param> /// <param name="accountPath">BIP32 path e.g. "44'/0'/0'/0/0 = first Bitcoin account, first public key., from this you can derive the address.</param> /// <returns>The public key of the for the account at the path specified.</returns> public PublicKey GetPublicKey(Func <PinMatrixRequestType?, string> pinChallenge, string accountPath) { // Get the path as units var path = NBitcoin.KeyPath.Parse(accountPath); // Build the message var xpub = new GetPublicKey { AddressN = new List <uint>(path.Indexes), EcdsaCurveName = "secp256k1", ShowDisplay = false }; // Serialize it to bytes var msg = Contracts.GetPublicKey.SerializeToBytes(xpub); // Send the message to the device if (!_communicator.SendMessage(msg, MessageType.MessageType_GetPublicKey)) { throw new ApplicationException("Error writing to device"); } // Get the response from the device MessageType recievedType; var received = _communicator.RecieveMessage(out recievedType); if (recievedType == MessageType.MessageType_PinMatrixRequest) { var pinRequest = PinMatrixRequest.Deserialize(received); var pin = pinChallenge(pinRequest.Type); if (!_communicator.SendMessage(PinMatrixAck.SerializeToBytes(new PinMatrixAck { Pin = pin }), MessageType.MessageType_PinMatrixAck)) { throw new ApplicationException("Error writing to device"); } received = _communicator.RecieveMessage(out recievedType); } // PublicKey received if (recievedType == MessageType.MessageType_PublicKey) { return(PublicKey.Deserialize(received)); } // The device returned Failure if (recievedType == MessageType.MessageType_Failure) { throw new KeepKeyException(Failure.Deserialize(received)); } throw new NotImplementedException("Unable to process unexpected message type: " + recievedType); }