Keycard Shell Library based on @ledgerhq/hw-app-eth and @ledgerhq/hw-transport.
ShellJS permits you to communicate with Keycard Shell through websites and through nodejs-based native applications.
Ethereum API
transport
Transport
import ShellJS from "Shelljs";
const cmd = new ShellJS.Commands(transport);
get public key for a given BIP 32 path.
const resp = await cmd.getPublicKey("44'/60'/0'/0/0");
console.log(resp.address);
Returns Promise<{publicKey: string, address: string, chainCode: string?}> an object with a publicKey, address and (optionally) chainCode
sign a transaction and retrieve v, r, s given the raw transaction and the BIP 32 path of the account to sign.
path
string : the BIP32 path to sign the transaction onrawTxHex
string : the raw ethereum transaction in hexadecimal to sign
const tx = "e8018504e3b292008252089428ee52a8f3d6e5d15f8b131996950d7f296c7952872bd72a2487400080"; // raw tx to sign
const resp = cmd.signEthTransaction("44'/60'/0'/0/0", tx);
console.log(resp);
Returns Promise<{s: string, v: string, r: string}>
get firmware and database version installed on device, Keycard Shell serial number and public key.
const {fwVersion, dbVersion, serialNumber, publicKey} = await cmd.getAppConfiguration();
console.log(fwVersion);
console.log(dbVersion);
console.log(serialNumber);
console.log(publicKey);
Returns Promise<{fwVersion: string, dbVersion: number, serialNumber: string, publicKey: string}>
sign a PSBT and return signed PSBT.
psbt
ArrayBuffer : partially signed bitcoin transaction
const resp = await cmd.signPSBT(psbt);
console.log(resp);
Returns Promise<ArrayBuffer>
sign an Eth personal message and retrieve v, r, s given the message and the BIP 32 path of the account to sign.
const resp = await cmd.signEthPersonalMessage("44'/60'/0'/0/0", "Hello world!");
let v = resp['v'] - 27;
v = v.toString(16);
if (v.length < 2) {
v = "0" + v;
}
console.log("Signature 0x" + resp['r'] + resp['s'] + v);
Returns Promise<{v: number, s: string, r: string}>
sign an EIP-712 formatted message
const resp = await cmd.signEIP712Message("44'/60'/0'/0/0", {
domain: {
chainId: 69,
name: "Da Domain",
verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
version: "1"
},
types: {
"EIP712Domain": [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" }
],
"Test": [
{ name: "contents", type: "string" }
]
},
primaryType: "Test",
message: {contents: "Hello, Bob!"},
});
Returns Promise<{v: number, s: string, r: string}>
load Keycard Shell firmware
fw
ArrayBuffer firmware
const fs = require('fs'),
let f = fs.readFileSync('./firmware.bin');
let fw = new Uint8Array(f);
await cmd.loadFirmware(fw);
load Keycard Shell database
db
ArrayBuffer database
const fs = require('fs'),
let f = fs.readFileSync('./db.bin');
let db = new Uint8Array(f);
await cmd.loadDatabase(db);
You can check a demo at Shell Web HID Example Page.