- It decodes. Every fixture is real network data, including shapes that synthetic tests rarely build: fee-bumps wrapping muxed destinations, signed-payload signers, Soroban metadata.
- It re-encodes byte-for-byte. Decode, encode, compare. If the bytes differ, your SDK will compute the wrong transaction hash and sign something different from what it showed the user.
- The values are right. A decoder can round-trip perfectly and still hand your users a corrupted muxed ID. These checks compare what your SDK exposes against values taken from an independent source.
Get the corpus
You have two options, and for CI you want the first.- Vendor a pinned copy (recommended)
- Fetch from the hosted API
Pin a release so your tests only change when you decide they should. The fixtures are about 100 KB.Fixtures land in
tests/istravex/corpus/fixtures/<id>/, each with a manifest.json and one .xdr.b64 file per XDR value. Commit them, add them as a submodule, or fetch them in CI. Whichever you choose, bump the tag deliberately.The round-trip test
Each manifest lists its files and their XDR types. Decode each one with the matching type, encode it back, and compare it with the original base64.unknown xdr_type rather than skipping it. That’s deliberate: a silently skipped fixture is a test that passes while proving nothing.
Check the values that matter
Round-tripping proves your codec is symmetric. It doesn’t prove the values your SDK hands to application code are right. Each manifest’sexpected_decoded lists what a correct decoder must extract, with values taken from Horizon or from the transaction as it was built, never from an SDK under test.
The muxed-payment fixture is the one most worth automating, because the failure mode is silent: a 64-bit muxed ID passed through a float comes out close, and nobody notices until a deposit lands in the wrong customer’s account.
trust() call created (CAP-0073). The kit’s own runners check all of them and are the best reference for how: JavaScript, Go and Rust. Current results are on the SDK runners page.
Run it in CI
The vendored corpus makes this an ordinary unit test with no network access. If you went with the API instead, run it on a schedule rather than on every PR, so a newly published fixture opens an issue instead of blocking someone’s unrelated change..github/workflows/istravex.yml
When a check fails
- Decode fails. Your XDR definitions are probably behind the protocol version in the manifest’s
protocol_version. Regenerate from the matching stellar-xdr release. - Re-encode differs. Usually a union arm or optional field that’s normalized on encode. This one matters: it changes hashes and signatures.
- A value is wrong. Find the pattern in the hardening guide; each rule explains the mechanism and the fix.
- You think the fixture is wrong. Open an issue. Each manifest’s
sourcesays exactly where the bytes came from, and provenance explains how they were verified against the ledger that closed them.