|
| 1 | +--- |
| 2 | +name: java-stellar-sdk |
| 3 | +description: Build Stellar blockchain applications in Java using stellar-sdk (network.lightsail:stellar-sdk). Use for transaction building, signing, Horizon queries, Soroban RPC, smart contract deployment/invocation, XDR/SCVal conversion, and SEP integrations. |
| 4 | +license: Apache-2.0 |
| 5 | +compatibility: Published artifacts target Java 8 bytecode (require Java 8+). Building from source requires JDK 21. |
| 6 | +metadata: |
| 7 | + sdk_package: network.lightsail:stellar-sdk |
| 8 | + repository: lightsail-network/java-stellar-sdk |
| 9 | + docs: https://javadoc.io/doc/network.lightsail/stellar-sdk |
| 10 | +--- |
| 11 | + |
| 12 | +# Stellar Java SDK (`network.lightsail:stellar-sdk`) |
| 13 | + |
| 14 | +Write correct Java for the Stellar network using the `stellar-sdk` package. This file is |
| 15 | +self-contained; load a file from `references/` only when the task needs that topic. |
| 16 | + |
| 17 | +## Install |
| 18 | + |
| 19 | +Maven: |
| 20 | + |
| 21 | +```xml |
| 22 | +<dependency> |
| 23 | + <groupId>network.lightsail</groupId> |
| 24 | + <artifactId>stellar-sdk</artifactId> |
| 25 | + <version>3.0.0</version> |
| 26 | +</dependency> |
| 27 | +``` |
| 28 | + |
| 29 | +Gradle: |
| 30 | + |
| 31 | +```groovy |
| 32 | +implementation 'network.lightsail:stellar-sdk:3.0.0' |
| 33 | +``` |
| 34 | + |
| 35 | +## Import style |
| 36 | + |
| 37 | +Public APIs live under `org.stellar.sdk`; operations under `org.stellar.sdk.operations`; |
| 38 | +the contract helpers under `org.stellar.sdk.contract`; SCVal helpers under |
| 39 | +`org.stellar.sdk.scval`; exceptions under `org.stellar.sdk.exception`. |
| 40 | + |
| 41 | +```java |
| 42 | +import org.stellar.sdk.Asset; |
| 43 | +import org.stellar.sdk.KeyPair; |
| 44 | +import org.stellar.sdk.Network; |
| 45 | +import org.stellar.sdk.Server; |
| 46 | +import org.stellar.sdk.Transaction; |
| 47 | +import org.stellar.sdk.TransactionBuilder; |
| 48 | +import org.stellar.sdk.operations.PaymentOperation; |
| 49 | +import org.stellar.sdk.scval.Scv; |
| 50 | +``` |
| 51 | + |
| 52 | +## Clients |
| 53 | + |
| 54 | +- `Server` — Horizon client. See `references/horizon.md`. |
| 55 | +- `SorobanServer` — Soroban RPC client (`Closeable`). See `references/soroban.md`. |
| 56 | +- `ContractClient` — high-level Soroban contract client (`Closeable`) that wraps the |
| 57 | + simulate → prepare → sign → submit flow. See `references/soroban.md`. |
| 58 | + |
| 59 | +The SDK is **synchronous** (built on OkHttp); there is no separate async client. |
| 60 | + |
| 61 | +## Java conventions (read this first) |
| 62 | + |
| 63 | +These are the things that most often trip people up with *this* SDK: |
| 64 | + |
| 65 | +- **Operations use Lombok builders.** Every operation is built with `XxxOperation.builder()... |
| 66 | + .build()`, e.g. `PaymentOperation.builder().destination(d).asset(a).amount(amt).build()`. |
| 67 | + `InvokeHostFunctionOperation` instead exposes static factories (see `references/operations.md`). |
| 68 | +- **There are three asset types — don't mix them up.** `Asset` (payments, offers, paths), |
| 69 | + `ChangeTrustAsset` (the `ChangeTrustOperation` line, wraps an `Asset` or `LiquidityPool`), and |
| 70 | + `TrustLineAsset` (balances/trustline entries). See `references/assets.md`. |
| 71 | +- **Amounts and balances are `BigDecimal`.** `new BigDecimal("10.5")`, never `double`/`float`. |
| 72 | +- **`G...` and `M...` both work as a destination.** Address strings accept plain ed25519 |
| 73 | + accounts and SEP-23 muxed accounts; use `MuxedAccount` to build/parse `M...` (see |
| 74 | + `references/sep.md`). |
| 75 | +- **Clients are `Closeable`.** `Server.close()`; wrap `SorobanServer`/`ContractClient` in |
| 76 | + try-with-resources. `SSEStream` from `.stream(...)` must also be closed to stop it. |
| 77 | +- **SDK exceptions are unchecked.** Everything extends `RuntimeException` |
| 78 | + (`org.stellar.sdk.exception.SdkException`), so the compiler will not force you to catch them — |
| 79 | + you still should. The common supertype for network/RPC errors is `NetworkException`. |
| 80 | +- **`KeyPair.getSecretSeed()` returns `char[]`,** not `String`, so it can be zeroed after use. |
| 81 | +- **Android:** works out of the box on API level 28+. For lower levels add the |
| 82 | + [Java Stellar SDK Android SPI](https://github.com/lightsail-network/java-stellar-sdk-android-spi). |
| 83 | +- **Example syntax.** The SDK runs on **Java 8+**, but the snippets in this skill use some |
| 84 | + Java 9–16 conveniences for brevity. On Java 8, substitute equivalents: `List.of(...)` → |
| 85 | + `Arrays.asList(...)`, `Map.of(...)` → a populated `LinkedHashMap`, `"x".repeat(n)` → a literal, |
| 86 | + pattern-matching `instanceof` → a classic cast, and `java.net.http` → `HttpURLConnection` or |
| 87 | + any HTTP client. |
| 88 | + |
| 89 | +## Critical rules (do not violate) |
| 90 | + |
| 91 | +1. **`BigDecimal` amounts, never `double`/`float`.** Use `new BigDecimal("350.1234567")`, |
| 92 | + not `350.1234567`. Lumens have 7 decimal places; binary floats lose precision. |
| 93 | +2. **Prefer loading secret seeds at runtime** (env / a secret manager) over embedding |
| 94 | + them in source: `KeyPair.fromSecretSeed(System.getenv("STELLAR_SECRET_KEY"))`. |
| 95 | +3. **Always set a timeout** with `.setTimeout(...)` (or explicit time bounds). A |
| 96 | + transaction without one can hang in the pending pool indefinitely. |
| 97 | +4. **Use the correct network.** `Network.TESTNET` vs `Network.PUBLIC`. Signatures are |
| 98 | + network-specific; a testnet-signed transaction is invalid on mainnet. |
| 99 | +5. **`TransactionBuilder.build()` increments the source account's sequence number.** If you |
| 100 | + build but do not submit (or submission fails with `tx_bad_seq`), reload the account with |
| 101 | + `server.loadAccount(...)` before building again. |
| 102 | +6. **For Soroban, prepare before signing.** `sorobanServer.prepareTransaction(tx)` (or |
| 103 | + `ContractClient.invoke(...)` which simulates by default) fills in footprint, auth, and |
| 104 | + resource fees. Signing before this produces an invalid transaction. |
| 105 | +7. **Convert contract args with `Scv.to*`** and read results with `Scv.from*`. Never pass |
| 106 | + raw Java values to a contract. |
| 107 | +8. **Restore archived state** when simulation reports archived entries (see |
| 108 | + `references/soroban.md`). |
| 109 | +9. **Close clients.** Call `server.close()` for `Server`; use try-with-resources for |
| 110 | + `SorobanServer` and `ContractClient` (both implement `Closeable`). |
| 111 | +10. **Catch specific SDK exceptions** (`BadRequestException`, `BadResponseException`, |
| 112 | + `PrepareTransactionException`, …) from `org.stellar.sdk.exception`, not a broad |
| 113 | + `Exception`. The common supertype is `NetworkException`. |
| 114 | + |
| 115 | +## Minimal end-to-end examples |
| 116 | + |
| 117 | +### 1. Create / load a keypair |
| 118 | + |
| 119 | +```java |
| 120 | +import org.stellar.sdk.KeyPair; |
| 121 | + |
| 122 | +// New random account (fund it before use — see example 2). |
| 123 | +KeyPair kp = KeyPair.random(); |
| 124 | +System.out.println(kp.getAccountId()); // G... (safe to share) |
| 125 | +System.out.println(kp.getSecretSeed()); // S... (secret — never log or commit in real code) |
| 126 | + |
| 127 | +// Load an existing account from the environment. |
| 128 | +KeyPair signer = KeyPair.fromSecretSeed(System.getenv("STELLAR_SECRET_KEY")); |
| 129 | + |
| 130 | +// Verify-only keypair (cannot sign). |
| 131 | +KeyPair publicOnly = KeyPair.fromAccountId("GD2JXEFGEO53CNQ22KN2ICOQ2LOASCABQHAIOMLZV265C246PFKKHPYU"); |
| 132 | +``` |
| 133 | + |
| 134 | +### 2. Build, sign, and submit a payment |
| 135 | + |
| 136 | +```java |
| 137 | +import java.math.BigDecimal; |
| 138 | +import org.stellar.sdk.*; |
| 139 | +import org.stellar.sdk.operations.PaymentOperation; |
| 140 | +import org.stellar.sdk.responses.TransactionResponse; |
| 141 | + |
| 142 | +KeyPair source = KeyPair.fromSecretSeed(System.getenv("STELLAR_SECRET_KEY")); |
| 143 | +String destination = "GD2JXEFGEO53CNQ22KN2ICOQ2LOASCABQHAIOMLZV265C246PFKKHPYU"; |
| 144 | + |
| 145 | +Server server = new Server("https://horizon-testnet.stellar.org"); |
| 146 | + |
| 147 | +// Reload right before building so the sequence number is current. |
| 148 | +TransactionBuilderAccount account = server.loadAccount(source.getAccountId()); |
| 149 | + |
| 150 | +PaymentOperation payment = |
| 151 | + PaymentOperation.builder() |
| 152 | + .destination(destination) |
| 153 | + .asset(Asset.createNativeAsset()) |
| 154 | + .amount(new BigDecimal("350.1234567")) // BigDecimal amount |
| 155 | + .build(); |
| 156 | + |
| 157 | +Transaction transaction = |
| 158 | + new TransactionBuilder(account, Network.TESTNET) |
| 159 | + .setBaseFee(Transaction.MIN_BASE_FEE) |
| 160 | + .addMemo(Memo.text("Hello, Stellar!")) |
| 161 | + .addOperation(payment) |
| 162 | + .setTimeout(30) |
| 163 | + .build(); |
| 164 | + |
| 165 | +transaction.sign(source); |
| 166 | +TransactionResponse response = server.submitTransaction(transaction); |
| 167 | +System.out.println(response.getHash()); |
| 168 | +server.close(); |
| 169 | +``` |
| 170 | + |
| 171 | +New testnet accounts can be funded by Friendbot: |
| 172 | +`GET https://friendbot.stellar.org?addr=<G...>`. |
| 173 | + |
| 174 | +### 3. Query Horizon |
| 175 | + |
| 176 | +```java |
| 177 | +import org.stellar.sdk.Server; |
| 178 | +import org.stellar.sdk.requests.RequestBuilder; |
| 179 | +import org.stellar.sdk.responses.Page; |
| 180 | +import org.stellar.sdk.responses.operations.OperationResponse; |
| 181 | + |
| 182 | +Server server = new Server("https://horizon.stellar.org"); |
| 183 | + |
| 184 | +// Request builders are chainable; .execute() runs the HTTP request. |
| 185 | +Page<OperationResponse> payments = |
| 186 | + server.payments() |
| 187 | + .forAccount("GB6NVEN5HSUBKMYCE5ZOWSK5K23TBWRUQLZY3KNMXUZ3AQ2ESC4MY4AQ") |
| 188 | + .order(RequestBuilder.Order.DESC) |
| 189 | + .limit(10) |
| 190 | + .execute(); |
| 191 | +for (OperationResponse op : payments.getRecords()) { |
| 192 | + System.out.println(op.getType()); |
| 193 | +} |
| 194 | +``` |
| 195 | + |
| 196 | +### 4. Invoke a Soroban contract (read-only) |
| 197 | + |
| 198 | +For contracts you call repeatedly, prefer **generated typed bindings** (see |
| 199 | +`references/bindings.md`). The hand-written form with `ContractClient` is: |
| 200 | + |
| 201 | +```java |
| 202 | +import java.util.List; |
| 203 | +import org.stellar.sdk.Network; |
| 204 | +import org.stellar.sdk.contract.ContractClient; |
| 205 | +import org.stellar.sdk.scval.Scv; |
| 206 | +import org.stellar.sdk.xdr.SCVal; |
| 207 | + |
| 208 | +// A read-only call needs no signer, but `source` is required and must be an account |
| 209 | +// that already exists on the target network — simulate() loads its sequence via |
| 210 | +// server.getAccount(), which throws AccountNotFoundException if the account is missing. |
| 211 | +String source = "GD2JXEFGEO53CNQ22KN2ICOQ2LOASCABQHAIOMLZV265C246PFKKHPYU"; |
| 212 | + |
| 213 | +try (ContractClient client = |
| 214 | + new ContractClient( |
| 215 | + "CACZTW72246RA2MOCNKUBRRRRPT26UZ7LXE5ZHH44OGKIMCTQJ74O4D5", |
| 216 | + "https://soroban-testnet.stellar.org:443", |
| 217 | + Network.TESTNET)) { |
| 218 | + SCVal result = |
| 219 | + client |
| 220 | + .invoke("hello", List.of(Scv.toSymbol("world")), source, null, null, |
| 221 | + (int) org.stellar.sdk.Transaction.MIN_BASE_FEE) |
| 222 | + .result(); // read-only: no signer needed |
| 223 | + System.out.println(result); |
| 224 | +} |
| 225 | +``` |
| 226 | + |
| 227 | +For a state-changing call, pass `source` and `signer`, then `signAndSubmit(...)`. See |
| 228 | +`references/soroban.md`. |
| 229 | + |
| 230 | +## Reference index |
| 231 | + |
| 232 | +Load on demand: |
| 233 | + |
| 234 | +- `references/quickstart.md` — install → keypair → fund → payment → query → contract. |
| 235 | +- `references/transactions.md` — transaction lifecycle, memos, preconditions, fee bump, |
| 236 | + multisig, XDR round-trips, sequence-number pitfalls. |
| 237 | +- `references/assets.md` — `Asset` vs `ChangeTrustAsset` vs `TrustLineAsset`, native vs |
| 238 | + alphanum4/12, canonical form. |
| 239 | +- `references/operations.md` — catalog of every operation and its builder. |
| 240 | +- `references/horizon.md` — Horizon client, request builders, pagination, streaming, errors. |
| 241 | +- `references/soroban.md` — Soroban RPC client + `ContractClient`/`AssembledTransaction`. |
| 242 | +- `references/bindings.md` — generate typed contract clients with `stellar-contract-bindings`. |
| 243 | +- `references/xdr_scval.md` — SCVal conversion, `Address`, XDR encode/decode. |
| 244 | +- `references/sep.md` — SEP support matrix and common flows (SEP-02/05/10/23/35/45/...). |
| 245 | +- `references/troubleshooting.md` — exception hierarchy and common failures. |
| 246 | + |
| 247 | +Full API docs (Javadoc): https://javadoc.io/doc/network.lightsail/stellar-sdk |
0 commit comments