@onekeyfe/hd-core 1.2.0-alpha.101 → 1.2.0-alpha.103
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__/base64Data.test.ts +70 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +2 -0
- package/__tests__/device-pool-state.test.ts +29 -0
- package/__tests__/deviceUploadNft.test.ts +33 -4
- package/__tests__/get-device-state.test.ts +102 -13
- package/__tests__/protocol-v2-legacy-recovery.test.ts +29 -0
- package/__tests__/protocol-v2.test.ts +309 -17
- package/__tests__/refresh-device-state.test.ts +4 -1
- package/__tests__/resourceBase64Boundary.test.ts +48 -0
- package/__tests__/search-devices.test.ts +2 -0
- package/__tests__/ton-sign-message.test.ts +84 -0
- package/dist/api/FirmwareUpdateV4.d.ts +3 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetDeviceState.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts +1 -1
- package/dist/api/UploadPortfolio.d.ts.map +1 -1
- package/dist/api/firmware/protocolV2Release.d.ts.map +1 -1
- package/dist/api/helpers/base64Data.d.ts +16 -0
- package/dist/api/helpers/base64Data.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +2 -3
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +2 -3
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/protocolV2LegacyRecovery.d.ts +5 -0
- package/dist/core/protocolV2LegacyRecovery.d.ts.map +1 -0
- package/dist/device/Device.d.ts +9 -2
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DevicePool.d.ts +1 -1
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/index.d.ts +16 -14
- package/dist/index.js +266 -86
- package/dist/protocols/protocol-v2/features.d.ts +8 -0
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/index.d.ts +2 -2
- package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
- package/dist/types/api/getDeviceState.d.ts +1 -0
- package/dist/types/api/getDeviceState.d.ts.map +1 -1
- package/dist/types/api/protocolV2.d.ts +1 -1
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/utils/pro2Nft.d.ts +7 -0
- package/dist/utils/pro2Nft.d.ts.map +1 -1
- package/package.json +6 -4
- package/src/api/FirmwareUpdateV4.ts +70 -23
- package/src/api/GetDeviceState.ts +1 -0
- package/src/api/SearchDevices.ts +2 -0
- package/src/api/UploadPortfolio.ts +9 -2
- package/src/api/firmware/protocolV2Release.ts +1 -0
- package/src/api/helpers/base64Data.ts +85 -0
- package/src/api/protocol-v2/DeviceUploadNft.ts +56 -8
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +37 -18
- package/src/api/ton/TonSignMessage.ts +5 -3
- package/src/core/index.ts +4 -0
- package/src/core/protocolV2LegacyRecovery.ts +12 -0
- package/src/device/Device.ts +78 -20
- package/src/device/DevicePool.ts +17 -5
- package/src/protocols/protocol-v2/features.ts +10 -0
- package/src/protocols/protocol-v2/index.ts +2 -0
- package/src/types/api/getDeviceState.ts +2 -0
- package/src/types/api/protocolV2.ts +1 -1
- package/src/utils/pro2Nft.ts +31 -8
|
@@ -7,6 +7,14 @@ export type ProtocolV2SeStateLabel = 'BOOT' | 'APP_FACTORY' | 'APP';
|
|
|
7
7
|
export declare const getProtocolV2SeState: (se?: DeviceSEInfo) => ProtocolV2SeStateLabel | null;
|
|
8
8
|
export declare const getProtocolV2SeType: (se?: DeviceSEInfo) => string | null;
|
|
9
9
|
export type ProtocolV2RuntimeMode = 'normal' | 'bootloader' | 'romloader';
|
|
10
|
+
export type ProtocolV2ProtocolInfo = ProtocolInfo & {
|
|
11
|
+
protobuf_definition?: string | null;
|
|
12
|
+
};
|
|
13
|
+
export declare const isLegacyProtocolV2ProtocolInfo: (protocolInfo: ProtocolInfo) => protocolInfo is ProtocolInfo & {
|
|
14
|
+
protobuf_definition?: string | null | undefined;
|
|
15
|
+
} & {
|
|
16
|
+
protobuf_definition: string | null;
|
|
17
|
+
};
|
|
10
18
|
export type ProtocolV2BuildFingerprint = {
|
|
11
19
|
binary: 'application' | 'bootloader' | 'romloader';
|
|
12
20
|
version: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/features.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAGlE,YAAY,EAAE,oBAAoB,EAAE,CAAC;AACrC,YAAY,EAAE,uBAAuB,IAAI,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrG,YAAY,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,aAAa,GAAG,KAAK,CAAC;AAoBpE,eAAO,MAAM,oBAAoB,QAAS,YAAY,KAAG,sBAAsB,GAAG,IAYjF,CAAC;AAKF,eAAO,MAAM,mBAAmB,QAAS,YAAY,KAAG,MAAM,GAAG,IACrB,CAAC;AAE7C,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"features.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/features.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAGlE,YAAY,EAAE,oBAAoB,EAAE,CAAC;AACrC,YAAY,EAAE,uBAAuB,IAAI,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACrG,YAAY,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/E,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,aAAa,GAAG,KAAK,CAAC;AAoBpE,eAAO,MAAM,oBAAoB,QAAS,YAAY,KAAG,sBAAsB,GAAG,IAYjF,CAAC;AAKF,eAAO,MAAM,mBAAmB,QAAS,YAAY,KAAG,MAAM,GAAG,IACrB,CAAC;AAE7C,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1E,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG;IAElD,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,8BAA8B,iBAC3B,YAAY;;;yBACuC,MAAM,GAAG,IAAI;CACL,CAAC;AAM5E,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,aAAa,GAAG,YAAY,GAAG,WAAW,CAAC;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,KAAK,CAAC;IAC5B,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,+BAA+B,qBACxB,MAAM,GAAG,IAAI,GAAG,SAAS,KAC1C,0BAA0B,GAAG,IAc/B,CAAC;AAEF,eAAO,MAAM,wBAAwB,iBACrB,YAAY,KACzB,qBAAqB,GAAG,SAI1B,CAAC;AAGF,eAAO,MAAM,0CAA0C,QAAQ,CAAC;AAEhE,eAAO,MAAM,yBAAyB,iBACtB,YAAY,eACb,MAAM,KAClB,OAAgE,CAAC;AAEpE,eAAO,MAAM,wCAAwC;;;;;;;;;;CAUpD,CAAC;AAMF,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;CAcpD,CAAC;AAEF,eAAO,MAAM,oCAAoC;;;;;;;;;;;;;;;;CAgBhD,CAAC;AAEF,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;CAAuC,CAAC;AACpF,eAAO,MAAM,kCAAkC,QAAY,CAAC;AAE5D,wBAAsB,6BAA6B,CAAC,EAClD,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,YAAY,CAAC,CAaxB;AAED,wBAAsB,2BAA2B,CAAC,EAChD,QAAQ,EACR,SAA8C,EAC9C,OAAkD,GACnD,EAAE;IACD,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAMhC;AAED,wBAAsB,6BAA6B,CAAC,EAClD,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,cAAc,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,YAAY,CAAC,CAOxB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { PROTOCOL_V2_DEVICE_INFO_REQUEST, PROTOCOL_V2_DEVICE_INFO_TIMEOUT_MS, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE, PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST, PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST, getProtocolV2RuntimeMode, getProtocolV2SeState, getProtocolV2SeType, parseProtocolV2BuildFingerprint, requestProtocolV2ProtocolInfo, supportsProtocolV2Message, } from './features';
|
|
2
|
-
export type { ProtocolV2BuildFingerprint, ProtocolV2DeviceInfo, ProtocolV2FirmwareImageInfo, ProtocolV2SEInfo, ProtocolV2SeStateLabel, ProtocolV2RuntimeMode, } from './features';
|
|
1
|
+
export { PROTOCOL_V2_DEVICE_INFO_REQUEST, PROTOCOL_V2_DEVICE_INFO_TIMEOUT_MS, PROTOCOL_V2_DEVICE_STATUS_GET_MESSAGE_TYPE, PROTOCOL_V2_FEATURES_DEVICE_INFO_REQUEST, PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST, getProtocolV2RuntimeMode, getProtocolV2SeState, getProtocolV2SeType, isLegacyProtocolV2ProtocolInfo, parseProtocolV2BuildFingerprint, requestProtocolV2ProtocolInfo, supportsProtocolV2Message, } from './features';
|
|
2
|
+
export type { ProtocolV2BuildFingerprint, ProtocolV2DeviceInfo, ProtocolV2FirmwareImageInfo, ProtocolV2SEInfo, ProtocolV2SeStateLabel, ProtocolV2RuntimeMode, ProtocolV2ProtocolInfo, } from './features';
|
|
3
3
|
export * from './firmware';
|
|
4
4
|
export * from './walletSession';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,EAClC,0CAA0C,EAC1C,wCAAwC,EACxC,wCAAwC,EACxC,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,2BAA2B,EAC3B,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/protocols/protocol-v2/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,+BAA+B,EAC/B,kCAAkC,EAClC,0CAA0C,EAC1C,wCAAwC,EACxC,wCAAwC,EACxC,wBAAwB,EACxB,oBAAoB,EACpB,mBAAmB,EACnB,8BAA8B,EAC9B,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,GAC1B,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,0BAA0B,EAC1B,oBAAoB,EACpB,2BAA2B,EAC3B,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC"}
|
|
@@ -7,6 +7,7 @@ export type GetDeviceStateParams = CommonParams & {
|
|
|
7
7
|
export type DeviceStateReadOptions = {
|
|
8
8
|
refreshSections?: DeviceStateSection[];
|
|
9
9
|
includeRaw?: boolean;
|
|
10
|
+
allowLegacyProtocolV2ProtocolInfo?: boolean;
|
|
10
11
|
};
|
|
11
12
|
export declare function getDeviceState(connectId?: string, params?: GetDeviceStateParams): Response<DeviceState>;
|
|
12
13
|
//# sourceMappingURL=getDeviceState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getDeviceState.d.ts","sourceRoot":"","sources":["../../../src/types/api/getDeviceState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnE,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG;IAChD,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAGF,MAAM,MAAM,sBAAsB,GAAG;IACnC,eAAe,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"getDeviceState.d.ts","sourceRoot":"","sources":["../../../src/types/api/getDeviceState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEnE,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG;IAChD,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAGF,MAAM,MAAM,sBAAsB,GAAG;IACnC,eAAe,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,iCAAiC,CAAC,EAAE,OAAO,CAAC;CAC7C,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,oBAAoB,GAC5B,QAAQ,CAAC,WAAW,CAAC,CAAC"}
|
|
@@ -24,7 +24,7 @@ export declare function deviceGetOnboardingStatus(connectId: string, params?: Co
|
|
|
24
24
|
export declare function deviceUploadWallpaper(connectId: string, params: CommonParams & DeviceUploadWallpaperParams): Response<DeviceUploadWallpaperResponse>;
|
|
25
25
|
export declare function deviceUploadNft(connectId: string, params: CommonParams & DeviceUploadNftParams): Response<DeviceUploadNftResponse>;
|
|
26
26
|
export declare function uploadPortfolio(connectId: string, params: {
|
|
27
|
-
|
|
27
|
+
packageBase64: string;
|
|
28
28
|
timeoutMs?: number | string;
|
|
29
29
|
}): Response<FileInfo & {
|
|
30
30
|
portfolioUpdated: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocolV2.d.ts","sourceRoot":"","sources":["../../../src/types/api/protocolV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EACV,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,uCAAuC,CAAC;AAG/C,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACzF,YAAY,EACV,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,6CAA6C,CAAC;AACrD,YAAY,EACV,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uCAAuC,CAAC;AAI/C,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG;IAEpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,wBAAwB,GAChC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,kBAAkB,GACxC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAE9B,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAC3C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,2BAA2B,GACjD,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AAE3C,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,qBAAqB,GAC3C,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAErC,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IACN,
|
|
1
|
+
{"version":3,"file":"protocolV2.d.ts","sourceRoot":"","sources":["../../../src/types/api/protocolV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EACV,2BAA2B,EAC3B,6BAA6B,EAC9B,MAAM,6CAA6C,CAAC;AACrD,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACxB,MAAM,uCAAuC,CAAC;AAG/C,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACzF,YAAY,EACV,2BAA2B,EAC3B,6BAA6B,GAC9B,MAAM,6CAA6C,CAAC;AACrD,YAAY,EACV,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,uCAAuC,CAAC;AAI/C,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG;IAEpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,kBAAkB,CACxC,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,wBAAwB,GAChC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,YAAY,CAClC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,kBAAkB,GACxC,QAAQ,CAAC,OAAO,CAAC,CAAC;AAErB,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAE9B,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAC3C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,2BAA2B,GACjD,QAAQ,CAAC,6BAA6B,CAAC,CAAC;AAE3C,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,qBAAqB,GAC3C,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAErC,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IACN,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B,GACA,QAAQ,CAAC,QAAQ,GAAG;IAAE,gBAAgB,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC"}
|
package/dist/utils/pro2Nft.d.ts
CHANGED
|
@@ -28,4 +28,11 @@ export declare function buildPro2NftBundle(options: {
|
|
|
28
28
|
subtitle: string;
|
|
29
29
|
timestampMs: number;
|
|
30
30
|
}): Pro2NftBundle;
|
|
31
|
+
export declare function buildPro2NftBundleFromEncodedImages(options: {
|
|
32
|
+
image: Uint8Array;
|
|
33
|
+
thumbnail: Uint8Array;
|
|
34
|
+
title: string;
|
|
35
|
+
subtitle: string;
|
|
36
|
+
timestampMs: number;
|
|
37
|
+
}): Pro2NftBundle;
|
|
31
38
|
//# sourceMappingURL=pro2Nft.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pro2Nft.d.ts","sourceRoot":"","sources":["../../src/utils/pro2Nft.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAClD,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAiCF,wBAAgB,2BAA2B,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB5E;AAsBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"pro2Nft.d.ts","sourceRoot":"","sources":["../../src/utils/pro2Nft.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,kBAAkB,cAAc,CAAC;AAC9C,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAC1C,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAClD,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAC5C,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAiCF,wBAAgB,2BAA2B,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAiB5E;AAsBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,KAAK,EAAE,YAAY,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,aAAa,CAgBhB;AAED,wBAAgB,mCAAmC,CAAC,OAAO,EAAE;IAC3D,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,UAAU,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,aAAa,CAiChB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.103",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,11 +25,13 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.103",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.103",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
|
+
"buffer": "^6.0.3",
|
|
32
33
|
"bytebuffer": "^5.0.1",
|
|
34
|
+
"jpeg-js": "^0.4.4",
|
|
33
35
|
"jszip": "^3.10.1",
|
|
34
36
|
"parse-uri": "^1.0.7",
|
|
35
37
|
"semver": "^7.3.7"
|
|
@@ -44,5 +46,5 @@
|
|
|
44
46
|
"@types/w3c-web-usb": "^1.0.10",
|
|
45
47
|
"@types/web-bluetooth": "^0.0.21"
|
|
46
48
|
},
|
|
47
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "ba7c3866269200b25a514202b8286d0c9e9105d3"
|
|
48
50
|
}
|
|
@@ -28,6 +28,7 @@ import { DevicePool } from '../device/DevicePool';
|
|
|
28
28
|
import {
|
|
29
29
|
PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
|
|
30
30
|
ProtocolV2FirmwareTargetType,
|
|
31
|
+
isLegacyProtocolV2ProtocolInfo,
|
|
31
32
|
} from '../protocols/protocol-v2';
|
|
32
33
|
import { requestProtocolV2DeviceInfo } from '../protocols/protocol-v2/features';
|
|
33
34
|
import {
|
|
@@ -393,6 +394,13 @@ const isProtocolV2FirmwareStatusEndpointUnavailable = (error: unknown) => {
|
|
|
393
394
|
);
|
|
394
395
|
};
|
|
395
396
|
|
|
397
|
+
const isProtocolV2FirmwareUpdateEndpointUnavailable = (error: unknown) => {
|
|
398
|
+
const message = getProtocolV2UnknownErrorText(error).toLowerCase();
|
|
399
|
+
return (
|
|
400
|
+
message.includes('handler not registered') || message.includes('message handler not found')
|
|
401
|
+
);
|
|
402
|
+
};
|
|
403
|
+
|
|
396
404
|
const isProtocolV2TerminalInstallStatusError = (error: unknown) =>
|
|
397
405
|
error instanceof HardwareError &&
|
|
398
406
|
(error.errorCode === HardwareErrorCode.FirmwareError ||
|
|
@@ -587,6 +595,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
587
595
|
|
|
588
596
|
private protocolV2ExecutionInLoader = false;
|
|
589
597
|
|
|
598
|
+
private protocolV2LegacyDirectUpdate = false;
|
|
599
|
+
|
|
590
600
|
private protocolV2BootResourceStagingSafe = false;
|
|
591
601
|
|
|
592
602
|
private protocolV2CompletedTargetVersions = new Map<number, number>();
|
|
@@ -2067,21 +2077,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2067
2077
|
return this.device.features?.mode === 'romloader';
|
|
2068
2078
|
}
|
|
2069
2079
|
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
Log.debug('Protocol V2 device is in romloader mode; start firmware update directly');
|
|
2075
|
-
this.protocolV2ExecutionInLoader = true;
|
|
2076
|
-
return false;
|
|
2077
|
-
}
|
|
2078
|
-
if (this.isProtocolV2BootloaderMode()) {
|
|
2079
|
-
Log.debug('Protocol V2 device is already in bootloader mode, skip reboot');
|
|
2080
|
-
this.protocolV2ExecutionInLoader = true;
|
|
2081
|
-
this.postTipMessage(FirmwareUpdateTipMessage.GoToBootloaderSuccess);
|
|
2082
|
-
return false;
|
|
2083
|
-
}
|
|
2080
|
+
private isLegacyProtocolV2Runtime() {
|
|
2081
|
+
const protocolInfo = this.device.state?.raw?.protocolV2ProtocolInfo;
|
|
2082
|
+
return protocolInfo ? isLegacyProtocolV2ProtocolInfo(protocolInfo) : false;
|
|
2083
|
+
}
|
|
2084
2084
|
|
|
2085
|
+
private async rebootProtocolV2ToBootloader() {
|
|
2085
2086
|
try {
|
|
2086
2087
|
this.postTipMessage(FirmwareUpdateTipMessage.AutoRebootToBootloader);
|
|
2087
2088
|
await this.protocolV2Reboot(DeviceRebootType.Bootloader);
|
|
@@ -2099,6 +2100,27 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2099
2100
|
}
|
|
2100
2101
|
}
|
|
2101
2102
|
|
|
2103
|
+
async enterProtocolV2BootloaderMode() {
|
|
2104
|
+
this.protocolV2LegacyDirectUpdate = false;
|
|
2105
|
+
// romloader is the first update environment and forwards targets to bootloader.
|
|
2106
|
+
// It rejects DeviceRebootType.Bootloader, so reuse the current connection.
|
|
2107
|
+
if (this.isProtocolV2RomloaderMode()) {
|
|
2108
|
+
Log.debug('Protocol V2 device is in romloader mode; start firmware update directly');
|
|
2109
|
+
this.protocolV2LegacyDirectUpdate = this.isLegacyProtocolV2Runtime();
|
|
2110
|
+
this.protocolV2ExecutionInLoader = true;
|
|
2111
|
+
return false;
|
|
2112
|
+
}
|
|
2113
|
+
if (this.isProtocolV2BootloaderMode()) {
|
|
2114
|
+
Log.debug('Protocol V2 device is already in bootloader mode, skip reboot');
|
|
2115
|
+
this.protocolV2LegacyDirectUpdate = this.isLegacyProtocolV2Runtime();
|
|
2116
|
+
this.protocolV2ExecutionInLoader = true;
|
|
2117
|
+
this.postTipMessage(FirmwareUpdateTipMessage.GoToBootloaderSuccess);
|
|
2118
|
+
return false;
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2121
|
+
return this.rebootProtocolV2ToBootloader();
|
|
2122
|
+
}
|
|
2123
|
+
|
|
2102
2124
|
private async waitForProtocolV2BootloaderMode(
|
|
2103
2125
|
timeout = PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT,
|
|
2104
2126
|
retryInterval = 1000
|
|
@@ -2120,7 +2142,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2120
2142
|
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
2121
2143
|
const features = await this.device.probeProtocolV2RuntimeState(
|
|
2122
2144
|
deviceInfo,
|
|
2123
|
-
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
2145
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
2146
|
+
{ allowLegacyProtocolV2ProtocolInfo: true }
|
|
2124
2147
|
);
|
|
2125
2148
|
if (features?.mode === 'bootloader') {
|
|
2126
2149
|
return features;
|
|
@@ -2809,7 +2832,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2809
2832
|
private async probeProtocolV2NormalMode(deviceInfo: ProtocolV2DeviceInfo) {
|
|
2810
2833
|
const features = await this.device.probeProtocolV2RuntimeState(
|
|
2811
2834
|
deviceInfo,
|
|
2812
|
-
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
2835
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
2836
|
+
{ allowLegacyProtocolV2ProtocolInfo: true }
|
|
2813
2837
|
);
|
|
2814
2838
|
return features.mode === 'normal' && !features.bootloaderMode;
|
|
2815
2839
|
}
|
|
@@ -2871,7 +2895,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2871
2895
|
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
2872
2896
|
const features = await this.device.probeProtocolV2RuntimeState(
|
|
2873
2897
|
deviceInfo,
|
|
2874
|
-
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
2898
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
2899
|
+
{ allowLegacyProtocolV2ProtocolInfo: true }
|
|
2875
2900
|
);
|
|
2876
2901
|
if (features.mode === 'normal' && !features.bootloaderMode) {
|
|
2877
2902
|
return features;
|
|
@@ -3044,12 +3069,34 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3044
3069
|
targets: Array<{ target_id: number; path: string }>;
|
|
3045
3070
|
}) {
|
|
3046
3071
|
const commands = this.device.getCommands();
|
|
3047
|
-
const
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3072
|
+
const startUpdate = () =>
|
|
3073
|
+
commands.typedCall(
|
|
3074
|
+
'DeviceFirmwareUpdateRequest',
|
|
3075
|
+
'Success',
|
|
3076
|
+
{ targets },
|
|
3077
|
+
{ timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT }
|
|
3078
|
+
);
|
|
3079
|
+
let response: ProtocolV2FirmwareUpdateStartResponse;
|
|
3080
|
+
try {
|
|
3081
|
+
response = await startUpdate();
|
|
3082
|
+
} catch (error) {
|
|
3083
|
+
if (
|
|
3084
|
+
!this.protocolV2LegacyDirectUpdate ||
|
|
3085
|
+
!isProtocolV2FirmwareUpdateEndpointUnavailable(error)
|
|
3086
|
+
) {
|
|
3087
|
+
throw error;
|
|
3088
|
+
}
|
|
3089
|
+
|
|
3090
|
+
// Both legacy loaders register this request. A missing handler therefore identifies
|
|
3091
|
+
// a legacy App before dispatch, so it is safe to reboot and retry the unhandled request.
|
|
3092
|
+
this.protocolV2LegacyDirectUpdate = false;
|
|
3093
|
+
Log.debug(
|
|
3094
|
+
'[FirmwareUpdateV4] legacy App does not expose DeviceFirmwareUpdateRequest; rebooting to bootloader'
|
|
3095
|
+
);
|
|
3096
|
+
await this.rebootProtocolV2ToBootloader();
|
|
3097
|
+
response = await startUpdate();
|
|
3098
|
+
}
|
|
3099
|
+
this.protocolV2LegacyDirectUpdate = false;
|
|
3053
3100
|
// Success acknowledges that the device accepted installation. End confirmation
|
|
3054
3101
|
// and begin status polling only after receiving this ACK.
|
|
3055
3102
|
this.postTipMessage(FirmwareUpdateTipMessage.FirmwareUpdating);
|
|
@@ -43,6 +43,7 @@ export default class GetDeviceState extends BaseMethod<
|
|
|
43
43
|
async run() {
|
|
44
44
|
const state = await this.device.getDeviceState({
|
|
45
45
|
refreshSections: SCOPE_SECTIONS[this.params.scope],
|
|
46
|
+
...(this.params.scope === 'firmware' ? { allowLegacyProtocolV2ProtocolInfo: true } : {}),
|
|
46
47
|
});
|
|
47
48
|
if (
|
|
48
49
|
this.params.scope === 'settings' &&
|
package/src/api/SearchDevices.ts
CHANGED
|
@@ -63,6 +63,8 @@ export default class SearchDevices extends BaseMethod {
|
|
|
63
63
|
connectProtocol: undefined,
|
|
64
64
|
forceProtocolDetection: true,
|
|
65
65
|
refreshRuntimeState: true,
|
|
66
|
+
// Old loader firmware predates build_fingerprint. Keep this recovery-only.
|
|
67
|
+
allowLegacyProtocolV2ProtocolInfo: true,
|
|
66
68
|
});
|
|
67
69
|
deviceList.push(...result.deviceList);
|
|
68
70
|
} catch (error) {
|
|
@@ -1,21 +1,28 @@
|
|
|
1
1
|
import { createDeviceNotSupportMethodError } from '@onekeyfe/hd-shared';
|
|
2
2
|
|
|
3
3
|
import { supportsProtocolV2Message } from '../protocols/protocol-v2/features';
|
|
4
|
+
import { decodeCanonicalBase64 } from './helpers/base64Data';
|
|
4
5
|
import FileWrite from './FileWrite';
|
|
5
6
|
|
|
6
7
|
export type UploadPortfolioParams = {
|
|
7
|
-
|
|
8
|
+
packageBase64: string;
|
|
8
9
|
timeoutMs?: number | string;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
const PORTFOLIO_PENDING_PATH = 'vol1:/portfolio/portfolio.okpkg.pending';
|
|
12
13
|
const PORTFOLIO_CHUNK_SIZE = 2048;
|
|
14
|
+
const PORTFOLIO_PACKAGE_MAX_BYTES = 128 * 1024;
|
|
13
15
|
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
14
16
|
const PORTFOLIO_UPDATE_MESSAGE_TYPE = 61400;
|
|
15
17
|
|
|
16
18
|
export default class UploadPortfolio extends FileWrite {
|
|
17
19
|
init() {
|
|
18
|
-
const {
|
|
20
|
+
const { packageBase64, timeoutMs } = this.payload as UploadPortfolioParams;
|
|
21
|
+
const packageBytes = decodeCanonicalBase64({
|
|
22
|
+
value: packageBase64,
|
|
23
|
+
parameterName: 'packageBase64',
|
|
24
|
+
maxBytes: PORTFOLIO_PACKAGE_MAX_BYTES,
|
|
25
|
+
});
|
|
19
26
|
this.payload = {
|
|
20
27
|
...this.payload,
|
|
21
28
|
path: PORTFOLIO_PENDING_PATH,
|
|
@@ -60,6 +60,7 @@ export async function loadProtocolV2FirmwareReleaseContext({
|
|
|
60
60
|
refreshSections: checkFirmwareHash
|
|
61
61
|
? ['identity', 'versions', 'verification']
|
|
62
62
|
: ['identity', 'versions'],
|
|
63
|
+
allowLegacyProtocolV2ProtocolInfo: true,
|
|
63
64
|
});
|
|
64
65
|
if (state.identity.deviceType !== 'pro2' && state.identity.deviceType !== 'neo') {
|
|
65
66
|
throw ERRORS.TypedError(
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { decode as decodeJpeg } from 'jpeg-js';
|
|
3
|
+
|
|
4
|
+
import { invalidParameter } from './filesystemValidation';
|
|
5
|
+
|
|
6
|
+
const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
7
|
+
const JPEG_CONTAINER_OVERHEAD_BYTES = 64 * 1024;
|
|
8
|
+
const JPEG_MAX_MEMORY_USAGE_IN_MB = 32;
|
|
9
|
+
const JPEG_MAX_RESOLUTION_IN_MP = 1;
|
|
10
|
+
|
|
11
|
+
export function decodeCanonicalBase64({
|
|
12
|
+
value,
|
|
13
|
+
parameterName,
|
|
14
|
+
maxBytes,
|
|
15
|
+
}: {
|
|
16
|
+
value: unknown;
|
|
17
|
+
parameterName: string;
|
|
18
|
+
maxBytes: number;
|
|
19
|
+
}): Uint8Array {
|
|
20
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
21
|
+
throw invalidParameter(`Parameter [${parameterName}] must be a non-empty Base64 string.`);
|
|
22
|
+
}
|
|
23
|
+
if (value.length > Math.ceil(maxBytes / 3) * 4) {
|
|
24
|
+
throw invalidParameter(`Parameter [${parameterName}] exceeds the maximum supported size.`);
|
|
25
|
+
}
|
|
26
|
+
if (value.length % 4 !== 0 || !BASE64_PATTERN.test(value)) {
|
|
27
|
+
throw invalidParameter(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const decoded = Buffer.from(value, 'base64');
|
|
31
|
+
if (decoded.byteLength === 0 || decoded.byteLength > maxBytes) {
|
|
32
|
+
throw invalidParameter(`Parameter [${parameterName}] exceeds the maximum supported size.`);
|
|
33
|
+
}
|
|
34
|
+
if (decoded.toString('base64') !== value) {
|
|
35
|
+
throw invalidParameter(`Parameter [${parameterName}] must use canonical Base64 encoding.`);
|
|
36
|
+
}
|
|
37
|
+
return Uint8Array.from(decoded);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function decodeJpegBase64ToRgba({
|
|
41
|
+
jpegBase64,
|
|
42
|
+
parameterName,
|
|
43
|
+
expectedWidth,
|
|
44
|
+
expectedHeight,
|
|
45
|
+
}: {
|
|
46
|
+
jpegBase64: unknown;
|
|
47
|
+
parameterName: string;
|
|
48
|
+
expectedWidth: number;
|
|
49
|
+
expectedHeight: number;
|
|
50
|
+
}): { width: number; height: number; data: Uint8Array } {
|
|
51
|
+
const jpegBytes = decodeCanonicalBase64({
|
|
52
|
+
value: jpegBase64,
|
|
53
|
+
parameterName,
|
|
54
|
+
maxBytes: expectedWidth * expectedHeight * 8 + JPEG_CONTAINER_OVERHEAD_BYTES,
|
|
55
|
+
});
|
|
56
|
+
if (jpegBytes[0] !== 0xff || jpegBytes[1] !== 0xd8) {
|
|
57
|
+
throw invalidParameter(`Parameter [${parameterName}] must contain a JPEG image.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let decoded: { width: number; height: number; data: Uint8Array };
|
|
61
|
+
try {
|
|
62
|
+
decoded = decodeJpeg(jpegBytes, {
|
|
63
|
+
useTArray: true,
|
|
64
|
+
formatAsRGBA: true,
|
|
65
|
+
tolerantDecoding: false,
|
|
66
|
+
maxResolutionInMP: JPEG_MAX_RESOLUTION_IN_MP,
|
|
67
|
+
maxMemoryUsageInMB: JPEG_MAX_MEMORY_USAGE_IN_MB,
|
|
68
|
+
});
|
|
69
|
+
} catch {
|
|
70
|
+
throw invalidParameter(`Parameter [${parameterName}] must contain a valid JPEG image.`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (decoded.width !== expectedWidth || decoded.height !== expectedHeight) {
|
|
74
|
+
throw invalidParameter(
|
|
75
|
+
`Parameter [${parameterName}] must contain a ${expectedWidth}x${expectedHeight} JPEG image.`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const expectedLength = expectedWidth * expectedHeight * 4;
|
|
79
|
+
if (decoded.data.byteLength !== expectedLength) {
|
|
80
|
+
throw invalidParameter(
|
|
81
|
+
`Decoded parameter [${parameterName}] must contain ${expectedLength} RGBA bytes.`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
return decoded;
|
|
85
|
+
}
|
|
@@ -7,21 +7,26 @@ import {
|
|
|
7
7
|
PRO2_NFT_DEFAULT_PACE_MS,
|
|
8
8
|
PRO2_NFT_DEFAULT_TIMEOUT_MS,
|
|
9
9
|
PRO2_NFT_DIRECTORY,
|
|
10
|
+
PRO2_NFT_IMAGE_HEIGHT,
|
|
11
|
+
PRO2_NFT_IMAGE_WIDTH,
|
|
10
12
|
PRO2_NFT_MAX_CHUNK_SIZE,
|
|
11
13
|
PRO2_NFT_MAX_ITEMS,
|
|
12
14
|
PRO2_NFT_MIN_CHUNK_SIZE,
|
|
15
|
+
PRO2_NFT_THUMBNAIL_HEIGHT,
|
|
16
|
+
PRO2_NFT_THUMBNAIL_WIDTH,
|
|
13
17
|
type Pro2NftBundle,
|
|
14
|
-
|
|
15
|
-
buildPro2NftBundle,
|
|
18
|
+
buildPro2NftBundleFromEncodedImages,
|
|
16
19
|
getCompletePro2NftBasenames,
|
|
17
20
|
} from '../../utils/pro2Nft';
|
|
21
|
+
import { encodePro2Image } from '../../utils/pro2Wallpaper';
|
|
18
22
|
import { BaseMethod } from '../BaseMethod';
|
|
23
|
+
import { decodeJpegBase64ToRgba } from '../helpers/base64Data';
|
|
19
24
|
import { invalidParameter } from '../helpers/filesystemValidation';
|
|
20
25
|
import { writeProtocolV2File } from '../helpers/protocolV2FileWrite';
|
|
21
26
|
|
|
22
27
|
export type DeviceUploadNftParams = {
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
imageJpegBase64: string;
|
|
29
|
+
thumbnailJpegBase64: string;
|
|
25
30
|
title: string;
|
|
26
31
|
subtitle: string;
|
|
27
32
|
timestampMs?: number;
|
|
@@ -54,8 +59,8 @@ export default class DeviceUploadNft extends BaseMethod<DeviceUploadNftParams> {
|
|
|
54
59
|
|
|
55
60
|
init() {
|
|
56
61
|
const {
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
imageJpegBase64,
|
|
63
|
+
thumbnailJpegBase64,
|
|
59
64
|
title,
|
|
60
65
|
subtitle,
|
|
61
66
|
timestampMs = Date.now(),
|
|
@@ -79,8 +84,51 @@ export default class DeviceUploadNft extends BaseMethod<DeviceUploadNftParams> {
|
|
|
79
84
|
throw invalidParameter('Parameter [timeoutMs] must be a positive integer.');
|
|
80
85
|
}
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
const encodedImage = (() => {
|
|
88
|
+
const decoded = decodeJpegBase64ToRgba({
|
|
89
|
+
jpegBase64: imageJpegBase64,
|
|
90
|
+
parameterName: 'imageJpegBase64',
|
|
91
|
+
expectedWidth: PRO2_NFT_IMAGE_WIDTH,
|
|
92
|
+
expectedHeight: PRO2_NFT_IMAGE_HEIGHT,
|
|
93
|
+
});
|
|
94
|
+
return encodePro2Image({
|
|
95
|
+
width: PRO2_NFT_IMAGE_WIDTH,
|
|
96
|
+
height: PRO2_NFT_IMAGE_HEIGHT,
|
|
97
|
+
rgba: decoded.data,
|
|
98
|
+
alphaMode: 'black-background',
|
|
99
|
+
}).data;
|
|
100
|
+
})();
|
|
101
|
+
const encodedThumbnail = (() => {
|
|
102
|
+
const decoded = decodeJpegBase64ToRgba({
|
|
103
|
+
jpegBase64: thumbnailJpegBase64,
|
|
104
|
+
parameterName: 'thumbnailJpegBase64',
|
|
105
|
+
expectedWidth: PRO2_NFT_THUMBNAIL_WIDTH,
|
|
106
|
+
expectedHeight: PRO2_NFT_THUMBNAIL_HEIGHT,
|
|
107
|
+
});
|
|
108
|
+
return encodePro2Image({
|
|
109
|
+
width: PRO2_NFT_THUMBNAIL_WIDTH,
|
|
110
|
+
height: PRO2_NFT_THUMBNAIL_HEIGHT,
|
|
111
|
+
rgba: decoded.data,
|
|
112
|
+
alphaMode: 'black-background',
|
|
113
|
+
}).data;
|
|
114
|
+
})();
|
|
115
|
+
this.bundle = buildPro2NftBundleFromEncodedImages({
|
|
116
|
+
image: encodedImage,
|
|
117
|
+
thumbnail: encodedThumbnail,
|
|
118
|
+
title,
|
|
119
|
+
subtitle,
|
|
120
|
+
timestampMs,
|
|
121
|
+
});
|
|
122
|
+
this.params = {
|
|
123
|
+
imageJpegBase64,
|
|
124
|
+
thumbnailJpegBase64,
|
|
125
|
+
title,
|
|
126
|
+
subtitle,
|
|
127
|
+
timestampMs,
|
|
128
|
+
chunkSize,
|
|
129
|
+
paceMs,
|
|
130
|
+
timeoutMs,
|
|
131
|
+
};
|
|
84
132
|
this.unlockPolicy = 'none';
|
|
85
133
|
this.skipForceUpdateCheck = true;
|
|
86
134
|
this.useDevicePassphraseState = false;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { blake2s } from '@noble/hashes/blake2s';
|
|
2
2
|
import { bytesToHex } from '@noble/hashes/utils';
|
|
3
|
+
import { createDeviceNotSupportMethodError } from '@onekeyfe/hd-shared';
|
|
3
4
|
|
|
4
5
|
import { BaseMethod } from '../BaseMethod';
|
|
6
|
+
import { decodeJpegBase64ToRgba } from '../helpers/base64Data';
|
|
5
7
|
import { invalidParameter } from '../helpers/filesystemValidation';
|
|
6
8
|
import { writeProtocolV2File } from '../helpers/protocolV2FileWrite';
|
|
7
9
|
import { UI_REQUEST, createUiMessage } from '../../events/ui-request';
|
|
10
|
+
import { supportsProtocolV2Message } from '../../protocols/protocol-v2/features';
|
|
8
11
|
import {
|
|
9
12
|
PRO2_WALLPAPER_HEIGHT,
|
|
10
13
|
PRO2_WALLPAPER_WIDTH,
|
|
@@ -13,9 +16,7 @@ import {
|
|
|
13
16
|
} from '../../utils/pro2Wallpaper';
|
|
14
17
|
|
|
15
18
|
export type DeviceUploadWallpaperParams = {
|
|
16
|
-
|
|
17
|
-
height: number;
|
|
18
|
-
rgba: Uint8Array | ArrayBuffer;
|
|
19
|
+
jpegBase64: string;
|
|
19
20
|
fileName?: string;
|
|
20
21
|
chunkSize?: number;
|
|
21
22
|
};
|
|
@@ -29,6 +30,9 @@ export type DeviceUploadWallpaperResponse = {
|
|
|
29
30
|
|
|
30
31
|
const WALLPAPER_DIRECTORY = 'vol1:/wallpapers';
|
|
31
32
|
const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
|
|
33
|
+
const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
|
|
34
|
+
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
35
|
+
const FILESYSTEM_DIR_MAKE_MESSAGE_TYPE = 60809;
|
|
32
36
|
|
|
33
37
|
function normalizeFileName(fileName: string | undefined, data: Uint8Array): string {
|
|
34
38
|
if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
|
|
@@ -54,31 +58,45 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
54
58
|
private path = '';
|
|
55
59
|
|
|
56
60
|
init() {
|
|
57
|
-
const {
|
|
58
|
-
if (width !== PRO2_WALLPAPER_WIDTH || height !== PRO2_WALLPAPER_HEIGHT) {
|
|
59
|
-
throw invalidParameter(
|
|
60
|
-
`Pro2 wallpaper dimensions must be ${PRO2_WALLPAPER_WIDTH}x${PRO2_WALLPAPER_HEIGHT}.`
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
if (!(rgba instanceof ArrayBuffer) && !ArrayBuffer.isView(rgba)) {
|
|
64
|
-
throw invalidParameter('Parameter [rgba] must be an ArrayBuffer or Uint8Array.');
|
|
65
|
-
}
|
|
61
|
+
const { jpegBase64, fileName, chunkSize } = this.payload;
|
|
66
62
|
if (chunkSize !== undefined && (!Number.isInteger(chunkSize) || chunkSize <= 0)) {
|
|
67
63
|
throw invalidParameter('Parameter [chunkSize] must be a positive integer.');
|
|
68
64
|
}
|
|
69
65
|
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
const decoded = decodeJpegBase64ToRgba({
|
|
67
|
+
jpegBase64,
|
|
68
|
+
parameterName: 'jpegBase64',
|
|
69
|
+
expectedWidth: PRO2_WALLPAPER_WIDTH,
|
|
70
|
+
expectedHeight: PRO2_WALLPAPER_HEIGHT,
|
|
71
|
+
});
|
|
72
|
+
this.encoded = encodePro2Wallpaper({
|
|
73
|
+
width: PRO2_WALLPAPER_WIDTH,
|
|
74
|
+
height: PRO2_WALLPAPER_HEIGHT,
|
|
75
|
+
rgba: decoded.data,
|
|
76
|
+
});
|
|
75
77
|
this.path = `${WALLPAPER_DIRECTORY}/${normalizeFileName(fileName, this.encoded.data)}`;
|
|
76
|
-
this.params = {
|
|
78
|
+
this.params = { jpegBase64, fileName, chunkSize };
|
|
77
79
|
this.unlockPolicy = 'none';
|
|
78
80
|
this.skipForceUpdateCheck = true;
|
|
79
81
|
this.useDevicePassphraseState = false;
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
private async assertCapabilities() {
|
|
85
|
+
const protocolInfo = await this.device.ensureProtocolV2RuntimeContext();
|
|
86
|
+
const requiredMessageTypes = [
|
|
87
|
+
DEVICE_SETTINGS_SET_MESSAGE_TYPE,
|
|
88
|
+
FILESYSTEM_FILE_WRITE_MESSAGE_TYPE,
|
|
89
|
+
FILESYSTEM_DIR_MAKE_MESSAGE_TYPE,
|
|
90
|
+
];
|
|
91
|
+
if (
|
|
92
|
+
requiredMessageTypes.some(
|
|
93
|
+
messageType => !supportsProtocolV2Message(protocolInfo, messageType)
|
|
94
|
+
)
|
|
95
|
+
) {
|
|
96
|
+
throw createDeviceNotSupportMethodError(this.name, this.device.getCurrentFirmwareType());
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
82
100
|
private async ensureDirectory() {
|
|
83
101
|
if (this.directoryReady) return;
|
|
84
102
|
try {
|
|
@@ -119,6 +137,7 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
119
137
|
async run(): Promise<DeviceUploadWallpaperResponse> {
|
|
120
138
|
const { encoded } = this;
|
|
121
139
|
if (!encoded) throw invalidParameter('Wallpaper data has not been initialized.');
|
|
140
|
+
await this.assertCapabilities();
|
|
122
141
|
await this.ensureDirectory();
|
|
123
142
|
await this.upload();
|
|
124
143
|
const response = await this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
|
|
@@ -174,12 +174,14 @@ export default class TonSignMessage extends BaseMethod<HardwareTonSignMessage> {
|
|
|
174
174
|
if (!request.init_data_length) {
|
|
175
175
|
const deviceType = this.device.getCurrentDeviceType();
|
|
176
176
|
const hasClassic = DeviceModelToTypes.model_classic1s.includes(deviceType);
|
|
177
|
-
|
|
178
|
-
|
|
177
|
+
const signingMessage = request.signing_message ?? request.signning_message;
|
|
178
|
+
// Blind signing omits the signing message in both protocol schemas.
|
|
179
|
+
const shouldSkipValidation = signingMessage == null;
|
|
179
180
|
|
|
180
181
|
return Promise.resolve({
|
|
181
182
|
...request,
|
|
182
|
-
|
|
183
|
+
signing_message: signingMessage,
|
|
184
|
+
skip_validate: hasClassic || shouldSkipValidation,
|
|
183
185
|
});
|
|
184
186
|
}
|
|
185
187
|
|