Palette Swap
Allow painters and illustrators to exchange and license color palettes with transparent, gasless transactions.
The primitive.
Painters sign in with Google through Privy — no seed phrase, no MetaMask popup — and their color exchange actions are sent as Sei Testnet transactions paid from their embedded wallet (a fraction of a cent per action, topped up from the Sei faucet).
Why this primitivePrivy social plus user-paid Sei Testnet transactions enable easy palette licensing with zero gas hurdles.
Required keys.
Add these in your Lovable project under Settings → Secrets before pasting the prompt below.
The build prompt.
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 + user-paid Sei Testnet tx. Why this primitive: Privy social plus user-paid Sei Testnet 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 Sei Testnet (atlantic-2, chainId 1328).
- Privy is always the auth layer (Google login, embedded wallet). USER PAYS GAS from that wallet.
- 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).
- Privy embedded wallet — USER-PAID gas on Sei Testnet (no ZeroDev, no smart-account
SDK, no bundler, no gas sponsorship). The EOA embedded wallet is the tx sender and
pays sub-cent SEI per action from its own balance.
- `defaultChain` and `supportedChains` MUST be a REAL viem `Chain` object, not a
`{ id, name }` stub (a stub compiles but breaks embedded-wallet transport init).
viem ships Sei Testnet — import it directly:
import { seiTestnet } from "viem/chains";
<PrivyProvider appId={import.meta.env.VITE_PRIVY_APP_ID}
config={{ loginMethods:['google'],
embeddedWallets:{ ethereum:{ createOnLogin:'users-without-wallets' } },
defaultChain: seiTestnet as never,
supportedChains: [seiTestnet] as never }}>
- IMPORTANT — Privy mount must be LAZY + CLIENT-ONLY (`@privy-io/react-auth` crashes
under SSR): load `PrivyProvider` via `lazy(() => import('./privy-client-entry'))`
inside `<ClientOnly><Suspense>` in a `privy-root.tsx`. Never import
`@privy-io/react-auth` at module scope of a route file.
- Every tx call passes `address: embedded.address` so Privy routes through the
embedded wallet (not a connected external wallet):
import { useSendTransaction, useWallets } from "@privy-io/react-auth";
const { sendTransaction } = useSendTransaction();
const embedded = wallets.find(w => w.walletClientType === "privy");
const receipt = await sendTransaction(
{ to: CONTRACT_ADDRESS, data, chainId: 1328 },
{ address: embedded.address },
);
DO NOT pass `{ sponsor: true }` — this app does not run a Privy gas
sponsorship policy; the user pays SEI gas from their embedded wallet.
- If the embedded wallet has 0 SEI, `sendTransaction` fails with "insufficient
funds for gas". Catch that error and show a link to https://sei.io/faucet so the
user can top up their embedded wallet address (copy `embedded.address` for them).
- PRIVY DASHBOARD (required, one-time, in the Privy console for VITE_PRIVY_APP_ID):
1. Chains -> add Sei Testnet (1328) with RPC https://evm-rpc-testnet.sei-apis.com
and explorer https://testnet.seiscan.io, then toggle
"Allow transactions from the client" ON. Without this, `sendTransaction`
hangs forever with no error.
2. DO NOT add a Gas Sponsorship policy — the user pays their own gas.
- Hardhat in /contracts (kept outside the Vite bundle). Install
`@nomicfoundation/hardhat-ethers` (>=3.x). DO NOT install
`@nomicfoundation/hardhat-toolbox` — it drags Hardhat 3 peers.
- hardhat.config.cjs — Sei Testnet (atlantic-2):
require("@nomicfoundation/hardhat-ethers");
const pk = process.env.METAMASK_PRIVATE_KEY;
module.exports = {
solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
networks: { seiTestnet: {
url: process.env.SEI_TESTNET_RPC_URL || "https://evm-rpc-testnet.sei-apis.com",
accounts: pk ? [pk.startsWith("0x") ? pk : "0x" + pk] : [],
chainId: 1328,
} },
// Seiscan has no Hardhat-compatible verification API on atlantic-2 — skip verify;
// bytecode + address are inspectable at https://testnet.seiscan.io/address/<addr>
};
- Deploy: `npx hardhat run scripts/deploy.cjs --network seiTestnet`.
- Frontend reads: create a viem public client with the Sei Testnet RPC too —
`createPublicClient({ chain: seiTestnet, transport: http(import.meta.env.VITE_SEI_TESTNET_RPC_URL) })`
(import `seiTestnet` from `viem/chains`).
Expose the RPC to the client by also setting VITE_SEI_TESTNET_RPC_URL to the same value.
- Write the deployed address to `src/data/contract.json` so the UI links to
`https://testnet.seiscan.io/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 Sei Testnet.
2. Every color exchange action the user performs is sent as a Sei Testnet tx (`log(payload)`) paid from their embedded wallet and displayed with a Seiscan 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 Sei Testnet deployer key. Fund it: https://sei.io/faucet
(verify captcha -> Request SEI; 1 request per address per 24h; atlantic-2 only)
- SEI_TESTNET_RPC_URL Public default https://evm-rpc-testnet.sei-apis.com works out of the box.
For heavy reads use Ankr (https://www.ankr.com/rpc/sei/) or DRPC.
- PRIVY_APP_ID Google sign-in + embedded wallet on Sei Testnet. USER PAYS THEIR OWN GAS.
Point new users to the Sei faucet (https://sei.io/faucet) to fund their 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
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.
Indicative figures for hackathon pitches — refine with your own research before raising.