Giter VIP home page Giter VIP logo

hdwallet's Introduction

HDWallet

CircleCI

A library for interacting with hardware wallets from JS/TS. Supports KeepKey, Trezor, and Ledger. Intended for use in web apps, chrome apps/extensions, and electron/node apps.

Try it out here!

Documentation

Installation

yarn add @shapeshiftoss/hdwallet-core
yarn add @shapeshiftoss/hdwallet-keepkey-webusb
yarn add @shapeshiftoss/hdwallet-trezor-connect
yarn add @shapeshiftoss/hdwallet-ledger-webusb

Importing Library

You can import the generated bundle to use each of the component libraries:

import { HDWallet } from "@shapeshiftoss/hdwallet-core";
import { isKeepKey, KeepKeyHDWallet } from "@shapeshiftoss/hdwallet-keepkey";
import { isLedger, LedgerHDWallet } from "@shapeshiftoss/hdwallet-ledger";
import { isTrezor, TrezorHDWallet } from "@shapeshiftoss/hdwallet-trezor";

import { WebUSBKeepKeyAdapter } from "@shapeshiftoss/hdwallet-keepkey-webusb";
import { WebUSBLedgerAdapter } from "@shapeshiftoss/hdwallet-ledger-webusb";
import { TrezorAdapter } from "@shapeshiftoss/hdwallet-trezor-connect";

Usage

The recommended way to use the library is through a Keyring singleton, which manages connected devices:

import { Keyring } from "@shapeshiftoss/hdwallet-core";
const keyring = new Keyring();

To add in support for a given wallet type, add in the relevant Transport adapter by calling useKeyring() on it:

import { WebUSBKeepKeyAdapter } from "@shapeshiftoss/hdwallet-keepkey-webusb";
import { TrezorAdapter } from "@shapeshiftoss/hdwallet-trezor-connect";

const keepkeyAdapter = WebUSBKeepKeyAdapter.useKeyring(keyring);

const trezorAdapter = TrezorAdapter.useKeyring(keyring, {
  debug: false,
  manifest: {
    email: "[email protected]", // TrezorConnect info
    appUrl: "https://example.com", // URL of hosted domain
  },
});

const ledgerAdapter = LedgerAdapter.useKeyring(keyring);

After setting up a Keyring, and plugging various transport adapters into it, the next step is to pair a device:

let wallet = await keepkeyAdapter.pairDevice();

wallet.getLabel().then((result) => {
  console.log(result);
});

Building

It is expected that this take quite some time (around 10 minutes), due to the large size of the compiled KeepKey protobuf encoder/decoder.

yarn clean
yarn
yarn build

Developing

To compile and watch the browser bundle, run:

yarn dev:sandbox

This will launch an ssl webserver that runs at https://localhost:1234, with a small demo app that shows how to use various HDWallet functionality.

We use Zeit Now for continuous deployment of this sandbox app. On pull requests, the builder will publish a new version of that app with the changes included (for example #68). Try out the latest build here: https://hdwallet.shapeshift.now.sh/

Tests

yarn
yarn build
yarn test

The integration tests have been set up to run either against a physical KeepKey with debug firmware on it, or in CI pointed at a dockerized version of the emulator. Trezor and Ledger tests run against mocks of their respective transport layers.

Contributing

See our developer guidelines here.

hdwallet's People

Contributors

0xapotheosis avatar 0xdef1cafe avatar 0xean avatar 0xmillz avatar 0xtekgrinder avatar 0xzoz avatar asamere avatar ascension avatar bithighlander avatar chxash avatar cjthompson avatar dviramontes avatar elmutt avatar gomesalexandre avatar kaladinlight avatar keepkeybrett avatar keepkeyjon avatar lmyslinski avatar loxator avatar majorhayes avatar markrypto avatar mrnerdhair avatar mvpratt avatar natven avatar neurone avatar pastaghost avatar sterl avatar stevehadow avatar thengoster avatar woodenfurniture avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hdwallet's Issues

Adding new hardware wallet: BitBox02

Hey!

What do you think about adding support for BitBox02?

We (Shift Cryptosecurity) have been around since 2015 and we have had two successful products in this space: the "Digital BitBox" and the "BitBox02". Both have been listed by bitcoin.org and you can currently find the BitBox02 there: https://bitcoin.org/en/wallets/hardware/bitbox/?step=5&platform=hardware

Recently we developed support for web wallets. We take a similar route to it as Trezor and require the user to install a bridge for usb to http communication. But we never redirect the user to anything hosted by us, so we can't collect metadata about the users. The communication is also end-to-end encrypted between the web service and our hardware wallet. Our bridge is open source and available here.

You can see how integration would look like in our npm package here. We are working on improving the demo to make it the documentation of how to do integrations.

What do you think?

Add WebHID support for Ledger

Add a new transport package called hdwallet-ledger-webhid that integrates @ledgerhq/hw-transport-webhid. This is a better transport option for Windows users and others that have problems with webUSB.

Integrate MetaMask into HDWallet

ShapeShift DAO HDWallet Bounty

Create support for MetaMask in HDWallet. Only need support for Ethereum and ERC20s. No other supported coins are required for this bounty.

Acceptance Criteria:

  1. All the Ethereum and ERC20 functions in examples/sandbox/index.html work correctly when run in a local browser. The sandbox can easily be run locally.
  2. Tests created in integration/src/metamask.test.ts

Details:

Add a new folder in the /packages folder. The current packages/hdwallet-portis should be a good starting point for creating /packages/hdwallet-metamask.

Implement all appropriate HDWallet interfaces including adapter, info, and ethereum. The transport interface can be an empty interface. Refer to the Portis transport interface as a reference.

Bounty will be paid once PR is submitted, reviewed and tested by core dev team, and merged. Changes may be required prior to merging.

Add npm install instructions.

While yarn add @shapeshiftoss/hdwallet may do something useful (not sure, I don't use yarn), npm add @shapeshiftoss/hdwallet just errors. A glance at NPM suggests there are actually a bunch of different libraries that all start with @shapeshiftoss/hdwallet but have different suffixes.

hdwallet-native ignores BNB account/sequence numbers

binanceSignTx() takes inputs for account and sequence number, but completely ignores them. They eventually get overwritten from the internet. This means that the integration tests can't rely on the same inputs always producing the same outputs, and has contributed to #267.

Any way to get public key and chain code from KeepKey device?

I'm looking to integrate KeepKey in my project, but for faster HD wallet derivation I'm trying to fetch the public key and chain code from the device for a derivation path, so I can do key derivation locally.

Currently I'm using ethGetAddress, but there doesn't seem a way to get a public key and chain code with this function. Is there any way to do this?

Trying to switch over the new keepkey library but failing on chrome

Hello,

I am trying to update our library with the new Keepkey library. We were using @keepkey/keepkey.js prior to this. I followed the documentation on your readme and everything was working up to the point,

wallet.getLabel().then((result) => {
console.log(result);
});

The result returns undefined. But I also noticed this warning in the console:

An attempt to claim a USB device interface has been blocked because it implements a protected interface class.

I think this means that Chrome blocks this class from initiating ? I also tried on firefox and got the error, WebUSB is not available in this browser. We recommend trying Chrome. Is there any way around this ? I could also be doing something completely incorrect so any help is appreciated!

The code is a bit messy right now because it still has the old keepkey integration there, but I am following the exact steps in the readme. The file is here (it is on line 53):
https://github.com/MyEtherWallet/MyEtherWallet/blob/devop/update-keepkey/src/wallets/hardware/keepkey/index.js

Thank you!!

inject metamask inpage provider so `unsafe-inline` isn't required in the CSP on Firefox

In hdwallet-metamask, use @metamask/providers (or maybe even the older metamask-inpage-provider -- see shapeshift/web#443 for some potentially-adaptable code) to try to instantiate a metamask provider for use in case detectEthereumProvider() can't find window.ethereum. This is relevant because Firefox applies page CSPs to code injected by extensions, which will block thing metamask's injected provider if we don't include the unsafe-inline options.

This may be better served as a change PRed to @metamask/detect-provider to resolve MetaMask/detect-provider#31.

(see also shapeshift/web#541)

Cosmos: Native Wallet Support

As a user, I want to be able to use Cosmos and Osmosis on ShapeShift native.

Users can send, receive, stake (delegate), unstake (undelegate), and get reward on Native Wallet

Add hdwallet-metamask integration tests

Background

The hdwallet-metamask package does not currently have a set of tests run alongside those for the other supported wallets in the integration test suite. Using the portis and native integration tests as an example, add test coverage for hdwallet-metamask in a metamask.test.ts file and wallets/metamask.ts file under the hdwallet/integration subdirectory. Mock data should be placed in hdwallet/integration/src/wallets/mocks.

Acceptance Criteria

  • The wallet should support Ethereum mainnet (add test for wallet.ethSupportsNetwork())
  • The wallet should not support BTC (add test for wallet.btcSupportsNetwork())
  • The wallet should use the correct ETH BIP-44 paths (add test for wallet.ethGetAccountPaths())
  • The wallet should describe ETH paths (add test for wallet.describeETHPath())
  • The wallet should return a valid ETH address (add test for wallet.ethGetAddress())
  • The wallet should sign a message (add test for wallet.ethSignMessage())

Note

Since these tests are run outside a browser, the provider property of the wallet will have to be mocked. The following pattern can be extended for any RPC calls made by each of the above functions that call ethereum.request().

  // mock wallet provider
  wallet.provider = {
    request: (args: any) => {
      switch (args.method) {
        case "eth_accounts":
          return ["0x3f2329C9ADFbcCd9A84f52c906E936A42dA18CB8"];
          break;
        default:
          return null;
      }
    },
  };
  // end mock

Bounty Hunters

  • Join our discord here.
  • Include an expected timeline for you to complete work in the work plan when you apply for this bounty!
  • Please refer to this link for some basic info

Cant Sign Transaction - Encountered invalid prevhash

image

Getting encountered invalid prevhash when attempting to sign a transaction with a coin that has no client typically (Denarius) but is in the firmware of Keepkey...Address derivation and all of that works great, and now pulling unspent transactions from the address and then attempting to sign it...this fails everytime with the "Encountered invalid prevhash" which seems to be linked to the Trezor firmware libs? This is all on a Keepkey though fyi and using WebUSB, other transactions are able to sign just fine like Dogecoin, Bitcoin, Litecoin, etc.

My btcSignTx call:

    const txid = "fb11728d7afbf705279dbe3ce8d964b903b23d1d75cda3e0b27b24e008321dca"; //UTXO TXID
    const hex =
      "010000003b4afc5e01acf0bb4ad63d880e590b80c5a3ee66e950fddeb8c5cc72578a1c89bbcf597251010000006a473044022003ddac31ed3d2dffc50169c0bcece812207876467d9863d78d6064d92349b915022066fc8187ec60dbff205878c570e13f7ca5377ebb8b5181d206a844f968942de6012103f5b29d1f63e06568912c4ca0ca2bf8827ed2bef532446ef3d379590e0d3316aeffffffff02a0bb0d00000000001976a914032c2288699a64540e81e9980b3e6598040ba10288aca8609200000000001976a9145ef9da5d87a0c17eb8dc08ad4c14ab948af8777b88ac00000000";
    // Raw TX HEX of TXID getrawtransaction

    const inputs = [
      {
        addressNList: denariusBip44.addressNList,
        scriptType: BTCInputScriptType.SpendAddress,
        amount: String(2160258),
        vout: 1, 
        txid,
        segwit: false,
        tx: dTxJson, 
        hex,
      },
    ];

    const outputs = [
      {
        address: "DFaSN5xF8Y7o9ifFuBcHQsub9UoT3yn7kx",
        addressType: BTCOutputAddressType.Spend,
        scriptType: BTCOutputScriptType.PayToAddress,
        amount: String(261614),
        isChange: false,
      },
    ];

    const res = await wallet.btcSignTx({
      coin: "Denarius",
      inputs,
      outputs,
      version: 1,
      locktime: 0,
    });

The dxTxJson just includes the full raw transaction json of the main input TXID as followed by other coins.

Denarius was added as a cointype under the bitcoin.ts file (Number 116) if anyone can test this and assist.

Add types field to package.json

Some IDEs (like WebStorm/IntelliJ) look for a types field in the package.json to provide TypeScript type hinting. It would be nice if each package had a types field for a better development experience.

Example:

{
  "...": "...",
  "types": "./dist"
}

Electron Support

I was about to use this lib for ledger device connection and found a problem.
It works in web but not in electron. I'm getting following issue when call pairDevice method.

WebUSBCouldNotPair: Could not pair Ledger: Failed to execute 'requestDevice' on 'USB': Must be handling a user gesture to show a permission request.

So I digged into it and noticed that this lib uses "@ledgerhq/hw-transport-webusb" which is not supported in electron.
Did I miss something or is it in progress or future plan?

[KeepKey] Module not found: Error: Can't resolve 'bs58'

@shapeshiftoss/hdwallet-keepkey depends on bs58, but this dependency isn't listed in package.json, which results in:

Module not found: Error: Can't resolve 'bs58' in '.../node_modules/@shapeshiftoss/hdwallet-keepkey/dist'

Node v16 support?

Curious if we can use this on v16 of Node. Currently the .nvmrc only allows up to v14 but wondering if that can be changed.

Error: The y-parity of the transaction should either be 0 or 1

I'm experimenting with the sandbox sample app, and get the following error in the debug console:

eip1559Transaction.ts:220 Uncaught (in promise) Error: The y-parity of the transaction should either be 0 or 1
    at new FeeMarketEIP1559Transaction (eip1559Transaction.ts:220)
    at Function.FeeMarketEIP1559Transaction.fromTxData (eip1559Transaction.ts:87)
    at Object.<anonymous> (ethereum.ts:166)
    at step (index.js:68)
    at Object.next (index.js:68)
    at fulfilled (index.js:68)
FeeMarketEIP1559Transaction @ eip1559Transaction.ts:220
FeeMarketEIP1559Transaction.fromTxData @ eip1559Transaction.ts:87
(anonymous) @ ethereum.ts:166
step @ index.js:68
(anonymous) @ index.js:68
fulfilled @ index.js:68
Promise.then (async)
step @ thorchainTx.json:1
(anonymous) @ thorchainTx.json:1
__awaiter @ thorchainTx.json:1
(anonymous) @ index.ts:1301
dispatch @ jquery.js:5430
elemData.handle @ jquery.js:5234

Repro Steps:

  1. Open the sandbox
  2. Pair your Keepkey device
  3. Click on the "EIP-1559?" button
  4. Click on the "TX" button
  5. Press the button on the keepkey twice to confirm
  6. Observe nothing shows up in the results text box just below the buttons
  7. Observer the error message in the debug console

KK Model: K1-14AM
Firmware: v7.1.8

The error is being thrown in eip1559Transaction.ts:220

    if (this.v && !this.v.eqn(0) && !this.v.eqn(1)) {
      throw new Error('The y-parity of the transaction should either be 0 or 1')
    }

I put a breakpoint on ethereum.ts:164 and observed that the v value was "0x26". Don't know what that means unfortunately.

Welcomed additions

I would like to buy sell and trade EPIC-001, Epic Cash, ECR and EPIC/USDT on the ShapeShift dex platform.
Thank you.

add/enforce eslint typescript warnings

ESLint includes many things that prevent footguns from going off.

  • add eslint to build pipeline
  • warnings should fail CI
  • existing code will need overrides of various things, like explicit any in the extends clause of conditional types

Having to add the overrides will help us triage any future refactoring efforts.

@next feature release discussion

Posting this thread as a placeholder for the next major branch features and architecture discussion.
(out of scope of this thread is asset additions)

ref: #354 PR

Things on my list:

1.) support for thorchain keystore import/export/migrate
2.) proposals for removing the mixin madness flying V's ref:
3.) Any features we can add to make xchain-js integration smoother/cleaner
4.) first class kk-bridge support with multi connecting multiplexing (bypassing claim device limitations)

BNB integration tests should verify that the signed TX matches the expected TX

The (already-passing) BNB integration tests try to sign one thing, and get a signature over another. Specifically, the account_number, sequence, and chain_id fields may all be overwritten with data from the interwebs before the transaction is returned. The input data should be updated to match the values that will actually be signed, and actually-signed data should be checked to make sure it matches the input.

hdwallet-keepkey should fail hard with invalid "amount" inputs

When processing BNB transactions, hdwallet-keepkey does not perform input validation before handing the "amount" value off to the protobuf library for serialization, which conveniently provides a textbook example of the sheer eldritch horror lurking behind the words "undefined behavior".

In particular, despite the applicable field in the structure being defined as an integer, the upstream protobuf library doesn't perform any input checking. It happily parses the provided string character-by-character, subtracting the ascii value of 0 to get the numeric value of each digit. When it encounters ., which has a lower value than zero, the fact that the subtraction results in a negative number doesn't stop it from computing with it, coercing the result to a hilariously-large unsigned integer, sticking that in an array that's supposed to only contain byte values, and then doing more non-type-checked serialization on that.

The design principal of speed-over-correctness seems to be a conscious choice by the authors of the upstream code, so the appropriate remedy would be improved type-checking in hdwallet-keepkey.

Please List Charg Coin (CHG)

Please list Charg Coin (CHG). Since 2017, Charg Coin (CHG) has been democratizing the price of energy-time.

  1. We have our own mainnet, located here:
    https://stats.chgcoin.org
    https://explorer.chgcoin.org
    https://hub.chgcoin.org

  2. Even though we have our own POA golang mainnet, the new mainnet supports the old ERC20, and CHG can live on EITHER blockchain with cap of 90MM CHG across both. For example, it 45MM CHG is living on the ERC20 chain, only 45MM CHG can live on the mainnet at that exact moment in time.

  3. Our ERC20 information for the listing is as follows. Since our mainnet supports the ERC20, we only require you to list the ERC20 for the time being:
    A) Contract address: 0x482EFd447bE88748e7625e2b7c522c388970B790
    B) Name: Charg Coin
    C) ticker: CHG
    D) # of digits: 18

  4. We have 50K facebook likes here - https://www.facebook.com/ChargCoin/
    and another 9K facebook likes for wecharg, located here - https://www.facebook.com/WeCharg.Official/

  5. Our websites are as follows:
    https://chgcoin.org (main website)
    https://wecharg.com (use case / partner company)
    https://forum.chgcoin.org
    https://t.me/chargchat

hdwallet-native doesn't handle the amount field properly

hdwallet is supposed to take integer amounts of the smallest-denomination unit of each coin (satoshis for BTC, wei for ETH, etc). The Binance on-chain protocol uses this representation as well, but the BNB JS SDK, despite having a very-similar API surface, expects a decimal amount of BNB and "helpfully" converts it by multiplying by 10^8. This results in signing transactions for 10^8 too much value, which only safe if the resulting TX is invalid because you don't have that much to spend.

[KeepKey] `isLocked` returns false even if device is locked with PIN

isLocked always returns false, even when the device is locked with a PIN (passphrase not tested). Looks like there is a bug on this line: https://github.com/shapeshift/hdwallet/blob/master/packages/hdwallet-keepkey/src/keepkey.ts#L691

features.pinProtection && !features.pinProtection always evaluates to false, since pinProtection is never truthy and falsy at the same time. This should probably be changed to features.pinProtection && !features.pinCached.

PRODUCT_ID on hdwallet-keepkey-nodehid is possibly incorrect

Hey, the source defines the USB product id as:

export declare const PRODUCT_ID = 1;

but my device reports it as 2:

> lsusb
...
Bus 001 Device 012: ID 2b24:0002 KeepKey LLC Bitcoin Wallet
...

Is this a mistake?

If it isn't, what's the appropriate way to check if a HID device is a KeepKey?

Recovery functionality throws error on button clicking

I wiped my KeepKey, and when tried to recover a seed the platform was unable to carry out the process. The buttons from the virtual keyboard that the user must use to input the recovery seed are not working and retrieving an error via console. I'm attaching a couple of gifs about my experience so this can be more clear. Looks like a global issue, I've attempted to do so in Chrome, Edge and Brave, all resulting on the same problem.

recover
recover-console

How to determine device state?

Hi, I'm modifying the sandbox web app to create a simple wallet for my keepkey. I'm trying to come up with a definitive way to determine what state a device is in. In other words, when can I know for sure the device has been paired and is ready for use? Does the reception of the CONNECT event imply a paired device, or is it possible to receive that event from an unpaired device? If a device is present in keyring.wallets, is that a definitive indicator? Sorry if these are all very elementary questions.

eventemitter2 provides its own type definitions

Minor issue, but when installing @shapeshiftoss/hdwallet-keepkey-webusb, I got the following warning:

warning @shapeshiftoss/hdwallet-keepkey-webusb > @shapeshiftoss/hdwallet-keepkey > @types/[email protected]: This is a stub types definition for eventemitter2 (https://github.com/asyncly/EventEmitter2). eventemitter2 provides its own type definitions, so you don't need @types/eventemitter2 installed!

Cosmos: KeepKey Firmware

As a user, I want to be able to use Cosmos and Osmosis on KeepKey. As platform admins, we want to limit Wallet functionality for Cosmos and Osmosis to wallets that support [Asset].

Make corresponding HD wallet KK changes

A/C:
Users can send, receive, stake (delegate), unstake (undelegate), and get reward on KeepKey

Nano Support

The Keepkey itself apparently supports nano but currently there seems to be no wallet to support nano and the Keepkey, but for other wallets (like nault) to be able to support the keepkey there needs to be some library or whatever to communicate with the keepkey and since this seems to be the official one as https://github.com/keepkey/device-client is deprecated and says to use this here.

ref Nault/Nault#144

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.