{"_id":"@whop/template-kit","_rev":"4-d9f5b35ab55953113737048ee9dfe125","name":"@whop/template-kit","dist-tags":{"latest":"0.3.1"},"versions":{"0.2.0":{"name":"@whop/template-kit","version":"0.2.0","keywords":["apps","payments","rest","sdk","template","whop"],"license":"MIT","_id":"@whop/template-kit@0.2.0","maintainers":[{"name":"ryanouyang","email":"ryan.ouyang01@gmail.com"},{"name":"stevo2","email":"steven@whop.com"},{"name":"baked-developer","email":"tristan@whop.com"},{"name":"noahs233","email":"noah.schoenhaus@whop.com"},{"name":"deels","email":"destineewalston7@gmail.com"},{"name":"connorwhop","email":"connor@whop.com"},{"name":"danielschwartz4","email":"schwartzray8@gmail.com"},{"name":"zhast","email":"stevezzhang@gmail.com"},{"name":"jjantschulev","email":"j.jantschulev@gmail.com"}],"homepage":"https://whop.com/developers/","bugs":{"url":"https://github.com/whopio/whop-monorepo/issues"},"dist":{"shasum":"63cc608a301516d8fbd70df381d9b367e401b04e","tarball":"https://registry.npmjs.org/@whop/template-kit/-/template-kit-0.2.0.tgz","fileCount":47,"integrity":"sha512-r4cSLCcEfE0BhNvnmxtzJvUpcWOUsXrOYFUx+grh8q/5ocB6OebS1G+wvr7KwyC3hewDvF5lRxCifj3QcLfF8w==","signatures":[{"sig":"MEUCIQCBszopd0xnF1ftyNIRmSOkd+D0qAz1oEUaoORilPfsiwIgMwN9UnQhr/Q7Sf+QdcC62lC3kDQsfXwzNTnQWGJFiy0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98247},"main":"./dist/index.cjs","type":"module","_from":"file:whop-template-kit-0.2.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.mjs","require":"./dist/server/index.cjs"}},"scripts":{"test":"vitest run","build":"pnpm run clean && concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","clean":"rm -rf dist","build:swc":"concurrently \"pnpm run build:swc:esm\" \"pnpm run build:swc:cjs\"","build:tsc":"tsc --emitDeclarationOnly","typecheck":"tsc --noEmit","build:swc:cjs":"swc src -d dist --strip-leading-paths --ignore \"**/*.test.ts\" --out-file-extension cjs -C module.type=commonjs","build:swc:esm":"swc src -d dist --strip-leading-paths --ignore \"**/*.test.ts\" --out-file-extension mjs -C module.type=es6 && node scripts/add-esm-import-extensions.mjs"},"_npmUser":{"name":"baked-developer","email":"tristan@whop.com"},"_resolved":"/tmp/ceb7663d23c1e2cf21476ca3f1ce7d8c/whop-template-kit-0.2.0.tgz","_integrity":"sha512-r4cSLCcEfE0BhNvnmxtzJvUpcWOUsXrOYFUx+grh8q/5ocB6OebS1G+wvr7KwyC3hewDvF5lRxCifj3QcLfF8w==","repository":{"url":"git+https://github.com/whopio/whop-monorepo.git","type":"git","directory":"developer-platform/packages/template-kit"},"_npmVersion":"10.9.8","description":"Data and server layer for building Whop templates on the Whop REST API","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"19.2.4","vitest":"^2.1.9","@swc/cli":"0.7.7","@swc/core":"1.11.29","typescript":"5.9.3","@types/node":"latest","@types/react":"19.2.14","concurrently":"9.1.2"},"peerDependencies":{"react":"^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/template-kit_0.2.0_1786998409300_0.7460047588330039","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@whop/template-kit","version":"0.3.0","keywords":["apps","payments","rest","sdk","template","whop"],"license":"MIT","_id":"@whop/template-kit@0.3.0","maintainers":[{"name":"ryanouyang","email":"ryan.ouyang01@gmail.com"},{"name":"stevo2","email":"steven@whop.com"},{"name":"baked-developer","email":"tristan@whop.com"},{"name":"noahs233","email":"noah.schoenhaus@whop.com"},{"name":"deels","email":"destineewalston7@gmail.com"},{"name":"connorwhop","email":"connor@whop.com"},{"name":"danielschwartz4","email":"schwartzray8@gmail.com"},{"name":"zhast","email":"stevezzhang@gmail.com"},{"name":"jjantschulev","email":"j.jantschulev@gmail.com"}],"homepage":"https://whop.com/developers/","bugs":{"url":"https://github.com/whopio/whop-monorepo/issues"},"dist":{"shasum":"2d1136422327d77e01c7ec2e902e4a46ad00ecea","tarball":"https://registry.npmjs.org/@whop/template-kit/-/template-kit-0.3.0.tgz","fileCount":50,"integrity":"sha512-eYRB06zb7uexvkneaYfonQBcPMdsCAfrggl7mXk8OAcM3A7Vy1tujOCnaUe3fYYYZptsNoE1K/b12WaLQXRRig==","signatures":[{"sig":"MEUCIBIAqXy4H5yVybHKvx/BW5uKnuZ4w4xcXHAh3ggk03WmAiEAobCIgkEZXRPXEfM/LOR3kH1+yIeASpS5mvUNqxbPOmg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":116948},"main":"./dist/index.cjs","type":"module","_from":"file:whop-template-kit-0.3.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.mjs","require":"./dist/server/index.cjs"}},"scripts":{"test":"vitest run","build":"pnpm run clean && concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","clean":"rm -rf dist","build:swc":"concurrently \"pnpm run build:swc:esm\" \"pnpm run build:swc:cjs\"","build:tsc":"tsc --emitDeclarationOnly","typecheck":"tsc --noEmit","build:swc:cjs":"swc src -d dist --strip-leading-paths --ignore \"**/*.test.ts\" --out-file-extension cjs -C module.type=commonjs","build:swc:esm":"swc src -d dist --strip-leading-paths --ignore \"**/*.test.ts\" --out-file-extension mjs -C module.type=es6 && node scripts/add-esm-import-extensions.mjs"},"_npmUser":{"name":"baked-developer","email":"tristan@whop.com"},"_resolved":"/tmp/24a82df80f3bec3bc3046309a6754188/whop-template-kit-0.3.0.tgz","_integrity":"sha512-eYRB06zb7uexvkneaYfonQBcPMdsCAfrggl7mXk8OAcM3A7Vy1tujOCnaUe3fYYYZptsNoE1K/b12WaLQXRRig==","repository":{"url":"git+https://github.com/whopio/whop-monorepo.git","type":"git","directory":"developer-platform/packages/template-kit"},"_npmVersion":"10.9.8","description":"Data and server layer for building Whop templates on the Whop REST API","directories":{},"sideEffects":false,"_nodeVersion":"22.23.2","dependencies":{"whop-sdk":"npm:@whop/sdk@^0.0.42"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"19.2.4","vitest":"^3.2.6","@swc/cli":"0.7.7","@swc/core":"1.11.29","typescript":"5.9.3","@types/node":"latest","@types/react":"19.2.14","concurrently":"9.1.2"},"peerDependencies":{"react":"^19.0.0"},"_npmOperationalInternal":{"tmp":"tmp/template-kit_0.3.0_1787218518517_0.6635028737224551","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@whop/template-kit","version":"0.3.1","description":"Data and server layer for building Whop templates on the Whop REST API","keywords":["apps","payments","rest","sdk","template","whop"],"homepage":"https://whop.com/developers/","bugs":{"url":"https://github.com/whopio/whop-monorepo/issues"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/whopio/whop-monorepo.git","directory":"developer-platform/packages/template-kit"},"type":"module","sideEffects":false,"exports":{".":{"import":"./dist/index.mjs","require":"./dist/index.cjs","types":"./dist/index.d.ts"},"./server":{"import":"./dist/server/index.mjs","require":"./dist/server/index.cjs","types":"./dist/server/index.d.ts"}},"publishConfig":{"access":"public"},"dependencies":{"whop-sdk":"npm:@whop/sdk@^0.0.42"},"devDependencies":{"@swc/cli":"0.7.7","@swc/core":"1.11.29","@types/node":"latest","@types/react":"19.2.14","concurrently":"9.1.2","react":"19.2.4","typescript":"5.9.3","vitest":"^3.2.6"},"peerDependencies":{"react":"^19.0.0"},"scripts":{"build":"pnpm run clean && concurrently \"pnpm run build:swc\" \"pnpm run build:tsc\"","build:swc":"concurrently \"pnpm run build:swc:esm\" \"pnpm run build:swc:cjs\"","build:swc:cjs":"swc src -d dist --strip-leading-paths --ignore \"**/*.test.ts\" --out-file-extension cjs -C module.type=commonjs","build:swc:esm":"swc src -d dist --strip-leading-paths --ignore \"**/*.test.ts\" --out-file-extension mjs -C module.type=es6 && node scripts/add-esm-import-extensions.mjs","build:tsc":"tsc --emitDeclarationOnly","clean":"rm -rf dist","typecheck":"tsc --noEmit","test":"vitest run"},"main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","_id":"@whop/template-kit@0.3.1","_integrity":"sha512-zhrDgbT3M1QLJsDcpH07ock7hjZiDrSO3RAmP7j2iBuBh5ZSeYsx1iuKMSzxSdLQb7COozD2A/Dv56RqNJo2hQ==","_resolved":"/tmp/46d8f3aee0292374c399641c7b7d38b1/whop-template-kit-0.3.1.tgz","_from":"file:whop-template-kit-0.3.1.tgz","_nodeVersion":"22.23.2","_npmVersion":"10.9.8","dist":{"integrity":"sha512-zhrDgbT3M1QLJsDcpH07ock7hjZiDrSO3RAmP7j2iBuBh5ZSeYsx1iuKMSzxSdLQb7COozD2A/Dv56RqNJo2hQ==","shasum":"58bdb35d7158bd921cfe4d67de62ac285c31804c","tarball":"https://registry.npmjs.org/@whop/template-kit/-/template-kit-0.3.1.tgz","fileCount":50,"unpackedSize":117118,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCSarN3hBfFYK2Q8zyNMuH+zm6oA59UdGF9x2LmatxG/wIhAIsxHngGIsWSOeBJGjnR016wfHxfoMNTfV+LAf70ppGi"}]},"_npmUser":{"name":"baked-developer","email":"tristan@whop.com"},"directories":{},"maintainers":[{"name":"ryanouyang","email":"ryan.ouyang01@gmail.com"},{"name":"stevo2","email":"steven@whop.com"},{"name":"baked-developer","email":"tristan@whop.com"},{"name":"noahs233","email":"noah.schoenhaus@whop.com"},{"name":"deels","email":"destineewalston7@gmail.com"},{"name":"connorwhop","email":"connor@whop.com"},{"name":"danielschwartz4","email":"schwartzray8@gmail.com"},{"name":"antonwhop","email":"anton.reza@whop.com"},{"name":"zhast","email":"stevezzhang@gmail.com"},{"name":"jjantschulev","email":"j.jantschulev@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/template-kit_0.3.1_1787767064941_0.9339760409709807"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-17T20:26:49.154Z","modified":"2026-08-26T17:57:45.290Z","0.2.0":"2026-08-17T20:26:49.450Z","0.3.0":"2026-08-20T09:35:18.685Z","0.3.1":"2026-08-26T17:57:45.096Z"},"bugs":{"url":"https://github.com/whopio/whop-monorepo/issues"},"license":"MIT","homepage":"https://whop.com/developers/","keywords":["apps","payments","rest","sdk","template","whop"],"repository":{"type":"git","url":"git+https://github.com/whopio/whop-monorepo.git","directory":"developer-platform/packages/template-kit"},"description":"Data and server layer for building Whop templates on the Whop REST API","maintainers":[{"name":"ryanouyang","email":"ryan.ouyang01@gmail.com"},{"name":"stevo2","email":"steven@whop.com"},{"name":"baked-developer","email":"tristan@whop.com"},{"name":"noahs233","email":"noah.schoenhaus@whop.com"},{"name":"deels","email":"destineewalston7@gmail.com"},{"name":"connorwhop","email":"connor@whop.com"},{"name":"danielschwartz4","email":"schwartzray8@gmail.com"},{"name":"antonwhop","email":"anton.reza@whop.com"},{"name":"zhast","email":"stevezzhang@gmail.com"},{"name":"jjantschulev","email":"j.jantschulev@gmail.com"}],"readme":"# @whop/template-kit\n\nThe data + server layer for building [Whop](https://whop.com) templates — deployable `*.whop.app` apps whose every screen is backed by the Whop public REST API.\n\nIt gives you one typed API contract (`WhopAPI`), React hooks to read it, a same-origin server proxy that keeps the company API key out of the browser, and a preview bridge so the exact same UI can render with fixtures in a catalog. The reference implementation is the **neobank** template.\n\n## Install\n\n```bash\npnpm add @whop/template-kit\n```\n\nPeer dependency: `react@^19`.\n\n## Quick start\n\nA template is a [TanStack Start](https://tanstack.com/start) app with three pieces of wiring.\n\n**1. Declare which endpoints your app may call** (`src/api-manifest.ts`) — select them by name; the kit owns the paths and copy:\n\n```ts\nimport { selectManifest } from \"@whop/template-kit\";\n\nexport const MANIFEST = selectManifest([\n  \"getAccount\",\n  \"listPayouts\",\n  \"createPayout\",\n]);\n```\n\nThis is your allowlist: only the endpoints you name are proxied. (You can still hand-write an `EndpointManifest` if you need a path the catalog doesn't cover.)\n\n**2. Mount the proxy route** (`src/routes/api.$.ts`) — this is the only place the app talks to `api.whop.com`:\n\n```ts\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { createApiProxy } from \"@whop/template-kit/server\";\nimport { MANIFEST } from \"../api-manifest\";\n\nexport const Route = createFileRoute(\"/api/$\")({\n  server: { handlers: createApiProxy(MANIFEST) },\n});\n```\n\n**3. Provide the API and read it in components:**\n\n```tsx\nimport { WhopAPIProvider, resolveAPI, useWhopAPI, useEndpoint } from \"@whop/template-kit\";\n\nfunction App() {\n  // resolveAPI() returns the real HTTP client, or the preview bridge when embedded with ?whop_preview=1\n  return (\n    <WhopAPIProvider endpoints={resolveAPI()}>\n      <Balance />\n    </WhopAPIProvider>\n  );\n}\n\nfunction Balance() {\n  const { getAccount } = useWhopAPI();\n  const { data, isLoading, error } = useEndpoint(getAccount);\n  if (isLoading) return null;\n  if (error) return <p>{error.message}</p>;\n  return <p>{data.total_usd}</p>;\n}\n```\n\nThat's it — no `fetch`, no URLs, no API key. You call typed methods on `WhopAPI`; the kit handles transport.\n\n## Security model\n\n- **The company API key is never in the browser or your app's JS.** The client calls same-origin `/api/*` with no key; your proxy forwards to `api.whop.com` with **no `Authorization` header**; Whop's hosting layer injects `Authorization: Bearer <company key>` at the edge on the outbound hop.\n- **The proxy is unauthenticated by default.** Anyone who can reach the app URL gets the account's data back. For anything beyond a public demo, **gate `/api/*` on the visitor's Whop identity/membership** before forwarding.\n- **The manifest is an allowlist.** Only declared paths are proxied, and traversal (`..`) is rejected before any upstream fetch.\n- **Money-out is scope-ceilinged.** The injected key strips money-out scopes, so `POST /transfers` and `POST /payouts` return `403`.\n\n## Preview mode\n\nThe same components render two ways because they only ever talk to a `WhopAPI` object handed in through `WhopAPIProvider`:\n\n- **Deployed app:** `resolveAPI()` → `httpAPI` → real REST via your `/api/*` proxy.\n- **Catalog preview:** when embedded with `?whop_preview=1`, `resolveAPI()` returns `createPreviewAPI()` — a proxy that answers every call over `postMessage` from the parent frame. The parent supplies fixtures, so the preview is credential-free.\n\nNo fixtures ship in this package or in a deployed template — a deploy is real-data-only by construction.\n\n## API\n\n- **`WhopAPI`** — the typed endpoint contract (account, financial activity, cards, transfers, payouts, swaps, metrics, reports, products, plans, memberships, reviews, payments, checkout configurations).\n- **`selectManifest` / `WHOP_ENDPOINTS`** — build your allowlist by endpoint name from the kit's canonical catalog (paths + copy included).\n- **`WhopAPIProvider` / `useWhopAPI` / `useEndpoint`** — provide the API and read a single call (`{ data, isLoading, error, refresh }`).\n- **`httpAPI` / `resolveAPI` / `createPreviewAPI`** — the real, resolved, and preview implementations of `WhopAPI`. `httpAPI` wraps the official [`@whop/sdk`](https://www.npmjs.com/package/@whop/sdk) pointed at your `/api` proxy — same client, no key in the browser — and lazy-loads it on first call so it never weighs down your initial bundle.\n- **`useRealtimeChannel` / `useRealtimeRefresh`** — subscribe a component to a realtime channel.\n- **`@whop/template-kit/server`** — `createApiProxy`, `proxyConfigFromManifest`, `createRealtimeRoute`, `createWebhookRoute`, `verifyWhopWebhook`, `publishRealtime`.\n- **`format` / `currency`** — display helpers for balances and amounts.\n\n## Links\n\n- [Whop developer docs](https://whop.com/developers/)\n- Reference template: `neobank`\n\n## Local development\n\n`whop apps dev` mints a short-lived credential, but the Cloudflare dev runtime doesn't inherit the CLI's environment — give the worker its own vars in a gitignored `.dev.vars` next to your `wrangler.jsonc`:\n\n```bash\nWHOP_API_KEY=<an API key for your business>\nWHOP_DEV_ACCOUNT_ID=biz_XXXXXXXXXXXX\n```\n\nWhen `WHOP_API_KEY` is present the proxy attaches it to upstream calls (in the hosted runtime the variable never exists — the edge injects the key instead), and `WHOP_DEV_ACCOUNT_ID` points `getAccount` at your business when the credential is a user token. Your template then runs locally against real data.\n","readmeFilename":"README.md"}