build strategy · onchain

Real onchain, four secrets, one build.

Every mega-prompt in this repo uses the same pattern, because it's the only pattern that lets a Lovable account ship a verifiable Robinhood Chain Testnet demo in one shot.

Why Robinhood Chain Testnet and not mainnet?

Robinhood Chain Testnet (chainId 46630) is a real Arbitrum L2 — same EVM, same wallets, Blockscout explorer — funded by a free faucet. Every contract you deploy is publicly inspectable, but you never spend real ETH and your demo can't accidentally drain a user. Move to Robinhood Chain Mainnet after the hackathon by swapping the RPC and chainId.

The recipe

recipe
# 1. In your Lovable project, add four secrets (Settings -> Secrets):
METAMASK_PRIVATE_KEY=0x...
ROBINHOOD_TESTNET_RPC_URL=https://robinhood-testnet.g.alchemy.com/v2/<alchemy-key>
PRIVY_APP_ID=...
PINATA_JWT=eyJhbGciOi...

# 2. Fund the MetaMask account on Robinhood Chain Testnet:
open https://faucet.testnet.chain.robinhood.com

# 3. Copy a mega-prompt from this repo into Lovable. One paste:
#    - scaffolds the React app
#    - writes the Solidity contract (with hackathon credit in NatSpec)
#    - deploys to Robinhood Chain Testnet and verifies on Blockscout (no API key)
#    - wires Privy social login + sponsored tx on chainId 46630
#    - pins generated assets to IPFS via Pinata
#    - exposes the contract address + Blockscout link in the UI

# 4. Open the live Blockscout link. Your demo is provably onchain.

1. The contract — credit baked in

Every Solidity file deployed from a Creative Blockchain prompt MUST carry the hackathon credit in NatSpec, so provenance lives onchain alongside the bytecode.

contracts/Provenance.sol
// contracts/Provenance.sol — every contract carries the hackathon credit in NatSpec
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title Provenance
/// @notice Built during the Creative AI & Quantum Hackathon
/// @notice organised by StreetKode Fam during Indian Krump Festival 14
contract Provenance {
    event Logged(address indexed author, string cid, uint256 at);

    function log(string calldata cid) external {
        emit Logged(msg.sender, cid, block.timestamp);
    }
}

2. Hardhat config — Blockscout verify

Blockscout uses the Etherscan-compatible API but does not require a key. Pass a placeholder string so hardhat-verify is happy.

hardhat.config.cjs
// hardhat.config.cjs — Robinhood Chain Testnet + Blockscout verify (no API key)
require("@nomicfoundation/hardhat-toolbox");
require("@nomicfoundation/hardhat-verify");

module.exports = {
  solidity: { version: "0.8.24", settings: { optimizer: { enabled: true, runs: 200 } } },
  networks: {
    robinhoodTestnet: {
      url: process.env.ROBINHOOD_TESTNET_RPC_URL || "https://rpc.testnet.chain.robinhood.com",
      accounts: [process.env.METAMASK_PRIVATE_KEY.startsWith("0x")
        ? process.env.METAMASK_PRIVATE_KEY
        : "0x" + process.env.METAMASK_PRIVATE_KEY],
      chainId: 46630,
    },
  },
  etherscan: {
    apiKey: { robinhoodTestnet: "blockscout-no-key-required" },
    customChains: [{
      network: "robinhoodTestnet",
      chainId: 46630,
      urls: {
        apiURL: "https://explorer.testnet.chain.robinhood.com/api",
        browserURL: "https://explorer.testnet.chain.robinhood.com",
      },
    }],
  },
  sourcify: { enabled: false },
};

3. Deploy + verify

scripts/deploy.cjs
// scripts/deploy.cjs
const hre = require("hardhat");
async function main() {
  const F = await hre.ethers.getContractFactory("Provenance");
  const c = await F.deploy();
  await c.waitForDeployment();
  const addr = await c.getAddress();
  console.log("deployed:", addr);
  // Blockscout accepts hardhat-verify without an API key
  await hre.run("verify:verify", { address: addr, constructorArguments: [] });
}
main();

4. Pin assets to IPFS via Pinata

src/lib/pinata.ts
// src/lib/pinata.ts — pin a Blob to IPFS via Pinata JWT
export async function pinToIPFS(file: Blob, name = "artifact") {
  const fd = new FormData();
  fd.append("file", file, name);
  const r = await fetch("https://api.pinata.cloud/pinning/pinFileToIPFS", {
    method: "POST",
    headers: { Authorization: `Bearer ${import.meta.env.VITE_PINATA_JWT}` },
    body: fd,
  });
  const { IpfsHash } = await r.json();
  return IpfsHash as string; // the CID
}

5. Sign in with Google via Privy

src/main.tsx
// src/main.tsx — Privy social login + sponsored tx on Robinhood Chain Testnet
import { PrivyProvider } from "@privy-io/react-auth";
import { defineChain } from "viem";

export const robinhoodTestnet = defineChain({
  id: 46630,
  name: "Robinhood Chain Testnet",
  nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
  rpcUrls: { default: { http: [import.meta.env.VITE_ROBINHOOD_TESTNET_RPC_URL || "https://rpc.testnet.chain.robinhood.com"] } },
  blockExplorers: { default: { name: "Blockscout", url: "https://explorer.testnet.chain.robinhood.com" } },
  testnet: true,
});

<PrivyProvider
  appId={import.meta.env.VITE_PRIVY_APP_ID}
  config={{
    loginMethods: ["google", "email"],
    embeddedWallets: { ethereum: { createOnLogin: "users-without-wallets" } },
    defaultChain: robinhoodTestnet,
    supportedChains: [robinhoodTestnet],
  }}
>
  <App />
</PrivyProvider>

Hackathon rules of thumb

  • · One mega-prompt = one build message. Don't iterate the architecture, iterate the UI.
  • · Always show the live Blockscout link in the UI — that's your proof.
  • · Use Privy sponsored tx so judges don't need a wallet to try the demo.
  • · Pin every user-generated asset to IPFS the moment it's created.
  • · For a stock-token idea, reference AAPL / TSLA / NVDA / USDG etc. by symbol — Robinhood Chain is the only L2 where that resolves onchain.
  • · Add a "Built during the Creative AI & Quantum Hackathon — StreetKode Fam · Indian Krump Festival 14" line to your footer.