@onekeyfe/hwk-trezor-adapter 1.2.7 → 1.2.8-alpha.1
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 +66 -25
- package/dist/index.d.ts +66 -25
- package/dist/index.js +1172 -234
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1158 -220
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -5,6 +5,21 @@
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
8
23
|
|
|
9
24
|
|
|
10
25
|
|
|
@@ -762,10 +777,34 @@ function debugLog(...args) {
|
|
|
762
777
|
emitLog("debug", ...args);
|
|
763
778
|
}
|
|
764
779
|
|
|
780
|
+
// src/utils/queueKey.ts
|
|
781
|
+
function trezorQueueKey({
|
|
782
|
+
operationId,
|
|
783
|
+
connectId
|
|
784
|
+
}) {
|
|
785
|
+
return operationId || connectId || "";
|
|
786
|
+
}
|
|
787
|
+
|
|
765
788
|
// src/adapter/TrezorAdapter.ts
|
|
766
789
|
var KNOWN_HARDWARE_ERROR_CODES = new Set(
|
|
767
790
|
Object.values(_hwkadaptercore.HardwareErrorCode).filter((value) => typeof value === "number")
|
|
768
791
|
);
|
|
792
|
+
var ALL_NETWORK_COMMON_PARAM_KEYS = [
|
|
793
|
+
"autoInstallApp",
|
|
794
|
+
"passphraseState",
|
|
795
|
+
"useEmptyPassphrase",
|
|
796
|
+
"operationId",
|
|
797
|
+
"knownConnections",
|
|
798
|
+
"extra",
|
|
799
|
+
"allowDeviceSelection",
|
|
800
|
+
"supportedTransports"
|
|
801
|
+
];
|
|
802
|
+
var ALL_NETWORK_ROUTING_PARAM_KEYS = [
|
|
803
|
+
"operationId",
|
|
804
|
+
"knownConnections",
|
|
805
|
+
"allowDeviceSelection",
|
|
806
|
+
"supportedTransports"
|
|
807
|
+
];
|
|
769
808
|
var TREZOR_BTC_NETWORK_COIN_MAP = {
|
|
770
809
|
btc: "Bitcoin",
|
|
771
810
|
bitcoin: "Bitcoin",
|
|
@@ -782,9 +821,24 @@ var TREZOR_BTC_NETWORK_COIN_MAP = {
|
|
|
782
821
|
dash: "Dash"
|
|
783
822
|
};
|
|
784
823
|
var _TrezorAdapter = class _TrezorAdapter {
|
|
785
|
-
constructor(connector) {
|
|
824
|
+
constructor(connector, options) {
|
|
786
825
|
this.vendor = "trezor";
|
|
826
|
+
// The connector has no protocol-level cancel: the adapter stops waiting and
|
|
827
|
+
// drops the late response, the device carries on.
|
|
828
|
+
this.cancelCapability = "stops-waiting";
|
|
787
829
|
this._emitter = new (0, _hwkadaptercore.TypedEventEmitter)();
|
|
830
|
+
this._operations = new (0, _hwkadaptercore.OperationRegistry)({
|
|
831
|
+
vendor: "trezor",
|
|
832
|
+
onEnded: (operation, reason) => {
|
|
833
|
+
this._emitter.emit(_hwkadaptercore.SDK.OPERATION_ENDED, {
|
|
834
|
+
type: _hwkadaptercore.SDK.OPERATION_ENDED,
|
|
835
|
+
payload: { operationId: operation.operationId, reason }
|
|
836
|
+
});
|
|
837
|
+
if (reason === "timeout") {
|
|
838
|
+
void this._releaseOperationConnection(operation).catch(() => void 0);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
});
|
|
788
842
|
this._devices = /* @__PURE__ */ new Map();
|
|
789
843
|
this._sessions = /* @__PURE__ */ new Map();
|
|
790
844
|
this._connectingPromises = /* @__PURE__ */ new Map();
|
|
@@ -793,12 +847,21 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
793
847
|
this._uiRegistry = new (0, _hwkadaptercore.UiRequestRegistry)();
|
|
794
848
|
this._passphraseRequestContextByConnectId = /* @__PURE__ */ new Map();
|
|
795
849
|
this._verifiedPassphraseSessionsByConnectId = /* @__PURE__ */ new Map();
|
|
850
|
+
/** Raw connector calls that outlive an aborted caller, keyed by session. */
|
|
851
|
+
this._unsettledConnectorOperations = /* @__PURE__ */ new Map();
|
|
852
|
+
this._connectorIdleWaiters = /* @__PURE__ */ new Set();
|
|
853
|
+
this._resetPromise = null;
|
|
854
|
+
this._connectorTeardownTail = Promise.resolve();
|
|
855
|
+
this._pendingConnectorTeardowns = 0;
|
|
856
|
+
this._stateGeneration = 0;
|
|
857
|
+
this._knownDeviceConnections = /* @__PURE__ */ new Map();
|
|
796
858
|
this._onDeviceConnect = (data) => {
|
|
797
859
|
const device = this._connectorDeviceToDeviceInfo(data.device);
|
|
798
860
|
this._devices.set(device.connectId, device);
|
|
799
861
|
this._emitter.emit(_hwkadaptercore.DEVICE.CONNECT, { type: _hwkadaptercore.DEVICE.CONNECT, payload: device });
|
|
800
862
|
};
|
|
801
863
|
this._onDeviceDisconnect = (data) => {
|
|
864
|
+
this._operations.endByConnectionKey(data.connectId, "disconnect");
|
|
802
865
|
this._sessions.delete(data.connectId);
|
|
803
866
|
this._verifiedPassphraseSessionsByConnectId.delete(data.connectId);
|
|
804
867
|
this._devices.delete(data.connectId);
|
|
@@ -818,25 +881,32 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
818
881
|
payload: { device }
|
|
819
882
|
});
|
|
820
883
|
};
|
|
884
|
+
// The one outlet for every connector-raised UI request (PIN, passphrase,
|
|
885
|
+
// button, THP pairing), so the operation is stamped here instead of at each
|
|
886
|
+
// connector call site.
|
|
821
887
|
this._onUiRequest = (data) => {
|
|
888
|
+
const operationId = this._activeOperationId();
|
|
889
|
+
const basePayload = data.payload && typeof data.payload === "object" ? data.payload : {};
|
|
890
|
+
const attribution = operationId === void 0 ? {} : { operationId };
|
|
822
891
|
if (data.type === _hwkadaptercore.UI_REQUEST.REQUEST_PASSPHRASE) {
|
|
823
|
-
const
|
|
824
|
-
const connectId = typeof payload.connectId === "string" ? payload.connectId : void 0;
|
|
892
|
+
const connectId = typeof basePayload.connectId === "string" ? basePayload.connectId : void 0;
|
|
825
893
|
const context = connectId ? this._passphraseRequestContextByConnectId.get(connectId) : void 0;
|
|
826
894
|
this._emitter.emit(
|
|
827
895
|
data.type,
|
|
828
896
|
{
|
|
829
897
|
...data,
|
|
830
898
|
payload: {
|
|
831
|
-
...
|
|
899
|
+
...basePayload,
|
|
832
900
|
..._optionalChain([context, 'optionalAccess', _13 => _13.passphraseState]) !== void 0 ? { passphraseState: context.passphraseState } : {},
|
|
833
|
-
..._optionalChain([context, 'optionalAccess', _14 => _14.useEmptyPassphrase]) !== void 0 ? { useEmptyPassphrase: context.useEmptyPassphrase } : {}
|
|
901
|
+
..._optionalChain([context, 'optionalAccess', _14 => _14.useEmptyPassphrase]) !== void 0 ? { useEmptyPassphrase: context.useEmptyPassphrase } : {},
|
|
902
|
+
...attribution
|
|
834
903
|
}
|
|
835
904
|
}
|
|
836
905
|
);
|
|
837
906
|
return;
|
|
838
907
|
}
|
|
839
|
-
|
|
908
|
+
const payload = operationId === void 0 ? data.payload : { ...basePayload, ...attribution };
|
|
909
|
+
this._emitter.emit(data.type, { ...data, payload });
|
|
840
910
|
};
|
|
841
911
|
this._onUiEvent = (data) => {
|
|
842
912
|
this._emitter.emit("ui-event", data);
|
|
@@ -848,6 +918,11 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
848
918
|
});
|
|
849
919
|
};
|
|
850
920
|
this._connector = connector;
|
|
921
|
+
for (const connection of _nullishCoalesce(_optionalChain([options, 'optionalAccess', _15 => _15.knownDeviceConnections]), () => ( []))) {
|
|
922
|
+
if (connection.deviceId) {
|
|
923
|
+
this._knownDeviceConnections.set(connection.deviceId, { ...connection });
|
|
924
|
+
}
|
|
925
|
+
}
|
|
851
926
|
this._jobQueue = new (0, _hwkadaptercore.DeviceJobQueue)();
|
|
852
927
|
this._registerConnectorEvents();
|
|
853
928
|
}
|
|
@@ -872,29 +947,35 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
872
947
|
const {
|
|
873
948
|
passphraseState,
|
|
874
949
|
autoInstallApp: _autoInstallApp,
|
|
950
|
+
operationId,
|
|
875
951
|
useEmptyPassphrase,
|
|
952
|
+
knownConnections,
|
|
953
|
+
extra,
|
|
954
|
+
allowDeviceSelection,
|
|
955
|
+
supportedTransports,
|
|
876
956
|
...rest
|
|
877
957
|
} = params;
|
|
878
958
|
return {
|
|
879
959
|
passphraseState: typeof passphraseState === "string" ? passphraseState : void 0,
|
|
880
960
|
useEmptyPassphrase: typeof useEmptyPassphrase === "boolean" ? useEmptyPassphrase : void 0,
|
|
961
|
+
operationId: typeof operationId === "string" ? operationId : void 0,
|
|
962
|
+
connectionContext: {
|
|
963
|
+
knownConnections,
|
|
964
|
+
extra,
|
|
965
|
+
allowDeviceSelection: typeof allowDeviceSelection === "boolean" ? allowDeviceSelection : void 0,
|
|
966
|
+
supportedTransports
|
|
967
|
+
},
|
|
881
968
|
rest
|
|
882
969
|
};
|
|
883
970
|
}
|
|
884
971
|
return { rest: _nullishCoalesce(params, () => ( {})) };
|
|
885
972
|
}
|
|
886
973
|
static _withAllNetworkRequestCommonParams(item, commonParams) {
|
|
887
|
-
const
|
|
888
|
-
const passphraseState = _optionalChain([commonParams, 'optionalAccess', _16 => _16.passphraseState]);
|
|
889
|
-
const useEmptyPassphrase = _optionalChain([commonParams, 'optionalAccess', _17 => _17.useEmptyPassphrase]);
|
|
890
|
-
if (autoInstallApp === void 0 && passphraseState === void 0 && useEmptyPassphrase === void 0) {
|
|
891
|
-
return item;
|
|
892
|
-
}
|
|
974
|
+
const defined = ALL_NETWORK_COMMON_PARAM_KEYS.filter((key) => _optionalChain([commonParams, 'optionalAccess', _16 => _16[key]]) !== void 0);
|
|
893
975
|
return {
|
|
894
976
|
...item,
|
|
895
|
-
...
|
|
896
|
-
...
|
|
897
|
-
...useEmptyPassphrase !== void 0 ? { useEmptyPassphrase } : {}
|
|
977
|
+
...Object.fromEntries(defined.map((key) => [key, _optionalChain([commonParams, 'optionalAccess', _17 => _17[key]])])),
|
|
978
|
+
...Object.fromEntries(ALL_NETWORK_ROUTING_PARAM_KEYS.map((key) => [key, _optionalChain([commonParams, 'optionalAccess', _18 => _18[key]])]))
|
|
898
979
|
};
|
|
899
980
|
}
|
|
900
981
|
static _normalizeLogKey(key) {
|
|
@@ -950,8 +1031,8 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
950
1031
|
};
|
|
951
1032
|
}
|
|
952
1033
|
static _trezorFailureMessage(error) {
|
|
953
|
-
const response = _optionalChain([error, 'optionalAccess',
|
|
954
|
-
const message = _optionalChain([response, 'optionalAccess',
|
|
1034
|
+
const response = _optionalChain([error, 'optionalAccess', _19 => _19.response]);
|
|
1035
|
+
const message = _optionalChain([response, 'optionalAccess', _20 => _20.message]);
|
|
955
1036
|
if (!message || typeof message !== "object") return {};
|
|
956
1037
|
const failureMessage = message;
|
|
957
1038
|
return {
|
|
@@ -960,7 +1041,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
960
1041
|
};
|
|
961
1042
|
}
|
|
962
1043
|
static _mapTrezorFailureCode(error) {
|
|
963
|
-
const directCode = _optionalChain([error, 'optionalAccess',
|
|
1044
|
+
const directCode = _optionalChain([error, 'optionalAccess', _21 => _21.code]);
|
|
964
1045
|
if (directCode === "Device_InitializeFailed") {
|
|
965
1046
|
return _hwkadaptercore.HardwareErrorCode.PinCancelled;
|
|
966
1047
|
}
|
|
@@ -973,7 +1054,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
973
1054
|
if (directCode === "Failure_UnexpectedMessage") {
|
|
974
1055
|
return _hwkadaptercore.HardwareErrorCode.MethodNotSupported;
|
|
975
1056
|
}
|
|
976
|
-
const message = _optionalChain([error, 'optionalAccess',
|
|
1057
|
+
const message = _optionalChain([error, 'optionalAccess', _22 => _22.message]);
|
|
977
1058
|
if (typeof message === "string" && message.includes("Failed to execute 'transfer") && message.includes("on 'USBDevice'")) {
|
|
978
1059
|
return _hwkadaptercore.HardwareErrorCode.TransportError;
|
|
979
1060
|
}
|
|
@@ -1018,13 +1099,11 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1018
1099
|
* selected is gone (the device evicted it from its limited slot pool). The
|
|
1019
1100
|
* caller drops the stale cache entry and recreates from scratch.
|
|
1020
1101
|
*
|
|
1021
|
-
*
|
|
1022
|
-
*
|
|
1023
|
-
* (which would silently re-prompt the passphrase).
|
|
1102
|
+
* Match only the protocol's explicit unallocated-channel code. Guessing from
|
|
1103
|
+
* an error message could replay a request after an unrelated business error.
|
|
1024
1104
|
*/
|
|
1025
1105
|
static _isStaleSessionError(code) {
|
|
1026
|
-
|
|
1027
|
-
return code === "ThpUnallocatedChannel" || /invalid.?session|unallocated.?session|session.?not.?found/i.test(code);
|
|
1106
|
+
return code === "ThpUnallocatedChannel";
|
|
1028
1107
|
}
|
|
1029
1108
|
static _errorCode(error) {
|
|
1030
1109
|
return _nullishCoalesce(error.code, () => ( _TrezorAdapter._trezorFailureMessage(error).code));
|
|
@@ -1038,13 +1117,13 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1038
1117
|
return protocolError.name === "TrezorProtocolError" && protocolError.code === "Malformed protocol format" && protocolError.message === "Malformed protocol format";
|
|
1039
1118
|
}
|
|
1040
1119
|
/**
|
|
1041
|
-
* Race a promise against an abort signal.
|
|
1042
|
-
*
|
|
1043
|
-
*
|
|
1044
|
-
* uselessly in the background.
|
|
1120
|
+
* Race a promise against an abort signal. IConnector.call() can't actually
|
|
1121
|
+
* be cancelled at the protocol level, so the caller gets the abort while the
|
|
1122
|
+
* adapter keeps the transport exclusively reserved until the raw call drains.
|
|
1045
1123
|
*/
|
|
1046
1124
|
static _abortable(signal, promise) {
|
|
1047
1125
|
if (signal.aborted) {
|
|
1126
|
+
void promise.catch(() => void 0);
|
|
1048
1127
|
return Promise.reject(
|
|
1049
1128
|
_nullishCoalesce(signal.reason, () => ( new Error("Aborted")))
|
|
1050
1129
|
);
|
|
@@ -1066,17 +1145,37 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1066
1145
|
);
|
|
1067
1146
|
});
|
|
1068
1147
|
}
|
|
1069
|
-
async _connectSession(connectId, signal) {
|
|
1148
|
+
async _connectSession(connectId, signal, stateGeneration, transportType) {
|
|
1070
1149
|
const connectOnce = async () => {
|
|
1071
|
-
|
|
1072
|
-
|
|
1150
|
+
if (_optionalChain([signal, 'optionalAccess', _23 => _23.aborted])) {
|
|
1151
|
+
throw _nullishCoalesce(signal.reason, () => ( new Error("Aborted")));
|
|
1152
|
+
}
|
|
1153
|
+
this._assertConnectorIdle("connectDevice");
|
|
1154
|
+
const releaseOperation = this._retainConnectorOperation(`connect:${connectId}`);
|
|
1155
|
+
let connectPromise;
|
|
1073
1156
|
try {
|
|
1074
|
-
|
|
1157
|
+
connectPromise = transportType ? this._connector.connect(connectId, { transportType }) : this._connector.connect(connectId);
|
|
1075
1158
|
} catch (error) {
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1159
|
+
releaseOperation();
|
|
1160
|
+
throw error;
|
|
1161
|
+
}
|
|
1162
|
+
if (!signal) {
|
|
1163
|
+
try {
|
|
1164
|
+
return await connectPromise;
|
|
1165
|
+
} finally {
|
|
1166
|
+
releaseOperation();
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
try {
|
|
1170
|
+
const session2 = await _TrezorAdapter._abortable(signal, connectPromise);
|
|
1171
|
+
releaseOperation();
|
|
1172
|
+
return session2;
|
|
1173
|
+
} catch (error) {
|
|
1174
|
+
if (signal.aborted) {
|
|
1175
|
+
void connectPromise.then((orphan) => this._connector.disconnect(orphan.sessionId).catch(() => void 0)).catch(() => void 0).finally(releaseOperation);
|
|
1176
|
+
} else {
|
|
1177
|
+
releaseOperation();
|
|
1178
|
+
}
|
|
1080
1179
|
throw error;
|
|
1081
1180
|
}
|
|
1082
1181
|
};
|
|
@@ -1084,7 +1183,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1084
1183
|
try {
|
|
1085
1184
|
session = await connectOnce();
|
|
1086
1185
|
} catch (error) {
|
|
1087
|
-
if (_optionalChain([signal, 'optionalAccess',
|
|
1186
|
+
if (_optionalChain([signal, 'optionalAccess', _24 => _24.aborted]) || !_TrezorAdapter._isRecoverableProtocolResidueError(error)) {
|
|
1088
1187
|
throw error;
|
|
1089
1188
|
}
|
|
1090
1189
|
debugLog("[TrezorAdapter] retrying connect after draining a stale THP frame", {
|
|
@@ -1092,8 +1191,13 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1092
1191
|
});
|
|
1093
1192
|
session = await connectOnce();
|
|
1094
1193
|
}
|
|
1095
|
-
if (this._disconnectRequested.delete(connectId)) {
|
|
1096
|
-
|
|
1194
|
+
if (_optionalChain([signal, 'optionalAccess', _25 => _25.aborted]) || stateGeneration !== this._stateGeneration || this._disconnectRequested.delete(connectId)) {
|
|
1195
|
+
const releaseCleanup = this._retainConnectorOperation(`disconnect:${session.sessionId}`);
|
|
1196
|
+
try {
|
|
1197
|
+
await this._connector.disconnect(session.sessionId).catch(() => void 0);
|
|
1198
|
+
} finally {
|
|
1199
|
+
releaseCleanup();
|
|
1200
|
+
}
|
|
1097
1201
|
throw Object.assign(new Error("Trezor connection aborted"), {
|
|
1098
1202
|
code: _hwkadaptercore.HardwareErrorCode.UserAborted
|
|
1099
1203
|
});
|
|
@@ -1109,14 +1213,9 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1109
1213
|
async init(_config) {
|
|
1110
1214
|
}
|
|
1111
1215
|
async dispose() {
|
|
1216
|
+
await this._resetStateAndDisconnectSessions();
|
|
1112
1217
|
this._unregisterConnectorEvents();
|
|
1113
|
-
this._uiRegistry.reset();
|
|
1114
|
-
this._jobQueue.clear();
|
|
1115
1218
|
this._connector.reset();
|
|
1116
|
-
this._devices.clear();
|
|
1117
|
-
this._sessions.clear();
|
|
1118
|
-
this._verifiedPassphraseSessionsByConnectId.clear();
|
|
1119
|
-
this._connectingPromises.clear();
|
|
1120
1219
|
this._emitter.removeAllListeners();
|
|
1121
1220
|
}
|
|
1122
1221
|
/**
|
|
@@ -1125,12 +1224,30 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1125
1224
|
* error flows. Aborts active jobs and releases UI waits.
|
|
1126
1225
|
*/
|
|
1127
1226
|
resetState() {
|
|
1227
|
+
void this._resetStateAndDisconnectSessions();
|
|
1228
|
+
}
|
|
1229
|
+
_resetStateAndDisconnectSessions() {
|
|
1230
|
+
if (this._resetPromise) return this._resetPromise;
|
|
1231
|
+
const sessionIds = new Set(this._sessions.values());
|
|
1232
|
+
this._stateGeneration += 1;
|
|
1233
|
+
this._operations.endAll("runtime-reset");
|
|
1128
1234
|
this._uiRegistry.reset();
|
|
1129
1235
|
this._jobQueue.clear();
|
|
1130
1236
|
this._devices.clear();
|
|
1131
1237
|
this._sessions.clear();
|
|
1132
1238
|
this._verifiedPassphraseSessionsByConnectId.clear();
|
|
1133
1239
|
this._connectingPromises.clear();
|
|
1240
|
+
const resetPromise = this._runConnectorTeardown(async () => {
|
|
1241
|
+
for (const sessionId of sessionIds) {
|
|
1242
|
+
await this._connector.disconnect(sessionId).catch(() => void 0);
|
|
1243
|
+
}
|
|
1244
|
+
});
|
|
1245
|
+
this._resetPromise = resetPromise;
|
|
1246
|
+
return resetPromise.finally(() => {
|
|
1247
|
+
if (this._resetPromise === resetPromise) {
|
|
1248
|
+
this._resetPromise = null;
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1134
1251
|
}
|
|
1135
1252
|
getAvailableTransports() {
|
|
1136
1253
|
return this.activeTransport ? [this.activeTransport] : [];
|
|
@@ -1138,32 +1255,162 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1138
1255
|
async switchTransport(_type) {
|
|
1139
1256
|
}
|
|
1140
1257
|
async searchDevices(options) {
|
|
1141
|
-
await this._ensureDevicePermission();
|
|
1258
|
+
await this._ensureDevicePermission(void 0, void 0, _optionalChain([options, 'optionalAccess', _26 => _26.transportType]));
|
|
1259
|
+
return this._searchDevices(options);
|
|
1260
|
+
}
|
|
1261
|
+
async _searchDevices(options, signal) {
|
|
1262
|
+
if (_optionalChain([options, 'optionalAccess', _27 => _27.transportType]) && !this._availableTransports().includes(options.transportType))
|
|
1263
|
+
return [];
|
|
1264
|
+
if (_optionalChain([options, 'optionalAccess', _28 => _28.resetSession])) {
|
|
1265
|
+
await this._resetStateAndDisconnectSessions();
|
|
1266
|
+
} else {
|
|
1267
|
+
await this._connectorTeardownTail;
|
|
1268
|
+
}
|
|
1269
|
+
if (_optionalChain([signal, 'optionalAccess', _29 => _29.aborted])) throw signal.reason;
|
|
1270
|
+
const stateGeneration = this._stateGeneration;
|
|
1142
1271
|
const scanned = await this._connector.searchDevices(
|
|
1143
|
-
_optionalChain([options, 'optionalAccess',
|
|
1272
|
+
_optionalChain([options, 'optionalAccess', _30 => _30.waitForAllTransports]) || _optionalChain([options, 'optionalAccess', _31 => _31.transportType]) ? {
|
|
1273
|
+
...options.waitForAllTransports ? { waitForAll: true } : {},
|
|
1274
|
+
...options.transportType ? { transportType: options.transportType } : {}
|
|
1275
|
+
} : void 0
|
|
1144
1276
|
);
|
|
1277
|
+
if (_optionalChain([signal, 'optionalAccess', _32 => _32.aborted])) throw signal.reason;
|
|
1278
|
+
if (stateGeneration !== this._stateGeneration) {
|
|
1279
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
1280
|
+
code: _hwkadaptercore.HardwareErrorCode.UserAborted,
|
|
1281
|
+
message: "Trezor discovery belongs to an ended operation"
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1145
1284
|
const scannedIds = new Set(scanned.map((d) => d.connectId));
|
|
1146
1285
|
for (const connectId of [...this._devices.keys()]) {
|
|
1147
|
-
if (!scannedIds.has(connectId) && !this._sessions.has(connectId)) {
|
|
1286
|
+
if ((!_optionalChain([options, 'optionalAccess', _33 => _33.transportType]) || _optionalChain([this, 'access', _34 => _34._devices, 'access', _35 => _35.get, 'call', _36 => _36(connectId), 'optionalAccess', _37 => _37.connectionType]) === options.transportType) && !scannedIds.has(connectId) && !this._sessions.has(connectId)) {
|
|
1148
1287
|
this._devices.delete(connectId);
|
|
1149
1288
|
}
|
|
1150
1289
|
}
|
|
1151
1290
|
for (const device of scanned) {
|
|
1152
1291
|
const info = this._connectorDeviceToDeviceInfo(device);
|
|
1153
|
-
this._devices.set(info.connectId, info);
|
|
1292
|
+
if (!this._sessions.has(info.connectId)) this._devices.set(info.connectId, info);
|
|
1293
|
+
}
|
|
1294
|
+
return Array.from(this._devices.values()).filter(
|
|
1295
|
+
(device) => !_optionalChain([options, 'optionalAccess', _38 => _38.transportType]) || device.connectionType === options.transportType
|
|
1296
|
+
);
|
|
1297
|
+
}
|
|
1298
|
+
async searchDeviceTargets(options) {
|
|
1299
|
+
const devices = await this.searchDevices(options);
|
|
1300
|
+
return devices.map((device) => ({
|
|
1301
|
+
searchTargetId: device.connectId,
|
|
1302
|
+
searchTargetReusePolicy: _hwkadaptercore.resolveSearchTargetReusePolicy.call(void 0, device),
|
|
1303
|
+
vendor: "trezor",
|
|
1304
|
+
connectionType: device.connectionType,
|
|
1305
|
+
kind: "physical",
|
|
1306
|
+
label: device.label,
|
|
1307
|
+
model: device.model,
|
|
1308
|
+
modelName: device.modelName,
|
|
1309
|
+
serialNumber: device.serialNumber
|
|
1310
|
+
}));
|
|
1311
|
+
}
|
|
1312
|
+
async listConnectionTargets(options) {
|
|
1313
|
+
const targets = await this.searchDeviceTargets(options);
|
|
1314
|
+
return targets.map(({ searchTargetId, ...target }) => ({
|
|
1315
|
+
...target,
|
|
1316
|
+
targetId: searchTargetId
|
|
1317
|
+
}));
|
|
1318
|
+
}
|
|
1319
|
+
async bindBleDevice(params) {
|
|
1320
|
+
if (_optionalChain([params, 'access', _39 => _39.identity, 'optionalAccess', _40 => _40.vendor]) !== "trezor" || !params.identity.value) {
|
|
1321
|
+
return _hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.InvalidParams, "Trezor device identity is required");
|
|
1322
|
+
}
|
|
1323
|
+
const { value: deviceId } = params.identity;
|
|
1324
|
+
try {
|
|
1325
|
+
return await this._jobQueue.enqueue(
|
|
1326
|
+
deviceId,
|
|
1327
|
+
async (signal) => {
|
|
1328
|
+
const selected = await this._selectBleDeviceForBinding(
|
|
1329
|
+
deviceId,
|
|
1330
|
+
signal,
|
|
1331
|
+
{ extra: params.extra },
|
|
1332
|
+
"manual-rebind"
|
|
1333
|
+
);
|
|
1334
|
+
try {
|
|
1335
|
+
const persisted = await this._emitVerifiedBinding(
|
|
1336
|
+
deviceId,
|
|
1337
|
+
selected.connectId,
|
|
1338
|
+
selected.selectionRequestId,
|
|
1339
|
+
{ extra: params.extra },
|
|
1340
|
+
signal
|
|
1341
|
+
);
|
|
1342
|
+
if (!persisted) {
|
|
1343
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
1344
|
+
code: _hwkadaptercore.HardwareErrorCode.UnknownError,
|
|
1345
|
+
message: "Bluetooth binding could not be saved",
|
|
1346
|
+
origin: "host"
|
|
1347
|
+
});
|
|
1348
|
+
}
|
|
1349
|
+
this._rememberVerifiedConnection(deviceId, selected.connectId);
|
|
1350
|
+
return _hwkadaptercore.success.call(void 0, selected.connectId);
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
await this._releaseProvisionalConnection(selected.connectId, signal);
|
|
1353
|
+
throw error;
|
|
1354
|
+
}
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
label: "bindBleDevice",
|
|
1358
|
+
rejectIfBusy: true,
|
|
1359
|
+
busyError: _TrezorAdapter._createDeviceBusyError("bindBleDevice")
|
|
1360
|
+
}
|
|
1361
|
+
);
|
|
1362
|
+
} catch (error) {
|
|
1363
|
+
return this._errorToFailure(error);
|
|
1154
1364
|
}
|
|
1155
|
-
return Array.from(this._devices.values());
|
|
1156
1365
|
}
|
|
1157
|
-
async connectDevice(
|
|
1366
|
+
async connectDevice(searchTargetId) {
|
|
1367
|
+
const scope = this._jobQueue.createCancelScope(searchTargetId);
|
|
1158
1368
|
try {
|
|
1159
|
-
await
|
|
1160
|
-
|
|
1161
|
-
|
|
1369
|
+
await _TrezorAdapter._abortable(
|
|
1370
|
+
scope.signal,
|
|
1371
|
+
this._ensureDevicePermission(
|
|
1372
|
+
searchTargetId,
|
|
1373
|
+
void 0,
|
|
1374
|
+
_optionalChain([this, 'access', _41 => _41._devices, 'access', _42 => _42.get, 'call', _43 => _43(searchTargetId), 'optionalAccess', _44 => _44.connectionType])
|
|
1375
|
+
)
|
|
1376
|
+
);
|
|
1377
|
+
await this._ensureSession(searchTargetId, scope.signal);
|
|
1378
|
+
if (scope.signal.aborted) throw scope.signal.reason;
|
|
1379
|
+
const device = this._devices.get(searchTargetId);
|
|
1380
|
+
if (!device) {
|
|
1381
|
+
return _hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.DeviceNotFound, "Trezor device not found after connect");
|
|
1382
|
+
}
|
|
1383
|
+
this._operations.endByConnectionKey(searchTargetId, "explicit");
|
|
1384
|
+
const operation = this._operations.create({
|
|
1385
|
+
searchTargetId,
|
|
1386
|
+
connectId: searchTargetId,
|
|
1387
|
+
device,
|
|
1388
|
+
connectionType: device.connectionType,
|
|
1389
|
+
connectionKeys: [_nullishCoalesce(this._sessions.get(searchTargetId), () => ( ""))]
|
|
1390
|
+
});
|
|
1391
|
+
return _hwkadaptercore.success.call(void 0, operation.operationId);
|
|
1162
1392
|
} catch (error) {
|
|
1393
|
+
if (scope.signal.aborted) {
|
|
1394
|
+
await this._waitForConnectorOperationsToDrain();
|
|
1395
|
+
return _hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.UserAborted, "Trezor connection aborted");
|
|
1396
|
+
}
|
|
1163
1397
|
return this._errorToFailure(error);
|
|
1398
|
+
} finally {
|
|
1399
|
+
scope.release();
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
async releaseOperation(operationId) {
|
|
1403
|
+
const operation = this._operations.find(operationId);
|
|
1404
|
+
if (!operation) {
|
|
1405
|
+
this._operations.resolve(operationId);
|
|
1406
|
+
return;
|
|
1164
1407
|
}
|
|
1408
|
+
const endedOperation = this._operations.end(operationId, "explicit");
|
|
1409
|
+
if (!endedOperation) return;
|
|
1410
|
+
await this._releaseOperationConnection(endedOperation);
|
|
1165
1411
|
}
|
|
1166
|
-
async
|
|
1412
|
+
async _releaseOperationConnection(operation) {
|
|
1413
|
+
const { connectId } = operation;
|
|
1167
1414
|
const connecting = this._connectingPromises.has(connectId);
|
|
1168
1415
|
this._connectingPromises.delete(connectId);
|
|
1169
1416
|
const sessionId = this._sessions.get(connectId);
|
|
@@ -1171,90 +1418,131 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1171
1418
|
if (connecting) this._disconnectRequested.add(connectId);
|
|
1172
1419
|
return;
|
|
1173
1420
|
}
|
|
1174
|
-
this.
|
|
1175
|
-
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1176
|
-
await this._connector.disconnect(sessionId);
|
|
1421
|
+
await this._disconnectSession(connectId, sessionId);
|
|
1177
1422
|
}
|
|
1178
|
-
async getDeviceInfo(
|
|
1423
|
+
async getDeviceInfo(connectIdOrOperationId, deviceId) {
|
|
1424
|
+
let connectId;
|
|
1425
|
+
try {
|
|
1426
|
+
connectId = _hwkadaptercore.isHardwareOperationId.call(void 0, connectIdOrOperationId) ? this._operations.resolve(connectIdOrOperationId).connectId : connectIdOrOperationId;
|
|
1427
|
+
} catch (error) {
|
|
1428
|
+
return this._errorToFailure(error);
|
|
1429
|
+
}
|
|
1179
1430
|
const device = _nullishCoalesce(this._devices.get(connectId), () => ( Array.from(this._devices.values()).find((item) => item.deviceId === deviceId)));
|
|
1180
1431
|
if (!device) return _hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.DeviceNotFound, "Trezor device not found");
|
|
1181
1432
|
return _hwkadaptercore.success.call(void 0, device);
|
|
1182
1433
|
}
|
|
1183
|
-
getSupportedChains() {
|
|
1184
|
-
return ["btc", "evm", "sol", "tron"];
|
|
1185
|
-
}
|
|
1186
1434
|
async allNetworkGetAddress(connectId, deviceId, params) {
|
|
1435
|
+
const target = _hwkadaptercore.resolveHardwareOperationTarget.call(void 0, connectId, params.operationId, "trezor");
|
|
1436
|
+
if (!target.success) return target;
|
|
1437
|
+
let effectiveTargetId = _nullishCoalesce(target.payload.targetId, () => ( ""));
|
|
1438
|
+
let releaseOperationRetention;
|
|
1439
|
+
try {
|
|
1440
|
+
releaseOperationRetention = target.payload.operationId ? this._operations.retain(target.payload.operationId) : void 0;
|
|
1441
|
+
} catch (error) {
|
|
1442
|
+
return this._errorToFailure(error);
|
|
1443
|
+
}
|
|
1444
|
+
const cancelScope = this._jobQueue.createCancelScope(
|
|
1445
|
+
trezorQueueKey({ operationId: target.payload.operationId, connectId: effectiveTargetId })
|
|
1446
|
+
);
|
|
1187
1447
|
let liveDeviceId = "";
|
|
1448
|
+
const bundleContext = {};
|
|
1188
1449
|
const topLevelFailureIndexes = /* @__PURE__ */ new Set();
|
|
1189
1450
|
const isSingleNetworkBundle = params.bundle.every(
|
|
1190
|
-
(item) => item.network === _optionalChain([params, 'access',
|
|
1451
|
+
(item) => item.network === _optionalChain([params, 'access', _45 => _45.bundle, 'access', _46 => _46[0], 'optionalAccess', _47 => _47.network])
|
|
1191
1452
|
);
|
|
1192
|
-
const getLiveDeviceId = async () => {
|
|
1453
|
+
const getLiveDeviceId = async (expectedDeviceId) => {
|
|
1193
1454
|
if (liveDeviceId) return _hwkadaptercore.success.call(void 0, liveDeviceId);
|
|
1194
|
-
const deviceIdResponse = await this._getTrezorDeviceId(
|
|
1455
|
+
const deviceIdResponse = await this._getTrezorDeviceId(
|
|
1456
|
+
effectiveTargetId,
|
|
1457
|
+
expectedDeviceId || deviceId,
|
|
1458
|
+
params,
|
|
1459
|
+
bundleContext
|
|
1460
|
+
);
|
|
1195
1461
|
if (deviceIdResponse.success) {
|
|
1196
1462
|
liveDeviceId = deviceIdResponse.payload;
|
|
1463
|
+
if (!target.payload.operationId) {
|
|
1464
|
+
effectiveTargetId = _nullishCoalesce(_optionalChain([bundleContext, 'access', _48 => _48.connection, 'optionalAccess', _49 => _49.connectId]), () => ( effectiveTargetId));
|
|
1465
|
+
}
|
|
1197
1466
|
}
|
|
1198
1467
|
return deviceIdResponse;
|
|
1199
1468
|
};
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
const fingerprint = await getLiveDeviceId();
|
|
1209
|
-
if (!fingerprint.success) {
|
|
1469
|
+
try {
|
|
1470
|
+
return await _hwkadaptercore.runAllNetworkGetAddress.call(void 0, {
|
|
1471
|
+
connectId: effectiveTargetId,
|
|
1472
|
+
deviceId,
|
|
1473
|
+
params,
|
|
1474
|
+
normalizeItem: _TrezorAdapter._normalizeAllNetworkItem,
|
|
1475
|
+
callItem: async ({ method, item, index }) => {
|
|
1476
|
+
if (cancelScope.signal.aborted) {
|
|
1210
1477
|
topLevelFailureIndexes.add(index);
|
|
1211
|
-
return
|
|
1478
|
+
return _TrezorAdapter._buildCancelledFailure(cancelScope.signal);
|
|
1212
1479
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1480
|
+
const expectedDeviceId = _nullishCoalesce(_TrezorAdapter._getItemDeviceId(item), () => ( deviceId));
|
|
1481
|
+
if (expectedDeviceId) {
|
|
1482
|
+
const fingerprint = await getLiveDeviceId(expectedDeviceId);
|
|
1483
|
+
if (!fingerprint.success) {
|
|
1484
|
+
topLevelFailureIndexes.add(index);
|
|
1485
|
+
return fingerprint;
|
|
1486
|
+
}
|
|
1487
|
+
if (expectedDeviceId !== fingerprint.payload) {
|
|
1488
|
+
topLevelFailureIndexes.add(index);
|
|
1489
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
1490
|
+
_hwkadaptercore.HardwareErrorCode.DeviceMismatch,
|
|
1491
|
+
`Wrong device: expected ${expectedDeviceId}, got ${fingerprint.payload}`,
|
|
1492
|
+
{ expected: expectedDeviceId, actual: fingerprint.payload }
|
|
1493
|
+
);
|
|
1494
|
+
}
|
|
1220
1495
|
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1496
|
+
const callItem = _TrezorAdapter._withAllNetworkRequestCommonParams(item, params);
|
|
1497
|
+
return this._callAllNetworkMethod(effectiveTargetId, method, callItem, bundleContext);
|
|
1498
|
+
},
|
|
1499
|
+
attachIdentity: async ({ item, chain, payload, index }) => {
|
|
1500
|
+
if (!liveDeviceId) {
|
|
1501
|
+
if (cancelScope.signal.aborted) {
|
|
1502
|
+
topLevelFailureIndexes.add(index);
|
|
1503
|
+
const cancelled = _TrezorAdapter._buildCancelledFailure(cancelScope.signal);
|
|
1504
|
+
return { ...item, success: false, payload: cancelled.payload };
|
|
1505
|
+
}
|
|
1506
|
+
const fingerprint = await getLiveDeviceId(deviceId);
|
|
1507
|
+
if (!fingerprint.success) {
|
|
1508
|
+
return { ...item, success: false, payload: fingerprint.payload };
|
|
1509
|
+
}
|
|
1230
1510
|
}
|
|
1511
|
+
return {
|
|
1512
|
+
...item,
|
|
1513
|
+
success: true,
|
|
1514
|
+
payload: {
|
|
1515
|
+
...payload,
|
|
1516
|
+
deviceIdentity: {
|
|
1517
|
+
vendor: "trezor",
|
|
1518
|
+
type: "deviceId",
|
|
1519
|
+
value: liveDeviceId
|
|
1520
|
+
},
|
|
1521
|
+
chainFingerprint: liveDeviceId,
|
|
1522
|
+
chainFingerprintChain: chain
|
|
1523
|
+
}
|
|
1524
|
+
};
|
|
1525
|
+
},
|
|
1526
|
+
// One named boolean per abort reason.
|
|
1527
|
+
shouldAbortBundle: (response, { index }) => {
|
|
1528
|
+
const isSessionLevelFailure = topLevelFailureIndexes.has(index);
|
|
1529
|
+
const isWholeChainForbidden = isSingleNetworkBundle && _optionalChain([response, 'access', _50 => _50.payload, 'optionalAccess', _51 => _51.code]) === _hwkadaptercore.HardwareErrorCode.DevicePathForbidden;
|
|
1530
|
+
const { code } = _nullishCoalesce(response.payload, () => ( {}));
|
|
1531
|
+
return isSessionLevelFailure || isWholeChainForbidden || _hwkadaptercore.isWalletSafetyFailure.call(void 0, code) || _hwkadaptercore.isUserRefusal.call(void 0, code) || _hwkadaptercore.isConnectionLost.call(void 0, code);
|
|
1231
1532
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
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 && _optionalChain([response, 'access', _27 => _27.payload, 'optionalAccess', _28 => _28.code]) === _hwkadaptercore.HardwareErrorCode.DevicePathForbidden;
|
|
1251
|
-
const isPassphrasePolicyFailure = _optionalChain([response, 'access', _29 => _29.payload, 'optionalAccess', _30 => _30.code]) === _hwkadaptercore.HardwareErrorCode.PassphraseAlwaysOnDevice;
|
|
1252
|
-
return isSessionLevelFailure || isWholeChainForbidden || isPassphrasePolicyFailure;
|
|
1253
|
-
}
|
|
1254
|
-
});
|
|
1533
|
+
});
|
|
1534
|
+
} finally {
|
|
1535
|
+
cancelScope.release();
|
|
1536
|
+
_optionalChain([releaseOperationRetention, 'optionalCall', _52 => _52()]);
|
|
1537
|
+
}
|
|
1255
1538
|
}
|
|
1256
|
-
getFeatures(connectId) {
|
|
1257
|
-
return this._callDeviceManagerMethod(
|
|
1539
|
+
getFeatures(connectId, operationContext) {
|
|
1540
|
+
return this._callDeviceManagerMethod(
|
|
1541
|
+
"getFeatures",
|
|
1542
|
+
connectId,
|
|
1543
|
+
{},
|
|
1544
|
+
operationContext
|
|
1545
|
+
);
|
|
1258
1546
|
}
|
|
1259
1547
|
/**
|
|
1260
1548
|
* Device authenticity attestation. Sends a host-generated challenge, has the
|
|
@@ -1289,7 +1577,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1289
1577
|
if (!internalModel) {
|
|
1290
1578
|
return _hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.UnknownError, "Device internal_model unavailable");
|
|
1291
1579
|
}
|
|
1292
|
-
const challengeHex = _nullishCoalesce(_optionalChain([params, 'access',
|
|
1580
|
+
const challengeHex = _nullishCoalesce(_optionalChain([params, 'access', _53 => _53.challenge, 'optionalAccess', _54 => _54.toLowerCase, 'call', _55 => _55()]), () => ( Buffer.from(_utils.randomBytes.call(void 0, 32)).toString("hex")));
|
|
1293
1581
|
const challenge = Buffer.from(challengeHex, "hex");
|
|
1294
1582
|
const proofRes = await this._callDeviceManagerMethod(
|
|
1295
1583
|
"authenticateDevice",
|
|
@@ -1314,28 +1602,65 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1314
1602
|
}
|
|
1315
1603
|
});
|
|
1316
1604
|
}
|
|
1317
|
-
deviceSettings(connectId, params) {
|
|
1605
|
+
deviceSettings(connectId, params, operationContext) {
|
|
1318
1606
|
return this._callDeviceManagerMethod(
|
|
1319
1607
|
"deviceSettings",
|
|
1320
1608
|
connectId,
|
|
1321
|
-
params
|
|
1609
|
+
params,
|
|
1610
|
+
operationContext
|
|
1322
1611
|
);
|
|
1323
1612
|
}
|
|
1324
|
-
setBrightness(connectId, params = {}) {
|
|
1613
|
+
setBrightness(connectId, params = {}, operationContext) {
|
|
1325
1614
|
return this._callDeviceManagerMethod(
|
|
1326
1615
|
"setBrightness",
|
|
1327
1616
|
connectId,
|
|
1328
|
-
params
|
|
1617
|
+
params,
|
|
1618
|
+
operationContext
|
|
1329
1619
|
);
|
|
1330
1620
|
}
|
|
1331
|
-
changePin(connectId, params = {}) {
|
|
1332
|
-
return this._callDeviceManagerMethod(
|
|
1621
|
+
changePin(connectId, params = {}, operationContext) {
|
|
1622
|
+
return this._callDeviceManagerMethod(
|
|
1623
|
+
"changePin",
|
|
1624
|
+
connectId,
|
|
1625
|
+
params,
|
|
1626
|
+
operationContext
|
|
1627
|
+
);
|
|
1333
1628
|
}
|
|
1334
|
-
wipeDevice(connectId) {
|
|
1335
|
-
return this._callDeviceManagerMethod(
|
|
1629
|
+
wipeDevice(connectId, operationContext) {
|
|
1630
|
+
return this._callDeviceManagerMethod(
|
|
1631
|
+
"wipeDevice",
|
|
1632
|
+
connectId,
|
|
1633
|
+
{},
|
|
1634
|
+
operationContext
|
|
1635
|
+
);
|
|
1336
1636
|
}
|
|
1337
|
-
async _getTrezorDeviceId(connectId) {
|
|
1338
|
-
const
|
|
1637
|
+
async _getTrezorDeviceId(connectId, expectedDeviceId, commonParams, bundleContext) {
|
|
1638
|
+
const hasConnectionContext = _optionalChain([commonParams, 'optionalAccess', _56 => _56.knownConnections]) !== void 0 || _optionalChain([commonParams, 'optionalAccess', _57 => _57.extra]) !== void 0;
|
|
1639
|
+
const features = bundleContext || hasConnectionContext ? await this._callMethod(
|
|
1640
|
+
"getFeatures",
|
|
1641
|
+
connectId,
|
|
1642
|
+
hasConnectionContext || !connectId ? expectedDeviceId : void 0,
|
|
1643
|
+
hasConnectionContext ? {
|
|
1644
|
+
operationId: commonParams.operationId,
|
|
1645
|
+
knownConnections: commonParams.knownConnections,
|
|
1646
|
+
extra: commonParams.extra,
|
|
1647
|
+
allowDeviceSelection: commonParams.allowDeviceSelection,
|
|
1648
|
+
supportedTransports: commonParams.supportedTransports,
|
|
1649
|
+
passphraseState: commonParams.passphraseState,
|
|
1650
|
+
useEmptyPassphrase: commonParams.useEmptyPassphrase
|
|
1651
|
+
} : {},
|
|
1652
|
+
false,
|
|
1653
|
+
bundleContext
|
|
1654
|
+
) : await this.getFeatures(
|
|
1655
|
+
connectId,
|
|
1656
|
+
!connectId && expectedDeviceId ? {
|
|
1657
|
+
expectedDeviceIdentity: {
|
|
1658
|
+
vendor: "trezor",
|
|
1659
|
+
type: "deviceId",
|
|
1660
|
+
value: expectedDeviceId
|
|
1661
|
+
}
|
|
1662
|
+
} : void 0
|
|
1663
|
+
);
|
|
1339
1664
|
if (!features.success) return features;
|
|
1340
1665
|
const liveDeviceId = features.payload.device_id;
|
|
1341
1666
|
if (typeof liveDeviceId !== "string" || liveDeviceId.length === 0) {
|
|
@@ -1344,23 +1669,67 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1344
1669
|
return _hwkadaptercore.success.call(void 0, liveDeviceId);
|
|
1345
1670
|
}
|
|
1346
1671
|
cancel(connectId) {
|
|
1672
|
+
if (_hwkadaptercore.isHardwareOperationId.call(void 0, connectId)) {
|
|
1673
|
+
try {
|
|
1674
|
+
this._operations.resolve(connectId);
|
|
1675
|
+
} catch (e5) {
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1347
1679
|
const userAbortReason = Object.assign(new Error("User aborted operation"), {
|
|
1348
1680
|
code: _hwkadaptercore.HardwareErrorCode.UserAborted
|
|
1349
1681
|
});
|
|
1350
|
-
this.
|
|
1351
|
-
|
|
1352
|
-
if (
|
|
1353
|
-
|
|
1354
|
-
|
|
1682
|
+
const activeJobId = _optionalChain([this, 'access', _58 => _58._jobQueue, 'access', _59 => _59.getActiveJob, 'call', _60 => _60(), 'optionalAccess', _61 => _61.deviceId]);
|
|
1683
|
+
const targetId = _nullishCoalesce(connectId, () => ( activeJobId));
|
|
1684
|
+
if (targetId) {
|
|
1685
|
+
let resolvedConnectId = targetId;
|
|
1686
|
+
let operationId;
|
|
1687
|
+
if (_hwkadaptercore.isHardwareOperationId.call(void 0, targetId)) {
|
|
1688
|
+
try {
|
|
1689
|
+
operationId = targetId;
|
|
1690
|
+
resolvedConnectId = this._operations.resolve(targetId).connectId;
|
|
1691
|
+
} catch (e6) {
|
|
1692
|
+
resolvedConnectId = "";
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
const interactionForPhysicalId = !operationId && connectId ? this._operations.findActiveByConnectionKey(connectId) : void 0;
|
|
1696
|
+
const pendingOperationId = _nullishCoalesce(operationId, () => ( _optionalChain([interactionForPhysicalId, 'optionalAccess', _62 => _62.operationId])));
|
|
1697
|
+
if (!connectId) {
|
|
1698
|
+
this._uiRegistry.cancel();
|
|
1699
|
+
} else if (pendingOperationId) {
|
|
1700
|
+
this._uiRegistry.cancel(void 0, void 0, pendingOperationId);
|
|
1701
|
+
}
|
|
1702
|
+
const queueKeys = /* @__PURE__ */ new Set([trezorQueueKey({ connectId: targetId })]);
|
|
1703
|
+
if (pendingOperationId) queueKeys.add(trezorQueueKey({ operationId: pendingOperationId }));
|
|
1704
|
+
const ownsConnectorInteraction = activeJobId !== void 0 ? queueKeys.has(activeJobId) || pendingOperationId !== void 0 && this._activeOperationId() === pendingOperationId : this._connectingPromises.size === 1 && this._connectingPromises.has(resolvedConnectId);
|
|
1705
|
+
if (connectId === void 0 || ownsConnectorInteraction) {
|
|
1706
|
+
this._connector.uiResponse({ type: _hwkadaptercore.UI_RESPONSE.CANCEL });
|
|
1707
|
+
}
|
|
1708
|
+
for (const key of queueKeys) {
|
|
1709
|
+
this._jobQueue.cancelActiveAndPending(key, userAbortReason);
|
|
1710
|
+
}
|
|
1711
|
+
if (resolvedConnectId) {
|
|
1712
|
+
void this._connector.cancel(_nullishCoalesce(this._sessions.get(resolvedConnectId), () => ( resolvedConnectId)));
|
|
1713
|
+
}
|
|
1355
1714
|
return;
|
|
1356
1715
|
}
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1716
|
+
this._uiRegistry.cancel();
|
|
1717
|
+
this._connector.uiResponse({ type: _hwkadaptercore.UI_RESPONSE.CANCEL });
|
|
1718
|
+
this._jobQueue.cancelActiveAndPending(void 0, userAbortReason);
|
|
1360
1719
|
for (const sessionId of this._sessions.values()) {
|
|
1361
1720
|
void this._connector.cancel(sessionId);
|
|
1362
1721
|
}
|
|
1363
1722
|
}
|
|
1723
|
+
/**
|
|
1724
|
+
* Operation owning the running job: its queue key when pinned, else the live
|
|
1725
|
+
* operation of its connectId, so a mid-call UI request can name it.
|
|
1726
|
+
*/
|
|
1727
|
+
_activeOperationId() {
|
|
1728
|
+
const activeJobId = _optionalChain([this, 'access', _63 => _63._jobQueue, 'access', _64 => _64.getActiveJob, 'call', _65 => _65(), 'optionalAccess', _66 => _66.deviceId]);
|
|
1729
|
+
if (!activeJobId) return void 0;
|
|
1730
|
+
if (_hwkadaptercore.isHardwareOperationId.call(void 0, activeJobId)) return activeJobId;
|
|
1731
|
+
return _optionalChain([this, 'access', _67 => _67._operations, 'access', _68 => _68.findActiveByConnectionKey, 'call', _69 => _69(activeJobId), 'optionalAccess', _70 => _70.operationId]);
|
|
1732
|
+
}
|
|
1364
1733
|
/**
|
|
1365
1734
|
* Routes to BOTH the adapter's local UI registry (preemption decisions,
|
|
1366
1735
|
* future SELECT_DEVICE / DEVICE_PERMISSION) AND the connector's registry
|
|
@@ -1369,6 +1738,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1369
1738
|
*/
|
|
1370
1739
|
uiResponse(response) {
|
|
1371
1740
|
this._uiRegistry.resolve(response.type, response.payload);
|
|
1741
|
+
if (response.type === _hwkadaptercore.UI_RESPONSE.RECEIVE_SELECT_DEVICE) return;
|
|
1372
1742
|
this._connector.uiResponse(response);
|
|
1373
1743
|
}
|
|
1374
1744
|
/**
|
|
@@ -1380,8 +1750,8 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1380
1750
|
* Unlike Ledger (which hashes a per-chain address), it is chain-global, so
|
|
1381
1751
|
* `chain` is accepted for API parity but ignored.
|
|
1382
1752
|
*/
|
|
1383
|
-
async getChainFingerprint(connectId,
|
|
1384
|
-
return this._getTrezorDeviceId(connectId);
|
|
1753
|
+
async getChainFingerprint(connectId, deviceId, _chain) {
|
|
1754
|
+
return this._getTrezorDeviceId(connectId, deviceId);
|
|
1385
1755
|
}
|
|
1386
1756
|
/**
|
|
1387
1757
|
* Resolve the active passphrase wallet identity (`passphraseState`).
|
|
@@ -1391,17 +1761,87 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1391
1761
|
* can't interleave with a chain call on the same device (which would desync
|
|
1392
1762
|
* the THP session selection).
|
|
1393
1763
|
*/
|
|
1394
|
-
getPassphraseState(connectId, passphraseState) {
|
|
1395
|
-
|
|
1764
|
+
getPassphraseState(connectId, passphraseState, operationContext) {
|
|
1765
|
+
const expectedIdentity = _optionalChain([operationContext, 'optionalAccess', _71 => _71.expectedDeviceIdentity]);
|
|
1766
|
+
if (expectedIdentity && (expectedIdentity.vendor !== "trezor" || expectedIdentity.type !== "deviceId")) {
|
|
1767
|
+
return Promise.resolve(
|
|
1768
|
+
_hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.InvalidParams, "Trezor device identity is required")
|
|
1769
|
+
);
|
|
1770
|
+
}
|
|
1771
|
+
const target = _hwkadaptercore.resolveHardwareOperationTarget.call(void 0,
|
|
1396
1772
|
connectId,
|
|
1773
|
+
_optionalChain([operationContext, 'optionalAccess', _72 => _72.operationId]),
|
|
1774
|
+
"trezor"
|
|
1775
|
+
);
|
|
1776
|
+
if (!target.success) return Promise.resolve(target);
|
|
1777
|
+
const { operationId } = target.payload;
|
|
1778
|
+
let resolvedConnectId = _nullishCoalesce(target.payload.targetId, () => ( ""));
|
|
1779
|
+
let releaseOperationRetention;
|
|
1780
|
+
if (operationId) {
|
|
1781
|
+
try {
|
|
1782
|
+
resolvedConnectId = this._operations.resolve(operationId).connectId;
|
|
1783
|
+
releaseOperationRetention = this._operations.retain(operationId);
|
|
1784
|
+
} catch (error) {
|
|
1785
|
+
return Promise.resolve(this._errorToFailure(error));
|
|
1786
|
+
}
|
|
1787
|
+
}
|
|
1788
|
+
return this._jobQueue.enqueue(
|
|
1789
|
+
trezorQueueKey({ operationId, connectId: resolvedConnectId }),
|
|
1397
1790
|
async (signal) => {
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
});
|
|
1791
|
+
let selectionRequestId;
|
|
1792
|
+
let verified = false;
|
|
1401
1793
|
try {
|
|
1402
|
-
|
|
1794
|
+
if (!operationId && _optionalChain([expectedIdentity, 'optionalAccess', _73 => _73.value]) && (!connectId || _optionalChain([operationContext, 'optionalAccess', _74 => _74.knownConnections]) !== void 0)) {
|
|
1795
|
+
const resolved = await this._resolveExpectedDeviceConnectId(
|
|
1796
|
+
expectedIdentity.value,
|
|
1797
|
+
signal,
|
|
1798
|
+
operationContext
|
|
1799
|
+
);
|
|
1800
|
+
resolvedConnectId = resolved.connectId;
|
|
1801
|
+
selectionRequestId = resolved.selectionRequestId;
|
|
1802
|
+
}
|
|
1803
|
+
if (_optionalChain([expectedIdentity, 'optionalAccess', _75 => _75.value])) {
|
|
1804
|
+
if (!operationId) await this._ensureSession(resolvedConnectId, signal);
|
|
1805
|
+
if (_optionalChain([this, 'access', _76 => _76._devices, 'access', _77 => _77.get, 'call', _78 => _78(resolvedConnectId), 'optionalAccess', _79 => _79.deviceId]) !== expectedIdentity.value) {
|
|
1806
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
1807
|
+
_hwkadaptercore.HardwareErrorCode.DeviceMismatch,
|
|
1808
|
+
"Trezor device identity does not match"
|
|
1809
|
+
);
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
const restorePassphraseRequestContext = this._setPassphraseRequestContext(
|
|
1813
|
+
resolvedConnectId,
|
|
1814
|
+
{
|
|
1815
|
+
passphraseState
|
|
1816
|
+
}
|
|
1817
|
+
);
|
|
1818
|
+
try {
|
|
1819
|
+
const result = await this._resolvePassphraseState(
|
|
1820
|
+
resolvedConnectId,
|
|
1821
|
+
passphraseState,
|
|
1822
|
+
signal,
|
|
1823
|
+
operationId
|
|
1824
|
+
);
|
|
1825
|
+
if (result.success && _optionalChain([expectedIdentity, 'optionalAccess', _80 => _80.value])) {
|
|
1826
|
+
await this._emitVerifiedBinding(
|
|
1827
|
+
expectedIdentity.value,
|
|
1828
|
+
resolvedConnectId,
|
|
1829
|
+
selectionRequestId,
|
|
1830
|
+
operationContext,
|
|
1831
|
+
signal
|
|
1832
|
+
);
|
|
1833
|
+
verified = true;
|
|
1834
|
+
this._rememberVerifiedConnection(expectedIdentity.value, resolvedConnectId);
|
|
1835
|
+
}
|
|
1836
|
+
return result;
|
|
1837
|
+
} finally {
|
|
1838
|
+
restorePassphraseRequestContext();
|
|
1839
|
+
}
|
|
1403
1840
|
} finally {
|
|
1404
|
-
|
|
1841
|
+
if (selectionRequestId && !verified) {
|
|
1842
|
+
this._emitBindingStatus(selectionRequestId, signal.aborted ? "cancelled" : "failed");
|
|
1843
|
+
await this._releaseProvisionalConnection(resolvedConnectId, signal);
|
|
1844
|
+
}
|
|
1405
1845
|
}
|
|
1406
1846
|
},
|
|
1407
1847
|
{
|
|
@@ -1409,7 +1849,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1409
1849
|
rejectIfBusy: true,
|
|
1410
1850
|
busyError: _TrezorAdapter._createDeviceBusyError("getPassphraseState")
|
|
1411
1851
|
}
|
|
1412
|
-
).catch((error) => this._errorToFailure(error));
|
|
1852
|
+
).catch((error) => this._errorToFailure(error)).finally(() => _optionalChain([releaseOperationRetention, 'optionalCall', _81 => _81()]));
|
|
1413
1853
|
}
|
|
1414
1854
|
evmGetAddress(connectId, deviceId, params) {
|
|
1415
1855
|
return this._callWalletMethod("evmGetAddress", connectId, deviceId, params);
|
|
@@ -1472,11 +1912,94 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1472
1912
|
}
|
|
1473
1913
|
return result;
|
|
1474
1914
|
}
|
|
1475
|
-
|
|
1476
|
-
|
|
1915
|
+
async _callConnector(sessionId, method, params, signal) {
|
|
1916
|
+
if (_optionalChain([signal, 'optionalAccess', _82 => _82.aborted])) {
|
|
1917
|
+
throw _nullishCoalesce(signal.reason, () => ( new Error("Aborted")));
|
|
1918
|
+
}
|
|
1919
|
+
this._assertConnectorIdle(method);
|
|
1920
|
+
const releaseOperation = this._retainConnectorOperation(`call:${sessionId}`);
|
|
1921
|
+
let promise;
|
|
1922
|
+
try {
|
|
1923
|
+
promise = this._connector.call(sessionId, method, params).finally(() => {
|
|
1924
|
+
releaseOperation();
|
|
1925
|
+
});
|
|
1926
|
+
} catch (error) {
|
|
1927
|
+
releaseOperation();
|
|
1928
|
+
throw error;
|
|
1929
|
+
}
|
|
1477
1930
|
const result = signal ? await _TrezorAdapter._abortable(signal, promise) : await promise;
|
|
1478
1931
|
return _TrezorAdapter._unwrapConnectorResult(result);
|
|
1479
1932
|
}
|
|
1933
|
+
_assertConnectorIdle(method) {
|
|
1934
|
+
if (this._resetPromise || this._pendingConnectorTeardowns > 0 || this._unsettledConnectorOperations.size > 0) {
|
|
1935
|
+
throw _TrezorAdapter._createDeviceBusyError(method);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
_runConnectorTeardown(task) {
|
|
1939
|
+
const previous = this._connectorTeardownTail;
|
|
1940
|
+
let releaseTail = () => void 0;
|
|
1941
|
+
this._connectorTeardownTail = new Promise((resolve) => {
|
|
1942
|
+
releaseTail = resolve;
|
|
1943
|
+
});
|
|
1944
|
+
this._pendingConnectorTeardowns += 1;
|
|
1945
|
+
return (async () => {
|
|
1946
|
+
try {
|
|
1947
|
+
await previous;
|
|
1948
|
+
await this._waitForConnectorOperationsToDrain();
|
|
1949
|
+
await task();
|
|
1950
|
+
} finally {
|
|
1951
|
+
this._pendingConnectorTeardowns -= 1;
|
|
1952
|
+
releaseTail();
|
|
1953
|
+
}
|
|
1954
|
+
})();
|
|
1955
|
+
}
|
|
1956
|
+
async _disconnectSession(connectId, sessionId = this._sessions.get(connectId)) {
|
|
1957
|
+
this._sessions.delete(connectId);
|
|
1958
|
+
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1959
|
+
if (sessionId) await this._runConnectorTeardown(() => this._connector.disconnect(sessionId));
|
|
1960
|
+
}
|
|
1961
|
+
_availableTransports() {
|
|
1962
|
+
return _nullishCoalesce(this._connector.availableTransports, () => ( [this._connector.connectionType]));
|
|
1963
|
+
}
|
|
1964
|
+
async _releaseProvisionalConnection(connectId, signal) {
|
|
1965
|
+
const sessionId = this._sessions.get(connectId);
|
|
1966
|
+
this._sessions.delete(connectId);
|
|
1967
|
+
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1968
|
+
if (!sessionId) return;
|
|
1969
|
+
const teardown = this._runConnectorTeardown(() => this._connector.disconnect(sessionId)).catch(
|
|
1970
|
+
() => void 0
|
|
1971
|
+
);
|
|
1972
|
+
if (!signal.aborted) await teardown;
|
|
1973
|
+
}
|
|
1974
|
+
_waitForConnectorOperationsToDrain() {
|
|
1975
|
+
if (this._unsettledConnectorOperations.size === 0) {
|
|
1976
|
+
return Promise.resolve();
|
|
1977
|
+
}
|
|
1978
|
+
return new Promise((resolve) => {
|
|
1979
|
+
this._connectorIdleWaiters.add(resolve);
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
_retainConnectorOperation(key) {
|
|
1983
|
+
this._unsettledConnectorOperations.set(
|
|
1984
|
+
key,
|
|
1985
|
+
(_nullishCoalesce(this._unsettledConnectorOperations.get(key), () => ( 0))) + 1
|
|
1986
|
+
);
|
|
1987
|
+
let released = false;
|
|
1988
|
+
return () => {
|
|
1989
|
+
if (released) return;
|
|
1990
|
+
released = true;
|
|
1991
|
+
const remaining = (_nullishCoalesce(this._unsettledConnectorOperations.get(key), () => ( 1))) - 1;
|
|
1992
|
+
if (remaining > 0) {
|
|
1993
|
+
this._unsettledConnectorOperations.set(key, remaining);
|
|
1994
|
+
} else {
|
|
1995
|
+
this._unsettledConnectorOperations.delete(key);
|
|
1996
|
+
}
|
|
1997
|
+
if (this._unsettledConnectorOperations.size === 0) {
|
|
1998
|
+
for (const resolve of this._connectorIdleWaiters) resolve();
|
|
1999
|
+
this._connectorIdleWaiters.clear();
|
|
2000
|
+
}
|
|
2001
|
+
};
|
|
2002
|
+
}
|
|
1480
2003
|
static _normalizeAllNetworkItem(method, item) {
|
|
1481
2004
|
if (method !== "btcGetAddress" && method !== "btcGetPublicKey") {
|
|
1482
2005
|
return item;
|
|
@@ -1495,18 +2018,21 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1495
2018
|
const { deviceId } = item;
|
|
1496
2019
|
return typeof deviceId === "string" && deviceId.length > 0 ? deviceId : void 0;
|
|
1497
2020
|
}
|
|
1498
|
-
|
|
2021
|
+
/** UserAborted is a top-level abort code, so this ends the bundle. */
|
|
2022
|
+
static _buildCancelledFailure(signal) {
|
|
2023
|
+
const reason = signal.reason;
|
|
2024
|
+
const code = typeof _optionalChain([reason, 'optionalAccess', _83 => _83.code]) === "number" ? reason.code : _hwkadaptercore.HardwareErrorCode.UserAborted;
|
|
2025
|
+
const message = typeof _optionalChain([reason, 'optionalAccess', _84 => _84.message]) === "string" ? reason.message : "";
|
|
2026
|
+
return _hwkadaptercore.failure.call(void 0, code, message || "All-network get-address cancelled");
|
|
2027
|
+
}
|
|
2028
|
+
_callAllNetworkMethod(connectId, method, item, bundleContext) {
|
|
1499
2029
|
switch (method) {
|
|
1500
2030
|
case "evmGetAddress":
|
|
1501
|
-
return this.evmGetAddress(connectId, "", item);
|
|
1502
2031
|
case "btcGetAddress":
|
|
1503
|
-
return this.btcGetAddress(connectId, "", item);
|
|
1504
2032
|
case "btcGetPublicKey":
|
|
1505
|
-
return this.btcGetPublicKey(connectId, "", item);
|
|
1506
2033
|
case "solGetAddress":
|
|
1507
|
-
return this.solGetAddress(connectId, "", item);
|
|
1508
2034
|
case "tronGetAddress":
|
|
1509
|
-
return this.
|
|
2035
|
+
return this._callMethod(method, connectId, "", item, true, bundleContext);
|
|
1510
2036
|
default:
|
|
1511
2037
|
return Promise.resolve(
|
|
1512
2038
|
_hwkadaptercore.failure.call(void 0,
|
|
@@ -1525,11 +2051,51 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1525
2051
|
_callWalletMethod(methodName, connectId, deviceId, params) {
|
|
1526
2052
|
return this._callMethod(methodName, connectId, deviceId, params, true);
|
|
1527
2053
|
}
|
|
1528
|
-
_callDeviceManagerMethod(methodName, connectId, params) {
|
|
1529
|
-
|
|
2054
|
+
_callDeviceManagerMethod(methodName, connectId, params, operationContext) {
|
|
2055
|
+
const expectedIdentity = _optionalChain([operationContext, 'optionalAccess', _85 => _85.expectedDeviceIdentity]);
|
|
2056
|
+
if (expectedIdentity && (expectedIdentity.vendor !== "trezor" || expectedIdentity.type !== "deviceId")) {
|
|
2057
|
+
return Promise.resolve(
|
|
2058
|
+
_hwkadaptercore.failure.call(void 0,
|
|
2059
|
+
_hwkadaptercore.HardwareErrorCode.InvalidParams,
|
|
2060
|
+
"Trezor device-manager operations require a Trezor deviceId identity"
|
|
2061
|
+
)
|
|
2062
|
+
);
|
|
2063
|
+
}
|
|
2064
|
+
return this._callMethod(
|
|
2065
|
+
methodName,
|
|
2066
|
+
connectId,
|
|
2067
|
+
_optionalChain([expectedIdentity, 'optionalAccess', _86 => _86.value]),
|
|
2068
|
+
{
|
|
2069
|
+
...params && typeof params === "object" ? params : {},
|
|
2070
|
+
knownConnections: _optionalChain([operationContext, 'optionalAccess', _87 => _87.knownConnections]),
|
|
2071
|
+
extra: _optionalChain([operationContext, 'optionalAccess', _88 => _88.extra]),
|
|
2072
|
+
allowDeviceSelection: _optionalChain([operationContext, 'optionalAccess', _89 => _89.allowDeviceSelection]),
|
|
2073
|
+
supportedTransports: _optionalChain([operationContext, 'optionalAccess', _90 => _90.supportedTransports]),
|
|
2074
|
+
..._optionalChain([operationContext, 'optionalAccess', _91 => _91.operationId]) ? { operationId: operationContext.operationId } : {}
|
|
2075
|
+
},
|
|
2076
|
+
false
|
|
2077
|
+
);
|
|
1530
2078
|
}
|
|
1531
|
-
async _callMethod(methodName, connectId, deviceId, params, requiresWalletIntent) {
|
|
2079
|
+
async _callMethod(methodName, connectId, deviceId, params, requiresWalletIntent, bundleContext) {
|
|
1532
2080
|
const call = _TrezorAdapter._normalizeCallArgs(connectId, deviceId, params);
|
|
2081
|
+
const commonParams = _TrezorAdapter._splitCommonParams(call.params);
|
|
2082
|
+
const positionalOperationId = _hwkadaptercore.isHardwareOperationId.call(void 0, call.connectId) ? call.connectId : void 0;
|
|
2083
|
+
if (positionalOperationId && commonParams.operationId && positionalOperationId !== commonParams.operationId) {
|
|
2084
|
+
return _hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.InvalidParams, "Conflicting Trezor operation ids", {
|
|
2085
|
+
positionalOperationId,
|
|
2086
|
+
commonOperationId: commonParams.operationId
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
const operationId = _nullishCoalesce(commonParams.operationId, () => ( positionalOperationId));
|
|
2090
|
+
let releaseOperationRetention;
|
|
2091
|
+
try {
|
|
2092
|
+
if (operationId) {
|
|
2093
|
+
call.connectId = this._operations.resolve(operationId).connectId;
|
|
2094
|
+
releaseOperationRetention = this._operations.retain(operationId);
|
|
2095
|
+
}
|
|
2096
|
+
} catch (error) {
|
|
2097
|
+
return this._errorToFailure(error);
|
|
2098
|
+
}
|
|
1533
2099
|
debugLog("[TrezorAdapter][REQ]", {
|
|
1534
2100
|
method: methodName,
|
|
1535
2101
|
connectId: call.connectId || "(empty)",
|
|
@@ -1538,15 +2104,40 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1538
2104
|
});
|
|
1539
2105
|
try {
|
|
1540
2106
|
const response = await this._jobQueue.enqueue(
|
|
1541
|
-
call.connectId,
|
|
1542
|
-
(signal) =>
|
|
1543
|
-
call.connectId
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
2107
|
+
trezorQueueKey({ operationId, connectId: call.connectId }),
|
|
2108
|
+
async (signal) => {
|
|
2109
|
+
let effectiveConnectId = call.connectId;
|
|
2110
|
+
let selectionRequestId;
|
|
2111
|
+
try {
|
|
2112
|
+
if (!_optionalChain([bundleContext, 'optionalAccess', _92 => _92.connection]) && !operationId && deviceId && (!connectId || _optionalChain([commonParams, 'access', _93 => _93.connectionContext, 'optionalAccess', _94 => _94.knownConnections]) !== void 0)) {
|
|
2113
|
+
const resolved = await this._resolveExpectedDeviceConnectId(
|
|
2114
|
+
deviceId,
|
|
2115
|
+
signal,
|
|
2116
|
+
commonParams.connectionContext
|
|
2117
|
+
);
|
|
2118
|
+
effectiveConnectId = resolved.connectId;
|
|
2119
|
+
selectionRequestId = resolved.selectionRequestId;
|
|
2120
|
+
}
|
|
2121
|
+
} catch (error) {
|
|
2122
|
+
return this._errorToFailure(error);
|
|
2123
|
+
}
|
|
2124
|
+
const response2 = await this._callWithRetry(
|
|
2125
|
+
_nullishCoalesce(_optionalChain([bundleContext, 'optionalAccess', _95 => _95.connection, 'optionalAccess', _96 => _96.connectId]), () => ( effectiveConnectId)),
|
|
2126
|
+
methodName,
|
|
2127
|
+
call.params,
|
|
2128
|
+
deviceId || "",
|
|
2129
|
+
requiresWalletIntent,
|
|
2130
|
+
true,
|
|
2131
|
+
signal,
|
|
2132
|
+
operationId,
|
|
2133
|
+
selectionRequestId,
|
|
2134
|
+
bundleContext
|
|
2135
|
+
);
|
|
2136
|
+
if (!response2.success && selectionRequestId) {
|
|
2137
|
+
await this._releaseProvisionalConnection(effectiveConnectId, signal);
|
|
2138
|
+
}
|
|
2139
|
+
return response2;
|
|
2140
|
+
},
|
|
1550
2141
|
{
|
|
1551
2142
|
label: methodName,
|
|
1552
2143
|
rejectIfBusy: true,
|
|
@@ -1567,16 +2158,53 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1567
2158
|
payload: _TrezorAdapter._sanitizeForLog(response.payload, methodName)
|
|
1568
2159
|
});
|
|
1569
2160
|
return response;
|
|
2161
|
+
} finally {
|
|
2162
|
+
_optionalChain([releaseOperationRetention, 'optionalCall', _97 => _97()]);
|
|
1570
2163
|
}
|
|
1571
2164
|
}
|
|
1572
|
-
async _callWithRetry(connectId, methodName, params, requiresWalletIntent, allowRetry, signal) {
|
|
1573
|
-
const { passphraseState, useEmptyPassphrase, rest } = _TrezorAdapter._splitCommonParams(params);
|
|
2165
|
+
async _callWithRetry(connectId, methodName, params, expectedDeviceId, requiresWalletIntent, allowRetry, signal, operationId, selectionRequestId, bundleContext) {
|
|
2166
|
+
const { passphraseState, useEmptyPassphrase, rest, connectionContext } = _TrezorAdapter._splitCommonParams(params);
|
|
2167
|
+
let pendingBindingRequestId = selectionRequestId;
|
|
2168
|
+
let businessCallStarted = false;
|
|
1574
2169
|
const restorePassphraseRequestContext = this._setPassphraseRequestContext(connectId, {
|
|
1575
2170
|
passphraseState,
|
|
1576
2171
|
useEmptyPassphrase
|
|
1577
2172
|
});
|
|
1578
2173
|
try {
|
|
1579
|
-
|
|
2174
|
+
if (_optionalChain([bundleContext, 'optionalAccess', _98 => _98.connection])) {
|
|
2175
|
+
const pinned = bundleContext.connection;
|
|
2176
|
+
if (this._sessions.get(pinned.connectId) !== pinned.sessionId) {
|
|
2177
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
2178
|
+
_hwkadaptercore.HardwareErrorCode.DeviceDisconnected,
|
|
2179
|
+
"Trezor all-network connection ended"
|
|
2180
|
+
);
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
const sessionId = operationId ? this._sessions.get(this._operations.resolve(operationId).connectId) : await this._ensureSession(connectId, signal);
|
|
2184
|
+
if (!sessionId) {
|
|
2185
|
+
if (operationId) {
|
|
2186
|
+
this._operations.end(operationId, "disconnect");
|
|
2187
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
2188
|
+
_hwkadaptercore.HardwareErrorCode.OperationEnded,
|
|
2189
|
+
"Trezor operation connection is no longer active",
|
|
2190
|
+
{ operationId, reason: "disconnect" }
|
|
2191
|
+
);
|
|
2192
|
+
}
|
|
2193
|
+
return _hwkadaptercore.failure.call(void 0, _hwkadaptercore.HardwareErrorCode.DeviceNotFound, "Trezor session was not found");
|
|
2194
|
+
}
|
|
2195
|
+
if (bundleContext && !bundleContext.connection) {
|
|
2196
|
+
bundleContext.connection = { connectId, sessionId };
|
|
2197
|
+
}
|
|
2198
|
+
if (expectedDeviceId) {
|
|
2199
|
+
const actualDeviceId = _optionalChain([this, 'access', _99 => _99._devices, 'access', _100 => _100.get, 'call', _101 => _101(connectId), 'optionalAccess', _102 => _102.deviceId]);
|
|
2200
|
+
if (!actualDeviceId || actualDeviceId !== expectedDeviceId) {
|
|
2201
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
2202
|
+
_hwkadaptercore.HardwareErrorCode.DeviceMismatch,
|
|
2203
|
+
`Wrong device: expected ${expectedDeviceId}, got ${actualDeviceId || "unknown"}`,
|
|
2204
|
+
{ expected: expectedDeviceId, actual: actualDeviceId || "" }
|
|
2205
|
+
);
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
1580
2208
|
if (requiresWalletIntent && !passphraseState && useEmptyPassphrase !== true) {
|
|
1581
2209
|
return _hwkadaptercore.failure.call(void 0,
|
|
1582
2210
|
_hwkadaptercore.HardwareErrorCode.InvalidParams,
|
|
@@ -1591,39 +2219,85 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1591
2219
|
} else if (useEmptyPassphrase === true) {
|
|
1592
2220
|
await _TrezorAdapter._abortable(signal, this._createFreshAppSession(sessionId, signal));
|
|
1593
2221
|
}
|
|
2222
|
+
if (expectedDeviceId) {
|
|
2223
|
+
await this._emitVerifiedBinding(
|
|
2224
|
+
expectedDeviceId,
|
|
2225
|
+
connectId,
|
|
2226
|
+
pendingBindingRequestId,
|
|
2227
|
+
connectionContext,
|
|
2228
|
+
signal
|
|
2229
|
+
);
|
|
2230
|
+
pendingBindingRequestId = void 0;
|
|
2231
|
+
this._rememberVerifiedConnection(expectedDeviceId, connectId);
|
|
2232
|
+
}
|
|
2233
|
+
businessCallStarted = true;
|
|
1594
2234
|
const result = await _TrezorAdapter._abortable(
|
|
1595
2235
|
signal,
|
|
1596
|
-
|
|
2236
|
+
this._callConnector(sessionId, methodName, rest, signal)
|
|
1597
2237
|
);
|
|
1598
2238
|
return _hwkadaptercore.success.call(void 0, result);
|
|
1599
2239
|
} catch (error) {
|
|
1600
2240
|
if (signal.aborted) {
|
|
2241
|
+
if (pendingBindingRequestId) {
|
|
2242
|
+
this._emitBindingStatus(pendingBindingRequestId, "cancelled");
|
|
2243
|
+
pendingBindingRequestId = void 0;
|
|
2244
|
+
}
|
|
1601
2245
|
return this._errorToFailure(error);
|
|
1602
2246
|
}
|
|
1603
2247
|
const code = _TrezorAdapter._errorCode(error);
|
|
1604
|
-
|
|
2248
|
+
const willRetryStaleSession = allowRetry && (passphraseState || useEmptyPassphrase === true) && _TrezorAdapter._isStaleSessionError(code);
|
|
2249
|
+
if (pendingBindingRequestId && !willRetryStaleSession) {
|
|
2250
|
+
this._emitBindingStatus(pendingBindingRequestId, "failed");
|
|
2251
|
+
pendingBindingRequestId = void 0;
|
|
2252
|
+
}
|
|
2253
|
+
const ambiguousTransportFailure = code === _hwkadaptercore.HardwareErrorCode.DeviceDisconnected || code === _hwkadaptercore.HardwareErrorCode.OperationTimeout || code === _hwkadaptercore.HardwareErrorCode.TransportError;
|
|
2254
|
+
if (ambiguousTransportFailure) {
|
|
1605
2255
|
this._sessions.delete(connectId);
|
|
1606
2256
|
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
2257
|
+
const mayHaveCompleted = businessCallStarted && !_hwkadaptercore.canReplayHardwareMethodAfterTransportFailure.call(void 0, methodName);
|
|
2258
|
+
const mayHaveCompletedMessage = `Trezor ${methodName} may have completed before the connection was lost`;
|
|
2259
|
+
if (operationId) {
|
|
2260
|
+
this._operations.end(operationId, "disconnect");
|
|
2261
|
+
const endedParams = { operationId, reason: "disconnect" };
|
|
2262
|
+
return mayHaveCompleted ? _hwkadaptercore.failure.call(void 0,
|
|
2263
|
+
_hwkadaptercore.HardwareErrorCode.OperationEnded,
|
|
2264
|
+
mayHaveCompletedMessage,
|
|
2265
|
+
_hwkadaptercore.operationMayHaveCompletedParams.call(void 0, methodName, endedParams),
|
|
2266
|
+
void 0,
|
|
2267
|
+
{ scope: "unknown" }
|
|
2268
|
+
) : _hwkadaptercore.failure.call(void 0,
|
|
2269
|
+
_hwkadaptercore.HardwareErrorCode.OperationEnded,
|
|
2270
|
+
"Trezor operation connection was lost",
|
|
2271
|
+
endedParams
|
|
2272
|
+
);
|
|
2273
|
+
}
|
|
2274
|
+
if (mayHaveCompleted) {
|
|
2275
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
2276
|
+
code,
|
|
2277
|
+
mayHaveCompletedMessage,
|
|
2278
|
+
_hwkadaptercore.operationMayHaveCompletedParams.call(void 0, methodName),
|
|
2279
|
+
void 0,
|
|
2280
|
+
{ scope: "unknown" }
|
|
2281
|
+
);
|
|
2282
|
+
}
|
|
1615
2283
|
}
|
|
1616
|
-
if (
|
|
2284
|
+
if (willRetryStaleSession) {
|
|
1617
2285
|
if (passphraseState) {
|
|
1618
2286
|
this._forgetVerifiedPassphraseSession(connectId, passphraseState);
|
|
1619
2287
|
}
|
|
2288
|
+
const retryBindingRequestId = pendingBindingRequestId;
|
|
2289
|
+
pendingBindingRequestId = void 0;
|
|
1620
2290
|
return await this._callWithRetry(
|
|
1621
2291
|
connectId,
|
|
1622
2292
|
methodName,
|
|
1623
2293
|
params,
|
|
2294
|
+
expectedDeviceId,
|
|
1624
2295
|
requiresWalletIntent,
|
|
1625
2296
|
false,
|
|
1626
|
-
signal
|
|
2297
|
+
signal,
|
|
2298
|
+
operationId,
|
|
2299
|
+
retryBindingRequestId,
|
|
2300
|
+
bundleContext
|
|
1627
2301
|
);
|
|
1628
2302
|
}
|
|
1629
2303
|
debugLog("[TrezorAdapter][ERROR]", {
|
|
@@ -1634,36 +2308,252 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1634
2308
|
return this._errorToFailure(error);
|
|
1635
2309
|
} finally {
|
|
1636
2310
|
restorePassphraseRequestContext();
|
|
2311
|
+
if (pendingBindingRequestId) {
|
|
2312
|
+
this._emitBindingStatus(pendingBindingRequestId, signal.aborted ? "cancelled" : "failed");
|
|
2313
|
+
pendingBindingRequestId = void 0;
|
|
2314
|
+
}
|
|
1637
2315
|
}
|
|
1638
2316
|
}
|
|
1639
|
-
async _ensureSession(connectId, signal) {
|
|
2317
|
+
async _ensureSession(connectId, signal, transportType) {
|
|
1640
2318
|
const existing = this._sessions.get(connectId);
|
|
1641
2319
|
if (existing) return existing;
|
|
1642
2320
|
const pending = this._connectingPromises.get(connectId);
|
|
1643
2321
|
if (pending) return pending;
|
|
2322
|
+
const stateGeneration = this._stateGeneration;
|
|
1644
2323
|
const promise = (async () => {
|
|
2324
|
+
if (_optionalChain([signal, 'optionalAccess', _103 => _103.aborted])) {
|
|
2325
|
+
throw Object.assign(new Error("Trezor connection aborted"), {
|
|
2326
|
+
code: _hwkadaptercore.HardwareErrorCode.UserAborted
|
|
2327
|
+
});
|
|
2328
|
+
}
|
|
1645
2329
|
try {
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
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);
|
|
1657
|
-
}
|
|
1658
|
-
throw error;
|
|
2330
|
+
return await this._connectSession(connectId, signal, stateGeneration, transportType);
|
|
2331
|
+
} catch (error) {
|
|
2332
|
+
if (_TrezorAdapter._isConnectionUnavailableError(error)) {
|
|
2333
|
+
this._sessions.delete(connectId);
|
|
2334
|
+
this._verifiedPassphraseSessionsByConnectId.delete(connectId);
|
|
1659
2335
|
}
|
|
1660
|
-
|
|
1661
|
-
this._connectingPromises.delete(connectId);
|
|
1662
|
-
this._disconnectRequested.delete(connectId);
|
|
2336
|
+
throw error;
|
|
1663
2337
|
}
|
|
1664
2338
|
})();
|
|
1665
2339
|
this._connectingPromises.set(connectId, promise);
|
|
1666
|
-
|
|
2340
|
+
try {
|
|
2341
|
+
return await promise;
|
|
2342
|
+
} finally {
|
|
2343
|
+
if (this._connectingPromises.get(connectId) === promise) {
|
|
2344
|
+
this._connectingPromises.delete(connectId);
|
|
2345
|
+
}
|
|
2346
|
+
this._disconnectRequested.delete(connectId);
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
/** An identity probe tears down only a session it opened; another caller's stays up. */
|
|
2350
|
+
_hasSessionOrConnect(connectId) {
|
|
2351
|
+
return this._sessions.has(connectId) || this._connectingPromises.has(connectId);
|
|
2352
|
+
}
|
|
2353
|
+
async _resolveExpectedDeviceConnectId(expectedDeviceId, signal, context) {
|
|
2354
|
+
const connectedMatch = Array.from(this._devices.values()).find(
|
|
2355
|
+
(device) => device.deviceId === expectedDeviceId && this._sessions.has(device.connectId)
|
|
2356
|
+
);
|
|
2357
|
+
if (connectedMatch) return { connectId: connectedMatch.connectId };
|
|
2358
|
+
const availableTransports = this._availableTransports();
|
|
2359
|
+
if (availableTransports.includes("usb")) {
|
|
2360
|
+
await _TrezorAdapter._abortable(
|
|
2361
|
+
signal,
|
|
2362
|
+
this._ensureDevicePermission(void 0, expectedDeviceId, "usb")
|
|
2363
|
+
);
|
|
2364
|
+
}
|
|
2365
|
+
const candidates = await _TrezorAdapter._abortable(
|
|
2366
|
+
signal,
|
|
2367
|
+
this._searchDevices({ transportType: "usb" }, signal)
|
|
2368
|
+
);
|
|
2369
|
+
const mismatchedDeviceIds = [];
|
|
2370
|
+
const knownConnection = this._knownDeviceConnections.get(expectedDeviceId);
|
|
2371
|
+
const knownUsbIds = _optionalChain([context, 'optionalAccess', _104 => _104.knownConnections]) !== void 0 ? context.knownConnections.flatMap(
|
|
2372
|
+
(connection) => connection.transport === "usb" ? [connection.connectId] : []
|
|
2373
|
+
) : [_optionalChain([knownConnection, 'optionalAccess', _105 => _105.usbConnectId])].filter((id) => Boolean(id));
|
|
2374
|
+
const suppliedBleIds = _optionalChain([context, 'optionalAccess', _106 => _106.knownConnections, 'optionalAccess', _107 => _107.flatMap, 'call', _108 => _108(
|
|
2375
|
+
(connection) => connection.transport === "ble" ? [connection.connectId] : []
|
|
2376
|
+
)]);
|
|
2377
|
+
const knownBleIds = _optionalChain([suppliedBleIds, 'optionalAccess', _109 => _109.length]) ? suppliedBleIds : [_optionalChain([knownConnection, 'optionalAccess', _110 => _110.bleConnectId])].filter((id) => Boolean(id));
|
|
2378
|
+
const usbCandidates = candidates.filter(
|
|
2379
|
+
(device) => device.connectionType === "usb" && (!knownUsbIds.length || knownUsbIds.includes(device.connectId))
|
|
2380
|
+
);
|
|
2381
|
+
for (const candidate of usbCandidates) {
|
|
2382
|
+
let sessionId;
|
|
2383
|
+
const probeOpensSession = !this._hasSessionOrConnect(candidate.connectId);
|
|
2384
|
+
try {
|
|
2385
|
+
sessionId = await this._ensureSession(candidate.connectId, signal, "usb");
|
|
2386
|
+
const actualDeviceId = _nullishCoalesce(_optionalChain([this, 'access', _111 => _111._devices, 'access', _112 => _112.get, 'call', _113 => _113(candidate.connectId), 'optionalAccess', _114 => _114.deviceId]), () => ( ""));
|
|
2387
|
+
if (actualDeviceId === expectedDeviceId) return { connectId: candidate.connectId };
|
|
2388
|
+
mismatchedDeviceIds.push(actualDeviceId || "unknown");
|
|
2389
|
+
} catch (error) {
|
|
2390
|
+
if (signal.aborted) throw error;
|
|
2391
|
+
if (!_TrezorAdapter._isConnectionUnavailableError(error)) throw error;
|
|
2392
|
+
}
|
|
2393
|
+
if (sessionId && probeOpensSession) {
|
|
2394
|
+
await this._disconnectSession(candidate.connectId, sessionId);
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
if (mismatchedDeviceIds.length) {
|
|
2398
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
2399
|
+
code: _hwkadaptercore.HardwareErrorCode.DeviceSearchMismatch,
|
|
2400
|
+
message: "The connected Trezor is not the wallet this operation needs. Unplug it and connect the right device.",
|
|
2401
|
+
params: { connectedDeviceIds: mismatchedDeviceIds }
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
if (usbCandidates.length > 0) {
|
|
2405
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
2406
|
+
code: _hwkadaptercore.HardwareErrorCode.DeviceNotFound,
|
|
2407
|
+
message: "Trezor devices are present but none could be opened to check its identity."
|
|
2408
|
+
});
|
|
2409
|
+
}
|
|
2410
|
+
const [knownBleConnectId] = knownBleIds;
|
|
2411
|
+
if (knownBleConnectId && availableTransports.includes("ble")) {
|
|
2412
|
+
await _TrezorAdapter._abortable(
|
|
2413
|
+
signal,
|
|
2414
|
+
this._ensureDevicePermission(knownBleConnectId, expectedDeviceId, "ble")
|
|
2415
|
+
);
|
|
2416
|
+
const probeOpensSession = !this._hasSessionOrConnect(knownBleConnectId);
|
|
2417
|
+
await this._ensureSession(knownBleConnectId, signal, "ble");
|
|
2418
|
+
const actualDeviceId = _optionalChain([this, 'access', _115 => _115._devices, 'access', _116 => _116.get, 'call', _117 => _117(knownBleConnectId), 'optionalAccess', _118 => _118.deviceId]);
|
|
2419
|
+
if (actualDeviceId === expectedDeviceId) return { connectId: knownBleConnectId };
|
|
2420
|
+
if (probeOpensSession) await this._disconnectSession(knownBleConnectId);
|
|
2421
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
2422
|
+
code: _hwkadaptercore.HardwareErrorCode.DeviceMismatch,
|
|
2423
|
+
message: "The bound Trezor Bluetooth device has a different identity"
|
|
2424
|
+
});
|
|
2425
|
+
}
|
|
2426
|
+
if (_optionalChain([context, 'optionalAccess', _119 => _119.supportedTransports]) && !context.supportedTransports.includes("ble")) {
|
|
2427
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
2428
|
+
code: _hwkadaptercore.HardwareErrorCode.DeviceNotFound,
|
|
2429
|
+
message: "This Trezor model has no Bluetooth transport; connect it over USB"
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
if (_optionalChain([context, 'optionalAccess', _120 => _120.allowDeviceSelection]) === false) {
|
|
2433
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
2434
|
+
code: _hwkadaptercore.HardwareErrorCode.DeviceNotFound,
|
|
2435
|
+
message: "No known Trezor connection is available"
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
return this._selectBleDeviceForBinding(expectedDeviceId, signal, context, "missing-binding");
|
|
2439
|
+
}
|
|
2440
|
+
async _selectBleDeviceForBinding(expectedDeviceId, signal, context, reason) {
|
|
2441
|
+
const availableTransports = this._availableTransports();
|
|
2442
|
+
const allowUsbFallback = reason !== "manual-rebind" && availableTransports.includes("usb");
|
|
2443
|
+
const knownUsbIds = _optionalChain([context, 'optionalAccess', _121 => _121.knownConnections]) ? context.knownConnections.flatMap(
|
|
2444
|
+
(connection) => connection.transport === "usb" ? [connection.connectId] : []
|
|
2445
|
+
) : [_optionalChain([this, 'access', _122 => _122._knownDeviceConnections, 'access', _123 => _123.get, 'call', _124 => _124(expectedDeviceId), 'optionalAccess', _125 => _125.usbConnectId])];
|
|
2446
|
+
if (availableTransports.includes("ble")) {
|
|
2447
|
+
await _TrezorAdapter._abortable(
|
|
2448
|
+
signal,
|
|
2449
|
+
this._ensureDevicePermission(void 0, expectedDeviceId, "ble")
|
|
2450
|
+
);
|
|
2451
|
+
}
|
|
2452
|
+
const bleCandidates = (await _TrezorAdapter._abortable(
|
|
2453
|
+
signal,
|
|
2454
|
+
this._searchDevices({ transportType: "ble", waitForAllTransports: true }, signal)
|
|
2455
|
+
)).filter((device) => device.connectionType === "ble");
|
|
2456
|
+
if (signal.aborted) throw signal.reason;
|
|
2457
|
+
const rejectedConnectIds = /* @__PURE__ */ new Set();
|
|
2458
|
+
const bindingSessionId = this._uiRegistry.createRequestId();
|
|
2459
|
+
let rejectedConnectId;
|
|
2460
|
+
while (availableTransports.includes("ble") && this._emitter.listenerCount(_hwkadaptercore.UI_REQUEST.REQUEST_SELECT_DEVICE)) {
|
|
2461
|
+
const { device: selected, requestId } = await _hwkadaptercore.requestBleDeviceSelection.call(void 0, {
|
|
2462
|
+
emitter: this._emitter,
|
|
2463
|
+
registry: this._uiRegistry,
|
|
2464
|
+
signal,
|
|
2465
|
+
allowUsbFallback,
|
|
2466
|
+
scan: async () => {
|
|
2467
|
+
if (allowUsbFallback) {
|
|
2468
|
+
const usbCandidates = (await this._searchDevices({ transportType: "usb" }, signal)).filter(
|
|
2469
|
+
(device) => device.connectionType === "usb" && !rejectedConnectIds.has(device.connectId)
|
|
2470
|
+
);
|
|
2471
|
+
const candidate = _nullishCoalesce(usbCandidates.find((device) => knownUsbIds.includes(device.connectId)), () => ( usbCandidates[0]));
|
|
2472
|
+
if (candidate) return [candidate];
|
|
2473
|
+
}
|
|
2474
|
+
return (await this._searchDevices({ transportType: "ble", waitForAllTransports: true }, signal)).filter(
|
|
2475
|
+
(device) => device.connectionType === "ble" && !rejectedConnectIds.has(device.connectId)
|
|
2476
|
+
);
|
|
2477
|
+
},
|
|
2478
|
+
request: {
|
|
2479
|
+
devices: bleCandidates.filter((device) => !rejectedConnectIds.has(device.connectId)),
|
|
2480
|
+
bindingSessionId,
|
|
2481
|
+
rejectedConnectId,
|
|
2482
|
+
context: {
|
|
2483
|
+
kind: "bind-connection",
|
|
2484
|
+
transport: "ble",
|
|
2485
|
+
reason
|
|
2486
|
+
},
|
|
2487
|
+
extra: _optionalChain([context, 'optionalAccess', _126 => _126.extra]),
|
|
2488
|
+
operationId: this._activeOperationId()
|
|
2489
|
+
}
|
|
2490
|
+
});
|
|
2491
|
+
let probeOpensSession = false;
|
|
2492
|
+
try {
|
|
2493
|
+
if (reason === "manual-rebind") {
|
|
2494
|
+
this._operations.endByConnectionKey(selected.connectId, "explicit");
|
|
2495
|
+
await this._releaseProvisionalConnection(selected.connectId, signal);
|
|
2496
|
+
}
|
|
2497
|
+
probeOpensSession = !this._hasSessionOrConnect(selected.connectId);
|
|
2498
|
+
await this._ensureSession(selected.connectId, signal, selected.connectionType);
|
|
2499
|
+
} catch (error) {
|
|
2500
|
+
this._emitBindingStatus(requestId, signal.aborted ? "cancelled" : "failed");
|
|
2501
|
+
throw error;
|
|
2502
|
+
}
|
|
2503
|
+
if (_optionalChain([this, 'access', _127 => _127._devices, 'access', _128 => _128.get, 'call', _129 => _129(selected.connectId), 'optionalAccess', _130 => _130.deviceId]) !== expectedDeviceId) {
|
|
2504
|
+
if (probeOpensSession) await this._disconnectSession(selected.connectId);
|
|
2505
|
+
rejectedConnectId = selected.connectId;
|
|
2506
|
+
rejectedConnectIds.add(selected.connectId);
|
|
2507
|
+
continue;
|
|
2508
|
+
}
|
|
2509
|
+
if (selected.connectionType === "usb") {
|
|
2510
|
+
this._emitBindingStatus(requestId, "cancelled");
|
|
2511
|
+
return { connectId: selected.connectId };
|
|
2512
|
+
}
|
|
2513
|
+
return { connectId: selected.connectId, selectionRequestId: requestId };
|
|
2514
|
+
}
|
|
2515
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
2516
|
+
code: _hwkadaptercore.HardwareErrorCode.DeviceNotFound,
|
|
2517
|
+
message: "No readable Trezor device is available"
|
|
2518
|
+
});
|
|
2519
|
+
}
|
|
2520
|
+
_emitBindingStatus(selectionRequestId, status) {
|
|
2521
|
+
this._emitter.emit(_hwkadaptercore.UI_REQUEST.DEVICE_BINDING_STATUS, {
|
|
2522
|
+
type: _hwkadaptercore.UI_REQUEST.DEVICE_BINDING_STATUS,
|
|
2523
|
+
payload: { selectionRequestId, status }
|
|
2524
|
+
});
|
|
2525
|
+
}
|
|
2526
|
+
_rememberVerifiedConnection(deviceId, connectId) {
|
|
2527
|
+
const device = this._devices.get(connectId);
|
|
2528
|
+
if (!device || device.deviceId !== deviceId) return;
|
|
2529
|
+
const known = _nullishCoalesce(this._knownDeviceConnections.get(deviceId), () => ( { deviceId }));
|
|
2530
|
+
if (device.connectionType === "ble") {
|
|
2531
|
+
known.bleConnectId = connectId;
|
|
2532
|
+
} else if (device.connectionType === "usb" && _optionalChain([device, 'access', _131 => _131.capabilities, 'optionalAccess', _132 => _132.persistentDeviceIdentity])) {
|
|
2533
|
+
known.usbConnectId = connectId;
|
|
2534
|
+
}
|
|
2535
|
+
this._knownDeviceConnections.set(deviceId, known);
|
|
2536
|
+
}
|
|
2537
|
+
async _emitVerifiedBinding(deviceId, connectId, selectionRequestId, context, signal) {
|
|
2538
|
+
if (!selectionRequestId) return false;
|
|
2539
|
+
const device = this._devices.get(connectId);
|
|
2540
|
+
if (!device || device.deviceId !== deviceId || device.connectionType !== "ble") {
|
|
2541
|
+
this._emitBindingStatus(selectionRequestId, "cancelled");
|
|
2542
|
+
return false;
|
|
2543
|
+
}
|
|
2544
|
+
const outcome = await _hwkadaptercore.requestSaveDeviceBinding.call(void 0,
|
|
2545
|
+
this._emitter,
|
|
2546
|
+
this._uiRegistry,
|
|
2547
|
+
{
|
|
2548
|
+
selectionRequestId,
|
|
2549
|
+
connection: { transport: "ble", connectId },
|
|
2550
|
+
identity: { vendor: "trezor", type: "deviceId", value: deviceId },
|
|
2551
|
+
extra: _optionalChain([context, 'optionalAccess', _133 => _133.extra]),
|
|
2552
|
+
operationId: this._activeOperationId()
|
|
2553
|
+
},
|
|
2554
|
+
signal
|
|
2555
|
+
);
|
|
2556
|
+
return outcome.saved;
|
|
1667
2557
|
}
|
|
1668
2558
|
/**
|
|
1669
2559
|
* Pin the device's active wallet session to `passphraseState` (the target
|
|
@@ -1685,12 +2575,21 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1685
2575
|
if (reused) return;
|
|
1686
2576
|
const created = await _TrezorAdapter._abortable(
|
|
1687
2577
|
signal,
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
2578
|
+
this._callConnector(
|
|
2579
|
+
sessionId,
|
|
2580
|
+
"__thpCreateSession",
|
|
2581
|
+
{
|
|
2582
|
+
passphraseMode: "prompt"
|
|
2583
|
+
},
|
|
2584
|
+
signal
|
|
2585
|
+
)
|
|
1691
2586
|
);
|
|
1692
|
-
if (_optionalChain([created, 'optionalAccess',
|
|
1693
|
-
|
|
2587
|
+
if (_optionalChain([created, 'optionalAccess', _134 => _134.protocol]) === "thp" && !created.thpSessionId || _optionalChain([created, 'optionalAccess', _135 => _135.protocol]) !== "thp" && _optionalChain([created, 'optionalAccess', _136 => _136.protocol]) !== "v1") {
|
|
2588
|
+
throw _hwkadaptercore.createHwkError.call(void 0, {
|
|
2589
|
+
code: _hwkadaptercore.HardwareErrorCode.TransportError,
|
|
2590
|
+
message: "Cannot verify the requested Trezor wallet session"
|
|
2591
|
+
});
|
|
2592
|
+
}
|
|
1694
2593
|
const state = await this._deriveState(sessionId, signal);
|
|
1695
2594
|
if (state !== passphraseState) {
|
|
1696
2595
|
throw Object.assign(
|
|
@@ -1704,13 +2603,13 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1704
2603
|
}
|
|
1705
2604
|
_rememberVerifiedPassphraseSession(connectId, passphraseState, sessionId, created) {
|
|
1706
2605
|
let session;
|
|
1707
|
-
if (_optionalChain([created, 'optionalAccess',
|
|
2606
|
+
if (_optionalChain([created, 'optionalAccess', _137 => _137.protocol]) === "thp" && typeof created.thpSessionId === "string") {
|
|
1708
2607
|
session = {
|
|
1709
2608
|
sessionId,
|
|
1710
2609
|
protocol: "thp",
|
|
1711
2610
|
thpSessionId: created.thpSessionId
|
|
1712
2611
|
};
|
|
1713
|
-
} else if (_optionalChain([created, 'optionalAccess',
|
|
2612
|
+
} else if (_optionalChain([created, 'optionalAccess', _138 => _138.protocol]) === "v1") {
|
|
1714
2613
|
session = {
|
|
1715
2614
|
sessionId,
|
|
1716
2615
|
protocol: "v1"
|
|
@@ -1730,7 +2629,7 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1730
2629
|
}
|
|
1731
2630
|
}
|
|
1732
2631
|
async _reuseVerifiedPassphraseSession(connectId, sessionId, passphraseState, signal) {
|
|
1733
|
-
const cached = _optionalChain([this, 'access',
|
|
2632
|
+
const cached = _optionalChain([this, 'access', _139 => _139._verifiedPassphraseSessionsByConnectId, 'access', _140 => _140.get, 'call', _141 => _141(connectId), 'optionalAccess', _142 => _142.get, 'call', _143 => _143(passphraseState)]);
|
|
1734
2633
|
if (!cached || cached.sessionId !== sessionId) {
|
|
1735
2634
|
this._forgetVerifiedPassphraseSession(connectId, passphraseState);
|
|
1736
2635
|
return false;
|
|
@@ -1740,9 +2639,14 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1740
2639
|
if (!cached.thpSessionId) return false;
|
|
1741
2640
|
await _TrezorAdapter._abortable(
|
|
1742
2641
|
signal,
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
2642
|
+
this._callConnector(
|
|
2643
|
+
sessionId,
|
|
2644
|
+
"__thpSelectSession",
|
|
2645
|
+
{
|
|
2646
|
+
thpSessionId: cached.thpSessionId
|
|
2647
|
+
},
|
|
2648
|
+
signal
|
|
2649
|
+
)
|
|
1746
2650
|
);
|
|
1747
2651
|
}
|
|
1748
2652
|
const state = await this._deriveState(sessionId, signal);
|
|
@@ -1760,9 +2664,14 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1760
2664
|
async _createFreshAppSession(sessionId, signal) {
|
|
1761
2665
|
await _TrezorAdapter._abortable(
|
|
1762
2666
|
signal,
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
2667
|
+
this._callConnector(
|
|
2668
|
+
sessionId,
|
|
2669
|
+
"__thpCreateSession",
|
|
2670
|
+
{
|
|
2671
|
+
passphraseMode: "empty"
|
|
2672
|
+
},
|
|
2673
|
+
signal
|
|
2674
|
+
)
|
|
1766
2675
|
);
|
|
1767
2676
|
}
|
|
1768
2677
|
/**
|
|
@@ -1777,12 +2686,17 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1777
2686
|
async _deriveState(sessionId, signal) {
|
|
1778
2687
|
const derived = await _TrezorAdapter._abortable(
|
|
1779
2688
|
signal,
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
2689
|
+
this._callConnector(
|
|
2690
|
+
sessionId,
|
|
2691
|
+
"btcGetPublicKey",
|
|
2692
|
+
{
|
|
2693
|
+
path: "m/44'/0'/0'",
|
|
2694
|
+
showOnDevice: false
|
|
2695
|
+
},
|
|
2696
|
+
signal
|
|
2697
|
+
)
|
|
1784
2698
|
);
|
|
1785
|
-
const state = _optionalChain([derived, 'optionalAccess',
|
|
2699
|
+
const state = _optionalChain([derived, 'optionalAccess', _144 => _144.publicKey]);
|
|
1786
2700
|
if (!state) {
|
|
1787
2701
|
throw Object.assign(new Error("Failed to derive passphrase state (wallet public key)"), {
|
|
1788
2702
|
code: _hwkadaptercore.HardwareErrorCode.UnknownError
|
|
@@ -1790,25 +2704,36 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1790
2704
|
}
|
|
1791
2705
|
return state;
|
|
1792
2706
|
}
|
|
1793
|
-
async _resolvePassphraseState(connectId, passphraseState, signal) {
|
|
2707
|
+
async _resolvePassphraseState(connectId, passphraseState, signal, operationId) {
|
|
1794
2708
|
try {
|
|
1795
|
-
const sessionId = await this._ensureSession(connectId, signal);
|
|
2709
|
+
const sessionId = operationId ? this._sessions.get(this._operations.resolve(operationId).connectId) : await this._ensureSession(connectId, signal);
|
|
2710
|
+
if (!sessionId) {
|
|
2711
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
2712
|
+
_hwkadaptercore.HardwareErrorCode.OperationEnded,
|
|
2713
|
+
"Trezor operation connection is no longer active"
|
|
2714
|
+
);
|
|
2715
|
+
}
|
|
1796
2716
|
if (passphraseState) {
|
|
1797
2717
|
await this._alignAppSession(connectId, sessionId, passphraseState, signal);
|
|
1798
2718
|
return _hwkadaptercore.success.call(void 0, passphraseState);
|
|
1799
2719
|
}
|
|
1800
2720
|
const created = await _TrezorAdapter._abortable(
|
|
1801
2721
|
signal,
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
2722
|
+
this._callConnector(
|
|
2723
|
+
sessionId,
|
|
2724
|
+
"__thpCreateSession",
|
|
2725
|
+
{
|
|
2726
|
+
passphraseMode: "prompt"
|
|
2727
|
+
},
|
|
2728
|
+
signal
|
|
2729
|
+
)
|
|
1805
2730
|
);
|
|
1806
2731
|
const state = await this._deriveState(sessionId, signal);
|
|
1807
2732
|
const features = await _TrezorAdapter._abortable(
|
|
1808
2733
|
signal,
|
|
1809
|
-
|
|
2734
|
+
this._callConnector(sessionId, "getFeatures", { refresh: true }, signal)
|
|
1810
2735
|
);
|
|
1811
|
-
if (_optionalChain([features, 'optionalAccess',
|
|
2736
|
+
if (_optionalChain([features, 'optionalAccess', _145 => _145.passphrase_protection]) !== true) {
|
|
1812
2737
|
return _hwkadaptercore.success.call(void 0, null);
|
|
1813
2738
|
}
|
|
1814
2739
|
this._rememberVerifiedPassphraseSession(connectId, state, sessionId, created);
|
|
@@ -1856,7 +2781,16 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1856
2781
|
}
|
|
1857
2782
|
const trustedNumericCode = typeof typed.code === "number" && KNOWN_HARDWARE_ERROR_CODES.has(typed.code) ? typed.code : void 0;
|
|
1858
2783
|
const code = _nullishCoalesce(_nullishCoalesce(trustedNumericCode, () => ( _TrezorAdapter._mapTrezorFailureCode(error))), () => ( _hwkadaptercore.HardwareErrorCode.UnknownError));
|
|
1859
|
-
|
|
2784
|
+
const stampedOrigin = _optionalChain([error, 'optionalAccess', _146 => _146.origin]);
|
|
2785
|
+
const origin = stampedOrigin === "device" || stampedOrigin === "transport" || stampedOrigin === "host" ? stampedOrigin : _hwkadaptercore.defaultOriginForCode.call(void 0, code);
|
|
2786
|
+
const params = typed.params && typeof typed.params === "object" ? typed.params : void 0;
|
|
2787
|
+
return _hwkadaptercore.failure.call(void 0,
|
|
2788
|
+
code,
|
|
2789
|
+
_nullishCoalesce(typed.message, () => ( String(error))),
|
|
2790
|
+
params,
|
|
2791
|
+
origin,
|
|
2792
|
+
_hwkadaptercore.isHwkRecoveryHint.call(void 0, typed.recovery) ? typed.recovery : void 0
|
|
2793
|
+
);
|
|
1860
2794
|
}
|
|
1861
2795
|
/**
|
|
1862
2796
|
* Emit `REQUEST_DEVICE_PERMISSION` and await the host's
|
|
@@ -1871,29 +2805,33 @@ var _TrezorAdapter = class _TrezorAdapter {
|
|
|
1871
2805
|
* - no `connectId` → environment-level check (scan / picker)
|
|
1872
2806
|
* - with `connectId` → device-level check (per-call gating)
|
|
1873
2807
|
*/
|
|
1874
|
-
async _ensureDevicePermission(connectId, deviceId) {
|
|
2808
|
+
async _ensureDevicePermission(connectId, deviceId, requestedTransport) {
|
|
1875
2809
|
if (!this._emitter.listenerCount(_hwkadaptercore.UI_REQUEST.REQUEST_DEVICE_PERMISSION)) {
|
|
1876
2810
|
return;
|
|
1877
2811
|
}
|
|
1878
|
-
const transportType = _nullishCoalesce(this.activeTransport, () => ( "usb"));
|
|
2812
|
+
const transportType = _nullishCoalesce(_nullishCoalesce(requestedTransport, () => ( this.activeTransport)), () => ( "usb"));
|
|
2813
|
+
const operationId = this._activeOperationId();
|
|
1879
2814
|
const waitPromise = this._uiRegistry.wait(
|
|
1880
2815
|
_hwkadaptercore.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
1881
|
-
{ timeoutMs: 6e4 }
|
|
2816
|
+
{ timeoutMs: 6e4, operationId }
|
|
1882
2817
|
);
|
|
1883
2818
|
this._emitter.emit(_hwkadaptercore.UI_REQUEST.REQUEST_DEVICE_PERMISSION, {
|
|
1884
2819
|
type: _hwkadaptercore.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
1885
|
-
payload: { transportType, connectId, deviceId }
|
|
2820
|
+
payload: { transportType, connectId, deviceId, operationId }
|
|
1886
2821
|
});
|
|
1887
|
-
const { granted } = await waitPromise;
|
|
2822
|
+
const { granted, reason } = await waitPromise;
|
|
1888
2823
|
if (!granted) {
|
|
1889
2824
|
throw Object.assign(new Error("Device permission denied"), {
|
|
1890
|
-
code: _hwkadaptercore.HardwareErrorCode.DevicePermissionDenied
|
|
2825
|
+
code: _hwkadaptercore.HardwareErrorCode.DevicePermissionDenied,
|
|
2826
|
+
...reason ? { params: { permissionDeniedReason: reason } } : {}
|
|
1891
2827
|
});
|
|
1892
2828
|
}
|
|
1893
2829
|
}
|
|
1894
2830
|
};
|
|
1895
2831
|
// Keys are matched after normalizeLogKey, so snake_case/camelCase both hit.
|
|
1896
2832
|
_TrezorAdapter._sensitiveLogKeys = /* @__PURE__ */ new Set([
|
|
2833
|
+
"extra",
|
|
2834
|
+
"knownconnections",
|
|
1897
2835
|
"credential",
|
|
1898
2836
|
"credentials",
|
|
1899
2837
|
"entropy",
|
|
@@ -2012,7 +2950,7 @@ async function fetchDefinitionHex(url, fetchImpl) {
|
|
|
2012
2950
|
}
|
|
2013
2951
|
return arrayBufferToHex(await response.arrayBuffer());
|
|
2014
2952
|
});
|
|
2015
|
-
} catch (
|
|
2953
|
+
} catch (e7) {
|
|
2016
2954
|
return void 0;
|
|
2017
2955
|
}
|
|
2018
2956
|
}
|
|
@@ -2041,7 +2979,7 @@ async function fetchSolanaTokenDefinition({
|
|
|
2041
2979
|
}
|
|
2042
2980
|
return Buffer.from(await response.arrayBuffer()).toString("hex");
|
|
2043
2981
|
});
|
|
2044
|
-
} catch (
|
|
2982
|
+
} catch (e8) {
|
|
2045
2983
|
return void 0;
|
|
2046
2984
|
}
|
|
2047
2985
|
}
|