@onekeyfe/hd-transport 1.2.0-alpha.8 → 1.2.0-alpha.9
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 +62 -0
- package/__tests__/protocol-v2-link-manager.test.js +326 -0
- package/__tests__/protocol-v2-usb-transport-base.test.js +296 -0
- package/__tests__/protocol-v2.test.js +112 -4
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +164 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +352 -29
- package/dist/protocols/index.d.ts +2 -0
- package/dist/protocols/index.d.ts.map +1 -1
- package/dist/protocols/v2/constants.d.ts +1 -0
- package/dist/protocols/v2/constants.d.ts.map +1 -1
- package/dist/protocols/v2/decode.d.ts +1 -0
- package/dist/protocols/v2/decode.d.ts.map +1 -1
- package/dist/protocols/v2/link-manager.d.ts +35 -0
- package/dist/protocols/v2/link-manager.d.ts.map +1 -0
- package/dist/protocols/v2/sequence-cursor.d.ts +5 -0
- package/dist/protocols/v2/sequence-cursor.d.ts.map +1 -0
- package/dist/protocols/v2/session.d.ts +15 -3
- package/dist/protocols/v2/session.d.ts.map +1 -1
- package/dist/protocols/v2/usb-transport-base.d.ts +31 -0
- package/dist/protocols/v2/usb-transport-base.d.ts.map +1 -0
- package/dist/types/messages.d.ts +51 -1
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/transport.d.ts +1 -1
- package/dist/types/transport.d.ts.map +1 -1
- package/messages-protocol-v2.json +134 -3
- package/package.json +2 -2
- package/scripts/protobuf-build.sh +46 -0
- package/src/constants.ts +6 -0
- package/src/index.ts +8 -0
- package/src/protocols/index.ts +3 -1
- package/src/protocols/v2/constants.ts +1 -0
- package/src/protocols/v2/decode.ts +36 -17
- package/src/protocols/v2/link-manager.ts +160 -0
- package/src/protocols/v2/sequence-cursor.ts +10 -0
- package/src/protocols/v2/session.ts +76 -40
- package/src/protocols/v2/usb-transport-base.ts +194 -0
- package/src/types/messages.ts +65 -1
- package/src/types/transport.ts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PROTOCOL_V2_PACKET_SRC_COMMAND } from '../../constants';
|
|
2
2
|
import { ProtocolV2FrameAssembler, concatUint8Arrays } from './frame-assembler';
|
|
3
|
-
import {
|
|
3
|
+
import { ProtocolV2SequenceCursor } from './sequence-cursor';
|
|
4
4
|
import { ProtocolV2 } from '..';
|
|
5
5
|
import * as check from '../../utils/highlevel-checks';
|
|
6
6
|
import { LogBlockCommand } from '../../utils/logBlockCommand';
|
|
@@ -13,6 +13,13 @@ export type ProtocolV2Schemas = {
|
|
|
13
13
|
protocolV2: Root;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
export type ProtocolV2CallContext = {
|
|
17
|
+
messageName: string;
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
highVolume: boolean;
|
|
20
|
+
generation: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
16
23
|
type ProtocolLogger = {
|
|
17
24
|
debug?: (...args: any[]) => void;
|
|
18
25
|
error?: (...args: any[]) => void;
|
|
@@ -22,11 +29,15 @@ export type ProtocolV2SessionOptions = {
|
|
|
22
29
|
schemas: ProtocolV2Schemas;
|
|
23
30
|
router: number;
|
|
24
31
|
packetSrc?: number;
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
maxFrameBytes?: number;
|
|
33
|
+
prepareCall?: (context: ProtocolV2CallContext) => Promise<void> | void;
|
|
34
|
+
writeFrame: (frame: Uint8Array, context: ProtocolV2CallContext) => Promise<void>;
|
|
35
|
+
readFrame: (context: ProtocolV2CallContext) => Promise<Uint8Array>;
|
|
27
36
|
logger?: ProtocolLogger;
|
|
28
37
|
logPrefix?: string;
|
|
29
38
|
createTimeoutError?: (name: string, timeoutMs: number) => Error;
|
|
39
|
+
sequenceCursor?: ProtocolV2SequenceCursor;
|
|
40
|
+
generation?: number;
|
|
30
41
|
};
|
|
31
42
|
|
|
32
43
|
export type ProtocolV2CallOptions = {
|
|
@@ -37,6 +48,7 @@ export type ProtocolV2CallOptions = {
|
|
|
37
48
|
};
|
|
38
49
|
|
|
39
50
|
export { concatUint8Arrays, ProtocolV2FrameAssembler };
|
|
51
|
+
export { ProtocolV2SequenceCursor };
|
|
40
52
|
|
|
41
53
|
export function hexToBytes(hex: string): Uint8Array {
|
|
42
54
|
const clean = hex.replace(/\s+/g, '');
|
|
@@ -237,15 +249,15 @@ export const PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS = 0;
|
|
|
237
249
|
export class ProtocolV2Session {
|
|
238
250
|
private readonly options: ProtocolV2SessionOptions;
|
|
239
251
|
|
|
252
|
+
private readonly sequenceCursor: ProtocolV2SequenceCursor;
|
|
253
|
+
|
|
240
254
|
// Serializes call() invocations: responses are matched only by type, so two
|
|
241
255
|
// in-flight calls on the same session would steal each other's responses.
|
|
242
256
|
private pendingCall: Promise<unknown> = Promise.resolve();
|
|
243
257
|
|
|
244
|
-
// Per-session sequence counter (1-255, wraps skipping 0).
|
|
245
|
-
private protoSeq = 0;
|
|
246
|
-
|
|
247
258
|
constructor(options: ProtocolV2SessionOptions) {
|
|
248
259
|
this.options = options;
|
|
260
|
+
this.sequenceCursor = options.sequenceCursor ?? new ProtocolV2SequenceCursor();
|
|
249
261
|
}
|
|
250
262
|
|
|
251
263
|
call(
|
|
@@ -270,25 +282,41 @@ export class ProtocolV2Session {
|
|
|
270
282
|
schemas,
|
|
271
283
|
router,
|
|
272
284
|
packetSrc = PROTOCOL_V2_PACKET_SRC_COMMAND,
|
|
285
|
+
maxFrameBytes,
|
|
286
|
+
prepareCall,
|
|
273
287
|
writeFrame,
|
|
274
288
|
readFrame,
|
|
275
289
|
logger,
|
|
276
290
|
logPrefix = 'ProtocolV2',
|
|
277
291
|
createTimeoutError,
|
|
292
|
+
generation = 0,
|
|
278
293
|
} = this.options;
|
|
279
294
|
|
|
280
295
|
const shouldReduceDebug = shouldReduceProtocolV2Debug(name);
|
|
281
|
-
|
|
296
|
+
const callContext: ProtocolV2CallContext = {
|
|
297
|
+
messageName: name,
|
|
298
|
+
timeoutMs: callOptions.timeoutMs,
|
|
299
|
+
highVolume: shouldReduceDebug,
|
|
300
|
+
generation,
|
|
301
|
+
};
|
|
302
|
+
await prepareCall?.(callContext);
|
|
303
|
+
const protoSeq = this.sequenceCursor.next();
|
|
282
304
|
const frame = ProtocolV2.encodeFrame(schemas, name, data, {
|
|
283
305
|
packetSrc,
|
|
284
306
|
router,
|
|
285
|
-
seq:
|
|
307
|
+
seq: protoSeq,
|
|
286
308
|
logger: shouldReduceDebug ? undefined : logger,
|
|
287
309
|
logPrefix,
|
|
288
310
|
context: `tx:${name}`,
|
|
289
311
|
});
|
|
290
312
|
const expectedSeq = frame[6];
|
|
291
313
|
|
|
314
|
+
if (maxFrameBytes !== undefined && frame.length > maxFrameBytes) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`Protocol V2 frame too large for transport: ${frame.length} > ${maxFrameBytes}`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
292
320
|
if (!shouldReduceDebug) {
|
|
293
321
|
logger?.debug?.(
|
|
294
322
|
`[${logPrefix}] TX payload name=${name}`,
|
|
@@ -304,7 +332,7 @@ export class ProtocolV2Session {
|
|
|
304
332
|
// Lenient watchdog on the write phase only — see
|
|
305
333
|
// PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS for the rationale.
|
|
306
334
|
await withProtocolTimeout(
|
|
307
|
-
writeFrame(frame),
|
|
335
|
+
writeFrame(frame, callContext),
|
|
308
336
|
PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS,
|
|
309
337
|
() =>
|
|
310
338
|
new Error(
|
|
@@ -323,7 +351,7 @@ export class ProtocolV2Session {
|
|
|
323
351
|
// terminal response. Consume those frames here so callers still see a
|
|
324
352
|
// request/terminal-response shaped API.
|
|
325
353
|
while (!cancellation.cancelled) {
|
|
326
|
-
const rxFrame = await readFrame();
|
|
354
|
+
const rxFrame = await readFrame(callContext);
|
|
327
355
|
if (cancellation.cancelled) {
|
|
328
356
|
// Timed out while waiting: drop the late frame and stop reading.
|
|
329
357
|
break;
|
|
@@ -335,37 +363,45 @@ export class ProtocolV2Session {
|
|
|
335
363
|
} seq=${rxFrame[6]} headerHex=${frameHeaderDebugHex(rxFrame)}`
|
|
336
364
|
);
|
|
337
365
|
}
|
|
338
|
-
const
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
if (!shouldReduceDebug && decoded.seq !== expectedSeq) {
|
|
344
|
-
logger?.debug?.(
|
|
345
|
-
`[${logPrefix}] seq differs for ${name}: tx=${expectedSeq}, rx=${decoded.seq}`
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
if (!shouldReduceDebug) {
|
|
349
|
-
logger?.debug?.(
|
|
350
|
-
`[${logPrefix}] TX name=${name} seq=${expectedSeq} | RX seq=${decoded.seq} messageTypeId=${decoded.messageTypeId} pbPayload=${decoded.pbPayload.length}B`
|
|
351
|
-
);
|
|
352
|
-
logger?.debug?.(
|
|
353
|
-
`[${logPrefix}] RX payload type=${decoded.type} messageTypeId=${decoded.messageTypeId}`,
|
|
354
|
-
sanitizeProtocolV2DebugPayload(decoded.message)
|
|
355
|
-
);
|
|
366
|
+
const isAck = ProtocolV2.isAckFrame(rxFrame);
|
|
367
|
+
if (isAck) {
|
|
368
|
+
if (!shouldReduceDebug) {
|
|
369
|
+
logger?.debug?.(`[${logPrefix}] skip Proto Link ACK seq=${rxFrame[6]}`);
|
|
370
|
+
}
|
|
356
371
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
)
|
|
372
|
+
if (!isAck) {
|
|
373
|
+
const decoded = ProtocolV2.decodeFrame(schemas, rxFrame, {
|
|
374
|
+
logger: shouldReduceDebug ? undefined : logger,
|
|
375
|
+
logPrefix,
|
|
376
|
+
context: `rx:${name}`,
|
|
377
|
+
});
|
|
378
|
+
if (!shouldReduceDebug && decoded.seq !== expectedSeq) {
|
|
379
|
+
logger?.debug?.(
|
|
380
|
+
`[${logPrefix}] seq differs for ${name}: tx=${expectedSeq}, rx=${decoded.seq}`
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
if (!shouldReduceDebug) {
|
|
384
|
+
logger?.debug?.(
|
|
385
|
+
`[${logPrefix}] TX name=${name} seq=${expectedSeq} | RX seq=${decoded.seq} messageTypeId=${decoded.messageTypeId} pbPayload=${decoded.pbPayload.length}B`
|
|
386
|
+
);
|
|
387
|
+
logger?.debug?.(
|
|
388
|
+
`[${logPrefix}] RX payload type=${decoded.type} messageTypeId=${decoded.messageTypeId}`,
|
|
389
|
+
sanitizeProtocolV2DebugPayload(decoded.message)
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
const response = check.call(decoded);
|
|
394
|
+
if (callOptions.intermediateTypes?.includes(response.type)) {
|
|
395
|
+
callOptions.onIntermediateResponse?.(response);
|
|
396
|
+
} else if (isExpectedTerminalResponse(response, callOptions.expectedTypes)) {
|
|
397
|
+
return response;
|
|
398
|
+
} else if (!shouldReduceDebug) {
|
|
399
|
+
logger?.debug?.(
|
|
400
|
+
`[${logPrefix}] skip unexpected response for ${name}: expected=${callOptions.expectedTypes?.join(
|
|
401
|
+
'|'
|
|
402
|
+
)} got=${response.type}`
|
|
403
|
+
);
|
|
404
|
+
}
|
|
369
405
|
}
|
|
370
406
|
}
|
|
371
407
|
// Only reachable after cancellation; the outer promise has already been
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { ProtocolV2FrameAssembler } from './frame-assembler';
|
|
2
|
+
import { ProtocolV2LinkManager } from './link-manager';
|
|
3
|
+
|
|
4
|
+
import type { MessageFromOneKey, TransportCallOptions } from '../../types';
|
|
5
|
+
import type { ProtocolV2CallContext, ProtocolV2Schemas, ProtocolV2SessionOptions } from './session';
|
|
6
|
+
|
|
7
|
+
export type ProtocolV2UsbTransportBaseOptions = {
|
|
8
|
+
router: number;
|
|
9
|
+
maxFrameBytes: number;
|
|
10
|
+
logPrefix: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type ProtocolV2UsbCancellation = {
|
|
14
|
+
generation: number;
|
|
15
|
+
reason?: string;
|
|
16
|
+
promise: Promise<string>;
|
|
17
|
+
cancel: (reason: string) => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export abstract class ProtocolV2UsbTransportBase<Key> {
|
|
21
|
+
private readonly protocolV2UsbLinks: ProtocolV2LinkManager<Key>;
|
|
22
|
+
|
|
23
|
+
private readonly protocolV2UsbAssemblers = new Map<Key, ProtocolV2FrameAssembler>();
|
|
24
|
+
|
|
25
|
+
private readonly protocolV2UsbGenerations = new Map<Key, number>();
|
|
26
|
+
|
|
27
|
+
private readonly protocolV2UsbCancellations = new Map<Key, ProtocolV2UsbCancellation>();
|
|
28
|
+
|
|
29
|
+
private readonly protocolV2UsbOptions: ProtocolV2UsbTransportBaseOptions;
|
|
30
|
+
|
|
31
|
+
protected constructor(options: ProtocolV2UsbTransportBaseOptions) {
|
|
32
|
+
this.protocolV2UsbOptions = options;
|
|
33
|
+
this.protocolV2UsbLinks = new ProtocolV2LinkManager<Key>({
|
|
34
|
+
getSchemas: () => this.getProtocolV2UsbSchemas(),
|
|
35
|
+
classifyError: () => 'link-fatal',
|
|
36
|
+
onLinkInvalidated: async (key, reason) => {
|
|
37
|
+
this.protocolV2UsbAssemblers.get(key)?.reset();
|
|
38
|
+
await this.resetProtocolV2UsbNativeLink(key, reason);
|
|
39
|
+
await this.onProtocolV2UsbLinkInvalidated(key, reason);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
protected abstract getProtocolV2UsbSchemas(): ProtocolV2Schemas;
|
|
45
|
+
|
|
46
|
+
protected abstract getProtocolV2UsbLogger(): ProtocolV2SessionOptions['logger'];
|
|
47
|
+
|
|
48
|
+
protected abstract writeProtocolV2UsbPacket(
|
|
49
|
+
key: Key,
|
|
50
|
+
frame: Uint8Array,
|
|
51
|
+
context: ProtocolV2CallContext
|
|
52
|
+
): Promise<void>;
|
|
53
|
+
|
|
54
|
+
protected abstract readProtocolV2UsbPacket(
|
|
55
|
+
key: Key,
|
|
56
|
+
context: ProtocolV2CallContext
|
|
57
|
+
): Promise<Uint8Array>;
|
|
58
|
+
|
|
59
|
+
protected abstract resetProtocolV2UsbNativeLink(key: Key, reason: string): Promise<void>;
|
|
60
|
+
|
|
61
|
+
protected abstract createProtocolV2UsbTimeoutError(name: string, timeoutMs: number): Error;
|
|
62
|
+
|
|
63
|
+
protected onProtocolV2UsbLinkInvalidated(_key: Key, _reason: string): Promise<void> | void {
|
|
64
|
+
// 子类按需清理协议缓存或记录平台日志。
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
protected async rotateProtocolV2UsbGeneration(key: Key, reason: string): Promise<number> {
|
|
68
|
+
await this.protocolV2UsbLinks.invalidateLink(key, reason);
|
|
69
|
+
const generation = (this.protocolV2UsbGenerations.get(key) ?? 0) + 1;
|
|
70
|
+
this.protocolV2UsbGenerations.set(key, generation);
|
|
71
|
+
this.protocolV2UsbCancellations.set(key, this.createProtocolV2UsbCancellation(generation));
|
|
72
|
+
this.protocolV2UsbAssemblers.set(
|
|
73
|
+
key,
|
|
74
|
+
new ProtocolV2FrameAssembler(this.protocolV2UsbOptions.maxFrameBytes)
|
|
75
|
+
);
|
|
76
|
+
return generation;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
protected callProtocolV2Usb(
|
|
80
|
+
key: Key,
|
|
81
|
+
name: string,
|
|
82
|
+
data: Record<string, unknown>,
|
|
83
|
+
options?: TransportCallOptions
|
|
84
|
+
): Promise<MessageFromOneKey> {
|
|
85
|
+
return this.protocolV2UsbLinks.call(
|
|
86
|
+
key,
|
|
87
|
+
() => this.createProtocolV2UsbAdapter(key),
|
|
88
|
+
name,
|
|
89
|
+
data,
|
|
90
|
+
options
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
protected invalidateProtocolV2UsbLink(key: Key, reason: string): Promise<void> {
|
|
95
|
+
return this.protocolV2UsbLinks.invalidateLink(key, reason);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected invalidateAllProtocolV2UsbLinks(reason: string): Promise<void> {
|
|
99
|
+
return this.protocolV2UsbLinks.invalidateAllLinks(reason);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected async disposeProtocolV2UsbLinks(reason: string): Promise<void> {
|
|
103
|
+
await this.protocolV2UsbLinks.dispose(reason);
|
|
104
|
+
this.protocolV2UsbAssemblers.clear();
|
|
105
|
+
this.protocolV2UsbGenerations.clear();
|
|
106
|
+
this.protocolV2UsbCancellations.clear();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private createProtocolV2UsbAdapter(key: Key) {
|
|
110
|
+
const generation = this.protocolV2UsbGenerations.get(key);
|
|
111
|
+
if (generation === undefined) {
|
|
112
|
+
throw new Error('Protocol V2 USB generation has not been initialized');
|
|
113
|
+
}
|
|
114
|
+
const cancellation = this.protocolV2UsbCancellations.get(key);
|
|
115
|
+
if (!cancellation || cancellation.generation !== generation) {
|
|
116
|
+
throw new Error('Protocol V2 USB cancellation state has not been initialized');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const assertCurrentGeneration = () => {
|
|
120
|
+
if (cancellation.reason) {
|
|
121
|
+
throw new Error(cancellation.reason);
|
|
122
|
+
}
|
|
123
|
+
if (this.protocolV2UsbGenerations.get(key) !== generation) {
|
|
124
|
+
throw new Error('Protocol V2 USB connection generation changed');
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
router: this.protocolV2UsbOptions.router,
|
|
130
|
+
maxFrameBytes: this.protocolV2UsbOptions.maxFrameBytes,
|
|
131
|
+
generation,
|
|
132
|
+
prepareCall: () => {
|
|
133
|
+
assertCurrentGeneration();
|
|
134
|
+
this.getProtocolV2UsbAssembler(key).reset();
|
|
135
|
+
},
|
|
136
|
+
writeFrame: async (frame: Uint8Array, context: ProtocolV2CallContext) => {
|
|
137
|
+
assertCurrentGeneration();
|
|
138
|
+
await this.writeProtocolV2UsbPacket(key, frame, context);
|
|
139
|
+
assertCurrentGeneration();
|
|
140
|
+
},
|
|
141
|
+
readFrame: async (context: ProtocolV2CallContext) => {
|
|
142
|
+
assertCurrentGeneration();
|
|
143
|
+
const assembler = this.getProtocolV2UsbAssembler(key);
|
|
144
|
+
let frame = assembler.push(new Uint8Array(0));
|
|
145
|
+
while (!frame) {
|
|
146
|
+
const packetRead = this.readProtocolV2UsbPacket(key, context).then(packet => ({
|
|
147
|
+
packet,
|
|
148
|
+
}));
|
|
149
|
+
const cancelled = cancellation.promise.then(reason => ({ reason }));
|
|
150
|
+
const result = await Promise.race([packetRead, cancelled]);
|
|
151
|
+
if ('reason' in result) {
|
|
152
|
+
throw new Error(result.reason);
|
|
153
|
+
}
|
|
154
|
+
assertCurrentGeneration();
|
|
155
|
+
frame = assembler.push(result.packet);
|
|
156
|
+
}
|
|
157
|
+
assertCurrentGeneration();
|
|
158
|
+
return frame;
|
|
159
|
+
},
|
|
160
|
+
reset: (reason: string) => {
|
|
161
|
+
cancellation.cancel(reason);
|
|
162
|
+
this.protocolV2UsbAssemblers.get(key)?.reset();
|
|
163
|
+
},
|
|
164
|
+
logger: this.getProtocolV2UsbLogger(),
|
|
165
|
+
logPrefix: this.protocolV2UsbOptions.logPrefix,
|
|
166
|
+
createTimeoutError: (messageName: string, timeoutMs: number) =>
|
|
167
|
+
this.createProtocolV2UsbTimeoutError(messageName, timeoutMs),
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
private getProtocolV2UsbAssembler(key: Key): ProtocolV2FrameAssembler {
|
|
172
|
+
const assembler = this.protocolV2UsbAssemblers.get(key);
|
|
173
|
+
if (!assembler) {
|
|
174
|
+
throw new Error('Protocol V2 USB assembler has not been initialized');
|
|
175
|
+
}
|
|
176
|
+
return assembler;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private createProtocolV2UsbCancellation(generation: number): ProtocolV2UsbCancellation {
|
|
180
|
+
let resolveCancellation: (reason: string) => void = () => undefined;
|
|
181
|
+
const cancellation: ProtocolV2UsbCancellation = {
|
|
182
|
+
generation,
|
|
183
|
+
promise: new Promise(resolve => {
|
|
184
|
+
resolveCancellation = resolve;
|
|
185
|
+
}),
|
|
186
|
+
cancel: reason => {
|
|
187
|
+
if (cancellation.reason) return;
|
|
188
|
+
cancellation.reason = reason;
|
|
189
|
+
resolveCancellation(reason);
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
return cancellation;
|
|
193
|
+
}
|
|
194
|
+
}
|
package/src/types/messages.ts
CHANGED
|
@@ -4478,6 +4478,15 @@ export type TxAckPaymentRequest = {
|
|
|
4478
4478
|
signature: string;
|
|
4479
4479
|
};
|
|
4480
4480
|
|
|
4481
|
+
// EthereumSignTypedDataQR
|
|
4482
|
+
export type EthereumSignTypedDataQR = {
|
|
4483
|
+
address_n: number[];
|
|
4484
|
+
json_data?: string;
|
|
4485
|
+
chain_id?: number;
|
|
4486
|
+
metamask_v4_compat?: boolean;
|
|
4487
|
+
request_id?: string;
|
|
4488
|
+
};
|
|
4489
|
+
|
|
4481
4490
|
// InternalMyAddressRequest
|
|
4482
4491
|
export type InternalMyAddressRequest = {
|
|
4483
4492
|
coin_type: number;
|
|
@@ -4589,12 +4598,26 @@ export type ViewTip = {
|
|
|
4589
4598
|
text: string;
|
|
4590
4599
|
};
|
|
4591
4600
|
|
|
4601
|
+
// ViewRawData
|
|
4602
|
+
export type ViewRawData = {
|
|
4603
|
+
initial_data: string;
|
|
4604
|
+
placeholder: number;
|
|
4605
|
+
};
|
|
4606
|
+
|
|
4607
|
+
export enum ViewSignLayout {
|
|
4608
|
+
LayoutDefault = 0,
|
|
4609
|
+
LayoutSafeTxCreate = 1,
|
|
4610
|
+
}
|
|
4611
|
+
|
|
4592
4612
|
// ViewSignPage
|
|
4593
4613
|
export type ViewSignPage = {
|
|
4594
4614
|
title: string;
|
|
4595
4615
|
amount?: UintType;
|
|
4596
4616
|
general: ViewDetail[];
|
|
4597
4617
|
tip?: ViewTip;
|
|
4618
|
+
raw_data?: ViewRawData;
|
|
4619
|
+
slide_to_confirm?: boolean;
|
|
4620
|
+
layout?: ViewSignLayout;
|
|
4598
4621
|
};
|
|
4599
4622
|
|
|
4600
4623
|
// ViewVerifyPage
|
|
@@ -4893,6 +4916,35 @@ export type DeviceStatus = {
|
|
|
4893
4916
|
unlocked_by_attach_to_pin?: boolean;
|
|
4894
4917
|
};
|
|
4895
4918
|
|
|
4919
|
+
// DeviceStatusGet
|
|
4920
|
+
export type DeviceStatusGet = {};
|
|
4921
|
+
|
|
4922
|
+
export enum DevOnboardingStage {
|
|
4923
|
+
DEV_ONBOARDING_STAGE_UNKNOWN = 0,
|
|
4924
|
+
DEV_ONBOARDING_STAGE_SAFETY_CHECK = 1,
|
|
4925
|
+
DEV_ONBOARDING_STAGE_PERSONALIZATION = 2,
|
|
4926
|
+
DEV_ONBOARDING_STAGE_SELECT_SETUP_METHOD = 3,
|
|
4927
|
+
DEV_ONBOARDING_STAGE_NEW_DEVICE = 4,
|
|
4928
|
+
DEV_ONBOARDING_STAGE_SELECT_RESTORE_METHOD = 5,
|
|
4929
|
+
DEV_ONBOARDING_STAGE_RESTORE_MNEMONIC = 6,
|
|
4930
|
+
DEV_ONBOARDING_STAGE_RESTORE_SEEDCARD = 7,
|
|
4931
|
+
DEV_ONBOARDING_STAGE_WALLET_READY = 8,
|
|
4932
|
+
DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP_PROMPT = 9,
|
|
4933
|
+
DEV_ONBOARDING_STAGE_SELECT_SEEDCARD_BACKUP_METHOD = 10,
|
|
4934
|
+
DEV_ONBOARDING_STAGE_SEEDCARD_BACKUP = 11,
|
|
4935
|
+
DEV_ONBOARDING_STAGE_DONE = 12,
|
|
4936
|
+
}
|
|
4937
|
+
|
|
4938
|
+
// DevGetOnboardingStatus
|
|
4939
|
+
export type DevGetOnboardingStatus = {};
|
|
4940
|
+
|
|
4941
|
+
// DevOnboardingStatus
|
|
4942
|
+
export type DevOnboardingStatus = {
|
|
4943
|
+
stage: DevOnboardingStage;
|
|
4944
|
+
status_code?: number;
|
|
4945
|
+
detail_code?: number;
|
|
4946
|
+
};
|
|
4947
|
+
|
|
4896
4948
|
// FilesystemPermissionFix
|
|
4897
4949
|
export type FilesystemPermissionFix = {};
|
|
4898
4950
|
|
|
@@ -4972,7 +5024,13 @@ export type FilesystemDirRemove = {
|
|
|
4972
5024
|
};
|
|
4973
5025
|
|
|
4974
5026
|
// FilesystemFormat
|
|
4975
|
-
export type FilesystemFormat = {
|
|
5027
|
+
export type FilesystemFormat = {
|
|
5028
|
+
data: boolean;
|
|
5029
|
+
user: boolean;
|
|
5030
|
+
};
|
|
5031
|
+
|
|
5032
|
+
// PortfolioUpdate
|
|
5033
|
+
export type PortfolioUpdate = {};
|
|
4976
5034
|
|
|
4977
5035
|
// custom connect definitions
|
|
4978
5036
|
export type MessageType = {
|
|
@@ -5538,6 +5596,7 @@ export type MessageType = {
|
|
|
5538
5596
|
CoinPurchaseMemo: CoinPurchaseMemo;
|
|
5539
5597
|
PaymentRequestMemo: PaymentRequestMemo;
|
|
5540
5598
|
TxAckPaymentRequest: TxAckPaymentRequest;
|
|
5599
|
+
EthereumSignTypedDataQR: EthereumSignTypedDataQR;
|
|
5541
5600
|
InternalMyAddressRequest: InternalMyAddressRequest;
|
|
5542
5601
|
StartSession: StartSession;
|
|
5543
5602
|
SetBusy: SetBusy;
|
|
@@ -5554,6 +5613,7 @@ export type MessageType = {
|
|
|
5554
5613
|
ViewAmount: ViewAmount;
|
|
5555
5614
|
ViewDetail: ViewDetail;
|
|
5556
5615
|
ViewTip: ViewTip;
|
|
5616
|
+
ViewRawData: ViewRawData;
|
|
5557
5617
|
ViewSignPage: ViewSignPage;
|
|
5558
5618
|
ViewVerifyPage: ViewVerifyPage;
|
|
5559
5619
|
ProtocolInfoRequest: ProtocolInfoRequest;
|
|
@@ -5590,6 +5650,9 @@ export type MessageType = {
|
|
|
5590
5650
|
DeviceSessionGet: DeviceSessionGet;
|
|
5591
5651
|
DeviceSession: DeviceSession;
|
|
5592
5652
|
DeviceStatus: DeviceStatus;
|
|
5653
|
+
DeviceStatusGet: DeviceStatusGet;
|
|
5654
|
+
DevGetOnboardingStatus: DevGetOnboardingStatus;
|
|
5655
|
+
DevOnboardingStatus: DevOnboardingStatus;
|
|
5593
5656
|
FilesystemPermissionFix: FilesystemPermissionFix;
|
|
5594
5657
|
FilesystemPathInfo: FilesystemPathInfo;
|
|
5595
5658
|
FilesystemPathInfoQuery: FilesystemPathInfoQuery;
|
|
@@ -5602,6 +5665,7 @@ export type MessageType = {
|
|
|
5602
5665
|
FilesystemDirMake: FilesystemDirMake;
|
|
5603
5666
|
FilesystemDirRemove: FilesystemDirRemove;
|
|
5604
5667
|
FilesystemFormat: FilesystemFormat;
|
|
5668
|
+
PortfolioUpdate: PortfolioUpdate;
|
|
5605
5669
|
};
|
|
5606
5670
|
|
|
5607
5671
|
export type MessageKey = keyof MessageType;
|
package/src/types/transport.ts
CHANGED
|
@@ -106,7 +106,7 @@ export type LowLevelDevice = OneKeyDeviceInfoBase & { id: string; name: string }
|
|
|
106
106
|
export type LowlevelTransportSharedPlugin = {
|
|
107
107
|
enumerate: () => Promise<LowLevelDevice[]>;
|
|
108
108
|
send: (uuid: string, data: string) => Promise<void>;
|
|
109
|
-
receive: () => Promise<string>;
|
|
109
|
+
receive: (uuid?: string) => Promise<string>;
|
|
110
110
|
connect: (uuid: string) => Promise<void>;
|
|
111
111
|
disconnect: (uuid: string) => Promise<void>;
|
|
112
112
|
|