@onekeyfe/hwk-ledger-adapter 1.1.26-alpha.5 → 1.1.26-alpha.7
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 +12 -8
- package/dist/index.d.ts +12 -8
- package/dist/index.js +94 -63
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +94 -63
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IHardwareWallet, IConnector, TransportType,
|
|
1
|
+
import { IHardwareWallet, IConnector, TransportType, UiResponseEvent, DeviceInfo, Response, ChainCapability, EvmGetAddressParams, EvmAddress, ProgressCallback, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, ChainForFingerprint, ConnectionType, DeviceDescriptor, ConnectorDevice, ConnectorSession, ConnectorEventType, ConnectorEventMap, DeviceChangeEvent, Failure, HardwareErrorCode } from '@onekeyfe/hwk-adapter-core';
|
|
2
2
|
import { DeviceManagementKit, DeviceActionState as DeviceActionState$1, DiscoveredDevice, ExecuteDeviceActionReturnType } from '@ledgerhq/device-management-kit';
|
|
3
3
|
import { Address, Signature, SignerEth as SignerEth$1, TypedData } from '@ledgerhq/device-signer-kit-ethereum';
|
|
4
4
|
import { SignerBtc as SignerBtc$1 } from '@ledgerhq/device-signer-kit-bitcoin';
|
|
@@ -21,13 +21,12 @@ interface LedgerAdapterOptions {
|
|
|
21
21
|
* - Translates IHardwareWallet method calls to connector.call() invocations
|
|
22
22
|
* - Maps connector results/errors to our Response<T> format with enriched error messages
|
|
23
23
|
* - Translates connector events to HardwareEventMap events
|
|
24
|
-
* -
|
|
24
|
+
* - Emits `REQUEST_DEVICE_PERMISSION` for OS-level permission checks
|
|
25
25
|
*/
|
|
26
26
|
declare class LedgerAdapter implements IHardwareWallet {
|
|
27
27
|
readonly vendor: "ledger";
|
|
28
28
|
private readonly connector;
|
|
29
29
|
private readonly emitter;
|
|
30
|
-
private _uiHandler;
|
|
31
30
|
private readonly _handleSelectDevice;
|
|
32
31
|
private _discoveredDevices;
|
|
33
32
|
private _sessions;
|
|
@@ -44,7 +43,6 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
44
43
|
get activeTransport(): TransportType | null;
|
|
45
44
|
getAvailableTransports(): TransportType[];
|
|
46
45
|
switchTransport(_type: TransportType): Promise<void>;
|
|
47
|
-
setUiHandler(handler: Partial<IUiHandler>): void;
|
|
48
46
|
init(_config?: unknown): Promise<void>;
|
|
49
47
|
/**
|
|
50
48
|
* Clear cached device/session state without tearing down the adapter.
|
|
@@ -149,10 +147,16 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
149
147
|
/** Clear stale session, reconnect, and retry the call. */
|
|
150
148
|
private _retryWithFreshConnection;
|
|
151
149
|
/**
|
|
152
|
-
* Ensure device permission before proceeding.
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
150
|
+
* Ensure OS-level device permission (Bluetooth / USB) before proceeding.
|
|
151
|
+
*
|
|
152
|
+
* Emits `REQUEST_DEVICE_PERMISSION` and awaits the consumer's
|
|
153
|
+
* `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers "probe → system
|
|
154
|
+
* prompt → user tap" plus a generous margin). If the consumer never wires
|
|
155
|
+
* a handler or never replies, the wait times out and the operation fails
|
|
156
|
+
* fast so scanners/callers don't hang silently.
|
|
157
|
+
*
|
|
158
|
+
* - No connectId (searchDevices): environment-level permission
|
|
159
|
+
* - With connectId (business methods): device-level permission
|
|
156
160
|
*/
|
|
157
161
|
private _ensureDevicePermission;
|
|
158
162
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IHardwareWallet, IConnector, TransportType,
|
|
1
|
+
import { IHardwareWallet, IConnector, TransportType, UiResponseEvent, DeviceInfo, Response, ChainCapability, EvmGetAddressParams, EvmAddress, ProgressCallback, EvmSignTxParams, EvmSignedTx, EvmSignMsgParams, EvmSignature, EvmSignTypedDataParams, BtcGetAddressParams, BtcAddress, BtcGetPublicKeyParams, BtcPublicKey, BtcSignTxParams, BtcSignedTx, BtcSignPsbtParams, BtcSignedPsbt, BtcSignMsgParams, BtcSignature, SolGetAddressParams, SolAddress, SolSignTxParams, SolSignedTx, SolSignMsgParams, SolSignature, TronGetAddressParams, TronAddress, TronSignTxParams, TronSignedTx, TronSignMsgParams, TronSignature, HardwareEventMap, DeviceEventListener, ChainForFingerprint, ConnectionType, DeviceDescriptor, ConnectorDevice, ConnectorSession, ConnectorEventType, ConnectorEventMap, DeviceChangeEvent, Failure, HardwareErrorCode } from '@onekeyfe/hwk-adapter-core';
|
|
2
2
|
import { DeviceManagementKit, DeviceActionState as DeviceActionState$1, DiscoveredDevice, ExecuteDeviceActionReturnType } from '@ledgerhq/device-management-kit';
|
|
3
3
|
import { Address, Signature, SignerEth as SignerEth$1, TypedData } from '@ledgerhq/device-signer-kit-ethereum';
|
|
4
4
|
import { SignerBtc as SignerBtc$1 } from '@ledgerhq/device-signer-kit-bitcoin';
|
|
@@ -21,13 +21,12 @@ interface LedgerAdapterOptions {
|
|
|
21
21
|
* - Translates IHardwareWallet method calls to connector.call() invocations
|
|
22
22
|
* - Maps connector results/errors to our Response<T> format with enriched error messages
|
|
23
23
|
* - Translates connector events to HardwareEventMap events
|
|
24
|
-
* -
|
|
24
|
+
* - Emits `REQUEST_DEVICE_PERMISSION` for OS-level permission checks
|
|
25
25
|
*/
|
|
26
26
|
declare class LedgerAdapter implements IHardwareWallet {
|
|
27
27
|
readonly vendor: "ledger";
|
|
28
28
|
private readonly connector;
|
|
29
29
|
private readonly emitter;
|
|
30
|
-
private _uiHandler;
|
|
31
30
|
private readonly _handleSelectDevice;
|
|
32
31
|
private _discoveredDevices;
|
|
33
32
|
private _sessions;
|
|
@@ -44,7 +43,6 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
44
43
|
get activeTransport(): TransportType | null;
|
|
45
44
|
getAvailableTransports(): TransportType[];
|
|
46
45
|
switchTransport(_type: TransportType): Promise<void>;
|
|
47
|
-
setUiHandler(handler: Partial<IUiHandler>): void;
|
|
48
46
|
init(_config?: unknown): Promise<void>;
|
|
49
47
|
/**
|
|
50
48
|
* Clear cached device/session state without tearing down the adapter.
|
|
@@ -149,10 +147,16 @@ declare class LedgerAdapter implements IHardwareWallet {
|
|
|
149
147
|
/** Clear stale session, reconnect, and retry the call. */
|
|
150
148
|
private _retryWithFreshConnection;
|
|
151
149
|
/**
|
|
152
|
-
* Ensure device permission before proceeding.
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
150
|
+
* Ensure OS-level device permission (Bluetooth / USB) before proceeding.
|
|
151
|
+
*
|
|
152
|
+
* Emits `REQUEST_DEVICE_PERMISSION` and awaits the consumer's
|
|
153
|
+
* `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers "probe → system
|
|
154
|
+
* prompt → user tap" plus a generous margin). If the consumer never wires
|
|
155
|
+
* a handler or never replies, the wait times out and the operation fails
|
|
156
|
+
* fast so scanners/callers don't hang silently.
|
|
157
|
+
*
|
|
158
|
+
* - No connectId (searchDevices): environment-level permission
|
|
159
|
+
* - With connectId (business methods): device-level permission
|
|
156
160
|
*/
|
|
157
161
|
private _ensureDevicePermission;
|
|
158
162
|
/**
|
package/dist/index.js
CHANGED
|
@@ -76,6 +76,58 @@ function getEthAppErrorCode(err) {
|
|
|
76
76
|
}
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
79
|
+
function extractApduHex(err) {
|
|
80
|
+
if (!err || typeof err !== "object") return null;
|
|
81
|
+
const e = err;
|
|
82
|
+
if (typeof e.errorCode === "string" && /^[0-9a-f]+$/i.test(e.errorCode)) {
|
|
83
|
+
return e.errorCode.toLowerCase();
|
|
84
|
+
}
|
|
85
|
+
if (typeof e.statusCode === "number" && Number.isFinite(e.statusCode)) {
|
|
86
|
+
return e.statusCode.toString(16).padStart(4, "0");
|
|
87
|
+
}
|
|
88
|
+
if (typeof e.statusCode === "string" && /^[0-9a-f]+$/i.test(e.statusCode)) {
|
|
89
|
+
return e.statusCode.toLowerCase();
|
|
90
|
+
}
|
|
91
|
+
if (e.originalError != null) {
|
|
92
|
+
const nested = extractApduHex(e.originalError);
|
|
93
|
+
if (nested) return nested;
|
|
94
|
+
}
|
|
95
|
+
if (e.error != null && typeof e._tag === "string") {
|
|
96
|
+
const nested = extractApduHex(e.error);
|
|
97
|
+
if (nested) return nested;
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
function mapSolanaAppError(hex) {
|
|
102
|
+
switch (hex) {
|
|
103
|
+
case "6808":
|
|
104
|
+
return import_hwk_adapter_core.HardwareErrorCode.SolanaBlindSigningRequired;
|
|
105
|
+
default:
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function mapTronAppError(hex) {
|
|
110
|
+
switch (hex) {
|
|
111
|
+
case "6a8d":
|
|
112
|
+
return import_hwk_adapter_core.HardwareErrorCode.TronCustomContractRequired;
|
|
113
|
+
case "6a8b":
|
|
114
|
+
return import_hwk_adapter_core.HardwareErrorCode.TronDataSigningRequired;
|
|
115
|
+
case "6a8c":
|
|
116
|
+
return import_hwk_adapter_core.HardwareErrorCode.TronSignByHashRequired;
|
|
117
|
+
default:
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function mapBtcAppError(hex) {
|
|
122
|
+
switch (hex) {
|
|
123
|
+
case "b008":
|
|
124
|
+
return import_hwk_adapter_core.HardwareErrorCode.BtcWalletPolicyHmacMismatch;
|
|
125
|
+
case "b007":
|
|
126
|
+
return import_hwk_adapter_core.HardwareErrorCode.BtcUnexpectedState;
|
|
127
|
+
default:
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
79
131
|
function mapEthAppError(ethCode, lastStep) {
|
|
80
132
|
switch (ethCode) {
|
|
81
133
|
case "6a80":
|
|
@@ -191,8 +243,10 @@ function mapLedgerError(err) {
|
|
|
191
243
|
} else {
|
|
192
244
|
const ethCode = getEthAppErrorCode(err);
|
|
193
245
|
const lastStep = err && typeof err === "object" ? err._lastStep : void 0;
|
|
194
|
-
const
|
|
195
|
-
|
|
246
|
+
const ethMapped = ethCode ? mapEthAppError(ethCode, lastStep) : null;
|
|
247
|
+
const apduHex = ethMapped ? null : extractApduHex(err);
|
|
248
|
+
const chainMapped = apduHex ? mapSolanaAppError(apduHex) ?? mapTronAppError(apduHex) ?? mapBtcAppError(apduHex) : null;
|
|
249
|
+
code = ethMapped ?? chainMapped ?? import_hwk_adapter_core.HardwareErrorCode.UnknownError;
|
|
196
250
|
}
|
|
197
251
|
const appName = err && typeof err === "object" ? err.appName : void 0;
|
|
198
252
|
return { code, message: (0, import_hwk_adapter_core.enrichErrorMessage)(code, originalMessage), appName };
|
|
@@ -225,7 +279,6 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
225
279
|
constructor(connector, options) {
|
|
226
280
|
this.vendor = "ledger";
|
|
227
281
|
this.emitter = new import_hwk_adapter_core2.TypedEventEmitter();
|
|
228
|
-
this._uiHandler = null;
|
|
229
282
|
// Device cache: tracks discovered devices from connector events
|
|
230
283
|
this._discoveredDevices = /* @__PURE__ */ new Map();
|
|
231
284
|
// Session tracking: maps connectId -> sessionId
|
|
@@ -291,12 +344,6 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
291
344
|
async switchTransport(_type) {
|
|
292
345
|
}
|
|
293
346
|
// ---------------------------------------------------------------------------
|
|
294
|
-
// UI handler
|
|
295
|
-
// ---------------------------------------------------------------------------
|
|
296
|
-
setUiHandler(handler) {
|
|
297
|
-
this._uiHandler = handler;
|
|
298
|
-
}
|
|
299
|
-
// ---------------------------------------------------------------------------
|
|
300
347
|
// Lifecycle
|
|
301
348
|
// ---------------------------------------------------------------------------
|
|
302
349
|
async init(_config) {
|
|
@@ -318,7 +365,6 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
318
365
|
this._jobQueue.clear();
|
|
319
366
|
this.unregisterEventListeners();
|
|
320
367
|
this.connector.reset();
|
|
321
|
-
this._uiHandler = null;
|
|
322
368
|
this._discoveredDevices.clear();
|
|
323
369
|
this._sessions.clear();
|
|
324
370
|
this.emitter.removeAllListeners();
|
|
@@ -864,33 +910,32 @@ var _LedgerAdapter = class _LedgerAdapter {
|
|
|
864
910
|
return _LedgerAdapter._abortable(signal, this.connector.call(retrySessionId, method, params));
|
|
865
911
|
}
|
|
866
912
|
/**
|
|
867
|
-
* Ensure device permission before proceeding.
|
|
868
|
-
*
|
|
869
|
-
*
|
|
870
|
-
*
|
|
913
|
+
* Ensure OS-level device permission (Bluetooth / USB) before proceeding.
|
|
914
|
+
*
|
|
915
|
+
* Emits `REQUEST_DEVICE_PERMISSION` and awaits the consumer's
|
|
916
|
+
* `RECEIVE_DEVICE_PERMISSION` reply (60s budget covers "probe → system
|
|
917
|
+
* prompt → user tap" plus a generous margin). If the consumer never wires
|
|
918
|
+
* a handler or never replies, the wait times out and the operation fails
|
|
919
|
+
* fast so scanners/callers don't hang silently.
|
|
920
|
+
*
|
|
921
|
+
* - No connectId (searchDevices): environment-level permission
|
|
922
|
+
* - With connectId (business methods): device-level permission
|
|
871
923
|
*/
|
|
872
924
|
async _ensureDevicePermission(connectId, deviceId) {
|
|
873
|
-
const transportType = "hid";
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
granted = result.granted;
|
|
884
|
-
context = result.context;
|
|
885
|
-
} catch {
|
|
886
|
-
granted = false;
|
|
887
|
-
}
|
|
888
|
-
}
|
|
925
|
+
const transportType = this.activeTransport ?? "hid";
|
|
926
|
+
const waitPromise = this._uiRegistry.wait(
|
|
927
|
+
import_hwk_adapter_core2.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
928
|
+
{ timeoutMs: 6e4 }
|
|
929
|
+
);
|
|
930
|
+
this.emitter.emit(import_hwk_adapter_core2.UI_REQUEST.REQUEST_DEVICE_PERMISSION, {
|
|
931
|
+
type: import_hwk_adapter_core2.UI_REQUEST.REQUEST_DEVICE_PERMISSION,
|
|
932
|
+
payload: { transportType, connectId, deviceId }
|
|
933
|
+
});
|
|
934
|
+
const { granted } = await waitPromise;
|
|
889
935
|
if (!granted) {
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
}
|
|
893
|
-
}
|
|
936
|
+
throw Object.assign(new Error("Device permission denied"), {
|
|
937
|
+
code: import_hwk_adapter_core2.HardwareErrorCode.DevicePermissionDenied
|
|
938
|
+
});
|
|
894
939
|
}
|
|
895
940
|
}
|
|
896
941
|
/**
|
|
@@ -2027,35 +2072,8 @@ var AppManager = class {
|
|
|
2027
2072
|
};
|
|
2028
2073
|
|
|
2029
2074
|
// src/connector/chains/legacyAppRetry.ts
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
27013,
|
|
2033
|
-
// user denied
|
|
2034
|
-
21781,
|
|
2035
|
-
// device locked
|
|
2036
|
-
27274,
|
|
2037
|
-
// invalid BIP32 path
|
|
2038
|
-
27275,
|
|
2039
|
-
27276,
|
|
2040
|
-
27277,
|
|
2041
|
-
// app-specific data errors
|
|
2042
|
-
27264,
|
|
2043
|
-
// invalid data
|
|
2044
|
-
27392,
|
|
2045
|
-
// wrong parameter
|
|
2046
|
-
26368
|
|
2047
|
-
// wrong length
|
|
2048
|
-
])
|
|
2049
|
-
};
|
|
2050
|
-
function isLegacyWrongAppError(err, appName) {
|
|
2051
|
-
if (isWrongAppError(err)) return true;
|
|
2052
|
-
const msg = err instanceof Error ? err.message : "";
|
|
2053
|
-
const match = msg.match(/0x([0-9a-fA-F]{4})/);
|
|
2054
|
-
if (!match) return false;
|
|
2055
|
-
const sw = parseInt(match[1], 16);
|
|
2056
|
-
const knownCodes = KNOWN_APP_CODES[appName];
|
|
2057
|
-
if (knownCodes?.has(sw)) return false;
|
|
2058
|
-
return true;
|
|
2075
|
+
function isLegacyWrongAppError(err, _appName) {
|
|
2076
|
+
return isWrongAppError(err);
|
|
2059
2077
|
}
|
|
2060
2078
|
async function withLegacyAppRetry(ctx, sessionId, appName, action) {
|
|
2061
2079
|
try {
|
|
@@ -2122,6 +2140,7 @@ var DmkTransport = class extends import_hw_transport.default {
|
|
|
2122
2140
|
// src/connector/chains/tron.ts
|
|
2123
2141
|
async function tronGetAddress(ctx, sessionId, params) {
|
|
2124
2142
|
const path = normalizePath(params.path);
|
|
2143
|
+
await _ensureTronAppOpen(ctx, sessionId);
|
|
2125
2144
|
return withLegacyAppRetry(ctx, sessionId, "Tron", async (sid) => {
|
|
2126
2145
|
const trx = await _createTrx(ctx, sid);
|
|
2127
2146
|
if (params.showOnDevice) {
|
|
@@ -2146,6 +2165,7 @@ async function tronSignTransaction(ctx, sessionId, params) {
|
|
|
2146
2165
|
);
|
|
2147
2166
|
}
|
|
2148
2167
|
const path = normalizePath(params.path);
|
|
2168
|
+
await _ensureTronAppOpen(ctx, sessionId);
|
|
2149
2169
|
return withLegacyAppRetry(ctx, sessionId, "Tron", async (sid) => {
|
|
2150
2170
|
const trx = await _createTrx(ctx, sid);
|
|
2151
2171
|
ctx.emit("ui-event", {
|
|
@@ -2166,6 +2186,7 @@ async function tronSignTransaction(ctx, sessionId, params) {
|
|
|
2166
2186
|
}
|
|
2167
2187
|
async function tronSignMessage(ctx, sessionId, params) {
|
|
2168
2188
|
const path = normalizePath(params.path);
|
|
2189
|
+
await _ensureTronAppOpen(ctx, sessionId);
|
|
2169
2190
|
return withLegacyAppRetry(ctx, sessionId, "Tron", async (sid) => {
|
|
2170
2191
|
const trx = await _createTrx(ctx, sid);
|
|
2171
2192
|
ctx.emit("ui-event", {
|
|
@@ -2184,6 +2205,16 @@ async function _createTrx(ctx, sessionId) {
|
|
|
2184
2205
|
const dmk = await ctx.getOrCreateDmk();
|
|
2185
2206
|
return new import_hw_app_trx.default(new DmkTransport(dmk, sessionId));
|
|
2186
2207
|
}
|
|
2208
|
+
async function _ensureTronAppOpen(ctx, sessionId) {
|
|
2209
|
+
const dmk = await ctx.getOrCreateDmk();
|
|
2210
|
+
const appManager = new AppManager(dmk);
|
|
2211
|
+
await appManager.ensureAppOpen(sessionId, "Tron", () => {
|
|
2212
|
+
ctx.emit("ui-event", {
|
|
2213
|
+
type: import_hwk_adapter_core10.EConnectorInteraction.ConfirmOpenApp,
|
|
2214
|
+
payload: { sessionId }
|
|
2215
|
+
});
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
2187
2218
|
|
|
2188
2219
|
// src/connector/LedgerConnectorBase.ts
|
|
2189
2220
|
async function defaultLedgerKitImporter(pkg) {
|