@onekeyfe/hd-transport 1.2.0-alpha.3 → 1.2.0-alpha.4
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/README.md +1 -1
- package/__tests__/protocol-v2.test.js +104 -77
- package/dist/constants.d.ts +2 -2
- package/dist/index.d.ts +329 -232
- package/dist/index.js +63 -43
- package/dist/protocols/v2/session.d.ts +1 -1
- package/dist/protocols/v2/session.d.ts.map +1 -1
- package/dist/types/messages.d.ts +235 -157
- package/dist/types/messages.d.ts.map +1 -1
- package/messages-protocol-v2.json +486 -1072
- package/package.json +2 -2
- package/scripts/protobuf-build.sh +51 -143
- package/src/constants.ts +2 -2
- package/src/protocols/v2/session.ts +4 -5
- package/src/types/messages.ts +291 -193
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.4",
|
|
4
4
|
"description": "Transport layer abstractions and utilities for OneKey hardware SDK.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"long": "^4.0.0",
|
|
29
29
|
"protobufjs": "^6.11.2"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "6f83d130f022a75003385bc4b2386cd0b2b539b5"
|
|
32
32
|
}
|
|
@@ -126,36 +126,6 @@ if [ -d "$SRC_PRO2_LATEST" ] && ls "$SRC_PRO2_LATEST"/messages*.proto 1>/dev/nul
|
|
|
126
126
|
| sed 's/^option /\/\/ option /' \
|
|
127
127
|
| grep -v ' reserved '
|
|
128
128
|
|
|
129
|
-
if ! grep -q '^message TonSignData ' "$SRC_PRO2_LEGACY"/messages*.proto; then
|
|
130
|
-
echo ''
|
|
131
|
-
echo '// --- TON signData (kept until firmware-pro2 legacy proto exports it) ---'
|
|
132
|
-
echo 'message TonSignData {'
|
|
133
|
-
echo ' repeated uint32 address_n = 1;'
|
|
134
|
-
echo ' required TonSignDataType type = 2;'
|
|
135
|
-
echo ' required bytes payload = 3;'
|
|
136
|
-
echo ' optional string schema = 4;'
|
|
137
|
-
echo ' required string appdomain = 5;'
|
|
138
|
-
echo ' required uint64 timestamp = 6;'
|
|
139
|
-
echo ' optional string from_address = 7;'
|
|
140
|
-
echo ' optional TonWalletVersion wallet_version = 8 [default=V4R2];'
|
|
141
|
-
echo ' optional uint32 wallet_id = 9 [default=698983191];'
|
|
142
|
-
echo ' optional TonWorkChain workchain = 10 [default=BASECHAIN];'
|
|
143
|
-
echo ' optional bool is_bounceable = 11 [default=false];'
|
|
144
|
-
echo ' optional bool is_testnet_only = 12 [default=false];'
|
|
145
|
-
echo ''
|
|
146
|
-
echo ' enum TonSignDataType {'
|
|
147
|
-
echo ' TEXT = 0;'
|
|
148
|
-
echo ' BINARY = 1;'
|
|
149
|
-
echo ' CELL = 2;'
|
|
150
|
-
echo ' }'
|
|
151
|
-
echo '}'
|
|
152
|
-
echo ''
|
|
153
|
-
echo 'message TonSignedData {'
|
|
154
|
-
echo ' optional bytes signature = 1;'
|
|
155
|
-
echo ' optional bytes digest = 2;'
|
|
156
|
-
echo '}'
|
|
157
|
-
fi
|
|
158
|
-
|
|
159
129
|
echo ''
|
|
160
130
|
echo '// --- Protocol V2 system messages ---'
|
|
161
131
|
grep -hv \
|
|
@@ -164,83 +134,49 @@ if [ -d "$SRC_PRO2_LATEST" ] && ls "$SRC_PRO2_LATEST"/messages*.proto 1>/dev/nul
|
|
|
164
134
|
"$SRC_PRO2_LATEST"/messages*.proto \
|
|
165
135
|
| grep -v ' reserved '
|
|
166
136
|
|
|
167
|
-
if ! grep -q '^message GetOnboardingStatus ' "$SRC_PRO2_LATEST"/messages*.proto; then
|
|
168
|
-
echo ''
|
|
169
|
-
echo '// --- Onboarding status (kept until firmware-pro2 latest proto exports it) ---'
|
|
170
|
-
echo 'enum OnboardingStep {'
|
|
171
|
-
echo ' ONBOARDING_STEP_UNKNOWN = 0;'
|
|
172
|
-
echo ' ONBOARDING_STEP_DEVICE_VERIFICATION = 1;'
|
|
173
|
-
echo ' ONBOARDING_STEP_PERSONALIZATION = 2;'
|
|
174
|
-
echo ' ONBOARDING_STEP_SETUP = 3;'
|
|
175
|
-
echo ' ONBOARDING_STEP_FIRMWARE = 4;'
|
|
176
|
-
echo '}'
|
|
177
|
-
echo ''
|
|
178
|
-
echo 'message GetOnboardingStatus {'
|
|
179
|
-
echo '}'
|
|
180
|
-
echo ''
|
|
181
|
-
echo 'message OnboardingStatus {'
|
|
182
|
-
echo ' message Setup {'
|
|
183
|
-
echo ' message NewDevice {'
|
|
184
|
-
echo ' optional bool seedcard_backup = 1;'
|
|
185
|
-
echo ' }'
|
|
186
|
-
echo ' message Restore {'
|
|
187
|
-
echo ' optional bool mnemonic = 1;'
|
|
188
|
-
echo ' optional bool seedcard = 2;'
|
|
189
|
-
echo ' }'
|
|
190
|
-
echo ' optional NewDevice new_device = 1;'
|
|
191
|
-
echo ' optional Restore restore = 2;'
|
|
192
|
-
echo ' }'
|
|
193
|
-
echo ' required OnboardingStep step = 1;'
|
|
194
|
-
echo ' optional Setup setup = 2;'
|
|
195
|
-
echo ' optional uint32 detail_code = 3;'
|
|
196
|
-
echo ' optional string detail_str = 4;'
|
|
197
|
-
echo '}'
|
|
198
|
-
fi
|
|
199
137
|
} > "$TMP_PROTO"
|
|
200
138
|
|
|
201
|
-
|
|
202
|
-
node - "$TMP_PROTO" <<'NODE'
|
|
203
|
-
const fs = require('fs');
|
|
204
|
-
|
|
205
|
-
const protoPath = process.argv[2];
|
|
206
|
-
const proto = fs.readFileSync(protoPath, 'utf8');
|
|
207
|
-
const updated = proto.replace(
|
|
208
|
-
/( MessageType_TonTxAck\s*=\s*11907[^\n]*;\n)/,
|
|
209
|
-
`$1 MessageType_TonSignData = 11908 [(wire_in) = true];\n MessageType_TonSignedData = 11909 [(wire_out) = true];\n`
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
if (updated === proto) {
|
|
213
|
-
throw new Error('Unable to insert TON signData MessageType entries into Pro2 schema');
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
fs.writeFileSync(protoPath, updated);
|
|
217
|
-
NODE
|
|
218
|
-
fi
|
|
219
|
-
|
|
220
|
-
if ! grep -q 'MessageType_GetOnboardingStatus' "$TMP_PROTO"; then
|
|
221
|
-
node - "$TMP_PROTO" <<'NODE'
|
|
139
|
+
node - "$TMP_PROTO" <<'NODE'
|
|
222
140
|
const fs = require('fs');
|
|
223
141
|
|
|
224
142
|
const protoPath = process.argv[2];
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
143
|
+
let proto = fs.readFileSync(protoPath, 'utf8');
|
|
144
|
+
|
|
145
|
+
const removeTopLevelMessage = (source, name) => {
|
|
146
|
+
const pattern = new RegExp(`(^|\\n)message\\s+${name}\\s*\\{`, 'm');
|
|
147
|
+
const match = pattern.exec(source);
|
|
148
|
+
if (!match) return source;
|
|
149
|
+
|
|
150
|
+
const start = match.index + (match[1] ? match[1].length : 0);
|
|
151
|
+
let index = start;
|
|
152
|
+
let depth = 0;
|
|
153
|
+
while (index < source.length) {
|
|
154
|
+
const char = source[index];
|
|
155
|
+
if (char === '{') {
|
|
156
|
+
depth += 1;
|
|
157
|
+
} else if (char === '}') {
|
|
158
|
+
depth -= 1;
|
|
159
|
+
if (depth === 0) {
|
|
160
|
+
index += 1;
|
|
161
|
+
while (index < source.length && /\s/.test(source[index])) index += 1;
|
|
162
|
+
return `${source.slice(0, start)}${source.slice(index)}`;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
index += 1;
|
|
166
|
+
}
|
|
167
|
+
throw new Error(`Unterminated message block: ${name}`);
|
|
168
|
+
};
|
|
234
169
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
170
|
+
[
|
|
171
|
+
'Initialize',
|
|
172
|
+
'GetFeatures',
|
|
173
|
+
'OnekeyGetFeatures',
|
|
174
|
+
'Features',
|
|
175
|
+
].forEach(name => {
|
|
176
|
+
proto = removeTopLevelMessage(proto, name);
|
|
177
|
+
});
|
|
178
|
+
fs.writeFileSync(protoPath, proto);
|
|
238
179
|
|
|
239
|
-
node - "$TMP_PROTO" <<'NODE'
|
|
240
|
-
const fs = require('fs');
|
|
241
|
-
|
|
242
|
-
const protoPath = process.argv[2];
|
|
243
|
-
const proto = fs.readFileSync(protoPath, 'utf8');
|
|
244
180
|
const messageNames = new Set(
|
|
245
181
|
Array.from(proto.matchAll(/^\s*message\s+([A-Za-z_][A-Za-z0-9_]*)\s*\{/gm)).map(
|
|
246
182
|
match => match[1]
|
|
@@ -252,17 +188,21 @@ const messageTypeNames = new Set(
|
|
|
252
188
|
)
|
|
253
189
|
);
|
|
254
190
|
const requiredMessages = [
|
|
191
|
+
'DeviceFactoryInfoSet',
|
|
192
|
+
'DeviceFactoryInfoGet',
|
|
193
|
+
'DeviceFactoryInfo',
|
|
194
|
+
'ProtocolInfoRequest',
|
|
195
|
+
'ProtocolInfo',
|
|
255
196
|
'Ping',
|
|
256
197
|
'Success',
|
|
257
198
|
'Failure',
|
|
258
|
-
'
|
|
259
|
-
'
|
|
199
|
+
'DeviceReboot',
|
|
200
|
+
'DeviceInfoGet',
|
|
260
201
|
'DeviceInfo',
|
|
261
|
-
'
|
|
262
|
-
'
|
|
263
|
-
'
|
|
264
|
-
'
|
|
265
|
-
'FilesystemFixPermission',
|
|
202
|
+
'DeviceFirmwareUpdateRequest',
|
|
203
|
+
'DeviceFirmwareUpdateStatusGet',
|
|
204
|
+
'DeviceFirmwareUpdateStatus',
|
|
205
|
+
'FilesystemPermissionFix',
|
|
266
206
|
'FilesystemPathInfo',
|
|
267
207
|
'FilesystemPathInfoQuery',
|
|
268
208
|
'FilesystemFile',
|
|
@@ -274,10 +214,6 @@ const requiredMessages = [
|
|
|
274
214
|
'FilesystemDirMake',
|
|
275
215
|
'FilesystemDirRemove',
|
|
276
216
|
'FilesystemFormat',
|
|
277
|
-
'TonSignData',
|
|
278
|
-
'TonSignedData',
|
|
279
|
-
'GetOnboardingStatus',
|
|
280
|
-
'OnboardingStatus',
|
|
281
217
|
];
|
|
282
218
|
const missingMessages = requiredMessages.filter(name => !messageNames.has(name));
|
|
283
219
|
const missingMessageTypes = requiredMessages.filter(name => !messageTypeNames.has(name));
|
|
@@ -288,39 +224,11 @@ if (missingMessages.length > 0 || missingMessageTypes.length > 0) {
|
|
|
288
224
|
', '
|
|
289
225
|
)}], messageTypes=[${missingMessageTypes.join(
|
|
290
226
|
', '
|
|
291
|
-
)}]. Make sure submodules/firmware-pro2 is checked out on branch
|
|
292
|
-
'(origin/
|
|
227
|
+
)}]. Make sure submodules/firmware-pro2 is checked out on branch dev ` +
|
|
228
|
+
'(origin/dev), which contains the latest Protocol V2 Device*/Filesystem* messages.'
|
|
293
229
|
);
|
|
294
230
|
}
|
|
295
231
|
|
|
296
|
-
// Provisional wire IDs injected by this script for messages the firmware proto does
|
|
297
|
-
// not export yet (pending firmware confirmation, see
|
|
298
|
-
// docs/protocol-v2-deviceinfo-field-gaps.md). If the firmware submodule starts
|
|
299
|
-
// exporting these MessageType entries itself, the injection above is skipped and the
|
|
300
|
-
// firmware-assigned IDs flow into TMP_PROTO — assert they still match the IDs the SDK
|
|
301
|
-
// was built against, and fail loudly on any drift.
|
|
302
|
-
const expectedInjectedIds = {
|
|
303
|
-
TonSignData: 11908,
|
|
304
|
-
TonSignedData: 11909,
|
|
305
|
-
GetOnboardingStatus: 60602,
|
|
306
|
-
OnboardingStatus: 60603,
|
|
307
|
-
};
|
|
308
|
-
const actualIds = {};
|
|
309
|
-
for (const match of proto.matchAll(/^\s*MessageType_([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(\d+)/gm)) {
|
|
310
|
-
actualIds[match[1]] = Number(match[2]);
|
|
311
|
-
}
|
|
312
|
-
const idMismatches = Object.entries(expectedInjectedIds)
|
|
313
|
-
.filter(([name, id]) => name in actualIds && actualIds[name] !== id)
|
|
314
|
-
.map(([name, id]) => `${name}: expected ${id}, firmware proto has ${actualIds[name]}`);
|
|
315
|
-
|
|
316
|
-
if (idMismatches.length > 0) {
|
|
317
|
-
throw new Error(
|
|
318
|
-
`Protocol V2 injected MessageType wire IDs conflict with the firmware proto: ${idMismatches.join(
|
|
319
|
-
'; '
|
|
320
|
-
)}. Update the injected IDs in protobuf-build.sh and the registry section in ` +
|
|
321
|
-
'docs/protocol-v2-deviceinfo-field-gaps.md.'
|
|
322
|
-
);
|
|
323
|
-
}
|
|
324
232
|
NODE
|
|
325
233
|
|
|
326
234
|
npx pbjs -t json \
|
|
@@ -345,8 +253,8 @@ else
|
|
|
345
253
|
# Unlike the optional Pro1 (legacy) section above, the firmware-pro2 submodule is
|
|
346
254
|
# the only source of the Protocol V2 schema, so a missing checkout is a hard error.
|
|
347
255
|
echo "firmware-pro2 latest protobuf schema not found at $SRC_PRO2_LATEST"
|
|
348
|
-
echo "The Protocol V2 schema requires firmware-pro2 on branch
|
|
256
|
+
echo "The Protocol V2 schema requires firmware-pro2 on branch dev."
|
|
349
257
|
echo "Run: git submodule update --init submodules/firmware-pro2"
|
|
350
|
-
echo "Then: git -C submodules/firmware-pro2 fetch origin
|
|
258
|
+
echo "Then: git -C submodules/firmware-pro2 fetch origin dev && git -C submodules/firmware-pro2 checkout origin/dev"
|
|
351
259
|
exit 1
|
|
352
260
|
fi
|
package/src/constants.ts
CHANGED
|
@@ -20,11 +20,11 @@ export const PROTOCOL_V1_ENVELOPE_HEADER_SIZE = 1 + 1 + PROTOCOL_V1_MESSAGE_HEAD
|
|
|
20
20
|
|
|
21
21
|
// ---- Protocol V2 (Pro2 USB / BLE transports) ----
|
|
22
22
|
|
|
23
|
-
/** Protocol V2 单帧最大长度,包含 header、payload 和 CRC;需容纳
|
|
23
|
+
/** Protocol V2 单帧最大长度,包含 header、payload 和 CRC;需容纳 4000 数据块及 protobuf 开销。 */
|
|
24
24
|
export const PROTOCOL_V2_FRAME_MAX_BYTES = 4608;
|
|
25
25
|
|
|
26
26
|
/** WebUSB 下 FilesystemFileWrite 的文件数据分块大小。 */
|
|
27
|
-
export const PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE =
|
|
27
|
+
export const PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE = 4000;
|
|
28
28
|
|
|
29
29
|
/** BLE 下 FilesystemFileWrite 的文件数据分块大小。 */
|
|
30
30
|
export const PROTOCOL_V2_BLE_FILE_CHUNK_SIZE = 1800;
|
|
@@ -229,11 +229,10 @@ export async function withProtocolTimeout<T>(
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
|
|
232
|
-
//
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
|
|
236
|
-
export const PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS = 30000;
|
|
232
|
+
// Write completion is owned by the concrete transport. A Promise.race watchdog
|
|
233
|
+
// here can return while libusb/WebUSB is still flushing a large Protocol V2
|
|
234
|
+
// frame, which desynchronizes later request/response pairs.
|
|
235
|
+
export const PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS = 0;
|
|
237
236
|
|
|
238
237
|
export class ProtocolV2Session {
|
|
239
238
|
private readonly options: ProtocolV2SessionOptions;
|