@@ -1,120 +0,0 @@
1−import * as bip32 from 'bip32';
2−import * as bip39 from 'bip39';
3−import keccak from 'keccak';
4−import { reduce } from 'lodash';
5−import { Just, Nothing } from 'folktale/maybe';
6−import * as secp256k1 from 'secp256k1';
7−import * as kg from 'urbit-key-generation';
8−import { isAddress } from 'web3-utils';
9−
10−export const DEFAULT_HD_PATH = "m/44'/60'/0'/0/0";
11−export const ETH_ZERO_ADDR = '0x0000000000000000000000000000000000000000';
12−export const ETH_ZERO_ADDR_SHORT = '0x0';
13−
14−export const WALLET_TYPES = {
15− MNEMONIC: Symbol('MNEMONIC'),
16− TICKET: Symbol('TICKET'),
17− SHARDS: Symbol('SHARDS'),
18− LEDGER: Symbol('LEDGER'),
19− TREZOR: Symbol('TREZOR'),
20− PRIVATE_KEY: Symbol('PRIVATE_KEY'),
21− KEYSTORE: Symbol('KEYSTORE'),
22− METAMASK: Symbol('METAMASK'),
23−};
24−
25−export const NONCUSTODIAL_WALLETS = new Set([
26− WALLET_TYPES.METAMASK,
27− WALLET_TYPES.TREZOR,
28− WALLET_TYPES.LEDGER,
29−]);
30−
31−export function EthereumWallet(privateKey) {
32− this.privateKey = privateKey;
33− this.publicKey = secp256k1.publicKeyCreate(this.privateKey);
34− const pub = this.publicKey.toString('hex');
35− this.address = addressFromSecp256k1Public(pub);
36−}
37−
38−export const addressFromSecp256k1Public = pub => {
39− const compressed = false;
40− const uncompressed = secp256k1.publicKeyConvert(
41− Buffer.from(pub, 'hex'),
42− compressed
43− );
44− const chopped = uncompressed.slice(1); // chop parity byte
45− const hashed = keccak256(chopped);
46− const addr = addHexPrefix(hashed.slice(-20).toString('hex'));
47− return toChecksumAddress(addr);
48−};
49−
50−// TODO: move all of these generic crypto helpers to another file
51−export const addHexPrefix = hex =>
52− hex.slice(0, 2) === '0x' ? hex : '0x' + hex;
53−
54−export const stripHexPrefix = hex =>
55− hex.slice(0, 2) === '0x' ? hex.slice(2) : hex;
56−
57−export const keccak256 = str =>
58− keccak('keccak256')
59− .update(str)
60− .digest();
61−
62−export const isValidAddress = a => '0x0' === a || isAddress(a);
63−
64−export const isZeroAddress = a =>
65− a === ETH_ZERO_ADDR || a === ETH_ZERO_ADDR_SHORT;
66−
67−export const toChecksumAddress = address => {
68− const addr = stripHexPrefix(address).toLowerCase();
69− const hash = keccak256(addr).toString('hex');
70−
71− return reduce(
72− addr,
73− (acc, char, idx) =>
74− parseInt(hash[idx], 16) >= 8 ? acc + char.toUpperCase() : acc + char,
75− '0x'
76− );
77−};
78−
79−export const eqAddr = (addr0, addr1) =>
80− toChecksumAddress(addr0) === toChecksumAddress(addr1);
81−
82−export const urbitWalletFromTicket = async (ticket, point, passphrase) => {
83− return await kg.generateWallet({
84− ticket: ticket,
85− ship: point,
86− passphrase: passphrase,
87− });
88−};
89−
90−export const walletFromMnemonic = (
91− mnemonic,
92− hdpath,
93− passphrase,
94− skipMnemonicCheck
95−) => {
96− const seed =
97− skipMnemonicCheck || bip39.validateMnemonic(mnemonic)
98− ? Just(bip39.mnemonicToSeed(mnemonic, passphrase))
99− : Nothing();
100−
101− const toWallet = (sd, path) => {
102− let wal;
103− try {
104− const hd = bip32.fromSeed(sd);
105− wal = hd.derivePath(path);
106− wal.address = addressFromSecp256k1Public(wal.publicKey);
107− wal.passphrase = passphrase || '';
108− wal = Just(wal);
109− } catch (_) {
110− wal = Nothing();
111− }
112− return wal;
113− };
114−
115− const wallet = seed.chain(sd => toWallet(sd, hdpath));
116− return wallet;
117−};
118−
119−export const abbreviateAddress = address =>
120− `${address.slice(0, 6)}…${address.slice(-4)}`;