Protocol 27: SDK Changes
XDR Changes
- XDR should be upgraded to stellar-xdr@
68fa1ac (the Protocol 27 XDR). The headline change is CAP-71, which adds
two new address-bound Soroban authorization credential types. The SorobanCredentialsType enum gains two arms:
SOROBAN_CREDENTIALS_ADDRESS_V2 = 2 — carries the identical SorobanAddressCredentials payload as the legacy ADDRESS, but binds the credential address into the signed payload.
SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES = 3 — wraps SorobanAddressCredentials together with a (recursively nested) tree of SorobanDelegateSignature for delegated / multi-party signing.
- A new
HashIdPreimage arm, ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS, is added. It is the legacy Soroban-auth preimage plus an SCAddress address field:
case ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS:
struct {
Hash networkID;
int64 nonce;
uint32 signatureExpirationLedger;
SCAddress address; // NEW — binds the signer's address
SorobanAuthorizedInvocation invocation;
} sorobanAuthorizationWithAddress;
struct SorobanDelegateSignature {
SCAddress address;
SCVal signature;
SorobanDelegateSignature nestedDelegates<>;
};
struct SorobanAddressCredentialsWithDelegates {
SorobanAddressCredentials addressCredentials;
SorobanDelegateSignature delegates<>;
};
Authorization signing — pick the preimage from the credential type. Code that hardcodes ENVELOPE_TYPE_SOROBAN_AUTHORIZATION when building the signature payload is wrong for the new types. Branch on the credential arm:
* ADDRESS → ENVELOPE_TYPE_SOROBAN_AUTHORIZATION (unchanged, not address-bound)
* ADDRESS_V2 and ADDRESS_WITH_DELEGATES → ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS
Reading credentials. Handle the two new union arms anywhere you unpack SorobanCredentials (e.g. a helper that extracts the inner SorobanAddressCredentials regardless of which arm carries it).
Delegated auth (ADDRESS_WITH_DELEGATES, CAP-71-01). Every signer — the top-level account and each (nested) delegate — signs the same payload, bound to the top-level address. Each delegate array must be sorted by address ascending with duplicates rejected, or
the host rejects the entry. Simulation never emits this variant on its own; which accounts use delegated auth is client-side policy (like a multisig policy), so the SDK ships low-level primitives and the client assembles the tree.
Default to legacy ADDRESS — make V2 opt-in. ADDRESS_V2 is only valid on networks that have upgraded to protocol 27; emitting it before a network upgrades fails submission. Keep ADDRESS as the default and gate V2 behind an opt-in flag. The default should flip to V2 once Protocol 28
makes it mandatory.
RPC Changes
simulateTransaction gains an opt-in request flag to ask simulation to return ADDRESS_V2 credentials instead of legacy ADDRESS:
RPC ignores request fields it doesn't recognize. Sending authV2: true to an RPC that hasn't been updated is a silent no-op: it returns legacy ADDRESS (V1) credentials with no error. So you can't detect support from an error — if you need to know whether you actually got V2 back, inspect the credential arm of the returned entries rather than assuming the flag took effect.
XDR Generation (xdrgen users)
If you generate your XDR types with xdrgen, note that the canonical .x files now contain feature-gated content (preprocessor directives) that xdrgen does not understand. Before running xdrgen, preprocess each .x file with the
stellar-xdr CLI to expand the feature gates, then feed the preprocessed output to xdrgen. For each downloaded .x file:
stellar-xdr xfile preprocess --features "$(XDR_FEATURES)" $@ > $@.pp && mv -f $@.pp $@
XDR_FEATURES selects which feature set to enable. Protocol 27 features have already been ungated so leaving this empty will return you only xdr types which are relevant for protocol 27.
Reference Implementations
- [
js-stellar-sdk] — see PR-1 PR-2 src/base/auth.ts (authorizeEntry, authorizeInvocation, buildAuthorizationEntryPreimage, buildWithDelegatesEntry, getAddressCredentials) and src/rpc/server.ts
(the simulateTransaction authV2 flag).
stellar-rpc
Protocol 27: SDK Changes
XDR Changes
68fa1ac(the Protocol 27 XDR). The headline change is CAP-71, which addstwo new address-bound Soroban authorization credential types. The
SorobanCredentialsTypeenum gains two arms:SOROBAN_CREDENTIALS_ADDRESS_V2 = 2— carries the identicalSorobanAddressCredentialspayload as the legacyADDRESS, but binds the credential address into the signed payload.SOROBAN_CREDENTIALS_ADDRESS_WITH_DELEGATES = 3— wrapsSorobanAddressCredentialstogether with a (recursively nested) tree ofSorobanDelegateSignaturefor delegated / multi-party signing.HashIdPreimagearm,ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESS, is added. It is the legacy Soroban-auth preimage plus anSCAddress addressfield:Authorization signing — pick the preimage from the credential type. Code that hardcodes
ENVELOPE_TYPE_SOROBAN_AUTHORIZATIONwhen building the signature payload is wrong for the new types. Branch on the credential arm:*
ADDRESS→ENVELOPE_TYPE_SOROBAN_AUTHORIZATION(unchanged, not address-bound)*
ADDRESS_V2andADDRESS_WITH_DELEGATES→ENVELOPE_TYPE_SOROBAN_AUTHORIZATION_WITH_ADDRESSReading credentials. Handle the two new union arms anywhere you unpack
SorobanCredentials(e.g. a helper that extracts the innerSorobanAddressCredentialsregardless of which arm carries it).Delegated auth (
ADDRESS_WITH_DELEGATES, CAP-71-01). Every signer — the top-level account and each (nested) delegate — signs the same payload, bound to the top-level address. Each delegate array must be sorted by address ascending with duplicates rejected, orthe host rejects the entry. Simulation never emits this variant on its own; which accounts use delegated auth is client-side policy (like a multisig policy), so the SDK ships low-level primitives and the client assembles the tree.
Default to legacy
ADDRESS— make V2 opt-in.ADDRESS_V2is only valid on networks that have upgraded to protocol 27; emitting it before a network upgrades fails submission. KeepADDRESSas the default and gate V2 behind an opt-in flag. The default should flip to V2 once Protocol 28makes it mandatory.
RPC ChangessimulateTransactiongains an opt-in request flag to ask simulation to returnADDRESS_V2credentials instead of legacyADDRESS:RPC ignores request fields it doesn't recognize. SendingauthV2: trueto an RPC that hasn't been updated is a silent no-op: it returns legacyADDRESS(V1) credentials with no error. So you can't detect support from an error — if you need to know whether you actually got V2 back, inspect the credential arm of the returned entries rather than assuming the flag took effect.XDR Generation (xdrgen users)
If you generate your XDR types with xdrgen, note that the canonical
.xfiles now contain feature-gated content (preprocessor directives) that xdrgen does not understand. Before running xdrgen, preprocess each.xfile with thestellar-xdrCLI to expand the feature gates, then feed the preprocessed output to xdrgen. For each downloaded.xfile:XDR_FEATURESselects which feature set to enable. Protocol 27 features have already been ungated so leaving this empty will return you only xdr types which are relevant for protocol 27.Reference Implementations
js-stellar-sdk] — see PR-1 PR-2src/base/auth.ts(authorizeEntry,authorizeInvocation,buildAuthorizationEntryPreimage,buildWithDelegatesEntry,getAddressCredentials) andsrc/rpc/server.ts(the
simulateTransactionauthV2flag).stellar-rpc