Skip to content

feat(mirror): add account mirror endpoints#122

Open
alejandroGM0 wants to merge 3 commits into
hiero-ledger:mainfrom
alejandroGM0:issue/100-account-mirror-endpoints
Open

feat(mirror): add account mirror endpoints#122
alejandroGM0 wants to merge 3 commits into
hiero-ledger:mainfrom
alejandroGM0:issue/100-account-mirror-endpoints

Conversation

@alejandroGM0

@alejandroGM0 alejandroGM0 commented May 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds account-related mirror-node endpoints to hiero-enterprise-java, allowing applications to retrieve account information through the enterprise API instead of calling the mirror node directly.

Closes #100

What Changed

  • Added account mirror endpoint support for querying account data.
  • Added the models needed to represent account mirror-node responses.
  • Wired account lookups through the API/resource layer, service layer, and mirror client integration.
  • Added support for account-related request parameters and response mapping.
  • Updated sample or configuration code so the new account functionality can be exercised consistently.
  • Added tests for the new account mirror endpoint behavior.

Why

This expands the mirror-node integration surface in the enterprise Java SDK/API and provides a standardized way for consumers to access account data. It also keeps account lookup workflows consistent with the existing mirror endpoint patterns already available in the project.

Testing

  • Verified the new account mirror endpoints are covered by tests.
  • Confirmed account lookup responses are mapped correctly from mirror-node data.
  • Checked behavior for valid account IDs.
  • Checked error handling for invalid or missing account IDs.
  • Ensured existing mirror endpoint behavior remains unchanged.

Working

image image image image

Summary by CodeRabbit

  • New Features
    • Added account allowance query APIs to retrieve HBAR, fungible token, and NFT allowances for any account.
    • Added account staking rewards query APIs to view historical reward payouts.
    • Added token airdrop query APIs to retrieve both pending and outstanding airdrops assigned to accounts.

Review Change Stack

Signed-off-by: Alejandro <26930485+alejandroGM0@users.noreply.github.com>

@manishdait manishdait left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alejandroGM0, Thanks for the PR added some requested changes. Also add the e2e test for the new methods in the AccountRepositoryTest in spring and microprofile module


@Inject
public HieroEndpoint(final AccountClient client, final BlockRepository blockRepository) {
public HieroEndpoint(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can ignore sample for now

private final List<String> requestedPaths = new CopyOnWriteArrayList<>();

@BeforeEach
void startServer() throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be replace to use mockito mock

private final AccountRepository accountRepository;

public HieroEndpoint(final AccountClient client, final BlockRepository blockRepository) {
public HieroEndpoint(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same with this can ignore sample for now

private final List<String> requestedPaths = new CopyOnWriteArrayList<>();

@BeforeEach
void startServer() throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace with mockito mocks

alejandroGM0 added a commit to alejandroGM0/hiero-enterprise-java that referenced this pull request May 15, 2026
- Revert sample HieroEndpoint and pom changes per maintainer (ignore samples for now)
- Replace HttpServer-based MirrorNodeClientImplAccountEndpointsTest with Mockito mocks
  (Spring uses MockRestServiceServer; MicroProfile mocks ClientBuilder.newClient)
- Add e2e tests for findCryptoAllowances/findTokenAllowances/findNftAllowances/
  findStakingRewards/findOutstandingAirdrops/findPendingAirdrops in spring and
  microprofile AccountRepositoryTest
- Revert sample HieroEndpoint and pom changes per maintainer (ignore samples for now)
- Replace HttpServer-based MirrorNodeClientImplAccountEndpointsTest with Mockito mocks
  (Spring uses MockRestServiceServer; MicroProfile mocks ClientBuilder.newClient)
- Add e2e tests for findCryptoAllowances/findTokenAllowances/findNftAllowances/
  findStakingRewards/findOutstandingAirdrops/findPendingAirdrops in spring and
  microprofile AccountRepositoryTest

Signed-off-by: Alejandro <26930485+alejandroGM0@users.noreply.github.com>
@alejandroGM0 alejandroGM0 force-pushed the issue/100-account-mirror-endpoints branch from 57b7f02 to 95627fd Compare May 15, 2026 22:54
@aceppaluni aceppaluni added the status: ready-for-review PR is ready to be reviewed by team member label May 22, 2026

@aceppaluni aceppaluni left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alejandroGM0 The work here looks very good, thank you for this.

Left a thought and would like your input.

outstandingAirdropsPath,
pendingAirdropsPath),
pathCaptor.getAllValues());
assertEquals(1, cryptoAllowances.getSize());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alejandroGM0 These assertions are great. I am wondering if we should add a few more to validate a few representative mapped fields per endpoint so converter regressions are caught more explicitly.

For example

assertEquals(AccountId.fromString("0.0.1000"),
    stakingRewards.getData().get(0).accountId());

assertEquals(10,
    stakingRewards.getData().get(0).amount());

assertFalse(nftAllowances.getData().get(0).approvedForAll());

What do you think?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes sense — happy to add representative field assertions
here. Since the fixtures are deterministic and there isn't a separate
MirrorNodeJsonConverterImplTest for these new account models, this
client test is currently the only unit-level coverage of the new
converter mappings, so field-level assertions add real value.

Will mirror the same assertions in the Spring test.

final Page<TokenAirdrop> outstandingAirdrops = client.queryOutstandingAirdrops(accountId);
final Page<TokenAirdrop> pendingAirdrops = client.queryPendingAirdrops(accountId);

assertEquals(1, cryptoAllowances.getSize());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question here

Split the combined account endpoint client tests into six per-endpoint
cases with representative field assertions so converter regressions are
caught explicitly in Spring and MicroProfile.

Signed-off-by: Alejandro <26930485+alejandroGM0@users.noreply.github.com>
@alejandroGM0 alejandroGM0 requested review from a team as code owners May 27, 2026 14:03
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR extends the Hiero enterprise library to expose six new Mirror Node account endpoints for allowances, staking rewards, and token airdrops. It introduces typed data models, updates repository and client interfaces with new query methods, implements the queries in both MicroProfile and Spring frameworks, and provides comprehensive test coverage across both implementations.

Changes

Account Allowances, Rewards, and Airdrops

Layer / File(s) Summary
Domain models and TimestampRange contract update
hiero-enterprise-base/src/main/java/org/hiero/base/data/*.java
Five new immutable records (CryptoAllowance, TokenAllowance, NftAllowance, StakingReward, TokenAirdrop) represent allowances and payouts with null-safety enforcement. TimestampRange is updated so the to field becomes nullable to support open-ended timestamp ranges.
Base repository and client interface contracts
hiero-enterprise-base/src/main/java/org/hiero/base/mirrornode/AccountRepository.java, MirrorNodeClient.java, MirrorNodeJsonConverter.java, implementation/AccountRepositoryImpl.java
MirrorNodeClient and AccountRepository interfaces each declare six new query methods (crypto allowances, token allowances, NFT allowances, staking rewards, outstanding airdrops, pending airdrops) with both AccountId and String overloads. MirrorNodeJsonConverter interface adds corresponding JSON-to-domain conversion method contracts. AccountRepositoryImpl implements delegation to MirrorNodeClient.
MicroProfile client and JSON converter implementation
hiero-enterprise-microprofile/pom.xml, src/main/java/org/hiero/microprofile/implementation/MirrorNodeClientImpl.java, MirrorNodeJsonConverterImpl.java
MirrorNodeClientImpl adds six query methods that build REST paths and return paginated results via JSON conversion. MirrorNodeJsonConverterImpl parses JSON arrays for allowances, rewards, and airdrops, extracting nested objects and handling nullable fields and fractional-second timestamps. Mockito dependency added for test support.
Spring client and JSON converter implementation
hiero-enterprise-spring/src/main/java/org/hiero/spring/implementation/MirrorNodeClientImpl.java, MirrorNodeJsonConverterImpl.java
MirrorNodeClientImpl implements six query methods with REST path construction and paginated response wrapping. MirrorNodeJsonConverterImpl provides element converters and timestamp/nullable parsing utilities for crypto allowances, token allowances, NFT allowances, staking rewards, and token airdrops.
MicroProfile integration and unit tests
hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/AccountRepositoryTest.java, MirrorNodeClientImplAccountEndpointsTest.java
AccountRepositoryTest adds methods verifying repository returns non-null pages for each endpoint. MirrorNodeClientImplAccountEndpointsTest mocks JAX-RS responses and validates that domain object fields are correctly mapped from JSON, including null vs. non-null serial number behavior.
Spring integration and unit tests
hiero-enterprise-spring/src/test/java/org/hiero/spring/test/AccountRepositoryTest.java, MirrorNodeClientImplAccountEndpointsTest.java
AccountRepositoryTest adds methods asserting repository returns non-null pages. MirrorNodeClientImplAccountEndpointsTest stubs MockRestServiceServer responses and asserts field mappings for all six endpoints, with special handling for nullable serial numbers in outstanding vs. pending airdrops.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🐰 A rabbit hops through the fields with glee,
Six new endpoints now set the data free!
Allowances, rewards, and airdrops so bright,
Both MicroProfile and Spring—fully right!
With tests that verify each timestamp's flight,

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.84% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(mirror): add account mirror endpoints' directly describes the main objective of adding new account-related Mirror Node endpoints, which aligns with the primary changes throughout the changeset.
Linked Issues check ✅ Passed The PR implements all six required Mirror Node account endpoints (crypto allowances, token allowances, NFT allowances, staking rewards, outstanding airdrops, pending airdrops) with typed models, extending both Spring and MicroProfile implementations with feature parity and comprehensive tests.
Out of Scope Changes check ✅ Passed All changes are directly scoped to adding the six account Mirror Node endpoints via new domain models, repository/client interfaces, implementations, and tests. The single test-scoped mockito dependency addition supports the test coverage for these endpoints.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/AccountRepositoryTest.java (1)

146-150: ⚡ Quick win

Replace fixed sleep with bounded polling wait.

Using a fixed 10s pause makes these integration tests flaky and slower than necessary. Please poll accountRepository.findById(accountId) (or the target endpoint) with timeout + short interval, then proceed once data is visible.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/AccountRepositoryTest.java`
around lines 146 - 150, The fixed Thread.sleep in newAccountVisibleOnMirrorNode
makes tests slow and flaky; replace it with a bounded polling loop that calls
accountRepository.findById(account.accountId()) (or the target visibility check)
every short interval (e.g., 200-500ms) until a deadline (e.g., 5-10s) is
reached, returning the AccountId as soon as the repository returns a non-empty
result; if the deadline expires throw an exception or fail the test with a clear
message. Ensure you use the existing accountClient.createAccount() result
(variable account) and poll using account.accountId(), and avoid indefinite
waits.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/AccountRepositoryTest.java`:
- Around line 146-150: The fixed Thread.sleep in newAccountVisibleOnMirrorNode
makes tests slow and flaky; replace it with a bounded polling loop that calls
accountRepository.findById(account.accountId()) (or the target visibility check)
every short interval (e.g., 200-500ms) until a deadline (e.g., 5-10s) is
reached, returning the AccountId as soon as the repository returns a non-empty
result; if the deadline expires throw an exception or fail the test with a clear
message. Ensure you use the existing accountClient.createAccount() result
(variable account) and poll using account.accountId(), and avoid indefinite
waits.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7db76a61-e909-4575-bcd4-c7b4167efcae

📥 Commits

Reviewing files that changed from the base of the PR and between 5f6f281 and 4e233b0.

📒 Files selected for processing (19)
  • hiero-enterprise-base/src/main/java/org/hiero/base/data/CryptoAllowance.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/data/NftAllowance.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/data/StakingReward.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/data/TimestampRange.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/data/TokenAirdrop.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/data/TokenAllowance.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/implementation/AccountRepositoryImpl.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/implementation/MirrorNodeJsonConverter.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/mirrornode/AccountRepository.java
  • hiero-enterprise-base/src/main/java/org/hiero/base/mirrornode/MirrorNodeClient.java
  • hiero-enterprise-microprofile/pom.xml
  • hiero-enterprise-microprofile/src/main/java/org/hiero/microprofile/implementation/MirrorNodeClientImpl.java
  • hiero-enterprise-microprofile/src/main/java/org/hiero/microprofile/implementation/MirrorNodeJsonConverterImpl.java
  • hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/AccountRepositoryTest.java
  • hiero-enterprise-microprofile/src/test/java/org/hiero/microprofile/test/MirrorNodeClientImplAccountEndpointsTest.java
  • hiero-enterprise-spring/src/main/java/org/hiero/spring/implementation/MirrorNodeClientImpl.java
  • hiero-enterprise-spring/src/main/java/org/hiero/spring/implementation/MirrorNodeJsonConverterImpl.java
  • hiero-enterprise-spring/src/test/java/org/hiero/spring/test/AccountRepositoryTest.java
  • hiero-enterprise-spring/src/test/java/org/hiero/spring/test/MirrorNodeClientImplAccountEndpointsTest.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: ready-for-review PR is ready to be reviewed by team member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expose account allowances, reward payouts, and airdrop Mirror Node endpoints

3 participants