* fix(rest): handle non-JSON error bodies on non-200 HTTP responses
When a REST upstream (e.g. TON) returns a non-200 status with a plain-text
body such as "Service Unavailable" but advertises application/json as the
content-type, the error parser would throw JsonParseException
("Unrecognized token 'Service'"), which bubbled up as a generic -32005
ChainException and obscured the real cause.
Catch JsonParseException/IOException around readError and fall back to a
"HTTP Code: X" ChainCallError (CODE_UPSTREAM_INVALID_RESPONSE), matching
the behavior already implemented in JsonRpcHttpReader. Also return the
fallback when readError returns null.
* fix(rest): close parser, log stack traces, fall back on empty errors
Address PR review feedback:
- Close the Jackson JsonParser via `use { ... }` to release buffers.
- Switch to parameterized SLF4J logging and pass the exception so stack
traces are preserved on parsing/IO failures.
- Treat a parsed error with code=0 and blank message (e.g. from a bare
`{}` body) as no useful error info and fall back to the generic
HTTP-status error so the upstream status isn't silently dropped.
* fix(rest): short-circuit HTTP 503 without JSON parsing
Narrow the fix to exactly the case reported: HTTP 503 Service Unavailable
responses (typically from Cloudflare) carry a plain-text or HTML body but
can be served with Content-Type: application/json, so attempting to parse
the body as JSON raises JsonParseException and surfaces as a confusing
-32005 "Unrecognized token 'Service'" error.
For status 503, skip parsing entirely and return a ChainCallError
directly. All other non-200 responses keep the existing behavior.
* docs(rest): align 503 branch comment with error code
---------
Co-authored-by: Claude <noreply@anthropic.com>
* docs: spec for unifying response signing with auth key
Design для замены отдельной SignatureConfig на подпись ответов
RSA-ключом, взятым из auth.server.provider-private-key.
Made-with: Cursor
* docs: implementation plan for auth-based response signing
План реализации по спеке 2026-04-20-response-signing-with-auth-key-design.md.
Разбит на 9 задач: новые RsaSigner/DisabledSigner по TDD, переработка фабрики
под AuthorizationConfig, удаление SignatureConfig/signed-response, снятие
cache-гейта в EthereumLocalReader, обновление документации.
Made-with: Cursor
* feat(signature): add RsaSigner using SHA256withRSA
Made-with: Cursor
* feat(signature): add DisabledSigner that throws on sign()
Made-with: Cursor
* refactor(signature): ResponseSigner.sign returns non-null Signature
Made-with: Cursor
* refactor(signature): build signer from AuthorizationConfig
Made-with: Cursor
* refactor(config): remove signed-response YAML section and SignatureConfig
Made-with: Cursor
* refactor(signature): remove EcdsaSigner and NoSigner
Remove the obsolete ECDSA signer and the transitional NoSigner stub.
Replace NoSigner usages in tests with DisabledSigner, and pass
DisabledSigner to BroadcastReader in tests (signer is now non-null).
Made-with: Cursor
* refactor(local-reader): serve cached results for requests with nonce
Made-with: Cursor
* docs: replace signed-response with auth section incl. response signing
Made-with: Cursor
* docs: correct auth section YAML and expand Response Signing note
- docs/reference-configuration.adoc: fix the YAML shape of the auth
section (server.keys.{provider-private-key,external-public-key} and
publicKeyOwner) to match AuthorizationConfigReader, and expand the
Response Signing subsection with the actual signed-message format.
- .gitignore: ignore /demo/response-signing/ (local sandbox with keys
and generated gRPC stubs — regenerate with generate-keys.sh + protoc)
and /docs/superpowers/ (specs/plans kept local-only for now). Any
previously tracked files under these paths are untracked here.
Made-with: Cursor
* feat(upstream): auto-inject secure-signed label when signing is enabled
Expose ResponseSigner.enabled and thread the bean through UpstreamCreator
so Generic/Ethereum/Bitcoin creators can enrich each upstream's labels
with secure-signed=true whenever auth-backed response signing is active.
A user-provided value for the label is preserved.
Made-with: Cursor
Add Content-Type to the beacon chain response headers whitelist.
Without this, REST endpoints returning SSZ binary data (e.g.
/eth/v2/debug/beacon/states) are mislabeled as application/json
by dproxy, breaking client-side parsing.
Companion fix: drpcorg/dproxy#2348
* add Robinhood Chain testnet support
Update emerald-grpc submodule with CHAIN_ROBINHOOD__TESTNET = 10190.
* update submodules to include TAC chain merge
Sync emerald-grpc and public submodules to latest.
* Implement Solana head detection strategies with metrics tracking and testing
* Add benchmark tests for Solana BlockSubscribe and SlotSubscribe strategies
* Implement metrics logging and strategy configuration for Solana head detection
* Add metrics logging and comparison for SLOT_SUBSCRIBE strategy
* Refactor SolanaChainSpecificTest: Consolidate tests for slotSubscribe strategy, remove BlockSubscribe tests, and enhance caching logic. Delete SolanaStrategyBenchmark for performance comparison.
* add synthetic parentHash, improve tests
* Fix linter
* Optimize Solana getLatestBlock to use single getEpochInfo call
Replace two separate RPC calls (getSlot + getBlockHeight) with a single getEpochInfo call that returns both absoluteSlot and blockHeight
* Enhance height estimation logic in SolanaChainSpecific: Implement optimistic height estimation and improve error handling for RPC failures. Update tests to validate new behavior.
* Refactor height verification in SolanaChainSpecific: Replace getBlockHeight with getEpochInfo for improved efficiency and accuracy in height estimation. Update logic to handle actual slot and height retrieval.
* Add WebSocket subscription support for Ripple and migrate to ledger_closed
- Replace deprecated `ledger` RPC method with `ledger_closed` for polling
- Add WebSocket subscription support for Ripple ledger stream
- Add RippleCommandParams for native Ripple WS command format (uses "command" instead of "method")
- Extend ResponseWSParser to handle Ripple subscription format (type: "ledgerClosed")
- Update WsSubscriptionsImpl to extract stream type for Ripple subscriptions
- Implement getFromHeader() for parsing ledgerClosed WS events
- Add RippleLedgerStreamEvent data class for WS subscription events
- Add unit tests for ResponseWSParser and RippleChainSpecific
* Remove legacy format