Skip to content

Commit 7bd0e09

Browse files
authored
feat: MirrorNodeAccountBalanceQuery (#2895)
Signed-off-by: Mustafa Uzun <mustafa.uzun@limechain.tech>
1 parent 3f59625 commit 7bd0e09

7 files changed

Lines changed: 1065 additions & 4 deletions

File tree

examples/src/main/java/com/hedera/hashgraph/sdk/examples/GetAccountBalanceExample.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: Apache-2.0
22
package com.hedera.hashgraph.sdk.examples;
33

4-
import com.hedera.hashgraph.sdk.AccountBalanceQuery;
54
import com.hedera.hashgraph.sdk.AccountId;
65
import com.hedera.hashgraph.sdk.Client;
76
import com.hedera.hashgraph.sdk.Hbar;
7+
import com.hedera.hashgraph.sdk.MirrorNodeAccountBalanceQuery;
88
import com.hedera.hashgraph.sdk.logger.LogLevel;
99
import com.hedera.hashgraph.sdk.logger.Logger;
1010
import io.github.cdimascio.dotenv.Dotenv;
@@ -49,18 +49,22 @@ public static void main(String[] args) throws Exception {
4949
* Step 0:
5050
* Create and configure the SDK Client.
5151
*
52-
* Because AccountBalanceQuery is a free query, we can make it without setting an operator on the client.
52+
* Because MirrorNodeAccountBalanceQuery is a free query, we can make it without setting an operator
53+
* on the client.
5354
*/
5455
Client client = ClientHelper.forName(HEDERA_NETWORK);
5556
// Attach logger to the SDK Client.
5657
client.setLogger(new Logger(LogLevel.valueOf(SDK_LOG_LEVEL)));
5758

5859
/*
5960
* Step 1:
60-
* Execute AccountBalanceQuery and output operator's account balance.
61+
* Execute MirrorNodeAccountBalanceQuery and output operator's account balance.
62+
*
63+
* Note: the mirror node is eventually consistent, so a balance read immediately after a
64+
* transaction may lag the network by a few seconds.
6165
*/
6266
Hbar operatorsBalance =
63-
new AccountBalanceQuery().setAccountId(OPERATOR_ID).execute(client).hbars;
67+
new MirrorNodeAccountBalanceQuery().setAccountId(OPERATOR_ID).execute(client).hbars;
6468

6569
System.out.println("Operator's Hbar account balance: " + operatorsBalance);
6670

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
package com.hedera.hashgraph.sdk;
3+
4+
import com.google.common.base.MoreObjects;
5+
import com.google.gson.JsonArray;
6+
import com.google.gson.JsonObject;
7+
import java.util.Objects;
8+
import javax.annotation.Nullable;
9+
10+
/**
11+
* The HBAR balance of an account as reported by the mirror node REST API.
12+
*
13+
* <p>Returned by {@link MirrorNodeAccountBalanceQuery}. Token balances are not included.
14+
*/
15+
public final class MirrorNodeAccountBalance {
16+
/**
17+
* The HBAR balance of the account.
18+
*/
19+
public final Hbar hbars;
20+
21+
/**
22+
* Constructor.
23+
*
24+
* @param hbars the HBAR balance of the account
25+
*/
26+
MirrorNodeAccountBalance(Hbar hbars) {
27+
this.hbars = Objects.requireNonNull(hbars);
28+
}
29+
30+
/**
31+
* Create a balance from a mirror node REST JSON payload.
32+
*
33+
* <p>The mirror node reports an account it does not know with an empty {@code balances} array — not
34+
* a 404. That case is signalled by returning {@code null}; the caller decides how to report it. An
35+
* account that exists but holds no HBAR is a populated entry with {@code "balance": 0} and is parsed
36+
* normally, so a genuine zero is never mistaken for a missing account.
37+
*
38+
* @param root the JSON object returned by {@code GET /api/v1/balances}
39+
* @return the new balance, or {@code null} if the mirror node knows no such account
40+
* @throws IllegalStateException if the payload is not a well-formed balances response
41+
*/
42+
@Nullable
43+
static MirrorNodeAccountBalance fromJson(JsonObject root) {
44+
if (!root.has("balances") || root.get("balances").isJsonNull()) {
45+
throw new IllegalStateException("Mirror Node returned a malformed response: no `balances` array");
46+
}
47+
48+
JsonArray balances = root.getAsJsonArray("balances");
49+
if (balances.isEmpty()) {
50+
return null;
51+
}
52+
53+
JsonObject balance = balances.get(0).getAsJsonObject();
54+
if (!balance.has("balance") || balance.get("balance").isJsonNull()) {
55+
throw new IllegalStateException(
56+
"Mirror Node returned a malformed response: balances entry has no `balance` field");
57+
}
58+
59+
return new MirrorNodeAccountBalance(
60+
Hbar.fromTinybars(balance.get("balance").getAsLong()));
61+
}
62+
63+
/**
64+
* Extract the HBAR balance.
65+
*
66+
* @return the HBAR balance of the account
67+
*/
68+
public Hbar getHbars() {
69+
return hbars;
70+
}
71+
72+
@Override
73+
public String toString() {
74+
return MoreObjects.toStringHelper(this).add("hbars", hbars).toString();
75+
}
76+
}

0 commit comments

Comments
 (0)