build strategy · onchain

Real onchain, three 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 Hedera demo in one shot.

Why Hedera and not an EVM testnet?

Fees are fixed and published in US cents — $0.0001 for an HBAR transfer or an HCS message, $0.001 for a token transfer — so a pay-per-call demo is economical instead of theoretical. Finality lands in about three seconds, the mirror node gives you a free public read API, and HashScan renders every receipt. Testnet HBAR is free from the portal faucet, and the same code runs on mainnet by switching one ledger id.

The recipe

recipe
# 1. In your Lovable project, add two secrets (Settings -> Secrets):
HEDERA_OPERATOR_ID=0.0.xxxxxx
HEDERA_OPERATOR_KEY=302e...            # ECDSA key from the Hedera portal
PINATA_JWT=eyJhbGciOi...               # optional, only if you pin media

# 2. Operator account: fund it from the Hedera portal faucet so it can create
#    user accounts and pay network fees:
open https://portal.hedera.com/faucet

# 3. Add Magic Link. Put your publishable key in src/data/hedera.json:
#    { "magicPublishableKey": "pk_live_..." }
#    Users sign in with email. The server seeds their new Hedera account with
#    a small starter balance and points them to the faucet for a top-up.

# 4. Copy a mega-prompt from this repo into Lovable. One paste:
#    - scaffolds the React app
#    - embeds Magic Link email sign-in (no seed phrase, no extension)
#    - settles payments as native HBAR transfers, or anchors data on HCS
#    - verifies every result against the Hedera mirror node
#    - exposes the transaction id + HashScan link in the UI

# 5. Open the live HashScan link. Your demo is provably onchain.

1. Pair HashPack, client-side only

The Reown DAppConnector touches window at construction time. Mount it with lazy() inside <ClientOnly> or SSR will crash on the first render.

magic-hedera-entry.tsx
// src/components/magic-hedera-entry.tsx — CLIENT ONLY (lazy + <ClientOnly>)
import { Magic } from "magic-sdk";
import { HederaExtension } from "@magic-ext/hedera";

const magic = new Magic("pk_live_...", {
  extensions: [new HederaExtension({ network: "testnet" })],
});

await magic.auth.loginWithEmailOTP({ email: "user@example.com" });
const info = await magic.user.getInfo();   // publicAddress is the EVM address
// Server-side: send a tiny HBAR to that address to auto-create the Hedera account

2. Verify x402 against the mirror node

Hedera transaction ids are 0.0.1234@1730000000.000000000; the mirror node wants 0.0.1234-1730000000-000000000. Convert, poll for up to ten seconds, and keep a set of settled ids so nobody replays a public receipt.

facilitator
// verify a payment against the mirror node — never trust the client
const toMirrorId = (id) => id.replace("@", "-").replace(/\.(\d+)$/, "-$1");

const res = await fetch(
  `https://testnet.mirrornode.hedera.com/api/v1/transactions/${toMirrorId(txId)}`,
);
const record = (await res.json()).transactions?.[0];

const paid = record?.result === "SUCCESS" &&
  record.token_transfers.some(
    (t) => t.token_id === "0.0.429274" && t.account === PAY_TO && t.amount >= 10000,
  );

3. Timestamp anything on HCS

src/lib/hcs.ts
// src/lib/hcs.ts — anchor anything on Hedera Consensus Service (~$0.0001)
import { Client, PrivateKey, TopicMessageSubmitTransaction } from "@hashgraph/sdk";

export async function anchor(topicId: string, payload: string) {
  const client = Client.forTestnet().setOperator(
    process.env.HEDERA_OPERATOR_ID!,
    PrivateKey.fromStringECDSA(process.env.HEDERA_OPERATOR_KEY!),
  );
  const tx = await new TopicMessageSubmitTransaction({ topicId, message: payload })
    .execute(client);
  const receipt = await tx.getReceipt(client);
  return { sequence: receipt.topicSequenceNumber?.toString(), txId: tx.transactionId.toString() };
}

4. Mint provenance with HTS

src/lib/hts.ts
// mint provenance as a native HTS NFT — no Solidity, fixed $0.05
import { TokenMintTransaction } from "@hashgraph/sdk";

const mint = await new TokenMintTransaction()
  .setTokenId(tokenId)
  .setMetadata([Buffer.from(`ipfs://${cid}`)])
  .execute(client);

const { serials } = await mint.getReceipt(client);
// link: https://hashscan.io/testnet/token/${tokenId}

Hackathon rules of thumb

  • · One mega-prompt = one build message. Don't iterate the architecture, iterate the UI.
  • · Always show the live HashScan link in the UI — that's your proof.
  • · Quote the fixed fee ($0.0001 / $0.001) instead of rendering a gas estimator.
  • · Prefer HTS and HCS over Solidity: cheaper, faster, and no deploy step.
  • · Pin every user-generated asset to IPFS the moment it's created.
  • · Add a "Built during the Creative AI & Quantum Hackathon — StreetKode Fam · Indian Krump Festival 14" line to your footer.