PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/gnoswap/gnft

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
gnft
Namespace
gnoswap
Files
8 (README)(gnomod.toml)
Exported functions
17
Module
gno.land/r/gnoswap/gnft
gno
0.9

Files (8)

  • README.mdmarkdown
  • gnomod.tomltoml
  • assert.gnogno
  • doc.gnogno
  • errors.gnogno
  • gnft.gnogno
  • svg_generator.gnogno
  • utils.gnogno
README.mdPreviewRaw
# GNFT

GRC721-compatible NFT contract for GnoSwap LP positions.

## Overview

GNFT represents each liquidity position as a unique NFT. It exposes ownership,
transfer, approval, and metadata operations while generating compact SVG artwork
for tokens whose URI is stored in GNFT's parameter format.

GNFT implements the position-NFT surface used by GnoSwap; it does not expose
every optional GRC721 extension. In particular, this package has no token
enumeration API and does not expose `safeTransferFrom`.

## Core Features

### Ownership and approvals

- Transfer, single-token approval, and operator approval
- Owner, balance, existence, and approval queries
- Staked tokens are locked to the staker contract
- Other transfers use the GRC721 owner and approval checks

### Dynamic SVG generation

- Generated tokens store compact gradient parameters
- Parameters are rendered to SVG and returned as a base64-encoded data URI
- Rendering occurs on `TokenURI` reads rather than storing the full SVG
- A custom non-empty URI set with `SetTokenURI` is returned unchanged when it is not in GNFT parameter format

### Storage

- Compact parameter storage reduces per-token metadata size
- Template-based SVG generation avoids storing repeated markup

## Key Functions

### `Mint`

Mints a new NFT for an LP position. Only the position role may call it.

**Parameters:**
- `cur realm`: Current realm context
- `to address`: Recipient address
- `tid grc721.TokenID`: Token ID to mint

**Returns:** `grc721.TokenID`

### `Burn`

Burns an NFT when its position is closed. Only the position role may call it.

**Parameters:**
- `cur realm`: Current realm context
- `tid grc721.TokenID`: Token ID to burn

### `TransferFrom`

Transfers NFT ownership.

**Parameters:**
- `cur realm`: Current realm context
- `from address`: Current owner
- `to address`: New owner
- `tid grc721.TokenID`: Token ID to transfer

For a token held by the staker contract, only the staker can move it. For other
tokens, the owner, token approval, or operator approval must authorize the
transfer.

### `TokenURI`

Returns metadata for a token. When the stored URI parses as GNFT image
parameters (`x1,y1,x2,y2,color1,color2`), GNFT renders those parameters as an
SVG and returns a base64-encoded data URI. A custom non-empty URI that is not in
that parameter format is returned unchanged.

**Parameters:**
- `tid grc721.TokenID`: Token ID

**Returns:** Token URI string and an error when the token or metadata is missing

### `SetTokenURI`

Sets a non-empty token URI. Only the position role may call it.

**Parameters:**
- `cur realm`: Current realm context
- `tid grc721.TokenID`: Token ID
- `tURI string`: Non-empty metadata URI

### `Approve`

Approves an address to manage a specific token.

**Parameters:**
- `cur realm`: Current realm context
- `approved address`: Address to approve
- `tid grc721.TokenID`: Token ID

### `SetApprovalForAll`

Approves or revokes an operator for all tokens owned by the caller.

**Parameters:**
- `cur realm`: Current realm context
- `operator address`: Operator address
- `approved bool`: Approval status

### Queries

- `Name() string`: Collection name
- `Symbol() string`: Collection symbol
- `TotalSupply() int64`: Number of minted NFTs
- `BalanceOf(owner address) (int64, error)`: Number of NFTs owned
- `OwnerOf(tid grc721.TokenID) (address, error)`: Current owner
- `MustOwnerOf(tid grc721.TokenID) address`: Owner or panic on error
- `Exists(tid grc721.TokenID) bool`: Whether a token exists
- `GetApproved(tid grc721.TokenID) (address, error)`: Token approval
- `IsApprovedForAll(owner, operator address) bool`: Operator approval

## SVG Generation

### Parameter Format

Generated token URIs store compact parameters:

```
"x1,y1,x2,y2,#COLOR1,#COLOR2"
Example: "10,12,125,123,#FF5733,#33B5FF"
```

### Parameter Ranges

- `x1`: 7-13
- `y1`: 7-13
- `x2`: 121-126
- `y2`: 121-126
- colors: 6-digit hex (`#RRGGBB`)

### Rendering Process

1. **Mint**: Generate pseudo-random parameters and store them as a CSV string
2. **TokenURI**: Parse the CSV, generate SVG, encode it as base64, and return a data URI
3. **Display**: The browser decodes the data URI and renders the SVG

The parameters use time-seeded `math/rand`; this is pseudo-random artwork
generation, not a security or cryptographic randomness source.

## Usage

These helpers illustrate calls from an integrating realm. `mintExample` and
`burnExample` require that realm to hold the position role; `transferExample`
requires the caller to satisfy the ownership/approval rules described above.

```go
import (
    "gno.land/p/nt/grc721/v0"
    "gno.land/r/gnoswap/gnft"
)

func mintExample(cur realm, owner address, tokenID grc721.TokenID) grc721.TokenID {
    return gnft.Mint(cross(cur), owner, tokenID)
}

func metadataExample(tokenID grc721.TokenID) (string, error) {
    return gnft.TokenURI(tokenID)
}

func transferExample(cur realm, from, to address, tokenID grc721.TokenID) error {
    return gnft.TransferFrom(cross(cur), from, to, tokenID)
}

func burnExample(cur realm, tokenID grc721.TokenID) {
    gnft.Burn(cross(cur), tokenID)
}
```

## Security and Access Control

- `Mint`, `SetTokenURI`, and `Burn` require the position role
- Staker-held tokens can only be moved by the staker contract
- Other transfers are checked by the owner/approval rules in the GRC721 ledger
- Token URI parameters are validated before generated artwork is rendered
- Generated artwork uses pseudo-random, time-seeded parameters and must not be
  treated as a source of secure randomness

## Architecture

### Dependencies

- `gno.land/p/nt/grc721/v0`: GRC721 token and ledger implementation
- `gno.land/p/nt/grc721/metadata/v0`: Metadata storage
- `gno.land/r/gnoswap/rbac/v1`: Access control
- `gno.land/r/gnoswap/access/v1`: Position-role authorization and role mirror

### State Variables

- `token`: GRC721 token metadata and supply state
- `ledger`: Ownership, transfer, and approval ledger
- `meta`: Token URI metadata
- `metaLedger`: Metadata update ledger

Generated image tokens store compact parameters in metadata; the full SVG data
URI is generated when `TokenURI` is called.

Functions

  • Approve(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, approved string, tid string) interface {Error func() string}

  • BalanceOf(owner string) (int64, interface {Error func() string})

  • Burn(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, tid string)

  • Exists(tid string) bool

  • GetApproved(tid string) (string, interface {Error func() string})

  • IsApprovedForAll(owner string, operator string) bool

  • Mint(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, to string, tid string) string

  • MustOwnerOf(tid string) string

  • Name() string

  • OwnerOf(tid string) (string, interface {Error func() string})

  • Render(path string) string

  • SetApprovalForAll(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, operator string, approved bool) interface {Error func() string}

  • SetTokenURI(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, tid string, tURI string) (bool, interface {Error func() string})

  • Symbol() string

  • TokenURI(tid string) (string, interface {Error func() string})

  • TotalSupply() int64

  • TransferFrom(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, from string, to string, tid string) interface {Error func() string}

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.