@onekeyfe/hd-transport 1.2.0-alpha.16 → 1.2.0-alpha.18
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__/messages.test.js +37 -2
- package/__tests__/protocol-v2.test.js +6 -39
- package/dist/index.d.ts +216 -30
- package/dist/index.js +69 -43
- package/dist/protocols/v2/session.d.ts.map +1 -1
- package/dist/serialization/protobuf/decode.d.ts.map +1 -1
- package/dist/types/messages.d.ts +153 -23
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/transport.d.ts +3 -1
- package/dist/types/transport.d.ts.map +1 -1
- package/messages-protocol-v2.json +122 -23
- package/package.json +2 -2
- package/scripts/protobuf-build.sh +112 -32
- package/scripts/protobuf-patches/index.js +1 -0
- package/scripts/protobuf-types.js +3 -0
- package/src/protocols/v2/session.ts +12 -6
- package/src/serialization/protobuf/decode.ts +4 -1
- package/src/types/messages.ts +190 -24
- package/src/types/transport.ts +5 -1
|
@@ -482,7 +482,7 @@
|
|
|
482
482
|
"MessageType_DeviceStatus": 60603,
|
|
483
483
|
"MessageType_DevGetOnboardingStatus": 60604,
|
|
484
484
|
"MessageType_DevOnboardingStatus": 60605,
|
|
485
|
-
"
|
|
485
|
+
"MessageType_DeviceSessionOpen": 60606,
|
|
486
486
|
"MessageType_DeviceSession": 60607,
|
|
487
487
|
"MessageType_DeviceSessionAskPin": 60608,
|
|
488
488
|
"MessageType_FilesystemPermissionFix": 60800,
|
|
@@ -12418,14 +12418,68 @@
|
|
|
12418
12418
|
}
|
|
12419
12419
|
}
|
|
12420
12420
|
},
|
|
12421
|
-
"
|
|
12421
|
+
"DeviceSessionResume": {
|
|
12422
12422
|
"fields": {
|
|
12423
12423
|
"session_id": {
|
|
12424
|
+
"rule": "required",
|
|
12424
12425
|
"type": "bytes",
|
|
12425
12426
|
"id": 1
|
|
12426
12427
|
}
|
|
12427
12428
|
}
|
|
12428
12429
|
},
|
|
12430
|
+
"DeviceHostPassphrase": {
|
|
12431
|
+
"fields": {
|
|
12432
|
+
"passphrase": {
|
|
12433
|
+
"rule": "required",
|
|
12434
|
+
"type": "string",
|
|
12435
|
+
"id": 1
|
|
12436
|
+
}
|
|
12437
|
+
}
|
|
12438
|
+
},
|
|
12439
|
+
"DevicePassphraseOnDevice": {
|
|
12440
|
+
"fields": {}
|
|
12441
|
+
},
|
|
12442
|
+
"DeviceAttachPinOnDevice": {
|
|
12443
|
+
"fields": {}
|
|
12444
|
+
},
|
|
12445
|
+
"DeviceWalletSelect": {
|
|
12446
|
+
"oneofs": {
|
|
12447
|
+
"access": {
|
|
12448
|
+
"oneof": ["host_passphrase", "passphrase_on_device", "attach_pin_on_device"]
|
|
12449
|
+
}
|
|
12450
|
+
},
|
|
12451
|
+
"fields": {
|
|
12452
|
+
"host_passphrase": {
|
|
12453
|
+
"type": "DeviceHostPassphrase",
|
|
12454
|
+
"id": 1
|
|
12455
|
+
},
|
|
12456
|
+
"passphrase_on_device": {
|
|
12457
|
+
"type": "DevicePassphraseOnDevice",
|
|
12458
|
+
"id": 2
|
|
12459
|
+
},
|
|
12460
|
+
"attach_pin_on_device": {
|
|
12461
|
+
"type": "DeviceAttachPinOnDevice",
|
|
12462
|
+
"id": 3
|
|
12463
|
+
}
|
|
12464
|
+
}
|
|
12465
|
+
},
|
|
12466
|
+
"DeviceSessionOpen": {
|
|
12467
|
+
"oneofs": {
|
|
12468
|
+
"mode": {
|
|
12469
|
+
"oneof": ["resume", "select"]
|
|
12470
|
+
}
|
|
12471
|
+
},
|
|
12472
|
+
"fields": {
|
|
12473
|
+
"resume": {
|
|
12474
|
+
"type": "DeviceSessionResume",
|
|
12475
|
+
"id": 1
|
|
12476
|
+
},
|
|
12477
|
+
"select": {
|
|
12478
|
+
"type": "DeviceWalletSelect",
|
|
12479
|
+
"id": 2
|
|
12480
|
+
}
|
|
12481
|
+
}
|
|
12482
|
+
},
|
|
12429
12483
|
"DeviceSession": {
|
|
12430
12484
|
"fields": {
|
|
12431
12485
|
"session_id": {
|
|
@@ -12481,21 +12535,59 @@
|
|
|
12481
12535
|
"DeviceStatusGet": {
|
|
12482
12536
|
"fields": {}
|
|
12483
12537
|
},
|
|
12484
|
-
"
|
|
12538
|
+
"DevOnboardingStep": {
|
|
12539
|
+
"values": {
|
|
12540
|
+
"DEV_ONBOARDING_STEP_UNKNOWN": 0,
|
|
12541
|
+
"DEV_ONBOARDING_STEP_CHECKING": 1,
|
|
12542
|
+
"DEV_ONBOARDING_STEP_PERSONALIZATION": 2,
|
|
12543
|
+
"DEV_ONBOARDING_STEP_PIN": 3,
|
|
12544
|
+
"DEV_ONBOARDING_STEP_SETUP": 4,
|
|
12545
|
+
"DEV_ONBOARDING_STEP_DONE": 5
|
|
12546
|
+
}
|
|
12547
|
+
},
|
|
12548
|
+
"DevOnboardingPhase": {
|
|
12549
|
+
"values": {
|
|
12550
|
+
"DEV_ONBOARDING_PHASE_UNKNOWN": 0,
|
|
12551
|
+
"DEV_ONBOARDING_PHASE_SAFETY_CHECK": 1,
|
|
12552
|
+
"DEV_ONBOARDING_PHASE_PIN_SETUP": 2,
|
|
12553
|
+
"DEV_ONBOARDING_PHASE_FINGERPRINT_SETUP": 3,
|
|
12554
|
+
"DEV_ONBOARDING_PHASE_SETUP_CHOICE": 4,
|
|
12555
|
+
"DEV_ONBOARDING_PHASE_WALLET_CREATE_START": 5,
|
|
12556
|
+
"DEV_ONBOARDING_PHASE_RECOVERY_PHRASE_VIEW": 6,
|
|
12557
|
+
"DEV_ONBOARDING_PHASE_RECOVERY_PHRASE_CONFIRM": 7,
|
|
12558
|
+
"DEV_ONBOARDING_PHASE_RESTORE_METHOD_CHOICE": 8,
|
|
12559
|
+
"DEV_ONBOARDING_PHASE_RECOVERY_PHRASE_RESTORE": 9,
|
|
12560
|
+
"DEV_ONBOARDING_PHASE_SEEDCARD_RESTORE": 10,
|
|
12561
|
+
"DEV_ONBOARDING_PHASE_WALLET_READY": 11,
|
|
12562
|
+
"DEV_ONBOARDING_PHASE_SEEDCARD_BACKUP_PROMPT": 12,
|
|
12563
|
+
"DEV_ONBOARDING_PHASE_SEEDCARD_BACKUP": 13
|
|
12564
|
+
}
|
|
12565
|
+
},
|
|
12566
|
+
"DevOnboardingSetupKind": {
|
|
12485
12567
|
"values": {
|
|
12486
|
-
"
|
|
12487
|
-
"
|
|
12488
|
-
"
|
|
12489
|
-
"
|
|
12490
|
-
|
|
12491
|
-
|
|
12492
|
-
|
|
12493
|
-
|
|
12494
|
-
"
|
|
12495
|
-
"
|
|
12496
|
-
"
|
|
12497
|
-
|
|
12498
|
-
|
|
12568
|
+
"DEV_ONBOARDING_SETUP_KIND_UNKNOWN": 0,
|
|
12569
|
+
"DEV_ONBOARDING_SETUP_KIND_CHOICE": 1,
|
|
12570
|
+
"DEV_ONBOARDING_SETUP_KIND_CREATE": 2,
|
|
12571
|
+
"DEV_ONBOARDING_SETUP_KIND_RESTORE": 3
|
|
12572
|
+
}
|
|
12573
|
+
},
|
|
12574
|
+
"DevOnboardingSetupMethod": {
|
|
12575
|
+
"values": {
|
|
12576
|
+
"DEV_ONBOARDING_SETUP_METHOD_UNKNOWN": 0,
|
|
12577
|
+
"DEV_ONBOARDING_SETUP_METHOD_RECOVERY_PHRASE": 1,
|
|
12578
|
+
"DEV_ONBOARDING_SETUP_METHOD_SEEDCARD": 2
|
|
12579
|
+
}
|
|
12580
|
+
},
|
|
12581
|
+
"DevOnboardingSetupStatus": {
|
|
12582
|
+
"fields": {
|
|
12583
|
+
"kind": {
|
|
12584
|
+
"type": "DevOnboardingSetupKind",
|
|
12585
|
+
"id": 1
|
|
12586
|
+
},
|
|
12587
|
+
"method": {
|
|
12588
|
+
"type": "DevOnboardingSetupMethod",
|
|
12589
|
+
"id": 2
|
|
12590
|
+
}
|
|
12499
12591
|
}
|
|
12500
12592
|
},
|
|
12501
12593
|
"DevGetOnboardingStatus": {
|
|
@@ -12503,18 +12595,25 @@
|
|
|
12503
12595
|
},
|
|
12504
12596
|
"DevOnboardingStatus": {
|
|
12505
12597
|
"fields": {
|
|
12506
|
-
"
|
|
12507
|
-
"
|
|
12508
|
-
"type": "DevOnboardingStage",
|
|
12598
|
+
"step": {
|
|
12599
|
+
"type": "DevOnboardingStep",
|
|
12509
12600
|
"id": 1
|
|
12510
12601
|
},
|
|
12511
|
-
"
|
|
12512
|
-
"type": "
|
|
12602
|
+
"phase": {
|
|
12603
|
+
"type": "DevOnboardingPhase",
|
|
12513
12604
|
"id": 2
|
|
12514
12605
|
},
|
|
12515
|
-
"
|
|
12516
|
-
"type": "
|
|
12606
|
+
"setup": {
|
|
12607
|
+
"type": "DevOnboardingSetupStatus",
|
|
12517
12608
|
"id": 3
|
|
12609
|
+
},
|
|
12610
|
+
"pin_set": {
|
|
12611
|
+
"type": "bool",
|
|
12612
|
+
"id": 4
|
|
12613
|
+
},
|
|
12614
|
+
"wallet_initialized": {
|
|
12615
|
+
"type": "bool",
|
|
12616
|
+
"id": 5
|
|
12518
12617
|
}
|
|
12519
12618
|
}
|
|
12520
12619
|
},
|
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.18",
|
|
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": "bdbc5bf74e48ca90f5c56f3079b2b974e61f7aa4"
|
|
32
32
|
}
|
|
@@ -2,57 +2,137 @@
|
|
|
2
2
|
|
|
3
3
|
set -euxo pipefail
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
PARENT_PATH=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)
|
|
6
|
+
PACKAGE_ROOT="$PARENT_PATH/.."
|
|
7
|
+
REPO_ROOT="$PARENT_PATH/../../.."
|
|
8
|
+
CORE_MESSAGES_DIR="$REPO_ROOT/packages/core/src/data/messages"
|
|
8
9
|
|
|
9
10
|
SRC="../../submodules/firmware/common/protob"
|
|
10
11
|
DIST="."
|
|
11
12
|
LANG="typescript"
|
|
12
13
|
|
|
13
|
-
if [[ $# -ne 0 && $# -ne 3 ]]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
if [[ $# -ne 0 && $# -ne 3 ]]; then
|
|
15
|
+
echo "must provide either 3 or 0 arguments. $# provided"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
if [[ $# -eq 3 ]]; then
|
|
20
|
+
SRC=$1
|
|
21
|
+
DIST=$2
|
|
22
|
+
LANG=$3
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
if [[ "$LANG" != "typescript" && "$LANG" != "flow" ]]; then
|
|
26
|
+
echo "either typescript or flow must be specified as the third argument"
|
|
27
|
+
exit 1
|
|
17
28
|
fi
|
|
18
29
|
|
|
19
|
-
if [[
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
LANG=$3
|
|
30
|
+
if [[ "$SRC" = /* ]]; then
|
|
31
|
+
SRC_PATH="$SRC"
|
|
32
|
+
else
|
|
33
|
+
SRC_PATH="$PACKAGE_ROOT/$SRC"
|
|
24
34
|
fi
|
|
25
35
|
|
|
26
|
-
if [[ "$
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
36
|
+
if [[ "$DIST" = /* ]]; then
|
|
37
|
+
DIST_PATH="$DIST"
|
|
38
|
+
else
|
|
39
|
+
DIST_PATH="$PACKAGE_ROOT/$DIST"
|
|
30
40
|
fi
|
|
31
41
|
|
|
42
|
+
V1_TMP_PROTO="$DIST_PATH/messages-tmp.proto"
|
|
43
|
+
V2_TMP_PROTO="$PARENT_PATH/messages-protocol-v2-tmp.proto"
|
|
44
|
+
trap 'rm -f "$V1_TMP_PROTO" "$V2_TMP_PROTO"' EXIT
|
|
32
45
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
echo 'import "google/protobuf/descriptor.proto";' >> $DIST/messages.proto
|
|
38
|
-
echo "Build proto file from $SRC"
|
|
39
|
-
grep -hv -e '^import ' -e '^syntax' -e '^package' -e 'option java_' $SRC/messages*.proto \
|
|
46
|
+
echo "=== Building Protocol V1 messages ==="
|
|
47
|
+
echo 'syntax = "proto2";' > "$V1_TMP_PROTO"
|
|
48
|
+
echo 'import "google/protobuf/descriptor.proto";' >> "$V1_TMP_PROTO"
|
|
49
|
+
grep -hv -e '^import ' -e '^syntax' -e '^package' -e 'option java_' "$SRC_PATH"/messages*.proto \
|
|
40
50
|
| sed 's/ hw\.trezor\.messages\.common\./ /' \
|
|
41
51
|
| sed 's/ common\./ /' \
|
|
42
52
|
| sed 's/ ethereum_definitions\./ /' \
|
|
43
53
|
| sed 's/ management\./ /' \
|
|
44
54
|
| sed 's/^option /\/\/ option /' \
|
|
45
|
-
| grep -v ' reserved '>> $
|
|
55
|
+
| grep -v ' reserved ' >> "$V1_TMP_PROTO"
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
rm $DIST/messages.proto
|
|
57
|
+
npx pbjs -t json -p "$DIST_PATH" -o "$DIST_PATH/messages.json" --keep-case "$V1_TMP_PROTO"
|
|
58
|
+
cp "$DIST_PATH/messages.json" "$CORE_MESSAGES_DIR/messages.json"
|
|
50
59
|
|
|
51
|
-
echo "
|
|
60
|
+
echo "=== Building Protocol V2 messages ==="
|
|
61
|
+
SRC_PRO2_LEGACY="$REPO_ROOT/submodules/firmware-pro2/sys/protobuf/onekey_protocol/legacy"
|
|
62
|
+
SRC_PRO2_LATEST="$REPO_ROOT/submodules/firmware-pro2/sys/protobuf/onekey_protocol/latest"
|
|
52
63
|
|
|
53
|
-
|
|
64
|
+
if [[ ! -d "$SRC_PRO2_LEGACY" || ! -d "$SRC_PRO2_LATEST" ]]; then
|
|
65
|
+
echo "firmware-pro2 protobuf schema is missing"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
{
|
|
70
|
+
echo 'syntax = "proto2";'
|
|
71
|
+
echo 'import "google/protobuf/descriptor.proto";'
|
|
72
|
+
echo ''
|
|
73
|
+
grep -hv \
|
|
74
|
+
-e '^import ' -e '^syntax' -e '^package' -e 'option java_' \
|
|
75
|
+
"$SRC_PRO2_LEGACY"/messages*.proto \
|
|
76
|
+
| sed 's/ hw\.onekey\.messages\.[a-zA-Z_]*\./ /g' \
|
|
77
|
+
| sed 's/ crypto\./ /g' \
|
|
78
|
+
| sed 's/ ethereum_definitions\./ /g' \
|
|
79
|
+
| sed 's/ management\./ /g' \
|
|
80
|
+
| sed 's/^option /\/\/ option /' \
|
|
81
|
+
| grep -v ' reserved '
|
|
82
|
+
echo ''
|
|
83
|
+
echo '// --- Protocol V2 system messages ---'
|
|
84
|
+
grep -hv \
|
|
85
|
+
-e '^import ' -e '^syntax' -e '^package' -e 'option java_' -e '^option ' \
|
|
86
|
+
"$SRC_PRO2_LATEST"/messages*.proto \
|
|
87
|
+
| grep -v ' reserved '
|
|
88
|
+
} > "$V2_TMP_PROTO"
|
|
54
89
|
|
|
55
|
-
|
|
90
|
+
# Protocol V2 latest schema defines common request names that also exist in
|
|
91
|
+
# legacy chain messages. Keep the legacy definitions and remove the duplicate
|
|
92
|
+
# top-level latest declarations before protobufjs parses the flattened schema.
|
|
93
|
+
node - "$V2_TMP_PROTO" <<'NODE'
|
|
94
|
+
const fs = require('fs');
|
|
95
|
+
|
|
96
|
+
const protoPath = process.argv[2];
|
|
97
|
+
let proto = fs.readFileSync(protoPath, 'utf8');
|
|
98
|
+
|
|
99
|
+
function removeLastTopLevelMessage(source, name) {
|
|
100
|
+
const pattern = new RegExp(`(^|\\n)message\\s+${name}\\s*\\{`, 'gm');
|
|
101
|
+
const matches = Array.from(source.matchAll(pattern));
|
|
102
|
+
if (matches.length < 2) return source;
|
|
103
|
+
const match = matches[matches.length - 1];
|
|
104
|
+
const start = match.index + (match[1] ? match[1].length : 0);
|
|
105
|
+
let depth = 0;
|
|
106
|
+
for (let index = start; index < source.length; index += 1) {
|
|
107
|
+
if (source[index] === '{') depth += 1;
|
|
108
|
+
if (source[index] === '}') {
|
|
109
|
+
depth -= 1;
|
|
110
|
+
if (depth === 0) {
|
|
111
|
+
let end = index + 1;
|
|
112
|
+
while (end < source.length && /\\s/.test(source[end])) end += 1;
|
|
113
|
+
return `${source.slice(0, start)}${source.slice(end)}`;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
throw new Error(`Unterminated message block: ${name}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
['Initialize', 'GetFeatures', 'OnekeyGetFeatures', 'Features'].forEach(name => {
|
|
121
|
+
proto = removeLastTopLevelMessage(proto, name);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
fs.writeFileSync(protoPath, proto);
|
|
125
|
+
NODE
|
|
126
|
+
|
|
127
|
+
npx pbjs -t json -p "$PARENT_PATH" -o "$PACKAGE_ROOT/messages-protocol-v2.json" --keep-case "$V2_TMP_PROTO"
|
|
128
|
+
cp "$PACKAGE_ROOT/messages-protocol-v2.json" "$CORE_MESSAGES_DIR/messages-protocol-v2.json"
|
|
129
|
+
|
|
130
|
+
echo "generating type definitions for: $LANG"
|
|
131
|
+
cd "$PARENT_PATH"
|
|
132
|
+
node ./protobuf-types.js "$LANG"
|
|
56
133
|
|
|
57
|
-
yarn prettier --write messages.json
|
|
58
|
-
yarn prettier --write
|
|
134
|
+
yarn --cwd "$PACKAGE_ROOT" prettier --write "$DIST_PATH/messages.json"
|
|
135
|
+
yarn --cwd "$PACKAGE_ROOT" prettier --write "$CORE_MESSAGES_DIR/messages.json"
|
|
136
|
+
yarn --cwd "$PACKAGE_ROOT" prettier --write "$PACKAGE_ROOT/messages-protocol-v2.json"
|
|
137
|
+
yarn --cwd "$PACKAGE_ROOT" prettier --write "$CORE_MESSAGES_DIR/messages-protocol-v2.json"
|
|
138
|
+
yarn --cwd "$PACKAGE_ROOT" prettier --write "$PACKAGE_ROOT/src/types/messages.ts"
|
|
@@ -201,14 +201,10 @@ export class ProtocolV2Session {
|
|
|
201
201
|
router,
|
|
202
202
|
seq: protoSeq,
|
|
203
203
|
});
|
|
204
|
+
// 暂停输出 Protocol V2 TX 帧日志,避免传输层产生大量调试信息。
|
|
205
|
+
/*
|
|
204
206
|
const txMetadata = ProtocolV2.inspectFrame(schemas, frame);
|
|
205
207
|
|
|
206
|
-
if (maxFrameBytes !== undefined && frame.length > maxFrameBytes) {
|
|
207
|
-
throw new Error(
|
|
208
|
-
`Protocol V2 frame too large for transport: ${frame.length} > ${maxFrameBytes}`
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
208
|
if (!shouldReduceDebug) {
|
|
213
209
|
logger?.debug?.(`[${logPrefix}] TX`, {
|
|
214
210
|
method: name,
|
|
@@ -218,6 +214,13 @@ export class ProtocolV2Session {
|
|
|
218
214
|
bytes: frame.length,
|
|
219
215
|
});
|
|
220
216
|
}
|
|
217
|
+
*/
|
|
218
|
+
|
|
219
|
+
if (maxFrameBytes !== undefined && frame.length > maxFrameBytes) {
|
|
220
|
+
throw new Error(
|
|
221
|
+
`Protocol V2 frame too large for transport: ${frame.length} > ${maxFrameBytes}`
|
|
222
|
+
);
|
|
223
|
+
}
|
|
221
224
|
|
|
222
225
|
// Lenient watchdog on the write phase only — see
|
|
223
226
|
// PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS for the rationale.
|
|
@@ -248,6 +251,8 @@ export class ProtocolV2Session {
|
|
|
248
251
|
}
|
|
249
252
|
const isAck = ProtocolV2.isAckFrame(rxFrame);
|
|
250
253
|
if (!isAck) {
|
|
254
|
+
// 暂停输出 Protocol V2 RX 帧日志,避免传输层产生大量调试信息。
|
|
255
|
+
/*
|
|
251
256
|
const rxMetadata = ProtocolV2.inspectFrame(schemas, rxFrame);
|
|
252
257
|
|
|
253
258
|
if (!shouldReduceDebug) {
|
|
@@ -259,6 +264,7 @@ export class ProtocolV2Session {
|
|
|
259
264
|
bytes: rxFrame.length,
|
|
260
265
|
});
|
|
261
266
|
}
|
|
267
|
+
*/
|
|
262
268
|
|
|
263
269
|
const decoded = ProtocolV2.decodeFrame(schemas, rxFrame);
|
|
264
270
|
|
|
@@ -70,7 +70,10 @@ function messageToJSON(Message: Message<Record<string, unknown>>, fields: Type['
|
|
|
70
70
|
}
|
|
71
71
|
// message type
|
|
72
72
|
else if (field.resolvedType!.fields) {
|
|
73
|
-
|
|
73
|
+
// [compatibility]: absent optional sub-messages are not own properties
|
|
74
|
+
// of the decoded instance, so value is undefined here; decode them to
|
|
75
|
+
// null, matching the optional primitive-field convention above.
|
|
76
|
+
res[key] = value == null ? null : messageToJSON(value, (field.resolvedType as Type).fields);
|
|
74
77
|
} else {
|
|
75
78
|
throw new Error(`case not handled: ${key}`);
|
|
76
79
|
}
|