Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
module = "gno.land/r/g1jg8mtutu9khhfwc4nxmuhcpftf0pajdhfvsqf5/tnft"
gno = "0.9"
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package tnft

import (
b64 "encoding/base64"
"math/rand"
"strings"

"gno.land/p/nt/ufmt"
)

var baseTempalte = `<svg width="135" height="135" viewBox="0 0 135 135" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_7698_56846)">
<circle cx="67.5" cy="67.5" r="67.5" fill="url(#paint0_linear_7698_56846)"/>
<path d="M51.2905 42.9449L66.4895 33L97 52.8061L81.8241 62.7425L51.2905 42.9449Z" fill="white"/>
<path d="M51.6055 67.5059L66.8044 57.561L97 77.0657L82.1046 87.1793L51.6055 67.5059Z" fill="white" fill-opacity="0.4"/>
<path d="M36.0464 81.7559L51.2905 71.811L81.7336 91.6547L66.4895 101.508L36.0464 81.7559Z" fill="white" fill-opacity="0.6"/>
<path d="M36.001 52.8055L51.2884 42.9177L51.2884 71.8145L36.001 81.779L36.001 52.8055Z" fill="white"/>
<path d="M82.1051 87.1797L97.0016 77.0662L97.0016 81.7029L81.7896 91.629L82.1051 87.1797Z" fill="white" fill-opacity="0.5"/>
<path d="M51.2905 42.9449L66.4895 33L97 52.8061L81.8241 62.7425L51.2905 42.9449Z" fill="white"/>
<path d="M51.6055 67.5059L66.8044 57.561L97 77.0657L82.1046 87.1793L51.6055 67.5059Z" fill="white" fill-opacity="0.4"/>
<path d="M36.0464 81.7559L51.2905 71.811L81.7336 91.6547L66.4895 101.508L36.0464 81.7559Z" fill="white" fill-opacity="0.6"/>
<path d="M36.001 52.8055L51.2884 42.9177L51.2884 71.8145L36.001 81.779L36.001 52.8055Z" fill="white"/>
<path d="M82.1051 87.1797L97.0016 77.0662L97.0016 81.7029L81.7896 91.629L82.1051 87.1797Z" fill="white" fill-opacity="0.5"/>
</g>
<defs>
<linearGradient id="paint0_linear_7698_56846" x1="%d" y1="%d" x2="%d" y2="%d" gradientUnits="userSpaceOnUse">
<stop stop-color="%s"/>
<stop offset="1" stop-color="%s"/>
</linearGradient>
<clipPath id="clip0_7698_56846">
<rect width="135" height="135" fill="white"/>
</clipPath>
</defs>
</svg>
`

// charset contains valid hex digits for color generation.
const charset = "0123456789ABCDEF"

// genImageURI generates a base64-encoded SVG image URI with random gradient colors.
func genImageURI(r *rand.Rand) string {
imageRaw := genImageRaw(r)
sEnc := b64.StdEncoding.EncodeToString([]byte(imageRaw))

return "data:image/svg+xml;base64," + sEnc
}

// genImageRaw generates an SVG image with random gradient parameters.
func genImageRaw(r *rand.Rand) string {
x1 := 7 + r.Uint64N(7)
y1 := 7 + r.Uint64N(7)

x2 := 121 + r.Uint64N(6)
y2 := 121 + r.Uint64N(6)

var color1, color2 strings.Builder
color1.Grow(7)
color2.Grow(7)
color1.WriteByte('#')
color2.WriteByte('#')

for i := 0; i < 6; i++ {
color1.WriteByte(charset[r.IntN(16)])
color2.WriteByte(charset[r.IntN(16)])
}

randImage := ufmt.Sprintf(baseTempalte, x1, y1, x2, y2, color1.String(), color2.String())
return randImage
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package tnft

import (
"chain/runtime"

"gno.land/p/demo/tokens/grc721"
"gno.land/p/nt/ownable"
"gno.land/p/nt/ufmt"
)

var (
nft = grc721.NewBasicNFT("Test NFT", "TNFT")
owner = ownable.NewWithAddress(runtime.PreviousRealm().Address())
)

// BulkMint mints a bulk of tokens to the specified address.
// For testing purposes, the bulk size is set to bulkSize.
// This function is not intended to be used in production.
func BulkMint(cur realm, to address, bulkSize int64) {
for i := int64(0); i < bulkSize; i++ {
nextTokenId := nft.TokenCount() + i + 1
tid := grc721.TokenID(ufmt.Sprintf("%d", nextTokenId))

err := nft.Mint(to, tid)
if err != nil {
panic(err)
}

tokenURI := genImageURI(generateRandInstance())
err = setTokenURI(tid, grc721.TokenURI(tokenURI))
if err != nil {
panic(err)
}
}
}

// BulkGenerateTokenURI generates a bulk of token URIs.
// For testing purposes, the bulk size is set to bulkSize.
// This function is not intended to be used in production.
func BulkGenerateTokenURI(bulkSize int64) bool {
for i := int64(0); i < bulkSize; i++ {
genImageURI(generateRandInstance())
}

return true
}

// setTokenURI sets the metadata URI for a specific token ID.
func setTokenURI(tid grc721.TokenID, tURI grc721.TokenURI) error {
_, err := nft.SetTokenURI(tid, tURI)
if err != nil {
return ufmt.Errorf("token id (%s) || %s", tid, err.Error())
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package tnft

import (
"math/rand"
"time"

"gno.land/p/demo/tokens/grc721"
"gno.land/p/nt/ufmt"
)

// tid converts uint64 to grc721.TokenID.
func tid(id uint64) grc721.TokenID {
return grc721.TokenID(ufmt.Sprintf("%d", id))
}

// generateRandInstance generates a new random instance.
func generateRandInstance() *rand.Rand {
seed1 := time.Now().Unix() + nft.TokenCount()
seed2 := time.Now().UnixNano() + nft.TokenCount()
pcg := rand.NewPCG(uint64(seed1), uint64(seed2))
return rand.New(pcg)
}
11 changes: 11 additions & 0 deletions gno.land/cmd/gnoland/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import (
"time"

"github.com/gnolang/gno/gno.land/pkg/gnoland"
apprpc "github.com/gnolang/gno/gno.land/pkg/gnoland/rpc"
"github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot"
"github.com/gnolang/gno/gno.land/pkg/log"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
abci "github.com/gnolang/gno/tm2/pkg/bft/abci/types"
"github.com/gnolang/gno/tm2/pkg/bft/config"
"github.com/gnolang/gno/tm2/pkg/bft/node"
signer "github.com/gnolang/gno/tm2/pkg/bft/privval/signer/local"
rpcserver "github.com/gnolang/gno/tm2/pkg/bft/rpc/lib/server"
bft "github.com/gnolang/gno/tm2/pkg/bft/types"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/crypto"
Expand Down Expand Up @@ -261,6 +263,15 @@ func execStart(ctx context.Context, c *startCfg, io commands.IO) error {
return fmt.Errorf("unable to start the Gnoland node, %w", err)
}

var (
appRPCAddr = "tcp://0.0.0.0:26660" // TODO: make configurable
appRPC = apprpc.NewServer(cfg.LocalApp.(apprpc.Application), logger)
)

if err = appRPC.Serve(ctx, appRPCAddr, rpcserver.DefaultConfig()); err != nil {
return fmt.Errorf("unable to start app RPC server: %w", err)
}

// Wait for the exit signal
<-ctx.Done()

Expand Down
25 changes: 24 additions & 1 deletion gno.land/pkg/gnoland/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,23 @@ import (
"github.com/gnolang/gno/tm2/pkg/store/types"
)

// App wraps the TM2 base-app, and the Gnoland keepers
type App struct {
*sdk.BaseApp

vmKeeper vm.VMKeeperI
}

// NewQueryContext creates a new app query context (read-only)
func (a *App) NewQueryContext(h int64) (sdk.Context, error) {
return a.BaseApp.NewQueryContext(h)
}

// VMKeeper returns the VM keeper associated with the app
func (a *App) VMKeeper() vm.VMKeeperI {
return a.vmKeeper
}

// AppOptions contains the options to create the gno.land ABCI application.
type AppOptions struct {
DB dbm.DB // required
Expand Down Expand Up @@ -208,7 +225,13 @@ func NewAppWithOptions(cfg *AppOptions) (abci.Application, error) {
vmk.Initialize(cfg.Logger, ms)
ms.MultiWrite() // XXX why was't this needed?

return baseApp, nil
// Wrap the app
app := &App{
BaseApp: baseApp,
vmKeeper: vmk,
}

return app, nil
}

// GenesisAppConfig wraps the most important
Expand Down
Loading
Loading