@onekeyfe/hwk-trezor-adapter 1.2.5-alpha.4 → 1.2.5
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 +25 -64
- package/dist/index.d.ts +25 -64
- package/dist/index.js +230 -1154
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +220 -1144
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -3,26 +3,12 @@ import {
|
|
|
3
3
|
DEVICE,
|
|
4
4
|
DeviceJobQueue,
|
|
5
5
|
HardwareErrorCode,
|
|
6
|
-
OperationRegistry,
|
|
7
|
-
SDK,
|
|
8
6
|
TypedEventEmitter,
|
|
9
7
|
UI_REQUEST,
|
|
10
8
|
UI_RESPONSE,
|
|
11
9
|
UiRequestRegistry,
|
|
12
|
-
canReplayHardwareMethodAfterTransportFailure,
|
|
13
|
-
createHwkError,
|
|
14
|
-
defaultOriginForCode,
|
|
15
10
|
failure,
|
|
16
|
-
isConnectionLost,
|
|
17
|
-
isHardwareOperationId,
|
|
18
|
-
isHwkRecoveryHint,
|
|
19
|
-
isUserRefusal,
|
|
20
|
-
operationMayHaveCompletedParams,
|
|
21
11
|
rehydrateConnectorError,
|
|
22
|
-
requestBleDeviceSelection,
|
|
23
|
-
requestSaveDeviceBinding,
|
|
24
|
-
resolveHardwareOperationTarget,
|
|
25
|
-
resolveSearchTargetReusePolicy,
|
|
26
12
|
runAllNetworkGetAddress,
|
|
27
13
|
success
|
|
28
14
|
} from "@onekeyfe/hwk-adapter-core";
|
|
@@ -776,28 +762,10 @@ function debugLog(...args) {
|
|
|
776
762
|
emitLog("debug", ...args);
|
|
777
763
|
}
|
|
778
764
|
|
|
779
|
-
// src/utils/queueKey.ts
|
|
780
|
-
function trezorQueueKey({
|
|
781
|
-
operationId,
|
|
782
|
-
connectId
|
|
783
|
-
}) {
|
|
784
|
-
return operationId || connectId || "";
|
|
785
|
-
}
|
|
786
|
-
|
|
787
765
|
// src/adapter/TrezorAdapter.ts
|
|
788
766
|
var KNOWN_HARDWARE_ERROR_CODES = new Set(
|
|
789
767
|
Object.values(HardwareErrorCode).filter((value) => typeof value === "number")
|
|
790
768
|
);
|
|
791
|
-
var ALL_NETWORK_COMMON_PARAM_KEYS = [
|
|
792
|
-
"autoInstallApp",
|
|
793
|
-
"passphraseState",
|
|
794
|
-
"useEmptyPassphrase",
|
|
795
|
-
"operationId",
|
|
796
|
-
"knownConnections",
|
|
797
|
-
"extra",
|
|
798
|
-
"allowDeviceSelection",
|
|
799
|
-
"supportedTransports"
|
|
800
|
-
];
|
|
801
769
|
var TREZOR_BTC_NETWORK_COIN_MAP = {
|
|
802
770
|
btc: "Bitcoin",
|
|
803
771
|
bitcoin: "Bitcoin",
|
|
@@ -814,24 +782,9 @@ var TREZOR_BTC_NETWORK_COIN_MAP = {
|
|
|
814
782
|
dash: "Dash"
|
|
815
783
|
};
|
|
816
784
|
var _TrezorAdapter = class _TrezorAdapter {
|
|
817
|
-
constructor(connector
|
|
785
|
+
constructor(connector) {
|
|
818
786
|
this.vendor = "trezor";
|
|
819
|
-
// The connector has no protocol-level cancel: the adapter stops waiting and
|
|
820
|
-
// drops the late response, the device carries on.
|
|
821
|
-
this.cancelCapability = "stops-waiting";
|
|
822
787
|
this._emitter = new TypedEventEmitter();
|
|
823
|
-
this._operations = new OperationRegistry({
|
|
824
|
-
vendor: "trezor",
|
|
825
|
-
onEnded: (operation, reason) => {
|
|
826
|
-
this._emitter.emit(SDK.OPERATION_ENDED, {
|
|
827
|
-
type: SDK.OPERATION_ENDED,
|
|
828
|
-
payload: { operationId: operation.operationId, reason }
|
|
829
|
-
});
|
|
830
|
-
if (reason === "timeout") {
|
|
831
|
-
void this._releaseOperationConnection(operation).catch(() => void 0);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
});
|
|
835
788
|
this._devices = /* @__PURE__ */ new Map();
|
|
836
789
|
this._sessions = /* @__PURE__ */ new Map();
|
|
837
790
|
this._connectingPromises = /* @__PURE__ */ new Map();
|
|
@@ -840,21 +793,12 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
840
793
|
this._uiRegistry = new UiRequestRegistry();
|
|
841
794
|
this._passphraseRequestContextByConnectId = /* @__PURE__ */ new Map();
|
|
842
795
|
this._verifiedPassphraseSessionsByConnectId = /* @__PURE__ */ new Map();
|
|
843
|
-
/** Raw connector calls that outlive an aborted caller, keyed by session. */
|
|
844
|
-
this._unsettledConnectorOperations = /* @__PURE__ */ new Map();
|
|
845
|
-
this._connectorIdleWaiters = /* @__PURE__ */ new Set();
|
|
846
|
-
this._resetPromise = null;
|
|
847
|
-
this._connectorTeardownTail = Promise.resolve();
|
|
848
|
-
this._pendingConnectorTeardowns = 0;
|
|
849
|
-
this._stateGeneration = 0;
|
|
850
|
-
this._knownDeviceConnections = /* @__PURE__ */ new Map();
|
|
851
796
|
this._onDeviceConnect = (data) => {
|
|
852
797
|
const device = this._connectorDeviceToDeviceInfo(data.device);
|
|
853
798
|
this._devices.set(device.connectId, device);
|
|
854
799
|
this._emitter.emit(DEVICE.CONNECT, { type: DEVICE.CONNECT, payload: device });
|
|
855
800
|
};
|
|
856
801
|
this._onDeviceDisconnect = (data) => {
|
|
857
|
-
this._operations.endByConnectionKey(data.connectId, "disconnect");
|
|
858
802
|
this._sessions.delete(data.connectId);
|
|
859
803
|
this._verifiedPassphraseSessionsByConnectId.delete(data.connectId);
|
|
860
804
|
this._devices.delete(data.connectId);
|
|
@@ -874,32 +818,25 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
874
818
|
payload: { device }
|
|
875
819
|
});
|
|
876
820
|
};
|
|
877
|
-
// The one outlet for every connector-raised UI request (PIN, passphrase,
|
|
878
|
-
// button, THP pairing), so the operation is stamped here instead of at each
|
|
879
|
-
// connector call site.
|
|
880
821
|
this._onUiRequest = (data) => {
|
|
881
|
-
const operationId = this._activeOperationId();
|
|
882
|
-
const basePayload = data.payload && typeof data.payload === "object" ? data.payload : {};
|
|
883
|
-
const attribution = operationId === void 0 ? {} : { operationId };
|
|
884
822
|
if (data.type === UI_REQUEST.REQUEST_PASSPHRASE) {
|
|
885
|
-
const
|
|
823
|
+
const payload = data.payload && typeof data.payload === "object" ? data.payload : {};
|
|
824
|
+
const connectId = typeof payload.connectId === "string" ? payload.connectId : void 0;
|
|
886
825
|
const context = connectId ? this._passphraseRequestContextByConnectId.get(connectId) : void 0;
|
|
887
826
|
this._emitter.emit(
|
|
888
827
|
data.type,
|
|
889
828
|
{
|
|
890
829
|
...data,
|
|
891
830
|
payload: {
|
|
892
|
-
...
|
|
831
|
+
...payload,
|
|
893
832
|
...context?.passphraseState !== void 0 ? { passphraseState: context.passphraseState } : {},
|
|
894
|
-
...context?.useEmptyPassphrase !== void 0 ? { useEmptyPassphrase: context.useEmptyPassphrase } : {}
|
|
895
|
-
...attribution
|
|
833
|
+
...context?.useEmptyPassphrase !== void 0 ? { useEmptyPassphrase: context.useEmptyPassphrase } : {}
|
|
896
834
|
}
|
|
897
835
|
}
|
|
898
836
|
);
|
|
899
837
|
return;
|
|
900
838
|
}
|
|
901
|
-
|
|
902
|
-
this._emitter.emit(data.type, { ...data, payload });
|
|
839
|
+
this._emitter.emit(data.type, data);
|
|
903
840
|
};
|
|
904
841
|
this._onUiEvent = (data) => {
|
|
905
842
|
this._emitter.emit("ui-event", data);
|
|
@@ -911,11 +848,6 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
911
848
|
});
|
|
912
849
|
};
|
|
913
850
|
this._connector = connector;
|
|
914
|
-
for (const connection of options?.knownDeviceConnections ?? []) {
|
|
915
|
-
if (connection.deviceId) {
|
|
916
|
-
this._knownDeviceConnections.set(connection.deviceId, { ...connection });
|
|
917
|
-
}
|
|
918
|
-
}
|
|
919
851
|
this._jobQueue = new DeviceJobQueue();
|
|
920
852
|
this._registerConnectorEvents();
|
|
921
853
|
}
|
|
@@ -940,35 +872,29 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
940
872
|
const {
|
|
941
873
|
passphraseState,
|
|
942
874
|
autoInstallApp: _autoInstallApp,
|
|
943
|
-
operationId,
|
|
944
875
|
useEmptyPassphrase,
|
|
945
|
-
knownConnections,
|
|
946
|
-
extra,
|
|
947
|
-
allowDeviceSelection,
|
|
948
|
-
supportedTransports,
|
|
949
876
|
...rest
|
|
950
877
|
} = params;
|
|
951
878
|
return {
|
|
952
879
|
passphraseState: typeof passphraseState === "string" ? passphraseState : void 0,
|
|
953
880
|
useEmptyPassphrase: typeof useEmptyPassphrase === "boolean" ? useEmptyPassphrase : void 0,
|
|
954
|
-
operationId: typeof operationId === "string" ? operationId : void 0,
|
|
955
|
-
connectionContext: {
|
|
956
|
-
knownConnections,
|
|
957
|
-
extra,
|
|
958
|
-
allowDeviceSelection: typeof allowDeviceSelection === "boolean" ? allowDeviceSelection : void 0,
|
|
959
|
-
supportedTransports
|
|
960
|
-
},
|
|
961
881
|
rest
|
|
962
882
|
};
|
|
963
883
|
}
|
|
964
884
|
return { rest: params ?? {} };
|
|
965
885
|
}
|
|
966
886
|
static _withAllNetworkRequestCommonParams(item, commonParams) {
|
|
967
|
-
const
|
|
968
|
-
|
|
887
|
+
const autoInstallApp = commonParams?.autoInstallApp;
|
|
888
|
+
const passphraseState = commonParams?.passphraseState;
|
|
889
|
+
const useEmptyPassphrase = commonParams?.useEmptyPassphrase;
|
|
890
|
+
if (autoInstallApp === void 0 && passphraseState === void 0 && useEmptyPassphrase === void 0) {
|
|
891
|
+
return item;
|
|
892
|
+
}
|
|
969
893
|
return {
|
|
970
894
|
...item,
|
|
971
|
-
...
|
|
895
|
+
...autoInstallApp !== void 0 ? { autoInstallApp } : {},
|
|
896
|
+
...passphraseState !== void 0 ? { passphraseState } : {},
|
|
897
|
+
...useEmptyPassphrase !== void 0 ? { useEmptyPassphrase } : {}
|
|
972
898
|
};
|
|
973
899
|
}
|
|
974
900
|
static _normalizeLogKey(key) {
|
|
@@ -1092,11 +1018,13 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1092
1018
|
* selected is gone (the device evicted it from its limited slot pool). The
|
|
1093
1019
|
* caller drops the stale cache entry and recreates from scratch.
|
|
1094
1020
|
*
|
|
1095
|
-
*
|
|
1096
|
-
*
|
|
1021
|
+
* NOTE: the exact eviction code still needs real-device confirmation — match
|
|
1022
|
+
* conservatively so a genuine error isn't mistaken for an evicted session
|
|
1023
|
+
* (which would silently re-prompt the passphrase).
|
|
1097
1024
|
*/
|
|
1098
1025
|
static _isStaleSessionError(code) {
|
|
1099
|
-
|
|
1026
|
+
if (typeof code !== "string") return false;
|
|
1027
|
+
return code === "ThpUnallocatedChannel" || /invalid.?session|unallocated.?session|session.?not.?found/i.test(code);
|
|
1100
1028
|
}
|
|
1101
1029
|
static _errorCode(error) {
|
|
1102
1030
|
return error.code ?? _TrezorAdapter._trezorFailureMessage(error).code;
|
|
@@ -1110,13 +1038,13 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1110
1038
|
return protocolError.name === "TrezorProtocolError" && protocolError.code === "Malformed protocol format" && protocolError.message === "Malformed protocol format";
|
|
1111
1039
|
}
|
|
1112
1040
|
/**
|
|
1113
|
-
* Race a promise against an abort signal.
|
|
1114
|
-
* be cancelled at the protocol level,
|
|
1115
|
-
*
|
|
1041
|
+
* Race a promise against an abort signal. Copied from LedgerAdapter:
|
|
1042
|
+
* IConnector.call() can't actually be cancelled at the protocol level, but
|
|
1043
|
+
* the caller gets the abort immediately and the underlying work completes
|
|
1044
|
+
* uselessly in the background.
|
|
1116
1045
|
*/
|
|
1117
1046
|
static _abortable(signal, promise) {
|
|
1118
1047
|
if (signal.aborted) {
|
|
1119
|
-
void promise.catch(() => void 0);
|
|
1120
1048
|
return Promise.reject(
|
|
1121
1049
|
signal.reason ?? new Error("Aborted")
|
|
1122
1050
|
);
|
|
@@ -1138,37 +1066,17 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1138
1066
|
);
|
|
1139
1067
|
});
|
|
1140
1068
|
}
|
|
1141
|
-
async _connectSession(connectId, signal
|
|
1069
|
+
async _connectSession(connectId, signal) {
|
|
1142
1070
|
const connectOnce = async () => {
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
}
|
|
1146
|
-
this._assertConnectorIdle("connectDevice");
|
|
1147
|
-
const releaseOperation = this._retainConnectorOperation(`connect:${connectId}`);
|
|
1148
|
-
let connectPromise;
|
|
1149
|
-
try {
|
|
1150
|
-
connectPromise = transportType ? this._connector.connect(connectId, { transportType }) : this._connector.connect(connectId);
|
|
1151
|
-
} catch (error) {
|
|
1152
|
-
releaseOperation();
|
|
1153
|
-
throw error;
|
|
1154
|
-
}
|
|
1155
|
-
if (!signal) {
|
|
1156
|
-
try {
|
|
1157
|
-
return await connectPromise;
|
|
1158
|
-
} finally {
|
|
1159
|
-
releaseOperation();
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1071
|
+
const connectPromise = this._connector.connect(connectId);
|
|
1072
|
+
if (!signal) return connectPromise;
|
|
1162
1073
|
try {
|
|
1163
|
-
|
|
1164
|
-
releaseOperation();
|
|
1165
|
-
return session2;
|
|
1074
|
+
return await _TrezorAdapter._abortable(signal, connectPromise);
|
|
1166
1075
|
} catch (error) {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
}
|
|
1076
|
+
void connectPromise.then(
|
|
1077
|
+
(orphan) => this._connector.disconnect(orphan.sessionId).catch(() => void 0),
|
|
1078
|
+
() => void 0
|
|
1079
|
+
);
|
|
1172
1080
|
throw error;
|
|
1173
1081
|
}
|
|
1174
1082
|
};
|
|
@@ -1184,13 +1092,8 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1184
1092
|
});
|
|
1185
1093
|
session = await connectOnce();
|
|
1186
1094
|
}
|
|
1187
|
-
if (
|
|
1188
|
-
|
|
1189
|
-
try {
|
|
1190
|
-
await this._connector.disconnect(session.sessionId).catch(() => void 0);
|
|
1191
|
-
} finally {
|
|
1192
|
-
releaseCleanup();
|
|
1193
|
-
}
|
|
1095
|
+
if (this._disconnectRequested.delete(connectId)) {
|
|
1096
|
+
await this._connector.disconnect(session.sessionId).catch(() => void 0);
|
|
1194
1097
|
throw Object.assign(new Error("Trezor connection aborted"), {
|
|
1195
1098
|
code: HardwareErrorCode.UserAborted
|
|
1196
1099
|
});
|
|
@@ -1206,9 +1109,14 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1206
1109
|
async init(_config) {
|
|
1207
1110
|
}
|
|
1208
1111
|
async dispose() {
|
|
1209
|
-
await this._resetStateAndDisconnectSessions();
|
|
1210
1112
|
this._unregisterConnectorEvents();
|
|
1113
|
+
this._uiRegistry.reset();
|
|
1114
|
+
this._jobQueue.clear();
|
|
1211
1115
|
this._connector.reset();
|
|
1116
|
+
this._devices.clear();
|
|
1117
|
+
this._sessions.clear();
|
|
1118
|
+
this._verifiedPassphraseSessionsByConnectId.clear();
|
|
1119
|
+
this._connectingPromises.clear();
|
|
1212
1120
|
this._emitter.removeAllListeners();
|
|
1213
1121
|
}
|
|
1214
1122
|
/**
|
|
@@ -1217,30 +1125,12 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1217
1125
|
* error flows. Aborts active jobs and releases UI waits.
|
|
1218
1126
|
*/
|
|
1219
1127
|
resetState() {
|
|
1220
|
-
void this._resetStateAndDisconnectSessions();
|
|
1221
|
-
}
|
|
1222
|
-
_resetStateAndDisconnectSessions() {
|
|
1223
|
-
if (this._resetPromise) return this._resetPromise;
|
|
1224
|
-
const sessionIds = new Set(this._sessions.values());
|
|
1225
|
-
this._stateGeneration += 1;
|
|
1226
|
-
this._operations.endAll("runtime-reset");
|
|
1227
1128
|
this._uiRegistry.reset();
|
|
1228
1129
|
this._jobQueue.clear();
|
|
1229
1130
|
this._devices.clear();
|
|
1230
1131
|
this._sessions.clear();
|
|
1231
1132
|
this._verifiedPassphraseSessionsByConnectId.clear();
|
|
1232
1133
|
this._connectingPromises.clear();
|
|
1233
|
-
const resetPromise = this._runConnectorTeardown(async () => {
|
|
1234
|
-
for (const sessionId of sessionIds) {
|
|
1235
|
-
await this._connector.disconnect(sessionId).catch(() => void 0);
|
|
1236
|
-
}
|
|
1237
|
-
});
|
|
1238
|
-
this._resetPromise = resetPromise;
|
|
1239
|
-
return resetPromise.finally(() => {
|
|
1240
|
-
if (this._resetPromise === resetPromise) {
|
|
1241
|
-
this._resetPromise = null;
|
|
1242
|
-
}
|
|
1243
|
-
});
|
|
1244
1134
|
}
|
|
1245
1135
|
getAvailableTransports() {
|
|
1246
1136
|
return this.activeTransport ? [this.activeTransport] : [];
|
|
@@ -1248,162 +1138,32 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1248
1138
|
async switchTransport(_type) {
|
|
1249
1139
|
}
|
|
1250
1140
|
async searchDevices(options) {
|
|
1251
|
-
await this._ensureDevicePermission(
|
|
1252
|
-
return this._searchDevices(options);
|
|
1253
|
-
}
|
|
1254
|
-
async _searchDevices(options, signal) {
|
|
1255
|
-
if (options?.transportType && !this._availableTransports().includes(options.transportType))
|
|
1256
|
-
return [];
|
|
1257
|
-
if (options?.resetSession) {
|
|
1258
|
-
await this._resetStateAndDisconnectSessions();
|
|
1259
|
-
} else {
|
|
1260
|
-
await this._connectorTeardownTail;
|
|
1261
|
-
}
|
|
1262
|
-
if (signal?.aborted) throw signal.reason;
|
|
1263
|
-
const stateGeneration = this._stateGeneration;
|
|
1141
|
+
await this._ensureDevicePermission();
|
|
1264
1142
|
const scanned = await this._connector.searchDevices(
|
|
1265
|
-
options?.waitForAllTransports
|
|
1266
|
-
...options.waitForAllTransports ? { waitForAll: true } : {},
|
|
1267
|
-
...options.transportType ? { transportType: options.transportType } : {}
|
|
1268
|
-
} : void 0
|
|
1143
|
+
options?.waitForAllTransports ? { waitForAll: true } : void 0
|
|
1269
1144
|
);
|
|
1270
|
-
if (signal?.aborted) throw signal.reason;
|
|
1271
|
-
if (stateGeneration !== this._stateGeneration) {
|
|
1272
|
-
throw createHwkError({
|
|
1273
|
-
code: HardwareErrorCode.UserAborted,
|
|
1274
|
-
message: "Trezor discovery belongs to an ended operation"
|
|
1275
|
-
});
|
|
1276
|
-
}
|
|
1277
1145
|
const scannedIds = new Set(scanned.map((d) => d.connectId));
|
|
1278
1146
|
for (const connectId of [...this._devices.keys()]) {
|
|
1279
|
-
if (
|
|
1147
|
+
if (!scannedIds.has(connectId) && !this._sessions.has(connectId)) {
|
|
1280
1148
|
this._devices.delete(connectId);
|
|
1281
1149
|
}
|
|
1282
1150
|
}
|
|
1283
1151
|
for (const device of scanned) {
|
|
1284
1152
|
const info = this._connectorDeviceToDeviceInfo(device);
|
|
1285
|
-
|
|
1153
|
+
this._devices.set(info.connectId, info);
|
|
1286
1154
|
}
|
|
1287
|
-
return Array.from(this._devices.values())
|
|
1288
|
-
(device) => !options?.transportType || device.connectionType === options.transportType
|
|
1289
|
-
);
|
|
1155
|
+
return Array.from(this._devices.values());
|
|
1290
1156
|
}
|
|
1291
|
-
async
|
|
1292
|
-
const devices = await this.searchDevices(options);
|
|
1293
|
-
return devices.map((device) => ({
|
|
1294
|
-
searchTargetId: device.connectId,
|
|
1295
|
-
searchTargetReusePolicy: resolveSearchTargetReusePolicy(device),
|
|
1296
|
-
vendor: "trezor",
|
|
1297
|
-
connectionType: device.connectionType,
|
|
1298
|
-
kind: "physical",
|
|
1299
|
-
label: device.label,
|
|
1300
|
-
model: device.model,
|
|
1301
|
-
modelName: device.modelName,
|
|
1302
|
-
serialNumber: device.serialNumber
|
|
1303
|
-
}));
|
|
1304
|
-
}
|
|
1305
|
-
async listConnectionTargets(options) {
|
|
1306
|
-
const targets = await this.searchDeviceTargets(options);
|
|
1307
|
-
return targets.map(({ searchTargetId, ...target }) => ({
|
|
1308
|
-
...target,
|
|
1309
|
-
targetId: searchTargetId
|
|
1310
|
-
}));
|
|
1311
|
-
}
|
|
1312
|
-
async bindBleDevice(params) {
|
|
1313
|
-
if (params.identity?.vendor !== "trezor" || !params.identity.value) {
|
|
1314
|
-
return failure(HardwareErrorCode.InvalidParams, "Trezor device identity is required");
|
|
1315
|
-
}
|
|
1316
|
-
const { value: deviceId } = params.identity;
|
|
1157
|
+
async connectDevice(connectId) {
|
|
1317
1158
|
try {
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
const selected = await this._selectBleDeviceForBinding(
|
|
1322
|
-
deviceId,
|
|
1323
|
-
signal,
|
|
1324
|
-
{ extra: params.extra },
|
|
1325
|
-
"manual-rebind"
|
|
1326
|
-
);
|
|
1327
|
-
try {
|
|
1328
|
-
const persisted = await this._emitVerifiedBinding(
|
|
1329
|
-
deviceId,
|
|
1330
|
-
selected.connectId,
|
|
1331
|
-
selected.selectionRequestId,
|
|
1332
|
-
{ extra: params.extra },
|
|
1333
|
-
signal
|
|
1334
|
-
);
|
|
1335
|
-
if (!persisted) {
|
|
1336
|
-
throw createHwkError({
|
|
1337
|
-
code: HardwareErrorCode.UnknownError,
|
|
1338
|
-
message: "Bluetooth binding could not be saved",
|
|
1339
|
-
origin: "host"
|
|
1340
|
-
});
|
|
1341
|
-
}
|
|
1342
|
-
this._rememberVerifiedConnection(deviceId, selected.connectId);
|
|
1343
|
-
return success(selected.connectId);
|
|
1344
|
-
} catch (error) {
|
|
1345
|
-
await this._releaseProvisionalConnection(selected.connectId, signal);
|
|
1346
|
-
throw error;
|
|
1347
|
-
}
|
|
1348
|
-
},
|
|
1349
|
-
{
|
|
1350
|
-
label: "bindBleDevice",
|
|
1351
|
-
rejectIfBusy: true,
|
|
1352
|
-
busyError: _TrezorAdapter._createDeviceBusyError("bindBleDevice")
|
|
1353
|
-
}
|
|
1354
|
-
);
|
|
1159
|
+
await this._ensureDevicePermission(connectId);
|
|
1160
|
+
await this._ensureSession(connectId);
|
|
1161
|
+
return success(connectId);
|
|
1355
1162
|
} catch (error) {
|
|
1356
1163
|
return this._errorToFailure(error);
|
|
1357
1164
|
}
|
|
1358
1165
|
}
|
|
1359
|
-
async
|
|
1360
|
-
const scope = this._jobQueue.createCancelScope(searchTargetId);
|
|
1361
|
-
try {
|
|
1362
|
-
await _TrezorAdapter._abortable(
|
|
1363
|
-
scope.signal,
|
|
1364
|
-
this._ensureDevicePermission(
|
|
1365
|
-
searchTargetId,
|
|
1366
|
-
void 0,
|
|
1367
|
-
this._devices.get(searchTargetId)?.connectionType
|
|
1368
|
-
)
|
|
1369
|
-
);
|
|
1370
|
-
await this._ensureSession(searchTargetId, scope.signal);
|
|
1371
|
-
if (scope.signal.aborted) throw scope.signal.reason;
|
|
1372
|
-
const device = this._devices.get(searchTargetId);
|
|
1373
|
-
if (!device) {
|
|
1374
|
-
return failure(HardwareErrorCode.DeviceNotFound, "Trezor device not found after connect");
|
|
1375
|
-
}
|
|
1376
|
-
this._operations.endByConnectionKey(searchTargetId, "explicit");
|
|
1377
|
-
const operation = this._operations.create({
|
|
1378
|
-
searchTargetId,
|
|
1379
|
-
connectId: searchTargetId,
|
|
1380
|
-
device,
|
|
1381
|
-
connectionType: device.connectionType,
|
|
1382
|
-
connectionKeys: [this._sessions.get(searchTargetId) ?? ""]
|
|
1383
|
-
});
|
|
1384
|
-
return success(operation.operationId);
|
|
1385
|
-
} catch (error) {
|
|
1386
|
-
if (scope.signal.aborted) {
|
|
1387
|
-
await this._waitForConnectorOperationsToDrain();
|
|
1388
|
-
return failure(HardwareErrorCode.UserAborted, "Trezor connection aborted");
|
|
1389
|
-
}
|
|
1390
|
-
return this._errorToFailure(error);
|
|
1391
|
-
} finally {
|
|
1392
|
-
scope.release();
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
async releaseOperation(operationId) {
|
|
1396
|
-
const operation = this._operations.find(operationId);
|
|
1397
|
-
if (!operation) {
|
|
1398
|
-
this._operations.resolve(operationId);
|
|
1399
|
-
return;
|
|
1400
|
-
}
|
|
1401
|
-
const endedOperation = this._operations.end(operationId, "explicit");
|
|
1402
|
-
if (!endedOperation) return;
|
|
1403
|
-
await this._releaseOperationConnection(endedOperation);
|
|
1404
|
-
}
|
|
1405
|
-
async _releaseOperationConnection(operation) {
|
|
1406
|
-
const { connectId } = operation;
|
|
1166
|
+
async disconnectDevice(connectId) {
|
|
1407
1167
|
const connecting = this._connectingPromises.has(connectId);
|
|
1408
1168
|
this._connectingPromises.delete(connectId);
|
|
1409
1169
|
const sessionId = this._sessions.get(connectId);
|
|
@@ -1411,132 +1171,90 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1411
1171
|
if (connecting) this._disconnectRequested.add(connectId);
|
|
1412
1172
|
return;
|
|
1413
1173
|
}
|
|
1414
|
-
|
|
1174
|
+
this._sessions.delete(connectId);
|
|
1175
|
+
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1176
|
+
await this._connector.disconnect(sessionId);
|
|
1415
1177
|
}
|
|
1416
|
-
async getDeviceInfo(
|
|
1417
|
-
let connectId;
|
|
1418
|
-
try {
|
|
1419
|
-
connectId = isHardwareOperationId(connectIdOrOperationId) ? this._operations.resolve(connectIdOrOperationId).connectId : connectIdOrOperationId;
|
|
1420
|
-
} catch (error) {
|
|
1421
|
-
return this._errorToFailure(error);
|
|
1422
|
-
}
|
|
1178
|
+
async getDeviceInfo(connectId, deviceId) {
|
|
1423
1179
|
const device = this._devices.get(connectId) ?? Array.from(this._devices.values()).find((item) => item.deviceId === deviceId);
|
|
1424
1180
|
if (!device) return failure(HardwareErrorCode.DeviceNotFound, "Trezor device not found");
|
|
1425
1181
|
return success(device);
|
|
1426
1182
|
}
|
|
1183
|
+
getSupportedChains() {
|
|
1184
|
+
return ["btc", "evm", "sol", "tron"];
|
|
1185
|
+
}
|
|
1427
1186
|
async allNetworkGetAddress(connectId, deviceId, params) {
|
|
1428
|
-
const target = resolveHardwareOperationTarget(connectId, params.operationId, "trezor");
|
|
1429
|
-
if (!target.success) return target;
|
|
1430
|
-
let effectiveTargetId = target.payload.targetId ?? "";
|
|
1431
|
-
let releaseOperationRetention;
|
|
1432
|
-
try {
|
|
1433
|
-
releaseOperationRetention = target.payload.operationId ? this._operations.retain(target.payload.operationId) : void 0;
|
|
1434
|
-
} catch (error) {
|
|
1435
|
-
return this._errorToFailure(error);
|
|
1436
|
-
}
|
|
1437
|
-
const cancelScope = this._jobQueue.createCancelScope(
|
|
1438
|
-
trezorQueueKey({ operationId: target.payload.operationId, connectId: effectiveTargetId })
|
|
1439
|
-
);
|
|
1440
1187
|
let liveDeviceId = "";
|
|
1441
|
-
const bundleContext = {};
|
|
1442
1188
|
const topLevelFailureIndexes = /* @__PURE__ */ new Set();
|
|
1443
1189
|
const isSingleNetworkBundle = params.bundle.every(
|
|
1444
1190
|
(item) => item.network === params.bundle[0]?.network
|
|
1445
1191
|
);
|
|
1446
|
-
const getLiveDeviceId = async (
|
|
1192
|
+
const getLiveDeviceId = async () => {
|
|
1447
1193
|
if (liveDeviceId) return success(liveDeviceId);
|
|
1448
|
-
const deviceIdResponse = await this._getTrezorDeviceId(
|
|
1449
|
-
effectiveTargetId,
|
|
1450
|
-
expectedDeviceId || deviceId,
|
|
1451
|
-
params,
|
|
1452
|
-
bundleContext
|
|
1453
|
-
);
|
|
1194
|
+
const deviceIdResponse = await this._getTrezorDeviceId(connectId);
|
|
1454
1195
|
if (deviceIdResponse.success) {
|
|
1455
1196
|
liveDeviceId = deviceIdResponse.payload;
|
|
1456
|
-
if (!target.payload.operationId) {
|
|
1457
|
-
effectiveTargetId = bundleContext.connection?.connectId ?? effectiveTargetId;
|
|
1458
|
-
}
|
|
1459
1197
|
}
|
|
1460
1198
|
return deviceIdResponse;
|
|
1461
1199
|
};
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1200
|
+
return runAllNetworkGetAddress({
|
|
1201
|
+
connectId,
|
|
1202
|
+
deviceId,
|
|
1203
|
+
params,
|
|
1204
|
+
normalizeItem: _TrezorAdapter._normalizeAllNetworkItem,
|
|
1205
|
+
callItem: async ({ method, item, index }) => {
|
|
1206
|
+
const expectedDeviceId = _TrezorAdapter._getItemDeviceId(item) ?? deviceId;
|
|
1207
|
+
if (expectedDeviceId) {
|
|
1208
|
+
const fingerprint = await getLiveDeviceId();
|
|
1209
|
+
if (!fingerprint.success) {
|
|
1470
1210
|
topLevelFailureIndexes.add(index);
|
|
1471
|
-
return
|
|
1211
|
+
return fingerprint;
|
|
1472
1212
|
}
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
if (expectedDeviceId !== fingerprint.payload) {
|
|
1481
|
-
topLevelFailureIndexes.add(index);
|
|
1482
|
-
return failure(
|
|
1483
|
-
HardwareErrorCode.DeviceMismatch,
|
|
1484
|
-
`Wrong device: expected ${expectedDeviceId}, got ${fingerprint.payload}`,
|
|
1485
|
-
{ expected: expectedDeviceId, actual: fingerprint.payload }
|
|
1486
|
-
);
|
|
1487
|
-
}
|
|
1213
|
+
if (expectedDeviceId !== fingerprint.payload) {
|
|
1214
|
+
topLevelFailureIndexes.add(index);
|
|
1215
|
+
return failure(
|
|
1216
|
+
HardwareErrorCode.DeviceMismatch,
|
|
1217
|
+
`Wrong device: expected ${expectedDeviceId}, got ${fingerprint.payload}`,
|
|
1218
|
+
{ expected: expectedDeviceId, actual: fingerprint.payload }
|
|
1219
|
+
);
|
|
1488
1220
|
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
}
|
|
1499
|
-
const fingerprint = await getLiveDeviceId(deviceId);
|
|
1500
|
-
if (!fingerprint.success) {
|
|
1501
|
-
return { ...item, success: false, payload: fingerprint.payload };
|
|
1502
|
-
}
|
|
1221
|
+
}
|
|
1222
|
+
const callItem = _TrezorAdapter._withAllNetworkRequestCommonParams(item, params);
|
|
1223
|
+
return this._callAllNetworkMethod(connectId, method, callItem);
|
|
1224
|
+
},
|
|
1225
|
+
attachIdentity: async ({ item, chain, payload }) => {
|
|
1226
|
+
if (!liveDeviceId) {
|
|
1227
|
+
const fingerprint = await getLiveDeviceId();
|
|
1228
|
+
if (!fingerprint.success) {
|
|
1229
|
+
return { ...item, success: false, payload: fingerprint.payload };
|
|
1503
1230
|
}
|
|
1504
|
-
return {
|
|
1505
|
-
...item,
|
|
1506
|
-
success: true,
|
|
1507
|
-
payload: {
|
|
1508
|
-
...payload,
|
|
1509
|
-
deviceIdentity: {
|
|
1510
|
-
vendor: "trezor",
|
|
1511
|
-
type: "deviceId",
|
|
1512
|
-
value: liveDeviceId
|
|
1513
|
-
},
|
|
1514
|
-
chainFingerprint: liveDeviceId,
|
|
1515
|
-
chainFingerprintChain: chain
|
|
1516
|
-
}
|
|
1517
|
-
};
|
|
1518
|
-
},
|
|
1519
|
-
// One named boolean per abort reason.
|
|
1520
|
-
shouldAbortBundle: (response, { index }) => {
|
|
1521
|
-
const isSessionLevelFailure = topLevelFailureIndexes.has(index);
|
|
1522
|
-
const isWholeChainForbidden = isSingleNetworkBundle && response.payload?.code === HardwareErrorCode.DevicePathForbidden;
|
|
1523
|
-
const isPassphrasePolicyFailure = response.payload?.code === HardwareErrorCode.PassphraseAlwaysOnDevice;
|
|
1524
|
-
const { code } = response.payload ?? {};
|
|
1525
|
-
return isSessionLevelFailure || isWholeChainForbidden || isPassphrasePolicyFailure || isUserRefusal(code) || isConnectionLost(code);
|
|
1526
1231
|
}
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1232
|
+
return {
|
|
1233
|
+
...item,
|
|
1234
|
+
success: true,
|
|
1235
|
+
payload: {
|
|
1236
|
+
...payload,
|
|
1237
|
+
deviceIdentity: {
|
|
1238
|
+
vendor: "trezor",
|
|
1239
|
+
type: "deviceId",
|
|
1240
|
+
value: liveDeviceId
|
|
1241
|
+
},
|
|
1242
|
+
chainFingerprint: liveDeviceId,
|
|
1243
|
+
chainFingerprintChain: chain
|
|
1244
|
+
}
|
|
1245
|
+
};
|
|
1246
|
+
},
|
|
1247
|
+
// One named boolean per abort reason.
|
|
1248
|
+
shouldAbortBundle: (response, { index }) => {
|
|
1249
|
+
const isSessionLevelFailure = topLevelFailureIndexes.has(index);
|
|
1250
|
+
const isWholeChainForbidden = isSingleNetworkBundle && response.payload?.code === HardwareErrorCode.DevicePathForbidden;
|
|
1251
|
+
const isPassphrasePolicyFailure = response.payload?.code === HardwareErrorCode.PassphraseAlwaysOnDevice;
|
|
1252
|
+
return isSessionLevelFailure || isWholeChainForbidden || isPassphrasePolicyFailure;
|
|
1253
|
+
}
|
|
1254
|
+
});
|
|
1532
1255
|
}
|
|
1533
|
-
getFeatures(connectId
|
|
1534
|
-
return this._callDeviceManagerMethod(
|
|
1535
|
-
"getFeatures",
|
|
1536
|
-
connectId,
|
|
1537
|
-
{},
|
|
1538
|
-
operationContext
|
|
1539
|
-
);
|
|
1256
|
+
getFeatures(connectId) {
|
|
1257
|
+
return this._callDeviceManagerMethod("getFeatures", connectId, {});
|
|
1540
1258
|
}
|
|
1541
1259
|
/**
|
|
1542
1260
|
* Device authenticity attestation. Sends a host-generated challenge, has the
|
|
@@ -1596,65 +1314,28 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1596
1314
|
}
|
|
1597
1315
|
});
|
|
1598
1316
|
}
|
|
1599
|
-
deviceSettings(connectId, params
|
|
1317
|
+
deviceSettings(connectId, params) {
|
|
1600
1318
|
return this._callDeviceManagerMethod(
|
|
1601
1319
|
"deviceSettings",
|
|
1602
1320
|
connectId,
|
|
1603
|
-
params
|
|
1604
|
-
operationContext
|
|
1321
|
+
params
|
|
1605
1322
|
);
|
|
1606
1323
|
}
|
|
1607
|
-
setBrightness(connectId, params = {}
|
|
1324
|
+
setBrightness(connectId, params = {}) {
|
|
1608
1325
|
return this._callDeviceManagerMethod(
|
|
1609
1326
|
"setBrightness",
|
|
1610
1327
|
connectId,
|
|
1611
|
-
params
|
|
1612
|
-
operationContext
|
|
1328
|
+
params
|
|
1613
1329
|
);
|
|
1614
1330
|
}
|
|
1615
|
-
changePin(connectId, params = {}
|
|
1616
|
-
return this._callDeviceManagerMethod(
|
|
1617
|
-
"changePin",
|
|
1618
|
-
connectId,
|
|
1619
|
-
params,
|
|
1620
|
-
operationContext
|
|
1621
|
-
);
|
|
1331
|
+
changePin(connectId, params = {}) {
|
|
1332
|
+
return this._callDeviceManagerMethod("changePin", connectId, params);
|
|
1622
1333
|
}
|
|
1623
|
-
wipeDevice(connectId
|
|
1624
|
-
return this._callDeviceManagerMethod(
|
|
1625
|
-
"wipeDevice",
|
|
1626
|
-
connectId,
|
|
1627
|
-
{},
|
|
1628
|
-
operationContext
|
|
1629
|
-
);
|
|
1334
|
+
wipeDevice(connectId) {
|
|
1335
|
+
return this._callDeviceManagerMethod("wipeDevice", connectId, {});
|
|
1630
1336
|
}
|
|
1631
|
-
async _getTrezorDeviceId(connectId
|
|
1632
|
-
const
|
|
1633
|
-
const features = bundleContext || hasConnectionContext ? await this._callMethod(
|
|
1634
|
-
"getFeatures",
|
|
1635
|
-
connectId,
|
|
1636
|
-
hasConnectionContext || !connectId ? expectedDeviceId : void 0,
|
|
1637
|
-
hasConnectionContext ? {
|
|
1638
|
-
operationId: commonParams.operationId,
|
|
1639
|
-
knownConnections: commonParams.knownConnections,
|
|
1640
|
-
extra: commonParams.extra,
|
|
1641
|
-
allowDeviceSelection: commonParams.allowDeviceSelection,
|
|
1642
|
-
supportedTransports: commonParams.supportedTransports,
|
|
1643
|
-
passphraseState: commonParams.passphraseState,
|
|
1644
|
-
useEmptyPassphrase: commonParams.useEmptyPassphrase
|
|
1645
|
-
} : {},
|
|
1646
|
-
false,
|
|
1647
|
-
bundleContext
|
|
1648
|
-
) : await this.getFeatures(
|
|
1649
|
-
connectId,
|
|
1650
|
-
!connectId && expectedDeviceId ? {
|
|
1651
|
-
expectedDeviceIdentity: {
|
|
1652
|
-
vendor: "trezor",
|
|
1653
|
-
type: "deviceId",
|
|
1654
|
-
value: expectedDeviceId
|
|
1655
|
-
}
|
|
1656
|
-
} : void 0
|
|
1657
|
-
);
|
|
1337
|
+
async _getTrezorDeviceId(connectId) {
|
|
1338
|
+
const features = await this.getFeatures(connectId);
|
|
1658
1339
|
if (!features.success) return features;
|
|
1659
1340
|
const liveDeviceId = features.payload.device_id;
|
|
1660
1341
|
if (typeof liveDeviceId !== "string" || liveDeviceId.length === 0) {
|
|
@@ -1663,67 +1344,23 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1663
1344
|
return success(liveDeviceId);
|
|
1664
1345
|
}
|
|
1665
1346
|
cancel(connectId) {
|
|
1666
|
-
if (isHardwareOperationId(connectId)) {
|
|
1667
|
-
try {
|
|
1668
|
-
this._operations.resolve(connectId);
|
|
1669
|
-
} catch {
|
|
1670
|
-
return;
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
1347
|
const userAbortReason = Object.assign(new Error("User aborted operation"), {
|
|
1674
1348
|
code: HardwareErrorCode.UserAborted
|
|
1675
1349
|
});
|
|
1676
|
-
const activeJobId = this._jobQueue.getActiveJob()?.deviceId;
|
|
1677
|
-
const targetId = connectId ?? activeJobId;
|
|
1678
|
-
if (targetId) {
|
|
1679
|
-
let resolvedConnectId = targetId;
|
|
1680
|
-
let operationId;
|
|
1681
|
-
if (isHardwareOperationId(targetId)) {
|
|
1682
|
-
try {
|
|
1683
|
-
operationId = targetId;
|
|
1684
|
-
resolvedConnectId = this._operations.resolve(targetId).connectId;
|
|
1685
|
-
} catch {
|
|
1686
|
-
resolvedConnectId = "";
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
const interactionForPhysicalId = !operationId && connectId ? this._operations.findActiveByConnectionKey(connectId) : void 0;
|
|
1690
|
-
const pendingOperationId = operationId ?? interactionForPhysicalId?.operationId;
|
|
1691
|
-
if (!connectId) {
|
|
1692
|
-
this._uiRegistry.cancel();
|
|
1693
|
-
} else if (pendingOperationId) {
|
|
1694
|
-
this._uiRegistry.cancel(void 0, void 0, pendingOperationId);
|
|
1695
|
-
}
|
|
1696
|
-
const queueKeys = /* @__PURE__ */ new Set([trezorQueueKey({ connectId: targetId })]);
|
|
1697
|
-
if (pendingOperationId) queueKeys.add(trezorQueueKey({ operationId: pendingOperationId }));
|
|
1698
|
-
const ownsConnectorInteraction = activeJobId !== void 0 ? queueKeys.has(activeJobId) || pendingOperationId !== void 0 && this._activeOperationId() === pendingOperationId : this._connectingPromises.size === 1 && this._connectingPromises.has(resolvedConnectId);
|
|
1699
|
-
if (connectId === void 0 || ownsConnectorInteraction) {
|
|
1700
|
-
this._connector.uiResponse({ type: UI_RESPONSE.CANCEL });
|
|
1701
|
-
}
|
|
1702
|
-
for (const key of queueKeys) {
|
|
1703
|
-
this._jobQueue.cancelActiveAndPending(key, userAbortReason);
|
|
1704
|
-
}
|
|
1705
|
-
if (resolvedConnectId) {
|
|
1706
|
-
void this._connector.cancel(this._sessions.get(resolvedConnectId) ?? resolvedConnectId);
|
|
1707
|
-
}
|
|
1708
|
-
return;
|
|
1709
|
-
}
|
|
1710
1350
|
this._uiRegistry.cancel();
|
|
1711
1351
|
this._connector.uiResponse({ type: UI_RESPONSE.CANCEL });
|
|
1712
|
-
|
|
1352
|
+
if (connectId) {
|
|
1353
|
+
this._jobQueue.forceCancelActive(connectId, userAbortReason);
|
|
1354
|
+
void this._connector.cancel(this._sessions.get(connectId) ?? connectId);
|
|
1355
|
+
return;
|
|
1356
|
+
}
|
|
1357
|
+
for (const cid of this._sessions.keys()) {
|
|
1358
|
+
this._jobQueue.forceCancelActive(cid, userAbortReason);
|
|
1359
|
+
}
|
|
1713
1360
|
for (const sessionId of this._sessions.values()) {
|
|
1714
1361
|
void this._connector.cancel(sessionId);
|
|
1715
1362
|
}
|
|
1716
1363
|
}
|
|
1717
|
-
/**
|
|
1718
|
-
* Operation owning the running job: its queue key when pinned, else the live
|
|
1719
|
-
* operation of its connectId, so a mid-call UI request can name it.
|
|
1720
|
-
*/
|
|
1721
|
-
_activeOperationId() {
|
|
1722
|
-
const activeJobId = this._jobQueue.getActiveJob()?.deviceId;
|
|
1723
|
-
if (!activeJobId) return void 0;
|
|
1724
|
-
if (isHardwareOperationId(activeJobId)) return activeJobId;
|
|
1725
|
-
return this._operations.findActiveByConnectionKey(activeJobId)?.operationId;
|
|
1726
|
-
}
|
|
1727
1364
|
/**
|
|
1728
1365
|
* Routes to BOTH the adapter's local UI registry (preemption decisions,
|
|
1729
1366
|
* future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry
|
|
@@ -1732,7 +1369,6 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1732
1369
|
*/
|
|
1733
1370
|
uiResponse(response) {
|
|
1734
1371
|
this._uiRegistry.resolve(response.type, response.payload);
|
|
1735
|
-
if (response.type === UI_RESPONSE.RECEIVE_SELECT_DEVICE) return;
|
|
1736
1372
|
this._connector.uiResponse(response);
|
|
1737
1373
|
}
|
|
1738
1374
|
/**
|
|
@@ -1744,8 +1380,8 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1744
1380
|
* Unlike Ledger (which hashes a per-chain address), it is chain-global, so
|
|
1745
1381
|
* `chain` is accepted for API parity but ignored.
|
|
1746
1382
|
*/
|
|
1747
|
-
async getChainFingerprint(connectId,
|
|
1748
|
-
return this._getTrezorDeviceId(connectId
|
|
1383
|
+
async getChainFingerprint(connectId, _deviceId, _chain) {
|
|
1384
|
+
return this._getTrezorDeviceId(connectId);
|
|
1749
1385
|
}
|
|
1750
1386
|
/**
|
|
1751
1387
|
* Resolve the active passphrase wallet identity (`passphraseState`).
|
|
@@ -1755,87 +1391,17 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1755
1391
|
* can't interleave with a chain call on the same device (which would desync
|
|
1756
1392
|
* the THP session selection).
|
|
1757
1393
|
*/
|
|
1758
|
-
getPassphraseState(connectId, passphraseState
|
|
1759
|
-
const expectedIdentity = operationContext?.expectedDeviceIdentity;
|
|
1760
|
-
if (expectedIdentity && (expectedIdentity.vendor !== "trezor" || expectedIdentity.type !== "deviceId")) {
|
|
1761
|
-
return Promise.resolve(
|
|
1762
|
-
failure(HardwareErrorCode.InvalidParams, "Trezor device identity is required")
|
|
1763
|
-
);
|
|
1764
|
-
}
|
|
1765
|
-
const target = resolveHardwareOperationTarget(
|
|
1766
|
-
connectId,
|
|
1767
|
-
operationContext?.operationId,
|
|
1768
|
-
"trezor"
|
|
1769
|
-
);
|
|
1770
|
-
if (!target.success) return Promise.resolve(target);
|
|
1771
|
-
const { operationId } = target.payload;
|
|
1772
|
-
let resolvedConnectId = target.payload.targetId ?? "";
|
|
1773
|
-
let releaseOperationRetention;
|
|
1774
|
-
if (operationId) {
|
|
1775
|
-
try {
|
|
1776
|
-
resolvedConnectId = this._operations.resolve(operationId).connectId;
|
|
1777
|
-
releaseOperationRetention = this._operations.retain(operationId);
|
|
1778
|
-
} catch (error) {
|
|
1779
|
-
return Promise.resolve(this._errorToFailure(error));
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1394
|
+
getPassphraseState(connectId, passphraseState) {
|
|
1782
1395
|
return this._jobQueue.enqueue(
|
|
1783
|
-
|
|
1396
|
+
connectId,
|
|
1784
1397
|
async (signal) => {
|
|
1785
|
-
|
|
1786
|
-
|
|
1398
|
+
const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {
|
|
1399
|
+
passphraseState
|
|
1400
|
+
});
|
|
1787
1401
|
try {
|
|
1788
|
-
|
|
1789
|
-
const resolved = await this._resolveExpectedDeviceConnectId(
|
|
1790
|
-
expectedIdentity.value,
|
|
1791
|
-
signal,
|
|
1792
|
-
operationContext
|
|
1793
|
-
);
|
|
1794
|
-
resolvedConnectId = resolved.connectId;
|
|
1795
|
-
selectionRequestId = resolved.selectionRequestId;
|
|
1796
|
-
}
|
|
1797
|
-
if (expectedIdentity?.value) {
|
|
1798
|
-
if (!operationId) await this._ensureSession(resolvedConnectId, signal);
|
|
1799
|
-
if (this._devices.get(resolvedConnectId)?.deviceId !== expectedIdentity.value) {
|
|
1800
|
-
return failure(
|
|
1801
|
-
HardwareErrorCode.DeviceMismatch,
|
|
1802
|
-
"Trezor device identity does not match"
|
|
1803
|
-
);
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
const restorePassphraseRequestContext = this._setPassphraseRequestContext(
|
|
1807
|
-
resolvedConnectId,
|
|
1808
|
-
{
|
|
1809
|
-
passphraseState
|
|
1810
|
-
}
|
|
1811
|
-
);
|
|
1812
|
-
try {
|
|
1813
|
-
const result = await this._resolvePassphraseState(
|
|
1814
|
-
resolvedConnectId,
|
|
1815
|
-
passphraseState,
|
|
1816
|
-
signal,
|
|
1817
|
-
operationId
|
|
1818
|
-
);
|
|
1819
|
-
if (result.success && expectedIdentity?.value) {
|
|
1820
|
-
await this._emitVerifiedBinding(
|
|
1821
|
-
expectedIdentity.value,
|
|
1822
|
-
resolvedConnectId,
|
|
1823
|
-
selectionRequestId,
|
|
1824
|
-
operationContext,
|
|
1825
|
-
signal
|
|
1826
|
-
);
|
|
1827
|
-
verified = true;
|
|
1828
|
-
this._rememberVerifiedConnection(expectedIdentity.value, resolvedConnectId);
|
|
1829
|
-
}
|
|
1830
|
-
return result;
|
|
1831
|
-
} finally {
|
|
1832
|
-
restorePassphraseRequestContext();
|
|
1833
|
-
}
|
|
1402
|
+
return await this._resolvePassphraseState(connectId, passphraseState, signal);
|
|
1834
1403
|
} finally {
|
|
1835
|
-
|
|
1836
|
-
this._emitBindingStatus(selectionRequestId, signal.aborted ? "cancelled" : "failed");
|
|
1837
|
-
await this._releaseProvisionalConnection(resolvedConnectId, signal);
|
|
1838
|
-
}
|
|
1404
|
+
restorePassphraseRequestContext();
|
|
1839
1405
|
}
|
|
1840
1406
|
},
|
|
1841
1407
|
{
|
|
@@ -1843,7 +1409,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1843
1409
|
rejectIfBusy: true,
|
|
1844
1410
|
busyError: _TrezorAdapter._createDeviceBusyError("getPassphraseState")
|
|
1845
1411
|
}
|
|
1846
|
-
).catch((error) => this._errorToFailure(error))
|
|
1412
|
+
).catch((error) => this._errorToFailure(error));
|
|
1847
1413
|
}
|
|
1848
1414
|
evmGetAddress(connectId, deviceId, params) {
|
|
1849
1415
|
return this._callWalletMethod("evmGetAddress", connectId, deviceId, params);
|
|
@@ -1906,94 +1472,11 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1906
1472
|
}
|
|
1907
1473
|
return result;
|
|
1908
1474
|
}
|
|
1909
|
-
async _callConnector(sessionId, method, params, signal) {
|
|
1910
|
-
|
|
1911
|
-
throw signal.reason ?? new Error("Aborted");
|
|
1912
|
-
}
|
|
1913
|
-
this._assertConnectorIdle(method);
|
|
1914
|
-
const releaseOperation = this._retainConnectorOperation(`call:${sessionId}`);
|
|
1915
|
-
let promise;
|
|
1916
|
-
try {
|
|
1917
|
-
promise = this._connector.call(sessionId, method, params).finally(() => {
|
|
1918
|
-
releaseOperation();
|
|
1919
|
-
});
|
|
1920
|
-
} catch (error) {
|
|
1921
|
-
releaseOperation();
|
|
1922
|
-
throw error;
|
|
1923
|
-
}
|
|
1475
|
+
static async _callConnector(connector, sessionId, method, params, signal) {
|
|
1476
|
+
const promise = connector.call(sessionId, method, params);
|
|
1924
1477
|
const result = signal ? await _TrezorAdapter._abortable(signal, promise) : await promise;
|
|
1925
1478
|
return _TrezorAdapter._unwrapConnectorResult(result);
|
|
1926
1479
|
}
|
|
1927
|
-
_assertConnectorIdle(method) {
|
|
1928
|
-
if (this._resetPromise || this._pendingConnectorTeardowns > 0 || this._unsettledConnectorOperations.size > 0) {
|
|
1929
|
-
throw _TrezorAdapter._createDeviceBusyError(method);
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
_runConnectorTeardown(task) {
|
|
1933
|
-
const previous = this._connectorTeardownTail;
|
|
1934
|
-
let releaseTail = () => void 0;
|
|
1935
|
-
this._connectorTeardownTail = new Promise((resolve) => {
|
|
1936
|
-
releaseTail = resolve;
|
|
1937
|
-
});
|
|
1938
|
-
this._pendingConnectorTeardowns += 1;
|
|
1939
|
-
return (async () => {
|
|
1940
|
-
try {
|
|
1941
|
-
await previous;
|
|
1942
|
-
await this._waitForConnectorOperationsToDrain();
|
|
1943
|
-
await task();
|
|
1944
|
-
} finally {
|
|
1945
|
-
this._pendingConnectorTeardowns -= 1;
|
|
1946
|
-
releaseTail();
|
|
1947
|
-
}
|
|
1948
|
-
})();
|
|
1949
|
-
}
|
|
1950
|
-
async _disconnectSession(connectId, sessionId = this._sessions.get(connectId)) {
|
|
1951
|
-
this._sessions.delete(connectId);
|
|
1952
|
-
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1953
|
-
if (sessionId) await this._runConnectorTeardown(() => this._connector.disconnect(sessionId));
|
|
1954
|
-
}
|
|
1955
|
-
_availableTransports() {
|
|
1956
|
-
return this._connector.availableTransports ?? [this._connector.connectionType];
|
|
1957
|
-
}
|
|
1958
|
-
async _releaseProvisionalConnection(connectId, signal) {
|
|
1959
|
-
const sessionId = this._sessions.get(connectId);
|
|
1960
|
-
this._sessions.delete(connectId);
|
|
1961
|
-
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1962
|
-
if (!sessionId) return;
|
|
1963
|
-
const teardown = this._runConnectorTeardown(() => this._connector.disconnect(sessionId)).catch(
|
|
1964
|
-
() => void 0
|
|
1965
|
-
);
|
|
1966
|
-
if (!signal.aborted) await teardown;
|
|
1967
|
-
}
|
|
1968
|
-
_waitForConnectorOperationsToDrain() {
|
|
1969
|
-
if (this._unsettledConnectorOperations.size === 0) {
|
|
1970
|
-
return Promise.resolve();
|
|
1971
|
-
}
|
|
1972
|
-
return new Promise((resolve) => {
|
|
1973
|
-
this._connectorIdleWaiters.add(resolve);
|
|
1974
|
-
});
|
|
1975
|
-
}
|
|
1976
|
-
_retainConnectorOperation(key) {
|
|
1977
|
-
this._unsettledConnectorOperations.set(
|
|
1978
|
-
key,
|
|
1979
|
-
(this._unsettledConnectorOperations.get(key) ?? 0) + 1
|
|
1980
|
-
);
|
|
1981
|
-
let released = false;
|
|
1982
|
-
return () => {
|
|
1983
|
-
if (released) return;
|
|
1984
|
-
released = true;
|
|
1985
|
-
const remaining = (this._unsettledConnectorOperations.get(key) ?? 1) - 1;
|
|
1986
|
-
if (remaining > 0) {
|
|
1987
|
-
this._unsettledConnectorOperations.set(key, remaining);
|
|
1988
|
-
} else {
|
|
1989
|
-
this._unsettledConnectorOperations.delete(key);
|
|
1990
|
-
}
|
|
1991
|
-
if (this._unsettledConnectorOperations.size === 0) {
|
|
1992
|
-
for (const resolve of this._connectorIdleWaiters) resolve();
|
|
1993
|
-
this._connectorIdleWaiters.clear();
|
|
1994
|
-
}
|
|
1995
|
-
};
|
|
1996
|
-
}
|
|
1997
1480
|
static _normalizeAllNetworkItem(method, item) {
|
|
1998
1481
|
if (method !== "btcGetAddress" && method !== "btcGetPublicKey") {
|
|
1999
1482
|
return item;
|
|
@@ -2012,21 +1495,18 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2012
1495
|
const { deviceId } = item;
|
|
2013
1496
|
return typeof deviceId === "string" && deviceId.length > 0 ? deviceId : void 0;
|
|
2014
1497
|
}
|
|
2015
|
-
|
|
2016
|
-
static _buildCancelledFailure(signal) {
|
|
2017
|
-
const reason = signal.reason;
|
|
2018
|
-
const code = typeof reason?.code === "number" ? reason.code : HardwareErrorCode.UserAborted;
|
|
2019
|
-
const message = typeof reason?.message === "string" ? reason.message : "";
|
|
2020
|
-
return failure(code, message || "All-network get-address cancelled");
|
|
2021
|
-
}
|
|
2022
|
-
_callAllNetworkMethod(connectId, method, item, bundleContext) {
|
|
1498
|
+
_callAllNetworkMethod(connectId, method, item) {
|
|
2023
1499
|
switch (method) {
|
|
2024
1500
|
case "evmGetAddress":
|
|
1501
|
+
return this.evmGetAddress(connectId, "", item);
|
|
2025
1502
|
case "btcGetAddress":
|
|
1503
|
+
return this.btcGetAddress(connectId, "", item);
|
|
2026
1504
|
case "btcGetPublicKey":
|
|
1505
|
+
return this.btcGetPublicKey(connectId, "", item);
|
|
2027
1506
|
case "solGetAddress":
|
|
1507
|
+
return this.solGetAddress(connectId, "", item);
|
|
2028
1508
|
case "tronGetAddress":
|
|
2029
|
-
return this.
|
|
1509
|
+
return this.tronGetAddress(connectId, "", item);
|
|
2030
1510
|
default:
|
|
2031
1511
|
return Promise.resolve(
|
|
2032
1512
|
failure(
|
|
@@ -2045,51 +1525,11 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2045
1525
|
_callWalletMethod(methodName, connectId, deviceId, params) {
|
|
2046
1526
|
return this._callMethod(methodName, connectId, deviceId, params, true);
|
|
2047
1527
|
}
|
|
2048
|
-
_callDeviceManagerMethod(methodName, connectId, params
|
|
2049
|
-
|
|
2050
|
-
if (expectedIdentity && (expectedIdentity.vendor !== "trezor" || expectedIdentity.type !== "deviceId")) {
|
|
2051
|
-
return Promise.resolve(
|
|
2052
|
-
failure(
|
|
2053
|
-
HardwareErrorCode.InvalidParams,
|
|
2054
|
-
"Trezor device-manager operations require a Trezor deviceId identity"
|
|
2055
|
-
)
|
|
2056
|
-
);
|
|
2057
|
-
}
|
|
2058
|
-
return this._callMethod(
|
|
2059
|
-
methodName,
|
|
2060
|
-
connectId,
|
|
2061
|
-
expectedIdentity?.value,
|
|
2062
|
-
{
|
|
2063
|
-
...params && typeof params === "object" ? params : {},
|
|
2064
|
-
knownConnections: operationContext?.knownConnections,
|
|
2065
|
-
extra: operationContext?.extra,
|
|
2066
|
-
allowDeviceSelection: operationContext?.allowDeviceSelection,
|
|
2067
|
-
supportedTransports: operationContext?.supportedTransports,
|
|
2068
|
-
...operationContext?.operationId ? { operationId: operationContext.operationId } : {}
|
|
2069
|
-
},
|
|
2070
|
-
false
|
|
2071
|
-
);
|
|
1528
|
+
_callDeviceManagerMethod(methodName, connectId, params) {
|
|
1529
|
+
return this._callMethod(methodName, connectId, void 0, params, false);
|
|
2072
1530
|
}
|
|
2073
|
-
async _callMethod(methodName, connectId, deviceId, params, requiresWalletIntent
|
|
1531
|
+
async _callMethod(methodName, connectId, deviceId, params, requiresWalletIntent) {
|
|
2074
1532
|
const call = _TrezorAdapter._normalizeCallArgs(connectId, deviceId, params);
|
|
2075
|
-
const commonParams = _TrezorAdapter._splitCommonParams(call.params);
|
|
2076
|
-
const positionalOperationId = isHardwareOperationId(call.connectId) ? call.connectId : void 0;
|
|
2077
|
-
if (positionalOperationId && commonParams.operationId && positionalOperationId !== commonParams.operationId) {
|
|
2078
|
-
return failure(HardwareErrorCode.InvalidParams, "Conflicting Trezor operation ids", {
|
|
2079
|
-
positionalOperationId,
|
|
2080
|
-
commonOperationId: commonParams.operationId
|
|
2081
|
-
});
|
|
2082
|
-
}
|
|
2083
|
-
const operationId = commonParams.operationId ?? positionalOperationId;
|
|
2084
|
-
let releaseOperationRetention;
|
|
2085
|
-
try {
|
|
2086
|
-
if (operationId) {
|
|
2087
|
-
call.connectId = this._operations.resolve(operationId).connectId;
|
|
2088
|
-
releaseOperationRetention = this._operations.retain(operationId);
|
|
2089
|
-
}
|
|
2090
|
-
} catch (error) {
|
|
2091
|
-
return this._errorToFailure(error);
|
|
2092
|
-
}
|
|
2093
1533
|
debugLog("[TrezorAdapter][REQ]", {
|
|
2094
1534
|
method: methodName,
|
|
2095
1535
|
connectId: call.connectId || "(empty)",
|
|
@@ -2098,40 +1538,15 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2098
1538
|
});
|
|
2099
1539
|
try {
|
|
2100
1540
|
const response = await this._jobQueue.enqueue(
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
commonParams.connectionContext
|
|
2111
|
-
);
|
|
2112
|
-
effectiveConnectId = resolved.connectId;
|
|
2113
|
-
selectionRequestId = resolved.selectionRequestId;
|
|
2114
|
-
}
|
|
2115
|
-
} catch (error) {
|
|
2116
|
-
return this._errorToFailure(error);
|
|
2117
|
-
}
|
|
2118
|
-
const response2 = await this._callWithRetry(
|
|
2119
|
-
bundleContext?.connection?.connectId ?? effectiveConnectId,
|
|
2120
|
-
methodName,
|
|
2121
|
-
call.params,
|
|
2122
|
-
deviceId || "",
|
|
2123
|
-
requiresWalletIntent,
|
|
2124
|
-
true,
|
|
2125
|
-
signal,
|
|
2126
|
-
operationId,
|
|
2127
|
-
selectionRequestId,
|
|
2128
|
-
bundleContext
|
|
2129
|
-
);
|
|
2130
|
-
if (!response2.success && selectionRequestId) {
|
|
2131
|
-
await this._releaseProvisionalConnection(effectiveConnectId, signal);
|
|
2132
|
-
}
|
|
2133
|
-
return response2;
|
|
2134
|
-
},
|
|
1541
|
+
call.connectId,
|
|
1542
|
+
(signal) => this._callWithRetry(
|
|
1543
|
+
call.connectId,
|
|
1544
|
+
methodName,
|
|
1545
|
+
call.params,
|
|
1546
|
+
requiresWalletIntent,
|
|
1547
|
+
true,
|
|
1548
|
+
signal
|
|
1549
|
+
),
|
|
2135
1550
|
{
|
|
2136
1551
|
label: methodName,
|
|
2137
1552
|
rejectIfBusy: true,
|
|
@@ -2152,53 +1567,16 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2152
1567
|
payload: _TrezorAdapter._sanitizeForLog(response.payload, methodName)
|
|
2153
1568
|
});
|
|
2154
1569
|
return response;
|
|
2155
|
-
} finally {
|
|
2156
|
-
releaseOperationRetention?.();
|
|
2157
1570
|
}
|
|
2158
1571
|
}
|
|
2159
|
-
async _callWithRetry(connectId, methodName, params,
|
|
2160
|
-
const { passphraseState, useEmptyPassphrase, rest
|
|
2161
|
-
let pendingBindingRequestId = selectionRequestId;
|
|
2162
|
-
let businessCallStarted = false;
|
|
1572
|
+
async _callWithRetry(connectId, methodName, params, requiresWalletIntent, allowRetry, signal) {
|
|
1573
|
+
const { passphraseState, useEmptyPassphrase, rest } = _TrezorAdapter._splitCommonParams(params);
|
|
2163
1574
|
const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {
|
|
2164
1575
|
passphraseState,
|
|
2165
1576
|
useEmptyPassphrase
|
|
2166
1577
|
});
|
|
2167
1578
|
try {
|
|
2168
|
-
|
|
2169
|
-
const pinned = bundleContext.connection;
|
|
2170
|
-
if (this._sessions.get(pinned.connectId) !== pinned.sessionId) {
|
|
2171
|
-
return failure(
|
|
2172
|
-
HardwareErrorCode.DeviceDisconnected,
|
|
2173
|
-
"Trezor all-network connection ended"
|
|
2174
|
-
);
|
|
2175
|
-
}
|
|
2176
|
-
}
|
|
2177
|
-
const sessionId = operationId ? this._sessions.get(this._operations.resolve(operationId).connectId) : await this._ensureSession(connectId, signal);
|
|
2178
|
-
if (!sessionId) {
|
|
2179
|
-
if (operationId) {
|
|
2180
|
-
this._operations.end(operationId, "disconnect");
|
|
2181
|
-
return failure(
|
|
2182
|
-
HardwareErrorCode.OperationEnded,
|
|
2183
|
-
"Trezor operation connection is no longer active",
|
|
2184
|
-
{ operationId, reason: "disconnect" }
|
|
2185
|
-
);
|
|
2186
|
-
}
|
|
2187
|
-
return failure(HardwareErrorCode.DeviceNotFound, "Trezor session was not found");
|
|
2188
|
-
}
|
|
2189
|
-
if (bundleContext && !bundleContext.connection) {
|
|
2190
|
-
bundleContext.connection = { connectId, sessionId };
|
|
2191
|
-
}
|
|
2192
|
-
if (expectedDeviceId) {
|
|
2193
|
-
const actualDeviceId = this._devices.get(connectId)?.deviceId;
|
|
2194
|
-
if (!actualDeviceId || actualDeviceId !== expectedDeviceId) {
|
|
2195
|
-
return failure(
|
|
2196
|
-
HardwareErrorCode.DeviceMismatch,
|
|
2197
|
-
`Wrong device: expected ${expectedDeviceId}, got ${actualDeviceId || "unknown"}`,
|
|
2198
|
-
{ expected: expectedDeviceId, actual: actualDeviceId || "" }
|
|
2199
|
-
);
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
1579
|
+
const sessionId = await this._ensureSession(connectId, signal);
|
|
2202
1580
|
if (requiresWalletIntent && !passphraseState && useEmptyPassphrase !== true) {
|
|
2203
1581
|
return failure(
|
|
2204
1582
|
HardwareErrorCode.InvalidParams,
|
|
@@ -2213,85 +1591,39 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2213
1591
|
} else if (useEmptyPassphrase === true) {
|
|
2214
1592
|
await _TrezorAdapter._abortable(signal, this._createFreshAppSession(sessionId, signal));
|
|
2215
1593
|
}
|
|
2216
|
-
if (expectedDeviceId) {
|
|
2217
|
-
await this._emitVerifiedBinding(
|
|
2218
|
-
expectedDeviceId,
|
|
2219
|
-
connectId,
|
|
2220
|
-
pendingBindingRequestId,
|
|
2221
|
-
connectionContext,
|
|
2222
|
-
signal
|
|
2223
|
-
);
|
|
2224
|
-
pendingBindingRequestId = void 0;
|
|
2225
|
-
this._rememberVerifiedConnection(expectedDeviceId, connectId);
|
|
2226
|
-
}
|
|
2227
|
-
businessCallStarted = true;
|
|
2228
1594
|
const result = await _TrezorAdapter._abortable(
|
|
2229
1595
|
signal,
|
|
2230
|
-
|
|
1596
|
+
_TrezorAdapter._callConnector(this._connector, sessionId, methodName, rest)
|
|
2231
1597
|
);
|
|
2232
1598
|
return success(result);
|
|
2233
1599
|
} catch (error) {
|
|
2234
1600
|
if (signal.aborted) {
|
|
2235
|
-
if (pendingBindingRequestId) {
|
|
2236
|
-
this._emitBindingStatus(pendingBindingRequestId, "cancelled");
|
|
2237
|
-
pendingBindingRequestId = void 0;
|
|
2238
|
-
}
|
|
2239
1601
|
return this._errorToFailure(error);
|
|
2240
1602
|
}
|
|
2241
1603
|
const code = _TrezorAdapter._errorCode(error);
|
|
2242
|
-
|
|
2243
|
-
if (pendingBindingRequestId && !willRetryStaleSession) {
|
|
2244
|
-
this._emitBindingStatus(pendingBindingRequestId, "failed");
|
|
2245
|
-
pendingBindingRequestId = void 0;
|
|
2246
|
-
}
|
|
2247
|
-
const ambiguousTransportFailure = code === HardwareErrorCode.DeviceDisconnected || code === HardwareErrorCode.OperationTimeout || code === HardwareErrorCode.TransportError;
|
|
2248
|
-
if (ambiguousTransportFailure) {
|
|
1604
|
+
if (allowRetry && code === HardwareErrorCode.DeviceDisconnected) {
|
|
2249
1605
|
this._sessions.delete(connectId);
|
|
2250
1606
|
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
operationMayHaveCompletedParams(methodName, endedParams),
|
|
2260
|
-
void 0,
|
|
2261
|
-
{ scope: "unknown" }
|
|
2262
|
-
) : failure(
|
|
2263
|
-
HardwareErrorCode.OperationEnded,
|
|
2264
|
-
"Trezor operation connection was lost",
|
|
2265
|
-
endedParams
|
|
2266
|
-
);
|
|
2267
|
-
}
|
|
2268
|
-
if (mayHaveCompleted) {
|
|
2269
|
-
return failure(
|
|
2270
|
-
code,
|
|
2271
|
-
mayHaveCompletedMessage,
|
|
2272
|
-
operationMayHaveCompletedParams(methodName),
|
|
2273
|
-
void 0,
|
|
2274
|
-
{ scope: "unknown" }
|
|
2275
|
-
);
|
|
2276
|
-
}
|
|
1607
|
+
return await this._callWithRetry(
|
|
1608
|
+
connectId,
|
|
1609
|
+
methodName,
|
|
1610
|
+
params,
|
|
1611
|
+
requiresWalletIntent,
|
|
1612
|
+
false,
|
|
1613
|
+
signal
|
|
1614
|
+
);
|
|
2277
1615
|
}
|
|
2278
|
-
if (
|
|
1616
|
+
if (allowRetry && (passphraseState || useEmptyPassphrase === true) && _TrezorAdapter._isStaleSessionError(code)) {
|
|
2279
1617
|
if (passphraseState) {
|
|
2280
1618
|
this._forgetVerifiedPassphraseSession(connectId, passphraseState);
|
|
2281
1619
|
}
|
|
2282
|
-
const retryBindingRequestId = pendingBindingRequestId;
|
|
2283
|
-
pendingBindingRequestId = void 0;
|
|
2284
1620
|
return await this._callWithRetry(
|
|
2285
1621
|
connectId,
|
|
2286
1622
|
methodName,
|
|
2287
1623
|
params,
|
|
2288
|
-
expectedDeviceId,
|
|
2289
1624
|
requiresWalletIntent,
|
|
2290
1625
|
false,
|
|
2291
|
-
signal
|
|
2292
|
-
operationId,
|
|
2293
|
-
retryBindingRequestId,
|
|
2294
|
-
bundleContext
|
|
1626
|
+
signal
|
|
2295
1627
|
);
|
|
2296
1628
|
}
|
|
2297
1629
|
debugLog("[TrezorAdapter][ERROR]", {
|
|
@@ -2302,244 +1634,36 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2302
1634
|
return this._errorToFailure(error);
|
|
2303
1635
|
} finally {
|
|
2304
1636
|
restorePassphraseRequestContext();
|
|
2305
|
-
if (pendingBindingRequestId) {
|
|
2306
|
-
this._emitBindingStatus(pendingBindingRequestId, signal.aborted ? "cancelled" : "failed");
|
|
2307
|
-
pendingBindingRequestId = void 0;
|
|
2308
|
-
}
|
|
2309
1637
|
}
|
|
2310
1638
|
}
|
|
2311
|
-
async _ensureSession(connectId, signal
|
|
1639
|
+
async _ensureSession(connectId, signal) {
|
|
2312
1640
|
const existing = this._sessions.get(connectId);
|
|
2313
1641
|
if (existing) return existing;
|
|
2314
1642
|
const pending = this._connectingPromises.get(connectId);
|
|
2315
1643
|
if (pending) return pending;
|
|
2316
|
-
const stateGeneration = this._stateGeneration;
|
|
2317
1644
|
const promise = (async () => {
|
|
2318
|
-
if (signal?.aborted) {
|
|
2319
|
-
throw Object.assign(new Error("Trezor connection aborted"), {
|
|
2320
|
-
code: HardwareErrorCode.UserAborted
|
|
2321
|
-
});
|
|
2322
|
-
}
|
|
2323
1645
|
try {
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1646
|
+
if (signal?.aborted) {
|
|
1647
|
+
throw Object.assign(new Error("Trezor connection aborted"), {
|
|
1648
|
+
code: HardwareErrorCode.UserAborted
|
|
1649
|
+
});
|
|
2329
1650
|
}
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
} finally {
|
|
2337
|
-
if (this._connectingPromises.get(connectId) === promise) {
|
|
2338
|
-
this._connectingPromises.delete(connectId);
|
|
2339
|
-
}
|
|
2340
|
-
this._disconnectRequested.delete(connectId);
|
|
2341
|
-
}
|
|
2342
|
-
}
|
|
2343
|
-
async _resolveExpectedDeviceConnectId(expectedDeviceId, signal, context) {
|
|
2344
|
-
const connectedMatch = Array.from(this._devices.values()).find(
|
|
2345
|
-
(device) => device.deviceId === expectedDeviceId && this._sessions.has(device.connectId)
|
|
2346
|
-
);
|
|
2347
|
-
if (connectedMatch) return { connectId: connectedMatch.connectId };
|
|
2348
|
-
const availableTransports = this._availableTransports();
|
|
2349
|
-
if (availableTransports.includes("usb")) {
|
|
2350
|
-
await _TrezorAdapter._abortable(
|
|
2351
|
-
signal,
|
|
2352
|
-
this._ensureDevicePermission(void 0, expectedDeviceId, "usb")
|
|
2353
|
-
);
|
|
2354
|
-
}
|
|
2355
|
-
const candidates = await _TrezorAdapter._abortable(
|
|
2356
|
-
signal,
|
|
2357
|
-
this._searchDevices({ transportType: "usb" }, signal)
|
|
2358
|
-
);
|
|
2359
|
-
const mismatchedDeviceIds = [];
|
|
2360
|
-
const knownConnection = this._knownDeviceConnections.get(expectedDeviceId);
|
|
2361
|
-
const knownUsbIds = context?.knownConnections !== void 0 ? context.knownConnections.flatMap(
|
|
2362
|
-
(connection) => connection.transport === "usb" ? [connection.connectId] : []
|
|
2363
|
-
) : [knownConnection?.usbConnectId].filter((id) => Boolean(id));
|
|
2364
|
-
const suppliedBleIds = context?.knownConnections?.flatMap(
|
|
2365
|
-
(connection) => connection.transport === "ble" ? [connection.connectId] : []
|
|
2366
|
-
);
|
|
2367
|
-
const knownBleIds = suppliedBleIds?.length ? suppliedBleIds : [knownConnection?.bleConnectId].filter((id) => Boolean(id));
|
|
2368
|
-
const usbCandidates = candidates.filter(
|
|
2369
|
-
(device) => device.connectionType === "usb" && (!knownUsbIds.length || knownUsbIds.includes(device.connectId))
|
|
2370
|
-
);
|
|
2371
|
-
for (const candidate of usbCandidates) {
|
|
2372
|
-
let sessionId;
|
|
2373
|
-
try {
|
|
2374
|
-
sessionId = await this._ensureSession(candidate.connectId, signal, "usb");
|
|
2375
|
-
const actualDeviceId = this._devices.get(candidate.connectId)?.deviceId ?? "";
|
|
2376
|
-
if (actualDeviceId === expectedDeviceId) return { connectId: candidate.connectId };
|
|
2377
|
-
mismatchedDeviceIds.push(actualDeviceId || "unknown");
|
|
2378
|
-
} catch (error) {
|
|
2379
|
-
if (signal.aborted) throw error;
|
|
2380
|
-
if (!_TrezorAdapter._isConnectionUnavailableError(error)) throw error;
|
|
2381
|
-
}
|
|
2382
|
-
if (sessionId) {
|
|
2383
|
-
await this._disconnectSession(candidate.connectId, sessionId);
|
|
2384
|
-
}
|
|
2385
|
-
}
|
|
2386
|
-
if (mismatchedDeviceIds.length) {
|
|
2387
|
-
throw createHwkError({
|
|
2388
|
-
code: HardwareErrorCode.DeviceSearchMismatch,
|
|
2389
|
-
message: "The connected Trezor is not the wallet this operation needs. Unplug it and connect the right device.",
|
|
2390
|
-
params: { connectedDeviceIds: mismatchedDeviceIds }
|
|
2391
|
-
});
|
|
2392
|
-
}
|
|
2393
|
-
if (usbCandidates.length > 0) {
|
|
2394
|
-
throw createHwkError({
|
|
2395
|
-
code: HardwareErrorCode.DeviceNotFound,
|
|
2396
|
-
message: "Trezor devices are present but none could be opened to check its identity."
|
|
2397
|
-
});
|
|
2398
|
-
}
|
|
2399
|
-
const [knownBleConnectId] = knownBleIds;
|
|
2400
|
-
if (knownBleConnectId && availableTransports.includes("ble")) {
|
|
2401
|
-
await _TrezorAdapter._abortable(
|
|
2402
|
-
signal,
|
|
2403
|
-
this._ensureDevicePermission(knownBleConnectId, expectedDeviceId, "ble")
|
|
2404
|
-
);
|
|
2405
|
-
await this._ensureSession(knownBleConnectId, signal, "ble");
|
|
2406
|
-
const actualDeviceId = this._devices.get(knownBleConnectId)?.deviceId;
|
|
2407
|
-
if (actualDeviceId === expectedDeviceId) return { connectId: knownBleConnectId };
|
|
2408
|
-
await this._disconnectSession(knownBleConnectId);
|
|
2409
|
-
throw createHwkError({
|
|
2410
|
-
code: HardwareErrorCode.DeviceMismatch,
|
|
2411
|
-
message: "The bound Trezor Bluetooth device has a different identity"
|
|
2412
|
-
});
|
|
2413
|
-
}
|
|
2414
|
-
if (context?.supportedTransports && !context.supportedTransports.includes("ble")) {
|
|
2415
|
-
throw createHwkError({
|
|
2416
|
-
code: HardwareErrorCode.DeviceNotFound,
|
|
2417
|
-
message: "This Trezor model has no Bluetooth transport; connect it over USB"
|
|
2418
|
-
});
|
|
2419
|
-
}
|
|
2420
|
-
if (context?.allowDeviceSelection === false) {
|
|
2421
|
-
throw createHwkError({
|
|
2422
|
-
code: HardwareErrorCode.DeviceNotFound,
|
|
2423
|
-
message: "No known Trezor connection is available"
|
|
2424
|
-
});
|
|
2425
|
-
}
|
|
2426
|
-
return this._selectBleDeviceForBinding(expectedDeviceId, signal, context, "missing-binding");
|
|
2427
|
-
}
|
|
2428
|
-
async _selectBleDeviceForBinding(expectedDeviceId, signal, context, reason) {
|
|
2429
|
-
const availableTransports = this._availableTransports();
|
|
2430
|
-
const allowUsbFallback = reason !== "manual-rebind" && availableTransports.includes("usb");
|
|
2431
|
-
const knownUsbIds = context?.knownConnections ? context.knownConnections.flatMap(
|
|
2432
|
-
(connection) => connection.transport === "usb" ? [connection.connectId] : []
|
|
2433
|
-
) : [this._knownDeviceConnections.get(expectedDeviceId)?.usbConnectId];
|
|
2434
|
-
if (availableTransports.includes("ble")) {
|
|
2435
|
-
await _TrezorAdapter._abortable(
|
|
2436
|
-
signal,
|
|
2437
|
-
this._ensureDevicePermission(void 0, expectedDeviceId, "ble")
|
|
2438
|
-
);
|
|
2439
|
-
}
|
|
2440
|
-
const bleCandidates = (await _TrezorAdapter._abortable(
|
|
2441
|
-
signal,
|
|
2442
|
-
this._searchDevices({ transportType: "ble", waitForAllTransports: true }, signal)
|
|
2443
|
-
)).filter((device) => device.connectionType === "ble");
|
|
2444
|
-
if (signal.aborted) throw signal.reason;
|
|
2445
|
-
const rejectedConnectIds = /* @__PURE__ */ new Set();
|
|
2446
|
-
const bindingSessionId = this._uiRegistry.createRequestId();
|
|
2447
|
-
let rejectedConnectId;
|
|
2448
|
-
while (availableTransports.includes("ble") && this._emitter.listenerCount(UI_REQUEST.REQUEST_SELECT_DEVICE)) {
|
|
2449
|
-
const { device: selected, requestId } = await requestBleDeviceSelection({
|
|
2450
|
-
emitter: this._emitter,
|
|
2451
|
-
registry: this._uiRegistry,
|
|
2452
|
-
signal,
|
|
2453
|
-
allowUsbFallback,
|
|
2454
|
-
scan: async () => {
|
|
2455
|
-
if (allowUsbFallback) {
|
|
2456
|
-
const usbCandidates = (await this._searchDevices({ transportType: "usb" }, signal)).filter(
|
|
2457
|
-
(device) => device.connectionType === "usb" && !rejectedConnectIds.has(device.connectId)
|
|
2458
|
-
);
|
|
2459
|
-
const candidate = usbCandidates.find((device) => knownUsbIds.includes(device.connectId)) ?? usbCandidates[0];
|
|
2460
|
-
if (candidate) return [candidate];
|
|
1651
|
+
try {
|
|
1652
|
+
return await this._connectSession(connectId, signal);
|
|
1653
|
+
} catch (error) {
|
|
1654
|
+
if (_TrezorAdapter._isConnectionUnavailableError(error)) {
|
|
1655
|
+
this._sessions.delete(connectId);
|
|
1656
|
+
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
2461
1657
|
}
|
|
2462
|
-
|
|
2463
|
-
(device) => device.connectionType === "ble" && !rejectedConnectIds.has(device.connectId)
|
|
2464
|
-
);
|
|
2465
|
-
},
|
|
2466
|
-
request: {
|
|
2467
|
-
devices: bleCandidates.filter((device) => !rejectedConnectIds.has(device.connectId)),
|
|
2468
|
-
bindingSessionId,
|
|
2469
|
-
rejectedConnectId,
|
|
2470
|
-
context: {
|
|
2471
|
-
kind: "bind-connection",
|
|
2472
|
-
transport: "ble",
|
|
2473
|
-
reason
|
|
2474
|
-
},
|
|
2475
|
-
extra: context?.extra,
|
|
2476
|
-
operationId: this._activeOperationId()
|
|
2477
|
-
}
|
|
2478
|
-
});
|
|
2479
|
-
try {
|
|
2480
|
-
if (reason === "manual-rebind") {
|
|
2481
|
-
this._operations.endByConnectionKey(selected.connectId, "explicit");
|
|
2482
|
-
await this._releaseProvisionalConnection(selected.connectId, signal);
|
|
1658
|
+
throw error;
|
|
2483
1659
|
}
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
this.
|
|
2487
|
-
throw error;
|
|
2488
|
-
}
|
|
2489
|
-
if (this._devices.get(selected.connectId)?.deviceId !== expectedDeviceId) {
|
|
2490
|
-
await this._disconnectSession(selected.connectId);
|
|
2491
|
-
rejectedConnectId = selected.connectId;
|
|
2492
|
-
rejectedConnectIds.add(selected.connectId);
|
|
2493
|
-
continue;
|
|
2494
|
-
}
|
|
2495
|
-
if (selected.connectionType === "usb") {
|
|
2496
|
-
this._emitBindingStatus(requestId, "cancelled");
|
|
2497
|
-
return { connectId: selected.connectId };
|
|
1660
|
+
} finally {
|
|
1661
|
+
this._connectingPromises.delete(connectId);
|
|
1662
|
+
this._disconnectRequested.delete(connectId);
|
|
2498
1663
|
}
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
code: HardwareErrorCode.DeviceNotFound,
|
|
2503
|
-
message: "No readable Trezor device is available"
|
|
2504
|
-
});
|
|
2505
|
-
}
|
|
2506
|
-
_emitBindingStatus(selectionRequestId, status) {
|
|
2507
|
-
this._emitter.emit(UI_REQUEST.DEVICE_BINDING_STATUS, {
|
|
2508
|
-
type: UI_REQUEST.DEVICE_BINDING_STATUS,
|
|
2509
|
-
payload: { selectionRequestId, status }
|
|
2510
|
-
});
|
|
2511
|
-
}
|
|
2512
|
-
_rememberVerifiedConnection(deviceId, connectId) {
|
|
2513
|
-
const device = this._devices.get(connectId);
|
|
2514
|
-
if (!device || device.deviceId !== deviceId) return;
|
|
2515
|
-
const known = this._knownDeviceConnections.get(deviceId) ?? { deviceId };
|
|
2516
|
-
if (device.connectionType === "ble") {
|
|
2517
|
-
known.bleConnectId = connectId;
|
|
2518
|
-
} else if (device.connectionType === "usb" && device.capabilities?.persistentDeviceIdentity) {
|
|
2519
|
-
known.usbConnectId = connectId;
|
|
2520
|
-
}
|
|
2521
|
-
this._knownDeviceConnections.set(deviceId, known);
|
|
2522
|
-
}
|
|
2523
|
-
async _emitVerifiedBinding(deviceId, connectId, selectionRequestId, context, signal) {
|
|
2524
|
-
if (!selectionRequestId) return false;
|
|
2525
|
-
const device = this._devices.get(connectId);
|
|
2526
|
-
if (!device || device.deviceId !== deviceId || device.connectionType !== "ble") {
|
|
2527
|
-
this._emitBindingStatus(selectionRequestId, "cancelled");
|
|
2528
|
-
return false;
|
|
2529
|
-
}
|
|
2530
|
-
const outcome = await requestSaveDeviceBinding(
|
|
2531
|
-
this._emitter,
|
|
2532
|
-
this._uiRegistry,
|
|
2533
|
-
{
|
|
2534
|
-
selectionRequestId,
|
|
2535
|
-
connection: { transport: "ble", connectId },
|
|
2536
|
-
identity: { vendor: "trezor", type: "deviceId", value: deviceId },
|
|
2537
|
-
extra: context?.extra,
|
|
2538
|
-
operationId: this._activeOperationId()
|
|
2539
|
-
},
|
|
2540
|
-
signal
|
|
2541
|
-
);
|
|
2542
|
-
return outcome.saved;
|
|
1664
|
+
})();
|
|
1665
|
+
this._connectingPromises.set(connectId, promise);
|
|
1666
|
+
return promise;
|
|
2543
1667
|
}
|
|
2544
1668
|
/**
|
|
2545
1669
|
* Pin the device's active wallet session to `passphraseState` (the target
|
|
@@ -2561,21 +1685,12 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2561
1685
|
if (reused) return;
|
|
2562
1686
|
const created = await _TrezorAdapter._abortable(
|
|
2563
1687
|
signal,
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
{
|
|
2568
|
-
passphraseMode: "prompt"
|
|
2569
|
-
},
|
|
2570
|
-
signal
|
|
2571
|
-
)
|
|
1688
|
+
_TrezorAdapter._callConnector(this._connector, sessionId, "__thpCreateSession", {
|
|
1689
|
+
passphraseMode: "prompt"
|
|
1690
|
+
})
|
|
2572
1691
|
);
|
|
2573
|
-
if (created?.protocol === "thp" && !created.thpSessionId
|
|
2574
|
-
|
|
2575
|
-
code: HardwareErrorCode.TransportError,
|
|
2576
|
-
message: "Cannot verify the requested Trezor wallet session"
|
|
2577
|
-
});
|
|
2578
|
-
}
|
|
1692
|
+
if (created?.protocol === "thp" && !created.thpSessionId) return;
|
|
1693
|
+
if (created?.protocol !== "thp" && created?.protocol !== "v1") return;
|
|
2579
1694
|
const state = await this._deriveState(sessionId, signal);
|
|
2580
1695
|
if (state !== passphraseState) {
|
|
2581
1696
|
throw Object.assign(
|
|
@@ -2625,14 +1740,9 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2625
1740
|
if (!cached.thpSessionId) return false;
|
|
2626
1741
|
await _TrezorAdapter._abortable(
|
|
2627
1742
|
signal,
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
{
|
|
2632
|
-
thpSessionId: cached.thpSessionId
|
|
2633
|
-
},
|
|
2634
|
-
signal
|
|
2635
|
-
)
|
|
1743
|
+
_TrezorAdapter._callConnector(this._connector, sessionId, "__thpSelectSession", {
|
|
1744
|
+
thpSessionId: cached.thpSessionId
|
|
1745
|
+
})
|
|
2636
1746
|
);
|
|
2637
1747
|
}
|
|
2638
1748
|
const state = await this._deriveState(sessionId, signal);
|
|
@@ -2650,14 +1760,9 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2650
1760
|
async _createFreshAppSession(sessionId, signal) {
|
|
2651
1761
|
await _TrezorAdapter._abortable(
|
|
2652
1762
|
signal,
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
{
|
|
2657
|
-
passphraseMode: "empty"
|
|
2658
|
-
},
|
|
2659
|
-
signal
|
|
2660
|
-
)
|
|
1763
|
+
_TrezorAdapter._callConnector(this._connector, sessionId, "__thpCreateSession", {
|
|
1764
|
+
passphraseMode: "empty"
|
|
1765
|
+
})
|
|
2661
1766
|
);
|
|
2662
1767
|
}
|
|
2663
1768
|
/**
|
|
@@ -2672,15 +1777,10 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2672
1777
|
async _deriveState(sessionId, signal) {
|
|
2673
1778
|
const derived = await _TrezorAdapter._abortable(
|
|
2674
1779
|
signal,
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
path: "m/44'/0'/0'",
|
|
2680
|
-
showOnDevice: false
|
|
2681
|
-
},
|
|
2682
|
-
signal
|
|
2683
|
-
)
|
|
1780
|
+
_TrezorAdapter._callConnector(this._connector, sessionId, "btcGetPublicKey", {
|
|
1781
|
+
path: "m/44'/0'/0'",
|
|
1782
|
+
showOnDevice: false
|
|
1783
|
+
})
|
|
2684
1784
|
);
|
|
2685
1785
|
const state = derived?.publicKey;
|
|
2686
1786
|
if (!state) {
|
|
@@ -2690,34 +1790,23 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2690
1790
|
}
|
|
2691
1791
|
return state;
|
|
2692
1792
|
}
|
|
2693
|
-
async _resolvePassphraseState(connectId, passphraseState, signal
|
|
1793
|
+
async _resolvePassphraseState(connectId, passphraseState, signal) {
|
|
2694
1794
|
try {
|
|
2695
|
-
const sessionId =
|
|
2696
|
-
if (!sessionId) {
|
|
2697
|
-
return failure(
|
|
2698
|
-
HardwareErrorCode.OperationEnded,
|
|
2699
|
-
"Trezor operation connection is no longer active"
|
|
2700
|
-
);
|
|
2701
|
-
}
|
|
1795
|
+
const sessionId = await this._ensureSession(connectId, signal);
|
|
2702
1796
|
if (passphraseState) {
|
|
2703
1797
|
await this._alignAppSession(connectId, sessionId, passphraseState, signal);
|
|
2704
1798
|
return success(passphraseState);
|
|
2705
1799
|
}
|
|
2706
1800
|
const created = await _TrezorAdapter._abortable(
|
|
2707
1801
|
signal,
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
{
|
|
2712
|
-
passphraseMode: "prompt"
|
|
2713
|
-
},
|
|
2714
|
-
signal
|
|
2715
|
-
)
|
|
1802
|
+
_TrezorAdapter._callConnector(this._connector, sessionId, "__thpCreateSession", {
|
|
1803
|
+
passphraseMode: "prompt"
|
|
1804
|
+
})
|
|
2716
1805
|
);
|
|
2717
1806
|
const state = await this._deriveState(sessionId, signal);
|
|
2718
1807
|
const features = await _TrezorAdapter._abortable(
|
|
2719
1808
|
signal,
|
|
2720
|
-
|
|
1809
|
+
_TrezorAdapter._callConnector(this._connector, sessionId, "getFeatures", { refresh: true })
|
|
2721
1810
|
);
|
|
2722
1811
|
if (features?.passphrase_protection !== true) {
|
|
2723
1812
|
return success(null);
|
|
@@ -2767,16 +1856,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2767
1856
|
}
|
|
2768
1857
|
const trustedNumericCode = typeof typed.code === "number" && KNOWN_HARDWARE_ERROR_CODES.has(typed.code) ? typed.code : void 0;
|
|
2769
1858
|
const code = trustedNumericCode ?? _TrezorAdapter._mapTrezorFailureCode(error) ?? HardwareErrorCode.UnknownError;
|
|
2770
|
-
|
|
2771
|
-
const origin = stampedOrigin === "device" || stampedOrigin === "transport" || stampedOrigin === "host" ? stampedOrigin : defaultOriginForCode(code);
|
|
2772
|
-
const params = typed.params && typeof typed.params === "object" ? typed.params : void 0;
|
|
2773
|
-
return failure(
|
|
2774
|
-
code,
|
|
2775
|
-
typed.message ?? String(error),
|
|
2776
|
-
params,
|
|
2777
|
-
origin,
|
|
2778
|
-
isHwkRecoveryHint(typed.recovery) ? typed.recovery : void 0
|
|
2779
|
-
);
|
|
1859
|
+
return failure(code, typed.message ?? String(error));
|
|
2780
1860
|
}
|
|
2781
1861
|
/**
|
|
2782
1862
|
* Emit `REQUEST_DEVICE_PERMISSION` and await the host's
|
|
@@ -2791,33 +1871,29 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
2791
1871
|
* - no `connectId` → environment-level check (scan / picker)
|
|
2792
1872
|
* - with `connectId` → device-level check (per-call gating)
|
|
2793
1873
|
*/
|
|
2794
|
-
async _ensureDevicePermission(connectId, deviceId
|
|
1874
|
+
async _ensureDevicePermission(connectId, deviceId) {
|
|
2795
1875
|
if (!this._emitter.listenerCount(UI_REQUEST.REQUEST_DEVICE_PERMISSION)) {
|
|
2796
1876
|
return;
|
|
2797
1877
|
}
|
|
2798
|
-
const transportType =
|
|
2799
|
-
const operationId = this._activeOperationId();
|
|
1878
|
+
const transportType = this.activeTransport ?? "usb";
|
|
2800
1879
|
const waitPromise = this._uiRegistry.wait(
|
|
2801
1880
|
UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
2802
|
-
{ timeoutMs: 6e4
|
|
1881
|
+
{ timeoutMs: 6e4 }
|
|
2803
1882
|
);
|
|
2804
1883
|
this._emitter.emit(UI_REQUEST.REQUEST_DEVICE_PERMISSION, {
|
|
2805
1884
|
type: UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
2806
|
-
payload: { transportType, connectId, deviceId
|
|
1885
|
+
payload: { transportType, connectId, deviceId }
|
|
2807
1886
|
});
|
|
2808
|
-
const { granted
|
|
1887
|
+
const { granted } = await waitPromise;
|
|
2809
1888
|
if (!granted) {
|
|
2810
1889
|
throw Object.assign(new Error("Device permission denied"), {
|
|
2811
|
-
code: HardwareErrorCode.DevicePermissionDenied
|
|
2812
|
-
...reason ? { params: { permissionDeniedReason: reason } } : {}
|
|
1890
|
+
code: HardwareErrorCode.DevicePermissionDenied
|
|
2813
1891
|
});
|
|
2814
1892
|
}
|
|
2815
1893
|
}
|
|
2816
1894
|
};
|
|
2817
1895
|
// Keys are matched after normalizeLogKey, so snake_case/camelCase both hit.
|
|
2818
1896
|
_TrezorAdapter._sensitiveLogKeys = /* @__PURE__ */ new Set([
|
|
2819
|
-
"extra",
|
|
2820
|
-
"knownconnections",
|
|
2821
1897
|
"credential",
|
|
2822
1898
|
"credentials",
|
|
2823
1899
|
"entropy",
|