Repository navigation
fix(sdk-js): decode v0 hex strictly instead of silently truncating - #1347
Merged
Merged
Conversation
This was referenced Sep 24, 2026
kvinwang
force-pushed
the
fix/sdk-js-v0-strict-hex
branch
from
September 24, 2026 05:21
35ecac4 to
6d5cef9
Compare
Node's hex decoder stops at the first pair it cannot parse and returns the prefix, with no error. A `GetKey` response whose 64 valid digits are followed by junk therefore yielded a plausible 32-byte `key`, and `toViemAccount` turned that into a working account at an address nobody chose. Rust, Python and Go all refuse the identical response. v1 already guards this (`decode_hex` in `client-v1.ts`); the frozen v0 client never got the same treatment. Move v1's decoders into `shared.ts` -- which exists for exactly this -- and use them from both surfaces, so the two cannot drift again. Also from the same pass: a null or absent `signature_chain` threw a bare `TypeError: Cannot read properties of null (reading 'map')`, which names no field and reads like an SDK bug; and `info()` accepted a numeric `tcb_info`, because `JSON.parse` stringifies its argument, handing back `42` typed as `TcbInfo` with every `.mrtd` read `undefined`. Compat: this rejects three response shapes that previously returned a value -- malformed hex, a missing repeated field, and a non-string `tcb_info`. In every case the value returned was unusable (a truncated private key, an empty chain, a number typed as a struct), so no working application can depend on it. A well-formed response, an empty hex string and an empty chain are unchanged. `getKey`, `info` and `sign` now call `throwOnRpcError` like the rest of v0, so an RPC error response throws instead of being decoded as a result.
kvinwang
force-pushed
the
fix/sdk-js-v0-strict-hex
branch
from
September 24, 2026 05:21
6d5cef9 to
6fce643
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Buffer.from(s, 'hex')stops at the first invalid pair and returns the prefix without error. A v0GetKeyresponse with junk after valid digits yielded a truncated but plausible key, andtoViemAccountturned it into a working account at an address nobody chose. Rust, Python and Go all reject the same input.Also: a null
signature_chainthrew a bareTypeErrornaming no field, and a non-stringtcb_infowas returned typed asTcbInfo.Fix
Move v1's strict decoders (unchanged) into
shared.tsand use them from v0 as well.Compatibility
signature_chain, and a non-stringtcb_infonow throw. The values previously returned were unusable (a truncated private key, a number typed asTcbInfo).getKey,infoandsignnow callthrowOnRpcErrorlike the other v0 methods, so an RPC error response throws instead of being decoded as a result.Well-formed responses, empty hex and empty chains are unchanged.
Verification
sdk/js: 164 passed against the simulator (13 new).Split out of #1281.