Transactions
Create transactions for sending assets.
Send ADA to Addresses
You can chain the component to send to multiple recipients. For each recipients, append:
tx.sendLovelace(address: Recipient, lovelace: string);
Where Recipient
is a string or an object with the following properties:
Recipient = string | { address: string; datum?: { value: Data; inline?: boolean | undefined; } | undefined; script?: NativeScript | PlutusScript | undefined; }
.build()
constructs the transaction and returns a transaction CBOR. Behind the scenes, it selects all of the necessary inputs belonging to the wallet, calculates the fee for this transaction and returns the remaining assets to the change address. Use wallet.signTx()
to sign transaction CBOR.
import { Transaction } from '@meshsdk/core'; const tx = new Transaction({ initiator: wallet }) .sendLovelace( 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '1000000' ) ; const unsignedTx = await tx.build(); const signedTx = await wallet.signTx(unsignedTx); const txHash = await wallet.submitTx(signedTx);
Recipients | ||
---|---|---|
Recipient #1 | ||
Send Multiple Assets to Addresses
Use sendAssets()
to send native assets to one or more recipients:
tx.sendAssets(recipient: Recipient, assets: Asset[])
For each recipient, we define a list of Asset
to send:
import type { Asset } from '@meshsdk/core'; let assets: Asset[] = []; for (const asset of nativeAssets) { let thisAsset = { unit: assetAsset, quantity: '1', }; assets.push(thisAsset); } tx.sendAssets(recipient.address, assets);
We can chain a series of tx.sendAssets()
and tx.sendLovelace()
to send multiple assets to multiple recipients.
import { Transaction } from '@meshsdk/core'; import type { Asset } from '@meshsdk/core'; const tx = new Transaction({ initiator: wallet }) .sendLovelace( 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '1000000' ) .sendAssets( 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', [ { unit: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e', quantity: '1', }, ] ); const unsignedTx = await tx.build(); const signedTx = await wallet.signTx(unsignedTx); const txHash = await wallet.submitTx(signedTx);
Recipients | |
---|---|
Recipient #1 | |
Send Token to Addresses
We can chain sendToken()
commands to send to multiple recipients. For each recipient, append like so:
tx.sendToken(recipient: Recipient, ticker: token, amount: string);
Like sendAssets()
, we can chain sendToken()
together with tx.sendAssets()
to send multiple assets to multiple recipients.
import { Transaction } from '@meshsdk/core'; const tx = new Transaction({ initiator: wallet }) .sendToken( 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', 'DJED', '1000000' ) ; const unsignedTx = await tx.build(); const signedTx = await wallet.signTx(unsignedTx); const txHash = await wallet.submitTx(signedTx);
Recipients | |
---|---|
Recipient #1 | |
Send Assets to Handle
Send assets to a handler.
We can get the ADA Handle's address with fetchHandleAddress()
:
import { KoiosProvider } from '@meshsdk/core'; const koios = new KoiosProvider('api'); const address = await koios.fetchHandleAddress('jingles');
Next, we can create a transactions, for instance, lets send some lovelace to jingles:
import { KoiosProvider, Transaction } from '@meshsdk/core'; const koios = new KoiosProvider('api'); const tx = new Transaction({ initiator: wallet }) .sendLovelace( await koios.fetchHandleAddress('jingles'), '1000000' ); const unsignedTx = await tx.build(); const signedTx = await wallet.signTx(unsignedTx); const txHash = await wallet.submitTx(signedTx);
Recipients |
---|
Send Value to Addresses
Specify an output for the transaction. This funcion allows you to design the output UTXOs, either by splitting the outputs from multiple UTxOs or by creating reference inputs.
tx.sendValue(address: Recipient, value: UTxO);
import { Transaction } from '@meshsdk/core'; const tx = new Transaction({ initiator: wallet }) .sendValue(recipient, UTxO); const unsignedTx = await tx.build(); const signedTx = await wallet.signTx(unsignedTx); const txHash = await wallet.submitTx(signedTx);
where UTxO
has the following format (use one of our providers):
{ input: { outputIndex: number; txHash: string; }; output: { address: string; amount: Asset[]; dataHash?: string; plutusData?: string; scriptRef?: string; }; }
Coin selection
There are currently three coin selection algorithms available:
- Largest First
- Largest First Multi-Asset
- Keep Relevant
Largest First
To select UTXOs for transaction that only requires lovelace, use largestFirst
.
largestFirst = ( lovelace: Quantity, initialUTxOSet: UTxO[], includeTxFees = false, { maxTxSize, minFeeA, minFeeB } = DEFAULT_PROTOCOL_PARAMETERS, ): UTxO[]
For example, selecting the UTXOs for sending 10000000 lovelace:
import { largestFirst } from '@meshsdk/core'; const utxos = await wallet.getUtxos(); const costLovelace = '10000000'; const selectedUtxos = largestFirst(costLovelace, utxos, true);
Largest First Multi-Asset
largestFirstMultiAsset
allows you to define which native assets you require for sending out by defining a Map
. The Map is matches the Unit
with the quantity of each asset.
largestFirstMultiAsset = ( requestedOutputSet: Map<Unit, Quantity>, initialUTxOSet: UTxO[], includeTxFees = false, parameters = DEFAULT_PROTOCOL_PARAMETERS, ): UTxO[]
Note that if lovelace, aside from the "minimum Ada" which in any case needs to accompany the other assets, this must be explicitly specified. This can also be useful in the case that your transaction only requires transfer of lovelace. In this case, the algorithm will exclude all multiasset UTxOs from the selection, which can result in more efficient selection of the required UTxOs.
import { largestFirstMultiAsset } from '@meshsdk/core'; import type { Unit, Quantity } from '@meshsdk/core'; const utxos = await wallet.getUtxos(); const assetMap = new Map<Unit, Quantity>(); assetMap.set( 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e', '1' ); // if you need to include lovelace assetMap.set( 'lovelace', '10000000' ); // if you need to include more than 1 native asset assetMap.set( 'another asset unit', '1' ); const selectedUtxos = largestFirstMultiAsset(assetMap, utxos, true);
The third parameter is includeTxFees
. If True
, Mesh will calculate the fees required for the transaction, and include additional UTxOs to necessary to fulfill the fees requirements.
Keep Relevant
keepRelevant
is a two-step coin selection algorithm. First, given a Map (of requested assets and respective quantities) and a set of UTxOs, it tries to eliminate the irrelevant UTxOs from the set. Next, it checks that this UTxO set includes enough lovelace to cover all/any multi-assets in the set. If the set does not include enough lovelace, then it will try to also pick up another UTxO from the wallet, containing the largest amount of lovelace.
keepRelevant = ( requestedOutputSet: Map<Unit, Quantity>, initialUTxOSet: UTxO[], minimumLovelaceRequired = '5000000', );
Here is an example how you can use keepRelevant()
:
import { keepRelevant } from '@meshsdk/core'; import type { Unit, Quantity } from '@meshsdk/core'; const utxos = await wallet.getUtxos(); const assetMap = new Map<Unit, Quantity>(); assetMap.set( 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e', '1' ); // if you need to include lovelace assetMap.set( 'lovelace', '10000000' ); const selectedUtxos = keepRelevant(assetMap, utxos);
Set Collateral
Specify the UTXOs that you want to use as collateral. This is especially useful if you are using App Wallet.
setCollateral(collateral: UTxO[])
Set Required Signers
Sets the required signers for the transaction. This is useful if you are using App Wallet or in a multi-signature transaction.
setRequiredSigners(addresses: string[])
Set Start and Expire Time
We can define the time-to-live (TTL) for the transaction. TTL is the time limit for our transaction to be included in a blockchain, if it is not in a blockchain by then the transaction will be cancelled. This time limit is defined as slot
.
In order to get the slot
of the time you wish the transaction would expire, you can use resolveSlotNo
. For example, if you would like the transaction to expire in 5 minutes, you can get the slot
in the following way:
import { resolveSlotNo } from '@meshsdk/core'; let minutes = 5; // add 5 minutes let nowDateTime = new Date(); let dateTimeAdd5Min = new Date(nowDateTime.getTime() + minutes*60000); const slot = resolveSlotNo('mainnet', dateTimeAdd5Min.getTime());
Next, we set the TTL with setTimeToExpire
and providing the slot
, this means that if the transaction is submitted after after slot
will not be valid.
const tx = new Transaction({ initiator: wallet }); // do tx.sendLovelace() or any transactions actions tx.setTimeToExpire(slot) const unsignedTx = await tx.build();
Likewise, we can set a "validity start interval" for the transaction, where it is the time the transaction will be valid. We can define the start time with setTimeToStart
and providing the slot
:
const tx = new Transaction({ initiator: wallet }); // do tx.sendLovelace() or any transactions actions tx.setTimeToStart(slot) const unsignedTx = await tx.build();
Note that, if you are using a policy locking script, you must define setTimeToExpire
before the expiry; otherwise, you will catch the ScriptWitnessNotValidatingUTXOW
error.
Set Metadata
Cardano Transaction Metadata specifies that any transaction can include arbitrary metadata which is then stored immutably in the blockchain. Metadata take the form of text, specific structured text, numbers, hashes, any combination of these, etc. If the content of metadata should remain secret, then it is the responsibility of the sender to first encrypt it. There are many use cases: for example, when combined with off-chain infrastructure (eg physical identifiers), metadata can act as a confirmation or assurance of authenticity. The current protocol parameters define the maximum size of metadata permitted to accompany each transaction.
Some uses for metadata:
- Validation and verification. Checking and verifying external physical objects and legitimate content, for example by coupling with a physical identifier such as a QR-code. This can be especially beneficial for low-cost supply chain tracking of fast-moving consumer goods.
- Authentication and attribution. Confirming the authenticity of credentials received from an educational institution or membership group, using the fact that metadata can serve as an immutable and always-accessible evidence of certification.
- Secure record of information. Saving vital information, so nobody one can alter it afterwards, meaning it will last as long as the Cardano blockchain exists.
You can insert metadata into a transaction with setMetadata(key, value)
. The key
is a number, and value
is a string.
import { Transaction } from '@meshsdk/core'; const tx = new Transaction({ initiator: wallet }); tx.sendLovelace( 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '1000000' ); tx.setMetadata(0, 'Transaction message');
Set Native Script
This function allows you to set the Native Script input for the transaction.
import { Transaction } from '@meshsdk/core'; const tx = new Transaction({ initiator: wallet }); tx.setNativeScriptInput(nativeScript, utxo);
where NativeScript
has the following format:
import type { NativeScript } from '@meshsdk/core'; const nativeScript: NativeScript = { type: 'all', scripts: [ { type: 'before', slot: '<insert slot here>' }, { type: 'sig', keyHash: '<insert keyHash here>' } ] };
where UTxO
has the following format (use one of our providers):
{ input: { outputIndex: number; txHash: string; }; output: { address: string; amount: Asset[]; dataHash?: string; plutusData?: string; scriptRef?: string; }; }