@onekeyfe/hd-core 1.2.8-alpha.10 → 1.2.8-alpha.100
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__/DeviceCommands.test.ts +66 -13
- package/__tests__/core-error-output.test.ts +34 -3
- package/__tests__/device-lifecycle-events.test.ts +22 -17
- package/__tests__/logBlockEvent.test.ts +43 -0
- package/__tests__/protocol-v2-bootloader-mode.test.ts +43 -2
- package/__tests__/protocol-v2.test.ts +0 -47
- package/__tests__/refresh-device-state.test.ts +19 -17
- package/__tests__/zcash-sign-pczt.test.ts +212 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetDeviceState.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/protocol-v2/DeviceReboot.d.ts.map +1 -1
- package/dist/api/zcash/ZcashGetAddress.d.ts +12 -0
- package/dist/api/zcash/ZcashGetAddress.d.ts.map +1 -0
- package/dist/api/zcash/ZcashSignPczt.d.ts +17 -0
- package/dist/api/zcash/ZcashSignPczt.d.ts.map +1 -0
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +4 -4
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/index.d.ts +39 -5
- package/dist/index.js +351 -27
- package/dist/inject.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +2 -0
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +4 -0
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/zcashGetAddress.d.ts +22 -0
- package/dist/types/api/zcashGetAddress.d.ts.map +1 -0
- package/dist/types/api/zcashSignPczt.d.ts +9 -0
- package/dist/types/api/zcashSignPczt.d.ts.map +1 -0
- package/dist/types/params.d.ts +1 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +8 -25
- package/src/api/GetDeviceState.ts +2 -5
- package/src/api/index.ts +2 -0
- package/src/api/protocol-v2/DeviceReboot.ts +2 -0
- package/src/api/zcash/ZcashGetAddress.ts +121 -0
- package/src/api/zcash/ZcashSignPczt.ts +153 -0
- package/src/core/index.ts +2 -6
- package/src/data/messages/messages-protocol-v2.json +138 -1
- package/src/device/Device.ts +1 -1
- package/src/device/DeviceCommands.ts +15 -1
- package/src/events/core.ts +2 -2
- package/src/events/logBlockEvent.ts +5 -2
- package/src/inject.ts +4 -0
- package/src/types/api/export.ts +2 -0
- package/src/types/api/index.ts +8 -0
- package/src/types/api/zcashGetAddress.ts +36 -0
- package/src/types/api/zcashSignPczt.ts +18 -0
- package/src/types/params.ts +1 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ZcashAddressScope, ZcashAddressType } from '@onekeyfe/hd-transport';
|
|
2
|
+
|
|
3
|
+
import { BaseMethod } from '../BaseMethod';
|
|
4
|
+
import { serializedPath, toHardened, validatePath } from '../helpers/pathUtils';
|
|
5
|
+
import { invalidParameter, validateParams, validateResult } from '../helpers/paramsValidator';
|
|
6
|
+
import { UI_REQUEST } from '../../constants/ui-request';
|
|
7
|
+
|
|
8
|
+
import type { ZcashGetAddress as HardwareZcashGetAddress } from '@onekeyfe/hd-transport';
|
|
9
|
+
import type { ZcashGetAddressParams, ZcashAddress } from '../../types/api/zcashGetAddress';
|
|
10
|
+
import type { DeviceFirmwareRange } from '../../types';
|
|
11
|
+
|
|
12
|
+
export default class ZcashGetAddress extends BaseMethod<HardwareZcashGetAddress[]> {
|
|
13
|
+
hasBundle = false;
|
|
14
|
+
|
|
15
|
+
getSupportedProtocols() {
|
|
16
|
+
return ['V2'] as const;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
init() {
|
|
20
|
+
this.checkDeviceId = true;
|
|
21
|
+
this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
|
|
22
|
+
this.strictCheckDeviceSupport = true;
|
|
23
|
+
|
|
24
|
+
this.hasBundle = !!this.payload?.bundle;
|
|
25
|
+
const payload = this.hasBundle ? this.payload : { bundle: [this.payload] };
|
|
26
|
+
|
|
27
|
+
validateParams(payload, [{ name: 'bundle', type: 'array' }]);
|
|
28
|
+
|
|
29
|
+
this.params = [];
|
|
30
|
+
payload.bundle.forEach((batch: ZcashGetAddressParams) => {
|
|
31
|
+
// ZIP-32 account path: m/32'/133'/account'
|
|
32
|
+
const addressN = validatePath(batch.path, 3);
|
|
33
|
+
if (
|
|
34
|
+
addressN.length !== 3 ||
|
|
35
|
+
addressN[0] !== toHardened(32) ||
|
|
36
|
+
addressN[1] !== toHardened(133) ||
|
|
37
|
+
addressN[2] < toHardened(0) ||
|
|
38
|
+
addressN[2] > 0xffffffff
|
|
39
|
+
) {
|
|
40
|
+
throw invalidParameter("Zcash requires a ZIP-32 account path m/32'/133'/account'");
|
|
41
|
+
}
|
|
42
|
+
const addressType = batch.addressType ?? ZcashAddressType.UNIFIED_ORCHARD_P2PKH;
|
|
43
|
+
const scope = batch.scope ?? ZcashAddressScope.EXTERNAL;
|
|
44
|
+
const diversifierIndex = batch.diversifierIndex ?? 0;
|
|
45
|
+
if (
|
|
46
|
+
![
|
|
47
|
+
ZcashAddressType.UNIFIED_ORCHARD_P2PKH,
|
|
48
|
+
ZcashAddressType.TRANSPARENT_P2PKH,
|
|
49
|
+
ZcashAddressType.UNIFIED_ORCHARD,
|
|
50
|
+
].includes(addressType) ||
|
|
51
|
+
![ZcashAddressScope.EXTERNAL, ZcashAddressScope.INTERNAL].includes(scope)
|
|
52
|
+
) {
|
|
53
|
+
throw invalidParameter('Invalid Zcash address type or scope');
|
|
54
|
+
}
|
|
55
|
+
const maxIndex = addressType === ZcashAddressType.UNIFIED_ORCHARD ? 0xffffffff : 0x7fffffff;
|
|
56
|
+
if (
|
|
57
|
+
!Number.isSafeInteger(diversifierIndex) ||
|
|
58
|
+
diversifierIndex < 0 ||
|
|
59
|
+
diversifierIndex > maxIndex
|
|
60
|
+
) {
|
|
61
|
+
throw invalidParameter('Invalid Zcash diversifier index');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
validateParams(batch, [
|
|
65
|
+
{ name: 'path', required: true },
|
|
66
|
+
{ name: 'showOnOneKey', type: 'boolean' },
|
|
67
|
+
{ name: 'includeUfvk', type: 'boolean' },
|
|
68
|
+
{ name: 'includeSeedFingerprint', type: 'boolean' },
|
|
69
|
+
]);
|
|
70
|
+
|
|
71
|
+
this.params.push({
|
|
72
|
+
address_n: addressN,
|
|
73
|
+
address_type: addressType,
|
|
74
|
+
scope,
|
|
75
|
+
diversifier_index: diversifierIndex,
|
|
76
|
+
show_display: batch.showOnOneKey ?? true,
|
|
77
|
+
include_ufvk: batch.includeUfvk ?? false,
|
|
78
|
+
include_seed_fingerprint: batch.includeSeedFingerprint ?? false,
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
getVersionRange(): DeviceFirmwareRange {
|
|
84
|
+
return {
|
|
85
|
+
model_pro2: {
|
|
86
|
+
min: '0.0.0',
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async run() {
|
|
92
|
+
const responses: ZcashAddress[] = [];
|
|
93
|
+
|
|
94
|
+
for (let i = 0; i < this.params.length; i++) {
|
|
95
|
+
const param = this.params[i];
|
|
96
|
+
|
|
97
|
+
const res = await this.device.commands.typedCall('ZcashGetAddress', 'ZcashAddress', {
|
|
98
|
+
...param,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const path = serializedPath(param.address_n);
|
|
102
|
+
responses.push({
|
|
103
|
+
path,
|
|
104
|
+
address: res.message.address,
|
|
105
|
+
ufvk: res.message.ufvk,
|
|
106
|
+
seedFingerprint: res.message.seed_fingerprint,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
this.postPreviousAddressMessage({
|
|
110
|
+
address: res.message.address,
|
|
111
|
+
path,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
validateResult(responses, ['address'], {
|
|
116
|
+
expectedLength: this.params.length,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return Promise.resolve(this.hasBundle ? responses : responses[0]);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { bytesToHex } from '@noble/hashes/utils';
|
|
2
|
+
import { ERRORS, HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
3
|
+
|
|
4
|
+
import { BaseMethod } from '../BaseMethod';
|
|
5
|
+
import { invalidParameter, validateParams } from '../helpers/paramsValidator';
|
|
6
|
+
import { formatAnyHex } from '../helpers/hexUtils';
|
|
7
|
+
import { UI_REQUEST } from '../../constants/ui-request';
|
|
8
|
+
|
|
9
|
+
import type { ZcashSignPczt as HardwareZcashSignPczt } from '@onekeyfe/hd-transport';
|
|
10
|
+
import type { TypedCall, TypedResponseMessage } from '../../device/DeviceCommands';
|
|
11
|
+
import type { ZcashSignedPczt } from '../../types/api/zcashSignPczt';
|
|
12
|
+
import type { DeviceFirmwareRange } from '../../types';
|
|
13
|
+
|
|
14
|
+
// Firmware buffers the whole PCZT in RAM in both directions.
|
|
15
|
+
export const ZCASH_PCZT_MAX_BYTES = 24 * 1024;
|
|
16
|
+
const CHUNK_BYTE_SIZE = 1024;
|
|
17
|
+
|
|
18
|
+
export default class ZcashSignPczt extends BaseMethod<HardwareZcashSignPczt> {
|
|
19
|
+
pczt: Buffer = Buffer.alloc(0);
|
|
20
|
+
|
|
21
|
+
getSupportedProtocols() {
|
|
22
|
+
return ['V2'] as const;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
init() {
|
|
26
|
+
this.checkDeviceId = true;
|
|
27
|
+
this.allowDeviceMode = [...this.allowDeviceMode, UI_REQUEST.NOT_INITIALIZE];
|
|
28
|
+
this.strictCheckDeviceSupport = true;
|
|
29
|
+
|
|
30
|
+
validateParams(this.payload, [{ name: 'pczt', type: 'hexString', required: true }]);
|
|
31
|
+
|
|
32
|
+
this.pczt = Buffer.from(formatAnyHex(this.payload.pczt), 'hex');
|
|
33
|
+
if (this.pczt.length === 0) {
|
|
34
|
+
throw invalidParameter('pczt is empty');
|
|
35
|
+
}
|
|
36
|
+
if (this.pczt.length > ZCASH_PCZT_MAX_BYTES) {
|
|
37
|
+
throw invalidParameter(`pczt exceeds ${ZCASH_PCZT_MAX_BYTES} bytes (${this.pczt.length})`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
this.params = {
|
|
41
|
+
pczt_length: this.pczt.length,
|
|
42
|
+
pczt_initial_chunk: bytesToHex(this.pczt.subarray(0, CHUNK_BYTE_SIZE)),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
getVersionRange(): DeviceFirmwareRange {
|
|
47
|
+
return {
|
|
48
|
+
model_pro2: {
|
|
49
|
+
min: '0.0.0',
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Upload: the device decides every chunk length via ZcashPcztChunkRequest and
|
|
55
|
+
// the host must answer with exactly that many bytes.
|
|
56
|
+
uploadPczt = async (
|
|
57
|
+
typedCall: TypedCall,
|
|
58
|
+
res: TypedResponseMessage<'ZcashSignedPczt'> | TypedResponseMessage<'ZcashPcztChunkRequest'>,
|
|
59
|
+
offset: number
|
|
60
|
+
): Promise<TypedResponseMessage<'ZcashSignedPczt'>> => {
|
|
61
|
+
if (res.type === 'ZcashSignedPczt') {
|
|
62
|
+
if (offset !== this.pczt.length) {
|
|
63
|
+
throw ERRORS.TypedError(
|
|
64
|
+
HardwareErrorCode.ResponseUnexpectTypeError,
|
|
65
|
+
'device completed signing before receiving the whole pczt'
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
return res;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const { chunk_length: chunkLength } = res.message;
|
|
72
|
+
if (
|
|
73
|
+
!Number.isSafeInteger(chunkLength) ||
|
|
74
|
+
chunkLength <= 0 ||
|
|
75
|
+
offset + chunkLength > this.pczt.length
|
|
76
|
+
) {
|
|
77
|
+
throw ERRORS.TypedError(
|
|
78
|
+
HardwareErrorCode.ResponseUnexpectTypeError,
|
|
79
|
+
`device requested ${chunkLength} bytes at offset ${offset} of ${this.pczt.length}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const chunk = this.pczt.subarray(offset, offset + chunkLength);
|
|
84
|
+
const next = await typedCall(
|
|
85
|
+
'ZcashPcztChunkAck',
|
|
86
|
+
['ZcashSignedPczt', 'ZcashPcztChunkRequest'],
|
|
87
|
+
{
|
|
88
|
+
data_chunk: bytesToHex(chunk),
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
return this.uploadPczt(typedCall, next, offset + chunkLength);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Download: the host decides chunk lengths via ZcashSignedPcztChunkRequest
|
|
96
|
+
// until the announced pczt_length has been received.
|
|
97
|
+
downloadSignedPczt = async (
|
|
98
|
+
typedCall: TypedCall,
|
|
99
|
+
res: TypedResponseMessage<'ZcashSignedPczt'>
|
|
100
|
+
): Promise<Buffer> => {
|
|
101
|
+
const { pczt_length: total, pczt_initial_chunk: initial } = res.message;
|
|
102
|
+
if (!Number.isSafeInteger(total) || total <= 0 || total > ZCASH_PCZT_MAX_BYTES) {
|
|
103
|
+
throw ERRORS.TypedError(
|
|
104
|
+
HardwareErrorCode.ResponseUnexpectTypeError,
|
|
105
|
+
`device announced invalid signed pczt length ${total}`
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const parts: Buffer[] = [Buffer.from(initial ?? '', 'hex')];
|
|
110
|
+
let received = parts[0].length;
|
|
111
|
+
if (received > total) {
|
|
112
|
+
throw ERRORS.TypedError(
|
|
113
|
+
HardwareErrorCode.ResponseUnexpectTypeError,
|
|
114
|
+
'device returned more initial pczt bytes than announced'
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
while (received < total) {
|
|
119
|
+
const chunkLength = Math.min(CHUNK_BYTE_SIZE, total - received);
|
|
120
|
+
const ack = await typedCall('ZcashSignedPcztChunkRequest', 'ZcashPcztChunkAck', {
|
|
121
|
+
chunk_length: chunkLength,
|
|
122
|
+
});
|
|
123
|
+
const chunk = Buffer.from(ack.message.data_chunk ?? '', 'hex');
|
|
124
|
+
if (chunk.length === 0 || received + chunk.length > total) {
|
|
125
|
+
throw ERRORS.TypedError(
|
|
126
|
+
HardwareErrorCode.ResponseUnexpectTypeError,
|
|
127
|
+
`device returned ${chunk.length} bytes at offset ${received} of ${total}`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
parts.push(chunk);
|
|
131
|
+
received += chunk.length;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return Buffer.concat(parts);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
async run(): Promise<ZcashSignedPczt> {
|
|
138
|
+
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
139
|
+
|
|
140
|
+
const first = await typedCall('ZcashSignPczt', ['ZcashSignedPczt', 'ZcashPcztChunkRequest'], {
|
|
141
|
+
...this.params,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const signed = await this.uploadPczt(
|
|
145
|
+
typedCall,
|
|
146
|
+
first,
|
|
147
|
+
Math.min(CHUNK_BYTE_SIZE, this.pczt.length)
|
|
148
|
+
);
|
|
149
|
+
const pczt = await this.downloadSignedPczt(typedCall, signed);
|
|
150
|
+
|
|
151
|
+
return { pczt: bytesToHex(pczt) };
|
|
152
|
+
}
|
|
153
|
+
}
|
package/src/core/index.ts
CHANGED
|
@@ -23,7 +23,6 @@ import {
|
|
|
23
23
|
createNeedUpgradeFirmwareHardwareError,
|
|
24
24
|
createNewFirmwareForceUpdateHardwareError,
|
|
25
25
|
createNewFirmwareUnReleaseHardwareError,
|
|
26
|
-
isBleStaleBondHardwareError,
|
|
27
26
|
} from '@onekeyfe/hd-shared';
|
|
28
27
|
|
|
29
28
|
import { LoggerNames, enableLog, getLogger, setLoggerPostMessage, wait } from '../utils';
|
|
@@ -1035,10 +1034,6 @@ export function isMissingDetectedProtocolV2Error(method: BaseMethod, error: unkn
|
|
|
1035
1034
|
);
|
|
1036
1035
|
}
|
|
1037
1036
|
|
|
1038
|
-
export function isTerminalBleStaleBondError(error: unknown) {
|
|
1039
|
-
return isBleStaleBondHardwareError(error);
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
1037
|
export function isDeviceIdentityMismatchError(error: unknown) {
|
|
1043
1038
|
return (
|
|
1044
1039
|
(error as { errorCode?: unknown })?.errorCode === HardwareErrorCode.DeviceCheckDeviceIdError
|
|
@@ -1277,6 +1272,7 @@ const ensureConnected = async (
|
|
|
1277
1272
|
HardwareErrorCode.BridgeNotInstalled,
|
|
1278
1273
|
HardwareErrorCode.BridgeTimeoutError,
|
|
1279
1274
|
HardwareErrorCode.BridgeNeedsPermission,
|
|
1275
|
+
HardwareErrorCode.WebUsbDeviceAccessError,
|
|
1280
1276
|
].includes(error.errorCode)
|
|
1281
1277
|
) {
|
|
1282
1278
|
_deviceList = undefined;
|
|
@@ -1363,6 +1359,7 @@ const ensureConnected = async (
|
|
|
1363
1359
|
HardwareErrorCode.DeviceDetectInBootloaderMode,
|
|
1364
1360
|
HardwareErrorCode.BleCharacteristicNotifyChangeFailure,
|
|
1365
1361
|
HardwareErrorCode.BridgeNeedsPermission,
|
|
1362
|
+
HardwareErrorCode.WebUsbDeviceAccessError,
|
|
1366
1363
|
HardwareErrorCode.DeviceInterruptedFromUser,
|
|
1367
1364
|
HardwareErrorCode.CallQueueActionCancelled,
|
|
1368
1365
|
].includes(error.errorCode) ||
|
|
@@ -1370,7 +1367,6 @@ const ensureConnected = async (
|
|
|
1370
1367
|
[HardwareErrorCode.BleDeviceDisconnected, HardwareErrorCode.PollingTimeout].includes(
|
|
1371
1368
|
error.errorCode
|
|
1372
1369
|
)) ||
|
|
1373
|
-
isTerminalBleStaleBondError(error) ||
|
|
1374
1370
|
isDeviceIdentityMismatchError(error)
|
|
1375
1371
|
) {
|
|
1376
1372
|
reject(error);
|
|
@@ -11034,6 +11034,61 @@
|
|
|
11034
11034
|
}
|
|
11035
11035
|
}
|
|
11036
11036
|
},
|
|
11037
|
+
"ZcashSignPczt": {
|
|
11038
|
+
"fields": {
|
|
11039
|
+
"pczt_length": {
|
|
11040
|
+
"rule": "required",
|
|
11041
|
+
"type": "uint32",
|
|
11042
|
+
"id": 1
|
|
11043
|
+
},
|
|
11044
|
+
"pczt_initial_chunk": {
|
|
11045
|
+
"rule": "required",
|
|
11046
|
+
"type": "bytes",
|
|
11047
|
+
"id": 2
|
|
11048
|
+
}
|
|
11049
|
+
}
|
|
11050
|
+
},
|
|
11051
|
+
"ZcashPcztChunkRequest": {
|
|
11052
|
+
"fields": {
|
|
11053
|
+
"chunk_length": {
|
|
11054
|
+
"rule": "required",
|
|
11055
|
+
"type": "uint32",
|
|
11056
|
+
"id": 1
|
|
11057
|
+
}
|
|
11058
|
+
}
|
|
11059
|
+
},
|
|
11060
|
+
"ZcashPcztChunkAck": {
|
|
11061
|
+
"fields": {
|
|
11062
|
+
"data_chunk": {
|
|
11063
|
+
"rule": "required",
|
|
11064
|
+
"type": "bytes",
|
|
11065
|
+
"id": 1
|
|
11066
|
+
}
|
|
11067
|
+
}
|
|
11068
|
+
},
|
|
11069
|
+
"ZcashSignedPczt": {
|
|
11070
|
+
"fields": {
|
|
11071
|
+
"pczt_length": {
|
|
11072
|
+
"rule": "required",
|
|
11073
|
+
"type": "uint32",
|
|
11074
|
+
"id": 1
|
|
11075
|
+
},
|
|
11076
|
+
"pczt_initial_chunk": {
|
|
11077
|
+
"rule": "required",
|
|
11078
|
+
"type": "bytes",
|
|
11079
|
+
"id": 2
|
|
11080
|
+
}
|
|
11081
|
+
}
|
|
11082
|
+
},
|
|
11083
|
+
"ZcashSignedPcztChunkRequest": {
|
|
11084
|
+
"fields": {
|
|
11085
|
+
"chunk_length": {
|
|
11086
|
+
"rule": "required",
|
|
11087
|
+
"type": "uint32",
|
|
11088
|
+
"id": 1
|
|
11089
|
+
}
|
|
11090
|
+
}
|
|
11091
|
+
},
|
|
11037
11092
|
"wire_in": {
|
|
11038
11093
|
"type": "bool",
|
|
11039
11094
|
"id": 50002,
|
|
@@ -11459,6 +11514,11 @@
|
|
|
11459
11514
|
"MessageType_NeoAddress": 12302,
|
|
11460
11515
|
"MessageType_NeoSignTx": 12303,
|
|
11461
11516
|
"MessageType_NeoSignedTx": 12304,
|
|
11517
|
+
"MessageType_ZcashSignPczt": 12402,
|
|
11518
|
+
"MessageType_ZcashSignedPczt": 12403,
|
|
11519
|
+
"MessageType_ZcashPcztChunkRequest": 12404,
|
|
11520
|
+
"MessageType_ZcashPcztChunkAck": 12405,
|
|
11521
|
+
"MessageType_ZcashSignedPcztChunkRequest": 12406,
|
|
11462
11522
|
"MessageType_DeviceFactoryInfoSet": 60000,
|
|
11463
11523
|
"MessageType_DeviceFactoryInfoGet": 60001,
|
|
11464
11524
|
"MessageType_DeviceFactoryInfo": 60002,
|
|
@@ -11511,7 +11571,9 @@
|
|
|
11511
11571
|
"MessageType_PortfolioUpdate": 61400,
|
|
11512
11572
|
"MessageType_NftUpdate": 61500,
|
|
11513
11573
|
"MessageType_OnboardingStatusGet": 61600,
|
|
11514
|
-
"MessageType_OnboardingStatus": 61601
|
|
11574
|
+
"MessageType_OnboardingStatus": 61601,
|
|
11575
|
+
"MessageType_ZcashGetAddress": 12400,
|
|
11576
|
+
"MessageType_ZcashAddress": 12401
|
|
11515
11577
|
},
|
|
11516
11578
|
"reserved": [
|
|
11517
11579
|
[90, 92],
|
|
@@ -13730,6 +13792,81 @@
|
|
|
13730
13792
|
}
|
|
13731
13793
|
}
|
|
13732
13794
|
}
|
|
13795
|
+
},
|
|
13796
|
+
"ZcashAddressType": {
|
|
13797
|
+
"values": {
|
|
13798
|
+
"UNIFIED_ORCHARD_P2PKH": 0,
|
|
13799
|
+
"TRANSPARENT_P2PKH": 1,
|
|
13800
|
+
"UNIFIED_ORCHARD": 2
|
|
13801
|
+
}
|
|
13802
|
+
},
|
|
13803
|
+
"ZcashAddressScope": {
|
|
13804
|
+
"values": {
|
|
13805
|
+
"EXTERNAL": 0,
|
|
13806
|
+
"INTERNAL": 1
|
|
13807
|
+
}
|
|
13808
|
+
},
|
|
13809
|
+
"ZcashGetAddress": {
|
|
13810
|
+
"fields": {
|
|
13811
|
+
"address_n": {
|
|
13812
|
+
"rule": "repeated",
|
|
13813
|
+
"type": "uint32",
|
|
13814
|
+
"id": 1,
|
|
13815
|
+
"options": {
|
|
13816
|
+
"packed": false
|
|
13817
|
+
}
|
|
13818
|
+
},
|
|
13819
|
+
"show_display": {
|
|
13820
|
+
"type": "bool",
|
|
13821
|
+
"id": 2
|
|
13822
|
+
},
|
|
13823
|
+
"include_seed_fingerprint": {
|
|
13824
|
+
"type": "bool",
|
|
13825
|
+
"id": 3
|
|
13826
|
+
},
|
|
13827
|
+
"include_ufvk": {
|
|
13828
|
+
"type": "bool",
|
|
13829
|
+
"id": 4
|
|
13830
|
+
},
|
|
13831
|
+
"diversifier_index": {
|
|
13832
|
+
"type": "uint32",
|
|
13833
|
+
"id": 5,
|
|
13834
|
+
"options": {
|
|
13835
|
+
"default": 0
|
|
13836
|
+
}
|
|
13837
|
+
},
|
|
13838
|
+
"address_type": {
|
|
13839
|
+
"type": "ZcashAddressType",
|
|
13840
|
+
"id": 6,
|
|
13841
|
+
"options": {
|
|
13842
|
+
"default": "UNIFIED_ORCHARD_P2PKH"
|
|
13843
|
+
}
|
|
13844
|
+
},
|
|
13845
|
+
"scope": {
|
|
13846
|
+
"type": "ZcashAddressScope",
|
|
13847
|
+
"id": 7,
|
|
13848
|
+
"options": {
|
|
13849
|
+
"default": "EXTERNAL"
|
|
13850
|
+
}
|
|
13851
|
+
}
|
|
13852
|
+
}
|
|
13853
|
+
},
|
|
13854
|
+
"ZcashAddress": {
|
|
13855
|
+
"fields": {
|
|
13856
|
+
"address": {
|
|
13857
|
+
"rule": "required",
|
|
13858
|
+
"type": "string",
|
|
13859
|
+
"id": 1
|
|
13860
|
+
},
|
|
13861
|
+
"ufvk": {
|
|
13862
|
+
"type": "string",
|
|
13863
|
+
"id": 2
|
|
13864
|
+
},
|
|
13865
|
+
"seed_fingerprint": {
|
|
13866
|
+
"type": "bytes",
|
|
13867
|
+
"id": 3
|
|
13868
|
+
}
|
|
13869
|
+
}
|
|
13733
13870
|
}
|
|
13734
13871
|
}
|
|
13735
13872
|
}
|
package/src/device/Device.ts
CHANGED
|
@@ -1811,7 +1811,7 @@ export class Device extends EventEmitter {
|
|
|
1811
1811
|
// both allow and require cases might generate single unexpected mode
|
|
1812
1812
|
if (!this.isUnacquired()) {
|
|
1813
1813
|
// allow cases
|
|
1814
|
-
if (this.isBootloader()
|
|
1814
|
+
if ((this.isBootloader() || this.isRomloader()) && !allow.includes(UI_REQUEST.BOOTLOADER)) {
|
|
1815
1815
|
return UI_REQUEST.BOOTLOADER;
|
|
1816
1816
|
}
|
|
1817
1817
|
if (!this.isInitialized() && !allow.includes(UI_REQUEST.NOT_INITIALIZE)) {
|
|
@@ -549,6 +549,16 @@ export class DeviceCommands {
|
|
|
549
549
|
this.device.isProtocolV2() &&
|
|
550
550
|
DEVICE_CONTROL_CALLS.has(callType) &&
|
|
551
551
|
subcode === DeviceErrorCode.DeviceError_Busy;
|
|
552
|
+
const isProtocolV2PinCancelledBusyFailure =
|
|
553
|
+
this.device.isProtocolV2() &&
|
|
554
|
+
!DEVICE_SESSION_CALLS.has(callType) &&
|
|
555
|
+
subcode === DeviceSessionErrorCode.DeviceSessionError_UserCancelled &&
|
|
556
|
+
/^pin cancelled$/i.test(normalizedMessage);
|
|
557
|
+
const isProtocolV2FirmwareUpdateBusyFailure =
|
|
558
|
+
this.device.isProtocolV2() &&
|
|
559
|
+
/^requested command not allowed while a firmware update is in progress$/i.test(
|
|
560
|
+
normalizedMessage
|
|
561
|
+
);
|
|
552
562
|
const isLegacyProtocolV2LockedFailure =
|
|
553
563
|
this.device.isProtocolV2() && /^device (?:is )?locked$/i.test(normalizedMessage);
|
|
554
564
|
if (
|
|
@@ -606,7 +616,11 @@ export class DeviceCommands {
|
|
|
606
616
|
subcode,
|
|
607
617
|
firmwareMessage: message,
|
|
608
618
|
});
|
|
609
|
-
} else if (
|
|
619
|
+
} else if (
|
|
620
|
+
isProtocolV2DeviceBusyFailure ||
|
|
621
|
+
isProtocolV2PinCancelledBusyFailure ||
|
|
622
|
+
isProtocolV2FirmwareUpdateBusyFailure
|
|
623
|
+
) {
|
|
610
624
|
error = ERRORS.TypedError(HardwareErrorCode.DeviceBusy, message, {
|
|
611
625
|
failureCode: code,
|
|
612
626
|
subcode,
|
package/src/events/core.ts
CHANGED
|
@@ -54,9 +54,9 @@ export const parseMessage = (messageData: any): CoreMessage => {
|
|
|
54
54
|
};
|
|
55
55
|
|
|
56
56
|
export const createErrorMessage = (error: Error & { code?: string | number }): Unsuccessful => {
|
|
57
|
-
let payload = { error: error.message, code: error.code };
|
|
57
|
+
let payload: Unsuccessful['payload'] = { error: error.message, code: error.code };
|
|
58
58
|
if (error instanceof HardwareError) {
|
|
59
|
-
payload = { error: error.message, code: error.errorCode };
|
|
59
|
+
payload = { error: error.message, code: error.errorCode, params: error.params };
|
|
60
60
|
}
|
|
61
61
|
return {
|
|
62
62
|
success: false,
|
|
@@ -8,8 +8,8 @@ export const LogBlockEvent: Set<string> = new Set([
|
|
|
8
8
|
UI_RESPONSE.RECEIVE_PASSPHRASE,
|
|
9
9
|
]);
|
|
10
10
|
|
|
11
|
-
//
|
|
12
|
-
//
|
|
11
|
+
// Drop sensitive wallet payloads and large resource data before logger caches
|
|
12
|
+
// or log events can retain them, regardless of whether debug output is enabled.
|
|
13
13
|
const LogPayloadBlockMethod: Set<string> = new Set([
|
|
14
14
|
'btcDeriveContextHash',
|
|
15
15
|
'deviceUploadNft',
|
|
@@ -17,6 +17,9 @@ const LogPayloadBlockMethod: Set<string> = new Set([
|
|
|
17
17
|
'uploadPortfolio',
|
|
18
18
|
'fileWrite',
|
|
19
19
|
'fileRead',
|
|
20
|
+
'zcashGetAddress',
|
|
21
|
+
'zcashGetUnifiedAddress',
|
|
22
|
+
'zcashSignPczt',
|
|
20
23
|
]);
|
|
21
24
|
|
|
22
25
|
export function getLogBlockLabel(message: unknown): string | undefined {
|
package/src/inject.ts
CHANGED
|
@@ -504,4 +504,8 @@ export const createCoreApi = (
|
|
|
504
504
|
call({ ...params, connectId, deviceId, method: 'neoGetAddress' }),
|
|
505
505
|
neoSignTransaction: (connectId, deviceId, params) =>
|
|
506
506
|
call({ ...params, connectId, deviceId, method: 'neoSignTransaction' }),
|
|
507
|
+
zcashGetAddress: (connectId, deviceId, params) =>
|
|
508
|
+
call({ ...params, connectId, deviceId, method: 'zcashGetAddress' }),
|
|
509
|
+
zcashSignPczt: (connectId, deviceId, params) =>
|
|
510
|
+
call({ ...params, connectId, deviceId, method: 'zcashSignPczt' }),
|
|
507
511
|
});
|
package/src/types/api/export.ts
CHANGED
|
@@ -227,3 +227,5 @@ export type { BenfenAddress, BenfenGetAddressParams } from './benfenGetAddress';
|
|
|
227
227
|
export type { BenfenPublicKey, BenfenGetPublicKeyParams } from './benfenGetPublicKey';
|
|
228
228
|
export type { BenfenSignMessageParams } from './benfenSignMessage';
|
|
229
229
|
export type { BenfenSignedTx, BenfenSignTransactionParams } from './benfenSignTransaction';
|
|
230
|
+
export type { ZcashAddress, ZcashGetAddressParams } from './zcashGetAddress';
|
|
231
|
+
export type { ZcashSignedPczt, ZcashSignPcztParams } from './zcashSignPczt';
|
package/src/types/api/index.ts
CHANGED
|
@@ -154,6 +154,8 @@ import type { benfenSignTransaction } from './benfenSignTransaction';
|
|
|
154
154
|
import type { benfenSignMessage } from './benfenSignMessage';
|
|
155
155
|
import type { neoGetAddress } from './neoGetAddress';
|
|
156
156
|
import type { neoSignTransaction } from './neoSignTransaction';
|
|
157
|
+
import type { zcashGetAddress } from './zcashGetAddress';
|
|
158
|
+
import type { zcashSignPczt } from './zcashSignPczt';
|
|
157
159
|
import type { ConnectSettings } from '../settings';
|
|
158
160
|
import type { HardwareConnectProtocol } from '@onekeyfe/hd-shared';
|
|
159
161
|
|
|
@@ -472,4 +474,10 @@ export type CoreApi = {
|
|
|
472
474
|
*/
|
|
473
475
|
neoGetAddress: typeof neoGetAddress;
|
|
474
476
|
neoSignTransaction: typeof neoSignTransaction;
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Zcash
|
|
480
|
+
*/
|
|
481
|
+
zcashGetAddress: typeof zcashGetAddress;
|
|
482
|
+
zcashSignPczt: typeof zcashSignPczt;
|
|
475
483
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ZcashAddressScope, ZcashAddressType } from '@onekeyfe/hd-transport';
|
|
2
|
+
|
|
3
|
+
import type { CommonParams, Response } from '../params';
|
|
4
|
+
|
|
5
|
+
export type ZcashAddress = {
|
|
6
|
+
path: string;
|
|
7
|
+
// ZIP-316 unified address or transparent P2PKH address
|
|
8
|
+
address: string;
|
|
9
|
+
// ZIP-316 unified full viewing key, present when includeUfvk was requested
|
|
10
|
+
ufvk?: string;
|
|
11
|
+
// ZIP-32 seed fingerprint (hex), present when includeSeedFingerprint was requested
|
|
12
|
+
seedFingerprint?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type ZcashGetAddressParams = {
|
|
16
|
+
// ZIP-32 account path, m/32'/133'/account'
|
|
17
|
+
path: string | number[];
|
|
18
|
+
showOnOneKey?: boolean;
|
|
19
|
+
diversifierIndex?: number;
|
|
20
|
+
addressType?: ZcashAddressType;
|
|
21
|
+
scope?: ZcashAddressScope;
|
|
22
|
+
includeUfvk?: boolean;
|
|
23
|
+
includeSeedFingerprint?: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export declare function zcashGetAddress(
|
|
27
|
+
connectId: string,
|
|
28
|
+
deviceId: string,
|
|
29
|
+
params: CommonParams & ZcashGetAddressParams
|
|
30
|
+
): Response<ZcashAddress>;
|
|
31
|
+
|
|
32
|
+
export declare function zcashGetAddress(
|
|
33
|
+
connectId: string,
|
|
34
|
+
deviceId: string,
|
|
35
|
+
params: CommonParams & { bundle?: ZcashGetAddressParams[] }
|
|
36
|
+
): Response<Array<ZcashAddress>>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CommonParams, Response } from '../params';
|
|
2
|
+
|
|
3
|
+
export type ZcashSignPcztParams = {
|
|
4
|
+
// Unproved PCZT (v2, tx v6) as hex; the device signs it and returns a
|
|
5
|
+
// redacted copy with signatures filled in.
|
|
6
|
+
pczt: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type ZcashSignedPczt = {
|
|
10
|
+
// Signed, redacted PCZT as hex
|
|
11
|
+
pczt: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export declare function zcashSignPczt(
|
|
15
|
+
connectId: string,
|
|
16
|
+
deviceId: string,
|
|
17
|
+
params: CommonParams & ZcashSignPcztParams
|
|
18
|
+
): Response<ZcashSignedPczt>;
|
package/src/types/params.ts
CHANGED
|
@@ -83,7 +83,7 @@ export type Params<T> = CommonParams & T & { bundle?: undefined };
|
|
|
83
83
|
|
|
84
84
|
export interface Unsuccessful {
|
|
85
85
|
success: false;
|
|
86
|
-
payload: { error: string; code?: string | number };
|
|
86
|
+
payload: { error: string; code?: string | number; params?: Record<string, unknown> };
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
export interface Success<T> {
|