This document describes the external packages used in the Morpher Wallet.
The frontend is split into two parts:
- The Keystore
- The iFrame SDK
In general both are written in TypeScript (or ported to TS).
The Keystore is written in VueJs with a Vuex datastore.
The iFrame SDK is written using a native iFrame HTML element and binding parent/child listeners through penpal to the parent/child document. More on the flow below.
The following is a non-exhaustive list of important packages used in the Keystore-App with their description:
https://web3js.readthedocs.io/en/v1.2.0/web3-eth-accounts.html The web3.eth.accounts contains functions to generate Ethereum accounts and sign transactions and data.
It's currently marked as "This package has NOT been audited and might potentially be unsafe. Take precautions to clear memory properly, store the private keys safely, and test transaction receiving and sending functionality properly before using in production!". We're aware of this fact, but no data leakage is indicated at this point. Web3js is a well maintained open source library and widely in use. Web3.eth.accounts is giving back an object containing scoped functions to sign a transaction. The object is never exposed
{
address: "0xb8CE9ab6943e0eCED004cDe8e3bBed6568B2Fa01",
privateKey: "0x348ce564d427a3311b6536bbcff9390d69395b06ed6c486954e971d960fe8709",
signTransaction: function(tx){...},
sign: function(data){...},
encrypt: function(password){...}
}
Web3js can either import private keys or generate them. Since we base the wallet on seed-phrases, another library, bip39, is used to generate the seed phrases.
https://www.npmjs.com/package/bip39
JavaScript implementation of Bitcoin BIP39: Mnemonic code for generating deterministic keys
const mnemonic = bip39.generateMnemonic()
// => 'seed sock milk update focus rotate barely fade car face mechanic mercy'
This generates a mnemonic using crypto.getRandomValues in the browser and then fetches words from an english wordlist. The wordlist is 2048 words long and the entropy generated by default is 128 bits. This gives 16 random bytes using the randombytes package.
This mnemonic is then piped through ethereumjs-utils to generate a private key.
https://www.npmjs.com/package/ethereumjs-util is a collection of utility functions for Ethereum.
The Morpher Wallet uses the hdkey functions from ethereumjs-wallet
We use it in vue/src/utils/keystore.ts to generate the private keys. Sample code:
import { hdkey } from 'ethereumjs-wallet';
function getPrivateKeyFromMnemonic(mnemonic: string, index: number) {
const seed = mnemonicToSeedSync(mnemonic);
const hdwallet = hdkey.fromMasterSeed(seed);
const walletHdPath = "m/44'/60'/0'/0/";
const wallet = hdwallet.derivePath(walletHdPath + index).getWallet();
const privateKey = wallet.getPrivateKey().toString("hex");
return privateKey;
}