@onekeyfe/hwk-adapter-core 1.2.3-alpha.1 → 1.2.3-alpha.3
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/dist/{chunk-72KOSYTH.mjs → chunk-E3UPXUN5.mjs} +15 -11
- package/dist/chunk-E3UPXUN5.mjs.map +1 -0
- package/dist/{chunk-KCIK56B5.mjs → chunk-ELC6PLKH.mjs} +2 -2
- package/dist/chunk-ELC6PLKH.mjs.map +1 -0
- package/dist/{chunk-RRCFH7X6.js → chunk-S7X2HM7P.js} +3 -3
- package/dist/chunk-S7X2HM7P.js.map +1 -0
- package/dist/{chunk-IZEVYMJK.js → chunk-Z3IH25KV.js} +15 -11
- package/dist/chunk-Z3IH25KV.js.map +1 -0
- package/dist/{errors-ChA_YEZY.d.ts → errors-C5GWtyVN.d.mts} +17 -9
- package/dist/{errors-ChA_YEZY.d.mts → errors-C5GWtyVN.d.ts} +17 -9
- package/dist/errors.d.mts +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +2 -2
- package/dist/errors.mjs +1 -1
- package/dist/index.d.mts +134 -135
- package/dist/index.d.ts +134 -135
- package/dist/index.js +174 -181
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +144 -151
- package/dist/index.mjs.map +1 -1
- package/dist/{ui-events-BXI9BBpx.d.ts → ui-events-CbZdnS8a.d.mts} +10 -1
- package/dist/{ui-events-BXI9BBpx.d.mts → ui-events-CbZdnS8a.d.ts} +10 -1
- package/dist/ui-events.d.mts +1 -1
- package/dist/ui-events.d.ts +1 -1
- package/dist/ui-events.js +3 -3
- package/dist/ui-events.mjs +2 -2
- package/package.json +2 -2
- package/dist/chunk-72KOSYTH.mjs.map +0 -1
- package/dist/chunk-IZEVYMJK.js.map +0 -1
- package/dist/chunk-KCIK56B5.mjs.map +0 -1
- package/dist/chunk-RRCFH7X6.js.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
UI_REQUEST_TIMEOUT_TAG,
|
|
11
11
|
UI_RESPONSE,
|
|
12
12
|
UiRequestRegistry
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-ELC6PLKH.mjs";
|
|
14
14
|
import {
|
|
15
15
|
HardwareErrorCode,
|
|
16
16
|
ORPHAN_ELIGIBLE_ERROR_CODES,
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
defaultRecoveryForCode,
|
|
20
20
|
isHwkRecoveryHint,
|
|
21
21
|
operationMayHaveCompletedParams
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-E3UPXUN5.mjs";
|
|
23
23
|
|
|
24
24
|
// src/types/response.ts
|
|
25
25
|
function success(payload) {
|
|
@@ -76,10 +76,6 @@ var DEVICE = {
|
|
|
76
76
|
DISCONNECT: "device-disconnect",
|
|
77
77
|
CHANGED: "device-changed",
|
|
78
78
|
FEATURES: "features",
|
|
79
|
-
/** Trezor transport binding, emitted only after matching the expected firmware device_id. */
|
|
80
|
-
TREZOR_CONNECTION_VERIFIED: "device-trezor-connection-verified",
|
|
81
|
-
/** Ledger BLE address repair, emitted only after matching the stored chain fingerprint. */
|
|
82
|
-
LEDGER_CONNECTION_VERIFIED: "device-ledger-connection-verified",
|
|
83
79
|
/**
|
|
84
80
|
* Trezor-only. Emitted after a successful THP handshake that minted or
|
|
85
81
|
* refreshed pairing credentials. The host should persist `credentials`
|
|
@@ -99,7 +95,7 @@ var SDK = {
|
|
|
99
95
|
DEVICE_UNRESPONSIVE: "device-unresponsive",
|
|
100
96
|
DEVICE_RECOVERED: "device-recovered",
|
|
101
97
|
DEVICE_INTERACTION: "device-interaction",
|
|
102
|
-
|
|
98
|
+
OPERATION_ENDED: "operation-ended"
|
|
103
99
|
};
|
|
104
100
|
|
|
105
101
|
// src/utils/DeviceJobQueue.ts
|
|
@@ -130,12 +126,13 @@ var DeviceJobQueue = class {
|
|
|
130
126
|
abortController: ac,
|
|
131
127
|
startedAt: Date.now()
|
|
132
128
|
};
|
|
133
|
-
this._jobs.set(jobToken,
|
|
129
|
+
this._jobs.set(jobToken, activeJob);
|
|
134
130
|
const next = prev.catch(() => {
|
|
135
131
|
}).then(async () => {
|
|
136
132
|
if (this._generation !== gen) {
|
|
137
133
|
throw this._generationCancelReasons.get(gen) ?? new Error("Job cancelled: queue was cleared");
|
|
138
134
|
}
|
|
135
|
+
if (ac.signal.aborted) throw ac.signal.reason;
|
|
139
136
|
this._active = activeJob;
|
|
140
137
|
try {
|
|
141
138
|
return await job(ac.signal);
|
|
@@ -151,31 +148,27 @@ var DeviceJobQueue = class {
|
|
|
151
148
|
});
|
|
152
149
|
return next;
|
|
153
150
|
}
|
|
154
|
-
/** Cancel the
|
|
155
|
-
cancelActive(deviceId) {
|
|
151
|
+
/** Cancel the running job. `reason` becomes signal.reason. */
|
|
152
|
+
cancelActive(deviceId, reason) {
|
|
156
153
|
if (!this._active) return false;
|
|
157
154
|
if (deviceId && this._active.deviceId !== deviceId) return false;
|
|
158
|
-
this._active.abortController.abort(new Error("
|
|
155
|
+
this._active.abortController.abort(reason ?? new Error("Cancelled"));
|
|
159
156
|
return true;
|
|
160
157
|
}
|
|
161
|
-
/** Force cancel the active job. `reason` becomes signal.reason. */
|
|
162
|
-
forceCancelActive(deviceId, reason) {
|
|
163
|
-
if (!this._active) return false;
|
|
164
|
-
if (deviceId && this._active.deviceId !== deviceId) return false;
|
|
165
|
-
this._active.abortController.abort(reason ?? new Error("Force cancelled for recovery"));
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
/** Cancel the active job (alias for callers that previously needed multi-device cancel). */
|
|
169
|
-
cancelAllActive(reason) {
|
|
170
|
-
if (!this._active) return;
|
|
171
|
-
this._active.abortController.abort(reason ?? new Error("Cancelled by cancelAllActive"));
|
|
172
|
-
}
|
|
173
158
|
/** Cancel the active job and invalidate queued jobs that have not started. */
|
|
174
159
|
cancelActiveAndPending(deviceId, reason) {
|
|
175
|
-
|
|
176
|
-
|
|
160
|
+
const cancelReason = reason ?? new Error("Cancelled by cancelActiveAndPending");
|
|
161
|
+
if (deviceId) {
|
|
162
|
+
let cancelled = false;
|
|
163
|
+
for (const job of this._jobs.values()) {
|
|
164
|
+
if (job.deviceId === deviceId) {
|
|
165
|
+
job.abortController.abort(cancelReason);
|
|
166
|
+
cancelled = true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return cancelled;
|
|
177
170
|
}
|
|
178
|
-
this.clear(
|
|
171
|
+
this.clear(cancelReason);
|
|
179
172
|
return true;
|
|
180
173
|
}
|
|
181
174
|
/** Get info about the currently active job, or null if idle. */
|
|
@@ -188,10 +181,6 @@ var DeviceJobQueue = class {
|
|
|
188
181
|
startedAt: this._active.startedAt
|
|
189
182
|
};
|
|
190
183
|
}
|
|
191
|
-
/** True if any job is currently running. */
|
|
192
|
-
isBusy() {
|
|
193
|
-
return this._jobs.size > 0;
|
|
194
|
-
}
|
|
195
184
|
clear(reason) {
|
|
196
185
|
const cancelledGeneration = this._generation;
|
|
197
186
|
this._generation++;
|
|
@@ -210,22 +199,28 @@ var DeviceJobQueue = class {
|
|
|
210
199
|
|
|
211
200
|
// src/utils/hardwareRuntimeId.ts
|
|
212
201
|
import { bytesToHex as bytesToHex2, randomBytes } from "@noble/hashes/utils";
|
|
213
|
-
var HARDWARE_RUNTIME_ID_PREFIX = "hwk:runtime
|
|
202
|
+
var HARDWARE_RUNTIME_ID_PREFIX = "hwk:runtime";
|
|
214
203
|
var RANDOM_ID_BYTES = 16;
|
|
215
204
|
var RANDOM_ID_PATTERN = /^[0-9a-f]{32}$/;
|
|
205
|
+
var KINDS = /* @__PURE__ */ new Set([
|
|
206
|
+
"operation",
|
|
207
|
+
"search-target",
|
|
208
|
+
"link"
|
|
209
|
+
]);
|
|
216
210
|
var VENDORS = /* @__PURE__ */ new Set(["trezor", "ledger", "keystone"]);
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
211
|
+
function create(kind, vendor) {
|
|
212
|
+
return `${HARDWARE_RUNTIME_ID_PREFIX}:${kind}:${vendor}:${bytesToHex2(
|
|
213
|
+
randomBytes(RANDOM_ID_BYTES)
|
|
214
|
+
)}`;
|
|
220
215
|
}
|
|
221
|
-
function
|
|
222
|
-
return
|
|
216
|
+
function createHardwareOperationId(vendor) {
|
|
217
|
+
return create("operation", vendor);
|
|
223
218
|
}
|
|
224
|
-
function createHardwareSearchTargetId(
|
|
225
|
-
return
|
|
219
|
+
function createHardwareSearchTargetId(vendor) {
|
|
220
|
+
return create("search-target", vendor);
|
|
226
221
|
}
|
|
227
|
-
function
|
|
228
|
-
return
|
|
222
|
+
function createHardwareLinkId(vendor) {
|
|
223
|
+
return create("link", vendor);
|
|
229
224
|
}
|
|
230
225
|
function hasHardwareRuntimeIdPrefix(value) {
|
|
231
226
|
return typeof value === "string" && value.startsWith(`${HARDWARE_RUNTIME_ID_PREFIX}:`);
|
|
@@ -233,50 +228,32 @@ function hasHardwareRuntimeIdPrefix(value) {
|
|
|
233
228
|
function parseHardwareRuntimeId(value) {
|
|
234
229
|
if (!hasHardwareRuntimeIdPrefix(value)) return void 0;
|
|
235
230
|
const parts = value.split(":");
|
|
236
|
-
|
|
237
|
-
const vendor = parts
|
|
238
|
-
if (!VENDORS.has(vendor)
|
|
239
|
-
|
|
240
|
-
return {
|
|
241
|
-
kind,
|
|
242
|
-
vendor,
|
|
243
|
-
nonce: parts[5]
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
const connectionType = parts[5];
|
|
247
|
-
if ((kind === "search-target" || kind === "connector-session") && parts.length === 7 && CONNECTION_TYPES.has(connectionType) && RANDOM_ID_PATTERN.test(parts[6])) {
|
|
248
|
-
return {
|
|
249
|
-
kind,
|
|
250
|
-
vendor,
|
|
251
|
-
connectionType,
|
|
252
|
-
nonce: parts[6]
|
|
253
|
-
};
|
|
231
|
+
if (parts.length !== 5) return void 0;
|
|
232
|
+
const [, , kind, vendor, nonce] = parts;
|
|
233
|
+
if (!KINDS.has(kind) || !VENDORS.has(vendor) || !RANDOM_ID_PATTERN.test(nonce)) {
|
|
234
|
+
return void 0;
|
|
254
235
|
}
|
|
255
|
-
return
|
|
256
|
-
}
|
|
257
|
-
function isHardwareInteractionId(value) {
|
|
258
|
-
return parseHardwareRuntimeId(value)?.kind === "interaction";
|
|
236
|
+
return { kind, vendor };
|
|
259
237
|
}
|
|
260
|
-
function
|
|
261
|
-
return parseHardwareRuntimeId(value)?.kind === "
|
|
238
|
+
function isHardwareOperationId(value) {
|
|
239
|
+
return parseHardwareRuntimeId(value)?.kind === "operation";
|
|
262
240
|
}
|
|
263
241
|
|
|
264
|
-
// src/utils/
|
|
265
|
-
var
|
|
266
|
-
var
|
|
242
|
+
// src/utils/OperationRegistry.ts
|
|
243
|
+
var OPERATION_DEFAULT_TTL_MS = 6e5;
|
|
244
|
+
var OperationRegistry = class {
|
|
267
245
|
constructor(options) {
|
|
268
246
|
this._active = /* @__PURE__ */ new Map();
|
|
269
247
|
this._ended = /* @__PURE__ */ new Map();
|
|
270
248
|
this._vendor = options.vendor;
|
|
271
|
-
this._ttlMs = options.ttlMs ??
|
|
249
|
+
this._ttlMs = options.ttlMs ?? OPERATION_DEFAULT_TTL_MS;
|
|
272
250
|
this._onEnded = options.onEnded;
|
|
273
251
|
}
|
|
274
252
|
create(params) {
|
|
275
253
|
const now = Date.now();
|
|
276
|
-
const
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
searchTargetId: params.searchTargetId,
|
|
254
|
+
const operationId = createHardwareOperationId(this._vendor);
|
|
255
|
+
const operation = {
|
|
256
|
+
operationId,
|
|
280
257
|
connectId: params.connectId,
|
|
281
258
|
device: params.device,
|
|
282
259
|
connectionKeys: Array.from(
|
|
@@ -289,35 +266,35 @@ var InteractionRegistry = class {
|
|
|
289
266
|
createdAt: now,
|
|
290
267
|
lastActiveAt: now
|
|
291
268
|
};
|
|
292
|
-
const timer = this._createTimer(
|
|
293
|
-
this._active.set(
|
|
294
|
-
return
|
|
269
|
+
const timer = this._createTimer(operationId);
|
|
270
|
+
this._active.set(operationId, { ...operation, timer, retainCount: 0 });
|
|
271
|
+
return operation;
|
|
295
272
|
}
|
|
296
|
-
resolve(
|
|
297
|
-
const active = this._active.get(
|
|
273
|
+
resolve(operationId) {
|
|
274
|
+
const active = this._active.get(operationId);
|
|
298
275
|
if (!active) {
|
|
299
|
-
const ended = this._ended.get(
|
|
276
|
+
const ended = this._ended.get(operationId);
|
|
300
277
|
if (ended) {
|
|
301
278
|
throw createHwkError({
|
|
302
|
-
code: 10113 /*
|
|
303
|
-
message: `Hardware
|
|
304
|
-
params: {
|
|
279
|
+
code: 10113 /* OperationEnded */,
|
|
280
|
+
message: `Hardware operation has ended (${ended.reason})`,
|
|
281
|
+
params: { operationId, reason: ended.reason }
|
|
305
282
|
});
|
|
306
283
|
}
|
|
307
284
|
throw createHwkError({
|
|
308
|
-
code: 10112 /*
|
|
309
|
-
message: "Hardware
|
|
310
|
-
params: {
|
|
285
|
+
code: 10112 /* OperationNotFound */,
|
|
286
|
+
message: "Hardware operation was not found",
|
|
287
|
+
params: { operationId }
|
|
311
288
|
});
|
|
312
289
|
}
|
|
313
290
|
if (active.timer) clearTimeout(active.timer);
|
|
314
291
|
active.lastActiveAt = Date.now();
|
|
315
|
-
active.timer = active.retainCount === 0 ? this._createTimer(
|
|
292
|
+
active.timer = active.retainCount === 0 ? this._createTimer(operationId) : void 0;
|
|
316
293
|
return active;
|
|
317
294
|
}
|
|
318
|
-
/** Keep an
|
|
319
|
-
retain(
|
|
320
|
-
const active = this.resolve(
|
|
295
|
+
/** Keep an operation alive while one device job is actively using it. */
|
|
296
|
+
retain(operationId) {
|
|
297
|
+
const active = this.resolve(operationId);
|
|
321
298
|
if (active.timer) clearTimeout(active.timer);
|
|
322
299
|
active.timer = void 0;
|
|
323
300
|
active.retainCount += 1;
|
|
@@ -325,31 +302,31 @@ var InteractionRegistry = class {
|
|
|
325
302
|
return () => {
|
|
326
303
|
if (released) return;
|
|
327
304
|
released = true;
|
|
328
|
-
const current = this._active.get(
|
|
305
|
+
const current = this._active.get(operationId);
|
|
329
306
|
if (!current) return;
|
|
330
307
|
current.retainCount = Math.max(0, current.retainCount - 1);
|
|
331
308
|
current.lastActiveAt = Date.now();
|
|
332
309
|
if (current.retainCount === 0) {
|
|
333
|
-
current.timer = this._createTimer(
|
|
310
|
+
current.timer = this._createTimer(operationId);
|
|
334
311
|
}
|
|
335
312
|
};
|
|
336
313
|
}
|
|
337
314
|
/** Return active or tombstoned binding data without refreshing its TTL. */
|
|
338
|
-
find(
|
|
339
|
-
return this._active.get(
|
|
315
|
+
find(operationId) {
|
|
316
|
+
return this._active.get(operationId) ?? this._ended.get(operationId)?.operation;
|
|
340
317
|
}
|
|
341
318
|
findActiveByConnectionKey(connectionKey) {
|
|
342
319
|
if (!connectionKey) return void 0;
|
|
343
320
|
return [...this._active.values()].find(
|
|
344
|
-
(
|
|
321
|
+
(operation) => operation.connectionKeys.includes(connectionKey)
|
|
345
322
|
);
|
|
346
323
|
}
|
|
347
324
|
/** Replace the live transport binding after the same target was reconnected. */
|
|
348
|
-
rebind(
|
|
349
|
-
const active = this._active.get(
|
|
325
|
+
rebind(operationId, params) {
|
|
326
|
+
const active = this._active.get(operationId);
|
|
350
327
|
if (!active) {
|
|
351
|
-
this.resolve(
|
|
352
|
-
throw new Error("Unreachable
|
|
328
|
+
this.resolve(operationId);
|
|
329
|
+
throw new Error("Unreachable operation rebind");
|
|
353
330
|
}
|
|
354
331
|
if (active.timer) clearTimeout(active.timer);
|
|
355
332
|
active.connectId = params.connectId;
|
|
@@ -358,42 +335,42 @@ var InteractionRegistry = class {
|
|
|
358
335
|
new Set([params.connectId, ...params.connectionKeys ?? []].filter(Boolean))
|
|
359
336
|
);
|
|
360
337
|
active.lastActiveAt = Date.now();
|
|
361
|
-
active.timer = active.retainCount === 0 ? this._createTimer(
|
|
338
|
+
active.timer = active.retainCount === 0 ? this._createTimer(operationId) : void 0;
|
|
362
339
|
return active;
|
|
363
340
|
}
|
|
364
|
-
end(
|
|
365
|
-
const active = this._active.get(
|
|
341
|
+
end(operationId, reason) {
|
|
342
|
+
const active = this._active.get(operationId);
|
|
366
343
|
if (!active) return void 0;
|
|
367
344
|
if (active.timer) clearTimeout(active.timer);
|
|
368
|
-
this._active.delete(
|
|
345
|
+
this._active.delete(operationId);
|
|
369
346
|
this._rememberEnded(active, reason);
|
|
370
347
|
this._onEnded?.(active, reason);
|
|
371
348
|
return active;
|
|
372
349
|
}
|
|
373
|
-
endByConnectionKey(connectionKey, reason,
|
|
350
|
+
endByConnectionKey(connectionKey, reason, exceptOperationId) {
|
|
374
351
|
if (!connectionKey) return;
|
|
375
|
-
for (const
|
|
376
|
-
if (
|
|
377
|
-
if (
|
|
378
|
-
this.end(
|
|
352
|
+
for (const operation of [...this._active.values()]) {
|
|
353
|
+
if (operation.operationId === exceptOperationId) continue;
|
|
354
|
+
if (operation.connectionKeys.includes(connectionKey)) {
|
|
355
|
+
this.end(operation.operationId, reason);
|
|
379
356
|
}
|
|
380
357
|
}
|
|
381
358
|
}
|
|
382
|
-
endAll(reason,
|
|
383
|
-
for (const
|
|
384
|
-
if (
|
|
385
|
-
this.end(
|
|
359
|
+
endAll(reason, exceptOperationId) {
|
|
360
|
+
for (const operationId of [...this._active.keys()]) {
|
|
361
|
+
if (operationId === exceptOperationId) continue;
|
|
362
|
+
this.end(operationId, reason);
|
|
386
363
|
}
|
|
387
364
|
}
|
|
388
|
-
_createTimer(
|
|
365
|
+
_createTimer(operationId) {
|
|
389
366
|
const timer = setTimeout(() => {
|
|
390
|
-
this.end(
|
|
367
|
+
this.end(operationId, "timeout");
|
|
391
368
|
}, this._ttlMs);
|
|
392
369
|
timer.unref?.();
|
|
393
370
|
return timer;
|
|
394
371
|
}
|
|
395
|
-
_rememberEnded(
|
|
396
|
-
this._ended.set(
|
|
372
|
+
_rememberEnded(operation, reason) {
|
|
373
|
+
this._ended.set(operation.operationId, { reason, operation });
|
|
397
374
|
if (this._ended.size <= 100) return;
|
|
398
375
|
const oldest = this._ended.keys().next().value;
|
|
399
376
|
if (oldest) this._ended.delete(oldest);
|
|
@@ -401,40 +378,40 @@ var InteractionRegistry = class {
|
|
|
401
378
|
};
|
|
402
379
|
|
|
403
380
|
// src/utils/hardwareOperationTarget.ts
|
|
404
|
-
function resolveHardwareOperationTarget(positionalTargetId,
|
|
381
|
+
function resolveHardwareOperationTarget(positionalTargetId, commonOperationId, expectedVendor) {
|
|
405
382
|
const normalizedPositionalTargetId = positionalTargetId ?? void 0;
|
|
406
|
-
const
|
|
407
|
-
const
|
|
383
|
+
const normalizedCommonOperationId = commonOperationId || void 0;
|
|
384
|
+
const positionalOperationId = isHardwareOperationId(normalizedPositionalTargetId) ? normalizedPositionalTargetId : void 0;
|
|
408
385
|
const parsedPositionalTarget = parseHardwareRuntimeId(normalizedPositionalTargetId);
|
|
409
|
-
const
|
|
386
|
+
const parsedCommonOperation = parseHardwareRuntimeId(normalizedCommonOperationId);
|
|
410
387
|
if (normalizedPositionalTargetId && hasHardwareRuntimeIdPrefix(normalizedPositionalTargetId) && !parsedPositionalTarget) {
|
|
411
388
|
return failure(10002 /* InvalidParams */, "Invalid hardware operation target id");
|
|
412
389
|
}
|
|
413
|
-
if (parsedPositionalTarget?.kind === "
|
|
390
|
+
if (parsedPositionalTarget?.kind === "link") {
|
|
414
391
|
return failure(
|
|
415
392
|
10002 /* InvalidParams */,
|
|
416
|
-
"Hardware
|
|
393
|
+
"Hardware transport link id cannot be used as an operation target"
|
|
417
394
|
);
|
|
418
395
|
}
|
|
419
|
-
if (
|
|
420
|
-
return failure(10002 /* InvalidParams */, "Invalid hardware
|
|
396
|
+
if (normalizedCommonOperationId && parsedCommonOperation?.kind !== "operation") {
|
|
397
|
+
return failure(10002 /* InvalidParams */, "Invalid hardware operation id");
|
|
421
398
|
}
|
|
422
|
-
if (expectedVendor && (parsedPositionalTarget && parsedPositionalTarget.vendor !== expectedVendor ||
|
|
399
|
+
if (expectedVendor && (parsedPositionalTarget && parsedPositionalTarget.vendor !== expectedVendor || parsedCommonOperation && parsedCommonOperation.vendor !== expectedVendor)) {
|
|
423
400
|
return failure(
|
|
424
401
|
10002 /* InvalidParams */,
|
|
425
|
-
`Hardware
|
|
402
|
+
`Hardware operation does not belong to ${expectedVendor}`
|
|
426
403
|
);
|
|
427
404
|
}
|
|
428
|
-
if (
|
|
429
|
-
return failure(10002 /* InvalidParams */, "Conflicting hardware
|
|
430
|
-
|
|
431
|
-
|
|
405
|
+
if (positionalOperationId && normalizedCommonOperationId && positionalOperationId !== normalizedCommonOperationId) {
|
|
406
|
+
return failure(10002 /* InvalidParams */, "Conflicting hardware operation ids", {
|
|
407
|
+
positionalOperationId,
|
|
408
|
+
commonOperationId: normalizedCommonOperationId
|
|
432
409
|
});
|
|
433
410
|
}
|
|
434
|
-
const
|
|
411
|
+
const operationId = normalizedCommonOperationId ?? positionalOperationId;
|
|
435
412
|
return success({
|
|
436
|
-
|
|
437
|
-
targetId:
|
|
413
|
+
operationId,
|
|
414
|
+
targetId: operationId ?? normalizedPositionalTargetId
|
|
438
415
|
});
|
|
439
416
|
}
|
|
440
417
|
|
|
@@ -815,7 +792,16 @@ var TypedEventEmitter = class {
|
|
|
815
792
|
// src/utils/requestSaveDeviceBinding.ts
|
|
816
793
|
async function requestSaveDeviceBinding(emitter, registry, binding, signal) {
|
|
817
794
|
const type = UI_REQUEST.REQUEST_SAVE_DEVICE_BINDING;
|
|
818
|
-
|
|
795
|
+
const declined = (reason) => {
|
|
796
|
+
emitter.emit(UI_REQUEST.DEVICE_BINDING_STATUS, {
|
|
797
|
+
type: UI_REQUEST.DEVICE_BINDING_STATUS,
|
|
798
|
+
payload: { selectionRequestId: binding.selectionRequestId, status: "failed" }
|
|
799
|
+
});
|
|
800
|
+
return { saved: false, reason };
|
|
801
|
+
};
|
|
802
|
+
if (!emitter.listenerCount(type)) {
|
|
803
|
+
return declined("skipped");
|
|
804
|
+
}
|
|
819
805
|
if (signal?.aborted) throw signal.reason;
|
|
820
806
|
const requestId = registry.createRequestId();
|
|
821
807
|
const pending = registry.wait(type, { requestId });
|
|
@@ -827,16 +813,13 @@ async function requestSaveDeviceBinding(emitter, registry, binding, signal) {
|
|
|
827
813
|
const response = await pending;
|
|
828
814
|
if (signal?.aborted) throw signal.reason;
|
|
829
815
|
if (response?.saved !== true) {
|
|
830
|
-
|
|
831
|
-
code: 1e4 /* UnknownError */,
|
|
832
|
-
message: "Verified device binding could not be saved"
|
|
833
|
-
});
|
|
816
|
+
return declined(response?.reason ?? "skipped");
|
|
834
817
|
}
|
|
835
818
|
emitter.emit(UI_REQUEST.DEVICE_BINDING_STATUS, {
|
|
836
819
|
type: UI_REQUEST.DEVICE_BINDING_STATUS,
|
|
837
820
|
payload: { selectionRequestId: binding.selectionRequestId, status: "saved" }
|
|
838
821
|
});
|
|
839
|
-
return true;
|
|
822
|
+
return { saved: true };
|
|
840
823
|
} catch (error) {
|
|
841
824
|
emitter.emit(UI_REQUEST.DEVICE_BINDING_STATUS, {
|
|
842
825
|
type: UI_REQUEST.DEVICE_BINDING_STATUS,
|
|
@@ -845,7 +828,8 @@ async function requestSaveDeviceBinding(emitter, registry, binding, signal) {
|
|
|
845
828
|
status: signal?.aborted ? "cancelled" : "failed"
|
|
846
829
|
}
|
|
847
830
|
});
|
|
848
|
-
throw error;
|
|
831
|
+
if (signal?.aborted) throw error;
|
|
832
|
+
return { saved: false, reason: "skipped" };
|
|
849
833
|
} finally {
|
|
850
834
|
signal?.removeEventListener("abort", cancel);
|
|
851
835
|
registry.cancel(type, requestId);
|
|
@@ -859,6 +843,7 @@ async function requestBleDeviceSelection({
|
|
|
859
843
|
request,
|
|
860
844
|
scan,
|
|
861
845
|
signal,
|
|
846
|
+
allowUsbFallback = false,
|
|
862
847
|
pollIntervalMs = 1500
|
|
863
848
|
}) {
|
|
864
849
|
const type = UI_REQUEST.REQUEST_SELECT_DEVICE;
|
|
@@ -870,7 +855,8 @@ async function requestBleDeviceSelection({
|
|
|
870
855
|
});
|
|
871
856
|
}
|
|
872
857
|
const requestId = registry.createRequestId();
|
|
873
|
-
let
|
|
858
|
+
let devices = allowUsbFallback ? request.devices.filter((device) => device.connectionType === "ble") : request.devices;
|
|
859
|
+
const publishedDevices = /* @__PURE__ */ new Map();
|
|
874
860
|
let stopped = false;
|
|
875
861
|
let timer;
|
|
876
862
|
let wake;
|
|
@@ -887,10 +873,13 @@ async function requestBleDeviceSelection({
|
|
|
887
873
|
const cancel = () => registry.cancel(type, requestId);
|
|
888
874
|
const reply = registry.wait(type, { requestId }).finally(stop);
|
|
889
875
|
void reply.catch(() => void 0);
|
|
890
|
-
const publish = () =>
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
876
|
+
const publish = () => {
|
|
877
|
+
for (const device of devices) publishedDevices.set(device.connectId, device);
|
|
878
|
+
emitter.emit(type, {
|
|
879
|
+
type,
|
|
880
|
+
payload: { ...request, devices, requestId, scanning: true }
|
|
881
|
+
});
|
|
882
|
+
};
|
|
894
883
|
signal.addEventListener("abort", cancel, { once: true });
|
|
895
884
|
let polling;
|
|
896
885
|
try {
|
|
@@ -900,17 +889,22 @@ async function requestBleDeviceSelection({
|
|
|
900
889
|
while (!stopped) {
|
|
901
890
|
const snapshot = await scan();
|
|
902
891
|
if (stopped || signal.aborted) return;
|
|
892
|
+
const usbFallback = allowUsbFallback ? snapshot.find((device2) => device2.connectionType === "usb") : void 0;
|
|
893
|
+
if (usbFallback) return usbFallback;
|
|
903
894
|
devices = snapshot;
|
|
904
895
|
publish();
|
|
905
896
|
if (stopped) return;
|
|
906
897
|
await waitForNextScan();
|
|
907
898
|
}
|
|
908
899
|
})();
|
|
909
|
-
const
|
|
900
|
+
const userSelection = reply.then((selected) => publishedDevices.get(selected.sdkConnectId));
|
|
901
|
+
const device = await Promise.race([
|
|
902
|
+
userSelection,
|
|
903
|
+
polling.then((usbFallback) => usbFallback ?? userSelection)
|
|
904
|
+
]);
|
|
910
905
|
stop();
|
|
911
906
|
await polling;
|
|
912
907
|
if (signal.aborted) throw signal.reason;
|
|
913
|
-
const device = devices.find((candidate) => candidate.connectId === selected.sdkConnectId);
|
|
914
908
|
if (!device) {
|
|
915
909
|
throw createHwkError({
|
|
916
910
|
code: 10100 /* DeviceNotFound */,
|
|
@@ -1253,9 +1247,9 @@ export {
|
|
|
1253
1247
|
HARDWARE_METHOD_CATALOG,
|
|
1254
1248
|
HARDWARE_RUNTIME_ID_PREFIX,
|
|
1255
1249
|
HardwareErrorCode,
|
|
1256
|
-
|
|
1257
|
-
InteractionRegistry,
|
|
1250
|
+
OPERATION_DEFAULT_TTL_MS,
|
|
1258
1251
|
ORPHAN_ELIGIBLE_ERROR_CODES,
|
|
1252
|
+
OperationRegistry,
|
|
1259
1253
|
SDK,
|
|
1260
1254
|
TypedEventEmitter,
|
|
1261
1255
|
UI_EVENT,
|
|
@@ -1273,8 +1267,8 @@ export {
|
|
|
1273
1267
|
compareSemver,
|
|
1274
1268
|
createBridgedConnector,
|
|
1275
1269
|
createCombinedConnector,
|
|
1276
|
-
|
|
1277
|
-
|
|
1270
|
+
createHardwareLinkId,
|
|
1271
|
+
createHardwareOperationId,
|
|
1278
1272
|
createHardwareSearchTargetId,
|
|
1279
1273
|
createHwkError,
|
|
1280
1274
|
defaultOriginForCode,
|
|
@@ -1290,8 +1284,7 @@ export {
|
|
|
1290
1284
|
hasHardwareRuntimeIdPrefix,
|
|
1291
1285
|
hexToBytes,
|
|
1292
1286
|
isAllNetworkMethodName,
|
|
1293
|
-
|
|
1294
|
-
isHardwareSearchTargetId,
|
|
1287
|
+
isHardwareOperationId,
|
|
1295
1288
|
isHwkRecoveryHint,
|
|
1296
1289
|
isKnownNonTargetHardwareVendor,
|
|
1297
1290
|
operationMayHaveCompletedParams,
|