SPIKE: Protocol 27 — CAP-71 + CAP-83 XDR regen#972
Draft
sisuresh wants to merge 4 commits into
Draft
Conversation
- Bump XDR_BASE_URL_{CURR,NEXT} to 5187e69 (CAP-71+CAP-83 .x).
- Add 'stellar-xdr xfile preprocess --features CAP_0071,CAP_0083' step
before Ruby xdrgen (Ruby xdrgen does not parse #ifdef; rs-stellar-xdr stellar#503
is the canonical preprocessor).
- Drop 'docker run -it' for CI-friendliness; switch dts-xdr base to
node:lts-alpine + install yarn.
- Regenerated src/generated/curr_generated.js + next_generated.js +
types/curr.d.ts with CAP-71-02 (SOROBAN_CREDENTIALS_ADDRESS_V2,
HashIdPreimageSorobanAuthorizationWithAddress), CAP-71-01
(SorobanAddressCredentialsWithDelegates, SorobanDelegateSignature),
and CAP-83 (STELLAR_VALUE_EMPTY_TX_SET).
Used to e2e-test the CAP-71 tx rendering in stellar-laboratory.
The xdrgen master JS generator no longer emits explicit `var` decls for
xdr.const, but @stellar/js-xdr's TypeBuilder.const() does not inject the
identifier into the calling scope. Bare references like
`xdr.string(SCSYMBOL_LIMIT)` then ReferenceError at runtime.
This commit re-injects them in src/generated/{curr,next}_generated.js and
documents the post-process step in the Makefile. Restores the runtime
behavior of the released v15.0.0 (which had explicit `var` decls in its
published output).
This was referenced May 28, 2026
The prior commit (4e362da) injected 'var <NAME> = <value>;' at the top of each generated IIFE so xdrgen master's bare-identifier 'xdr.string(NAME)' pattern would resolve. That works in unminified dev builds but terser DCE strips the var declarations from the production browser dist, leaving the bare identifiers unbound (ReferenceError: SCSYMBOL_LIMIT is not defined inside dist/stellar-base.min.js at runtime). This commit: 1. Moves the post-process from an unreadable Makefile one-liner to scripts/post-process-generated.py. 2. Switches the approach: instead of injecting 17 var declarations (which terser drops), substitute every bare-identifier usage with the literal value (xdr.string(SCSYMBOL_LIMIT) -> xdr.string(32)). There's no identifier for terser to drop. 3. As a side effect, the diff against upstream/master shrinks: only constants that are actually referenced as bare identifiers downstream (SCSYMBOL_LIMIT, SC_SPEC_DOC_LIMIT) appear in the diff now. Constants like MASK_ACCOUNT_FLAGS that are only referenced via xdr.lookup("NAME") string lookups stay untouched. Long-term fix belongs upstream — either xdrgen should re-emit explicit var declarations the way the v15.0.0 release did, or @stellar/js-xdr's TypeBuilder.const() should attach the identifier to a scope terser can see. This post-process is a stopgap.
…er uses Looking at upstream/master's curr_generated.js, the maintainers patch the file by hand after every regen with: // Workaround for stellar/xdrgen#152 const SCSYMBOL_LIMIT = 32; const SC_SPEC_DOC_LIMIT = 1024; inserted at the top of the IIFE. The bare 'xdr.string(SCSYMBOL_LIMIT)' patterns xdrgen master emits then resolve to those IIFE-scope const declarations at runtime. This is the same pattern upstream uses; the inline-consts post-process I added in d00b392 was unnecessary scope. This commit: 1. Drops scripts/post-process-generated.py (added in d00b392). 2. Restores the Makefile to just curl + 'stellar-xdr xfile preprocess' (no post-process-generated target). 3. Regenerates src/generated/{curr,next}_generated.js cleanly and inserts the 2-line workaround block at the IIFE top, mirroring upstream master. Net effect: the PR diff shrinks substantially. The only changes beyond the CAP-71+83 XDR types are now: - Makefile: bump XDR_BASE_URL_{CURR,NEXT}, add 'stellar-xdr xfile preprocess' step before xdrgen, drop 'docker run -it', switch dts-xdr container to node:lts-alpine + apk add yarn. - The 2-line xdrgen#152 workaround block (mirroring upstream).
Shaptic
reviewed
May 29, 2026
Comment on lines
597
to
+600
| case SOROBAN_CREDENTIALS_ADDRESS: | ||
| SorobanAddressCredentials address; | ||
| case SOROBAN_CREDENTIALS_ADDRESS_V2: | ||
| SorobanAddressCredentials addressV2; |
Contributor
There was a problem hiding this comment.
I'm confused about what makes V2 actually a V2 if it's using the exact same struct type for that branch. Is this a generator bug?
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.
What this changes
Makefile: bump
XDR_BASE_URL_{CURR,NEXT}to5187e69(the Protocol 27 .x with CAP-71 + CAP-83). Add a `stellar-xdr xfile preprocess --features CAP_0071,CAP_0083` step before the Ruby xdrgen invocation, because Ruby xdrgen does not parse `#ifdef CAP_` directives — stellar/rs-stellar-xdr#503 is the canonical preprocessor. Drop `docker run -it` (breaks non-TTY). Switch the dts-xdr container from `node:alpine` to `node:lts-alpine` and `apk add yarn` (newer alpine no longer bundles yarn).Source post-process (the experimental workaround): inline each `xdr.const("", )` value at every bare-identifier usage site (`xdr.string(SCSYMBOL_LIMIT)` → `xdr.string(32)`). xdrgen master no longer emits the `var = ;` declarations the released v15.0.0 had, and `@stellar/js-xdr`'s `TypeBuilder.const()` doesn't inject the identifier into the calling scope. The obvious patch (re-inject the `var` decls) works in unminified dev builds but terser tree-shakes them out of the production browser dist, leaving bare identifiers at runtime. Inlining the literal is the only fix that survives minification.
Regenerated `src/generated/{curr,next}_generated.js` + `types/curr.d.ts` with CAP-71-02 (`SOROBAN_CREDENTIALS_ADDRESS_V2`, `HashIdPreimageSorobanAuthorizationWithAddress`), CAP-71-01 (`SorobanAddressCredentialsWithDelegates`, `SorobanDelegateSignature`), and CAP-83 (`STELLAR_VALUE_EMPTY_TX_SET`).
Verification
Decoded a live CAP-71-01 envelope all the way through `xdr.TransactionEnvelope.fromXDR` → `sorobanCredentialsAddressWithDelegates` → root contract address → 1 `SorobanDelegateSignature` → `scvVec` delegate sig, in both Node and the browser-bundled (terser-minified) `dist/stellar-base.min.js`. Then end-to-end through js-stellar-sdk → laboratory to render the transaction view in lab.
Why this should not be merged as-is
Related experiments
Source: pod-fsr#33 — full-stack CAP spike workflow exploration.