@onekeyfe/hd-transport 1.2.0-alpha.23 → 1.2.0-alpha.25

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.
@@ -11506,6 +11506,33 @@
11506
11506
  }
11507
11507
  }
11508
11508
  },
11509
+ "UiAnimationType": {
11510
+ "values": {
11511
+ "Unknown": 0,
11512
+ "Signing": 1
11513
+ }
11514
+ },
11515
+ "UiAnimationCommand": {
11516
+ "values": {
11517
+ "CommandUnknown": 0,
11518
+ "Start": 1,
11519
+ "Stop": 2,
11520
+ "Refresh": 3
11521
+ }
11522
+ },
11523
+ "UiAnimationRequest": {
11524
+ "fields": {
11525
+ "command": {
11526
+ "rule": "required",
11527
+ "type": "UiAnimationCommand",
11528
+ "id": 1
11529
+ },
11530
+ "type": {
11531
+ "type": "UiAnimationType",
11532
+ "id": 2
11533
+ }
11534
+ }
11535
+ },
11509
11536
  "ViewAmount": {
11510
11537
  "fields": {
11511
11538
  "is_unlimited": {
@@ -12482,7 +12509,12 @@
12482
12509
  }
12483
12510
  },
12484
12511
  "DeviceSessionAskPassphrase": {
12485
- "fields": {}
12512
+ "fields": {
12513
+ "passphrase": {
12514
+ "type": "string",
12515
+ "id": 1
12516
+ }
12517
+ }
12486
12518
  },
12487
12519
  "DeviceSessionAskPin_FailureSubCodes": {
12488
12520
  "values": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport",
3
- "version": "1.2.0-alpha.23",
3
+ "version": "1.2.0-alpha.25",
4
4
  "description": "Transport layer abstractions and utilities for OneKey hardware SDK.",
5
5
  "author": "OneKey",
6
6
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
@@ -28,5 +28,5 @@
28
28
  "long": "^4.0.0",
29
29
  "protobufjs": "^6.11.2"
30
30
  },
31
- "gitHead": "7cadb40ca6414053a488756f28a9f413164b235d"
31
+ "gitHead": "20bb98b8530c509299b9e109d2b5ada7c6a6d034"
32
32
  }
package/src/index.ts CHANGED
@@ -41,9 +41,10 @@ export type {
41
41
  OneKeyDeviceInfoBase,
42
42
  OneKeyDeviceCommType,
43
43
  ProtocolType,
44
+ TransportDeviceDisconnectEvent,
44
45
  } from './types';
45
46
 
46
- export { Messages } from './types';
47
+ export { Messages, TRANSPORT_EVENT } from './types';
47
48
  export * from './types/messages';
48
49
  export * from './utils/logBlockCommand';
49
50
 
@@ -1,5 +1,7 @@
1
1
  export type ProtocolV2LinkErrorCode =
2
2
  | 'response-timeout'
3
+ | 'io'
4
+ | 'generation'
3
5
  | 'router'
4
6
  | 'packet-source'
5
7
  | 'ack-sequence'
@@ -1,4 +1,5 @@
1
1
  import { ProtocolV2SequenceCursor } from './sequence-cursor';
2
+ import { ProtocolV2LinkError } from './errors';
2
3
  import { ProtocolV2Session, getErrorMessage } from './session';
3
4
 
4
5
  import type { MessageFromOneKey, TransportCallOptions } from '../../types';
@@ -40,6 +41,10 @@ export class ProtocolV2LinkManager<Key> {
40
41
 
41
42
  private readonly callQueues = new Map<Key, Promise<unknown>>();
42
43
 
44
+ private readonly generations = new Map<Key, number>();
45
+
46
+ private readonly invalidationReasons = new Map<Key, { generation: number; reason: string }>();
47
+
43
48
  private readonly options: ProtocolV2LinkManagerOptions<Key>;
44
49
 
45
50
  constructor(options: ProtocolV2LinkManagerOptions<Key>) {
@@ -53,7 +58,11 @@ export class ProtocolV2LinkManager<Key> {
53
58
  data: Record<string, unknown>,
54
59
  options?: TransportCallOptions
55
60
  ): Promise<MessageFromOneKey> {
56
- const run = () => this.executeCall(key, createAdapter, name, data, options);
61
+ const generation = this.generations.get(key) ?? 0;
62
+ const run = () => {
63
+ this.assertCallGeneration(key, generation);
64
+ return this.executeCall(key, createAdapter, name, data, options);
65
+ };
57
66
  const previous = this.callQueues.get(key) ?? Promise.resolve();
58
67
  const result = previous.then(run, run);
59
68
  const queue = result.catch(() => undefined);
@@ -68,6 +77,10 @@ export class ProtocolV2LinkManager<Key> {
68
77
  }
69
78
 
70
79
  async invalidateLink(key: Key, reason: string): Promise<void> {
80
+ const generation = (this.generations.get(key) ?? 0) + 1;
81
+ this.generations.set(key, generation);
82
+ this.invalidationReasons.set(key, { generation, reason });
83
+
71
84
  const link = this.links.get(key);
72
85
  if (!link) return;
73
86
 
@@ -78,7 +91,8 @@ export class ProtocolV2LinkManager<Key> {
78
91
  }
79
92
 
80
93
  async invalidateAllLinks(reason: string): Promise<void> {
81
- await Promise.all(Array.from(this.links.keys(), key => this.invalidateLink(key, reason)));
94
+ const keys = new Set([...this.links.keys(), ...this.callQueues.keys()]);
95
+ await Promise.all(Array.from(keys, key => this.invalidateLink(key, reason)));
82
96
  }
83
97
 
84
98
  async dispose(reason: string): Promise<void> {
@@ -157,4 +171,16 @@ export class ProtocolV2LinkManager<Key> {
157
171
  this.callQueues.delete(key);
158
172
  }
159
173
  }
174
+
175
+ private assertCallGeneration(key: Key, generation: number) {
176
+ const currentGeneration = this.generations.get(key) ?? 0;
177
+ if (currentGeneration === generation) return;
178
+
179
+ const invalidation = this.invalidationReasons.get(key);
180
+ const reason =
181
+ invalidation?.generation === currentGeneration
182
+ ? invalidation.reason
183
+ : 'Protocol V2 link generation changed';
184
+ throw new ProtocolV2LinkError('generation', reason);
185
+ }
160
186
  }
@@ -1,5 +1,7 @@
1
1
  import { ProtocolV2FrameAssembler } from './frame-assembler';
2
+ import { ProtocolV2LinkError, isProtocolV2LinkError } from './errors';
2
3
  import { ProtocolV2LinkManager } from './link-manager';
4
+ import { getErrorMessage } from './session';
3
5
 
4
6
  import type { MessageFromOneKey, TransportCallOptions } from '../../types';
5
7
  import type { ProtocolV2CallContext, ProtocolV2Schemas, ProtocolV2SessionOptions } from './session';
@@ -32,7 +34,7 @@ export abstract class ProtocolV2UsbTransportBase<Key> {
32
34
  this.protocolV2UsbOptions = options;
33
35
  this.protocolV2UsbLinks = new ProtocolV2LinkManager<Key>({
34
36
  getSchemas: () => this.getProtocolV2UsbSchemas(),
35
- classifyError: () => 'link-fatal',
37
+ classifyError: error => (isProtocolV2LinkError(error) ? 'link-fatal' : 'recoverable'),
36
38
  onLinkInvalidated: async (key, reason) => {
37
39
  this.protocolV2UsbAssemblers.get(key)?.reset();
38
40
  await this.resetProtocolV2UsbNativeLink(key, reason);
@@ -118,10 +120,13 @@ export abstract class ProtocolV2UsbTransportBase<Key> {
118
120
 
119
121
  const assertCurrentGeneration = () => {
120
122
  if (cancellation.reason) {
121
- throw new Error(cancellation.reason);
123
+ throw new ProtocolV2LinkError('generation', cancellation.reason);
122
124
  }
123
125
  if (this.protocolV2UsbGenerations.get(key) !== generation) {
124
- throw new Error('Protocol V2 USB connection generation changed');
126
+ throw new ProtocolV2LinkError(
127
+ 'generation',
128
+ 'Protocol V2 USB connection generation changed'
129
+ );
125
130
  }
126
131
  };
127
132
 
@@ -131,11 +136,14 @@ export abstract class ProtocolV2UsbTransportBase<Key> {
131
136
  generation,
132
137
  prepareCall: () => {
133
138
  assertCurrentGeneration();
134
- this.getProtocolV2UsbAssembler(key).reset();
135
139
  },
136
140
  writeFrame: async (frame: Uint8Array, context: ProtocolV2CallContext) => {
137
141
  assertCurrentGeneration();
138
- await this.writeProtocolV2UsbPacket(key, frame, context);
142
+ try {
143
+ await this.writeProtocolV2UsbPacket(key, frame, context);
144
+ } catch (error) {
145
+ throw this.createProtocolV2UsbIoError('write', error);
146
+ }
139
147
  assertCurrentGeneration();
140
148
  },
141
149
  readFrame: async (context: ProtocolV2CallContext) => {
@@ -143,13 +151,15 @@ export abstract class ProtocolV2UsbTransportBase<Key> {
143
151
  const assembler = this.getProtocolV2UsbAssembler(key);
144
152
  let frame = assembler.push(new Uint8Array(0));
145
153
  while (!frame) {
146
- const packetRead = this.readProtocolV2UsbPacket(key, context).then(packet => ({
147
- packet,
148
- }));
154
+ const packetRead = this.readProtocolV2UsbPacket(key, context)
155
+ .then(packet => ({ packet }))
156
+ .catch(error => {
157
+ throw this.createProtocolV2UsbIoError('read', error);
158
+ });
149
159
  const cancelled = cancellation.promise.then(reason => ({ reason }));
150
160
  const result = await Promise.race([packetRead, cancelled]);
151
161
  if ('reason' in result) {
152
- throw new Error(result.reason);
162
+ throw new ProtocolV2LinkError('generation', result.reason);
153
163
  }
154
164
  assertCurrentGeneration();
155
165
  frame = assembler.push(result.packet);
@@ -191,4 +201,13 @@ export abstract class ProtocolV2UsbTransportBase<Key> {
191
201
  };
192
202
  return cancellation;
193
203
  }
204
+
205
+ private createProtocolV2UsbIoError(operation: 'read' | 'write', error: unknown) {
206
+ if (isProtocolV2LinkError(error)) return error;
207
+ return new ProtocolV2LinkError(
208
+ 'io',
209
+ `Protocol V2 USB ${operation} failed: ${getErrorMessage(error) || 'unknown error'}`,
210
+ error
211
+ );
212
+ }
194
213
  }
@@ -4679,6 +4679,24 @@ export enum MoneroNetworkType {
4679
4679
  FAKECHAIN = 3,
4680
4680
  }
4681
4681
 
4682
+ export enum UiAnimationType {
4683
+ Unknown = 0,
4684
+ Signing = 1,
4685
+ }
4686
+
4687
+ export enum UiAnimationCommand {
4688
+ CommandUnknown = 0,
4689
+ Start = 1,
4690
+ Stop = 2,
4691
+ Refresh = 3,
4692
+ }
4693
+
4694
+ // UiAnimationRequest
4695
+ export type UiAnimationRequest = {
4696
+ command: UiAnimationCommand;
4697
+ type?: UiAnimationType;
4698
+ };
4699
+
4682
4700
  // ViewAmount
4683
4701
  export type ViewAmount = {
4684
4702
  is_unlimited: boolean;
@@ -5083,7 +5101,9 @@ export type DeviceSessionAskPin = {
5083
5101
  };
5084
5102
 
5085
5103
  // DeviceSessionAskPassphrase
5086
- export type DeviceSessionAskPassphrase = {};
5104
+ export type DeviceSessionAskPassphrase = {
5105
+ passphrase?: string;
5106
+ };
5087
5107
 
5088
5108
  export enum DeviceSessionAskPin_FailureSubCodes {
5089
5109
  UserCancel = 1,
@@ -5865,6 +5885,7 @@ export type MessageType = {
5865
5885
  Wallpaper: Wallpaper;
5866
5886
  UnlockPath: UnlockPath;
5867
5887
  UnlockedPathRequest: UnlockedPathRequest;
5888
+ UiAnimationRequest: UiAnimationRequest;
5868
5889
  ViewAmount: ViewAmount;
5869
5890
  ViewDetail: ViewDetail;
5870
5891
  ViewTip: ViewTip;
@@ -1,5 +1,15 @@
1
1
  import type EventEmitter from 'events';
2
2
 
3
+ export const TRANSPORT_EVENT = {
4
+ DEVICE_DISCONNECT: 'transport-device-disconnect',
5
+ } as const;
6
+
7
+ export type TransportDeviceDisconnectEvent = {
8
+ id: string;
9
+ connectId: string;
10
+ name: string | null;
11
+ };
12
+
3
13
  export type ProtocolType = 'V1' | 'V2';
4
14
 
5
15
  export type OneKeyDeviceCommType =