UTXO-based smart contracts

A new scalable way to build smart contracts on MVC. Standardized NFT / Token contracts out of the box.

sell-nft.ts
nft.contract.ts
token-mint.contract.ts
const nftInfo = { genesis, codehash, tokenIndex }
const { txid } = await nftManager.sell({
...nftInfo,
sellerWif: wif,
price: 4600000,
})

Introduction

Getting started

Welcome to the documentation of Meta Contract! This page will give you an introduction to the 80% of core concepts that you will utilize.

Installation

Install meta-contract package in a breeze.

Architecture guide

Learn how the internals work and contribute.

Plugins

Extend the library with third-party plugins or write your own.

API reference

Learn to easily customize and modify your app's visual design to fit your brand.

Keep in mind that this documentation is a work in progress. If you have any questions, feel free to reach out to us on GitHub.


Quick start

Installing dependencies

npm install meta-contract

Install meta-contract and its dependencies via num. You can also use yarn / pnpm / bun if you prefer.


Basic usage

Utilize Meta Contract to create, manage, and trade NFTs on the blockchain. We will use the standard contract implementation provided by the library. You can also customize the contract to fit your needs, or write your own.

Mint a new NFT from a series that you own

To mint a new NFT, you need to be the owner of the series. That means you control the Genesis UTXO of the series.

You can mint a new NFT by calling the mint method which under the hood use nftGenesis and nft contracts. The mint action will create a new NFT UTXO representing the NFT, and a new NFT Genesis UTXO for future minting.

// mint-nft.ts
import { NftManager } from 'meta-contract'

const nftManager = new NftManager({
  network: 'mainnet',
  apiTarget: API_TARGET.MVC, // your blockchain API provider
  purse: wif, // your wallet WIF
  feeb: 1, // fee per byte, default is 1
})

const {
  txid, // the transaction id of the minting transaction
  tx, // the minting transaction
  tokenIndex, // the unique serial index of the NFT
} = await nftManager.mint({
  version: 2, // version of the NFT contract
  sensibleId: genesisInfo.sensibleId, // sensibleId of the series
  metaTxId, // metaTxId and metaOutputIndex locate the UTXO which contains the meta data of the NFT like name, description, etc.
  metaOutputIndex,
})

Alright! You have successfully minted a new NFT.

You can now observe the NFT's details from an MVC blockchain explorer like mvcscan.com. You can also trade it with others, or transfer it to others.

Get NFTs from the blockchain

Choose an MVC api provider to fetch related information from the blockchain. We will use mvcapi as an example.

// Alice-nfts.ts
const AliceAddress = '1xxxxyeahitsAlicefromdowntownxxxxx'

// get NFT summary of Alice's address
const nftSummary: {
  codehash: string // represents contract version of the NFT series
  genesis: string // the unique identifier of the NFT series
  count: string // the total count of the NFTs of the series from Alice
  supply: string // the total supply of the NFTs of the series
}[] = await nftManager.api.getNonFungibleTokenSummary(AliceAddress)

// get NFT list of one specific series from Alice
const series = {
  codehash,
  genesis,
} // these 2 fields identify a series
const nftList: {
  txId: string // the transaction id of the NFT UTXO
  outputIndex: number // the output index of the NFT UTXO
  tokenAddress: string // the address of the NFT contract, which is the same as Alice's address
  tokenIndex: string // the unique serial index of the NFT
  metaTxId: string
  metaOutputIndex: number
}[] = await nftManager.api.getNonFungibleTokenUnspents(series.codehash, series.genesis, AliceAddress)

// get detail of one specific NFT
const nftId = {
  codehash,
  genesis,
  tokenIndex,
} // these 3 fields identify a specific NFT
const nftInfo: {
  txId: string // the transaction id of the NFT UTXO
  outputIndex: number // the output index of the NFT UTXO
  tokenAddress: string // the address of the NFT contract, which is the same as Alice's address
  tokenIndex: string // the unique serial index of the NFT
  metaTxId: string
  metaOutputIndex: number
} = await nftManager.api.getNonFungibleTokenUnspentDetail(nftId.codehash, nftId.genesis, nftId.tokenIndex)

Sell an NFT

Call NFTSell contract to sell an NFT. The NFTSell contract is a standard contract provided by the library.

const nftId = {
  codehash,
  genesis,
  tokenIndex,
} // these 3 fields identify a specific NFT

const { sellTxId } = await nftManager.sell({
  ...nftId,
  sellerWif: wif, // the WIF of the seller, aka Alice
  price: 46000, // the price of the NFT, in satoshis
})

OK, now the NFT is on sale. Let's check if the NFT is indeed sitting on a sell contract address.

// let's wait for several seconds to make sure the blockchain is up to date
await new Promise((resolve) => setTimeout(resolve, 5000))

// query the sell contract address of the NFT
const { contractAddress } = await wallet.api.getNftSellUtxo(
  codehash,
  genesis,
  tokenIndex,
  true, // set true to includes those sale UTXOs which are not confirmed yet; otherwise, only return confirmed UTXOs
)
// query the NFT current information
const { tokenAddress } = await wallet.api.getNonFungibleTokenUnspentDetail(
  codehash,
  genesis,
  tokenIndex,
)
// the sell contract address should be the same as the NFT contract address;
// that means the NFT is indeed on sale
expect(contractAddress).toBe(tokenAddress)

Buy an NFT

Bob wants to buy the NFT from Alice. He can call the NFTBuy contract to buy the NFT.

NftManager.buy will call this contract to buy the NFT.

const bobNftManager = new NftManager({
  purse: bobWif, // the WIF of Bob
})

const { buyTxId } = await bobNftManager.buy({
  ...nftId, // the NFT id from Alice, which we previously sold
  buyerWif: bobWif,
})

That's it!

We have successfully go through the basic usage of NFT related contracts. You also have bunch of other methods to manage your NFTs, like transfer, cancel sell, etc.


Getting help

If you have any questions, feel free to reach out to us on GitHub.

Submit an issue

If you find a bug or have a feature request, please open an issue.