@faast/ethereum-payments
Version:
Library to assist in processing ethereum payments, such as deriving addresses and sweeping funds
101 lines (84 loc) • 2.54 kB
text/typescript
import Web3 from 'web3'
const web3 = new Web3()
import { EthereumSignatory } from './types'
import { pubToAddress } from 'ethereumjs-util'
import { fromBase58, fromSeed } from 'bip32'
import crypto from 'crypto'
import { ec as EC } from 'elliptic'
const ec = new EC('secp256k1')
class EthereumBIP44 {
static fromExtKey(xkey: string) {
if (['xprv', 'xpub'].includes(xkey.substring(0, 4))) {
return new EthereumBIP44(fromBase58(xkey))
}
throw new Error('Not extended key')
}
private parts: string[]
key: any
constructor(hdKey: any) {
this.parts = [
'm',
"44'", // bip 44
"60'", // coin
"0'", // wallet
'0' // 0 - public, 1 = private
// index
]
this.key = hdKey
}
getAddress(index?: number): string {
const derived = this.deriveByIndex(index)
let address = pubToAddress(derived.publicKey, true)
return web3.utils.toChecksumAddress(`0x${address.toString('hex')}`).toLowerCase()
}
getPrivateKey(index?: number): string {
const derived = this.deriveByIndex(index)
if (!derived.privateKey) {
return ''
}
return `0x${derived.privateKey.toString('hex')}`
}
getPublicKey(index?: number): string {
return this.deriveByIndex(index).publicKey.toString('hex')
}
getXPrivateKey(index?: number): string {
const key = this.deriveByIndex(index).toBase58()
return key.substring(0, 4) === 'xpub' ? '' : key
}
getXPublicKey(index?: number) {
return this.deriveByIndex(index).neutered().toBase58()
}
private deriveByIndex(index?: number) {
if (typeof index === 'undefined') {
return this.key
}
const path = this.parts.slice(this.key.depth)
const keyPath = path.length > 0 ? path.join('/') + '/' : ''
return this.key.derivePath(`${keyPath}${index.toString()}`)
}
}
// XXX if index is not provided, derived key will be hardened
export function deriveSignatory(xkey?: string, index?: number): EthereumSignatory {
const wallet = xkey ?
EthereumBIP44.fromExtKey(xkey) :
EthereumBIP44.fromExtKey(fromSeed(crypto.randomBytes(32)).toBase58())
return {
address: wallet.getAddress(index),
keys: {
prv: wallet.getPrivateKey(index) || '',
pub: wallet.getPublicKey(index),
},
xkeys: {
xprv: wallet.getXPrivateKey(index) || '',
xpub: wallet.getXPublicKey(index),
}
}
}
export function isValidXkey(key: string): boolean {
try {
EthereumBIP44.fromExtKey(key)
return true
} catch (e) {
return false
}
}