React Native Shield SDK

React Native uses the same @akedly/shield npm package as web. The library automatically detects the React Native environment and switches to batched main-thread PoW solving (no Web Worker).

Installation

Installation

BASH
npm install @akedly/shield

For Turnstile support, you also need a WebView package:

npm install react-native-webview

Key Differences from Web

FeatureWebReact Native
PoW SolverWeb Worker (off-thread)Batched main-thread with setTimeout(fn, 0)
UI during PoWFully responsiveResponsive (batched yields to event loop)
TurnstilegetTurnstileToken() (hidden DOM widget)WebView pointing to bridge page
ImportSameSame

The solvePow function works identically -- it detects the environment and falls back to batched solving automatically. No configuration needed.

For Turnstile, getTurnstileToken() is browser-only. In React Native, use a WebView pointing to the Turnstile bridge page at turnstile.akedly.io.


Complete Example

React Native Component

JS
OTPScreen.js
// Express proxy — deploy this on your server, not inside the RN bundle.
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 a reverse proxy (1 = trust first hop).
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());
});

Expo Considerations

If using Expo, install the WebView via:

npx expo install react-native-webview

The @akedly/shield package works with Expo without any additional configuration. The PoW solver uses JavaScript-only crypto (no native modules required).

For managed Expo projects, the Turnstile WebView approach works out of the box since react-native-webview is supported in the Expo Go client.


Was this page helpful?