AccountTemplate.java
/*
* @copyright defined in LICENSE.txt
*/
package hera.client;
import static hera.api.function.Functions.identify;
import static hera.client.ClientConstants.ACCOUNT_CREATE_NAME;
import static hera.client.ClientConstants.ACCOUNT_GETNAMEOWNER;
import static hera.client.ClientConstants.ACCOUNT_GETSTAKINGINFO;
import static hera.client.ClientConstants.ACCOUNT_GETSTATE;
import static hera.client.ClientConstants.ACCOUNT_LIST_ELECTED;
import static hera.client.ClientConstants.ACCOUNT_SIGN;
import static hera.client.ClientConstants.ACCOUNT_STAKING;
import static hera.client.ClientConstants.ACCOUNT_UNSTAKING;
import static hera.client.ClientConstants.ACCOUNT_UPDATE_NAME;
import static hera.client.ClientConstants.ACCOUNT_VERIFY;
import static hera.client.ClientConstants.ACCOUNT_VOTE;
import static hera.client.ClientConstants.ACCOUNT_VOTESOF;
import hera.ContextProvider;
import hera.ContextProviderInjectable;
import hera.annotation.ApiAudience;
import hera.annotation.ApiStability;
import hera.api.AccountOperation;
import hera.api.function.Function1;
import hera.api.function.Function2;
import hera.api.function.Function3;
import hera.api.function.Function4;
import hera.api.model.Account;
import hera.api.model.AccountAddress;
import hera.api.model.AccountState;
import hera.api.model.AccountTotalVote;
import hera.api.model.Aer;
import hera.api.model.ElectedCandidate;
import hera.api.model.RawTransaction;
import hera.api.model.StakeInfo;
import hera.api.model.Transaction;
import hera.api.model.TxHash;
import hera.client.internal.AccountBaseTemplate;
import hera.exception.RpcException;
import hera.exception.RpcExceptionConverter;
import hera.key.Signer;
import hera.strategy.PriorityProvider;
import hera.strategy.StrategyApplier;
import hera.util.ExceptionConverter;
import io.grpc.ManagedChannel;
import java.util.List;
import java.util.concurrent.Future;
import lombok.AccessLevel;
import lombok.Getter;
@ApiAudience.Private
@ApiStability.Unstable
public class AccountTemplate
implements AccountOperation, ChannelInjectable, ContextProviderInjectable {
protected final ExceptionConverter<RpcException> exceptionConverter = new RpcExceptionConverter();
protected AccountBaseTemplate accountBaseTemplate = new AccountBaseTemplate();
protected ContextProvider contextProvider;
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final StrategyApplier strategyApplier =
StrategyApplier.of(contextProvider.get(), PriorityProvider.get());
@Override
public void setChannel(final ManagedChannel channel) {
this.accountBaseTemplate.setChannel(channel);;
}
@Override
public void setContextProvider(final ContextProvider contextProvider) {
this.contextProvider = contextProvider;
this.accountBaseTemplate.setContextProvider(contextProvider);
}
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<AccountAddress, Future<AccountState>> stateFunction =
getStrategyApplier()
.apply(identify(this.accountBaseTemplate.getStateFunction(), ACCOUNT_GETSTATE));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function3<Signer, String, Long,
Future<TxHash>> createNameFunction =
getStrategyApplier()
.apply(identify(this.accountBaseTemplate.getCreateNameFunction(),
ACCOUNT_CREATE_NAME));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function4<Signer, String, AccountAddress, Long,
Future<TxHash>> updateNameFunction =
getStrategyApplier().apply(
identify(this.accountBaseTemplate.getUpdateNameFunction(), ACCOUNT_UPDATE_NAME));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function2<String, Long, Future<AccountAddress>> nameOwnerFunction =
getStrategyApplier().apply(
identify(this.accountBaseTemplate.getGetNameOwnerFunction(), ACCOUNT_GETNAMEOWNER));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function3<Signer, Aer, Long,
Future<TxHash>> stakingFunction =
getStrategyApplier().apply(
identify(this.accountBaseTemplate.getStakingFunction(), ACCOUNT_STAKING));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function3<Signer, Aer, Long,
Future<TxHash>> unstakingFunction =
getStrategyApplier().apply(
identify(this.accountBaseTemplate.getUnstakingFunction(), ACCOUNT_UNSTAKING));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<AccountAddress, Future<StakeInfo>> stakingInfoFunction =
getStrategyApplier().apply(
identify(this.accountBaseTemplate.getStakingInfoFunction(), ACCOUNT_GETSTAKINGINFO));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function2<Account, RawTransaction,
Future<Transaction>> signFunction =
getStrategyApplier()
.apply(identify(this.accountBaseTemplate.getSignFunction(), ACCOUNT_SIGN));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function2<Account, Transaction, Future<Boolean>> verifyFunction =
getStrategyApplier()
.apply(identify(this.accountBaseTemplate.getVerifyFunction(), ACCOUNT_VERIFY));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function4<Signer, String, List<String>, Long,
Future<TxHash>> voteFunction =
getStrategyApplier().apply(
identify(this.accountBaseTemplate.getVoteFunction(), ACCOUNT_VOTE));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function2<String, Integer,
Future<List<ElectedCandidate>>> listElectedFunction = getStrategyApplier().apply(
identify(this.accountBaseTemplate.getListElectedFunction(), ACCOUNT_LIST_ELECTED));
@Getter(lazy = true, value = AccessLevel.PROTECTED)
private final Function1<AccountAddress, Future<AccountTotalVote>> votesOfFunction =
getStrategyApplier().apply(
identify(this.accountBaseTemplate.getVotesOfFunction(), ACCOUNT_VOTESOF));
@Override
public AccountState getState(final Account account) {
return getState(account.getAddress());
}
@Override
public AccountState getState(final AccountAddress address) {
try {
return getStateFunction().apply(address).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public TxHash createName(final Account account, final String name, final long nonce) {
if (!(account.getKey() instanceof Signer)) {
throw new UnsupportedOperationException();
}
return createName(account.getKey(), name, nonce);
}
@Override
public TxHash createName(final Signer signer, final String name, final long nonce) {
try {
return getCreateNameFunction().apply(signer, name, nonce).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public TxHash updateName(final Account account, final String name, final AccountAddress newOwner,
final long nonce) {
if (!(account.getKey() instanceof Signer)) {
throw new UnsupportedOperationException();
}
return updateName(account.getKey(), name, newOwner, nonce);
}
@Override
public TxHash updateName(final Signer signer, final String name, final AccountAddress newOwner,
final long nonce) {
try {
return getUpdateNameFunction().apply(signer, name, newOwner, nonce).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public AccountAddress getNameOwner(final String name) {
return getNameOwner(name, 0);
}
@Override
public AccountAddress getNameOwner(final String name, final long blockNumber) {
try {
return getNameOwnerFunction().apply(name, blockNumber).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public TxHash stake(final Account account, final Aer amount, final long nonce) {
if (!(account.getKey() instanceof Signer)) {
throw new UnsupportedOperationException();
}
return stake(account.getKey(), amount, nonce);
}
@Override
public TxHash stake(final Signer signer, final Aer amount, final long nonce) {
try {
return getStakingFunction().apply(signer, amount, nonce).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public TxHash unstake(final Account account, final Aer amount, final long nonce) {
if (!(account.getKey() instanceof Signer)) {
throw new UnsupportedOperationException();
}
return unstake(account.getKey(), amount, nonce);
}
@Override
public TxHash unstake(final Signer signer, final Aer amount, final long nonce) {
try {
return getUnstakingFunction().apply(signer, amount, nonce).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public StakeInfo getStakingInfo(final AccountAddress accountAddress) {
try {
return getStakingInfoFunction().apply(accountAddress).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public Transaction sign(final Account account, final RawTransaction rawTransaction) {
try {
return getSignFunction().apply(account, rawTransaction).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public boolean verify(final Account account, final Transaction signedTransaction) {
try {
return getVerifyFunction().apply(account, signedTransaction).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public TxHash vote(final Signer signer, final String voteId, final List<String> candidates,
final long nonce) {
try {
return getVoteFunction().apply(signer, voteId, candidates, nonce).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public List<ElectedCandidate> listElected(final String voteId, final int showCount) {
try {
return getListElectedFunction().apply(voteId, showCount).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
@Override
public AccountTotalVote getVotesOf(final AccountAddress accountAddress) {
try {
return getVotesOfFunction().apply(accountAddress).get();
} catch (Exception e) {
throw exceptionConverter.convert(e);
}
}
}