TransactionApiImpl.java
/*
* @copyright defined in LICENSE.txt
*/
package hera.wallet.internal;
import hera.api.function.Function0;
import hera.api.function.Function2;
import hera.api.model.AccountAddress;
import hera.api.model.Aer;
import hera.api.model.BytesValue;
import hera.api.model.ContractAddress;
import hera.api.model.ContractDefinition;
import hera.api.model.ContractInvocation;
import hera.api.model.ContractTxHash;
import hera.api.model.Fee;
import hera.api.model.RawTransaction;
import hera.api.model.Transaction;
import hera.api.model.TxHash;
import hera.api.model.internal.TryCountAndInterval;
import hera.api.transaction.SimpleNonceProvider;
import hera.client.AergoClient;
import hera.exception.WalletException;
import hera.exception.WalletExceptionConverter;
import hera.key.Signer;
import hera.util.ExceptionConverter;
import hera.wallet.TransactionApi;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import lombok.NonNull;
import lombok.Setter;
public class TransactionApiImpl implements TransactionApi, ClientInjectable {
protected final Trier trier;
protected final Signer signer;
@Setter
@NonNull
protected AergoClient client;
protected final ExceptionConverter<WalletException> converter = new WalletExceptionConverter();
/**
* TransactionApiImpl constructor.
*
* @param tryCountAndInterval a tryCountAndInterval
* @param signer a signe
*/
public TransactionApiImpl(final TryCountAndInterval tryCountAndInterval, final Signer signer) {
final Trier trier = new Trier();
trier.setTryCountAndInterval(tryCountAndInterval);
trier.setNonceProvider(new SimpleNonceProvider());
trier.setClientProvider(new Function0<AergoClient>() {
@Override
public AergoClient apply() {
return client;
}
});
this.trier = trier;
this.signer = signer;
}
@Override
public TxHash createName(final String name) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getAccountOperation().createName(getSigner(), name, t);
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash updateName(final String name, final AccountAddress newOwner) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getAccountOperation().updateName(getSigner(), name, newOwner, t);
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash stake(final Aer amount) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getAccountOperation().stake(getSigner(), amount, t);
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash unstake(final Aer amount) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getAccountOperation().unstake(getSigner(), amount, t);
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash voteBp(List<String> candidates) {
return vote("voteBP", candidates);
}
@Override
public TxHash vote(final String voteId, final List<String> candidates) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getAccountOperation().vote(getSigner(), voteId, candidates, t);
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash send(String recipient, Aer amount, Fee fee) {
return send(recipient, amount, fee, BytesValue.EMPTY);
}
@Override
public TxHash send(final String recipient, final Aer amount, final Fee fee,
final BytesValue payload) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
final RawTransaction rawTransaction = RawTransaction.newBuilder()
.chainIdHash(getClient().getCachedChainIdHash())
.from(getSigner().getPrincipal())
.to(recipient)
.amount(amount)
.nonce(t)
.fee(fee)
.payload(payload)
.build();
return getClient().getTransactionOperation().commit(getSigner().sign(rawTransaction));
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash send(AccountAddress recipient, Aer amount, Fee fee) {
return send(recipient, amount, fee, BytesValue.EMPTY);
}
@Override
public TxHash send(final AccountAddress recipient, final Aer amount, final Fee fee,
final BytesValue payload) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
final RawTransaction rawTransaction = RawTransaction.newBuilder()
.chainIdHash(getClient().getCachedChainIdHash())
.from(getSigner().getPrincipal())
.to(recipient)
.amount(amount)
.nonce(t)
.fee(fee)
.payload(payload)
.build();
return getClient().getTransactionOperation().commit(getSigner().sign(rawTransaction));
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash commit(final RawTransaction rawTransaction) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
protected AtomicBoolean isFirst = new AtomicBoolean(true);
@Override
public TxHash apply(Signer signer, Long t) {
if (isFirst.get()) {
isFirst.set(false);
return getClient().getTransactionOperation().commit(getSigner().sign(rawTransaction));
} else {
final RawTransaction withNewNonce = rawTransaction.withNonce(t);
return getClient().getTransactionOperation().commit(getSigner().sign(withNewNonce));
}
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public TxHash commit(final Transaction signedTransaction) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
protected AtomicBoolean isFirst = new AtomicBoolean(true);
@Override
public TxHash apply(Signer signer, Long t) {
if (isFirst.get()) {
isFirst.set(false);
return getClient().getTransactionOperation().commit(signedTransaction);
} else {
final RawTransaction rawTransaction = signedTransaction.getRawTransaction();
final RawTransaction withNewNonce = rawTransaction.withNonce(t);
return getClient().getTransactionOperation().commit(getSigner().sign(withNewNonce));
}
}
});
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public ContractTxHash deploy(final ContractDefinition contractDefinition, final Fee fee) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getContractOperation().deploy(getSigner(), contractDefinition, t,
fee);
}
}).adapt(ContractTxHash.class);
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public ContractTxHash redeploy(final ContractAddress existingContract,
final ContractDefinition contractDefinition, final Fee fee) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getContractOperation().redeploy(getSigner(), existingContract,
contractDefinition, t, fee);
}
}).adapt(ContractTxHash.class);
} catch (Exception e) {
throw converter.convert(e);
}
}
@Override
public ContractTxHash execute(final ContractInvocation contractInvocation, final Fee fee) {
try {
return trier.request(getSigner(), new Function2<Signer, Long, TxHash>() {
@Override
public TxHash apply(Signer signer, Long t) {
return getClient().getContractOperation().execute(getSigner(), contractInvocation, t,
fee);
}
}).adapt(ContractTxHash.class);
} catch (Exception e) {
throw converter.convert(e);
}
}
protected Signer getSigner() {
if (null == this.signer || null == this.signer.getPrincipal()) {
throw new WalletException("Unlock account first");
}
return this.signer;
}
protected AergoClient getClient() {
if (null == this.client) {
throw new WalletException("Aergo client isn't binded yet");
}
return this.client;
}
}