@ukeyfe/hardware-transport 1.1.13
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.
- package/.eslintrc +24 -0
- package/README.md +29 -0
- package/__tests__/build-receive.test.js +117 -0
- package/__tests__/decode-features.test.js +72 -0
- package/__tests__/encode-decode-basic.test.js +272 -0
- package/__tests__/encode-decode.test.js +532 -0
- package/__tests__/messages.test.js +86 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/index.d.ts +5203 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +942 -0
- package/dist/serialization/index.d.ts +6 -0
- package/dist/serialization/index.d.ts.map +1 -0
- package/dist/serialization/protobuf/decode.d.ts +6 -0
- package/dist/serialization/protobuf/decode.d.ts.map +1 -0
- package/dist/serialization/protobuf/encode.d.ts +5 -0
- package/dist/serialization/protobuf/encode.d.ts.map +1 -0
- package/dist/serialization/protobuf/index.d.ts +4 -0
- package/dist/serialization/protobuf/index.d.ts.map +1 -0
- package/dist/serialization/protobuf/messages.d.ts +11 -0
- package/dist/serialization/protobuf/messages.d.ts.map +1 -0
- package/dist/serialization/protocol/decode.d.ts +11 -0
- package/dist/serialization/protocol/decode.d.ts.map +1 -0
- package/dist/serialization/protocol/encode.d.ts +11 -0
- package/dist/serialization/protocol/encode.d.ts.map +1 -0
- package/dist/serialization/protocol/index.d.ts +3 -0
- package/dist/serialization/protocol/index.d.ts.map +1 -0
- package/dist/serialization/receive.d.ts +8 -0
- package/dist/serialization/receive.d.ts.map +1 -0
- package/dist/serialization/send.d.ts +7 -0
- package/dist/serialization/send.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/messages.d.ts +3762 -0
- package/dist/types/messages.d.ts.map +1 -0
- package/dist/types/transport.d.ts +62 -0
- package/dist/types/transport.d.ts.map +1 -0
- package/dist/utils/highlevel-checks.d.ts +10 -0
- package/dist/utils/highlevel-checks.d.ts.map +1 -0
- package/dist/utils/logBlockCommand.d.ts +2 -0
- package/dist/utils/logBlockCommand.d.ts.map +1 -0
- package/dist/utils/protobuf.d.ts +2 -0
- package/dist/utils/protobuf.d.ts.map +1 -0
- package/jest.config.js +7 -0
- package/package.json +31 -0
- package/protocol.md +21 -0
- package/scripts/protobuf-build.sh +58 -0
- package/scripts/protobuf-patches/TxAck.js +44 -0
- package/scripts/protobuf-patches/TxInputType.js +49 -0
- package/scripts/protobuf-patches/TxOutputType.js +50 -0
- package/scripts/protobuf-patches/index.js +274 -0
- package/scripts/protobuf-types.js +283 -0
- package/src/constants.ts +8 -0
- package/src/index.ts +41 -0
- package/src/serialization/index.ts +8 -0
- package/src/serialization/protobuf/decode.ts +95 -0
- package/src/serialization/protobuf/encode.ts +79 -0
- package/src/serialization/protobuf/index.ts +3 -0
- package/src/serialization/protobuf/messages.ts +37 -0
- package/src/serialization/protocol/decode.ts +48 -0
- package/src/serialization/protocol/encode.ts +59 -0
- package/src/serialization/protocol/index.ts +2 -0
- package/src/serialization/receive.ts +18 -0
- package/src/serialization/send.ts +56 -0
- package/src/types/index.ts +2 -0
- package/src/types/messages.ts +4864 -0
- package/src/types/transport.ts +71 -0
- package/src/utils/highlevel-checks.ts +88 -0
- package/src/utils/logBlockCommand.ts +1 -0
- package/src/utils/protobuf.ts +24 -0
- package/tsconfig.json +11 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Type, Message, Field } from 'protobufjs/light';
|
|
2
|
+
import ByteBuffer from 'bytebuffer';
|
|
3
|
+
import { isPrimitiveField } from '../../utils/protobuf';
|
|
4
|
+
|
|
5
|
+
const transform = (field: Field, value: any) => {
|
|
6
|
+
// [compatibility]: optional undefined keys should be null. Example: Features.fw_major.
|
|
7
|
+
if (field?.optional && typeof value === 'undefined') {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (field?.type === 'bytes') {
|
|
12
|
+
return ByteBuffer.wrap(value).toString('hex');
|
|
13
|
+
// return value.toString('hex');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// [compatibility]
|
|
17
|
+
// it is likely that we can remove this right away because trezor-connect tests don't ever trigger this condition
|
|
18
|
+
// we should probably make sure that trezor-connect treats following protobuf types as strings: int64, uint64, sint64, fixed64, sfixed64
|
|
19
|
+
if (field?.long) {
|
|
20
|
+
if (Number.isSafeInteger(value.toNumber())) {
|
|
21
|
+
// old trezor-link behavior https://github.com/trezor/trezor-link/blob/9c200cc5608976cff0542484525e98c753ba1888/src/lowlevel/protobuf/message_decoder.js#L80
|
|
22
|
+
return value.toNumber();
|
|
23
|
+
}
|
|
24
|
+
// otherwise return as string
|
|
25
|
+
return value.toString();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return value;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function messageToJSON(Message: Message<Record<string, unknown>>, fields: Type['fields']) {
|
|
32
|
+
// get rid of Message.prototype references
|
|
33
|
+
const { ...message } = Message;
|
|
34
|
+
const res: { [key: string]: any } = {};
|
|
35
|
+
|
|
36
|
+
Object.keys(fields).forEach(key => {
|
|
37
|
+
const field = fields[key];
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
const value = message[key];
|
|
40
|
+
|
|
41
|
+
/* istanbul ignore else */
|
|
42
|
+
if (field.repeated) {
|
|
43
|
+
/* istanbul ignore else */
|
|
44
|
+
if (isPrimitiveField(field.type)) {
|
|
45
|
+
res[key] = value.map((v: any) => transform(field, v));
|
|
46
|
+
}
|
|
47
|
+
// [compatibility]: keep array enums as array of numbers.
|
|
48
|
+
else if ('valuesById' in field.resolvedType!) {
|
|
49
|
+
res[key] = value;
|
|
50
|
+
} else if ('fields' in field.resolvedType!) {
|
|
51
|
+
res[key] = value.map((v: any) => messageToJSON(v, (field.resolvedType as Type).fields));
|
|
52
|
+
} else {
|
|
53
|
+
throw new Error(`case not handled for repeated key: ${key}`);
|
|
54
|
+
}
|
|
55
|
+
} else if (isPrimitiveField(field.type)) {
|
|
56
|
+
res[key] = transform(field, value);
|
|
57
|
+
}
|
|
58
|
+
// enum type
|
|
59
|
+
else if ('valuesById' in field.resolvedType!) {
|
|
60
|
+
res[key] = field.resolvedType.valuesById[value];
|
|
61
|
+
}
|
|
62
|
+
// message type
|
|
63
|
+
else if (field.resolvedType!.fields) {
|
|
64
|
+
res[key] = messageToJSON(value, field.resolvedType!.fields);
|
|
65
|
+
} else {
|
|
66
|
+
throw new Error(`case not handled: ${key}`);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return res;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const decode = (Message: Type, data: ByteBuffer) => {
|
|
74
|
+
const buff = data.toBuffer();
|
|
75
|
+
const a = new Uint8Array(buff);
|
|
76
|
+
|
|
77
|
+
let decoded;
|
|
78
|
+
try {
|
|
79
|
+
decoded = Message.decode(a);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
// Fix a battery_level problem with the device
|
|
82
|
+
if (a.length > 1 && a[a.length - 1] === 0xff) {
|
|
83
|
+
a[a.length - 1] = 0x04;
|
|
84
|
+
decoded = Message.decode(a);
|
|
85
|
+
} else {
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// [compatibility]: in the end it should be possible to get rid of messageToJSON method and call
|
|
91
|
+
// Message.toObject(decoded) to return result as plain javascript object. This method should be able to do
|
|
92
|
+
// all required conversions (for example bytes to hex) but we can't use it at the moment for compatibility reasons
|
|
93
|
+
// for example difference between enum decoding when [enum] vs enum
|
|
94
|
+
return messageToJSON(decoded, decoded.$type.fields);
|
|
95
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Type } from 'protobufjs/light';
|
|
2
|
+
import { Buffer } from 'buffer';
|
|
3
|
+
import ByteBuffer from 'bytebuffer';
|
|
4
|
+
|
|
5
|
+
import { isPrimitiveField } from '../../utils/protobuf';
|
|
6
|
+
|
|
7
|
+
const transform = (fieldType: string, value: any) => {
|
|
8
|
+
if (fieldType === 'bytes') {
|
|
9
|
+
// special edge case
|
|
10
|
+
// for example MultisigRedeemScriptType might have field signatures ['', '', ''] (check in TrezorConnect signTransactionMultisig test fixtures).
|
|
11
|
+
// trezor needs to receive such field as signatures: [b'', b'', b'']. If we transfer this to empty buffer with protobufjs, this will be decoded by
|
|
12
|
+
// trezor as signatures: [] (empty array)
|
|
13
|
+
if (typeof value === 'string' && !value) return value;
|
|
14
|
+
|
|
15
|
+
// normal flow
|
|
16
|
+
return Buffer.from(value, 'hex');
|
|
17
|
+
}
|
|
18
|
+
if (typeof value === 'number' && !Number.isSafeInteger(value)) {
|
|
19
|
+
throw new RangeError('field value is not within safe integer range');
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function patch(Message: Type, payload: any) {
|
|
25
|
+
const patched: any = {};
|
|
26
|
+
|
|
27
|
+
if (!Message.fields) {
|
|
28
|
+
return patched;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
Object.keys(Message.fields).forEach(key => {
|
|
32
|
+
const field = Message.fields[key];
|
|
33
|
+
const value = payload[key];
|
|
34
|
+
|
|
35
|
+
// no value for this field
|
|
36
|
+
if (typeof value === 'undefined') {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// primitive type
|
|
40
|
+
if (field && isPrimitiveField(field.type)) {
|
|
41
|
+
if (field.repeated) {
|
|
42
|
+
patched[key] = value.map((v: any) => transform(field.type, v));
|
|
43
|
+
} else {
|
|
44
|
+
patched[key] = transform(field.type, value);
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// repeated
|
|
49
|
+
if (field.repeated) {
|
|
50
|
+
const RefMessage = Message.lookupTypeOrEnum(field.type);
|
|
51
|
+
patched[key] = value.map((v: any) => patch(RefMessage, v));
|
|
52
|
+
}
|
|
53
|
+
// message type
|
|
54
|
+
else if (typeof value === 'object' && value !== null) {
|
|
55
|
+
const RefMessage = Message.lookupType(field.type);
|
|
56
|
+
patched[key] = patch(RefMessage, value);
|
|
57
|
+
}
|
|
58
|
+
// enum type
|
|
59
|
+
else if (typeof value === 'number') {
|
|
60
|
+
const RefMessage = Message.lookupEnum(field.type);
|
|
61
|
+
patched[key] = RefMessage.values[value];
|
|
62
|
+
} else {
|
|
63
|
+
patched[key] = value;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
return patched;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const encode = (Message: Type, data: Record<string, unknown>) => {
|
|
71
|
+
const payload = patch(Message, data);
|
|
72
|
+
const message = Message.fromObject(payload);
|
|
73
|
+
// Encode a message to an Uint8Array (browser) or Buffer (node)
|
|
74
|
+
const buffer = Message.encode(message).finish();
|
|
75
|
+
const bytebuffer = new ByteBuffer(buffer.byteLength);
|
|
76
|
+
bytebuffer.append(buffer);
|
|
77
|
+
bytebuffer.reset();
|
|
78
|
+
return bytebuffer;
|
|
79
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as protobuf from 'protobufjs/light';
|
|
2
|
+
|
|
3
|
+
export function parseConfigure(data: protobuf.INamespace) {
|
|
4
|
+
// @ts-ignore [compatiblity]: connect is sending stringified json
|
|
5
|
+
if (typeof data === 'string') {
|
|
6
|
+
return protobuf.Root.fromJSON(JSON.parse(data));
|
|
7
|
+
}
|
|
8
|
+
return protobuf.Root.fromJSON(data);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const createMessageFromName = (messages: protobuf.Root, name: string) => {
|
|
12
|
+
const Message = messages.lookupType(name);
|
|
13
|
+
const MessageType = messages.lookupEnum('MessageType');
|
|
14
|
+
let messageType = MessageType.values[`MessageType_${name}`];
|
|
15
|
+
|
|
16
|
+
if (!messageType && Message.options) {
|
|
17
|
+
messageType = Message.options['(wire_type)'];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
Message,
|
|
22
|
+
messageType,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const createMessageFromType = (messages: protobuf.Root, typeId: number) => {
|
|
27
|
+
const MessageType = messages.lookupEnum('MessageType');
|
|
28
|
+
|
|
29
|
+
const messageName = MessageType.valuesById[typeId].replace('MessageType_', '');
|
|
30
|
+
|
|
31
|
+
const Message = messages.lookupType(messageName);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
Message,
|
|
35
|
+
messageName,
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import ByteBuffer from 'bytebuffer';
|
|
2
|
+
import { MESSAGE_HEADER_BYTE } from '../../constants';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Reads meta information from buffer
|
|
6
|
+
*/
|
|
7
|
+
const readHeader = (buffer: ByteBuffer) => {
|
|
8
|
+
const typeId = buffer.readUint16();
|
|
9
|
+
const length = buffer.readUint32();
|
|
10
|
+
|
|
11
|
+
return { typeId, length };
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Reads meta information from chunked buffer
|
|
16
|
+
*/
|
|
17
|
+
const readHeaderChunked = (buffer: ByteBuffer) => {
|
|
18
|
+
const sharp1 = buffer.readByte();
|
|
19
|
+
const sharp2 = buffer.readByte();
|
|
20
|
+
const typeId = buffer.readUint16();
|
|
21
|
+
const length = buffer.readUint32();
|
|
22
|
+
|
|
23
|
+
return { sharp1, sharp2, typeId, length };
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const decode = (byteBuffer: ByteBuffer) => {
|
|
27
|
+
const { typeId } = readHeader(byteBuffer);
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
typeId,
|
|
31
|
+
buffer: byteBuffer,
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Parses first raw input that comes from Trezor and returns some information about the whole message.
|
|
36
|
+
// [compatibility]: accept Buffer just like decode does. But this would require changes in lower levels
|
|
37
|
+
export const decodeChunked = (bytes: ArrayBuffer) => {
|
|
38
|
+
// convert to ByteBuffer so it's easier to read
|
|
39
|
+
const byteBuffer = ByteBuffer.wrap(bytes, undefined, undefined, true);
|
|
40
|
+
|
|
41
|
+
const { sharp1, sharp2, typeId, length } = readHeaderChunked(byteBuffer);
|
|
42
|
+
|
|
43
|
+
if (sharp1 !== MESSAGE_HEADER_BYTE || sharp2 !== MESSAGE_HEADER_BYTE) {
|
|
44
|
+
throw new Error("Didn't receive expected header signature.");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return { length, typeId, restBuffer: byteBuffer };
|
|
48
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import ByteBuffer from 'bytebuffer';
|
|
2
|
+
|
|
3
|
+
import { HEADER_SIZE, MESSAGE_HEADER_BYTE, BUFFER_SIZE } from '../../constants';
|
|
4
|
+
|
|
5
|
+
type Options<Chunked> = {
|
|
6
|
+
chunked: Chunked;
|
|
7
|
+
addTrezorHeaders: boolean;
|
|
8
|
+
messageType: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
function encode(data: ByteBuffer, options: Options<true>): Buffer[];
|
|
12
|
+
function encode(data: ByteBuffer, options: Options<false>): Buffer;
|
|
13
|
+
function encode(data: any, options: any): any {
|
|
14
|
+
const { addTrezorHeaders, chunked, messageType } = options;
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
|
16
|
+
const fullSize = (addTrezorHeaders ? HEADER_SIZE : HEADER_SIZE - 2) + data.limit;
|
|
17
|
+
|
|
18
|
+
const encodedByteBuffer = new ByteBuffer(fullSize);
|
|
19
|
+
|
|
20
|
+
if (addTrezorHeaders) {
|
|
21
|
+
// 2*1 byte
|
|
22
|
+
encodedByteBuffer.writeByte(MESSAGE_HEADER_BYTE);
|
|
23
|
+
encodedByteBuffer.writeByte(MESSAGE_HEADER_BYTE);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 2 bytes
|
|
27
|
+
encodedByteBuffer.writeUint16(messageType);
|
|
28
|
+
|
|
29
|
+
// 4 bytes (so 8 in total)
|
|
30
|
+
encodedByteBuffer.writeUint32(data.limit);
|
|
31
|
+
|
|
32
|
+
// then put in the actual message
|
|
33
|
+
encodedByteBuffer.append(data.buffer);
|
|
34
|
+
|
|
35
|
+
encodedByteBuffer.reset();
|
|
36
|
+
|
|
37
|
+
if (chunked === false) {
|
|
38
|
+
return encodedByteBuffer;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const result: Buffer[] = [];
|
|
42
|
+
const size = BUFFER_SIZE;
|
|
43
|
+
|
|
44
|
+
// How many pieces will there actually be
|
|
45
|
+
const count = Math.floor((encodedByteBuffer.limit - 1) / size) + 1 || 1;
|
|
46
|
+
|
|
47
|
+
// slice and dice
|
|
48
|
+
for (let i = 0; i < count; i++) {
|
|
49
|
+
const start = i * size;
|
|
50
|
+
const end = Math.min((i + 1) * size, encodedByteBuffer.limit);
|
|
51
|
+
const slice = encodedByteBuffer.slice(start, end);
|
|
52
|
+
slice.compact();
|
|
53
|
+
result.push(slice.buffer);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export { encode };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Root } from 'protobufjs/light';
|
|
2
|
+
import ByteBuffer from 'bytebuffer';
|
|
3
|
+
|
|
4
|
+
import * as decodeProtobuf from './protobuf/decode';
|
|
5
|
+
import * as decodeProtocol from './protocol/decode';
|
|
6
|
+
import { createMessageFromType } from './protobuf/messages';
|
|
7
|
+
|
|
8
|
+
export function receiveOne(messages: Root, data: string) {
|
|
9
|
+
const bytebuffer = ByteBuffer.wrap(data, 'hex');
|
|
10
|
+
|
|
11
|
+
const { typeId, buffer } = decodeProtocol.decode(bytebuffer);
|
|
12
|
+
const { Message, messageName } = createMessageFromType(messages, typeId);
|
|
13
|
+
const message = decodeProtobuf.decode(Message, buffer);
|
|
14
|
+
return {
|
|
15
|
+
message,
|
|
16
|
+
type: messageName,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Logic of sending data to trezor
|
|
2
|
+
//
|
|
3
|
+
// Logic of "call" is broken to two parts - sending and receiving
|
|
4
|
+
import { Root } from 'protobufjs/light';
|
|
5
|
+
import ByteBuffer from 'bytebuffer';
|
|
6
|
+
import { encode as encodeProtobuf } from './protobuf';
|
|
7
|
+
import { encode as encodeProtocol } from './protocol';
|
|
8
|
+
import { createMessageFromName } from './protobuf/messages';
|
|
9
|
+
import { BUFFER_SIZE, MESSAGE_TOP_CHAR } from '../constants';
|
|
10
|
+
|
|
11
|
+
// Sends message to device.
|
|
12
|
+
// Resolves if everything gets sent
|
|
13
|
+
export function buildOne(messages: Root, name: string, data: Record<string, unknown>) {
|
|
14
|
+
const { Message, messageType } = createMessageFromName(messages, name);
|
|
15
|
+
|
|
16
|
+
const buffer = encodeProtobuf(Message, data);
|
|
17
|
+
return encodeProtocol(buffer, {
|
|
18
|
+
addTrezorHeaders: false,
|
|
19
|
+
chunked: false,
|
|
20
|
+
messageType,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const buildEncodeBuffers = (messages: Root, name: string, data: Record<string, unknown>) => {
|
|
25
|
+
const { Message, messageType } = createMessageFromName(messages, name);
|
|
26
|
+
const buffer = encodeProtobuf(Message, data);
|
|
27
|
+
return encodeProtocol(buffer, {
|
|
28
|
+
addTrezorHeaders: true,
|
|
29
|
+
chunked: true,
|
|
30
|
+
messageType,
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const buildBuffers = (messages: Root, name: string, data: Record<string, unknown>) => {
|
|
35
|
+
// const { Message, messageType } = createMessageFromName(messages, name);
|
|
36
|
+
// const buffer = encodeProtobuf(Message, data);
|
|
37
|
+
// const encodeBuffers = encodeProtocol(buffer, {
|
|
38
|
+
// addTrezorHeaders: true,
|
|
39
|
+
// chunked: true,
|
|
40
|
+
// messageType,
|
|
41
|
+
// });
|
|
42
|
+
|
|
43
|
+
const encodeBuffers = buildEncodeBuffers(messages, name, data);
|
|
44
|
+
|
|
45
|
+
const outBuffers: ByteBuffer[] = [];
|
|
46
|
+
|
|
47
|
+
for (const buf of encodeBuffers) {
|
|
48
|
+
const chunkBuffer = new ByteBuffer(BUFFER_SIZE + 1);
|
|
49
|
+
chunkBuffer.writeByte(MESSAGE_TOP_CHAR);
|
|
50
|
+
chunkBuffer.append(buf);
|
|
51
|
+
chunkBuffer.reset();
|
|
52
|
+
outBuffers.push(chunkBuffer);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return outBuffers;
|
|
56
|
+
};
|