Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
        /// <summary>Displays a message on the KeepKey screen.  Supply true to the second parameter to force the user to press the device button.</summary>
        /// <param name="message">The message to display.  Note the maximum number of characters is approximately 130 - text longer than this gets truncated by the device.</param>
        /// <param name="buttonProtection">true to wait for the user to press and hold the button on the device, false to return the message immediately.</param>
        /// <returns></returns>
        public string Ping(string message, bool buttonProtection = true)
        {
            // Build the message
            var ping = new Ping
            {                       // Provide ALL fields
                Message              = message,
                ButtonProtection     = buttonProtection,
                PinProtection        = false,
                PassphraseProtection = false
            };
            // Serialize it to bytes
            var msg = Contracts.Ping.SerializeToBytes(ping);

            // Send the message to the device
            if (!_communicator.SendMessage(msg, MessageType.MessageType_Ping))
            {
                throw new ApplicationException("Error writing to device");
            }

            // Get the response from the device
            MessageType recievedType;
            var         received = _communicator.RecieveMessage(out recievedType);

            // ButtonRequest was received
            if (recievedType == MessageType.MessageType_ButtonRequest)
            {
                // Acknowledge the button request & wait for the next response
                if (!_communicator.SendMessage(ButtonAck.SerializeToBytes(new ButtonAck()), MessageType.MessageType_ButtonAck))
                {
                    throw new ApplicationException("Error writing to device");
                }
                received = _communicator.RecieveMessage(out recievedType);
            }

            // The device returned Success
            if (recievedType == MessageType.MessageType_Success)
            {
                return(Success.Deserialize(received).Message);
            }

            // The device returned Failure
            if (recievedType == MessageType.MessageType_Failure)
            {
                var failure = Failure.Deserialize(received);
                return(failure.Code.HasValue ? $"{failure.Code.GetValueOrDefault()} - {failure.Message}" : failure.Message);
            }

            throw new NotImplementedException("Unable to process unexpected message type: " + recievedType);
        }