This package provides reusable Vue 3 composable functions, Pinia stores, and utilities for working with ERC721 NFTs on EVM-compatible blockchains like Ethereum, Avalanche, Polygon, Binance Smart Chain and more.
No API is needed, the blockchain is the API!
- The Web Browser makes calls directly to the blockchain.
- No Crypto wallet needed.
- List NFTs with Meta Data, token ID, and Owner.
- List all NFTs on a contract.
- List all NFTs on contract, that are held by a specific wallet.
- Paging through large collections.
- Sorting by Token ID.
- Local caching with Pinia.
- More efficient RPC Batch Call support.
- Utilities for working with Meta Data structures.
This package depends on other packages such as axios
, ethers.js
, pinia
, and vue
. Your project should already have these installed, this package has been tested with...
- axios 1.7.7
- ethers.js 6.13.3
- pinia 2.2.4
- vue 3.5.11
You can install the package directly from npm:
npm install vue-evm-nft
This project is free and open source, although it was originally built to work with Dig-A-Hash Dynamic Meta Data Services. We build lots of websites that display NFTs, so this component was super useful to us. However, Dig-A-Hash specific settings have been removed from this package so that these components can be used for any NFT project, on any EVM-compatible blockchain.
This package ships with 2 composables, 2 Pinia stores, and modules containing the ABI arrays for the various Dig-A-Hash NFT Smart Contracts.
import {
useEvmNftGallery,
blockchains,
dahDemoV1Abi as abi,
} from 'vue-evm-nft';
const { page, numberOfPages, nfts, isAscending, toggleSortOrder, getNftPage, getTokenOwner, getTokenMetaData } =
useEvmNftGallery(
contractPublicKey,
contractAddress,
abi,
chainId,
null,
blockchains.fantom.publicRpc,
itemsPerPage,
nftStoreCollectionName,
false
);
The useEvmNftGallery
composable is designed to manage and display NFTs stored in EVM-based contracts. It allows sorting and pagination through NFTs while leveraging other composables (useEvmNft
and useEvmNftStore
) for local caching and enhanced functionality.
-
contractPublicKey
(string
): The public key of the wallet holding the contract. -
contractAddress
(string
): The address of the NFT contract. -
abi
(array
): The contract's ABI (Application Binary Interface). -
chainId
(number
): The EVM Chain ID. Passnull
if you are not using Dig-A-Hash meta data, then the composable will get the Meta Dat from the token by making a call to the contract. Pass a chain ID if using Dig-A-Hash hosted meta data for improved performance when fetching meta data. -
holderPublicKey
(string
): (Optional) If provided, fetches NFTs owned by this wallet. Ifnull
, it will return all NFTs associated with the contract. Warning: If the contract has burned tokens, then passing null here will result in inaccurate counts and listings, the only option for this case is to pass a public Key instead (not null). -
ethersProviderUrl
(string
): The URL of the Ethers provider corresponding to the specified chain. -
itemsPerPage
(number
): The number of NFTs to display per page. -
nftStoreItemCollectionName
(string
): The name of the NFT store collection. -
isAscendingSort
(boolean
): Determines the starting sorting order of the NFTs. Set totrue
for ascending order,false
for descending. Use onToggleSortOrder() to change the sort direction.
-
page
: The current page of NFTs being displayed. Changing page will cause the component to fetch and store the new page of NFTs in Pinia. If the page has already been fetched, it will not fetch again until page refresh. -
numberOfPages
: The total number of pages based on the number of items and theitemsPerPage
specified in the params above. -
nfts
: The current page of NFTs to be displayed. -
isAscending
: The current sorting order of NFTs. -
toggleSortOrder
: A function to toggle or change the sorting order of NFTs. -
isLoading
: A boolean that will indicate whether or not the component is fetching. Create a vue watcher to track changes. -
loadingMessage
: A string that will indicate exactly what the component is doing while isLoading is true. Create a vue watcher to track changes. -
getNftPage
: An async function that takes a param indicating which page of NFTs to fetch from the contract. -
getTokenOwner
: An async function to get the current token holder wallet address. -
getTokenMetaData
: An async function to get meta data for an array of Token Ids. If chain ID is not null, then we get the meta data without needing to access the blockchain at all because we use Dig-A-Hash predictable storage paths based on that chain ID.
This is used internally by useEvmNftGallery but it can still be used directly. The useEvmNft composable fetches NFT data from an ERC721 contract and retrieves metadata either directly from the blockchain or via the Dig-A-Hash storage pattern. It supports pagination, sorting, and retrieving the current owner of a token.
-
pageSize
(number
): The number of NFTs to display per page. -
provider
(object
): Theethers.js
provider instance. -
holderPublicKey
(string
): The public key of the NFT holder. Set tonull
to retrieve all NFTs on the contract. -
contractOwnerPublicKey
(string
): The public key of the contract owner. -
contractAddress
(string
): The contract address. -
contractABI
(array
): The ABI (Application Binary Interface) of the contract. -
chainId
(number
): The chain ID. Passnull
if the metadata is not stored in the Dig-A-Hash pattern. -
excludeWallet
(string
): (Optional) The wallet to exclude from the list of NFTs.
-
getNfts
(function
): Fetches NFTs based on the current page, pagination size, and sorting order. -
getTokenOwner
(function
): Retrieves the owner of a specific NFT. -
getMetaDataBatch
(function
): Retrieves metadata for a batch of NFTs. -
getTokenMetaData
(function
): Retrieves metadata for specific token IDs. -
loadingMessage
(ref
): A reactive reference to track the loading status message.
import { useEvmNft, blockchains, dahNftV2Abi } from 'vue-evm-nft';
const { getNfts, getTokenOwner, loadingMessage } = useEvmNft(
10, // pageSize
blockchains.fantom.publicRpc, // ethers.js provider
null, // holderPublicKey
'0xOwnerPublicKey', // contractOwnerPublicKey
'0xContractAddress', // contractAddress
dahNftV2Abi, // contractABI
1 // chainId (if applicable)
);
const loadNFTs = async () => {
const nfts = await getNfts(1, true); // Fetches the first page in ascending order
console.log(nfts);
};
This Pinia store used internally by useEvmNftGallery but it can still be used directly. The useNftStore
is a Pinia store used to manage collections of NFTs, their metadata, and associated image URLs. It allows for efficient retrieval and management of NFT attributes, including safe handling of different image sizes.
-
itemCollections
(object
): Stores NFT collections. Each collection is keyed by its name and contains the following properties:-
items
(array
): An array of NFTs for each page. -
itemCount
(number
): The total number of items in the collection. -
page
(number
): The current page of items being viewed.
-
-
getNftUrl
(function
): Generates the URL for viewing an NFT on the website.-
Parameters:
-
tokenId
(string
): The NFT's token ID. -
path
(string
): The base path for the NFT page.
-
- Returns: A URL string for the NFT.
-
Parameters:
-
getImageLarge
(function
): Retrieves a large version of the NFT image if available, otherwise defaults to the NFT's standard image.-
Parameters:
-
metaData
(object
): The NFT's metadata object.
-
- Returns: The URL of the large image or the default image.
-
Parameters:
-
getImageMedium
(function
): Retrieves a medium version of the NFT image if available, otherwise defaults to the NFT's standard image.-
Parameters:
-
metaData
(object
): The NFT's metadata object.
-
- Returns: The URL of the medium image or the default image.
-
Parameters:
-
getPublicAttributeValue
(function
): Retrieves a specific attribute from the NFT's public metadata.-
Parameters:
-
metaData
(object
): The NFT's metadata object. -
attributeName
(string
): The name of the attribute to retrieve.
-
-
Returns: The value of the specified attribute or
null
if not found.
-
Parameters:
-
setCollectionItems
(function
): Adds or updates items in a specific collection for a given page.-
Parameters:
-
page
(number
): The page number to set. -
items
(array
): The items to be added to the collection. -
collectionName
(string
): The name of the collection.
-
-
Parameters:
-
addCollection
(function
): Adds a new collection to the store.-
Parameters:
-
collectionName
(string
): The name of the collection to add.
-
-
Parameters:
-
removeCollection
(function
): Removes a collection from the store.-
Parameters:
-
collectionName
(string
): The name of the collection to remove.
-
-
Parameters:
import { useNftStore } from 'vue-evm-nft';
const nftStore = useNftStore();
// Add a new collection
nftStore.addCollection('myCollection');
// Set items for page 1 in the 'myCollection' collection
nftStore.setCollectionItems(1, [{ tokenId: 1, metaData: {} }], 'myCollection');
// Retrieve a large image URL for an NFT
const largeImageUrl = nftStore.getImageLarge(nft.metaData);
// Get a specific public attribute value from the NFT metadata
const attributeValue = nftStore.getPublicAttributeValue(nft.metaData, 'rarity');
// Remove a collection
nftStore.removeCollection('myCollection');
This is a Pinia store that you can copy and place into the Pinia stores folder in your project, so this file cannot be imported. This file shows lots of good examples on how to create shortcut/helpers to the various bits of meta data attributes. This is a good way to extend the nftStore described above.
There are still some Smart Contract ABI arrays that belong to Dig-A-Hash, but any ABI can be used.
Dig-A-Hash uses a predictable pattern to store Meta-Data based on the contract address, the contract owners public key, chain ID, and token ID. So we do not need to lookup the Token URI with a call to the contract if the chainId is passed to useEvmNftGallery. This increases performance in fetching NFT Meta Data because we can easily derive the path to the Meta Data based on the predictable storage pattern as follows...
https://nft.dah-services.com/profiles/{ContractOwnerPublicKey}/meta-data/{ChainId}/{ContractAddress}/{TokenId}.json
While this is a very small performance improvement, all Dig-A-Hash specific settings can be easily ignored.
This is a JS module that contains info about the various blockchains in use (chainIds, blockchain explorer links, blockchain name, etc). Blockchains commonly used by Dig-A-Hash have been included, which you can use. This is not a comprehensive list.
import { blockchains } from 'vue-evm-nft';
-
dahDemoV1Abi
:import { dahDemoV1Abi } from 'vue-evm-nft';
- The ABI for the first NFT Smart Contract built to use Dig-A-Hash dynamic Meta Data. The Token ID starts at 1, and it uses a classic counter for Token IDs, costs more in gas than more modern versions. This contract supports public mints. -
dahNftV2Abi
:import { dahNftV2Abi } from 'vue-evm-nft';
- The ABI for the 2nd NFT Smart Contract built to use Dig-A-Hash dynamic Meta Data. The Token ID starts at 0, and it does not use counter so it is more gas efficient than the first version. This contract supports public mints.
This package works with standard NFT contracts following OpenZeppelin's ERC721 specifications. Custom contracts or contracts that deviate from these standards may require additional adjustments.
To contribute to this package, please fork the repository and submit a pull request with your changes. Make sure to test your changes locally before opening the pull request by using npm link as described above. PRs will only be merged after substantial local testing by the maintainer.
This project is licensed under the ISC License.