Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.openelements.hiero.base.data;

import com.hedera.hashgraph.sdk.AccountId;
import org.jspecify.annotations.NonNull;

import java.util.Objects;

public record Balance(@NonNull AccountId accountId, long balance, long decimals) {
public Balance {
Objects.requireNonNull(accountId, "accountId must not be null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.openelements.hiero.base.data;

import org.jspecify.annotations.NonNull;

import java.util.List;
import java.util.Objects;

public record CustomFee(
@NonNull List<FixedFee> fixedFees,
@NonNull List<FractionalFee> fractionalFees,
@NonNull List<RoyaltyFee> royaltyFees
) {
public CustomFee {
Objects.requireNonNull(fixedFees, "fixedFees must not be null");
Objects.requireNonNull(fractionalFees, "fractionalFees must not be null");
Objects.requireNonNull(royaltyFees, "royaltyFees must not be null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.openelements.hiero.base.data;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.TokenId;
import org.jspecify.annotations.Nullable;

public record FixedFee(long amount, @Nullable AccountId collectorAccountId, @Nullable TokenId denominatingTokenId) {
Copy link
Member

Choose a reason for hiding this comment

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

NullChecks should be added in constructor.

public FixedFee {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.openelements.hiero.base.data;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.TokenId;
import org.jspecify.annotations.Nullable;

public record FractionalFee(
long numeratorAmount,
long denominatorAmount,
@Nullable AccountId collectorAccountId,
Copy link
Member

Choose a reason for hiding this comment

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

NullChecks should be added in constructor.

@Nullable TokenId denominatingTokenId
) {
public FractionalFee {
if (numeratorAmount < 0) {
throw new IllegalArgumentException("numeratorAmount must be greater than or equal to 0");
}
if (denominatorAmount < 0) {
throw new IllegalArgumentException("denominatorAmount must be greater than or equal to 0");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.openelements.hiero.base.data;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.TokenId;
import org.jspecify.annotations.Nullable;

public record RoyaltyFee(
Copy link
Member

Choose a reason for hiding this comment

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

@Ndacyayisenga-droid we should check if Hedera provides a documentation for those objects and add a javadoc here (we can create an issue for that)

Choose a reason for hiding this comment

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

@Ndacyayisenga-droid we should check if Hedera provides a documentation for those objects and add a javadoc here (we can create an issue for that)

There's hedera documentation for all that actually. I will get an issue once this is merged.

long numeratorAmount,
long denominatorAmount,
long fallbackFeeAmount,
@Nullable AccountId collectorAccountId,
Copy link
Member

Choose a reason for hiding this comment

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

NullChecks should be added in constructor.

Copy link
Member

Choose a reason for hiding this comment

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

@Ndacyayisenga-droid can you create an issue once the PR is merged

@Nullable TokenId denominatingTokenId
) {
public RoyaltyFee {
if (numeratorAmount < 0) {
throw new IllegalArgumentException("numeratorAmount must be greater than or equal to 0");
}
if (denominatorAmount < 0) {
throw new IllegalArgumentException("denominatorAmount must be greater than or equal to 0");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.openelements.hiero.base.data;

import com.hedera.hashgraph.sdk.TokenId;
import com.hedera.hashgraph.sdk.TokenType;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.util.Objects;

public record Token(
long decimals,
byte[] metadata,
@NonNull String name,
@NonNull String symbol,
@Nullable TokenId tokenId,
@NonNull TokenType type
) {
public Token {
Objects.requireNonNull(type, "type must not be null");
Objects.requireNonNull(name, "name must not be null");
Objects.requireNonNull(symbol, "symbol must not be null");
Objects.requireNonNull(metadata, "metadata must not be null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.openelements.hiero.base.data;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.TokenId;
import com.hedera.hashgraph.sdk.TokenSupplyType;
import com.hedera.hashgraph.sdk.TokenType;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.time.Instant;
import java.util.Objects;

public record TokenInfo(
@NonNull TokenId tokenId,
@NonNull TokenType type,
@NonNull String name,
@NonNull String symbol,
@Nullable String memo,
long decimals,
byte[] metadata,
@NonNull Instant createdTimestamp,
@NonNull Instant modifiedTimestamp,
@Nullable Instant expiryTimestamp,
@NonNull TokenSupplyType supplyType,
@NonNull String initialSupply,
@NonNull String totalSupply,
@NonNull String maxSupply,
@NonNull AccountId treasuryAccountId,
boolean deleted,
@NonNull CustomFee customFees
) {
public TokenInfo {
Objects.requireNonNull(tokenId, "tokenId must not be null");
Objects.requireNonNull(type, "type must not be null");
Objects.requireNonNull(name, "name must not be null");
Objects.requireNonNull(symbol, "symbol must not be null");
Objects.requireNonNull(metadata, "metadata must not be null");
Objects.requireNonNull(createdTimestamp, "createdTimestamp must not be null");
Objects.requireNonNull(modifiedTimestamp, "modifiedTimestamp must not be null");
Objects.requireNonNull(supplyType, "supplyType must not be null");
Objects.requireNonNull(initialSupply, "initialSupply must not be null");
Objects.requireNonNull(totalSupply, "totalSupply must not be null");
Objects.requireNonNull(maxSupply, "maxSupply must not be null");
Objects.requireNonNull(treasuryAccountId, "treasuryAccountId must not be null");
Objects.requireNonNull(customFees, "customFees must not be null");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.openelements.hiero.base.data.NetworkSupplies;
import com.openelements.hiero.base.data.Nft;
import com.openelements.hiero.base.data.NftMetadata;
import com.openelements.hiero.base.data.TokenInfo;
import com.openelements.hiero.base.mirrornode.MirrorNodeClient;
import java.util.List;
import java.util.Objects;
Expand Down Expand Up @@ -68,6 +69,12 @@ final Optional<NetworkSupplies> queryNetworkSupplies() throws HieroException {
return getJsonConverter().toNetworkSupplies(json);
}

@NonNull
public final Optional<TokenInfo> queryTokenById(@NonNull TokenId tokenId) throws HieroException {
final JSON json = getRestClient().queryTokenById(tokenId);
return getJsonConverter().toTokenInfo(json);
}

@Override
public @NonNull Optional<NftMetadata> getNftMetadata(TokenId tokenId) throws HieroException {
throw new UnsupportedOperationException("Not yet implemented");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import com.openelements.hiero.base.data.NetworkSupplies;
import com.openelements.hiero.base.data.Nft;
import com.openelements.hiero.base.data.TransactionInfo;
import com.openelements.hiero.base.data.Token;
import com.openelements.hiero.base.data.TokenInfo;
import com.openelements.hiero.base.data.Balance;

import java.util.List;
import java.util.Optional;
import org.jspecify.annotations.NonNull;
Expand Down Expand Up @@ -36,4 +40,9 @@ public interface MirrorNodeJsonConverter<JSON> {

List<Nft> toNfts(@NonNull JSON json);

Optional<TokenInfo> toTokenInfo(JSON json);

List<Balance> toBalances(JSON node);

List<Token> toTokens(JSON node);
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ default JSON queryNetworkSupplies() throws HieroException {
return doGetCall("/api/v1/network/supply");
}

@NonNull
default JSON queryTokenById(TokenId tokenId) throws HieroException {
return doGetCall("/api/v1/tokens/" + tokenId);
}

@NonNull
JSON doGetCall(@NonNull String path) throws HieroException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.openelements.hiero.base.implementation;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.TokenId;
import com.openelements.hiero.base.HieroException;
import com.openelements.hiero.base.data.Balance;
import com.openelements.hiero.base.data.Page;
import com.openelements.hiero.base.data.Token;
import com.openelements.hiero.base.data.TokenInfo;
import com.openelements.hiero.base.mirrornode.MirrorNodeClient;
import com.openelements.hiero.base.mirrornode.TokenRepository;
import org.jspecify.annotations.NonNull;

import java.util.Objects;
import java.util.Optional;

public class TokenRepositoryImpl implements TokenRepository {
private final MirrorNodeClient mirrorNodeClient;

public TokenRepositoryImpl(@NonNull final MirrorNodeClient mirrorNodeClient) {
this.mirrorNodeClient = Objects.requireNonNull(mirrorNodeClient, "mirrorNodeClient must not be null");
}

@Override
public Page<Token> findByAccount(@NonNull AccountId accountId) throws HieroException {
return mirrorNodeClient.queryTokensForAccount(accountId);
}

@Override
public Optional<TokenInfo> findById(@NonNull TokenId tokenId) throws HieroException {
return mirrorNodeClient.queryTokenById(tokenId);
}

@Override
public Page<Balance> getBalances(@NonNull TokenId tokenId) throws HieroException {
return mirrorNodeClient.queryTokenBalances(tokenId);
}

@Override
public Page<Balance> getBalancesForAccount(@NonNull TokenId tokenId, @NonNull AccountId accountId) throws HieroException {
return mirrorNodeClient.queryTokenBalancesForAccount(tokenId, accountId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
import com.openelements.hiero.base.data.NftMetadata;
import com.openelements.hiero.base.data.Page;
import com.openelements.hiero.base.data.TransactionInfo;
import com.openelements.hiero.base.data.TokenInfo;
import com.openelements.hiero.base.data.Balance;
import com.openelements.hiero.base.data.Token;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -237,6 +240,99 @@ default Optional<AccountInfo> queryAccount(@NonNull String accountId) throws Hie
@NonNull
Optional<NetworkSupplies> queryNetworkSupplies() throws HieroException;

/**
* Return Tokens associated with given accountId.
*
* @param accountId id of the account
* @return Optional of TokenInfo
* @throws HieroException if the search fails
*/
Page<Token> queryTokensForAccount(@NonNull AccountId accountId) throws HieroException;

/**
* Return Tokens associated with given accountId.
*
* @param accountId id of the account
* @return Optional of TokenInfo
* @throws HieroException if the search fails
*/
default Page<Token> queryTokensForAccount(@NonNull String accountId) throws HieroException {
Objects.requireNonNull(accountId, "accountId must not be null");
return queryTokensForAccount(AccountId.fromString(accountId));
}

/**
* Return Token Info for given tokenID.
*
* @param tokenId id of the token
* @return Optional of Token
* @throws HieroException if the search fails
*/
@NonNull
Optional<TokenInfo> queryTokenById(@NonNull TokenId tokenId) throws HieroException;

/**
* Return Token Info for given tokenID.
*
* @param tokenId id of the token
* @return Optional of Token
* @throws HieroException if the search fails
*/
@NonNull
default Optional<TokenInfo> queryTokenById(@NonNull String tokenId) throws HieroException {
Objects.requireNonNull(tokenId, "tokenId must not be null");
return queryTokenById(TokenId.fromString(tokenId));
}

/**
* Return Balance Info for given tokenID.
*
* @param tokenId id of the token
* @return Page of Balance
* @throws HieroException if the search fails
*/
@NonNull
Page<Balance> queryTokenBalances(@NonNull TokenId tokenId) throws HieroException;

/**
* Return Balance Info for given tokenID.
*
* @param tokenId id of the token
* @return Page of Balance
* @throws HieroException if the search fails
*/
@NonNull
default Page<Balance> queryTokenBalances(@NonNull String tokenId) throws HieroException {
Objects.requireNonNull(tokenId, "tokenId must not be null");
return queryTokenBalances(TokenId.fromString(tokenId));
}

/**
* Return Balance Info for given tokenID and accountId.
*
* @param tokenId id of the token
* @param accountId id of the account
* @return Page of Balance
* @throws HieroException if the search fails
*/
@NonNull
Page<Balance> queryTokenBalancesForAccount(@NonNull TokenId tokenId, @NonNull AccountId accountId) throws HieroException;

/**
* Return Balance Info for given tokenID and accountId.
*
* @param tokenId id of the token
* @param accountId id of the account
* @return Page of Balance
* @throws HieroException if the search fails
*/
@NonNull
default Page<Balance> queryTokenBalancesForAccount(@NonNull String tokenId, @NonNull String accountId) throws HieroException {
Objects.requireNonNull(tokenId, "tokenId must not be null");
Objects.requireNonNull(accountId, "accountId must not be null");
return queryTokenBalancesForAccount(TokenId.fromString(tokenId), AccountId.fromString(accountId));
}

@NonNull
Optional<NftMetadata> getNftMetadata(TokenId tokenId) throws HieroException;

Expand Down
Loading
Loading