diff --git a/skills/java-stellar-sdk/SKILL.md b/skills/java-stellar-sdk/SKILL.md index 2963d8bba..b12670e3b 100644 --- a/skills/java-stellar-sdk/SKILL.md +++ b/skills/java-stellar-sdk/SKILL.md @@ -72,7 +72,9 @@ These are the things that most often trip people up with *this* SDK: - **Amounts and balances are `BigDecimal`.** `new BigDecimal("10.5")`, never `double`/`float`. - **`G...` and `M...` both work as a destination.** Address strings accept plain ed25519 accounts and SEP-23 muxed accounts; use `MuxedAccount` to build/parse `M...` (see - `references/sep.md`). + `references/sep.md`). Contracts have a muxed form too, `W...` (CAP-84, Protocol 30): a valid + SAC `transfer`/`mint` destination, but never a signer or storage owner (see + `references/xdr_scval.md`). - **Clients are `Closeable`.** `Server.close()`; wrap `SorobanServer`/`ContractClient` in try-with-resources. `SSEStream` from `.stream(...)` must also be closed to stop it. - **SDK exceptions are unchecked.** Everything extends `RuntimeException` diff --git a/skills/java-stellar-sdk/references/sep.md b/skills/java-stellar-sdk/references/sep.md index 595ca77c2..054e3b432 100644 --- a/skills/java-stellar-sdk/references/sep.md +++ b/skills/java-stellar-sdk/references/sep.md @@ -8,7 +8,7 @@ across top-level classes rather than a single `sep` package. | SEP-02 | Federation | `org.stellar.sdk.federation.Federation` | | SEP-05 | Key derivation (BIP-39 seed) | `KeyPair.fromBip39Seed(byte[], int)` | | SEP-10 | Web authentication | `org.stellar.sdk.Sep10Challenge` | -| SEP-23 | Muxed accounts | `org.stellar.sdk.MuxedAccount` | +| SEP-23 | Muxed addresses (`M...`, `W...`) | `org.stellar.sdk.MuxedAccount`; `Address` | | SEP-29 | Memo-required check | submission helpers / `AccountRequiresMemoException` | | SEP-35 | Operation IDs (TOID) | `org.stellar.sdk.TOID` | | SEP-45 | Soroban web auth | `org.stellar.sdk.Sep45Challenge` | @@ -81,6 +81,9 @@ String mAddress = muxed.getAddress(); // M... MuxedAccount parsed = new MuxedAccount("M..."); // parse an existing M-address ``` +SEP-23 also defines the muxed contract strkey (`W...`, CAP-84), a contract plus a 64-bit ID. +It has no `MuxedAccount` counterpart; see "Addresses" in `xdr_scval.md`. + ## SEP-35: TOID (total order ID) ```java diff --git a/skills/java-stellar-sdk/references/troubleshooting.md b/skills/java-stellar-sdk/references/troubleshooting.md index 859e9a558..0fd5ec858 100644 --- a/skills/java-stellar-sdk/references/troubleshooting.md +++ b/skills/java-stellar-sdk/references/troubleshooting.md @@ -93,3 +93,9 @@ Operation-level codes you'll hit often: `assembled.signAuthEntries(theirKeyPair)` before `signAndSubmit(...)`. - **Transaction still pending** → `getTransaction` returns status `NOT_FOUND` until it is in a ledger; poll with `pollTransaction` or a loop. See `soroban.md`. +- **Address cannot authorize** → `IllegalArgumentException` from `Auth`; only `G...` and `C...` + addresses sign Soroban authorization entries, never a muxed (`M...`/`W...`), claimable balance + or liquidity pool address. Sign for the base address. +- **Muxed address in contract storage** → `IllegalArgumentException` from `getContractData`; the + owner must be a `C...` and the key cannot contain an `M...`/`W...`. Use the base address (see + "Addresses" in `xdr_scval.md`). diff --git a/skills/java-stellar-sdk/references/xdr_scval.md b/skills/java-stellar-sdk/references/xdr_scval.md index 26fae7c44..0d363aff5 100644 --- a/skills/java-stellar-sdk/references/xdr_scval.md +++ b/skills/java-stellar-sdk/references/xdr_scval.md @@ -22,7 +22,7 @@ Scv.toTimePoint(BigInteger.valueOf(1700000000)); Scv.toDuration(BigInteger.value Scv.toBytes(new byte[] {1, 2}); Scv.toString("hello"); Scv.toSymbol("increment"); Scv.toExecutableTag("v1"); // CAP-85 tag; byte[] overload for a binary tag -Scv.toAddress("G..."); // account or contract ("C...") address +Scv.toAddress("G..."); // G/C/M/W... address, see "Addresses" Scv.toVec(List.of(Scv.toUint32(1L), Scv.toUint32(2L))); Scv.toMap(Map.of(Scv.toSymbol("k"), Scv.toUint32(1L))); ``` @@ -50,8 +50,20 @@ import org.stellar.sdk.xdr.SCVal; Address addr = new Address("G..."); // account or "C..." contract SCVal scVal = addr.toSCVal(); // SCVal for contract args Address back = Address.fromSCVal(scVal); +back.getAddressType(); // ACCOUNT, CONTRACT, MUXED_ACCOUNT, ... + +new Address("M..."); // muxed account (SEP-23) +new Address("W..."); // muxed contract (CAP-84, Protocol 30) +Address.fromMuxedContract(raw); // raw: 32-byte contract ID + 8-byte big-endian ID +new Address("B..."); // claimable balance, e.g. in events +new Address("L..."); // liquidity pool, e.g. in events ``` +`M...` and `W...` are payment destinations only, such as the `to` of a Stellar Asset Contract +`transfer`; the balance goes to the base `G...`/`C...`. They cannot authorize or key contract +storage, and the SDK rejects them there (`Auth`, `SorobanServer.getContractData`, the balance +helpers), so use the base address. + ## Transaction XDR ```java