@onekeyfe/hd-transport 1.2.0-alpha.34 → 1.2.0-alpha.35
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/__tests__/messages.test.js +37 -29
- package/__tests__/protocol-v2.test.js +14 -14
- package/__tests__/transport-log.test.js +79 -0
- package/dist/index.d.ts +219 -242
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +153 -74
- package/dist/types/messages.d.ts +155 -177
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/utils/transportLog.d.ts +9 -0
- package/dist/utils/transportLog.d.ts.map +1 -0
- package/messages-protocol-v2.json +393 -485
- package/package.json +2 -2
- package/src/index.ts +1 -0
- package/src/types/messages.ts +196 -225
- package/src/utils/transportLog.ts +102 -0
|
@@ -101,10 +101,10 @@ describe('messages', () => {
|
|
|
101
101
|
expect(v2Messages.nested.MessageType.values).toMatchObject({
|
|
102
102
|
MessageType_DeviceStatusGet: 60602,
|
|
103
103
|
MessageType_DeviceStatus: 60603,
|
|
104
|
-
MessageType_DeviceSessionGet:
|
|
105
|
-
MessageType_DeviceSession:
|
|
106
|
-
MessageType_DeviceSessionAskPin:
|
|
107
|
-
MessageType_DeviceSessionAskPassphrase:
|
|
104
|
+
MessageType_DeviceSessionGet: 61200,
|
|
105
|
+
MessageType_DeviceSession: 61201,
|
|
106
|
+
MessageType_DeviceSessionAskPin: 61202,
|
|
107
|
+
MessageType_DeviceSessionAskPassphrase: 61203,
|
|
108
108
|
});
|
|
109
109
|
expect(v2Messages.nested.DeviceStatusGet).toEqual({ fields: {} });
|
|
110
110
|
expect(v2Messages.nested.ProtocolInfoRequest.fields.eventless_wallet_session).toMatchObject({
|
|
@@ -112,6 +112,11 @@ describe('messages', () => {
|
|
|
112
112
|
type: 'bool',
|
|
113
113
|
options: { default: false },
|
|
114
114
|
});
|
|
115
|
+
expect(v2Messages.nested.ProtocolInfo.fields).toMatchObject({
|
|
116
|
+
version: { id: 1, type: 'uint32', rule: 'required' },
|
|
117
|
+
build_fingerprint: { id: 2, type: 'string', rule: 'required' },
|
|
118
|
+
supported_messages: { id: 3, type: 'uint32', rule: 'repeated' },
|
|
119
|
+
});
|
|
115
120
|
expect(v2Messages.nested.DeviceSessionGet.fields.session_id).toMatchObject({
|
|
116
121
|
id: 1,
|
|
117
122
|
type: 'bytes',
|
|
@@ -147,6 +152,7 @@ describe('messages', () => {
|
|
|
147
152
|
id: 1,
|
|
148
153
|
},
|
|
149
154
|
on_device: {
|
|
155
|
+
rule: 'required',
|
|
150
156
|
type: 'bool',
|
|
151
157
|
id: 2,
|
|
152
158
|
},
|
|
@@ -163,52 +169,54 @@ describe('messages', () => {
|
|
|
163
169
|
);
|
|
164
170
|
});
|
|
165
171
|
|
|
166
|
-
test('Protocol V2 passphrase selection
|
|
172
|
+
test('Protocol V2 passphrase selection explicitly selects host or device input on wire', () => {
|
|
167
173
|
const messages = parseConfigure(v2Messages);
|
|
168
174
|
const { Message } = createMessageFromName(messages, 'DeviceSessionAskPassphrase');
|
|
169
175
|
|
|
170
|
-
const onDevice = Message.encode(Message.create({ on_device: true })).finish();
|
|
171
176
|
const onHost = Message.encode(
|
|
172
|
-
Message.create({
|
|
173
|
-
passphrase: 'host hidden wallet',
|
|
174
|
-
on_device: false,
|
|
175
|
-
})
|
|
177
|
+
Message.create({ passphrase: 'host hidden wallet', on_device: false })
|
|
176
178
|
).finish();
|
|
179
|
+
const onDevice = Message.encode(Message.create({ on_device: true })).finish();
|
|
177
180
|
|
|
178
|
-
expect(Buffer.from(onDevice).toString('hex')).toBe('1001');
|
|
179
181
|
expect(Buffer.from(onHost).toString('hex')).toBe(
|
|
180
182
|
'0a12686f73742068696464656e2077616c6c65741000'
|
|
181
183
|
);
|
|
184
|
+
expect(Buffer.from(onDevice).toString('hex')).toBe('1001');
|
|
182
185
|
expect(Message.decode(onHost)).toMatchObject({
|
|
183
186
|
passphrase: 'host hidden wallet',
|
|
184
187
|
on_device: false,
|
|
185
188
|
});
|
|
189
|
+
expect(Message.decode(onDevice)).toMatchObject({ on_device: true });
|
|
186
190
|
});
|
|
187
191
|
|
|
188
192
|
test('Protocol V2 onboarding status matches the current firmware-pro2 schema', () => {
|
|
189
|
-
expect(v2Messages.nested.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
193
|
+
expect(v2Messages.nested.MessageType.values).toMatchObject({
|
|
194
|
+
MessageType_OnboardingStatusGet: 61600,
|
|
195
|
+
MessageType_OnboardingStatus: 61601,
|
|
196
|
+
});
|
|
197
|
+
expect(v2Messages.nested.OnboardingStep.values).toMatchObject({
|
|
198
|
+
ONBOARDING_STEP_UNKNOWN: 0,
|
|
199
|
+
ONBOARDING_STEP_CHECKING: 1,
|
|
200
|
+
ONBOARDING_STEP_PERSONALIZATION: 2,
|
|
201
|
+
ONBOARDING_STEP_PIN: 3,
|
|
202
|
+
ONBOARDING_STEP_SETUP: 4,
|
|
203
|
+
ONBOARDING_STEP_DONE: 5,
|
|
196
204
|
});
|
|
197
|
-
expect(v2Messages.nested.
|
|
198
|
-
expect(v2Messages.nested.
|
|
199
|
-
expect(v2Messages.nested.
|
|
200
|
-
expect(v2Messages.nested.
|
|
201
|
-
kind: { id: 1, type: '
|
|
202
|
-
method: { id: 2, type: '
|
|
205
|
+
expect(v2Messages.nested.OnboardingPhase.values).toBeDefined();
|
|
206
|
+
expect(v2Messages.nested.OnboardingSetupKind.values).toBeDefined();
|
|
207
|
+
expect(v2Messages.nested.OnboardingSetupMethod.values).toBeDefined();
|
|
208
|
+
expect(v2Messages.nested.OnboardingSetupStatus.fields).toMatchObject({
|
|
209
|
+
kind: { id: 1, type: 'OnboardingSetupKind' },
|
|
210
|
+
method: { id: 2, type: 'OnboardingSetupMethod' },
|
|
203
211
|
});
|
|
204
|
-
expect(v2Messages.nested.
|
|
205
|
-
step: { id: 1, type: '
|
|
206
|
-
phase: { id: 2, type: '
|
|
207
|
-
setup: { id: 3, type: '
|
|
212
|
+
expect(v2Messages.nested.OnboardingStatus.fields).toMatchObject({
|
|
213
|
+
step: { id: 1, type: 'OnboardingStep' },
|
|
214
|
+
phase: { id: 2, type: 'OnboardingPhase' },
|
|
215
|
+
setup: { id: 3, type: 'OnboardingSetupStatus' },
|
|
208
216
|
pin_set: { id: 4, type: 'bool' },
|
|
209
217
|
wallet_initialized: { id: 5, type: 'bool' },
|
|
210
218
|
});
|
|
211
|
-
expect(v2Messages.nested).not.toHaveProperty('
|
|
219
|
+
expect(v2Messages.nested).not.toHaveProperty('DevOnboardingStatus');
|
|
212
220
|
});
|
|
213
221
|
|
|
214
222
|
test('Protocol V2 does not restore retired unlock or passphrase ids', () => {
|
|
@@ -73,14 +73,14 @@ const protocolV2Messages = parseConfigure({
|
|
|
73
73
|
type: 'uint32',
|
|
74
74
|
id: 1,
|
|
75
75
|
},
|
|
76
|
-
|
|
77
|
-
type: '
|
|
76
|
+
build_fingerprint: {
|
|
77
|
+
type: 'string',
|
|
78
78
|
id: 2,
|
|
79
|
-
rule: 'repeated',
|
|
80
79
|
},
|
|
81
|
-
|
|
82
|
-
type: '
|
|
80
|
+
supported_messages: {
|
|
81
|
+
type: 'uint32',
|
|
83
82
|
id: 3,
|
|
83
|
+
rule: 'repeated',
|
|
84
84
|
},
|
|
85
85
|
},
|
|
86
86
|
},
|
|
@@ -211,7 +211,7 @@ const protocolV2Messages = parseConfigure({
|
|
|
211
211
|
MessageType_FileWrite: 60805,
|
|
212
212
|
MessageType_DeviceFirmwareUpdateRequest: 61000,
|
|
213
213
|
MessageType_DeviceFirmwareUpdateStatus: 61002,
|
|
214
|
-
MessageType_DeviceSession:
|
|
214
|
+
MessageType_DeviceSession: 61201,
|
|
215
215
|
MessageType_PartialNested: 62000,
|
|
216
216
|
},
|
|
217
217
|
},
|
|
@@ -235,8 +235,8 @@ describe('Protocol V2 framing and session', () => {
|
|
|
235
235
|
test('encodes and decodes Protocol V2 protobuf frames', () => {
|
|
236
236
|
const frame = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
|
|
237
237
|
version: 1,
|
|
238
|
+
build_fingerprint: 'application__1.0.0__abc__DEV__DEBUG',
|
|
238
239
|
supported_messages: [60200, 60201],
|
|
239
|
-
protobuf_definition: 'proto',
|
|
240
240
|
});
|
|
241
241
|
|
|
242
242
|
const parsed = protocolV2.decodeFrame(frame);
|
|
@@ -251,8 +251,8 @@ describe('Protocol V2 framing and session', () => {
|
|
|
251
251
|
seq: parsed.seq,
|
|
252
252
|
message: {
|
|
253
253
|
version: 1,
|
|
254
|
+
build_fingerprint: 'application__1.0.0__abc__DEV__DEBUG',
|
|
254
255
|
supported_messages: [60200, 60201],
|
|
255
|
-
protobuf_definition: 'proto',
|
|
256
256
|
},
|
|
257
257
|
});
|
|
258
258
|
});
|
|
@@ -297,10 +297,10 @@ describe('Protocol V2 framing and session', () => {
|
|
|
297
297
|
const malformedPayload = new Uint8Array(32);
|
|
298
298
|
malformedPayload[0] = 0x0a;
|
|
299
299
|
malformedPayload[1] = 101;
|
|
300
|
-
const frame = protocolV2.encodeProtobufFrame(
|
|
300
|
+
const frame = protocolV2.encodeProtobufFrame(61201, malformedPayload);
|
|
301
301
|
|
|
302
302
|
expect(() => ProtocolV2.decodeFrame(schemas, frame)).toThrow(
|
|
303
|
-
'Protocol V2 protobuf decode failed for "DeviceSession" (
|
|
303
|
+
'Protocol V2 protobuf decode failed for "DeviceSession" (61201, 32-byte payload); ' +
|
|
304
304
|
'the payload is malformed or incompatible with the active SDK schema.'
|
|
305
305
|
);
|
|
306
306
|
});
|
|
@@ -397,8 +397,8 @@ describe('Protocol V2 framing and session', () => {
|
|
|
397
397
|
type: 'ProtocolInfo',
|
|
398
398
|
message: {
|
|
399
399
|
version: 2,
|
|
400
|
+
build_fingerprint: null,
|
|
400
401
|
supported_messages: [60206],
|
|
401
|
-
protobuf_definition: null,
|
|
402
402
|
},
|
|
403
403
|
});
|
|
404
404
|
});
|
|
@@ -408,8 +408,8 @@ describe('Protocol V2 framing and session', () => {
|
|
|
408
408
|
const logger = { debug: jest.fn() };
|
|
409
409
|
const response = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
|
|
410
410
|
version: 2,
|
|
411
|
+
build_fingerprint: 'application__1.0.0__sensitive__DEV__DEBUG',
|
|
411
412
|
supported_messages: [60206],
|
|
412
|
-
protobuf_definition: 'sensitive-schema',
|
|
413
413
|
});
|
|
414
414
|
const session = new ProtocolV2Session({
|
|
415
415
|
schemas,
|
|
@@ -648,8 +648,8 @@ describe('Protocol V2 framing and session', () => {
|
|
|
648
648
|
type: 'ProtocolInfo',
|
|
649
649
|
message: {
|
|
650
650
|
version: 2,
|
|
651
|
+
build_fingerprint: null,
|
|
651
652
|
supported_messages: [],
|
|
652
|
-
protobuf_definition: null,
|
|
653
653
|
},
|
|
654
654
|
});
|
|
655
655
|
expect(logger.debug).not.toHaveBeenCalled();
|
|
@@ -770,8 +770,8 @@ describe('Protocol V2 framing and session', () => {
|
|
|
770
770
|
type: 'ProtocolInfo',
|
|
771
771
|
message: {
|
|
772
772
|
version: 2,
|
|
773
|
+
build_fingerprint: null,
|
|
773
774
|
supported_messages: [],
|
|
774
|
-
protobuf_definition: null,
|
|
775
775
|
},
|
|
776
776
|
});
|
|
777
777
|
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const { createTransportCallLog, getSafeTransportLogPayload } = require('../src/utils/transportLog');
|
|
2
|
+
|
|
3
|
+
describe('transport log sanitization', () => {
|
|
4
|
+
test('logs non-sensitive request fields and redacts passphrases recursively', () => {
|
|
5
|
+
expect(
|
|
6
|
+
createTransportCallLog('DeviceSessionAskPassphrase', 'V2', {
|
|
7
|
+
passphrase: 'hidden-wallet-secret',
|
|
8
|
+
on_device: false,
|
|
9
|
+
metadata: {
|
|
10
|
+
retry: 1,
|
|
11
|
+
session_id: 'wallet-session-secret',
|
|
12
|
+
},
|
|
13
|
+
})
|
|
14
|
+
).toEqual({
|
|
15
|
+
name: 'DeviceSessionAskPassphrase',
|
|
16
|
+
protocol: 'V2',
|
|
17
|
+
request: {
|
|
18
|
+
passphrase: '[REDACTED]',
|
|
19
|
+
on_device: false,
|
|
20
|
+
metadata: {
|
|
21
|
+
retry: 1,
|
|
22
|
+
session_id: '[REDACTED]',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test('logs response fields while redacting device and wallet identifiers', () => {
|
|
29
|
+
expect(
|
|
30
|
+
getSafeTransportLogPayload({
|
|
31
|
+
message: 'Passphrase accepted',
|
|
32
|
+
device_id: 'device-secret',
|
|
33
|
+
nested: {
|
|
34
|
+
btc_test_address: 'wallet-address',
|
|
35
|
+
unlocked: true,
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
).toEqual({
|
|
39
|
+
message: 'Passphrase accepted',
|
|
40
|
+
device_id: '[REDACTED]',
|
|
41
|
+
nested: {
|
|
42
|
+
btc_test_address: '[REDACTED]',
|
|
43
|
+
unlocked: true,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('does not log raw signing request or response payloads', () => {
|
|
49
|
+
expect(
|
|
50
|
+
getSafeTransportLogPayload(
|
|
51
|
+
{
|
|
52
|
+
transaction: 'raw-transaction',
|
|
53
|
+
path: "m/44'/60'/0'/0/0",
|
|
54
|
+
},
|
|
55
|
+
'EthereumSignTx'
|
|
56
|
+
)
|
|
57
|
+
).toBe('[REDACTED]');
|
|
58
|
+
expect(
|
|
59
|
+
getSafeTransportLogPayload(
|
|
60
|
+
{
|
|
61
|
+
signature: 'raw-signature',
|
|
62
|
+
},
|
|
63
|
+
'EthereumSignedTx'
|
|
64
|
+
)
|
|
65
|
+
).toBe('[REDACTED]');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('replaces binary content with its byte length', () => {
|
|
69
|
+
expect(
|
|
70
|
+
getSafeTransportLogPayload({
|
|
71
|
+
file_name: 'resource.bin',
|
|
72
|
+
data: new Uint8Array(128),
|
|
73
|
+
})
|
|
74
|
+
).toEqual({
|
|
75
|
+
file_name: 'resource.bin',
|
|
76
|
+
data: '[BINARY:128]',
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
});
|