Skip to content

[ANCHOR-1399]: Publish SEP-45 and Platform API fields under their snake_case wire keys - #2086

Open
ceciliaromao wants to merge 7 commits into
developfrom
fix/anchor-1399
Open

ceciliaromao wants to merge 7 commits into
developfrom
fix/anchor-1399

Conversation

@ceciliaromao

@ceciliaromao ceciliaromao commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Description

  • GetTransactionResponse now publishes funding_method (was fundingMethod) and required_info_updates_fields (was requiredInfoUpdatesFields). The unannotated redeclaration of requiredInfoUpdatesFields that shadowed the annotated field in PlatformTransactionData is deleted, so the key is emitted once and matches what the PATCH side already accepts.
  • sep45/ChallengeResponse, sep45/ValidationRequest, sep45/ChallengeRequest and sep10/ChallengeRequest get @SerializedName next to the existing @JsonProperty. GET /sep45/auth now answers authorization_entries / network_passphrase, and POST /sep45/auth with a JSON body {"authorization_entries": "..."} is accepted instead of failing with 400 authorization_entries is required.
  • AnchorEvent.clientName / clientDomain are now published as client_name / client_domain, like the event's own transaction.
  • Sep45Service.validate now answers 400 Failed to decode auth entries for any value that is not valid base64. It used to catch only IOException, so IllegalArgumentException from the decoder surfaced as a 500.
  • Tests that read raw JSON keys instead of round-tripping through the same DTO: WireKeyNamingTest, a standalone-MockMvc Sep45ControllerTest (real Gson converter), and updated TransactionMapperTest / ClientStatusCallbackHandlerTest.
  • JacksonOnlyDtoGuardTest fails the build on two cases in org.stellar.anchor.api: a field with @JsonProperty and no @SerializedName of the same value, and a serialized field whose wire key contains an upper-case letter (six named exceptions, each with its reason). It also asserts that its scan reaches the classes Spring's default filter skips. core/build.gradle.kts gains testImplementation(libs.jackson.annotations) for its self-test.

Context

  • HackerOne #4108396. All four servers use Gson as the only JSON converter (spring.mvc.converters.preferred-json-mapper=gson) and GsonUtils.builder() sets no FieldNamingPolicy, so @JsonProperty is inert and an unannotated field goes out under its camelCase Java name.
  • The repo's own tests did not see it: Sep45Tests and TransactionMapperTest round-trip through the same DTO, so a wrong key is symmetric. TransactionMapperTest even asserted the camelCase keys; those two assertions are updated.
  • Fixed per field with @SerializedName, not with a global FieldNamingPolicy: GsonUtils.getInstance() also serializes DB JSON columns and the event queue, so a global policy would silently rename every unannotated field.

Testing

  • ./gradlew test
  • ./gradlew :core:test :platform:test unfiltered: core 1151 tests, platform 1427, 0 failures, 0 errors, 0 skipped.
  • New wire tests fail on develop for the reason in the report (authorizationEntries on the challenge, authorization_entries left null on a JSON body) and pass with the fix.
  • Independent review with 3 mutations (wrong key, shadow field re-added, SEP-45 key reverted), all killed by the tests.
  • Not run: the e2e suites (Sep45Tests, Sep31End2EndTests).

Documentation

N/A. The upstream Platform API OpenAPI (stellar-docs/openapi/anchor-platform) documents neither fundingMethod nor funding_method, nor either spelling of required_info_updates_fields, so there is no published contract to update.

Known limitations

  • Breaking wire change: business servers that parse fundingMethod or requiredInfoUpdatesFields from the Platform API or from AnchorEvent.transaction, or clientName / clientDomain from the AnchorEvent published to Kafka, SQS or the event callback, read nothing after the upgrade. No dual emission was added, and during a rolling upgrade an old consumer and a new producer disagree on the key. This belongs in the release notes.
  • ClientConfigRequest / ClientConfigResponse (PUT /clients/{name} and the other /clients endpoints) still use camelCase keys (signingKeys, callbackUrls, allowAnyDestination, destinationAccounts) in both directions. The endpoint has been released since 4.7.0, so renaming it would break existing callers; left unchanged on purpose. It lives outside org.stellar.anchor.api, so the guard does not scan it.
  • requestClientIpAddress stays camelCase on the five request DTOs; the controllers overwrite it from the connection and never read it from the body (see [ANCHOR-1398]: Derive request_client_ip_address from a trusted source #2085).

@ceciliaromao ceciliaromao self-assigned this Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant