ScriptSphere
Share scripts for peer review with gasless, onchain social wallet transactions.
Algorand smart contract· onchain logic
Section · Onchain
full primer →The primitive.
Script feedback runs through a PuyaPy smart contract on Algorand TestNet; writers see a 'live on Algorand' badge with the App ID and a one-tap AlgoExplorer link, settled in ~3 seconds.
Why this primitiveAlgorand's AVM settles a contract call in ~3 seconds with a fixed 0.001 ALGO fee, so authorship or state proofs land instantly and can be re-verified from any AlgoExplorer link.
Kernel
a PuyaPy smart contract compiled and deployed to Algorand TestNet with AlgoKit — the AVM instruction set is Python-friendly, deploys settle in ~3 s, and every call is inspectable on AlgoExplorer
Drives the UI as
a 'live on Algorand TestNet' badge with the App ID and an AlgoExplorer link
Required keys.
ALGORAND_DEPLOYER_MNEMONIC
24-word mnemonic of the account that deploys apps and mints ASAs. Fund on TestNet via the Algorand dispenser.
open ↗SPONSOR_MNEMONIC
24-word mnemonic of the sponsor account that fee-pools user transactions (0.001 ALGO each).
open ↗Add these in your Lovable project under Settings → Secrets before pasting the prompt below.
Appendix · Mega-prompt
The build prompt.
budget · 1 message
Paste into a fresh Lovable project. Make sure all four secrets above are set first. read the build strategy →
Build "ScriptSphere" in ONE Lovable message. Single-page demo.
CONCEPT
Share scripts for peer review with gasless, onchain social wallet transactions.
Discipline: writing (script feedback).
Onchain primitive: Algorand smart contract. Why this primitive: Algorand's AVM settles a contract call in ~3 seconds with a fixed 0.001 ALGO fee, so authorship or state proofs land instantly and can be re-verified from any AlgoExplorer link.
5-CREDIT BUDGET (HARD LIMIT):
- ONE single-page app. No router, no Lovable Cloud, no database, no auth flows beyond the wallet connect.
- ONE PuyaPy contract (<=80 lines) OR one ASA acfg — deployed to Algorand TestNet, inspectable on AlgoExplorer.
- Users sign via TxnLab use-wallet (Pera / Defly / Exodus / Lute / WalletConnect); a sponsor account fee-pools the atomic group so users never fund an account.
- Pinata/IPFS only if the idea genuinely needs to store a file or metadata.
- At most ONE AI call per user action (use Lovable AI Gateway with LOVABLE_API_KEY if AI is part of the idea).
- Skip tests, skip CI, skip docs pages. Ship the demo, nothing else.
STACK
- React + Vite single page (the index route). Algorand JS SDK: `algosdk` (npm).
- Wallet layer (recommended): TxnLab **use-wallet** — one hook, every Algorand wallet.
npm: `@txnlab/use-wallet-react @txnlab/use-wallet-ui @perawallet/connect @blockshake/defly-connect @agoralabs-sh/avm-web-provider lute-connect @walletconnect/sign-client`
docs: https://txnlab.gitbook.io/use-wallet (llms.txt: https://txnlab.gitbook.io/use-wallet/llms.txt)
Setup (client-only — never at SSR module scope of a route file):
// src/wallet.tsx
import { WalletProvider, WalletManager, WalletId, NetworkId } from "@txnlab/use-wallet-react";
import "@txnlab/use-wallet-ui/dist/style.css";
const manager = new WalletManager({
wallets: [WalletId.PERA, WalletId.DEFLY, WalletId.EXODUS, WalletId.LUTE],
defaultNetwork: NetworkId.TESTNET,
});
export const Wallets = ({ children }) => <WalletProvider manager={manager}>{children}</WalletProvider>;
Use in a component:
import { useWallet } from "@txnlab/use-wallet-react";
import { WalletButton } from "@txnlab/use-wallet-ui";
const { activeAddress, transactionSigner, algodClient } = useWallet();
// <WalletButton /> renders connect/disconnect/account UI for you.
Fallback (minimal builds only): raw `@perawallet/connect`
(https://github.com/perawallet/connect). Same SSR rule — client-only.
- Contracts: prefer PuyaPy (`pipx install puyapy`, compile with `puyapy contract.py`).
If you cannot install the Python toolchain in this sandbox, hand-write TEAL v10
directly — it's the compiled output anyway — and compile it at deploy time via
`algod.compile(teal).do()`. A minimal approval program that just approves every call:
#pragma version 10
int 1
return
Clear program is identical. That's enough for a demo app that logs via `note`.
- Fee pooling / sponsored tx (users pay 0 ALGO — Algorand has NO paymaster/bundler,
fees pool natively across an atomic group):
const sp = await algod.getTransactionParams().do();
const userTx = algosdk.makeApplicationNoOpTxnFromObject({
from: activeAddress, appIndex: APP_ID, appArgs: [...],
suggestedParams: { ...sp, fee: 0, flatFee: true },
});
const sponsorTx = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
from: sponsorAddr, to: sponsorAddr, amount: 0,
suggestedParams: { ...sp, fee: 2000, flatFee: true }, // covers both txs
});
algosdk.assignGroupID([userTx, sponsorTx]);
// user signs userTx via use-wallet's transactionSigner (works for every wallet);
// sponsor signs sponsorTx server-side; submit the group with algod.sendRawTransaction.
- Deploy address / App ID / Asset ID gets written to `src/data/contract.json`
so the UI links to `https://testnet.explorer.perawallet.app/application/<id>`
or `.../asset/<id>`.
NON-OBVIOUS RULES (each of these silently breaks the demo — read all 8):
1. Pera "Universal Wallet" mnemonics are 24 words (BIP-39). `algosdk.mnemonicToSecretKey`
ONLY accepts 25-word Algo25. For 24 words, derive via SLIP-0010 path
m/44'/283'/0'/0'/0' using `@scure/bip39` + `micro-ed25519-hdkey`:
import { mnemonicToSeedSync, validateMnemonic } from "@scure/bip39";
import { wordlist } from "@scure/bip39/wordlists/english";
import { HDKey } from "micro-ed25519-hdkey";
import algosdk from "algosdk";
export function resolveAccount(phrase) {
const words = phrase.trim().split(/\s+/);
if (words.length === 25) return algosdk.mnemonicToSecretKey(phrase);
if (words.length === 24 && validateMnemonic(phrase, wordlist)) {
const seed = mnemonicToSeedSync(phrase);
const { privateKey } = HDKey.fromMasterSeed(seed).derive("m/44'/283'/0'/0'/0'");
const sk = new Uint8Array(64); sk.set(privateKey); sk.set(algosdk.encodeAddress(
algosdk.decodeAddress(algosdk.encodeAddress(
(require('tweetnacl').sign.keyPair.fromSeed(privateKey)).publicKey)).publicKey), 32);
const kp = require('tweetnacl').sign.keyPair.fromSeed(privateKey);
return { addr: algosdk.encodeAddress(kp.publicKey), sk: new Uint8Array([...privateKey, ...kp.publicKey]) };
}
throw new Error("mnemonic must be 24 or 25 words");
}
2. Pera's Universal Wallet UI address may NOT match the SLIP-0010 derivation
(Pera uses proprietary BIP32-Ed25519 / ARC-52 that standard libs can't
reproduce). Fix: print the derived address on first run, then send TestNet
ALGO from the Pera UI to that derived address. Do NOT try to reproduce Pera's derivation.
3. Every app-create / ASA-mint MUST set `note: new TextEncoder().encode(CREDIT)`
with the hackathon credit string. Notes are on-chain forever and free.
4. Min-balance goes UP with every asset opt-in and every app opt-in:
base account = 0.1 ALGO, +0.1 per asset, +0.1 per app + schema costs.
"balance below min" errors are almost always this.
5. `waitForConfirmation` returns BEFORE the indexer has the tx — AlgoExplorer
/ Pera Explorer links may 404 for 5-15s after deploy. Do NOT retry in the
deploy script; just tell users in the UI "may take ~15 s to appear".
6. Do NOT import `algosdk`, `@txnlab/use-wallet-react`, `@txnlab/use-wallet-ui`,
or `@perawallet/connect` at module scope of a route file with SSR — they break
the SSR bundle (Buffer, window, IndexedDB). Import inside the handler, behind
a `ClientOnly` boundary, or in a `.client.tsx` file, and wrap the app in
`<WalletProvider>` on the client only.
7. `ALGOD_TOKEN` for Nodely public endpoints is an EMPTY STRING, not "-".
Only set a real token for a self-hosted algod or a paid provider.
8. TestNet faucet is Google Cloud's Web3 faucet, not the deprecated
bank.testnet.algorand.network. URL:
https://cloud.google.com/application/web3/faucet/algorand/testnet
CONTRACT (contracts/app.py — PuyaPy):
```python
# Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
from algopy import ARC4Contract, String, arc4
class Scriptsphere(ARC4Contract):
@arc4.abimethod
def log(self, cid: String) -> String:
# Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
return cid
```
Compile: `algokit compile py contracts/app.py`
Deploy (scripts/deploy.ts, run locally):
```ts
import algosdk from "algosdk";
const algod = new algosdk.Algodv2(process.env.ALGOD_TOKEN ?? "", process.env.ALGOD_SERVER!, "");
const deployer = algosdk.mnemonicToSecretKey(process.env.ALGORAND_DEPLOYER_MNEMONIC!);
// ...build appl-create tx from compiled TEAL, sign with deployer, submit, log APP_ID
```
Write the resulting App ID to `src/data/contract.json` and link to
`https://testnet.explorer.perawallet.app/application/<APP_ID>`.
USER FLOW
1. Land on page -> tap `<WalletButton />` -> pick Pera / Defly / Exodus / Lute -> address in ~1 tap, sponsor fees the group so no funding needed.
2. User performs a script feedback action; the app builds an atomic group (user call + sponsor pay), use-wallet's `transactionSigner` signs the user tx via whichever wallet is connected, the sponsor signs server-side, the group submits; UI shows the AlgoExplorer 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):
- ALGORAND_DEPLOYER_MNEMONIC 24-word (Pera Universal / BIP-39) OR 25-word (Algo25) mnemonic for the deploy account. Fund on TestNet via https://cloud.google.com/application/web3/faucet/algorand/testnet (the classic bank.testnet faucet is deprecated).
- SPONSOR_MNEMONIC Mnemonic for the account that pays fees for the user's atomic group (can equal the deployer). Fund the same way.
- ALGOD_SERVER Algorand node HTTPS endpoint. Nodely free tier: https://testnet-api.4160.nodely.dev
- ALGOD_TOKEN Leave as an EMPTY STRING for Nodely free tier — do NOT put "-" or a placeholder.
- PINATA_JWT IPFS uploads (only if app pins media). Docs: https://docs.pinata.cloud/llms-full.txt
- LOVABLE_API_KEY Only if the idea calls Lovable AI Gateway.
CLIENT-SIDE ENV (Vite exposes these to the browser):
- VITE_ALGOD_SERVER same value as ALGOD_SERVER
CREDIT (must appear in UI footer AND in every app-create / ASA-mint `note` bytefield):
Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
Market sizing.
TAM
$700M
script review platforms
SAM
$170M
collaborative feedback tools
SOM
$21M
screenwriters getting onchain critiques
Indicative figures for hackathon pitches — refine with your own research before raising.
Adjacent entries.
poetry archiving
VerseLedger
Securely timestamp and prove original poem authorship on the blockchain to prevent plagiarism.
interactive storytellingNarrativeVote
Enable readers to vote on story plot directions through blockchain-based decision contracts.
screenwriting rightsScriptRoyalty
Automate royalty distribution for collaborative screenplays using verified smart contract agreements.
collaborative poetryPoetChain
Facilitate co-authored poems with edit histories securely stored on blockchain for trust.