This repository has been archived by the owner on Feb 21, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 21
/
index.js
109 lines (102 loc) · 3.31 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/* @flow */
import {
derivationPathSerializer,
userInputValidator,
} from '@colony/purser-core/helpers';
import { PATH, CHAIN_IDS } from '@colony/purser-core/defaults';
import type { WalletArgumentsType } from '@colony/purser-core/flowtypes';
import LedgerWallet from './class';
import { ledgerConnection, handleLedgerConnectionError } from './helpers';
import { staticMethods as messages } from './messages';
import type { LedgerInstanceType } from './flowtypes';
/**
* Open a new wallet from the public key and chain code, which are received
* form the Ledger device (after unlocking it and entering the Ethereum app)
*
* @method open
*
* @param {number} addressCount the number of extra addresses to generate from the derivation path
* @param {number} chainId The id of the network to use, defaults to mainnet (1)
*
* The above param is sent in as a prop of an {WalletArgumentsType} object.
*
* @return {WalletType} The wallet object resulted by instantiating the class
* (Object is wrapped in a promise).
*
*/
export const open = async (
argumentObject: WalletArgumentsType = {},
): Promise<LedgerWallet | void> => {
/*
* Validate the trasaction's object input
*/
userInputValidator({
firstArgument: argumentObject,
});
const { addressCount, chainId = CHAIN_IDS.HOMESTEAD } = argumentObject;
/*
* @TODO Reduce code repetition
* By moving this inside a helper. This same patter will be used on the
* trezor wallet as well.
*
* If we're on a testnet set the coin type id to `1`
* This will be used in the derivation path
*/
const coinType: number =
chainId === CHAIN_IDS.HOMESTEAD ? PATH.COIN_MAINNET : PATH.COIN_TESTNET;
/*
* Get to root derivation path based on the coin type.
*
* Based on this, we will then derive all the needed address indexes
* (inside the class constructor)
*/
const rootDerivationPath: string = derivationPathSerializer({
coinType,
});
try {
const ledger: LedgerInstanceType = await ledgerConnection();
/*
* Get the harware wallet's root public key and chain code, to use
* for deriving the rest of the accounts
*/
const { publicKey, chainCode } = await ledger.getAddress(
/*
* @NOTE Ledger requires a derivation path containing only the account value
* No change and index
*
* If you want to prompt the user on the device, set the second argument
* as true.
*/
rootDerivationPath,
false,
true,
);
const walletInstance: LedgerWallet = new LedgerWallet({
publicKey,
chainCode,
/*
* Since we need to strip out the change values when opening the Ledger
* wallet, we need to remove the post-pending slash. This way, the final
* derivation path gets concatenated correctly.
*
* The only alternative would be to re-generate the derivation path inside
* the class's constructor, but that would mean extra computational resources.
*/
rootDerivationPath,
addressCount,
chainId,
});
return walletInstance;
} catch (caughtError) {
return handleLedgerConnectionError(
caughtError,
`${messages.userExportGenericError}: ${rootDerivationPath} ${
caughtError.message
}`,
);
}
};
const ledgerWallet: Object = {
open,
};
export default ledgerWallet;