diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..957cd15 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["next/core-web-vitals"] +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3f01223 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +.next/ +node_modules/ +out/ +dist/ +.env* +!.env.example +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +.DS_Store +tsconfig.tsbuildinfo diff --git a/README.md b/README.md index 5f1a2e0..15d55b8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,26 @@ -# x402-directory +# x402 Directory + A curated, agent-maintained directory of x402 payment-enabled applications and endpoints. Browse, search, and discover services that accept x402 micropayments. Agents can contribute by adding new listings, verifying endpoint liveness, and categorizing services. + +## Getting Started + +Install dependencies: + +```bash +npm install +``` + +Run the development server: + +```bash +npm run dev +``` + +Open [http://localhost:3000](http://localhost:3000) to view the app. + +## Scripts + +- `npm run dev` starts the local Next.js server. +- `npm run build` creates a production build. +- `npm run typecheck` runs TypeScript without emitting files. +- `npm run lint` runs the Next.js lint checks. diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..a2fdc07 --- /dev/null +++ b/app/globals.css @@ -0,0 +1,33 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --background: #f7fbfb; + --foreground: #1b1f23; +} + +* { + box-sizing: border-box; +} + +html { + min-height: 100%; +} + +body { + min-height: 100vh; + margin: 0; + background: var(--background); + color: var(--foreground); +} + +a { + color: inherit; + text-decoration: none; +} + +button, +input { + font: inherit; +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..0cdd3a5 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,24 @@ +import type { Metadata } from "next"; +import { Inter } from "next/font/google"; +import "./globals.css"; + +const inter = Inter({ subsets: ["latin"], variable: "--font-inter" }); + +export const metadata: Metadata = { + title: "x402 Directory", + description: "Browse and discover x402 payment-enabled applications and endpoints.", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + {children} + + + ); +} diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..b89d450 --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,114 @@ +import { PageShell } from "@/components/page-shell"; +import { placeholderListings } from "@/data/placeholder-listings"; + +export default function Home() { + return ( + +
+
+

+ x402 endpoint discovery +

+

+ Find applications and APIs that accept x402 payments. +

+

+ A curated directory for agents, developers, and services building + with HTTP-native micropayments. +

+
+ + Browse preview + + + Learn about x402 + +
+
+ +
+
+
+

+ Endpoint liveness +

+

Placeholder status panel

+
+ + Preview + +
+
+
+
Apps
+
24
+
+
+
APIs
+
18
+
+
+
Live
+
92%
+
+
+
+
+ +
+
+
+
+

+ Directory preview +

+

+ Example cards for the first searchable directory experience. +

+
+
+ Search and filters can land in the next iteration. +
+
+ +
+ {placeholderListings.map((listing) => ( +
+
+
+

+ {listing.name} +

+

+ {listing.category} +

+
+ + {listing.status} + +
+

+ {listing.description} +

+
+ ))} +
+
+
+
+ ); +} diff --git a/components/page-shell.tsx b/components/page-shell.tsx new file mode 100644 index 0000000..9b7d045 --- /dev/null +++ b/components/page-shell.tsx @@ -0,0 +1,44 @@ +type PageShellProps = { + children: React.ReactNode; +}; + +export function PageShell({ children }: PageShellProps) { + return ( +
+
+ +
+ +
{children}
+ + +
+ ); +} diff --git a/data/placeholder-listings.ts b/data/placeholder-listings.ts new file mode 100644 index 0000000..91074c5 --- /dev/null +++ b/data/placeholder-listings.ts @@ -0,0 +1,23 @@ +export const placeholderListings = [ + { + name: "Micropay API", + category: "Developer tool", + status: "Live", + description: + "A sample payment-enabled API listing with category metadata and endpoint status.", + }, + { + name: "Agent File Store", + category: "Storage", + status: "Live", + description: + "Placeholder listing for an app that accepts x402 payments for file access.", + }, + { + name: "Inference Gateway", + category: "AI service", + status: "Checking", + description: + "Example service card for future liveness checks, tags, and verification details.", + }, +]; diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..40c3d68 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..4678774 --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,4 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = {}; + +export default nextConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..69e60f8 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "x402-directory", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "typecheck": "tsc --noEmit", + "lint": "next lint" + }, + "dependencies": { + "next": "14.2.35", + "react": "18.3.1", + "react-dom": "18.3.1" + }, + "devDependencies": { + "@types/node": "20.19.7", + "@types/react": "18.3.23", + "@types/react-dom": "18.3.7", + "autoprefixer": "10.4.21", + "eslint": "8.57.1", + "eslint-config-next": "14.2.35", + "postcss": "8.5.6", + "tailwindcss": "3.4.17", + "typescript": "5.8.3" + } +} diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 0000000..a982c64 --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,8 @@ +const config = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +}; + +export default config; diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..3668858 --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,24 @@ +import type { Config } from "tailwindcss"; + +const config: Config = { + content: [ + "./app/**/*.{js,ts,jsx,tsx,mdx}", + "./components/**/*.{js,ts,jsx,tsx,mdx}", + "./data/**/*.{js,ts,jsx,tsx,mdx}", + ], + theme: { + extend: { + colors: { + stone: { + 650: "#57534a", + }, + }, + fontFamily: { + sans: ["var(--font-inter)", "system-ui", "sans-serif"], + }, + }, + }, + plugins: [], +}; + +export default config; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..47fabac --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": false, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "baseUrl": ".", + "paths": { + "@/*": ["./*"] + }, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +}