1 | require = require('esm')(module);
|
2 | import format from './util/format';
|
3 | import { randomPrivateKey, privateKeyToAddress, privateKeyToPublicKey } from './util/sign'; // and decrypt, encrypt
|
4 | import Transaction from './Transaction';
|
5 | import Message from './Message';
|
6 |
|
7 | export default class Account {
|
8 | /**
|
9 | * Create a new Account with random privateKey.
|
10 | *
|
11 | * @param entropy
|
12 | * @return {Account}
|
13 | *
|
14 | * @example
|
15 | * > Account.random()
|
16 | Account {
|
17 | privateKey: '0xd28edbdb7bbe75787b84c5f525f47666a3274bb06561581f00839645f3c26f66',
|
18 | publicKey: '0xc42b53ae2ef95fee489948d33df391c4a9da31b7a3e29cf772c24eb42f74e94ab3bfe00bf29a239c17786a5b921853b7c5344d36694db43aa849e401f91566a5',
|
19 | address: '0x1cecb4a2922b7007e236daf0c797de6e55496e84'
|
20 | }
|
21 | * > Account.random() // gen a different account from above
|
22 | Account {
|
23 | privateKey: '0x1b67150f56f49556ef7e3899024d83c125d84990d311ec08fa98aa1433bc0f53',
|
24 | publicKey: '0xd442207828ffd4dad918fea0d75d42dbea1fe5e3789c00a82e18ce8229714eae3f70b12f2f1abd795ad3e5c52a5a597289eb5096548438c233431f498b47b9a6',
|
25 | address: '0x16c25691aadc3363f5862d264072584f3ebf4613'
|
26 | }
|
27 | * > Account.random('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
28 | Account {
|
29 | privateKey: '0x1d41e006afd28ea339922d8ab4be93154a14d4f1b6d0ad4e7aabf807e7536a5f',
|
30 | publicKey: '0x4c07c75d3fdc5b1d6afef6ec374b0eaac86bcaa771a1d536bc4ce6f111b1c60e414b370e4cf31bf7770ae6818a3518c485398a43857d9053153f6eb4f5644a90',
|
31 | address: '0x113d49784c80d6f8fdbc0bef5a5ab0d9c9fee520'
|
32 | }
|
33 | * > Account.random('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
34 | * // gen a different account from above, even use same entropy
|
35 | Account {
|
36 | privateKey: '0x5a34ff3318674c33209ce856218890e9a6ee3811e8a51e3094ed1e6a94bf58ef',
|
37 | publicKey: '0xe530d77c3ed6115cb46ba79821085bf67d2a7a8c808c1d52dec03fd7a82e569c2136dba84b21d40f46d90484722b21a9d5a8038495adf93f2eed564ababa2422',
|
38 | address: '0x1f63fcef4aaa88c03cbb5c9fb34be69dee65d0a8'
|
39 | }
|
40 | */
|
41 | static random(entropy) {
|
42 | const privateKeyBuffer = randomPrivateKey(entropy !== undefined ? format.buffer(entropy) : undefined);
|
43 | return new this(privateKeyBuffer);
|
44 | }
|
45 |
|
46 | /**
|
47 | * Create a account by privateKey.
|
48 | *
|
49 | * @param privateKey {string|Buffer}
|
50 | * @return {Account}
|
51 | */
|
52 | constructor(privateKey) {
|
53 | this.privateKey = format.privateKey(privateKey);
|
54 | this.publicKey = format.publicKey(privateKeyToPublicKey(format.buffer(privateKey)));
|
55 | this.address = format.address(privateKeyToAddress(format.buffer(privateKey)));
|
56 | }
|
57 |
|
58 | // /**
|
59 | // * Decrypt account encrypt info.
|
60 | // *
|
61 | // * @param info {object}
|
62 | // * @param password {string}
|
63 | // * @return {Account}
|
64 | // */
|
65 | // static decrypt(info, password) {
|
66 | // const privateKeyBuffer = decrypt(lodash.mapValues(info, format.buffer), Buffer.from(password));
|
67 | // return new this(privateKeyBuffer);
|
68 | // }
|
69 | //
|
70 | // /**
|
71 | // * Encrypt account privateKey to object.
|
72 | // *
|
73 | // * @param password {string}
|
74 | // * @return {object}
|
75 | // */
|
76 | // encrypt(password) {
|
77 | // const info = encrypt(format.buffer(this.privateKey), Buffer.from(password));
|
78 | // return lodash.mapValues(info, format.hex);
|
79 | // }
|
80 |
|
81 | /**
|
82 | * Sign a transaction.
|
83 | *
|
84 | * @param options {object} - See 'Transaction'
|
85 | * @return {Transaction}
|
86 | */
|
87 | signTransaction(options) {
|
88 | const tx = new Transaction(options);
|
89 | tx.sign(this.privateKey); // sign will cover r,s,v fields
|
90 | if (tx.from !== this.address) {
|
91 | throw new Error(`Invalid signature, transaction.from !== ${this.address}`);
|
92 | }
|
93 | return tx;
|
94 | }
|
95 |
|
96 | /**
|
97 | * Sign a string.
|
98 | *
|
99 | * @param message {string}
|
100 | * @return {Message}
|
101 | *
|
102 | * @example
|
103 | * > const account = new Account('0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef')
|
104 | * > const msg = account.signMessage('Hello World!')
|
105 | * > console.log(msg);
|
106 | Message {
|
107 | message: 'Hello World',
|
108 | signature: '0x6e913e2b76459f19ebd269b82b51a70e912e909b2f5c002312efc27bcc280f3c29134d382aad0dbd3f0ccc9f0eb8f1dbe3f90141d81574ebb6504156b0d7b95f01'
|
109 | }
|
110 | */
|
111 | signMessage(message) {
|
112 | const msg = new Message(message);
|
113 | msg.sign(this.privateKey); // sign will cover r,s,v fields
|
114 | if (msg.from !== this.address) {
|
115 | throw new Error(`Invalid signature, message.from !== ${this.address}`);
|
116 | }
|
117 | return msg;
|
118 | }
|
119 |
|
120 | /**
|
121 | * @return {string} Account address as string.
|
122 | */
|
123 | toString() {
|
124 | return this.address;
|
125 | }
|
126 | }
|