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 API Endpoints 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,
evaluator: 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 fetcher
submitTx 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
Below provides some examples of transaction building. Complete working examples can be found in mesh-lower-level-api-demo
Build a simple transaction to send values
The following shows a simple example of building a transaction to send values to a recipient:
await mesh
.txIn(txInHash, txInId)
.txOut(this.constants.walletAddress, [{ unit: "lovelace", quantity: amount.toString() }])
.changeAddress(this.constants.walletAddress)
.signingKey(this.constants.skey)
.complete();
const signedTx = mesh.completeSigning()
Build a transaction to send fund to smart contract
The following shows a simple example of building a transaction to lock fund in a smart contact. It is equivalent to the following CLI command in PPBL Module 102.4.
await mesh
.txIn(txInHash, txInId)
.txOut(validatorAddress, [])
.txOutInlineDatumValue(1618)
.changeAddress(this.constants.walletAddress)
.signingKey(this.constants.skey)
.complete();
const signedTx = mesh.completeSigning()
Build a transaction to unlock fund from smart contract
The following shows a simple example of building a transaction to unlock fund from a smart contract. It is equivalent to the following CLI command in PPBL Module 102.5
await mesh
.txIn(txInHash, txInId)
.spendingPlutusScriptV2()
.txIn(validatorInput.txHash, validatorInput.outputIndex)
.txInInlineDatumPresent()
.txInRedeemerValue(mConStr0([]))
.txInScript(getScriptCbor("Spending"))
.txOut(this.constants.walletAddress, [])
.changeAddress(this.constants.walletAddress)
.txInCollateral(this.constants.collateralUTxO.txHash, this.constants.collateralUTxO.outputIndex)
.signingKey(this.constants.skey)
.complete();
const signedTx = mesh.completeSigning()
Build a transaction to mint tokens
The following shows a simple example of building a transaction to mint a token with smart contract:
await mesh
.txIn(txInHash, txInId)
.mintPlutusScriptV2()
.mint("1", policyId, tokenName)
.mintingScript(mintingScript)
.mintRedeemerValue(mConStr0([]))
.txOut(this.constants.walletAddress, [{ unit: policyId + tokenName, quantity: "1" }])
.changeAddress(this.constants.walletAddress)
.txInCollateral(this.constants.collateralUTxO.txHash, this.constants.collateralUTxO.outputIndex)
.signingKey(this.constants.skey)
.complete();
const signedTx = mesh.completeSigning()
Build a transaction to (register stake certificate and) delegate stake to a pool
The following shows a simple example of building a transaction to (register stake certificate and) delegate stake to a pool for the first time.
const usedAddress = await wallet.getUnusedAddresses();
const { stakeCredential } = serializeBech32Address(usedAddress[0]);
await mesh
.txIn(txInHash, txInId)
.registerStakeCertificate(stakeCredential) // Skip this line if you are not staking for the first time
.delegateStakeCertificate(
stakeCredential,
'poolxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
)
.changeAddress(changeAddress)
.complete();
const signedTx = mesh.completeSigning()
Build a complex transaction
The following shows a simple example of building a transaction of both unlocking from script and minting tokens:
await mesh
.txIn(txInHash, txInId)
.spendingPlutusScriptV2()
.txIn(validatorInput.txHash, validatorInput.outputIndex)
.txInInlineDatumPresent()
.txInRedeemerValue(mConStr0([]))
.txInScript(getScriptCbor("Spending"))
.mintPlutusScriptV2()
.mint("1", policyId, tokenName)
.mintingScript(mintingScript)
.mintRedeemerValue(mConStr0([]))
.txOut(this.constants.walletAddress, [{ unit: policyId + tokenName, quantity: "1" }])
.changeAddress(this.constants.walletAddress)
.txInCollateral(this.constants.collateralUTxO.txHash, this.constants.collateralUTxO.outputIndex)
.signingKey(this.constants.skey)
.complete();
const signedTx = mesh.completeSigning()
Build a transaction without any dependency
The following shows a example of building transaction without any dependency:
const signedTx = 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 meshTxBody: MeshTxBuilderBody = {
inputs: [
{
type: "PubKey",
txIn: {
txHash: txHash1,
txIndex: txIndex1,
},
},
{
type: "PubKey",
txIn: {
txHash: txHash2,
txIndex: txIndex2,
},
},
],
outputs: [
{
address: walletAddress,
amount: [{ unit: "lovelace", quantity: "1000000" }],
},
],
collaterals: [
{
type: "PubKey",
txIn: {
txHash: "ee8369ffadd6ed6efdd939639b393f08974fca388b2c43d03a96a1fa4840c5f8",
txIndex: 0,
},
},
],
requiredSignatures: [],
referenceInputs: [],
mints: [],
changeAddress: walletAddress,
metadata: [],
validityRange: {},
signingKey: [skey],
};
await mesh.complete(meshTxBody);
const signedTx = mesh.completeSigning();