GRUDGE STUDIO · ACCOUNT ARCHITECTURE v2.0

PUTER-POWERED
ACCOUNT SYSTEM

The definitive, most implementable, most reliable setup for Grudge user accounts — with cloud, storage, wallet, and AI built in from the moment they sign up.

Stack: Puter.js + Next.js + Supabase + Crossmint
Cost to dev: $0 infra
Setup time: Hours, not weeks

🧠 Why Puter — The Honest Analysis

You asked for best, most usable, most reliable, most implementable. Here's the full comparison so you understand exactly what you're choosing and why.

✦ Verdict: Puter for auth + cloud + player data. Supabase for game-critical server data. Crossmint for wallets.

Puter handles what players interact with directly — their account, their cloud files, their preferences. Supabase handles what you need to own and control — GBux ledgers, characters, transactions. Crossmint handles the blockchain. These three together are the most implementable, most reliable, lowest-cost architecture for Grudge Studio.

Puter.js — Auth & Cloud Supabase — Game State Crossmint — Wallets & NFT Next.js — App Framework Vercel — Deployment
Feature Puter.js Supabase Only Firebase Custom Backend
Setup time 1 script tag Few hours Few hours Days/weeks
Auth (email+social) Built-in, free Built-in Built-in Must build
Player cloud storage Auto per user You provision You provision Must build
Dev infra cost $0 always Free tier, then $ Free tier, then $ Server costs
Scales to 1M users User-pays model Costs scale with you Costs scale with you You handle it
Atomic transactions KV only (no SQL) Full Postgres Firestore limited Full control
GBux ledger integrity Not suitable Perfect fit Risky Full control
NFT / Web3 built-in None None None DIY + Crossmint
💡 The key insight: Puter is brilliant for the player-facing experience — their account, their cloud drive, their files, their AI access. Supabase is essential for the game engine — the stuff you absolutely must own, control, and audit. Don't make Puter do everything, and don't make Supabase do everything. Use each for what it's best at.
Puter handles

Player Layer

Account identity, cloud storage (screenshots, saves, character art), AI access, session management. Zero cost to you, players pay their own usage.

Supabase handles

Game Layer

GBux ledger (atomic transactions), characters, islands, inventory, game state, everything that needs SQL integrity and server-side validation.

Crossmint handles

Web3 Layer

Custodial wallets (auto-provisioned on signup), cNFT minting for characters/islands, NFT transfers, on-chain ownership. Abstracted from the player.

🏗️ Full System Architecture

How every piece connects — from a player clicking Sign Up to having a full cloud account, wallet, and Grudge identity in seconds.

✦ Design principle: A Grudge account = Puter identity + Supabase player record + Crossmint wallet. All three are created atomically on first sign-in. The player never sees the complexity.
👤
Player
Clicks Sign In
🔑
Puter Auth
puter.auth.signIn()
🗄️
Supabase
Player row created
👛
Crossmint
Wallet provisioned
☁️
Puter Cloud
Storage ready
🎮
Grudge Account
Fully active

WHAT EACH PLAYER GETS ON SIGNUP
Via Puter (automatic)

✦ Puter account (UUID identity)
✦ Personal cloud drive (unlimited storage)
✦ App-scoped KV store (preferences, settings)
✦ AI API access (Claude, GPT, DALL-E)
✦ Serverless compute access
✦ File hosting (for character art, screenshots)

Via Supabase (server-triggered)

✦ Player DB record with UUID
✦ GBux balance (starts at 0)
✦ Character slots
✦ Island ownership
✦ Transaction ledger history
✦ Achievement/quest state

WHAT CROSSMINT ADDS
Via Crossmint (auto-provisioned)

✦ Custodial Solana wallet (player owns it, you manage it)
✦ Wallet address stored in player record
✦ Can receive cNFTs immediately
✦ Player can export to self-custody later
✦ No crypto knowledge required by player

The magic combination

Puter is the identity layer — who you are.
Supabase is the game state layer — what you own.
Crossmint is the ownership layer — provably yours on-chain.

🚀 The Signup Flow

One click → full Grudge account. Here's exactly what happens technically.

⚡ Critical design decision: Puter sign-in must be triggered by a user action (button click). Once authenticated, your server-side code immediately creates the Supabase player record and provisions the Crossmint wallet in parallel. The player sees none of this — they just land in the game.
// ============================================================
// STEP 1: Frontend — Grudge sign-in button click
// ============================================================

import puter from '@heyputer/puter.js'

async function grudgeSignIn() {
  // 1. Trigger Puter auth (user's own Puter account)
  const user = await puter.auth.signIn()
  
  // user.uuid — their permanent Puter ID
  // user.username — their Puter username
  // user.email — their email (if shared)

  // 2. Call YOUR server to register/sync them in Supabase
  const grudgeAccount = await fetch('/api/auth/sync', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      puterId: user.uuid,
      username: user.username,
      email: user.email
    })
  }).then(r => r.json())

  // 3. Store Grudge session locally
  await puter.kv.set('grudge:session', JSON.stringify({
    playerId: grudgeAccount.playerId,
    walletAddress: grudgeAccount.walletAddress,
    gbuxBalance: grudgeAccount.gbuxBalance
  }))

  // Player is now fully initialized → redirect to game
  window.location.href = '/game/hub'
}
    
// ============================================================
// STEP 2: Server — /api/auth/sync (Next.js API Route)
// Creates or retrieves the full Grudge account
// ============================================================

import { supabase } from '@/lib/supabase'
import { provisionWallet } from '@/lib/crossmint'
import { z } from 'zod'

const Schema = z.object({
  puterId: z.string().uuid(),
  username: z.string().min(1).max(50),
  email: z.string().email().optional()
})

export async function POST(req) {
  const { puterId, username, email } = Schema.parse(await req.json())

  // Check if player already exists
  let { data: player } = await supabase
    .from('players')
    .select('*')
    .eq('puter_id', puterId)
    .single()

  if (!player) {
    // NEW PLAYER — create everything in parallel
    const [newPlayer, walletAddress] = await Promise.all([
      // Create Supabase player record
      supabase.from('players').insert({
        puter_id: puterId,
        username,
        email,
        gbux_balance: 100, // welcome bonus!
      }).select().single(),

      // Provision Crossmint custodial wallet
      provisionWallet(puterId, email)
    ])

    // Store wallet address on player record
    await supabase.from('players').update({
      wallet_address: walletAddress
    }).eq('puter_id', puterId)

    // Log the welcome GBux award
    await supabase.from('gbux_transactions').insert({
      player_id: newPlayer.data.id,
      amount: 100,
      reason: 'welcome_bonus'
    })

    player = { ...newPlayer.data, wallet_address: walletAddress }
  }

  return Response.json({
    playerId: player.id,
    walletAddress: player.wallet_address,
    gbuxBalance: player.gbux_balance,
    isNewPlayer: !player.created_at
  })
}
    
// ============================================================
// STEP 3: Puter Cloud — Set up player's Grudge folder
// Run this after sign-in to give them their cloud space
// ============================================================

async function initPlayerCloud(username) {
  // Create folder structure in player's Puter cloud drive
  await Promise.all([
    puter.fs.mkdir(`grudge-studio/characters`, { createMissingParents: true }),
    puter.fs.mkdir(`grudge-studio/screenshots`, { createMissingParents: true }),
    puter.fs.mkdir(`grudge-studio/saves`, { createMissingParents: true }),

    // Write their initial profile card to their cloud
    puter.fs.write('grudge-studio/profile.json', JSON.stringify({
      username,
      joinedAt: new Date().toISOString(),
      studio: 'Grudge Studio'
    }))
  ])
}
    

⚙️ Step-by-Step Implementation

In exact order. Do these one at a time. Each step works before moving to the next.

01

Install Puter.js in your Next.js project

Add to your app layout. No API keys, no config. That's it.

npm install @heyputer/puter.js

// In app/layout.tsx
import Script from 'next/script'

export default function Layout({ children }) {
  return (
    <html>
      <body>
        <Script src="https://js.puter.com/v2/" strategy="beforeInteractive" />
        {children}
      </body>
    </html>
  )
}
Do now ~5 min
02

Set up Supabase project + schema

Create a new Supabase project. Run the schema migrations. Enable Row Level Security.

-- Run in Supabase SQL editor

CREATE TABLE players (
  id              UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  puter_id        TEXT UNIQUE NOT NULL,  -- Puter UUID
  username        TEXT UNIQUE NOT NULL,
  email           TEXT,
  wallet_address  TEXT,                  -- Crossmint wallet
  gbux_balance    BIGINT DEFAULT 0,
  created_at      TIMESTAMPTZ DEFAULT NOW(),
  last_seen       TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE gbux_transactions (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  player_id   UUID REFERENCES players(id) ON DELETE CASCADE,
  amount      BIGINT NOT NULL,
  reason      TEXT NOT NULL,
  ref_id      UUID,
  created_at  TIMESTAMPTZ DEFAULT NOW()
);

-- RLS: players can only read their own data
ALTER TABLE players ENABLE ROW LEVEL SECURITY;
CREATE POLICY "players_self" ON players
  FOR SELECT USING (auth.uid()::text = puter_id);
Do now ~20 min
03

Build the /api/auth/sync endpoint

This is the bridge between Puter identity and your game. See the full code in the Signup Flow tab. Add Crossmint wallet provisioning here.

Do now ~1 hour
04

Set up Crossmint staging account

Create a Crossmint developer account. Get your Server API key. Create your first collection (Characters) on devnet. Test wallet provisioning end-to-end.

// lib/crossmint.ts
export async function provisionWallet(userId, email) {
  const res = await fetch('https://staging.crossmint.com/api/2022-06-09/wallets', {
    method: 'POST',
    headers: {
      'X-API-KEY': process.env.CROSSMINT_SERVER_KEY!,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      type: 'solana-custodial-wallet',
      linkedUser: `email:${email}`
    })
  })
  const data = await res.json()
  return data.publicKey
}
~1 hour
05

Build the Grudge account UI

Profile page that shows: Puter username, GBux balance, wallet address (truncated), character count, cloud storage usage. Pull from both Puter KV and your API.

After steps 1-4
06

Characters + Islands (off-chain first)

Add characters and islands tables. Character images stored in player's Puter cloud. Character stats/ownership in Supabase. NFT minting added in Phase 2.

Phase 2

💎 GBux + Wallet System

How GBux and crypto wallets coexist. GBux is your game economy. Wallet is for on-chain NFT ownership. They're separate — but connected.

GBux — Off-Chain (Supabase)

Virtual Currency

GBux lives entirely in your Supabase database. You control it. Atomic transactions. Ledger accounting. Can be earned in-game, purchased via Stripe, or spent on upgrades and minting.

Wallet — On-Chain (Crossmint)

NFT Ownership

The Crossmint custodial wallet holds cNFTs (characters, islands). Players own the NFTs but you manage the wallet. They can optionally self-custody later by exporting their private key.

// Spending GBux to mint a character as cNFT
// This is the key flow connecting GBux economy to Web3

export async function mintCharacter(playerId, characterId) {
  const MINT_COST = 500 // GBux

  // Step 1: Debit GBux atomically (Supabase transaction)
  const { data: player } = await supabase
    .from('players')
    .select('gbux_balance, wallet_address')
    .eq('id', playerId)
    .single()

  if (player.gbux_balance < MINT_COST) {
    throw new Error('Insufficient GBux')
  }

  // Atomic: debit balance + log transaction
  await supabase.rpc('spend_gbux', {
    p_player_id: playerId,
    p_amount: MINT_COST,
    p_reason: 'character_mint',
    p_ref_id: characterId
  })

  // Step 2: Queue the mint job (don't block the request)
  await inngest.send({
    name: 'character/mint.requested',
    data: { playerId, characterId, walletAddress: player.wallet_address }
  })

  return { queued: true, message: 'Minting in progress...' }
}
    
☁️ Puter + GBux integration: Use puter.kv to cache the player's GBux balance locally for instant UI display. Always verify the real balance from Supabase before any spend operation. The KV cache is a read-through cache only — never write the authoritative balance there.

🗺️ Exact Next Steps — In Order

Prioritized by what unlocks everything else. Do these in sequence and you'll have a fully operational account + game system.

01

This week — Auth + Account Foundation

Puter auth in your Next.js app → /api/auth/sync endpoint → Supabase players table → Crossmint staging wallet provision. End state: user clicks Sign In, gets a full account with a wallet in <3 seconds.

Right now ~1 day total
02

This week — GBux Engine

gbux_transactions table + spend_gbux Postgres function (atomic) + awardGbux server utility. Welcome bonus on signup. Balance visible in UI. End state: GBux is tracked and unhackable.

Right now ~4 hours
03

Next — Player Profile & Cloud UI

Account page showing: avatar, username, GBux, wallet, cloud storage usage. Player can upload avatar directly to their Puter cloud. Pull stats from Supabase via your API.

This week
04

Next — Characters

Character creation → stored in Supabase + art in player's Puter cloud. Dynamic metadata endpoint. No minting yet — just gameplay. Crossmint minting added in Phase 2.

Next sprint
05

Next — Islands

Island creation, ownership, and GBux earning. Same pattern as characters — off-chain first, NFT later. Island maps/data stored in Puter cloud (large files), ownership in Supabase.

Next sprint
06

Phase 2 — Crossmint Collections + cNFT Minting

Create Character + Island collections on Crossmint. Set royalties. Test mint pipeline on devnet. Build the "Mint for 500 GBux" flow with Inngest background jobs. Webhook confirms mint → updates DB.

Phase 2
07

Phase 2 — GBux Purchase (Stripe)

Stripe checkout for GBux packs. Webhook confirms payment → atomic GBux award. Track "purchased GBux" separately from "earned GBux" for compliance.

Phase 2
08

Phase 3 — Marketplace

Player-to-player GBux trades. NFT transfers via Crossmint. Secondary sales with royalties. Listing, offers, escrow — all server-side logic, all auditable.

Phase 3
0
Skip to Content
Grudge Studio
Studio Grudge
BUDZ WP
web3
THCBUDZ
THC Growerz
THClabz
Poker
igg
app-ads.txt
swaps
mintinfo
nexus mk
Gruda Math
unitytool
how to
basiczero
Season0
Nemesis
GRUDA USB
Nexus-tribes-images
Presale
nexus-images
about us
000
Nexus White Page
gruda
GRUDA Main
GrudaNode
cardinfo
Gbux
github
third
phonegruda
arena
compendium
grudabeta
skill tree
info
weapons
panel
CraftSkills
Referral
Stats
masterindex
remint
VM GRUDA
Launcher Form
Tos
Privacy
WoWMacro
Races
GoFD
Card Minter
GofD How to
Sigils
Durotan
bettas
Star
grudgematch
Battle
Legends
nexus
Crawl
gc
tactic
words
school
Apply
invest
Contact
About
Studio
thc
Unity tool
Mystic
Grudge Studio
Studio Grudge
BUDZ WP
web3
THCBUDZ
THC Growerz
THClabz
Poker
igg
app-ads.txt
swaps
mintinfo
nexus mk
Gruda Math
unitytool
how to
basiczero
Season0
Nemesis
GRUDA USB
Nexus-tribes-images
Presale
nexus-images
about us
000
Nexus White Page
gruda
GRUDA Main
GrudaNode
cardinfo
Gbux
github
third
phonegruda
arena
compendium
grudabeta
skill tree
info
weapons
panel
CraftSkills
Referral
Stats
masterindex
remint
VM GRUDA
Launcher Form
Tos
Privacy
WoWMacro
Races
GoFD
Card Minter
GofD How to
Sigils
Durotan
bettas
Star
grudgematch
Battle
Legends
nexus
Crawl
gc
tactic
words
school
Apply
invest
Contact
About
Studio
thc
Unity tool
Mystic
Studio Grudge
Folder: THC LABZ
Back
BUDZ WP
web3
THCBUDZ
THC Growerz
THClabz
Poker
igg
app-ads.txt
Folder: Nexus
Back
swaps
mintinfo
nexus mk
Gruda Math
unitytool
how to
basiczero
Season0
Nemesis
GRUDA USB
Nexus-tribes-images
Presale
nexus-images
about us
000
Nexus White Page
gruda
GRUDA Main
GrudaNode
cardinfo
Gbux
github
third
phonegruda
Folder: Warlords
Back
arena
compendium
grudabeta
skill tree
info
weapons
panel
CraftSkills
Referral
Stats
Folder: tools
Back
masterindex
remint
VM GRUDA
Launcher Form
Tos
Privacy
WoWMacro
Folder: Durotan
Back
Races
GoFD
Card Minter
GofD How to
Sigils
Durotan
bettas
Folder: Game Demos
Back
Star
grudgematch
Battle
Legends
nexus
Crawl
gc
tactic
words
school
Folder: Grudge Sites
Back
Apply
invest
Contact
About
Studio
thc
Unity tool
Mystic

Sign up with Grudge

We are happy to have you come Join our discord for direct access with team.

About Contact Discord