Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 110 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

NFT Kit

What is the NFT KIT?

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Getting started

Loading...

Ecosystems

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Query NFTs

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Concepts

Loading...

NFT Kit | Basics

Learn what the NFT Kit is.

The NFT Kit offers everything you need to use Non-Fungible Tokens (NFTs) with ease.

The following sections elaborate the NFT Kit's unique properties and enabled functionality.

Introduction

This documentation will help you understand how the NFT Kit works and how you can use it. However, it presumes a certain level of knowledge about Non-Fungible Tokens (NFTs) so

if you are already familiar with NFTs, you can jump to the .

if you are new to the world of NFTs, please continue with our

NFT Kit
introduction to Non-Fungible Tokens (NFTs).

Overview

Here are the most important things you need to know about the NFT Kit:

  • It is written in Kotlin/Java. It can be directly integrated (Maven/Gradle dependency) or run as RESTful web-service. A CLI tool allows you to run all functions manually.

  • It is open source (Apache 2). You can use the code for free and without strings attached.

  • It is a holistic solution that allows you to build use cases “end-to-end”. There is no need to research, combine or tweak different libraries to build pilots or production systems.

  • It abstracts complexity such as low-level functionality related to key handling, data storage, minting operations and interactions with third party systems.

  • It is customizable in a sense that you can build NFTs in all kinds of variations based on different smart contracts (e.g. ERC-721, ERC-1155) using various configurations (e.g. supply size, metadata storage).

  • It gives you advanced features like "soulbound" or "dynamic" NFTs or royalties.

  • It is modular, composable and built on open standards allowing you to customize and extend functionality with your own or third party implementations and to preventing lock-in.

  • It is flexible in a sense that you can deploy and run it on-premise, in your (multi) cloud environment or as a library in your application.

  • It enables you to use different blockchains / ecosystems - starting with EVM-compatible blockchains (e.g. Ethereum, Polygon, Binance Smart Chain, Avalanche).

  • Metadata is one of the core components of a NFT. We have a flexible and an abstract system to manage metadata. It can be on-chain (struct in smart contract, base64 string) or off-chain (IPFS, Arweave, centralized server).

NFT | Basics

Learn what SSI is.

What are NFTs?

In a nutshell, NFTs are non-fungible tokens which digitally represent ownership of something.

Following this definition each NFT shares at least three properties:

  1. NFTs are “non-fungible” which means that each NFT (or token) is unique in a sense that there is no other thing just like it. In other words, each NFT is one of a kind just like there is only one painting that is the real Mona Lisa. (A fungible token, on the other hand, is not unique. It would not make any difference if a fungible token would be exchanged for another token of the same kind such as a Bitcoin.)

  2. NFTs represent ownership which implies that an NFTs is treated as the actual thing that it stands for so that by selling an NFT you are also selling “the real thing” that it represents.

  3. NFTs can be used to tokenize and represent anything from physical things (like a house) to natively digital assets (like a crypto punk) to ideas and intellectual property.

How NFTs work ?

To understand how NFTs work, one must consider two perspectives:

  • The functional perspective which is about understanding the implications of NFTs for its adopters and the market, particularly what NFTs enable one to do (that could not be done without NFTs).

Functional Perspective

NFTs allow us to have digital representations of potentially anything in a way that these representations are unique, trustworthy (or at least a tamper proof record of ownership) and can be traded. We can distinguish the following roles or functionalities:

  • Issuers - Parties who create (“mint”) NFTs and issue (“drop”) them to someone else (“Holders”). Issuers are the original sources of an NFT. For example, artists who mint their creations as NFTs and transfers them to buyers.

  • Holders - Individuals or organizations who receive NFTs from someone else (but not necessarily from the original “Issuer”, considering that NFTs are transferable).

  • Verifiers - Parties who verify NFT ownership and metadata in order to provide access to information, services, products or other benefits, such as is the case with tickets, vouchers or other forms of memberships more generally.

Illustration of functional roles in NFT ecosystems

The , which is about understanding the technologies on which NFTs are built and their properties which give rise to NFT’s functionality in the first place.

technical perspective

NFT Flavors & Ecosystems

The NFT Kit abstracts complexity for developers by following a "multi-stack approach" that enables you to use different implementations or "flavours" of NFT.

As a result, you can participate in different ecosystems (e.g. Ethereum, Polygon, Tezos, ...) and avoid technology-related lock-in effects.

Based on our , we distinguish the following concepts or building blocks, which illustrate the variety of NFT "flavours" that exists.

Introduction to Non-Fungible Token (NFT)
Intro NFT-Kit

NFT Kit

This section elaborates the theory behind the NFT Kit:

Architecture

The architecture of the NFT Kit consists of three layers:

  1. Low-Level Services Abstraction: Abstracts complex, low-level operations (e.g. cryptography, key management, smart contract or minting operations).

  2. Ecosystem Abstraction: Abstracts ecosystem-specific requirements based on the relevant technical and governance frameworks of a blockchain / NFT ecosystem.

  3. High-Level Interfaces / APIs: Provides high-level interfaces that hide complexity and facilitate usage for developers.

Also, the architecture allows for the integration of third party solutions throughout the stack. For example:

  • Key storage (e.g. HSM)

  • Data storage (e.g. IPFS)

  • Registries (e.g. blockchains)

This architectural openness prevents vendor lock-in and allows you to build NFT-based solutions that meet your unique requirements.

Illustration:

Read on to explore all three abstraction layers in more detail.

- Learn what the NFT Kit is and what it does.

- Learn which NFT flavors and ownership ecosystems we support.

- Explore the NFT Kit's multi-layered architecture and components.

- Explore use cases you can implement with the NFT Kit.

- Explore all features in an overview list

NFT Kit | Basics
NFT Flavors & Ecosystems
Architecture
Use Cases
NFT Kit Feature List

Non-Fungible Tokens (NFTs)

Learn about Non-Fungible Tokens (NFTs).

Welcome to our introduction to Non-Fungible Tokens (NFTs) for developers and technical readers.

Before you get started, feel free to explore other (less technical) resources that will help you and your team to get a more holistic understanding of NFTs and digital assets in general:

Quick Start

Getting started with the NFT-Kit.

The NFT Kit offers everything you need to use Non-Fungible Tokens (NFTs) with ease on different ecosystems. Chose yours and get started.

If you want to learn more about the NFT-Kit architecture and the general ideas? Visit the .

Introduction to NFTs for Identity
The future of decentralized identity: SSI vs NFTs

Ethereum | Polygon | Shimmer

Tezos

Ocean Protocol

Near

Polkadot

intro section
Each building block is available in different variations and can be put together in different ways. The result: different "SSI flavours".

Low-Level Service Abstraction

This software-layer holds a set of generic core services for common NFT and cryptographic functions. The services are in the scope of Smart Contract deployment, Meta Data management, Token Minting etc..

The low-level services expose common interfaces that can be conveniently utilised directly via Kotlin/Java or via the REST API (Swagger doc of the core API).

High-Level Interfaces / APIs

The following is a short summary of the interfaces available. The detailed functions are described in the documentation further on.

The NFT Kit exposes high-level interfaces / APIs to hide the complex introduced by

  • low-level services (e.g. key management, smart contract and minting operations)

  • different ecosystems (i.e. different NFT flavours, business logic and governance frameworks).

The functionality of the high-level interfaces are grouped around:

  • Creating / Minting NFTs

  • Managing NFTs

  • Verifying NFTs (ownership, metadata)

The interfaces can be used in JVM-based applications directly, or via the REST API. Get Started

Ecosystem Abstraction

We believe in a multi-blockchain & multi-ecosystem future.

This is why we built an abstraction layer for ecosystem-specific operations and business logic. The idea is to support any ecosystem with a single solution that does not put any additional burden on developers. As a result, you can use our solutions to participate in different ecosystems without having to switch between different technical implementations.

Ethereum | Polygon | Shimmer

Learn how to create and mange NFTs on Ethereum, Polygon and the Shimmer Network using the NFT-Kit's REST API or our Kotlin/Java library

Getting Started

Use Cases

Use cases you can build with the NFT Kit.

As the world is going digital, it becomes necessary to model ownership in a digital way. NFTs allow us to do just that by encoding ownership of any type of asset in a digital format.

As a result, NFT use cases can be found wherever there’s a need to digitally model ownership. In other words, the list of use cases is long and NFTs will likely be among the most important building blocks on which the digital world (or something like a metaverse) will be built.

The following graphic shows a range of NFT use cases across different industries to illustrate the potential of NFTs:

Ownership and Access Management

You can use the NFT Kit to enable your users, customers, employees or partners to create and manage any form of ownership (whether it's about a physical good, or digital items). This allows businesses to create digital ownership documents that are very hard to counterfeit but easy to verify, which makes the user experience more secure and enjoyable.

Decoupling the access to a product or service from a users’ identity is also possible as access can be given to the owner of a specific NFT only without having to know the identity of this owner in advance. The following categories show more specific use cases and examples.

Creator economy

The most famous NFT use case is certainly digital art. With NFTs, artist have the ability to create digital scarcity and thus sell their digital art as NFT. The creator economy also includes fashion brands that uses NFT as a "digital twin" of a physical product that a customer bought. In the luxury industries, NFT can also be used to issue authenticity certificates.

Entertainment

Entertainment is a big industry for NFTs. They can be used to represent items in video games which makes the players the true owners of those NFT gaming items, while allowing them to trade them and even use them in another video game or another context. Another use case that is becoming more and more popular is ticketing. When NFTs are used for ticketing, it allows a better management of events ticket because they are on a public blockchain with a high level of traceability, but it also reduces fraud because users can verify that the NFT they are buying is authentic. Lastly, NFT ticketing also provides consumers with a better user experience.

Travel and mobility

Similar tho the ticketing use case for events, NFT can be use to represent airplane or any public transport tickets; but also membership cards to access any services and transport.

Tourism and Travel

Loyalty program, exclusive content and vouchers are 3 practical use cases for NFTs in the Tourism and Travel industry. They are a great way to engage guests in a digital and interactive way as well as rewarding them.

Supply Chain

Thanks to its traceability characteristic, NFT are of course perfectly designed for Supply Chain usage. Product tracking and product authenticity is made easy when physical products are associated with NFTs.

Art

Digital art can be monetized by making unique digital assets that can have exclusive properties, on top of being easily sold or rented. In DeFi (Decentralized Finance), art NFTs can also be used as collateral for a loan

Music

In a similar way to digital art, musicians and singers can link their music to NFTs which makes it possible to own a piece of a song or album and receive royalties from it.

Ticketing

Event organizers may issue event tickets using NFT, as it would avoid fraud (by providing an easy way to verify tickets), but it would also allow for a better traceability of all the tickets that are resold.

Real Estate

Property ownership documents can also be made (created and issued) via NFTs which would represent a digital and immutable certificate of ownership of a physical real estate property. In another fashion, NFTs are also used to represent virtual properties.

Gaming

Items in online games can now be truly owned by the players, which offers many new possibilities such as selling and buying items outside of a game’s centralized marketplace, but also using those items in other digital environments like in other games.

Product Authenticity

Similar to the property ownership documents for the real estate use case, NFTs can also be used to prove the authenticity of any other physical products, such as clothing items, jewelry, cars, etc.

Fundraising and crowdfunding

Foundations and charities have already started to raise money by selling their own NFT collection, but crowdfunding platforms are now challenged by NFTs as it allows startups to raise funds in a peer to peer way.

Any Questions

Technologies & Concepts

Learn about the technologies and concepts on which SSI is based.

Technical Perspective

Understanding NFTs from a technological perspective requires the understanding of a few core concepts:

  • Registries, typically blockchains, which serve as a shared and trusted record of information. They serve as a “layer of trust” and a “single source of truth”.

  • Cryptographic keys, which convey control over NFTs and enable other crucial functionality such as authentication.

  • Token IDs, which are used to distinguish NFTs on a blockchain such that each token ID is linked to a unique address (establishing a public key infrastructure) and to metadata. This way different parties can easily find and interact with each other as well as benefit from blockchains’ unique properties like immutability.

  • Metadata, which can be anything like a piece of digital art or a digital representation of a physical asset. Importantly, metadata can be stored on-chain or off-chain.

  • Smart contracts, which can be thought of as the programs or apps that run on a blockchain and are responsible for minting NFTs.

  • Wallets, which are used to store keys or potentially even metadata. Also, they enable the management and sharing of NFTs via easy-to-use applications.

Illustration of main technical concepts related to NFTs:

One can think of these core concepts as different building blocks that are available in different variations and can be put together in different ways. For example:

Different blockchains (or other distributed ledger technologies) can be used to establish Registries (e.g. Ethereum, Polygon, Solana, Avalanche, Polkadot, Tezos, IOTA). Similarly, NFT metadata can be stored in different ways such as on blockchains, other distributed data storage protocols (e.g. IPFS, filecoin) or even traditional databases. Similarly, different smart contract development standards with different strengths and weaknesses can be used (e.g. ERC-721 or ERC-1155 for EVM compatible chains like Ethereum).

As a result, there are many different “flavors” of NFTs depending on which variations of which building blocks have been used and how they have been put together.

Functionality

The NFT Kit establishes an ownership infrastructure layer for any use case in any industry. Its core services are in the scope of:

  • Registry Interactions e.g. read, write; agnostic towards the underlying tech e.g. blockchain

  • Key Management e.g. generate, sign, import, export, manage lifecycle

  • Smart Contracts and NFT/Token e.g. create, mint, distribute, claim, verify ownership

  • Metadata handling e.g. on-chain or off-chain storage, look-up, verify metadata and attributes

Illustration:

NFT | Ownership Verification

In this section, we have a set of APIs that help you verify ownership or traits of an NFT, making ownership-based access management possible.

NFT ownership verification

You can use this API to verify if an account is the real owner of an NFT.

NFT ownership verification with traits

The verification process can be based on NFT ownership and metadata traits.

Setup

Learn how to setup the NFT-Kit on your local system

Choose your system

Do you want to build using our APIs or add the NFT-Kits functionalities as a direct dependency in a Kotlin/Java application

API

Installation & Running the Project

Make sure you have Docker or a JDK 16 build environment including Gradle installed on your machine

Start Building

Kotlin/Java SDK

Gradle

Maven

Required Maven repos:

Start Building

Select your ecosystem/blockchain of choice and start exploring the REST API.

Get started with your preferred option .

- How to use the NFT-Kit

- How to deploy Smart Contracts and mint NFTs

- How to verify NFT ownership within a collection and traits

- Pause token transfers, minting and burning

- Access Control functionalities

If you have any questions, feel free to .

|

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

  • account: [string] the NFT owner address.

  • tokenId: [string] the NFT token ID.

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

  • account: [string] the NFT owner address.

  • tokenId: [string] the NFT token ID.

  • traitType: [string] the name of the trait that you want to verify..

  • traitValue: [string] the trait value.

  1. Clone the project

2. Change the folder

3. your project

4. Building the docker container

5. Running the container

  1. Clone the project

2. Change the folder

3. your project

4. Build the project

5. Run the executable

In build/distributions/ you have two archives, a .tar, and a .zip.

Extract the one that is built for your system and run it.

- How to deploy Smart Contracts and mint NFTs

- How to verify NFT ownership within a collection and traits

- Pause token transfers, minting and burning

- Access Control functionalities

- How to deploy Smart Contracts and mint NFTs

- How to verify NFT ownership within a collection and traits

- Pause token transfers, minting and burning

- Access Control functionalities

here
here
Setup
NFT | Creation & Management
NFT | Ownership Verification
Smart Contract | Extensions
Smart Contract | Access Control
get in touch
curl -X POST "http://0.0.0.0:7000/nftkit/nft/verifier/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/verifyCollection" \ 
-H  "Content-Type: application/json" \
-d '{"account":"0x2555e3a97c4ac9705d70b9e5b9b6cc6fe2977a74","tokenId":"1"}'
{
  "account": "string",
  "tokenId": "string"
}
curl -X POST "http://0.0.0.0:7000/nftkit/nft/verifier/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/verifyTrait" \ 
-H  "Content-Type: application/json" \
-d '{"account":"0x2555e3a97c4ac9705d70b9e5b9b6cc6fe2977a74","tokenId":"1","traitType":"pass","traitValue":"silver"}'
{
  "account": "string",
  "tokenId": "string",
  "traitType": "string",
  "traitValue": "string"
}
implementation("id.walt:waltid-nftkit:VERSION")
  <dependency>
        <groupId>id.walt</groupId>
        <artifactId>waltid-nftkit</artifactId>
        <version>VERSION</version>
   </dependency>
https://maven.walt.id/repository/waltid/

API

Get started building with our API endpoints

Java/Kotlin SDK

Add the NFT-Kits functionality as a direct dependency

Swagger Doc
ReDoc
git clone https://github.com/walt-id/waltid-nftkit.git
cd waltid-nftkit/
docker build -t nftkit .
docker run -p 7000:7000 -it nftkit
git clone https://github.com/walt-id/waltid-nftkit.git
cd waltid-nftkit/
gradle clean build
cd build/distributions/
tar xf waltid-nftkit-1.SNAPSHOT.tar
./waltid-nftkit-1.SNAPSHOT/bin/waltid-nftkit
Configure
Configure
NFT | Creation & Management
NFT | Ownership Verification
Smart Contract | Extensions
Smart Contract | Access Control
NFT | Creation & Management
NFT | Ownership Verification
Smart Contract | Extensions
Smart Contract | Access Control

Smart Contract | Extensions

Improving the base functionalities of smart contract standards with Extensions.

Pausable

Pause token transfers, minting and burning.

Get pausable state of the smart contract.

curl -X GET "http://0.0.0.0:7000/nftkit/nft/extensions/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/paused" \

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

Pause smart contract

curl -X POST "http://0.0.0.0:7000/nftkit/nft/extensions/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/pause" \

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI

contract: smart contract address

Unpause smart contract

curl -X POST "http://0.0.0.0:7000/nftkit/nft/extensions/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/unpause" -H  

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

Burnable

Pause token burning.

Get burnable state of the smart contract.

curl -X GET "http://0.0.0.0:7000/nftkit/nft/extensions/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/burnable"

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

Activate/Deactivate burnable feature.

curl -X POST "http://0.0.0.0:7000/nftkit/nft/extensions/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/burnable" \
-H  "Content-Type: application/json" \
-d '{"burnable":false}'

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

{
  "burnable": true
}

  • burnable: [boolean] set to true if you want to activate the burn token feature and false if not.

Burn an NFT token.

curl -X DELETE "http://0.0.0.0:7000/nftkit/nft/extensions/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/token/1" 

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

token: token ID

Update NFT metadata

curl -X PUT "http://0.0.0.0:7000/nftkit/nft/extensions/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/token/1/tokenURI?signedAccount=0x6E7448a6335d5C947953994d071D4Dc1F6e5BE96" \
-H  "Content-Type: application/json" \
-d '{"metadataUri":"string","metadata":{"description":"string","name":"string","image":"string","image_data":"string","external_url":"string","attributes":[{"trait_type":"string","value":"string"}]}}'

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

token: token ID

signedAccount: the account used to sign the transaction.

{
  "metadataUri": "string",
  "metadata": {
    "description": "string",
    "name": "string",
    "image": "string",
    "image_data": "string",
    "external_url": "string",
    "attributes": [
      {
        "trait_type": "string",
        "value": "string"
      }
    ]
  }

  • metadataUri: [string] metadata URI of the token.If you want to generate metadata URI using NFT KIT, set the "metadataUri "value as an empty string.

  • description: [string] a description of the token

  • name: [string] the name of this specific token

  • image: [string] this is the URL to the image of the item. Can be just about any type of image and can be IPFS URLs or paths.

  • image_data: [string] Raw SVG image data, if you want to generate images on the fly (not recommended). Only use this if you're not including the image parameter.

  • external_url: [string] This is the URL that will appear below the asset's image on OpenSea and will allow users to leave OpenSea and view the item on your site.

  • attributes: [string] To give your items a little more pizazz, we also allow you to add custom "attributes" to your metadata that will show up underneath each of your assets.

  • trait_type: [string] the name of the trait

  • value: [string] the value of the trait

Ocean Protocol

You will learn how you can use the NFT Kit to verify the ownership and properties of Ocean protocol's (V4) ERC721 data NFT.

Getting Started

Deep dive

|

metadata: NFT KIT will use values inside metadata to generate metadata URI of the token. It confirms the structure defined by ERC721 and ERC1155 standards. For more details about .

Ocean protocol V4 data NFTs have a specialized Smart Contract architecture to handle data or intellectual property related use cases. Therefore, the NFT Kit was extended with special interfaces to deploy contracts, mint tokens and most importantly to verify the ownership of data NFTs. Learn more in detail how things were implemented in the .

- How to use the NFT-Kit

- How to verify NFT ownership and properties in the metadata

- View NFTs via a Web-Wallet

- See how the Ocean Protocol was integrated into the NFT-Kit

Swagger Doc
ReDoc
NFT metadata standard
architecture section
Setup
NFT | Verification
NFT | Wallet
Architecture

NFT | Wallet

The following example shows an OCEAN Data NFT minted by a contract from our own deployed contract factory on MUMBAI.

Tezos

Proof of State Blockchain - Open-Source, Self-Upgradable, Energy-Efficient

Tezos is an open-source, self-upgradable, energy-efficient and built to last Proof of Stake blockchain protocol for assets and applications, backed by a global community of validators, researchers, and builders. Tezos will drive social, political and economic innovation on a global scale.

Getting Started

Depending on your preference, start exploring with the deep dive or a tutorial.

Deep dive

Tutorials

Smart Contracts & Formal Verification

Tezos offers a platform to create smart contracts and build decentralized applications, that cannot be censored or shut-down by third parties. Furthermore, Tezos facilitates formal verification, a technique used to improve security by mathematically proving properties about programs such as smart contracts. This technique, if used properly, can help avoid costly bugs and the contentious debates that follow.

NFT | Creation & Management

Description of the main functions to manage NFTs: smart contract deployment, minting tokens, etc.

API Docs

Smart Contracts

The NFT-Kit supports the ERC-721 standard with the option to be deployed as regular contract for NFTs or modified for Soulbound Tokens.

Do you want to modify your contract further? Have a look at our Smart Contract Extension Sections:

NFT Contract Deployment | ERC-721

Soulbound Token Contract Deployment | ERC-721 with extension

curl -X POST http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/deploy \
-H  "Content-Type: application/json" \
-d '{"name":"Ticket","symbol":"TK","tokenStandard":"ERC721","accessControl":"OWNABLE","options":{"transferable":false,"burnable":true}}'
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

After you have successflully deployed the contract, you can start minting NFTs to your users.

{
  "name": "string",
  "symbol": "string",
  "tokenStandard": "ERC721",
  "accessControl": "OWNABLE|ROLE_BASED_ACCESS_CONTROL",
  "options": {
    "transferable": false,
    "burnable": true
  }
}

  • name: [string] the human-readable name of the contract.

  • symbol: [string] the abbreviated symbol of the contract.

  • tokenStandard: [string] NFTs smart contract standard. Supported values: ERC721.

  • transferable: [boolean] in order to make sure a soulbound token contract is created we need to set this option to false otherwise it will create a regular NFT contract as shown in the section above.

  • burnable: [boolean] activate/deactivate token burn.

val deploymentOptions = DeploymentOptions(AccessControl.OWNABLE, TokenStandard.ERC721)
val deploymentParameter = DeploymentParameter("Metaverse", "MTV",DeploymentParameter.Options(false, true))
val result = NftService.deploySmartContractToken(Chain.POLYGON, deploymentParameter, deploymentOptions)

Mint an NFT

It is a rich API to mint a new NFT token. It manages NFT metadata in multiple ways. You can generate token URI by yourself or let the NFT KIT generate it.

curl -X POST "http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/0xf277be034881ee38a9b270e5b6c5c6f333af2517/token/mint" \
-H  "Content-Type: application/json" \
-d '{"metadataUri":"","metadata":{"description":"Ticket #1 Description","name":"Ticket #1","image":"ipfs://bafkreibpc3wpdg4mq3bbkesqrxtoho25s3shnfhyotd6rymsag3bcfpeni","attributes":[{"trait_type":"Trait 1","value":"Value 1"}]},"recipientAddress":"0x2555e3a97c4ac9705D70b9e5B9b6cc6Fe2977A74","metadataStorageType":"ON_CHAIN"}'
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

{
  "metadataUri": "string",
  "metadata": {
    "description": "string",
    "name": "string",
    "image": "string",
    "image_data": "string",
    "external_url": "string",
    "attributes": [
      {
        "trait_type": "string",
        "value": "string"
      }
    ]
  },
  "recipientAddress": "string",
  "metadataStorageType": "ON_CHAIN|OFF_CHAIN"
}

  • metadataUri: [string] metadata URI of the new token.If you want to generate metadata URI using NFT KIT, set the "metadataUri "value as an empty string.

  • description: [string] a description of the token

  • name: [string] the name of this specific token

  • image: [string] this is the URL to the image of the item. Can be just about any type of image and can be IPFS URLs or paths.

  • image_data: [string] Raw SVG image data, if you want to generate images on the fly (not recommended). Only use this if you're not including the image parameter.

  • external_url: [string] This is the URL that will appear below the asset's image on OpenSea and will allow users to leave OpenSea and view the item on your site.

  • attributes: [string] To give your items a little more pizazz, we also allow you to add custom "attributes" to your metadata that will show up underneath each of your assets.

  • trait_type: [string] the name of the trait

  • value: [string] the value of the trait

  • recipientAddress: [string] the account address who will receive the NFT

  • metadataStorageType: [string] when you let the NFT KIT to generate metadata URI, you need to specify how the metadata will be stored. Supported values: ON_CHAIN, OFF_CHAIN. You can use ON_CHAIN if you want to store NFT metadata on the chain. You can use OFF_CHAIN if you want store NFT metadata off chain using IPFS.

val attribute1 : NftMetadata.Attributes = NftMetadata.Attributes(trait_type = "trait_type1", value = JsonPrimitive("value1"))
val attribute2 : NftMetadata.Attributes = NftMetadata.Attributes(trait_type = "trait_type2", value = JsonPrimitive("value1"))
val attributes = mutableListOf(attribute1, attribute2)
val nftMetadata : NftMetadata = NftMetadata(name = "name", description = "description", image = "", attributes = attributes)
val mintingParameter = MintingParameter("", "0xaf87c5Ce7a1fb6BD5aaDB6dd9C0b8EF51EF1BC31",nftMetadata)
val mintingOptions = MintingOptions(MetadataStorageType.ON_CHAIN)
val result = NftService.mintToken(Chain.POLYGON,"0xFd9426f82Ae1edBC6b5eC2B0Ea5416D34Ca6E9b6", mintingParameter, mintingOptions)

Revoke NFT

Owner of a soul bound NFT smart contract , can revoke a minted Token.

curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/SHIMMEREVM/contract/0x3A4D948a123824Fc34FDDA0654D3C8D0D29c2FA9/token/1/revokeToken"
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

token: token ID

val result = NftService.revokeToken(Chain.SHIMMEREVM, "0xFd9426f82Ae1edBC6b5eC2B0Ea5416D34Ca6E9b6", BigInteger.valueOf(26))

NFT metadata

Find out more information about your NFTs with the following actions.

Fetch NFT metadata URI

curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/token/1/metadataUri"
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

token: token ID

val result = NftService.getNftMetadataUri(Chain.POLYGON, "0xFd9426f82Ae1edBC6b5eC2B0Ea5416D34Ca6E9b6", BigInteger.valueOf(26))

Fetch NFT metadata

curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/token/1/metadata" 
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

token: token ID

val result = NftService.getNftMetadata(Chain.POLYGON, "0xFd9426f82Ae1edBC6b5eC2B0Ea5416D34Ca6E9b6", BigInteger.valueOf(26))

Update NFTs metadata trait

curl -X POST "http://0.0.0.0:7000/nftkit/nft/chain/ETHEREUM/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/token/1/metadata" \
-H  "Content-Type: application/json" \
-d '{"key":"key1","value":"value1"}'

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

token: token ID

{
  "key": "string",
  "value": "string"
}

  • key: [string] the name of the metadata attribute that you want to update.

  • value: [string] the new value of the attribute

Get Account balance

curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/owner/0x2555e3a97c4ac9705d70b9e5b9b6cc6fe2977a74/balance" 
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

owner: account address

Get Token owner

curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/token/1/owner" 
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

token: token ID

Get collection info

curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/info" 
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

Get NFTs by account

It will return a list of all NFTs which are associated with the provided account address.

curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/owner/0x2555e3a97c4ac9705d70b9e5b9b6cc6fe2977a74" 
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

owner: account address

Smart Contract | Access Control

The access control of your contract is an important concept that governs many features provided by your smart contract.

Almost every smart contract must have an access control mechanism. We provide two:

  1. Ownership

  2. Role-Based Access Control

Ownership

Get smart contract owner.

Transfer ownership of the contract to a new account.

Renounce ownership of the smart contract.

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: RINKEBY, ROPSTEN, MUMBAI, SHIMMEREVM

contract: smart contract address

Role-Based Access Control

"Role-Based Access Control" is a more complex approach than "Ownership" to manage access control. With this approach, you can define a hierarchy of roles, each allowed to perform a different set of actions. You can also assign multiple accounts to each role.

Verify if an account has been granted role

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: RINKEBY, ROPSTEN, MUMBAI, SHIMMEREVM

contract: smart contract address

account: an account address

role: role name

As we have a role hierarchy, You can use this API to get role admin that controls a sub role.

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: RINKEBY, ROPSTEN, MUMBAI, SHIMMEREVM

contract: smart contract address

role: role name

Grant role to account. The caller must have role's admin role.

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: RINKEBY, ROPSTEN, MUMBAI, SHIMMEREVM

contract: smart contract address

  • role: [string] the role you want to grant to the specified account.

  • account: [string] an account address.

Revoke role to account. The caller must have role's admin role.

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

  • role: [string] the role you want to revoke from the specified account.

  • account: [string] an account address.

Renounce role from the calling account.

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

contract: smart contract address

  • role: [string] the role you want to renounce from the specified account.

  • account: [string] an account address.

NFT | Verification

Verify ownership of data NFTs

The goal of the NFT Kit is to provide a simple library and web service for NFT-based access management. Therefore the ownership of NFTs, aligned with OCEAN protocols specifications, must be verified.

The library provides a VerificationService which exposed the method dataNftVerification that takes the following parameter:

  • chain: the EVM-compatible chain name or chain ID

  • factorycontractAddress: The address of the factory contract

  • erc721contractAddress: The address of the custom contract

  • account: The account to be verified

  • propertyKey: The NFT meta data property key that should exist

  • propertyValue: The NFT meta data property value that should exist

Verify data NFT

Architecture

Architecture of data NFTs

Unlike typical ERC 721 tokens where a Smart Contract allows the creation of multiple tokens, Smart Contracts of data NFTs allow just one token per contract. Therefore, a Factory Contract serves as creator of a number of custom contracts which may have each one token minted at max. This architecture allowed the custom contracts to have individual rules, which provides a lot of flexibility compared to the traditional architecture.

The following graphic illustrates the Factory Contract, which serves as creator for several custom contracts (need to be registered first) that are bound to a data NFT.

A further notable difference to classical NFTs is that data NFTs don't make use of external storage solutions like IPFS. Data NFTs use on-chain meta-data, which has the advantage that meta-data remains persistent due to the nature of the blockchain. Nevertheless, it comes with the disadvantage that on-chain storage space is limited and costly.

Architecture

Tezos + NFT-Kit Integration Diagramm

This diagram resume the integration of Tezos ecosystem in our NFT Kit. Tezos is rich ecosystem, theirs is flexibility in the integration of a such ecosystem. You can use our product either using REST APIs our as a library.

In general, there are two types of interactions: reading or writing from the Tezos blockchain.

For the writing operation, you need the smart contract (address or code), private key to sign operation, and an RPC connection. The NFT Kit will take care of the operation signing with the specified private key. Then, send the operation the the specified network(Mainnet or Testnet).

For reading operation, We use a Tezos indexer. We are making queries to TzKT API.

The smart contract is developed using the Archetype high-level programming language. We use FA2 Tezos standard.

NFT | Creation & Management

Financial Application 2 (FA2) token standard

Create and mint NFTs via the FA2 (Financial Application 2) unified token standard on Tezos, offering the following token types:

FA2 implementations

The FA2 standard has multiple implementations. We support the following:

Single

With this implementation, you can only have one collection. It is like the ERC-721 style. Only owner minter can mint new NFTs.

Multiple

With this implementation, you can have multiple collections. In each collection, you can define the number of copies of each NFT. It is somehow like the ERC-1155 style.

Smart contract deployment

We offer a set of default FA2 based smart contract templates, providing the main functionality needed for NFT projects.

Add minter

The FA2 smart contract implementation allows minting NFTs from different accounts. The owner of the smart contract is allowed to add new minters.

API Doc

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • contract: [string] smart contract address.

Body parameters:

  • minterAddress: [string] an account address that will be able to mint new NFTs.

Example:

NFT Minting

With this API, you can mint a new NFT. It have multiple options to manages NFT minting. You can generate NFT URI metadata by yourself or let the NFT KIT generate it.

API Doc

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • contract: [string] smart contract address

Body parameters:

  • metadataUri: [string] metadata URI of the new token.If you want to generate metadata URI using NFT KIT, set the "metadataUri "value as an empty string.

  • tokenId: [string] the account address who will receive the NFT

  • amount: [string] the account address who will receive the NFT

  • recipientAddress: [string] the account address who will receive the NFT

  • description: [string] a description of the token

  • name: [string] the name of this specific token

  • image: [string] this is the URL to the image of the item. Can be just about any type of image and can be IPFS URLs or paths.

  • image_data: [string] Raw SVG image data, if you want to generate images on the fly (not recommended). Only use this if you're not including the image parameter.

  • external_url: [string] This is the URL that will appear below the asset's image on OpenSea and will allow users to leave OpenSea and view the item on your site.

  • attributes: [string] To give your items a little more pizazz, we also allow you to add custom "attributes" to your metadata that will show up underneath each of your assets.

  • trait_type: [string] the name of the trait

  • value: [string] the value of the trait

Example:

Fetch NFT metadata

You can get the NFT metadata based on the NFT smart contract address and the NFT token ID.

API Doc

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • contract: [string] smart contract address

  • tokenId: [string] token id of the NFT

Example:

Get account NFTs

You get the NFTs list of an account on the specified network.

API Doc

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • owner: [string] owner address

Example:

Get contract metadata

This API allows fetching contract metadata.

API Doc

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • contract: [string] smart contract address

Example:

Setup

Learn how to use Ocean Protocols Data NFTs in your solutions

Get started by choosing your system

Do you want to build using our APIs or add the NFT-Kits functionalities as a direct dependency in a Kotlin/Java application

API

Installation & Running the Project

Make sure you have Docker or a JDK 16 build environment including Gradle installed on your machine

Start Building

Kotlin/Java SDK

Gradle

Maven

Required Maven repos:

Start Building

Visit the

- See how Tezos was integrated into the NFT-Kit

- How to deploy Smart Contracts and mint NFTs

- How to verify NFT ownership within a collection and traits

- View NFTs via a Web-Wallet

- Deploy a contract, mint, validate and view an NFT in a web wallet

|

- Pause token minting and burning.

Enable role-based access control

Ensure that the is configured with the appropriate gasPrice and gasLimit based on current market conditions prior to smart contract deployment, to ensure successful transactions.

curl -X POST http://0.0.0.0:7000/nftkit/nft/chain/MUMBAI/contract/deploy \
-H  "Content-Type: application/json" \
-d '{"name":"Ticket","symbol":"TK","tokenStandard":"ERC721","accessControl":"OWNABLE","options":{"transferable":true,"burnable":true}}'
  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: SEPOLIA, GOERLI, MUMBAI, SHIMMEREVM

After you have successflully deployed the contract, you can start minting NFTs to your users.

{
  "name": "string",
  "symbol": "string",
  "tokenStandard": "ERC721",
  "accessControl": "OWNABLE|ROLE_BASED_ACCESS_CONTROL",
  "options": {
    "transferable": true,
    "burnable": true
  }
}

  • name: [string] the human-readable name of the contract.

  • symbol: [string] the abbreviated symbol of the contract.

  • tokenStandard: [string] NFTs smart contract standard. Supported values: ERC721.

  • accessControl: [string] access control approach for the smart contract. Supported values: OWNABLE, ROLE_BASED_ACCESS_CONTROL. For more details about approaches.

  • transferable: [boolean] activate/deactivate token transfer.

  • burnable: [boolean] activate/deactivate token burn.

val deploymentOptions = DeploymentOptions(AccessControl.OWNABLE, TokenStandard.ERC721)
val deploymentParameter = DeploymentParameter("Metaverse", "MTV",DeploymentParameter.Options(true, true))
val result = NftService.deploySmartContractToken(Chain.POLYGON, deploymentParameter, deploymentOptions)

Ensure that the is configured with the appropriate gasPrice and gasLimit based on current market conditions prior to smart contract deployment, to ensure successful transactions. In the contract deployment call we set the transferable option to false, which deploys a soulbound token contract. This contract prevents any token transfers after the initial mint.

accessControl: [string] access control approach for the smart contract. Supported values: OWNABLE, ROLE_BASED_ACCESS_CONTROL. For more details about approaches.

Ensure that the is configured with the appropriate gasPrice and gasLimit based on current market conditions prior to minting, to ensure successful transactions.

metadata: NFT KIT will use values inside metadata to generate metadata URI of the new token. It confirms the structure defined by ERC721 and ERC1155 standards. For more details about .

Managing a required us to update the NFT metadata

|

"Ownership" is a simple approach to set up access control within your smart contract. You can easily provide the "accessControl" property with "OWNABLE" to get started. Thereby, the restricted areas of the contract can only be called by the owner of the contract.

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: RINKEBY, ROPSTEN, MUMBAI, SHIMMEREVM

contract: smart contract address

  • Path parameter:

chain: chain to work with.

Main chains: ETHEREUM, POLYGON

Testnet chains: RINKEBY, ROPSTEN, MUMBAI, SHIMMEREVM

contract: smart contract address

  • account: [string] the new owner address.

The verification function is shown in the following screenshot.

A test deployment of the NFT kit and the oceanDao data NFT verification API can be accessed here

In the verification process, the NFT is fetched from the chain per contract and account address, and it is checked if it was created by the particular factory contract and if the properties match. Note the properties might be any key/value pair of the JSON-structure. Either of the main data or of the nested structures (e.g. traits). By implementing the property-based validation in this generic way the NFT kit is future proof for any modifications to the meta data.

fungible (equals on Ethereum)

non-fungible (equals on Ethereum)

non-transferable (equals on Ethereum)

multi-asset contracts (equals on Ethereum)

API Doc

|

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

Body parameters

  • owner: [string] the owner(Admin) of the smart contract.

  • type: [string] the FA2 smart contract implementation. Either SINGLE or MULTIPLE. For more explanation, you can click .

Example:

|

|

metadata: NFT KIT will use values inside metadata to generate metadata URI of the new token. It confirms the structure defined by ERC721 and ERC1155 standards. For more details about .

|

|

|

  1. Clone the project

2. Change the folder

3. your project

4. Building the docker container

5. Running the container

  1. Clone the project

2. Change the folder

3. your project

4. Build the project

5. Run the executable

In build/distributions/ you have two archives, a .tar, and a .zip.

Extract the one that is built for your system and run it.

- How to verify NFT ownership and properties in the metadata

- View NFTs via a Web-Wallet

- See how the Ocean Protocol was integrated into the NFT-Kit

- How to verify NFT ownership and properties in the metadata

- View NFTs via a Web-Wallet

- See how the Ocean Protocol was integrated into the NFT-Kit

wallet
Architecture
NFT | Minting
NFT | Ownership
NFT | Wallet
Minting NFTs on Tezos
Swagger Doc
ReDoc
Smart Contract Extensions
Smart Contract Access Control -
GasProvider
access control
GasProvider
access control
GasProvider
NFT metadata standard
dynamic NFT
curl -X GET "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/owner"
curl -X POST "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/ownershipTransfer" \
-H  "Content-Type: application/json" \
-d '{"account":"0x8448Ff4b2733b52f62d81ca46d64bD16786299Cd"}'
{
  "account": "string"
}
curl -X POST "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/MUMBAI/contract/0xf277BE034881eE38A9b270E5b6C5c6f333Af2517/ownershipRenounce" 
curl -X GET "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/MUMBAI/contract/0xDc22fE8b277c03B5Af231b6a049631a06961F20d/account/0x8448Ff4b2733b52f62d81ca46d64bD16786299Cd/role/MINTING_ROLE" 
curl -X GET "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/ETHEREUM/contract/0xDc22fE8b277c03B5Af231b6a049631a06961F20d/role/METADATA_UPDATER_ROLE/admin" 
curl -X POST "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/MUMBAI/contract/0xDc22fE8b277c03B5Af231b6a049631a06961F20d/grantrole" \
-H  "Content-Type: application/json" \
-d '{"role":"minting_role","account":"0x8448Ff4b2733b52f62d81ca46d64bD16786299Cd"}'
{
  "role": "string",
  "account": "string"
}
curl -X POST "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/MUMBAI/contract/0xDc22fE8b277c03B5Af231b6a049631a06961F20d/revokeRole" \
-H  "Content-Type: application/json" \
-d '{"role":"METADATA_UPDATER_ROLE","account":"0x8448Ff4b2733b52f62d81ca46d64bD16786299Cd"}'
{
  "role": "string",
  "account": "string"
}
curl -X POST "http://0.0.0.0:7000/nftkit/nft/accessControl/chain/POLYGON/contract/0xDc22fE8b277c03B5Af231b6a049631a06961F20d/renounceRole" \
-H  "Content-Type: application/json" \
-d '{"role":"METADATA_UPDATER_ROLE","account":"0x8448Ff4b2733b52f62d81ca46d64bD16786299Cd"}'
{
  "role": "string",
  "account": "string"
}
val chain= TezosChain.GHOSTNET
val smartContractOwner= "tz1YiZtFfeu6qmr2G6PnyisJNjxDyaEWXs9J"
val smartContractType= Fa2SmartContractType.SINGLE
val result = TezosNftService.deploySmartContract(chain, smartContractOwner, smartContractType)
println("Smart contract address: ${result.contractAddress}"
println("Smart contract external url: ${result.contractExternalUrl}")
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/tezos/chain/{{chain}}/contract/{{contract}}/minter" 
-H  "Content-Type: application/json" 
-d "{"minterAddress":"string"}"
{
  "minterAddress": "string"
}
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/TEZOS/chain/GHOSTNET/contract/KT1QDuCUqmgotFqRtCK757J7xu47Bc7Ajp6q/minter" 
-H  "Content-Type: application/json" 
-d "{"minterAddress":"tz1YiZtFfeu6qmr2G6PnyisJNjxDyaEWXs9J"}"
 val chain= TezosChain.GHOSTNET
 val smartContractAddress= "KT1Ennr99qgqzKEUCEqypXEexH4wWzVL5a9m"
 val minterAddress= "tz1YiZtFfeu6qmr2G6PnyisJNjxDyaEWXs9J"
 val result = TezosNftService.addMinter(chain, smartContractAddress , minterAddress)
 println("Operation ID: ${result.operationHash}")
 println("Operation external url: ${result.operationExternalUrl}")tl
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/tezos/chain/{{chain}}/contract/{{contract}}/mint" 
-H  "Content-Type: application/json" 
-d "{"metadataUri":"string","tokenId":"string","amount":"string","recipientAddress":"string","metadata":{"name":"string","description":"string","symbol":"string","image":"string","creators":["string"],"decimals":"string","displayUri":"string","artifactUri":"string","thumbnailUri":"string","isTransferable":true,"isBooleanAmount":true,"shouldPreferSymbol":false,"attributes":[{"trait_type":"string","value":"string"},{"trait_type":"string","value":"string"},{"trait_type":"string","value":"string"}],"tags":["string"],"category":"string","collectionName":"string","creatorName":"string","keywords":"string"}}"
{
  "metadataUri": "string",
  "tokenId": "string",
  "amount": "string",
  "recipientAddress": "string",
  "metadata": {
    "name": "string",
    "description": "string",
    "symbol": "string",
    "image": "string",
    "creators": [
      "string"
    ],
    "decimals": "string",
    "displayUri": "string",
    "artifactUri": "string",
    "thumbnailUri": "string",
    "isTransferable": true,
    "isBooleanAmount": true,
    "shouldPreferSymbol": true,
    "attributes": [
      {
        "trait_type": "string",
        "value": "string"
      }
    ],
    "tags": [
      "string"
    ],
    "category": "string",
    "collectionName": "string",
    "creatorName": "string",
    "keywords": "string"
  }
}
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/tezos/chain/TEZOS/contract/KT1QDuCUqmgotFqRtCK757J7xu47Bc7Ajp6q/mint" 
-H  "Content-Type: application/json" 
-d "{"metadataUri":"","tokenId":"0","amount":"","recipientAddress":"tz1fXH6Tt2Qgvp7pjVpyNcZmunEbgRaHKcoQ","metadata":{"name":"NFT #0","description":"Rocket Monsters 10k Bear Battalion","symbol":"RM10KBB","image":"","creators":["tz1YiZtFfeu6qmr2G6PnyisJNjxDyaEWXs9J"],"decimals":"0","displayUri":"ipfs://QmZ6tRBw9cxDrc6dzy74JgNLSRYSbQAp3GHEbFqg2EQ8og","artifactUri":"ipfs://QmZ6tRBw9cxDrc6dzy74JgNLSRYSbQAp3GHEbFqg2EQ8og","thumbnailUri":"ipfs://QmZ6tRBw9cxDrc6dzy74JgNLSRYSbQAp3GHEbFqg2EQ8og","isTransferable":true,"isBooleanAmount":true,"shouldPreferSymbol":false,"attributes":[{"trait_type":"Backgrounds","value":"Green"},{"trait_type":"Fur","value":"Yellow"},{"trait_type":"Belly","value":"Blue_Steel"}],"tags":["string"],"category":"gaming","collectionName":"Rocket Monsters","creatorName":"rocketmonsters","keywords":"gaming,collectible,rocket,monster,bear,battalion"}}"
val chain= TezosChain.GHOSTNET
val smartContractAddress= "KT1Ennr99qgqzKEUCEqypXEexH4wWzVL5a9m"
val metadataUri=""
val recipientAddress= "tz1LeScZyZqmg8ZXYoN3mE8vA9GFrPm4HXkx"
val tokenId= "0"
val attribute1= NftMetadata.Attributes(trait_type = "Backgrounds", value = "Green")
val attribute2= NftMetadata.Attributes(trait_type = "Fur", value = "Yellow")
val attributes= listOf(attribute1, attribute2)
val metadata= TezosNftMetadata(name = "NFT #0", description = "Rocket Monsters Battalion", symbol = "RMB", displayUri = "ipfs://QmZ6tRBw9cxDrc6dzy74JgNLSRYSbQAp3GHEbFqg2EQ8og",
    artifactUri = "ipfs://QmZ6tRBw9cxDrc6dzy74JgNLSRYSbQAp3GHEbFqg2EQ8og", thumbnailUri = "ipfs://QmZ6tRBw9cxDrc6dzy74JgNLSRYSbQAp3GHEbFqg2EQ8og", isTransferable = true,
    attributes = attributes)
val parameter= TezosMintingParameter(metadataUri, recipientAddress, tokenId, null, metadata)
val result = TezosNftService.mintNftToken(chain, smartContractAddress , parameter)
println("Operation ID: ${result.operationHash}")
println("Operation external url: ${result.operationExternalUrl}")
curl -X GET "http://0.0.0.0:7000/nftkit/nft/tezos/chain/{{chain}}/contract/{{contract}}/token/{{tokenId}}/metadata"
curl -X GET "http://0.0.0.0:7000/nftkit/nft/tezos/chain/TEZOS/contract/KT1Ennr99qgqzKEUCEqypXEexH4wWzVL5a9m/token/0/metadata"
val nftMetadata = TezosNftService.getNftTezosMetadata(Chain.TEZOS, "KT1RCzrLhBpdKXkyasKGpDTCcdbBTipUk77x", "93531")
curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/{{chain}}/owner/{{owner}}" 
curl -X GET "http://0.0.0.0:7000/nftkit/nft/chain/TEZOS/owner/tz1fXH6Tt2Qgvp7pjVpyNcZmunEbgRaHKcoQ" 
val nfts = NftService.getAccountNFTs(Chain.GHOSTNET, "tz1LFRt8fCjtJmkUpVhRtfFba9VVHH4oSrUz")
curl -X GET "https://0.0.0.0:7000/nftkit/nft/tezos/chain/{{chain}}/contract/{{contract}}/metadata"
curl -X GET "https://0.0.0.0:7000/nftkit/nft/tezos/chain/TEZOS/contract/KT1WGDVRnff4rmGzJUbdCRAJBmYt12BrPzdD/metadata" -H  "accept: */*"
val contractMetadata= TezosNftService.getContractMetadata(TezosChain.TEZOS, "KT1WGDVRnff4rmGzJUbdCRAJBmYt12BrPzdD")
implementation("id.walt:waltid-nftkit:VERSION")
  <dependency>
        <groupId>id.walt</groupId>
        <artifactId>waltid-nftkit</artifactId>
        <version>VERSION</version>
   </dependency>
https://maven.walt.id/repository/waltid/

API

Get started building with our API endpoints

Kotlin/Java SDK

Add the NFT-Kits functionality as a direct dependency

Minting NFTs on Tezos

How to mint NFTs on Tezos

In this tutorial with 5 modules, we will create our first Tezos NFT collection, mint one of the NFTs to our address, learn how to verify ownership + metadata and how to admire the minted token in a web wallet.

Modules

  1. Setup - Clone and run the NFT-Kit

  2. A new collection - Configurations and Deployment of the NFT Smart Contract

  3. First NFT - Minting of the collection NFTs

  4. Verification - How to verify NFT ownership + metadata fields

  5. Wallet - Viewing the NFT in a web-wallet

Tutorials

Smart Contract

Smart contracts are simple programs that live in a NEAR network. As any modern application, smart contracts store data and expose methods to interact with them.

NFT standard :

NEP-171 is the standard for creating and managing NFTs on the NEAR blockchain. It specifies the data structure and smart contract interface for NFTs, allowing developers to create and manage NFTs in a consistent and interoperable way.

Rust Language :

The NEAR Pathway utilizes AssemblyScript as the primary programming language for its smart contracts, which are then compiled to WebAssembly (WASM) for execution on the blockchain.

However, NEAR also supports the use of Rust, a language that is particularly well-suited for server applications and has gained popularity for its built-in safety checks and testing infrastructure.

The NEAR team highly recommends the use of Rust for any smart contracts of a financial nature.

Smart contract scaffolding :

which is a framework of how Dapps work

use near_sdk::{near_bindgen,
borsh::{self, BorshDeserialize, BorshSerialize}
};
near_sdk::setup_alloc!();
#[near_bindgen]
#[derive(BorshDeserialize, BorshDeserialize)]
pub struct Contract {}
#[near_bindgen]
impl Contract {}

Swagger Doc
ReDoc
during deployment
ERC-20
ERC-721
ERC-1238
ERC-1155
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/tezos/chain/{{chain}}/contract/deploy" 
-H  "Content-Type: application/json" 
-d "{"owner":"string","type":"string"}"
{
  "owner": "tz1YiZtFfeu6qmr2G6PnyisJNjxDyaEWXs9J",
  "type": "SINGLE"
}
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/tezos/chain/GHOSTNET/contract/deploy" 
-H  "Content-Type: application/json" 
-d "{"owner":"tz1YiZtFfeu6qmr2G6PnyisJNjxDyaEWXs9J","type":"SINGLE"}"
Swagger Doc
ReDoc
here
Swagger Doc
ReDoc
Swagger Doc
ReDoc
NFT metadata standard
Swagger Doc
ReDoc
Swagger Doc
ReDoc
Swagger Doc
ReDoc
git clone https://github.com/walt-id/waltid-nftkit.git
cd waltid-nftkit/
docker build -t nftkit .
docker run -p 7000:7000 -it nftkit
git clone https://github.com/walt-id/waltid-nftkit.git
cd waltid-nftkit/
gradle clean build
cd build/distributions/
tar xf waltid-nftkit-1.0.0.tar 
./waltid-nftkit-1.0.0/bin/waltid-nftki
Configure
Configure
NFT | Verification
NFT | Wallet
Architecture
NFT | Verification
NFT | Wallet
Architecture

NFT | Wallet

Using our wallet, you can fetch and list your NFTs on Tezos blockchain.

Step1: Click on "Connect Tezos wallet" button.

Step 2: Choose an account.

Step 3: You will have the list of your NFTs in the main Tezos chain.

Step 4: You can switch between networks. Choose another network.

Step 5: You will have the list of your NFTs on the selected network.

Step 6: Click on the NFT you want to see their details.

NFT | Ownership Verification

NFT ownership verification

You can use this API to verify if an account is the real owner of an NFT existed in Tezos blockchain.

NFT ownership verification within a collection

We use this API to verify that an account has a NFT within a particular collection.

API Doc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{{chain}}/contract/{{contract}}/verifyNftOwnershipWithinCollection?account={{account}}" 
-H  "accept: application/json"

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • contract: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/GHOSTNET/contract/KT1RCzrLhBpdKXkyasKGpDTCcdbBTipUk77x/verifyNftOwnershipWithinCollection?account=tz1fXH6Tt2Qgvp7pjVpyNcZmunEbgRaHKcoQ" 
-H  "accept: application/json"
 val chain= Chain.GHOSTNET
 val smartContractAddress= "KT1Ennr99qgqzKEUCEqypXEexH4wWzVL5a9m"
 val account= "tz1LeScZyZqmg8ZXYoN3mE8vA9GFrPm4HXkx"
 val result = VerificationService.verifyNftOwnershipWithinCollection(chain, smartContractAddress, account!!)
 println("Result: ${result}")

NFT ownership verification with traits

You can use this API to verify if an account is the real owner of an NFT existed in Tezos blockchain with NFT property verification.

API Doc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{{chain}}/contract/{{contract}}/verifyNftOwnershipWithTraits?account={{account}}&tokenId={{tokenId}}&traitType={{traitType}}&traitValue={{traitValue}}"
-H  "accept: application/json"

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • contract: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

  • tokenId: [string] token id of the NFT

  • traitType: [string] name of the property you want to verify

  • tokenId: [string] value of the property you want to verify

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/TEZOS/contract/KT1RCzrLhBpdKXkyasKGpDTCcdbBTipUk77x/verifyNftOwnershipWithTraits?account=tz1fXH6Tt2Qgvp7pjVpyNcZmunEbgRaHKcoQ&tokenId=0&traitType=trait&traitValue=value"
-H  "accept: application/json"
val chain= Chain.GHOSTNET
val smartContractAddress= "KT1Ennr99qgqzKEUCEqypXEexH4wWzVL5a9m"
val account= "tz1LeScZyZqmg8ZXYoN3mE8vA9GFrPm4HXkx"
val tokenId= "0"
val traitType = "Backgrounds"
val traitValue = "Green"
val result = VerificationService.verifyNftOwnershipWithTraits(chain, smartContractAddress, account, tokenId, traitType,traitValue)
println("Result: ${result}")

Setup

Before we can start with configuring our NFT collection, we need to clone and run the NFT-Kits REST API on our machine.

Installation & Running the Project

Make sure you have a JDK 16 build environment including Gradle installed on your machine

Make sure you have a Node.js and the npm installed on your machine.

Now we can visit the REST API at the endpoint displayed in the terminal after running the project. In the next section, we will be configuring our NFT collection and deploy the Smart Contract on Tezos.

New Collection

Before we can mint an NFT, we need to define the collection, of which the NFT will be a part, via the deployment of a smart contract. Thanks to the REST-API from the NFT-Kit, we can easily deploy a contract based on the FA2 unified token standard from Tezos with the multiple implementation (equal to ERC-721 or ERC-1155on Ethereum). Which is one of the standards for creating NFTs.

Deploying the Contract

Before you mint a new NFT, you need to have an already deployed smart contract or deploy a new one. For this tutorial, we will deploy a new smart contract.

We will deploy the smart contract on the Tezos testnet "GHOSTNET". We need to provide the owner and the type of smart contract(our NFT Kit supports two smart contract implementations: you can click here for more details).

Response:

{
  "contractAddress": "KT1TPCdHiLQudhH79Zv7e5Ah46YYGQAA4t8o",
  "contractExternalUrl": "https://better-call.dev/ghostnet/KT1TPCdHiLQudhH79Zv7e5Ah46YYGQAA4t8o"
}

After that, you must define who can mint new tokens within an already deployed smart contract. In our case, we take the previously deployed contract.

The "minteraddress" is the account that will sign the mint transaction.

Response:

{
  "operationExternalUrl": "https://better-call.dev/ghostnet/opg/ooRwreh2VAkbK2C3REws1WLsJ1DcSWSZZMvKSrRjzcFji4f3BKL",
  "operationHash": "ooRwreh2VAkbK2C3REws1WLsJ1DcSWSZZMvKSrRjzcFji4f3BKL"
}

Architecture

Near Protocol + NFT-Kit Integration Diagramm

The NFT Kit is designed to make the process of creating, managing and transferring NFTs easy and accessible to anyone.

Our NFT kit implements the NEP-171 standard for NFTs on the NEAR Protocol that provides the core functionalities of creating, transferring and managing ownership of unique digital assets .

One of the main ways we integrate the Near Protocol ecosystem is through the use of the NEAR JavaScript API. This API allows us to interact with the NEAR blockchain and perform a variety of operations such as deploying contracts and minting NFTs. By using the NEAR JavaScript API, we are able to easily and securely interact with the Near Protocol and perform the necessary actions to create and manage NFTs.

Another way we integrate the Near Protocol ecosystem is through the use of the Near Java API. This is a library that allows for interaction with the NEAR Protocol through the use of the RPC API. This means that we are able to query information from the NEAR blockchain and retrieve data such as NFTs metadata. By using the Near Java API, we are able to easily access the data stored on the Near Protocol and use it within our NFT Kit.

All of these functionalities are exposed through a Rest API in our NFT Kit.

First NFT

Now, you're able to mint your first NFT. We will use the deployed smart contract in the previous section to mint a new NFT. Every NFT must have metadata. Using the NFT Kit, you have two options to provide the NFT metadata. Either give the metadata URI directly or let the NFT Kit generate the metadata URI based on IPFS. This tutorial will provide the metadata and let the NFT Kit generate the metadata URI.

We also need to provide the token id and the recipient account for the NFT.

The amount parameter must be an empty string because the type of the deployed smart contract is "SINGLE". If you use the "MULTIPLE" smart contract type, you should provide the number of copies of the minted NFT.

Wallet

Near Protocol

The NEAR protocol is a sharded, proof-of-stake, layer-one blockchain that is simple to use, secure and scalable.

NEAR Protocol is a public Proof-of-Stake (PoS) blockchain that aims to bring DeFi to the masses with low transfer fees and fast transactions. NEAR competes with Avalanche, Solana, Cardano, Algorand, the new version of Ethereum, and other PoS networks.

Getting Started

Depending on your preference, start exploring with the deep dive or a tutorial.

Deep dive

Tutorials

NEAR Sub-Account

In NEAR, users can register named accounts (e.g. bob.near) which are simpler to use and remember.

Named accounts can create sub-accounts of themselves, helping to better organize related-accounts. In this way, named accounts work as domains, particularly:

  1. Anyone can create long top-level accounts, e.g. verylongaccountnamethatis32chars.

  2. near can create bob.near, and bob.near can create app.bob.near.

  3. near cannot create app.bob.near, and test.near cannot create sub.example.near.

Create a Near Sub-Account for NFT smart contract

NFTs Queries

To acquire information from the Near Blockchain, we have incorporated the near-java-api into our NFTKit. This allows us to effectively interact with the rpc-api, providing us with the ability to retrieve and process data from the blockchain in a efficient and streamlined manner.

Verification

NFTs verification enables multiple use cases. The NFT Kit provides numerous approaches to verify the ownership of the NFTs and that the NFTs have customized properties.

1- You can verify that an account owns a particular NFT.

2- You can verify that an account owns an NFT in a specific collection.

3- You can verify that an account owns a particular NFT with a specific NFT metadata property.

4- You can also verify that an NFT metadata confirms a policy. The policy is implemented using the high-level declarative language called Rego. It is based on open policy agent(OPA).

You need to add new policy:

Then, you can apply the policy to any NFT metadata.

Blockchain NFTs operations

The NEAR Protocol provides a JavaScript API, known as near-api-js, that allows developers to interact with the Smart Contract and perform various operations related to Non-Fungible Tokens (NFTs).

near-api-js is a complete library to interact with the NEAR blockchain. You can use it in the browser, or in Node.js runtime.

Using near-api-js, developers can deploy smart contracts , mint new NFTs and transfer ownership of NFTs.

In the NFT kit we are using near-api-js to do interactions with the Near Protocol Blockchain

Create sub-account :

When developing it's a best practice to create a subaccount and deploy the contract to it. This function allows the subaccount creation and transfering Near token from the main account to use them for gas fees and storage.

Deploy smart contract with default Metadata :

Every NFT smart contract should be initialized , here we can deploy it with walt.id default metadata.

Deploy smart contract with custom Metadata :

For more flexibility we offer a custom metadata initialization to the deployed smart contract.

Mint NFT :

Finally we mint the non-fungible token with the custom metadata .

NFT | Creation & Management

Deploy NFT Contract

On Near Protocol , NFTs are not stored in the user's wallet, instead, each NFT lives in a NFT contract. The NFT contract works as a bookkeeper, this is: it is in charge of handling the creation, storage and transfers of NFTs.

Smart contract deployment with default metadata

Smart contract deployment with custom metadata

API Doc

Swagger Doc | ReDoc

Curl call example

Path parameters:

  • chain : [string] chain to work with. Either testnet or mainnet .

  • account_id :[string] your account.

Body Details:

Body parameters:

  • spec : a string that MUST be formatted nft-n.n.n where "n.n.n" is replaced with the implemented version of this Metadata spec.

  • name : the human-readable name of the contract.

  • symbol : the abbreviated symbol of the contract.

  • base_uri : Centralized gateway known to have reliable access to decentralized storage assets referenced by reference or media URLs. Can be used by other frontends for initial retrieval of assets, even if these frontends then replicate the data to their own decentralized nodes, which they are encouraged to do.

    val chain= Chain.ROPSTEN
    val factorycontractAddress= "0x13d474cc837549cd8106d6b945cf591a32a84e88"
    val erc721contractAddress= "0x0310aC2748616Ce399Ba83051DdE35126807c4DE"
    val account= "0xf31fc0d18a24c6ae4225a0d4eeb709ac0a18e993"
    val propertyKey= "color"
    val propertyValue="green"
    val verififcationResult= VerificationService.dataNftVerification(chain, factorycontractAddress, erc721contractAddress, account, propertyKey,propertyValue)
https://nftkit.walt.id/nftkit/swagger#/NFT%20verification/OceanDaoVerification

API Doc

|

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{{chain}}/contract/{{contract}}/verifyNftOwnership?account={{account}}&tokenId={{tokenId}}" 
-H  "accept: application/json"

Path parameters:

  • chain: [string] chain to work with. Either TEZOS or GHOSTNET.

  • contract: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

  • tokenId: [string] token id of the NFT

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/GHOSTNET/contract/KT1RCzrLhBpdKXkyasKGpDTCcdbBTipUk77x/verifyNftOwnership?account=tz1fXH6Tt2Qgvp7pjVpyNcZmunEbgRaHKcoQ&tokenId=0" 
-H  "accept: application/json"
val chain= Chain.GHOSTNET
val smartContractAddress= "KT1Ennr99qgqzKEUCEqypXEexH4wWzVL5a9m"
val account= "tz1LeScZyZqmg8ZXYoN3mE8vA9GFrPm4HXkx"
val tokenId= "0"
val result = VerificationService.verifyNftOwnership(chain, smartContractAddress, account, tokenId)
println("Result: ${result}")

|

|

  1. Clone the project

git clone https://github.com/walt-id/waltid-nftkit.git

2. Change the folder

cd waltid-nftkit/js

3. Put the needed by the file under the path: js/.envof the project

4. Run the following command:

npm install

4. Run the following command:

npm start

5. Open new terminal under the path: waltid-nftkit

6. Make the rest of the

7. Build the project

gradle clean build

8. Run the executable

In build/distributions/ you have two archives, a .tar, and a .zip.

Extract the one that is built for your system and run it.

cd build/distributions/
tar xf waltid-nftkit-1.0.0.tar 
./waltid-nftkit-1.0.0/bin/waltid-nftki

After minting your first NFT, you can see it using our wallet. It displays NFT details like smart contract address, token id, NFT name, etc. Click to use the test deployment of our wallet.

Click for more details about our wallet

- See how Near was integrated into the NFT-Kit

- How to deploy Smart Contracts and mint NFTs

- How to verify NFT ownership within a collection and traits

- View NFTs via a Web-Wallet

- Learn how to mint an NFT on Near using the REST interface

- Learn how to verify NFT ownership on Near using the REST interface

Only can create short top-level accounts (e.g. near, aurora).

API Doc

Swagger Doc | ReDoc

Curl call example

Path parameters:

  • chain : [string] chain to work with. Either testnet or mainnet .

Body Details:

Body parameters:

  • account_id : Top-level account.

  • newAccountId : New Sub-account.

  • amount : Number of Near tokens to transfer to the sub-account.

Example:

.

.

In order for a contract to be considered a NFT-contract it has to follow the . The NEP-171 & NEP-177 standards explain the minimum interface required to be implemented, as well as the expected functionality.

API Doc

Swagger Doc | ReDoc

Curl call example

Path parameters:

  • chain : [string] chain to work with. Either testnet or mainnet .

  • account_id :[string] your account.

Example:

icon : a small image associated with this contract. Encouraged to be a .

Swagger Doc
ReDoc
Swagger Doc
ReDoc
Swagger Doc
ReDoc
configuration
configuration
Smart Contract
Creation | Management Controller
Querying NFT information controller
here
here
Architecture
NFT | Minting
NFT | Ownership
NFT | Wallet
Mint an NFT
Verify NFT Ownership
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/{chain}/account/create"
-H  "Content-Type: application/json"
-d "{"account_id": "string","newAccountId": "string","amount": "string"}"
{
  "account_id": "string",
  "newAccountId": "string",
  "amount": "string"
}
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/testnet/account/create"
-H  "Content-Type: application/json"
-d "{"account_id": "waltid.testnet","newAccountId": "nft.waltid.testnet","amount": "4"}"
val accountId = "test.near"
val newAccountId = "test-sub.near"
val amount = "4"
val chain = "testnet"
val result = NearNftService.createSubAccount(accountId, newAccountId , amount , chain )
println("operation result: $result")
  async createAccount(createSubAccount: CreateSubAccount) {
    try {
      let rpcUrl;
      let networkId;
      if (createSubAccount.chain === "testnet") {
        rpcUrl = "https://rpc.testnet.near.org";
        networkId = "testnet";
      } else if (createSubAccount.chain === "mainnet") {
        rpcUrl = "https://rpc.mainnet.near.org";
        networkId = "mainnet";
      } else {
        throw new Error("Chain parameter is not defined");
      }
      this.addKeyPairToKeyStore(
        createSubAccount.account_id,
        createSubAccount.chain
      );
      this.connectionConfig = {
        networkId: networkId,
        keyStore: this.myKeyStore, 
        nodeUrl: "https://rpc.testnet.near.org",
        walletUrl: "",
        helperUrl: "",
        explorerUrl: "",
      };
      const near = await nearAPI.connect(this.connectionConfig);
      const account = await near.account(createSubAccount.account_id);
      const publickey = this.keyPair.getPublicKey().toString();
      const PK = publickey.replace("ed25519:", "");
      const amount = new BN(createSubAccount.amount);
      const response = account.createAccount(
        createSubAccount.newAccountId,
        PK,
        amount.mul(new BN("1000000000000000000000000"))
      );
      return JSON.stringify( (await response).transaction.hash );
    } catch (err) {
      console.log(err);
    }
  }
  async deployContract(contractDeployment: ContractDeployment) {
    this.addKeyPairToKeyStore(
      contractDeployment.account_id,
      contractDeployment.chain
    );
    const near = await nearAPI.connect(this.connectionConfig);
    const account = await near.account(contractDeployment.account_id);
    const response = await account.deployContract(
      fs.readFileSync("near/smart contract/waltid_nftkit.wasm")
    );
    const contract = new Contract(account, contractDeployment.account_id, {
      viewMethods: [],
      changeMethods: ["new_default_meta"],
    });
    const GAS = new BN("100000000000000");
    contract.new_default_meta({
      args: {
        owner_id: contractDeployment.account_id,
      },
      gas: GAS,
    });
    return JSON.stringify((await response).transaction.hash);
  }
  async deployContractWithCustomMetadata(
    ContractDeploymentWithCustomMetadata: DeployContractWithCustomInit
  ) {
    let rpcUrl;
    let networkId;
    if (ContractDeploymentWithCustomMetadata.chain === "testnet") {
      rpcUrl = "https://rpc.testnet.near.org";
      networkId = "testnet";
    } else if (ContractDeploymentWithCustomMetadata.chain === "mainnet") {
      rpcUrl = "https://rpc.mainnet.near.org";
      networkId = "mainnet";
    } else {
      throw new Error("Chain parameter is not defined");
    }
    this.addKeyPairToKeyStore(
      ContractDeploymentWithCustomMetadata.account_id,
      ContractDeploymentWithCustomMetadata.chain
    );
    this.connectionConfig = {
      networkId: networkId,
      keyStore: this.myKeyStore,
      nodeUrl: rpcUrl,
      walletUrl: "",
      helperUrl: "",
    };
    const near = await nearAPI.connect(this.connectionConfig);
    const account = await near.account(
      ContractDeploymentWithCustomMetadata.account_id
    );

    const response = await account.deployContract(
      fs.readFileSync("near/smart contract/waltid_nftkit.wasm")
    );
    const contract = new Contract(
      account,
      ContractDeploymentWithCustomMetadata.account_id,
      {
        viewMethods: [],
        changeMethods: ["new"],
      }
    );

    const GAS = new BN("100000000000000");
    contract.new({
      args: {
        owner_id: ContractDeploymentWithCustomMetadata.account_id,
        metadata: {
          spec: ContractDeploymentWithCustomMetadata.spec,
          name: ContractDeploymentWithCustomMetadata.name,
          symbol: ContractDeploymentWithCustomMetadata.symbol,
          icon: ContractDeploymentWithCustomMetadata.icon,
          base_uri: ContractDeploymentWithCustomMetadata.base_uri,
          reference: ContractDeploymentWithCustomMetadata.reference,
          reference_hash: ContractDeploymentWithCustomMetadata.reference_hash,
        },
      },
      gas: GAS,
    });
    return JSON.stringify((await response).transaction.hash);
  }
  async mintToken(nftmint: NftMint) {
    let rpcUrl;
    let networkId;
    if (nftmint.chain === "testnet") {
      rpcUrl = "https://rpc.testnet.near.org";
      networkId = "testnet";
    } else if (nftmint.chain === "mainnet") {
      rpcUrl = "https://rpc.mainnet.near.org";
      networkId = "mainnet";
    } else {
      throw new Error("Chain parameter is not defined");
    }
    this.addKeyPairToKeyStore(
      nftmint.account_id,
      nftmint.chain
    );
    this.connectionConfig = {
      networkId: networkId,
      keyStore: this.myKeyStore, 
      nodeUrl: rpcUrl,
      walletUrl: "",
      helperUrl: "",
    };
    const near = await nearAPI.connect(this.connectionConfig);
    const account = await near.account(nftmint.account_id);
    const GAS = new BN("100000000000000");
    const Amount_deposited = new BN("100000000000000000000000");
    const functionCallResponse = await account.functionCall({
      contractId: nftmint.contract_id,
      methodName: "nft_mint",
      args: {
              token_id: nftmint.token_id,
              metadata: {
                title: nftmint.title,
                description: nftmint.description,
                media: nftmint.media,
                media_hash: null,
              },
              receiver_id: nftmint.receiver_id,
            },
      gas: GAS,
      attachedDeposit: Amount_deposited,
    });
    return JSON.stringify(functionCallResponse.transaction.hash);
  }
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/{chain}/contract/account/{account_id}/deploy/default"
-H  "Content-Type: application/json" 
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/testnet/contract/account/nft.waltid.testnet/deploy/default"
-H  "Content-Type: application/json" 
val accountId = "nft.waltid.testnet"
val chain = "testnet"
val result = NearNftService.deployContractDefault(accountId, chain)
println("operation result: $result")
curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/{chain}/account/{account_id}/deploy"
-H  "Content-Type: application/json" 
-d "{"spec": "string","name": "string","symbol": "string","icon": "string","base_uri": "string","reference": "string","reference_hash": "string","owner_id": "string"}"
{
  "spec": "string",
  "name": "string",
  "symbol": "string",
  "icon": "string",
  "base_uri": "string",
  "reference": "string",
  "reference_hash": "string",
  "owner_id": "string"
}
val accountId = "nft.waltid.testnet"
val ownerId = "waltid.testnet"
val chain = "testnet"

val result = NearNftService.deployContractWithCustomMetadata(
        account_id = accountId,
        owner_id = ownerId,
        spec = "nft-1.0.0",
        name = "My NFT",
        symbol = "NFT",
        icon = "",
        base_uri = "",
        reference = "",
        reference_hash = "",
        chain = chain,
    )
println("operation result: $result")

📎 Create a Sub-account

📎 Deploy NFT Contract

🖼️ NFT | Minting

NFT | Minting

Minting an NFT on a blockchain allows the creator to prove ownership and authenticity of the digital asset

Mint NFT

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/{chain}/contract/{contract_id}/mint"
-H  "Content-Type: application/json"
-d  "{"account_id": "string","token_id": "string","title": "string","description": "string","media": "string","media_hash": "string","reference": "string","reference_hash": "string","receiver_id": "string"}"

Path parameters:

  • chain:[string] chain to work with. Either testnet or mainnet .

  • contract_id:[string] smart contract account .

Body parameters:

{
  "account_id": "string",
  "token_id": "string",
  "title": "string",
  "description": "string",
  "media": "string",
  "media_hash": "string",
  "reference": "string",
  "reference_hash": "string",
  "receiver_id": "string"
}
  • account_id: Your account id.

  • token_id: The token ID , must be unique.

  • title: The name of this specific token.

  • description: A longer description of the token.

  • media: URL to associated media. Preferably to decentralized, content-addressed storage.

  • media_hash : The base64-encoded sha256 hash of content referenced by the media field. This is to guard against off-chain tampering.

  • reference : URL to an off-chain JSON file with more info.

  • reference_hash : Base64-encoded sha256 hash of JSON from reference field. Required if reference is included.

  • receiver_id: The account that's receiving the token.

Example:

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/testnet/contract/nft.waltid.testnet/mint"
-H  "Content-Type: application/json"
-d  "{"account_id": "waltid.testnet","token_id": "0","title": "Walt.id NFT Art","description": "Waltid NFT Kit Example","media": "https://avatars.githubusercontent.com/u/84637756","media_hash": "","reference": "","reference_hash": "","receiver_id": "nft.waltid.testnet"}"
val accountId = "waltid.testnet"
val contractId =  "nft.waltid.testnet"
val receiverId = "waltid.testnet"
val chain = "testnet"


val result = NearNftService.mintNftToken(
        account_id = accountId,
        contract_id = contractId,
        token_id = "1",
        title = "waltid",
        description = "My NFT",
        media = "https://waltid.net",
        media_hash = "",
        reference = "",
        reference_hash = "",
        receiver_id = receiverId,
        chain = chain,
        
    )
println("operation result: $result")

Get NFT contract metadata

This API allows fetching contract metadata.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/{chain}/contract/{contract_id}/NFT/metadata"
-H "Content-Type: application/json" 

Path parameters:

  • chain:[string] chain to work with. Either testnet or mainnet .

  • contract_id:[string] smart contract account .

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/testnet/contract/nft.waltid.testnet/NFT/metadata"
-H "Content-Type: application/json" 
val contractId = "demo.khaled_lightency1.testnet"
val chain = "testnet"
val result = NearNftService.getNftNearMetadata(contractId , chain)
println("operation result: $result")

Get NFTs for account

Smart contract is responsible for NFTs ownership as it keeps a record of minted NFT per owner

NFT ownership verification

With this API , you can verify the ownership of All The NFTs for a given account.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/{chain}/contract/{contract_id}/account/{account_id}/NFTS"
-H  "Content-Type: application/json" 

Path parameters:

  • chain:[string] chain to work with. Either testnet or mainnet .

  • contract_id:[string] smart contract account .

  • account_id : your account.

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/testnet/contract/nft.waltid.testnet/account/waltid.testnet/NFTS"
-H  "Content-Type: application/json" 
val accountId = "waltid.testnet"
val contractId = "nft.waltid.testnet"
val chain = "testnet"
    
val result = NearNftService.getNFTforAccount(accountId , contractId, chain)
println("operation result: $result")

Get NFT By Token Id

Smart contract is responsible for NFTs ownership as it keeps a record of minted NFT per owner .

NFT ownership verification

With this API , you can verify the ownership of a specific NFT by its unique Token_id.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/{chain}/contract/{contract_id}/NFT/{token_id}"
-H  "Content-Type: application/json" 

Path parameters:

  • chain:[string] chain to work with. Either testnet or mainnet .

  • contract_id:[string] smart contract account .

  • token_id : Unique token_id of the NFT.

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/near/chain/testnet/contract/nft.waltid.testnet/NFT/0"
-H  "Content-Type: application/json" 
val contractId = "nft.waltid.testnet"
val tokenId = "0"
val chain = "testnet"
    
val result = NearNftService.getTokenById(contractId, tokenId, chain)
println("operation result: $result")

Minting NFT on Near Protocol

We will learn how to use this NFT-kit to mint our first NFT on Near Protocol

registrar
Verify all NFTs of a given account.
Get NFT contract Metadata
Get NFT by Token Id
NEP-171 and NEP-177 standards
data URL

Polkadot

Querying NFT information controller

NFT | Wallet

Installation :

1 - Download waltid web wallet :

git clone https://github.com/walt-id/waltid-web-wallet.git

2 - Build Setup :

# install dependencies
$ yarn install

# serve with hot reload at localhost:3000
$ yarn dev

# build for production and launch server
$ yarn build
$ yarn start

# generate static project
$ yarn generate

Usage :

Step1: Click on "Connect with web3" button.

Step 2: Click on "Near"

Step 3: Choose your wallet.

Step 4: Choose an account.

Step 5 : You will have the list of NFTs on the selected Network.

Step 6 : Click on "View" to see more details.

Smart Contract ( Collection )

Before we can mint an NFT, we need to define the collection, of which the NFT will be a part, via the deployment of a smart contract.

Deploying the Contract

Before you mint a new NFT, you need to have an already deployed smart contract or deploy a new one. For this tutorial, we will deploy a new smart contract.

We will deploy the smart contract on the Near testnet. We need to provide the owner and the metadata of smart contract.

Example 1 : Default Contract metadata

Example 2 : Custom Contract metadata

Near Wallet Creation

We will need a Near wallet in order to mint our NFT , creating a wallet is very easy! Here are a few easy steps to get you started

Click on “Get Started”

Step 2: Choose a Security Method

To protect your account, you’ll have to select an option to secure your NEAR wallet.

Choose from the three security methods mentioned to start your wallet initialization — Secure Passphrase / Ledger Hardware Wallet / Email

Step 3: Fund Your NEAR Wallet

Tutorials

What are NFTs?

NFTs (Non-Fungible Tokens) are a type of digital asset that are stored on a blockchain network and represent unique items or pieces of content. NFTs are typically used to represent things like artwork, music, videos, or other types of creative works, as they allow creators to verify and authenticate the ownership and provenance of their creations.

On the Near Protocol, NFTs are created and managed through smart contracts that are stored on the blockchain. These contracts define the rules and logic for how the NFTs are created, transferred, and managed.

To create an NFT on the Near Protocol, you would first need to create a smart contract that defines the NFT's properties and behaviors. This contract would typically include things like the NFT's name, description, image, and any other relevant metadata.

Once the NFT contract is deployed to the blockchain, you can then use it to mint new NFTs. To mint an NFT, you would typically need to provide some sort of payment, such as Near tokens, in exchange for the new NFT.

Once the NFT is minted, it can be transferred and traded just like any other asset on the blockchain. The unique properties of NFTs, such as their provenance and authenticity, make them particularly valuable for creators and collectors of digital content.

Start with our Tutorials

Setup NFT-Kit

Before we can start with configuring our NFT collection, we need to clone and run the NFT-Kits REST API on our machine.

Installation & Running the Project

Make sure you have a JDK 16 build environment including Gradle installed on your machine

Make sure you have a Node.js and the npm installed on your machine.

Now we can visit the REST API at the endpoint displayed in the terminal after running the project. In the next section, we will be configuring our NFT collection and deploy the Smart Contract on Near Protocol blockchain

Minting your first NFT

Now, you're able to mint your first NFT. We will use the deployed smart contract in the previous section to mint a new NFT. We also need to provide the token id and the recipient account for the NFT.

Create Sub-account

Your account can create direct sub accounts of itself, for example, user.near can create sub.user.near.

Create a sub-account

Sub accounts on near help with the organisation of your project , it separates the smart contract address from your main account.

NFT Ownership Verification

NFTs verification enables multiple use cases. The NFT Kit provides numerous approaches to verify the ownership of the NFTs and that the NFTs have customized properties.

1- You can verify that an account owns a particular NFT.

2- You can verify that an account owns an NFT in a specific collection.

3- You can also verify that an NFT metadata confirms a policy. The policy is implemented using the high-level declarative language called Rego. It is based on open policy agent(OPA).

You need to add new policy:

Unique network

Fetching Token id & Collection id

With this API , you can return the list of token ids and collection ids for a given account

Fetching NFT metadata

With this API , you can return the list of NFTs on unique network.

API Doc

Swagger Doc | ReDoc

Curl call example

Path parameters:

  • chain:[string] chain to work with. Either UNIQUE or OPAL .

  • collectionId : the collection id on the network.

  • tokenId : NFT token id

Example:

Architecture

Polkadot Protocol + NFT-Kit Integration Diagram

The NFT Kit is responsible for fetching NFTs and their details from Polkadot. We have three main components:

  1. REST APIs/Library: you can access the functionalities provided by the NFT Kit through two interfaces: as a library or through REST APIs.

  2. NFTs operation: within this component, we will have a list of NFTs operations like fetching NFT metadata, a list of NFTs, verify NFT ownership/metadata against policies.

  3. NFTs queries: this component generates a query and routes it to the specific ecosystem based on the demand of the NFTs operation component.

Different approaches to managing NFTs in the Polkadot ecosystem include PSP-34, PSP-37, RMRK, Uniques, etc. The NFT Kit provides an abstract layer for operations with any NFTs approach within the Polkadot ecosystem. With the NFT Kit, the NFTs ecosystem in Polkadot will be more accessible to developers to build more advanced use cases.

RMRK 2.0

  • RMRK is a set of NFT standards which compose several "NFT 2.0 lego" primitives. Putting these legos together allows a user to create NFT systems of arbitrary complexity.

  • Our solution will be integrated with Kusama canary network Implementation (Remarks).

Uniques

  • Unique Network is the next generation NFT chain for advanced use cases and mass adoption.

  • Unique provides REST APIs to query NFTs details in the Unique Network.

  • Unique has three networks:

  1. Unique is a Polkadot parachain.

  2. Quartz is a Kusama parachain.

  3. Opal is a testnet.

Astar

  • Astar Network supports the building of dApps with EVM and WASM smart contracts and offers developers true interoperability.

  • Astar supports EVM smart contracts.

  • It enables Wasm smart-contract using The pallet-contracts. The pallet-contracts is a sandbox environment to deploy and execute WebAssembly smart contracts. Any language that compiles to Wasm can be used. But the code should be compatible with the pallet-contracts API.

  • The Polkadot ecosystem provides two standard interfaces for Non-Fungible Token: PSP-34(Non-Fungible Token (ERC721 equivalent) with extensions) and PSP37( ERC1155 equivalent with extensions). The goal is to have a standard contract interface that allows tokens deployed on Substrate's contracts pallet.

  • Blockscout: BlockScout provides a comprehensive, easy-to-use interface for users to view, confirm, and inspect transactions on EVM blockchains

  • Subscan API: it provides a simple way to access the chain data of more than 10 substrate-based networks.

  • Unique REST APIs

  • Subsquid: A squid is a project that extracts and transforms on-chain data in order to present it as a GraphQL API.

  • Polkaholic API: It gives you powerful access to over 50+ networks in Polkadot and Kusama ecosystems.

  • Substrate API Sidecar: REST service that makes it easy to interact with blockchain nodes built using Substrate's FRAME framework.

NFT | Ownership Verification

NFT ownership verification

You can use this API to verify if an account is the real owner of an NFT.

NFT ownership verification within a collection

We use this API to verify that an account has a NFT within a particular collection.

API Doc

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either ASTAR, MOONBEAM, UNIQUE, OPAL.

  • contract: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

Example:

NFT ownership verification with traits

You can use this API to verify if an account is the real owner of an NFT existed in Polkadot blockchain with NFT property verification.

API Doc

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either ASTAR, MOONBEAM, UNIQUE, OPAL.

  • contract: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

  • tokenId: [string] token id of the NFT

  • traitType: [string] name of the property you want to verify

  • tokenId: [string] value of the property you want to verify

Example:

Polkadot EVM compatible parachains

Usage :

Step1: Click on "Connect Polkadot (EVM)" button.

Step 2: Allow connection to the application.

Step 3 : You will have the list of NFTs on the selected Network.

Polkadot parachains

Usage :

Step1: Click on "Connect Polkadot wallet" button:

Step 2: Allow connection to the application.

Step 3 : You will have the list of NFTs on the selected Network.

Step 4 : You can display NFT details .

Parachain Networks

Fetching Tokens by subscan

With this API , you can return the list of tokens by subscan.

Fetching EVM ERC721 Collectibles by subscan

With this API , you can return the list of NFTs on unique network.

API Doc

Swagger Doc | ReDoc

Curl call example

Path parameters:

  • Chain:[string] chain to work with. Either MOONBEAM or ASTAR .

  • account : your account.

Example:

NFT | Wallet

Installation :

1 - Download waltid web wallet :

2 - Build Setup :

Using our , you can fetch and list your NFTs on Near Protocol blockchain.

smart contract deployment - default metadata

Step 1: Go to and “Create Account”

  1. Clone the project

git clone https://github.com/walt-id/waltid-nftkit.git

2. Change the folder

cd waltid-nftkit/js

3. Put the needed by the file under the path: js/.envof the project

4. Run the following command:

npm install

4. Run the following command:

npm start

5. Open new terminal under the path: waltid-nftkit

6. Make the rest of the

7. Build the project

gradle clean build

8. Run the executable

In build/distributions/ you have two archives, a .tar, and a .zip.

Extract the one that is built for your system and run it.

cd build/distributions/
tar xf waltid-nftkit-1.0.0.tar 
./waltid-nftkit-1.0.0/bin/waltid-nftki

API Doc

Swagger Doc | ReDoc

Curl call example

Path parameters:

  • Network:[string] chain to work with. Either UNIQUE or OPAL .

  • account : your account.

Example:

API Doc

|

Curl call example

Path parameters:

  • chain: [string] chain to work with. Either ASTAR, MOONBEAM, UNIQUE, OPAL.

  • contract: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

  • tokenId: [string] token id of the NFT

Example:

|

|

Using our , you can fetch and list your NFTs on Polkadot EVM compatible chains.

Using our , you can fetch and list your NFTs on Polkadot chains.

API Doc

Swagger Doc | ReDoc

Curl call example

Path parameters:

  • Chain:[string] chain to work with. Either MOONBEAM or ASTAR .

  • account : your account.

Example:

Using our , you can fetch and list your NFTs on Polkadot blockchain.

🖼️ Get NFTs for account

🖼️ Get NFT contract Metadata

🖼️ GET NFT By Token id

testnet.mynearwallet.com

Minting NFTs

Ownership verification

Wallet integration

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/unique/chain/{network}/account/{account}"
-H  "Content-Type: application/json" 
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/unique/chain/UNIQUE/account/DoiHfvzkJsZP2MjXkVe6EVrMNjhcSLzXtR29tZS2HNTyDQt"
-H  "Content-Type: application/json" 
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/unique/chain/{chain}/collection/{collectionId}/token/{tokenId}/metadata"
-H  "Content-Type: application/json" 
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/unique/chain/UNIQUE/account/DoiHfvzkJsZP2MjXkVe6EVrMNjhcSLzXtR29tZS2HNTyDQt"
-H  "Content-Type: application/json" 
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{{chain}}/contract/{{contract}}/verifyNftOwnershipWithinCollection?account={{account}}" 
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/MOONBEAM/contract/0x41Ee4762421d659C1525D04B41CB740e9E262b21/verifyNftOwnershipWithinCollection?account=0x2e3A8FAb541F188Eb2378a8a3720E6616fd38830" 
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{{chain}}/contract/{{contract}}/verifyNftOwnershipWithTraits?account={{account}}&tokenId={{tokenId}}&traitType={{traitType}}&traitValue={{traitValue}}"
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/MOONBEAM/contract/0x41Ee4762421d659C1525D04B41CB740e9E262b21/verifyNftOwnershipWithTraits?account=0x2e3A8FAb541F188Eb2378a8a3720E6616fd38830&tokenId=7&traitType=trait&traitValue=value"
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/parachain/{chain}/account/{account}"
-H  "Content-Type: application/json" 
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/parachain/MOONBEAM/account/0x2e3A8FAb541F188Eb2378a8a3720E6616fd38830"
-H  "Content-Type: application/json" 
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/parachain/{chain}/account/{account}/EvmErc721"
-H  "Content-Type: application/json" 
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/parachain/ASTAR/account/0x2e3A8FAb541F188Eb2378a8a3720E6616fd38830/EvmErc721
"
-H  "Content-Type: application/json" 
git clone https://github.com/walt-id/waltid-web-wallet.git
# install dependencies
$ yarn install

# serve with hot reload at localhost:3000
$ yarn dev

# build for production and launch server
$ yarn build
$ yarn start

# generate static project
$ yarn generate

Get NFTs for an account

NFT ownership verification

With this API , you can verify the ownership of All The NFTs for a given account.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/flow/chain/{chain}/account/{account_id}/AllNFTs" 
-H  "accept: application/json" -d ""

Path parameters:

  • chain:[string] chain to work with. Either testnet or mainnet .

  • account_id : your account.

Example:

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/flow/chain/testnet/account/0xe8e83eb775b67bc2/AllNFTs" 
-H  "accept: application/json" -d ""
var chain = "TESTNET"
var account_id = "0xe8e83eb775b67bc2"

var result = FlowNftService.getAllNFTs(account_id, FlowChain.valueOf(chain))
println(result)

NFT Operations (FCL)

The Flow Client Library (FCL)

The FCL JS package enables communication between user wallets and the Flow blockchain, making it unnecessary for dapps to modify their code or integrate custom solutions when utilizing FCL for authentication. Its purpose is to simplify and secure the development of applications that interface with the Flow blockchain by providing a standardized set of communication patterns for wallets, applications, and users. Additionally, FCL JS includes an SDK and utilities to interact with the Flow blockchain, and can be used in both browser and server environments.

Installation

To use the FCL JS in your application, install using yarn or npm

npm i -S @onflow/fcl
yarn add @onflow/fcl

Importing

ES6

import * as fcl from "@onflow/fcl";

Node.js

const fcl = require("@onflow/fcl");

Configuration

import { config } from "@onflow/fcl";

config({
  "accessNode.api": "https://rest-testnet.onflow.org", // Mainnet: "https://rest-mainnet.onflow.org"
  "discovery.wallet": "https://fcl-discovery.onflow.org/testnet/authn" // Mainnet: "https://fcl-discovery.onflow.org/authn"
})

The accessNode.api key specifies the address of a Flow access node. Flow provides these, but in the future access to Flow may be provided by other 3rd parties, through their own access nodes. discovery.wallet is an address that points to a service that lists FCL compatible wallets. Flow's FCL Discovery service is a service that FCL wallet providers can be added to, and be made 'discoverable' to any application that uses the discovery.wallet endpoint.

Blockchain Interactions

FCL enables interactions with the Flow blockchain by :

  • Query the chain: Send arbitrary Cadence scripts to the chain and receive back decoded values.

import * as fcl from "@onflow/fcl";

const result = await fcl.query({
  cadence: `
    pub fun main(a: Int, b: Int, addr: Address): Int {
      log(addr)
      return a + b
    }
  `,
  args: (arg, t) => [
    arg(7, t.Int), // a: Int
    arg(6, t.Int), // b: Int
    arg("0xba1132bc08f82fe2", t.Address), // addr: Address
  ],
});
console.log(result); // 13
  • Mutate the chain: Send arbitrary transactions with your own signatures or via a user's wallet to perform state changes on chain.

import * as fcl from "@onflow/fcl";
// in the browser, FCL will automatically connect to the user's wallet to request signatures to run the transaction
const txId = await fcl.mutate({
  cadence: `
    import Profile from 0xba1132bc08f82fe2
    
    transaction(name: String) {
      prepare(account: AuthAccount) {
        account.borrow<&{Profile.Owner}>(from: Profile.privatePath)!.setName(name)
      }
    }
  `,
  args: (arg, t) => [arg("myName", t.String)],
});

Retrieve All NFTs

  async getAllNFTs(Address: string , chain: string) {
    const ad = Address;

      if (chain === "mainnet") {
          var MetadataViews = process.env.MetadataViews_mainnet;
          var NFTCatalog = process.env.NFTCatalog_mainnet;
          var NFTRetrieval = process.env.NFTRetrieval_mainnet;
          var url = "https://access-mainnet-beta.onflow.org";
      }
      else
      {
          var MetadataViews =process.env.MetadataViews_testnet;
          var NFTCatalog =process.env.NFTCatalog_testnet;
          var NFTRetrieval = process.env.NFTRetrieval_testnet;
          var url = "https://access-testnet.onflow.org";
      }

      fcl.config().put("accessNode.api", url);

      console.log(ad);
    try {

        const response = await fcl.query({
            cadence: `
import MetadataViews from ${MetadataViews}
import NFTCatalog from ${NFTCatalog}
import NFTRetrieval from ${NFTRetrieval}

pub struct NFT {
    pub let id: UInt64
    pub let name: String
    pub let description: String
    pub let thumbnail: String
    pub let externalURL: String
    pub let collectionStoragePath: StoragePath
    pub let collectionPublicPath: PublicPath
    pub let collectionPrivatePath: PrivatePath
    pub let publicLinkedType: Type
    pub let privateLinkedType: Type
    pub let collectionName: String
    pub let collectionDescription: String
    pub let collectionSquareImage: String
    pub let collectionBannerImage: String
    pub let collectionExternalURL: String
    pub let royalties: [MetadataViews.Royalty]

    init(
        id: UInt64,
        name: String,
        description: String,
        thumbnail: String,
        externalURL: String,
        collectionStoragePath: StoragePath,
        collectionPublicPath: PublicPath,
        collectionPrivatePath: PrivatePath,
        publicLinkedType: Type,
        privateLinkedType: Type,
        collectionName: String,
        collectionDescription: String,
        collectionSquareImage: String,
        collectionBannerImage: String,
        collectionExternalURL: String,
        royalties: [MetadataViews.Royalty]
    ) {
        self.id = id
        self.name = name
        self.description = description
        self.thumbnail = thumbnail
        self.externalURL = externalURL
        self.collectionStoragePath = collectionStoragePath
        self.collectionPublicPath = collectionPublicPath
        self.collectionPrivatePath = collectionPrivatePath
        self.publicLinkedType = publicLinkedType
        self.privateLinkedType = privateLinkedType
        self.collectionName = collectionName
        self.collectionDescription = collectionDescription
        self.collectionSquareImage = collectionSquareImage
        self.collectionBannerImage = collectionBannerImage
        self.collectionExternalURL = collectionExternalURL
        self.royalties = royalties
    }
}

pub fun main(ownerAddress: Address): {String: [NFT]} {
    let account = getAuthAccount(ownerAddress)
    let items: [MetadataViews.NFTView] = []
    let data: {String: [NFT]} = {}

    NFTCatalog.forEachCatalogKey(fun (collectionIdentifier: String):Bool {
        let value = NFTCatalog.getCatalogEntry(collectionIdentifier: collectionIdentifier)!
        let keyHash = String.encodeHex(HashAlgorithm.SHA3_256.hash(collectionIdentifier.utf8))
        let tempPathStr = "catalog".concat(keyHash)
        let tempPublicPath = PublicPath(identifier: tempPathStr)!

        account.link<&{MetadataViews.ResolverCollection}>(
            tempPublicPath,
            target: value.collectionData.storagePath
        )

        let collectionCap = account.getCapability<&AnyResource{MetadataViews.ResolverCollection}>(tempPublicPath)

        if !collectionCap.check() {
            return true
        }

        let views = NFTRetrieval.getNFTViewsFromCap(collectionIdentifier: collectionIdentifier, collectionCap: collectionCap)
        let items: [NFT] = []

        for view in views {
            let displayView = view.display
            let externalURLView = view.externalURL
            let collectionDataView = view.collectionData
            let collectionDisplayView = view.collectionDisplay
            let royaltyView = view.royalties

            if (displayView == nil || externalURLView == nil || collectionDataView == nil || collectionDisplayView == nil || royaltyView == nil) {
                // Bad NFT. Skipping....
                return true
            }

            items.append(
                NFT(
                    id: view.id,
                    name: displayView!.name,
                    description: displayView!.description,
                    thumbnail: displayView!.thumbnail.uri(),
                    externalURL: externalURLView!.url,
                    collectionStoragePath: collectionDataView!.storagePath,
                    collectionPublicPath: collectionDataView!.publicPath,
                    collectionPrivatePath: collectionDataView!.providerPath,
                    publicLinkedType: collectionDataView!.publicLinkedType,
                    privateLinkedType: collectionDataView!.providerLinkedType,
                    collectionName: collectionDisplayView!.name,
                    collectionDescription: collectionDisplayView!.description,
                    collectionSquareImage: collectionDisplayView!.squareImage.file.uri(),
                    collectionBannerImage: collectionDisplayView!.bannerImage.file.uri(),
                    collectionExternalURL: collectionDisplayView!.externalURL.url,
                    royalties: royaltyView!.getRoyalties()
                )
            )
        }

        data[collectionIdentifier] = items
        return true
    })

    return data
}
  `,
            //@ts-ignore
            args: (arg, t) => [arg(Address, t.Address)],
        });
        return response;
    }
    catch (error) {
        return error;
    }
  }

Get NFT by Token id

  async getNftById(account_id : String  , contractAddress: string,  collectionPublicPath : string,id: number, chain: string) {
      if (chain === "mainnet") {
          var MetadataViews = process.env.MetadataViews_mainnet;
          var url = "https://access-mainnet-beta.onflow.org";
      }
      else
      {
          var MetadataViews =process.env.MetadataViews_testnet;
          var url = "https://access-testnet.onflow.org";
      }

      fcl.config().put("accessNode.api", url);

    const ad = id;

    try {
        const response = await fcl.query({
            cadence: `
        
import MetadataViews from ${MetadataViews}

pub struct NFTView {
          pub let id: UInt64
          pub let name: String
          pub let description: String
          pub let externalURL: String
          pub let thumbnail : String
        
          init(
              id: UInt64,
              name: String,
              description: String,
              externalURL: String,
              thumbnail : String
              
          ) {
              self.id = id
              self.name = name
              self.description = description
              self.externalURL = externalURL
              self.thumbnail = thumbnail
          }
        }
/// This script gets all the view-based metadata associated with the specified NFT
/// and returns it as a single struct

pub fun main(address: Address, id: UInt64) : NFTView {
    let account = getAccount(address)

    
    
 let collection = account
              .getCapability(${collectionPublicPath})
              .borrow<&{MetadataViews.ResolverCollection}>()
              ?? panic("Could not borrow a reference to the collection")
        
          let viewResolver = collection.borrowViewResolver(id: id)!
        
          let nftView = MetadataViews.getNFTView(id: id, viewResolver : viewResolver)
        
          let collectionSocials: {String: String} = {}
          for key in nftView.collectionDisplay!.socials.keys {
              collectionSocials[key] = nftView.collectionDisplay!.socials[key]!.url
          }

            

 return NFTView(
              id: nftView.id,
              name: nftView.display!.name,
              description: nftView.display!.description,
              externalURL: nftView.externalURL!.url,
              thumbnail :  nftView.display!.thumbnail.uri()
          )
   
}
 
     `,
            //@ts-ignore
            args: (arg, t) => [
                arg(account_id, t.Address),
                arg(ad, t.UInt64)
            ],

        });
        return response;
    }catch (error) {
        return error;
    }

  }

Get NFTs in Collection

  async getNftsByAddressInCollection(Address: string ,collectionPath : string ,chain: string) {

      if (chain === "mainnet") {
          var MetadataViews = process.env.MetadataViews_mainnet;
          var url = "https://access-mainnet-beta.onflow.org";
      }
      else
      {
          var MetadataViews =process.env.MetadataViews_testnet;
          var url = "https://access-testnet.onflow.org";
      }

      fcl.config().put("accessNode.api", url);



    try {
        const response = await fcl.query({
            cadence: `

import MetadataViews from ${MetadataViews}

/// This script gets all the view-based metadata associated with the specified NFT
/// and returns it as a single struct

pub fun main(address: Address): [{String: AnyStruct}] {
    let account = getAccount(address)

    let collection = account
        .getCapability(${collectionPath})
        .borrow<&{MetadataViews.ResolverCollection}>()
        ?? panic("Could not borrow a reference to the collection")

    let nft = collection.getIDs()
       var nfts: [{String: AnyStruct}] = []
    for id in nft {
       
       let nft = collection.borrowViewResolver(id: id)

    // Get the basic display information for this NFT
         let display = MetadataViews.getDisplay(nft)!

        let identifier = nft.getType().identifier
        let traits = MetadataViews.getTraits(nft)!
        
        let externalURL = MetadataViews.getExternalURL(nft)!.url

        
        

        
      let nftData = {
        "id": UInt64(id), 
        
         "name": display.name,
         "description": display.description, 
         "thumbnail": display.thumbnail.uri(),
         "identifier": identifier,
         "traits": traits,
         "externalURL": externalURL
            
       
          
      }
        nfts.append(nftData)
    }
  
    

    return nfts
}
 
  `,
            //@ts-ignore
            args: (arg, t) => [arg(Address, t.Address)],
        });
        return response;
    }catch (error) {
        return error;
    }
  }

Get NFTs in Collection

NFT ownership verification

With this API , you can verify the ownership of NFTs within a collection.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/flow/chain/{chain}/account/{account_id}/{collectionPath}/getNFTinCollection"
-H  "Content-Type: application/json" 

Path parameters:

  • chain:[string] chain to work with. Either testnet or mainnet .

  • account_id:[string] your account .

  • collectionPublicPath:[string] path of the collection.

Example:

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/flow/chain/testnet/account/0xe8e83eb775b67bc2/%2Fpublic%2FexampleNFTCollection/getNFTinCollection" 
-H  "accept: application/json" -d ""
var chain = "TESTNET"
var account_id = "0xe8e83eb775b67bc2"
var collectionPath = "/public/exampleNFTCollection"

var result = FlowNftService.getNFTinCollectionPath(account_id,collectionPath, FlowChain.valueOf(chain))
println(result)

Account Creation

A standalone account is an Algorand address and private key pair that is not stored on disk. The private key is most often in the 25-word mnemonic form.

Standalone accounts have a low setup cost as you do not need to connect to a separate client that depends on separate hardware. All you need is the 25-word human-readable mnemonic of the relevant account.

Create an Algorand Account

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/Algorand/account/create" 
-H  "accept: application/json" 
-d ""

Response :

{
  "address": "string",
  "mnemonic": "string"
}
import id.walt.nftkit.services.AlgorandNftService

val algroand_new_account = AlgorandNftService.createAccount()
println("algroand_new_account: $algroand_new_account")

You can later import the created account to any wallet supporting Algorand using the mnemonic phrase.

Get NFT by Token Id

NFT ownership verification

With this API , you can verify the ownership of a specific NFT by its unique Token_id.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/flow/chain/{chain}/account/{account_id}/{contractAddress}/{collectionPublicPath}/{token_id}/getNFTById"
-H  "Content-Type: application/json" 

Path parameters:

  • chain:[string] chain to work with. Either testnet or mainnet .

  • contractAddress:[string] smart contract account .

  • token_id:[string] Flow token_id of the NFT.

  • collectionPublicPath:[string] path of the collection.

Example:

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/flow/chain/testnet/account/0xe8e83eb775b67bc2/0xa9ccb9756a0ee7eb/%2Fpublic%2FexampleNFTCollection/1/getNFTById" 
-H  "accept: application/json" -d ""
var chain = "TESTNET"
var account_id = "0xe8e83eb775b67bc2"
var collectionPath = "/public/exampleNFTCollection"
var token_id = "1"
var contractAddress = "0xa9ccb9756a0ee7eb"

var result = FlowNftService.getNFTbyId(account_id, contractAddress, collectionPath, token_id, FlowChain.valueOf(chain))
println(result)
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{{chain}}/contract/{{contract}}/verifyNftOwnership?account={{account}}&tokenId={{tokenId}}" 
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/MOONBEAM/contract/0x41Ee4762421d659C1525D04B41CB740e9E262b21/verifyNftOwnership?account=0x2e3A8FAb541F188Eb2378a8a3720E6616fd38830&tokenId=7" 
-H  "accept: application/json"
Swagger Doc
ReDoc
Swagger Doc
ReDoc
Swagger Doc
ReDoc

Algorand Standard Assets (ASAs)

Overview

The Algorand protocol enables the creation of on-chain assets that enjoy the same level of security, compatibility, speed, and user-friendliness as the Algo cryptocurrency. These assets are officially known as Algorand Standard Assets (ASA). ASA allows for the representation of various assets, including stablecoins, loyalty points, system credits, in-game points, and more. It also enables the representation of unique assets such as property deeds, collectible items, specific components in a supply chain, and others.

How to create NFTs on Algorand ?

Algorand Standard Assets (ASAs) are utilized to create Non-Fungible Tokens (NFTs) within the Algorand blockchain. ASAs are integrated into the protocol itself and can be generated through a specific type of transaction, distinguishing it from other blockchains that require smart contracts for asset representation. To create an NFT, only a few parameters need to be specified to designate it as such and establish a link to the metadata. This metadata provides potential owners with the necessary information to verify the asset's integrity. For example, setting the total amount of units to 1 and the number of decimals to 0 ensures the creation of a single, indivisible unit of the ASA. For proper formatting of NFT properties, the Algorand community adheres to the standards outlined in the Algorand Request for Comments. The creation transaction for such an asset can be implemented using any of Algorand's SDKs, in our case we will be using the java sdk.

Algorand Standard Asset for Non-Fungible Tokens

ARC-3 is the official Algorand Standard Asset Parameters Conventions for Fungible and Non-Fungible Tokens. It provides a standard for specifying ASA metadata, including asset name, unit name, and other properties. ARC-3 is more general and can be applied to both fungible and non-fungible tokens.

ASA Parameters Conventions (arc3) :

  1. Asset Name: The asset name is either arc3 or suffixed by @arc3. This allows client software to know when an asset follows the ARC-3 conventions.

  2. JSON Metadata File Schema: ARC-3 introduces a JSON Metadata File Schema that allows indicating the MIME type of the files pointed by any URI field. This helps clients to display the resource appropriately without having to first query it to find out the MIME type.

  3. Asset Integrity: A digest of the JSON Metadata file is included in the ASA parameters to ensure the integrity of this file. This is important to ensure the integrity of the JSON file when IPFS is not used.

  4. MIME Type Fields: MIME type fields are added to help clients know how to display the files pointed by URI.

  5. Relative URI Support: Support for relative URI is added to allow storing both the JSON Metadata files and the files it refers to in the same IPFS directory.

  6. Asset Configuration: Asset Name and Asset Unit can be optionally specified in the ASA parameters. This allows wallets that are not aware of ARC-3 or that are not able to retrieve the JSON file to still display meaningful information.

ARC-69 is an unofficial Algorand Standard Asset Parameters Convention popular in the Algorand NFT community. It is inspired by Open Sea's metadata standards and EIP-1155. ARC-69 focuses on optimization for fetching digital media and the use of on-chain metadata. It also allows for mutable or immutable metadata, depending on the use case.

ASA Parameters Conventions (arc69) :

  1. Asset Name, Unit Name, and URL: These are specified in the ASA parameters. This allows applications to efficiently display meaningful information, even if they aren't aware of ARC-69 metadata.

  2. MIME types: These help clients more effectively fetch and render media.

  3. Metadata: All asset metadata is stored on-chain. Metadata can be either mutable or immutable. If an ASA has a manager address, then the manager may update an ASA's ARC-69 metadata by sending a new acfg transaction with the entire metadata represented as JSON in the transaction's note field.

Architecture

Flow Blockchain Integration Diagram

The NFT Kit enables users to verify ownership of non-fungible tokens (NFTs) and access related data across multiple blockchains, helping them build decentralized applications, games and more. This document outlines the integration components to make all functionality also available on Flow. The NFT Kit can be used through a REST API or as a library in Java/Kotlin.

To enable support for Flow, the NFT-Kit uses the underlaying components NFTs Operation, and Cadence Scripts. Those components are hidden from the end-user, but offer developers to extend functionality offered by the NFT-Kit for Flow when needed.

Underlying components enabling Flow

Flow

Flow Blockchain is a permission-less layer 1 blockchain, empowering developers to create limitless Web3 apps for mainstream adoption.

Getting Started:

Querying NFT information Controller

Flow Blockchain

Usage :

Step1: Click on "Connect Flow wallet" button:

Step 2: Allow connection to the application.

Step 3 : You will have the list of NFTs on the selected Network.

Step 4 : You can display NFT details

NFT | Ownership Verification

NFT ownership verification on Flow

You can use this API to verify if an account is the real owner of an NFT existed in Flow blockchain.

NFT ownership verification in collection on Flow

We use this API to verify that an account has a NFT within a particular collection.

API Doc

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{chain}/contract/{contractAddress}/verifyNftOwnershipWithinCollection/Flow" 
-H  "accept: application/json"

Path parameters:

  • chain: [string] chain to work with. Either TESTNET or MAINNET.

  • contractAddress: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

  • collectionPath: [string] Collection storage/public/private path.

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/TESTNET/contract/0xa9ccb9756a0ee7eb/verifyNftOwnershipWithinCollection/Flow?account=0xe8e83eb775b67bc2&collectionPath=%2Fpublic%2FexampleNFTCollection" 
-H  "accept: application/json"
val chain= Flow.TESTNET
val smartContractAddress= "0xa9ccb9756a0ee7eb"
val account= "0xe8e83eb775b67bc2"
val collectionPath = "/public/exampleNFTCollection"
 val result = VerificationService.verifyNftOwnershipWithinCollectionOnFlow(chain, smartContractAddress, account,collectionPath)
 println("Result: ${result}")

Architecture

Algorand Blockchain Integration Diagram

The NFT Kit is designed to make the process of creating, managing and transferring NFTs easy and accessible to anyone.

NFT operations :

By using the AlgoSDK, we are able to easily and securely interact with Algorand Blockchain and perform the necessary actions to create and manage NFTs.

NFT Queries :

NFT | Creation & Management

To create NFTs on Algorand you need to:

Cadence Scripts

What is cadence ?

Cadence is a programming language designed for developing smart contracts in a blockchain environment. It introduces new features to smart contract programming that help developers ensure that their code is safe, secure, clear, and approachable. Cadence utilizes a strong static type system, resource-oriented programming, built-in pre- and post-conditions for functions and transactions, and capability-based security. Its syntax is inspired by popular modern general-purpose programming languages such as Swift, Kotlin, and Rust. Cadence aims to be safe and secure, clear, approachable, and developer-friendly. It makes use of resources to intuit ownership, which is tied to the account that owns it, ensuring that assets can only exist in one location at a time and cannot be copied or lost due to a coding mistake. The language addresses challenges with existing languages, such as safety and security concerns due to the immutable nature of blockchains and the lack of support for modifying or updating smart contracts.

Cadence Capabilities

In the Flow blockchain, the concept of "capabilities" is used to enforce access control and ensure security. A capability is an object that represents a specific permission to access a resource, such as a smart contract or a resource stored in an account.

In Flow, capabilities are created and owned by the resource itself, and can only be passed to other accounts or contracts through a special "borrow" mechanism. This mechanism ensures that access to a resource can only be granted by the owner of the resource, and that the permission to access the resource is explicitly granted on a per-resource basis.

Capabilities are also used to limit the scope of access to a resource. For example, a capability can be created that allows read-only access to a resource, or that only allows access to a specific function or method within a resource. By limiting the scope of access in this way, capabilities help to prevent unintended or malicious access to resources and reduce the risk of attacks.

Overall, the use of capabilities in Flow provides a flexible and secure access control mechanism that is well-suited to the needs of decentralized applications and smart contracts.

NFTs on Flow Blockchain

NFTs are digital assets that represent ownership of a unique asset and are indivisible. Cadence, the smart contract language on Flow blockchain, represents NFTs as a resource object stored in user accounts. This ensures NFTs benefit from resource ownership rules, protecting them from accidental or malicious programming errors.

NFTs allow for the trading of assets and proving of ownership, and on Flow, NFTs are interoperable across different smart contracts and app contexts. All NFTs on Flow implement the NFT Token Standard, defining a basic set of properties.

Core features

The NonFungibleToken contract defines the following set of functionality that must be included in each implementation.

Contracts that implement the NonFungibleToken interface are required to implement two resource interfaces:

  • NFT - A resource that describes the structure of a single NFT.

  • Collection - A resource that can hold multiple NFTs of the same type.

    Users typically store one collection per NFT type, saved at a well-known location in their account storage.

List NFTs in an account

This function is available on the NonFungibleToken.CollectionPublic interface, which accounts publish as public capability.

let collection = account.getCapability(/public/ExampleNFTCollection)
    .borrow<&{NonFungibleToken.CollectionPublic}>()
    ?? panic("Could not borrow a reference to the receiver's collection")

let ids = collection.getIDs()

NFT Metadata

Each view represents a different type of metadata, such as an on-chain creator biography or an off-chain video clip. Views do not specify or require how to store your metadata, they only specify the format to query and return them, so projects can still be flexible with how they store their data.

The NonFungibleToken and MetadataViews contracts are already deployed on various networks. You can import them in your contracts from these addresses. There is no need to deploy them yourself.

Note: With the emulator, you must use the -contracts flag to deploy these contracts.

Network
Contract Address

Emulator/Canary

0xf8d6e0586b0a20c7

Testnet

0x631e88ae7f1d7c20

Mainnet

0x1d7e57aa55817448

How to read metadata

This example shows how to read basic information about an NFT including the name, description, image and owner.

import ExampleNFT from "..."
import MetadataViews from "..."

// ...

// Get the regular public capability
let collection = account.getCapability(ExampleNFT.CollectionPublicPath)
    .borrow<&{ExampleNFT.ExampleNFTCollectionPublic}>()
    ?? panic("Could not borrow a reference to the collection")

// Borrow a reference to the NFT as usual
let nft = collection.borrowExampleNFT(id: 42)
    ?? panic("Could not borrow a reference to the NFT")

// Call the resolveView method
// Provide the type of the view that you want to resolve
// View types are defined in the MetadataViews contract
// You can see if an NFT supports a specific view type by using the `getViews()` method
if let view = nft.resolveView(Type<MetadataViews.Display>()) {
    let display = view as! MetadataViews.Display

    log(display.name)
    log(display.description)
    log(display.thumbnail)
}

// The owner is stored directly on the NFT object
let owner: Address = nft.owner!.address!

// Inspect the type of this NFT to verify its origin
let nftType = nft.getType()

// `nftType.identifier` is `A.e03daebed8ca0615.ExampleNFT.NFT`

Core views

The views categorized as "Core views" are deemed as the essential views that must be included to offer a comprehensive representation of an NFT. If you intend to have your NFT displayed on the Flow NFT Catalog, it is mandatory to have all of these views implemented.

NFT Catalog

The NFT Catalog is a registry that resides on the blockchain and catalogs the NFT collections available on Flow blockchain that conform to the NFT metadata standard. This enables developers of decentralized applications to conveniently develop on top of and find compatible NFT collections on Flow.

NFTCatalog.cdc: This contract contains the NFT Catalog

Network
Address

Mainnet

0x49a7cda3a1eecc29

Testnet

0x324c34e1c517e4db

NFTRetrieval.cdc: This contract contains helper functions to make it easier to discover NFTs within accounts and from the catalog

Network
Address

Mainnet

0x49a7cda3a1eecc29

Testnet

0x324c34e1c517e4db

NFT Creation (ARC3)

ARC Standards we support:

NFT creation based on ARC3

curl -X POST "http://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/{chain}/asset/create/{assetName}/{assetUnitName}/{url}" 
-H  "accept: application/json" -d ""

Path parameters:

  • chain:[string] chain to work with. Either TESTNET , BETANET or MAINNET

Body Details:

{
  "name": "string",
  "description": "string",
  "image": "string",
  "decimals": 0,
  "unitName": "string",
  "image_integrity": "string",
  "image_mimetype": "string",
  "properties": {
    "additionalProp1": "string",
    "additionalProp2": "string",
    "additionalProp3": "string"
  }
}

Body parameters:

name : The Name for this asset

description : A description of this asset

image : A URI pointing to a file with MIME type image/* representing the asset to which this token represents

decimals : A value of >0 is considered a 'Fractional NFT'

unitName : The Unit Name for this asset

image_integrity : The SHA-256 digest of the file pointed by the URI image.

image_mimetype : The MIME type of the file pointed by the URI image. MUST be of the form 'image/*'

properties : Arbitrary properties (also called attributes). Values may be strings, numbers, object or arrays.

Example:

curl -X POST "https://nftkit.walt-test.cloud/v2/nftkit/nft/Algorand/chain/ALGORAND_TESTNET/asset/create" 
-H  "accept: application/json" 
-H  "Content-Type: application/json" 
-d "{\"name\":\"waltid\",\"description\":\"nft of waltid\",\"image\":\"ipfs://bafkreihph3lc43efz44d5hgukfbdxib4bdkwp4lrdg3pdrtw57nh4nkbwy\",\"decimals\":0,\"unitName\":\"waltid\",\"image_integrity\":\"string\",\"image_mimetype\":\"image/png\",\"properties\":{\"color\":\"blue\"}}"

Response:

{
  "txId": "string",
  "explorerUrl": "string"
}
import id.walt.nftkit.services.AlgorandChain
import id.walt.nftkit.services.AlgorandNftService

val result = AlgorandNftService.createAssetArc3(
        AlgorandChain.ALGORAND_TESTNET,
        "testAsset",
        "test",
        "ipfs://bafkreidsvna6qass5ntkgfa7xp6x3u53oee2wao2vjt26s6upqngsntpc4",
        "testAsset",
        0,
        mapOf("cap" to "red")
    )

Algorand

Algorand is a blockchain platform. It offers a secure, scalable, and decentralized infrastructure for developing decentralized applications (DApps).

Algorand utilizes a consensus algorithm called Pure Proof-of-Stake (PPoS), which ensures security and scalability while eliminating energy-intensive mining. The platform can handle high transaction throughput with low latency, processing thousands of transactions per second.

Getting Started

Get NFT by Asset id

NFT | Wallet

Installation :

1 - Download waltid web wallet :

2 - Build Setup :

NFT | Wallet

Installation :

1 - Download waltid web wallet :

2 - Build Setup :

Querying Asset information

Ways to query information about Assets:

Get Assets for account

Retrieve all the Assets in a given account.

Get Asset Details

Return details about The Asset created using ASA on Algorand

Get NFT Metadata by asset id

Return the NFT metadata of an ASA on Algorand

configuration

The Cadence Scripts Component: Scripts to run non-permanent Cadence snippets in a flexible and powerful way, helping the NFT-Kit retrieve data from the Flow blockchain. is the smart contract programming language used on the Flow blockchain.

NFT Operation Component: A JavaScript project that uses the to establish safe and secure interactions with the Flow blockchain. With it, the NFT-Kit can retrieve NFTs and their details from chain and perform various operations on them.

- Learn how Flow was integrated into the NFT-Kit

- Query NFT information

- How to verify NFT ownership within a collection and traits

- View NFTs via a Web-Wallet

Using our , you can fetch and list your NFTs on the Flow chains.

API Doc

|

Curl call example

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/{chain}/contract/{contractAddress}/verifyNftOwnership/Flow" 
-H  "accept: application/json"

Path parameters:

  • chain: [string] chain to work with. Either TESTNET or MAINNET.

  • contractAddress: [string] smart contract address.

Query parameters:

  • account: [string] owner of the NFT.

  • tokenId: [string] token id of the NFT.

  • collectionPath: [string] Collection storage/public/private path.

Example:

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/chain/TESTNET/contract/0xa9ccb9756a0ee7eb/verifyNftOwnership/Flow?account=0xe8e83eb775b67bc2&tokenId=1&collectionPath=%2Fpublic%2FexampleNFTCollection" 
-H  "accept: application/json"
val chain= Flow.TESTNET
val smartContractAddress= "0xa9ccb9756a0ee7eb"
val account= "0xe8e83eb775b67bc2"
val tokenId= "1"
val collectionPath = "/public/exampleNFTCollection"
val result = VerificationService.verifyNftOwnershipOnFlow(chain, smartContractAddress, account, tokenId , collectionPath)
println("Result: ${result}")

|

One of the main ways we integrate the Algorand ecosystem is through the use of the for account creation , NFT minting and other functionalities.

This module enables querying data from the Algorand Network using . PureStake provides highly reliable and secure access to native Algorand REST APIs for Main, Test and Beta-Net, hence we can retrieve data such as NFTs metadata from Algorand.

.

For example, all NBA Top Shot Moments owned by a single user are held in a stored in their account at the path /storage/MomentCollection.

Return a list of NFTs in a Collection using the function.

NFT metadata is represented in a flexible and modular way using the .

When writing an NFT contract, you should implement the interface, which allows your NFT to implement one or more metadata types called views.

Source:

NFTs on Algorand are created using the Algorand Standard Assets (ASAs), which are part of the core protocol and created using a special type of transaction. This makes Algorand different to other chains where smart contracts are needed for the creation of an NFT. You can learn more about it .

- See how Algorand was integrated into the NFT-Kit

- How to create NFTs using the Algorand Standard Assets (ASAs)

- How to verify NFT ownership

API Doc

Swagger Doc | ReDoc

Curl call example

Path Params :

  • chain : chain to work with. Either ALGORAND_TESTNET , ALGORAND_BETANET, ALGORAND_MAINNET

  • assetId : The id of the Asset

Example :

Response :

Using our , you can fetch and list your NFTs on the Flow blockchain.

Using our , you can fetch and list your NFTs on the Flow blockchain.

- Get a list of assets (e.g. NFTs) of provided account

- Get all information available for an Asset (e.g. NFT)

- Query the NFT metadata

API Doc

Swagger Doc | ReDoc

Curl call example

Path Params :

  • chain : chain to work with. Either TESTNET , BETANET, MAINNET

  • address : Account address

Example :

Response :

API Doc

Swagger Doc | ReDoc

Curl call example

Path Params :

  • chain : chain to work with. Either ALGORAND_TESTNET , ALGORAND_BETANET, ALGORAND_MAINNET

  • assetId : The id of the Asset

Example :

Response :

API Doc

Swagger Doc | ReDoc

Curl call example

Path Params :

  • chain : chain to work with. Either ALGORAND_TESTNET , ALGORAND_BETANET, ALGORAND_MAINNET

  • assetId : The id of the Asset

Example :

Response :

Cadence
Flow Client Library (FCL)
Architecture
NFT | Metadata
NFT | Ownership
NFT | Wallet

🖼️

Get NFTs for Account

📌

Get NFTs in Collection

🚀

Get NFT by Token id

Swagger Doc
ReDoc
Swagger Doc
ReDoc
Java-Algosdk
Pure Stake APIs
Create an Account
Upload image to IPFS and create the NFT.
TopShot.Collection
getIDs
standard proposed in FLIP-0636
MetadataViews.Resolver
get_nft_metadata.cdc
here
ARC-003 Standard
Architecture
NFT | Creation
NFT | Ownership
curl -X GET "https://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/{chain}/asset/{assetId}" 
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/ALGORAND_TESTNET/asset/262542054" 
-H  "accept: application/json"
{
  "Metadata": {
    "decimals": 0,
    "description": "waltid logo NFT",
    "image": "ipfs://bafkreihph3lc43efz44d5hgukfbdxib4bdkwp4lrdg3pdrtw57nh4nkbwy",
    "name": "Waltid",
    "properties": {
      "size": {
        "content": "9814",
        "isString": false
      }
    },
    "unitName": "Waltid"
  },
  "TokenParams": {
    "createdAtRound": null,
    "deleted": null,
    "destroyedAtRound": null,
    "index": 262542054,
    "params": {
      "clawback": "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y",
      "creator": "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y",
      "decimals": 0,
      "defaultFrozen": false,
      "freeze": "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y",
      "manager": "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y",
      "name": "WaltId",
      "reserve": "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y",
      "total": 1,
      "unitName": "Waltid",
      "url": "ipfs://bafkreierprwpdih54puuu2bnk5vjmf2lx7jr2qtptad2ncuqnd2k6aouxi#arc3"
    }
  }
}
import id.walt.nftkit.services.AlgorandNftService
import id.walt.nftkit.services.AlgorandChain


val assetId = "257177850"
val result = AlgorandNftService.getNftMetadata(assetId, AlgorandChain.TESTNET)
println(result)
git clone https://github.com/walt-id/waltid-web-wallet.git
# install dependencies
$ yarn install

# serve with hot reload at localhost:3000
$ yarn dev

# build for production and launch server
$ yarn build
$ yarn start

# generate static project
$ yarn generate
git clone https://github.com/walt-id/waltid-web-wallet.git
# install dependencies
$ yarn install

# serve with hot reload at localhost:3000
$ yarn dev

# build for production and launch server
$ yarn build
$ yarn start

# generate static project
$ yarn generate
curl -X POST "http://0.0.0.0:7000
​/v2​/nftkit​/nft​/Algorand​/chain​/{chain}​/assets​/account​/{address}" 
-H  "accept: application/json" 
-d ""
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/ALGORAND_TESTNET/assets/account/GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y" 
-H  "accept: application/json"
{
  "assets": [
    {
      "amount": 0,
      "assetId": 0,
      "deleted": true,
      "isFrozen": true
    }
  ]
}
import id.walt.nftkit.services.AlgorandNftService
import id.walt.nftkit.services.AlgorandChain


val address = "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y"
val result = AlgorandNftService.getAccountAssets(address, AlgorandChain.ALGORAND_TESTNET)
println(result)
curl -X GET "https://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/{chain}/asset/{assetId}/params" 
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/ALGORAND_TESTNET/asset/257177850/params" 
-H  "accept: application/json"
{
  "index": 0,
  "createdAtRound": 0,
  "deleted": true,
  "destroyedAtRound": 0,
  "params": {
    "clawback": "string",
    "creator": "string",
    "decimals": 0,
    "defaultFrozen": true,
    "freeze": "string",
    "manager": "string",
    "name": "string",
    "reserve": "string",
    "total": 0,
    "unitName": "string",
    "url": "string"
  }
}
import id.walt.nftkit.services.AlgorandNftService
import id.walt.nftkit.services.AlgorandChain


val assetId = "257177850"
val result = AlgorandNftService.getAssetMeatadata(assetId, AlgorandChain.ALGORAND_TESTNET)
println(result)
curl -X GET "https://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/{chain}/asset/{assetId}/metadata" 
-H  "accept: application/json"
curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/Algorand/chain/ALGORAND_TESTNET/asset/257177850/metadata" 
-H  "accept: application/json"
{
  "name": "string",
  "description": "string",
  "image": "string",
  "decimals": 0,
  "unitName": "string",
  "properties": {
    "size": 0
  }
}
import id.walt.nftkit.services.AlgorandNftService
import id.walt.nftkit.services.AlgorandChain


val assetId = "257177850"
val result = AlgorandNftService.getNftMetadata(assetId, AlgorandChain.TESTNET)
println(result)

IPFS

Interact with the Interplanetary File System(IPFS) using walt.id tools

The Interplanetary File System(IPFS) is a protocol and peer-to-peer network for storing and sharing data in a distributed file system.

Upload file to IPFS

You can add a file to IPFS with the following action:

curl -X POST "http://0.0.0.0:7000/nftkit/nft/ipfs/file/Upload" \
-H  "Content-Type: multipart/form-data" \
-F "file=@file"

NFT | Ownership Verification

NFTs verification enables multiple use cases. The NFT Kit provides numerous approaches to verify the ownership of the NFTs and that the NFTs have customized properties.

NFT ownership verification:

You can use this API to verify if an account is the real owner of an NFT.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "https://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/{chain}/verifyNftOwnership" 
-H  "accept: application/json"

Path Params :

  • chain : chain to work with. Either ALGORAND_TESTNET , ALGORAND_BETANET, ALGORAND_MAINNET

  • assetId : The id of the Asset

  • address : Address of the NFT holder

Example :

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/ALGORAND_TESTNET/verifyNftOwnership?assetId=257177857&account=GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y" 
-H  "accept: application/json"
import id.walt.nftkit.services.AlgorandNftService
import id.walt.nftkit.services.AlgorandChain


val assetId = "257177850"
val address = "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y"
val result = AlgorandNftService.verifyOwnership(address , assetId, AlgorandChain.TESTNET)
println(result)

NFT ownership verification with traits :

You can use this API to verify if an account is the real owner of an NFT existed in Algorand blockchain with NFT property verification.

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "https://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/{chain}/verifyAlgorandNftOwnershipWithTraits" 
-H  "accept: application/json"

Path Params :

  • chain : chain to work with. Either ALGORAND_TESTNET , ALGORAND_BETANET, ALGORAND_MAINNET

  • assetId : The id of the Asset

  • address : Address of the NFT holder

  • trait : trait type

  • value : the value of the trait

Example :

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/ALGORAND_TESTNET/verifyNftOwnershipWithTraits?assetId=257177850&account=GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y&trait=size&value=9814" 
-H  "accept: application/json"
import id.walt.nftkit.services.AlgorandNftService
import id.walt.nftkit.services.AlgorandChain


val assetId = "257177850"
val address = "GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y"

val traitType = "cap"
val traitValue = "red"
    
val result = AlgorandNftService.verifyOwnerShipWithTraits(address , assetId, AlgorandChain.TESTNET , traitType, traitValue)
println(result)

NFT ownership verification Based on Creator Address :

This Endpoint will verify if a given account has an NFT minted from a particular account .

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "https://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/{chain}/{address}/verifyNftOwnershipBasedOnCreator/{creatorAddress}"
-H  "accept: application/json"

Path Params :

  • chain : chain to work with. Either ALGORAND_TESTNET , ALGORAND_BETANET, ALGORAND_MAINNET

  • address : Address of the NFT holder

  • creatorAddress : The initial creator address

Example :

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/ALGORAND_TESTNET/PVY6K7CB4JDRSOSPM7HZPTAOVDMVGHPF7TN6O5CBMD7UEDJWHOCRWI2OU4/verifyNftOwnershipBasedOnCreator/GYFVJLKGSWQDHFBHBLABUXYHHSU544RV3WH4ZCF3S6HONSDP73TK4VGY3Y" 
-H  "accept: application/json"

NFT Metadata verification Against Dynamic Policy :

API Doc

Swagger Doc | ReDoc

Curl call example

curl -X GET "https://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/{chain}/token/{token id}/policy/{policyName}/verification"
-H  "accept: application/json"

Path Params :

  • chain : chain to work with. Either ALGORAND_TESTNET , ALGORAND_BETANET, ALGORAND_MAINNET

  • token id : the token id

  • policyName : Name of the policy you want to verify against

Example :

curl -X GET "http://0.0.0.0:7000/v2/nftkit/nft/verifier/algorand/chain/ALGORAND_TESTNET/token/287718643/policy/policy%20algorand/verification"
-H  "accept: application/json"

Code of the Rego policy that can be used for creating the dynamic policy :

{
  "name": "policy algorand",
  "description": "policy 1",
  "input": {
    "name": "waltid",
    "description" : "waltid nft on algorand#2"
         
  },
  "policy": "package app.nft

import future.keywords.if

default allow := false


allow if {
	valid_nft_name
	valid_nft_description
}


valid_nft_name if input.name= data.name
valid_nft_description if input.description= data.description



",
  "policyQuery": "data.app.nft.allow",
  "policyEngine": "OPA"
}

Assets by Account
Asset Details
NFT Metadata
configuration

Soulbound Tokens (SBTs)

SBTs are non-transferable digital tokens containing information about a person or entity.

What are SBTs

SBTs are non-transferable unique digital tokens. They are issued once to an address, which could be owned by an individual or entity, stating information or accomplishments about the address owner.

Use-Cases of SBTs:

  • Proof Of Personhood, e.g through verification of a phone number.

  • Proof Of Attendance, e.g. proofing that an individual attended an event.

  • Proof Of Steps Completed e.g. that the owner went through an KYC process successfully.

Nonetheless, the SBTs offer great utility for many different use-cases, like reputation building and more.

How you can use SBTs with walt.id

Leveraging the walt.id open-source products, you can mint and verify SBTs and create wallet solutions where users can view their digital tokens.

Minting Solution

Deploy SBT smart contracts directly via Java, Kotlin or our REST interface on different EVM chains, thereunder:

  • Ethereum

  • Polygon

  • Shimmer

Verification Solution

Verify SBT ownership, metadata and more using REST endpoints for common use-cases or more complex ones by creating dynamic verification policies with the Open-Policy-Agent (OPA) and the REGO language.

Web2 Login

Wallet Solution

Algorand Blockchain

Usage :

Step1: Click on "Connect Algorand wallet" button:

Step 2: Allow connection to the application.

Step 3 : You will have the list of NFTs on the selected Network.

Step 4 : You can display NFT details

However, the data stored in SBTs should never include sensible personal information. For that, Verifiable Credentials and mdocs are a much better fit, because here, no sensible data is stored on the blockchain. A privacy requirement in many countries. Read more about it our post about

Deploy your first and start .

Start verifying SBTs or learn about dynamic verification policies with .

You can also enable Login In Web2 by launching your own decentralised identity provider that can be integrated with popular identity and access management tools like Keycloak or Auth0. Read more about it .

Extend your application with SBT viewing capabilities and web3 login using our .

Using our , you can fetch and list your NFTs on the Algorand chains.

SSI vs. NFTs
SBT Smart Contract
minting SBTs
here
OPA
here
wallet-kit
web wallet
web wallet
web wallet
web wallet
web wallet
web wallet
web wallet
web wallet
The blue boxes symbolise our products and their interfaces. The green boxes symbolise third party solutions that can be integrated via open APIs to avoid rip-and-replace and extend functionality to meet diverse customer requirements.
Wallet Kit: Data NFTs
Data NFT verification API
Relation ship of Smart Contracts and data NFTs
Tezos + NFT-Kit Integration Diagram
Step 1
Step2
Step 3
Step 4
Step 5
Step 6
Smart contract deployment
Add new minter
Near Protocol + NFT-Kit Integration Diagramm
Wallet - NFT
NFT ownership verification
NFT ownership verification within a collection
NFT ownership and property verification
Add new policy
Apply a policy to an NFT metadata
smart contract deployment - custom metadata
NFT ownership and property verification
NFT ownership and property verification
add new policy
Apply a policy to an NFT metadata
Polkadot + NFT-Kit Integration Diagram
Flow Blockchain + NFT Kit integration Diagram
Algorand + NFT-Kit Integration Diagramm