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,41 @@
package com.openelements.hiero.base.data;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.ContractId;
import com.hedera.hashgraph.sdk.PublicKey;
import java.time.Instant;
import java.util.Objects;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

/**
* Represents a smart contract on the Hiero network.
*/
public record Contract(
@NonNull ContractId contractId,
@Nullable PublicKey adminKey,
@Nullable AccountId autoRenewAccount,
int autoRenewPeriod,
@NonNull Instant createdTimestamp,
boolean deleted,
@Nullable Instant expirationTimestamp,
@Nullable String fileId,
@Nullable String evmAddress,
@Nullable String memo,
@Nullable Integer maxAutomaticTokenAssociations,
@Nullable Long nonce,
@Nullable String obtainerId,
boolean permanentRemoval,
@Nullable String proxyAccountId,
@NonNull Instant fromTimestamp,
@NonNull Instant toTimestamp,
@Nullable String bytecode,
@Nullable String runtimeBytecode
) {
public Contract {
Objects.requireNonNull(contractId, "contractId must not be null");
Objects.requireNonNull(createdTimestamp, "createdTimestamp must not be null");
Objects.requireNonNull(fromTimestamp, "fromTimestamp must not be null");
Objects.requireNonNull(toTimestamp, "toTimestamp must not be null");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.openelements.hiero.base.data;

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

/**
* Basic {@link Page} implementation backed by an in-memory list.
*
* @param <T> element type for the page
*/
public final class SinglePage<T> implements Page<T> {

private final List<T> data;

public SinglePage(final List<T> data) {
this.data = List.copyOf(Objects.requireNonNull(data, "data must not be null"));
}

@Override
public int getPageIndex() {
return 0;
}

@Override
public int getSize() {
return data.size();
}

@Override
public List<T> getData() {
return data;
}

@Override
public boolean hasNext() {
return false;
}

@Override
public Page<T> next() {
throw new IllegalStateException("No next page");
}

@Override
public Page<T> first() {
return this;
}

@Override
public boolean isFirst() {
return true;
}
}

Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package com.openelements.hiero.base.implementation;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.ContractId;
import com.hedera.hashgraph.sdk.TokenId;
import com.hedera.hashgraph.sdk.TopicId;
import com.openelements.hiero.base.HieroException;
import com.openelements.hiero.base.data.Contract;
import com.openelements.hiero.base.data.Nft;
import com.openelements.hiero.base.data.NftMetadata;
import com.openelements.hiero.base.data.AccountInfo;
import com.openelements.hiero.base.data.ExchangeRates;
import com.openelements.hiero.base.data.NetworkFee;
import com.openelements.hiero.base.data.NetworkStake;
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.Page;
import com.openelements.hiero.base.data.TokenInfo;
import com.openelements.hiero.base.data.TransactionInfo;
import com.openelements.hiero.base.data.Topic;
Expand Down Expand Up @@ -105,4 +108,17 @@ public final Optional<TopicMessage> queryTopicMessageBySequenceNumber(TopicId to
throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public @NonNull Page<Contract> queryContracts() throws HieroException {
final JSON json = getRestClient().queryContracts();
return getJsonConverter().toContractPage(json);
}

@Override
public @NonNull Optional<Contract> queryContractById(@NonNull final ContractId contractId) throws HieroException {
Objects.requireNonNull(contractId, "contractId must not be null");
final JSON json = getRestClient().queryContractById(contractId);
return getJsonConverter().toContract(json);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.openelements.hiero.base.implementation;

import com.hedera.hashgraph.sdk.ContractId;
import com.openelements.hiero.base.HieroException;
import com.openelements.hiero.base.data.Contract;
import com.openelements.hiero.base.data.Page;
import com.openelements.hiero.base.mirrornode.ContractRepository;
import com.openelements.hiero.base.mirrornode.MirrorNodeClient;
import java.util.Objects;
import java.util.Optional;
import org.jspecify.annotations.NonNull;

/**
* Implementation of ContractRepository that uses MirrorNodeClient to query contract data.
*/
public class ContractRepositoryImpl implements ContractRepository {

private final MirrorNodeClient mirrorNodeClient;

/**
* Creates a new ContractRepositoryImpl with the given MirrorNodeClient.
*
* @param mirrorNodeClient the mirror node client to use for queries
*/
public ContractRepositoryImpl(@NonNull final MirrorNodeClient mirrorNodeClient) {
this.mirrorNodeClient = Objects.requireNonNull(mirrorNodeClient, "mirrorNodeClient must not be null");
}

@NonNull
@Override
public Page<Contract> findAll() throws HieroException {
return mirrorNodeClient.queryContracts();
}

@NonNull
@Override
public Optional<Contract> findById(@NonNull final ContractId contractId) throws HieroException {
return mirrorNodeClient.queryContractById(contractId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
import com.openelements.hiero.base.data.Balance;
import com.openelements.hiero.base.data.Topic;
import com.openelements.hiero.base.data.TopicMessage;
import com.openelements.hiero.base.data.Contract;
import com.openelements.hiero.base.data.Page;

import java.util.List;
import java.util.Optional;
import org.jspecify.annotations.NonNull;

public interface MirrorNodeJsonConverter<JSON> {

@NonNull
Optional<Nft> toNft(@NonNull JSON json);

Expand Down Expand Up @@ -59,4 +60,13 @@ public interface MirrorNodeJsonConverter<JSON> {

@NonNull
List<TopicMessage> toTopicMessages(JSON json);

@NonNull
Optional<Contract> toContract(@NonNull JSON json);

@NonNull
Page<Contract> toContractPage(@NonNull JSON json);

@NonNull
List<Contract> toContracts(@NonNull JSON json);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.openelements.hiero.base.implementation;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.ContractId;
import com.hedera.hashgraph.sdk.TokenId;
import com.hedera.hashgraph.sdk.TopicId;
import com.openelements.hiero.base.HieroException;
Expand Down Expand Up @@ -68,4 +69,15 @@ default JSON queryTopicMessageBySequenceNumber(TopicId topicId, long sequenceNum

@NonNull
JSON doGetCall(@NonNull String path) throws HieroException;

@NonNull
default JSON queryContracts() throws HieroException {
return doGetCall("/api/v1/contracts");
}

@NonNull
default JSON queryContractById(@NonNull final ContractId contractId) throws HieroException {
Objects.requireNonNull(contractId, "contractId must not be null");
return doGetCall("/api/v1/contracts/" + contractId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.openelements.hiero.base.mirrornode;

import com.hedera.hashgraph.sdk.ContractId;
import com.openelements.hiero.base.HieroException;
import com.openelements.hiero.base.data.Contract;
import com.openelements.hiero.base.data.Page;
import java.util.Objects;
import java.util.Optional;
import org.jspecify.annotations.NonNull;

/**
* Interface for interacting with smart contracts on a Hiero network. This interface provides methods for searching for contracts.
*/
public interface ContractRepository {

/**
* Return all contracts.
*
* @return first page of contracts
* @throws HieroException if the search fails
*/
@NonNull
Page<Contract> findAll() throws HieroException;

/**
* Return a contract by its contract ID.
*
* @param contractId id of the contract
* @return {@link Optional} containing the found contract or null
* @throws HieroException if the search fails
*/
@NonNull
Optional<Contract> findById(@NonNull ContractId contractId) throws HieroException;

/**
* Return a contract by its contract ID.
*
* @param contractId id of the contract
* @return {@link Optional} containing the found contract or null
* @throws HieroException if the search fails
*/
@NonNull
default Optional<Contract> findById(@NonNull String contractId) throws HieroException {
Objects.requireNonNull(contractId, "contractId must not be null");
return findById(ContractId.fromString(contractId));
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.openelements.hiero.base.mirrornode;

import com.hedera.hashgraph.sdk.AccountId;
import com.hedera.hashgraph.sdk.ContractId;
import com.hedera.hashgraph.sdk.TokenId;
import com.hedera.hashgraph.sdk.TopicId;
import com.openelements.hiero.base.HieroException;
import com.openelements.hiero.base.data.AccountInfo;
import com.openelements.hiero.base.data.Balance;
import com.openelements.hiero.base.data.Contract;
import com.openelements.hiero.base.data.ExchangeRates;
import com.openelements.hiero.base.data.NetworkFee;
import com.openelements.hiero.base.data.NetworkStake;
Expand Down Expand Up @@ -143,7 +145,7 @@ default Optional<Nft> queryNftsByTokenIdAndSerial(@NonNull String tokenId, long
*/
@NonNull
default Optional<Nft> queryNftsByAccountAndTokenIdAndSerial(@NonNull AccountId accountId, @NonNull TokenId tokenId,
long serialNumber) throws HieroException {
long serialNumber) throws HieroException {
Objects.requireNonNull(accountId, "newAccountId must not be null");
return queryNftsByTokenIdAndSerial(tokenId, serialNumber)
.filter(nft -> Objects.equals(nft.owner(), accountId));
Expand All @@ -160,7 +162,7 @@ default Optional<Nft> queryNftsByAccountAndTokenIdAndSerial(@NonNull AccountId a
*/
@NonNull
default Optional<Nft> queryNftsByAccountAndTokenIdAndSerial(@NonNull String accountId, @NonNull String tokenId,
long serialNumber) throws HieroException {
long serialNumber) throws HieroException {
Objects.requireNonNull(accountId, "accountId must not be null");
Objects.requireNonNull(tokenId, "tokenId must not be null");
return queryNftsByAccountAndTokenIdAndSerial(AccountId.fromString(accountId), TokenId.fromString(tokenId),
Expand Down Expand Up @@ -459,4 +461,37 @@ default Optional<TopicMessage> queryTopicMessageBySequenceNumber(String topicId,

@NonNull
Page<NftMetadata> findAllNftTypes();

/**
* Queries all contracts.
*
* @return the contracts
* @throws HieroException if an error occurs
*/
@NonNull
Page<Contract> queryContracts() throws HieroException;

/**
* Queries a contract by its contract ID.
*
* @param contractId the contract ID
* @return the contract information
* @throws HieroException if an error occurs
*/
@NonNull
Optional<Contract> queryContractById(@NonNull ContractId contractId) throws HieroException;

/**
* Queries a contract by its contract ID.
*
* @param contractId the contract ID
* @return the contract information
* @throws HieroException if an error occurs
*/
@NonNull
default Optional<Contract> queryContractById(@NonNull String contractId) throws HieroException {
Objects.requireNonNull(contractId, "contractId must not be null");
return queryContractById(ContractId.fromString(contractId));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
import com.openelements.hiero.base.implementation.SmartContractClientImpl;
import com.openelements.hiero.base.implementation.TokenRepositoryImpl;
import com.openelements.hiero.base.implementation.TransactionRepositoryImpl;
import com.openelements.hiero.base.implementation.ContractRepositoryImpl;
import com.openelements.hiero.base.mirrornode.AccountRepository;
import com.openelements.hiero.base.mirrornode.MirrorNodeClient;
import com.openelements.hiero.base.mirrornode.NetworkRepository;
import com.openelements.hiero.base.mirrornode.NftRepository;
import com.openelements.hiero.base.mirrornode.TokenRepository;
import com.openelements.hiero.base.mirrornode.TransactionRepository;
import com.openelements.hiero.base.mirrornode.ContractRepository;
import com.openelements.hiero.base.protocol.ProtocolLayerClient;
import com.openelements.hiero.base.verification.ContractVerificationClient;
import com.openelements.hiero.microprofile.implementation.ContractVerificationClientImpl;
Expand Down Expand Up @@ -159,4 +161,11 @@ TransactionRepository createTransactionRepository(@NonNull final MirrorNodeClien
TokenRepository createTokenRepository(@NonNull final MirrorNodeClient mirrorNodeClient) {
return new TokenRepositoryImpl(mirrorNodeClient);
}

@NonNull
@Produces
@ApplicationScoped
ContractRepository createContractRepository(@NonNull final MirrorNodeClient mirrorNodeClient) {
return new ContractRepositoryImpl(mirrorNodeClient);
}
}
Loading
Loading