@onekeyfe/hd-core 1.1.27-alpha.42 → 1.1.27-alpha.43

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.
Files changed (146) hide show
  1. package/__tests__/DeviceCommands.test.ts +99 -0
  2. package/__tests__/evmLedgerLegacySafety.test.ts +261 -0
  3. package/__tests__/preInitialize.test.ts +22 -0
  4. package/__tests__/protocol-v2.test.ts +10 -15
  5. package/dist/api/BaseMethod.d.ts +7 -1
  6. package/dist/api/BaseMethod.d.ts.map +1 -1
  7. package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
  8. package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
  9. package/dist/api/GetPassphraseState.d.ts.map +1 -1
  10. package/dist/api/alephium/AlephiumSignMessage.d.ts.map +1 -1
  11. package/dist/api/alephium/AlephiumSignTransaction.d.ts.map +1 -1
  12. package/dist/api/algo/AlgoSignTransaction.d.ts.map +1 -1
  13. package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
  14. package/dist/api/aptos/AptosSignInMessage.d.ts.map +1 -1
  15. package/dist/api/aptos/AptosSignMessage.d.ts.map +1 -1
  16. package/dist/api/aptos/AptosSignTransaction.d.ts.map +1 -1
  17. package/dist/api/benfen/BenfenSignMessage.d.ts.map +1 -1
  18. package/dist/api/benfen/BenfenSignTransaction.d.ts.map +1 -1
  19. package/dist/api/btc/BTCSignMessage.d.ts.map +1 -1
  20. package/dist/api/btc/BTCSignPsbt.d.ts.map +1 -1
  21. package/dist/api/btc/BTCSignTransaction.d.ts.map +1 -1
  22. package/dist/api/cardano/CardanoSignMessage.d.ts.map +1 -1
  23. package/dist/api/cardano/CardanoSignTransaction.d.ts.map +1 -1
  24. package/dist/api/conflux/ConfluxSignMessage.d.ts.map +1 -1
  25. package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts.map +1 -1
  26. package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
  27. package/dist/api/cosmos/CosmosSignTransaction.d.ts.map +1 -1
  28. package/dist/api/device/PreInitialize.d.ts +6 -0
  29. package/dist/api/device/PreInitialize.d.ts.map +1 -0
  30. package/dist/api/dynex/DnxSignTransaction.d.ts.map +1 -1
  31. package/dist/api/evm/EVMSignMessage.d.ts.map +1 -1
  32. package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
  33. package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
  34. package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
  35. package/dist/api/filecoin/FilecoinSignTransaction.d.ts.map +1 -1
  36. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +2 -10
  37. package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
  38. package/dist/api/index.d.ts +1 -0
  39. package/dist/api/index.d.ts.map +1 -1
  40. package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
  41. package/dist/api/near/NearSignTransaction.d.ts.map +1 -1
  42. package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -1
  43. package/dist/api/neo/NeoSignTransaction.d.ts.map +1 -1
  44. package/dist/api/nervos/NervosSignTransaction.d.ts.map +1 -1
  45. package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
  46. package/dist/api/nostr/NostrSignEvent.d.ts.map +1 -1
  47. package/dist/api/nostr/NostrSignSchnorr.d.ts.map +1 -1
  48. package/dist/api/polkadot/PolkadotSignTransaction.d.ts.map +1 -1
  49. package/dist/api/scdo/ScdoSignMessage.d.ts.map +1 -1
  50. package/dist/api/scdo/ScdoSignTransaction.d.ts.map +1 -1
  51. package/dist/api/solana/SolSignMessage.d.ts.map +1 -1
  52. package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
  53. package/dist/api/solana/SolSignTransaction.d.ts.map +1 -1
  54. package/dist/api/starcoin/StarcoinSignMessage.d.ts.map +1 -1
  55. package/dist/api/starcoin/StarcoinSignTransaction.d.ts.map +1 -1
  56. package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -1
  57. package/dist/api/sui/SuiSignMessage.d.ts.map +1 -1
  58. package/dist/api/sui/SuiSignTransaction.d.ts.map +1 -1
  59. package/dist/api/ton/TonSignData.d.ts.map +1 -1
  60. package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
  61. package/dist/api/ton/TonSignProof.d.ts.map +1 -1
  62. package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
  63. package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
  64. package/dist/api/xrp/XrpSignTransaction.d.ts.map +1 -1
  65. package/dist/core/PollingStateManager.d.ts +8 -0
  66. package/dist/core/PollingStateManager.d.ts.map +1 -0
  67. package/dist/core/RequestQueue.d.ts +1 -1
  68. package/dist/core/RequestQueue.d.ts.map +1 -1
  69. package/dist/core/index.d.ts.map +1 -1
  70. package/dist/device/Device.d.ts +15 -0
  71. package/dist/device/Device.d.ts.map +1 -1
  72. package/dist/index.d.ts +19 -0
  73. package/dist/index.js +431 -177
  74. package/dist/types/api/index.d.ts +2 -0
  75. package/dist/types/api/index.d.ts.map +1 -1
  76. package/dist/types/api/preInitialize.d.ts +3 -0
  77. package/dist/types/api/preInitialize.d.ts.map +1 -0
  78. package/dist/types/params.d.ts +1 -0
  79. package/dist/types/params.d.ts.map +1 -1
  80. package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
  81. package/package.json +4 -4
  82. package/src/api/BaseMethod.ts +82 -2
  83. package/src/api/FirmwareUpdateV3.ts +0 -4
  84. package/src/api/FirmwareUpdateV4.ts +1 -19
  85. package/src/api/GetPassphraseState.ts +4 -3
  86. package/src/api/alephium/AlephiumSignMessage.ts +1 -0
  87. package/src/api/alephium/AlephiumSignTransaction.ts +1 -0
  88. package/src/api/algo/AlgoSignTransaction.ts +1 -0
  89. package/src/api/allnetwork/AllNetworkGetAddressBase.ts +8 -0
  90. package/src/api/aptos/AptosSignInMessage.ts +1 -0
  91. package/src/api/aptos/AptosSignMessage.ts +1 -0
  92. package/src/api/aptos/AptosSignTransaction.ts +1 -0
  93. package/src/api/benfen/BenfenSignMessage.ts +1 -0
  94. package/src/api/benfen/BenfenSignTransaction.ts +1 -0
  95. package/src/api/btc/BTCSignMessage.ts +1 -0
  96. package/src/api/btc/BTCSignPsbt.ts +1 -0
  97. package/src/api/btc/BTCSignTransaction.ts +1 -0
  98. package/src/api/cardano/CardanoSignMessage.ts +1 -0
  99. package/src/api/cardano/CardanoSignTransaction.ts +1 -0
  100. package/src/api/conflux/ConfluxSignMessage.ts +1 -0
  101. package/src/api/conflux/ConfluxSignMessageCIP23.ts +1 -0
  102. package/src/api/conflux/ConfluxSignTransaction.ts +1 -0
  103. package/src/api/cosmos/CosmosSignTransaction.ts +1 -0
  104. package/src/api/device/PreInitialize.ts +41 -0
  105. package/src/api/dynex/DnxSignTransaction.ts +1 -0
  106. package/src/api/evm/EVMSignMessage.ts +2 -0
  107. package/src/api/evm/EVMSignMessageEIP712.ts +1 -0
  108. package/src/api/evm/EVMSignTransaction.ts +2 -0
  109. package/src/api/evm/EVMSignTypedData.ts +2 -0
  110. package/src/api/filecoin/FilecoinSignTransaction.ts +1 -0
  111. package/src/api/firmware/FirmwareUpdateBaseMethod.ts +4 -27
  112. package/src/api/index.ts +1 -0
  113. package/src/api/kaspa/KaspaSignTransaction.ts +1 -0
  114. package/src/api/near/NearSignTransaction.ts +1 -0
  115. package/src/api/nem/NEMSignTransaction.ts +1 -0
  116. package/src/api/neo/NeoSignTransaction.ts +1 -0
  117. package/src/api/nervos/NervosSignTransaction.ts +1 -0
  118. package/src/api/nexa/NexaSignTransaction.ts +2 -0
  119. package/src/api/nostr/NostrSignEvent.ts +1 -0
  120. package/src/api/nostr/NostrSignSchnorr.ts +1 -0
  121. package/src/api/polkadot/PolkadotSignTransaction.ts +1 -0
  122. package/src/api/scdo/ScdoSignMessage.ts +1 -0
  123. package/src/api/scdo/ScdoSignTransaction.ts +1 -0
  124. package/src/api/solana/SolSignMessage.ts +1 -0
  125. package/src/api/solana/SolSignOffchainMessage.ts +1 -0
  126. package/src/api/solana/SolSignTransaction.ts +1 -0
  127. package/src/api/starcoin/StarcoinSignMessage.ts +1 -0
  128. package/src/api/starcoin/StarcoinSignTransaction.ts +1 -0
  129. package/src/api/stellar/StellarSignTransaction.ts +1 -0
  130. package/src/api/sui/SuiSignMessage.ts +1 -0
  131. package/src/api/sui/SuiSignTransaction.ts +1 -0
  132. package/src/api/ton/TonSignData.ts +1 -0
  133. package/src/api/ton/TonSignMessage.ts +1 -0
  134. package/src/api/ton/TonSignProof.ts +1 -0
  135. package/src/api/tron/TronSignMessage.ts +1 -0
  136. package/src/api/tron/TronSignTransaction.ts +1 -0
  137. package/src/api/xrp/XrpSignTransaction.ts +1 -0
  138. package/src/core/PollingStateManager.ts +47 -0
  139. package/src/core/RequestQueue.ts +10 -3
  140. package/src/core/index.ts +153 -34
  141. package/src/device/Device.ts +71 -18
  142. package/src/inject.ts +1 -1
  143. package/src/types/api/index.ts +2 -0
  144. package/src/types/api/preInitialize.ts +3 -0
  145. package/src/types/params.ts +5 -0
  146. package/src/utils/deviceFeaturesUtils.ts +8 -17
@@ -14,6 +14,7 @@ export default class EVMSignMessageEIP712 extends BaseMethod<EthereumSignMessage
14
14
  init() {
15
15
  this.checkDeviceId = true;
16
16
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
17
+ this.allowUsePreInitialize = true;
17
18
 
18
19
  validateParams(this.payload, [
19
20
  { name: 'path', required: true },
@@ -46,10 +46,12 @@ export default class EVMSignTransaction extends BaseMethod {
46
46
  init() {
47
47
  this.checkDeviceId = true;
48
48
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
49
+ this.allowUsePreInitialize = true;
49
50
 
50
51
  validateParams(this.payload, [
51
52
  { name: 'path', required: true },
52
53
  { name: 'transaction', type: 'object', required: true },
54
+ { name: 'usePreInitialize', type: 'boolean' },
53
55
  ]);
54
56
  const { path, transaction } = this.payload;
55
57
  this.addressN = validatePath(path, 3);
@@ -52,6 +52,7 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
52
52
  init() {
53
53
  this.checkDeviceId = true;
54
54
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
55
+ this.allowUsePreInitialize = true;
55
56
 
56
57
  validateParams(this.payload, [
57
58
  { name: 'path', required: true },
@@ -60,6 +61,7 @@ export default class EVMSignTypedData extends BaseMethod<EVMSignTypedDataParams>
60
61
  { name: 'domainHash', type: 'hexString' },
61
62
  { name: 'messageHash', type: 'hexString' },
62
63
  { name: 'chainId', type: 'number' },
64
+ { name: 'usePreInitialize', type: 'boolean' },
63
65
  ]);
64
66
 
65
67
  const { path, data, metamaskV4Compat, domainHash, messageHash, chainId } = this.payload;
@@ -12,6 +12,7 @@ export default class FilecoinSignTransaction extends BaseMethod<HardwareFilecoin
12
12
  init() {
13
13
  this.checkDeviceId = true;
14
14
  this.allowDeviceMode = [...this.allowDeviceMode];
15
+ this.allowUsePreInitialize = true;
15
16
 
16
17
  // check payload
17
18
  validateParams(this.payload, [
@@ -28,13 +28,6 @@ const Log = getLogger(LoggerNames.Method);
28
28
  const SESSION_ERROR = 'session not found';
29
29
  const FIRMWARE_UPDATE_CONFIRM = 'Firmware install confirmed';
30
30
 
31
- type FirmwareProgressMetadata = {
32
- transferredBytes?: number;
33
- totalBytes?: number;
34
- rateBytesPerSecond?: number;
35
- elapsedMs?: number;
36
- };
37
-
38
31
  const isDeviceDisconnectedError = (error: unknown) => {
39
32
  const message = error instanceof Error ? error.message : String(error ?? '');
40
33
  return (
@@ -89,17 +82,12 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
89
82
  * @description Post the progress message
90
83
  * @param progress Post the percentage of the progress
91
84
  */
92
- postProgressMessage = (
93
- progress: number,
94
- progressType: IFirmwareUpdateProgressType,
95
- metadata: FirmwareProgressMetadata = {}
96
- ) => {
85
+ postProgressMessage = (progress: number, progressType: IFirmwareUpdateProgressType) => {
97
86
  this.postMessage(
98
87
  createUiMessage(UI_REQUEST.FIRMWARE_PROGRESS, {
99
88
  device: this.device.toMessageObject() as KnownDevice,
100
89
  progress,
101
90
  progressType,
102
- ...metadata,
103
91
  })
104
92
  );
105
93
  };
@@ -337,12 +325,10 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
337
325
  filePath,
338
326
  processedSize,
339
327
  totalSize,
340
- transferStartTime = Date.now(),
341
328
  }: PROTO.FirmwareUpload & {
342
329
  filePath: string;
343
330
  processedSize?: number;
344
331
  totalSize?: number;
345
- transferStartTime?: number;
346
332
  }) {
347
333
  if (!filePath.startsWith('0:')) {
348
334
  throw new Error('filePath must start with 0:');
@@ -352,6 +338,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
352
338
  const chunkSize = 1024 * perPackageSize;
353
339
  const totalChunks = Math.ceil(payload.byteLength / chunkSize);
354
340
  let offset = 0;
341
+ let currentFileProcessed = 0;
355
342
 
356
343
  for (let i = 0; i < totalChunks; i++) {
357
344
  const chunkStart = i * chunkSize;
@@ -363,7 +350,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
363
350
  // Calculate progress based on whether we're tracking overall progress or single file progress
364
351
  let progress: number;
365
352
  if (totalSize !== undefined && processedSize !== undefined) {
366
- const currentFileProcessed = processedSize + chunkEnd;
353
+ currentFileProcessed = processedSize + chunkEnd;
367
354
  progress = Math.min(Math.ceil((currentFileProcessed / totalSize) * 100), 99);
368
355
  } else {
369
356
  progress = Math.min(Math.ceil(((i + 1) / totalChunks) * 100), 99);
@@ -379,17 +366,7 @@ export class FirmwareUpdateBaseMethod<Params> extends BaseMethod<Params> {
379
366
  );
380
367
  // @ts-expect-error
381
368
  offset += writeRes.message.processed_byte;
382
- const elapsedMs = Date.now() - transferStartTime;
383
- const transferredBytes =
384
- totalSize !== undefined && processedSize !== undefined ? processedSize + offset : offset;
385
- const totalBytes = totalSize ?? payload.byteLength;
386
- this.postProgressMessage(progress, 'transferData', {
387
- transferredBytes,
388
- totalBytes,
389
- rateBytesPerSecond:
390
- elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
391
- elapsedMs,
392
- });
369
+ this.postProgressMessage(progress, 'transferData');
393
370
  }
394
371
 
395
372
  // Return processed size only if we're tracking overall progress
package/src/api/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { default as testInitializeDeviceDuration } from './test/TestInitializeDeviceDuration';
2
+ export { default as preInitialize } from './device/PreInitialize';
2
3
 
3
4
  export { default as searchDevices } from './SearchDevices';
4
5
  export { default as getFeatures } from './GetFeatures';
@@ -22,6 +22,7 @@ export default class KaspaSignTransaction extends BaseMethod<KaspaSignTransactio
22
22
  init() {
23
23
  this.checkDeviceId = true;
24
24
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
25
+ this.allowUsePreInitialize = true;
25
26
 
26
27
  const payload = this.payload as KaspaSignTransactionParams;
27
28
 
@@ -10,6 +10,7 @@ export default class NearSignTransaction extends BaseMethod<HardwareNearSignTx>
10
10
  init() {
11
11
  this.checkDeviceId = true;
12
12
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
13
+ this.allowUsePreInitialize = true;
13
14
 
14
15
  // check payload
15
16
  validateParams(this.payload, [
@@ -230,6 +230,7 @@ export default class NEMSignTransaction extends BaseMethod<NEMSignTx> {
230
230
  init() {
231
231
  this.checkDeviceId = true;
232
232
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
233
+ this.allowUsePreInitialize = true;
233
234
 
234
235
  validateParams(this.payload, [
235
236
  { name: 'path', required: true },
@@ -11,6 +11,7 @@ export default class NeoSignTransaction extends BaseMethod<NeoSignTx> {
11
11
  init() {
12
12
  this.checkDeviceId = true;
13
13
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
14
+ this.allowUsePreInitialize = true;
14
15
  this.strictCheckDeviceSupport = true;
15
16
 
16
17
  validateParams(this.payload, [
@@ -19,6 +19,7 @@ export default class NervosSignTransaction extends BaseMethod<NervosSignTx> {
19
19
  init() {
20
20
  this.checkDeviceId = true;
21
21
  this.allowDeviceMode = [...this.allowDeviceMode];
22
+ this.allowUsePreInitialize = true;
22
23
 
23
24
  // check payload
24
25
  validateParams(this.payload, [
@@ -12,6 +12,8 @@ export default class NexaSignTransaction extends BaseMethod<NexaSignTransactionP
12
12
  hasBundle = false;
13
13
 
14
14
  init() {
15
+ this.allowUsePreInitialize = true;
16
+
15
17
  const payload = this.payload as NexaSignTransactionParams;
16
18
 
17
19
  payload.inputs.forEach(input => {
@@ -15,6 +15,7 @@ export default class NostrSignEvent extends BaseMethod<SignEvent> {
15
15
  init() {
16
16
  this.checkDeviceId = true;
17
17
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
18
+ this.allowUsePreInitialize = true;
18
19
 
19
20
  const { payload } = this;
20
21
  if (!validateEvent(payload.event)) {
@@ -11,6 +11,7 @@ export default class NostrSignSchnorr extends BaseMethod<SignSchnorr> {
11
11
  init() {
12
12
  this.checkDeviceId = true;
13
13
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
14
+ this.allowUsePreInitialize = true;
14
15
 
15
16
  const { payload } = this;
16
17
  validateParams(payload, [
@@ -13,6 +13,7 @@ export default class PolkadotSignTransaction extends BaseMethod<HardwarePolkadot
13
13
  init() {
14
14
  this.checkDeviceId = true;
15
15
  this.allowDeviceMode = [...this.allowDeviceMode];
16
+ this.allowUsePreInitialize = true;
16
17
 
17
18
  // check payload
18
19
  validateParams(this.payload, [
@@ -11,6 +11,7 @@ export default class ScdoSignMessage extends BaseMethod<HardwareScdoSignMessage>
11
11
  init() {
12
12
  this.checkDeviceId = true;
13
13
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
14
+ this.allowUsePreInitialize = true;
14
15
 
15
16
  // check payload
16
17
  validateParams(this.payload, [
@@ -18,6 +18,7 @@ export default class ScdoSignTransaction extends BaseMethod<HardwareScdoSignTx>
18
18
  init() {
19
19
  this.checkDeviceId = true;
20
20
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
21
+ this.allowUsePreInitialize = true;
21
22
 
22
23
  // check payload
23
24
  validateParams(this.payload, [
@@ -10,6 +10,7 @@ export default class SolSignMessage extends BaseMethod<HardwareSolSignUnsafeMess
10
10
  init() {
11
11
  this.checkDeviceId = true;
12
12
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
13
+ this.allowUsePreInitialize = true;
13
14
 
14
15
  // check payload
15
16
  validateParams(this.payload, [
@@ -10,6 +10,7 @@ export default class SolSignOffchainMessage extends BaseMethod<HardwareSolSignOf
10
10
  init() {
11
11
  this.checkDeviceId = true;
12
12
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
13
+ this.allowUsePreInitialize = true;
13
14
 
14
15
  // check payload
15
16
  validateParams(this.payload, [
@@ -13,6 +13,7 @@ export default class SolSignTransaction extends BaseMethod<HardwareSolanaSignTx[
13
13
  init() {
14
14
  this.checkDeviceId = true;
15
15
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
16
+ this.allowUsePreInitialize = true;
16
17
 
17
18
  this.hasBundle = !!this.payload?.bundle;
18
19
  const payload = this.hasBundle ? this.payload : { bundle: [this.payload] };
@@ -10,6 +10,7 @@ export default class StarcoinSignMessage extends BaseMethod<HardwareStarcoinSign
10
10
  init() {
11
11
  this.checkDeviceId = true;
12
12
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
13
+ this.allowUsePreInitialize = true;
13
14
 
14
15
  // check payload
15
16
  validateParams(this.payload, [
@@ -10,6 +10,7 @@ export default class StarcoinSignTransaction extends BaseMethod<StarcoinSignTx>
10
10
  init() {
11
11
  this.checkDeviceId = true;
12
12
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
13
+ this.allowUsePreInitialize = true;
13
14
 
14
15
  // check payload
15
16
  validateParams(this.payload, [
@@ -231,6 +231,7 @@ export default class StellarSignTransaction extends BaseMethod<HardwareStellarSi
231
231
  init() {
232
232
  this.checkDeviceId = true;
233
233
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
234
+ this.allowUsePreInitialize = true;
234
235
 
235
236
  // check payload
236
237
  validateParams(this.payload, [
@@ -10,6 +10,7 @@ export default class SuiSignMessage extends BaseMethod<HardwareSuiSignMessage> {
10
10
  init() {
11
11
  this.checkDeviceId = true;
12
12
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
13
+ this.allowUsePreInitialize = true;
13
14
 
14
15
  // check payload
15
16
  validateParams(this.payload, [
@@ -19,6 +19,7 @@ export default class SuiSignTransaction extends BaseMethod<SuiSignTx> {
19
19
  init() {
20
20
  this.checkDeviceId = true;
21
21
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
22
+ this.allowUsePreInitialize = true;
22
23
 
23
24
  // check payload
24
25
  validateParams(this.payload, [
@@ -14,6 +14,7 @@ export default class TonSignData extends BaseMethod<HardwareTonSignData> {
14
14
  this.strictCheckDeviceSupport = false;
15
15
  this.checkDeviceId = true;
16
16
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
17
+ this.allowUsePreInitialize = true;
17
18
 
18
19
  validateParams(this.payload, [
19
20
  { name: 'path', required: true },
@@ -26,6 +26,7 @@ export default class TonSignMessage extends BaseMethod<HardwareTonSignMessage> {
26
26
  this.strictCheckDeviceSupport = true;
27
27
  this.checkDeviceId = true;
28
28
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
29
+ this.allowUsePreInitialize = true;
29
30
 
30
31
  // init params
31
32
  validateParams(this.payload, [
@@ -11,6 +11,7 @@ export default class TonSignProof extends BaseMethod<HardwareTonSignProof> {
11
11
  this.strictCheckDeviceSupport = true;
12
12
  this.checkDeviceId = true;
13
13
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
14
+ this.allowUsePreInitialize = true;
14
15
 
15
16
  // init params
16
17
  validateParams(this.payload, [
@@ -14,6 +14,7 @@ export default class TronSignMessage extends BaseMethod<HardwareTronSignMessage>
14
14
  init() {
15
15
  this.checkDeviceId = true;
16
16
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
17
+ this.allowUsePreInitialize = true;
17
18
 
18
19
  // check payload
19
20
  validateParams(this.payload, [
@@ -123,6 +123,7 @@ export default class TronSignTransaction extends BaseMethod<TronSignTx> {
123
123
  init() {
124
124
  this.checkDeviceId = true;
125
125
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
126
+ this.allowUsePreInitialize = true;
126
127
 
127
128
  // check payload
128
129
  validateParams(this.payload, [
@@ -11,6 +11,7 @@ export default class XrpGetAddress extends BaseMethod<XrpSignTransactionParams>
11
11
  init() {
12
12
  this.checkDeviceId = true;
13
13
  this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
14
+ this.allowUsePreInitialize = true;
14
15
 
15
16
  const { payload } = this;
16
17
  validateParams(payload, [
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Manages polling state for device connection attempts.
3
+ *
4
+ * Polling is isolated by connectId (device), so:
5
+ * - New request for device A only stops device A's previous polling
6
+ * - Device B's polling is unaffected
7
+ */
8
+ export class PollingStateManager {
9
+ // connectId -> current polling ID
10
+ private activePolls = new Map<string, number>();
11
+
12
+ /**
13
+ * Start a new polling session for a device.
14
+ * Automatically stops the previous polling for the same device.
15
+ * @param connectId - Device identifier (use empty string for USB without connectId)
16
+ * @returns The new polling ID
17
+ */
18
+ start(connectId: string): number {
19
+ const currentId = (this.activePolls.get(connectId) ?? 0) + 1;
20
+ this.activePolls.set(connectId, currentId);
21
+ return currentId;
22
+ }
23
+
24
+ /**
25
+ * Check if a polling session is still active.
26
+ * @param connectId - Device identifier
27
+ * @param pollingId - The polling ID to check
28
+ */
29
+ isActive(connectId: string, pollingId: number): boolean {
30
+ return this.activePolls.get(connectId) === pollingId;
31
+ }
32
+
33
+ /**
34
+ * Stop polling for a specific device.
35
+ * @param connectId - Device identifier
36
+ */
37
+ stop(connectId: string): void {
38
+ this.activePolls.delete(connectId);
39
+ }
40
+
41
+ /**
42
+ * Stop all active polling sessions.
43
+ */
44
+ stopAll(): void {
45
+ this.activePolls.clear();
46
+ }
47
+ }
@@ -113,13 +113,20 @@ export default class RequestQueue {
113
113
 
114
114
  callbackPromise.promise.finally(() => {
115
115
  Log.debug(`Callback task completed for connectId: ${connectId}`);
116
- this.pendingCallbackTasks.delete(connectId);
116
+ // Delete by identity so a newer task that replaced this slot isn't orphaned.
117
+ if (this.pendingCallbackTasks.get(connectId) === callbackPromise) {
118
+ this.pendingCallbackTasks.delete(connectId);
119
+ }
117
120
  });
118
121
  }
119
122
 
120
- public async waitForPendingCallbackTasks(connectId: string): Promise<void> {
123
+ public async waitForPendingCallbackTasks(
124
+ connectId: string,
125
+ exceptTask?: Deferred<void>
126
+ ): Promise<void> {
121
127
  const pendingTask = this.pendingCallbackTasks.get(connectId);
122
- if (pendingTask) {
128
+ // Skip only the caller's own task (self-wait); a different one is still awaited.
129
+ if (pendingTask && pendingTask !== exceptTask) {
123
130
  Log.debug(`Waiting for pending callback task to complete for connectId: ${connectId}`);
124
131
  await pendingTask.promise;
125
132
  }