> ## Documentation Index
> Fetch the complete documentation index at: https://ribaunt-e66481b6-mintlify-4e7c3afc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# solveChallenge

> solveChallenge and solveChallengeAsync solve JWT challenge tokens in Node.js. Use them in tests and tooling — not in production request handlers.

`solveChallenge()` runs the same proof-of-work algorithm used by the browser widget, but synchronously in Node.js. It is designed for automated testing of your challenge and verify endpoints — not for production use in request handlers.

`solveChallenge()` supports SHA-256 tokens only and returns `undefined` for `argon2id` tokens. Use [`solveChallengeAsync()`](#solvechallengeasync) to solve both algorithms.

## Import

```ts theme={null}
import { solveChallenge, solveChallengeAsync } from 'ribaunt';
```

## Signature

```ts theme={null}
// Single token
function solveChallenge(
  token: ChallengeToken,
  options?: SolveChallengeOptions
): ChallengeSolution | undefined

// Array of tokens
function solveChallenge(
  token: ChallengeToken[],
  options?: SolveChallengeOptions
): ChallengeSolution[] | undefined
```

## Parameters

<ParamField path="token" type="ChallengeToken | ChallengeToken[]" required>
  A single JWT challenge token or an array of tokens from `createChallenge()`.
</ParamField>

<ParamField path="options" type="SolveChallengeOptions">
  Optional guardrails to prevent long-running synchronous solves.

  <Expandable title="SolveChallengeOptions">
    <ParamField path="maxIterations" type="number">
      Hard cap on nonce attempts per token. Returns `undefined` if reached.
    </ParamField>

    <ParamField path="maxDurationMs" default="30000" type="number">
      Max synchronous solve time in milliseconds per token. Returns `undefined` if exceeded.
    </ParamField>
  </Expandable>
</ParamField>

## Return value

Returns a `ChallengeSolution` (`{ nonce: string; hash: string }`) for a single token input, or `ChallengeSolution[]` for an array input. Returns `undefined` if any guardrail is hit, a token is invalid, or a token uses `argon2id`. When solving an array, `undefined` is returned as soon as any single token fails — no partial results are returned.

## Example

```ts theme={null}
import { createChallenge, solveChallenge, verifySolution } from 'ribaunt';

const tokens = await createChallenge({ difficulty: 3, amount: 2, ttlSeconds: 60 });
const solutions = solveChallenge(tokens);

if (solutions) {
  const result = await verifySolution(tokens, solutions);
  console.log('Valid:', result.valid);
}
```

With guardrails:

```ts theme={null}
const solution = solveChallenge(token, {
  maxDurationMs: 2000,
  maxIterations: 500_000,
});

if (!solution) {
  console.log('Solver gave up — difficulty too high or timeout reached');
}
```

<Warning>
  `solveChallenge()` is synchronous and CPU-intensive. Never call it in a production HTTP request handler — it will block your Node.js event loop.
</Warning>

<Tip>
  Use difficulty 3–4 in tests. Difficulty 5 will noticeably slow down your test suite.
</Tip>

## solveChallengeAsync

`solveChallengeAsync()` is the asynchronous variant. It reads the algorithm from each token and solves SHA-256 and `argon2id` tokens alike, so use it when your tests cover [Argon2id challenges](/api/create-challenge#argon2id-opt-in) or mixed batches. It accepts the same `SolveChallengeOptions` guardrails and returns `undefined` under the same conditions.

```ts theme={null}
// Single token
function solveChallengeAsync(
  token: ChallengeToken,
  options?: SolveChallengeOptions
): Promise<ChallengeSolution | undefined>

// Array of tokens
function solveChallengeAsync(
  token: ChallengeToken[],
  options?: SolveChallengeOptions
): Promise<ChallengeSolution[] | undefined>
```

```ts theme={null}
import { createChallenge, solveChallengeAsync, verifySolution } from 'ribaunt';

const tokens = await createChallenge({
  algorithm: 'argon2id',
  difficulty: 1,
  amount: 2,
  ttlSeconds: 60,
});

const solutions = await solveChallengeAsync(tokens);

if (solutions) {
  const result = await verifySolution(tokens, solutions);
  console.log('Valid:', result.valid);
}
```

<Tip>
  Argon2id hashes take milliseconds each, so keep test difficulty at `1` and amounts small to keep suites fast.
</Tip>
