Home / Cardano Foundation / cardano-rosetta-java
Mar 27, 4-5 AM (0)
Mar 27, 5-6 AM (0)
Mar 27, 6-7 AM (2)
Mar 27, 7-8 AM (0)
Mar 27, 8-9 AM (0)
Mar 27, 9-10 AM (0)
Mar 27, 10-11 AM (2)
Mar 27, 11-12 PM (0)
Mar 27, 12-1 PM (0)
Mar 27, 1-2 PM (0)
Mar 27, 2-3 PM (0)
Mar 27, 3-4 PM (0)
Mar 27, 4-5 PM (0)
Mar 27, 5-6 PM (0)
Mar 27, 6-7 PM (0)
Mar 27, 7-8 PM (0)
Mar 27, 8-9 PM (0)
Mar 27, 9-10 PM (0)
Mar 27, 10-11 PM (0)
Mar 27, 11-12 AM (0)
Mar 28, 12-1 AM (0)
Mar 28, 1-2 AM (0)
Mar 28, 2-3 AM (0)
Mar 28, 3-4 AM (0)
Mar 28, 4-5 AM (0)
Mar 28, 5-6 AM (0)
Mar 28, 6-7 AM (0)
Mar 28, 7-8 AM (0)
Mar 28, 8-9 AM (0)
Mar 28, 9-10 AM (0)
Mar 28, 10-11 AM (0)
Mar 28, 11-12 PM (0)
Mar 28, 12-1 PM (0)
Mar 28, 1-2 PM (0)
Mar 28, 2-3 PM (0)
Mar 28, 3-4 PM (0)
Mar 28, 4-5 PM (0)
Mar 28, 5-6 PM (0)
Mar 28, 6-7 PM (0)
Mar 28, 7-8 PM (0)
Mar 28, 8-9 PM (0)
Mar 28, 9-10 PM (0)
Mar 28, 10-11 PM (0)
Mar 28, 11-12 AM (0)
Mar 29, 12-1 AM (0)
Mar 29, 1-2 AM (0)
Mar 29, 2-3 AM (0)
Mar 29, 3-4 AM (0)
Mar 29, 4-5 AM (0)
Mar 29, 5-6 AM (0)
Mar 29, 6-7 AM (0)
Mar 29, 7-8 AM (0)
Mar 29, 8-9 AM (0)
Mar 29, 9-10 AM (0)
Mar 29, 10-11 AM (0)
Mar 29, 11-12 PM (0)
Mar 29, 12-1 PM (0)
Mar 29, 1-2 PM (0)
Mar 29, 2-3 PM (0)
Mar 29, 3-4 PM (0)
Mar 29, 4-5 PM (0)
Mar 29, 5-6 PM (0)
Mar 29, 6-7 PM (0)
Mar 29, 7-8 PM (0)
Mar 29, 8-9 PM (0)
Mar 29, 9-10 PM (0)
Mar 29, 10-11 PM (0)
Mar 29, 11-12 AM (0)
Mar 30, 12-1 AM (0)
Mar 30, 1-2 AM (0)
Mar 30, 2-3 AM (0)
Mar 30, 3-4 AM (0)
Mar 30, 4-5 AM (0)
Mar 30, 5-6 AM (0)
Mar 30, 6-7 AM (0)
Mar 30, 7-8 AM (4)
Mar 30, 8-9 AM (6)
Mar 30, 9-10 AM (0)
Mar 30, 10-11 AM (0)
Mar 30, 11-12 PM (0)
Mar 30, 12-1 PM (0)
Mar 30, 1-2 PM (0)
Mar 30, 2-3 PM (0)
Mar 30, 3-4 PM (0)
Mar 30, 4-5 PM (0)
Mar 30, 5-6 PM (0)
Mar 30, 6-7 PM (0)
Mar 30, 7-8 PM (0)
Mar 30, 8-9 PM (0)
Mar 30, 9-10 PM (0)
Mar 30, 10-11 PM (0)
Mar 30, 11-12 AM (0)
Mar 31, 12-1 AM (0)
Mar 31, 1-2 AM (0)
Mar 31, 2-3 AM (0)
Mar 31, 3-4 AM (0)
Mar 31, 4-5 AM (0)
Mar 31, 5-6 AM (0)
Mar 31, 6-7 AM (0)
Mar 31, 7-8 AM (2)
Mar 31, 8-9 AM (1)
Mar 31, 9-10 AM (0)
Mar 31, 10-11 AM (0)
Mar 31, 11-12 PM (0)
Mar 31, 12-1 PM (3)
Mar 31, 1-2 PM (0)
Mar 31, 2-3 PM (0)
Mar 31, 3-4 PM (0)
Mar 31, 4-5 PM (0)
Mar 31, 5-6 PM (0)
Mar 31, 6-7 PM (0)
Mar 31, 7-8 PM (0)
Mar 31, 8-9 PM (0)
Mar 31, 9-10 PM (0)
Mar 31, 10-11 PM (0)
Mar 31, 11-12 AM (0)
Apr 01, 12-1 AM (0)
Apr 01, 1-2 AM (0)
Apr 01, 2-3 AM (0)
Apr 01, 3-4 AM (0)
Apr 01, 4-5 AM (0)
Apr 01, 5-6 AM (0)
Apr 01, 6-7 AM (0)
Apr 01, 7-8 AM (4)
Apr 01, 8-9 AM (0)
Apr 01, 9-10 AM (1)
Apr 01, 10-11 AM (0)
Apr 01, 11-12 PM (0)
Apr 01, 12-1 PM (1)
Apr 01, 1-2 PM (0)
Apr 01, 2-3 PM (0)
Apr 01, 3-4 PM (0)
Apr 01, 4-5 PM (0)
Apr 01, 5-6 PM (0)
Apr 01, 6-7 PM (0)
Apr 01, 7-8 PM (0)
Apr 01, 8-9 PM (0)
Apr 01, 9-10 PM (0)
Apr 01, 10-11 PM (0)
Apr 01, 11-12 AM (0)
Apr 02, 12-1 AM (0)
Apr 02, 1-2 AM (0)
Apr 02, 2-3 AM (2)
Apr 02, 3-4 AM (0)
Apr 02, 4-5 AM (0)
Apr 02, 5-6 AM (3)
Apr 02, 6-7 AM (0)
Apr 02, 7-8 AM (0)
Apr 02, 8-9 AM (0)
Apr 02, 9-10 AM (2)
Apr 02, 10-11 AM (0)
Apr 02, 11-12 PM (0)
Apr 02, 12-1 PM (4)
Apr 02, 1-2 PM (0)
Apr 02, 2-3 PM (0)
Apr 02, 3-4 PM (0)
Apr 02, 4-5 PM (0)
Apr 02, 5-6 PM (0)
Apr 02, 6-7 PM (0)
Apr 02, 7-8 PM (0)
Apr 02, 8-9 PM (0)
Apr 02, 9-10 PM (0)
Apr 02, 10-11 PM (0)
Apr 02, 11-12 AM (0)
Apr 03, 12-1 AM (0)
Apr 03, 1-2 AM (0)
Apr 03, 2-3 AM (0)
Apr 03, 3-4 AM (0)
Apr 03, 4-5 AM (0)
37 commits this week Mar 27, 2026 - Apr 03, 2026
fix: handle malformed coin_identifier in search and align validator null semantics
Replace ArrayIndexOutOfBoundsException and NumberFormatException with proper
ApiException when coin_identifier lacks a colon separator or has a non-numeric
output index. Also align TokenNameValidator.validate() to accept null
consistently with PolicyIdValidator and SymbolValidator.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
test: add input validation tests for currency, address, and coin identifier (#727)
Adds 4 test classes to test_error_handling.py with 17 parametrized cases:
- SearchCurrencyValidation: policyId and symbol rejection (requires PR #726)
- AccountCurrencyValidation: policyId and token name rejection
- AddressValidation: invalid bech32 on /account/balance and /account/coins
- CoinIdentifierValidation: malformed identifier without colon separator
test: add input validation tests for currency, address, and coin identifier
Adds 4 test classes to test_error_handling.py with 17 parametrized cases:
- SearchCurrencyValidation: policyId and symbol rejection (requires PR #726)
- AccountCurrencyValidation: policyId and token name rejection
- AddressValidation: invalid bech32 on /account/balance and /account/coins
- CoinIdentifierValidation: malformed identifier without colon separator
test: add input validation tests for currency, address, and coin identifier
Adds 4 test classes to test_error_handling.py with 17 parametrized cases:
- SearchCurrencyValidation: policyId and symbol rejection (requires PR #726)
- AccountCurrencyValidation: policyId and token name rejection
- AddressValidation: invalid bech32 on /account/balance and /account/coins
- CoinIdentifierValidation: malformed identifier without colon separator
refactor: replace custom requireHex/requireValidSymbol with shared validators
Remove defense-in-depth validation methods from BaseCurrencyConditionBuilder
and delegate to PolicyIdValidator.validate() and SymbolValidator.validate()
instead, keeping the template method pattern for DB-specific SQL generation.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
refactor: add validate() methods to validators and remove private wrappers
Extract validate-and-throw logic from SearchServiceImpl and AccountServiceImpl
into PolicyIdValidator, SymbolValidator, and TokenNameValidator, eliminating
duplicated private validation methods across service classes.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
refactor: simplify validators to expose only isValid()
Validators now have a clean API - only isValid() per domain concept:
- PolicyIdValidator.isValid(): exactly 56 hex chars
- SymbolValidator.isValid(): non-empty hex string
- TokenNameValidator.isValid(): 0-64 hex chars or empty hex

Removed requireValid/requireHexOnly/requireValidHex from validators.
For raw hex checks (defense-in-depth at repository layer, AssetFingerprint),
use HexUtils.isHexString() directly.

All error types (INVALID_POLICY_ID 4023, INVALID_TOKEN_NAME 4024,
CURRENCY_SYMBOL_NOT_HEX 5059) are registered in RosettaErrorType and
returned by /network/options via ALL_ROSETTA_ERRORS.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
refactor: consolidate remaining hex validation calls through validators
Update SearchServiceImpl.validateCurrencySymbolIsHex and
AssetFingerprint.fromSubject to use PolicyIdValidator.isHexOnly()
instead of calling HexUtils.isHexString() directly. All hex validation
in the codebase now flows through the centralized validator classes.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
refactor: introduce PolicyIdValidator and TokenNameValidator classes
Consolidate scattered policyId/tokenName/hex validation into dedicated
validator classes under common.validation package. This replaces
duplicate regex patterns in AccountServiceImpl, CardanoAddressUtils,
ValidateParseUtil, and GovActionParamsUtil with single-source-of-truth
validators backed by HexUtils.isHexString().

- PolicyIdValidator: isValid(), requireValid(), isHexOnly(), requireHexOnly()
- TokenNameValidator: isValid()
- 35 unit tests for both validators
- All callers updated to delegate to validators

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
refactor: use JOOQ bind parameters in currency condition builders
Replace string concatenation into DSL.condition() SQL strings with
JOOQ's DSL.val() bind parameters. This makes the query construction
structurally safe — the database driver handles escaping via prepared
statement parameters, eliminating any possibility of unsanitized data
reaching SQL regardless of upstream validation.

PostgreSQL: uses jsonb_build_array(jsonb_build_object('key', ?)) to
build JSONB containment checks from bind parameters instead of
interpolating values into JSON literals.

H2: uses ? bind parameters in LIKE conditions instead of concatenating
values into the LIKE pattern string.

The requireHex() validation in BaseCurrencyConditionBuilder is retained
as a fast-fail check for better error messages, but is no longer the
sole protection against unsanitized input reaching queries.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
fix: align policyId validation in search endpoint with account endpoint
The search/transactions endpoint was missing policyId input validation
that the account endpoint already enforces. This aligns both endpoints
to use the same hex regex validation for policyId, and strengthens the
repository layer to also validate inputs before query construction.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>