diff --git a/src/pages/_api/api/faucet.ts b/src/pages/_api/api/faucet.ts new file mode 100644 index 0000000..6051c13 --- /dev/null +++ b/src/pages/_api/api/faucet.ts @@ -0,0 +1,71 @@ +import { createClient, http } from 'viem' +import { tempoModerato } from 'viem/chains' +import { Actions } from 'viem/tempo' + +function getClient() { + return createClient({ + chain: tempoModerato, + transport: http(), + }) +} + +export async function POST(request: Request): Promise { + const origin = request.headers.get('origin') + const corsHeaders = cors(origin) + + let body: { address?: string } + try { + body = await request.json() + } catch { + return Response.json( + { data: null, error: 'Invalid request: could not parse JSON' }, + { status: 400, headers: corsHeaders }, + ) + } + + const address = body?.address + if (!address || !/^0x[a-fA-F0-9]{40}$/.test(address)) { + return Response.json( + { data: null, error: 'Invalid or missing address' }, + { status: 400, headers: corsHeaders }, + ) + } + + return fund(address.toLowerCase() as `0x${string}`, corsHeaders) +} + +export async function OPTIONS(request: Request): Promise { + const origin = request.headers.get('origin') + return new Response(null, { status: 200, headers: cors(origin) }) +} + +async function fund(address: `0x${string}`, headers: Record): Promise { + try { + const client = getClient() + const hashes = await Actions.faucet.fund(client, { account: address }) + + const data = hashes.map((hash) => ({ hash })) + return Response.json({ data, error: null }, { headers }) + } catch (error) { + console.error('Faucet error:', error) + const message = error instanceof Error ? error.message : 'Unknown error occurred' + return Response.json({ data: null, error: message }, { status: 500, headers }) + } +} + +function cors(origin: string | null): Record { + const allowedOrigins = ['https://docs.tempo.xyz'] + + if (origin?.includes('vercel.app')) allowedOrigins.push(origin) + if (process.env.NODE_ENV === 'development') allowedOrigins.push('http://localhost:5173') + + const headers: Record = { + 'Access-Control-Allow-Methods': 'POST, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, x-api-token', + } + + if (origin && allowedOrigins.some((allowed) => origin.startsWith(allowed))) + headers['Access-Control-Allow-Origin'] = origin + + return headers +} diff --git a/src/pages/guide/use-accounts/add-funds.mdx b/src/pages/guide/use-accounts/add-funds.mdx index bac91f3..fcced80 100644 --- a/src/pages/guide/use-accounts/add-funds.mdx +++ b/src/pages/guide/use-accounts/add-funds.mdx @@ -43,14 +43,14 @@ Send test stablecoins to any address.
-Request tokens programmatically via the [Tempo API](https://api.tempo.xyz/docs). +Request tokens programmatically via the faucet API.
```bash -curl "https://api.tempo.xyz/actions/faucet\ -?chainId=42431\ -&address=" +curl -X POST https://docs.tempo.xyz/api/faucet \ + -H "Content-Type: application/json" \ + -d '{"address": ""}' ```
diff --git a/src/pages/quickstart/faucet.mdx b/src/pages/quickstart/faucet.mdx index 7b06e0e..26e6b5a 100644 --- a/src/pages/quickstart/faucet.mdx +++ b/src/pages/quickstart/faucet.mdx @@ -44,14 +44,14 @@ Send test stablecoins to any address.
-Request tokens programmatically via the [Tempo API](https://api.tempo.xyz/docs). +Request tokens programmatically via the faucet API.
```bash -curl "https://api.tempo.xyz/actions/faucet\ -?chainId=42431\ -&address=" +curl -X POST https://docs.tempo.xyz/api/faucet \ + -H "Content-Type: application/json" \ + -d '{"address": ""}' ```