@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
package/.eslintrc
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rules": {
|
|
3
|
+
"no-console": "off",
|
|
4
|
+
"@typescript-eslint/no-non-null-assertion": "off",
|
|
5
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
6
|
+
"@typescript-eslint/ban-ts-ignore": "off",
|
|
7
|
+
// We need empty functions for mocking modules for react-native
|
|
8
|
+
"@typescript-eslint/no-empty-function": "off",
|
|
9
|
+
"no-useless-constructor": "off",
|
|
10
|
+
"@typescript-eslint/no-useless-constructor": "error",
|
|
11
|
+
// valid case of class method overloads in typescript
|
|
12
|
+
"no-dupe-class-members": "off",
|
|
13
|
+
"@typescript-eslint/ban-ts-comment": "off",
|
|
14
|
+
// Missing return type on function
|
|
15
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
16
|
+
// note you must disable the base rule as it can report incorrect errors
|
|
17
|
+
"no-use-before-define": "off",
|
|
18
|
+
"@typescript-eslint/no-use-before-define": ["error"],
|
|
19
|
+
"@typescript-eslint/no-var-requires": "off",
|
|
20
|
+
"require-await": ["error"],
|
|
21
|
+
"import/no-named-default": "off",
|
|
22
|
+
"@typescript-eslint/ban-types": "off"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/README.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# `@ukeyfe/hardware-transport`
|
|
2
|
+
|
|
3
|
+
`@ukeyfe/hardware-transport` is a library for low-level communication with UKey Hardware.
|
|
4
|
+
|
|
5
|
+
## What is the purpose
|
|
6
|
+
|
|
7
|
+
- translate JSON payloads to binary messages using protobuf definitions comprehensible to UKey devices
|
|
8
|
+
- chunking and reading chunked messages according to the [UKey protocol](./protocol.md)
|
|
9
|
+
- exposing single API for various transport methods:
|
|
10
|
+
- Http Transport
|
|
11
|
+
- React Native Transport
|
|
12
|
+
- WebUSB
|
|
13
|
+
- Create and expose typescript definitions based on protobuf definitions.
|
|
14
|
+
|
|
15
|
+
### The short version
|
|
16
|
+
|
|
17
|
+
In order to be able to use new features of ukey-firmware you need to update protobuf definitions.
|
|
18
|
+
|
|
19
|
+
1. `git submodule update --init --recursive` to initialize git submodules.
|
|
20
|
+
1. `yarn update-submodules` to update firmware submodule
|
|
21
|
+
1. `yarn update:protobuf` to generate new `./messages.json` and `./src/types/messages.ts`
|
|
22
|
+
|
|
23
|
+
git submodule update --init --recursive to initialize firmware submodule
|
|
24
|
+
yarn update-submodules to update firmware submodule
|
|
25
|
+
yarn update:protobuf to generate new ./messages.json and ./src/types/messages.ts
|
|
26
|
+
|
|
27
|
+
## Docs
|
|
28
|
+
|
|
29
|
+
Documentation is available [hardware-js-sdk](https://developer.ukey.so/connect-to-hardware/hardware-sdk/start)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const { parseConfigure } = require('../src/serialization/protobuf/messages');
|
|
2
|
+
const { buildOne } = require('../src/serialization/send');
|
|
3
|
+
const { receiveOne } = require('../src/serialization/receive');
|
|
4
|
+
|
|
5
|
+
const { buildEncodeBuffers } = require('../src/serialization/send');
|
|
6
|
+
|
|
7
|
+
const messages = {
|
|
8
|
+
StellarPaymentOp: {
|
|
9
|
+
fields: {
|
|
10
|
+
source_account: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
id: 1,
|
|
13
|
+
},
|
|
14
|
+
destination_account: {
|
|
15
|
+
rule: 'required',
|
|
16
|
+
type: 'string',
|
|
17
|
+
id: 2,
|
|
18
|
+
},
|
|
19
|
+
asset: {
|
|
20
|
+
rule: 'required',
|
|
21
|
+
type: 'StellarAsset',
|
|
22
|
+
id: 3,
|
|
23
|
+
},
|
|
24
|
+
amount: {
|
|
25
|
+
rule: 'required',
|
|
26
|
+
type: 'sint64',
|
|
27
|
+
id: 4,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
StellarAssetType: {
|
|
32
|
+
values: {
|
|
33
|
+
NATIVE: 0,
|
|
34
|
+
ALPHANUM4: 1,
|
|
35
|
+
ALPHANUM12: 2,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
StellarAsset: {
|
|
39
|
+
fields: {
|
|
40
|
+
type: {
|
|
41
|
+
rule: 'required',
|
|
42
|
+
type: 'StellarAssetType',
|
|
43
|
+
id: 1,
|
|
44
|
+
},
|
|
45
|
+
code: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
id: 2,
|
|
48
|
+
},
|
|
49
|
+
issuer: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
id: 3,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
MessageType: {
|
|
56
|
+
values: {
|
|
57
|
+
MessageType_StellarSignTx: 202,
|
|
58
|
+
MessageType_StellarTxOpRequest: 203,
|
|
59
|
+
MessageType_StellarGetAddress: 207,
|
|
60
|
+
MessageType_StellarAddress: 208,
|
|
61
|
+
MessageType_StellarCreateAccountOp: 210,
|
|
62
|
+
MessageType_StellarPaymentOp: 211,
|
|
63
|
+
MessageType_StellarPathPaymentOp: 212,
|
|
64
|
+
MessageType_StellarManageOfferOp: 213,
|
|
65
|
+
MessageType_StellarCreatePassiveOfferOp: 214,
|
|
66
|
+
MessageType_StellarSetOptionsOp: 215,
|
|
67
|
+
MessageType_StellarChangeTrustOp: 216,
|
|
68
|
+
MessageType_StellarAllowTrustOp: 217,
|
|
69
|
+
MessageType_StellarAccountMergeOp: 218,
|
|
70
|
+
MessageType_StellarManageDataOp: 220,
|
|
71
|
+
MessageType_StellarBumpSequenceOp: 221,
|
|
72
|
+
MessageType_StellarSignedTx: 230,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const fixtures = [
|
|
78
|
+
{
|
|
79
|
+
name: 'StellarPaymentOp',
|
|
80
|
+
in: {
|
|
81
|
+
source_account: 'meow'.repeat(100), // make message longer then 63 bytes
|
|
82
|
+
destination_account: 'wuff',
|
|
83
|
+
asset: {
|
|
84
|
+
type: 'NATIVE',
|
|
85
|
+
code: 'hello',
|
|
86
|
+
issuer: 'world',
|
|
87
|
+
},
|
|
88
|
+
amount: 10,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const parsedMessages = parseConfigure({
|
|
94
|
+
nested: { hw: { nested: { trezor: { nested: { messages: { nested: messages } } } } } },
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('encoding json -> protobuf -> json', () => {
|
|
98
|
+
fixtures.forEach(f => {
|
|
99
|
+
describe(f.name, () => {
|
|
100
|
+
test('buildOne - receiveOne', () => {
|
|
101
|
+
// encoded message
|
|
102
|
+
const encodedMessage = buildOne(parsedMessages, f.name, f.in);
|
|
103
|
+
// then decode message and check, whether decoded message matches original json
|
|
104
|
+
const decodedMessage = receiveOne(parsedMessages, encodedMessage);
|
|
105
|
+
expect(decodedMessage.type).toEqual(f.name);
|
|
106
|
+
expect(decodedMessage.message).toEqual(f.in);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('buildBuffers - receiveAndParse', () => {
|
|
110
|
+
const result = buildEncodeBuffers(parsedMessages, f.name, f.in);
|
|
111
|
+
result.forEach(r => {
|
|
112
|
+
expect(r.byteLength).toBeLessThanOrEqual(63);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const ProtoBuf = require('protobufjs/light');
|
|
2
|
+
const ByteBuffer = require('bytebuffer');
|
|
3
|
+
|
|
4
|
+
const { decode } = require('../src/serialization/protobuf/decode');
|
|
5
|
+
const { decode: decodeProtocol } = require('../src/serialization/protocol/decode');
|
|
6
|
+
|
|
7
|
+
// eslint-disable-next-line import/no-unresolved
|
|
8
|
+
const messages = require('../messages.json');
|
|
9
|
+
|
|
10
|
+
const fixtures = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Features-error-battery_level',
|
|
13
|
+
encodeMessage:
|
|
14
|
+
'0011000000260a096f6e656b65792e736f1002180020002801900101aa010131b00101b80163c00163c020ff',
|
|
15
|
+
out: {
|
|
16
|
+
vendor: 'ukey.so',
|
|
17
|
+
major_version: 2,
|
|
18
|
+
minor_version: 0,
|
|
19
|
+
patch_version: 0,
|
|
20
|
+
bootloader_mode: true,
|
|
21
|
+
firmware_present: true,
|
|
22
|
+
capabilities: [],
|
|
23
|
+
model: '1',
|
|
24
|
+
fw_major: 1,
|
|
25
|
+
fw_minor: 99,
|
|
26
|
+
fw_patch: 99,
|
|
27
|
+
battery_level: 4,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'Features-success',
|
|
32
|
+
encodeMessage:
|
|
33
|
+
'0011000000260a096f6e656b65792e736f1002180020002801900101aa010131b00102b80163c00163c02004',
|
|
34
|
+
out: {
|
|
35
|
+
vendor: 'ukey.so',
|
|
36
|
+
major_version: 2,
|
|
37
|
+
minor_version: 0,
|
|
38
|
+
patch_version: 0,
|
|
39
|
+
bootloader_mode: true,
|
|
40
|
+
firmware_present: true,
|
|
41
|
+
capabilities: [],
|
|
42
|
+
model: '1',
|
|
43
|
+
fw_major: 2,
|
|
44
|
+
fw_minor: 99,
|
|
45
|
+
fw_patch: 99,
|
|
46
|
+
battery_level: 4,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
describe('Fix messages decode', () => {
|
|
52
|
+
const Messages = ProtoBuf.Root.fromJSON(messages);
|
|
53
|
+
const Message = Messages.lookup(`Features`);
|
|
54
|
+
fixtures.forEach(f => {
|
|
55
|
+
describe(f.name, () => {
|
|
56
|
+
test('decode', () => {
|
|
57
|
+
// deserialize
|
|
58
|
+
const encoded = ByteBuffer.fromHex(f.encodeMessage);
|
|
59
|
+
const { buffer } = decodeProtocol(encoded);
|
|
60
|
+
const decoded = decode(Message, buffer);
|
|
61
|
+
|
|
62
|
+
// filter null values
|
|
63
|
+
Object.keys(decoded).forEach(key => {
|
|
64
|
+
if (decoded[key] == null) {
|
|
65
|
+
delete decoded[key];
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
expect(decoded).toEqual(f.out);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
const ProtoBuf = require('protobufjs/light');
|
|
2
|
+
const { encode } = require('../src/serialization/protobuf/encode');
|
|
3
|
+
const { decode } = require('../src/serialization/protobuf/decode');
|
|
4
|
+
|
|
5
|
+
const messages = {
|
|
6
|
+
nested: {
|
|
7
|
+
messages: {
|
|
8
|
+
nested: {
|
|
9
|
+
String: {
|
|
10
|
+
fields: {
|
|
11
|
+
field: {
|
|
12
|
+
rule: 'required',
|
|
13
|
+
type: 'string',
|
|
14
|
+
id: 1,
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
Uint32: {
|
|
19
|
+
fields: {
|
|
20
|
+
field: {
|
|
21
|
+
rule: 'required',
|
|
22
|
+
type: 'uint32',
|
|
23
|
+
id: 2,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
Uint64: {
|
|
28
|
+
fields: {
|
|
29
|
+
field: {
|
|
30
|
+
rule: 'required',
|
|
31
|
+
type: 'uint64',
|
|
32
|
+
id: 3,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
Bool: {
|
|
37
|
+
fields: {
|
|
38
|
+
field: {
|
|
39
|
+
rule: 'required',
|
|
40
|
+
type: 'bool',
|
|
41
|
+
id: 4,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
Sint32: {
|
|
46
|
+
fields: {
|
|
47
|
+
field: {
|
|
48
|
+
rule: 'required',
|
|
49
|
+
type: 'sint32',
|
|
50
|
+
id: 5,
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
Sint64: {
|
|
55
|
+
fields: {
|
|
56
|
+
field: {
|
|
57
|
+
rule: 'required',
|
|
58
|
+
type: 'sint64',
|
|
59
|
+
id: 6,
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
Bytes: {
|
|
64
|
+
fields: {
|
|
65
|
+
field: {
|
|
66
|
+
rule: 'required',
|
|
67
|
+
type: 'bytes',
|
|
68
|
+
id: 7,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
// complex and real life examples
|
|
74
|
+
ComplexFieldOfOptionals: {
|
|
75
|
+
fields: {
|
|
76
|
+
bool: {
|
|
77
|
+
rule: 'optional',
|
|
78
|
+
type: 'bool',
|
|
79
|
+
id: 8,
|
|
80
|
+
},
|
|
81
|
+
number: {
|
|
82
|
+
rule: 'optional',
|
|
83
|
+
type: 'uint32',
|
|
84
|
+
id: 9,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
Repeated: {
|
|
90
|
+
fields: {
|
|
91
|
+
bool: {
|
|
92
|
+
rule: 'repeated',
|
|
93
|
+
type: 'bool',
|
|
94
|
+
id: 8,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
Defaults: {
|
|
100
|
+
fields: {
|
|
101
|
+
string: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
id: 8,
|
|
104
|
+
options: {
|
|
105
|
+
defaults: 'hello world',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const basicFixtures = [
|
|
116
|
+
{
|
|
117
|
+
name: 'String',
|
|
118
|
+
params: { field: 'foo' },
|
|
119
|
+
encoded: '0a03666f6f',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'Uint32',
|
|
123
|
+
params: { field: 4294967295 },
|
|
124
|
+
encoded: '10ffffffff0f',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'Uint64',
|
|
128
|
+
params: { field: 1844674407370955 },
|
|
129
|
+
encoded: '18cba19cd68bb7a303',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: 'Uint64',
|
|
133
|
+
params: { field: '166054873161269248' }, // over Number.MAX_SAFE_INTEGER is sent as string
|
|
134
|
+
encoded: '1880808080f0c0fca602',
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'Sint64',
|
|
138
|
+
params: { field: '-166054873161269248' }, // over Number.MAX_SAFE_INTEGER is sent as string
|
|
139
|
+
encoded: '30ffffffffdf81f9cd04',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'Bool',
|
|
143
|
+
params: { field: true },
|
|
144
|
+
encoded: '2001',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'Bool',
|
|
148
|
+
params: { field: false },
|
|
149
|
+
encoded: '2000',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'Sint32',
|
|
153
|
+
params: { field: -4294967 },
|
|
154
|
+
encoded: '28eda48c04',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: 'Sint64',
|
|
158
|
+
params: { field: -1844674407370955 },
|
|
159
|
+
encoded: '3095c3b8ac97eec606',
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'Bytes',
|
|
163
|
+
params: {
|
|
164
|
+
field:
|
|
165
|
+
'851fc9542342321af63ecbba7d3ece545f2a42bad01ba32cff5535b18e54b6d3106e10b6a4525993d185a1443d9a125186960e028eabfdd8d76cf70a3a7e3100',
|
|
166
|
+
},
|
|
167
|
+
encoded:
|
|
168
|
+
'3a40851fc9542342321af63ecbba7d3ece545f2a42bad01ba32cff5535b18e54b6d3106e10b6a4525993d185a1443d9a125186960e028eabfdd8d76cf70a3a7e3100',
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
// note: difference in bool encoding. if type === bool && field = optional && not message of only one field, bool is encoded as ""
|
|
173
|
+
const advancedFixtures = [
|
|
174
|
+
{
|
|
175
|
+
name: 'ComplexFieldOfOptionals',
|
|
176
|
+
in: { number: 1 },
|
|
177
|
+
encoded: '4801',
|
|
178
|
+
out: { bool: null, number: 1 },
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
name: 'Repeated',
|
|
182
|
+
in: { bool: [true, false, true, false] },
|
|
183
|
+
encoded: '420401000100',
|
|
184
|
+
out: { bool: [true, false, true, false] },
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: 'Defaults',
|
|
188
|
+
in: { string: '' },
|
|
189
|
+
encoded: '4200',
|
|
190
|
+
out: { string: '' },
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
describe('basic concepts', () => {
|
|
195
|
+
const Messages = ProtoBuf.Root.fromJSON(messages);
|
|
196
|
+
|
|
197
|
+
describe('primitives encode/decode', () => {
|
|
198
|
+
basicFixtures.forEach(f => {
|
|
199
|
+
describe(f.name, () => {
|
|
200
|
+
const Message = Messages.lookup(`messages.${f.name}`);
|
|
201
|
+
|
|
202
|
+
test(f.name, () => {
|
|
203
|
+
// serialize new way - this is to confirm new lib won't break old behavior
|
|
204
|
+
const encoded = encode(Message, f.params);
|
|
205
|
+
expect(encoded.toString('hex')).toEqual(f.encoded);
|
|
206
|
+
|
|
207
|
+
// deserialize new way - this is to confirm new lib won't break old behavior
|
|
208
|
+
const decoded = decode(Message, encoded);
|
|
209
|
+
expect(decoded).toEqual(f.params);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
describe('advanced', () => {
|
|
216
|
+
advancedFixtures.forEach(f => {
|
|
217
|
+
describe(f.name, () => {
|
|
218
|
+
const Message = Messages.lookup(`messages.${f.name}`);
|
|
219
|
+
|
|
220
|
+
test(f.name, () => {
|
|
221
|
+
// serialize new way - this is to confirm new lib won't break old behavior
|
|
222
|
+
const encoded = encode(Message, f.in);
|
|
223
|
+
|
|
224
|
+
expect(encoded.toString('hex')).toEqual(f.encoded);
|
|
225
|
+
|
|
226
|
+
// deserialize new way - this is to confirm new lib won't break old behavior
|
|
227
|
+
const decoded = decode(Message, encoded);
|
|
228
|
+
|
|
229
|
+
expect(decoded).toEqual(f.out);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test('Different protobuf between receiving ends', () => {
|
|
235
|
+
const messages = {
|
|
236
|
+
nested: {
|
|
237
|
+
messages: {
|
|
238
|
+
nested: {
|
|
239
|
+
ButtonRequest: {
|
|
240
|
+
fields: {
|
|
241
|
+
code: {
|
|
242
|
+
type: 'string',
|
|
243
|
+
id: 1,
|
|
244
|
+
},
|
|
245
|
+
pages: {
|
|
246
|
+
type: 'uint32',
|
|
247
|
+
id: 2,
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const SenderMessages = ProtoBuf.Root.fromJSON(messages);
|
|
257
|
+
const senderEncoded = encode(SenderMessages.lookup('messages.ButtonRequest'), {
|
|
258
|
+
type: 'foo',
|
|
259
|
+
pages: 123,
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const receiverMessages = messages;
|
|
263
|
+
// now change field type from uint32 to string
|
|
264
|
+
receiverMessages.nested.messages.nested.ButtonRequest.fields.pages.type = 'string';
|
|
265
|
+
const ReceiverMessages = ProtoBuf.Root.fromJSON(receiverMessages);
|
|
266
|
+
|
|
267
|
+
expect(() => {
|
|
268
|
+
decode(ReceiverMessages.lookup('messages.ButtonRequest'), senderEncoded);
|
|
269
|
+
}).toThrow();
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
});
|