V17 feature branch - #1580
Conversation
* feat(xdr): codegen tool + schema source * feat(xdr): add class-based XDR runtime and sep51 JSON walker * refactor(numbers): drop LargeInt classes, delegate to new XDR layer * refactor(base): migrate src/base to new XDR layer; drop legacy xdr.ts + generated * refactor: migrate downstream consumers (bindings/contract/horizon/rpc/webauth) * feat(base/scval): add bool to ScValType * allow opaque xdr types to be initalized via string * refactor xdr strings to be represented soley via bytes with a dx friendly XdrString wrapper class * generate a value getter function for void union cases * add a is() function to the generated XDR union classes for instanceOf checks * build: adopt @stellar/js-xdr v5 as an external dependency * feat(xdr): regenerate schemas against @stellar/js-xdr and add CAP-71 credentials * feat(xdr): wire the toJSON hook so JSON.stringify emits SEP-0051 * fix(bindings): emit Uint8Array for bytes/bytesN to match scValToNative * refactor(contract): rename fromJSON to fromJson with deprecated aliases * feat(xdr): accept ASCII asset codes with zero padding in constructors
* feat(base): migrate crypto and strkey APIs to Uint8Array * feat(base)!: migrate value types to Uint8Array * feat(base)!: migrate transactions, operations, and auth to Uint8Array * feat!: migrate contract, rpc, and webauth layers to Uint8Array * test: migrate tests off Buffer to Uint8Array * build!: drop buffer polyfill and dependency * docs: add Uint8Array migration guide and changelog entry * test: add coverage for Keypair to ensure seed copying instead of aliasing memory * docs: update changelog to clarify Uint8Array migration details * regen docs * test: update bindings snapshot for Uint8Array deploy signature * fix(horizon): type manage_data value as string to match runtime API * docs: add changelog entry for manage_data value type fix * docs: drop stale Buffer polyfill guidance for RN, Expo, and Workers
… ungated (#1576) * build(xdr): regenerate schema from stellar-xdr with CAP-83 and CAP-85 ungated * fix(xdr): keep consumers compiling against the regenerated union arms * ci(browser-tests): run each transport in its own job * fix(vitest): isolate browser dep cache per transport
…cutables (#1577) * build(xdr): fail the schema download instead of masking it in a pipe * feat(xdr): support CAP-83 and CAP-85 protocol values
…ode (#1581) * fix(xdr): bound decimal string length before BigInt parse in json decode * refactor(xdr): name the digit-budget constants in bigint-parts
#1582) * fix(xdr): restrict fromJson to SEP-51 keys and reject unknown fields * fix(test): correct horizon corpus fixture path so corpus tests run * test(xdr): add JSON round-trips for mainnet corpus values
* fix(strkey): validate signed payload framing in decodeCheck * docs: regenerate core-keys source line references * test(strkey): cover SEP-23 signed payload invalid vectors * docs(changelog): note signed payload strkey framing validation
…1589) * test(xdr): source the real-traffic corpus from both Horizon and RPC * Update comment Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix(xdr): throw on unknown union discriminant in fromXdrObject * test(xdr): cover the union dispatch guard across every union * fix(strkey): validate the claimable balance discriminant byte * fix(xdr): reject non-decimal integer strings in JSON decoding * test(xdr): assert JSON and XDR decoding reject the same values
* docs(changelog): rewrite the xdr breaking-change entry * docs(xdr): correct migration guide errors and link both guides * docs(xdr): document renames, optionals, removed exports, and errors * docs: link migration guides from readme, the source of docs/index.md * docs: index v17 migrations in the central migration guide * docs: update migration section wording for clarity * docs(xdr): apply review feedback on counts, aliases, and optionals * Update docs/index.md Co-authored-by: Iveta <quietbits@users.noreply.github.com> * V17.0.0 rc.1 (#1593) * docs(changelog): record sdk-level behavior changes from the xdr rebuild * chore(release): cut v17.0.0-rc.1 * test(e2e): restore test-contracts pointer lost in the #1579 merge * simplify rc tag for npm publish --------- Co-authored-by: Iveta <quietbits@users.noreply.github.com>
* feat(xdr): add validateXdr static to every generated type * docs(xdr): file validateXdr under renames, not removals
| * Enums are singletons, not factory calls: `xdr.ContractDataDurability.persistent()` becomes `xdr.ContractDataDurability.persistent`. | ||
| * Primitives are plain JS values. Integers are `number` or `bigint` instead of class wrappers, `LargeInt` subclasses are gone, byte fields are `Uint8Array`, and fields are `readonly`. | ||
| * Absent optional fields decode to `null` instead of `undefined`, so `=== undefined` checks silently stop matching. Prefer `== null`. | ||
| * Acronyms in method names collapse to single-initial-cap form, with no back-compat aliases. This reaches beyond the `xdr` namespace to the wrapper classes: `Transaction#toXDR()`, `TransactionBuilder.fromXDR()`, `Operation.fromXDRObject()`, `Asset#toXDRObject()`, `contract.AssembledTransaction#toXDR()` and others all gained the `Xdr` spelling. |
There was a problem hiding this comment.
why are some of these #s and some aren't?
| * Removed: `Reader` and `Writer`; the v4 runtime type constructors (`Hyper`, `UnsignedHyper`, `Option`, `Opaque`, `VarOpaque`, `XDRArray`, `XDRString`, `Bool`, `SignedInt`, `UnsignedInt`), plus top-level `Hyper` / `UnsignedHyper` / `cereal`; the `validateXDR()` static on every type (use `try`/`catch` around `fromXdr`); and `xdr.scvSortedMap` (use the top-level `scvSortedMap`). | ||
| * `ScInt` and `XdrLargeInt` lost their `.int` property; read `.value` (a `bigint`) instead, and note `valueOf()` now returns a `bigint`. | ||
|
|
||
| [`docs/XDR_MIGRATION.md`](./docs/XDR_MIGRATION.md) covers every change with before/after examples and a quick-reference table. |
There was a problem hiding this comment.
This should be earlier, either before the top-level bullet or first bullet and also bolded.
| [`docs/XDR_MIGRATION.md`](./docs/XDR_MIGRATION.md) covers every change with before/after examples and a quick-reference table. | ||
|
|
||
| * Rebuilding the XDR layer changed a few SDK-level behaviors that don't involve typing `xdr.` yourself. Most of these fail silently, so they won't surface as compile errors ([#1422](https://github.com/stellar/js-stellar-sdk/pull/1422)): | ||
| * `scValToNative` returns a `Uint8Array` for an `scvString` / `scvSymbol` whose contents aren't valid UTF-8. It previously always returned a string, substituting U+FFFD — its byte-returning branch was unreachable. Guards like `typeof result === "string"` and calls like `result.startsWith(...)` are now data-dependent. The same applies to `contract.Spec#scValToNative` and `#funcResToNative` for `Bytes` / `BytesN`, which return `Uint8Array`; those are generically typed, so TypeScript won't flag it. |
There was a problem hiding this comment.
whose contents aren't valid UTF-8
Symbol will always be UTF8
There was a problem hiding this comment.
Its not guaranteed since you can also provide bytes outside of the utf8 range
There was a problem hiding this comment.
Symbols are guaranteed by Core itself to always be in the range [A-Za-z_] or something like that.
There was a problem hiding this comment.
| [`docs/XDR_MIGRATION.md`](./docs/XDR_MIGRATION.md) covers every change with before/after examples and a quick-reference table. | ||
|
|
||
| * Rebuilding the XDR layer changed a few SDK-level behaviors that don't involve typing `xdr.` yourself. Most of these fail silently, so they won't surface as compile errors ([#1422](https://github.com/stellar/js-stellar-sdk/pull/1422)): | ||
| * `scValToNative` returns a `Uint8Array` for an `scvString` / `scvSymbol` whose contents aren't valid UTF-8. It previously always returned a string, substituting U+FFFD — its byte-returning branch was unreachable. Guards like `typeof result === "string"` and calls like `result.startsWith(...)` are now data-dependent. The same applies to `contract.Spec#scValToNative` and `#funcResToNative` for `Bytes` / `BytesN`, which return `Uint8Array`; those are generically typed, so TypeScript won't flag it. |
There was a problem hiding this comment.
It'd be cool and easy to link each of these methods to its docs URL since AI can prolly one-shot that. Not a blocker by any means but could be an easy readability win.
|
|
||
| * Rebuilding the XDR layer changed a few SDK-level behaviors that don't involve typing `xdr.` yourself. Most of these fail silently, so they won't surface as compile errors ([#1422](https://github.com/stellar/js-stellar-sdk/pull/1422)): | ||
| * `scValToNative` returns a `Uint8Array` for an `scvString` / `scvSymbol` whose contents aren't valid UTF-8. It previously always returned a string, substituting U+FFFD — its byte-returning branch was unreachable. Guards like `typeof result === "string"` and calls like `result.startsWith(...)` are now data-dependent. The same applies to `contract.Spec#scValToNative` and `#funcResToNative` for `Bytes` / `BytesN`, which return `Uint8Array`; those are generically typed, so TypeScript won't flag it. | ||
| * `Operation.fromXdrObject` decodes `manageData`'s `name`, `setOptions`'s `homeDomain`, and `revokeSponsorship`'s data-entry name as UTF-8 rather than ASCII. For any byte ≥ `0x80` the string differs (`[0xC3, 0xA9]` now decodes to `"é"`, was `"C)"`), so round-tripping a decoded name can produce different wire bytes. |
There was a problem hiding this comment.
Uhhhh don't like that.. why?
There was a problem hiding this comment.
Uh well the scValToNative claim about strings and symbols is just wrong I checked js-base and its always fallen back to return bytes when the utf8 decode failed.
The manageData entry is also stale. The strings provided for this operation get validated to be ascii so its not possible to get that different wire bytes when round-tripping
There was a problem hiding this comment.
Hmm okay fair enough, so it's just more correct in general
| built on js-xdr v5. Affects anyone who reads or builds `xdr.*` values, plus | ||
| anyone calling `tx.toXDR()` or `TransactionBuilder.fromXDR()`, which were | ||
| renamed. | ||
| - **[Uint8Array migration guide](/uint8array_migration/)** — `Buffer` → |
There was a problem hiding this comment.
The link looks weird, but it is correct if you generate the docs and run them
| | ------------------ | ------------------ | | ||
| | `UInt128Parts` | `Uint128Parts` | | ||
| | `UInt256Parts` | `Uint256Parts` | | ||
| | `ThresholdIndices` | `ThresholdIndexes` | |
There was a problem hiding this comment.
In an effort to conform to modern ts naming rules. FWIW the built in Uint8Array also uses this naming structure. The ThresholdIndices is one that I am genuinely confused on. Something in the old xdr-gen was manually changing it to this naming. The .x definitions spell it as ThresholdIndexes
There was a problem hiding this comment.
Yeah I was only commenting on that one. Indices seems more grammatically correct which is why I was confused, but it should def just match .x lol
| | `SorobanAuthorizationEntries` | array of `SorobanAuthorizationEntry` | `xdr.SorobanAuthorizationEntry[]` | | ||
| | `ScString`, `ScSymbol`, `String32`, `String64` | `XDRString` | `xdr.XdrString` (§ 11) | | ||
| | `SponsorshipDescriptor` | `undefined \| AccountId` | `xdr.AccountId \| null` (§ 14) | | ||
|
|
There was a problem hiding this comment.
Lotta these are kinda whack - what's wrong with ScVec and friends?
There was a problem hiding this comment.
Its not that theres anything wrong with them they just mostly don't do anything as a type. You get more info knowing that its an array
There was a problem hiding this comment.
Hmm yeah I guess so - too much indirection
| `new XdrLargeInt("u64", 1n << 64n)` throws a `RangeError`, as does a slice that | ||
| doesn't fit its width (e.g. `new XdrLargeInt("u128", [0n, 2n ** 80n])`). | ||
|
|
||
| ### `XdrLargeInt` and `ScInt` |
There was a problem hiding this comment.
Have you seen stellar/js-stellar-base#809? I don't think we should have both of these at all.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
* fix(xdr): restore wide-int MIN_VALUE/MAX_VALUE statics * docs(memo): record Memo.text dropping plain array input * docs(migration): record the three byte-input narrowings * Updated docs and changelog
No description provided.