Prompt Your LLM: Flutter / Dart

Copy the prompt below into ChatGPT, Claude, Cursor, or any AI coding assistant. It contains everything the LLM needs to generate a working Akedly Shield V1.2 integration for your Flutter project.


Copy This Prompt

I need to integrate Akedly Shield V1.2 OTP authentication into my Flutter application.

## Architecture: keep APIKey on the backend

APIKey and pipelineID are credentials. They MUST NOT be compiled into a Flutter app — the binary is shippable and anything inside it is public.
My backend exposes three thin proxy routes that the Flutter app will call:
  GET  /auth/akedly/challenge
  POST /auth/akedly/send            body: { phoneNumber, powSolution, turnstileToken? }
  POST /auth/akedly/verify          body: { transactionReqID, otp }

The Flutter code you generate must ONLY call these three routes.
Never reference APIKey or pipelineID in Dart code. Never call api.akedly.io from the client.

## Reference backend (Node.js / Express) — drop in if I don't have one yet

import express from 'express';

const app = express();
app.use(express.json());
// Optional: only needed if you want per-end-user-IP rate limiting (drop
// this line and the x-end-user-ip header below if you don't). Makes req.ip
// the real client IP behind Cloudflare / Vercel / AWS ALB / Nginx.
app.set('trust proxy', 1);

app.get('/auth/akedly/challenge', async (_req, res) => {
  const r = await fetch(
    `https://api.akedly.io/api/v1.2/transactions/challenge` +
    `?APIKey=${process.env.AKEDLY_API_KEY}` +
    `&pipelineID=${process.env.AKEDLY_PIPELINE_ID}`
  );
  res.status(r.status).json(await r.json());
});

app.post('/auth/akedly/send', async (req, res) => {
  const { phoneNumber, powSolution, turnstileToken } = req.body;
  const r = await fetch('https://api.akedly.io/api/v1.2/transactions/send', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'x-end-user-ip': req.ip },
    body: JSON.stringify({
      APIKey: process.env.AKEDLY_API_KEY,
      pipelineID: process.env.AKEDLY_PIPELINE_ID,
      verificationAddress: { phoneNumber },
      powSolution,
      turnstileToken,
    }),
  });
  res.status(r.status).json(await r.json());
});

app.post('/auth/akedly/verify', async (req, res) => {
  const { transactionReqID, otp } = req.body;
  const r = await fetch('https://api.akedly.io/api/v1.2/transactions/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ transactionReqID, otp }),
  });
  res.status(r.status).json(await r.json());
});

## Challenge response shape (what Flutter receives from /auth/akedly/challenge)

{ status, data: { challenge, difficulty, challengeToken, challengeRequired, turnstile: { required, siteKey } } }

## Frontend flow

1. GET {backendUrl}/auth/akedly/challenge
2. Solve PoW in a Dart Isolate: `final nonce = await solvePowInIsolate(challenge, difficulty)`
   Algorithm: SHA256(challenge + ":" + nonce) must start with `difficulty` leading hex zeros.
3. If turnstile.required, use the AkedlyTurnstile widget with siteKey and an onToken callback.
4. POST {backendUrl}/auth/akedly/send   body: { phoneNumber, powSolution: { challengeToken, nonce }, turnstileToken? }
   Response: { status, data: { transactionReqID } }
5. POST {backendUrl}/auth/akedly/verify   body: { transactionReqID, otp: "123456" }

## SDK: akedly_shield (GitHub-only, not on pub.dev)

Repository: https://github.com/Akedly-Org/akedly-shield-dart

Add to pubspec.yaml as a git dependency:
  akedly_shield:
    git:
      url: https://github.com/Akedly-Org/akedly-shield-dart.git
      ref: main  # or a release tag like v1.0.0

Key functions:
- solvePow(String challenge, int difficulty) -> Future<int> (main thread, yields every 10k iterations)
- solvePowInIsolate(String challenge, int difficulty) -> Future<int> (background Isolate, recommended)
- AkedlyTurnstile widget: siteKey (required), onToken (required), onError (optional), bridgeDomain (default: turnstile.akedly.io)

## Requirements

Please generate a complete Flutter screen/widget with:
- Full OTP flow (challenge -> solve in Isolate -> send -> verify) that ONLY talks to my backend
- AkedlyTurnstile widget integration when turnstile is required
- Error handling and loading states
- Phone number input field
- OTP input with 6-digit field
- Use the http package for API calls
- A top-level `const backendUrl = 'https://yourapp.com';` the user can change
- Clean, production-ready code following Flutter best practices
- No APIKey and no pipelineID anywhere in Dart code

Customizing the Prompt

Add any of these to the end of the prompt to tailor the output:

  • Framework: "I'm using Next.js App Router with TypeScript" or "I'm using Expo with React Navigation"
  • State management: "Use Zustand for state" or "Use Redux Toolkit"
  • Styling: "Use Tailwind CSS" or "Use styled-components" or "Use NativeWind"
  • Auth flow: "After OTP verification, create a JWT session" or "Store the session in SecureStore"
  • Error handling: "Show toast notifications for errors" or "Use react-hot-toast"

Was this page helpful?