11package com .openelements .hiero .microprofile .implementation ;
22
33import com .hedera .hashgraph .sdk .AccountId ;
4+ import com .hedera .hashgraph .sdk .TokenId ;
45import com .openelements .hiero .base .data .AccountInfo ;
6+ import com .openelements .hiero .base .data .ExchangeRate ;
57import com .openelements .hiero .base .data .ExchangeRates ;
68import com .openelements .hiero .base .data .NetworkFee ;
79import com .openelements .hiero .base .data .NetworkStake ;
810import com .openelements .hiero .base .data .NetworkSupplies ;
911import com .openelements .hiero .base .data .Nft ;
1012import com .openelements .hiero .base .data .TransactionInfo ;
1113import com .openelements .hiero .base .implementation .MirrorNodeJsonConverter ;
14+ import jakarta .json .JsonArray ;
1215import jakarta .json .JsonObject ;
16+
17+ import java .time .Instant ;
1318import java .util .List ;
1419import java .util .Optional ;
20+ import java .util .Spliterator ;
21+ import java .util .Spliterators ;
22+ import java .util .stream .Stream ;
23+ import java .util .stream .StreamSupport ;
24+
25+ import jakarta .json .JsonValue ;
1526import org .jspecify .annotations .NonNull ;
1627
1728public class MirrorNodeJsonConverterImpl implements MirrorNodeJsonConverter <JsonObject > {
1829
1930 @ Override
2031 public @ NonNull Optional <Nft > toNft (@ NonNull JsonObject jsonObject ) {
21- throw new RuntimeException ("Not implemented" );
32+ try {
33+ final TokenId parsedTokenId = TokenId .fromString (jsonObject .getString ("token_id" ));
34+ final AccountId account = AccountId .fromString (jsonObject .getString ("account_id" ));
35+ final long serial = jsonObject .getJsonNumber ("serial_number" ).longValue ();
36+ final byte [] metadata = jsonObject .getString ("metadata" ).getBytes ();
37+ return Optional .of (new Nft (parsedTokenId , serial , account , metadata ));
38+ } catch (final Exception e ) {
39+ throw new IllegalStateException ("Can not parse JSON: " + jsonObject , e );
40+ }
2241 }
2342
2443 @ Override
2544 public @ NonNull Optional <NetworkSupplies > toNetworkSupplies (@ NonNull JsonObject jsonObject ) {
26- throw new RuntimeException ("Not implemented" );
45+ try {
46+ final String releasedSupply = jsonObject .getString ("released_supply" );
47+ final String totalSupply = jsonObject .getString ("total_supply" );
48+ return Optional .of (new NetworkSupplies (releasedSupply , totalSupply ));
49+ } catch (final Exception e ) {
50+ throw new IllegalStateException ("Can not parse JSON: " + jsonObject , e );
51+ }
2752 }
2853
2954 @ Override
3055 public @ NonNull Optional <NetworkStake > toNetworkStake (@ NonNull JsonObject jsonObject ) {
31- throw new RuntimeException ("Not implemented" );
56+ try {
57+ final long maxStakeReward = jsonObject .getJsonNumber ("max_stake_rewarded" ).longValue ();
58+ final long maxStakeRewardPerHbar = jsonObject .getJsonNumber ("max_staking_reward_rate_per_hbar" ).longValue ();
59+ final long maxTotalReward = jsonObject .getJsonNumber ("max_total_reward" ).longValue ();
60+ final double nodeRewardFeeFraction = jsonObject .getJsonNumber ("node_reward_fee_fraction" ).doubleValue ();
61+ final long reservedStakingRewards = jsonObject .getJsonNumber ("reserved_staking_rewards" ).longValue ();
62+ final long rewardBalanceThreshold = jsonObject .getJsonNumber ("reward_balance_threshold" ).longValue ();
63+ final long stakeTotal = jsonObject .getJsonNumber ("stake_total" ).longValue ();
64+ final long stakingPeriodDuration = jsonObject .getJsonNumber ("staking_period_duration" ).longValue ();
65+ final long stakingPeriodsStored = jsonObject .getJsonNumber ("staking_periods_stored" ).longValue ();
66+ final double stakingRewardFeeFraction = jsonObject .getJsonNumber ("staking_reward_fee_fraction" ).doubleValue ();
67+ final long stakingRewardRate = jsonObject .getJsonNumber ("staking_reward_rate" ).longValue ();
68+ final long stakingStartThreshold = jsonObject .getJsonNumber ("staking_start_threshold" ).longValue ();
69+ final long unreservedStakingRewardBalance = jsonObject .getJsonNumber ("unreserved_staking_reward_balance" ).longValue ();
70+
71+ return Optional .of (new NetworkStake (
72+ maxStakeReward ,
73+ maxStakeRewardPerHbar ,
74+ maxTotalReward ,
75+ nodeRewardFeeFraction ,
76+ reservedStakingRewards ,
77+ rewardBalanceThreshold ,
78+ stakeTotal ,
79+ stakingPeriodDuration ,
80+ stakingPeriodsStored ,
81+ stakingRewardFeeFraction ,
82+ stakingRewardRate ,
83+ stakingStartThreshold ,
84+ unreservedStakingRewardBalance
85+ ));
86+ } catch (final Exception e ) {
87+ throw new IllegalStateException ("Can not parse JSON: " + jsonObject , e );
88+ }
3289 }
3390
3491 @ Override
3592 public @ NonNull Optional <ExchangeRates > toExchangeRates (@ NonNull JsonObject jsonObject ) {
36- throw new RuntimeException ("Not implemented" );
93+ try {
94+ final int currentCentEquivalent = jsonObject .getJsonObject ("current_rate" ).getJsonNumber ("cent_equivalent" ).intValue ();
95+ final int currentHbarEquivalent = jsonObject .getJsonObject ("current_rate" ).getJsonNumber ("hbar_equivalent" ).intValue ();
96+ final Instant currentExpirationTime = Instant .ofEpochSecond (
97+ jsonObject .getJsonObject ("current_rate" ).getJsonNumber ("expiration_time" ).longValue ()
98+ );
99+
100+ final int nextCentEquivalent = jsonObject .getJsonObject ("next_rate" ).getJsonNumber ("cent_equivalent" ).intValue ();
101+ final int nextHbarEquivalent = jsonObject .getJsonObject ("next_rate" ).getJsonNumber ("hbar_equivalent" ).intValue ();
102+ final Instant nextExpirationTime = Instant .ofEpochSecond (
103+ jsonObject .getJsonObject ("next_rate" ).getJsonNumber ("expiration_time" ).longValue ()
104+ );
105+
106+ return Optional .of (new ExchangeRates (
107+ new ExchangeRate (currentCentEquivalent , currentHbarEquivalent , currentExpirationTime ),
108+ new ExchangeRate (nextCentEquivalent , nextHbarEquivalent , nextExpirationTime )
109+ ));
110+ } catch (final Exception e ) {
111+ throw new IllegalStateException ("Can not parse JSON: " + jsonObject , e );
112+ }
37113 }
38114
39115 @ Override
@@ -52,16 +128,70 @@ public class MirrorNodeJsonConverterImpl implements MirrorNodeJsonConverter<Json
52128
53129 @ Override
54130 public @ NonNull List <NetworkFee > toNetworkFees (@ NonNull JsonObject jsonObject ) {
55- throw new RuntimeException ("Not implemented" );
131+
132+ if (!jsonObject .containsKey ("nfts" )) {
133+ return List .of ();
134+ }
135+
136+ final JsonArray feesNode = jsonObject .getJsonArray ("fees" );
137+ return jsonArrayToStream (feesNode )
138+ .map (n -> {
139+ try {
140+ final long gas = n .asJsonObject ().getJsonNumber ("gas" ).longValue ();
141+ final String transactionType = n .asJsonObject ().getString ("transaction_type" );
142+ return new NetworkFee (gas , transactionType );
143+ } catch (final Exception e ) {
144+ throw new IllegalStateException ("Can not parse JSON: " + n , e );
145+ }
146+ })
147+ .toList ();
56148 }
57149
58150 @ Override
59151 public @ NonNull List <TransactionInfo > toTransactionInfos (@ NonNull JsonObject jsonObject ) {
60- throw new RuntimeException ("Not implemented" );
152+ if (!jsonObject .containsKey ("transactions" )) {
153+ return List .of ();
154+ }
155+
156+ final JsonArray transactionsNode = jsonObject .getJsonArray ("transactions" );
157+ return jsonArrayToStream (transactionsNode )
158+ .map (n -> {
159+ try {
160+ final String transactionId = n .asJsonObject ().getString ("transaction_id" );
161+ return new TransactionInfo (transactionId );
162+ } catch (final Exception e ) {
163+ throw new IllegalStateException ("Can not parse JSON: " + n , e );
164+ }
165+ })
166+ .toList ();
61167 }
62168
63169 @ Override
64170 public List <Nft > toNfts (@ NonNull JsonObject jsonObject ) {
65- throw new RuntimeException ("Not implemented" );
171+ if (!jsonObject .containsKey ("transactions" )) {
172+ return List .of ();
173+ }
174+
175+ final JsonArray nftsArray = jsonObject .getJsonArray ("nfts" );
176+ if (nftsArray .isEmpty ()) {
177+ throw new IllegalArgumentException ("NFTs jsonObject is not an array: " + nftsArray );
178+ }
179+ Spliterator <JsonValue > spliterator = Spliterators .spliteratorUnknownSize (nftsArray .iterator (),
180+ Spliterator .ORDERED );
181+ return StreamSupport .stream (spliterator , false )
182+ .map (n -> toNft (n .asJsonObject ()))
183+ .filter (Optional ::isPresent )
184+ .map (Optional ::get )
185+ .toList ();
186+ }
187+
188+ @ NonNull
189+ private Stream <JsonValue > jsonArrayToStream (@ NonNull final JsonArray jsonObject ) {
190+ if (jsonObject .isEmpty ()) {
191+ throw new IllegalStateException ("not an array" );
192+ }
193+ return StreamSupport
194+ .stream (Spliterators .spliteratorUnknownSize (jsonObject .iterator (), Spliterator .ORDERED ), false );
66195 }
67196}
197+
0 commit comments