{{ message }}
Releases: lightsail-network/java-stellar-sdk
Releases · lightsail-network/java-stellar-sdk
Release list
5.0.0
This release adds support for Protocol 28.
Breaking changes
- feat!: CAP-71
SOROBAN_CREDENTIALS_ADDRESS_V2credentials 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.authorizeInvocationbuildsADDRESS_V2entries. ThecredentialsTypeoverloads are the legacy opt-out: passSOROBAN_CREDENTIALS_ADDRESSfor the pre-CAP-71 format.SorobanServer.simulateTransactionsendsuseUpgradedAuth: true, so simulation recordsADDRESS_V2entries. Passfalseto the four-argument overload for the legacy format. The same default flows throughSorobanServer.prepareTransaction,ContractClient.invoke, andAssembledTransaction.simulate, each of which has its ownuseUpgradedAuthopt-out.Sep45Challenge.buildChallengeAuthorizationEntriesfollows the new default too, so on a protocol 27 network the challenge it hands to the client carriesADDRESS_V2entries. 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 ownuseUpgradedAuthopt-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_V2entries are only valid on networks that have activated CAP-71 (protocol 27), and the legacySOROBAN_CREDENTIALS_ADDRESStype stays valid until protocol 28 — use the opt-outs until the signing clients are ready. useUpgradedAuthis transitional: once RPC recordsADDRESS_V2credentials by default (protocol 28) it becomes a no-op, so do not rely on passingfalseto keep receiving the legacy format.- Code that reads the credential arm by hand must handle
getAddressV2()and not justgetAddress(), or useAuth.getAddressCredentials, which extracts the innerSorobanAddressCredentialsfrom any address-based arm. - A hand-rolled signer that hardcodes the legacy
ENVELOPE_TYPE_SOROBAN_AUTHORIZATIONpreimage now produces signatures the network rejects — build the payload withAuth.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_REFexecutable — 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 bySCV_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 singlegetLedgerEntriescall; the owner contract is not invoked. SorobanServer.getContractWasm— and sogetContractMeta,getContractSpec, andgetContractInfo— follows an external reference automatically, at the cost of that one extra request.- New
ExternalRefNotFoundException(aContractIntrospectionException) 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:getExternalRefWasmHashthrowsIllegalArgumentException, where the reference is the caller's own argument, whilegetContractWasmreports it asContractWasmRetrievalException, where it came off the ledger instead. EverygetContractWasmfailure therefore stays catchable asContractIntrospectionException. - New
InvokeHostFunctionOperation.createContractFromExternalRefOperationBuilder(...)builds aCREATE_CONTRACT_V2operation that deploys from a reference instead of a Wasm hash, taking the owner contract plus aStringorbyte[]tag. - New
Scv.toExecutableTag(String)/Scv.toExecutableTag(byte[])/Scv.fromExecutableTag(SCVal)for theSCV_EXECUTABLE_TAGvalue. A tag is an unboundedSCStringthat need not be valid UTF-8 and identifies the code being deployed, so it is never decoded leniently:fromExecutableTagreturns raw bytes, ledger keys are built from the original bytes, and binary tags are passed through undecoded. - New
Util.decodeUtf8(byte[])returnsOptional<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. ScvComparatororders the newSCV_EXECUTABLE_TAGvalue (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.
- New
- feat: add
useUpgradedAuthopt-outs at every layer that simulates:SorobanServer.prepareTransaction(Transaction, boolean),AssembledTransaction.simulate(boolean, boolean), and theContractClient.invokeoverload takinguseUpgradedAuth. Derived transactions inherit the choice — the restore transactionAssembledTransactionbuilds during automatic restoration simulates with the same flag rather than falling back to the default. (#815) - feat: add a
useUpgradedAuthopt-out toSep45Challenge.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 passfalseto keep issuing legacy challenges. (#815) - chore: upgrade generated XDR definitions to Protocol 28. (#816)
4.0.1
4.0.0
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.Signerto natively support custom account contracts (BLS, WebAuthn / secp256r1, threshold, policy contracts, ...). (#806)Auth.Signer.signnow returns the signatureSCValaccepted by the account contract at the credential node being signed — the default Stellar Account shape for aG...account, or whatever a custom account contract's__check_authexpects — instead of anAuth.Signature. The returned value is attached verbatim. This also unlocks signing a custom-contract delegate node of aSOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATESentry (CAP-71-01).Auth.Signaturehas been removed.- Client-side ed25519 signature verification inside
authorizeEntryis removed; the network performs the authoritative check via the account contract's__check_auth(anullreturn from aSigneris still rejected). Auth.authorizeInvocation(Signer, ...): thepublicKeyparameter is renamed toaddress(it already acceptedC...contract addresses).- New
Auth.authorizationPayloadHash(HashIDPreimage)returns the 32-byte payload an account contract receives in__check_auth. - New
Auth.defaultAccountSignatureScValbuilds the default Stellar Account signature shape (Vec<Map{public_key, signature}>), the building block for ed25519Signers that sign via an HSM or remote service. Two overloads accept either the rawbyte[]ed25519 public key or aG...accountId. TheKeyPairoverloads are unchanged and produce byte-identical output.
Migration for a custom (non-
KeyPair)Signertargeting a classicG...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 legacyADDRESS, 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
ADDRESSkeeps the non-address-bound preimage;ADDRESS_V2andADDRESS_WITH_DELEGATESsign the new address-boundENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESSpreimage. - Gains an optional
forAddressparameter 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.
- Signs all three address-based credential types, selecting the signature payload from the credential type: legacy
Auth.authorizeInvocation:- Still builds legacy
ADDRESSentries by default, so its output stays valid on every network regardless of protocol 27 activation. - New
credentialsTypeoverloads opt in toADDRESS_V2. The default will flip to V2 once Protocol 28 makes it mandatory.
- Still builds legacy
- New helpers in
Auth:buildAuthorizationEntryPreimage— builds the exact payload a signer must sign for a given entry.buildWithDelegatesEntry/Auth.DelegateSignature— wrap anADDRESS/ADDRESS_V2entry together with delegate signers, sorting each delegates level by address and rejecting duplicates, as the protocol requires.getAddressCredentials— extracts the innerSorobanAddressCredentialsfrom any address-based credential type.
AssembledTransaction:signAuthEntriesandneedsNonInvokerSigningByhandle all address-based credential types.- SEP-45 (
Sep45Challenge):- Challenge parsing and building accept
ADDRESS_V2entries 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.
- Challenge parsing and building accept
- New credential types (from the Protocol 27 XDR):
- feat: add
useUpgradedAuthtoSorobanServer.simulateTransaction, mapping to theuseUpgradedAuthflag from Stellar RPC v27.1.0 to opt simulation into recordingADDRESS_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, Kotlin2.4.0, Spotless plugin8.7.0, Lombok plugin9.5.0, NMCP plugin1.6.0, Gson2.14.0, Commons Codec1.22.0). (#808)
4.0.0-beta0
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 legacyADDRESS, 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
ADDRESSkeeps the non-address-bound preimage;ADDRESS_V2andADDRESS_WITH_DELEGATESsign the new address-boundENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESSpreimage. - Gains an optional
forAddressparameter 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.
- Signs all three address-based credential types, selecting the signature payload from the credential type: legacy
Auth.authorizeInvocation:- Still builds legacy
ADDRESSentries by default, so its output stays valid on every network regardless of protocol 27 activation. - New
credentialsTypeoverloads opt in toADDRESS_V2. The default will flip to V2 once Protocol 28 makes it mandatory.
- Still builds legacy
- New helpers in
Auth:buildAuthorizationEntryPreimage— builds the exact payload a signer must sign for a given entry.buildWithDelegatesEntry/Auth.DelegateSignature— wrap anADDRESS/ADDRESS_V2entry together with delegate signers, sorting each delegates level by address and rejecting duplicates, as the protocol requires.getAddressCredentials— extracts the innerSorobanAddressCredentialsfrom any address-based credential type.
AssembledTransaction:signAuthEntriesandneedsNonInvokerSigningByhandle all address-based credential types.- SEP-45 (
Sep45Challenge):- Challenge parsing and building accept
ADDRESS_V2entries 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.
- Challenge parsing and building accept
- New credential types (from the Protocol 27 XDR):
3.1.0
Update
- fix: make
RootRequestBuilderrequest the Horizon root endpoint as/instead of the percent-encoded/%2Fpath. (#801) - fix: make Horizon request builder URL generation idempotent so repeated
buildUri()orexecute()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 withstellar-sdk. (#797) - feat: add SEP-0046, SEP-0047, and SEP-0048 contract introspection support. New
ContractMeta,ContractSpec, andContractInfowrappers underorg.stellar.sdk.contractparse contract Wasm metadata and interface specs locally.SorobanServeraddsgetContractWasm,getContractWasmByHash,getContractMeta,getContractSpec, andgetContractInfofor RPC-backed retrieval. (#796)
3.0.0
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
ScMapentries by key inScv.toMapfollowing Soroban runtime ordering rules, as the network requiresScMapkeys to be in ascending order.Scv.toMapnow acceptsMap<SCVal, SCVal>; the previoustoMap(LinkedHashMap<SCVal, SCVal>)overload is deprecated. (#766) - feat: add SEP-0051 support. (#774)
- feat: add
closeTime,headerXdr, andmetadataXdrtoGetLatestLedgerResponse. (#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-xdrv26.0, including the v25.0 changes introduced earlier in this release cycle. (#769, #781)
Breaking changes
- refactor!: remove deprecated
StrKeyhelpersencodeEd25519PublicKey(AccountID),encodeMuxedAccount(MuxedAccount),decodeMuxedAccount(String),encodeToXDRAccountId(String), andencodeToXDRMuxedAccount(String); useStrKey.encodeEd25519PublicKey(byte[]),org.stellar.sdk.MuxedAccount, andKeyPair#getXdrAccountId()instead. (#779)
3.0.0-beta1
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 oldpublishAggregationToCentralPortaltask name after the nmcp plugin switch.
3.0.0-beta0
Update
- fix: use OkHttp's public SSE factory for Horizon streams and force SSE requests to bypass caches. (#791)
- feat: sort
ScMapentries by key inScv.toMapfollowing Soroban runtime ordering rules, as the network requiresScMapkeys to be in ascending order.Scv.toMapnow acceptsMap<SCVal, SCVal>; the previoustoMap(LinkedHashMap<SCVal, SCVal>)overload is deprecated. (#766) - feat: add SEP-0051 support. (#774)
- feat: add
closeTime,headerXdr, andmetadataXdrtoGetLatestLedgerResponse. (#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-xdrv26.0, including the v25.0 changes introduced earlier in this release cycle. (#769, #781)
Breaking changes
- refactor!: remove deprecated
StrKeyhelpersencodeEd25519PublicKey(AccountID),encodeMuxedAccount(MuxedAccount),decodeMuxedAccount(String),encodeToXDRAccountId(String), andencodeToXDRMuxedAccount(String); useStrKey.encodeEd25519PublicKey(byte[]),org.stellar.sdk.MuxedAccount, andKeyPair#getXdrAccountId()instead. (#779)
2.2.3
Update
- fix: replace
commons-codecHex with pure-Java implementation inUtilto fixNoSuchMethodErrorcrash on Android API 24-27. (#763) - refactor!: remove
InvokeHostFunctionOperation.createStellarAssetContractOperationBuilder(Address, byte[]), useInvokeHostFunctionOperation.createContractOperationBuilderinstead. (#764)
2.2.2
Update
- fix: add stricter validation for Ed25519 Signed Payload. (#751)
- fix: replace assert statements with explicit null checks in
Federationclass 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
ManageDataOperationvalue length to ensure it does not exceed 64 bytes. (#754) - fix: use
StandardCharsets.UTF_8explicitly when converting byte arrays to strings to ensure consistent behavior across different platforms. (#756) - refactor: use static initialization for
GsonSingletonto ensure thread safety. (#757) - fix: use
commons-codecfor hex encoding/decoding inUtilclass 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
Federationby limiting stellar.toml and federation response sizes to 100KB, adding proper timeouts, and handling UTF-8 BOM. (#760)
