Craft Customized Transactions

Build all possible transaction with our cardano-cli like APIs.

For a complete walkthrough of all available cardano-cli like APIs, please refer to the MeshTxBuilder - All APIs page.

Getting started

To start building an customized transaction, you need to first initialize MeshTxBuilder with MaestroProvider:

const maestro = new MaestroProvider({
  network: 'Preprod',
  apiKey: MAESTRO_API_KEY,
});
const mesh = new MeshTxBuilder({
  fetcher: maestro,
  submitter: maestro,
});

There are 4 optional fields to pass in to initialized the lower level APIs instance:

1. fetcher: When you build the transaction without sufficient fields as required by the serialization library, we would index the blockchain to fill the information for you. Affected APIs aretxIn,txInCollateral,spendingTxInReference.

2. submitter: It is used if you would like to use the fetchersubmitTx API directly from the instance.

3. evaluator: It would perform redeemer execution unit optimization.

4. isHydra: Use another set of default protocol parameters for building transactions

Build a simple transaction to send values

The following shows a simple example of building a transaction to send values to a recipient:

const recipient = 'addr_test1qz8j439j54afpl4hw978xcw8qsa0dsmyd6wm9v8xzeyz7ucrj5rt3et7z59mvmmpxnejvn2scwmseezdq5h5fpw08z8s8d93my';
const policyIdHex = 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc81700';
const tokenNameHex = '6d65736874657374696e672e616461';
const walletAddress = 'addr_test1vpw22xesfv0hnkfw4k5vtrz386tfgkxu6f7wfadug7prl7s6gt89x';
const privateKey = '5820xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

await mesh
  .txIn('572bca237e440b596f4f71374b4b610a995095c6b62a6dcc8549089b93ba0e33', 0)
  .txIn('572bca237e440b596f4f71374b4b610a995095c6b62a6dcc8549089b93ba0e33', 3)
  .txOut(recipient, [
    { unit: 'lovelace', quantity: '2000000' },
    { unit: policyIdHex + tokenNameHex, quantity: '1' },
  ])
  .changeAddress(walletAddress)
  .txInCollateral('3fbdf2b0b4213855dd9b87f7c94a50cf352ba6edfdded85ecb22cf9ceb75f814', 6)
  .signingKey(privateKey)
  .complete();

const signedTx = mesh.completeSigning()

Build a complex transaction

The following shows a example of building complex transaction:

await mesh
  .txIn('a02913bff2a1681f562e0b3aa1effa20a8ff192986f9106698b691707b274d8f', 3)
  .readOnlyTxInReference('8b7ea04a142933b3d8005bf98be906bdba10978891593b383deac933497e2ea7', 1)
  .mintPlutusScriptV2()
  .mint(1, mintPolicyIdHex, mintTokenNameHex)
  .mintTxInReference('63210437b543c8a11afbbc6765aa205eb2733cb74e2805afd4c1c8cb72bd8e22', 0)
  .mintRedeemerValue({ alternative: 0, fields: [myMintRedeemerValue] }, { mem: 3386819, steps: 1048170931 })
  .spendingPlutusScriptV2()
  .txIn('42ee770080d0e440aabd5b328cc00a65edc4b7bf2612d2bbcf6302bf0e504714', 0)
  .spendingReferenceTxInInlineDatumPresent()
  .spendingReferenceTxInRedeemerValue(
    {
      alternative: 0,
      fields: [mySpendRedeemerValue],
    },
    { mem: 9978951, steps: 4541421719 }
  )
  .spendingTxInReference('bb712547a5abe3697f8aba72870e33a52fd2c0401715950197f9b7370d137998', 0)
  .txOut(walletAddress, [
    { unit: 'lovelace', quantity: '2000000' },
    { unit: mintPolicyIdHex + mintTokenNameHex, quantity: '1' },
  ])
  .txOut(feeCollector, [{ unit: 'lovelace', quantity: '30000000' }])
  .txOut(validatorAddress, [
    { unit: 'lovelace', quantity: '20000000' },
    {
      unit: oracleTokenPolicyIdHex + oracleTokenNameHex,
      quantity: '1',
    },
  ])
  .txOutInlineDatumValue(complexDatumValue)
  .requiredSignerHash(feeCollector)
  .metadataValue('721', metadataObject)
  .txInCollateral('3fbdf2b0b4213855dd9b87f7c94a50cf352ba6edfdded85ecb22cf9ceb75f814', 6)
  .txInCollateral('3fbdf2b0b4213855dd9b87f7c94a50cf352ba6edfdded85ecb22cf9ceb75f814', 7)
  .changeAddress(walletAddress)
  .signingKey(appOwnerPrivateKey)
  .signingKey(minterPrivateKey)
  .complete();

const signedTx = mesh.completeSigning()

Build a transaction without any dependency

The following shows a example of building transaction without any dependency:

const signedTx = await mesh
  .txIn('572bca237e440b596f4f71374b4b610a995095c6b62a6dcc8549089b93ba0e33', 0, [{ unit: 'lovelace', quantity: '2000000' }], myAddress)
  .txIn('572bca237e440b596f4f71374b4b610a995095c6b62a6dcc8549089b93ba0e33', 3, [{ unit: 'lovelace', quantity: '2000000' }], myAddress)
  .txOut(recipient, [
    { unit: 'lovelace', quantity: '2000000' },
    { unit: policyIdHex + tokenNameHex, quantity: '1' },
  ])
  .changeAddress(walletAddress)
  .txInCollateral('3fbdf2b0b4213855dd9b87f7c94a50cf352ba6edfdded85ecb22cf9ceb75f814', 6, [{ unit: 'lovelace', quantity: '5000000' }], myAddress)
  .signingKey(privateKey)
  .completeSync();
  .completeSigning();

Build a transaction with an object

One alternative to use the lower level APIs is to build the transaction with an object in type MeshTxBuilderBody.

The following shows a example of building the same transaction in the Build a transaction without any dependency section with an object:

const myTx = {
  inputs: [
    {
      type: 'PubKey',
      txIn: {
        txHash: '572bca237e440b596f4f71374b4b610a995095c6b62a6dcc8549089b93ba0e33',
        txIndex: 0,
      },
    },
    {
      type: 'PubKey',
      txIn: {
        txHash: '572bca237e440b596f4f71374b4b610a995095c6b62a6dcc8549089b93ba0e33',
        txIndex: 3,
      },
    },
  ],
  outputs: [
    {
      address: 'addr_test1qz8j439j54afpl4hw978xcw8qsa0dsmyd6wm9v8xzeyz7ucrj5rt3et7z59mvmmpxnejvn2scwmseezdq5h5fpw08z8s8d93my',
      amount: [
        { unit: 'lovelace', quantity: '2000000' },
        { unit: 'baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817006d65736874657374696e672e616461', quantity: '1' },
      ],
    },
  ],
  collaterals: [
    {
      type: 'PubKey',
      txIn: {
        txHash: '3fbdf2b0b4213855dd9b87f7c94a50cf352ba6edfdded85ecb22cf9ceb75f814',
        txIndex: 6,
      },
    },
  ],
  requiredSignatures: [],
  referenceInputs: [],
  mints: [],
  changeAddress: 'addr_test1vpw22xesfv0hnkfw4k5vtrz386tfgkxu6f7wfadug7prl7s6gt89x',
  metadata: [],
  validityRange: {},
  signingKey: [
    '5820xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
  ],
};

await mesh.complete(myTx);
const signedTx = mesh.completeSigning();