Shield SDKs
Akedly Shield SDKs handle Proof-of-Work challenge solving and Cloudflare Turnstile token retrieval for the V1.2 REST API. Each SDK manages threading automatically -- Web Workers in browsers, Isolates in Dart, async/await in Swift, and coroutines in Kotlin.
Distribution
Web and React Native ship as the @akedly/shield package on npm. The iOS, Flutter, and Android SDKs are distributed directly from GitHub: iOS via Swift Package Manager's native Git URL support, Flutter via a git: pubspec entry, and Android via JitPack or a local Gradle module. The Flutter and Android SDKs are not published on pub.dev or Maven Central yet.
Keep your API key on your backend
APIKey and pipelineID are credentials. Never embed them in web bundles, APKs, or iOS/Flutter binaries — they can be extracted. Each SDK page below shows the recommended two-tab pattern: a Node.js backend that proxies /auth/akedly/challenge, /auth/akedly/send, /auth/akedly/verify, and a frontend that only talks to that proxy. The Shield SDK still runs on the client so PoW and Turnstile stay tied to the real user.
Optional: per-end-user-IP rate limiting
Per-IP rate limiting is opt-in. If you want it, your proxy should include the x-end-user-ip header on /transactions/send with the real end user's IP — the one that hit your backend, not your server or load balancer IP. Every SDK page's backend example enables this with req.ip plus app.set('trust proxy', 1); drop those lines if you don't need per-IP limiting (phone and pipeline limits always apply). See the V1.2 API reference for Node/Express, Next.js, Flask, and PHP extraction patterns.
Platform SDKs
| Platform | Package | Install | PoW | Turnstile |
|---|---|---|---|---|
| Web / JavaScript | @akedly/shield | npm / CDN | Web Worker (auto) | getTurnstileToken() |
| Flutter / Dart | akedly_shield | GitHub (pubspec git:) | Isolate | AkedlyTurnstile widget |
| iOS / Swift | AkedlyShield | SPM (GitHub URL) | async/await | AkedlyTurnstile (WKWebView) |
| Android / Kotlin | akedly-shield-kotlin | GitHub (JitPack / local module) | Coroutines | AkedlyTurnstile (WebView) |
| React Native | @akedly/shield | npm | Batched main-thread | Bridge page |
PoW Algorithm
All Shield SDKs implement the same Proof-of-Work algorithm. The solver computes SHA256(challenge + ":" + nonce) and checks whether the hex digest starts with the required number of leading zeros.
challenge = "a1b2c3d4e5f6..." // 64-char hex string from server
difficulty = 4 // number of leading hex zeros required
nonce = 0
loop:
hash = SHA256(challenge + ":" + String(nonce))
if hash starts with "0000": // difficulty = 4 leading zeros
return nonce
nonce++
The difficulty is set per-pipeline in the Akedly dashboard. Higher difficulty increases computational cost, providing stronger bot protection at the expense of longer solve times. Adaptive difficulty mode automatically adjusts based on traffic patterns.
Performance
Typical solve times range from under 100ms (difficulty 3) to a few seconds (difficulty 5+). Shield SDKs use background threads to keep the UI responsive during solving.
Turnstile Integration
When turnstile.required is true in the challenge response, the client must obtain a Cloudflare Turnstile token before calling the Send endpoint.
Each platform handles Turnstile differently:
- Name
Web- Type
- getTurnstileToken()
- Description
Creates a hidden Turnstile widget in the DOM, resolves with the token, and cleans up automatically.
- Name
Flutter- Type
- AkedlyTurnstile widget
- Description
Flutter widget that loads a Turnstile bridge page via WebView. Add it to your widget tree and receive the token via
onTokencallback.
- Name
iOS- Type
- AkedlyTurnstile.getToken()
- Description
Uses a hidden WKWebView to load the Turnstile bridge page at
turnstile.akedly.io. Returns the token via async/await.
- Name
Android- Type
- AkedlyTurnstile.getToken()
- Description
Creates an invisible WebView to load the Turnstile bridge page. Returns the token via coroutine.
- Name
React Native- Type
- Bridge page
- Description
Uses a WebView pointing to
turnstile.akedly.ioto obtain the token. See the React Native SDK page for details.
Turnstile tokens expire after 2 minutes. Generate a new token for each OTP request.