Skip to content

bhaagiKenpachi/linera-gen-nft

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Generative NFT Example Application

This example application implements generative non-fungible tokens (NFTs). It is based on the Non-Fungible Token Example Application, with the difference being that instead of representing the token payload as an arbitrary sequence of bytes, it is represented as a string generated by a large-language model.

The main purpose of this application is to show how to run an artificial intelligence model in the application service, allowing it to generate strings used as the contents of non-fungible tokens. The application service runs on the client (usually inside the wallet), which means it executes off-chain. In this example, it is used to prepare the mint operation by running the AI model to generate the token contents from a user provided prompt. The resulting operation can then be placed by the wallet in a block proposal, minting the token on-chain.

This application's contract is mostly identical to the one from the NFT Example application. The only difference is the change of the token payload to be a text string instead of an arbitrary sequence of bytes. Like the NFT example application, this also shows cross-chain messages, demonstrating how NFTs can be minted, transferred, and claimed across different chains, emphasizing the instantiation and auto-deployment of application instances within the Linera blockchain ecosystem.

For more details on the application's contract and how it manages multiple different NFTs, see the NFT example.

Usage

Setting Up

Most of this can be referred to the fungible app README, except for at the end when compiling and publishing the bytecode, what you'll need to do will be slightly different.

export PATH="$PWD/target/debug:$PATH"
source /dev/stdin <<<"$(linera net helper 2>/dev/null)"

linera_spawn_and_read_wallet_variables linera net up --testing-prng-seed 37

Compile the non-fungible application WebAssembly binaries, and publish them as an application bytecode:

(cd examples/gen-nft && cargo build --release --target wasm32-unknown-unknown)

BYTECODE_ID=$(linera publish-bytecode \
    examples/target/wasm32-unknown-unknown/release/gen_nft_{contract,service}.wasm)

Here, we stored the new bytecode ID in a variable BYTECODE_ID to be reused later.

Creating an NFT

Unlike fungible tokens, each NFT is unique and identified by a unique token ID. Also unlike fungible tokens, when creating the NFT application you don't need to specify an initial state or parameters. NFTs will be minted later.

Refer to the fungible app README to figure out how to list the chains created for the test in the default wallet, as well as defining some variables corresponding to these values.

linera wallet show

CHAIN_1=e476187f6ddfeb9d588c7b45d3df334d5501d6499b3f9ad5595cae86cce16a65  # default chain for the wallet
OWNER_1=7136460f0c87ae46f966f898d494c4b40c4ae8c527f4d1c0b1fa0f7cff91d20f  # owner of chain 1
CHAIN_2=256e1dbc00482ddd619c293cc0df94d366afe7980022bb22d99e33036fd465dd  # another chain in the wallet
OWNER_2=598d18f67709fe76ed6a36b75a7c9889012d30b896800dfd027ee10e1afd49a3  # owner of chain 2

To create the NFT application, run the command below:

APP_ID=$(linera create-application $BYTECODE_ID)

This will store the application ID in a new variable APP_ID.

Using the NFT Application

Operations such as minting NFTs, transferring NFTs, and claiming NFTs from other chains follow a similar approach to fungible tokens, with adjustments for the unique nature of NFTs.

First, a node service for the current wallet has to be started:

PORT=8080
linera service --port $PORT &

Using GraphiQL

Type each of these in the GraphiQL interface and substitute the env variables with their actual values that we've defined above.

  • Navigate to the URL you get by running echo "http://localhost:8080/chains/$CHAIN_1/applications/$APP_ID".
  • To mint an NFT, run the query:
mutation {
  mint(
    minter: "User:$OWNER_1",
    prompt: "Hello!"
  )
}
  • To check that it's assigned to the owner, run the query:
query {
  ownedNfts(owner: "User:$OWNER_1")
}

Set the QUERY_RESULT variable to have the result returned by the previous query, and TOKEN_ID will be properly set for you. Alternatively you can set the TOKEN_ID variable to the tokenId value returned by the previous query yourself.

TOKEN_ID=$(echo "$QUERY_RESULT" | jq -r '.ownedNfts[].tokenId')
  • To check that it's there, run the query:
query {
  nft(tokenId: "$TOKEN_ID") {
    tokenId,
    owner,
    prompt,
    minter,
  }
}
  • To check everything that it's there, run the query:
query {
  nfts
}
  • To transfer the NFT to user $OWNER_2, still on chain $CHAIN_1, run the query:
mutation {
  transfer(
    sourceOwner: "User:$OWNER_1",
    tokenId: "$TOKEN_ID",
    targetAccount: {
      chainId: "$CHAIN_1",
      owner: "User:$OWNER_2"
    }
  )
}

Using Web Frontend

Installing and starting the web server:

cd examples/gen-nft/web-frontend
npm install --no-save

# Start the server but not open the web page right away.
BROWSER=none npm start &
echo "http://localhost:3000/$CHAIN_1?app=$APP_ID&owner=$OWNER_1&port=$PORT"
echo "http://localhost:3000/$CHAIN_1?app=$APP_ID&owner=$OWNER_2&port=$PORT"

For the final part, refer to Fungible Token Example Application - Using web frontend.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published