@onekeyfe/hd-transport 0.1.39 → 0.1.42
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 +3 -1
- package/__tests__/build-receive.test.js +117 -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/index.js +127 -161
- package/dist/serialization/protobuf/decode.d.ts +1 -1
- package/dist/serialization/protobuf/decode.d.ts.map +1 -1
- package/dist/serialization/protobuf/encode.d.ts +1 -1
- package/dist/serialization/protobuf/encode.d.ts.map +1 -1
- package/dist/serialization/receive.d.ts.map +1 -1
- package/dist/serialization/send.d.ts +1 -1
- package/dist/serialization/send.d.ts.map +1 -1
- package/jest.config.js +7 -0
- package/package.json +5 -3
- package/scripts/protobuf-build.sh +57 -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 +305 -0
- package/scripts/protobuf-types.js +283 -0
- package/src/serialization/protobuf/decode.ts +1 -1
- package/src/serialization/protobuf/encode.ts +1 -1
- package/src/serialization/receive.ts +1 -1
- package/src/serialization/send.ts +1 -1
package/.eslintrc
CHANGED
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
// note you must disable the base rule as it can report incorrect errors
|
|
17
17
|
"no-use-before-define": "off",
|
|
18
18
|
"@typescript-eslint/no-use-before-define": ["error"],
|
|
19
|
-
"
|
|
19
|
+
"@typescript-eslint/no-var-requires": "off",
|
|
20
|
+
"require-await": ["error"],
|
|
21
|
+
"import/no-named-default": "off"
|
|
20
22
|
}
|
|
21
23
|
}
|
|
@@ -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,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
|
+
});
|