Search in sources :

Example 1 with PaymentTransaction

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;
}
Also used : PaymentTransaction(com.bloxbean.cardano.client.transaction.model.PaymentTransaction) BigInteger(java.math.BigInteger) BigDecimal(java.math.BigDecimal)

Example 2 with 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;
    }
}
Also used : CBORMetadata(com.bloxbean.cardano.client.metadata.cbor.CBORMetadata) Account(com.bloxbean.cardano.client.account.Account) FormRow(org.joget.apps.form.model.FormRow) HashMap(java.util.HashMap) CBORMetadataMap(com.bloxbean.cardano.client.metadata.cbor.CBORMetadataMap) WorkflowManager(org.joget.workflow.model.service.WorkflowManager) TransactionDetailsParams(com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams) Metadata(com.bloxbean.cardano.client.metadata.Metadata) CBORMetadata(com.bloxbean.cardano.client.metadata.cbor.CBORMetadata) WorkflowAssignment(org.joget.workflow.model.WorkflowAssignment) BackendService(com.bloxbean.cardano.client.backend.api.BackendService) ApplicationContext(org.springframework.context.ApplicationContext) AppDefinition(org.joget.apps.app.model.AppDefinition) Network(com.bloxbean.cardano.client.common.model.Network) PluginThread(org.joget.commons.util.PluginThread) AppService(org.joget.apps.app.service.AppService) TransactionResult(com.bloxbean.cardano.client.backend.api.helper.model.TransactionResult) FormRowSet(org.joget.apps.form.model.FormRowSet) ApiException(com.bloxbean.cardano.client.backend.exception.ApiException) CborSerializationException(com.bloxbean.cardano.client.exception.CborSerializationException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) PluginThread(org.joget.commons.util.PluginThread) PaymentTransaction(com.bloxbean.cardano.client.transaction.model.PaymentTransaction) BlockService(com.bloxbean.cardano.client.backend.api.BlockService) TransactionContent(com.bloxbean.cardano.client.backend.model.TransactionContent) HashMap(java.util.HashMap) CBORMetadataMap(com.bloxbean.cardano.client.metadata.cbor.CBORMetadataMap) Map(java.util.Map) TransactionHelperService(com.bloxbean.cardano.client.backend.api.helper.TransactionHelperService)

Example 3 with PaymentTransaction

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();
}
Also used : PaymentTransaction(com.bloxbean.cardano.client.transaction.model.PaymentTransaction) Account(com.bloxbean.cardano.client.account.Account) MintTransaction(com.bloxbean.cardano.client.transaction.model.MintTransaction) Transaction(com.bloxbean.cardano.client.transaction.spec.Transaction) PaymentTransaction(com.bloxbean.cardano.client.transaction.model.PaymentTransaction)

Example 4 with PaymentTransaction

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);
}
Also used : PaymentTransaction(com.bloxbean.cardano.client.transaction.model.PaymentTransaction) InsufficientBalanceException(com.bloxbean.cardano.client.backend.exception.InsufficientBalanceException)

Example 5 with PaymentTransaction

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);
    });
}
Also used : PaymentTransaction(com.bloxbean.cardano.client.transaction.model.PaymentTransaction) Account(com.bloxbean.cardano.client.account.Account) TransactionDetailsParams(com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams) BigInteger(java.math.BigInteger) Utxo(com.bloxbean.cardano.client.backend.model.Utxo) Test(org.junit.jupiter.api.Test) BaseTest(com.bloxbean.cardano.client.BaseTest)

Aggregations

PaymentTransaction (com.bloxbean.cardano.client.transaction.model.PaymentTransaction)65 Account (com.bloxbean.cardano.client.account.Account)57 Test (org.junit.jupiter.api.Test)56 BigInteger (java.math.BigInteger)41 Utxo (com.bloxbean.cardano.client.backend.model.Utxo)36 TransactionDetailsParams (com.bloxbean.cardano.client.transaction.model.TransactionDetailsParams)32 Transaction (com.bloxbean.cardano.client.transaction.spec.Transaction)26 TransactionResult (com.bloxbean.cardano.client.backend.api.helper.model.TransactionResult)24 MintTransaction (com.bloxbean.cardano.client.transaction.model.MintTransaction)24 BaseTest (com.bloxbean.cardano.client.BaseTest)10 Metadata (com.bloxbean.cardano.client.metadata.Metadata)10 CBORMetadata (com.bloxbean.cardano.client.metadata.cbor.CBORMetadata)10 GqlBaseTest (com.bloxbean.cardano.client.backend.gql.it.GqlBaseTest)9 Amount (com.bloxbean.cardano.client.backend.model.Amount)7 BigDecimal (java.math.BigDecimal)7 JsonNode (com.fasterxml.jackson.databind.JsonNode)6 UtxoSelectionStrategy (com.bloxbean.cardano.client.coinselection.UtxoSelectionStrategy)5 DefaultUtxoSelectionStrategyImpl (com.bloxbean.cardano.client.coinselection.impl.DefaultUtxoSelectionStrategyImpl)4 CBORMetadataMap (com.bloxbean.cardano.client.metadata.cbor.CBORMetadataMap)4 BaseITTest (com.bloxbean.cardano.client.backend.api.BaseITTest)3