SDK for creating Video NFT minting applications.
Also provides a CLI for minting an NFT in 1-command.
yarn add @livepeer/video-nft
npm install @livepeer/video-nft
Then the API can then be imported as a regular module:
import { videonft } from '@livepeer/video-nft'
// To upload videos from the filesystem
const uploader = new videonft.minter.Uploader();
// To process videos and export to IPFS
const vodApi = new videonft.minter.Api({ auth: { apiKey } });
// To mint the NFT from the IPFS files
const { chainId } = ethereum
const web3 = new videonft.minter.Web3({ ethereum, chainId });
Add the following script tag to the header of your HTML file:
<script src="https://unpkg.com/@livepeer/[email protected]/dist/index.umd.js"></script>
The SDK will be available as a global named videonft
:
const web3 = new videonft.minter.FullMinter({}, { ethereum, chainId });
For more information about using the SDK check the Usage section.
Check our entry-point guides for getting started with this project:
Browse the code documentation online.
- Continue reading this for Usage and Examples
- Deploy your own ERC-721 contract
This SDK can be used both from Node.js (like in a backend) as well as the
browser, and is currently best used with the
Polygon blockchain. It consists of a couple
different modules which are all included in the videonft
object.
On the browser-side, it has been thoroughly tested with the MetaMask wallet. It should work with any other Web3 wallet compatible with MetaMask though.
The SDK provides built-in support for a couple of chains, specifically Polygon mainnet and testnet. This means that you can get started with the SDK immediately without deploying your own custom smart contract. That naturally means that we have a simple smart contract deployed in these chains which is used by default to mint the NFTs.
You can override these default contracts by passing your own smart contract
address to the
mintNft
or
createNft
functions. The only requirement is that your smart contract implements the
required
ABI. You
can also use any other chain that we don't have built-in support,
you will only need to provide a custom smart contract every time.
For help creating your own smart contract, follow our Deploy your own ERC-721 contract guide.
The main module is the
videonft.minter
which consists of 3 parts:
- The
Uploader
to send files from the local context (e.g. picked by the user on a file picker) to the Livepeer API. - The
Api
component, used to interact with the Livepeer API or a proxy to it. Abstracts the video-processing and IPFS exporting APIs for preparing the video for an NFT. - The
Web3
component, used to actually mint the NFT given the IPFS URLs obtained from theApi
component above.
The SDK also provides a couple other modules that can be useful when developing an NFT-minting application:
videonft.chains
: Provides some utilities for handling different blockchains that the user might be connected to. The SDK also has a couple of built-in chains (basically Polygon right now) where we have pre-deployed ERC-721 smart contracts for minting the NFTs. Check the documentation for more information.videonft.api
: Raw client for the Livepeer VOD API. Can be used directly if you need more control or use the API in a different way than abstracted by theminter.Api
helper.videonft.transcode
: Provides some utilities for determining the parameters of a transcode task to be performed with the video asset. It is also abstracted by theminter.Api
component through thenftNormalize
andcheckNftNormalize
functions.
We will focus on the main minter
module here which provides the higher-level
abstractions for minting an NFT. The module has 3 main parts as shown
above, the Uploader
, Api
and Web3
.
You would normally split parts of the logic between your frontend and your backend for different reasons like security or performance. Let's explore some of the alternatives here.
You can do the entire minting flow from the browser. This is the quickest way to get started, but could have some security implications. Anyone with the proper knowledge will be able to snoop the API key from your code or network requests and impersonate you in the Livepeer API.
So it is recommended that you use a CORS-enabled API key with restricted access to the API. Check the documentation on getting an API key for more information.
The code below shows a simple example of how the whole flow would look like from the browser:
import { videonft } from '@livepeer/video-nft'
const apiOpts = {
auth: { apiKey: 'your-api-key-here' },
// defaults to current origin if not specified
endpoint: videonft.api.prodApiEndpoint
};
const chainId = ethereum.chainId; // or await ethereum.request({ method: 'eth_chainId' });
const minter = new videonft.minter.FullMinter(apiOpts, { ethereum, chainId });
// file is optional, will open a file picker if not provided.
async function mintNft(file) {
const nftInfo = await minter.createNft({
name: 'My NFT',
file,
nftMetadata: {
description: 'My NFT description',
traits: { 'my-custom-trait': 'my-custom-value' }
}
});
console.log(`minted NFT on contract ${nftInfo.contractAddress} with ID ${nftInfo.tokenId}`);
return nftInfo;
}
It is common to prefer more control over the individual steps of the minting process. You can use it to show some feedback to your user and ask for additional information or confirmation. That same example would look like this:
async function mintNft() {
const file = await minter.uploader.pickFile();
let asset = await minter.api.createAsset('My NFT', file);
// optional, optimizes the video for the NFT
asset = await minter.api.nftNormalize(asset);
const nftMetadata = {
description: 'My NFT description',
traits: { 'my-custom-trait': 'my-custom-value' }
};
const ipfs = await minter.api.exportToIPFS(asset.id, nftMetadata);
const tx = await minter.web3.mintNft(ipfs.nftMetadataUrl);
const nftInfo = await minter.web3.getMintedNftInfo(tx);
console.log(`minted NFT on contract ${nftInfo.contractAddress} with ID ${nftInfo.tokenId}`);
return nftInfo;
}
If you'd rather have the maximum security for your API key, you can create a backend to serve as a proxy to the Livepeer API and optionally provide higher-level abstractions for all the minting operations.
You can even do the entire flow from the backend as well, including the
blockchain transaction via the Web3
helper. On that case, it would not be your
users doing the minting but you. That means not only you would need to pay for
the gas costs yourself, but your users would also not own the NFTs they mint.
You could circumvent that by immediately transferring the minted NFT to the user
(more gas) or creating a custom contract that allows minting to another address
in the mint()
call, but the recommended approach here is to just let your
users do the minting themselves. So we suggest you to keep the Web3
minting
part in the browser, close to your users.
The simplest backend you could make is one that just forwards the calls to the Livepeer API whilst injecting an API key:
import express from 'express';
import { createProxyMiddleware } from 'http-proxy-middleware';
const app = express();
const proxy = createProxyMiddleware({
target: 'https://livepeer.com',
changeOrigin: true,
headers: {
authorization: process.env.LP_API_KEY ?? ''
}
});
app.get('/api/asset/:id', proxy);
app.get('/api/task/:id', proxy);
app.post('/api/asset/request-upload', proxy);
app.post('/api/asset/transcode', proxy);
app.post('/api/asset/:id/export', proxy);
app.listen(3000);
By running that backend you can use the same code examples from the
browser-only section above. All you need to change is the
apiOpts
object to remove the auth
option (since your proxy will be adding
that) and changing the endpoint
to where your backend is:
- If your backend is running on the same domain as your frontend, you can
actually omit the
endpoint
field as well and the client will default to the current origin:
const apiOpts = {};
const minter = new videonft.minter.FullMinter(apiOpts, { ethereum, chainId });
- You can also run your backend on a different domain than your frontend.
You'll likely need some CORS logic or middleware in your backend to support
the cross-origin request. You can use a package like
cors for that. On the frontend, you
only need to add the domain (with the scheme) to the
endpoint
field:
const apiOpts = { endpoint: 'https://backend.example.com' };
const minter = new videonft.minter.FullMinter(apiOpts, { ethereum, chainId });
Everything else can be kept the same!
This project also contains a CLI that uses the SDK and can be used to mint NFTs
from the terminal. All you need is an API key and a file to mint. To run it
directly with npx
:
npx @livepeer/video-nft
You can also check the source code of the CLI or the livepeer.com/mint-nft page for further examples on how to use the SDK:
For more information using the CLI check this guide.
Pull Requests are always welcome!
Also feel free to open Issues with bug reports or feature requests. We're glad for any feedback!
MIT