---
title: "Cinderace Captcha"
description: "Solvers de captcha no browser para reCAPTCHA, Turnstile e detecção automática."
---
O **Cinderace Captcha** resolve os desafios de captcha no browser e entrega o token no formato que a API espera.

```bash
yarn add @luckymaker/sdk-captcha
```

## Como funciona

1. A SDK faz a requisição normalmente.
2. Se a API responder `CAPTCHA_NOT_PROVIDED` (ou outro erro de captcha), a SDK chama o solver configurado.
3. O solver devolve `{ provider, token }`.
4. A SDK injeta `PROVIDER$token` no campo `captcha` e repete a requisição **uma vez**.

Não é preciso saber de antemão quais rotas pedem captcha: o retry acontece só quando a API recusa a chamada.

## Google reCAPTCHA

```ts
import { GoogleRecaptchaSolver } from "@luckymaker/sdk-captcha";
import { LMSdk } from "@luckymaker/sdk-core";

const sdk = new LMSdk({
    baseUrl: "api.sualoja.com.br",
    captcha: {
        solver: new GoogleRecaptchaSolver()
    }
});
```

O solver carrega `recaptcha/api.js` e executa `grecaptcha.execute` com a action configurada. A site key vem das system options automaticamente.

## Cloudflare Turnstile

```ts
import { CloudflareTurnstileSolver } from "@luckymaker/sdk-captcha";

const sdk = new LMSdk({
    baseUrl: "api.sualoja.com.br",
    captcha: {
        solver: new CloudflareTurnstileSolver()
    }
});
```

O Turnstile roda em um widget off-screen. Quando a Cloudflare exige interação, o solver lança `CaptchaSolverError` com código `SOLVE_TIMEOUT`.

## Detecção automática

```ts
import {
    AutoCaptchaResolve,
    CloudflareTurnstileSolver,
    GoogleRecaptchaSolver
} from "@luckymaker/sdk-captcha";

const sdk = new LMSdk({
    baseUrl: "api.sualoja.com.br",
    captcha: {
        solver: new AutoCaptchaResolve({
            solvers: [
                new GoogleRecaptchaSolver(),
                new CloudflareTurnstileSolver()
            ]
        })
    }
});
```

O `AutoCaptchaResolve` escolhe o solver nesta ordem:

1. callback `resolve` customizado;
2. hint `request.provider`;
3. provider informado no erro da API (`newProvider`, `provider` ou `activeProvider`);
4. provider ativo nas system options;
5. o único solver registrado;
6. o global já carregado no browser (`grecaptcha` ou `turnstile`).

## Action

Use `action` para reCAPTCHA v3 ou Turnstile:

```ts
const sdk = new LMSdk({
    baseUrl: "api.sualoja.com.br",
    captcha: {
        solver: new GoogleRecaptchaSolver(),
        action: "login"
    }
});
```

Também aceita uma função, quando a action muda por rota:

```ts
captcha: {
    solver,
    action: (request) => request.url.includes("/user/sign-in") ? "login" : undefined
}
```

## Opções

| Opção | Padrão | Para que serve |
|---|---|---|
| `solver` | — | Solver que gera o token. |
| `field` | `"captcha"` | Campo que recebe o token. |
| `placement` | `"body"` | `body` ou `header`. |
| `action` | — | Action do provider, fixa ou por request. |
| `retryOnFailure` | `true` | Resolve e repete uma vez em erros de captcha. |

A API do LuckyMaker lê o token do body no campo `captcha`. Use `placement: "header"` apenas para rotas que aceitam o token no header.

## Site key automática

Quando a instância tem `captcha.solver`, a SDK injeta o próprio contexto de system options no solver:

```ts
const sdk = new LMSdk({
    baseUrl: "api.sualoja.com.br",
    captcha: {
        solver: new GoogleRecaptchaSolver()
    }
});
```

No primeiro solve, o solver lê `security.captcha.providers.recaptcha.key` (ou `.turnstile.key`) das system options. Você ainda pode passar `siteKey` explicitamente para sobrescrever:

```ts
new GoogleRecaptchaSolver({ siteKey: "<site-key>" });
```

## Solver customizado

```ts
import { AbstractCaptchaSolver } from "@luckymaker/sdk-captcha";

class MeuSolver extends AbstractCaptchaSolver {
    public readonly provider = "RECAPTCHA" as const;

    public async solve() {
        return {
            provider: this.provider,
            token: await gerarToken()
        };
    }
}
```

:::caution[SSR]
Os solvers dependem do browser. Configure `captcha` apenas em instâncias que rodam no cliente.
:::