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