@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.d.mts
CHANGED
|
@@ -102,6 +102,8 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
102
102
|
private readonly _operations;
|
|
103
103
|
private _discoveredDevices;
|
|
104
104
|
private _sessions;
|
|
105
|
+
private readonly _pendingOperationBindings;
|
|
106
|
+
private readonly _pendingPickBindings;
|
|
105
107
|
private readonly _sessionTransports;
|
|
106
108
|
private readonly _selectedBleReconnectTargets;
|
|
107
109
|
private readonly _uiRegistry;
|
|
@@ -119,6 +121,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
119
121
|
private _pendingConnectorTeardowns;
|
|
120
122
|
private _activeConnectionType;
|
|
121
123
|
private _bindingSelectionRequestId;
|
|
124
|
+
private _discardPendingBinding;
|
|
122
125
|
private _finishBleBinding;
|
|
123
126
|
private _isBleConnection;
|
|
124
127
|
constructor(connector: IConnector, options?: {
|
|
@@ -153,7 +156,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
153
156
|
private _installProgressLastKey;
|
|
154
157
|
private static _createDeviceBusyError;
|
|
155
158
|
connectDevice(searchTargetId: string): Promise<Response<string>>;
|
|
156
|
-
/**
|
|
159
|
+
/** Binds the picked BLE device; with a recorded wallet identity it must match first. */
|
|
157
160
|
bindBleDevice(params: BindBleDeviceParams): Promise<Response<string>>;
|
|
158
161
|
acquireOperation(connectId: string, context: IHardwareConnectionContext): Promise<Response<string>>;
|
|
159
162
|
private _createOperation;
|
|
@@ -213,7 +216,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
213
216
|
cancel(connectId?: string): void;
|
|
214
217
|
/** A non-empty deviceId is an expected chain fingerprint, not a transport identifier. */
|
|
215
218
|
getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
|
|
216
|
-
/**
|
|
219
|
+
/** Saves a picked BLE endpoint; `identity` is set when its wallet was just checked. */
|
|
217
220
|
private _saveSelectedBleBinding;
|
|
218
221
|
private _dropSession;
|
|
219
222
|
/** Verify on the acquired session without re-entering the job queue. */
|
package/dist/index.d.ts
CHANGED
|
@@ -102,6 +102,8 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
102
102
|
private readonly _operations;
|
|
103
103
|
private _discoveredDevices;
|
|
104
104
|
private _sessions;
|
|
105
|
+
private readonly _pendingOperationBindings;
|
|
106
|
+
private readonly _pendingPickBindings;
|
|
105
107
|
private readonly _sessionTransports;
|
|
106
108
|
private readonly _selectedBleReconnectTargets;
|
|
107
109
|
private readonly _uiRegistry;
|
|
@@ -119,6 +121,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
119
121
|
private _pendingConnectorTeardowns;
|
|
120
122
|
private _activeConnectionType;
|
|
121
123
|
private _bindingSelectionRequestId;
|
|
124
|
+
private _discardPendingBinding;
|
|
122
125
|
private _finishBleBinding;
|
|
123
126
|
private _isBleConnection;
|
|
124
127
|
constructor(connector: IConnector, options?: {
|
|
@@ -153,7 +156,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
153
156
|
private _installProgressLastKey;
|
|
154
157
|
private static _createDeviceBusyError;
|
|
155
158
|
connectDevice(searchTargetId: string): Promise<Response<string>>;
|
|
156
|
-
/**
|
|
159
|
+
/** Binds the picked BLE device; with a recorded wallet identity it must match first. */
|
|
157
160
|
bindBleDevice(params: BindBleDeviceParams): Promise<Response<string>>;
|
|
158
161
|
acquireOperation(connectId: string, context: IHardwareConnectionContext): Promise<Response<string>>;
|
|
159
162
|
private _createOperation;
|
|
@@ -213,7 +216,7 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
213
216
|
cancel(connectId?: string): void;
|
|
214
217
|
/** A non-empty deviceId is an expected chain fingerprint, not a transport identifier. */
|
|
215
218
|
getChainFingerprint(connectId: string, deviceId: string, chain: ChainForFingerprint): Promise<Response<string>>;
|
|
216
|
-
/**
|
|
219
|
+
/** Saves a picked BLE endpoint; `identity` is set when its wallet was just checked. */
|
|
217
220
|
private _saveSelectedBleBinding;
|
|
218
221
|
private _dropSession;
|
|
219
222
|
/** Verify on the acquired session without re-entering the job queue. */
|
package/dist/index.js
CHANGED
|
@@ -892,6 +892,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
892
892
|
this._operations = new import_hwk_adapter_core3.OperationRegistry({
|
|
893
893
|
vendor: "ledger",
|
|
894
894
|
onEnded: (operation, reason) => {
|
|
895
|
+
this._discardPendingBinding(this._pendingOperationBindings.get(operation.operationId));
|
|
896
|
+
this._pendingOperationBindings.delete(operation.operationId);
|
|
895
897
|
this.emitter.emit(import_hwk_adapter_core3.SDK.OPERATION_ENDED, {
|
|
896
898
|
type: import_hwk_adapter_core3.SDK.OPERATION_ENDED,
|
|
897
899
|
payload: { operationId: operation.operationId, reason }
|
|
@@ -903,6 +905,11 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
903
905
|
});
|
|
904
906
|
this._discoveredDevices = /* @__PURE__ */ new Map();
|
|
905
907
|
this._sessions = /* @__PURE__ */ new Map();
|
|
908
|
+
// An operation's BLE pick is saved by its first call that gets past the wallet check.
|
|
909
|
+
this._pendingOperationBindings = /* @__PURE__ */ new Map();
|
|
910
|
+
// A one-shot call's unchecked BLE pick, by connectId. It outlives the call only
|
|
911
|
+
// through an unlock retry; any other failure drops it with its session.
|
|
912
|
+
this._pendingPickBindings = /* @__PURE__ */ new Map();
|
|
906
913
|
// Transport each session was opened on, by sessionId. The adapter-wide
|
|
907
914
|
// `_activeConnectionType` moves with every discovery and can go stale.
|
|
908
915
|
this._sessionTransports = /* @__PURE__ */ new Map();
|
|
@@ -1031,6 +1038,12 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1031
1038
|
this._jobQueue = new import_hwk_adapter_core3.DeviceJobQueue();
|
|
1032
1039
|
this.registerEventListeners();
|
|
1033
1040
|
}
|
|
1041
|
+
_discardPendingBinding(owner, status = "cancelled") {
|
|
1042
|
+
const pending = owner?.pendingBinding;
|
|
1043
|
+
if (!owner || !pending) return;
|
|
1044
|
+
owner.pendingBinding = void 0;
|
|
1045
|
+
if (pending.requestId === this._bindingSelectionRequestId) this._finishBleBinding(status);
|
|
1046
|
+
}
|
|
1034
1047
|
_finishBleBinding(status) {
|
|
1035
1048
|
const selectionRequestId = this._bindingSelectionRequestId;
|
|
1036
1049
|
this._bindingSelectionRequestId = void 0;
|
|
@@ -1081,6 +1094,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1081
1094
|
this._discoveredDevices.clear();
|
|
1082
1095
|
this._sessions.clear();
|
|
1083
1096
|
this._sessionTransports.clear();
|
|
1097
|
+
this._pendingOperationBindings.clear();
|
|
1098
|
+
this._pendingPickBindings.clear();
|
|
1084
1099
|
this._selectedBleReconnectTargets.clear();
|
|
1085
1100
|
this._connectingPromise = null;
|
|
1086
1101
|
this._doConnectAbortController = null;
|
|
@@ -1225,8 +1240,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1225
1240
|
return this.errorToFailure(error);
|
|
1226
1241
|
}
|
|
1227
1242
|
}
|
|
1228
|
-
/**
|
|
1243
|
+
/** Binds the picked BLE device; with a recorded wallet identity it must match first. */
|
|
1229
1244
|
async bindBleDevice(params) {
|
|
1245
|
+
const identity = params.identity?.vendor === "ledger" ? params.identity : void 0;
|
|
1230
1246
|
try {
|
|
1231
1247
|
return await this._jobQueue.enqueue(
|
|
1232
1248
|
"__ledger_bind_ble__",
|
|
@@ -1241,7 +1257,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1241
1257
|
await this._ensureDevicePermission(void 0, void 0, signal);
|
|
1242
1258
|
const attempt = {
|
|
1243
1259
|
extra: params.extra,
|
|
1244
|
-
bindingReason: "manual-rebind"
|
|
1260
|
+
bindingReason: "manual-rebind",
|
|
1261
|
+
deferBindingSave: Boolean(identity)
|
|
1245
1262
|
};
|
|
1246
1263
|
try {
|
|
1247
1264
|
const connectId = await this._connectFirstOrSelect(
|
|
@@ -1252,6 +1269,45 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1252
1269
|
attempt,
|
|
1253
1270
|
signal
|
|
1254
1271
|
);
|
|
1272
|
+
const pending = attempt.pendingBinding;
|
|
1273
|
+
if (identity && pending) {
|
|
1274
|
+
attempt.pendingBinding = void 0;
|
|
1275
|
+
const sessionId = this._sessions.get(connectId);
|
|
1276
|
+
if (!sessionId) {
|
|
1277
|
+
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
1278
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceDisconnected,
|
|
1279
|
+
message: "Selected Ledger connection ended"
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
const fingerprint = await this._computeChainFingerprint(
|
|
1283
|
+
identity.chain,
|
|
1284
|
+
(method, callParams) => this._runConnectorCall(
|
|
1285
|
+
connectId,
|
|
1286
|
+
method,
|
|
1287
|
+
callParams,
|
|
1288
|
+
signal,
|
|
1289
|
+
void 0,
|
|
1290
|
+
void 0,
|
|
1291
|
+
{ autoInstallApp: true },
|
|
1292
|
+
{ connection: { connectId, sessionId } }
|
|
1293
|
+
)
|
|
1294
|
+
);
|
|
1295
|
+
if (fingerprint !== identity.value) {
|
|
1296
|
+
await this._dropSession(connectId, signal);
|
|
1297
|
+
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
1298
|
+
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch,
|
|
1299
|
+
message: formatDeviceMismatchError(identity.value, fingerprint)
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
await this._saveSelectedBleBinding(
|
|
1303
|
+
connectId,
|
|
1304
|
+
pending.requestId,
|
|
1305
|
+
attempt,
|
|
1306
|
+
void 0,
|
|
1307
|
+
signal,
|
|
1308
|
+
identity
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1255
1311
|
if (!attempt.bindingSaved) {
|
|
1256
1312
|
await this._dropSession(connectId, signal);
|
|
1257
1313
|
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
@@ -1289,7 +1345,9 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1289
1345
|
await this._ensureDevicePermission(target, void 0, signal);
|
|
1290
1346
|
const attempt = {
|
|
1291
1347
|
...context,
|
|
1292
|
-
extra: context.extra ? { ...context.extra } : void 0
|
|
1348
|
+
extra: context.extra ? { ...context.extra } : void 0,
|
|
1349
|
+
// The operation's calls decide whether the pick is the right wallet.
|
|
1350
|
+
deferBindingSave: true
|
|
1293
1351
|
};
|
|
1294
1352
|
try {
|
|
1295
1353
|
const resolvedConnectId = await this.ensureConnected(
|
|
@@ -1300,7 +1358,11 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1300
1358
|
attempt
|
|
1301
1359
|
);
|
|
1302
1360
|
_LedgerAdapter._throwIfAborted(signal);
|
|
1303
|
-
|
|
1361
|
+
const result = this._createOperation(connectId, resolvedConnectId);
|
|
1362
|
+
if (result.success && attempt.pendingBinding) {
|
|
1363
|
+
this._pendingOperationBindings.set(result.payload, attempt);
|
|
1364
|
+
}
|
|
1365
|
+
return result;
|
|
1304
1366
|
} catch (error) {
|
|
1305
1367
|
this._finishBleBinding(signal.aborted ? "cancelled" : "failed");
|
|
1306
1368
|
throw error;
|
|
@@ -1915,6 +1977,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1915
1977
|
this._uiRegistry.cancel(void 0, void 0, pendingOperationId);
|
|
1916
1978
|
}
|
|
1917
1979
|
this._finishBleBinding("cancelled");
|
|
1980
|
+
if (!connectId) this._pendingOperationBindings.clear();
|
|
1981
|
+
else if (pendingOperationId) this._pendingOperationBindings.delete(pendingOperationId);
|
|
1918
1982
|
const queueKeys = /* @__PURE__ */ new Set();
|
|
1919
1983
|
if (connectId) queueKeys.add(ledgerQueueKey({ connectId }));
|
|
1920
1984
|
if (pendingOperationId) queueKeys.add(ledgerQueueKey({ operationId: pendingOperationId }));
|
|
@@ -1966,8 +2030,8 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1966
2030
|
return this.errorToFailure(err);
|
|
1967
2031
|
}
|
|
1968
2032
|
}
|
|
1969
|
-
/**
|
|
1970
|
-
async _saveSelectedBleBinding(connectId, selectionRequestId, context, operationId, signal) {
|
|
2033
|
+
/** Saves a picked BLE endpoint; `identity` is set when its wallet was just checked. */
|
|
2034
|
+
async _saveSelectedBleBinding(connectId, selectionRequestId, context, operationId, signal, identity) {
|
|
1971
2035
|
try {
|
|
1972
2036
|
const outcome = await (0, import_hwk_adapter_core3.requestSaveDeviceBinding)(
|
|
1973
2037
|
this.emitter,
|
|
@@ -1975,6 +2039,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
1975
2039
|
{
|
|
1976
2040
|
selectionRequestId,
|
|
1977
2041
|
connection: { transport: "ble", connectId },
|
|
2042
|
+
...identity ? { identity } : {},
|
|
1978
2043
|
extra: context?.extra,
|
|
1979
2044
|
operationId
|
|
1980
2045
|
},
|
|
@@ -2428,13 +2493,17 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2428
2493
|
signal
|
|
2429
2494
|
);
|
|
2430
2495
|
if (context) context.selectedConnection = { connectId: connected, requestId };
|
|
2431
|
-
|
|
2432
|
-
connected,
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2496
|
+
if (context?.deferBindingSave) {
|
|
2497
|
+
context.pendingBinding = { connectId: connected, requestId };
|
|
2498
|
+
} else {
|
|
2499
|
+
await this._saveSelectedBleBinding(
|
|
2500
|
+
connected,
|
|
2501
|
+
requestId,
|
|
2502
|
+
context,
|
|
2503
|
+
preserveOperationId,
|
|
2504
|
+
signal
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2438
2507
|
return connected;
|
|
2439
2508
|
}
|
|
2440
2509
|
if (devices.length > 0 && (devices.length > 1 || requiresBleSelection)) {
|
|
@@ -2630,7 +2699,13 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2630
2699
|
operationId
|
|
2631
2700
|
);
|
|
2632
2701
|
} catch (error) {
|
|
2633
|
-
|
|
2702
|
+
const status = signal.aborted ? "cancelled" : "failed";
|
|
2703
|
+
for (const [pickedConnectId, owner] of this._pendingPickBindings) {
|
|
2704
|
+
this._pendingPickBindings.delete(pickedConnectId);
|
|
2705
|
+
this._discardPendingBinding(owner, status);
|
|
2706
|
+
await this._dropSession(pickedConnectId, signal);
|
|
2707
|
+
}
|
|
2708
|
+
this._finishBleBinding(status);
|
|
2634
2709
|
throw error;
|
|
2635
2710
|
} finally {
|
|
2636
2711
|
if (operationId) {
|
|
@@ -2737,7 +2812,13 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2737
2812
|
);
|
|
2738
2813
|
const inputConnectId = hintedConnectId && hintedConnectId.transport !== "qr" ? hintedConnectId.connectId : connectId;
|
|
2739
2814
|
const preferredConnectId = fingerprint && !fingerprint.skipFingerprint && selectedBleTarget?.chain === fingerprint.chain && selectedBleTarget.fingerprint === fingerprint.deviceId ? selectedBleTarget.connectId : inputConnectId;
|
|
2740
|
-
const
|
|
2815
|
+
const checksWallet = Boolean(
|
|
2816
|
+
fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId
|
|
2817
|
+
);
|
|
2818
|
+
const connectionAttempt = {
|
|
2819
|
+
...commonParams,
|
|
2820
|
+
deferBindingSave: checksWallet
|
|
2821
|
+
};
|
|
2741
2822
|
const bundleConnection = installContext?.connection;
|
|
2742
2823
|
if (bundleConnection && this._sessions.get(bundleConnection.connectId) !== bundleConnection.sessionId) {
|
|
2743
2824
|
throw (0, import_hwk_adapter_core3.createHwkError)({
|
|
@@ -2771,7 +2852,12 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2771
2852
|
}
|
|
2772
2853
|
try {
|
|
2773
2854
|
const isBleSession = this._sessionTransports.get(sessionId) === "ble";
|
|
2774
|
-
if (
|
|
2855
|
+
if (!operationId && connectionAttempt.pendingBinding) {
|
|
2856
|
+
this._pendingPickBindings.set(resolvedConnectId, connectionAttempt);
|
|
2857
|
+
}
|
|
2858
|
+
const bindingOwner = operationId ? this._pendingOperationBindings.get(operationId) : this._pendingPickBindings.get(resolvedConnectId);
|
|
2859
|
+
const pendingBinding = bindingOwner?.pendingBinding?.connectId === resolvedConnectId ? bindingOwner.pendingBinding : void 0;
|
|
2860
|
+
if (fingerprint && checksWallet) {
|
|
2775
2861
|
const fp = await this._abortable(
|
|
2776
2862
|
signal,
|
|
2777
2863
|
this._verifyDeviceFingerprintWithSession(
|
|
@@ -2781,11 +2867,38 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2781
2867
|
)
|
|
2782
2868
|
);
|
|
2783
2869
|
if (!fp.success) {
|
|
2870
|
+
if (pendingBinding) {
|
|
2871
|
+
this._discardPendingBinding(bindingOwner, "failed");
|
|
2872
|
+
this._pendingPickBindings.delete(resolvedConnectId);
|
|
2873
|
+
if (operationId) {
|
|
2874
|
+
this._pendingOperationBindings.delete(operationId);
|
|
2875
|
+
this._operations.end(operationId, "explicit");
|
|
2876
|
+
await this._dropSession(resolvedConnectId, signal);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2784
2879
|
throw Object.assign(new Error(formatDeviceMismatchError(fp.expected, fp.actual)), {
|
|
2785
2880
|
code: import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch
|
|
2786
2881
|
});
|
|
2787
2882
|
}
|
|
2788
2883
|
}
|
|
2884
|
+
if (pendingBinding && bindingOwner) {
|
|
2885
|
+
bindingOwner.pendingBinding = void 0;
|
|
2886
|
+
if (operationId) this._pendingOperationBindings.delete(operationId);
|
|
2887
|
+
else this._pendingPickBindings.delete(resolvedConnectId);
|
|
2888
|
+
await this._saveSelectedBleBinding(
|
|
2889
|
+
pendingBinding.connectId,
|
|
2890
|
+
pendingBinding.requestId,
|
|
2891
|
+
bindingOwner,
|
|
2892
|
+
operationId,
|
|
2893
|
+
signal,
|
|
2894
|
+
fingerprint && checksWallet ? {
|
|
2895
|
+
vendor: "ledger",
|
|
2896
|
+
type: "chainFingerprint",
|
|
2897
|
+
chain: fingerprint.chain,
|
|
2898
|
+
value: fingerprint.deviceId
|
|
2899
|
+
} : void 0
|
|
2900
|
+
);
|
|
2901
|
+
}
|
|
2789
2902
|
if (fingerprint && !fingerprint.skipFingerprint && fingerprint.deviceId && !operationId && isBleSession && connectionAttempt.selectedConnection?.connectId === resolvedConnectId) {
|
|
2790
2903
|
this._selectedBleReconnectTargets.set(connectId, {
|
|
2791
2904
|
connectId: resolvedConnectId,
|
|
@@ -2874,6 +2987,7 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
2874
2987
|
}
|
|
2875
2988
|
if (!operationId && errObj?.code === import_hwk_adapter_core3.HardwareErrorCode.DeviceMismatch) {
|
|
2876
2989
|
this._sessions.delete(resolvedConnectId);
|
|
2990
|
+
this._sessionTransports.delete(sessionId);
|
|
2877
2991
|
this._discoveredDevices.delete(resolvedConnectId);
|
|
2878
2992
|
await this.connector.disconnect(sessionId).catch(() => void 0);
|
|
2879
2993
|
throw err;
|