Context
Soroban connectors must decode SCVal and ContractEvent XDR in-process, since Horizon is ruled out (ADR-0001). The XDR definitions are large and regenerate with every protocol release, so a hand-rolled fork would need a rebase each time and has already produced bugs elsewhere.
Decision
Decode SCVal with github.com/stellar/go-stellar-sdk/xdr, pinned in VERSIONS.md and go.mod.
internal/scvalis a thin wrapper that re-exportsscval.ScValandscval.ScMapEntryas aliases and holds the shared decode helpers; the lint allowlist in the Invariant bounds where elsexdrmay be imported.- The original limit of the SDK dependency to
.../xdrand.../strkeyis retired: the ingest path also uses the SDK's ledger, datastore and history-archive packages. - The SDK's own RPC client is not adopted. Production ingest reads Galexie MinIO LedgerCloseMeta, and
internal/stellarrpcsurvives only for therpc-probediagnostic and fixture capture (AGENTS.md invariant 6). - Rejected: a hand-rolled or vendored SCVal parser, a separate decoder process, and decoding stellar-rpc
getEventsJSON (it returns opaque base64 XDR).
Invariant
- The SDK version is pinned, and an upgrade that changes wire encoding fails
TestGolden_symbolBytesininternal/scval/scval_test.gobefore it ships. - The SDK
xdrpackage is imported only underinternal/scval/and the allowlist in lint ruleB/xdr-scoped-to-scval(scripts/ci/lint-imports.sh):internal/canonical/sac.goandasset_xdr.go,internal/ledgerstream/,archivecompleteness/,dispatcher/,pipeline/,storage/clickhouse/,xdrjson/,sdexclaim/,entrywalk/,ops/,stellarrpc/, the ledger-meta source packages (sdex,classicmovements,accounts,trustlines,claimable_balances,liquidity_pools,sac_balances,sep41_supply,sep41_transfers),cmd/stellarindex-indexer/,scripts/dev/and_test.gofiles. Any other package importsinternal/scvalinstead. - Decoders keep ADR-0003 amount safety across the decode path.
Consequences
Each protocol bump costs one pin change, not a fork rebase. The dependency graph grows by the SDK's indirect modules. Decoders depend on the internal/scval wrapper, so a different decoder could replace the SDK behind it.
Evidence
internal/scval/ and its golden test, scripts/ci/lint-imports.sh rule B/xdr-scoped-to-scval, per-venue decode_test.go files with captured fixtures under test/fixtures/, and VERSIONS.md.