Releases · lightsail-network/java-stellar-sdk · GitHub
Skip to content

Releases: lightsail-network/java-stellar-sdk

5.0.0

Choose a tag to compare

@overcat overcat released this 01 Sep 09:14
ce6f88f

This release adds support for Protocol 28.

Breaking changes

  • feat!: CAP-71 SOROBAN_CREDENTIALS_ADDRESS_V2 credentials are now the default on both ends of the authorization flow — the entries this SDK builds, and the entries it asks RPC to record during simulation. (#815)
    • Auth.authorizeInvocation builds ADDRESS_V2 entries. The credentialsType overloads are the legacy opt-out: pass SOROBAN_CREDENTIALS_ADDRESS for the pre-CAP-71 format.
    • SorobanServer.simulateTransaction sends useUpgradedAuth: true, so simulation records ADDRESS_V2 entries. Pass false to the four-argument overload for the legacy format. The same default flows through SorobanServer.prepareTransaction, ContractClient.invoke, and AssembledTransaction.simulate, each of which has its own useUpgradedAuth opt-out.
    • Sep45Challenge.buildChallengeAuthorizationEntries follows the new default too, so on a protocol 27 network the challenge it hands to the client carries ADDRESS_V2 entries. This flip is felt by the client signing the challenge rather than by the anchor calling the SDK, and SEP-45 does not specify a credential format, so it has its own useUpgradedAuth opt-out for anchors serving clients whose SDK predates CAP-71. Challenge parsing and verification accept both credential arms either way.
    • There is no need to migrate the moment protocol 27 activates. ADDRESS_V2 entries are only valid on networks that have activated CAP-71 (protocol 27), and the legacy SOROBAN_CREDENTIALS_ADDRESS type stays valid until protocol 28 — use the opt-outs until the signing clients are ready.
    • useUpgradedAuth is transitional: once RPC records ADDRESS_V2 credentials by default (protocol 28) it becomes a no-op, so do not rely on passing false to keep receiving the legacy format.
    • Code that reads the credential arm by hand must handle getAddressV2() and not just getAddress(), or use Auth.getAddressCredentials, which extracts the inner SorobanAddressCredentials from any address-based arm.
    • A hand-rolled signer that hardcodes the legacy ENVELOPE_TYPE_SOROBAN_AUTHORIZATION preimage now produces signatures the network rejects — build the payload with Auth.buildAuthorizationEntryPreimage, which picks the address-bound preimage off the entry. SDK-driven signing (Auth.authorizeEntry, AssembledTransaction.signAuthEntries, ContractClient) needs no change.

Update

  • feat: add CAP-85 external executable reference support. A contract instance can now hold a CONTRACT_EXECUTABLE_EXTERNAL_REF executable — an owner contract plus an owner-scoped tag — instead of its own Wasm hash. The owner publishes the Wasm hash in a persistent contract data entry keyed by SCV_EXECUTABLE_TAG(tag), so it can upgrade every contract referencing that tag at once. (#817)
    • New SorobanServer.getExternalRefWasmHash(ContractExecutableExternalRef) resolves a reference to the 32-byte Wasm hash it names, with a single getLedgerEntries call; the owner contract is not invoked.
    • SorobanServer.getContractWasm — and so getContractMeta, getContractSpec, and getContractInfo — follows an external reference automatically, at the cost of that one extra request.
    • New ExternalRefNotFoundException (a ContractIntrospectionException) is thrown when the tag entry is missing or archived. An unresolvable reference — one whose owner is not a contract, say, since only a contract can hold the tag entry — is rejected before any request is made: getExternalRefWasmHash throws IllegalArgumentException, where the reference is the caller's own argument, while getContractWasm reports it as ContractWasmRetrievalException, where it came off the ledger instead. Every getContractWasm failure therefore stays catchable as ContractIntrospectionException.
    • New InvokeHostFunctionOperation.createContractFromExternalRefOperationBuilder(...) builds a CREATE_CONTRACT_V2 operation that deploys from a reference instead of a Wasm hash, taking the owner contract plus a String or byte[] tag.
    • New Scv.toExecutableTag(String) / Scv.toExecutableTag(byte[]) / Scv.fromExecutableTag(SCVal) for the SCV_EXECUTABLE_TAG value. A tag is an unbounded SCString that need not be valid UTF-8 and identifies the code being deployed, so it is never decoded leniently: fromExecutableTag returns raw bytes, ledger keys are built from the original bytes, and binary tags are passed through undecoded.
    • New Util.decodeUtf8(byte[]) returns Optional<String> — the text when the bytes are valid UTF-8, empty otherwise. Use it to display a tag, falling back to the raw bytes, instead of a lenient decode that would render two distinct tags identically.
    • ScvComparator orders the new SCV_EXECUTABLE_TAG value (lexicographic unsigned bytes) and the new executable arm (by owner, then tag), so a contract instance holding an external reference sorts correctly.
    • CAP-85 requires protocol 28. On an earlier network the new executable arm is not accepted, so deploying from a reference fails at submission; the read paths never encounter one, since no contract can hold a reference there.
  • feat: add useUpgradedAuth opt-outs at every layer that simulates: SorobanServer.prepareTransaction(Transaction, boolean), AssembledTransaction.simulate(boolean, boolean), and the ContractClient.invoke overload taking useUpgradedAuth. Derived transactions inherit the choice — the restore transaction AssembledTransaction builds during automatic restoration simulates with the same flag rather than falling back to the default. (#815)
  • feat: add a useUpgradedAuth opt-out to Sep45Challenge.buildChallengeAuthorizationEntries. SEP-45 does not specify a credential format, and the challenge entries are signed by a remote client rather than by the caller, so an anchor serving clients whose SDK cannot sign the address-bound payload can pass false to keep issuing legacy challenges. (#815)
  • chore: upgrade generated XDR definitions to Protocol 28. (#816)

4.0.1

Choose a tag to compare

@overcat overcat released this 16 Jul 09:10
ba6e281

Update

  • fix: allow extendTo to be 0 in ExtendFootprintTTLOperation. (#810)

4.0.0

Choose a tag to compare

@overcat overcat released this 04 Jul 00:46
3836471

This release contains everything from 4.0.0-beta0, plus the changes made since. Below is the changelog since 3.1.0.

Breaking changes

  • refactor: redesign Auth.Signer to natively support custom account contracts (BLS, WebAuthn / secp256r1, threshold, policy contracts, ...). (#806)

    • Auth.Signer.sign now returns the signature SCVal accepted by the account contract at the credential node being signed — the default Stellar Account shape for a G... account, or whatever a custom account contract's __check_auth expects — instead of an Auth.Signature. The returned value is attached verbatim. This also unlocks signing a custom-contract delegate node of a SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES entry (CAP-71-01).
    • Auth.Signature has been removed.
    • Client-side ed25519 signature verification inside authorizeEntry is removed; the network performs the authoritative check via the account contract's __check_auth (a null return from a Signer is still rejected).
    • Auth.authorizeInvocation(Signer, ...): the publicKey parameter is renamed to address (it already accepted C... contract addresses).
    • New Auth.authorizationPayloadHash(HashIDPreimage) returns the 32-byte payload an account contract receives in __check_auth.
    • New Auth.defaultAccountSignatureScVal builds the default Stellar Account signature shape (Vec<Map{public_key, signature}>), the building block for ed25519 Signers that sign via an HSM or remote service. Two overloads accept either the raw byte[] ed25519 public key or a G... accountId. The KeyPair overloads are unchanged and produce byte-identical output.

    Migration for a custom (non-KeyPair) Signer targeting a classic G... account:

    // before
    Auth.Signer signer =
        preimage -> {
          byte[] payload = Util.hash(preimage.toXdrByteArray());
          return new Auth.Signature(accountId, signRemotely(payload));
        };
    
    // after
    Auth.Signer signer =
        preimage ->
            Auth.defaultAccountSignatureScVal(
                accountId, signRemotely(Auth.authorizationPayloadHash(preimage)));

Update

  • feat: add CAP-0071 (Protocol 27) Soroban authorization support. (#804)
    • New credential types (from the Protocol 27 XDR):
      • SOROBAN_CREDENTIALS_ADDRESS_V2 (CAP-71-02) — same fields as the legacy ADDRESS, but the signed payload is bound to the signer's address.
      • SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES (CAP-71-01) — delegated / multi-party signing via a (possibly nested) tree of delegate signatures.
    • Auth.authorizeEntry:
      • Signs all three address-based credential types, selecting the signature payload from the credential type: legacy ADDRESS keeps the non-address-bound preimage; ADDRESS_V2 and ADDRESS_WITH_DELEGATES sign the new address-bound ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS preimage.
      • Gains an optional forAddress parameter that writes the signature into a specific (possibly nested) delegate node. All signers of one delegated entry sign the same payload, bound to the top-level address.
    • Auth.authorizeInvocation:
      • Still builds legacy ADDRESS entries by default, so its output stays valid on every network regardless of protocol 27 activation.
      • New credentialsType overloads opt in to ADDRESS_V2. The default will flip to V2 once Protocol 28 makes it mandatory.
    • New helpers in Auth:
      • buildAuthorizationEntryPreimage — builds the exact payload a signer must sign for a given entry.
      • buildWithDelegatesEntry / Auth.DelegateSignature — wrap an ADDRESS/ADDRESS_V2 entry together with delegate signers, sorting each delegates level by address and rejecting duplicates, as the protocol requires.
      • getAddressCredentials — extracts the inner SorobanAddressCredentials from any address-based credential type.
    • AssembledTransaction: signAuthEntries and needsNonInvokerSigningBy handle all address-based credential types.
    • SEP-45 (Sep45Challenge):
      • Challenge parsing and building accept ADDRESS_V2 entries in addition to the legacy type; delegated entries are rejected.
      • Challenge building fails fast on unsupported credential types instead of passing the entries through unsigned.
  • feat: add useUpgradedAuth to SorobanServer.simulateTransaction, mapping to the useUpgradedAuth flag from Stellar RPC v27.1.0 to opt simulation into recording ADDRESS_V2 (CAP-71) auth credentials. Best-effort and transitional; older RPC servers ignore it. (#807)
  • chore: upgrade generated XDR definitions to Protocol 27. (#800)
  • chore: update dependencies and build tooling to the latest compatible versions (Gradle 9.6.1, Kotlin 2.4.0, Spotless plugin 8.7.0, Lombok plugin 9.5.0, NMCP plugin 1.6.0, Gson 2.14.0, Commons Codec 1.22.0). (#808)

4.0.0-beta0

4.0.0-beta0 Pre-release
Pre-release

Choose a tag to compare

@overcat overcat released this 17 Jun 07:48
d9632c9

Update

  • chore: upgrade generated XDR definitions to Protocol 27. (#800)
  • feat: add CAP-0071 (Protocol 27) Soroban authorization support. (#804)
    • New credential types (from the Protocol 27 XDR):
      • SOROBAN_CREDENTIALS_ADDRESS_V2 (CAP-71-02) — same fields as the legacy ADDRESS, but the signed payload is bound to the signer's address.
      • SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES (CAP-71-01) — delegated / multi-party signing via a (possibly nested) tree of delegate signatures.
    • Auth.authorizeEntry:
      • Signs all three address-based credential types, selecting the signature payload from the credential type: legacy ADDRESS keeps the non-address-bound preimage; ADDRESS_V2 and ADDRESS_WITH_DELEGATES sign the new address-bound ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS preimage.
      • Gains an optional forAddress parameter that writes the signature into a specific (possibly nested) delegate node. All signers of one delegated entry sign the same payload, bound to the top-level address.
    • Auth.authorizeInvocation:
      • Still builds legacy ADDRESS entries by default, so its output stays valid on every network regardless of protocol 27 activation.
      • New credentialsType overloads opt in to ADDRESS_V2. The default will flip to V2 once Protocol 28 makes it mandatory.
    • New helpers in Auth:
      • buildAuthorizationEntryPreimage — builds the exact payload a signer must sign for a given entry.
      • buildWithDelegatesEntry / Auth.DelegateSignature — wrap an ADDRESS/ADDRESS_V2 entry together with delegate signers, sorting each delegates level by address and rejecting duplicates, as the protocol requires.
      • getAddressCredentials — extracts the inner SorobanAddressCredentials from any address-based credential type.
    • AssembledTransaction: signAuthEntries and needsNonInvokerSigningBy handle all address-based credential types.
    • SEP-45 (Sep45Challenge):
      • Challenge parsing and building accept ADDRESS_V2 entries in addition to the legacy type; delegated entries are rejected.
      • Challenge building fails fast on unsupported credential types instead of passing the entries through unsigned.

3.1.0

Choose a tag to compare

@overcat overcat released this 12 Jun 01:02
88063c0

Update

  • fix: make RootRequestBuilder request the Horizon root endpoint as / instead of the percent-encoded /%2F path. (#801)
  • fix: make Horizon request builder URL generation idempotent so repeated buildUri() or execute() calls on the same builder do not duplicate path segments. (#798)
  • docs: add an Agent Skill for the Java Stellar SDK under skills/, plus Claude Code plugin manifests in .claude-plugin/. The skill gives AI coding agents concise, Stellar-specific guidance (transactions, operations, Horizon, Soroban, XDR/SCVal, and SEP protocols) when generating application code with stellar-sdk. (#797)
  • feat: add SEP-0046, SEP-0047, and SEP-0048 contract introspection support. New ContractMeta, ContractSpec, and ContractInfo wrappers under org.stellar.sdk.contract parse contract Wasm metadata and interface specs locally. SorobanServer adds getContractWasm, getContractWasmByHash, getContractMeta, getContractSpec, and getContractInfo for RPC-backed retrieval. (#796)

3.0.0

Choose a tag to compare

@overcat overcat released this 22 Apr 03:59
19b2601

This release contains the exact same content as 3.0.0-beta1. Below is the changelog since 2.2.3.

Update

  • fix: use OkHttp's public SSE factory for Horizon streams and force SSE requests to bypass caches. (#791)
  • feat: sort ScMap entries by key in Scv.toMap following Soroban runtime ordering rules, as the network requires ScMap keys to be in ascending order. Scv.toMap now accepts Map<SCVal, SCVal>; the previous toMap(LinkedHashMap<SCVal, SCVal>) overload is deprecated. (#766)
  • feat: add SEP-0051 support. (#774)
  • feat: add closeTime, headerXdr, and metadataXdr to GetLatestLedgerResponse. (#768)
  • chore: update various dependencies to the latest compatible versions. (#786, #790)
  • docs: add more detailed API and XDR generator documentation. (#783, #784)
  • chore: building the project from source now requires JDK 21 and Gradle 9.4.1. Published SDK artifacts still target Java 8 bytecode. (#788, #789)
  • chore: bump generated XDR definitions to stellar-xdr v26.0, including the v25.0 changes introduced earlier in this release cycle. (#769, #781)

Breaking changes

  • refactor!: remove deprecated StrKey helpers encodeEd25519PublicKey(AccountID), encodeMuxedAccount(MuxedAccount), decodeMuxedAccount(String), encodeToXDRAccountId(String), and encodeToXDRMuxedAccount(String); use StrKey.encodeEd25519PublicKey(byte[]), org.stellar.sdk.MuxedAccount, and KeyPair#getXdrAccountId() instead. (#779)

3.0.0-beta1

3.0.0-beta1 Pre-release
Pre-release

Choose a tag to compare

@overcat overcat released this 22 Apr 02:17

Update

  • chore: re-release of 3.0.0-beta0; no SDK changes. The prior tag failed to reach Maven Central because the release workflow still invoked the old publishAggregationToCentralPortal task name after the nmcp plugin switch.

3.0.0-beta0

3.0.0-beta0 Pre-release
Pre-release

Choose a tag to compare

@overcat overcat released this 22 Apr 01:27
fc16db3

Update

  • fix: use OkHttp's public SSE factory for Horizon streams and force SSE requests to bypass caches. (#791)
  • feat: sort ScMap entries by key in Scv.toMap following Soroban runtime ordering rules, as the network requires ScMap keys to be in ascending order. Scv.toMap now accepts Map<SCVal, SCVal>; the previous toMap(LinkedHashMap<SCVal, SCVal>) overload is deprecated. (#766)
  • feat: add SEP-0051 support. (#774)
  • feat: add closeTime, headerXdr, and metadataXdr to GetLatestLedgerResponse. (#768)
  • chore: update various dependencies to the latest compatible versions. (#786, #790)
  • docs: add more detailed API and XDR generator documentation. (#783, #784)
  • chore: building the project from source now requires JDK 21 and Gradle 9.4.1. Published SDK artifacts still target Java 8 bytecode. (#788, #789)
  • chore: bump generated XDR definitions to stellar-xdr v26.0, including the v25.0 changes introduced earlier in this release cycle. (#769, #781)

Breaking changes

  • refactor!: remove deprecated StrKey helpers encodeEd25519PublicKey(AccountID), encodeMuxedAccount(MuxedAccount), decodeMuxedAccount(String), encodeToXDRAccountId(String), and encodeToXDRMuxedAccount(String); use StrKey.encodeEd25519PublicKey(byte[]), org.stellar.sdk.MuxedAccount, and KeyPair#getXdrAccountId() instead. (#779)

2.2.3

Choose a tag to compare

@overcat overcat released this 22 Feb 10:26
64abf03

Update

  • fix: replace commons-codec Hex with pure-Java implementation in Util to fix NoSuchMethodError crash on Android API 24-27. (#763)
  • refactor!: remove InvokeHostFunctionOperation.createStellarAssetContractOperationBuilder(Address, byte[]), use InvokeHostFunctionOperation.createContractOperationBuilder instead. (#764)

2.2.2

Choose a tag to compare

@overcat overcat released this 03 Feb 23:53
15ca931

Update

  • fix: add stricter validation for Ed25519 Signed Payload. (#751)
  • fix: replace assert statements with explicit null checks in Federation class to ensure validation is not bypassed when assertions are disabled. (#752)
  • fix: add overflow check in TimeBounds.expiresAfter() to prevent integer overflow when timeout is too large. (#753)
  • fix: add validation for ManageDataOperation value length to ensure it does not exceed 64 bytes. (#754)
  • fix: use StandardCharsets.UTF_8 explicitly when converting byte arrays to strings to ensure consistent behavior across different platforms. (#756)
  • refactor: use static initialization for GsonSingleton to ensure thread safety. (#757)
  • fix: use commons-codec for hex encoding/decoding in Util class to properly validate input and throw clear exceptions for invalid hex strings. (#758)
  • fix: improve XDR decoding security and correctness. (#759)
    • Add decoding depth limit to prevent stack overflow (default: 200)
    • Add input length tracking to prevent DoS via oversized allocations
    • Validate variable-length array/opaque/string sizes before allocation
    • Validate variable-length types don't exceed declared max size
    • Validate fixed-length opaque/array sizes match declared size
    • Fix short read handling for opaque/string with proper padding
    • Remove incorrect auto-padding from read(byte[], int, int)
    • Reject unknown union discriminant values when no default arm
    • Validate boolean/optional flags are strictly 0 or 1 per RFC 4506
    • Fix EOF handling in single-byte read
    • Deprecate unsafe readIntArray/readFloatArray/readDoubleArray methods
  • fix: prevent DoS attacks in Federation by limiting stellar.toml and federation response sizes to 100KB, adding proper timeouts, and handling UTF-8 BOM. (#760)