@hiveio/dhive 1.2.4 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ /// <reference types="node" />
2
+ import * as ByteBuffer from 'bytebuffer';
3
+ export declare type Deserializer = (buffer: ByteBuffer) => void;
4
+ export declare const types: {
5
+ EncryptedMemoD: (buf: Buffer | ByteBuffer) => {};
6
+ };
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ByteBuffer = require("bytebuffer");
4
+ const crypto_1 = require("../crypto");
5
+ const PublicKeyDeserializer = (buf) => {
6
+ const c = fixed_buf(buf, 33);
7
+ return crypto_1.PublicKey.fromBuffer(c);
8
+ };
9
+ const UInt64Deserializer = (b) => b.readUint64();
10
+ const UInt32Deserializer = (b) => b.readUint32();
11
+ const BinaryDeserializer = (b) => {
12
+ const len = b.readVarint32();
13
+ const b_copy = b.copy(b.offset, b.offset + len);
14
+ b.skip(len);
15
+ return Buffer.from(b_copy.toBinary(), 'binary');
16
+ };
17
+ const BufferDeserializer = (keyDeserializers) => (buf) => {
18
+ const obj = {};
19
+ for (const [key, deserializer] of keyDeserializers) {
20
+ try {
21
+ // Decodes a binary encoded string to a ByteBuffer.
22
+ buf = ByteBuffer.fromBinary(buf.toString('binary'), ByteBuffer.LITTLE_ENDIAN);
23
+ obj[key] = deserializer(buf);
24
+ }
25
+ catch (error) {
26
+ error.message = `${key}: ${error.message}`;
27
+ throw error;
28
+ }
29
+ }
30
+ return obj;
31
+ };
32
+ function fixed_buf(b, len) {
33
+ if (!b) {
34
+ throw Error('No buffer found on first parameter');
35
+ }
36
+ else {
37
+ const b_copy = b.copy(b.offset, b.offset + len);
38
+ b.skip(len);
39
+ return Buffer.from(b_copy.toBinary(), 'binary');
40
+ }
41
+ }
42
+ const EncryptedMemoDeserializer = BufferDeserializer([
43
+ ['from', PublicKeyDeserializer],
44
+ ['to', PublicKeyDeserializer],
45
+ ['nonce', UInt64Deserializer],
46
+ ['check', UInt32Deserializer],
47
+ ['encrypted', BinaryDeserializer]
48
+ ]);
49
+ exports.types = {
50
+ EncryptedMemoD: EncryptedMemoDeserializer
51
+ };
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  /**
2
3
  * @file Hive protocol serialization.
3
4
  * @author Johan Nordberg <code@johan-nordberg.com>
@@ -32,7 +33,6 @@
32
33
  * You acknowledge that this software is not designed, licensed or intended for use
33
34
  * in the design, construction, operation or maintenance of any military facility.
34
35
  */
35
- /// <reference types="node" />
36
36
  import * as ByteBuffer from 'bytebuffer';
37
37
  import { PublicKey } from '../crypto';
38
38
  import { Asset } from './asset';
@@ -48,6 +48,9 @@ export declare const Types: {
48
48
  Binary: (size?: number | undefined) => (buffer: ByteBuffer, data: Buffer | HexBuffer) => void;
49
49
  Boolean: (buffer: ByteBuffer, data: boolean) => void;
50
50
  Date: (buffer: ByteBuffer, data: string) => void;
51
+ EncryptedMemo: (buffer: ByteBuffer, data: {
52
+ [key: string]: any;
53
+ }) => void;
51
54
  FlatMap: (keySerializer: Serializer, valueSerializer: Serializer) => (buffer: ByteBuffer, data: [any, any][]) => void;
52
55
  Int16: (buffer: ByteBuffer, data: number) => void;
53
56
  Int32: (buffer: ByteBuffer, data: number) => void;
@@ -71,5 +74,5 @@ export declare const Types: {
71
74
  UInt32: (buffer: ByteBuffer, data: number) => void;
72
75
  UInt64: (buffer: ByteBuffer, data: number) => void;
73
76
  UInt8: (buffer: ByteBuffer, data: number) => void;
74
- Void: (buffer: ByteBuffer) => never;
77
+ Void: () => never;
75
78
  };
@@ -1,43 +1,9 @@
1
1
  "use strict";
2
- /**
3
- * @file Hive protocol serialization.
4
- * @author Johan Nordberg <code@johan-nordberg.com>
5
- * @license
6
- * Copyright (c) 2017 Johan Nordberg. All Rights Reserved.
7
- *
8
- * Redistribution and use in source and binary forms, with or without modification,
9
- * are permitted provided that the following conditions are met:
10
- *
11
- * 1. Redistribution of source code must retain the above copyright notice, this
12
- * list of conditions and the following disclaimer.
13
- *
14
- * 2. Redistribution in binary form must reproduce the above copyright notice,
15
- * this list of conditions and the following disclaimer in the documentation
16
- * and/or other materials provided with the distribution.
17
- *
18
- * 3. Neither the name of the copyright holder nor the names of its contributors
19
- * may be used to endorse or promote products derived from this software without
20
- * specific prior written permission.
21
- *
22
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
26
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31
- * OF THE POSSIBILITY OF SUCH DAMAGE.
32
- *
33
- * You acknowledge that this software is not designed, licensed or intended for use
34
- * in the design, construction, operation or maintenance of any military facility.
35
- */
36
2
  Object.defineProperty(exports, "__esModule", { value: true });
37
3
  const crypto_1 = require("../crypto");
38
4
  const asset_1 = require("./asset");
39
5
  const misc_1 = require("./misc");
40
- const VoidSerializer = (buffer) => {
6
+ const VoidSerializer = () => {
41
7
  throw new Error('Void can not be serialized');
42
8
  };
43
9
  const StringSerializer = (buffer, data) => {
@@ -178,6 +144,13 @@ const ChainPropertiesSerializer = ObjectSerializer([
178
144
  ['maximum_block_size', UInt32Serializer],
179
145
  ['hbd_interest_rate', UInt16Serializer]
180
146
  ]);
147
+ const EncryptedMemoSerializer = ObjectSerializer([
148
+ ['from', PublicKeySerializer],
149
+ ['to', PublicKeySerializer],
150
+ ['nonce', UInt64Serializer],
151
+ ['check', UInt32Serializer],
152
+ ['encrypted', BinarySerializer()]
153
+ ]);
181
154
  const OperationDataSerializer = (operationId, definitions) => {
182
155
  const objectSerializer = ObjectSerializer(definitions);
183
156
  return (buffer, data) => {
@@ -537,6 +510,7 @@ exports.Types = {
537
510
  Binary: BinarySerializer,
538
511
  Boolean: BooleanSerializer,
539
512
  Date: DateSerializer,
513
+ EncryptedMemo: EncryptedMemoSerializer,
540
514
  FlatMap: FlatMapSerializer,
541
515
  Int16: Int16Serializer,
542
516
  Int32: Int32Serializer,
package/lib/client.d.ts CHANGED
@@ -154,11 +154,11 @@ export declare class Client {
154
154
  * Address prefix for current network.
155
155
  */
156
156
  readonly addressPrefix: string;
157
+ currentAddress: string;
157
158
  private timeout;
158
159
  private backoff;
159
160
  private failoverThreshold;
160
161
  private consoleOnFailover;
161
- currentAddress: string;
162
162
  /**
163
163
  * @param address The address to the Hive RPC server,
164
164
  * e.g. `https://api.hive.blog`. or [`https://api.hive.blog`, `https://another.api.com`]
package/lib/crypto.d.ts CHANGED
@@ -33,6 +33,7 @@
33
33
  * in the design, construction, operation or maintenance of any military facility.
34
34
  */
35
35
  /// <reference types="node" />
36
+ import * as ByteBuffer from 'bytebuffer';
36
37
  import { SignedTransaction, Transaction } from './chain/transaction';
37
38
  /**
38
39
  * Network id used in WIF-encoding.
@@ -74,9 +75,13 @@ declare function isWif(privWif: string | Buffer): boolean;
74
75
  * ECDSA (secp256k1) public key.
75
76
  */
76
77
  export declare class PublicKey {
77
- readonly key: Buffer;
78
+ readonly key: any;
78
79
  readonly prefix: string;
79
- constructor(key: Buffer, prefix?: string);
80
+ readonly uncompressed: Buffer;
81
+ constructor(key: any, prefix?: string);
82
+ static fromBuffer(key: ByteBuffer): {
83
+ key: ByteBuffer;
84
+ };
80
85
  /**
81
86
  * Create a new instance from a WIF-encoded key.
82
87
  */
@@ -110,6 +115,7 @@ export declare type KeyRole = 'owner' | 'active' | 'posting' | 'memo';
110
115
  */
111
116
  export declare class PrivateKey {
112
117
  private key;
118
+ secret: Buffer;
113
119
  constructor(key: Buffer);
114
120
  /**
115
121
  * Convenience to create a new instance from WIF string or buffer.
@@ -127,6 +133,7 @@ export declare class PrivateKey {
127
133
  * Create key from username and password.
128
134
  */
129
135
  static fromLogin(username: string, password: string, role?: KeyRole): PrivateKey;
136
+ multiply(pub: any): Buffer;
130
137
  /**
131
138
  * Sign message.
132
139
  * @param message 32-byte message.
@@ -145,6 +152,10 @@ export declare class PrivateKey {
145
152
  * to get the full encoded key you need to explicitly call {@link toString}.
146
153
  */
147
154
  inspect(): string;
155
+ /**
156
+ * Get shared secret for memo cryptography
157
+ */
158
+ get_shared_secret(public_key: PublicKey): Buffer;
148
159
  }
149
160
  /**
150
161
  * ECDSA (secp256k1) signature.
package/lib/crypto.js CHANGED
@@ -35,15 +35,21 @@
35
35
  */
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
37
  const assert = require("assert");
38
+ const bigInteger = require("bigi");
38
39
  const bs58 = require("bs58");
39
40
  const ByteBuffer = require("bytebuffer");
40
41
  const crypto_1 = require("crypto");
42
+ const ecurve = require("ecurve");
41
43
  const Ripemd160 = require("ripemd160");
42
44
  const secp256k1 = require("secp256k1");
43
45
  const verror_1 = require("verror");
44
46
  const serializer_1 = require("./chain/serializer");
45
47
  const client_1 = require("./client");
46
48
  const utils_1 = require("./utils");
49
+ /**
50
+ * secp256k1 ecurve
51
+ */
52
+ const secp256k1Curve = ecurve.getCurveByName('secp256k1');
47
53
  /**
48
54
  * Network id used in WIF-encoding.
49
55
  */
@@ -64,6 +70,14 @@ function sha256(input) {
64
70
  .update(input)
65
71
  .digest();
66
72
  }
73
+ /**
74
+ * Return sha512 hash of input
75
+ */
76
+ function sha512(input) {
77
+ return crypto_1.createHash('sha512')
78
+ .update(input)
79
+ .digest();
80
+ }
67
81
  /**
68
82
  * Return 2-round sha256 hash of input.
69
83
  */
@@ -145,6 +159,11 @@ class PublicKey {
145
159
  this.key = key;
146
160
  this.prefix = prefix;
147
161
  assert(secp256k1.publicKeyVerify(key), 'invalid public key');
162
+ this.uncompressed = Buffer.from(secp256k1.publicKeyConvert(key, false));
163
+ }
164
+ static fromBuffer(key) {
165
+ assert(secp256k1.publicKeyVerify(key), 'invalid buffer as public key');
166
+ return { key };
148
167
  }
149
168
  /**
150
169
  * Create a new instance from a WIF-encoded key.
@@ -230,6 +249,9 @@ class PrivateKey {
230
249
  const seed = username + role + password;
231
250
  return PrivateKey.fromSeed(seed);
232
251
  }
252
+ multiply(pub) {
253
+ return Buffer.from(secp256k1.publicKeyTweakMul(pub.key, this.secret, false));
254
+ }
233
255
  /**
234
256
  * Sign message.
235
257
  * @param message 32-byte message.
@@ -265,6 +287,15 @@ class PrivateKey {
265
287
  const key = this.toString();
266
288
  return `PrivateKey: ${key.slice(0, 6)}...${key.slice(-6)}`;
267
289
  }
290
+ /**
291
+ * Get shared secret for memo cryptography
292
+ */
293
+ get_shared_secret(public_key) {
294
+ const KBP = ecurve.Point.fromAffine(secp256k1Curve, bigInteger.fromBuffer(public_key.uncompressed.slice(1, 33)), bigInteger.fromBuffer(public_key.uncompressed.slice(33, 65)));
295
+ const P = KBP.multiply(bigInteger.fromBuffer(this.key));
296
+ const S = P.affineX.toBuffer({ size: 32 });
297
+ return sha512(S);
298
+ }
268
299
  }
269
300
  exports.PrivateKey = PrivateKey;
270
301
  /**
@@ -0,0 +1,26 @@
1
+ import { PrivateKey, PublicKey } from '../crypto';
2
+ /**
3
+ * Spec: http://peakd.com/steem/@dantheman/how-to-encrypt-a-memo-when-transferring-steem
4
+ * @throws {Error|TypeError} - "Invalid Key, ..."
5
+ * @param {PrivateKey} private_key - required and used for decryption
6
+ * @param {PublicKey} public_key - required and used to calcualte the shared secret
7
+ * @param message - message to be encrypted
8
+ * @param {string} [nonce = uniqueNonce()] - assigned a random unique uint64
9
+ *
10
+ * @return {object}
11
+ * @property {string} nonce - random or unique uint64, provides entropy when re-using the same private/public keys.
12
+ * @property {Buffer} message - Plain text message
13
+ * @property {number} checksum - shared secret checksum
14
+ */
15
+ export declare function encrypt(private_key: PrivateKey, public_key: PublicKey, message: any, nonce: any): any;
16
+ /**
17
+ * Spec: http://peakd.com/steem/@dantheman/how-to-encrypt-a-memo-when-transferring-steem
18
+ * @arg {PrivateKey} private_key - required and used for decryption
19
+ * @arg {PublicKey} public_key - required and used to calcualte the shared secret
20
+ * @arg {string} nonce - random or unique uint64, provides entropy when re-using the same private/public keys.
21
+ * @arg {Buffer} message - Encrypted or plain text message
22
+ * @arg {number} checksum - shared secret checksum
23
+ * @throws {Error|TypeError} - "Invalid Key, ..."
24
+ * @return {Buffer} - message
25
+ */
26
+ export declare function decrypt(private_key: PrivateKey, public_key: PublicKey, nonce: any, message: any, checksum: number): string;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const assert = require("assert");
4
+ const crypto_1 = require("crypto");
5
+ const ByteBuffer = require('bytebuffer');
6
+ const Long = ByteBuffer.Long;
7
+ /**
8
+ * Spec: http://peakd.com/steem/@dantheman/how-to-encrypt-a-memo-when-transferring-steem
9
+ * @throws {Error|TypeError} - "Invalid Key, ..."
10
+ * @param {PrivateKey} private_key - required and used for decryption
11
+ * @param {PublicKey} public_key - required and used to calcualte the shared secret
12
+ * @param message - message to be encrypted
13
+ * @param {string} [nonce = uniqueNonce()] - assigned a random unique uint64
14
+ *
15
+ * @return {object}
16
+ * @property {string} nonce - random or unique uint64, provides entropy when re-using the same private/public keys.
17
+ * @property {Buffer} message - Plain text message
18
+ * @property {number} checksum - shared secret checksum
19
+ */
20
+ function encrypt(private_key, public_key, message, nonce) {
21
+ // Change message to varint32 prefixed encoded string
22
+ const mbuf = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
23
+ mbuf.writeVString(message);
24
+ message = Buffer.from(mbuf.flip().toBinary());
25
+ return crypt(private_key, public_key, uniqueNonce(), message);
26
+ }
27
+ exports.encrypt = encrypt;
28
+ /**
29
+ * Spec: http://peakd.com/steem/@dantheman/how-to-encrypt-a-memo-when-transferring-steem
30
+ * @arg {PrivateKey} private_key - required and used for decryption
31
+ * @arg {PublicKey} public_key - required and used to calcualte the shared secret
32
+ * @arg {string} nonce - random or unique uint64, provides entropy when re-using the same private/public keys.
33
+ * @arg {Buffer} message - Encrypted or plain text message
34
+ * @arg {number} checksum - shared secret checksum
35
+ * @throws {Error|TypeError} - "Invalid Key, ..."
36
+ * @return {Buffer} - message
37
+ */
38
+ function decrypt(private_key, public_key, nonce, message, checksum) {
39
+ return crypt(private_key, public_key, nonce, message, checksum).message;
40
+ }
41
+ exports.decrypt = decrypt;
42
+ /**
43
+ * @arg {Buffer} message - Encrypted or plain text message (see checksum)
44
+ * @arg {number} checksum - shared secret checksum (null to encrypt, non-null to decrypt)
45
+ */
46
+ function crypt(private_key, public_key, nonce, message, checksum) {
47
+ nonce = toLongObj(nonce);
48
+ // Appending nonce to buffer "ebuf" and rehash with sha512
49
+ const S = private_key.get_shared_secret(public_key);
50
+ let ebuf = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
51
+ ebuf.writeUint64(nonce);
52
+ ebuf.append(S.toString('binary'), 'binary');
53
+ ebuf = Buffer.from(ebuf.copy(0, ebuf.offset).toBinary(), 'binary');
54
+ const encryption_key = crypto_1.createHash('sha512').update(ebuf).digest();
55
+ const iv = encryption_key.slice(32, 48);
56
+ const tag = encryption_key.slice(0, 32);
57
+ // check if first 64 bit of sha256 hash treated as uint64_t truncated to 32 bits.
58
+ let check = crypto_1.createHash('sha256').update(encryption_key).digest();
59
+ check = check.slice(0, 4);
60
+ const cbuf = ByteBuffer.fromBinary(check.toString('binary'), ByteBuffer.LITTLE_ENDIAN);
61
+ check = cbuf.readUint32();
62
+ if (checksum) {
63
+ if (check !== checksum) {
64
+ throw new Error('Invalid nonce');
65
+ }
66
+ message = cryptoJsDecrypt(message, tag, iv);
67
+ }
68
+ else {
69
+ message = cryptoJsEncrypt(message, tag, iv);
70
+ }
71
+ return { nonce, message, checksum: check };
72
+ }
73
+ /**
74
+ * This method does not use a checksum, the returned data must be validated some other way.
75
+ * @arg {string|Buffer} ciphertext - binary format
76
+ * @return {Buffer} the decrypted message
77
+ */
78
+ function cryptoJsDecrypt(message, tag, iv) {
79
+ assert(message, 'Missing cipher text');
80
+ message = toBinaryBuffer(message);
81
+ const decipher = crypto_1.createDecipheriv('aes-256-cbc', tag, iv);
82
+ message = Buffer.concat([decipher.update(message), decipher.final()]);
83
+ return message;
84
+ }
85
+ /**
86
+ * This method does not use a checksum, the returned data must be validated some other way.
87
+ * @arg {string|Buffer} plaintext - binary format
88
+ * @return {Buffer} binary
89
+ */
90
+ function cryptoJsEncrypt(message, tag, iv) {
91
+ assert(message, 'Missing plain text');
92
+ message = toBinaryBuffer(message);
93
+ const cipher = crypto_1.createCipheriv('aes-256-cbc', tag, iv);
94
+ message = Buffer.concat([cipher.update(message), cipher.final()]);
95
+ return message;
96
+ }
97
+ /** @return {string} unique 64 bit unsigned number string. Being time based,
98
+ * this is careful to never choose the same nonce twice. This value could
99
+ * clsbe recorded in the blockchain for a long time.
100
+ */
101
+ let unique_nonce_entropy = null;
102
+ function uniqueNonce() {
103
+ if (unique_nonce_entropy === null) {
104
+ const uint8randomArr = new Uint8Array(2);
105
+ for (let i = 0; i < 2; ++i) {
106
+ uint8randomArr[i] = crypto_1.randomBytes(2).readUInt8(i);
107
+ }
108
+ unique_nonce_entropy = uint8randomArr[0] << 8 | uint8randomArr[1];
109
+ }
110
+ let long = Long.fromNumber(Date.now());
111
+ const entropy = ++unique_nonce_entropy % 0xFFFF;
112
+ long = long.shiftLeft(16).or(Long.fromNumber(entropy));
113
+ return long.toString();
114
+ }
115
+ const toLongObj = o => (o ? Long.isLong(o) ? o : Long.fromString(o) : o);
116
+ const toBinaryBuffer = o => (o ? Buffer.isBuffer(o) ? o : Buffer.from(o, 'binary') : o);
package/lib/index.d.ts CHANGED
@@ -46,6 +46,9 @@ export * from './chain/comment';
46
46
  export * from './chain/misc';
47
47
  export * from './chain/operation';
48
48
  export * from './chain/serializer';
49
+ export * from './chain/deserializer';
49
50
  export * from './chain/transaction';
51
+ export * from './chain/hivemind';
50
52
  export * from './client';
51
53
  export * from './crypto';
54
+ export * from './memo';
package/lib/index.js CHANGED
@@ -48,5 +48,7 @@ __export(require("./chain/account"));
48
48
  __export(require("./chain/asset"));
49
49
  __export(require("./chain/misc"));
50
50
  __export(require("./chain/serializer"));
51
+ __export(require("./chain/deserializer"));
51
52
  __export(require("./client"));
52
53
  __export(require("./crypto"));
54
+ __export(require("./memo"));
package/lib/memo.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { PrivateKey, PublicKey } from './crypto';
2
+ /**
3
+ * Memo/Any message encoding using AES (aes-cbc algorithm)
4
+ * @param {Buffer|String} private_key Privatekey of sender
5
+ * @param {Buffer|String}public_key publickey of recipient
6
+ * @param {String}memo message to be encrypted
7
+ * @param {Number}testNonce nonce with high entropy
8
+ */
9
+ declare function encode(private_key: PrivateKey | string, public_key: PublicKey | string, memo: string, testNonce?: number): string;
10
+ /**
11
+ * Encrypted memo/message decryption
12
+ * @param {Buffer|string}private_key Privatekey of recipient
13
+ * @param {any}memo Encrypted message/memo
14
+ */
15
+ declare function decode(private_key: PrivateKey | string, memo: any): any;
16
+ export declare const Memo: {
17
+ decode: typeof decode;
18
+ encode: typeof encode;
19
+ };
20
+ export {};
package/lib/memo.js ADDED
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const bs58 = require("bs58");
4
+ const ByteBuffer = require("bytebuffer");
5
+ const deserializer_1 = require("./chain/deserializer");
6
+ const serializer_1 = require("./chain/serializer");
7
+ const crypto_1 = require("./crypto");
8
+ const Aes = require("./helpers/aes");
9
+ /**
10
+ * Memo/Any message encoding using AES (aes-cbc algorithm)
11
+ * @param {Buffer|String} private_key Privatekey of sender
12
+ * @param {Buffer|String}public_key publickey of recipient
13
+ * @param {String}memo message to be encrypted
14
+ * @param {Number}testNonce nonce with high entropy
15
+ */
16
+ function encode(private_key, public_key, memo, testNonce) {
17
+ if (!memo.startsWith('#')) {
18
+ return memo;
19
+ }
20
+ memo = memo.substring(1);
21
+ private_key = toPrivateObj(private_key);
22
+ public_key = toPublicObj(public_key);
23
+ const { nonce, message, checksum } = Aes.encrypt(private_key, public_key, memo, testNonce);
24
+ const mbuf = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
25
+ serializer_1.Types.EncryptedMemo(mbuf, {
26
+ check: checksum,
27
+ encrypted: message,
28
+ from: private_key.createPublic(),
29
+ nonce,
30
+ to: public_key
31
+ });
32
+ mbuf.flip();
33
+ const data = Buffer.from(mbuf.toBuffer());
34
+ return '#' + bs58.encode(data);
35
+ }
36
+ /**
37
+ * Encrypted memo/message decryption
38
+ * @param {Buffer|string}private_key Privatekey of recipient
39
+ * @param {any}memo Encrypted message/memo
40
+ */
41
+ function decode(private_key, memo) {
42
+ if (!memo.startsWith('#')) {
43
+ return memo;
44
+ }
45
+ memo = memo.substring(1);
46
+ // checkEncryption()
47
+ private_key = toPrivateObj(private_key);
48
+ memo = bs58.decode(memo);
49
+ memo = deserializer_1.types.EncryptedMemoD(Buffer.from(memo, 'binary'));
50
+ const { from, to, nonce, check, encrypted } = memo;
51
+ const pubkey = private_key.createPublic().toString();
52
+ const otherpub = pubkey === new crypto_1.PublicKey(from.key).toString() ? new crypto_1.PublicKey(to.key) : new crypto_1.PublicKey(from.key);
53
+ memo = Aes.decrypt(private_key, otherpub, nonce, encrypted, check);
54
+ // remove varint length prefix
55
+ const mbuf = ByteBuffer.fromBinary(memo.toString('binary'), ByteBuffer.LITTLE_ENDIAN);
56
+ try {
57
+ mbuf.mark();
58
+ return '#' + mbuf.readVString();
59
+ }
60
+ catch (e) {
61
+ mbuf.reset();
62
+ // Sender did not length-prefix the memo
63
+ memo = Buffer.from(mbuf.toString('binary'), 'binary').toString('utf-8');
64
+ return '#' + memo;
65
+ }
66
+ }
67
+ const toPrivateObj = (o) => (o ? o.key ? o : crypto_1.PrivateKey.fromString(o) : o /* null or undefined*/);
68
+ const toPublicObj = (o) => (o ? o.key ? o : crypto_1.PublicKey.fromString(o) : o /* null or undefined*/);
69
+ exports.Memo = {
70
+ decode,
71
+ encode
72
+ };
package/lib/utils.d.ts CHANGED
@@ -71,7 +71,7 @@ export interface WitnessProps {
71
71
  hbd_interest_rate?: number;
72
72
  url?: string;
73
73
  }
74
- export declare function buildWitnessUpdateOp(owner: string, props: WitnessProps): WitnessSetPropertiesOperation;
74
+ export declare const buildWitnessUpdateOp: (owner: string, props: WitnessProps) => WitnessSetPropertiesOperation;
75
75
  export declare const operationOrders: {
76
76
  vote: number;
77
77
  comment: number;
package/lib/utils.js CHANGED
@@ -182,15 +182,15 @@ const failover = (url, urls, currentAddress, consoleOnFailover) => {
182
182
  // Can hopefully be removed when hived's JSON representation is fixed
183
183
  const ByteBuffer = require("bytebuffer");
184
184
  const serializer_1 = require("./chain/serializer");
185
- function serialize(serializer, data) {
185
+ const serialize = (serializer, data) => {
186
186
  const buffer = new ByteBuffer(ByteBuffer.DEFAULT_CAPACITY, ByteBuffer.LITTLE_ENDIAN);
187
187
  serializer(buffer, data);
188
188
  buffer.flip();
189
189
  // `props` values must be hex
190
190
  return buffer.toString('hex');
191
191
  // return Buffer.from(buffer.toBuffer());
192
- }
193
- function buildWitnessUpdateOp(owner, props) {
192
+ };
193
+ exports.buildWitnessUpdateOp = (owner, props) => {
194
194
  const data = {
195
195
  extensions: [],
196
196
  owner,
@@ -227,8 +227,7 @@ function buildWitnessUpdateOp(owner, props) {
227
227
  }
228
228
  data.props.sort((a, b) => a[0].localeCompare(b[0]));
229
229
  return ['witness_set_properties', data];
230
- }
231
- exports.buildWitnessUpdateOp = buildWitnessUpdateOp;
230
+ };
232
231
  const JSBI = require('jsbi');
233
232
  exports.operationOrders = {
234
233
  vote: 0,
package/lib/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = '1.2.3';
3
+ exports.default = '1.2.5';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hiveio/dhive",
3
- "version": "1.2.4",
3
+ "version": "1.2.5",
4
4
  "description": "Hive blockchain RPC client library",
5
5
  "author": "hive-network",
6
6
  "license": "BSD-3-Clause-No-Military-License",
@@ -32,10 +32,12 @@
32
32
  "dhive"
33
33
  ],
34
34
  "dependencies": {
35
+ "bigi": "^1.4.2",
35
36
  "bs58": "^4.0.1",
36
37
  "bytebuffer": "^5.0.1",
37
38
  "core-js": "^3.6.4",
38
39
  "cross-fetch": "^3.0.4",
40
+ "ecurve": "^1.0.6",
39
41
  "https": "^1.0.0",
40
42
  "jsbi": "^3.1.4",
41
43
  "node-fetch": "^2.6.0",