use of com.bloxbean.cardano.client.transaction.model.PaymentTransaction in project cardano-blockchain-pack by jogetoss.
the class CardanoSendTransactionTool method constructPayment.
protected PaymentTransaction constructPayment(BackendService backendService, TransactionDetailsParams detailsParams, Metadata metadata, Account senderAccount, String receiverAddress, String amount) throws ApiException, CborSerializationException, AddressExcepion {
PaymentTransaction paymentTransaction = PaymentTransaction.builder().sender(senderAccount).receiver(receiverAddress).amount(getPaymentAmount(new BigDecimal(amount))).unit(getPaymentUnit()).build();
final BigInteger fee = calculateFeeFromTransactionSize(backendService, detailsParams, paymentTransaction, metadata);
paymentTransaction.setFee(fee);
return paymentTransaction;
}
use of com.bloxbean.cardano.client.transaction.model.PaymentTransaction in project cardano-blockchain-pack by jogetoss.
the class CardanoSendTransactionTool method execute.
@Override
public Object execute(Map props) {
Object result = null;
Metadata metadata = null;
WorkflowAssignment wfAssignment = (WorkflowAssignment) props.get("workflowAssignment");
ApplicationContext ac = AppUtil.getApplicationContext();
final WorkflowManager workflowManager = (WorkflowManager) ac.getBean("workflowManager");
final String senderAddress = WorkflowUtil.processVariable(getPropertyString("senderAddress"), "", wfAssignment);
final String accountMnemonic = CardanoUtil.decrypt(WorkflowUtil.processVariable(getPropertyString("accountMnemonic"), "", wfAssignment));
final String receiverAddress = WorkflowUtil.processVariable(getPropertyString("receiverAddress"), "", wfAssignment);
final String amount = WorkflowUtil.processVariable(getPropertyString("amount"), "", wfAssignment);
try {
String networkType = getPropertyString("networkType");
boolean isTest = "testnet".equalsIgnoreCase(networkType);
final Network.ByReference network = CardanoUtil.getNetwork(isTest);
final BackendService backendService = CardanoUtil.getBackendService(getProperties());
final Account senderAccount = new Account(network, accountMnemonic);
if (!senderAddress.equals(senderAccount.baseAddress())) {
LogUtil.warn(getClass().getName(), "Transaction failed! Sender account encountered invalid mnemonic phrase.");
return null;
}
AppService appService = (AppService) AppUtil.getApplicationContext().getBean("appService");
final String primaryKey = appService.getOriginProcessId(wfAssignment.getProcessId());
// Optional insert metadata from form data
if ("true".equals(getPropertyString("enableMetadata"))) {
String formDefId = getPropertyString("formDefId");
Object[] metadataFields = (Object[]) props.get("metadata");
AppDefinition appDef = (AppDefinition) props.get("appDef");
FormRow row = new FormRow();
FormRowSet rowSet = appService.loadFormData(appDef.getAppId(), appDef.getVersion().toString(), formDefId, primaryKey);
if (!rowSet.isEmpty()) {
row = rowSet.get(0);
}
CBORMetadataMap metadataMap = new CBORMetadataMap();
for (Object o : metadataFields) {
Map mapping = (HashMap) o;
String fieldId = mapping.get("fieldId").toString();
// String isFile = mapping.get("isFile").toString();
// if ("true".equalsIgnoreCase(isFile)) {
// String appVersion = appDef.getVersion().toString();
// String filePath = getFilePath(row.getProperty(fieldId), appDef.getAppId(), appVersion, formDefId, primaryKey);
// metadataMap.put(fieldId, getFileHashSha256(filePath));
// } else {
// metadataMap.put(fieldId, row.getProperty(fieldId));
// }
metadataMap.put(fieldId, row.getProperty(fieldId));
}
CBORMetadata binaryMetadata = new CBORMetadata();
binaryMetadata.put(BigInteger.ZERO, metadataMap);
metadata = binaryMetadata;
}
BlockService blockService = backendService.getBlockService();
TransactionHelperService transactionHelperService = backendService.getTransactionHelperService();
long ttl = blockService.getLastestBlock().getValue().getSlot() + 1000;
TransactionDetailsParams detailsParams = TransactionDetailsParams.builder().ttl(ttl).build();
final PaymentTransaction paymentTransaction = constructPayment(backendService, detailsParams, metadata, senderAccount, receiverAddress, amount);
final Result<TransactionResult> transactionResult = transactionHelperService.transfer(paymentTransaction, detailsParams, metadata);
// Store successful unvalidated txn result first
storeToWorkflowVariable(wfAssignment.getActivityId(), workflowManager, props, isTest, transactionResult, null);
// Workaround for waiting validation in separate thread
final boolean isTestFinal = isTest;
Thread waitTransactionThread = new PluginThread(() -> {
Result<TransactionContent> validatedTransactionResult = null;
if (transactionResult.isSuccessful()) {
validatedTransactionResult = waitForTransaction(backendService, transactionResult);
} else {
LogUtil.warn(getClass().getName(), "Transaction failed with status code " + transactionResult.code() + ". Response returned --> " + transactionResult.getResponse());
}
// Store validated/confirmed txn result for current activity instance
storeToWorkflowVariable(wfAssignment.getActivityId(), workflowManager, props, isTestFinal, transactionResult, validatedTransactionResult);
// Store validated/confirmed txn result for future running activity instance
storeToWorkflowVariable(workflowManager.getRunningActivityIdByRecordId(primaryKey, wfAssignment.getProcessDefId(), null, null), workflowManager, props, isTestFinal, transactionResult, validatedTransactionResult);
});
waitTransactionThread.start();
return result;
} catch (Exception ex) {
LogUtil.error(getClass().getName(), ex, "Error executing plugin...");
return null;
}
}
use of com.bloxbean.cardano.client.transaction.model.PaymentTransaction in project cardano-client-lib by bloxbean.
the class TransactionHelperService method createSignedTransaction.
/**
* Get cbor serialized signed transaction in Hex
*
* @param paymentTransactions
* @param detailsParams
* @param metadata
* @return
* @throws ApiException
* @throws AddressExcepion
* @throws CborSerializationException
*/
public String createSignedTransaction(List<PaymentTransaction> paymentTransactions, TransactionDetailsParams detailsParams, Metadata metadata) throws ApiException, AddressExcepion, CborSerializationException {
if (log.isDebugEnabled())
log.debug("Requests: \n" + JsonUtil.getPrettyJson(paymentTransactions));
Transaction transaction = utxoTransactionBuilder.buildTransaction(paymentTransactions, detailsParams, metadata, getProtocolParams());
transaction.setValid(true);
if (log.isDebugEnabled())
log.debug(JsonUtil.getPrettyJson(transaction));
Transaction finalTxn = transaction;
for (PaymentTransaction txn : paymentTransactions) {
finalTxn = txn.getSender().sign(finalTxn);
if (txn.getAdditionalWitnessAccounts() != null) {
// Add additional witnesses
for (Account additionalWitnessAcc : txn.getAdditionalWitnessAccounts()) {
finalTxn = additionalWitnessAcc.sign(finalTxn);
}
}
}
return finalTxn.serializeToHex();
}
use of com.bloxbean.cardano.client.transaction.model.PaymentTransaction in project cardano-client-lib by bloxbean.
the class FeeCalculationServiceImpl method calculateFee.
@Override
public BigInteger calculateFee(PaymentTransaction paymentTransaction, TransactionDetailsParams detailsParams, Metadata metadata, ProtocolParams protocolParams) throws CborSerializationException, AddressExcepion, ApiException {
PaymentTransaction clonePaymentTransaction = paymentTransaction.toBuilder().build();
if (// Just a dummy fee
clonePaymentTransaction.getFee() == null || clonePaymentTransaction.getFee().compareTo(DUMMY_FEE) == -1)
// Set a min fee just for calculation purpose if not set
clonePaymentTransaction.setFee(DUMMY_FEE);
String txnCBORHash;
try {
// Build transaction
txnCBORHash = transactionHelperService.createSignedTransaction(Arrays.asList(clonePaymentTransaction), detailsParams, metadata);
} catch (InsufficientBalanceException e) {
if (LOVELACE.equals(clonePaymentTransaction.getUnit())) {
clonePaymentTransaction.setFee(MIN_DUMMY_FEE);
clonePaymentTransaction.setAmount(clonePaymentTransaction.getAmount().subtract(MIN_DUMMY_FEE));
txnCBORHash = transactionHelperService.createSignedTransaction(Arrays.asList(clonePaymentTransaction), detailsParams, metadata);
} else
throw e;
}
// Calculate fee
return doFeeCalculationFromTxnSize(HexUtil.decodeHexString(txnCBORHash), protocolParams);
}
use of com.bloxbean.cardano.client.transaction.model.PaymentTransaction in project cardano-client-lib by bloxbean.
the class FeeCalculationServiceTest method testBuildTransaction_whenNotEnoughUtxosLeft.
@Test
public void testBuildTransaction_whenNotEnoughUtxosLeft() throws ApiException, IOException, AddressExcepion, CborSerializationException {
String receiver = "addr_test1qqwpl7h3g84mhr36wpetk904p7fchx2vst0z696lxk8ujsjyruqwmlsm344gfux3nsj6njyzj3ppvrqtt36cp9xyydzqzumz82";
List<Utxo> utxos = loadUtxos(LIST_2);
given(utxoService.getUtxos(any(), anyInt(), eq(1), any())).willReturn(Result.success(utxos.toString()).withValue(utxos).code(200));
given(utxoService.getUtxos(any(), anyInt(), eq(2), any())).willReturn(Result.success(utxos.toString()).withValue(Collections.EMPTY_LIST).code(200));
given(epochService.getProtocolParameters()).willReturn(Result.success(protocolParams.toString()).withValue(protocolParams).code(200));
Account sender = new Account(Networks.testnet());
PaymentTransaction paymentTransaction = PaymentTransaction.builder().sender(sender).unit(CardanoConstants.LOVELACE).amount(BigInteger.valueOf(11000000)).receiver(receiver).build();
TransactionDetailsParams detailsParams = TransactionDetailsParams.builder().ttl(199999).build();
Assertions.assertThrows(InsufficientBalanceException.class, () -> {
BigInteger fee = feeCalculationService.calculateFee(paymentTransaction, detailsParams, null, protocolParams);
});
}
Aggregations