Palette Swap
Allow painters and illustrators to exchange and license color palettes with transparent, gasless transactions.
Privy social + sponsored tx· wallet UX
Section · Onchain
full primer →The primitive.
Painters sign in with Google through Privy — no seed phrase, no MetaMask popup — and their color exchange actions are sent from an embedded Flow EVM wallet with a fractional-cent gas fee.
Why this primitivePrivy social plus sponsored transactions enable easy palette licensing with zero gas hurdles.
Kernel
Privy embedded wallet bootstrapped with PRIVY_APP_ID — Google sign-in on Flow EVM Testnet, embedded wallet pays fractional-cent gas from user's own FLOW
Drives the UI as
a one-click 'Sign in with Google' that drops the user straight into the app with an onchain identity
Required keys.
PRIVY_APP_ID
Enables Google sign-in and an embedded wallet (user pays fractional-cent FLOW gas).
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 five secrets above are set first. read the build strategy →
Build "Palette Swap" in ONE Lovable message. Single-page demo.
CONCEPT
Allow painters and illustrators to exchange and license color palettes with transparent, gasless transactions.
Discipline: Visual Art (color exchange).
Onchain primitive: Privy social + sponsored tx. Why this primitive: Privy social plus sponsored transactions enable easy palette licensing with zero gas hurdles.
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 Flow EVM Testnet (chainId 545), verified on Flowscan (Blockscout).
- Privy is the auth layer (Google login, embedded wallet). USER PAYS GAS from the embedded wallet — Flow testnet gas is fractional cents.
- 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).
- Chain: Flow EVM Testnet — chainId 545, RPC https://testnet.evm.nodes.onflow.org,
explorer https://testnet.flowscan.io/evm. Define it in src/lib/flow-chain.ts via
viem's `defineChain({ id:545, name:'Flow EVM Testnet',
nativeCurrency:{ name:'Flow', symbol:'FLOW', decimals:18 },
rpcUrls:{ default:{ http:['https://testnet.evm.nodes.onflow.org'] } },
blockExplorers:{ default:{ name:'Flowscan', url:'https://testnet.flowscan.io/evm' } } })`.
Never stub the chain as a bare `{ id, name }` object anywhere — Privy requires a full viem chain.
- SSR-safe Privy mount is mandatory. Never import @privy-io/react-auth at
module scope of a route file — it crashes SSR. Use
lazy(() => import('./privy-client-entry')) inside <ClientOnly> + <Suspense>,
and put <PrivyProvider> only inside privy-client-entry.tsx.
- PrivyProvider config (pass the viem `flowEvmTestnet` chain — do NOT stub as {id,name}):
<PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
config={{ loginMethods:['google','email'],
embeddedWallets:{ ethereum:{ createOnLogin:'users-without-wallets' } },
appearance:{ theme:'dark' },
supportedChains:[flowEvmTestnet],
defaultChain: flowEvmTestnet }}>
- Read the embedded wallet from useWallets, not user.wallet:
const embedded = wallets.find(w => w.walletClientType === 'privy');
- Every send goes through Privy `useSendTransaction` with `address` ONLY.
DO NOT PASS `sponsor: true` — ZeroDev and native Privy gas sponsorship do
NOT cover Flow EVM. The user's embedded wallet pays the gas directly
(fractional-cent testnet FLOW). Wrap in a 45s Promise.race timeout that
tells the user to fund the wallet from the faucet:
await Promise.race([
sendTransaction(
{ to, data, chainId: 545 },
{ address: embedded.address }
),
new Promise((_, r) => setTimeout(() => r(new Error(
"Transaction timed out after 45s. Fund your embedded wallet with testnet FLOW at https://testnet-faucet.onflow.org."
)), 45_000)),
]);
- Do NOT pass uiOptions:{ showWalletUIs:false } — it aborts with
"signal is aborted without reason". The approval sheet still shows on
the embedded-EOA path; the fee reads a few cents in FLOW.
- Do NOT add ZeroDev / SmartWalletsProvider / a paymaster URL / a bundler
key. There is no Privy dashboard toggle for Flow EVM sponsorship — user
pays gas, period. Show a "Need FLOW? Faucet ↗" link when signed in.
- Hardhat in /contracts (kept outside the Vite bundle). Install
`@nomicfoundation/hardhat-toolbox` AND `@nomicfoundation/hardhat-verify@latest` (>=3.x).
- hardhat.config.cjs — Flowscan is a Blockscout instance; declare it via
`customChains` and pass the `apiKey` field with a placeholder string
("empty" — Blockscout ignores the value, but the field MUST exist):
require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-verify");
module.exports = {
solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
networks: { flowEvmTestnet: {
url: process.env.FLOW_EVM_RPC_URL || "https://testnet.evm.nodes.onflow.org",
accounts: [process.env.FLOW_EVM_PRIVATE_KEY.startsWith("0x")
? process.env.FLOW_EVM_PRIVATE_KEY : "0x" + process.env.FLOW_EVM_PRIVATE_KEY],
chainId: 545,
} },
etherscan: {
apiKey: { flowEvmTestnet: "empty" },
customChains: [{
network: "flowEvmTestnet",
chainId: 545,
urls: { apiURL: "https://testnet.flowscan.io/evm/api",
browserURL: "https://testnet.flowscan.io/evm" },
}],
},
sourcify: { enabled: false },
};
- Deploy: `npx hardhat run scripts/deploy.cjs --network flowEvmTestnet`.
- Verify (run RIGHT AFTER deploy, no constructor args for these contracts):
`npx hardhat verify --network flowEvmTestnet <address>`
On success the source becomes readable at
`https://testnet.flowscan.io/evm/address/<address>#code`.
- Frontend reads: `createPublicClient({ chain: flowEvmTestnet, transport: http() })`.
The public Flow EVM RPC handles wide getLogs ranges — `fromBlock = head - 50000n` is fine.
- Write the deployed address to `src/data/contract.json` so the UI links to
`https://testnet.flowscan.io/evm/address/<address>`.
CONTRACT (contracts/PaletteSwap.sol):
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @title SocialLogPaletteSwap
/// @notice Allow painters and illustrators to exchange and license color palettes with transparent, gasless transactions.
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
contract SocialLogPaletteSwap {
event Logged(address indexed author, string cid, uint256 at);
/// @notice Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14
function log(string calldata cid) external {
emit Logged(msg.sender, cid, block.timestamp);
}
}
```
USER FLOW
1. Land on page -> 'Sign in with Google' (Privy) -> embedded wallet auto-provisioned on Flow EVM Testnet.
2. Show a "Need FLOW? Faucet ↗" link to https://testnet-faucet.onflow.org so the user can top up.
3. Every color exchange action the user performs is sent as a Flow EVM tx (`log(payload)`) from the Privy embedded wallet and displayed with a Flowscan link. Gas is fractional-cent testnet FLOW.
4. Footer renders: "Built during the Creative AI & Quantum Hackathon organised by StreetKode Fam during Indian Krump Festival 14"
REQUIRED SECRETS (Lovable -> Project Settings -> Secrets):
- FLOW_EVM_PRIVATE_KEY Flow EVM Testnet deployer key. Fund it (free): https://testnet-faucet.onflow.org
- PRIVY_APP_ID Google sign-in + embedded wallet. Docs: https://docs.privy.io/llms-full.txt
- PINATA_JWT IPFS uploads (only if app pins media). Docs: https://docs.pinata.cloud/llms-full.txt
- FLOW_EVM_RPC_URL Optional. Defaults to https://testnet.evm.nodes.onflow.org (public RPC works fine).
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
$500M
digital color licensing market
SAM
$120M
palette trading platforms
SOM
$10M
early palette exchange adopters
Indicative figures for hackathon pitches — refine with your own research before raising.
Adjacent entries.
collaborative painting
Canvas Collaborate
Enable painters to co-create artworks with seamless onchain identity and gasless contributions.
illustrator communityIllustrator Guild
Create a hosted network for illustrators to share, sell, and verify work with easy login and zero gas fees.
generative artGenerative Canvas
Let generative artists deploy and monetize code-driven art with instant gasless onboarding and transactions.
art provenance trackingGallery Ledger
Provide gallerists with gasless, onchain tools to prove artwork provenance and authenticity effortlessly.