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();