Silver Halide Timer
Lovable AI calculates dodging times so you print perfectly; Anyway turns it into a paid service in USDC or fiat.
The kernel.
Analog darkroom printing becomes sellable: one Anyway payment link takes a human paying USDC on Base from their own wallet — or an agent paying it automatically through the public agent endpoint — and photographers watch orders settle in the same screen where the work happens.
Why this primitiveAnyway payment links turn analog darkroom printing in Photography into a business — a shareable USDC or fiat link, with orders and settlements readable straight from the API.
Required key.
Add this in your Lovable project under Settings → Secrets before pasting the prompt below.
The build prompt.
Paste into a fresh Lovable project. Make sure the key above is set first. read the build strategy →
Build "Silver Halide Timer" as a ONE-SHOT Lovable build. The participant has only
5 credits — this single message must produce a working demo with no follow-ups.
Single-page TanStack Start app. Cut scope ruthlessly.
CONCEPT
Lovable AI calculates dodging times so you print perfectly; Anyway turns it into a paid service in USDC or fiat.
Discipline: Photography (analog darkroom printing).
Recipe: Anyway Payment Links (get paid) as the single creative surface.
Why this kernel: Anyway payment links turn analog darkroom printing in Photography into a business — a shareable USDC or fiat link, with orders and settlements readable straight from the API.
LOVABLE BUDGET (HARD CAP: ONE-SHOT, ~5 CREDITS TOTAL):
The participant has FIVE Lovable credits for the whole build. This prompt MUST
ship a working demo on the FIRST message with zero follow-ups. Engineer for that.
- ONE TanStack Start app, ONE route (`src/routes/index.tsx`). No extra pages, no auth, no nav.
- ONE TanStack server function in `src/lib/anyway.functions.ts` that proxies the Anyway call.
- ONE client surface (a textarea + button, a wallet panel, or a pay button) wired to it.
- NO database, NO Lovable Cloud, NO auth, NO file uploads, NO extra integrations.
- NO tests, NO docs pages, NO settings screens, NO theming toggles.
- Libraries: template defaults + `zod`. Nothing else.
- Keep the diff small enough to land in one build pass. If a feature is not on
screen in the user flow below, do not build it. Cut scope before adding scope.
STACK
- TanStack Start app, the index route only.
- Anyway is the only paid dependency. Every Anyway call lives inside a
`createServerFn` handler so the keys stay on the server.
- Client surface fits the kernel: a service page with a price, a one-tap payment link and a live list of paid orders.
- Tailwind + shadcn. Editorial look: gold accent on a dark or warm-cream
background, generous type, one strong headline, one primary action.
- Footer renders: "Built during the Anyway Creative Hackathon organised by StreetKode Fam during Indian Krump Festival 14".
PAYMENT LINKS HAVE TWO MODES — build both, they are both verified live:
A. HUMAN MODE — the hosted checkout `https://app.anyway.sh/pay/{linkId}`.
The buyer connects a PERSONAL wallet (MetaMask / Coinbase / 1inch via Privy) and pays USDC on Base.
The wallet needs USDC on Base *and* a small amount of ETH on Base for gas.
Do NOT tell buyers to connect an Anyway Agent Wallet here: its spending policy refuses the
direct `eth_sendTransaction` the checkout asks for ("RPC request denied due to policy violation").
Fiat is also accepted at the same link and settles to the same Main Wallet.
B. AGENT / AUTOMATION MODE — public, no key:
`GET https://app-prod.anyway.sh/v1/pay/agent/{linkId}` returns the recipient address, the USDC
contract (`0x8335...2913`), chain `base`, markdown instructions and a `confirmUrl`.
Two sub-paths:
1. plain ERC-20 `transfer` of the amount to the recipient, then
`POST https://app-prod.anyway.sh/v1/pay/{linkId}/confirm` with `{ txHash }`;
2. x402 (gasless, instant): `POST https://app-prod.anyway.sh/v1/pay/x402/{linkId}` with no
signature -> `402` challenge -> repost with the EIP-3009 signature envelope (same flow the
Agent Wallet uses for SuperAPI).
SERVER FUNCTION (src/lib/anyway.functions.ts) — thin wrappers only:
```ts
import { createServerFn } from "@tanstack/react-start";
import { z } from "zod";
const LINK_ID = "PL26LCHP1LHQ8W24"; // your link id from Products & Payment Links
/** Built during the Anyway Creative Hackathon organised by StreetKode Fam during Indian Krump Festival 14 */
export const getAgentInstructions = createServerFn({ method: "GET" }).handler(async () => {
const { fetchAgentInstructions } = await import("./anyway-paylink.server");
return fetchAgentInstructions(LINK_ID); // { recipient, asset, network, confirmUrl, instructions }
});
/** Built during the Anyway Creative Hackathon organised by StreetKode Fam during Indian Krump Festival 14 */
export const listOrders = createServerFn({ method: "GET" }).handler(async () => {
const key = process.env.ANYWAY_API_KEY;
if (!key) throw new Error("ANYWAY_API_KEY is not configured");
const r = await fetch("https://api.anyway.sh/v1/orders?limit=20", {
headers: { Authorization: `Bearer ${key}` },
});
if (r.status === 401) throw new Error("Anyway rejected the API key.");
if (!r.ok) throw new Error(`Anyway orders failed: ${r.status}`);
const j = await r.json();
return { orders: j.data ?? [] };
});
```
`src/lib/anyway-paylink.server.ts`:
```ts
export async function fetchAgentInstructions(linkId: string) {
const r = await fetch(`https://app-prod.anyway.sh/v1/pay/agent/${linkId}`);
if (!r.ok) throw new Error(`Anyway agent instructions failed: ${r.status}`);
return r.json();
}
```
AGENT PAYS THE LINK ITSELF (verified live — settles on Base, no browser wallet):
```ts
/** Built during the Anyway Creative Hackathon organised by StreetKode Fam during Indian Krump Festival 14 */
export const payLinkAsAgent = createServerFn({ method: "POST" }).handler(async () => {
const { payX402 } = await import("./anyway-wallet.server");
// Open-amount links REQUIRE ?amount= in USD on the x402 endpoint.
return payX402({
url: `https://app-prod.anyway.sh/v1/pay/x402/${LINK_ID}?amount=0.00001`,
method: "POST", // POST settles; GET only returns the challenge
body: JSON.stringify({ note: "agentic demo payment" }),
maxAtomic: 10, // hard cap: 0.00001 USDC
});
});
```
402 -> EIP-3009 signed by the Agent Wallet -> repost with `PAYMENT-SIGNATURE` -> 200 with an
`orderId` and a tx hash in `PAYMENT-RESPONSE`. Always cap `maxAtomic` and rate-limit the button.
CLIENT (in `src/routes/index.tsx`): a service page for analog darkroom printing — one price, a "Pay with Anyway"
button that opens the hosted checkout (with the one-line note: personal wallet on Base, USDC +
a little ETH for gas), a live "what an agent receives" panel rendering the real recipient, USDC
contract, network and confirm URL from `getAgentInstructions`, and the paid orders list underneath.
Docs: https://docs.anyway.sh/features/products (links) and
https://docs.anyway.sh/api-reference/orders (orders).
USER FLOW (the entire app — nothing else exists)
1. Land on the page; the headline previews what the demo does for analog darkroom printing.
2. The primary action (a service page with a price, a one-tap payment link and a live list of paid orders) is one tap away; the rest of the layout supports it.
3. Anyway runs the kernel server-side, the result lands on screen, the user can retry or copy.
KEYS — Anyway secrets (server-side only, never `VITE_`):
1. `ANYWAY_AGENT_WALLET_KEY` — the Agent Wallet Key from
https://app.anyway.sh/wallets?view=agent (or `anyway login --agent-wallet`).
Lets the agent pay x402 endpoints in USDC under an owner-set spending policy.
2. `ANYWAY_API_KEY` — the Agent Traces key from Business profile -> Developers.
Only needed if the build reports traces to https://collector.anyway.sh.
Put them in Project Settings -> Secrets and read them only inside a
`createServerFn` `.handler()` via `process.env.ANYWAY_...`.
CREDIT (must appear in UI footer AND as JSDoc on the server function):
Built during the Anyway Creative Hackathon organised by StreetKode Fam during Indian Krump Festival 14
Market sizing.
Indicative figures for hackathon pitches — refine with your own research before raising.