# Branding
URL: /about/branding
These resources exist to help you use Mesh's assets.
***
title: "Branding"
description: "These resources exist to help you use Mesh's assets."
-------------------------------------------------------------------
import Link from "next/link";
import Image from "next/image";
## Logo \[!toc]
The Mesh logo is available in two color schemes: black and white. You can use the logo in either color scheme depending on your design needs. The logo is available in various sizes to suit different use cases.
# Project Catalyst
URL: /about/catalyst
Proposals that we have submitted to Project Catalyst and its progress.
***
title: "Project Catalyst"
description: "Proposals that we have submitted to Project Catalyst and its progress."
-------------------------------------------------------------------------------------
import { Status } from "@/components/ui/Status";
import { TaskList } from "@/components/ui/TaskList";
import Link from "fumadocs-core/link";
import { CatalystCard } from "@/components/ui/CatalystCard";
import { fund13, fund12, fund11, fund10 } from "./funding";
# Feature complete Web3 SDK
URL: /about
Our enterprise-ready SDK is professionally designed, robust, and developer-friendly. With simple transaction builders, seamless wallet integrations, and reliable data services, building Web3 applications has never been this effortless.
***
title: "Feature complete Web3 SDK"
description: "Our enterprise-ready SDK is professionally designed, robust, and developer-friendly. With simple transaction builders, seamless wallet integrations, and reliable data services, building Web3 applications has never been this effortless."
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
import Image from 'next/image';
import Link from 'fumadocs-core/link';
import {
SiDiscord,
SiX,
SiGithub
} from "@icons-pack/react-simple-icons";
import { GlobeAltIcon } from '@heroicons/react/24/outline';
Our Team
Abdelkrim
Erick
Felix
Hinson
Jingles
Tszwai
What are we working on?
Check out our GitHub milestones to see what we are currently working on.
Incorporation
MeshJS Pte. Ltd. is a company registered in Singapore since 2023, with the registration number (UEN): 202344120W.
Status
Stay up to date with our latest releases, tests and build status.
Published on NPM
Build status
Publish status
# Support Us
URL: /about/support-us
Thank you for your interest in Mesh, we appreciate any kind of support! Here are some ways you can support us.
***
title: "Support Us"
description: "Thank you for your interest in Mesh, we appreciate any kind of support! Here are some ways you can support us."
-----------------------------------------------------------------------------------------------------------------------------
import Link from 'fumadocs-core/link';
import Image from 'next/image';
import { cn } from '@/lib/cn';
import { buttonVariants } from '@/components/ui/button';
import { useTheme } from 'next-themes';
# Follow us on Twitter \[!toc]
Follow us on Twitter so you get updated with the latest development!
Follow us on Twitter
# Donate to Mesh \[!toc]
Your support for this open-source SDK will go a long way. So thank you!
Coming soon
{/* surprise svg has kinda padding which doesnt look when not able to right align */}
# Star Mesh GitHub Repo \[!toc]
Visit our GitHub and star it!
Star GitHub repo
# Add Mesh Badge in your Application \[!toc]
Add our beautiful Mesh Badge to give your users confidence knowing that your application is running on top of a solid SDK.
```tsx
import { MeshBadge } from '@meshsdk/react';
export default function Page() {
return (
<>
>
);
}
```
# Join our Discord Server \[!toc]
Come and talk to us in our Discord server.
Join Mesh's Discord server
# Write a Smart Contract
URL: /aiken/first-script
Learn how to write your first Aiken script, with a simple redeemer
***
title: "Write a Smart Contract"
description: "Learn how to write your first Aiken script, with a simple redeemer"
---------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
## Write your first smart contract in Aiken
In this section, we will walk you through the process of writing a simple smart contract in Aiken.
We will use the Visual Studio Code editor for this tutorial. You can use any other editor of your choice, but we recommend using Visual Studio Code for its rich feature set and support for Aiken.
First, we create a new Aiken project within this project folder:
```bash
$ aiken new meshjs/hello_world
$ cd hello_world
$ aiken check
```
Remember to check your Aiken project by running `aiken check` after creating a new project and as you develop the contract.
### Write the smart contract \[!toc]
Let's create file for our validator, `validators/hello_world.ak`:
```tsx
use aiken/hash.{Blake2b_224, Hash}
use aiken/list
use aiken/transaction.{ScriptContext}
use aiken/transaction/credential.{VerificationKey}
type Datum {
owner: Hash,
}
type Redeemer {
msg: ByteArray,
}
validator {
fn hello_world(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool {
let must_say_hello =
redeemer.msg == "Hello, World!"
let must_be_signed =
list.has(context.transaction.extra_signatories, datum.owner)
must_say_hello && must_be_signed
}
}
```
The validator checks for two conditions:
* The redeemer message is `Hello, World!`
* The transaction is signed by the owner
If both conditions are met, the validator returns `true`. Otherwise, it returns `false`.
## Compile and build
Let's compile the smart contract with the Aiken CLI:
```tsx
$ aiken build
```
This command will compile the smart contract and generate the `plutus.json` file in the root folder. This file is a CIP-0057 Plutus blueprint, blueprint describes your on-chain contract and its binary interface.
# Getting Started
URL: /aiken/getting-started
Setting up your system to compile Aiken smart contracts
***
title: "Getting Started"
description: "Setting up your system to compile Aiken smart contracts"
----------------------------------------------------------------------
import Link from "fumadocs-core/link";
## Installation Instructions
This section will guide you through the process of setting up your system compile Aiken smart contracts. You can skip this section if you have already set up your system or do not wish to compile the contract.
### Using aikup (on Linux & MacOS only) \[!toc]
If you are using Linux or MacOS, you can use the utility tool to download and manage Aiken's pre-compiled executables.
You can install the Aiken CLI by running the following command in your terminal:
```bash
$ curl -sSfL https://install.aiken-lang.org | bash
```
After installing the Aiken CLI, you can use the following command to installs the latest version available. `aikup` is a cross-platform utility tool to download and manage Aiken's across multiple versions and for seamless upgrades.
```tsx
$ aikup
```
### From sources (all platforms) \[!toc]
You will know you have successfully installed Rust and Cargo when you can run the following commands in your terminal:
```tsx
$ rustc --version
$ cargo --version
```
Next, you will need to install the Aiken CLI. You can install the Aiken CLI by running the following command in your terminal:
```tsx
$ cargo install aiken
```
### Check your installation \[!toc]
You will know you have successfully installed the Aiken CLI when you can run the following command in your terminal:
```tsx
$ aiken -V
```
If you face any issues, please check the installation instructions on the Aiken website for more information.
## Editor integrations
Aiken language support for Visual Studio Code is provided by the Aiken extension. This extension provides syntax highlighting, code snippets, and error checking for Aiken smart contracts. Download the extension from the Visual Studio Code Marketplace or search `aiken` in the extensions tab of Visual Studio Code.
## Useful commands
Here are some useful commands you can use to compile and test your scripts.
* `aiken build` - compiles the Aiken smart contract and generates a `plutus.json` file which contains type information, params, redeemer, datum, and the compiled code for each validator of your project and their corresponding hash digests to be used in addresses
* `aiken check` - type-check a project and run tests
* `aiken docs` - if you're writing a library, this generate documentation from you project
* `aiken blueprint` - provides utility functions to generate addresses, apply parameters and convert the build output to various formats
# Aiken
URL: /aiken
A programming language and toolkit for developing smart contracts
***
title: "Aiken"
description: "A programming language and toolkit for developing smart contracts"
icon: "icons/aiken.png"
-----------------------
Aiken is a functional programming language created for Cardano smart contract development. It prioritizes on-chain execution and offers a user-friendly approach for building secure and efficient smart contracts, making it a valuable choice for developers aiming to create robust on-chain applications.
## Getting Started \[!toc]
Setting up your system to compile Aiken smart contracts
## Write a Smart Contract \[!toc]
Learn how to write your first Aiken script, with a simple redeemer
## Build Transactions \[!toc]
Build transactions to interact with smart contracts
## Smart Contract Library \[!toc]
Open-source smart contracts, complete with documentation, and live demos
# Build Transactions
URL: /aiken/transactions
Build transactions to interact with smart contracts
***
title: "Build Transactions"
description: "Build transactions to interact with smart contracts"
------------------------------------------------------------------
import Link from "fumadocs-core/link";
## Create transaction to lock tokens
In this section, we will create a simple UI that allows users to lock assets on the Cardano blockchain.
First, we get initialze the `PlutusScript` and resolve the script address:
```tsx
function getScript() {
const scriptCbor = applyParamsToScript(compiledCode, []);
const script: PlutusScript = {
code: scriptCbor,
version: "V2",
};
const scriptAddress = resolvePlutusScriptAddress(script, 0);
return { script, scriptAddress };
}
```
```tsx
const { scriptAddress } = await getScript();
```
We are using the `resolvePlutusScriptAddress` function to resolve the script address.
You notice here we use the `applyParamsToScript`, which apply parameters to a script allows you to create a custom CIP-57 compliant script based on some inputs. For this script, we don't have any parameters to apply, but simply applied with double CBOR encoding to `scriptCbor`.
Next, we get the wallet address hash:
```tsx
async function getWalletAddress(wallet: BrowserWallet) {
const addresses = await wallet.getUsedAddresses();
const address = addresses[0];
if (!address) {
throw new Error("No address found");
}
const hash = resolvePaymentKeyHash(address);
return { address, hash };
}
```
```tsx
const { hash } = await getWalletAddress(wallet);
```
Here, we use the `resolvePaymentKeyHash` function to resolve the payment key hash of the wallet.
Then, we create the `Data` (datum) object containing the address hash:
```tsx
const datum: Data = {
alternative: 0,
fields: [hash],
};
```
Finally, we prepare the transaction to lock the assets on the Cardano blockchain.
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace(
{
address: scriptAddress,
datum: { value: datum },
},
"5000000",
);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Create transaction to redeem tokens
In this section, we will walk you through the process of creating a transaction to redeem tokens.
First, we need to get the script and script address. We can do this by calling the function we created in the previous section.
```tsx
const { script, scriptAddress } = await getScript();
```
Next, we need to get the wallet address and its hash. We can do this by calling the function we created in the previous section.
```tsx
const { address, hash } = await getWalletAddress(wallet);
```
As the contracts requires the owner's address in the datum field, we are creating a new datum with the owner's address. We create the `Data` (datum) object containing the address hash:
```tsx
const datum: Data = {
alternative: 0,
fields: [hash],
};
```
After that, we get the UTXO in the script based on the datum:
```tsx
async function getAssetUtxo({
scriptAddress,
asset,
datum,
}: {
scriptAddress: string;
asset: string;
datum: any;
}) {
const provider = getProvider();
const utxos = await provider.fetchAddressUTxOs(
scriptAddress,
asset,
);
const dataHash = resolveDataHash(datum);
let utxo = utxos.find((utxo: any) => {
return utxo.output.dataHash == dataHash;
});
return utxo;
}
```
```tsx
const assetUtxo = await getAssetUtxo({
scriptAddress: scriptAddress,
asset: "lovelace",
datum: datum,
});
```
Finally, we prepare the transaction to redeem the tokens:
```tsx
const redeemer = { data: { alternative: 0, fields: ["Hello, World!"] } };
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datum,
redeemer: redeemer,
})
.sendValue(address, assetUtxo)
.setRequiredSigners([address]);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
Here you notice that in the `redeemer`. As the validator requires, here we specify `Hello, World!`, which is the message we need to provide to unlock the tokens.
For the transaction, we use the `redeemValue` function to redeem the locked assets, the `sendValue` function to send the assets to the owner's address, and the `setRequiredSigners` function to set the required signers.
# Mesh AI Features
URL: /ai
We've built AI tools to help you work with Mesh faster
***
title: "Mesh AI Features"
description: "We've built AI tools to help you work with Mesh faster"
---------------------------------------------------------------------
import Link from "fumadocs-core/link";
## Ask MeshAI
Ask MeshAI is the chatbot on the website which answers your queries instantly and accurately by utilizing the contextual retrieval built on top of traditional RAG.
### How it works:
MeshAI searches through all the vector embeddings of Mesh documentation, code examples and starter templates to find the right answer for your question. It uses contextual retrieval technique to pull closet vectors to your query and make an LLM call to produce accurate answer without making things up.
### Example Response:
In this demo, we create a transaction that transfers ADA back to the sender’s own address using MeshAI.
## LLMs.txt
Mesh provides llms.txt file that is easily understood by AI tools. This file contains everything from Mesh documentation and code examples. This file can be plugged into any AI code editors and will be instantly indexed to help you code with AI using up-to-date documentation from Mesh. Because the file follows a standardized AI-friendly format, code generation stays consistent across different tools. Since it's written in markdown text, it's just as easy for humans to browse as it is for machines to process. You can find llms.txt file here.
AI code editors like Cursor let you add and index documentation, so you can reference it directly in your chats. For example, you can bring Mesh docs into Cursor by typing @Docs → Add new doc. A modal will open where you can paste the link to the /llms.txt file. Once added, the doc becomes available as context, making it easier and faster to build apps with AI.
## Mesh MCP (Coming Soon)
We’re bringing Model Context Protocol (MCP) integration to Mesh, so you’ll be able to access Mesh knowledge right inside your favorite development tools. This means your editor will be able to help as you code, suggest snippets as you type, and even assist with debugging issues directly in your IDE. It’s designed to work seamlessly with tools like VS Code, Cursor, and other AI-powered editors, making your development workflow smoother and faster.
# Layer 2 scaling solution
URL: /hydra
Scaling solution for Cardano that increases transaction throughput and ensures cost efficiency while maintaining rigorous security.
***
title: "Layer 2 scaling solution"
description: "Scaling solution for Cardano that increases transaction throughput and ensures cost efficiency while maintaining rigorous security."
icon: "icons/hydra.svg"
-----------------------
## Hydra Provider (beta) \[!toc]
Layer 2 scaling solution for Cardano that increases transaction throughput and ensures cost efficiency while maintaining security.
## End-to-end Hydra Tutorial \[!toc]
Open a layer 2 state channel between two participants, build transactions, and close the Hydra head
# End-to-end Hydra Tutorial
URL: /hydra/tutorial
Open a layer 2 state channel between two participants, build transactions, and close the Hydra head
***
title: "End-to-end Hydra Tutorial"
description: "Open a layer 2 state channel between two participants, build transactions, and close the Hydra head"
------------------------------------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
This tutorial demonstrates how to use Hydra Head protocol on Cardano's preprod testing environment to open a layer 2 state channel between two participants using Mesh.
Hydra Head is a layer 2 scaling solution for Cardano that enables fast, low-cost transactions between participants.
This tutorial is adapted from the Hydra documentation.
### Initialize Hydra with Mesh \[!toc]
To initialize Hydra with Mesh, you need to set the `HydraProvider` with the Hydra API URL and then use it to initialize the `HydraInstance`. You can use one of the cardano providers, example: `blockfrostProvider`, or `maestroProvider`, to initialize the `HydraInstance`.
```tsx
import { HydraInstance, HydraProvider } from "@meshsdk/hydra";
const provider = new HydraProvider({
url: "",
});
const hydraInstance = new HydraInstance({
provider: provider,
fetcher: "",
submitter: "",
});
```
## Prerequisites
* A running cardano node is required to access `cardano-cli`
* A `Hydra-node`
* Another participant following this tutorial (recommended), or
* Access to two such machines
* 100 test ada per participant in a wallet on the `preprod` network
Hydra-node and cardano-node running, check Installation.
You could also set-up a Docker container for a `cardano-node` and `Hydra-node` to quickly follow this tutorial. Check the setup example/demo for a devnet here
## Step 1. Prepare keys and funding
In a Hydra head, each participant is authenticated using two sets of keys. The first set identifies a participant on the Cardano layer 1 and is used to hold ada for paying fees. Each hydra-node requires a `cardano-signing-key`, and you must provide the `cardano-verification-key` for each participant. First, generate Cardano key pairs and addresses for both participants with `cardano-cli` to identify the hydra-node and manage funds on layer 1.
Alice's keys:
```bash
mkdir -p credentials
cardano-cli address key-gen \
--verification-key-file credentials/alice-node.vk \
--signing-key-file credentials/alice-node.sk
cardano-cli address build \
--payment-verification-key-file credentials/alice-node.vk \
--out-file credentials/alice-node.addr \
--testnet-magic 1
cardano-cli address key-gen \
--verification-key-file credentials/alice-funds.vk \
--signing-key-file credentials/alice-funds.sk
cardano-cli address build \
--payment-verification-key-file credentials/alice-funds.vk \
--out-file credentials/alice-funds.addr \
--testnet-magic 1
```
Bob's keys:
```bash
mkdir -p credentials
cardano-cli address key-gen \
--verification-key-file credentials/bob-node.vk \
--signing-key-file credentials/bob-node.sk
cardano-cli address build \
--payment-verification-key-file credentials/bob-node.vk \
--out-file credentials/bob-node.addr \
--testnet-magic 1
cardano-cli address key-gen \
--verification-key-file credentials/bob-funds.vk \
--signing-key-file credentials/bob-funds.sk
cardano-cli address build \
--payment-verification-key-file credentials/bob-funds.vk \
--out-file credentials/bob-funds.addr \
--testnet-magic 1
```
After generating the addresses, make sure to fund both Alice's and Bob's addresses with test ADA. if you don't have testAda, you can use cardano-faucet to fund the generated addresses
* Send at least `30 tADA` to `alice-node.addr` and `bob-node.addr` addresses.
* Send any amount of `tADA` to `alice-funds.addr` and `bob-funds.addr` addresses.
Next, generate Hydra key pairs for use on layer 2. Use this Hydra-node command to generate the keys for alice and/or bob respectively:
```tsx
hydra-node gen-hydra-key --output-file credentials/alice-hydra
```
```tsx
hydra-node gen-hydra-key --output-file credentials/bob-hydra
```
The next step involves configuring the protocol parameters for the ledger within our Hydra head. For the purposes of this tutorial, we'll modify the default Cardano layer 1 parameters to eliminate transaction fees,
```tsx
cardano-cli query protocol-parameters --testnet-magic 1 --socket-path /"${socketPath}" --out-file protocol-parameters.json
```
Simplifying Hydra fees and environments, change the following parameters:
* `txFeeFixed` to 0
* `txFeePerByte` to 0
* `executionUnitPrices.priceMemory` to 0
* `executionUnitPrices.priceSteps` to 0
## Step 2. Configure Hydra nodes
Configure your Hydra nodes with the generated keys and network settings. Each participant needs to set up their hydra-node with the correct configuration.
Alice:
```tsx
hydra-node \
--node-id alice-node \
--api-host 0.0.0.0 \
--api-port 4001 \
--listen 172.16.239.10:5001 \
--monitoring-port 6001 \
--peer 172.16.239.20:5001 \
--hydra-scripts-tx-id c9c4d820d5575173cfa81ba2d2d1096fc40f84d16d8c17284da410a4fb5e64eb,ae4443b46f550289337fc5c2c52b24f1288dab36d1a229167a6e04f056a966fe,48bd29e43dd01d12ab464f75fe40eed80e4051c8d3409e1cb20b8c01120b425e \
--cardano-signing-key /credentials/alice-node.sk \
--cardano-verification-key /credentials/bob-node.vk \
--hydra-signing-key /keys/alice-hydra.sk \
--hydra-verification-key /keys/bob-hydra.vk \
--ledger-protocol-parameters ./testnet/protocol-parameters.json \
--testnet-magic 1 \
--node-socket /cardano-node/db/node.socket \
--contestation-period 300s
```
Bob:
```tsx
hydra-node \
--node-id bob-node \
--api-host 0.0.0.0 \
--api-port 4002 \
--listen 172.16.239.20:5001 \
--monitoring-port 6001 \
--peer 172.16.239.10:5001 \
--hydra-scripts-tx-id c9c4d820d5575173cfa81ba2d2d1096fc40f84d16d8c17284da410a4fb5e64eb,ae4443b46f550289337fc5c2c52b24f1288dab36d1a229167a6e04f056a966fe,48bd29e43dd01d12ab464f75fe40eed80e4051c8d3409e1cb20b8c01120b425e \
--cardano-signing-key /credentials/bob-node.sk \
--cardano-verification-key /credentials/alice-node.vk \
--hydra-signing-key /keys/bob-hydra.sk \
--hydra-verification-key /keys/alice-hydra.vk \
--ledger-protocol-parameters ./testnet/protocol-parameters.json \
--testnet-magic 1 \
--node-socket /cardano-node/db/node.socket \
--contestation-period 300s
```
Fields in the Hydra node configuration:
* `node-id`: Unique identifier for each Hydra node. This distinguishes Alice's node from Bob's node.
* `api-host`: as the API is not authenticated by default, the node is only binding to `0.0.0.0`.
* `api-port`: The port on which the API will listen.
* `listen`: The IP address and port on which the Hydra node will listen for incoming connections.
* `peer`: The IP address of another Hydra node to connect to. This is how nodes discover and communicate with each other.
* `monitoring-port`: The port on which the monitoring API will listen. This is used to monitor the Hydra node's performance.
* `cardano-signing-key`: These keys authenticate on-chain transactions and ensure that only authorized participants can control the head's lifecycle used to hold ada for paying fees
* `hydra-signing-key`: Used for multi-signing snapshots within a head. Although these keys may eventually support an aggregated multi-signature scheme, they currently use the Ed25519 format.
* `hydra-scripts-tx-id`: The hydra-node uses reference scripts to reduce transaction sizes driving the head's lifecycle. For public (test) networks, you can use the pre-published Hydra scripts with each new release, listing transaction IDs in the release notes and networks.json. Note: The value of above `--hydra-scripts-tx-id` comes from the hydra-node release 0.22.2.
* `ledger-protocol-parameters`: This defines the updatable protocol parameters to be used on L2 such as fees or transaction sizes. These parameters follow the same format as the `cardano-cli query protocol-parameters` output.
* `contestation-period`:This is an important protocol parameter, defined in seconds The contestation period is used to set the contestation deadline. That is, after `Close`, all participants have at minimum `CP` to submit a `Contest` transaction
More on hydra configuration.
Ensure both nodes can communicate with each other and change to your correct file paths in the above configuration. This configuration sets up Alice's node to listen to API connection on port 4001 Bob's node on port 4002.
## Step 3. Open a Hydra head
### Connect to the Hydra head \[!toc]
Now that both Hydra nodes are running and connected, we can start using the head API url and port together with Mesh `HydraProvider` in connecting to the Hydra head.
```tsx
await provider.connect();
```
### Initialize the Head \[!toc]
Send the initialization command to start the Hydra head:
```tsx
await provider.init();
```
### Commit Funds \[!toc]
After initialization, both participants need to commit funds to the head. In this tutorial we use the `commitFunds` function on `HydraInstance` by selecting specific UTxOs and make them available for layer 2 transactions:
```tsx
import { HydraInstance , HydraProvider} from "@meshsdk/hydra";
const provider = new HydraProvider({
url: "",
});
const hInstance = new HydraInstance({
provider: provider,
fetcher: "",
submitter: "",
});
const wallet = new MeshWallet({
networkId: 0, // 0: testnet
fetcher: "",
submitter: "",
key: {
type: 'cli',
payment: 'alice-funds.sk',
},
});
const outputIndex = 0;
const txHash = "00000000000000000000000000000000000000000000000000000000000000000";
const commitTx = await hInstance.commitFunds(txHash, outputIndex);
const signedTx = await wallet.signTx(commitTx, true);
const commitTxHash = await wallet.submitTx(signedTx);
console.log(commitTxHash);
```
The hydra-node will create a draft commit transaction for you to sign. Once signed and submitted to the Cardano network, you'll see a `Committed` message in your WebSocket connection.
When both parties have committed their funds, the Hydra head will open automatically. You'll see a `HeadIsOpen` message confirming the head is operational and ready for transactions.
### Hydra Head Status Flow \[!toc]
The head goes through these status changes:
* `HeadIsInitializing` - Head is being initialized
* `Committed` - Funds are committed to the head
* `HeadIsOpen` - Head is open and ready for transactions
## Step 4. Use the Hydra head
Now that the Hydra head is open, you can perform transactions within the layer 2 state channel. Hydra Head operates as an isomorphic protocol, meaning that functionalities available on Cardano layer 1 are also available on layer 2. This allows us to use Mesh SDK for transaction creation within the head.
### Fetch UTxOs \[!toc]
First, let's see what UTxOs are available in the Hydra head:
```tsx
const utxos = await provider.fetchUTxOs();
```
### Fetch Address UTxOs \[!toc]
Alternatively, you can fetch Head UTxOs for a specific address:
```tsx
const utxos = await provider.fetchAddressUTxOs("alice-funds.addr")
```
### Build and Submit Transaction \[!toc]
You can build transactions just like on layer 1 assuming you are sending from alice to bob:
```tsx
const pp = await provider.fetchProtocolParameters();
const utxos = await provider.fetchAddressUTxOs("address");
const txBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
isHydra: true,
params: pp,
});
const unsignedTx = await txBuilder
.txOut(
"bob-funds.addr",
[{ unit: "lovelace", quantity: "3000000" }]
)
.changeAddress("alice-funds.addr")
.selectUtxosFrom(utxos)
.setNetwork("preprod")
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await provider.submitTx(signedTx);
console.log(txHash);
```
The transaction will be validated by both hydra-nodes and either result in a `TxValid` message or a `TxInvalid` message If valid, you'll see a `SnapshotConfirmedmessage` shortly after with the new UTxO set.
### Transaction Flow \[!toc]
The transaction goes through these steps:
* `NewTx` - Transaction submitted to head
* `TxValid` - Transaction validated by all nodes
* `SnapshotConfirmed` - New state confirmed
## Step 5. Close the Hydra head
You can close the head to return head utxos to layer 1. This process involves closing the head, waiting for the contestation period, and then fan out the final state.
### Close the Head \[!toc]
Any participant can initiate closing the Hydra head. Once closed, no more transactions can be submitted to the head. The head enters a contestation period where participants can challenge the closing snapshot.
```tsx
await provider.close()
```
### Contestation Period \[!toc]
After closing, there's a contestation period (configurable with `--contestation-period`). During this time:
* Participants can contest the closing snapshot
* If contested, a more recent snapshot can be used
* After the deadline, fanout becomes possible
### Fanout the Head \[!toc]
After the contestation period, the head participants can use the `fanout` to fully close the `hydra-head` and return the head utxos to layer one.
```tsx
await provider.fanout()
```
### Check Final Balances \[!toc]
After fanout, check the final balances on layer one:
```tsx
const aliceFundsBalance = await blockchainProvider.fetchAddressUTxOs("alice-funds.addr");
const bobFundsBalance = await blockchainProvider.fetchAddressUTxOs("bob-funds.addr");
```
### Head Lifecycle \[!toc]
The complete head lifecycle:
* `INITIALIZE` - Initial state
* `COMMIT` - Committing to Hydra head
* `OPEN` - Head open for transactions
* `NEW TX` - New transaction submitted in Hydra head
* `CLOSE` - Ready to fanout
* `CONTEST` - Head closed, contestation period
* `FANOUT` - Head finalized on layer one
Congratulations! You've completed the full lifecycle of a Hydra head from initialization to finalization.
# Aiken Hello World
URL: /guides/aiken
undefined
***
title: "Aiken Hello World"
icon: "guides/aiken.png"
------------------------
import Link from "fumadocs-core/link";
Aiken is a functional programming language created for Cardano smart contract development. It prioritizes on-chain execution and offers a user-friendly approach for building secure and efficient smart contracts, making it a valuable choice for developers aiming to create robust on-chain applications.
In this tutorial, we will walk you through the process of writing a simple smart contract in Aiken, and create 2 transactions to lock and unlock assets on the Cardano blockchain.
You can also try the live demo and here are the codes on the GitHub repository
## System setup
This section will guide you through the process of setting up your system compile Aiken smart contracts. You can skip this section if you have already set up your system or do not wish to compile the contract.
You can also check the installation instructions on the Aiken website for more information.
### Using aikup (on Linux & MacOS only) \[!toc]
If you are using Linux or MacOS, you can use the utility tool to download and manage Aiken's pre-compiled executables.
You can install the Aiken CLI by running the following command in your terminal:
```tsx
$ curl -sSfL https://install.aiken-lang.org | bash
$ aikup
```
### From sources (all platforms) \[!toc]
Aiken is written in Rust, so you will need to install Rust and Cargo to compile the smart contract. You can install Rust by following the instructions on the Rust website.
Next, you will need Cargo, the Rust package manager. You can install Cargo by following the instructions on the Cargo website.
You will know you have successfully installed Rust and Cargo when you can run the following commands in your terminal:
```tsx
$ rustc --version
$ cargo --version
```
Next, you will need to install the Aiken CLI. You can install the Aiken CLI by running the following command in your terminal:
```tsx
$ cargo install aiken
```
### Check your installation \[!toc]
You will know you have successfully installed the Aiken CLI when you can run the following command in your terminal:
```tsx
$ aiken -V
```
If you face any issues, please check the installation instructions on the Aiken website for more information.
## Writing a smart contract with Aiken
In this section, we will walk you through the process of writing a simple smart contract in Aiken. We will also create 2 transactions to lock and unlock assets on the Cardano blockchain.
You can read more about this example on the Aiken website.
### Create a new project \[!toc]
First, we will create a new project. Please refer to this guide for more information on creating a new Next.js project.
Next, we create a new Aiken project within this project folder:
```tsx
$ aiken meshjs/hello_world
$ cd hello_world
$ aiken check
```
Remember to check your Aiken project by running `aiken check` after creating a new project and as you develop the contract.
### Write the smart contract \[!toc]
Let's create file for our validator, `validators/hello_world.ak`:
```tsx
use aiken/hash.{Blake2b_224, Hash}
use aiken/list
use aiken/transaction.{ScriptContext}
use aiken/transaction/credential.{VerificationKey}
type Datum {
owner: Hash,
}
type Redeemer {
msg: ByteArray,
}
validator {
fn hello_world(datum: Datum, redeemer: Redeemer, context: ScriptContext) -> Bool {
let must_say_hello =
redeemer.msg == "Hello, World!"
let must_be_signed =
list.has(context.transaction.extra_signatories, datum.owner)
must_say_hello && must_be_signed
}
}
```
This validator checks that the redeemer message is "Hello, World!" and that the transaction is signed by the owner of the datum. If both conditions are met, the validator returns `true`. Otherwise, it returns `false`.
Let's compile the smart contract with the Aiken CLI:
```tsx
$ aiken build
```
This command will compile the smart contract and generate the `plutus.json` file in the root folder. This file is a CIP-0057 Plutus blueprint, blueprint describes your on-chain contract and its binary interface.
## Creating locking transaction
### Preparing the frontend \[!toc]
In this section, we will prepare the frontend for our smart contract. We will create a simple UI that allows users to lock and unlock assets on the Cardano blockchain.
Firstly, we need to install the `cbor` package:
```tsx
$ npm install cbor
```
Then, we create a folder, `data` and copy the `plutus.json` file into it.
Next, open `pages/index.tsx` and import the following packages:
```tsx
import {
resolvePlutusScriptAddress,
Transaction,
KoiosProvider,
resolveDataHash,
resolvePaymentKeyHash,
} from "@meshsdk/core";
import type { PlutusScript, Data } from "@meshsdk/core";
import { CardanoWallet, useWallet } from "@meshsdk/react";
import plutusScript from "../data/plutus.json";
import cbor from "cbor";
```
### Importing the contract \[!toc]
We import the contract into our frontend:
```tsx
const script: PlutusScript = {
code: cbor
.encode(Buffer.from(plutusScript.validators[0].compiledCode, "hex"))
.toString("hex"),
version: "V2",
};
const scriptAddress = resolvePlutusScriptAddress(script, 0);
```
Here, we are using the `plutus.json` file to create the script. We are also using the `resolvePlutusScriptAddress` function to resolve the script address.
If you look at it closely, we are encoding with cbor the compiled code of the validator. This is because the validator is encoded in a flat format, which is not the format expected by the cardano-cli and `cardano serialization library`.
### Locking assets \[!toc]
We create the transactions to lock assets on the Cardano blockchain:
```tsx
const hash = resolvePaymentKeyHash((await wallet.getUsedAddresses())[0]);
const datum: Data = {
alternative: 0,
fields: [hash],
};
const tx = new Transaction({ initiator: wallet }).sendLovelace(
{
address: scriptAddress,
datum: { value: datum },
},
"5000000"
);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
Here, we are creating a new transaction to lock assets on the Cardano blockchain. We are using the `resolvePaymentKeyHash` function to resolve the payment key hash of the wallet. We are also using the `sendLovelace` function to send lovelace to the script address.
As the contracts requires the owner's address in the datum field, we are creating a new datum with the owner's address. We are then using the `build` function to build the transaction, the `signTx` function to sign the transaction, and the `submitTx` function to submit the transaction to the Cardano blockchain.
## Unlocking assets
Next, we create the transactions to unlock assets.
First, we create a useful function to retrieve the UTXO of the locked assets:
```tsx
async function _getAssetUtxo({ scriptAddress, asset, datum }) {
const utxos = await koios.fetchAddressUTxOs(scriptAddress, asset);
const dataHash = resolveDataHash(datum);
let utxo = utxos.find((utxo: any) => {
return utxo.output.dataHash == dataHash;
});
return utxo;
}
```
And here are the codes to create the transactions to unlock assets:
```tsx
const scriptAddress = resolvePlutusScriptAddress(script, 0);
const address = (await wallet.getUsedAddresses())[0];
const hash = resolvePaymentKeyHash(address);
const datum: Data = {
alternative: 0,
fields: [hash],
};
const assetUtxo = await _getAssetUtxo({
scriptAddress: scriptAddress,
asset: "lovelace",
datum: datum,
});
const redeemer = { data: { alternative: 0, fields: ['Hello, World!'] } };
// create the unlock asset transaction
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datum,
redeemer: redeemer,
})
.sendValue(address, assetUtxo)
.setRequiredSigners([address]);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
Here, we are creating a new transaction to unlock assets on the Cardano blockchain. We are using the `resolvePlutusScriptAddress` function to resolve the script address. We are also using the `resolvePaymentKeyHash` function to resolve the payment key hash of the wallet.
As the contracts requires the owner's address in the datum field, we are creating a new datum with the owner's address. We are then using the `_getAssetUtxo` function to retrieve the UTXO of the locked assets. We are then using the `redeemValue` function to redeem the locked assets, the `sendValue` function to send the assets to the owner's address, and the `setRequiredSigners` function to set the required signers.
As the validator requires `Hello, World!` as the redeemer message, we are creating a new redeemer with the message `Hello, World!`. We are then using the `build` function to build the transaction, the `signTx` function to sign the transaction, and the `submitTx` function to submit the transaction to the Cardano blockchain.
You can check the full code on GitHub.
# Implement Custom Provider
URL: /guides/custom-provider
undefined
***
title: "Implement Custom Provider"
icon: "guides/implement-custom-provider.png"
--------------------------------------------
import Link from "fumadocs-core/link";
As of writing (Dec 2022), Mesh offers a few options: Blockfrost or Koios (see a list of Providers). These blockchain providers allow developers to access the Cardano blockchain and retrieve intricate data. For example, they can be used to query the UTXO of a smart contract and use it as part of a transaction, or to submit a signed transaction to the chain.
You can customize a provider to utilize GraphQL, cardano-cli, or websocket with Mesh SDK. Whatever the query method used to obtain the data, it will work perfectly with Mesh SDK so long as the output of the function is compatible with the interface.
This guide will show us how to make a custom provider and how to integrate it with Mesh so that it works in tandem with the transaction builder.
## How Does It Work?
JavaScript interfaces are structures that define the interface of an application: they are used to define the syntax for classes to follow. Thus, any classes which are based on an interface must abide by the structure laid out in the interface.
All providers have one or more interface(s). For example, the **KoiosProvider** Class implements the **IFetcher** and **ISubmitter** interfaces, thus **KoiosProvider** needs to strictly conform to the structure of these two interfaces.
**IFetcher** and **ISubmitter** are implemented in the **KoiosProvider** class using the **implement** keyword:
```tsx
export class KoiosProvider implements IFetcher, ISubmitter {}
```
To see the latest up-to-date list of interfaces used by Mesh, visit the GitHub repo, packages/module/src/common/contracts.
To create a custom provider class, one must create functions with the same name, input parameters, and return type as the list of defined methods for each interface. Doing so will allow the functions to work as expected when building transactions and any of the other many functions provided in Mesh.
For example, as of writing, IFetcher has 6 functions (see packages/module/src/common/contracts/fetcher.ts for latest implemention):
```tsx
import type { AccountInfo, AssetMetadata, Protocol, UTxO } from '@mesh/common/types';
export interface IFetcher {
fetchAccountInfo(address: string): Promise;
fetchAddressUTxOs(address: string, asset?: string): Promise;
fetchAssetAddresses(asset: string): Promise<{ address: string; quantity: string }[]>;
fetchAssetMetadata(asset: string): Promise;
fetchHandleAddress(handle: string): Promise;
fetchProtocolParameters(epoch: number): Promise;
}
```
As such, **KoiosProvider** must implement these functions as defined in **IFetcher**.
## Implement Your Own Provider
If you want to begin utilizing your own provider, looking at one of the existing providers is the ideal way to get started. Visit the GitHub repo, packages/module/src/providers to see a list of providers.
This code base below can be used as a starting point:
```tsx
import { IFetcher, ISubmitter } from "@mesh/common/contracts";
import { parseHttpError } from "@mesh/common/utils";
import type {
AccountInfo,
AssetMetadata,
Protocol,
UTxO,
} from "@mesh/common/types";
export class NAMEProvider implements IFetcher, ISubmitter {
constructor(network: "") {
// init variables and other Javascript libraries needed
}
async fetchAccountInfo(address: string): Promise {
try {
// return {
// ...
// };
} catch (error) {
throw parseHttpError(error);
}
}
async fetchAddressUTxOs(address: string, asset?: string): Promise {
try {
// return [
// ...
// ];
} catch (error) {
throw parseHttpError(error);
}
}
async fetchAssetAddresses(
asset: string
): Promise<{ address: string; quantity: string }[]> {
try {
// return AssetAddresses;
} catch (error) {
throw parseHttpError(error);
}
}
async fetchAssetMetadata(asset: string): Promise {
try {
// return [
// ...
// ];
} catch (error) {
throw parseHttpError(error);
}
}
async fetchHandleAddress(handle: string): Promise {
try {
// return handleAddress;
} catch (error) {
throw parseHttpError(error);
}
}
async fetchProtocolParameters(epoch = Number.NaN): Promise {
try {
// return {
// ...
// };
} catch (error) {
throw parseHttpError(error);
}
}
async submitTx(tx: string): Promise {
try {
// if (status === 200)
// return txHash;
} catch (error) {
throw parseHttpError(error);
}
}
}
```
However, please note that it may no longer be valid when the interface is updated. It is also important to note that the interface you require may not be **IFetcher** or **ISubmitter**, but rather other interfaces, depending on the purpose of the provider you are implementing.
## Implement Constructor and Functions
To start, we want to define the constructor.
A constructor is a special function that creates and initializes a class. This constructor gets called when an object is created using the **new** keyword. The purpose of a constructor is to create a new object and set values for any existing object properties.
When setting up a provider, it is usually necessary to provide some basic information, such as which network it should be connected to and if an API key is required.
In the case of **KoiosProvider**, we want the users to define the **network** and **version** (optional):
```tsx
private readonly _axiosInstance: AxiosInstance;
constructor(network: 'api' | 'preview' | 'preprod' | 'guild', version = 0) {
this._axiosInstance = axios.create({
baseURL: `https://${network}.koios.rest/api/v${version}`,
});
}
```
This constructor initializes the Axios instance, with the parameters provided by the user.
Next, we can define each function that is required by the interface. To do this, you must understand the answers to the following:
* how to query the blockchain provider?
* what are the input parameters of the interface?
* what are the input parameters needed to query the blockchain provider?
* what are the expected outputs of the interface?
* what is being returned by the blockchain provider?
By knowing the inputs and outputs of both the interface and the blockchain provider, one can create the functions that map the data correctly from the blockchain provider to the interface's required data type.
For example, below we have implemeted the **fetchProtocolParameters()** for **KoiosProvider** to map the responses returned from Koios, transforming the output into the required Protocol data type. This function is used for fetching protocol parameters:
```tsx
async fetchProtocolParameters(epoch: number): Promise {
try {
const { data, status } = await this._axiosInstance.get(
`epoch_params?_epoch_no=${epoch}`,
);
if (status === 200)
return {
coinsPerUTxOSize: data[0].coins_per_utxo_size,
collateralPercent: data[0].collateral_percent,
decentralisation: data[0].decentralisation,
epoch: data[0].epoch_no,
keyDeposit: data[0].key_deposit,
maxBlockExMem: data[0].max_block_ex_mem.toString(),
maxBlockExSteps: data[0].max_block_ex_steps.toString(),
maxBlockHeaderSize: data[0].max_bh_size,
maxBlockSize: data[0].max_block_size,
maxCollateralInputs: data[0].max_collateral_inputs,
maxTxExMem: data[0].max_tx_ex_mem.toString(),
maxTxExSteps: data[0].max_tx_ex_steps.toString(),
maxTxSize: data[0].max_tx_size,
maxValSize: data[0].max_val_size.toString(),
minFeeA: data[0].min_fee_a,
minFeeB: data[0].min_fee_b,
minPoolCost: data[0].min_pool_cost,
poolDeposit: data[0].pool_deposit,
priceMem: data[0].price_mem,
priceStep: data[0].price_step,
};
throw parseHttpError(data);
} catch (error) {
throw parseHttpError(error);
}
}
```
To complete implementation of your custom provider, simply do the same for every function specified by the interface and test that they work as expected.
If you think that the provider you have implemented will benefit the Cardano developer community, create a pull request.
# Guides
URL: /guides
Whether you are new to web development or a seasoned blockchain full-stack developer, these guides will help you get started.
***
title: "Guides"
description: "Whether you are new to web development or a seasoned blockchain full-stack developer, these guides will help you get started."
icon: BookOpenIcon
------------------
import { iconResolver } from "@/lib/iconResolver";
## Develop your first Web3 App
A step-by-step guide to setup a Next.js web application, add a wallet connection and browse assets.
## Minting Application
Load CLI generated keys and mint assets on Node.js.
## Multi-Signatures Transaction
Learn about multi-sig transaction, build a minting transaction involving MeshWallet and BrowserWallet.
## Prove Wallet Ownership
Cryptographically prove the ownership of a wallet by signing a piece of data using data sign.
## Implement Custom Provider
Build custom Providers that provides an API to access and process information provided by services.
## Smart Contract Transactions
Build a marketplace with Plutus (Haskell), where users can list their assets for sale and purchase the listed assets.
## Aiken Hello World
Create smart contracts with Aiken and execute transactions with Mesh.
## Executing a standalone script
Learn how to execute a standalone script to manage wallets and creating transactions.
## Vesting Script End-to-End
Learn how to vesting contract that locks up funds for a period of time and allows the beneficiary to withdraw the funds after the lockup period.
## Resolve Node-Specific Imports Errors
How to Resolve Node-Specific Imports Errors (e.g., Buffer, TextEncoder) in Browser-Based Projects
## Mint an NFT Collection
Learn to mint an NFT Collection with JavaScript & the MeshSDK.
# Minting Application
URL: /guides/minting-on-nodejs
undefined
***
title: "Minting Application"
icon: "guides/minting-application.png"
--------------------------------------
import Link from "fumadocs-core/link";
In this guide, we will be minting some assets with **MeshWallet** on Node.js.
## System setup
### 1. Visual Studio Code \[!toc]
Visual Studio Code is a code editor made by Microsoft. Download and install Visual Studio Code for code editing.
### 2. Node.js \[!toc]
Node.js is a cross-platform JavaScript runtime environment that runs on the V8 engine and executes JavaScript code. Install the Long-Term Support (LTS) version of Node.js (as of writing v22.18.0).
## Project setup
Firstly, create a new folder, and initialize a Node.js project:
```tsx
npm init
```
Next, install the **typescript** and **Mesh** package:
```tsx
npm install --dev typescript && npm install @meshsdk/core
```
Then, initialize Typescript which is require to compile a TypeScript:
```tsx
npx tsc --init
```
After that, open the **tsconfig.json** file and define the following configurations:
```tsx
{
...
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"outDir": "dist",
...
}
```
Finally, open the **package.json** file add the following configurations:
```tsx
{
...
"type": "module",
"scripts": {
"start": "tsc && node ./dist/main.js"
}
...
}
```
## Build the minting transaction
### 1. Create list of NFT's metadata \[!toc]
Create a file named **metadata.ts** and define the metadata for our NFTs:
```tsx
export const metadata: { [assetName: string]: any } = {
MeshToken01: {
name: "Mesh Token 1",
image: "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
mediaType: "image/jpg",
description: "Just a purple coin.",
artist: "This NFT was minted by Mesh (https://meshjs.dev/).",
},
MeshToken02: {
name: "Mesh Token 2",
image: "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
mediaType: "image/jpg",
description: "This is suppose to be a gold coin.",
artist: "This NFT was minted by Mesh (https://meshjs.dev/).",
},
MeshToken03: {
name: "Mesh Token 3",
image: "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
mediaType: "image/jpg",
description: "A coin with a M on it.",
artist: "This NFT was minted by Mesh (https://meshjs.dev/).",
},
};
```
### 2. Create a list of recipients \[!toc]
Create a file named **recipients.ts** and specify the list of recipients:
```tsx
export const recipients: { [recipient: string]: string } = {
addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr:
"MeshToken01",
addr_test1qqlcxawu4gxarenqvdqyw0tqyjy69mrgsmfqhm6h65jwm4vvldqg2n2p8y4kyjm8sqfyg0tpq9042atz0fr8c3grjmyscxry4r:
"MeshToken02",
addr_test1qq5tay78z9l77vkxvrvtrv70nvjdk0fyvxmqzs57jg0vq6wk3w9pfppagj5rc4wsmlfyvc8xs7ytkumazu9xq49z94pqzl95zt:
"MeshToken03",
};
```
### 3. Create main.ts and import the packages: \[!toc]
Lets create a file named **main.ts** and import the packages we need and the files we have created:
```tsx
import {
MeshWallet,
Transaction,
ForgeScript,
BlockfrostProvider,
resolveTxHash,
} from '@meshsdk/core';
import type { Mint, AssetMetadata } from '@meshsdk/core';
import { metadata } from './metadata.js';
import { recipients } from './recipients.js';
```
### 4. Define variables \[!toc]
Next, lets define some variables we will need for minting. You should be using your own wallet if you want to mint a collection of your own. For this example, these are the variables we need:
```tsx
const demoCLIKey = {
paymentSkey:
'5820aaca553a7b95b38b5d9b82a5daa7a27ac8e34f3cf27152a978f4576520dd6503',
stakeSkey:
'582097c458f19a3111c3b965220b1bef7d548fd75bc140a7f0a4f080e03cce604f0e',
};
const networkId = 0;
const blockfrostKey = 'BLOCKFROST_KEY_HERE';
```
### 5. Build the minting transaction \[!toc]
In this guide, we are building a minting transaction, but it could be any transactions. Learn more about Transaction.
Firstly, we need a blockchain provider, in this guide, we will import **BlockfrostProvider**, but you can use other providers as well:
```tsx
const provider = new BlockfrostProvider(blockfrostKey);
```
Next, lets initialize the **MeshWallet** and its forging script. In this example, we initialize using CLI generated keys, but you can also load your wallet with private key and mnemonic phrases. Learn more about MeshWallet.
```tsx
const wallet = new MeshWallet({
networkId: networkId,
fetcher: provider,
submitter: provider,
key: {
type: 'cli',
payment: demoCLIKey.paymentSkey,
stake: demoCLIKey.stakeSkey,
},
});
const walletAddress = wallet.getPaymentAddress();
const forgingScript = ForgeScript.withOneSignature(walletAddress);
```
Then, lets create a new Transaction, loop through each recipient, and mint an assets with **mintAsset** (Learn more about minting transactions):
```tsx
const tx = new Transaction({ initiator: wallet });
for (let recipient in recipients) {
const recipientAddress = recipient;
const assetName = recipients[recipient];
const assetMetadata: AssetMetadata = metadata[assetName];
const asset: Mint = {
assetName: assetName,
assetQuantity: '1',
metadata: assetMetadata,
label: '721',
recipient: recipientAddress
};
tx.mintAsset(forgingScript, asset);
}
```
Finally, lets sign and submit the transaction:
```tsx
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, false);
const txHash = await wallet.submitTx(signedTx);
```
To execute the script, run the following on your Terminal:
```tsx
npm start
```
For a successful transaction, you should get a transaction hash, you should have minted multiple assets in a single transaction, and sent them to multiple recipients.
# Multi-Signatures Transaction
URL: /guides/multisig-minting
undefined
***
title: "Multi-Signatures Transaction"
icon: "guides/multi-signatures-transaction.png"
-----------------------------------------------
import Link from "fumadocs-core/link";
A multi-signature (multi-sig) transaction requires more than one user to sign a transaction prior to the transaction being broadcast on a blockchain. You can think of it like a husband and wife savings account, where both signatures are required to spend the funds, preventing one spouse from spending the money without the approval of the other. For a multi-sig transaction, you can include 2 or more required signers, these signers can be wallets (Browser Wallet or Mesh Wallet) or Plutus script.
In this guide, we will build a multi-sig transaction for minting. There are 2 wallets involved,
1. client wallet belonging to the user who wishes to buy a native asset
2. application wallet that holds the forging script
In this guide, we will connect to user's CIP30 wallet (`BrowserWallet`) to request for a minting transaction. Then, the backend application wallet (`MeshWallet`) will build the transaction, and we will sign it with our wallet. Check out the code here.
## Connect wallet (client)
In this section, we will connect client's wallet and obtain their wallet address and UTXO.
Users can connect their wallet with `BrowserWallet`:
```tsx
import { BrowserWallet } from '@meshsdk/core';
const wallet = await BrowserWallet.enable(walletName);
```
Alternatively, you can use the `CardanoWallet` component to connect to the user's wallet:
```tsx
import { CardanoWallet, useWallet } from "@meshsdk/react";
export default function Page() {
const { wallet, connected } = useWallet();
return
}
```
Then, we get client's wallet address and UTXOs:
```tsx
const recipientAddress = await wallet.getChangeAddress();
const utxos = await wallet.getUtxos();
```
The change address will be the address receiving the minted NFTs and the transaction's change. Additionally, we will need the client's wallet UTXOs to build the minting transaction.
We can search for the UTXOs required for the transaction with one of the coin selection algorithms, such as `largestFirst` or `experimentalSelectUtxos`. In this example, we use `experimentalSelectUtxos` to select the UTXOs required for the transaction.:
```tsx
const assetMap = new Map();
assetMap.set("lovelace", mintingFee);
const selectedUtxos = experimentalSelectUtxos(assetMap, utxos, "5000000");
```
The `experimentalSelectUtxos` function will return the UTXOs required for the transaction. The `mintingFee` is the cost of minting the NFT, and the `5000000` is an amount that creates a buffer for the transaction fee.
Next, we will send the `selectedUtxos` and `recipientAddress` to the backend to build the minting transaction.
## Build transaction (application)
In this section, we will build the minting transaction.
In this guide, we won't be showing how to set up RESTful APIs and backend servers. There are thousands of tutorials on YouTube, we recommend building your backend server with Vercel API or NestJs or ExpressJs.
First, we initialize a blockchain provider and Mesh Wallet. In this example, we use mnemonic to restore our wallet, but you can initialize a wallet with mnemonic phrases, private keys, and Cardano CLI generated keys.
```tsx
const provider = new BlockfrostProvider(
''
);
const meshWallet = new MeshWallet({
networkId: 0,
fetcher: provider,
submitter: provider,
key: {
type: 'mnemonic',
words: yourMnemonic,
},
});
```
Next, let's define the forging script, here we used the first wallet address, but you can also define using `NativeScript`, see Transaction - Minting assets:
```tsx
const meshWalletAddress = meshWallet.getChangeAddress();
const forgingScript = ForgeScript.withOneSignature(meshWalletAddress);
```
Then, we define the `AssetMetadata` which contains the NFT metadata. In a NFT collection mint, you would need a selection algorithm and a database to select available NFTs.
```tsx
const assetName = 'MeshToken';
const assetMetadata: AssetMetadata = {
name: 'Mesh Token',
image: 'ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua',
mediaType: 'image/jpg',
description: 'This NFT was minted by Mesh (https://meshjs.dev/).',
};
```
After that, we create the `Mint` object:
```tsx
const asset: Mint = {
assetName: assetName,
assetQuantity: '1',
metadata: assetMetadata,
label: '721',
recipient: recipientAddress,
};
```
Finally, we are ready to create the transaction. We set the transaction inputs, mint the asset, send the lovelace to the bank wallet, set the change address, and build the transaction:
```tsx
const tx = new Transaction({ initiator: meshWallet });
tx.setTxInputs(userUtxos);
tx.mintAsset(forgingScript, asset);
tx.sendLovelace(bankWalletAddress, mintingFee);
tx.setChangeAddress(recipientAddress);
const unsignedTx = await tx.build();
```
Optionally, we can mask the metadata so users do not see the NFT metadata:
```tsx
originalMetadata = Transaction.readMetadata(unsignedTx);
```
This `originalMetadata` can be stored in a database to merge with the original transaction after user signature.
Send the transaction to the client for their signature.
## Sign transaction (client)
In this section, we need the client's signature to send the payment to the `bankWalletAddress`. The client's wallet will open and prompts for payment password. Note that the partial sign is set to `true`.
```tsx
const signedTx = await wallet.signTx(unsignedTx, true);
```
## Sign transaction (application)
The backend will sign the transaction with the application wallet:
```tsx
const meshWalletSignedTx = await systemWallet.signTx(unsignedTx, true);
```
If you have masked the metadata, you can merge the metadata with the signed transaction:
```tsx
const signedOriginalTx = Transaction.writeMetadata(
unsignedTx,
originalMetadata,
);
const meshWalletSignedTx = await systemWallet.signTx(
signedOriginalTx,
true,
);
```
## Submit transaction (application)
Finally, we submit the transaction to the blockchain:
```tsx
const txHash = await wallet.submitTx(signedTx);
```
Voila! You can build any multi-sig transactions!
Check out the code here.
# Develop your first Web3 App
URL: /guides/nextjs
undefined
***
title: "Develop your first Web3 App"
icon: "guides/develop-first-web-app.png"
----------------------------------------
import Link from "fumadocs-core/link";
In this guide, we will set up a Next.js application and connect it to the Cardano blockchain using Mesh. We will create a simple application that allows users to connect their wallets and view the assets in their wallets.
Though this guide is focused on Next.js which uses Mesh React you can also use Mesh with other frameworks like Remix, React, and Vue. Mesh SDK has Svelte UI components too.
You may follow this guide to setup your project or use the Mesh CLI to scaffold a new project.
```tsx
npx meshjs your-app-name
```
## Setup Next.js
Next.js is a web development framework built on top of Node.js enabling React-based web applications functionalities such as server-side rendering and generating static websites.
Next.js and Mesh are JavaScript libraries, and so we will assume that you have some familiarity with HTML and JavaScript language, but you should be able to follow along even if you are coming from a different programming language. If you don't feel very confident, we recommend going through this JS tutorial, or the MDN JavaScript Reference or my preferred method, watching a few videos from YouTube.
### 1. Create project folder and open Visual Studio Code \[!toc]
Create a new folder for your project, and give the folder a meaningful name. Open the Visual Studio Code application and drag your project folder into Visual Studio Code.
### 2. Create Next.js app \[!toc]
From the menu options in on your Visual Studio Code, open the **Terminal** and execute this command to create a new NextJs application:
```tsx
npx create-next-app@latest --typescript .
```
```tsx
Need to install the following packages:
Ok to proceed? (y)
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like your code inside a `src/` directory? … Yes
✔ Would you like to use App Router? … No
✔ Would you like to use Turbopack for next dev? … No
✔ Would you like to customize the import alias (@/* by default)? … No
```
### 3. Start development server \[!toc]
After the installation is complete, start the development server with:
```tsx
npm run dev
```
Visit [http://localhost:3000](http://localhost:3000) to view your application. `CTRL+C` to stop the application.
## Setup Mesh
Mesh is a JavaScript library that provides a simple way to interact with the Cardano blockchain. It provides a set of APIs that allow you to interact with the Cardano blockchain without having to deal with the complexities of the Cardano blockchain.
Install the latest version of Mesh with npm:
```tsx
npm install @meshsdk/core @meshsdk/react
```
Your Next.js application is ready to connect wallet, browse assets and make some transactions.
## Connect wallet and view assets
### 1. Add MeshProvider \[!toc]
React context is an essential tool for building web applications. It allow you to easily share state in your applications, so you can use the data in any component within the app. This means that when the user has connected their wallet, visiting different pages on the app ensure their wallet is still connected.
Open **pages/\_app.tsx**, import and include MeshProvider. Your **\_app.tsx** should look similar to this:
```tsx
import "../styles/globals.css";
import "@meshsdk/react/styles.css";
import type { AppProps } from "next/app";
import { MeshProvider } from "@meshsdk/react";
function MyApp({ Component, pageProps }: AppProps) {
return (
);
}
export default MyApp;
```
### 2. Add connect wallet component and check wallet's assets \[!toc]
Lets add the connect wallet component to allow users to connect wallets they have installed on their device. Connecting to wallets will ask the user for permission if not granted, and proceed to connect the selected wallet.
Lastly, we link those components together, allowing users to choose a wallet to connect, and query for assets in the wallet with **wallet.getAssets()**.
Open **pages/index.tsx** and replace it with the following codes:
```tsx
import { useState } from "react";
import type { NextPage } from "next";
import { useWallet } from '@meshsdk/react';
import { CardanoWallet } from '@meshsdk/react';
const Home: NextPage = () => {
const { connected, wallet } = useWallet();
const [assets, setAssets] = useState(null);
const [loading, setLoading] = useState(false);
async function getAssets() {
if (wallet) {
setLoading(true);
const _assets = await wallet.getAssets();
setAssets(_assets);
setLoading(false);
}
}
return (
Connect Wallet
{connected && (
<>
Get Wallet Assets
{assets ? (
{JSON.stringify(assets, null, 2)}
) : (
)}
>
)}
);
};
export default Home;
```
Start the development server and try it:
```tsx
npm run dev
```
Visit [http://localhost:3000](http://localhost:3000) to connect available wallets and view the assets in wallet.
If you do not have any assets in your wallet, you can receive test ADA (tADA) from the official faucet.
If you are new to Cardano, you will first have to download one of the Cardano wallets. Tall Nupinks has written a detailed Cardano Wallets 101 guide to help you understand the fundamentals of a Cardano wallet, including its features and how it works. With this guide, you will be able to make an informed decision on the best Cardano wallet for your needs.
### 3. Try on your own \[!toc]
Implement another component to display wallet's address and the amount of lovelace in your Next.js application. Check out the wallet page for more details.
# Mint an NFT Collection
URL: /guides/nft-collection
undefined
***
title: "Mint an NFT Collection"
icon: "guides/mint-nft-collection.png"
--------------------------------------
import Youtube from "@/components/ui/Youtube";
### Course Materials: \[!toc]
1. Install Bun ([https://bun.sh/docs/installation](https://bun.sh/docs/installation))
2. Fund Your Preprod Wallet ([https://docs.cardano.org/cardano-testnets/tools/faucet](https://docs.cardano.org/cardano-testnets/tools/faucet))
3. Create a Blockfrost Preprod Project ([https://blockfrost.io/dashboard](https://blockfrost.io/dashboard))
4. CIP-20 Definition ([https://cips.cardano.org/cip/CIP-20](https://cips.cardano.org/cip/CIP-20))
We are going to learn how to mint native assets on top of the cardano blockchain. You will:
1. Gain knowledge about tokens on cardano.
2. Learn how to build simple minting transactions.
3. Learn the basics of community accepted standards for non-fungible tokens.
## Project Setup
At course material #1 install the bun toolchain.
Initialize a new directory and run `bun init` & `bun install @meshsdk/core`
We need to generate and fund a Cardano wallet. Create a new file in `/scripts/brew.ts` and use the MeshSDK to generate a new wallet and log information about it.
```tsx
import { MeshWallet } from "@meshsdk/core";
const words = MeshWallet.brew() as string[];
const mnemonicString = words.join(" ");
console.log("mnemonic:", mnemonicString);
const wallet = new MeshWallet({
key: { type: "mnemonic", words },
networkId: 0,
});
console.log("Public Change Address:", await wallet.getChangeAddress());
```
Run the script with `bun run scripts/brew.ts`.
Copy your public address and fund the wallet using course material #2. Obtain a blockfrost preprod project using course material #3.
Copy your mnemonic and blockfrost preprod project api key into a `.env` file at the root of your project.
## Mint Your Collection
In the `index.ts` file generated by initializing your project, use core Mesh building blocks to interact with the blockchain.
```tsx
import {
MeshTxBuilder,
MeshWallet,
BlockfrostProvider
} from "@meshsdk/core"
const provider = new BlockfrostProvider(process.env.BLOCKFROST_KEY!);
const words = process.env.MNEMONIC!.split(" ");
const wallet = new MeshWallet({
key: { type: "mnemonic", words },
networkId: 0,
fetcher: provider,
submitter: provider,
});
const txBuilder = new MeshTxBuilder({ fetcher: provider });
const address = await wallet.getChangeAddress();
const utxos = await wallet.getUtxos();
const { pubKeyHash } = deserializeAddress(address);
```
Create a ruleset for minting your NFT using a native script. This will be used to derive the policy id.
```tsx
const nativeScript: NativeScript = {
type: "all",
scripts: [
{
type: "before",
slot: "90000000", // Any value beyond the current preprod absolute slot. When you read this, it's possible this slot has passed.
},
{ type: "sig", keyHash: pubKeyHash },
],
};
const forgeScript = ForgeScript.fromNativeScript(nativeScript);
const policyId = resolveScriptHash(forgeScript);
```
Let's write a function to generate the onchain metadata used to give our tokens an image and attributes.
```tsx
type AssetMetadata = {
files: {
mediaType: string;
name: string;
src: string;
}[];
image: string;
mediaType: string;
name: string;
};
function get721Metadata(
name: string,
attributes?: Record
): AssetMetadata {
return {
...attributes,
files: [
{
mediaType: "image/png",
name,
src: "ipfs://QmPS4PBvpGc2z6Dd6JdYqfHrKnURjtRGPTJWdhnAXNA8bQ",
},
],
image: "ipfs://QmPS4PBvpGc2z6Dd6JdYqfHrKnURjtRGPTJWdhnAXNA8bQ",
mediaType: "image/png",
name,
};
}
```
Now we can write a loop to create 9 unique tokens using our forge script. Commit, sign, and submit the transaction.
```tsx
const metadata: {
[policyId: string]: {
[assetName: string]: AssetMetadata;
};
} = { [policyId]: {} };
for (let i = 1; i < 10; i++) {
const tokenName = "Asset #" + i;
const tokenHex = stringToHex(tokenName);
txBuilder.mint("1", policyId, tokenHex).mintingScript(forgeScript);
metadata[policyId]![tokenName] = get721Metadata(tokenName, { Attribute: i });
}
const unsignedTx = await txBuilder
.metadataValue(721, metadata)
.changeAddress(address)
.invalidHereafter(90000000)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
console.log("Submitted TX Hash:", txHash);
```
Read the returned transaction hash, and use a chain explorer to view the preprod transaction.
# Resolve Node-Specific Imports Errors
URL: /guides/node-specific-imports
undefined
***
title: "Resolve Node-Specific Imports Errors"
icon: "guides/node-specific-imports.png"
----------------------------------------
import Link from "fumadocs-core/link";
How to Resolve Node-Specific Imports Errors (e.g., Buffer, TextEncoder) in Browser-Based Projects?
When working on a web-based project (React, Vue, Svelte, Angular, etc.), you may encounter errors such as:
```bash
Uncaught ReferenceError: Buffer is not defined
```
or
```bash
Module not found: Can't resolve 'buffer'
```
or
```bash
ReferenceError: TextEncoder is not defined
```
These errors often occur because your code (or one of your dependencies) is relying on Node.js-specific modules or globals that are not available by default in a browser environment. Common examples include:
* `Buffer`
* `TextEncoder` / `TextDecoder` (older browsers / polyfills)
* `crypto`
* `process`
* Node’s built-in modules (e.g., `fs`, `path`, `stream`)
Modern bundlers and frameworks (Webpack 5, Vite, Next.js, etc.) do **not** automatically include Node polyfills as was common in Webpack 4 and earlier. Below are some guidelines and configurations to fix these errors by adding the required polyfills for a browser environment.
## 1. General Concepts \[!toc]
1. **Polyfill**: A script that implements functionality missing in certain environments.
* Example: Using the `buffer` npm package to polyfill the `Buffer` API in the browser.
2. **Fallback configuration**: Telling your bundler to replace Node modules (like `buffer`) with a browser-friendly version.
3. **npm dependencies**: You may need to install extra packages to provide browser equivalents:
```tsx
npm install buffer process stream-browserify crypto-browserify --save
```
(You may not need all of them, but this is just an example.)
4. **ES Modules vs CommonJS**: Make sure your imports match your bundler’s expectations. Some polyfills are distributed as ESM (e.g., `import { Buffer } from 'buffer'`) or CommonJS.
## 2. Webpack \[!toc]
### 2.1 Webpack 5 and Above \[!toc]
Webpack 5 **no longer** includes Node polyfills by default. You have two main approaches:
**Approach A: Use NodePolyfillPlugin**
1. Install the plugin:
```tsx
npm install node-polyfill-webpack-plugin --save-dev
```
2. Add to your `webpack.config.js`:
```tsx
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
module.exports = {
// ...your existing config
plugins: [
new NodePolyfillPlugin(),
// ...other plugins
],
};
```
This plugin automatically injects commonly used polyfills (for `Buffer`, `process`, `stream`, etc.) where possible.
**Approach B: Use the `resolve.fallback` Setting**
For more granular control, you can manually configure fallbacks:
1. Install the required polyfills (if not already):
```tsx
npm install buffer process stream-browserify --save
```
2. Edit `webpack.config.js`:
```tsx
module.exports = {
// ...
resolve: {
fallback: {
buffer: require.resolve('buffer/'), // or 'buffer'
process: require.resolve('process/browser'),
stream: require.resolve('stream-browserify'),
// ...add more if needed
},
},
};
```
3. Import polyfills if needed in your code:
```tsx
import { Buffer } from 'buffer';
global.Buffer = global.Buffer || Buffer;
```
## 3. Vite
Vite uses Rollup under the hood, which does not automatically provide Node polyfills. However, there is a Rollup plugin that can help.
1. Install the Rollup polyfill plugin:
```tsx
npm install rollup-plugin-polyfill-node --save-dev
```
2. Add it to `vite.config.js`:
```tsx
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' // or react, svelte, etc.
import rollupNodePolyFill from 'rollup-plugin-polyfill-node'
export default defineConfig({
plugins: [
vue(),
// any other plugins
],
build: {
rollupOptions: {
plugins: [
rollupNodePolyFill()
],
},
},
resolve: {
alias: {
// Optionally, if you want the polyfill for `buffer` and `process` as top-level
buffer: 'rollup-plugin-polyfill-node/polyfills/buffer-es6',
process: 'rollup-plugin-polyfill-node/polyfills/process-es6',
// Add more if needed
},
},
})
```
3. Use the polyfilled global in your code if necessary:
```tsx
import { Buffer } from 'buffer';
globalThis.Buffer = globalThis.Buffer || Buffer;
```
## 4. Next.js
Next.js uses Webpack under the hood, so you can either:
1. Use `node-polyfill-webpack-plugin` directly in your `next.config.js`.
2. Manually configure the `webpack` property in `next.config.js` with `resolve.fallback`.
Example using `node-polyfill-webpack-plugin`:
```tsx
// next.config.js
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
module.exports = {
webpack: (config, { isServer }) => {
if (!isServer) {
config.plugins.push(new NodePolyfillPlugin())
}
return config
},
}
```
Now, references to Node modules like `Buffer` or `process` will be polyfilled in the client build.
## 5. Create React App (CRA)
Create React App **v5** switched to Webpack 5, which does not automatically include Node polyfills. Since CRA does not allow direct modifications to the Webpack config out of the box, you have two main options:
1. **Eject** your CRA setup to edit the Webpack config directly (not recommended usually).
2. Use a tool like react-app-rewired or craco to override Webpack config without ejecting.
### 5.1 Example with craco \[!toc]
1.Install craco:
```tsx
npm install @craco/craco --save-dev
```
2. Update your `package.json` scripts:
```tsx
{
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test"
}
}
```
3. Create `craco.config.js` in your project root:
```tsx
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
module.exports = {
webpack: {
plugins: {
add: [
new NodePolyfillPlugin()
],
},
configure: (webpackConfig) => {
// Optionally, if you want to set fallback manually:
webpackConfig.resolve.fallback = {
...webpackConfig.resolve.fallback,
buffer: require.resolve('buffer'),
process: require.resolve('process/browser'),
}
return webpackConfig;
}
},
};
```
4. Use your polyfills in code (e.g., `Buffer`):
```tsx
import { Buffer } from 'buffer';
global.Buffer = global.Buffer || Buffer;
```
## 6. Angular
Angular CLI also uses Webpack behind the scenes. To polyfill Node modules:
1. Install necessary polyfills:
```tsx
npm install buffer process stream-browserify --save
```
2. Edit `angular.jso`n to include the polyfill files or modify the Webpack config via a custom builder or a third-party library (e.g., ngx-build-plus).
An example using `ngx-build-plus` to extend the Angular CLI’s Webpack config:
```tsx
npm install ngx-build-plus --save-dev
```
Then in your `angular.json`:
```tsx
{
"projects": {
"my-app": {
"architect": {
"build": {
"builder": "ngx-build-plus:browser",
"options": {
// ...
},
"configurations": {
"production": {
// ...
}
}
},
"serve": {
"builder": "ngx-build-plus:dev-server",
"options": {
// ...
}
}
}
}
}
}
```
Create or update a `webpack.config.js`:
```tsx
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
module.exports = {
plugins: [
new NodePolyfillPlugin(),
],
resolve: {
fallback: {
buffer: require.resolve('buffer'),
process: require.resolve('process/browser'),
// ...
},
},
};
```
Then run your Angular commands via `ng build --extra-webpack-config webpack.config.js --output-hashing=none`.
## 7. Svelte
SvelteKit or a custom Svelte setup may use Vite or Rollup. Use the Vite instructions (Section **3** above) or directly add the polyfill plugin if you’re using a plain Rollup config:
```tsx
// rollup.config.js
import nodePolyfills from 'rollup-plugin-polyfill-node'
export default {
plugins: [
nodePolyfills(),
// ...
],
// ...
}
```
# Prove Wallet Ownership
URL: /guides/prove-wallet-ownership
undefined
***
title: "Prove Wallet Ownership"
icon: "guides/cryptographically-prove-wallet-ownership.png"
-----------------------------------------------------------
import Link from "fumadocs-core/link";
It's cryptographically easy to prove the ownership of an account by signing a piece of data using a private key. Since a user's public address can be used as their identifier, we can build an authentication mechanism that is based on message signing. This mechanism is made possible because we are able to cryptographically prove the ownership of an account by signing a specific piece of data using the corresponding private key. If the data is correctly signed, then the backend will recognize it as coming from the owner of the public address.
JSON Web Token (JWT) claims can typically be used to pass identity of authenticated users between an identity provider and a service provider. A server (service provider) could generate a token and provide that to a client (identity provider). For example, a client could then use that token to prove ownership of a wallet, as these tokens can be signed by one party's private key (in this case, the client's).
Some example uses of data signing to cryptographically prove ownership:
* **Authenticate user sign in using JSON Web Token (JWT)**: A cryptographically-secure login to prove the ownership of an account by signing a piece of data using a private key.
* **Authenticate user's action**: If the backend wants to confirm a user's authorization on an off-chain action, for example, engaging in in-game trading.
* **Off chain account flow**: If you need to display certain data that is off-chain or on a website only to a particular user identified by their wallet, you could use message signing as a means of doing so.
## How does it work?

By signing a message, you are affirming that you are in control of the wallet address linked to the Blockchain, and thus can prove ownership of it.
There are 4 ingredients to signing a message:
* user wallet address
* private key
* public key
* message to sign
To check if a user owns a certain address on a Web3 site, one needs to provide a message and have the user "sign" it. This "signature" is generated using the message, the user's private key, the public key, and a cryptographic algorithm.
To ensure the signature is valid, the same cryptographic algorithm is applied to the message and the public key is obtained. You may be wondering how this can be secure? The answer is that without the private key, the validation of the message and the public key cannot be cryptographically matched, thereby confirming ownership.
## Client: Connect Wallet and Get Staking Address
The User model stored in the database of the backend server must have two compulsory fields: public address and nonce. Furthermore, this address has to be unique. Other details about the user, such as username, Twitter ID, and name fields can be added, but are not essential for this process.
On Cardano, to obtain a user's public address as an identifier, we can use their wallet's staking address. This will be stored in the server side database, so that authorized wallets can be linked. The user never has to worry about manually entering their address, since it can be retrieved using **wallet.getUsedAddresses()**.
With the user's wallet connected, the first step is to get the user's staking address and send it to our backend server.
```tsx
const { wallet, connected } = useWallet();
async function frontendStartLoginProcess() {
if (connected) {
const userAddress = (await wallet.getUsedAddresses())[0];
// do: send request with 'userAddress' to the backend
}
}
```
## Server: Generate Nonce and Store in Database
In the backend, we first need to generate a new nonce, which is initialized as a random string. The purpose of this is to create a unique message that can be used for authentication of the user's wallet. This nonce will be the payload for the user to prove ownership of the wallet. With Mesh, you can generate a new nonce with **generateNonce()**, and set the message as **I agree to the term and conditions of the Mesh: nonce**.
By utilizing the **userAddress**, we can look up the database to determine whether the user is new or already exists.
If the user is new, we can create a new user entry, storing their staking address, nonce, and set their status as "not verified". Once the user has successfully verified, we can update their status to "verified" in our database.
For existing users, we just have to store the newly generated nonce in the database.
```tsx
import { generateNonce } from '@meshsdk/core';
async function backendGetNonce(userAddress) {
// do: if new user, create new user model in the database
const nonce = generateNonce('I agree to the term and conditions of the Mesh: ');
// do: store 'nonce' in user model in the database
// do: return 'nonce'
}
```
Lastly, we will return the **nonce** for the user to sign using their private key.
## Client: Verify ownership by signing the nonce
We are ready to use the private key associated with the wallet to sign the nonce with **await wallet.signData(nonce, userAddress)**, which enables the app to request the user to sign a payload according to CIP-8.
We request the user's authorization and show them the message that is to be signed: **I agree to the term and conditions of the Mesh: nonce**. Once accepted, the signature will be generated and the app will process the signature to authenticate the user.
```tsx
async function frontendSignMessage(nonce) {
try {
const userAddress = (await wallet.getUsedAddresses())[0];
const signature = await wallet.signData(nonce, userAddress);
// do: send request with 'signature' and 'userAddress' to the backend
} catch (error) {
// catch error if user refuse to sign
}
}
```
## Server: Verify Signature
When the backend receives the request, it retrieves the user associated with the specified address from the database. It then obtains the associated nonce from the database, which is a random value that is only known to the user.
With the nonce, staking address, and signature, the backend can cryptographically check that the nonce has been correctly signed by the user. This allows the backend to verify that the user is the owner of the public address, as only the owner of the address would know the nonce value and be able to sign it with the associated private key.
If the signature is verified, the user has successfully authenticated and the frontend will then receive a JSON Web Token (JWT) or session identifier to allow the user to access further resources. This is an example is for login process, but you can change it to use in approving a specific action, for example.
We also ensure that the nonce is not re-used (as this would make it possible for an attacker to gain access to the user's account). This is done by generating a random nonce for the user and saving it to the database. By constantly generating a unique nonce each time the user logs in, we can guarantee the user's signature is secure and keep their account safe.
```tsx
import { checkSignature } from '@meshsdk/core';
async function backendVerifySignature(userAddress, signature) {
// do: get 'nonce' from user (database) using 'userAddress'
const result = checkSignature(nonce, signature, userAddress);
// do: update 'nonce' in the database with another random string
// do: do whatever you need to do, once the user has proven ownership
// it could be creating a valid JSON Web Token (JWT) or session
// it could be doing something offchain
// it could just be updating something in the database
}
```
## Putting It All Together
OK, let's put it all together! Your frontend code should now contain two functions **frontendStartLoginProcess()** and **frontendSignMessage(nonce)**.
For signing in with a wallet, you can use the **CardanoWallet** React UI component to connect and sign in with the user's wallet:
```tsx
frontendStartLoginProcess()}
/>
```
Putting the frontend code together might look like this:
```tsx
import { CardanoWallet, useWallet } from '@meshsdk/react';
export default function Page() {
const { wallet, connected } = useWallet();
async function frontendStartLoginProcess() {
if (connected) {
const userAddress = (await wallet.getUsedAddresses())[0];
const nonce = await backendGetNonce(userAddress);
await frontendSignMessage(nonce);
}
}
async function frontendSignMessage(nonce) {
try {
const userAddress = (await wallet.getUsedAddresses())[0];
const signature = await wallet.signData(nonce, userAddress);
await backendVerifySignature(userAddress, signature);
} catch (error) {
setState(0);
}
}
return (
<>
frontendStartLoginProcess()}
/>
>
);
}
```
And the server side code should have 2 REST endpoints, **backendGetNonce(userAddress)** and **backendVerifySignature(userAddress, signature)**. The code might look like this:
```tsx
import { checkSignature, generateNonce } from '@meshsdk/core';
async function backendGetNonce(userAddress) {
const nonce = generateNonce('I agree to the term and conditions of the Mesh: ');
return nonce;
}
async function backendVerifySignature(userAddress, signature) {
// do: get 'nonce' from database
const result = checkSignature(nonce, signature, userAddress);
if(result){
// create JWT or approve certain process
}
else{
// prompt user that signature is not correct
}
}
```
There you go! Although this guide shows you how somebody can sign in with wallet, the same technique can be used to authenticate any of a user's actions.
# Smart Contract Transactions
URL: /guides/smart-contract-transactions
undefined
***
title: "Smart Contract Transactions"
icon: "guides/smart-contract-transactions.png"
----------------------------------------------
import Link from "fumadocs-core/link";
In this guide, we will build a marketplace where users can list their assets for sale and purchase the listed assets. The seller can update or cancel the listing at any time.
## Initialize the Plutus script
The first step is to initialize the Plutus script. The compiled plutus smart contract script CBOR is:
```tsx
const scriptCbor = '59079559079201000033232323232323232323232323232332232323232323232222232325335333006300800530070043333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4060064d5d0a80619a80c00c9aba1500b33501801a35742a014666aa038eb9406cd5d0a804999aa80e3ae501b35742a01066a0300466ae85401cccd54070091d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40b9d69aba15002302f357426ae8940088c98c80c8cd5ce01981901809aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a8173ad35742a004605e6ae84d5d1280111931901919ab9c033032030135573ca00226ea8004d5d09aba2500223263202e33573805e05c05826aae7940044dd50009aba1500533501875c6ae854010ccd540700808004d5d0a801999aa80e3ae200135742a00460446ae84d5d1280111931901519ab9c02b02a028135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a00460246ae84d5d1280111931900e19ab9c01d01c01a101b13263201b3357389201035054350001b135573ca00226ea80054049404448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080548c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8054cd5ce00b00a80989aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8068cd5ce00d80d00c09aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403866ae700740700680640604d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201633573802e02c02826ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301313574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900899ab9c01201100f00e135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900899ab9c01201100f00e00d00c135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900699ab9c00e00d00b135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c802ccd5ce00600580489baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c8050cd5ce00a80a00900880800780700680609aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401a66ae7003803402c0284d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200a33573801601401000e26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401666ae7003002c02402001c4d55cea80089baa0012323333573466e1d40052002212200223333573466e1d40092000212200123263200733573801000e00a00826aae74dd5000891999ab9a3370e6aae74dd5000a40004008464c6400866ae700140100092612001490103505431001123230010012233003300200200122212200201';
```
The Plutus script is initialized with the following code:
```tsx
const script: PlutusScript = {
code: scriptCbor,
version: 'V2',
};
```
Let's say we are testing our marketplace implementation on **preprod**, we can resolve the Plutus script address with **resolvePlutusScriptAddress** where we input the **PlutusScript** and define the **network** (in our demo we use **0** for testnet):
```tsx
const scriptAddress = resolvePlutusScriptAddress(script, 0);
```
## Listing Asset for Sale
Firstly, we get the user's wallet address: this address is the seller's address. We can acquire the first wallet's address from the connected wallet with **getUsedAddresses()**:
```tsx
const addr = (await wallet.getUsedAddresses())[0];
```
Then, we create the datum that has the following schema:
```tsx
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr), // seller address as pubkeyhash
listPriceInLovelace, // price
policyId, // policy ID of token
assetId, // asset name of token in hex
],
};
```
Lastly, we create a transaction that uses **sendAssets()**, to send the asset for sale to the script address with the datum we have defined. **policyId + assetId** is the asset name in hex. We build the transaction, the seller signs the transaction and submits the transaction to the blockchain.
```tsx
const tx = new Transaction({ initiator: wallet })
.sendAssets(
{
address: scriptAddress,
datum: {
value: datumConstr,
},
},
[
{
unit: policyId + assetId,
quantity: '1',
},
]
);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
Now implement your own marketplace. Note: you may need a database to store the listing information.
Full code on how to list an asset for sale:
```tsx
const addr = (await wallet.getUsedAddresses())[0];
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr),
listPriceInLovelace,
policyId,
assetId,
],
};
const tx = new Transaction({ initiator: wallet })
.sendAssets(
{
address: scriptAddress,
datum: {
value: datumConstr,
},
},
[
{
unit: policyId + assetId,
quantity: '1',
},
]
);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Cancel the Listing
Next, we will learn how to cancel the listing. Only the seller of the NFT can cancel the listing, thus we will define the datum with the following information:
```tsx
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr), // seller address as pubkeyhash
listPriceInLovelace, // price
policyId, // policy ID of token
assetId, // asset name of token in hex
],
};
```
For cancel, update and purchase endpoints, we need the UTxO in the script address as inputs to create the transaction. We use **fetchAddressUTxOs()** from one of the providers to query for UTxOs that contain the asset of our interest. Next, we filter the UTxO list by the datum hash, which we can get from the datum with **resolveDataHash()** (see resolvers). Here is the implementation for **\_getAssetUtxo()**, to get the UTxO in the script address that consists of the listed asset, and we use the datum hash to filter and get the correct UTxO for the transaction's input:
```tsx
async function _getAssetUtxo({ scriptAddress, asset, datum }) {
const utxos = await blockchainFetcher.fetchAddressUTxOs(
scriptAddress,
asset
);
if (utxos.length == 0) {
throw 'No listing found.';
}
const dataHash = resolveDataHash(datum);
let utxo = utxos.find((utxo: any) => {
return utxo.output.dataHash == dataHash;
});
return utxo;
}
```
Next, we define the redeemer for cancelling the listing:
```tsx
const redeemer = { data: { alternative: 1, fields: [] } };
```
Finally, we can build the transaction with the following code. We use the **redeemValue()** method to redeem the UTxO in the script address, and send the value back to the seller's address. We also need to set the "required signers" to include just the seller's address.
```tsx
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datumConstr,
redeemer: redeemer,
})
.sendValue(addr, assetUtxo)
.setRequiredSigners([addr]);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
Full code for cancelling a listing:
```tsx
const addr = (await wallet.getUsedAddresses())[0];
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr),
listPriceInLovelace,
policyId,
assetId,
],
};
const assetUtxo = await _getAssetUtxo({
scriptAddress: scriptAddress,
asset: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e',
datum: datumConstr,
});
if (assetUtxo === undefined) {
throw 'No listing found.';
}
const redeemer = { data: { alternative: 1, fields: [] } };
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datumConstr,
redeemer: redeemer,
})
.sendValue(addr, assetUtxo)
.setRequiredSigners([addr]);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
## Purchase the Listed Asset
A key feature of a marketplace is the ability to purchase the listed asset from the seller. The purchase endpoint will take the asset, the price and the seller address as parameters. These parameters will be used to create the datum for the validator. A successful purchase will result in the transfer of the asset to the buyer and the listed price to the seller.
First, we need the buyer's address to send the asset to:
```tsx
const addr = (await wallet.getUsedAddresses())[0]; // buyer's address
```
Like the cancel endpoint, we need to create the datum for the validator. It is important to note that we are using the seller's address to create the datum:
```tsx
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(sellerAddr), // seller address as pubkeyhash
listPriceInLovelace, // price
policyId, // policy ID of token
assetId, // asset name of token in hex
],
};
```
Then, we will define the redeemer:
```tsx
const redeemer = { data: { alternative: 0, fields: [] } };
```
Finally, we can build the transaction and submit it to the blockchain. We will use the **redeemValue()** method to redeem the asset from the validator, use **sendValue()** to send the asset to the buyer and **sendLovelace()** to send the payment price to the seller:
```tsx
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datumConstr,
redeemer: redeemer,
})
.sendValue(addr, assetUtxo)
.sendLovelace(sellerAddr, listPriceInLovelace.toString())
.setRequiredSigners([addr]);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
Full code for purchasing an asset:
```tsx
const addr = (await wallet.getUsedAddresses())[0]; // buyer's address
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(sellerAddr),
listPriceInLovelace,
policyId,
assetId,
],
};
const assetUtxo = await _getAssetUtxo({
scriptAddress: scriptAddress,
asset: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e',
datum: datumConstr,
});
const redeemer = { data: { alternative: 0, fields: [] } };
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datumConstr,
redeemer: redeemer,
})
.sendValue(addr, assetUtxo)
.sendLovelace(sellerAddr, listPriceInLovelace.toString())
.setRequiredSigners([addr]);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
## Update the Listing
Finally, we will learn how to update the listing. Only the seller of the NFT can update the listing, thus we will define the datum with the following information:
```tsx
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr), // seller address as pubkeyhash
listPriceInLovelace, // listed price
policyId, // policy ID of token
assetId, // asset name of token in hex
],
};
```
We will also need to create the updated datum with the new price:
```tsx
const datumConstrNew: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr), // seller address as pubkeyhash
updatedPriceInLovelace, // updated price
policyId, // policy ID of token
assetId, // asset name of token in hex
],
};
```
Next, we define the redeemer for updating the listing:
```tsx
const redeemer = { data: { alternative: 1, fields: [] } };
```
Finally, we can build the transaction to update the listing. We use the **redeemValue()** method to redeem the UTxO in the script address with the original datum, and then we use the **sendAssets()** method to send the NFT to the same script address, with the new datum.
```tsx
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datumConstr,
redeemer: redeemer,
})
.setRequiredSigners([addr])
.sendAssets(
{
address: scriptAddress,
datum: {
value: datumConstrNew,
},
},
[
{
unit: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e',
quantity: '1',
},
]
);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
Full code for updating the listing:
```tsx
const addr = (await wallet.getUsedAddresses())[0];
const datumConstr: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr),
listPriceInLovelace,
policyId,
assetId,
],
};
const datumConstrNew: Data = {
alternative: 0,
fields: [
resolvePaymentKeyHash(addr),
updatedPriceInLovelace,
policyId,
assetId,
],
};
const assetUtxo = await _getAssetUtxo({
scriptAddress: scriptAddress,
asset: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e',
datum: datumConstr,
});
const redeemer = { data: { alternative: 1, fields: [] } };
const tx = new Transaction({ initiator: wallet })
.redeemValue({
value: assetUtxo,
script: script,
datum: datumConstr,
redeemer: redeemer,
})
.setRequiredSigners([addr])
.sendAssets(
{
address: scriptAddress,
datum: {
value: datumConstrNew,
},
},
[
{
unit: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e',
quantity: '1',
},
]
);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
And there you go! I hope this is a good starting point for you to start building your own apps that use smart contracts!
# Executing a standalone script
URL: /guides/standalone
undefined
***
title: "Executing a standalone script"
icon: "guides/standalone.png"
-----------------------------
import Link from "fumadocs-core/link";
If you're looking to run a javascript files to interact with the blockchain, you can use the tsx package to run the files directly from the command line.
This guide will walk you through setting up a simple project using MeshSDK. By the end, you'll have a working environment that can create a wallet, build and sign transactions, and submit them to the blockchain.
In this tutorial, we'll cover:
* Creating a package.json file to manage your project dependencies.
* Installing the necessary packages, including MeshSDK.
* Writing a TypeScript script to create a wallet and send a transaction.
* Running your project to see the results.
Let's get started!
## System setup
### Create a package.json file \[!toc]
First, create a new `package.json` file in the root of your project with the following content:
```tsx
{
"type": "module",
"dependencies": {},
"scripts": {
"dev": "tsx index.ts"
}
}
```
### Install the necessary packages \[!toc]
Open your terminal and run these commands to install the required packages and MeshSDK:
```tsx
npm install
npm install tsx @meshsdk/core
```
Here's how your `package.json` file should look after installing the packages:
```tsx
{
"type": "module",
"dependencies": {
"@meshsdk/core": "^1.5.18",
"tsx": "^4.9.4"
},
"scripts": {
"dev": "tsx index.ts"
}
}
```
* @meshsdk/core: Core functionality for network interactions, wallets, and transactions.
* tsx: Allows running TypeScript files directly from the command line.
## Make a simple transaction
### Create the index.ts file \[!toc]
Next, create a new `index.ts` file in the root of your project and add the following code:
```tsx
import { BlockfrostProvider, MeshWallet, Transaction } from "@meshsdk/core";
// Set up the blockchain provider with your key
const provider = new BlockfrostProvider("YOUR_KEY_HERE");
// Initialize the wallet with a mnemonic key
const wallet = new MeshWallet({
networkId: 0,
fetcher: provider,
submitter: provider,
key: {
type: "mnemonic",
words: [
"your", "mnemonic", "...", "here",
],
},
});
// Create and send a transaction
const tx = new Transaction({ initiator: wallet }).sendLovelace(
"addr_test1qp2k7wnshzngpqw0xmy33hvexw4aeg60yr79x3yeeqt3s2uvldqg2n2p8y4kyjm8sqfyg0tpq9042atz0fr8c3grjmysdp6yv3",
"1000000"
);
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
Explanation:
* Wallet Initialization: The code sets up a new wallet using MeshWallet with a mnemonic key and a blockchain provider.
* Transaction Creation: A new transaction is created to send 1 ADA to a specific address. The transaction is built, signed, and submitted to the blockchain.
* Output: The transaction hash is logged to the console.
### Run Your Application \[!toc]
In the code, you must replace `YOUR\_KEY\_HERE` with a valid blockfrost key, and replace the mnemonic words with your own. You can visit Blockfrost to get a free API key, and generate a new mnemonic key from the Mesh website.
Finally, start your application by running this command:
```tsx
npm run dev
```
If everything is set up correctly, you should see the transaction hash logged to the console. Congratulations! You've successfully created a wallet and sent a transaction using MeshSDK.
You can find the complete code for this guide in the Mesh GitHub repo.
# Vesting Script End-to-End
URL: /guides/vesting
undefined
***
title: "Vesting Script End-to-End"
icon: "guides/vesting.png"
--------------------------
import Link from "fumadocs-core/link";
Vesting contract is a smart contract that locks up funds and allows the beneficiary to withdraw the funds after the lockup period.
When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure.
## On-Chain code
First, we define the datum's shape, as this datum serves as configuration and contains the different parameters of our vesting operation.
```tsx
pub type VestingDatum {
/// POSIX time in milliseconds, e.g. 1672843961000
lock_until: Int,
/// Owner's credentials
owner: ByteArray,
/// Beneficiary's credentials
beneficiary: ByteArray,
}
```
In this example, we define a `VestingDatum` that contains the following fields:
* `lock_until`: The POSIX timestamp in milliseconds until which the funds are locked.
* `owner`: The credentials (public key hash) of the owner of the funds.
* `beneficiary`: The credentials (public key hash) of the beneficiary of the funds.
This datum can be found in `aiken-vesting/aiken-workspace/lib/vesting/types.ak`.
Next, we define the spend validator.
```tsx
use aiken/transaction.{ScriptContext, Spend}
use vesting/types.{VestingDatum}
use vodka_extra_signatories.{key_signed}
use vodka_validity_range.{valid_after}
validator {
pub fn vesting(datum: VestingDatum, _redeemer: Data, ctx: ScriptContext) {
// In principle, scripts can be used for different purpose (e.g. minting
// assets). Here we make sure it's only used when 'spending' from a eUTxO
when ctx.purpose is {
Spend(_) -> or {
key_signed(ctx.transaction.extra_signatories, datum.owner),
and {
key_signed(ctx.transaction.extra_signatories, datum.beneficiary),
valid_after(ctx.transaction.validity_range, datum.lock_until),
},
}
_ -> False
}
}
}
```
In this example, we define a `vesting` validator that ensures the following conditions are met:
* The transaction must be signed by owner
Or:
* The transaction must be signed by beneficiary
* The transaction must be valid after the lockup period
This validator can be found in `aiken-vesting/aiken-workspace/validators/vesting.ak`.
### How it works \[!toc]
The owner of the funds deposits the funds into the vesting contract. The funds are locked up until the lockup period expires.
Transactions can include validity intervals that specify when the transaction is valid, both from and until a certain time. The ledger verifies these validity bounds before executing a script and will only proceed if they are legitimate.
This approach allows scripts to incorporate a sense of time while maintaining determinism within the script's context. For instance, if a transaction has a lower bound `A`, we can infer that the current time is at least `A`.
It's important to note that since we don't control the upper bound, a transaction might be executed even 30 years after the vesting delay. However, from the script's perspective, this is entirely acceptable.
The beneficiary can withdraw the funds after the lockup period expires. The beneficiary can also be different from the owner of the funds.
## Testing
To test the vesting contract, we have provided the a comphrehensive test script,you can run tests with `aiken check`.
The test script includes the following test cases:
* success unlocking
* success unlocking with only owner signature
* success unlocking with beneficiary signature and time passed
* fail unlocking with only beneficiary signature
* fail unlocking with only time passed
We recommend you to check out `aiken-vesting/aiken-workspace/validators/tests/vesting.ak` to learn more.
## Compile and build script
To compile the script, run the following command:
```tsx
aiken build
```
This command will generate a CIP-0057 Plutus blueprint, which you can find in `aiken-vesting/aiken-workspace/plutus.json`.
## Off-Chain code
### Deposit funds \[!toc]
First, the owner can deposit funds into the vesting contract. The owner can specify the lockup period and the beneficiary of the funds.
```tsx
const assets: Asset[] = [
{
unit: "lovelace",
quantity: "10000000",
},
];
const lockUntilTimeStamp = new Date();
lockUntilTimeStamp.setMinutes(lockUntilTimeStamp.getMinutes() + 1);
const beneficiary =
"addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9";
```
In this example, we deposit 10 ADA into the vesting contract. The funds are locked up for 1 minute, and the beneficiary is specified.
Then, we prepare a few variables to be used in the transaction. We get the wallet address and the UTXOs of the wallet. We also get the script address of the vesting contract, to send the funds to the script address. We also get the owner and beneficiary public key hashes.
```tsx
const { utxos, walletAddress } = await getWalletInfoForTx();
const { scriptAddr } = getScript();
const { pubKeyHash: ownerPubKeyHash } = deserializeAddress(walletAddress);
const { pubKeyHash: beneficiaryPubKeyHash } = deserializeAddress(beneficiary);
```
Next, we construct the transaction to deposit the funds into the vesting contract.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
await txBuilder
.txOut(scriptAddr, amount)
.txOutInlineDatumValue(
mConStr0([lockUntilTimeStampMs, ownerPubKeyHash, beneficiaryPubKeyHash])
)
.changeAddress(walletAddress)
.selectUtxosFrom(utxos)
.complete();
const unsignedTx = txBuilder.txHex;
```
In this example, we construct the transaction to deposit the funds into the vesting contract. We specify the script address of the vesting contract, the amount to deposit, and the lockup period, owner, and beneficiary of the funds.
Finally, we sign and submit the transaction.
```tsx
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
To execute this code, ensure you have defined blockfrost key in the `.env` file. You can also define your wallet mnemonic in `aiken-vesting/src/configs.ts` file.
You can run the following command execute the deposit funds code:
```tsx
npm run deposit
```
Upon successful execution, you will receive a transaction hash. Save this transaction hash for withdrawing the funds.
Example of a successful deposit transaction.
### Withdraw funds \[!toc]
After the lockup period expires, the beneficiary can withdraw the funds from the vesting contract. The owner can also withdraw the funds from the vesting contract.
First, let's look for the UTxOs containing the funds locked in the vesting contract.
```tsx
const txHashFromDesposit =
"ede9f8176fe41f0c84cfc9802b693dedb5500c0cbe4377b7bb0d57cf0435200b";
const utxos = await provider.fetchUTxOs(txHash);
const vestingUtxo = utxos[0];
```
In this example, we fetch the UTxOs containing the funds locked in the vesting contract. We specify the transaction hash of the deposit transaction.
Like before, we prepare a few variables to be used in the transaction. We get the wallet address and the UTXOs of the wallet. We also get the script address of the vesting contract, to send the funds to the script address. We also get the owner and beneficiary public key hashes.
```tsx
const { utxos, walletAddress, collateral } = await getWalletInfoForTx();
const { input: collateralInput, output: collateralOutput } = collateral;
const { scriptAddr, scriptCbor } = getScript();
const { pubKeyHash } = deserializeAddress(walletAddress);
```
Next, we prepare the datum and the slot number to set the transaction valid interval to be valid only after the slot.
```tsx
const datum = deserializeDatum(vestingUtxo.output.plutusData!);
const invalidBefore =
unixTimeToEnclosingSlot(
Math.min(datum.fields[0].int as number, Date.now() - 15000),
SLOT_CONFIG_NETWORK.preprod
) + 1;
```
In this example, we prepare the datum and the slot number to set the transaction valid interval to be valid only after the slot. We get the lockup period from the datum and set the transaction valid interval to be valid only after the lockup period.
Next, we construct the transaction to withdraw the funds from the vesting contract.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
await txBuilder
.spendingPlutusScriptV2()
.txIn(
vestingUtxo.input.txHash,
vestingUtxo.input.outputIndex,
vestingUtxo.output.amount,
scriptAddr
)
.spendingReferenceTxInInlineDatumPresent()
.spendingReferenceTxInRedeemerValue("")
.txInScript(scriptCbor)
.txOut(walletAddress, [])
.txInCollateral(
collateralInput.txHash,
collateralInput.outputIndex,
collateralOutput.amount,
collateralOutput.address
)
.invalidBefore(invalidBefore)
.requiredSignerHash(pubKeyHash)
.changeAddress(walletAddress)
.selectUtxosFrom(utxos)
.complete();
const unsignedTx = txBuilder.txHex;
```
In this example, we construct the transaction to withdraw the funds from the vesting contract. We specify the UTxO containing the funds locked in the vesting contract, the script address of the vesting contract, the wallet address to send the funds to, and the transaction valid interval.
Finally, we sign and submit the transaction. Notice that since we are unlocking fund from validator, partial sign has to be specified by passing a `true` parameter into `wallet.signTx`.
```tsx
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
To execute this code, update `aiken-vesting/src/withdraw-fund.ts` with the transaction hash from the deposit transaction. Ensure you have defined blockfrost key in the `.env` file. You can also define your wallet mnemonic in `aiken-vesting/src/configs.ts` file.
Run the following command:
```tsx
npm run withdraw
```
Example of a successful withdraw transaction.
# Blockfrost Provider
URL: /providers/blockfrost
Featuring over 100 APIs tailored for easy access to Cardano blockchain
***
title: "Blockfrost Provider"
description: "Featuring over 100 APIs tailored for easy access to Cardano blockchain"
-------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
Blockfrost provides restful APIs which allows your app to access information stored on the blockchain.
Get started:
```tsx
import { BlockfrostProvider } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
```
If you are using a privately hosted Blockfrost instance, you can set the URL in the parameter:
```tsx
const provider = new BlockfrostProvider('');
```
### Get data from URL
You can fetch any data from the blockchain by providing the URL path.
```tsx
await provider.get('/addresses/addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9/transactions')
```
## Fetch Account Info
Obtain information about a specific stake account.
```tsx
await provider.fetchAccountInfo('stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n')
```
## Fetch Address Assets
Fetch assets from an address.
```tsx
await provider.fetchAddressAssets('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
**Address**
```bash
addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9
```
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch assets from address \[!toc]
Fetch assets given an address
**Address**
```bash
addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9
```
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
## Fetch Address UTxOs
Fetch UTxOs controlled by an address.
```tsx
await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
Optionally, you can filter UTXOs containing a particular `asset` by providing asset, where it is the concatenation of policy ID and asset.
```tsx
await fetchAddressUTxOs(address: string, asset?: string)
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
**Address**
```bash
addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9
```
```tsx
await provider.fetchAddressUTxOs(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch UTxOs with Asset \[!toc]
Fetch UTxOs from address with asset
**Address**
```bash
addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9
```
**Asset**:
`d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
```tsx
await provider.fetchAddressUTxOs(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
## Fetch Asset Addresses
Fetch a list of a addresses containing a specific `asset` where it is the concatenation of policy ID and asset.
```tsx
await provider.fetchAssetAddresses('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
### Fetch Asset Addresses \[!toc]
Fetch list of addresses containing a specific asset
**Asset Unit**:
`d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
```tsx
await provider.fetchAssetAddresses(
'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e'
);
```
## Fetch Asset Metadata
Fetch the asset metadata by providing asset's `unit`, which is the concatenation of policy ID and asset name in hex.
```tsx
// Asset Unit: `d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
await provider.fetchAssetMetadata('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Block Info
Fetch block infomation. You can get the hash from `fetchTxInfo()`.
```tsx
// Block hash: `79f60880b097ec7dabb81f75f0b52fedf5e922d4f779a11c0c432dcf22c56089`
await provider.fetchBlockInfo('79f60880b097ec7dabb81f75f0b52fedf5e922d4f779a11c0c432dcf22c56089')
```
## Fetch Collection Assets
Fetch a list of assets belonging to a collection by providing its Policy ID.
```tsx
await provider.fetchCollectionAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527')
```
The API will return a list of `assets` and a cursor `next`. If the cursor is not null, you can use it to fetch the next page of results.
Here is an example of the response.
```tsx
{
"assets": [
{
"unit": "d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527",
"quantity": "1"
},
],
"next": 2
}
```
The `fetchCollectionAssets` function also accepts an optional `cursor` parameter to fetch the next page of results. The default value is `1`.
```tsx
await fetchCollectionAssets(
policyId: string,
cursor = 1
)
```
## Fetch Handle Address
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
We can resolve the handle's address with `fetchHandleAddress`.
```tsx
// Handle: `meshsdk`
await provider.fetchHandleAddress('meshsdk')
```
## Fetch Handle
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
ADA Handle also released a CIP68 handle and this function will fetch the metadata of the handle.
```tsx
// Handle: `meshsdk`
await provider.fetchHandle('meshsdk')
```
## Fetch Protocol Parameters
Fetch the latest protocol parameters.
```tsx
await provider.fetchProtocolParameters()
```
Optionally, you can provide an epoch number to fetch the protocol parameters of that epoch.
## Fetch Transaction Info
Fetch transaction infomation. Only confirmed transaction can be retrieved.
```tsx
// Transaction hash: `f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159`
await provider.fetchTxInfo('f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159')
```
## Fetch UTxOs
Get UTxOs for a given hash.
```tsx
await provider.fetchUTxOs('dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70')
```
Optionally, you can specify the index of the index output.
```tsx
await provider.fetchUTxOs('hash_here', 0)
```
## Fetch Proposal Info
Get information for a given governance proposal, identified by the txHash and proposal index
```tsx
await provider.fetchGovernanceProposal('372d688faa77e146798b581b322c0f2981a9023764736ade5d12e0e4e796af8c', 0)
```
## Evaluate Transaction
`evaluateTx()` accepts an unsigned transaction (`unsignedTx`) and it evaluates the resources required to execute the transaction. Note that, this is only valid for transaction interacting with redeemer (smart contract). By knowing the budget required, you can use this to adjust the redeemer's budget so you don't spend more than you need to execute transactions for this smart contract.
```tsx
const unsignedTx = await tx.build();
const evaluateTx = await provider.evaluateTx(unsignedTx);
```
Example responses from unlocking assets from the always succeed smart contract.
```tsx
[
{
"index": 0,
"tag": "SPEND",
"budget": {
"mem": 1700,
"steps": 368100
}
}
]
```
With the `mem` and `steps`, you can refine the budget for the redeemer. For example:
```tsx
const redeemer = {
data: { alternative: 0, fields: [...] },
budget: {
mem: 1700,
steps: 368100,
},
};
```
## Submit Transaction
Submit a serialized transaction to the network.
```tsx
await provider.submitTx(signedTx);
```
## On Transaction Confirmed
Allow you to listen to a transaction confirmation. Upon confirmation, the callback will be called.
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '5000000');
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
provider.onTxConfirmed(txHash, () => {
// Transaction confirmed
});
```
# Hydra Provider (beta)
URL: /providers/hydra
undefined
***
title: "Hydra Provider (beta)"
desceription: "Layer 2 scaling solution for Cardano that increases transaction throughput and ensures cost efficiency while maintaining security."
--------------------------------------------------------------------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
The Hydra Head protocol is a layer 2 scaling solution for Cardano rooted in peer-reviewed research that increases transaction throughput and ensures cost efficiency while maintaining rigorous security.
Get started:
```tsx
import { HydraProvider } from "@meshsdk/hydra";
// Hydra Head URL and PORT: e.g. http://123.45.67.890:4001
const provider = new HydraProvider('');
await provider.connect();
```
## Connect Hydra Head
Connects to the Hydra Head. This command is a no-op when a Head is already open.
```tsx
await provider.connect();
```
## Initializes a new Hydra Head
Initializes a new Head. This command is a no-op when a Head is already open and the server will output an `CommandFailed` message should this happen.
```tsx
await provider.init();
```
## Commit to Hydra Head
Commit a particular UTxO to the head. This will make the UTxO available on the layer 2.
```tsx
// Params: CommitUtxo, KeyToSign
await instance.commit("", undefined);
```
## Aborts a head
Aborts a head before it is opened. This can only be done before all participants have committed. Once opened, the head can't be aborted anymore but it can be closed using: `Close`.
```tsx
await provider.abort();
```
## New Transaction
Submit a transaction through the head. Note that the transaction is only broadcast if well-formed and valid.
You can also the `await provider.submitTx(signedTx)` method to submit a signed transaction.
The `newTx` method accepts the following arguments:
```tsx
async newTx(
cborHex: string,
type:
| "Tx ConwayEra"
| "Unwitnessed Tx ConwayEra"
| "Witnessed Tx ConwayEra",
description = "",
txId?: string
)
```
Here is an example of how to create a transaction using the Hydra provider, Mesh wallet and Mesh transaction builder:
```tsx
async function makeTx() {
const walletA = {
addr: "addr_test1vpsthwvxgfkkm2lm8ggy0c5345u6vrfctmug6tdyx4rf4mqn2xcyw",
key: "58201aae63d93899640e91b51c5e8bd542262df3ecf3246c3854f39c40f4eb83557d",
};
const wallet = new MeshWallet({
networkId: 0,
key: {
type: "cli",
payment: walletA.key,
},
fetcher: provider,
submitter: provider,
});
const pp = await provider.fetchProtocolParameters();
const utxos = await wallet.getUtxos("enterprise");
const changeAddress = walletA.addr;
const txBuilder = new MeshTxBuilder({
fetcher: provider,
params: pp,
verbose: true,
});
const unsignedTx = await txBuilder
.txOut(
"addr_test1vpd5axpq4qsh8sxvzny49cp22gc5tqx0djf6wmjv5cx7q5qyrzuw8",
[{ unit: "lovelace", quantity: "3000000" }],
)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
console.log("txHash", txHash);
}
```
## Decommit
Request to decommit a UTxO from a Head by providing a decommit tx. Upon reaching consensus, this will eventually result in corresponding transaction outputs becoming available on the layer 1.
The decommit method accepts the following arguments:
```tsx
async decommit(
cborHex: string,
type:
| "Tx ConwayEra"
| "Unwitnessed Tx ConwayEra"
| "Witnessed Tx ConwayEra",
description = "",
)
```
## Close Hydra Head
Terminate a head with the latest known snapshot. This effectively moves the head from the Open state to the Close state where the contestation phase begin. As a result of closing a head, no more transactions can be submitted via NewTx.
```tsx
await provider.close();
```
## Contest
Challenge the latest snapshot announced as a result of a head closure from another participant. Note that this necessarily contest with the latest snapshot known of your local Hydra node. Participants can only contest once.
```tsx
await provider.contest();
```
## Fanout
Finalize a head after the contestation period passed. This will distribute the final (as closed and maybe contested) head state back on the layer 1.
```tsx
await provider.fanout();
```
## Listens for new messages from Hydra node
Listens for new messages from Hydra node. The callback function will be called with the message as the only argument. Check all events emitted by the Hydra node.
```tsx
provider.onMessage((message) => {
console.log("HydraProvider received message", message);
// do something with the message
});
```
The callback function is typed, so you can access the message properties directly.
```tsx
provider.onMessage((message) => {
if (message.tag === "Greetings") {
console.log("message.snapshotUtxo", message.snapshotUtxo);
}
});
```
## Fetch Address UTxOs
Fetch UTxOs controlled by an address.
```tsx
await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
Optionally, you can filter UTXOs containing a particular asset by providing `asset`, where it is the concatenation of policy ID and asset.
```tsx
// Assest f.e. d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e
await fetchAddressUTxOs(address: string, asset?: string)
```
## Fetch Protocol Parameters
Fetch the latest protocol parameters.
```tsx
await provider.fetchProtocolParameters()
```
Optionally, you can provide an epoch number to fetch the protocol parameters of that epoch.
## Fetch UTxOs
Get UTxOs for a given hash.
```tsx
await provider.fetchUTxOs('dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70')
```
Optionally, you can specify the index of the index output.
```tsx
await provider.fetchUTxOs('hash_here', 0)
```
## Submit Transaction
Submit a serialized transaction to the network.
```tsx
await provider.submitTx(signedTx);
```
# Providers
URL: /providers
Data providers for connecting to the blockchain
***
title: "Providers"
description: "Data providers for connecting to the blockchain"
icon: CloudIcon
---------------
## Blockfrost Provider
Featuring over 100 APIs tailored for easy access to Cardano blockchain
## Hydra Provider (beta)
Layer 2 scaling solution for Cardano that increases transaction throughput and ensures cost efficiency while maintaining security.
## Koios Provider
Distributed & open-source public API query layer for Cardano
## Maestro Provider
Advanced UTxO-indexing data layer to supercharge Defi on Bitcoin, Cardano & Dogecoin
## Ogmios Provider
Lightweight bridge interface for cardano-node that offers WebSockets API that enables local clients to speak Ouroboros' mini-protocols
## UTxORPC Provider
Highly efficient through gRPC, using a compact and high-performance binary format
## Yaci Provider
Custom Cardano devnet to tailor your devnet needs with a builtin indexer and custom viewer for devnet
## Offline Fetcher
An offline blockchain data provider for testing, development and offline scenarios.
## Offline Evaluator
An offline Plutus script evaluator for testing and validation.
# Koios Provider
URL: /providers/koios
Distributed & open-source public API query layer for Cardano
***
title: "Koios Provider"
description: "Distributed & open-source public API query layer for Cardano"
---------------------------------------------------------------------------
import Link from "fumadocs-core/link";
import Youtube from "@/components/ui/Youtube";
Koios provides a query layer which allows your app to access information stored on the blockchain.
Get started:
```tsx
import { KoiosProvider } from "@meshsdk/core";
const provider = new KoiosProvider(
'preprod', // "api" | "preview" | "preprod" | "guild"
'',
);
```
Get your API key from Koios User Profile page.
## Get data from URL
You can fetch any data from the blockchain by providing the URL path.
```tsx
await provider.get('/addresses/addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9/transactions')
```
## Fetch Account Info
Obtain information about a specific stake account.
```tsx
await provider.fetchAccountInfo('stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n')
```
## Fetch Address Assets
Fetch assets from an address.
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch assets from address \[!toc]
Fetch assets given an address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
);
```
## Fetch Address UTxOs
Fetch UTxOs controlled by an address.
```tsx
await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
Optionally, you can filter UTXOs containing a particular `asset` by providing asset, where it is the concatenation of policy ID and asset.
```tsx
await fetchAddressUTxOs(address: string, asset?: string)
```
## Fetch Asset Addresses
Fetch a list of a addresses containing a specific `asset` where it is the concatenation of policy ID and asset.
```tsx
await provider.fetchAssetAddresses('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Asset Metadata
Fetch the asset metadata by providing asset's `unit`, which is the concatenation of policy ID and asset name in hex.
```tsx
await provider.fetchAssetMetadata('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Block Info
Fetch block infomation. You can get the hash from `fetchTxInfo()`.
```tsx
await provider.fetchBlockInfo('79f60880b097ec7dabb81f75f0b52fedf5e922d4f779a11c0c432dcf22c56089')
```
## Fetch Collection Assets
Fetch a list of assets belonging to a collection by providing its Policy ID.
```tsx
await provider.fetchCollectionAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527')
```
The API will return a list of `assets` and a cursor `next`. If the cursor is not null, you can use it to fetch the next page of results. Here is an example of the response.
```tsx
{
"assets": [
{
"unit": "d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527",
"quantity": "1"
},
],
"next": 2
}
```
The `fetchCollectionAssets` function also accepts an optional `cursor` parameter to fetch the next page of results. The default value is `1`.
```tsx
await fetchCollectionAssets(
policyId: string,
cursor = 1
)
```
## Fetch Handle Address
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
We can resolve the handle's address with `fetchHandleAddress`.
```tsx
// Handle: `meshsdk`
await provider.fetchHandleAddress('meshsdk')
```
## Fetch Handle
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
ADA Handle also released a CIP68 handle and this function will fetch the metadata of the handle.
```tsx
// Handle: `meshsdk`
await provider.fetchHandle('meshsdk')
```
## Fetch Protocol Parameters
Fetch the latest protocol parameters.
```tsx
await provider.fetchProtocolParameters()
```
Optionally, you can provide an epoch number to fetch the protocol parameters of that epoch.
## Fetch Transaction Info
Fetch transaction infomation. Only confirmed transaction can be retrieved.
```tsx
await provider.fetchTxInfo('f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159')
```
## Fetch UTxOs
Get UTxOs for a given hash.
```tsx
await provider.fetchUTxOs('dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70')
```
Optionally, you can specify the index of the index output.
```tsx
await provider.fetchUTxOs('hash_here', 0)
```
## Fetch Proposal Info
Get information for a given governance proposal, identified by the txHash and proposal index
```tsx
await provider.fetchGovernanceProposal('372d688faa77e146798b581b322c0f2981a9023764736ade5d12e0e4e796af8c', 0)
```
## Submit Transaction
Submit a serialized transaction to the network.
```tsx
await provider.submitTx(signedTx);
```
## On Transaction Confirmed
Allow you to listen to a transaction confirmation. Upon confirmation, the callback will be called.
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '5000000');
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
provider.onTxConfirmed(txHash, () => {
// Transaction confirmed
});
```
# Maestro Provider
URL: /providers/maestro
Advanced UTxO-indexing data layer to supercharge Defi on Bitcoin, Cardano & Dogecoin
***
title: "Maestro Provider"
description: "Advanced UTxO-indexing data layer to supercharge Defi on Bitcoin, Cardano & Dogecoin"
---------------------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
Maestro is the complete Web3 stack for Cardano which provides among others:-
* ⛓️ Enterprise-grade onchain data access.
* ⚡️ Transaction monitoring system with submission retires, rollback notifications and accelerated tranaction finality.
* 💰 High-fidelity smart contract data feeds from top Cardano DeFi protocols.
* 📝 Fully managed smart contract APIs and ready-to-go UI plugins.
Get started:
```tsx
import { MaestroProvider } from "@meshsdk/core";
const provider = new MaestroProvider({
network: 'Preprod', // Mainnet / Preprod / Preview
apiKey: '', // Get key at https://docs.gomaestro.org/
turboSubmit: false // Read about paid turbo transaction submission feature at https://docs.gomaestro.org
});
```
## Get data from URL
You can fetch any data from the blockchain by providing the URL path.
```tsx
await provider.get('/addresses/addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9/transactions')
```
## Fetch Account Info
Obtain information about a specific stake account.
```tsx
await provider.fetchAccountInfo('stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n')
```
## Fetch Address Assets
Fetch assets from an address.
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
## Fetch Address UTxOs
Fetch UTxOs from address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
## Fetch assets from address
Fetch assets given an address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
);
```
## Fetch Address UTxOs
Fetch UTxOs controlled by an address.
```tsx
await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
Optionally, you can filter UTXOs containing a particular asset by providing `asset`, where it is the concatenation of policy ID and asset.
```tsx
await provider.fetchAddressUTxOs(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e'
);
```
## Fetch Asset Addresses
Fetch a list of a addresses containing a specific `asset` where it is the concatenation of policy ID and asset.
```tsx
await provider.fetchAssetAddresses('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Asset Metadata
Fetch the asset metadata by providing asset's `unit`, which is the concatenation of policy ID and asset name in hex.
```tsx
await provider.fetchAssetMetadata('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Block Info
Fetch block infomation. You can get the hash from `fetchTxInfo()`.
```tsx
await provider.fetchBlockInfo('79f60880b097ec7dabb81f75f0b52fedf5e922d4f779a11c0c432dcf22c56089')
```
## Fetch Collection Assets
Fetch a list of assets belonging to a collection by providing its Policy ID.
```tsx
await provider.fetchCollectionAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527')
```
The API will return a list of `assets` and a cursor `next`. If the cursor is not null, you can use it to fetch the next page of results. Here is an example of the response.
```tsx
{
"assets": [
{
"unit": "d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527",
"quantity": "1"
},
],
"next": 2
}
```
The `fetchCollectionAssets` function also accepts an optional `cursor` parameter to fetch the next page of results. The default value is `1`.
```tsx
await fetchCollectionAssets(
policyId: string,
cursor = 1
)
```
## Fetch Handle Address
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
We can resolve the handle's address with `fetchHandleAddress`.
```tsx
// Handle: `meshsdk`
await provider.fetchHandleAddress('meshsdk')
```
## Fetch Handle
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
ADA Handle also released a CIP68 handle and this function will fetch the metadata of the handle.
```tsx
// Handle: `meshsdk`
await provider.fetchHandle('meshsdk')
```
## Fetch Protocol Parameters
Fetch the latest protocol parameters.
```tsx
await provider.fetchProtocolParameters()
```
Optionally, you can provide an epoch number to fetch the protocol parameters of that epoch.
## Fetch Transaction Info
Fetch transaction infomation. Only confirmed transaction can be retrieved.
```tsx
// Transaction hash f.e. f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159
await provider.fetchTxInfo('f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159')
```
## Fetch UTxOs
Get UTxOs for a given hash.
```tsx
await provider.fetchUTxOs('dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70')
```
Optionally, you can specify the index of the index output.
```tsx
await provider.fetchUTxOs('hash_here', 0)
```
## Fetch Proposal Info
Get information for a given governance proposal, identified by the txHash and proposal index
```tsx
// Params: TxHash, CertIndex
await provider.fetchGovernanceProposal('372d688faa77e146798b581b322c0f2981a9023764736ade5d12e0e4e796af8c', 0)
```
## Evaluate Transaction
`evaluateTx()` accepts an unsigned transaction (`unsignedTx`) and it evaluates the resources required to execute the transaction. Note that, this is only valid for transaction interacting with redeemer (smart contract). By knowing the budget required, you can use this to adjust the redeemer's budget so you don't spend more than you need to execute transactions for this smart contract.
```tsx
const unsignedTx = await tx.build();
const evaluateTx = await provider.evaluateTx(unsignedTx);
```
Example responses from unlocking assets from the always succeed smart contract.
```tsx
[
{
"index": 0,
"tag": "SPEND",
"budget": {
"mem": 1700,
"steps": 368100
}
}
]
```
With the `mem` and `steps`, you can refine the budget for the redeemer. For example:
```tsx
const redeemer = {
data: { alternative: 0, fields: [...] },
budget: {
mem: 1700,
steps: 368100,
},
};
```
## Submit Transaction
Submit a serialized transaction to the network.
```tsx
await provider.submitTx(signedTx);
```
## On Transaction Confirmed
Allow you to listen to a transaction confirmation. Upon confirmation, the callback will be called.
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '5000000');
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
provider.onTxConfirmed(txHash, () => {
// Transaction confirmed
});
```
# Offline Evaluator
URL: /providers/offline-evaluator
An offline Plutus script evaluator for testing and validation.
***
title: "Offline Evaluator"
description: "An offline Plutus script evaluator for testing and validation."
-----------------------------------------------------------------------------
import Link from "fumadocs-core/link";
The OfflineEvaluator calculates execution costs (memory and CPU steps) for Plutus scripts in transactions without requiring network connectivity. It works with an OfflineFetcher to resolve the UTXOs needed for script validation. This is also compatible with any other fetchers to provide online data fetching.
Get started:
```tsx
import { OfflineEvaluator } from "@meshsdk/core-csl";
import { OfflineFetcher } from "@meshsdk/core";
// Create fetcher for resolving UTXOs
const fetcher = new OfflineFetcher();
// Add UTXOs required for script evaluation
fetcher.addUTxOs([
{
input: {
txHash: "5de23a2...",
outputIndex: 0
},
output: {
address: "addr1...",
amount: [{ unit: "lovelace", quantity: "1000000" }],
scriptHash: "32b7e3d..." // For script UTXOs
}
}
]);
// Create evaluator for the desired network
const evaluator = new OfflineEvaluator(fetcher, "preprod");
```
Once initialized, you can evaluate Plutus scripts in transactions:
```tsx
// Evaluate Plutus scripts in a transaction
try {
const actions = await evaluator.evaluateTx(transactionCbor);
// Example result:
// [{
// index: 0,
// tag: "MINT",
// budget: {
// mem: 508703, // Memory units used
// steps: 164980381 // CPU steps used
// }
// }]
} catch (error) {
console.error('Script evaluation failed:', error);
}
```
The evaluator is particularly useful for testing Plutus scripts, ensuring they execute within memory and CPU limits:
```tsx
// In your test file
describe("Plutus Script Tests", () => {
let evaluator: OfflineEvaluator;
let fetcher: OfflineFetcher;
beforeEach(() => {
fetcher = new OfflineFetcher();
evaluator = new OfflineEvaluator(fetcher, "preprod");
// Add test UTXOs
fetcher.addUTxOs([...]);
});
it("should evaluate minting policy", async () => {
const result = await evaluator.evaluateTx(txCbor);
expect(result[0].tag).toBe("MINT");
expect(result[0].budget.mem).toBeLessThan(600000);
});
});
```
The evaluation results include memory units and CPU steps required for each script execution, helping you optimize your scripts and ensure they meet protocol constraints.
## Evaluate Transaction
`evaluateTx()` accepts an unsigned transaction (`unsignedTx`) and it evaluates the resources required to execute the transaction. Note that, this is only valid for transaction interacting with redeemer (smart contract). By knowing the budget required, you can use this to adjust the redeemer's budget so you don't spend more than you need to execute transactions for this smart contract.
```tsx
const unsignedTx = await tx.build();
const evaluateTx = await provider.evaluateTx(unsignedTx);
```
Example responses from unlocking assets from the always succeed smart contract.
```tsx
[
{
"index": 0,
"tag": "SPEND",
"budget": {
"mem": 1700,
"steps": 368100
}
}
]
```
With the `mem` and `steps`, you can refine the budget for the redeemer. For example:
```tsx
const redeemer = {
data: { alternative: 0, fields: [...] },
budget: {
mem: 1700,
steps: 368100,
},
};
```
# OfflineFetcher
URL: /providers/offline-fetcher
An offline blockchain data provider for testing, development and offline scenarios.
***
title: "OfflineFetcher"
description: "An offline blockchain data provider for testing, development and offline scenarios."
--------------------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
The OfflineFetcher provides access to blockchain data without requiring network connectivity. It's ideal for testing, development, and scenarios where you need to work with pre-loaded blockchain data offline.
Initialize the fetcher:
```tsx
import { OfflineFetcher } from "@meshsdk/core";
// Create a new instance
const fetcher = new OfflineFetcher();
// Create with specified network
const fetcherWithNetwork = new OfflineFetcher("mainnet");
```
Before you can fetch data, you need to add it to the fetcher. Here are examples of adding different types of blockchain data:
```tsx
// Add account information
fetcher.addAccount("addr1...", {
balance: "1000000",
rewards: "500000",
withdrawals: "100000",
poolId: "pool1..." // optional
});
// Add UTXOs
fetcher.addUTxOs([
{
input: {
txHash: "1234...",
outputIndex: 0
},
output: {
address: "addr1...",
amount: [{ unit: "lovelace", quantity: "1000000" }],
// Optional fields for script UTXOs:
scriptHash: "abcd...",
dataHash: "ef12...",
plutusData: "...",
scriptRef: "..."
}
}
]);
// Add asset addresses
fetcher.addAssetAddresses("policyID.assetName", [
{ address: "addr1...", quantity: "1" }
]);
// Add asset metadata
fetcher.addAssetMetadata("policyID.assetName", {
name: "Asset Name",
image: "ipfs://...",
// Any other metadata attributes
});
// Add protocol parameters
fetcher.addProtocolParameters({
epoch: 290,
minFeeA: 44,
minFeeB: 155381,
maxBlockSize: 73728,
maxTxSize: 16384,
maxBlockHeaderSize: 1100,
keyDeposit: 2000000,
poolDeposit: 500000000,
minPoolCost: "340000000",
// Other parameters...
});
// Add serilized transaction
fetcher.addSerializedTransaction("txHash");
```
The fetcher's state can be saved and loaded, making it easy to persist data between sessions:
```tsx
// Save state
const state = fetcher.toJSON();
localStorage.setItem('fetcher-state', state);
// Load state
const savedState = localStorage.getItem('fetcher-state');
const fetcher = OfflineFetcher.fromJSON(savedState);
```
Once data is added, you can use the fetch\* methods just like with other providers such as BlockfrostProvider. This makes OfflineFetcher a drop-in replacement for testing and offline scenarios.
## Get data from URL
You can fetch any data from the blockchain by providing the URL path.
```tsx
// Params: URL
await provider.get('/addresses/addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9/transactions')
```
## Fetch Account Info
Obtain information about a specific stake account.
```tsx
// Params: Stake Address
await provider.fetchAccountInfo('stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n')
```
## Fetch Address Assets
Fetch assets from an address.
```tsx
// Params: Address
await provider.fetchAddressAssets('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch assets from address \[!toc]
Fetch assets given an address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
);
```
## Fetch Address UTxOs
Fetch UTxOs controlled by an address.
```tsx
// Params: Address
await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
Optionally, you can filter UTXOs containing a particular asset by providing `asset`, where it is the concatenation of policy ID and asset.
```tsx
await fetchAddressUTxOs(address: string, asset?: string)
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
```tsx
await provider.fetchAddressUTxOs(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch UTxOs with Asset \[!toc]
Fetch UTxOs from address with asset
```tsx
await provider.fetchAddressUTxOs(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e'
);
```
## Fetch Asset Addresses
Fetch a list of a addresses containing a specific asset where it is the concatenation of policy ID and asset.
```tsx
// Params: Asset Unit
await provider.fetchAssetAddresses('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Asset Metadata
Fetch the asset metadata by providing asset's `unit`, which is the concatenation of policy ID and asset name in hex.
```tsx
// Params: Asset Unit
await provider.fetchAssetMetadata('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Block Info
Fetch block infomation. You can get the hash from `fetchTxInfo()`.
```tsx
// Params: Block hash
await provider.fetchBlockInfo('79f60880b097ec7dabb81f75f0b52fedf5e922d4f779a11c0c432dcf22c56089')
```
## Fetch Collection Assets
Fetch a list of assets belonging to a collection by providing its Policy ID.
```tsx
await provider.fetchCollectionAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527')
```
The API will return a list of `assets` and a cursor `next`. If the cursor is not null, you can use it to fetch the next page of results. Here is an example of the response.
```tsx
{
"assets": [
{
"unit": "d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527",
"quantity": "1"
},
],
"next": 2
}
```
The `fetchCollectionAssets` function also accepts an optional `cursor` parameter to fetch the next page of results. The default value is `1`.
```tsx
await fetchCollectionAssets(
policyId: string,
cursor = 1
)
```
## Fetch Handle Address
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
We can resolve the handle's address with `fetchHandleAddress`.
```tsx
// Params: Handle
await provider.fetchHandleAddress('meshsdk')
```
## Fetch Handle
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
ADA Handle also released a CIP68 handle and this function will fetch the metadata of the handle.
```tsx
// Params: Handle
await provider.fetchHandle('meshsdk')
```
## Fetch Protocol Parameters
Fetch the latest protocol parameters.
```tsx
await provider.fetchProtocolParameters()
```
Optionally, you can provide an epoch number to fetch the protocol parameters of that epoch.
## Fetch Transaction Info
Fetch transaction infomation. Only confirmed transaction can be retrieved.
```tsx
await provider.fetchTxInfo('f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159')
```
## Fetch UTxOs
Get UTxOs for a given hash.
```tsx
// Params: Hash
await provider.fetchUTxOs('dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70')
```
Optionally, you can specify the index of the index output.
```tsx
await provider.fetchUTxOs('hash_here', 0)
```
## Fetch Proposal Info
Get information for a given governance proposal, identified by the txHash and proposal index
```tsx
// Params: TxHash, CertIndex
await provider.fetchGovernanceProposal('372d688faa77e146798b581b322c0f2981a9023764736ade5d12e0e4e796af8c', 0)
```
# Ogmios Provider
URL: /providers/ogmios
Lightweight bridge interface for cardano-node that offers WebSockets API that enables local clients to speak Ouroboros' mini-protocols
***
title: "Ogmios Provider"
description: "Lightweight bridge interface for cardano-node that offers WebSockets API that enables local clients to speak Ouroboros' mini-protocols"
-----------------------------------------------------------------------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
Ogmios is a lightweight bridge interface for cardano-node. It offers a WebSockets API that enables local clients to speak Ouroboros' mini-protocols via JSON/RPC. Ogmios is a fast and lightweight solution that can be deployed alongside relays to create entry points on the Cardano network for various types of applications.
Get started:
```tsx
import { OgmiosProvider } from "@meshsdk/core";
const provider = new OgmiosProvider('');
```
## Evaluate Transaction
`evaluateTx()` accepts an unsigned transaction (`unsignedTx`) and it evaluates the resources required to execute the transaction. Note that, this is only valid for transaction interacting with redeemer (smart contract). By knowing the budget required, you can use this to adjust the redeemer's budget so you don't spend more than you need to execute transactions for this smart contract.
```tsx
const unsignedTx = await tx.build();
const evaluateTx = await provider.evaluateTx(unsignedTx);
```
Example responses from unlocking assets from the always succeed smart contract.
```tsx
[
{
"index": 0,
"tag": "SPEND",
"budget": {
"mem": 1700,
"steps": 368100
}
}
]
```
With the `mem` and `steps`, you can refine the budget for the redeemer. For example:
```tsx
const redeemer = {
data: { alternative: 0, fields: [...] },
budget: {
mem: 1700,
steps: 368100,
},
};
```
## Submit Transaction
Submit a serialized transaction to the network.
```tsx
await provider.submitTx(signedTx);
```
# UTxORPC Provider
URL: /providers/utxorpc
Highly efficient through gRPC, using a compact and high-performance binary format
***
title: "UTxORPC Provider"
description: "Highly efficient through gRPC, using a compact and high-performance binary format"
------------------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
Highly efficient through gRPC, using a compact and high-performance binary format
The UTxORPC (u5c) provider facilitates access to this state in a standardized and efficient manner through gRPC, using a compact and high-performance binary format. It enables seamless interaction with the Cardano blockchain, to facilitate the creation, signing, and submission of transactions.
* Standardized Interface: Implements the UTxORPC specification to ensure compatibility and interoperability across UTxO-based blockchains.
* Performance Optimized: Utilizes gRPC for efficient communication with blockchain nodes, minimizing network overhead and message size.
* Flexible Provider Options: Suitable for use with hosted services, local nodes like Dolos, or any UTxORPC-compliant service.
The following code samples assume that the UTxORPC node is running locally on localhost:50051. If your node is hosted remotely or on a different server, replace "[http://localhost:50051](http://localhost:50051)" with the appropriate server URL and port for your environment.
You can also use the UTxORPC provider with a hosted service like Demeter.run. Demeter is a PaaS (Platform-as-a-Service) that provides managed Cardano infrastructure. One of their services consists of a cloud-hosted endpoint for Cardano integration using the UTxO RPC spec. Developers can sign-up and get access to the API on a per-request basis.
For more details on configuring your node, refer to the UTxORPC Ecosystem Servers Documentation.
```tsx
import { U5CProvider } from "@meshsdk/core";
const provider = new U5CProvider({
url: "http://localhost:50051",
headers: {
"dmtr-api-key": "",
},
});
```
## Get data from URL
You can fetch any data from the blockchain by providing the URL path.
```tsx
await provider.get('/addresses/addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9/transactions')
```
## Fetch Account Info
Obtain information about a specific stake account.
```tsx
await provider.fetchAccountInfo('stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n')
```
## Fetch Address Assets
Fetch assets from an address.
```tsx
await provider.fetchAddressAssets('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch assets from address \[!toc]
Fetch assets given an address.
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
);
```
## Fetch Address UTxOs
Fetch UTxOs controlled by an address.
```tsx
await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
Optionally, you can filter UTXOs containing a particular asset by providing `asset`, where it is the concatenation of policy ID and asset.
```tsx
await fetchAddressUTxOs(address: string, asset?: string)
```
## Fetch Asset Addresses
Fetch a list of a addresses containing a specific asset where it is the concatenation of policy ID and asset.
```tsx
await provider.fetchAssetAddresses('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Asset Metadata
Fetch the asset metadata by providing asset's `unit`, which is the concatenation of policy ID and asset name in hex.
```tsx
await provider.fetchAssetMetadata('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Block Info
Fetch block infomation. You can get the hash from `fetchTxInfo()`.
```tsx
await provider.fetchBlockInfo('79f60880b097ec7dabb81f75f0b52fedf5e922d4f779a11c0c432dcf22c56089')
```
## Fetch Collection Assets
Fetch a list of assets belonging to a collection by providing its Policy ID.
```tsx
await provider.fetchCollectionAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527')
```
The API will return a list of `assets` and a cursor `next`. If the cursor is not null, you can use it to fetch the next page of results. Here is an example of the response.
```tsx
{
"assets": [
{
"unit": "d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527",
"quantity": "1"
},
],
"next": 2
}
```
The `fetchCollectionAssets` function also accepts an optional `cursor` parameter to fetch the next page of results. The default value is `1`.
```tsx
await fetchCollectionAssets(
policyId: string,
cursor = 1
)
```
## Fetch Handle Address
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
We can resolve the handle's address with `fetchHandleAddress`.
```tsx
// Handle: `meshsdk`
await provider.fetchHandleAddress('meshsdk')
```
## Fetch Handle
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
ADA Handle also released a CIP68 handle and this function will fetch the metadata of the handle.
```tsx
// Handle: `meshsdk`
await provider.fetchHandle('meshsdk')
```
### Fetch Protocol Parameters
Fetch the latest protocol parameters.
```tsx
await provider.fetchProtocolParameters()
```
Optionally, you can provide an epoch number to fetch the protocol parameters of that epoch.
## Fetch Transaction Info
Fetch transaction infomation. Only confirmed transaction can be retrieved.
```tsx
await provider.fetchTxInfo('f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159')
```
## Fetch UTxOs
Get UTxOs for a given hash.
```tsx
// Hash f.e. dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70
await provider.fetchUTxOs('dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70')
```
Optionally, you can specify the index of the index output.
```tsx
await provider.fetchUTxOs('hash_here', 0)
```
## Fetch Proposal Info
Get information for a given governance proposal, identified by the txHash and proposal index
```tsx
await provider.fetchGovernanceProposal('372d688faa77e146798b581b322c0f2981a9023764736ade5d12e0e4e796af8c', 0)
```
## Evaluate Transaction
`evaluateTx()` accepts an unsigned transaction (`unsignedTx`) and it evaluates the resources required to execute the transaction. Note that, this is only valid for transaction interacting with redeemer (smart contract). By knowing the budget required, you can use this to adjust the redeemer's budget so you don't spend more than you need to execute transactions for this smart contract.
```tsx
const unsignedTx = await tx.build();
const evaluateTx = await provider.evaluateTx(unsignedTx);
```
Example responses from unlocking assets from the always succeed smart contract.
```tsx
[
{
"index": 0,
"tag": "SPEND",
"budget": {
"mem": 1700,
"steps": 368100
}
}
]
```
With the `mem` and `steps`, you can refine the budget for the redeemer. For example:
```tsx
const redeemer = {
data: { alternative: 0, fields: [...] },
budget: {
mem: 1700,
steps: 368100,
},
};
```
## Submit Transaction
Submit a serialized transaction to the network.
```tsx
await provider.submitTx(signedTx);
```
## On Transaction Confirmed
Allow you to listen to a transaction confirmation. Upon confirmation, the callback will be called.
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '5000000');
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
provider.onTxConfirmed(txHash, () => {
// Transaction confirmed
});
```
# Yaci Provider
URL: /providers/yaci
Custom Cardano devnet to tailor your devnet needs with a builtin indexer and custom viewer for devnet
***
title: "Yaci Provider"
description: "Custom Cardano devnet to tailor your devnet needs with a builtin indexer and custom viewer for devnet"
--------------------------------------------------------------------------------------------------------------------
import Link from "fumadocs-core/link";
Yaci DevKit is a development tool designed for rapid and efficient Cardano blockchain development. It allows developers to create and destroy custom Cardano devnets in seconds, providing fast feedback loops and simplifying the iteration process.
Get started:
```tsx
import { YaciProvider } from "@meshsdk/core";
const provider = new YaciProvider('', '');
```
## Get data from URL
You can fetch any data from the blockchain by providing the URL path.
```tsx
await provider.get('/addresses/addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9/transactions')
```
## Fetch Account Info
Obtain information about a specific stake account.
```tsx
await provider.fetchAccountInfo('stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n')
```
## Fetch Address Assets
Fetch assets from an address.
```tsx
await provider.fetchAddressAssets('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch assets from address \[!toc]
Fetch assets given an address
```tsx
await provider.fetchAddressAssets(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
);
```
## Fetch Address UTxOs
Fetch UTxOs controlled by an address.
```tsx
await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9')
```
Optionally, you can filter UTXOs containing a particular `asset` by providing asset, where it is the concatenation of policy ID and asset.
```tsx
await fetchAddressUTxOs(address: string, asset?: string)
```
### Fetch Address UTxOs \[!toc]
Fetch UTxOs from address
```tsx
await provider.fetchAddressUTxOs(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9'
);
```
### Fetch UTxOs with Asset \[!toc]
Fetch UTxOs from address with asset
```tsx
await provider.fetchAddressUTxOs(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e'
);
```
## Fetch Asset Addresses
Fetch a list of a addresses containing a specific `asset` where it is the concatenation of policy ID and asset.
```tsx
await provider.fetchAssetAddresses('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Asset Metadata
Fetch the asset metadata by providing asset's `unit`, which is the concatenation of policy ID and asset name in hex.
```tsx
await provider.fetchAssetMetadata('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e')
```
## Fetch Block Info
Fetch block infomation. You can get the hash from `fetchTxInfo()`.
```tsx
await provider.fetchBlockInfo('79f60880b097ec7dabb81f75f0b52fedf5e922d4f779a11c0c432dcf22c56089')
```
## Fetch Collection Assets
Fetch a list of assets belonging to a collection by providing its Policy ID.
```tsx
await provider.fetchCollectionAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527')
```
The API will return a list of `assets` and a cursor `next`. If the cursor is not null, you can use it to fetch the next page of results. Here is an example of the response.
```tsx
{
"assets": [
{
"unit": "d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527",
"quantity": "1"
},
],
"next": 2
}
```
The `fetchCollectionAssets` function also accepts an optional `cursor` parameter to fetch the next page of results. The default value is `1`.
```tsx
await fetchCollectionAssets(
policyId: string,
cursor = 1
)
```
## Fetch Handle Address
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
We can resolve the handle's address with `fetchHandleAddress`.
```tsx
// Handle: `meshsdk`
await provider.fetchHandleAddress('meshsdk')
```
## Fetch Handle
ADA Handle allows users to use a human-readable "Handle" to associate an address.
Each Handle is a unique NFT, minted and issued on the Cardano blockchain. These NFTs act as unique identifiers for the UTXO that they reside in.
ADA Handle also released a CIP68 handle and this function will fetch the metadata of the handle.
```tsx
// Handle: `meshsdk`
await provider.fetchHandle('meshsdk')
```
## Fetch Protocol Parameters
Fetch the latest protocol parameters.
```tsx
await provider.fetchProtocolParameters()
```
Optionally, you can provide an epoch number to fetch the protocol parameters of that epoch.
## Fetch Transaction Info
Fetch transaction infomation. Only confirmed transaction can be retrieved.
```tsx
await provider.fetchTxInfo('f4ec9833a3bf95403d395f699bc564938f3419537e7fb5084425d3838a4b6159')
```
## Fetch UTxOs
Get UTxOs for a given hash.
```tsx
// Hash: `dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70`
await provider.fetchUTxOs('dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70')
```
Optionally, you can specify the index of the index output.
```tsx
await provider.fetchUTxOs('hash_here', 0)
```
## Fetch Proposal Info
Get information for a given governance proposal, identified by the txHash and proposal index
```tsx
await provider.fetchGovernanceProposal('372d688faa77e146798b581b322c0f2981a9023764736ade5d12e0e4e796af8c', 0)
```
## Evaluate Transaction
`evaluateTx()` accepts an unsigned transaction (`unsignedTx`) and it evaluates the resources required to execute the transaction. Note that, this is only valid for transaction interacting with redeemer (smart contract). By knowing the budget required, you can use this to adjust the redeemer's budget so you don't spend more than you need to execute transactions for this smart contract.
```tsx
const unsignedTx = await tx.build();
const evaluateTx = await provider.evaluateTx(unsignedTx);
```
Example responses from unlocking assets from the always succeed smart contract.
```tsx
[
{
"index": 0,
"tag": "SPEND",
"budget": {
"mem": 1700,
"steps": 368100
}
}
]
```
With the `mem` and `steps`, you can refine the budget for the redeemer. For example:
```tsx
const redeemer = {
data: { alternative: 0, fields: [...] },
budget: {
mem: 1700,
steps: 368100,
},
};
```
## Submit Transaction
Submit a serialized transaction to the network.
```tsx
await provider.submitTx(signedTx);
```
## On Transaction Confirmed
Allow you to listen to a transaction confirmation. Upon confirmation, the callback will be called.
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '5000000');
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
provider.onTxConfirmed(txHash, () => {
// Transaction confirmed
});
```
## Admin Get Devnet Info
Get information about the devnet.
```tsx
await provider.getDevnetInfo()
```
Example response:
```tsx
{
"nodePort": 0,
"submitApiPort": 0,
"socketPath": "string",
"protocolMagic": 0,
"slotLength": 0,
"blockTime": 0,
"epochLength": 0,
"p2pEnabled": true,
"startTime": 0,
"masterNode": true,
"adminNodeUrl": "string",
"era": "Byron",
"genesisProfile": "zero_fee",
"ogmiosPort": 0,
"kupoPort": 0,
"yaciStorePort": 0,
"socatPort": 0,
"prometheusPort": 0,
"blockProducer": true
}
```
## Admin Get Genesis Info By Era
You can topup ADA for any address. To topup ADA in your wallet, run the following command from devnet:
```tsx
await provider.getGenesisByEra()
```
Example response:
```tsx
{
"activeSlotsCoeff": 1,
"epochLength": 500,
"genDelegs": {
"337bc5ef0f1abf205624555c13a37258c42b46b1259a6b1a6d82574e": {
"delegate": "41fd6bb31f34469320aa47cf6ccc3918e58a06d60ea1f2361efe2458",
"vrf": "7053e3ecd2b19db13e5338aa75fb518fc08b6c218f56ad65760d3eb074be95d4"
}
},
"initialFunds": {
"60ba957a0fff6816021b2afa7900beea68fd10f2d78fb5b64de0d2379c": 3000000000000000,
"007290ea8fa9433c1045a4c8473959ad608e6c03a58c7de33bdbd3ce6f295b987135610616f3c74e11c94d77b6ced5ccc93a7d719cfb135062": 300000000000,
"605276322ac7882434173dcc6441905f6737689bd309b68ad8b3614fd8": 3000000000000000,
"60a0f1aa7dca95017c11e7e373aebcf0c4568cf47ec12b94f8eb5bba8b": 3000000000000000,
"005867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e6": 1000000000
},
"maxKESEvolutions": 60,
"maxLovelaceSupply": 45000000000000000,
"networkId": "Testnet",
"networkMagic": 42,
"protocolParams": {
"a0": 0,
"decentralisationParam": 0,
"eMax": 18,
"extraEntropy": {
"tag": "NeutralNonce"
},
"keyDeposit": 2000000,
"maxBlockBodySize": 65536,
"maxBlockHeaderSize": 1100,
"maxTxSize": 16384,
"minFeeA": 0,
"minFeeB": 0,
"minPoolCost": 340000000,
"minUTxOValue": 1000000,
"nOpt": 100,
"poolDeposit": 500000000,
"protocolVersion": {
"major": 8,
"minor": 0
},
"rho": 0.003,
"tau": 0.2
},
"securityParam": 300,
"slotLength": 1,
"slotsPerKESPeriod": 129600,
"staking": {
"pools": {
"7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57": {
"cost": 340000000,
"margin": 0,
"metadata": null,
"owners": [],
"pledge": 0,
"publicKey": "7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57",
"relays": [],
"rewardAccount": {
"credential": {
"keyHash": "11a14edf73b08a0a27cb98b2c57eb37c780df18fcfcf6785ed5df84a"
},
"network": "Testnet"
},
"vrf": "c2b62ffa92ad18ffc117ea3abeb161a68885000a466f9c71db5e4731d6630061"
}
},
"stake": {
"9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e6": "7301761068762f5900bde9eb7c1c15b09840285130f5b0f53606cc57"
}
},
"systemStart": "2024-10-30T05:11:07.442512Z",
"updateQuorum": 1
}
```
## Admin Address Topup
You can topup ADA for any address. To topup ADA in your wallet, run the following command from devnet:
```tsx
await provider.addressTopup(, )
```
## Topup Address \[!toc]
Admin function to topup address with ADA
**Address**
`addr_test1qpvx....9uu0nq93swx9`
**Amount**
`20000000`
```tsx
await provider.addressTopup('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9', '20000000');
```
# Getting Started with React
URL: /react/getting-started
Frontend components for wallet connections, and useful React hooks to getting wallet states
***
title: "Getting Started with React"
description: "Frontend components for wallet connections, and useful React hooks to getting wallet states"
icon: RocketLaunchIcon
----------------------
import Link from "fumadocs-core/link";
Mesh provide a collection of useful UI components, so you can easily include web3 functionality and convenient utilities for your application.
## Setup
The fastest way to get started a new project with React is to use the Mesh-CLI, which will scaffold a new project for you. To do this, run the following:
```tsx
npx meshjs your-app-name
```
During the installation process, you will be asked to choose a template. Choose the React template. This will scaffold a new React project with Mesh pre-installed.
To manually, install the Mesh React package, run the following:
```tsx
npm install @meshsdk/react
```
Next, add the Mesh CSS to your application, doing so will apply the default styles to the components. You can add this in `/pages/_app.tsx`.
```tsx
import "@meshsdk/react/styles.css";
```
## Mesh Provider
React Context allows apps to share data across the app, and `MeshProvider` allows your app to subscribe to context changes. If you use the CLI to initialize your project, `MeshProvider` has been added in the root component. Otherwise, you can wrap `MeshProvider` at the root of your application, for example in Next.js:
```tsx
import "@meshsdk/react/styles.css";
import { MeshProvider } from "@meshsdk/react";
function MyApp({ Component, pageProps }: AppProps) {
return (
);
};
```
Now your application is ready, explore the available UI components and wallet hooks and start using them in your application.
## Connect Wallet
In order for pps to communicate with the user's wallet, we need a way to connect to their wallet.
Add this CardanoWallet to allow the user to select a wallet to connect to your app. After the wallet is connected, see Browser Wallet for a list of CIP-30 APIs.
The signature for the CardanoWallet component is as follows:
```tsx
{
label?: string;
onConnected?: Function;
isDark?: boolean;
}
```
### Customization \[!toc]
For dark mode style, add isDark.
```tsx
```
For a custom label, add the label prop.
```tsx
```
The customization is limited. For more customization, you can easily build your own wallet connection component. If you are using React, the React hooks will be useful. You may also take reference from this component.
### Persist user session \[!toc]
If you would like to save the user last connected wallet and automatically connect to it on the next visit, you can use the persist prop.
```tsx
```
### onConnected \[!toc]
If you want to run a function after the wallet is connected, you can add the onConnected prop.
```tsx
export default function Page() {
function afterConnectedWallet() {
// do something
}
return (
<>
>
);
}
```
The above code will log "Hello, World!" to the console when the wallet is connected.
### Mesh Web3 Services \[!toc]
Mesh Web3 Services streamline user onboarding and on-chain feature integration, accelerating your app's time to market.
To integrate Mesh Web3 Services, use the `web3Services` prop. The `networkId` is the network ID of the wallet you are connecting to. You may use any providers for `fetcher` and `submitter`.
```tsx
const provider = new BlockfrostProvider('');
```
### Decentralized WebRTC Wallet Communication (CIP 45) \[!toc]
CIP-45 is a communication method between pps and wallets based on WebTorrent trackers and WebRTC. Using WebTorrent trackers for the peer discovery to remove the need of this central component.
### Burner wallet \[!toc]
Burner wallets are wallets that are created on the fly on the user's device. They are temporary wallets useful for testing purposes. The private keys are generated and stored on the user's device.
```tsx
```
### MetaMask Snaps \[!toc]
MetaMask Snaps are a new way to extend MetaMask with custom functionality and integrations. You can check the implementation to integrate NuFi from the GitHub repository.
Use the `injectFn` prop to add custom functionality.
```tsx
await checkIfMetamaskInstalled("preprod")}
/>
```
### Connect Wallet Component \[!toc]
Connect to user's wallet to interact with app
```tsx
import { CardanoWallet } from '@meshsdk/react';
export default function Page() {
return (
<>
{console.log('on connected')}}
cardanoPeerConnect={{
dAppInfo: {
name: "Mesh SDK",
url: "https://meshjs.dev/",
},
announce: [
"wss://dev.btt.cf-identity-wallet.metadata.dev.cf-deployments.org",
],
}}
burnerWallet={{
networkId: 0,
provider: provider,
}}
/>
>
);
}
```
## useWallet Hook
Provide information on the current wallet's state, and functions for connecting and disconnecting user wallet.
```tsx
const { wallet, state, connected, name, connecting, connect, disconnect, error } = useWallet();
```
`wallet` is a Browser Wallet instance, which expose all CIP wallets functions from getting assets to signing tranasction.
`state`, a enum string, the state of the wallet, can be `NOT_CONNECTED`, `CONNECTING` or `CONNECTED`.
`connected`, a boolean, `true` if user's wallet is connected.
`name`, a string, the name of the connect wallet.
`connecting`, a boolean, `true` if the wallet is connecting and initializing.
`connect(walletName: string)`, a function, provide the wallet name to connect wallet. Retrive a list of available wallets with `useWalletList()`.
`disconnect()`, a function, to disconnect the connected wallet.
`error`, returns the error object if any error occurs during wallet connection, such as "account not set".
### useWallet Hook \[!toc]
Interact with user's wallet
```tsx
import { useWallet } from '@meshsdk/react';
export default function Page() {
const { wallet, state, connected, name, connecting, connect, disconnect, error } = useWallet();
return (
);
}
```
# React Components
URL: /react
Frontend React UI components and React hooks
***
title: "React Components"
description: "Frontend React UI components and React hooks"
icon: ComputerDesktopIcon
-------------------------
import {
BoltIcon,
PaintBrushIcon,
RocketLaunchIcon,
} from "@heroicons/react/24/solid";
}>
## Getting Started with React \[!toc]
Frontend components for wallet connections, and useful React hooks to getting wallet states
}>
## UI Components \[!toc]
UI components to speed up your app development.
}>
## Wallet Hooks \[!toc]
React hooks for interacting with connected wallets.
# UI Components
URL: /react/ui-components
UI components to speed up your app development.
***
title: "UI Components"
description: "UI components to speed up your app development."
icon: PaintBrushIcon
--------------------
import Link from "fumadocs-core/link";
Mesh provide a collection of useful UI components, so you can easily include web3 functionality and convenient utilities for your application.
## Connect Wallet
In order for pps to communicate with the user's wallet, we need a way to connect to their wallet.
Add this CardanoWallet to allow the user to select a wallet to connect to your app. After the wallet is connected, see Browser Wallet for a list of CIP-30 APIs.
The signature for the CardanoWallet component is as follows:
```tsx
{
label?: string;
onConnected?: Function;
isDark?: boolean;
}
```
### Customization \[!toc]
For dark mode style, add isDark.
```tsx
```
For a custom label, add the label prop.
```tsx
```
The customization is limited. For more customization, you can easily build your own wallet connection component. If you are using React, the React hooks will be useful. You may also take reference from this component.
### Persist user session \[!toc]
If you would like to save the user last connected wallet and automatically connect to it on the next visit, you can use the persist prop.
```tsx
```
### onConnected \[!toc]
If you want to run a function after the wallet is connected, you can add the onConnected prop.
```tsx
export default function Page() {
function afterConnectedWallet() {
// do something
}
return (
<>
>
);
}
```
The above code will log "Hello, World!" to the console when the wallet is connected.
### Mesh Web3 Services \[!toc]
Mesh Web3 Services streamline user onboarding and on-chain feature integration, accelerating your app's time to market.
To integrate Mesh Web3 Services, use the `web3Services` prop. The `networkId` is the network ID of the wallet you are connecting to. You may use any providers for `fetcher` and `submitter`.
```tsx
const provider = new BlockfrostProvider('');
```
### Decentralized WebRTC Wallet Communication (CIP 45) \[!toc]
CIP-45 is a communication method between pps and wallets based on WebTorrent trackers and WebRTC. Using WebTorrent trackers for the peer discovery to remove the need of this central component.
### Burner wallet \[!toc]
Burner wallets are wallets that are created on the fly on the user's device. They are temporary wallets useful for testing purposes. The private keys are generated and stored on the user's device.
```tsx
```
### MetaMask Snaps \[!toc]
MetaMask Snaps are a new way to extend MetaMask with custom functionality and integrations. You can check the implementation to integrate NuFi from the GitHub repository.
Use the `injectFn` prop to add custom functionality.
```tsx
await checkIfMetamaskInstalled("preprod")}
/>
```
### Connect Wallet Component \[!toc]
Connect to user's wallet to interact with app
```tsx
import { CardanoWallet } from '@meshsdk/react';
export default function Page() {
return (
<>
{console.log('on connected')}}
cardanoPeerConnect={{
dAppInfo: {
name: "Mesh SDK",
url: "https://meshjs.dev/",
},
announce: [
"wss://dev.btt.cf-identity-wallet.metadata.dev.cf-deployments.org",
],
}}
burnerWallet={{
networkId: 0,
provider: provider,
}}
/>
>
);
}
```
## Powered by Mesh Badge
If you love Mesh, here's a beautifully designed badge for you to embed in your application.
```tsx
```
### Mesh Badge Component \[!toc]
Show your support for Mesh
```tsx
import { CardanoWallet } from '@meshsdk/react';
export default function Page() {
return (
<>
>
);
}
```
# Wallet Hooks
URL: /react/wallet-hooks
React hooks for interacting with connected wallets.
***
title: "Wallet Hooks"
description: "React hooks for interacting with connected wallets."
icon: BoltIcon
--------------
import Link from "fumadocs-core/link";
React Hooks allow function components to have access to state and other React features. With Mesh Hooks, you can easily interact and access wallet data.
## useWallet Hook
Provide information on the current wallet's state, and functions for connecting and disconnecting user wallet.
```tsx
const { wallet, state, connected, name, connecting, connect, disconnect, error } = useWallet();
```
`wallet` is a Browser Wallet instance, which expose all CIP wallets functions from getting assets to signing tranasction.
`state`, a enum string, the state of the wallet, can be `NOT_CONNECTED`, `CONNECTING` or `CONNECTED`.
`connected`, a boolean, `true` if user's wallet is connected.
`name`, a string, the name of the connect wallet.
`connecting`, a boolean, `true` if the wallet is connecting and initializing.
`connect(walletName: string)`, a function, provide the wallet name to connect wallet. Retrive a list of available wallets with `useWalletList()`.
`disconnect()`, a function, to disconnect the connected wallet.
`error`, returns the error object if any error occurs during wallet connection, such as "account not set".
### useWallet Hook \[!toc]
Interact with user's wallet
```tsx
import { useWallet } from '@meshsdk/react';
export default function Page() {
const { wallet, state, connected, name, connecting, connect, disconnect, error } = useWallet();
return (
);
}
```
## useWalletList Hook
Returns a list of wallets installed on user's device.
```tsx
const wallets = useWalletList();
```
You can define a function to be injected into the wallet provider by passing it as the `injectFn` prop.
```tsx
const wallets = useWalletList({injectFn={async () => await checkIfMetamaskInstalled("preprod")})}
```
### useWalletList Hook \[!toc]
List of wallets installed on user's device
```tsx
const wallets = useWalletList();
```
```tsx
[]
```
```tsx
import { useWalletList } from '@meshsdk/react';
export default function Page() {
const wallets = useWalletList();
return (
<>
{wallets.map((wallet, i) => {
return (
{wallet.name}
);
})}
>
);
}
```
## useAddress Hook
Return address of connected wallet.
`accountId` is an optional parameter, that allows you to choose which address to return.
```tsx
const address = useAddress(accountId = 0);
```
### useAddress Hook \[!toc]
List of wallets installed on user's device
```tsx
import { useAddress } from '@meshsdk/react';
const address = useAddress();
Your wallet address is: {address}
```
## useAssets Hook
Return a list of assets in connected wallet from all UTXOs.
```tsx
const assets = useAssets();
```
### useAssets Hook \[!toc]
List assets of connected wallet
```tsx
import { useAssets } from '@meshsdk/react';
const assets = useAssets();
{JSON.stringify(assets, null, 2)}
```
## useLovelace Hook
Return amount of lovelace in wallet.
```tsx
const lovelace = useLovelace();
```
### useLovelace Hook \[!toc]
Fetch the lovelace balance of the connected wallet
```tsx
import { useLovelace } from '@meshsdk/react';
const lovelace = useLovelace();
Your lovelace balance is: {lovelace}
```
## useNetwork Hook
Return the network of connected wallet.
```tsx
const network = useNetwork();
```
### useNetwork Hook \[!toc]
Fetch the network of the connected wallet
```tsx
import { useNetwork } from '@meshsdk/react';
const network = useNetwork();
Connected network: {network}.
```
# Content Ownership
URL: /smart-contracts/content-ownership
Manage ownership of digital content and assets
***
title: "Content Ownership"
description: "Manage ownership of digital content and assets"
icon: DocumentCheckIcon
-----------------------
import Link from "fumadocs-core/link";
This contract allows you to create a content registry and users can create content that is stored in the registry.
It facilitates on-chain record of content (i.e. file on IPFS) ownership and transfer. While one cannot prefer others from obtaining a copy of the content, the app owner of the contract can serve the single source of truth of who owns the content. With the blockchain trace and record in place, it provides a trustless way to verify the ownership of the content and facilitates further application logics such as royalties, licensing, etc.
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the contract \[!toc]
To initialize the contract, we need to initialize a provider, `MeshTxBuilder` and `MeshContentOwnershipContract`.
```tsx
import { MeshContentOwnershipContract } from "@meshsdk/contract";
import { MeshTxBuilder, BlockfrostProvider } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshContentOwnershipContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
{
operationAddress: operationAddress, // the address of the app owner, where most of the actions should be signed by the spending key of this address
paramUtxo: { outputIndex: 0, txHash: "0000000000000000000000000000000000000000000000000000000000000000" }, // you can get this from the output of mintOneTimeMintingPolicy() transaction
refScriptUtxos?: { // you can get these from the output of sendRefScriptOnchain() transactions
contentRegistry: { outputIndex: 0, txHash: "0000000000000000000000000000000000000000000000000000000000000000" },
contentRefToken: { outputIndex: 0, txHash: "0000000000000000000000000000000000000000000000000000000000000000" },
ownershipRegistry: { outputIndex: 0, txHash: "0000000000000000000000000000000000000000000000000000000000000000" },
ownershipRefToken: { outputIndex: 0, txHash: "0000000000000000000000000000000000000000000000000000000000000000" },
},
},
);
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Mint One Time Minting Policy
This is the first transaction you need to setup the contract.
This transaction mints the one-time minting policy (a NFT) for the contract.
It will be attached with the datum which serves as the single source of truth for the contract oracle.
Note: You must save the `paramUtxo` for future transactions.
### Mint One Time Minting Policy \[!toc]
This transaction mints the one-time minting policy (a NFT) for the contract.
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
```tsx
const { tx, paramUtxo } = await contract.mintOneTimeMintingPolicy();
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Setup Oracle Utxo
This transaction send the NFT to a oracle contract locking the datum, which serves as the single source of truth for the contract oracle with data integrity.
This is the second transaction you need to setup the contract.
Note: You must provide the `paramUtxo` from the `mintOneTimeMintingPolicy` transaction.
### Setup Oracle Utxo \[!toc]
This transaction send the NFT to a oracle contract locking the datum.
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Param UTxO**
`{"outputIndex":0,"txHash":"2aba4d6705cfe6405cf02...f3f8bded3df2359"}`
```tsx
const tx = await contract.setupOracleUtxo();
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Send Ref-Script Onchain
This are the next transactions you need to setup the contract. You need to run once for each script, and you would likely have to run one after the previous one is confirmed.
This transaction sends the reference scripts to the blockchain for later transactions, boosting efficiency and avoid exceeding 16kb of transaction size limits enforced by protocol parameter.
Note: You must provide the `paramUtxo` from the `mintOneTimeMintingPolicy` transaction.
Note: You must save txHash (after signed and submitted) for `ContentRegistry`, `ContentRefToken`, `OwnershipRegistry`,`OwnershipRefToken` transactions for future transactions.
### Send Ref-Script Onchain \[!toc]
This transaction sends the reference scripts to the blockchain for later transactions.
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Param UTxO**
`{"outputIndex":0,"txHash":"2aba4d6705cfe6405cf02...f3f8bded3df2359"}`
**Select script index**
`OracleNFT`
```tsx
const tx = await contract.sendRefScriptOnchain('OracleNFT');
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Create Content Registry
This is the next transaction you need to setup the contract after completing all the `sendRefScriptOnchain` transactions.
This transaction creates one content registry. Each registry should comes in pair with one ownership registry and each pair of registry serves around 50 records of content ownership. The application can be scaled indefinitely according to the number of parallelization needed and volumes of content expected to be managed.
Note: You must provide the `paramUtxo` from the `mintOneTimeMintingPolicy` transaction.
Note: You must provide the txHash `forContentRegistry`, `ContentRefToken`, `OwnershipRegistry`, `OwnershipRefToken` transactions.
### Create Ownership Registry \[!toc]
This transaction creates one content registry
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Param UTxO**
`{"outputIndex":0,"txHash":"2aba4d6705cfe6405cf02...f3f8bded3df2359"}`
**Content Registry Tx Hash**
`dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70`
**Content Ref Token Tx Hash**
`8f731be135171df172c07578a5d74589ec8fb30b37c12fdbe2639d69b7587f5e`
**Ownership Registry Tx Hash**
`ec874b61eec4e5e8e395dead6c9bb18690e6d6ea64d773760c5e654ec9ff5f97`
**Ownership Ref Token Tx Hash**
`e1bdfc7ae6929f934cf9d418273dde143cbb65ec0eec23bdb6c342e4cd91dbd0`
```tsx
const tx = await contract.createContentRegistry();
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Create Ownership Registry
This is the last transaction you need to setup the contract after completing all the `sendRefScriptOnchain` transactions.
This transaction creates one content registry. Each registry should comes in pair with one content registry and each pair of registry serves around 50 records of content ownership. The application can be scaled indefinitely according to the number of parallelization needed and volumes of content expected to be managed.
**Note**: You must provide the `paramUtxo` from the `mintOneTimeMintingPolicy` transaction.
**Note**: You must provide the txHash for `ContentRegistry`, `ContentRefToken`, `OwnershipRegistry`,`OwnershipRefToken` transactions.
### Create Ownership Registry \[!toc]
This transaction creates one content registry
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Param UTxO**
`{"outputIndex":0,"txHash":"2aba4d6705cfe6405cf02e4e2c8b7...ed3df2359"}`
**Content Registry Tx Hash**
`dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70`
**Content Ref Token Tx Hash**
`8f731be135171df172c07578a5d74589ec8fb30b37c12fdbe2639d69b7587f5e
`
**Ownership Registry Tx Hash**
`ec874b61eec4e5e8e395dead6c9bb18690e6d6ea64d773760c5e654ec9ff5f97`
**Ownership Ref Token Tx Hash**
`e1bdfc7ae6929f934cf9d418273dde143cbb65ec0eec23bdb6c342e4cd91dbd0`
```tsx
const tx = await contract.createOwnershipRegistry();
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Get Oracle Data
Getting the oracle data is essential to fetch the current state of the registry.
To facilitate this process, you must provide the `paramUtxo` that contains the output index and transaction hash of the NFT minting policy.
The `getOracleData()` function will return the current oracle data.
```tsx
const oracleData = await contract.getOracleData();
```
For example:
```tsx
{
"contentNumber": 2,
"ownershipNumber": 2
}
```
## Mint User Token
This transaction mints a token that users can use to create content.
Note that you can actually use any tokens for `createContent()`, this `mintUserToken()` function is just helpful if you want to mint a token specifically for this purpose.
Note that you signTx with `true` to mint the token to enable partial signing.
### Mint User Token \[!toc]
Mint a token that users can use to create content
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Param UTxO**
`{"outputIndex":0,"txHash":"2aba4d6705cfe6405cf02e4e2c8b7...ed3df2359"}`
```tsx
const tx = await contract.mintUserToken("MeshContentOwnership", {
name: "Mesh Content Ownership",
description: "Demo at https://meshjs.dev/smart-contracts/content-ownership",
});
const signedTx = await wallet.signTx(tx, true);
const txHash = await wallet.submitTx(signedTx);
```
## Create Content
This transaction creates a content attached to the registry reference by a token. You can use any token for `ownerAssetHex` and the `contentHashHex` is a string to identify the content.
**Note**: You must provide the `paramUtxo` from the `mintOneTimeMintingPolicy` transaction.
**Note**: You must provide the txHash for `ContentRegistry`, `ContentRefToken`, `OwnershipRegistry`,`OwnershipRefToken` transactions.
### Create Content \[!toc]
For users to create a content attached to the registry reference by a token
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Param UTxO**
`{"outputIndex":0,"txHash":"2aba4d6705cfe6405cf02e4e2c8b7...ed3df2359"}`
**Content Registry Tx Hash**
`dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70`
**Content Ref Token Tx Hash**
`8f731be135171df172c07578a5d74589ec8fb30b37c12fdbe2639d69b7587f5e
`
**Ownership Registry Tx Hash**
`ec874b61eec4e5e8e395dead6c9bb18690e6d6ea64d773760c5e654ec9ff5f97`
**Ownership Ref Token Tx Hash**
`e1bdfc7ae6929f934cf9d418273dde143cbb65ec0eec23bdb6c342e4cd91dbd0`
```tsx
const asset = demoAsset;
const contentHashHex = "ipfs://contentHashHex";
const registryNumber = 0;
const tx = await contract.createContent(
asset,
contentHashHex,
registryNumber,
);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Get Content
This transaction fetches the content data from the registry.
### Get Oracle Data \[!toc]
Fetch the current oracle data
**Operation address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Param UTxO**
`{"outputIndex":0,"txHash":"2aba4d6705cfe6405cf02e4e2c8b7...ed3df2359"}`
**Content Registry Tx Hash**
`dfd2a2616e6154a092807b1ceebb9ddcadc0f22cf5c8e0e6b0757815083ccb70`
**Content Ref Token Tx Hash**
`8f731be135171df172c07578a5d74589ec8fb30b37c12fdbe2639d69b7587f5e
`
**Ownership Registry Tx Hash**
`ec874b61eec4e5e8e395dead6c9bb18690e6d6ea64d773760c5e654ec9ff5f97`
**Ownership Ref Token Tx Hash**
`e1bdfc7ae6929f934cf9d418273dde143cbb65ec0eec23bdb6c342e4cd91dbd0`
```tsx
const content = await contract.getContent(0, 0);
```
# Escrow
URL: /smart-contracts/escrow
Secure exchange of assets between two parties
***
title: "Escrow"
description: "Secure exchange of assets between two parties"
icon: ArrowsRightLeftIcon
-------------------------
import Link from "fumadocs-core/link";
The escrow smart contract allows two parties to exchange assets securely. The contract holds the assets until both parties agree and sign off on the transaction.
There are 4 actions available to interact with this smart contract:
* initiate escrow and deposit assets
* deposit assets
* complete escrow
* cancel escrow
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the contract \[!toc]
To initialize the escrow, we need to initialize a provider, `MeshTxBuilder` and `MeshEscrowContract`.
```tsx
import { MeshEscrowContract } from "@meshsdk/contract";
import { MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshEscrowContract({
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
});
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Initiate Escrow
An escrow is initiated by one of the party, user A, by locking assets to the escrow contract.
`initiateEscrow()` initiate an escrow. The function accepts the following parameters:
* escrowAmount (Asset\[]) - a list of assets user A is trading
The function returns a transaction hex if the escrow is successfully initiated.
### Initiate Escrow \[!toc]
Initiate an escrow, in this demo, person A is initiating the escrow and deposit ADA.
**Listing price in Lovelace** `10000000`
```tsx
const escrowAmount: Asset[] = [
{
unit: "lovelace",
quantity: '10000000',
},
];
const tx = await contract.initiateEscrow(escrowAmount);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Recipient Deposit
User B can deposit assets into the escrow after initiation step (`initiateEscrow()`).
`recipientDeposit()` deposit assets into the escrow. The function accepts the following parameters:
* escrowUtxo (UTxO) - the utxo of the transaction on the contract
* depositAmount (Asset\[]) - a list of assets user B is trading
We have provided a very handle function, `getUtxoByTxHash`, which will return the UTxO object for a given transaction hash.
### Recipient Deposit \[!toc]
Deposit funds into the escrow for trade. In this demo, person B is depositing an asset into the escrow.
**Tx hash:** `Tx hash`
**Asset unit**
`d9312da562da182b02322fd8acb536f37eb9d29fba7...68546f6b656e`
```tsx
const utxo = await contract.getUtxoByTxHash('');const escrowAmount: Asset[] = [
{
unit: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e',
quantity: '1',
},
];
const tx = await contract.initiateEscrow(escrowAmount);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Complete Escrow
A user can complete an escrow if the terms of the agreement are met. The completion can be initiated by any recipient of the escrow.
`completeEscrow()` complete an escrow. The function accepts the following parameters:
* escrowUtxo (UTxO) - the utxo of the transaction in the script to be completed
**Important**: This is a multi-signature transaction. Both users must sign the transaction to complete the escrow.
A successful completion of the escrow will result in the assets being swapped between the two parties.
### Person A signs the transaction \[!toc]
User A completes the escrow by calling the `completeEscrow()` function and partial sign the transaction.
**Tx hash:** `Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.completeEscrow(utxo);
const signedTxUserA = await wallet.signTx(tx, true);
```
### Person B signs and submits the transaction \[!toc]
The signed transaction will be handled to User B to sign the transaction and submits it to the blockchain to complete the escrow.
**Tx hash:** `Tx hash`
**Transaction CBOR** `Transaction CBOR`
```tsx
const signedTxUserB = await wallet.signTx(signedTxUserA, true);
const txHash = await wallet.submitTx(signedTxUserB);
```
## Cancel Escrow
A user can cancel an escrow if the other party fails to fulfill the terms of the agreement. Cancel can be initiated by any users who have partcipated in the escrow and can be done at any time before complete. Canceling the escrow will return the assets to the respective users.
`cancelEscrow()` cancel an escrow. The function accepts the following parameters:
* escrowUtxo (UTxO) - the utxo of the transaction to be canceled
We have provided a very handle function, `getUtxoByTxHash`, which will return the UTxO object for a given transaction hash.
### Cancel Escrow \[!toc]
Any users who have partcipated in the escrow and can cancel the trade at any time before complete.
**Tx hash:** `Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.cancelEscrow(utxo);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
# GiftCard
URL: /smart-contracts/giftcard
Create a giftcard with native tokens
***
title: "GiftCard"
description: "Create a giftcard with native tokens"
icon: GiftIcon
--------------
import Link from "fumadocs-core/link";
Giftcard contract allows users to create a transactions to lock assets into the smart contract, which can be redeemed by any user.
Creating a giftcard will mint a token and send the assets to the contract. While redeeming will burn the token and send the assets to the redeemer.
There are 2 actions (or endpoints) available to interact with this smart contract:
* create giftcard
* redeem giftcard
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the contract \[!toc]
To initialize the contract, we need to initialize a provider, `MeshTxBuilder` and `MeshGiftCardContract`.
```tsx
import { MeshGiftCardContract } from "@meshsdk/contract";
import { MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshGiftCardContract({
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
});
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Create Giftcard
`createGiftCard()` create a gift card. The function accepts the following parameters:
* tokenName (string) - name of the token
* giftValue (Asset\[]) - a list of assets
The function returns a transaction hash if the gift card is successfully created.
The function returns a transaction hex if giftcard has been created successfully.
### Create Giftcard \[!toc]
Create a gift card with a given amount of lovelace
**Gitfcard amount** `10000000`
**Giftcard name** `Mesh_Gift_Card`
```tsx
const giftValue: Asset[] = [
{
unit: "lovelace",
quantity: '10000000',
},
];
const tx = await contract.createGiftCard('Mesh_Gift_Card', giftValue);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Redeem Giftcard
`redeemGiftCard()` redeem a gift card. The function accepts the following parameters:
* giftCardUtxo (UTxO) - unspent transaction output in the script
The function returns a transaction hash if the gift card is successfully redeemed. It will burn the gift card and transfer the value to the wallet signing this transaction.
The function returns a transaction hex if the gift card has been redeemed successfully.
We have provided a very handle function, `getUtxoByTxHash`, which will return the UTxO object for a given transaction hash. You can always create another function that searches by token name.
A successful redemption will send the value to the wallet that signed the transaction to redeem the gift card.
### Redeem Giftcard \[!toc]
Redeem a gift card given the gift card UTxO
**Tx hash** `Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.redeemGiftCard(utxo);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
# Hello World
URL: /smart-contracts/hello-world
Simple lock and unlock assets contract
***
title: "Hello World"
description: "Simple lock and unlock assets contract"
icon: PlayIcon
--------------
import Link from "fumadocs-core/link";
The Hello World smart contract is a simple lock-and-unlock assets contract, providing a hands-on introduction to end-to-end smart contract validation and transaction building.
There are 2 conditions to unlock the assets:
* Signer must be the same as the one who locked the assets
* Signer must provide the message `Hello, World!`
There are 2 actions (or endpoints) available to interact with this smart contract:
* Lock assets
* Redeem assets
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the contract \[!toc]
To initialize the contract, we need to initialize a provider, `MeshTxBuilder` and `MeshGiftCardContract`.
```tsx
import { MeshHelloWorldContract } from "@meshsdk/contract";
import { MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshHelloWorldContract({
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
});
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Lock Assets
This transaction locks funds into the contract.
The datum must match the representation expected by the validator (and as specified in the blueprint), so this is a constructor with a single field that is a byte array.
```tsx
pub type Datum {
owner: VerificationKeyHash,
}
```
Thus, we provide a hash digest of our public key, which will be needed to unlock the funds.
```tsx
await txBuilder
.txOut(scriptAddress, assets)
.txOutDatumHashValue(mConStr0([signerHash]))
.changeAddress(walletAddress)
.selectUtxosFrom(utxos)
.complete();
```
### Lock Asset \[!toc]
Lock asset in the contract
**Lovelace amount**
`5000000`
```tsx
const assets: Asset[] = [
{
unit: "lovelace",
quantity: '5000000',
},
];
const tx = await contract.lockAsset(assets);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Unlock Assets
There are 2 conditions to unlock the assets:
* Signer must be the same as the one who locked the assets
* Signer must provide the message `Hello, World!`
The validator script for the contract checks that the redeemer is the same as the owner of the datum and that the message is `Hello, World!`:
```tsx
validator hello_world {
spend(
datum_opt: Option,
redeemer: Redeemer,
_input: OutputReference,
tx: Transaction,
) {
expect Some(datum) = datum_opt
let must_say_hello = redeemer.msg == "Hello, World!"
let must_be_signed = list.has(tx.extra_signatories, datum.owner)
must_say_hello && must_be_signed
}
else(_) {
fail
}
}
```
### Redeem Giftcard \[!toc]
Redeem a gift card given the gift card UTxO
**Tx hash**
`Tx hash`
**Message**
`Hello, World!`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.unlockAsset(utxo, 'Hello, World!');
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
# Smart Contracts
URL: /smart-contracts
Open-source smart contracts, complete with documentation, and live demos
***
title: "Smart Contracts"
description: "Open-source smart contracts, complete with documentation, and live demos"
icon: DocumentCheckIcon
-----------------------
import {
ArrowsPointingOutIcon,
ArrowsRightLeftIcon,
DocumentCheckIcon,
GiftIcon,
LockClosedIcon,
PhotoIcon,
PlayIcon,
ShoppingCartIcon,
} from "@heroicons/react/24/solid";
}>
## Content Ownership
Manage ownership of digital content and assets
}>
## Escrow
Secure exchange of assets between two parties
}>
## Giftcard
Create a giftcard with native tokens
}>
## Hello World
Simple lock and unlock assets contract
}>
## Marketplace
Build a NFT marketplace to buy and sell NFTs
}>
## NFT Minting Machine
Mint NFT that ensure the token name is incremented by a counter
}>
## Payment Splitter
Split payouts equally among a list of specified payees
}>
## Swap
Swap contract facilitates the exchange of assets between two parties
}>
## Vesting
Locks up funds and allows the beneficiary to withdraw the funds after the lockup period
# Marketplace
URL: /smart-contracts/marketplace
Build a NFT marketplace to buy and sell NFTs
***
title: "Marketplace"
description: "Build a NFT marketplace to buy and sell NFTs"
icon: ShoppingCartIcon
----------------------
import Link from "fumadocs-core/link";
The marketplace smart contract allows users to buy and sell NFTs. A seller list an NFT for sales by specifying a certain price, and anyone can buy it by paying the demanded price.
There are 4 actions (or endpoints) available to interact with this smart contract:
* list asset
* buy asset
* updating listing
* cancel listing
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the Marketplace \[!toc]
Utilizing the Marketplace contract requires a blockchain provider and a connected browser wallet. Here is an example how we can initialize the Marketplace.
```tsx
import { MeshMarketplaceContract } from "@meshsdk/contract";
import { MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshMarketplaceContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr',
200, // 2% fee
);
```
To initialize the Marketplace, we import the `MeshMarketplaceContract`. The first JSON object is the `inputs` for the `MeshTxInitiatorInput`, this requires a `MeshTxBuilder`, a `Provider`, a `Wallet`, and define the network ID.
Second and third parameters are the `ownerAddress` and `feePercentageBasisPoint`. The `ownerAddress` is the address of the marketplace owner which will receive the marketplace fee. The `feePercentageBasisPoint` is the percentage of the sale price that the marketplace `owner` will take. The fee numerator is in the order of hundreds, for example `200` implies a fee of `2%`.
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## List Asset
List an asset on the marketplace. This will allow other users to buy the asset. The seller will receive the listing price in ADA. The seller can cancel the listing at any time. The seller can also update the listing price at any time.
`listAsset()` list an asset for sale. The function accepts the following parameters:
* asset (string) - the asset's unit to be listed
* price (number) - the listing price in Lovelace
### List Asset \[!toc]
List an asset for sale
**Listing price in Lovelace** `10000000`
**Asset unit**
`d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
```tsx
const tx = await contract.listAsset('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e', 10000000);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Buy Asset
Purchase a listed asset from the marketplace. The seller will receive the listed price in ADA and the buyer will receive the asset. The marketplace owner will receive a fee if it is specified.
`purchaseAsset()` purchase a listed asset. The function accepts the following parameters:
* utxo (UTxO) - unspent transaction output in the script
We have provided a very handle function, `getUtxoByTxHash`, which will return the UTxO object for a given transaction hash.
A successful purchase will send the asset to the wallet that signed the transaction to purchase the asset.
### Buy Asset \[!toc]
Purchase a listed asset from the marketplace
**Tx hash**
`Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.purchaseAsset(utxo);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Update Listing
Update a listing on the marketplace. For the contract, the seller can update the listing price.
`relistAsset()` update a listing on the marketplace. The function accepts the following parameters:
* utxo (UTxO) - unspent transaction output in the script
* newListPrice (number) - the new listing price in Lovelace
We have provided a very handle function, `getUtxoByTxHash`, which will return the UTxO object for a given transaction hash.
### Update Listing \[!toc]
Update the listing price of an asset on the marketplace
**Tx hash**
`Tx hash`
**New listing price in Lovelace**
`20000000`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.relistAsset(utxo, 20000000);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Cancel Listing
Cancel a listing on the marketplace. The seller can cancel the listing at any time. The seller will receive the listed asset back.
`delistAsset()` cancel a listing on the marketplace. The function accepts the following parameters:
* utxo (UTxO) - unspent transaction output in the script
We have provided a very handle function, `getUtxoByTxHash`, which will return the UTxO object for a given transaction hash.
### Cancel Listing \[!toc]
Cancel a listing on the marketplace
**Tx hash**
`Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.delistAsset(utxo);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
# Payment Splitter
URL: /smart-contracts/payment-splitter
Split payouts equally among a list of specified payees
***
title: "Payment Splitter"
description: "Split payouts equally among a list of specified payees"
icon: ArrowsPointingOutIcon
---------------------------
import Link from "fumadocs-core/link";
A payment splitter can be used for example to create a shared project donation address, ensuring that all payees receive the same amount
Sending lovelace to the contract works similarly to sending lovelace to any other address. The payout transaction can only be submitted by one of the payees, and the output addresses are restricted to the payees. The output sum must be equally divided to ensure the transaction is successful.
There are 2 actions (or endpoints) available to interact with this smart contract:
* Send Lovelace to Payment Splitter
* Trigger Payout
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the contract \[!toc]
To initialize the payment splitter, we need to initialize a provider, a `MeshTxBuilder`, and a `MeshPaymentSplitterContract`. Additionally, a list of payees is required to define the allowed payout addresses for the contract.
```tsx
import { MeshPaymentSplitterContract } from "@meshsdk/contract";
import { MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshPaymentSplitterContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
[
'addr_test1vpg334d6skwu6xxq0r4lqrnsjd5293n8s3d80em60kf6guc7afx8k',
'addr_test1vp4l2kk0encl7t7972ngepgm0044fu8695prkgh5vjj5l6sxu0l3p',
'addr_test1vqqnfs2vt42nq4htq460wd6gjxaj05jg9vzg76ur6ws4sngs55pwr',
'addr_test1vqv2qhqddxmf87pzky2nkd9wm4y5599mhp62mu4atuss5dgdja5pw',
]
);
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Send Lovelace to Payment Splitter
`sendLovelaceToSplitter()` will lock Lovelace in the contract. The function accepts the following parameters:
* lovelaceAmount (number) - the amount of Lovelace you want to send to the contract
The function returns a transaction hash.
### Send Lovelace to Payment Splitter \[!toc]
Send Lovelace to the Payment Splitter contract to be distributed to the beneficiaries.
**Listing price in Lovelace**
`15000000`
```tsx
const tx = await contract.sendLovelaceToSplitter(15000000);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Trigger Payout
`triggerPayout()` will split the locked amount equally among the list of payees. The function doesn't need any parameters.
The function returns a transaction hash if the payout has been done successfully.
### Trigger Payout \[!toc]
After the amount has been locked in the contract, you can trigger the payout to the payees.
```tsx
const tx = await contract.triggerPayout();
const signedTx = await wallet.signTx(tx, true);
const txHash = await wallet.submitTx(signedTx);
```
# NFT Minting Machine
URL: /smart-contracts/plutus-nft
Mint NFT that ensure the token name is incremented by a counter
***
title: "NFT Minting Machine"
description: "Mint NFT that ensure the token name is incremented by a counter"
icon: PhotoIcon
---------------
import Link from "fumadocs-core/link";
This NFT minting script enables users to mint NFTs with an automatically incremented index, which increases by one for each newly minted NFT.
To facilitate this process, the first step is to set up a one-time minting policy by minting an oracle token. This oracle token is essential as it holds the current state and index of the NFTs, acting as a reference for the minting sequence.
With each new NFT minted, the token index within the oracle is incremented by one, ensuring a consistent and orderly progression in the numbering of the NFTs.
There are 3 actions available to interact with this smart contract:
* **Setup Oracle:** Mint one-time minting policy to set up the oracle
* **Mint Token:** Mint NFT that ensures the token name is incremented by a counter
* **Get Oracle Data:** Fetch the current oracle data to get the current NFT index and other information
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Setup Oracle
First, we need to set up a one-time minting policy by minting an oracle token. This oracle token is essential as it holds the current state and index of the NFTs, acting as a reference for the minting sequence.
We need to provide 2 parameters to setup the oracle, the price of the NFT in lovelace and the collection name. The collection name is used when initializing `MeshPlutusNFTContract` which is used to derive the script CBOR. The price of the NFT in lovelace is used in `setupOracle()` function which will be added into the oracle token.
```tsx
const contract = new MeshPlutusNFTContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
{
collectionName: 'collectionName', // your nft collection name
},
);
const { tx, paramUtxo } = await contract.setupOracle(15000000); // price in lovelace
```
The `setupOracle()` function will return a transaction CBOR and a `paramUtxo`. The `paramUtxo` will be used in the minting transaction of the NFT, so it is important to store it. Here is an example of the `paramUtxo`:
```tsx
{
"outputIndex": 0,
"txHash": "63dbd563ee9979574401599a42841e0d5b63a691af95df863cbf37d5cb44a558"
}
```
The transaction CBOR can be signed and submitted using the following code:
```tsx
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
### Setup Oracle \[!toc]
Mint one time minting policy to set up the oracle
**NFT Price in Lovelace**
`10000000`
**Collection Name**
`mesh`
```tsx
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
verbose: true,
});
const contract = new MeshPlutusNFTContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
{
collectionName: 'mesh',
},
);
const { tx, paramUtxo } = await contract.setupOracle(10000000);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Mint Token
This NFT minting script enables users to mint NFTs with an automatically incremented index, which increases by one for each newly minted NFT.
To facilitate this process, you must provide the `paramUtxo` that contains the output index and transaction hash of the NFT minting policy.
```tsx
const contract = new MeshPlutusNFTContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
{
collectionName: 'collectionName',
paramUtxo: {"outputIndex":0,"txHash":"63dbd563ee9979574401599a42841e0d5b63a691af95df863cbf37d5cb44a558"},
},
);
```
The `mintPlutusNFT()` function mints an NFT with asset metadata, which is a JSON object containing the NFT metadata. You can use the `getOracleData()` function to fetch the oracle data, which includes the current NFT index. This index will be helpful if you need to define the NFT name and its metadata. Here is an example of the how we can define the asset metadata:
```tsx
const oracleData = await contract.getOracleData();
const assetMetadata = {
...demoAssetMetadata,
name: `Mesh Token ${oracleData.nftIndex}`,
};
```
The `mintPlutusNFT()` function will return a transaction object that can be signed and submitted using the following code:
```tsx
const tx = await contract.mintPlutusNFT(assetMetadata);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
### Mint Token \[!toc]
Mint an NFT with asset metadata
**Collection Name**
`mesh`
**Param UTxO**
`{"outputIndex":0,"txHash":"63dbd563ee9979574401599a...37d5cb44a558"}`
```tsx
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
verbose: true,
});
const contract = new MeshPlutusNFTContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
{
collectionName: 'mesh',
paramUtxo: {"outputIndex":0,"txHash":"63dbd563ee9979574401599a42841e0d5b63a691af95df863cbf37d5cb44a558"},
},
);
// Get Oracle Data
const oracleData = await contract.getOracleData(); // see getOracleData()
// define your NFT metadata here
const assetMetadata = {
...demoAssetMetadata,
name: `Mesh Token ${oracleData.nftIndex}`,
};
const tx = await contract.mintPlutusNFT(assetMetadata);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Get Oracle Data
Getting the oracle data is essential to fetch the current NFT index.
To facilitate this process, you must provide the `paramUtxo` that contains the output index and transaction hash of the NFT minting policy.
```tsx
const contract = new MeshPlutusNFTContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
{
collectionName: 'collectionName',
paramUtxo: {"outputIndex":0,"txHash":"63dbd563ee9979574401599a42841e0d5b63a691af95df863cbf37d5cb44a558"},
},
);
```
The `getOracleData()` function will return the current oracle data.
```tsx
const oracleData = await contract.getOracleData();
```
### Get Oracle Data \[!toc]
Fetch the current oracle data to get the current NFT index and other information
**Collection Name**
`mesh`
**Param UTxO**
`{"outputIndex":0,"txHash":"63dbd563ee9979574401599a...37d5cb44a558"}`
```tsx
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
verbose: true,
});
const contract = new MeshPlutusNFTContract(
{
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
},
{
collectionName: 'mesh',
paramUtxo: {"outputIndex":0,"txHash":"63dbd563ee9979574401599a42841e0d5b63a691af95df863cbf37d5cb44a558"},
},
);
// Get Oracle Data
const oracleData = await contract.getOracleData();
```
# Swap
URL: /smart-contracts/swap
Swap contract facilitates the exchange of assets between two parties
***
title: "Swap"
description: "Swap contract facilitates the exchange of assets between two parties"
icon: ArrowsRightLeftIcon
-------------------------
import Link from "fumadocs-core/link";
Swap contract facilitates the exchange of assets between two parties. This contract is designed to be used in a peer-to-peer exchange scenario where two parties agree to exchange assets. The contract ensures that the assets are locked up until it is accepted by the other party. At any point before it is accepted, one can cancel the swap to retrieve the assets.
There are 2 actions (or endpoints) available to interact with this smart contract:
* initiate swap
* accept asset
* cancel swap
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the contract \[!toc]
To initialize the payment splitter, we need to initialize a provider, `MeshTxBuilder` and `MeshSwapContract`.
```tsx
import { MeshSwapContract } from "@meshsdk/contract";
import { MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshSwapContract({
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
});
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Initiate Swap
User A can initiate a swap by providing assets to the swap contract.
`initiateSwap()` initiate a swap. The function accepts the following parameters:
* toProvide (Asset\[]) - a list of assets user A is trading
* toReceive (Asset\[]) - a list of assets user A is expecting to receive from another user
Note that the parameters are arrays, so you can provide multiple assets to the swap, and these assets can be tokens and lovelace.
### Initiate Swap \[!toc]
Initiate a swap by defining the assets for the swap contract
**Amount lovelace to give**
`10000000`
**Asset to receive**
`d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
```tsx
const assetToProvide: Asset = {
unit: "lovelace",
quantity: '10000000',
};
const assetToReceive: Asset = {
unit: 'd9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e',
quantity: "1",
};
const tx = await contract.initiateSwap([assetToProvide], [assetToReceive]);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Accept Swap
User B can accept a swap by providing the swap transaction hash to the contract.
`acceptSwap()` accept a swap. The function accepts the following parameters:
* swapUtxo (UTxO) - the utxo of the transaction in the script for the swap
The function accepts a swap transaction hash and returns a transaction hash if the swap is successfully accepted.
A successful transaction will send the assets to the wallet that signed the transaction to accept the swap.
### Accept Swap \[!toc]
Accept a swap by providing the assets to the swap contract
**Tx hash**
`Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.acceptSwap(utxo);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Cancel Swap
Any any time before swap is accepted, user A can cancel the swap.
`cancelSwap()` cancel a swap. The function accepts the following parameters:
* swapUtxo (UTxO) - the utxo of the transaction in the script for the swap
The function accepts a swap transaction hash and returns a transaction hash if the swap is successfully canceled.
### Cancel Swap \[!toc]
Cancel a swap to get your funds back
**Tx hash**
`Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.cancelSwap(utxo);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
# Vesting
URL: /smart-contracts/vesting
Locks up funds and allows the beneficiary to withdraw the funds after the lockup period
***
title: "Vesting"
description: "Locks up funds and allows the beneficiary to withdraw the funds after the lockup period"
icon: LockClosedIcon
--------------------
import Link from "fumadocs-core/link";
When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure.
There are 2 actions (or endpoints) available to interact with this smart contract:
* deposit asset
* withdraw asset
### Install package \[!toc]
First you can to install the `@meshsdk/contracts` package:
```tsx
npm install @meshsdk/contract
```
### Initialize the contract \[!toc]
To initialize the contract, we need to initialize a provider, `MeshTxBuilder` and `MeshVestingContract`.
```tsx
import { MeshVestingContract } from "@meshsdk/contract";
import { MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const meshTxBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
const contract = new MeshVestingContract({
mesh: meshTxBuilder,
fetcher: provider,
wallet: wallet,
networkId: 0,
});
```
Both on-chain and off-chain codes are open-source and available on Mesh Github Repository.
## Deposit Fund
After the lockup period has expired, the beneficiary can withdraw the funds from the vesting contract.
`withdrawFund()` withdraw funds from a vesting contract. The function accepts the following parameters:
* vestingUtxo (UTxO) - unspent transaction output in the script
### Deposit Fund \[!toc]
Deposit funds into a vesting contract with a locking period for a beneficiary
**Amount in lovelace**
`5000000`
**Beneficiary address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
```tsx
const assets: Asset[] = [
{
unit: "lovelace",
quantity: '5000000',
},
];
const lockUntilTimeStamp = new Date();
lockUntilTimeStamp.setMinutes(lockUntilTimeStamp.getMinutes() + 1);
const beneficiary = 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr';
const tx = await contract.depositFund(
assets,
lockUntilTimeStamp.getTime(),
beneficiary,
);
const signedTx = await wallet.signTx(tx);
const txHash = await wallet.submitTx(signedTx);
```
## Withdraw Fund
After the lockup period has expired, the beneficiary can withdraw the funds from the vesting contract.
`withdrawFund()` withdraw funds from a vesting contract. The function accepts the following parameters:
* vestingUtxo (UTxO) - unspent transaction output in the script
A successful withdrawal will send the funds to the wallet that signed the transaction to withdraw the funds.
### Withdraw Fund \[!toc]
Withdraw funds from a vesting contract
**Tx hash**
`Tx hash`
```tsx
const utxo = await contract.getUtxoByTxHash('');
const tx = await contract.withdrawFund(utxo);
const signedTx = await wallet.signTx(tx, true);
const txHash = await wallet.submitTx(signedTx);
```
## Full Tutorial
Vesting contract is a smart contract that locks up funds for a period of time and allows the beneficiary to withdraw the funds after the lockup period. Usually, vesting contract defines a beneficiary who can be different from the original owner.
When a new employee joins an organization, they typically receive a promise of compensation to be disbursed after a specified duration of employment. This arrangement often involves the organization depositing the funds into a vesting contract, with the employee gaining access to the funds upon the completion of a predetermined lockup period. Through the utilization of vesting contracts, organizations establish a mechanism to encourage employee retention by linking financial rewards to tenure.
### On-Chain code \[!toc]
First, we define the datum's shape, as this datum serves as configuration and contains the different parameters of our vesting operation.
```tsx
pub type VestingDatum {
/// POSIX time in milliseconds, e.g. 1672843961000
lock_until: Int,
/// Owner's credentials
owner: ByteArray,
/// Beneficiary's credentials
beneficiary: ByteArray,
}
```
In this example, we define a `VestingDatum` that contains the following fields:
* `lock_until`: The POSIX timestamp in milliseconds until which the funds are locked.
* `owner`: The credentials (public key hash) of the owner of the funds.
* `beneficiary`: The credentials (public key hash) of the beneficiary of the funds.
This datum can be found in `aiken-vesting/aiken-workspace/lib/vesting/types.ak`.
Next, we define the spend validator.
```tsx
use aiken/transaction.{ScriptContext, Spend}
use vesting/types.{VestingDatum}
use vodka_extra_signatories.{key_signed}
use vodka_validity_range.{valid_after}
validator {
pub fn vesting(datum: VestingDatum, _redeemer: Data, ctx: ScriptContext) {
// In principle, scripts can be used for different purpose (e.g. minting
// assets). Here we make sure it's only used when 'spending' from a eUTxO
when ctx.purpose is {
Spend(_) -> or {
key_signed(ctx.transaction.extra_signatories, datum.owner),
and {
key_signed(ctx.transaction.extra_signatories, datum.beneficiary),
valid_after(ctx.transaction.validity_range, datum.lock_until),
},
}
_ -> False
}
}
}
```
In this example, we define a `vesting` validator that ensures the following conditions are met:
* The transaction must be signed by owner
Or:
* The transaction must be signed by beneficiary
* The transaction must be valid after the lockup period
This validator can be found in `aiken-vesting/aiken-workspace/validators/vesting.ak`.
### How it works \[!toc]
The owner of the funds deposits the funds into the vesting contract. The funds are locked up until the lockup period expires.
Transactions can include validity intervals that specify when the transaction is valid, both from and until a certain time. The ledger verifies these validity bounds before executing a script and will only proceed if they are legitimate.
This approach allows scripts to incorporate a sense of time while maintaining determinism within the script's context. For instance, if a transaction has a lower bound `A`, we can infer that the current time is at least `A`.
It's important to note that since we don't control the upper bound, a transaction might be executed even 30 years after the vesting delay. However, from the script's perspective, this is entirely acceptable.
The beneficiary can withdraw the funds after the lockup period expires. The beneficiary can also be different from the owner of the funds.
### Testing \[!toc]
To test the vesting contract, we have provided the a comphrehensive test script,you can run tests with `aiken check`.
The test script includes the following test cases:
* success unlocking
* success unlocking with only owner signature
* success unlocking with beneficiary signature and time passed
* fail unlocking with only beneficiary signature
* fail unlocking with only time passed
We recommend you to check out `aiken-vesting/aiken-workspace/validators/tests/vesting.ak` to learn more.
### Compile and build script \[!toc]
To compile the script, run the following command:
```tsx
aiken build
```
This command will generate a CIP-0057 Plutus blueprint, which you can find in `aiken-vesting/aiken-workspace/plutus.json`.
## Off-Chain code \[!toc]
### Deposit funds \[!toc]
First, the owner can deposit funds into the vesting contract. The owner can specify the lockup period and the beneficiary of the funds.
```tsx
const assets: Asset[] = [
{
unit: "lovelace",
quantity: "10000000",
},
];
const lockUntilTimeStamp = new Date();
lockUntilTimeStamp.setMinutes(lockUntilTimeStamp.getMinutes() + 1);
const beneficiary =
"addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9";
```
In this example, we deposit 10 ADA into the vesting contract. The funds are locked up for 1 minute, and the beneficiary is specified.
Then, we prepare a few variables to be used in the transaction. We get the wallet address and the UTXOs of the wallet. We also get the script address of the vesting contract, to send the funds to the script address. We also get the owner and beneficiary public key hashes.
```tsx
const { utxos, walletAddress } = await getWalletInfoForTx();
const { scriptAddr } = getScript();
const { pubKeyHash: ownerPubKeyHash } = deserializeAddress(walletAddress);
const { pubKeyHash: beneficiaryPubKeyHash } = deserializeAddress(beneficiary);
```
Next, we construct the transaction to deposit the funds into the vesting contract.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
await txBuilder
.txOut(scriptAddr, amount)
.txOutInlineDatumValue(
mConStr0([lockUntilTimeStampMs, ownerPubKeyHash, beneficiaryPubKeyHash])
)
.changeAddress(walletAddress)
.selectUtxosFrom(utxos)
.complete();
const unsignedTx = txBuilder.txHex;
```
In this example, we construct the transaction to deposit the funds into the vesting contract. We specify the script address of the vesting contract, the amount to deposit, and the lockup period, owner, and beneficiary of the funds.
Finally, we sign and submit the transaction.
```tsx
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
To execute this code, ensure you have defined blockfrost key in the `.env` file. You can also define your wallet mnemonic in `aiken-vesting/src/configs.ts` file.
You can run the following command execute the deposit funds code:
```tsx
npm run deposit
```
Upon successful execution, you will receive a transaction hash. Save this transaction hash for withdrawing the funds.
Example of a successful deposit transaction.
### Withdraw funds \[!toc]
After the lockup period expires, the beneficiary can withdraw the funds from the vesting contract. The owner can also withdraw the funds from the vesting contract.
First, let's look for the UTxOs containing the funds locked in the vesting contract.
```tsx
const txHashFromDesposit =
"ede9f8176fe41f0c84cfc9802b693dedb5500c0cbe4377b7bb0d57cf0435200b";
const utxos = await provider.fetchUTxOs(txHash);
const vestingUtxo = utxos[0];
```
In this example, we fetch the UTxOs containing the funds locked in the vesting contract. We specify the transaction hash of the deposit transaction.
Like before, we prepare a few variables to be used in the transaction. We get the wallet address and the UTXOs of the wallet. We also get the script address of the vesting contract, to send the funds to the script address. We also get the owner and beneficiary public key hashes.
```tsx
const { utxos, walletAddress, collateral } = await getWalletInfoForTx();
const { input: collateralInput, output: collateralOutput } = collateral;
const { scriptAddr, scriptCbor } = getScript();
const { pubKeyHash } = deserializeAddress(walletAddress);
```
Next, we prepare the datum and the slot number to set the transaction valid interval to be valid only after the slot.
```tsx
const datum = deserializeDatum(vestingUtxo.output.plutusData!);
const invalidBefore =
unixTimeToEnclosingSlot(
Math.min(datum.fields[0].int as number, Date.now() - 15000),
SLOT_CONFIG_NETWORK.preprod
) + 1;
```
In this example, we prepare the datum and the slot number to set the transaction valid interval to be valid only after the slot. We get the lockup period from the datum and set the transaction valid interval to be valid only after the lockup period.
Next, we construct the transaction to withdraw the funds from the vesting contract.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider,
submitter: provider,
});
await txBuilder
.spendingPlutusScriptV2()
.txIn(
vestingUtxo.input.txHash,
vestingUtxo.input.outputIndex,
vestingUtxo.output.amount,
scriptAddr
)
.spendingReferenceTxInInlineDatumPresent()
.spendingReferenceTxInRedeemerValue("")
.txInScript(scriptCbor)
.txOut(walletAddress, [])
.txInCollateral(
collateralInput.txHash,
collateralInput.outputIndex,
collateralOutput.amount,
collateralOutput.address
)
.invalidBefore(invalidBefore)
.requiredSignerHash(pubKeyHash)
.changeAddress(walletAddress)
.selectUtxosFrom(utxos)
.complete();
const unsignedTx = txBuilder.txHex;
```
In this example, we construct the transaction to withdraw the funds from the vesting contract. We specify the UTxO containing the funds locked in the vesting contract, the script address of the vesting contract, the wallet address to send the funds to, and the transaction valid interval.
Finally, we sign and submit the transaction. Notice that since we are unlocking fund from validator, partial sign has to be specified by passing a `true` parameter into `wallet.signTx`.
```tsx
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
To execute this code, update `aiken-vesting/src/withdraw-fund.ts` with the transaction hash from the deposit transaction. Ensure you have defined blockfrost key in the `.env` file. You can also define your wallet mnemonic in `aiken-vesting/src/configs.ts` file.
Run the following command:
```tsx
npm run withdraw
```
Example of a successful withdraw transaction.
# Getting Started with Svelte
URL: /svelte/getting-started
Svelte frontend components for wallet connections.
***
title: "Getting Started with Svelte"
description: "Svelte frontend components for wallet connections."
icon: RocketLaunchIcon
----------------------
import Link from "fumadocs-core/link";
## Setup
The fastest way to get started a new project with Svelte is to use the Mesh-CLI, which will scaffold a new project for you. To do this, run the following:
```tsx
npx meshjs your-app-name
```
During the installation process, you will be asked to choose a template. Choose the Svelte template. This will scaffold a new Svelte project with Mesh pre-installed.
To manually, install the Mesh Svelte package, run the following:
```tsx
npm install @meshsdk/svelte
```
Next, add the Mesh CSS to your application, doing so will apply the default styles to the components. You can add this in `+layout.svelte`.
```tsx
{@render children()}
```
## Connect Wallet
In order for apps to communicate with the user's wallet, we need a way to connect to their wallet.
Add `CardanoWallet` to allow the user to select a wallet to connect to your app. After the wallet is connected, see Browser Wallet for a list of CIP-30 APIs.
The signature for the `CardanoWallet` component is as follows:
```tsx
{
label?: string;
onConnected?: Function;
isDark?: boolean;
}
```
### Customization \[!toc]
For dark mode style, add isDark.
```tsx
```
For a custom label, add the label prop.
```tsx
```
The customization is limited. For more customization, you can easily build your own wallet connection component. You may also take reference from this component.
### onConnected \[!toc]
If you want to run a function after the wallet is connected, you can add the onConnected prop.
```tsx
export default function Page() {
function afterConnectedWallet() {
// do something
}
return (
<>
>
);
}
```
The above code will log "Hello, World!" to the console when the wallet is connected.
### Connect Wallet Component \[!toc]
Connect to user's wallet to interact with app
```tsx
```
## Get Wallet State
Obtain information on the current wallet's state, all fields on the `BrowserWalletState` JavaScript object are Svelte 5 runes, meaning when using the accessor, these values are reactive.
```tsx
```
`wallet` is a Browser Wallet instance, which expose all CIP wallets functions from getting assets to signing tranasction.
`connected`, a boolean, `true` if user's wallet is connected.
`name`, a string, the name of the connect wallet.
`connecting`, a boolean, `true` if the wallet is connecting and initializing.
### Wallet State \[!toc]
Get the current wallet's state
```tsx
```
# Svelte Components
URL: /svelte
Svelte UI components for wallet connections
***
title: "Svelte Components"
description: "Svelte UI components for wallet connections"
icon: ComputerDesktopIcon
-------------------------
import {
ComputerDesktopIcon,
PaintBrushIcon,
RocketLaunchIcon,
} from "@heroicons/react/24/solid";
}>
## Getting Started with React \[!toc]
Svelte frontend components for wallet connections.
}>
## UI Components \[!toc]
UI components to speed up your app development.
# UI Components
URL: /svelte/ui-components
UI components to speed up your app development.
***
title: "UI Components"
description: "UI components to speed up your app development."
icon: PaintBrushIcon
--------------------
import Link from "fumadocs-core/link";
Mesh provide a collection of useful UI components, so you can easily include web3 functionality and convenient utilities for your application.
## Connect Wallet
In order for apps to communicate with the user's wallet, we need a way to connect to their wallet.
Add `CardanoWallet` to allow the user to select a wallet to connect to your app. After the wallet is connected, see Browser Wallet for a list of CIP-30 APIs.
The signature for the `CardanoWallet` component is as follows:
```tsx
{
label?: string;
onConnected?: Function;
isDark?: boolean;
}
```
### Customization \[!toc]
For dark mode style, add isDark.
```tsx
```
For a custom label, add the label prop.
```tsx
```
The customization is limited. For more customization, you can easily build your own wallet connection component. You may also take reference from this component.
### onConnected \[!toc]
If you want to run a function after the wallet is connected, you can add the onConnected prop.
```tsx
export default function Page() {
function afterConnectedWallet() {
// do something
}
return (
<>
>
);
}
```
The above code will log "Hello, World!" to the console when the wallet is connected.
### Connect Wallet Component \[!toc]
Connect to user's wallet to interact with app
```tsx
```
# Getting Started
URL: /yaci/getting-started
Set up Yaci Dev Kit and start the devnet
***
title: "Getting Started"
description: "Set up Yaci Dev Kit and start the devnet"
-------------------------------------------------------
import Link from "fumadocs-core/link";
## Mesh Hosted Yaci Devnet
### Connect right away with Yaci Provider \[!toc]
Mesh has a hosted Yaci Devnet that you can connect to right away. You can use the following URL to connect to the hosted Yaci Devnet:
```bash
https://yaci-node.meshjs.dev/api/v1/
```
### Import Yaci Provider \[!toc]
Import `YaciProvider` and start using it to interact with the Yaci Devnet.
```tsx
import { YaciProvider } from "@meshsdk/core";
const provider = new YaciProvider();
const params = await provider.fetchProtocolParameters();
console.log(params);
```
Learn more about Yaci Provider and learn more about hosted Yaci Devnet
## Set up your system to run Yaci Devkit
### Download and install Docker \[!toc]
You can download Docker from the official website. Docker is a platform for developers and sysadmins to develop, deploy, and run applications with containers.
Go to the Docker website and download the latest version, then follow the instructions to install it.
After installing, open the Docker Desktop app and make sure it's running in the background.
### Download the latest Yaci DevKit release \[!toc]
Go to Yaci releases on Github and download the latest release. Under `Assets`, you will find the `yaci-devkit-version.zip` file.
Extract the zip file to a folder on your system. This folder will be your Yaci DevKit root directory.
## Start a Yaci Devnet
Open a terminal and navigate to the Yaci DevKit root directory. Run the following command to start the DevKit containers and yaci-cli:
```bash
$ ./bin/devkit.sh start
```
### Start node \[!toc]
To create a new devnet, run the following command from yaci-cli:
```bash
yaci-cli:>create-node -o --start
```
To create a new devnet with Babbage era, run the following command from yaci-cli:
```bash
yaci-cli:>create-node -o --era babbage --start
```
To start a devnet with zero fees, run the following command from yaci-cli:
```bash
yaci-cli:>create-node -o --genesis-profile zero_fee --start
```
To start a devnet with 30 slots per epoch, run the following command from yaci-cli:
```bash
yaci-cli:>create-node -o -e 30 --start
```
After you have started your devnet, you can open Yaci Viewer from [http://localhost:5173](http://localhost:5173). Here you can view the blocks, transactions, and other details of the devnet.
If you want to configure the devnet, go to `config/node.properties`. And if you want to change settings and change default topup addreses, go to `config/env`.
You can use `YaciProvider` with the Yaci Store Api URL ([http://localhost:8080/api/v1](http://localhost:8080/api/v1)), to interact with the Yaci Devnet.
```tsx
import { YaciProvider } from "@meshsdk/core";
const provider = new YaciProvider('http://localhost:8080/api/v1/');
const params = await provider.fetchProtocolParameters();
console.log(params);
```
### Support external PostgreSQL database for indexer \[!toc]
By default, Yaci DevKit's indexer uses an embedded H2 database. With this update, you can also configure an external PostgreSQL database.
For Non-Docker distribution, edit config/application.properties and uncomment the following properties to set PostgreSQL database details:
```bash
yaci.store.db.url=jdbc:postgresql://:/?currentSchema=
yaci.store.db.username=user
yaci.store.db.password=password
```
For Docker distribution, edit config/env and uncomment the following properties:
```bash
yaci_store_db_url=jdbc:postgresql://:/?currentSchema=
yaci_store_db_username=user
yaci_store_db_password=password
```
## Useful commands
Here are some useful commands to interact with the Yaci DevKit.
### Topup ADA \[!toc]
After you have started your devnet, you can topup ADA in your wallet. To topup ADA in your wallet, run the following command from devnet:
```bash
devnet:default>topup
```
For example:
```bash
devnet:default>topup addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9 1000
```
### Check UTXO \[!toc]
To check the UTXO of an address, run the following command from devnet:
```bash
devnet:default>utxos
```
For example:
```bash
devnet:default>utxos addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9
```
### Default address info \[!toc]
You can get the default addresses of the devnet by running:
```bash
devnet:default> default-addresses
```
By default, wallet mnemonic is
```bash
test test test test test test test test test test test test test test test test test test test test test test test sauce
```
And it's address is
```bash
addr_test1qryvgass5dsrf2kxl3vgfz76uhp83kv5lagzcp29tcana68ca5aqa6swlq6llfamln09tal7n5kvt4275ckwedpt4v7q48uhex
```
### Stop Devnet and yaci-cli \[!toc]
To stop the devnet, run the following command from devnet:
```bash
devnet:default>exit
```
To stop yaci-cli, run the following command:
```bash
yaci-cli:>exit
```
To stop the DevKit containers, run the following command from the Yaci DevKit root directory:
```bash
./bin/devkit.sh stop
```
Sometimes you just want to reset the devnet and start from scratch. To do that, run:
```bash
devnet:default>reset
```
# Yaci
URL: /yaci
Customizable Cardano devnet for enabling faster iterations
***
title: "Yaci"
description: "Customizable Cardano devnet for enabling faster iterations"
icon: "icons/yaci.png"
----------------------
Custom Cardano devnet that can be created and reset in seconds using the user-friendly Yaci CLI. This allows for rapid iteration and experimentation, tailored to specific needs through flexible configuration options. The default devnet is optimized for speed, with customizable parameters for various testing scenarios. Integrated tools like the lightweight chain indexer Yaci Store and the browser-based Yaci Viewer enhance transaction building and submission. Yaci DevKit's compatibility with Blockfrost API endpoints ensures seamless integration with client SDKs.
## Getting Started \[!toc]
Set up Yaci Dev Kit and start the devnet
## Hosted Yaci Devnet \[!toc]
Connect to the hosted Yaci Devnet
## Build Transactions \[!toc]
Building and submitting transactions on Yaci
## Yaci Provider \[!toc]
For fetching data and submitting transactions on Yaci
# Build Transactions
URL: /yaci/transactions
Building and submitting transactions on Yaci
***
title: "Build Transactions"
description: "Building and submitting transactions on Yaci"
-----------------------------------------------------------
## Import Yaci Provider
First, We import `YaciProvider`
```tsx
import { YaciProvider } from "@meshsdk/core";
const provider = new YaciProvider('', '');
```
By default, the `YaciProvider` will use the default URL, `https://yaci-node.meshjs.dev/api/v1/`. If you want to use a custom URL, you can pass it as a parameter.
In this example, we initialize the `YaciProvider` and fetch the UTxOs of an address.
You can topup ADA in your wallet by running the following command from devne in order to fetch the UTxOs of an address.
```bash
devnet:default>topup addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9 1000
```
### Get UTxOs \[!toc]
Fetch UTxOs of an address. Note: your Yaci devnet must be running.
**Address**
`addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337...pmtv7cc3yel9uu0nq93swx9`
**Yaci URL**
`https://yaci-node.meshjs.dev/api/v1/`
```tsx
import { YaciProvider } from "@meshsdk/core";
const provider = new YaciProvider('https://yaci-node.meshjs.dev/api/v1/');
const utxos = await provider.fetchAddressUTxOs('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9');
```
## Basic Transaction
We import a wallet, for example `MeshWallet` with `YaciProvider` as the `fetcher` and `submitter`:
```tsx
const provider = new YaciProvider();
const wallet = new MeshWallet({
networkId: 0,
fetcher: provider,
submitter: provider,
key: {
type: "mnemonic",
words: demoMnemonic,
},
});
```
Next, we create a transaction and send 1 ADA to the recipient address.
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace('', "1000000");
const unsignedTx = await tx.build();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
Note: for this transaction to work, you must have a Yaci devnet running and the wallet is funded. You can topup ADA in your wallet by running the following command from devnet:
```bash
devnet:default>topup addr_test1qryvgass5dsrf2kxl3vgfz76uhp83kv5lagzcp29tcana68ca5aqa6swlq6llfamln09tal7n5kvt4275ckwedpt4v7q48uhex 1000
```
### Get UTxOs \[!toc]
Fetch UTxOs of an address. Note: your Yaci devnet must be running.
**Recipient Address**
`addr_test1qryvgass5dsrf2kxl3vgfz76uhp83kv5lag...tal7n5kvt4275ckwedpt4v7q48uhex`
**Yaci URL**
`https://yaci-node.meshjs.dev/api/v1/`
```tsx
import { YaciProvider } from "@meshsdk/core";
const provider = new YaciProvider('https://yaci-node.meshjs.dev/api/v1/');
const utxos = await provider.fetchAddressUTxOs('addr_test1qryvgass5dsrf2kxl3vgfz76uhp83kv5lagzcp29tcana68ca5aqa6swlq6llfamln09tal7n5kvt4275ckwedpt4v7q48uhex');
```
# Data
URL: /apis/data
Useful utilities to parse and manipulate data
***
title: "Data"
description: "Useful utilities to parse and manipulate data"
------------------------------------------------------------
import {
Bars2Icon,
Bars3Icon,
CircleStackIcon,
} from "@heroicons/react/24/solid";
}>
### Data Overview \[!toc]
Learn about the basics, and how Mesh handles Cardano data
}>
### Mesh Data \[!toc]
Parse and manipulate data with Mesh Data type
}>
### JSON Data \[!toc]
Parse and manipulate data with JSON
}>
### Value \[!toc]
Manipulate Value Easily
# JSON Data
URL: /apis/data/json
Parse and manipulate data with JSON
***
title: "JSON Data"
description: "Parse and manipulate data with JSON"
icon: Bars3Icon
---------------
Mesh offers a full set of utility functions to help constructing the JSON data you need for your Web3 app, with the naming philosophy similar to Mesh `Data` type, with extra utilities mimicing the data type names in PlutusTx and Aiken.
**Types Support**
All the utilities are designed to return a type with the same naming as the utilities function, with capitalizing first letter, you can build your data in JSON with robust type supports, some examples:
* `constr` returns `Constr` type
* `integer` returns `Integer` type
* `byteString` returns `ByteString` type
## Utilities in Building Constructor Data in JSON
`conStr` build the constructor object, with parameters:
* constructor (number) - the constructor index
* fields (any\[]) - the constructor fields in array
There are also some quick utilities only taking in **fields** as parameters for 0 - 2 indices:
* `conStr0` - building index 0 constructor
* `conStr1` - building index 1 constructor
* `conStr2` - building index 2 constructor
### Constructor \[!toc]
Building JSON constructor object
```tsx
import { conStr } from "@meshsdk/core";
conStr(0, []);
```
## Utilities in Building Integer Data in JSON
`integer` build the integer object, with parameters:
* int (number | bigint) - the integer to be built
This utility is compatible for both number and bigint type, which allow big integer exceeding the JS precision limit.
**Aliases**
* `posixTime` - for the same functionality.
### Constructor \[!toc]
Building JSON integer object
**int** `1000000`
```tsx
import { integer } from "@meshsdk/core";
integer(1000000);
```
## Utilities in Building ByteString Data in JSON
`byteString` build the byte string object, with parameters:
* bytes (string) - the byte string in hex to be built, validation would be performed on whether the bytes is a valid hex string
**Aliases**
* `builtinByteString` - for the same functionality, for developers more familiar to the PlutusTx naming convention.
* `scriptHash` / `pubKeyHash` / `policyId` / `currencySymbol` / `assetName` / token\`Name - same building the byte string JSON but with further input validation.
### Constructor \[!toc]
Building JSON byteString object
**byteString**
`a0bd47e8938e7c41d4c1d7c22033892319d28f86fdace791d45c51946553791b`
```tsx
import { byteString } from "@meshsdk/core";
byteString("a0bd47e8938e7c41d4c1d7c22033892319d28f86fdace791d45c51946553791b");
```
## Utilities in Building Boolean Data in JSON
`bool` build the boolean object, with parameters:
* b (boolean | boolean) - the boolean to be built
### Constructor \[!toc]
Building JSON bool object
```tsx
import { bool } from "@meshsdk/core";
bool(true);
```
## Utilities in Building List Data in JSON
`list` build the list object, with parameters:
* pList (T\[]) - the list with items to be built. The items in the
* optional - validation (boolean) - indicate if the current data construction should perform basic validation of whether it is of typeobject (where all JSON data is in type of object)
### Constructor \[!toc]
Building JSON list object
```tsx
import { bool, byteString, integer, list } from "@meshsdk/core";
list([
byteString(
"a0bd47e8938e7c41d4c1d7c22033892319d28f86fdace791d45c51946553791b"
),
integer(1000000),
bool(false),
]);
```
## Utilities in Building Map Data in JSON
`assocMap` build the (associative) map object, with parameters:
* mapItems - (\[KeyType, ValueType]\[]) - the array of map item in JS tuple format (array of array).
* optional - validation (boolean) - indicate if the current data construction should perform basic validation of whether it is of typeobject (where all JSON data is in type of object)
### Constructor \[!toc]
Building JSON list object
```tsx
import { assocMap, byteString, integer } from "@meshsdk/core";
assocMap([
[byteString("aa"), integer(1000000)],
[byteString("bb"), integer(2000000)],
]);
```
## Other Utilities
The code example showing above does not cover all utilities, please checkout the hosted documentation for more details. The not covered utilities are as below:
* `assetClass`
* `outputReference`
* `txOutRef`
* `dict`
* `tuple`
* `maybeStakingHash`
* `pubKeyAddress`
* `scriptAddress`
# Mesh Data
URL: /apis/data/mesh
Parse and manipulate data with Mesh Data type
***
title: "Mesh Data"
description: "Parse and manipulate data with Mesh Data type"
icon: Bars2Icon
---------------
Mesh provides a full set of utility functions to help constructing the Mesh `Data` type you need for your Web3 app.
**Types Support**
All utility functions start with the prefix of m and all types All the utility functions start with the prefix of m, and are designed to return a type with the same naming as the utilities function, with capitalizing first letter, you can build your data with type supports in complex types, some examples:
* `mConstr` returns `MConstr` type
* `mBool` returns `MBool` type
## Utilities in Building Constructor Mesh Data
`mConStr` build the constructor object in Mesh `Data` type, with parameters:
* alternative (number) - the constructor index
* fields (any\[]) - the constructor fields in array
There are also some quick utilities only taking in **fields** as parameters for 0 - 2 indices:
* `mConStr0` - building index 0 constructor
* `mConStr1` - building index 1 constructor
* `mConStr2` - building index 2 constructor
### Constructor \[!toc]
Building Mesh constructor object
```tsx
import { mConStr } from "@meshsdk/core";
mConStr(0, []);
```
## Utilities in Building Primitives Mesh Data
`mBool` build the boolean object in , with parameters:
* b (boolean | boolean) - the boolean to be built
For the rest of data primitives, they are represented by JS primitives:
* Integer - `number` and `bigint`
* Byte string - `string`
* List - JS `Array`
* Map - JS `Map`
### Constructor \[!toc]
Building Mesh bool object
```tsx
import { mBool } from "@meshsdk/core";
mBool(true);
```
## Other Utilities
The code example showing above does not cover all utilities, please checkout the hosted documentation for more details. The not covered utilities are as below:
* `mAssetClass`
* `mOutputReference`
* `mTxOutRef`
* `mTuple`
* `mMaybeStakingHash`
* `mPubKeyAddress`
* `mScriptAddress`
# Data Overview
URL: /apis/data/overview
Learn about the basics, and how Mesh handles Cardano data
***
title: "Data Overview"
description: "Learn about the basics, and how Mesh handles Cardano data"
icon: CircleStackIcon
---------------------
import Link from "fumadocs-core/link";
Parsing and converting data in Plutus is a common task when working with transactions. This page will show you how to do that.
## Use of Data in Cardano
Cardano data and information is usually communicated in `CBOR` encoding format, which can be decoded into `JSON` representation.
On top of the 2, Mesh also provides the `Data` type which get rids of unnecessary wrappers.
Mesh supports building data for your app in all 3 different formats.
* `Mesh` - the `Data` type
* `JSON`
* `CBOR`
## Mesh Data Type
Mesh `Data` type is best used when you want to quickly and easily compose your data types.
Learn more
## JSON Data Type
All Cardano data has the JSON representation, which is suitable for building Web3 app which needs frequent back and forth conversion between on-chain and off-chain code. Mesh also supports building data in JSON format with strong input validation support.
Learn more
## CBOR
CBOR is the lowest level representation of data in Cardano. Mesh provides endpoints to allow users to provide CBOR in providing data, which is the case for developers utilizing other serialization package other than mesh in part the application.
# Value
URL: /apis/data/value
Manipulate Value Easily
***
title: "Value"
description: "Manipulate Value Easily"
icon: Bars3Icon
---------------
We all know the pain of conducting `Value` operation in Cardano. Mesh provides a full set of value methods to help converting, operating, accessing and comparing Cardano data.
### Value Types Support
**Convertors**
Convertor functions provide utilities around round trip among Cardano onchain data and off chain `JSON` and `Data` type.
**Operators**
Operator functions provide utilities into performing value manipulation. They are useful in apps which check against value payment involving calculation in value.
**Accessor**
Accessor functions provide utilities in obtaining keys or values of the `Value` type.
**Comparator**
Comparator functions provide utilities in comparing different `Value`. It helps with offchain validation before using for transaction building.
## Convertor - converts assets into Cardano data Value in JSON
`value` converts assets into Cardano data Value in JSON with parameters:
* assets - Asset\[] to convert
### value \[!toc]
Converts assets into MeshValue with parameters - asset\[] e.g. ada value, simple token token, complex value.
```tsx
const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
const datum: Value = value(val);
const nameMap = dict([[byteString(""), integer(1000000)]]);
const valMap = dict>([[byteString(""), nameMap]]);
if (JSON.stringify(datum) === JSON.stringify(valMap)) {
return true;
```
## Convertor - converts assets into Cardano data Value in Mesh Data type
`mValue` converts assets into Cardano data value in Mesh Data type with parameters:
* assets - Asset\[] to convert
### mValue \[!toc]
Converts assets into MeshValue with parameters - asset\[] e.g. ada value, simple token token, complex value.
```tsx
const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
const datum: MValue = mValue(val);
const nameMap = new Map().set("", 1000000);
const valMap = new Map().set("", nameMap);
if (JSON.stringify(datum) === JSON.stringify(valMap)) {
return true;
```
## Convertor - converts assets into MeshValue with parameters - asset\[]
`fromAssets` converts assets into MeshValue with parameters:
* assets - the assets to convert
### fromAssets \[!toc]
Converts assets into MeshValue with parameters - asset\[] e.g. ada value, simple token token, complex value.
```tsx
import { MeshValue } from "@meshsdk/common";
const assets: Asset[] = [
{ unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64", quantity: "100" },
{ unit: "lovelace", quantity: "10" },
];
const value = MeshValue.fromAssets(assets);
return value;
```
## Convertor - converts the MeshValue object into an array of Asset
`toAssets` Convert the MeshValue object into an array of Asset
### toAssets \[!toc]
Converts the MeshValue object into an array of Asset
```tsx
import { MeshValue } from "@meshsdk/common";
const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
const plutusValue: Value = value(val);
const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets();
return assets;
```
## Convertor - converts Value (the JSON representation of Cardano data Value) into MeshValue
`fromValue` Convert Value (the JSON representation of Cardano data Value) into MeshValue with parameters:
* plutusValue - the value to convert
### fromValue \[!toc]
Convert Value (the JSON representation of Cardano data Value) into MeshValue.
```tsx
import { MeshValue } from "@meshsdk/common";
const val: Asset[] = [{ unit: "lovelace", quantity: "1000000" }];
const plutusValue: Value = value(val);
const assets: Asset[] = MeshValue.fromValue(plutusValue).toAssets();
return assets;
```
## Convertor - converts the MeshValue object into Cardano data Value in Mesh Data type
`toData` Convert the MashValue object into Cardano data Value in Mesh Data type
### toData \[!toc]
Converts the MeshValue object into Cardano data Value in Mesh Data type
```tsx
import { MeshValue } from "@meshsdk/common";
const val: Asset[] = [
{
unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234",
quantity: "100",
},
{
unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234",
quantity: "200",
},
];
const plutusValue: Value = value(val);
const data = MeshValue.fromValue(plutusValue).toData();
const expected: MValue = mValue(val);
if (JSON.stringify(expected) === JSON.stringify(data)) {
return true;
```
## Convertor - converts the MeshValue object into a JSON representation of Cardano data Value
`toJSON` Converts the MeshValue object into a JSON representation of Cardano data Value
### toJSON \[!toc]
Converts the MeshValue object into a JSON representation of Cardano data Value
```tsx
import { MeshValue } from "@meshsdk/common";
const assets: Asset[] = [
{ unit: "lovelace", quantity: "1000000" },
{
unit: "c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64",
quantity: "500",
},
];
const expectedValue = assocMap([
[currencySymbol(""), assocMap([[tokenName(""), integer(1000000)]])],
[
currencySymbol(
"c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c",
),
assocMap([[tokenName("000643b04d65736820676f6f64"), integer(500)]]),
],
]);
const meshValue = new MeshValue();
meshValue.toAssets = () => assets;
const jsonValue = meshValue.toJSON();
if (JSON.stringify(jsonValue) === JSON.stringify(expectedValue)) {
return true;
}
```
## Operator - add an asset to the Value class's value record with parameters - asset
`addAsset` Add an asset to the Value class's value record with parameters:
* asset - Asset to add
### addAsset \[!toc]
Add an asset to the Value class's value record with parameters - asset
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue();
const singleAsset: Asset = { unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "100" };
value.addAsset(singleAsset);
return value.value;
```
## Operator - add an array of assets to the Value class's value record with parameters - assets
`addAssets` Add an array of assets to the Value class's value record with parameters:
* assets - Asset\[] to add
### addAssets \[!toc]
Add an array of assets to the Value class's value record with parameters - assets
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue();
const assets: Asset[] = [
{ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "100" },
{ unit: "lovelace", quantity: "10" },
{ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "100" },
{ unit: "lovelace", quantity: "10" },
];
value.addAssets(assets);
return value.value;
```
## Operator - substract an asset from the Value class's value record with parameters - asset
`negateAsset` Substract an asset from the Value class's value record with parameters:
* asset - Asset to substract
### negateAsset \[!toc]
Substract an asset from the Value class's value record with parameters - asset
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue();
value.value = { lovelace: 10n };
value.negateAsset({ unit: "lovelace", quantity: "5" });
return value.value;
```
## Operator - substract an array of assets from the Value class's value record with parameters - assets
`negateAssets` Substract an array of assets from the Value class's value record with parameters:
* assets - Asset\[] to substract
### negateAssets \[!toc]
Substract an array of assets from the Value class's value record with parameters - assets
```tsx
const value = new MeshValue();
value.value = { lovelace: 20n, "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 10n };
value.negateAssets([
{ unit: "lovelace", quantity: "5" },
{ unit: "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234", quantity: "3" },
]);
return value.value;
```
## Operator - merge the given values with parameters - values
`merge` Merge the given values
* values - The other values to merge
## merge \[!toc]
Merge the given values with parameters - values
```tsx
const value1 = new MeshValue();
value1.value = { lovelace: 20n, "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 10n };
const value2 = new MeshValue();
value2.value = { lovelace: 10n, "baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 5n };
return value1.merge(value2).value;
```
## Accessor - get the quantity of asset object per lovelace unit
`get` get the quantity of asset object per unit, with parameters
* unit - the unit to get the quantity of the assets e.g. lovelace
### get \[!toc]
Get the quantity of asset object per unit
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue({ lovelace: 20n });
value.get("lovelace");
return value;
```
## Accessor - get all asset units with no parameters needed
`units` get all asset units with no parameters (e.g. unit) needed
### units \[!toc]
Get all asset units with no parameters needed
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue({
lovelace: 20n,
"baefdc6c5b191be372a794cd8d40d839ec0dbdd3c28957267dc817001234": 10n,
});
return value.units();
```
## Comparator - check if the value is greater than or equal to another value with parameters - other
`geq` Check if the value is greater than or equal to another value with parameters:
* other - The MeshValue to compare against
### geq \[!toc]
Check if the value is greater than or equal to another value with parameters - other
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue({
lovelace: 20n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 10n,
});
const target = new MeshValue({
lovelace: 10n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 5n,
});
return value.geq(target);
```
## Comparator - check if the value is greater than or equal to another value with parameters - unit, other
`geqUnit` Check if the value is greater than or equal to another value with parameters:
* unit - The unit to compare
* other - The MeshValue to compare against
### geqUnit \[!toc]
Check if the value is greater than or equal to another value with parameters - unit, other
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue({
lovelace: 20n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64:
10n,
});
const target = new MeshValue({
lovelace: 10n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64:
5n,
});
const resultLovelace = value.geqUnit("lovelace", target);
const resultmockvalue = value.geqUnit(
"c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64",
target,
);
return { resultLovelace, resultmockvalue };
}
```
## Comparator - check if the value is less than or equal to another value with parameters - other
`leq` Check if the value is less than or equal to another value with parameters:
* other - The MeshValue to compare against
### leq \[!toc]
Check if the value is less than or equal to another value with parameters - other
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue({
lovelace: 20n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64:
10n,
});
const target = new MeshValue({
lovelace: 30n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64:
15n,
});
return value.leq(target);
```
## Comparator - check if the specific unit of value is less than or equal to that unit of another value with parameters - unit, other
`leqUnit` Check if the specific unit of value is less than or equal to that unit of another value with parameters:
* unit - The unit to compare
* other - The MeshValue to compare against
### lequnit \[!toc]
Check if the specific unit of value is less than or equal to that unit of another value with parameters - unit, other
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue({
lovelace: 20n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 10n,
});
const target = new MeshValue({
lovelace: 30n,
c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64: 15n,
});
const resultLovelace = value.leqUnit("lovelace", target);
const resultmockvalue = value.leqUnit(
"c21d710605bb00e69f3c175150552fc498316d80e7efdb1b186db38c000643b04d65736820676f6f64",
target,
);
return { resultLovelace, resultmockvalue };
```
## Comparator - check if the value is empty
`isEmpty` Check if the value is empty
### isEmpty \[!toc]
Check if the value is empty
```tsx
import { MeshValue } from "@meshsdk/common";
const value = new MeshValue();
return value.isEmpty();
```
# Parser Basics
URL: /apis/txparser/basics
Parse transactions and rebuild
***
title: "Parser Basics"
description: "Parse transactions and rebuild"
icon: PaperAirplaneIcon
-----------------------
import Link from "fumadocs-core/link";
The `TxParser` is a tool where you can parse the typical transaction CBOR hex back into the `MeshTxBuilderBody`. With such capability, you can proceed with rebuilding a transaction or examing the with unit testing frameworks.
In this page, we will cover how to initialize the `TxParser`.
## Initialize Tx Parser
To start parsing transaction, you need to first initialize `TxParser`:
```tsx
import { BlockfrostProvider, TxParser } from "@meshsdk/core";
import { CSLSerializer } from "@meshsdk/core-csl";
const fetcher = new BlockfrostProvider('');
const serializer = new CSLSerializer();
const txParser = new TxParser(serializer, fetcher);
```
There are 2 fields to pass in to initialized `TxParser`:
1. `serializer`: The serializer instance that will be used for parsing transaction
2. `fetcher` (optional): `TxParser` requires all input `UTxO` information provided since the transaction CBOR hex only preserves transaction hash and output index. When you are not providing all input `UTxO` information, the `fetcher` instance is used to fetch the missing `UTxO`
## Rebuild Transaction
To parse a transaction, you only need:
```tsx
const txBuilderBody = await txParser.parse(txHex, utxos);
```
With the parsed `txBuilderBody` in type `MeshTxBuilderBody`, you can proceed with adding / removing elements and rebuilding the transaction.
There are 2 necessary fields to pass in:
1. `txHex`: The transaction CBOR to be parsed
2. `providedUtxos`: The input information, for all inputs, reference inputs, and collateral. You can either construct it manually or obtain it from `fetcher`.
## Unit Testing Transaction
To unit test a transaction, you can parse the transaction and then convert the instance to `TxTester`:
```tsx
await txParser.parse(txHex, utxos);
const txTester = txParser.toTester();
```
The detailed testing APIs can be found in the documentation.
# Transaction Parser
URL: /apis/txparser
Parse transactions for testing and rebuilding
***
title: "Transaction Parser"
description: "Parse transactions for testing and rebuilding"
icon: MagnifyingGlassIcon
-------------------------
import {
PaperAirplaneIcon,
ShieldCheckIcon,
} from "@heroicons/react/24/solid";
}>
## Parser Basics \[!toc]
Parse transactions and rebuild
}>
## Unit Testing Transaction \[!toc]
Parse and test transactions with various options
# Unit Testing Transaction
URL: /apis/txparser/txtester
Parse and test transactions with various options
***
title: "Unit Testing Transaction"
description: "Parse and test transactions with various options"
icon: ShieldCheckIcon
---------------------
The `TxParser` is a tool where you can parse the typical transaction CBOR hex back into the `MeshTxBuilderBody`. With such capability, you can proceed with rebuilding a transaction or examing the with unit testing frameworks.
In this page, we will cover how to initialize the `TxParser`.
## Initialize Tx Parser
To start parsing transaction, you need to first initialize `TxParser`:
```tsx
import { BlockfrostProvider, TxParser } from "@meshsdk/core";
import { CSLSerializer } from "@meshsdk/core-csl";
const fetcher = new BlockfrostProvider('');
const serializer = new CSLSerializer();
const txParser = new TxParser(serializer, fetcher);
```
There are 2 fields to pass in to initialized `TxParser`:
1. `serializer`: The serializer instance that will be used for parsing transaction
2. `fetcher` (optional): `TxParser` requires all input `UTxO` information provided since the transaction CBOR hex only preserves transaction hash and output index. When you are not providing all input `UTxO` information, the `fetcher` instance is used to fetch the missing `UTxO`
## Interpret Result
After performing the tests, you can interpret the results of the tests using the `success` and `errors` methods.
```tsx
const result = txTester.success();
console.log("Errors:", txTester.errors());
```
1. `success`: Return a boolean indicating if all tests are passed
2. `errors`: Show all the errors that occurred during the tests . If there are no errors, it will return an empty string.
## Testing Inputs
Testing inputs starts with locating the inputs you want to test. The filtering will not reset until the filtering methods are called again.
```tsx
txTester
.inputsAt(
"addr_test1qrs3jlcsapdufgagzt35ug3nncwl26mlkcux49gs673sflmrjfm6y2eu7del3pprckzt4jaal9s7w9gq5kguqs5pf6fq542mmq",
)
.inputsValue(
MeshValue.fromAssets([{ unit: "lovelace", quantity: "10000000000" }]),
)
```
There are multiple methods available to filter the inputs:
1. `allInputs`: not apply filters
2. `inputsAt`: filtering inputs with address
3. `inputsWith`: filtering inputs with token
4. `inputsWithPolicy`: filtering inputs with policy id
5. `inputsAtWith`: filtering inputs with address and token
6. `inputsAtWithPolicy`: filtering inputs with address and policy id
After applying filters, you can proceed with checking value:
1. `inputsValue`: Check the total value of the filtered inputs
## Testing Outputs
Testing outputs starts with locating the outputs you want to test. The filtering will not reset until the filtering methods are called again.
```tsx
txTester
.outputsAt(
"addr_test1qrs3jlcsapdufgagzt35ug3nncwl26mlkcux49gs673sflmrjfm6y2eu7del3pprckzt4jaal9s7w9gq5kguqs5pf6fq542mmq",
)
.outputsValue(
MeshValue.fromAssets([{ unit: "lovelace", quantity: "10000000000" }]),
)
.outputsInlineDatumExist(datumCbor);
```
There are multiple methods available to filter the outputs:
1. `allOutputs`: not apply filters
2. `outputsAt`: filtering outputs with address
3. `outputsWith`: filtering outputs with token
4. `outputsWithPolicy`: filtering outputs with policy id
5. `outputsAtWith`: filtering outputs with address and token
6. `outputsAtWithPolicy`: filtering outputs with address and policy id
After applying filters, you can proceed with checking value:
1. `outputsValue`: Check the total value of the filtered outputs
2. `outputsInlineDatumExist`: Check whether any one of the outputs contains inline datum (provided as CBOR)
## Testing Mints
Testing mints with below APIs:
```tsx
txTester
.tokenMinted(
"eab3a1d125a3bf4cd941a6a0b5d7752af96fae7f5bcc641e8a0b6762",
"",
1,
);
```
1. `tokenMinted`: Checks if a specific token is minted in the transaction.
2. `onlyTokenMinted`: Checks if a specific token is minted in the transaction and that it is the only mint.
3. `policyOnlyMintedToken`: Checks if a specific token is minted in the transaction, ensuring that it is the only mint for the given policy ID.
4. `checkPolicyOnlyBurn`: Checks if a specific policy ID is burned in the transaction, ensuring that it is the only minting (i.e. burning item).
## Testing Time
Testing time with below APIs:
```tsx
txTester
.validBefore(beforeTimestamp)
.validAfter(afterTimestamp);
```
1. `validAfter`: Checks if the transaction is valid after a specified timestamp.
2. `validBefore`: Checks if the transaction is valid before a specified timestamp.
## Testing Signature
Testing time with below APIs:
```tsx
txTester
.keySigned("fa5136e9e9ecbc9071da73eeb6c9a4ff73cbf436105cf8380d1c525c");
```
1. `keySigned`: Checks if a specific key is signed in the transaction.
2. `oneOfKeysSigned`: Checks if any one of the specified keys is signed in the transaction.
3. `allKeysSigned`: Checks if all specified keys are signed in the transaction.
# Blueprints
URL: /apis/utilities/blueprints
Blueprints for script with either apply parameters or no parameters
***
title: "Blueprints"
description: "Blueprints for script with either apply parameters or no parameters"
icon: DocumentTextIcon
----------------------
import Link from "fumadocs-core/link";
In Mesh, we have in built `Blueprint` utility classes to help manipulating serialization and deserialization logic around Cardano smart contracts / validators. Now it is supporting the basic use case around 3 purposes - `Spending`,`Minting` and `Withdrawal`. You can either directly use the `Blueprint` utility classes imported from Mesh, or use the Cardano Bar from SIDAN Lab, which perform a comprehensive parsing of the CIP57 blueprint object into Mesh's type.
## Spending Script Blueprint
`SpendingBlueprint` is a class for handling spending blueprint particularly. You can provide `plutusVersion`, `networkId` and the potential `stakeKeyHash` for the spending validator address to initialized the class. After that, providing the `compiledCode` and parameters to finish the setup. The class then provide easy access to common script information:
* Script Hash
* Script Cbor
* Script Address
A Spending validator with no parameter, allows to provides only the `compiledCode` instead.
### Spending Script Blueprint - Apply parameter to script \[!toc]
Creates a spending script blueprint with apply parameter to script.
```tsx
import { SpendingBlueprint } from "@meshsdk/core";
const demoCompiledCode = "5906f401010032323232323232223225333005323232323253323300b3001300c37540042646464646464a66602260060022a66602860266ea8024540085854ccc044c01c00454ccc050c04cdd50048a8010b0b18089baa0081533300f30013010375400426464a64666024600860266ea80284c94ccc04cc014c050dd50008991919191919191919299980e1929998100008a5015333020302300114a22940cc88c8cc00400400c894ccc08c00452f5c026464a66604466ebcc048c090dd5180718121baa002005133026002330040040011330040040013027002302500137586018603c6ea8058c030c078dd51804180f1baa0091533301c001100214a02940cc00ccc008dd61802180e9baa01501a30063370666e08dd69803980e9baa00c018482827004cc008cc004dd61801980e1baa014300a301c3754016600a66e00dd69803180e1baa00b3330043756600c60386ea8c018c070dd5003a450048810022323300100100322533302000114bd6f7b63009991299980f99baf300f3021375400400a2646660020020046eacc030c088dd50019112999812801080089919980200218148019991191980080080291299981500089981599bb037520086e9800d2f5bded8c0264646464a66605666e400200084cc0bccdd81ba9008374c00e00a2a66605666e3c0200084c94ccc0b0c078c0b4dd500089981819bb037520126062605c6ea80040104010c94ccc0b14ccc0bc0045288a5014c0103d87a80001301b33030374c00297ae03233300100100800222253330310021001132333004004303500333223233001001005225333036001133037337606ea4010dd4001a5eb7bdb1804c8c8c8c94ccc0dccdc800400109981d99bb037520106ea001c01454ccc0dccdc7804001099299981c1815181c9baa00113303c337606ea4024c0f4c0e8dd5000802080219299981c18150008a60103d87a8000130273303c375000297ae03370000e00226607666ec0dd48011ba800133006006003375a60700066eb8c0d8008c0e8008c0e0004dd718180009bad3031001303300213302f337606ea4008dd3000998030030019bab302c003375c6054004605c00460580026eb8c090004dd5981280098138010800981100099801001181180091191980080099198008008019129998100008a5eb804c8ccc888c8cc00400400c894ccc098004400c4c8cc0a0dd3998141ba90063302830250013302830260014bd7019801801981500118140009bae301f00137566040002660060066048004604400244a66603e00229444c94ccc074c8cdc49bad3007001333008006375c601c0026eb8c028004dd618110010998018018008a5030220012301d301e301e00122232533301a3010301b37540022900009bad301f301c375400264a666034602060366ea8004530103d87a80001323300100137566040603a6ea8008894ccc07c004530103d87a80001323232325333020337220100042a66604066e3c0200084c03ccc090dd4000a5eb80530103d87a8000133006006003375a60420066eb8c07c008c08c008c084004c8cc004004010894ccc0780045300103d87a8000132323232533301f337220100042a66603e66e3c0200084c038cc08cdd3000a5eb80530103d87a8000133006006003375660400066eb8c078008c088008c08000494ccc058c02000452f5bded8c0264646600200297adef6c6022533301c00113301d337609801014000374c00697adef6c60132323232533301d33720910100002133021337609801014000374c00e00a2a66603a66e3d22100002133021337609801014000374c00e00626604266ec0dd48011ba6001330060060033756603c0066eb8c070008c080008c078004c8cc0040052f5bded8c044a66603600226603866ec13001014000375000697adef6c60132323232533301c33720910100002133020337609801014000375000e00a2a66603866e3d22100002133020337609801014000375000e00626604066ec0dd48011ba800133006006003375a603a0066eb8c06c008c07c008c0740048c068c06c004c060c054dd50008b19198008009bac30033015375401a44a66602e002298103d87a80001323253330163375e600c60306ea80080284c014cc0680092f5c026600800800260360046032002264a666026600a60286ea80044cc88c8cc00400400c894ccc068004528099299980c19b8f375c603a00400829444cc00c00c004c074004dd6180c180c980c980c980c980c980c980c980c980a9baa00d375c6030602a6ea800458c94ccc04cc014c050dd5000898011980b980c180a9baa0014bd700a60103d87a8000300230143754600460286ea800cdd2a40004602c002602860226ea800858dc3a4000602460260046022002601a6ea8008dc3a40042c601c601e004601a002601a0046016002600e6ea800452613656375a002ae6955ceaab9e5573eae815d0aba201";
// provide your staking part for the compiled address
const stakeHash = "9e8a6e5fcbbb5b84deefc71d7cb6319a3da9cc3d19765efb303647ef";
const blueprint = new SpendingBlueprint("V2", 0, stakeHash);
blueprint.paramScript(
demoCompiledCode,
mPubKeyAddress("aa048e4cc8a1e67e1d97ffbd4be614388014cbc2b2451527202943b6", "9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e6")],
"Mesh" // Mesh data type
);
const scriptHash = blueprint.hash;
const scriptCbor = blueprint.cbor;
const scriptAddress = blueprint.address;
```
### Spending Script blueprint - no parameter to script \[!toc]
Creates a spending script blueprint with no parameter to script.
```tsx
const blueprint = new SpendingBlueprint("V2", 0 , stakeHash);
blueprint.noParamScript(demoCompiledCode);
const scriptHash = blueprint.hash;
const scriptCbor = blueprint.cbor;
const scriptAddress = bluePrint.address;
;
```
## Minting Script Blueprint
`MintingBlueprint` is a class for handling minting blueprint particularly. You can provide `plutusVersion`, for the minting validator to initialize the class. After that, providing the `compiledCode` and parameters to finish the setup. The class then provide easy access to common script information:
* Policy ID (i.e Script Hash)
* Script Cbor
A Minting validator with no parameter, allows to provides only the `compiledCode` instead.
### Minting Script Blueprint - Apply parameter to script \[!toc]
Creates a Minting script blueprint with apply parameter to script.
```tsx
const demoCompiledCode = "5906f401010032323232323232223225333005323232323253323300b3001300c37540042646464646464a66602260060022a66602860266ea8024540085854ccc044c01c00454ccc050c04cdd50048a8010b0b18089baa0081533300f30013010375400426464a64666024600860266ea80284c94ccc04cc014c050dd50008991919191919191919299980e1929998100008a5015333020302300114a22940cc88c8cc00400400c894ccc08c00452f5c026464a66604466ebcc048c090dd5180718121baa002005133026002330040040011330040040013027002302500137586018603c6ea8058c030c078dd51804180f1baa0091533301c001100214a02940cc00ccc008dd61802180e9baa01501a30063370666e08dd69803980e9baa00c018482827004cc008cc004dd61801980e1baa014300a301c3754016600a66e00dd69803180e1baa00b3330043756600c60386ea8c018c070dd5003a450048810022323300100100322533302000114bd6f7b63009991299980f99baf300f3021375400400a2646660020020046eacc030c088dd50019112999812801080089919980200218148019991191980080080291299981500089981599bb037520086e9800d2f5bded8c0264646464a66605666e400200084cc0bccdd81ba9008374c00e00a2a66605666e3c0200084c94ccc0b0c078c0b4dd500089981819bb037520126062605c6ea80040104010c94ccc0b14ccc0bc0045288a5014c0103d87a80001301b33030374c00297ae03233300100100800222253330310021001132333004004303500333223233001001005225333036001133037337606ea4010dd4001a5eb7bdb1804c8c8c8c94ccc0dccdc800400109981d99bb037520106ea001c01454ccc0dccdc7804001099299981c1815181c9baa00113303c337606ea4024c0f4c0e8dd5000802080219299981c18150008a60103d87a8000130273303c375000297ae03370000e00226607666ec0dd48011ba800133006006003375a60700066eb8c0d8008c0e8008c0e0004dd718180009bad3031001303300213302f337606ea4008dd3000998030030019bab302c003375c6054004605c00460580026eb8c090004dd5981280098138010800981100099801001181180091191980080099198008008019129998100008a5eb804c8ccc888c8cc00400400c894ccc098004400c4c8cc0a0dd3998141ba90063302830250013302830260014bd7019801801981500118140009bae301f00137566040002660060066048004604400244a66603e00229444c94ccc074c8cdc49bad3007001333008006375c601c0026eb8c028004dd618110010998018018008a5030220012301d301e301e00122232533301a3010301b37540022900009bad301f301c375400264a666034602060366ea8004530103d87a80001323300100137566040603a6ea8008894ccc07c004530103d87a80001323232325333020337220100042a66604066e3c0200084c03ccc090dd4000a5eb80530103d87a8000133006006003375a60420066eb8c07c008c08c008c084004c8cc004004010894ccc0780045300103d87a8000132323232533301f337220100042a66603e66e3c0200084c038cc08cdd3000a5eb80530103d87a8000133006006003375660400066eb8c078008c088008c08000494ccc058c02000452f5bded8c0264646600200297adef6c6022533301c00113301d337609801014000374c00697adef6c60132323232533301d33720910100002133021337609801014000374c00e00a2a66603a66e3d22100002133021337609801014000374c00e00626604266ec0dd48011ba6001330060060033756603c0066eb8c070008c080008c078004c8cc0040052f5bded8c044a66603600226603866ec13001014000375000697adef6c60132323232533301c33720910100002133020337609801014000375000e00a2a66603866e3d22100002133020337609801014000375000e00626604066ec0dd48011ba800133006006003375a603a0066eb8c06c008c07c008c0740048c068c06c004c060c054dd50008b19198008009bac30033015375401a44a66602e002298103d87a80001323253330163375e600c60306ea80080284c014cc0680092f5c026600800800260360046032002264a666026600a60286ea80044cc88c8cc00400400c894ccc068004528099299980c19b8f375c603a00400829444cc00c00c004c074004dd6180c180c980c980c980c980c980c980c980c980a9baa00d375c6030602a6ea800458c94ccc04cc014c050dd5000898011980b980c180a9baa0014bd700a60103d87a8000300230143754600460286ea800cdd2a40004602c002602860226ea800858dc3a4000602460260046022002601a6ea8008dc3a40042c601c601e004601a002601a0046016002600e6ea800452613656375a002ae6955ceaab9e5573eae815d0aba201";
const blueprint = new MintingBlueprint("V2");
blueprint.paramScript(
demoCompiledCode,
[mPubKeyAddress('aa048e4cc8a1e67e1d97ffbd4be614388014cbc2b2451527202943b6' , '9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e6'), 100],
"Mesh"// Mesh data type
);
const policyId = blueprint.hash;
const scriptCbor = blueprint.cbor
```
### Minting Script blueprint - no parameter to script \[!toc]
Creates a Minting script blueprint with no parameter to script.
```tsx
const blueprint = new MintingBlueprint("V2");
blueprint.noParamScript(demoCompiledCode);
const policyId = bluePrint.hash
const scriptCbor = bluePrint.cbor
```
## Withdrawal Script Blueprint
`WithdrawalBlueprint` is a class for handling withdrawal blueprint particularly. You can provide `plutusVersion`, and `networkId` for the withdrawal validator to initialize the class. After that, providing the `compiledCode` and parameters to finish the setup. The class then provide easy access to common script information:
* Script Hash
* Script Cbor
* Reward Address
A withdrawal validator with no parameter, allows to provides only the `compiledCode` instead.
### Withdrawal Script Blueprint - Apply parameter to script \[!toc]
Creates a withdrawal script blueprint with apply parameter to script.
```tsx
import { WithdrawalBlueprint } from "@meshsdk/core";
const blueprint = new WithdrawalBlueprint("V2", 0);
blueprint.paramScript(
demoCompiledCode,
mPubKeyAddress('aa048e4cc8a1e67e1d97ffbd4be614388014cbc2b2451527202943b6', '9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e6'), 100],
"Mesh", // Mesh Data type
)
const scripthash = blueprint.hash;
const scriptCbor = blueprint.cbor;
const rewardAddress = blueprint.address;
```
### Withdrawal Script blueprint - No parameter to script \[!toc]
Creates a withdrawal script blueprint with no parameter to script
```tsx
const blueprint = new WithdrawalBlueprint("V2" ,0);
blueprint.noParamScript(demoCompiledCode);
const scriptHash = bluerint.hash
const scriptCbor = bluerint.cbor
const rewardAddress = blueprint.address;
```
# Deserializers
URL: /apis/utilities/deserializers
Parse CBOR or bech32 into objects
***
title: "Deserializers"
description: "Parse CBOR or bech32 into objects"
icon: ArrowTurnRightUpIcon
--------------------------
## Deserialize Address
Deserialize bech32 address into payment and staking parts, with visibility of whether they are script or key hash.
### Deserialize Address \[!toc]
Convert bech32 address to The deserialized address object
**Address:** `addr_test1qpvx0...93swx9`
```tsx
deserializeAddress('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9');
```
## Deserialize Datum
Deserialize a datum from a CBOR string to JSON object.
### Deserialize Datum \[!toc]
Deserialize a datum from a CBOR string to JSON object
**Datum**
`167a4a048d87fcee0425ed200615ff2356f472c6413472c6106b8c5da52e3fd0`
```tsx
deserializeDatum('167a4a048d87fcee0425ed200615ff2356f472c6413472c6106b8c5da52e3fd0');
```
## Deserialize Pool Id
Deserialize a script from a pool id to Ed25519 key hash.
### Deserialize Pool Id \[!toc]
Deserialize a script from a pool id to Ed25519 key hash
**Pool Id**
`pool107k26e3wrqxwghju2py40ngngx2qcu48ppeg7lk0cm35jl2aenx`
```tsx
deserializePoolId('pool107k26e3wrqxwghju2py40ngngx2qcu48ppeg7lk0cm35jl2aenx');
```
# Utilities
URL: /apis/utilities
Serializers, resolvers and data types for converting between different formats.
***
title: "Utilities"
description: "Serializers, resolvers and data types for converting between different formats."
icon: WrenchScrewdriverIcon
---------------------------
import {
ArrowRightIcon,
ArrowTurnRightDownIcon,
ArrowTurnRightUpIcon,
DocumentTextIcon,
CircleStackIcon
} from "@heroicons/react/24/solid";
}>
### Serializers \[!toc]
Encode objects into CBOR or bech32 format.
}>
### Deserializers \[!toc]
Parse CBOR or bech32 into objects.
}>
### Resolvers \[!toc]
Converts between different formats.
}>
### Data \[!toc]
Useful utilities to parse and manipulate data
}>
### Blueprints \[!toc]
Blueprints for script with either apply parameters or no parameters
# Resolvers
URL: /apis/utilities/resolvers
Converts between different formats.
***
title: "Resolvers"
description: "Converts between different formats."
icon: ArrowRightIcon
--------------------
import Link from "fumadocs-core/link";
## Resolve Private Key
Provide the mnemonic phrases and `resolvePrivateKey` will return a private key.
### Resolve Private Key \[!toc]
Convert mnemonic to private key
**Mnemonic**
```
[
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution",
"solution"
]
```
```tsx
resolvePrivateKey(["solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution"]);
```
## Resolve Transaction Hash
Provide a `cborTx`, `resolveTxHash` will return the transaction hash. This hash is useful for creating chain transactions.
### Resolve Transaction Hash \[!toc]
Convert transaction cborTx to transaction hash
```tsx
const tx = new Transaction({ initiator: wallet });
tx.sendLovelace('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', '1500000');
const unsignedTx = await tx.build();
const hash1 = resolveTxHash(unsignedTx);
const signedTx = await wallet.signTx(unsignedTx, false);
const hash2 = resolveTxHash(signedTx);
const txHash = await wallet.submitTx(signedTx);
// txHash == hash1 == hash2
```
## Resolve Data Hash
Converts datum into hash. Getting the hash is useful when you need to query for the UTXO that contain the assets you need for your transaction's input.
Explore Transaction to learn more about designing Datum, and learn how to query for UTXOs containing the datum hash.
### Resolve Data Hash \[!toc]
Convert datum into hash
**Datum:** `supersecretdatum`
```tsx
resolveDataHash('supersecretdatum');
```
## Resolve Native Script Hash
Converts NativeScript into hash.
### Resolve Native Script Hash \[!toc]
Convert NativeScript to hash
**Address**
`addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
```tsx
const keyHash = resolvePaymentKeyHash('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr');
const nativeScript: NativeScript = {
type: "all",
scripts: [
{
type: "sig",
keyHash: keyHash,
},
],
};
resolveNativeScriptHash(nativeScript);
```
## Resolve Script Hash
`resolveScriptHash` will return a script hash. For example, this is useful when you want to convert a script to a policy ID.
### Resolve Script Hash \[!toc]
Convert script to hash (like policy ID)
**script address**
`8200581c5867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f`
```tsx
resolveScriptHash('8200581c5867c3b8e27840f556ac268b781578b14c5661fc63ee720dbeab663f')
```
## Resolve Stake Address
Provide a wallet address, and `resolveRewardAddress` will return a staking address in bech32 format.
### Resolve Stake Address \[!toc]
Convert wallet address to staking address
**Address**
`addr_test1qpvx0sacuf...swx9`
```tsx
resolveRewardAddress('addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9');
```
## Resolve Fingerprint
Takes policy ID and asset name, and return asset fingerprint based on CIP-14.
## Resolve Asset Fingerprint \[!toc]
Convert asset policy ID and asset name to asset fingerprint.
**Policy ID**
`426117329844ccb3b0ba877220ff06a5bdf21eab3fb33e2f3a3f8e69`
**Asset Name**
`4d657368546f6b656e`
```tsx
resolveFingerprint(
'426117329844ccb3b0ba877220ff06a5bdf21eab3fb33e2f3a3f8e69',
'4d657368546f6b656e'
)
```
## Resolve Stake Key Hash
Provide a stake address, and `resolveStakeKeyHash` will return the pub key hash of the stake address. This key hash is useful for building the NativeScript.
## Resolve Stake Key Hash \[!toc]
Convert stake address to pub key hash
**Address**
`stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n`
```tsx
resolveStakeKeyHash('stake_test1uzw5mnt7g4xjgdqkfa80hrk7kdvds6sa4k0vvgjvlj7w8eskffj2n');
```
## Resolve Rep Id
Resolve Rep Id from scrip hash.
### Resolve Rep Id \[!toc]
Resolve rep id from scrip hash
```tsx
let script: NativeScript = {
type: "all",
scripts: [
{
type: "sig",
keyHash: 'aa048e4cc8a1e67e1d97ffbd4be614388014cbc2b2451527202943b6'
},
],
};
resolveScriptHashDRepId(resolveNativeScriptHash(script));
```
## Resolve Epoch Number
With `resolveEpochNo`, you can get the current epoch with:
```tsx
import { resolveEpochNo } from '@meshsdk/core';
const epoch = resolveEpochNo('preprod');
```
You can also provide date in `milliseconds` to get epoch in the past or the future. For example, get the epoch 1 year from now:
```tsx
import { resolveEpochNo } from '@meshsdk/core';
let oneYearFromNow = new Date();
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1);
const epoch = resolveEpochNo('preprod', oneYearFromNow.getTime());
```
### Resolve Epoch number \[!toc]
Get the epoch number for the network
**Select network**
`preprod`
```tsx
resolveEpochNo('preprod');
```
### Resolve Epoch number 1 year from now \[!toc]
Get the epoch number for the network 1 year from now
**Select network**
`preprod`
```tsx
let oneYearFromNow = new Date()
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1);
resolveEpochNo(userInput, oneYearFromNow.getTime());
```
## Resolve Slot Number
With `resolveSlotNo`, you can get the current slot number with:
```tsx
import { resolveSlotNo } from '@meshsdk/core';
const slot = resolveSlotNo('preprod');
```
You can also provide date in `milliseconds` to get slots in the past or the future. For example, get the slot number 1 year from now:
```tsx
import { resolveSlotNo } from '@meshsdk/core';
let oneYearFromNow = new Date();
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1);
const slot = resolveSlotNo('preprod', oneYearFromNow.getTime());
```
### Resolve Slot number \[!toc]
Get the Slot number for the network
**Select network**
`preprod`
```tsx
resolveSlotNo('preprod');
```
### Resolve Slot number 1 year from now \[!toc]
Get the Slot number for the network 1 year from now
**Select network**
`preprod`
```tsx
let oneYearFromNow = new Date()
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1);
resolveSlotNo(userInput, oneYearFromNow.getTime());
```
# Serializers
URL: /apis/utilities/serializers
Encode objects into CBOR or bech32 format.
***
title: "Serializers"
description: "Encode objects into CBOR or bech32 format."
icon: ArrowTurnRightDownIcon
----------------------------
import Link from "fumadocs-core/link";
In smart contract manipulations, serialization is a crucial process that encode data structures or objects into a format that can be easily stored or transmitted and later reconstructed. Below are utilities to help serialize various Cardano smart contracts components.
## Serialize Native Script
The function `serializeNativeScript` allows you to provide the `nativeScript` with an option of `networkId` and `stakeCredentialHash`, returns:
* Bech32 address
* Script Cbor
This example demonstrates how to derive the native script from the `pubKeyHash` with the `deserializeAddress` then serialize the native script to a bech32 address and script Cbor. To read more on deserializeAddress.
### Serialize Native Script \[!toc]
Serialize Native script into bech32 address
```tsx
import {
serializeNativeScript,
NativeScript,
deserializeAddress
} from "@meshsdk/core";
const { pubKeyHash: keyHash } = deserializeAddress(
'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
);
const nativeScript: NativeScript = {
type: "all",
scripts: [
{
type: "before",
slot: "99999999",
},
{
type: "sig",
keyHash: keyHash,
},
],
};
serializeNativeScript(nativeScript);
```
## Serialize Plutus Script
The function `serializePlutusScript` allows you to provide the `plutusScript` with an option of `networkId` and `stakeCredentialHash`, returns:
* Bech32 address
This example demonstrates how to derive and serialize a plutus script into a bech32 address.
### Serialize Plutus Script \[!toc]
Serialize Plutus script into bech32 address
```tsx
import { PlutusScript, serializePlutusScript } from "@meshsdk/core";
const plutusScript: PlutusScript = {
code: demoPlutusAlwaysSucceedScript,
version: "V2",
};
serializePlutusScript(plutusScript);
```
## Serialize Address Object
Serialize address in Cardano data JSON format into bech32 address with `serializeAddressObj()`.
First you need to create an address object with `pubKeyAddress()` or `scriptAddress()`.
`pubKeyAddress()` accepts the following parameters:
```tsx
pubKeyAddress(
bytes: string,
stakeCredential?: string,
isStakeScriptCredential?: boolean
): PubKeyAddress
```
`scriptAddress()` accepts the following parameters:
```tsx
scriptAddress(
bytes: string,
stakeCredential?: string,
isStakeScriptCredential?: boolean
): ScriptAddress
```
`serializeAddressObj()` accepts the following parameters:
```tsx
serializeAddressObj(
address: PubKeyAddress | ScriptAddress,
networkId?: number
): string
```
### Serialize Address Object \[!toc]
Serialize address in Cardano data JSON format into bech32 address
```tsx
import { pubKeyAddress, serializeAddressObj } from "@meshsdk/core";
const address = pubKeyAddress(
'aa048e4cc8a1e67e1d97ffbd4be614388014cbc2b2451527202943b6',
'9d4dcd7e454d2434164f4efb8edeb358d86a1dad9ec6224cfcbce3e6'
);
serializeAddressObj(address, 1);
```
# Transaction Basics
URL: /apis/txbuilder/basics
Working with transactions and its various options
***
title: "Transaction Basics"
description: "Working with transactions and its various options"
icon: PaperAirplaneIcon
-----------------------
import Link from 'fumadocs-core/link';
In the code snippet, you will find `txBuilder`, which is an instance of `MeshTxBuilder`, a powerful low-level APIs that allows you to build transactions. Learn how to initialize **MeshTxBuilder**.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
```
The `MeshTxBuilder` is a powerful interface where the higher level `Transaction` class is indeed a pre-built combination of the `MeshTxBuilder` APIs. With these lower level APIs, it builds the object to be passing to the serialization libraries like `cardano-sdk` and `Whisky SDK` to construct transactions.
In this page, we will cover how to initialize the `MeshTxBuilder` and the basic operations of building a transaction.
## Initialize Tx Builder
To start building an customized transaction, you need to first initialize `MeshTxBuilder`:
```tsx
import { BlockfrostProvider, MeshTxBuilder } from "@meshsdk/core";
const provider = new BlockfrostProvider('');
const txBuilder = new MeshTxBuilder({
fetcher: provider,
verbose: true,
});
```
The `MeshTxBuilder` instance has the following signature:
```tsx
{
fetcher?: IFetcher;
submitter?: ISubmitter;
evaluator?: IEvaluator;
serializer?: IMeshTxSerializer;
isHydra?: boolean;
params?: Partial;
verbose?: boolean;
}
```
There are 6 optional fields to pass in to initialized the lower level APIs instance:
* `serializer`: The default serializer is `CSLSerializer`. You can pass in your own serializer instance.
* `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 are `txIn`, `txInCollateral`, `spendingTxInReference`.
* `submitter`: It is used if you would like to use the `submitter` submitTx API directly from the instance.
* `evaluator`: It would perform redeemer execution unit optimization, returning error message in case of invalid transaction.
* `isHydra`: Use another set of default protocol parameters for building transactions.
* `params`: You can pass in the protocol parameters directly.
* `verbose`: Set to `true` to enable verbose logging.
## Send Value
Sending value with `MeshTxBuilder` come with the `.txOut()` endpoint:
```tsx
.txOut(address: string, amount: Asset[])
```
In order to send values (so as every transaction), we have to fund the transaction to do so. There are 2 ways to provide values in a transaction:
* Specifying which input to spend with
```tsx
.txIn(txHash: string, txIndex: number, amount?: Asset[], address?: string)
```
* Providing an array of UTxOs, and perform auto UTxO selection:
```tsx
.selectUtxosFrom(extraInputs: UTxO[])
```
Since the input and output values might not be the same, we have to specify the address (usually own's address) to receive change:
```tsx
.changeAddress(addr: string)
```
The following shows a simple example of building a transaction to send values with UTxO selection:
```tsx
txBuilder
.txOut(address, [{ unit: "lovelace", quantity: amount }])
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
```
### Send Value \[!toc]
Send assests to a recipient
**Address**: `addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
**Amount**: `1000000`
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.txOut('addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr', [{ unit: "lovelace", quantity: '1000000' }])
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Multi-signature Transaction
The main idea of a multi-signature (multisig) transaction is to have multiple signatures to authorize a transaction.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mint("1", policyId, stringToHex("MeshToken"))
.mintingScript(forgingScript)
.metadataValue(721, { [policyId]: { [assetName]: demoAssetMetadata } })
.changeAddress(address)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet1.signTx(unsignedTx, true);
const signedTx2 = await mintingWallet.signTx(signedTx, true);
const txHash = await wallet.submitTx(signedTx2);
```
In the above code snippet, we are signing the transaction with the user wallet and then signing the transaction with the minting wallet. The `signTx` function is used to sign the transaction. The second argument is a boolean value that indicates whether the transaction is a multi-signature transaction.
```tsx
await wallet.signTx(unsignedTx, true);
```
### Multi-signature Transaction \[!toc]
Create a multi-signature transaction. In this demo, we will create a transaction with two signatures, where one signature is from the user wallet and the other is from a minting wallet.
```tsx
const mintingWallet = new MeshWallet({
networkId: 0,
fetcher: provider,
submitter: provider,
key: {
type: "mnemonic",
words: ['your','mnemonic','here'],
},
});
const forgingScript = ForgeScript.withOneSignature(
await mintingWallet.getChangeAddress(),
);
const assetName = "MeshToken";
const policyId = resolveScriptHash(forgingScript);
const usedAddress = await wallet.getUsedAddresses();
const utxos = await wallet.getUtxos();
const address = usedAddress[0]!;
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mint("1", policyId, stringToHex("MeshToken"))
.mintingScript(forgingScript)
.metadataValue(721, { [policyId]: { [assetName]: demoAssetMetadata } })
.changeAddress(address)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx, true);
const signedTx2 = await mintingWallet.signTx(signedTx, true);
const txHash = await wallet.submitTx(signedTx2);
```
## Multi-signature Transaction with Native Script
Here is an example of creating a multi-signature (multisig) transaction with a native script, where you need to spend from a script address.
**Create native script**
First, we need to create a native script. In this example, we will create a native script with two signatures. That means we need to get the key hashes of the two wallets.
```tsx
const { pubKeyHash: keyHash1 } = deserializeAddress(walletAddress1);
const { pubKeyHash: keyHash2 } = deserializeAddress(walletAddress2);
```
Next, we will create a native script object with the two key hashes. The native script object will be used to create a multi-signature transaction.
```tsx
const nativeScript: NativeScript = {
type: "all",
scripts: [
{
type: "sig",
keyHash: keyHash1,
},
{
type: "sig",
keyHash: keyHash2,
},
],
};
```
The native script object is then serialized into a CBOR object and an address.
```tsx
const { address: scriptAddress, scriptCbor } =
serializeNativeScript(nativeScript);
```
**Create transaction**
Now that we have the native script, we can create a transaction with the script. We first need to get the UTXO from the script address.
```tsx
// get utxo from script
const utxos = await provider.fetchAddressUTxOs(scriptAddress);
const utxo = utxos[0];
// create tx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.txIn(
utxo.input.txHash,
utxo.input.outputIndex,
utxo.output.amount,
utxo.output.address,
)
.txInScript(scriptCbor)
.txOut(
"addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr",
[{ unit: "lovelace", quantity: "2000000" }],
)
.changeAddress(scriptAddress)
.selectUtxosFrom(utxos)
.complete();
```
Finally, we sign the transaction with the two wallets and submit the transaction.
```tsx
const signedTx1 = await wallet1.signTx(unsignedTx, true);
const signedTx2 = await wallet2.signTx(signedTx1, true);
const txHash = await wallet.submitTx(signedTx2);
```
## Build with Object
One alternative to use the lower level APIs is to build the transaction with JSON.
The following shows a simple example of building a transaction to send values to a recipient:
```tsx
const meshTxBody: Partial = {
outputs: [
{
address: address,
amount: [{ unit: "lovelace", quantity: amount }],
},
],
changeAddress: changeAddress,
extraInputs: utxos,
selectionConfig: {
threshold: "5000000",
strategy: "largestFirst",
includeTxFees: true,
},
};
const unsignedTx = await txBuilder.complete(meshTxBody);
```
## Coin selection
You can select UTxOs from a list of UTxOs using the `selectUtxosFrom` method. This method allows you to specify the conditions for selecting UTxOs. The method signature is as follows:
```tsx
selectUtxosFrom(
extraInputs: UTxO[]
strategy?: UtxoSelectionStrategy
threshold?: string
includeTxFees?: boolean
)
```
The second parameter of `selectUtxosFrom` is the strategy to be used for selecting UTxOs. There are 4 strategies (`UtxoSelectionStrategy`) available for selecting UTxOs:
* experimental
* keepRelevant
* largestFirst
* largestFirstMultiAsset
We may introduce more strategies in the future. Check the Mesh Docs for more details.
The `threshold` parameter is used to specify the minimum amount of lovelace to be selected. You may specify a larger amount to if the transactions requires it.
The last parameter is `includeTxFees` which is a boolean value to include transaction fees in the selection.
## Set Metadata - Taransaction message
Add messages / comments / memos as transaction metadata. This is useful for attaching additional information to a transaction. This is an example of setting metadata with transaction message.
```tsx
txBuilder
.metadataValue(label, metadata)
```
The specification for the individual strings follow the general design specification for JSON metadata, which is already implemented and in operation on the cardano blockchain. The used metadatum label is `674`: this number was chosen because it is the T9 encoding of the string `msg`. The message content has the key `msg`: and consists of an array of individual message-strings. The number of theses message-strings must be at least one for a single message, more for multiple messages/lines. Each of theses individual message-strings array entries must be at most 64 bytes when UTF-8 encoded.
### Transaction message \[!toc]
Add messages/comments/memos as transaction metadata
**Message (breakline for new line)**
```
Invoice-No: 1234567890
Customer-No: 555-1234
```
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const label = 674;
const metadata = {
msg: [
'Invoice-No: 1234567890',
'Customer-No: 555-1234',
],
});
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.changeAddress(changeAddress)
.metadataValue(label, metadata)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Set Required Signers
Sets the required signers for the transaction. This is useful when you want to include multiple signers, such as in a multi-signature transaction or smart contracts.
```tsx
txBuilder
.requiredSignerHash(pubKeyHash)
```
## 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:
```tsx
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 `invalidHereafter` and providing the `slot`, this means that if the transaction is submitted after after `slot` will not be valid.
```tsx
txBuilder
.invalidHereafter(Number(slot));
```
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 `invalidBefore` and providing the `slot`:
```tsx
txBuilder
.invalidBefore(Number(slot));
```
## Set Network
Sets the network to use, this is mainly to know the cost models to be used to calculate script integrity hash. You can set the network for the transaction with `setNetwork`.
\`
txBuilder.setNetwork(network: Network)
````
The network parameter is a string that can be one of the following:
```tsx
"testnet" | "preview" | "preprod" | "mainnet"
````
## Set Fee
Set the fee for the transaction.
```tsx
.setFee(fee: string)
```
The following shows a simple example of building a transaction to send values with UTxO selection:
```tsx
const unsignedTx = await txBuilder
.txOut(...)
.changeAddress(...)
.setFee("0")
.complete();
```
## Custom Protocol Parameter
Custom protocol parameters can be fetched from the provider and passed to the transaction builder. This is useful when the provider does not provide the protocol parameters, or when the user wants to use a custom set of parameters.
```tsx
const pp = await provider.fetchProtocolParameters();
const txBuilder = new MeshTxBuilder({
fetcher: provider,
params: pp,
});
```
# Governance Transactions
URL: /apis/txbuilder/governance
Transactions for participating in Cardano's on-chain governance
***
title: "Governance Transactions"
description: "Transactions for participating in Cardano's on-chain governance"
icon: ScaleIcon
---------------
import Link from 'fumadocs-core/link';
In **CIP-1694**, Cardano's on-chain governance system was proposed to allow the community to vote on proposals and protocol updates. This system is designed to be decentralized and transparent, allowing the community to have a say in the future of the network.
In the code snippet, you will find `txBuilder`, which is an instance of `MeshTxBuilder`, a powerful low-level APIs that allows you to build transactions. Learn how to initialize MeshTxBuilder
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
```
This page list the governance transactions that can be created using the Mesh SDK.
## Vote Delegation
Any wallet can delegate its voting power to another DRep. This is done by creating a vote delegation certificate and submitting it to the blockchain.
First we need to get the wallet information. This includes the UTXOs, the reward address, and the change address.
```tsx
const utxos = await wallet.getUtxos();
const rewardAddresses = await wallet.getRewardAddresses();
const rewardAddress = rewardAddresses[0];
const changeAddress = await wallet.getChangeAddress();
```
Next we need to select the UTXOs to use to pay for the transaction. We will select the UTXOs that have at least 5 ADA. Though the fee is less than 1 ADA.
We can now start building the transaction. We will add the selected UTXOs as inputs to the transaction. We will also add the vote delegation certificate to the transaction. The vote delegation certificate requires the DRep ID of the DRep to delegate to and the reward address of the delegator. Note that we would need to have at least 5 ADA for the certificate delegation, in the `selectUtxosFrom` we will configure 10 ADA as threshold buffer.
```tsx
txBuilder
.voteDelegationCertificate(
{
dRepId: dRepId,
},
rewardAddress,
)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
```
Finally we can build, sign the transaction and submit it to the blockchain.
```tsx
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
The transaction will be submitted to the blockchain and the DRep will be registered. The deposit will be taken from the DRep owner and the DRep will be added to the list of registered DReps.
## DRep Vote Delegation \[!toc]
Delegate your voting power to another DRep
**DRep ID**
`drep1yv4uesaj92wk8ljlsh4p7jzndnzrflchaz5fzug3zxg4naqkpeas3`
```tsx
const utxos = await wallet.getUtxos();
const rewardAddresses = await wallet.getRewardAddresses();
const rewardAddress = rewardAddresses[0];
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.voteDelegationCertificate(
{
dRepId: 'drep1yv4uesaj92wk8ljlsh4p7jzndnzrflchaz5fzug3zxg4naqkpeas3',
},
rewardAddress,
)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## DRep Registration
In Voltaire, stake credentials can delegate their stake to Decentralized Representatives (DReps) for voting, in addition to the current delegation to stake pools for block production. This DRep delegation will work similarly to the current stake delegation process, using on-chain certificates. Registering as a DRep will also follow the same process as stake registration.
However, registered DReps need to vote regularly to remain active. If a DRep does not vote for a set number of epochs (defined by the new protocol parameter, drepActivity), they are considered inactive and will not count towards the active voting stake. To become active again, DReps need to vote on governance actions or submit a DRep update certificate within the drepActivity period.
A DRep registration certificates include:
* a DRep ID
* a deposit
* an optional anchor
An anchor is a pair of:
* a URL to a JSON payload of metadata
* a hash of the contents of the metadata URL
First we need to get the DRep ID of the DRep we want to register. We can do this by calling `getDRep` method on the wallet. This will return the DRep object which contains the DRep ID.
```tsx
const dRep = await wallet.getDRep();
const dRepId = dRep.dRepIDCip105;
```
Next we need to get the hash of the anchor. We can do this by calling the `getMeshJsonHash` function. This function fetches the anchor from the given URL and returns the hash of the anchor.
```tsx
async function getMeshJsonHash(url: string) {
var drepAnchor = getFile(url);
const anchorObj = JSON.parse(drepAnchor);
return hashDrepAnchor(anchorObj);
}
const anchorUrl = "https://meshjs.dev/governance/meshjs.jsonld";
const anchorHash = await getMeshJsonHash(anchorUrl);
```
We can now build the transaction by adding the DRep registration certificate to the transaction. We also need to add the change address and the selected UTxOs to the transaction. Note that the deposit for registering a DRep is 500 ADA, we would set 505 ADA as UTxO selection threshold.
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.drepRegistrationCertificate(dRepId, {
anchorUrl: anchorUrl,
anchorDataHash: anchorHash,
})
.changeAddress(changeAddress)
.selectUtxosFrom(selectedUtxos);
```
Finally we can sign the transaction and submit it to the blockchain.
```tsx
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
The transaction will be submitted to the blockchain and the DRep will be registered. The deposit will be taken from the DRep owner and the DRep will be added to the list of registered DReps.
### DRep Registration \[!toc]
Register a DRep certificate and pay the deposit
**Anchor Url:** `eg: https://path.to/file-name.jsonld`
```tsx
const dRep = await wallet.getDRep();
const dRepId = dRep.dRepIDCip105;
const anchorUrl = '';
const anchorHash = await getMeshJsonHash(anchorUrl);
// get utxo to pay for the registration
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.drepRegistrationCertificate(dRepId, {
anchorUrl: anchorUrl,
anchorDataHash: anchorHash,
})
.changeAddress(changeAddress)
.selectUtxosFrom(utxos);
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## DRep Update
Updating a DRep is similar to registering.
We build the transaction by adding the DRep update certificate to the transaction, providing the change address and the UTxOs needed for the transaction's fees.
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.drepUpdateCertificate(dRepId, {
anchorUrl: anchorUrl,
anchorDataHash: anchorHash,
})
.changeAddress(utxos)
.selectUtxosFrom(selectedUtxos);
```
This transaction is an example of a successful DRep update for DRep ID.
### DRep Update \[!toc]
Update DRep metadata
**Anchor Url:** `eg: https://path.to/file-name.jsonld`
```tsx
const dRep = await wallet.getDRep();
const dRepId = dRep.dRepIDCip105;
const anchorUrl = '';
const anchorHash = await getMeshJsonHash(anchorUrl);
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.drepUpdateCertificate(dRepId, {
anchorUrl: anchorUrl,
anchorDataHash: anchorHash,
})
.changeAddress(changeAddress)
.selectUtxosFrom(utxos);
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## DRep Retirement
A DRep is retired right away when the blockchain accepts a retirement certificate. The deposit is refunded immediately as part of the transaction that submits the retirement certificate, just like how deposits are returned when a stake credential is unregistered.
First we need to get the DRep ID of the DRep we want to retire. We can do this by calling `getDRep` method on the wallet. This will return the DRep object which contains the DRep ID.
```tsx
const dRep = await wallet.getDRep();
const dRepId = dRep.dRepIDCip105;
```
We then need to initialize the transaction builder by creating a new instance of `MeshTxBuilder`. We need to pass the blockchain provider to the constructor.
```tsx
const changeAddress = await wallet.getChangeAddress();
const utxos = await wallet.getUtxos();
const provider = new BlockfrostProvider('');
```
We can now build the transaction by adding the UTxOs as inputs to the transaction and adding the DRep deregistration certificate to the transaction.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.drepDeregistrationCertificate(dRepId)
.selectUtxosFrom(selectedUtxos)
.changeAddress(changeAddress);
const unsignedTx = await txBuilder.complete();
```
Finally we can sign the transaction and submit it to the blockchain.
```tsx
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
The transaction will be submitted to the blockchain and the DRep will be retired. The deposit will be refunded to the DRep owner.
### DRep Retirement \[!toc]
Retire a DRep certificate and return the deposit
```tsx
const dRep = await wallet.getDRep();
const dRepId = dRep.dRepIDCip105;
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.drepDeregistrationCertificate(dRepId)
.selectUtxosFrom(utxos)
.changeAddress(changeAddress);
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Vote
Each vote transaction consists of the following:
* a governance action ID
* a role - constitutional committee member, DRep, or SPO
* a governance credential witness for the role
* an optional anchor (as defined above) for information that is relevant to the vote
* a 'Yes'/'No'/'Abstain' vote
First, we get the DRep ID from the wallet, the DRep ID voting for this governance action.
```tsx
const dRep = await wallet.getDRep();
const dRepId = dRep.dRepIDCip105;
```
Then we get the utxos and the change address from the wallet.
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
```
We then create the vote transaction using the `vote()` function.
```tsx
txBuilder
.vote(
{
type: "DRep",
drepId: dRepId,
},
{
txHash: 'aff2909f8175ee02a8c1bf96ff516685d25bf0c6b95aac91f4dfd53a5c0867cc',
txIndex: 0,
},
{
voteKind: "Yes",
},
)
.selectUtxosFrom(utxos)
.changeAddress(changeAddress);
```
The `vote()` takes 3 parameters:
* `voter` - The voter, can be a Constitutional Commitee, a DRep or a StakePool
* `govActionId` - The transaction hash and transaction id of the governance action
* `votingProcedure` - The voting kind (Yes, No, Abstain) with an optional anchor
Check the full documentation or the source code for more details.
Finally, we sign the transaction and submit it to the blockchain.
```tsx
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
You can check here a successful vote transaction for this governance action.
Here is another example of a vote transaction:
```tsx
txBuilder
.changeAddress(
"addr_test1qpsmz8q2xj43wg597pnpp0ffnlvr8fpfydff0wcsyzqyrxguk5v6wzdvfjyy8q5ysrh8wdxg9h0u4ncse4cxhd7qhqjqk8pse6",
)
.txIn(
"2cb57168ee66b68bd04a0d595060b546edf30c04ae1031b883c9ac797967dd85",
3,
[
{
unit: "lovelace",
quantity: "9891607895",
},
],
"addr_test1vru4e2un2tq50q4rv6qzk7t8w34gjdtw3y2uzuqxzj0ldrqqactxh",
)
.vote(
{
type: "DRep",
drepId: "drep1j6257gz2swty9ut46lspyvujkt02pd82am2zq97p7p9pv2euzs7",
},
{
txHash:
"2cb57168ee66b68bd04a0d595060b546edf30c04ae1031b883c9ac797967dd85",
txIndex: 3,
},
{
voteKind: "Yes",
anchor: {
anchorUrl: "https://path-to.jsonld",
anchorDataHash:
"2aef51273a566e529a2d5958d981d7f0b3c7224fc2853b6c4922e019657b5060",
},
},
)
```
And another example of a vote transaction with a Plutus script and a redeemer:
```tsx
txBuilder
.changeAddress(
"addr_test1qpsmz8q2xj43wg597pnpp0ffnlvr8fpfydff0wcsyzqyrxguk5v6wzdvfjyy8q5ysrh8wdxg9h0u4ncse4cxhd7qhqjqk8pse6",
)
.txIn(
"2cb57168ee66b68bd04a0d595060b546edf30c04ae1031b883c9ac797967dd85",
3,
[
{
unit: "lovelace",
quantity: "9891607895",
},
],
"addr_test1vru4e2un2tq50q4rv6qzk7t8w34gjdtw3y2uzuqxzj0ldrqqactxh",
)
.txInCollateral(
"2cb57168ee66b68bd04a0d595060b546edf30c04ae1031b883c9ac797967dd85",
3,
[
{
unit: "lovelace",
quantity: "9891607895",
},
],
"addr_test1vru4e2un2tq50q4rv6qzk7t8w34gjdtw3y2uzuqxzj0ldrqqactxh",
)
.votePlutusScriptV3()
.vote(
{
type: "DRep",
drepId: resolveScriptHashDRepId(
resolveScriptHash(
applyCborEncoding(
"5834010100323232322533300232323232324a260106012004600e002600e004600a00260066ea8004526136565734aae795d0aba201",
),
"V3",
),
),
},
{
txHash:
"2cb57168ee66b68bd04a0d595060b546edf30c04ae1031b883c9ac797967dd85",
txIndex: 3,
},
{
voteKind: "Yes",
anchor: {
anchorUrl: "https://path-to.jsonld",
anchorDataHash:
"2aef51273a566e529a2d5958d981d7f0b3c7224fc2853b6c4922e019657b5060",
},
},
)
.voteScript(
applyCborEncoding(
"5834010100323232322533300232323232324a260106012004600e002600e004600a00260066ea8004526136565734aae795d0aba201",
),
)
.voteRedeemerValue("")
```
### Vote \[!toc]
Vote on a governance action
```tsx
const dRep = await wallet.getDRep();
const dRepId = dRep.dRepIDCip105;
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.vote(
{
type: "DRep",
drepId: dRepId,
},
{
txHash: 'aff2909f8175ee02a8c1bf96ff516685d25bf0c6b95aac91f4dfd53a5c0867cc',
txIndex: 0,
},
{
voteKind: "Yes",
},
)
.selectUtxosFrom(utxos)
.changeAddress(changeAddress);
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
# Transaction Builder
URL: /apis/txbuilder
Build transactions with Cardano-CLI like APIs
***
title: "Transaction Builder"
description: "Build transactions with Cardano-CLI like APIs"
icon: BanknotesIcon
-------------------
import {
ArrowsPointingInIcon,
FireIcon,
NewspaperIcon,
PaperAirplaneIcon,
ScaleIcon,
} from "@heroicons/react/24/solid";
}>
## Transaction Basics
Working with transactions and its various options
}>
## Mint and Burn Assets
Minting and burning assets with Native Script and Plutus Script
}>
## Smart Contracts
Transactions to work with smart contracts
}>
## Staking Transactions
Transactions for delegating ADA and managing stakepools
}>
## Governance Transactions
Transactions for participating in Cardano's on-chain governance
# Mint and Burn Assets
URL: /apis/txbuilder/minting
Minting and burning assets with Native Script and Plutus Script
***
title: "Mint and Burn Assets"
description: "Minting and burning assets with Native Script and Plutus Script"
icon: FireIcon
--------------
import Link from "fumadocs-core/link";
Minting and burning assets with Native Script and Plutus Script
Minting and burning assets is a common operation in blockchain applications. In the Cardano ecosystem, minting and burning are achieved through Native Scripts and Plutus Scripts.
To view a video demonstration of this feature of the MeshSDK, navigate to the video guide Mint an NFT Collection.
In the code snippet, you will find `txBuilder`, which is an instance of `MeshTxBuilder`, a powerful low-level APIs that allows you to build transactions. Learn how to initialize MeshTxBuilder.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
```
In this page, you will find the APIs to create transactions for minting and burning assets.
## Minting with One Signature
In this section, we will see how to mint native assets with a `MeshTxBuilder`. For minting assets with smart contract, visit MeshTxBuilder - Smart Contract - Minting Assets with Smart Contract.
Firstly, we need to define the `forgingScript` with `ForgeScript`. We use the first wallet address as the "minting address" (you can use other addresses).
```tsx
const changeAddress = await wallet.getChangeAddress();
const forgingScript = ForgeScript.withOneSignature(changeAddress);
```
Then, we define the metadata.
```tsx
const demoAssetMetadata = {
name: "Mesh Token",
image: "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
mediaType: "image/jpg",
description: "This NFT was minted by Mesh (https://meshjs.dev/).",
};
const policyId = resolveScriptHash(forgingScript);
const tokenName = "MeshToken";
const tokenNameHex = stringToHex(tokenName);
const metadata = { [policyId]: { [tokenName]: { ...demoAssetMetadata } } };
```
Finally, we create a transaction and mint the asset with the lower level APIs.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.txIn(utxo.input.txHash, utxo.input.outputIndex)
.mint("1", policyId, tokenName)
.mintingScript(forgingScript)
.changeAddress(changeAddress)
.complete();
```
### Mint Asset
Mint an asset with a ntive script
```tsx
import { MeshTxBuilder, ForgeScript, resolveScriptHash, stringToHex } from '@meshsdk/core';
import type { Asset } from '@meshsdk/core';
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const forgingScript = ForgeScript.withOneSignature(changeAddress);
const demoAssetMetadata = {
name: "Mesh Token",
image: "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
mediaType: "image/jpg",
description: "This NFT was minted by Mesh (https://meshjs.dev/).",
};
const policyId = resolveScriptHash(forgingScript);
const tokenName = "MeshToken";
const tokenNameHex = stringToHex(tokenName);
const metadata = { [policyId]: { [tokenName]: { ...demoAssetMetadata } } };
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mint("1", policyId, tokenNameHex)
.mintingScript(forgingScript)
.metadataValue(721, metadata)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Minting Multiple Assets
Minting multiple assets with a single transaction is a common operation in blockchain applications. Like minting single assets, you can mint multiple assets by calling `mint()` and `mintingScript` multiple times.
```tsx
const metadata = {};
metadata[policyId] = {};
for (let i = 1; i < 3; i++) {
const tokenName = `MeshToken${i}`;
const tokenNameHex = stringToHex(tokenName);
metadata[policyId][tokenName] = {
...demoAssetMetadata,
name: tokenName,
};
txBuilder.mint("1", policyId, tokenNameHex);
txBuilder.mintingScript(forgingScript);
}
```
You appending the metadata into one object and pass it to `metadataValue()` method.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.metadataValue(721, metadata)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos);
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
### Mint Multiple Assets \[!toc]
Mint multiple assets with a single transaction
```tsx
import { MeshTxBuilder, ForgeScript, resolveScriptHash, stringToHex } from '@meshsdk/core';
import type { Asset } from '@meshsdk/core';
const { wallet, connected } = useWallet();
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const forgingScript = ForgeScript.withOneSignature(changeAddress);
const policyId = resolveScriptHash(forgingScript);
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const metadata = {};
metadata[policyId] = {};
for (let i = 1; i < 3; i++) {
const tokenName = `MeshToken${i}`;
const tokenNameHex = stringToHex(tokenName);
metadata[policyId][tokenName] = {
...demoAssetMetadata,
name: tokenName,
};
txBuilder.mint("1", policyId, tokenNameHex);
txBuilder.mintingScript(forgingScript);
}
txBuilder
.metadataValue(721, metadata)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos);
const unsignedTx = await txBuilder.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Burning assets
Like minting assets, we need to define the `forgingScript` with `ForgeScript`. We use the first wallet address as the "minting address". Note that, assets can only be burned by its minting address.
```tsx
const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];
const forgingScript = ForgeScript.withOneSignature(address);
```
Then, we resolve the policy ID and hex of token name, setting set `txBuilder.mint("-1", policyId, tokenNameHex)`
```tsx
const policyId = resolveScriptHash(forgingScript);
const tokenNameHex = stringToHex("MeshToken");
```
Finally, we create a transaction and burn the asset with the lower level APIs.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mint("-1", policyId, tokenNameHex)
.mintingScript(forgingScript)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
```
### Burn Native Assets \[!toc]
Burn native assets
**Asset Unit**
`d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
```tsx
import { ForgeScript, resolveScriptHash, stringToHex } from "@meshsdk/core";
import { useWallet } from "@meshsdk/react";
const { wallet, connected } = useWallet();
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const forgingScript = ForgeScript.withOneSignature(changeAddress);
const policyId = resolveScriptHash(forgingScript);
const tokenNameHex = stringToHex("MeshToken");
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mint("-1", policyId, tokenNameHex)
.mintingScript(forgingScript)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Minting Assets with Native Script
The above minting and burning one signature are indeed the mint and burn with native script examples. Here we would explain the logic you need to know for native script minting.
With `MeshTxBuilder`, you just need `.mint()` and provide script to mint or burn native script tokens:
```tsx
txBuilder
.mint("1", policyId, tokenNameHex)
.mintingScript(forgingScript)
```
On top on these 2 core logics, you can attach metadata if needed with `.metadataValue()`, and construct the transaction as needed.
### Mint Assets with Native Script \[!toc]
Mint native assets with Native Script
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const { pubKeyHash: keyHash } = deserializeAddress(changeAddress);
const nativeScript: NativeScript = {
type: "all",
scripts: [
{
type: "before",
slot: "99999999",
},
{
type: "sig",
keyHash: keyHash,
},
],
};
const forgingScript = ForgeScript.fromNativeScript(nativeScript);
const policyId = resolveScriptHash(forgingScript);
const tokenName = "MeshToken";
const tokenNameHex = stringToHex(tokenName);
const metadata = { [policyId]: { [tokenName]: { ...demoAssetMetadata } } };
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mint("1", policyId, tokenNameHex)
.mintingScript(forgingScript)
.metadataValue(721, metadata)
.changeAddress(changeAddress)
.invalidHereafter(99999999)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Minting Assets with Plutus Script
Minting Plutus tokens with `MeshTxBuilder` starts with anyone of the below script version indicators:
```tsx
.mintPlutusScriptV1()
.mintPlutusScriptV2()
.mintPlutusScriptV3()
```
Followed by specifying the minting information:
```tsx
.mint(quantity: string, policy: string, name: string)
```
Similar to unlocking assets, minting or burning Plutus tokens require providing redeemer and scripts. However, no datum information is needed in minting or burning.
**Script of the token**
The actual script can be either provided by transaction builder or referenced from an UTxO onchain.
* (i) Reference script
```tsx
.mintTxInReference(txHash: string, txIndex: number)
```
* (ii) Supplying script
```tsx
.mintingScript(scriptCbor: string)
```
**Redeemer of the mint**
Redeemer can be provided in different **data types**. If your MeshTxBuilder does not include an `evaluator` instance, you can also provide your budget for the unlock with this redeemer endpoint
```tsx
.mintRedeemerValue(redeemer: Data | object | string, type: "Mesh" | "CBOR" | "JSON", exUnits?: Budget)
```
### Mint Assets with Plutus Script \[!toc]
Mint native assets with Plutus Script. For this example, the Plutus script expects a data field of 'mesh'.
**Redeemer value:** `mesh`
```tsx
const utxos = await wallet.getUtxos();
const collateral: UTxO = (await wallet.getCollateral())[0]!;
const changeAddress = await wallet.getChangeAddress();
const policyId = resolveScriptHash(demoPlutusMintingScript, "V2");
const tokenName = 'mesh';
const tokenNameHex = stringToHex(tokenName);
const metadata = { [policyId]: { [tokenName]: { ...demoAssetMetadata } } };
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mintPlutusScriptV2()
.mint("1", policyId, tokenNameHex)
.mintingScript(demoPlutusMintingScript)
.mintRedeemerValue(mConStr0(['mesh']))
.metadataValue(721, metadata)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.txInCollateral(
collateral.input.txHash,
collateral.input.outputIndex,
collateral.output.amount,
collateral.output.address,
)
.complete();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
## Minting Assets with CIP-68 Metadata standard
Minting CIP-68 tokens with `MeshTxBuilder` means 2 consecutive sets of minting APIs. The first is to mint the 100 token, and the second is the mint the 222 tokens:
```tsx
txBuilder
.mintPlutusScriptV2()
.mint("1", policyId, CIP68_100(tokenNameHex))
.mintingScript(scriptCode)
.mintRedeemerValue(mConStr0([]))
.mintPlutusScriptV2()
.mint("1", policyId, CIP68_222(tokenNameHex))
.mintingScript(scriptCode)
.mintRedeemerValue(mConStr0([]))
```
A side note, Mesh also provides the utility function of `CIP68_100(tokenNameHex: string)` and `CIP68_222(tokenNameHex: string)` to help easily construct the token names as needed. So you dont have to memorize the prefix bytes to correctly mint the CIP68-compliant tokens.
### Mint Assets with CIP68 metadata standard \[!toc]
Mint assets with CIP68 metadata standard where two assets are issued, one referencing the other user token.
**Token Name:** `Test1`
```tsx
const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];
if (address === undefined) {
throw "Address not found";
}
const userTokenMetadata = {
name: userInput,
image: "ipfs://QmRzicpReutwCkM6aotuKjErFCUD213DpwPq6ByuzMJaua",
mediaType: "image/jpg",
description: "Hello world - CIP68",
};
const alawysSucceedPlutusScript: PlutusScript = {
code: demoPlutusAlwaysSucceedScript,
version: "V1",
};
const { address: scriptAddress } = serializePlutusScript(
alawysSucceedPlutusScript,
);
const utxos = await wallet.getUtxos();
if (!utxos || utxos.length <= 0) {
throw "No UTxOs found in wallet";
}
const scriptCode = applyParamsToScript(oneTimeMintingPolicy, [
mTxOutRef(utxos[0]?.input.txHash!, utxos[0]?.input.outputIndex!),
]);
const collateral: UTxO = (await wallet.getCollateral())[0]!;
const changeAddress = await wallet.getChangeAddress();
const policyId = resolveScriptHash(scriptCode, "V2");
const tokenName = 'Test1';
const tokenNameHex = stringToHex(tokenName);
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.txIn(
utxos[0]?.input.txHash!,
utxos[0]?.input.outputIndex!,
utxos[0]?.output.amount!,
utxos[0]?.output.address!,
)
.mintPlutusScriptV2()
.mint("1", policyId, CIP68_100(tokenNameHex))
.mintingScript(scriptCode)
.mintRedeemerValue(mConStr0([]))
.mintPlutusScriptV2()
.mint("1", policyId, CIP68_222(tokenNameHex))
.mintingScript(scriptCode)
.mintRedeemerValue(mConStr0([]))
.txOut(scriptAddress, [
{ unit: policyId + CIP68_100(tokenNameHex), quantity: "1" },
])
.txOutInlineDatumValue(metadataToCip68(userTokenMetadata))
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.txInCollateral(
collateral.input.txHash,
collateral.input.outputIndex,
collateral.output.amount,
collateral.output.address,
)
.complete();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
## Minting Royalty Token
Royalty tokens is a special type of token that allows the creator to collect a royalty fee, this proposed standard will allow for uniform royalties' distributions across the secondary market space. Read CIP-27 for more information.
The implementation of royalty tokens is very simple, minting a token with `777` label, with "rate" and "addr" in the metadata.
Here is the example of the metadata:
```tsx
const assetMetadata = {
rate: '0.2',
addr: 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr'
};
```
### Mint Native Assets \[!toc]
Mint native assets with ForgeScript
**Rate:** `0.2`
**Address:** `addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr`
```tsx
const utxos = await wallet.getUtxos();
const usedAddress = await wallet.getUsedAddresses();
const address = usedAddress[0];
if (address === undefined) {
throw "No address found";
}
const forgingScript = ForgeScript.withOneSignature(address);
const policyId = resolveScriptHash(forgingScript);
const assetMetadata: RoyaltiesStandard = {
rate: '0.2',
address: 'addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr',
};
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mint("1", policyId, "")
.mintingScript(forgingScript)
.metadataValue(777, assetMetadata)
.changeAddress(address)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
# Smart Contracts
URL: /apis/txbuilder/smart-contracts
Transactions to work with smart contracts
***
title: "Smart Contracts"
description: "Transactions to work with smart contracts"
icon: NewspaperIcon
-------------------
import Link from "fumadocs-core/link";
In this guide, you will understand all logics you need to know for interacting with smart contracts with `MeshTxBuilder`.
In the code snippet, you will find `txBuilder`, which is an instance of `MeshTxBuilder`, a powerful low-level APIs that allows you to build transactions. Learn how to initialize MeshTxBuilder.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
```
In Cardano, whenever you need the nodes' computing power to execute a smart contract, you need to provide collateral to prevent spamming. You will see this is everywhere when script execution is needed in below's examples, and here's how you can do so:
```tsx
txBuilder
.txInCollateral(txHash: string, txIndex: number, amount?: Asset[], address?: string)
```
## Lock Assets
Locking assets meaning sending value to a script address with datum.
Same as `Transaction` demo, we will lock selected assets from your wallet in an `always succeed` smart contract. We use one API to represent sending value, another API to represent attaching datum to complete the locking assets process:
```tsx
// For inline datumtxBuilder
.txOut(address, assets)
.txOutInlineDatumValue(data)
```
```tsx
// For datum hashtxBuilder
.txOut(address, assets)
.txOutDatumHashValue(data)
```
The lower level APIs support providing your datum in all Mesh `Data` (default), JSON and CBOR representations. For details and helper utilities, please check Data section.
```tsx
// For inline datum provided in JSONtxBuilder
.txOut(address, assets)
.txOutInlineDatumValue(jsonData, "JSON")
```
### Lock Assets \[!toc]
Lock assets in a Plutus script
**Asset unit**
`d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
**Datum:** `meshsecretcode`
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const script: PlutusScript = {
code: demoPlutusAlwaysSucceedScript,
version: "V2",
};
const { address: scriptAddress } = serializePlutusScript(script);
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.txOut(scriptAddress, [{ unit: "d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e", quantity: "1" }])
.txOutInlineDatumValue("meshsecretcode")
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Unlock Assets
Unlocking with `MeshTxBuilder` starts with anyone of the below script version indicators:
```tsx
.spendingPlutusScriptV1()
.spendingPlutusScriptV2()
.spendingPlutusScriptV3()
```
Followed by specifying the exact script input to spend with:
```tsx
.txIn(txHash: string, txIndex: number, amount?: Asset[], address?: string)
```
In Cardano, if you want to unlock assets from a script address, you have to provide 3 other necessary information apart from `.txIn()` itself. They are:
* Actual script
* Datum of the input
* Redeemer of the unlock
**Actual script**
The actual script can be either provided by transaction builder or referenced from an UTxO onchain.
* (i) Reference script
```tsx
.spendingTxInReference()
```
* (ii) Supplying script
```tsx
.txInScript(scriptCbor: string)
```
**Datum of the input**
Similar to script, datum can also either be provided by transaction builder or as inline datum.
* (i) Referencing inline datum
```tsx
.txInInlineDatumPresent()
```
* (ii) Supplying datum
```tsx
.txInDatumValue(datum: Data | object | string, type?: "Mesh" | "CBOR" | "JSON")
```
**Redeemer of the unlock**
Redeemer can be provided in different data types. If your MeshTxBuilder does not include an `evaluator` instance, you can also provide your budget for the unlock with this redeemer endpoint
```tsx
.txInRedeemerValue(redeemer: Data | object | string, type: "Mesh" | "CBOR" | "JSON", exUnits?: Budget)
```
An example of complete set of endpoints to unlock assets from a script address:
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
txBuilder
.spendingPlutusScriptV2()
.txIn(txHash: string, txIndex: number, amount?: Asset[], address?: string)
.txInInlineDatumPresent() // or .txInDatumValue(datum: Data | string | object)
.txInRedeemerValue(redeemer: Data | object | string, type?: string, exUnits?: Budget)
.spendingTxInReference(txHash: string, txIndex: number, spendingScriptHash?: string) // or supplying script
```
### Unlock Assets \[!toc]
Unlock assets in a Plutus script
**Asset unit**
`d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc172555274d657368546f6b656e`
**Datum:** `meshsecretcode`
```tsx
const utxos = await wallet.getUtxos();
const collateral = await wallet.getCollateral();
const changeAddress = await wallet.getChangeAddress();
const script: PlutusScript = {
code: demoPlutusAlwaysSucceedScript,
version: "V2",
};
const { address: scriptAddress } = serializePlutusScript(script);
const assetUtxo = await fetchAssetUtxo({
address: scriptAddress,
asset: userInput,
datum: userInput2,
});
if (assetUtxo === undefined) {
throw "Asset UTXO not found";
}
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.spendingPlutusScriptV2()
.txIn(assetUtxo.input.txHash, assetUtxo.input.outputIndex)
.txInInlineDatumPresent()
.txInRedeemerValue(mConStr0([]))
.txInScript(demoPlutusAlwaysSucceedScript)
.changeAddress(changeAddress)
.txInCollateral(
collateral[0]?.input.txHash!,
collateral[0]?.input.outputIndex!,
collateral[0]?.output.amount!,
collateral[0]?.output.address!,
)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Minting Assets with Plutus Script
Minting Plutus tokens with `MeshTxBuilder` starts with anyone of the below script version indicators:
```tsx
.mintPlutusScriptV1()
.mintPlutusScriptV2()
.mintPlutusScriptV3()
```
Followed by specifying the minting information:
```tsx
.mint(quantity: string, policy: string, name: string)
```
Similar to unlocking assets, minting or burning Plutus tokens require providing redeemer and scripts. However, no datum information is needed in minting or burning.
**Script of the token**
The actual script can be either provided by transaction builder or referenced from an UTxO onchain.
* (i) Reference script
```tsx
.mintTxInReference(txHash: string, txIndex: number)
```
* (ii) Supplying script
```tsx
.mintingScript(scriptCbor: string)
```
**Redeemer of the mint**
Redeemer can be provided in different data types. If your MeshTxBuilder does not include an `evaluator` instance, you can also provide your budget for the unlock with this redeemer endpoint
```tsx
.mintRedeemerValue(redeemer: Data | object | string, type: "Mesh" | "CBOR" | "JSON", exUnits?: Budget)
```
### Mint Assets with Plutus Script \[!toc]
Mint native assets with Plutus Script. For this example, the Plutus script expects a data field of 'mesh'.
**Redeemer value:** `mesh`
```tsx
const utxos = await wallet.getUtxos();
const collateral: UTxO = (await wallet.getCollateral())[0]!;
const changeAddress = await wallet.getChangeAddress();
const policyId = resolveScriptHash(demoPlutusMintingScript, "V2");
const tokenName = 'mesh';
const tokenNameHex = stringToHex(tokenName);
const metadata = { [policyId]: { [tokenName]: { ...demoAssetMetadata } } };
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.mintPlutusScriptV2()
.mint("1", policyId, tokenNameHex)
.mintingScript(demoPlutusMintingScript)
.mintRedeemerValue(mConStr0(['mesh']))
.metadataValue(721, metadata)
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.txInCollateral(
collateral.input.txHash,
collateral.input.outputIndex,
collateral.output.amount,
collateral.output.address,
)
.complete();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
## Send Reference Scripts Onchain
For all smart contract executions, you have option to provide script as referencing onchain. To do so, you must send the script onchain first. You can attach the script like attaching datum to a output with this:
```tsx
.txOutReferenceScript(scriptCbor: string, version?: LanguageVersion)
```
### Send Reference Script \[!toc]
Provide script as referencing onchain
```tsx
const utxos = await wallet.getUtxos();
const changeAddress = await wallet.getChangeAddress();
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.txOut("addr_test1vpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0c7e4cxr", [])
.txOutReferenceScript("4e4d01000033222220051200120011", "V2")
.changeAddress(changeAddress)
.selectUtxosFrom(utxos)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
# Staking Transactions
URL: /apis/txbuilder/staking
Transactions for delegating ADA and managing stakepools
***
title: "Staking Transactions"
description: "Transactions for delegating ADA and managing stakepools"
icon: ArrowsPointingInIcon
--------------------------
In the code snippet, you will find `txBuilder`, which is an instance of `MeshTxBuilder`, a powerful low-level APIs that allows you to build transactions. Learn how to initialize MeshTxBuilder.
```tsx
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
```
## Register Stake Address
Same as Transaction, with `MeshTxBuilder` you have to register a stake address before delegate to stakepools. Here's the 2 APIs you need:
```tsx
txBuilder
.registerStakeCertificate(rewardAddress)
.delegateStakeCertificate(rewardAddress, poolIdHash)
```
Since we need to provide the deserilized hash of pool id, we can use the following util to get it:
```tsx
const poolIdHash = deserializePoolId(
"pool107k26e3wrqxwghju2py40ngngx2qcu48ppeg7lk0cm35jl2aenx",
);
```
### Register Stake Address \[!toc]
Register a stake address before delegate to stakepools.
**Pool ID**
`pool107k26e3wrqxwghju2py40ngngx2qcu48ppeg7lk0cm35jl2aenx`
```tsx
const utxos = await wallet.getUtxos();
const address = await wallet.getChangeAddress();
const addresses = await wallet.getRewardAddresses();
const rewardAddress = addresses[0]!;
const poolIdHash = deserializePoolId("pool107k26e3wrqxwghju2py40ngngx2qcu48ppeg7lk0cm35jl2aenx");
if (rewardAddress === undefined) {
throw "No address found";
}
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.registerStakeCertificate(rewardAddress)
.delegateStakeCertificate(rewardAddress, poolIdHash)
.selectUtxosFrom(utxos)
.changeAddress(address)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Delegate Stake
Delegation with `MeshTxBuilder` is exactly the same as first delegate, but without registering stake key, so only one API is needed:
```tsx
txBuilder
.delegateStakeCertificate(rewardAddress, poolIdHash)
```
### Delegate Stake \[!toc]
Delegate stake to a stake pool
**Pool ID**
`pool107k26e3wrqxwghju2py40ngngx2qcu48ppeg7lk0cm35jl2aenx`
```tsx
const utxos = await wallet.getUtxos();
const address = await wallet.getChangeAddress();
const addresses = await wallet.getRewardAddresses();
const rewardAddress = addresses[0]!;
const poolIdHash = deserializePoolId("pool107k26e3wrqxwghju2py40ngngx2qcu48ppeg7lk0cm35jl2aenx");
if (rewardAddress === undefined) {
throw "No address found";
}
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.delegateStakeCertificate(rewardAddress, poolIdHash)
.selectUtxosFrom(utxos)
.changeAddress(address)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Withdraw Rewards
Withdrawal with `MeshTxBuilder` comes with only one API, to specify the reward address and the amount to withdraw.
* rewardAddress (string) - the reward address to withdraw from
* lovelace (number) - the amount to withdraw in Lovelace
```tsx
txBuilder
.withdrawal(rewardAddress, lovelace)
```
### Withdraw Rewards \[!toc]
Withdraw staking rewards.
**Amount in lovelace:** `1000000`
```tsx
const utxos = await wallet.getUtxos();
const address = await wallet.getChangeAddress();
const addresses = await wallet.getRewardAddresses();
const rewardAddress = addresses[0]!;
if (rewardAddress === undefined) {
throw "No address found";
}
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.withdrawal(rewardAddress, "1000000")
.selectUtxosFrom(utxos)
.changeAddress(address)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Deregister Stake
Deregister a stake address. The function accepts the following parameters:
* rewardAddress (string) - the bech32 reward address to deregister
```tsx
txBuilder
.deregisterStakeCertificate(rewardAddress: string)
```
### Deregister Stake \[!toc]
Deregister a stake address.
```tsx
const utxos = await wallet.getUtxos();
const address = await wallet.getChangeAddress();
const addresses = await wallet.getRewardAddresses();
const rewardAddress = addresses[0]!;
if (rewardAddress === undefined) {
throw "No address found";
}
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.deregisterStakeCertificate(rewardAddress)
.selectUtxosFrom(utxos)
.changeAddress(address)
.complete();
const signedTx = await wallet.signTx(unsignedTx);
const txHash = await wallet.submitTx(signedTx);
```
## Script Withdrawal - Supporting Withdraw Zero
Withdrawal from script is supported by `MeshTxBuilder` with this set of APIs:
```tsx
txBuilder
.withdrawalPlutusScriptV2()
.withdrawal(rewardAddress, withdrawalAmount)
.withdrawalScript(stakeScriptCbor)
.withdrawalRedeemerValue(redeemer)
```
**Withdraw Zero**
With that capability, it supports a Cardano technique - withdraw zero - which is a technique to trigger withdrawal script validation without actually withdrawing any value. This is a technique to help boost script ExUnits performance especially comes to validating multiple script inputs. In order to perform withdraw zero, 2 steps are involved:
* Register script stake key
```tsx
txBuilder
.registerStakeCertificate(stakeScriptHash)
```
* Withdraw Zero
```tsx
txBuilder
.withdrawalPlutusScriptV2()
.withdrawal(rewardAddress, "0")
.withdrawalScript(stakeScriptCbor)
.withdrawalRedeemerValue(redeemer)
```
### Register Script Stake Key \[!toc]
One off setup before triggering withdraw zero
```tsx
const utxos = await wallet.getUtxos();
const address = await wallet.getChangeAddress();
const txBuilder = getTxBuilder();
const stakeScriptCbor = alwaysSucceedMintingStakingScriptCbor(
deserializeAddress(address).pubKeyHash,
);
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.registerStakeCertificate(resolveScriptHash(stakeScriptCbor, "V2"))
.selectUtxosFrom(utxos)
.changeAddress(address)
.complete();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
### Withdraw Zero \[!toc]
Actual withdrawal of zero to trigger script validation
```tsx
const utxos = await wallet.getUtxos();
const collateral = await wallet.getCollateral();
const address = await wallet.getChangeAddress();
const stakeScriptCbor = alwaysSucceedMintingStakingScriptCbor(
deserializeAddress(address).pubKeyHash,
);
const rewardAddress = serializeRewardAddress(
resolveScriptHash(stakeScriptCbor, "V2"),
true,
0,
);
const txBuilder = new MeshTxBuilder({
fetcher: provider, // get a provider https://meshjs.dev/providers
verbose: true,
});
const unsignedTx = await txBuilder
.withdrawalPlutusScriptV2()
.withdrawal(rewardAddress, "0")
.withdrawalScript(stakeScriptCbor)
.withdrawalRedeemerValue("")
.selectUtxosFrom(utxos)
.changeAddress(address)
.txInCollateral(...utxoToTxIn(collateral[0]!))
.complete();
const signedTx = await wallet.signTx(unsignedTx, true);
const txHash = await wallet.submitTx(signedTx);
```
# Browser Wallet
URL: /apis/wallets/browserwallet
For connecting, querying and performing wallet functions in accordance to CIP-30.
***
title: "Browser Wallet"
description: "For connecting, querying and performing wallet functions in accordance to CIP-30."
icon: BanknotesIcon
-------------------
`BrowserWallet` provides APIs for interacting with browser-based wallets in accordance with CIP-30. This standard defines the communication protocol between applications and user wallets, ensuring compatibility and security.
In addition to the CIP-30 APIs, `BrowserWallet` includes utility functions that simplify common tasks such as retrieving wallet balances, signing transactions, and managing UTXOs.
This section allows you to explore and test the available APIs for browser wallets, enabling seamless integration into your applications.
## Get Available Wallets
Returns a list of wallets available on user's device. Each wallet is an object with the following properties:
* A name is provided to display wallet's name on the user interface.
* A version is provided to display wallet's version on the user interface.
* An icon is provided to display wallet's icon on the user interface.
#### Get Available Wallets \[!toc]
Get a list of wallets on user's device
```tsx
import { BrowserWallet } from 'meshsdk/core';
await BrowserWallet.getAvailableWallets()
```
Example response:
```tsx
[
{
"name": "eternl",
"icon": "data:image/png;base64,ICONBASE64HERE",
"version": "0.1.0"
}
]
```
## Connect Wallet
This is the entrypoint to start communication with the user's wallet. The wallet should request the user's permission to connect the web page to the user's wallet, and if permission has been granted, the wallet will be returned and exposing the full API for the app to use.
Query `BrowserWallet.getAvailableWallets()` to get a list of available wallets, then provide the wallet `name` for which wallet the user would like to connect with.
You can also provide an `extensions` object to enable specific CIPs. For Example response, to enable CIP95, you would pass:
```tsx
await BrowserWallet.enable('eternl', [95]);
```
#### Connect Wallet \[!toc]
Connect to a CIP30 compatible wallet
```tsx
import { BrowserWallet } from '@meshsdk/core';
const wallet = await BrowserWallet.enable('eternl');
```
## Get Balance
This API retrieves a list of all assets in the connected wallet. Each asset is represented as an object containing the following properties:
* Unit: A unique identifier for the asset, which can be used to display its name in the user interface.
* Quantity: The amount of the asset held in the wallet.
This information is useful for applications that need to display wallet balances or perform operations involving specific assets.
#### Get Balance \[!toc]
Get all assets in the connected wallet
```tsx
await wallet.getBalance();
```
Example response:
```tsx
[
{
"unit": "lovelace",
"quantity": "796105407"
},
{
"unit": "0f5560dbc05282e05507aedb02d823d9d9f0e583cce579b81f9d1cd8",
"quantity": "1"
},
{
"unit": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d4d657368546f6b656e",
"quantity": "2"
},
]
```
## Get Change Address
This API returns an address owned by the wallet that should be used as a change address. A change address is where leftover assets from a transaction are returned during its creation. This ensures that any unspent assets are sent back to the connected wallet.
Applications can use this API to manage transaction outputs effectively, ensuring proper handling of change during transactions.
#### Get Change Address \[!toc]
Get address that should be used for transaction's change
```tsx
await wallet.getChangeAddress();
```
## Get Collateral
This API retrieves a list of UTXOs (unspent transaction outputs) controlled by the wallet that can be used as collateral inputs for transactions involving Plutus scripts. The returned UTXOs must meet or exceed the specified ADA value target.
If the target cannot be met, an error message will be returned explaining the issue. Wallets may return UTXOs with a greater total ADA value than requested but must never return UTXOs with a smaller total value.
This functionality is essential for applications that need to create transactions requiring collateral inputs.
#### Get Collateral \[!toc]
Get list of UTXOs that used as collateral inputs for transactions with plutus script inputs
```tsx
await wallet.getCollateral();
```
Example response:
```tsx
[
{
"input": {
"outputIndex": 1,
"txHash": "ff8d1e97c60989b4f...02ee937595ad741ff597af1"
},
"output": {
"address": "addr_test1qzm...z0fr8c3grjmysm5e6yx",
"amount": [ { "unit": "lovelace", "quantity": "5000000" } ]
}
}
]
```
## Get Network ID
This API retrieves the network ID of the currently connected account. The network ID indicates the blockchain network the wallet is connected to. For example:
* 0: Testnet
* 1: Mainnet
Other network IDs may be returned by wallets, but these are not governed by CIP-30. The network ID remains consistent unless the connected account changes.
Applications can use this information to ensure compatibility with the connected network.
#### Get Network ID \[!toc]
Get currently connected network
```tsx
await wallet.getNetworkId();
```
## Get Reward Addresses
Returns a list of reward addresses owned by the wallet. A reward address is a stake address that is used to receive rewards from staking, generally starts from `stake` prefix.
#### Get Reward Addresses \[!toc]
Get stake addresses
```tsx
await wallet.getRewardAddresses();
```
Example response:
```tsx
[
"stake_test1uzx0ksy9f4qnj2mzfdncqyjy84sszh64w43853nug5pedjgytgke9"
]
```
## Get Unused Addresses
Returns a list of unused addresses controlled by the wallet.
#### Get Unused Addresses \[!toc]
Get addresses that are unused
```tsx
await wallet.getUnusedAddresses();
```
Example response:
```tsx
[
"addr_test1qzk9x08mtre4jp8f7j8zu8802...r8c3grjmys7fl22c",
"addr_test1qrmf35xyw2petfr0e0p4at0r7...8sc3grjmysm73dk8",
"addr_test1qq6ts58hdaasd2q78fdjj0arm...i8c3grjmys85k8mf",
]
```
## Get Used Addresses
Returns a list of used addresses controlled by the wallet.
#### Get Used Addresses \[!toc]
Get addresses that are used
```tsx
await wallet.getUsedAddresses();
```
Example response:
```tsx
[
"addr_test1qzk9x08mtre4jp8f7j8zu8802...r8c3grjmys7fl88a",
"addr_test1qrmf35xyw2petfr0e0p4at0r7...8sc3grjmysm76gt3",
"addr_test1qq6ts58hdaasd2q78fdjj0arm...i8c3grjmys85dn39",
]
```
## Get UTXOs
Return a list of all UTXOs (unspent transaction outputs) controlled by the wallet.
#### Get UTXOs \[!toc]
Get UTXOs of the connected wallet
```tsx
const utxos = await wallet.getUtxos();
```
Example response:
```tsx
[
{
"input": {
"outputIndex": 0,
"txHash": "16dcbb1f93b4f9d5e...9106c7b121463c210ba"
},
"output": {
"address": "addr_test1qzag7whju08xwrq...z0fr8c3grjmysgaw9y8",
"amount": [
{
"unit": "lovelace",
"quantity": "1314550"
},
{
"unit": "f05c91a850...3d824d657368546f6b656e3032",
"quantity": "1"
}
]
}
}
]
```
## Sign Data
This endpoint utilizes the CIP-8 - Message Signing to sign arbitrary data, to verify the data was signed by the owner of the private key.
`signData` takes two arguments, the first one is the payload to sign and the second one is the address (optional).
By default, we get the first wallet's address with `wallet.getRewardAddresses()`, alternativelly you can specify the address to use.
#### Sign Data \[!toc]
Define a payload and sign it with wallet.
`Payload: mesh`
```tsx
const signature = await wallet.signData(mesh);
```
Example response:
```tsx
{
"signature": "845846a2012...f9119a18e8977d436385cecb08",
"key": "a4010103272006215...b81a7f6ed4fa29cc7b33186c"
}
```
Continue reading this guide to learn how to verify the signature.
## Sign Transaction
Requests user to sign the provided transaction (`tx`). The wallet should ask the user for permission, and if given, try to sign the supplied body and return a signed transaction. `partialSign` should be `true` if the transaction provided requires multiple signatures.
#### Sign Transaction \[!toc]
Create a transaction and sign it
```tsx
const signedTx = await wallet.signTx(tx, partialSign?);
```
Check out Transaction to learn more on how to use this API.
## Submit Transaction
Wallets inherently have the ability to submit transactions. This API allows applications to request the wallet to send a transaction. If the wallet accepts the transaction and successfully sends it, it will return the transaction ID, enabling the application to track its status. In case of errors during submission, the wallet will provide error messages or failure details.
This functionality is useful for applications that need to interact with the blockchain by submitting signed transactions through the user's wallet.
#### Submit Transaction \[!toc]
Submit a signed transaction with wallet
```tsx
const txHash = await wallet.submitTx(signedTx);
```
Check out Transaction to learn more on how to use this API.
## Get Assests
Returns a list of assets in wallet excluding lovelace.
#### Get Assets \[!toc]
Get assets in the connected wallet
```tsx
const assets = await wallet.getAssets();
```
Example response:
```tsx
[
{
"unit": "1207329a668cf5c42b80a220a8c85d5e82ac0b6f5ecedda4c07a8acc4d657368486f6e6f72546f6b656e2d3530343935",
"policyId": "1207329a668cf5c42b80a220a8c85d5e82ac0b6f5ecedda4c07a8acc",
"assetName": "Mesh Token Of Appreciation",
"fingerprint": "asset1dw74h0w0meqg9cxkc9sezp8zqcxu8nl93fzfpz",
"quantity": "1"
}
{
"unit": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d4d657368546f6b656e",
"policyId": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d",
"assetName": "MeshToken",
"fingerprint": "asset177e7535dclmkkph8ewt9fsghllkwmpspa3n98p",
"quantity": "10"
}
]
```
## Get Lovelace
This API retrieves the Lovelace balance in the connected wallet. Lovelace is the smallest denomination of ADA, where 1 ADA equals 1,000,000 Lovelace.
Applications can use this information to display the wallet's balance or perform operations involving ADA.
#### Get Lovelace \[!toc]
Get amount of ADA in connected wallet
```tsx
await wallet.getLovelace();
```
## Get Policy IDs
This API retrieves a list of policy IDs for all assets in the connected wallet. A policy ID is a unique identifier for a group of assets, often used to manage collections or verify asset ownership.
Applications can use this information to query assets belonging to specific policy IDs or display asset details to the user.
#### Get Policy IDs \[!toc]
Get a list of policy IDs from all assets in wallet
```tsx
await wallet.getPolicyIds();
```
Example response:
```tsx
[
"0f5560dbc05282e05507aedb02d823d9d9f0e583cce579b81f9d1cd8",
"5bed9e89299c69d9a54bbc82d88aa5a86698b2b7b9d0ed030fc4b0ff",
"9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d",
]
```
## Get a Collection of Assets
This API retrieves a list of assets associated with a specific policy ID. If no assets in the wallet belong to the specified policy ID, an empty list is returned.
Applications can use this API to query assets belonging to a particular policy ID, which is useful for managing collections of assets or verifying ownership.
To obtain a list of all policy IDs in the wallet, use `wallet.getPolicyIds()`.
#### Get a Collection of Assets \[!toc]
Get a list of assets belonging to the policy ID
`Policy ID: d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527`
```tsx
await wallet.getPolicyIdAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527');
```
## Get Supported Extensions
`getSupportedExtensions` is a static function that returns a list of CIPs that are supported by a wallet. You can query this function without connecting to a wallet, by providing the wallet name.
You can get the list of wallet on user's device with `await BrowserWallet.getAvailableWallets()`.
#### Get Supported Extensions \[!toc]
Get a list of CIPs that are supported by a wallet
`Wallet Name: eternl`
```tsx
await wallet.getSupportedExtensions('eternl');
```
## Get Extensions
This API retrieves a list of CIP-30 extensions enabled by the connected wallet. CIP-30 extensions define additional capabilities that wallets can support, enhancing their functionality.
Applications can use this information to determine the features supported by the wallet and adapt their behavior accordingly.
#### Get Extensions \[!toc]
Get a list of CIPs that are supported by the connected wallet
```tsx
await wallet.getExtensions();
```
Example response:
```tsx
[
{
"cip": 30
}
]
```
## Get DRep
This API retrieves the key, hash, and bech32 encoding of the DRep ID associated with the wallet. The DRep ID is a unique identifier used for delegation representation in the Cardano blockchain.
Applications can use this information to interact with delegation-related features or display the DRep ID details to the user.
#### Get DRep ID Key \[!toc]
Get the key, hash, and bech32 address of the DRep ID
```tsx
await wallet.getDRep();
```
Example response:
```tsx
{
"publicKey": "6984e406dd81...39e43d798fe1a89ab",
"publicKeyHash": "9f7f4b78...df83bd227e943e9808450",
"dRepIDCip105": "drep1vz0h7jmc...0axqgg5q4dls5u"
}
```
## Get Registered Pub Stake Keys
Get a list of registered public stake keys.
#### Get Registered Pub Stake Keys \[!toc]
Get a list of registered public stake keys
```tsx
await wallet.getRegisteredPubStakeKeys();
```
Example response:
```tsx
{
"pubStakeKeys": [
"d7eb3004c14647646...40f89c1a4b8a2eb0a3"
],
"pubStakeKeyHashes": [
"8cfb40854d41392b..5575627a467c450396c9"
]
}
```
## Get Unregistered Pub Stake Keys
Get a list of unregistered public stake keys.
#### Get Unregistered Pub Stake Keys \[!toc]
Get a list of unregistered public stake keys
```tsx
await wallet.getUnregisteredPubStakeKeys();
```
# Wallets
URL: /apis/wallets
Wallets APIs for interacting with the blockchain.
***
title: "Wallets"
description: "Wallets APIs for interacting with the blockchain."
icon: WalletIcon
full: true
----------
import { BanknotesIcon, WalletIcon } from '@heroicons/react/24/solid'
}>
## Browser Wallet \[!toc]
For connecting, querying and performing wallet functions in accordance to CIP-30.
}>
## Mesh Wallet \[!toc]
Mesh Wallet provides a set of APIs to interact with the blockchain. This wallet is compatible with Mesh transaction builders.
# Mesh Wallet
URL: /apis/wallets/meshwallet
Mesh Wallet provides a set of APIs to interact with the blockchain. This wallet is compatible with Mesh transaction builders.
***
title: "Mesh Wallet"
description: "Mesh Wallet provides a set of APIs to interact with the blockchain. This wallet is compatible with Mesh transaction builders."
icon: WalletIcon
----------------
Whether you are building a minting script, or an application that requires multi-signature, `MeshWallet` is all you need to get started.
## Initialize Wallet
This API enables applications to load and initialize a wallet connection. It provides access to the wallet's capabilities, such as signing transactions, submitting transactions, and querying blockchain data.
The wallet connection is established securely, ensuring that sensitive operations are handled by the wallet and not exposed to the application directly. This is crucial for maintaining security and user trust.
Applications can use this functionality to integrate wallet features seamlessly, enabling blockchain interactions without requiring users to manage private keys manually.
You can initialize Mesh Wallet with:
* Mnemonic Phrases
* Private Keys
* Cardano CLI Generated Keys
* Address (Read Only Wallet)
First, we initialize a Provider, which we will assign provider to the `fetcher` and `submitter`.
```tsx
import { MaestroProvider } from '@meshsdk/core';
const provider = new MaestroProvider({
network: 'Preprod',
apiKey: '', // Get yours by visiting https://docs.gomaestro.org/.
turboSubmit: false
});
```
```tsx
import { BlockfrostProvider } from '@meshsdk/core';
const provider = new BlockfrostProvider('');
```
```tsx
import { KoiosProvider } from '@meshsdk/core';
const provider = new KoiosProvider('', '');
```
```tsx
import { U5CProvider } from "@meshsdk/core";
const provider = new U5CProvider({
url: "http://localhost:5005U5c",
headers: {
"dmtr-api-key": "",
},
});
```
### Menmonice Phrases
We can load wallet with menmonice phrases:
```tsx
import { MeshWallet } from '@meshsdk/core';
const wallet = new MeshWallet({
networkId: 0, // 0: testnet, 1: mainnet
fetcher: provider,
submitter: provider,
key: {
type: 'mnemonic',
words: ["solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution","solution"],
},
});
```
With the `wallet` loaded, you can sign transactions, we will see how to do this in the next section, for now lets get the wallet's address:
```tsx
const address = wallet.getChangeAddress();
```
### Private Keys
We can load wallet with private keys:
```tsx
import { MeshWallet } from '@meshsdk/core';
const wallet = new MeshWallet({
networkId: 0, // 0: testnet, 1: mainnet
fetcher: provider,
submitter: provider,
key: {
type: 'root',
bech32: 'xprv1cqa46gk29plgkg98upclnjv5t425fcpl4rgf9mq2txdxuga7jfq5shk7np6l55nj00sl3m4syzna3uwgrwppdm0azgy9d8zahyf32s62klfyhe0ayyxkc7x92nv4s77fa0v25tufk9tnv7x6dgexe9kdz5gpeqgu',
},
});
```
### Cardano CLI generated skeys
We can load wallet with CLI generated keys by providing the `skey` generated by Cardano CLI. There are two files generated by Cardano CLI, by default it is named `signing.skey` and `stake.skey`. Opening the `signing.skey` file it should contains:
```tsx
{
"type": "PaymentSigningKeyShelley_ed25519",
"description": "Payment Signing Key",
"cborHex": "5820aaca553a7b95b38b5d9b82a5daa7a27ac8e34f3cf27152a978f4576520dd6503"
}
```
We can get the `cborHex` from the `signing.skey` file, and load wallet with Cardano CLI generated skeys. Stake key is optional, but without it, you cannot sign staking transactions.
```tsx
import { MeshWallet } from '@meshsdk/core';
const wallet = new MeshWallet({
networkId: 0, // 0: testnet, 1: mainnet
fetcher: provider,
submitter: provider,
key: {
type: 'cli',
payment: '5820aaca553a7b95b38b5d9b82a5daa7a27ac8e34f3cf27152a978f4576520dd6503',
stake: '582097c458f19a3111c3b965220b1bef7d548fd75bc140a7f0a4f080e03cce604f0e',
},
});
```
### Address
We can load wallet with address, this is useful for read-only wallets. A read-only wallet can only query the blockchain, it cannot sign transactions. This is useful for monitoring wallets. We can load wallet with the `address` type:
```tsx
import { MeshWallet } from '@meshsdk/core';
const wallet = new MeshWallet({
networkId: 0, // 0: testnet, 1: mainnet
fetcher: provider,
key: {
type: 'address',
address: 'addr_test1qpvx0sacufuypa2k4sngk7q40zc5c4npl337uusdh64kv0uafhxhu32dys6pvn6wlw8dav6cmp4pmtv7cc3yel9uu0nq93swx9',
},
});
```
### Initialize Wallet
After creating the wallet, we need to initialize it. This will initialize the cryptography library.
```tsx
await wallet.init()
```
With the `wallet` loaded, you can sign transactions, we will see how to do this in the next section, for now lets get the wallet's address:
```tsx
const address = wallet.getChangeAddress();
```
## Generate Wallet
You can generate deterministic keys based on the `Bitcoin BIP39`. These mnemonic phrases are essential for recovering your wallet and ensuring secure access to your funds.
```tsx
const mnemonic = MeshWallet.brew();
```
Once you have your mnemonic phrase, you can use it to generate deterministic keys. These keys include a series of private and public keys, which are crucial for managing your cryptocurrencies securely.
Alternatively, you can generate private keys directly by passing `true` to the `brew` function. This approach is useful for scenarios where you need immediate access to private keys without mnemonic phrases.
```tsx
const privatekey = MeshWallet.brew(true);
```
## Get Balance
This API returns a comprehensive list of all assets in the wallet, including lovelace. Each asset is represented as an object with the following properties:
* `unit`: A unique identifier for the asset, often used for display purposes.
* `quantity`: The amount of the asset held in the wallet.
### Get Balance \[!toc]
Get all assets in the connected wallet
```tsx
const balance = await wallet.getBalance();
```
Example response:
```tsx
[
{
"unit": "lovelace",
"quantity": "796105407"
},
{
"unit": "0f5560dbc05282e05507aedb02d823d9d9f0e583cce579b81f9d1cd8",
"quantity": "1"
},
{
"unit": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d4d657368546f6b656e",
"quantity": "2"
},
]
```
## Get Change Address
This API returns an address owned by the wallet that should be used as a change address. A change address is essential during transaction creation to ensure leftover assets are securely returned to the connected wallet.
The change address helps maintain the integrity of transactions by preventing asset loss and ensuring proper allocation of funds.
### Get Change Address \[!toc]
Get address that should be used for transaction's change
```tsx
const changeAddress = await wallet.getChangeAddress();
```
## Get Collateral
This API retrieves a list of UTXOs (unspent transaction outputs) controlled by the wallet that are suitable for use as collateral inputs in transactions involving Plutus script inputs. Collateral UTXOs are pure ADA-only UTXOs required to meet the specified ADA value target.
If the target cannot be met, an error message explaining the issue will be returned. Wallets may return UTXOs exceeding the target value but must never return UTXOs below the specified value.
This API accepts the `addressType` parameter, where you can specify the type of address you want to get. The available options are:
* payment (default)
* enterprise
### Get Collateral \[!toc]
Get list of UTXOs that used as collateral inputs for transactions with plutus script inputs
```tsx
const collateralUtxos = await wallet.getCollateral();
```
Example response:
```tsx
[
{
"input": {
"outputIndex": 1,
"txHash": "ff8d1e97c60989b4f...02ee937595ad741ff597af1"
},
"output": {
"address": "addr_test1qzm...z0fr8c3grjmysm5e6yx",
"amount": [ { "unit": "lovelace", "quantity": "5000000" } ]
}
}
]
```
## Get Network ID
This API returns the network ID of the currently connected account. The network ID indicates the environment in which the wallet is operating:
* `0`: Testnet
* `1`: Mainnet
Other network IDs may be returned by wallets, but these are not governed by CIP-30. The network ID remains consistent unless the connected account changes.
### Get Network ID \[!toc]
Get currently connected network
```tsx
const networkId = wallet.getNetworkId();
```
## Get Reward Addresses
This API retrieves a list of reward addresses owned by the wallet. Reward addresses are stake addresses used to receive rewards from staking activities.
Reward addresses typically start with the `stake` prefix, making them easily identifiable. These addresses are essential for tracking staking rewards and managing staking operations.
### Get Reward Addresses \[!toc]
Get stake addresses
```tsx
const rewardAddresses = wallet.getRewardAddresses();
```
Example response:
```tsx
[
"stake_test1uzx0ksy9f4qnj2mzfdncqyjy84sszh64w43853nug5pedjgytgke9"
]
```
## Get Unused Addresses
This API retrieves a list of unused addresses controlled by the wallet. Unused addresses are wallet-controlled addresses that have not been involved in any transactions.
Unused addresses are important for maintaining privacy and security in transactions. They can be used for new transactions without revealing previous activity.
### Get Unused Addresses \[!toc]
Get addresses that are unused
```tsx
const unusedAddresses = wallet.getUnusedAddresses();
```
Example response:
```tsx
[
"addr_test1qzk9x08mtre4jp8f7j8zu8802...r8c3grjmys7fl22c",
"addr_test1qrmf35xyw2petfr0e0p4at0r7...8sc3grjmysm73dk8",
"addr_test1qq6ts58hdaasd2q78fdjj0arm...i8c3grjmys85k8mf",
]
```
## Get Used Addresses
This API retrieves a list of used addresses controlled by the wallet. Used addresses are wallet-controlled addresses that have been involved in transactions.
Tracking used addresses is essential for analyzing transaction history and managing wallet activity. These addresses provide insights into past transactions.
### Get Used Addresses \[!toc]
Get addresses that are used
```tsx
const usedAddresses = wallet.getUsedAddresses();
```
Example response:
```tsx
[
"addr_test1qzk9x08mtre4jp8f7j8zu8802...r8c3grjmys7fl88a",
"addr_test1qrmf35xyw2petfr0e0p4at0r7...8sc3grjmysm76gt3",
"addr_test1qq6ts58hdaasd2q78fdjj0arm...i8c3grjmys85dn39",
]
```
## Get UTXOs
This API retrieves a list of all UTXOs (unspent transaction outputs) controlled by the wallet. UTXOs are essential for constructing transactions and managing wallet balances.
Each UTXO includes details such as the transaction hash, output index, address, and amount. These details are crucial for identifying and utilizing unspent outputs.
This API accepts the addressType parameter, where you can specify the type of address you want to get. The available options are:
* payment (default)
* enterprise
### Get UTXOs \[!toc]
Get UTXOs of the connected wallet
```tsx
const utxos = await wallet.getUtxos();
```
Example response:
```tsx
[
{
"input": {
"outputIndex": 0,
"txHash": "16dcbb1f93b4f9d5e...9106c7b121463c210ba"
},
"output": {
"address": "addr_test1qzag7whju08xwrq...z0fr8c3grjmysgaw9y8",
"amount": [
{
"unit": "lovelace",
"quantity": "1314550"
},
{
"unit": "f05c91a850...3d824d657368546f6b656e3032",
"quantity": "1"
}
]
}
}
]
```
## Sign Data
This API allows applications to request the signing of arbitrary data using the private keys managed by the connected wallet. This is useful for verifying the authenticity of data or creating cryptographic proofs.
The wallet ensures that the signing process is secure and that private keys are not exposed during the operation. The signed data can be used for various purposes, such as authentication, data integrity checks, or blockchain interactions.
This functionality is essential for applications that require secure and verifiable data signing capabilities.
### Sign Data \[!toc]
Define a payload and sign it with wallet.
`Payload: mesh`
```tsx
const signature = await wallet.signData('mesh');
```
Continue reading this guide to learn how to verify the signature.
Example response:
```tsx
{
"signature": "845846a2012...f9119a18e8977d436385cecb08",
"key": "a4010103272006215...b81a7f6ed4fa29cc7b33186c"
}
```
## Sign Transaction
This API enables applications to request the signing of a transaction using the private keys managed by the connected wallet. Signing a transaction is a critical step in ensuring its authenticity and authorization.
The wallet ensures that the transaction is signed securely, preventing unauthorized access to private keys. Once signed, the transaction can be submitted to the blockchain network for processing.
This functionality is vital for applications that need to interact with the blockchain securely, as it delegates sensitive operations to the wallet.
### Sign Transaction \[!toc]
Create a transaction and sign it
Check out **Transaction** to learn more on how to use this API.
```tsx
const signedTx = await wallet.signTx(tx, partialSign?);
```
## Submit Transaction
This API allows applications to request the submission of a signed transaction through the connected wallet. The wallet will attempt to send the transaction to the blockchain network.
If the transaction is successfully submitted, the wallet returns the transaction ID, which can be used by the application to track its status on the blockchain. In case of an error during submission, the wallet provides error messages or failure details.
This functionality is essential for applications that rely on wallet integration to handle transaction submission securely and efficiently.
### Submit Transaction \[!toc]
Submit a signed transaction with wallet
Check out **Transaction** to learn more on how to use this API.
```tsx
const txHash = await wallet.submitTx(signedTx);
```
## Create Collateral UTXO
Collateral is a monetary guarantee provided by the user to ensure the integrity of smart contracts and compensate nodes in case phase-2 validation fails. It is specified during transaction construction by adding collateral inputs to the transaction.
The total balance in the UTXOs corresponding to these inputs represents the transaction's collateral amount. If the contract executes successfully, the collateral remains safe. This mechanism ensures that contracts are carefully designed and thoroughly tested.
```tsx
const txhash = await wallet.createCollateral();
```
## Get Assets
This API retrieves a list of assets in the wallet, excluding lovelace. Each asset is represented as an object with the following properties:
* `unit`: A unique identifier for the asset.
* `policyId`: The policy ID associated with the asset.
* `assetName`: The name of the asset.
* `fingerprint`: A unique fingerprint for the asset.
* `quantity`: The amount of the asset held in the wallet.
### Get Assets \[!toc]
Get all assets in the connected wallet
```tsx
const assets = await wallet.getAssets();
```
Example response:
```tsx
[
{
"unit": "1207329a668cf5c42b80a220a8c85d5e82ac0b6f5ecedda4c07a8acc4d657368486f6e6f72546f6b656e2d3530343935",
"policyId": "1207329a668cf5c42b80a220a8c85d5e82ac0b6f5ecedda4c07a8acc",
"assetName": "Mesh Token Of Appreciation",
"fingerprint": "asset1dw74h0w0meqg9cxkc9sezp8zqcxu8nl93fzfpz",
"quantity": "1"
}
{
"unit": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d4d657368546f6b656e",
"policyId": "9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d",
"assetName": "MeshToken",
"fingerprint": "asset177e7535dclmkkph8ewt9fsghllkwmpspa3n98p",
"quantity": "10"
}
]
```
## Get Lovelace
This API retrieves the lovelace balance in the wallet. Lovelace is the smallest unit of ADA, where 1 ADA equals 1,000,000 lovelace.
Knowing the lovelace balance is essential for managing wallet funds and performing transactions.
### Get Lovelace \[!toc]
Get lovelace balance in the connected wallet
```tsx
const lovelace = await wallet.getLovelace();
```
## Get Policy IDs
This API retrieves a list of policy IDs from all assets in the wallet. A policy ID is a unique identifier that groups assets under a common policy.
Policy IDs are useful for querying assets associated with specific policies. For example, you can use a policy ID to retrieve all assets belonging to that policy.
### Get Policy IDs \[!toc]
Get a list of policy IDs from all assets in wallet
```tsx
const policyIds = await wallet.getPolicyIds();
```
Example response:
```tsx
[
"0f5560dbc05282e05507aedb02d823d9d9f0e583cce579b81f9d1cd8",
"5bed9e89299c69d9a54bbc82d88aa5a86698b2b7b9d0ed030fc4b0ff",
"9c8e9da7f81e3ca90485f32ebefc98137c8ac260a072a00c4aaf142d",
]
```
## Get a Collection of Assets
This API retrieves a list of assets associated with a specific policy ID. A policy ID is a unique identifier that groups assets under a common policy.
If no assets in the wallet belong to the specified policy ID, an empty list is returned. To query for available policy IDs, use `wallet.getPolicyIds()`.
### Get a Collection of Assets \[!toc]
Get a list of assets belonging to the policy ID
`Policy ID: d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527`
```tsx
const assets = await wallet.getPolicyIdAssets('d9312da562da182b02322fd8acb536f37eb9d29fba7c49dc17255527');
```
## Get DRep
The DRep ID is a unique identifier for the user's wallet. It consists of three components:
* `publicKey`: The public key associated with the wallet.
* `publicKeyHash`: A hash of the public key for verification purposes.
* `dRepIDCip105`: The bech32 encoding of the DRep ID.
### Get DRep \[!toc]
Get the key, hash, and bech32 address of the DRep ID
```tsx
await wallet.getDRep();
```
Example response:
```tsx
{
"publicKey": "6984e406dd81...39e43d798fe1a89ab",
"publicKeyHash": "9f7f4b78...df83bd227e943e9808450",
"dRepIDCip105": "drep1vz0h7jmc...0axqgg5q4dls5u"
}
```