@onekeyfe/hwk-ledger-adapter 1.2.5-alpha.4 → 1.2.6-alpha.0
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/index.d.mts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +130 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +130 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -874,6 +874,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
874
874
|
this._operations = new OperationRegistry({
|
|
875
875
|
vendor: "ledger",
|
|
876
876
|
onEnded: (operation, reason) => {
|
|
877
|
+
this._discardPendingBinding(this._pendingOperationBindings.get(operation.operationId));
|
|
878
|
+
this._pendingOperationBindings.delete(operation.operationId);
|
|
877
879
|
this.emitter.emit(SDK.OPERATION_ENDED, {
|
|
878
880
|
type: SDK.OPERATION_ENDED,
|
|
879
881
|
payload: { operationId: operation.operationId, reason }
|
|
@@ -885,6 +887,11 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
885
887
|
});
|
|
886
888
|
this._discoveredDevices = /* @__PURE__ */ new Map();
|
|
887
889
|
this._sessions = /* @__PURE__ */ new Map();
|
|
890
|
+
// An operation's BLE pick is saved by its first call that gets past the wallet check.
|
|
891
|
+
this._pendingOperationBindings = /* @__PURE__ */ new Map();
|
|
892
|
+
// A one-shot call's unchecked BLE pick, by connectId. It outlives the call only
|
|
893
|
+
// through an unlock retry; any other failure drops it with its session.
|
|
894
|
+
this._pendingPickBindings = /* @__PURE__ */ new Map();
|
|
888
895
|
// Transport each session was opened on, by sessionId. The adapter-wide
|
|
889
896
|
// `_activeConnectionType` moves with every discovery and can go stale.
|
|
890
897
|
this._sessionTransports = /* @__PURE__ */ new Map();
|
|
@@ -1013,6 +1020,12 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1013
1020
|
this._jobQueue = new DeviceJobQueue();
|
|
1014
1021
|
this.registerEventListeners();
|
|
1015
1022
|
}
|
|
1023
|
+
_discardPendingBinding(owner, status = "cancelled") {
|
|
1024
|
+
const pending = owner?.pendingBinding;
|
|
1025
|
+
if (!owner || !pending) return;
|
|
1026
|
+
owner.pendingBinding = void 0;
|
|
1027
|
+
if (pending.requestId === this._bindingSelectionRequestId) this._finishBleBinding(status);
|
|
1028
|
+
}
|
|
1016
1029
|
_finishBleBinding(status) {
|
|
1017
1030
|
const selectionRequestId = this._bindingSelectionRequestId;
|
|
1018
1031
|
this._bindingSelectionRequestId = void 0;
|
|
@@ -1063,6 +1076,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1063
1076
|
this._discoveredDevices.clear();
|
|
1064
1077
|
this._sessions.clear();
|
|
1065
1078
|
this._sessionTransports.clear();
|
|
1079
|
+
this._pendingOperationBindings.clear();
|
|
1080
|
+
this._pendingPickBindings.clear();
|
|
1066
1081
|
this._selectedBleReconnectTargets.clear();
|
|
1067
1082
|
this._connectingPromise = null;
|
|
1068
1083
|
this._doConnectAbortController = null;
|
|
@@ -1207,8 +1222,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1207
1222
|
return this.errorToFailure(error);
|
|
1208
1223
|
}
|
|
1209
1224
|
}
|
|
1210
|
-
/**
|
|
1225
|
+
/** Binds the picked BLE device; with a recorded wallet identity it must match first. */
|
|
1211
1226
|
async bindBleDevice(params) {
|
|
1227
|
+
const identity = params.identity?.vendor === "ledger" ? params.identity : void 0;
|
|
1212
1228
|
try {
|
|
1213
1229
|
return await this._jobQueue.enqueue(
|
|
1214
1230
|
"__ledger_bind_ble__",
|
|
@@ -1223,7 +1239,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1223
1239
|
await this._ensureDevicePermission(void 0, void 0, signal);
|
|
1224
1240
|
const attempt = {
|
|
1225
1241
|
extra: params.extra,
|
|
1226
|
-
bindingReason: "manual-rebind"
|
|
1242
|
+
bindingReason: "manual-rebind",
|
|
1243
|
+
deferBindingSave: Boolean(identity)
|
|
1227
1244
|
};
|
|
1228
1245
|
try {
|
|
1229
1246
|
const connectId = await this._connectFirstOrSelect(
|
|
@@ -1234,6 +1251,45 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1234
1251
|
attempt,
|
|
1235
1252
|
signal
|
|
1236
1253
|
);
|
|
1254
|
+
const pending = attempt.pendingBinding;
|
|
1255
|
+
if (identity && pending) {
|
|
1256
|
+
attempt.pendingBinding = void 0;
|
|
1257
|
+
const sessionId = this._sessions.get(connectId);
|
|
1258
|
+
if (!sessionId) {
|
|
1259
|
+
throw createHwkError({
|
|
1260
|
+
code: HardwareErrorCode3.DeviceDisconnected,
|
|
1261
|
+
message: "Selected Ledger connection ended"
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
const fingerprint = await this._computeChainFingerprint(
|
|
1265
|
+
identity.chain,
|
|
1266
|
+
(method, callParams) => this._runConnectorCall(
|
|
1267
|
+
connectId,
|
|
1268
|
+
method,
|
|
1269
|
+
callParams,
|
|
1270
|
+
signal,
|
|
1271
|
+
void 0,
|
|
1272
|
+
void 0,
|
|
1273
|
+
{ autoInstallApp: true },
|
|
1274
|
+
{ connection: { connectId, sessionId } }
|
|
1275
|
+
)
|
|
1276
|
+
);
|
|
1277
|
+
if (fingerprint !== identity.value) {
|
|
1278
|
+
await this._dropSession(connectId, signal);
|
|
1279
|
+
throw createHwkError({
|
|
1280
|
+
code: HardwareErrorCode3.DeviceMismatch,
|
|
1281
|
+
message: formatDeviceMismatchError(identity.value, fingerprint)
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
await this._saveSelectedBleBinding(
|
|
1285
|
+
connectId,
|
|
1286
|
+
pending.requestId,
|
|
1287
|
+
attempt,
|
|
1288
|
+
void 0,
|
|
1289
|
+
signal,
|
|
1290
|
+
identity
|
|
1291
|
+
);
|
|
1292
|
+
}
|
|
1237
1293
|
if (!attempt.bindingSaved) {
|
|
1238
1294
|
await this._dropSession(connectId, signal);
|
|
1239
1295
|
throw createHwkError({
|
|
@@ -1271,7 +1327,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1271
1327
|
await this._ensureDevicePermission(target, void 0, signal);
|
|
1272
1328
|
const attempt = {
|
|
1273
1329
|
...context,
|
|
1274
|
-
extra: context.extra ? { ...context.extra } : void 0
|
|
1330
|
+
extra: context.extra ? { ...context.extra } : void 0,
|
|
1331
|
+
// The operation's calls decide whether the pick is the right wallet.
|
|
1332
|
+
deferBindingSave: true
|
|
1275
1333
|
};
|
|
1276
1334
|
try {
|
|
1277
1335
|
const resolvedConnectId = await this.ensureConnected(
|
|
@@ -1282,7 +1340,11 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1282
1340
|
attempt
|
|
1283
1341
|
);
|
|
1284
1342
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1285
|
-
|
|
1343
|
+
const result = this._createOperation(connectId, resolvedConnectId);
|
|
1344
|
+
if (result.success && attempt.pendingBinding) {
|
|
1345
|
+
this._pendingOperationBindings.set(result.payload, attempt);
|
|
1346
|
+
}
|
|
1347
|
+
return result;
|
|
1286
1348
|
} catch (error) {
|
|
1287
1349
|
this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
|
|
1288
1350
|
throw error;
|
|
@@ -1897,6 +1959,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1897
1959
|
this._uiRegistry.cancel(void 0, void 0, pendingOperationId);
|
|
1898
1960
|
}
|
|
1899
1961
|
this._finishBleBinding("cancelled");
|
|
1962
|
+
if (!connectId) this._pendingOperationBindings.clear();
|
|
1963
|
+
else if (pendingOperationId) this._pendingOperationBindings.delete(pendingOperationId);
|
|
1900
1964
|
const queueKeys = /* @__PURE__ */ new Set();
|
|
1901
1965
|
if (connectId) queueKeys.add(ledgerQueueKey({ connectId }));
|
|
1902
1966
|
if (pendingOperationId) queueKeys.add(ledgerQueueKey({ operationId: pendingOperationId }));
|
|
@@ -1948,8 +2012,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1948
2012
|
return this.errorToFailure(err);
|
|
1949
2013
|
}
|
|
1950
2014
|
}
|
|
1951
|
-
/**
|
|
1952
|
-
async _saveSelectedBleBinding(connectId, selectionRequestId, context, operationId, signal) {
|
|
2015
|
+
/** Saves a picked BLE endpoint; `identity` is set when its wallet was just checked. */
|
|
2016
|
+
async _saveSelectedBleBinding(connectId, selectionRequestId, context, operationId, signal, identity) {
|
|
1953
2017
|
try {
|
|
1954
2018
|
const outcome = await requestSaveDeviceBinding(
|
|
1955
2019
|
this.emitter,
|
|
@@ -1957,6 +2021,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1957
2021
|
{
|
|
1958
2022
|
selectionRequestId,
|
|
1959
2023
|
connection: { transport: "ble", connectId },
|
|
2024
|
+
...identity ? { identity } : {},
|
|
1960
2025
|
extra: context?.extra,
|
|
1961
2026
|
operationId
|
|
1962
2027
|
},
|
|
@@ -2410,13 +2475,17 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2410
2475
|
signal
|
|
2411
2476
|
);
|
|
2412
2477
|
if (context) context.selectedConnection = { connectId: connected, requestId };
|
|
2413
|
-
|
|
2414
|
-
connected,
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2478
|
+
if (context?.deferBindingSave) {
|
|
2479
|
+
context.pendingBinding = { connectId: connected, requestId };
|
|
2480
|
+
} else {
|
|
2481
|
+
await this._saveSelectedBleBinding(
|
|
2482
|
+
connected,
|
|
2483
|
+
requestId,
|
|
2484
|
+
context,
|
|
2485
|
+
preserveOperationId,
|
|
2486
|
+
signal
|
|
2487
|
+
);
|
|
2488
|
+
}
|
|
2420
2489
|
return connected;
|
|
2421
2490
|
}
|
|
2422
2491
|
if (devices.length > 0 && (devices.length > 1 || requiresBleSelection)) {
|
|
@@ -2612,7 +2681,13 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2612
2681
|
operationId
|
|
2613
2682
|
);
|
|
2614
2683
|
} catch (error) {
|
|
2615
|
-
|
|
2684
|
+
const status = signal.aborted ? "cancelled" : "failed";
|
|
2685
|
+
for (const [pickedConnectId, owner] of this._pendingPickBindings) {
|
|
2686
|
+
this._pendingPickBindings.delete(pickedConnectId);
|
|
2687
|
+
this._discardPendingBinding(owner, status);
|
|
2688
|
+
await this._dropSession(pickedConnectId, signal);
|
|
2689
|
+
}
|
|
2690
|
+
this._finishBleBinding(status);
|
|
2616
2691
|
throw error;
|
|
2617
2692
|
} finally {
|
|
2618
2693
|
if (operationId) {
|
|
@@ -2719,7 +2794,13 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2719
2794
|
);
|
|
2720
2795
|
const inputConnectId = hintedConnectId && hintedConnectId.transport !== "qr" ? hintedConnectId.connectId : connectId;
|
|
2721
2796
|
const preferredConnectId = fingerprint && !fingerprint.skipFingerprint && selectedBleTarget?.chain === fingerprint.chain && selectedBleTarget.fingerprint === fingerprint.deviceId ? selectedBleTarget.connectId : inputConnectId;
|
|
2722
|
-
const
|
|
2797
|
+
const checksWallet = Boolean(
|
|
2798
|
+
fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId
|
|
2799
|
+
);
|
|
2800
|
+
const connectionAttempt = {
|
|
2801
|
+
...commonParams,
|
|
2802
|
+
deferBindingSave: checksWallet
|
|
2803
|
+
};
|
|
2723
2804
|
const bundleConnection = installContext?.connection;
|
|
2724
2805
|
if (bundleConnection && this._sessions.get(bundleConnection.connectId) !== bundleConnection.sessionId) {
|
|
2725
2806
|
throw createHwkError({
|
|
@@ -2753,7 +2834,12 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2753
2834
|
}
|
|
2754
2835
|
try {
|
|
2755
2836
|
const isBleSession = this._sessionTransports.get(sessionId) === "ble";
|
|
2756
|
-
if (
|
|
2837
|
+
if (!operationId && connectionAttempt.pendingBinding) {
|
|
2838
|
+
this._pendingPickBindings.set(resolvedConnectId, connectionAttempt);
|
|
2839
|
+
}
|
|
2840
|
+
const bindingOwner = operationId ? this._pendingOperationBindings.get(operationId) : this._pendingPickBindings.get(resolvedConnectId);
|
|
2841
|
+
const pendingBinding = bindingOwner?.pendingBinding?.connectId === resolvedConnectId ? bindingOwner.pendingBinding : void 0;
|
|
2842
|
+
if (fingerprint && checksWallet) {
|
|
2757
2843
|
const fp = await this._abortable(
|
|
2758
2844
|
signal,
|
|
2759
2845
|
this._verifyDeviceFingerprintWithSession(
|
|
@@ -2763,11 +2849,38 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2763
2849
|
)
|
|
2764
2850
|
);
|
|
2765
2851
|
if (!fp.success) {
|
|
2852
|
+
if (pendingBinding) {
|
|
2853
|
+
this._discardPendingBinding(bindingOwner, "failed");
|
|
2854
|
+
this._pendingPickBindings.delete(resolvedConnectId);
|
|
2855
|
+
if (operationId) {
|
|
2856
|
+
this._pendingOperationBindings.delete(operationId);
|
|
2857
|
+
this._operations.end(operationId, "explicit");
|
|
2858
|
+
await this._dropSession(resolvedConnectId, signal);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2766
2861
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
2767
2862
|
code: HardwareErrorCode3.DeviceMismatch
|
|
2768
2863
|
});
|
|
2769
2864
|
}
|
|
2770
2865
|
}
|
|
2866
|
+
if (pendingBinding && bindingOwner) {
|
|
2867
|
+
bindingOwner.pendingBinding = void 0;
|
|
2868
|
+
if (operationId) this._pendingOperationBindings.delete(operationId);
|
|
2869
|
+
else this._pendingPickBindings.delete(resolvedConnectId);
|
|
2870
|
+
await this._saveSelectedBleBinding(
|
|
2871
|
+
pendingBinding.connectId,
|
|
2872
|
+
pendingBinding.requestId,
|
|
2873
|
+
bindingOwner,
|
|
2874
|
+
operationId,
|
|
2875
|
+
signal,
|
|
2876
|
+
fingerprint && checksWallet ? {
|
|
2877
|
+
vendor: "ledger",
|
|
2878
|
+
type: "chainFingerprint",
|
|
2879
|
+
chain: fingerprint.chain,
|
|
2880
|
+
value: fingerprint.deviceId
|
|
2881
|
+
} : void 0
|
|
2882
|
+
);
|
|
2883
|
+
}
|
|
2771
2884
|
if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId && !operationId && isBleSession && connectionAttempt.selectedConnection?.connectId === resolvedConnectId) {
|
|
2772
2885
|
this._selectedBleReconnectTargets.set(connectId, {
|
|
2773
2886
|
connectId: resolvedConnectId,
|
|
@@ -2856,6 +2969,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2856
2969
|
}
|
|
2857
2970
|
if (!operationId && errObj?.code === HardwareErrorCode3.DeviceMismatch) {
|
|
2858
2971
|
this._sessions.delete(resolvedConnectId);
|
|
2972
|
+
this._sessionTransports.delete(sessionId);
|
|
2859
2973
|
this._discoveredDevices.delete(resolvedConnectId);
|
|
2860
2974
|
await this.connector.disconnect(sessionId).catch(() => void 0);
|
|
2861
2975
|
throw err;
|