Skip to content

v17.1.0

Choose a tag to compare

@Ryang-21 Ryang-21 released this 14 Sep 21:59
· 27 commits to main since this release
e07ded5

v17.1.0

Added

  • getClaimableBalanceIdFromResult(result, opIndex): reads the claimable balance ID created by a CreateClaimableBalance operation out of a submitted transaction's xdr.TransactionResult, unwrapping a fee bump when there is one. It returns the same 72-character hex form as Transaction.getClaimableBalanceId(opIndex), which derives the ID before submission; use this one when you only have the result. Horizon's result_xdr is base64, so decode it first with xdr.TransactionResult.fromXdr(result_xdr, "base64"), while rpc.Server.getTransaction already returns a parsed resultXdr. It throws a RangeError for an out-of-range opIndex, and a TypeError when result is not a transaction result, when the transaction failed, or when the operation at opIndex is not a successful CreateClaimableBalance (#1719).

Fixed

  • Generated TypeScript bindings keep the raw spec name for a function parameter or struct field that is a reserved word or not a valid identifier, instead of renaming it: since #1345 a parameter new was typed as new_ while the runtime read new, so the typed call threw Missing field new, and a typed struct read of a renamed field was undefined. Methods and deploy now take a single args object, set(args: { new: number }, options?); call sites are unchanged, callers who used a renamed key switch to the raw name (new_ to new, _1st to args["1st"]), method names still get the trailing _, and a __constructor with no inputs now generates deploy(null, options) instead of deploy(options) (#1733).
  • Horizon call builders now confine a resource identifier to one URL path segment, so a / in it no longer opens a new segment. An identifier that is empty, ., .., or not a string/number/bigint throws a TypeError instead of re-pointing the request at a different endpoint — accountId("") previously reached the collection endpoint and returned a page of records, and accountId([".."]) resolved to the server root. Affects accountId(), transaction(), operation(), offer(), claimableBalance(), ledger(), liquidityPoolId(), loadAccount() and the for*() neighbor filters; liquidityPoolId() was reachable the same way because its hex check is unanchored, which is tracked separately in #1703. A decimal number or bigint identifier still works, and well-formed identifiers are unaffected, since no valid Stellar identifier contains /, ., ? or # (#1702).
  • These TypeErrors are thrown synchronously from call() and stream() rather than as a rejected promise, which matches the existing Too many filters specified error, so a caller that only attaches .catch() needs a try/catch. Three cases sit outside that, all unchanged by this release: loadAccount() is async, so it rejects and .catch() does work; liquidityPools().liquidityPoolId() throws from the builder method; and ledgers().ledger() with the forLedger() filters coerce the sequence with toString() first, so a nullish sequence throws there rather than reaching this guard (#1702).
  • Templated Horizon _links functions now apply the call builders' path-segment guard to a path variable. One that is empty, ., .., or not a string/number/bigint throws a TypeError instead of re-pointing the request at a different endpoint: account.data({ key: ".." }) previously requested the account endpoint, not the data endpoint. Query values are unaffected. AccountResponse.data() and the server.root() links both take the path variable through an option TypeScript does not declare, so no call that compiles today changes behavior (#1718).
  • StellarToml.Resolver.resolve() now validates the domain and throws Invalid domain before making a request (#1720). It previously put the string straight into the URL, so some inputs reached a different host, or a different path, than the caller named. A domain must be a plain host name with an optional port: credentials and an embedded /, ?, # or \ are rejected, as is an empty domain. Surrounding whitespace and a trailing / are stripped rather than rejected, so input that worked before keeps working. Host names, IP literals, IPv6 literals, and ports still work, but the request URL is normalized, so ACME.com is requested as acme.com.
  • Asset.fromOperation preserves the assetTypeCreditAlphanum12 union arm even when the decoded code is four characters or shorter, instead of re-deriving the arm from code length. Such an asset now re-encodes to the same XDR bytes it was decoded from, and its getAssetType(), contractId(), equals(), and Asset.compare() results reflect the alphanum12 arm. equals() now also compares the asset type, so a decoded short-code alphanum12 asset is no longer equal to the alphanum4 asset with the same code and issuer. User-constructed assets are unaffected: new Asset(code, issuer) still derives the type from code length (#1584).
  • rpc.Server.getContractData no longer reports a transport failure as a missing entry. It previously caught every error from the ledger lookup and rethrew { code: 404 }, so a 429, a 5xx, or a network error looked the same as an absent entry. Those errors now propagate untouched, and only a lookup that returns no entry throws the 404-shaped error, whose shape is unchanged (#1679).

Changed

  • HorizonApi.Predicate gains the unconditional and abs_before_epoch fields it previously omitted, so the type now describes every predicate Horizon serves (#1701). It stays an interface, so declaration merging still works. One case does break at compile time: a consumer who already augmented the namespace to declare unconditional or abs_before_epoch with a different type than the SDK now uses gets TS2717 and must drop that part of their augmentation.
  • Updated the production axios dependency from 1.18.0 to 1.20.0 (#1712).

New Contributors

Full Changelog: v17.0.1...v17.1.0