Building a ETH signer dapp with the KeepKey SDK.
Open-source hardware wallet. Bitcoin, Ethereum, Solana, TON, TRON, Cosmos, and all EVM chains. Your keys never leave the device.
Open-source hardware wallet. Bitcoin, Ethereum, Solana, TON, TRON, Cosmos, and all EVM chains. Your keys never leave the device.

TL:DR the completed GitHub repo: https://github.com/BitHighlander/eth-message-signer
Signing messages can be useful for proof of reserves and other cases where you want to prove to a third party you own an address.
(To start, this tutorial assumes you have a cloned and ready project from keepkey-template. See tutorial: here)
First, we set up the state vars of the app:
const [message, setMessage] = React.useState("");
const [address, setAddress] = React.useState("");
const [signature, setSignature] = React.useState("");
const [sdk, setSdk] = React.useState({});Next, we add a helper function that updates the state every time the user enters text into the form:
const handleInputChangeMessage = (e: any) => setMessage(e.target.value);Now we add an OnStart function into the app using React's built-in useEffect():
// onstart get data
useEffect(() => {
onStart();
}, []);Next, we import the SDK into the project and build our onStart() function:
localStorage.setItems("chakra-ui-color-mode", "dark");
const spec = "http://localhost:1646/spec/swagger.json";
const apiKey = localStorage.getItem("apiKey") || "1234";
const config = {
apiKey,
pairingInfo: {
name: "KeepKey-template Demo App",
imageUrl: "https://github.com/BitHighlander/keepkey-desktop/raw/master/electron/icon.png",
basePath: spec,
url: "http://localhost:1646",
},
};
// init
const sdkInit = await KeepKeySdk.create(config);
setSdk(sdkInit);
if (config.apiKey !== apiKey)
localStorage.setItem("apiKey", config.apiKey);And finally, we build the JSX portion of the app, this is the content displayed on the page:
return (
<Grid gap={4}>
<div>
<FormControl isInvalid={isError}>
<FormLabel>Sign a message! address: {address}</FormLabel>
<Input
type="email"
value={message}
onChange={handleInputChangeMessage}
/>
{!isError ? (
<FormHelperText>Enter your message</FormHelperText>
) : (
<FormErrorMessage>pioneer username is required.</FormErrorMessage>
)}
</FormControl>
<Button
mt={4}
colorScheme="teal"
// isLoading={props.isSubmitting}
type="submit"
onClick={() => onSubmit()}
>
Submit
</Button>
</div>
<div>
{signature ? (
<div>
<small>signature: {signature}</small>
</div>
) : (
<div>no sig</div>
)}
</div>
</Grid>
);This is a simple form, with a single input: the message.
And now we run the project:
yarn && yarn devAnd view our dapp on localhost!
http://127.0.0.1:5176/Commit and push your code and it will deploy and update Vercel.
Now that you have a completed dapp, let's publish it.
Continue to “submit your dapp to Pioneers Dapp store”