@onekeyfe/hd-core 1.2.0-alpha.67 → 1.2.0-alpha.69
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/__tests__/AllNetworkGetAddressBase.tracing.test.ts +313 -0
- package/__tests__/DeviceCommands.test.ts +59 -13
- package/__tests__/DeviceEventRegistration.test.ts +6 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +226 -3
- package/__tests__/connectSettings.test.ts +5 -47
- package/__tests__/core-initialization.test.ts +23 -0
- package/__tests__/device-connector-protocol.test.ts +81 -0
- package/__tests__/device-lifecycle-events.test.ts +105 -3
- package/__tests__/device-pool-state.test.ts +22 -0
- package/__tests__/device-settings.test.ts +39 -18
- package/__tests__/device-state-contract.test.ts +1 -0
- package/__tests__/device-state-mapper.test.ts +13 -1
- package/__tests__/device-utils.test.ts +48 -1
- package/__tests__/deviceSettings.test.ts +11 -1
- package/__tests__/deviceUploadNft.test.ts +316 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +31 -59
- package/__tests__/get-device-state.test.ts +132 -12
- package/__tests__/homescreen.test.ts +41 -1
- package/__tests__/kaspa-use-tweak-pro2.test.ts +2 -2
- package/__tests__/kaspaSignTransaction.test.ts +3 -26
- package/__tests__/logBlockEvent.test.ts +1 -1
- package/__tests__/method-protocol-support.test.ts +19 -0
- package/__tests__/open-wallet-session.test.ts +568 -37
- package/__tests__/pro2Nft.test.ts +108 -0
- package/__tests__/protocol-binding.test.ts +89 -0
- package/__tests__/protocol-v2-firmware-targets.test.ts +33 -1
- package/__tests__/protocol-v2-resources.test.ts +343 -0
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
- package/__tests__/protocol-v2-unlock-policy.test.ts +300 -37
- package/__tests__/protocol-v2.test.ts +1586 -1213
- package/__tests__/protocolV2FileWrite.test.ts +193 -0
- package/__tests__/protocolV2UiInteraction.test.ts +63 -0
- package/__tests__/public-pro2-api-boundary.test.ts +1 -0
- package/__tests__/search-devices.test.ts +12 -3
- package/__tests__/tron-sign-message-init.test.ts +2 -2
- package/__tests__/uiProgressThrottle.test.ts +74 -0
- package/__tests__/uiPromiseRegistry.test.ts +115 -0
- package/dist/api/BaseMethod.d.ts +3 -1
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts +3 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/DetectDeviceConnectProtocol.d.ts +7 -0
- package/dist/api/DetectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +0 -10
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts +3 -7
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +15 -27
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/device/DeviceSettings.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +2 -2
- package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts +1 -5
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts +4 -11
- package/dist/api/firmware/FirmwareUpdateBaseMethod.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +0 -7
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/firmware/updateBootloader.d.ts +0 -2
- package/dist/api/firmware/updateBootloader.d.ts.map +1 -1
- package/dist/api/firmware/uploadFirmware.d.ts +1 -9
- package/dist/api/firmware/uploadFirmware.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +9 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaGetAddress.d.ts +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
- package/dist/api/polkadot/PolkadotGetAddress.d.ts +1 -1
- package/dist/api/polkadot/networks.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +31 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/solana/SolSignMessage.d.ts +1 -1
- package/dist/api/solana/SolSignOffchainMessage.d.ts +1 -1
- package/dist/api/solana/SolSignTransaction.d.ts +2 -2
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -1
- package/dist/api/sui/SuiGetAddress.d.ts +1 -1
- package/dist/api/sui/SuiGetPublicKey.d.ts +1 -1
- package/dist/api/sui/SuiSignMessage.d.ts +1 -1
- package/dist/api/sui/SuiSignTransaction.d.ts +1 -1
- package/dist/api/ton/TonGetAddress.d.ts +1 -1
- package/dist/api/ton/TonSignMessage.d.ts +1 -1
- package/dist/api/ton/TonSignProof.d.ts +1 -1
- package/dist/api/tron/TronSignMessage.d.ts +2 -2
- package/dist/api/tron/TronSignTransaction.d.ts +1 -1
- package/dist/core/deviceEventRegistration.d.ts +2 -0
- package/dist/core/deviceEventRegistration.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/uiPromiseRegistry.d.ts +6 -0
- package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
- package/dist/data-manager/DataManager.d.ts +9 -4
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/TransportManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +29 -6
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DeviceConnector.d.ts +2 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -1
- package/dist/events/device.d.ts +4 -0
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-promise.d.ts +4 -2
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +31 -2
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +10 -2
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +243 -247
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3135 -3785
- package/dist/inject.d.ts +6 -1
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/features.d.ts +0 -4
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/resources.d.ts +30 -0
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +7 -4
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +1 -3
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +6 -1
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -1
- package/dist/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +3 -5
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
- package/dist/types/api/deviceUnlock.d.ts +5 -1
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/deviceUpdateBootloader.d.ts +0 -6
- package/dist/types/api/deviceUpdateBootloader.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +2 -4
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +4 -70
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +7 -10
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +3 -0
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/device.d.ts +2 -2
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts +1 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +38 -21
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +0 -1
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesUtils.d.ts +4 -0
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/deviceSettings.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +4 -0
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/dist/utils/pro2Nft.d.ts +31 -0
- package/dist/utils/pro2Nft.d.ts.map +1 -0
- package/dist/utils/pro2Wallpaper.d.ts +10 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -1
- package/dist/utils/uiProgressThrottle.d.ts +3 -0
- package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +8 -10
- package/src/api/CheckAllFirmwareRelease.ts +78 -64
- package/src/api/DetectDeviceConnectProtocol.ts +18 -0
- package/src/api/FirmwareUpdate.ts +7 -15
- package/src/api/FirmwareUpdateV2.ts +126 -298
- package/src/api/FirmwareUpdateV3.ts +63 -265
- package/src/api/FirmwareUpdateV4.ts +645 -1018
- package/src/api/GetPassphraseState.ts +7 -1
- package/src/api/OpenWalletSession.ts +71 -17
- package/src/api/SearchDevices.ts +3 -1
- package/src/api/allnetwork/AllNetworkGetAddress.ts +21 -21
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +36 -11
- package/src/api/device/DeviceSettings.ts +5 -4
- package/src/api/device/DeviceUnlock.ts +8 -3
- package/src/api/device/DeviceUpdateBootloader.ts +6 -125
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +27 -83
- package/src/api/firmware/updateBootloader.ts +4 -19
- package/src/api/firmware/uploadFirmware.ts +39 -144
- package/src/api/helpers/protocolV2FileWrite.ts +252 -63
- package/src/api/index.ts +2 -0
- package/src/api/kaspa/KaspaGetAddress.ts +1 -1
- package/src/api/kaspa/KaspaSignTransaction.ts +2 -13
- package/src/api/polkadot/networks.ts +3 -3
- package/src/api/protocol-v2/DeviceUploadNft.ts +197 -0
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +3 -1
- package/src/api/protocol-v2/helpers.ts +1 -1
- package/src/api/solana/SolSignMessage.ts +1 -1
- package/src/api/solana/SolSignOffchainMessage.ts +1 -1
- package/src/api/solana/SolSignTransaction.ts +2 -2
- package/src/api/sui/SuiGetAddress.ts +1 -1
- package/src/api/sui/SuiGetPublicKey.ts +1 -1
- package/src/api/sui/SuiSignMessage.ts +1 -1
- package/src/api/sui/SuiSignTransaction.ts +1 -1
- package/src/api/ton/TonGetAddress.ts +1 -1
- package/src/api/ton/TonSignMessage.ts +1 -1
- package/src/api/ton/TonSignProof.ts +1 -1
- package/src/api/tron/TronSignMessage.ts +2 -2
- package/src/api/tron/TronSignTransaction.ts +1 -1
- package/src/core/deviceEventRegistration.ts +4 -0
- package/src/core/index.ts +213 -111
- package/src/core/uiPromiseRegistry.ts +63 -0
- package/src/data/messages/messages-protocol-v2.json +25 -0
- package/src/data-manager/DataManager.ts +113 -41
- package/src/data-manager/TransportManager.ts +6 -0
- package/src/data-manager/connectSettings.ts +0 -11
- package/src/device/Device.ts +274 -49
- package/src/device/DeviceCommands.ts +31 -4
- package/src/device/DeviceConnector.ts +33 -13
- package/src/device/DevicePool.ts +21 -7
- package/src/deviceProfile/buildDeviceFeatures.ts +2 -2
- package/src/deviceProfile/protocolV2DeviceIdentity.ts +3 -0
- package/src/events/device.ts +4 -0
- package/src/events/logBlockEvent.ts +1 -0
- package/src/events/ui-promise.ts +4 -2
- package/src/events/ui-request.ts +36 -2
- package/src/events/ui-response.ts +12 -2
- package/src/index.ts +0 -5
- package/src/inject.ts +60 -24
- package/src/lowLevelInject.ts +7 -8
- package/src/protocols/protocol-v2/features.ts +10 -7
- package/src/protocols/protocol-v2/firmware.ts +2 -0
- package/src/protocols/protocol-v2/resources.ts +394 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +46 -6
- package/src/protocols/protocol-v2/unlockPolicy.ts +1 -105
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +131 -0
- package/src/protocols/protocol-v2/walletSession.ts +214 -36
- package/src/topLevelInject.ts +7 -8
- package/src/types/api/checkAllFirmwareRelease.ts +3 -5
- package/src/types/api/detectDeviceConnectProtocol.ts +6 -0
- package/src/types/api/deviceUnlock.ts +12 -1
- package/src/types/api/deviceUpdateBootloader.ts +0 -6
- package/src/types/api/export.ts +1 -18
- package/src/types/api/firmwareUpdate.ts +6 -78
- package/src/types/api/index.ts +13 -14
- package/src/types/api/protocolV2.ts +13 -0
- package/src/types/device.ts +15 -3
- package/src/types/params.ts +7 -1
- package/src/types/settings.ts +61 -22
- package/src/utils/deviceFeaturesCompat.ts +5 -6
- package/src/utils/deviceFeaturesUtils.ts +14 -3
- package/src/utils/deviceInfoUtils.ts +2 -0
- package/src/utils/deviceSettings.ts +3 -0
- package/src/utils/homescreen.ts +32 -6
- package/src/utils/index.ts +6 -1
- package/src/utils/pro2Nft.ts +142 -0
- package/src/utils/pro2Wallpaper.ts +35 -8
- package/src/utils/uiProgressThrottle.ts +63 -0
- package/__tests__/device-initialize-timeout.test.ts +0 -56
- package/__tests__/firmware-update/check-all-firmware-release.test.ts +0 -175
- package/__tests__/firmware-update/device-update-bootloader.test.ts +0 -87
- package/__tests__/firmware-update/firmware-artifact-source.test.ts +0 -119
- package/__tests__/firmware-update/firmware-host-binding.test.ts +0 -70
- package/__tests__/firmware-update/firmware-preparation-error.test.ts +0 -27
- package/__tests__/firmware-update/firmware-update-bootloader-poll.test.ts +0 -200
- package/__tests__/firmware-update/firmware-update-capabilities.test.ts +0 -13
- package/__tests__/firmware-update/firmware-update-plan-bootloader-identity.test.ts +0 -394
- package/__tests__/firmware-update/firmware-update-plan.test.ts +0 -593
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +0 -231
- package/__tests__/firmware-update/firmware-update-v3-reconnect.test.ts +0 -58
- package/__tests__/firmware-update/firmware-upload-source.test.ts +0 -70
- package/dist/api/firmware/FirmwareArtifactSource.d.ts +0 -25
- package/dist/api/firmware/FirmwareArtifactSource.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareHostBinding.d.ts +0 -6
- package/dist/api/firmware/FirmwareHostBinding.d.ts.map +0 -1
- package/dist/api/firmware/FirmwarePreparationError.d.ts +0 -3
- package/dist/api/firmware/FirmwarePreparationError.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts +0 -3
- package/dist/api/firmware/FirmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -25
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +0 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts +0 -32
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/dist/api/firmware/progressThrottle.d.ts +0 -3
- package/dist/api/firmware/progressThrottle.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/lockedError.d.ts +0 -2
- package/dist/protocols/protocol-v2/lockedError.d.ts.map +0 -1
- package/dist/protocols/protocol-v2/unlockRetry.d.ts +0 -10
- package/dist/protocols/protocol-v2/unlockRetry.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdateCapabilities.d.ts +0 -9
- package/dist/types/api/firmwareUpdateCapabilities.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePlan.d.ts +0 -28
- package/dist/types/api/firmwareUpdatePlan.d.ts.map +0 -1
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts +0 -42
- package/dist/types/api/firmwareUpdatePreparedPlan.d.ts.map +0 -1
- package/src/api/firmware/FirmwareArtifactSource.ts +0 -278
- package/src/api/firmware/FirmwareHostBinding.ts +0 -100
- package/src/api/firmware/FirmwarePreparationError.ts +0 -12
- package/src/api/firmware/FirmwareUpdateCapabilities.ts +0 -9
- package/src/api/firmware/FirmwareUpdatePlan.ts +0 -772
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +0 -449
- package/src/api/firmware/progressThrottle.ts +0 -44
- package/src/protocols/protocol-v2/lockedError.ts +0 -10
- package/src/protocols/protocol-v2/unlockRetry.ts +0 -109
- package/src/types/api/firmwareUpdateCapabilities.ts +0 -9
- package/src/types/api/firmwareUpdatePlan.ts +0 -38
- package/src/types/api/firmwareUpdatePreparedPlan.ts +0 -53
package/src/device/Device.ts
CHANGED
|
@@ -74,7 +74,9 @@ import type { DeviceStateReadOptions } from '../types/api/getDeviceState';
|
|
|
74
74
|
import type {
|
|
75
75
|
DeviceButtonRequestPayload,
|
|
76
76
|
DeviceFeaturesPayload,
|
|
77
|
+
HardwareUiInteractionMeta,
|
|
77
78
|
PassphraseRequestPayload,
|
|
79
|
+
ProtocolV2UiEventMetadata,
|
|
78
80
|
} from '../events';
|
|
79
81
|
import type { PassphrasePromptResponse } from './DeviceCommands';
|
|
80
82
|
import type { Deferred, HardwareConnectProtocol } from '@onekeyfe/hd-shared';
|
|
@@ -93,14 +95,10 @@ export type InitOptions = {
|
|
|
93
95
|
passphraseState?: string;
|
|
94
96
|
deriveCardano?: boolean;
|
|
95
97
|
connectProtocol?: HardwareConnectProtocol;
|
|
98
|
+
forceProtocolDetection?: boolean;
|
|
96
99
|
protocolV2DeviceInfoTimeoutMs?: number;
|
|
97
100
|
/** Refresh Protocol V2 runtime state before returning discovery results. */
|
|
98
101
|
refreshRuntimeState?: boolean;
|
|
99
|
-
/**
|
|
100
|
-
* Protocol V1 Initialize response timeout override. Reboot-wait polling passes a
|
|
101
|
-
* short value so an unanswered probe settles before the next poll tick.
|
|
102
|
-
*/
|
|
103
|
-
timeoutMs?: number;
|
|
104
102
|
};
|
|
105
103
|
|
|
106
104
|
export type RunOptions = {
|
|
@@ -137,6 +135,8 @@ const isProtocolV2DeviceStatusUnsupportedError = (error: unknown) => {
|
|
|
137
135
|
|
|
138
136
|
export interface DeviceEvents {
|
|
139
137
|
[DEVICE.PIN]: [Device, PROTO.PinMatrixRequestType | undefined, (err: any, pin: string) => void];
|
|
138
|
+
[DEVICE.PIN_ON_DEVICE]: [Device, DeviceSessionPinType, ProtocolV2UiEventMetadata?];
|
|
139
|
+
[DEVICE.PIN_ON_DEVICE_COMPLETE]: [Device, HardwareUiInteractionMeta];
|
|
140
140
|
[DEVICE.PASSPHRASE_ON_DEVICE]: [Device, PassphraseRequestPayload?];
|
|
141
141
|
[DEVICE.ATTACH_PIN_ON_DEVICE]: [Device, PassphraseRequestPayload?];
|
|
142
142
|
[DEVICE.BUTTON]: [Device, DeviceButtonRequestPayload];
|
|
@@ -235,6 +235,24 @@ export class Device extends EventEmitter {
|
|
|
235
235
|
/** Force the next initialization to reload DeviceInfo after reconnect or reboot. */
|
|
236
236
|
private protocolV2StateNeedsReload = false;
|
|
237
237
|
|
|
238
|
+
/** Runtime context negotiated once per active Protocol V2 link. */
|
|
239
|
+
private protocolV2RuntimeContext?: ProtocolInfo;
|
|
240
|
+
|
|
241
|
+
/** Coalesces concurrent first-use runtime negotiation on the same active link. */
|
|
242
|
+
private protocolV2RuntimeContextPromise?: Promise<ProtocolInfo>;
|
|
243
|
+
|
|
244
|
+
/** Invalidates an in-flight runtime-context response without adding a transport epoch. */
|
|
245
|
+
private protocolV2RuntimeContextRequestToken?: object;
|
|
246
|
+
|
|
247
|
+
private protocolV2UiInteraction?: {
|
|
248
|
+
interactionId: string;
|
|
249
|
+
phaseCounter: number;
|
|
250
|
+
sequence: number;
|
|
251
|
+
opened: boolean;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
private protocolV2UiInteractionCounter = 0;
|
|
255
|
+
|
|
238
256
|
get state() {
|
|
239
257
|
return this.stateStore.getState();
|
|
240
258
|
}
|
|
@@ -342,7 +360,7 @@ export class Device extends EventEmitter {
|
|
|
342
360
|
deviceId,
|
|
343
361
|
path: this.originalDescriptor?.path,
|
|
344
362
|
bleName,
|
|
345
|
-
name:
|
|
363
|
+
name: bleName || displayName || `OneKey ${deviceType?.toUpperCase()}`,
|
|
346
364
|
// Keep the legacy top-level field string-compatible while preserving
|
|
347
365
|
// the canonical nullable value at state.identity.label.
|
|
348
366
|
label: displayName ?? '',
|
|
@@ -360,7 +378,10 @@ export class Device extends EventEmitter {
|
|
|
360
378
|
* Device connect
|
|
361
379
|
* @returns {Promise<boolean>}
|
|
362
380
|
*/
|
|
363
|
-
connect(
|
|
381
|
+
connect(
|
|
382
|
+
connectProtocol?: HardwareConnectProtocol,
|
|
383
|
+
options?: { forceProtocolDetection?: boolean }
|
|
384
|
+
) {
|
|
364
385
|
const env = DataManager.getSettings('env');
|
|
365
386
|
// eslint-disable-next-line no-async-promise-executor
|
|
366
387
|
return new Promise<boolean>(async (resolve, reject) => {
|
|
@@ -370,7 +391,7 @@ export class Device extends EventEmitter {
|
|
|
370
391
|
return;
|
|
371
392
|
}
|
|
372
393
|
try {
|
|
373
|
-
await this.acquire(connectProtocol);
|
|
394
|
+
await this.acquire(connectProtocol, options);
|
|
374
395
|
resolve(true);
|
|
375
396
|
} catch (error) {
|
|
376
397
|
reject(error);
|
|
@@ -380,7 +401,7 @@ export class Device extends EventEmitter {
|
|
|
380
401
|
// 不存在 Session ID 或存在 Session ID 但设备在别处使用,都需要 acquire 获取最新 sessionID
|
|
381
402
|
if (!this.mainId || (!this.isUsedHere() && this.originalDescriptor)) {
|
|
382
403
|
try {
|
|
383
|
-
await this.acquire(connectProtocol);
|
|
404
|
+
await this.acquire(connectProtocol, options);
|
|
384
405
|
resolve(true);
|
|
385
406
|
} catch (error) {
|
|
386
407
|
reject(error);
|
|
@@ -397,11 +418,16 @@ export class Device extends EventEmitter {
|
|
|
397
418
|
|
|
398
419
|
async acquire(
|
|
399
420
|
expectedProtocol?: HardwareConnectProtocol,
|
|
400
|
-
options?: { throwOnRunPromiseError?: boolean }
|
|
421
|
+
options?: { throwOnRunPromiseError?: boolean; forceProtocolDetection?: boolean }
|
|
401
422
|
) {
|
|
402
423
|
const env = DataManager.getSettings('env');
|
|
403
424
|
const mainIdKey = DataManager.isBleConnect(env) ? 'id' : 'session';
|
|
404
|
-
const
|
|
425
|
+
const previousProtocol = this.originalDescriptor.protocolType;
|
|
426
|
+
// A protocol stored after a successful probe is authoritative. Only the explicit
|
|
427
|
+
// first-connection/recovery path may bypass it and probe both protocols again.
|
|
428
|
+
const strictProtocol = options?.forceProtocolDetection
|
|
429
|
+
? undefined
|
|
430
|
+
: expectedProtocol ?? this.originalDescriptor.protocolType;
|
|
405
431
|
try {
|
|
406
432
|
let acquireResult: unknown;
|
|
407
433
|
if (DataManager.isBleConnect(env)) {
|
|
@@ -413,8 +439,8 @@ export class Device extends EventEmitter {
|
|
|
413
439
|
this.originalDescriptor.id,
|
|
414
440
|
undefined,
|
|
415
441
|
true,
|
|
416
|
-
|
|
417
|
-
|
|
442
|
+
strictProtocol,
|
|
443
|
+
undefined
|
|
418
444
|
);
|
|
419
445
|
this.mainId = (acquireResult as any)?.uuid ?? '';
|
|
420
446
|
Log.debug('Expected uuid:', this.mainId);
|
|
@@ -423,24 +449,31 @@ export class Device extends EventEmitter {
|
|
|
423
449
|
this.originalDescriptor.path,
|
|
424
450
|
this.originalDescriptor.session,
|
|
425
451
|
undefined,
|
|
426
|
-
|
|
427
|
-
|
|
452
|
+
strictProtocol,
|
|
453
|
+
undefined
|
|
428
454
|
);
|
|
429
455
|
this.mainId = acquireResult as string | undefined;
|
|
430
456
|
Log.debug('Expected session id:', this.mainId);
|
|
431
457
|
}
|
|
432
|
-
this.deviceAcquired = true;
|
|
433
|
-
this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
|
|
434
|
-
|
|
435
458
|
// Propagate protocol version detected during acquire.
|
|
436
459
|
const detectedProtocol =
|
|
437
460
|
(acquireResult as { protocolType?: HardwareConnectProtocol } | undefined)?.protocolType ??
|
|
438
461
|
TransportManager.transport?.getProtocolType?.(
|
|
439
462
|
DataManager.isBleConnect(env) ? this.originalDescriptor.id : this.originalDescriptor.path
|
|
440
463
|
);
|
|
464
|
+
if (options?.forceProtocolDetection && !detectedProtocol) {
|
|
465
|
+
throw ERRORS.TypedError(
|
|
466
|
+
HardwareErrorCode.RuntimeError,
|
|
467
|
+
`Active protocol detection returned no protocol for ${
|
|
468
|
+
this.originalDescriptor.path || this.originalDescriptor.id
|
|
469
|
+
}`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
441
472
|
if (detectedProtocol) {
|
|
442
473
|
this.originalDescriptor.protocolType = detectedProtocol;
|
|
443
474
|
}
|
|
475
|
+
this.deviceAcquired = true;
|
|
476
|
+
this.updateDescriptor({ [mainIdKey]: this.mainId } as unknown as DeviceDescriptor);
|
|
444
477
|
|
|
445
478
|
if (this.commands) {
|
|
446
479
|
await this.commands.dispose(false);
|
|
@@ -448,6 +481,22 @@ export class Device extends EventEmitter {
|
|
|
448
481
|
|
|
449
482
|
this.commands = new DeviceCommands(this, this.mainId ?? '');
|
|
450
483
|
} catch (error) {
|
|
484
|
+
if (options?.forceProtocolDetection) {
|
|
485
|
+
this.originalDescriptor.protocolType = previousProtocol;
|
|
486
|
+
const failedSession = this.mainId;
|
|
487
|
+
this.deviceAcquired = false;
|
|
488
|
+
if (failedSession) {
|
|
489
|
+
try {
|
|
490
|
+
await this.deviceConnector?.release?.(failedSession, false);
|
|
491
|
+
} catch (releaseError) {
|
|
492
|
+
Log.debug('Failed to release an unsuccessful protocol probe', releaseError);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (!DataManager.isBleConnect(env)) {
|
|
496
|
+
this.mainId = null;
|
|
497
|
+
this.updateDescriptor({ session: null } as DeviceDescriptor);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
451
500
|
if (options?.throwOnRunPromiseError) {
|
|
452
501
|
throw error;
|
|
453
502
|
}
|
|
@@ -647,6 +696,7 @@ export class Device extends EventEmitter {
|
|
|
647
696
|
// Most-specific model first; must match getMethodVersionRange in deviceInfoUtils,
|
|
648
697
|
// otherwise e.g. Classic1s resolves the looser model_mini range before model_classic1s.
|
|
649
698
|
const modelFallbacks: IDeviceModel[] = [
|
|
699
|
+
'model_pro2',
|
|
650
700
|
'model_classic1s',
|
|
651
701
|
'model_classic',
|
|
652
702
|
'model_mini',
|
|
@@ -666,7 +716,8 @@ export class Device extends EventEmitter {
|
|
|
666
716
|
if (
|
|
667
717
|
deviceType === EDeviceType.Touch ||
|
|
668
718
|
deviceType === EDeviceType.Pro ||
|
|
669
|
-
deviceType === EDeviceType.Pro2
|
|
719
|
+
deviceType === EDeviceType.Pro2 ||
|
|
720
|
+
deviceType === EDeviceType.Neo
|
|
670
721
|
) {
|
|
671
722
|
return { support: true };
|
|
672
723
|
}
|
|
@@ -683,7 +734,8 @@ export class Device extends EventEmitter {
|
|
|
683
734
|
if (
|
|
684
735
|
deviceType === EDeviceType.Touch ||
|
|
685
736
|
deviceType === EDeviceType.Pro ||
|
|
686
|
-
deviceType === EDeviceType.Pro2
|
|
737
|
+
deviceType === EDeviceType.Pro2 ||
|
|
738
|
+
deviceType === EDeviceType.Neo
|
|
687
739
|
) {
|
|
688
740
|
return { support: false };
|
|
689
741
|
}
|
|
@@ -856,7 +908,7 @@ export class Device extends EventEmitter {
|
|
|
856
908
|
const initStartAt = Date.now();
|
|
857
909
|
const { message } = await this.commands.typedCall('Initialize', 'Features', payload, {
|
|
858
910
|
// iOS BLE bound devices can need close to 20 seconds.
|
|
859
|
-
timeoutMs:
|
|
911
|
+
timeoutMs: 25 * 1000,
|
|
860
912
|
});
|
|
861
913
|
this.setLastInitializeDuration(Date.now() - initStartAt);
|
|
862
914
|
this._updateFeatures(message, initSession);
|
|
@@ -969,7 +1021,10 @@ export class Device extends EventEmitter {
|
|
|
969
1021
|
await this.getFeatures();
|
|
970
1022
|
}
|
|
971
1023
|
|
|
972
|
-
|
|
1024
|
+
const supportsProtocolV1OnekeyFeatures =
|
|
1025
|
+
this.getCurrentDeviceType() === EDeviceType.Touch ||
|
|
1026
|
+
this.getCurrentDeviceType() === EDeviceType.Pro;
|
|
1027
|
+
if (!this.isProtocolV2() && refresh.has('verification') && supportsProtocolV1OnekeyFeatures) {
|
|
973
1028
|
const { message } = await this.commands.typedCall('OnekeyGetFeatures', 'OnekeyFeatures');
|
|
974
1029
|
this.updateState(mapProtocolV1OnekeyFeaturesToState(message), 'device-info');
|
|
975
1030
|
}
|
|
@@ -992,13 +1047,7 @@ export class Device extends EventEmitter {
|
|
|
992
1047
|
}
|
|
993
1048
|
|
|
994
1049
|
if (refresh.has('status') && !initializedWithDeviceInfo) {
|
|
995
|
-
|
|
996
|
-
refreshedDeviceInfo ??
|
|
997
|
-
(await requestProtocolV2DeviceInfo({
|
|
998
|
-
commands: this.commands,
|
|
999
|
-
request: getProtocolV2DeviceInfoRequest(),
|
|
1000
|
-
}));
|
|
1001
|
-
await this.probeProtocolV2RuntimeState(deviceInfo);
|
|
1050
|
+
await this.probeProtocolV2RuntimeState(refreshedDeviceInfo);
|
|
1002
1051
|
}
|
|
1003
1052
|
|
|
1004
1053
|
if (refresh.has('settings') && this.state?.status.mode === 'normal') {
|
|
@@ -1069,19 +1118,66 @@ export class Device extends EventEmitter {
|
|
|
1069
1118
|
return this.features;
|
|
1070
1119
|
}
|
|
1071
1120
|
|
|
1072
|
-
async
|
|
1073
|
-
const
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1121
|
+
async ensureProtocolV2RuntimeContext(timeoutMs?: number): Promise<ProtocolInfo> {
|
|
1122
|
+
const cachedProtocolInfo =
|
|
1123
|
+
this.protocolV2RuntimeContext ??
|
|
1124
|
+
(!this.protocolV2StateNeedsReload
|
|
1125
|
+
? this.state?.raw?.protocolV2ProtocolInfo ?? undefined
|
|
1126
|
+
: undefined);
|
|
1127
|
+
if (cachedProtocolInfo) {
|
|
1128
|
+
this.protocolV2RuntimeContext = cachedProtocolInfo;
|
|
1129
|
+
return cachedProtocolInfo;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
if (this.protocolV2RuntimeContextPromise) {
|
|
1133
|
+
return this.protocolV2RuntimeContextPromise;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
const requestToken = {};
|
|
1137
|
+
const pendingRequest = (async () => {
|
|
1138
|
+
const protocolInfo = await requestProtocolV2ProtocolInfo({
|
|
1139
|
+
commands: this.commands,
|
|
1140
|
+
timeoutMs,
|
|
1141
|
+
});
|
|
1142
|
+
if (this.protocolV2RuntimeContextRequestToken !== requestToken) {
|
|
1143
|
+
throw ERRORS.TypedError(
|
|
1144
|
+
HardwareErrorCode.DeviceInitializeFailed,
|
|
1145
|
+
'Protocol V2 runtime context was invalidated while loading.'
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
this.protocolV2RuntimeContext = protocolInfo;
|
|
1149
|
+
return protocolInfo;
|
|
1150
|
+
})();
|
|
1151
|
+
this.protocolV2RuntimeContextRequestToken = requestToken;
|
|
1152
|
+
this.protocolV2RuntimeContextPromise = pendingRequest;
|
|
1153
|
+
|
|
1154
|
+
try {
|
|
1155
|
+
return await pendingRequest;
|
|
1156
|
+
} finally {
|
|
1157
|
+
if (this.protocolV2RuntimeContextPromise === pendingRequest) {
|
|
1158
|
+
this.protocolV2RuntimeContextPromise = undefined;
|
|
1159
|
+
}
|
|
1160
|
+
if (this.protocolV2RuntimeContextRequestToken === requestToken) {
|
|
1161
|
+
this.protocolV2RuntimeContextRequestToken = undefined;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
async probeProtocolV2RuntimeState(deviceInfo?: ProtocolV2DeviceInfo, timeoutMs?: number) {
|
|
1167
|
+
const protocolInfo = await this.ensureProtocolV2RuntimeContext(timeoutMs);
|
|
1077
1168
|
const runtimeMode = getProtocolV2RuntimeMode(protocolInfo);
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1169
|
+
const runtimeDeviceInfo = deviceInfo ?? this.state?.raw?.protocolV2DeviceInfo;
|
|
1170
|
+
const protocolV2DeviceType = runtimeDeviceInfo
|
|
1171
|
+
? resolveProtocolV2DeviceIdentity(runtimeDeviceInfo.hw?.Device_type).deviceType
|
|
1172
|
+
: this.getCurrentDeviceType();
|
|
1173
|
+
if (
|
|
1174
|
+
runtimeMode === 'romloader' &&
|
|
1175
|
+
protocolV2DeviceType !== EDeviceType.Pro2 &&
|
|
1176
|
+
protocolV2DeviceType !== EDeviceType.Neo
|
|
1177
|
+
) {
|
|
1082
1178
|
throw ERRORS.TypedError(
|
|
1083
1179
|
HardwareErrorCode.DeviceInitializeFailed,
|
|
1084
|
-
'Protocol V2 romloader mode is only supported for Pro2.'
|
|
1180
|
+
'Protocol V2 romloader mode is only supported for Pro2 and Neo.'
|
|
1085
1181
|
);
|
|
1086
1182
|
}
|
|
1087
1183
|
const deviceStatusSupported = supportsProtocolV2Message(
|
|
@@ -1152,6 +1248,9 @@ export class Device extends EventEmitter {
|
|
|
1152
1248
|
this.deviceAcquired = false;
|
|
1153
1249
|
if (!this.isProtocolV2()) return;
|
|
1154
1250
|
this.protocolV2StateNeedsReload = true;
|
|
1251
|
+
this.protocolV2RuntimeContext = undefined;
|
|
1252
|
+
this.protocolV2RuntimeContextPromise = undefined;
|
|
1253
|
+
this.protocolV2RuntimeContextRequestToken = undefined;
|
|
1155
1254
|
this.clearPreInitialized();
|
|
1156
1255
|
}
|
|
1157
1256
|
|
|
@@ -1160,9 +1259,14 @@ export class Device extends EventEmitter {
|
|
|
1160
1259
|
if (deviceId) {
|
|
1161
1260
|
deviceWalletSessionStore.deleteDevice(deviceId);
|
|
1162
1261
|
}
|
|
1163
|
-
if (this.isProtocolV2()
|
|
1164
|
-
|
|
1262
|
+
if (this.isProtocolV2()) {
|
|
1263
|
+
if (this.originalDescriptor.path !== deviceId) {
|
|
1264
|
+
deviceWalletSessionStore.deleteDevice(this.originalDescriptor.path);
|
|
1265
|
+
}
|
|
1165
1266
|
this.protocolV2StateNeedsReload = true;
|
|
1267
|
+
this.protocolV2RuntimeContext = undefined;
|
|
1268
|
+
this.protocolV2RuntimeContextPromise = undefined;
|
|
1269
|
+
this.protocolV2RuntimeContextRequestToken = undefined;
|
|
1166
1270
|
}
|
|
1167
1271
|
|
|
1168
1272
|
this.passphraseState = undefined;
|
|
@@ -1175,6 +1279,9 @@ export class Device extends EventEmitter {
|
|
|
1175
1279
|
if (!this.isProtocolV2()) return;
|
|
1176
1280
|
|
|
1177
1281
|
this.protocolV2StateNeedsReload = true;
|
|
1282
|
+
this.protocolV2RuntimeContext = undefined;
|
|
1283
|
+
this.protocolV2RuntimeContextPromise = undefined;
|
|
1284
|
+
this.protocolV2RuntimeContextRequestToken = undefined;
|
|
1178
1285
|
this.clearPreInitialized();
|
|
1179
1286
|
let loaderMode: 'bootloader' | 'romloader' | undefined;
|
|
1180
1287
|
if (rebootType === DeviceRebootType.Bootloader) {
|
|
@@ -1281,11 +1388,17 @@ export class Device extends EventEmitter {
|
|
|
1281
1388
|
}
|
|
1282
1389
|
};
|
|
1283
1390
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1391
|
+
const env = DataManager.getSettings('env');
|
|
1392
|
+
if (options.forceProtocolDetection && env !== 'react-native' && this.isUsedHere()) {
|
|
1393
|
+
await this.release();
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
if (options.forceProtocolDetection || !this.isUsedHere() || this.commands.disposed) {
|
|
1286
1397
|
if (env !== 'react-native') {
|
|
1287
1398
|
try {
|
|
1288
|
-
await this.acquire(options.connectProtocol
|
|
1399
|
+
await this.acquire(options.connectProtocol, {
|
|
1400
|
+
forceProtocolDetection: options.forceProtocolDetection,
|
|
1401
|
+
});
|
|
1289
1402
|
} catch (error) {
|
|
1290
1403
|
clearRunPromise();
|
|
1291
1404
|
runPromise.reject(error);
|
|
@@ -1463,7 +1576,8 @@ export class Device extends EventEmitter {
|
|
|
1463
1576
|
if (!this.state) return undefined;
|
|
1464
1577
|
return (
|
|
1465
1578
|
this.isProtocolV2() &&
|
|
1466
|
-
this.getCurrentDeviceType() === EDeviceType.Pro2
|
|
1579
|
+
(this.getCurrentDeviceType() === EDeviceType.Pro2 ||
|
|
1580
|
+
this.getCurrentDeviceType() === EDeviceType.Neo) &&
|
|
1467
1581
|
this.state.status.mode === 'romloader'
|
|
1468
1582
|
);
|
|
1469
1583
|
}
|
|
@@ -1509,7 +1623,8 @@ export class Device extends EventEmitter {
|
|
|
1509
1623
|
const isModeT =
|
|
1510
1624
|
deviceType === EDeviceType.Touch ||
|
|
1511
1625
|
deviceType === EDeviceType.Pro ||
|
|
1512
|
-
deviceType === EDeviceType.Pro2
|
|
1626
|
+
deviceType === EDeviceType.Pro2 ||
|
|
1627
|
+
deviceType === EDeviceType.Neo;
|
|
1513
1628
|
const unlocked = this.state?.status.unlocked;
|
|
1514
1629
|
const preCheckTouch = isModeT && unlocked === false;
|
|
1515
1630
|
const passphraseProtection = this.getCurrentPassphraseProtection();
|
|
@@ -1527,6 +1642,85 @@ export class Device extends EventEmitter {
|
|
|
1527
1642
|
return res.message;
|
|
1528
1643
|
}
|
|
1529
1644
|
|
|
1645
|
+
beginProtocolV2UiInteraction() {
|
|
1646
|
+
if (!this.isProtocolV2()) return;
|
|
1647
|
+
this.protocolV2UiInteraction = {
|
|
1648
|
+
interactionId: `${this.instanceId}:${Date.now()}:${++this.protocolV2UiInteractionCounter}`,
|
|
1649
|
+
phaseCounter: 0,
|
|
1650
|
+
sequence: 0,
|
|
1651
|
+
opened: false,
|
|
1652
|
+
};
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
createProtocolV2UiPhaseMetadata(
|
|
1656
|
+
phase: HardwareUiInteractionMeta['phase'],
|
|
1657
|
+
transition: HardwareUiInteractionMeta['transition'],
|
|
1658
|
+
options?: {
|
|
1659
|
+
phaseId?: string;
|
|
1660
|
+
outcome?: HardwareUiInteractionMeta['outcome'];
|
|
1661
|
+
}
|
|
1662
|
+
): HardwareUiInteractionMeta | undefined {
|
|
1663
|
+
if (!this.isProtocolV2()) return undefined;
|
|
1664
|
+
if (!this.protocolV2UiInteraction) this.beginProtocolV2UiInteraction();
|
|
1665
|
+
|
|
1666
|
+
const interaction = this.protocolV2UiInteraction;
|
|
1667
|
+
if (!interaction) return undefined;
|
|
1668
|
+
const phaseId =
|
|
1669
|
+
options?.phaseId ?? `${interaction.interactionId}:phase-${++interaction.phaseCounter}`;
|
|
1670
|
+
interaction.opened = true;
|
|
1671
|
+
interaction.sequence += 1;
|
|
1672
|
+
|
|
1673
|
+
return {
|
|
1674
|
+
interactionId: interaction.interactionId,
|
|
1675
|
+
phaseId,
|
|
1676
|
+
sequence: interaction.sequence,
|
|
1677
|
+
phase,
|
|
1678
|
+
transition,
|
|
1679
|
+
...(options?.outcome ? { outcome: options.outcome } : {}),
|
|
1680
|
+
protocol: 'V2',
|
|
1681
|
+
};
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
completeProtocolV2UiPhase(
|
|
1685
|
+
phase: HardwareUiInteractionMeta,
|
|
1686
|
+
outcome: HardwareUiInteractionMeta['outcome'] = 'succeeded'
|
|
1687
|
+
) {
|
|
1688
|
+
return this.createProtocolV2UiPhaseMetadata(phase.phase, 'complete', {
|
|
1689
|
+
phaseId: phase.phaseId,
|
|
1690
|
+
outcome,
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
finishProtocolV2UiInteraction(
|
|
1695
|
+
outcome?: HardwareUiInteractionMeta['outcome'],
|
|
1696
|
+
options?: { ensureMetadata?: boolean }
|
|
1697
|
+
) {
|
|
1698
|
+
const interaction = this.protocolV2UiInteraction;
|
|
1699
|
+
if (!interaction || (!interaction.opened && !options?.ensureMetadata)) {
|
|
1700
|
+
this.protocolV2UiInteraction = undefined;
|
|
1701
|
+
return undefined;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
const phaseId = `${interaction.interactionId}:phase-${Math.max(interaction.phaseCounter, 1)}`;
|
|
1705
|
+
interaction.opened = true;
|
|
1706
|
+
interaction.sequence += 1;
|
|
1707
|
+
const metadata: HardwareUiInteractionMeta = {
|
|
1708
|
+
interactionId: interaction.interactionId,
|
|
1709
|
+
phaseId,
|
|
1710
|
+
sequence: interaction.sequence,
|
|
1711
|
+
phase: 'processing',
|
|
1712
|
+
transition: 'finish',
|
|
1713
|
+
outcome: outcome ?? 'succeeded',
|
|
1714
|
+
protocol: 'V2',
|
|
1715
|
+
};
|
|
1716
|
+
this.protocolV2UiInteraction = undefined;
|
|
1717
|
+
return metadata;
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
hasOpenProtocolV2UiInteraction() {
|
|
1721
|
+
return this.protocolV2UiInteraction?.opened === true;
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1530
1724
|
supportUnlockVersionRange(): DeviceFirmwareRange {
|
|
1531
1725
|
// This range applies to Protocol V1 Pro devices; Pro2 has a dedicated unlock flow.
|
|
1532
1726
|
return {
|
|
@@ -1536,10 +1730,33 @@ export class Device extends EventEmitter {
|
|
|
1536
1730
|
};
|
|
1537
1731
|
}
|
|
1538
1732
|
|
|
1539
|
-
async unlockDevice(
|
|
1733
|
+
async unlockDevice(
|
|
1734
|
+
pinType?: DeviceSessionPinType,
|
|
1735
|
+
options?: ProtocolV2UiEventMetadata & { emitUiEvent?: boolean }
|
|
1736
|
+
) {
|
|
1540
1737
|
if (this.isProtocolV2()) {
|
|
1738
|
+
const requestedPinType = pinType ?? DeviceSessionPinType.Main;
|
|
1739
|
+
const interaction =
|
|
1740
|
+
options?.interaction ??
|
|
1741
|
+
(options?.emitUiEvent === false
|
|
1742
|
+
? undefined
|
|
1743
|
+
: this.createProtocolV2UiPhaseMetadata('pin', 'start'));
|
|
1744
|
+
if (options?.emitUiEvent !== false) {
|
|
1745
|
+
this.emit(DEVICE.PIN_ON_DEVICE, this, requestedPinType, {
|
|
1746
|
+
source: options?.source ?? 'unlock-coordinator',
|
|
1747
|
+
reason: options?.reason ?? 'device-unlock',
|
|
1748
|
+
deviceOnly: options?.deviceOnly ?? true,
|
|
1749
|
+
completion: options?.completion,
|
|
1750
|
+
method: options?.method,
|
|
1751
|
+
page: options?.page,
|
|
1752
|
+
operation: options?.operation,
|
|
1753
|
+
interaction: options?.interaction ?? interaction,
|
|
1754
|
+
});
|
|
1755
|
+
}
|
|
1541
1756
|
try {
|
|
1542
|
-
await this.commands.typedCall('DeviceSessionAskPin', 'Success', {
|
|
1757
|
+
await this.commands.typedCall('DeviceSessionAskPin', 'Success', {
|
|
1758
|
+
type: requestedPinType,
|
|
1759
|
+
});
|
|
1543
1760
|
} catch (error) {
|
|
1544
1761
|
const errorText =
|
|
1545
1762
|
error instanceof Error
|
|
@@ -1551,6 +1768,11 @@ export class Device extends EventEmitter {
|
|
|
1551
1768
|
throw error;
|
|
1552
1769
|
}
|
|
1553
1770
|
|
|
1771
|
+
const completion = interaction ? this.completeProtocolV2UiPhase(interaction) : undefined;
|
|
1772
|
+
if (completion) {
|
|
1773
|
+
this.emit(DEVICE.PIN_ON_DEVICE_COMPLETE, this, completion);
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1554
1776
|
const status = await requestProtocolV2DeviceStatus({ commands: this.commands });
|
|
1555
1777
|
return this.updateProtocolV2Status(status);
|
|
1556
1778
|
}
|
|
@@ -1612,7 +1834,8 @@ export class Device extends EventEmitter {
|
|
|
1612
1834
|
async checkPassphraseStateSafety(
|
|
1613
1835
|
passphraseState?: string,
|
|
1614
1836
|
useEmptyPassphrase?: boolean,
|
|
1615
|
-
skipPassphraseCheck?: boolean
|
|
1837
|
+
skipPassphraseCheck?: boolean,
|
|
1838
|
+
deriveCardano?: boolean
|
|
1616
1839
|
) {
|
|
1617
1840
|
if (this.isUnacquired()) return false;
|
|
1618
1841
|
|
|
@@ -1621,6 +1844,8 @@ export class Device extends EventEmitter {
|
|
|
1621
1844
|
await getPassphraseStateWithRefreshDeviceInfo(this, {
|
|
1622
1845
|
expectPassphraseState: expectedPassphraseState,
|
|
1623
1846
|
onlyMainPin: useEmptyPassphrase,
|
|
1847
|
+
deriveCardano,
|
|
1848
|
+
rejectAttachPinForMainWallet: useEmptyPassphrase === true,
|
|
1624
1849
|
});
|
|
1625
1850
|
|
|
1626
1851
|
// Main wallet and unlock Attach Pin, throw safe error
|
|
@@ -54,9 +54,19 @@ const DEVICE_SESSION_CALLS = new Set([
|
|
|
54
54
|
'DeviceSessionAskPin',
|
|
55
55
|
'DeviceSessionAskPassphrase',
|
|
56
56
|
]);
|
|
57
|
+
const DEVICE_CONTROL_CALLS = new Set([
|
|
58
|
+
'DeviceReboot',
|
|
59
|
+
'DeviceSettingsGet',
|
|
60
|
+
'DeviceSettingsSet',
|
|
61
|
+
'DeviceSettingsPageShow',
|
|
62
|
+
'DeviceCertificateWrite',
|
|
63
|
+
'DeviceCertificateRead',
|
|
64
|
+
'DeviceCertificateSign',
|
|
65
|
+
'DeviceMiscUsbMscControl',
|
|
66
|
+
]);
|
|
57
67
|
|
|
58
|
-
// Protocol V2
|
|
59
|
-
//
|
|
68
|
+
// Older Protocol V2 firmware may omit the cancellation subcode, so retain a
|
|
69
|
+
// narrow message fallback for compatibility.
|
|
60
70
|
const isProtocolV2ActionCancelledMessage = (message: string) =>
|
|
61
71
|
/^(?:cancel(?:led|ed)(?: on device)?|confirm dismissed|user cancel(?:led|ed)(?:\s+.*)?)$/i.test(
|
|
62
72
|
message
|
|
@@ -435,7 +445,13 @@ export class DeviceCommands {
|
|
|
435
445
|
if (!shouldReduceDebugForCall(callType)) {
|
|
436
446
|
Log.debug('_filterCommonTypes: ', {
|
|
437
447
|
request: callType,
|
|
438
|
-
response:
|
|
448
|
+
response:
|
|
449
|
+
callType === 'DeviceFirmwareUpdateStatusGet'
|
|
450
|
+
? {
|
|
451
|
+
type: res.type,
|
|
452
|
+
message: getSafeTransportLogPayload(res.message, res.type),
|
|
453
|
+
}
|
|
454
|
+
: res.type,
|
|
439
455
|
});
|
|
440
456
|
}
|
|
441
457
|
} catch (error) {
|
|
@@ -493,6 +509,10 @@ export class DeviceCommands {
|
|
|
493
509
|
const normalizedMessage = message?.trim() ?? '';
|
|
494
510
|
const isProtocolV2ActionCancelledFailure =
|
|
495
511
|
this.device.isProtocolV2() && isProtocolV2ActionCancelledMessage(normalizedMessage);
|
|
512
|
+
const isProtocolV2DeviceBusyFailure =
|
|
513
|
+
this.device.isProtocolV2() &&
|
|
514
|
+
DEVICE_CONTROL_CALLS.has(callType) &&
|
|
515
|
+
subcode === DeviceErrorCode.DeviceError_Busy;
|
|
496
516
|
const isLegacyProtocolV2LockedFailure =
|
|
497
517
|
this.device.isProtocolV2() && /^device (?:is )?locked$/i.test(normalizedMessage);
|
|
498
518
|
if (
|
|
@@ -550,8 +570,15 @@ export class DeviceCommands {
|
|
|
550
570
|
subcode,
|
|
551
571
|
firmwareMessage: message,
|
|
552
572
|
});
|
|
573
|
+
} else if (isProtocolV2DeviceBusyFailure) {
|
|
574
|
+
error = ERRORS.TypedError(HardwareErrorCode.DeviceBusy, message, {
|
|
575
|
+
failureCode: code,
|
|
576
|
+
subcode,
|
|
577
|
+
firmwareMessage: message,
|
|
578
|
+
});
|
|
553
579
|
} else if (
|
|
554
|
-
|
|
580
|
+
(DEVICE_CONTROL_CALLS.has(callType) &&
|
|
581
|
+
subcode === DeviceErrorCode.DeviceError_ActionCancelled) ||
|
|
555
582
|
isProtocolV2ActionCancelledFailure
|
|
556
583
|
) {
|
|
557
584
|
error = ERRORS.TypedError(HardwareErrorCode.ActionCancelled, message, {
|