Epic Editions
Mint chapters of novels as NFTs to prove authorship and track unpublished drafts.
NFT provenance mint· onchain authorship
Section · Onchain
full primer →The primitive.
Writers mint each long-form fiction as an ERC-721 token on 0G Galileo pointing at a 0G Storage root hash, so authorship and timestamp are provable from a single Chainscan link.
Why this primitiveERC-721 tokens anchor each chapter’s IPFS CID immutably on-chain.
Kernel
an ERC-721 / ERC-7857 contract on 0G Galileo that mints a creator-owned token pointing at a 0G Storage root hash
Drives the UI as
a 'mint to claim authorship' button that returns the tokenId, owner address, and 0G Chainscan link
Required keys.
PRIVY_APP_ID
Enables Google sign-in and an embedded wallet on 0G Galileo. User signs their own tx and pays gas in OG (faucet: 0.1 OG/day).
open ↗LOVABLE_API_KEY
Auto-provisioned by Lovable for AI calls via Lovable AI Gateway — nothing to paste. Default model: google/gemini-3-flash-preview.
open ↗Add these three in your Lovable project under Settings → Secrets before pasting the prompt below. 0G's public RPC (https://evmrpc-testnet.0g.ai) is hardcoded — no RPC key needed.
Appendix · Mega-prompt
The build prompt.
budget · 1 message
Paste into a fresh Lovable project. Make sure all five secrets above are set first. read the build strategy →
Build "Epic Editions" in ONE Lovable message. Single-page demo.
CONCEPT
Mint chapters of novels as NFTs to prove authorship and track unpublished drafts.
Discipline: Writing, Poetry & Narrative (long-form fiction).
Onchain primitive: NFT provenance mint. Why this primitive: ERC-721 tokens anchor each chapter’s IPFS CID immutably on-chain.
5-CREDIT BUDGET (HARD LIMIT):
- ONE single-page app. No router, no Lovable Cloud, no database, no auth flows beyond Privy drop-in.
- ONE Solidity contract, <=80 lines, deployed to 0G Galileo testnet, source uploaded to Chainscan-Galileo.
- Privy is always the auth + embedded-wallet layer (Google login, chainId 16602). Privy does NOT sponsor gas on 0G — the user signs every tx and pays in OG (top up from https://faucet.0g.ai, 0.1 OG/day).
- 0G Storage SDK (`@0glabs/0g-ts-sdk`) only if the idea genuinely needs to store a file.
- At most ONE AI call per user action via Lovable AI Gateway (LOVABLE_API_KEY, auto-provisioned) from a server route / server function. Default model: google/gemini-3-flash-preview.
- Skip tests, skip CI, skip docs pages. Ship the demo, nothing else.
0G GALILEO TESTNET (hardcode — no RPC secret needed):
chainId: 16602 (0x40DA)
name: "0G Galileo Testnet"
nativeCurrency: { name: "0G", symbol: "OG", decimals: 18 }
rpcUrl: "https://evmrpc-testnet.0g.ai"
explorer: "https://chainscan-galileo.0g.ai"
storageExplorer: "https://storagescan-galileo.0g.ai"
storageIndexer: "https://indexer-storage-testnet-turbo.0g.ai"
STACK
- React + Vite single page (the index route).
- Privy embedded wallet wraps `<App />` in src/main.tsx:
<PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
config={{ loginMethods:['google'], embeddedWallets:{createOnLogin:'users-without-wallets'},
defaultChain:{ id: 16602, name:'0G Galileo Testnet',
nativeCurrency:{ name:'0G', symbol:'OG', decimals:18 },
rpcUrls:{ default:{ http:['https://evmrpc-testnet.0g.ai'] } },
blockExplorers:{ default:{ name:'Chainscan', url:'https://chainscan-galileo.0g.ai' } } } }}>
- All txs via Privy `useSendTransaction` with `chainId: 16602`. Privy does NOT sponsor gas on 0G — the user signs and pays in OG from their embedded wallet. Surface a "Top up at https://faucet.0g.ai" hint when balance is 0.
- src/lib/zerog-storage.ts uses the 0G TypeScript SDK:
import { Indexer, ZgFile } from '@0glabs/0g-ts-sdk';
import { ethers } from 'ethers';
const RPC = 'https://evmrpc-testnet.0g.ai';
const INDEXER = 'https://indexer-storage-testnet-turbo.0g.ai';
export async function uploadToZeroG(file: File): Promise<string> {
const signer = new ethers.Wallet(import.meta.env.VITE_METAMASK_PRIVATE_KEY,
new ethers.JsonRpcProvider(RPC));
const zg = await ZgFile.fromBlob(file);
const [tree] = await zg.merkleTree();
const rootHash = tree!.rootHash()!;
const indexer = new Indexer(INDEXER);
const [, err] = await indexer.upload(zg, RPC, signer);
if (err) throw err;
await zg.close();
return rootHash; // the CID written onchain
}
- Hardhat in /contracts (kept outside the Vite bundle). Install `@nomicfoundation/hardhat-toolbox`.
- hardhat.config.cjs (no Etherscan plugin — 0G uses Chainscan's web UI for verification):
require("@nomicfoundation/hardhat-toolbox");
module.exports = {
solidity: { version: "0.8.28", settings: { optimizer: { enabled: false }, evmVersion: "paris" } },
networks: { galileo: {
url: "https://evmrpc-testnet.0g.ai",
accounts: [process.env.METAMASK_PRIVATE_KEY.startsWith("0x")
? process.env.METAMASK_PRIVATE_KEY : "0x" + process.env.METAMASK_PRIVATE_KEY],
chainId: 16602,
} },
};
- Deploy: `npx hardhat run scripts/deploy.cjs --network galileo`.
- VERIFY on 0G Chainscan (manual, web UI — there is no Etherscan-compatible API):
1. Open `https://chainscan-galileo.0g.ai/address/<deployedAddress>` and click "Contract" -> "Verify and Publish".
2. Compiler: solc 0.8.28, optimization OFF, evmVersion: paris. These exact settings are required for Chainscan-Galileo to match bytecode — do not deviate.
3. Paste the flattened source (`npx hardhat flatten contracts/X.sol > flat.sol`, strip duplicate SPDX/pragma lines).
4. Submit. On success the source becomes readable at `https://chainscan-galileo.0g.ai/address/<address>#code`.
If verification fails with a bytecode mismatch, the cause is almost always optimizer ON or a different evmVersion — redeploy with the settings above rather than fighting the verifier.
- Frontend reads use viem with the hardcoded 0G RPC:
import { defineChain, createPublicClient, http } from 'viem';
export const galileo = defineChain({
id: 16602, name: '0G Galileo Testnet',
nativeCurrency: { name: '0G', symbol: 'OG', decimals: 18 },
rpcUrls: { default: { http: ['https://evmrpc-testnet.0g.ai'] } },
blockExplorers: { default: { name: 'Chainscan', url: 'https://chainscan-galileo.0g.ai' } },
});
const client = createPublicClient({ chain: galileo, transport: http() });
- Write the deployed address to `src/data/contract.json` so the UI links to
`https://chainscan-galileo.0g.ai/address/<address>`.
CONTRACT (contracts/EpicEditions.sol):
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
/// @title EpicEditions
/// @notice ERC-721 provenance for: Mint chapters of novels as NFTs to prove authorship and track unpublished drafts.
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
contract EpicEditions is ERC721 {
uint256 public nextId;
mapping(uint256 => string) public cidOf;
constructor() ERC721("EpicEditions", "EPICED") {}
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
function mint(string calldata cid) external returns (uint256 id) {
id = ++nextId; cidOf[id] = cid; _safeMint(msg.sender, id);
}
function tokenURI(uint256 id) public view override returns (string memory) {
return string(abi.encodePacked("0g://", cidOf[id]));
}
}
```
USER FLOW
1. Land on page -> 'Sign in with Google' (Privy) -> embedded wallet auto-provisioned on 0G Galileo (chainId 16602).
2. After the user creates a long-form fiction artefact, upload the file to 0G Storage via the 0G SDK (returns a root-hash CID), then call `mint(cid)` on the deployed contract via the Privy embedded wallet (`useSendTransaction`, `chainId: 16602`). User signs and pays gas in OG from the embedded wallet. Show tokenId, the Storagescan-Galileo preview (`https://storagescan-galileo.0g.ai/tx/<rootHash>`), and the Chainscan-Galileo mint-tx link.
3. Footer renders: "Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14"
REQUIRED SECRETS (Lovable -> Project Settings -> Secrets):
- METAMASK_PRIVATE_KEY 0G Galileo deployer key. Fund it: https://faucet.0g.ai (0.1 OG/day) or https://hub.0g.ai/faucet?network=testnet
- PRIVY_APP_ID Google sign-in + embedded wallet on 0G Galileo (user signs their own tx). Docs: https://docs.privy.io/llms-full.txt
AI calls (if the idea uses AI) go through Lovable AI Gateway via the auto-provisioned LOVABLE_API_KEY — no secret to add.
Base URL: https://ai.gateway.lovable.dev/v1 Header: Lovable-API-Key: $LOVABLE_API_KEY
Default model: google/gemini-3-flash-preview. Call from a server route / server function only; never expose the key client-side.
No SEPOLIA_RPC_URL, no ETHERSCAN_API_KEY, no PINATA_JWT, no AISA_API_KEY. 0G's public RPC is hardcoded
(https://evmrpc-testnet.0g.ai), verification happens on Chainscan-Galileo's web UI,
and blobs go through the 0G Storage SDK signed by the deployer key.
CREDIT (must appear in UI footer AND as NatSpec on every deployed contract):
Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
Market sizing.
TAM
$1.5B
global writing tools market
SAM
$250M
novel writing software users
SOM
$25M
NFT chapter provenance creators
Indicative figures for hackathon pitches — refine with your own research before raising.
Adjacent entries.
poetry archiving
Verse Vault
Securely mint and prove ownership of original poetry on-chain for authentic literary legacy.
interactive storytellingNarrative Nexus
Mint branching story nodes as NFTs to ensure unique creator control and provenance.
screenwriting rightsScript Stamp
Mint screenplay drafts as NFTs to certify original authorship and version history.
lyric poetryPoet’s Provenance
Create unique NFT tokens for lyric poems, certifying creators and preserving provenance.