Skip to content

Commit d467128

Browse files
Merge pull request #132 from theboywholived/main
Resolves #127 to add implementation for Microprofile JSON parser
2 parents e397a34 + 33c053c commit d467128

File tree

1 file changed

+137
-7
lines changed

1 file changed

+137
-7
lines changed

hiero-enterprise-microprofile/src/main/java/com/openelements/hiero/microprofile/implementation/MirrorNodeJsonConverterImpl.java

Lines changed: 137 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,115 @@
11
package com.openelements.hiero.microprofile.implementation;
22

33
import com.hedera.hashgraph.sdk.AccountId;
4+
import com.hedera.hashgraph.sdk.TokenId;
45
import com.openelements.hiero.base.data.AccountInfo;
6+
import com.openelements.hiero.base.data.ExchangeRate;
57
import com.openelements.hiero.base.data.ExchangeRates;
68
import com.openelements.hiero.base.data.NetworkFee;
79
import com.openelements.hiero.base.data.NetworkStake;
810
import com.openelements.hiero.base.data.NetworkSupplies;
911
import com.openelements.hiero.base.data.Nft;
1012
import com.openelements.hiero.base.data.TransactionInfo;
1113
import com.openelements.hiero.base.implementation.MirrorNodeJsonConverter;
14+
import jakarta.json.JsonArray;
1215
import jakarta.json.JsonObject;
16+
17+
import java.time.Instant;
1318
import java.util.List;
1419
import 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;
1526
import org.jspecify.annotations.NonNull;
1627

1728
public 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

Comments
 (0)