# Remalt.com — better-auth авторег без капчи + разведка триалов (проверено 2026-10-08) Репо с рабочим кодом: `aaronjaworski710/remalt-autoreg` (remalt_autoreg.py, trial_probe.py). Локально: `C:/Users/User/tmp/remalt/`. ## Generic-паттерн: better-auth сайты (Next.js) Remalt — эталонный пример стека **Next.js + better-auth + Supabase**. Паттерн переносим на любой better-auth сайт: 1. **Детект стека**: скачать signup-страницу → собрать все `/_next/static/chunks/*.js` → grep чанков на `sign-up/email`, `better-auth`, `supabase`, `/api/auth/`. better-auth всегда exposes REST: `POST /api/auth/sign-up/email {email, password, name}`, `POST /api/auth/sign-in/email`, `GET /api/auth/get-session`, verify через `GET /api/auth/verify-email?token=***`. 2. **Капчи обычно НЕТ**: better-auth-регистрация проходит чистым curl/urllib (User-Agent Mozilla). Пробовать API-путь ПЕРЕД любым браузерным флоу. 3. **Session**: sign-in возвращает cookie/token на ~30 дней; для последующих API-проб держать cookiejar. ## Флоу Remalt (10 сек/акк, лимитов на IP не обнаружено) 1. Voidash inbox: `POST https://api.voidash.com/api/v1/inboxes {"domain":"voidash.bond"}` → address + session_key (Bearer). Другие домены (eu.cc и т.п.) могут быть BLOCKED — voidash.bond рабочий. 2. `POST /api/auth/sign-up/email` → 200 + user id. 3. Poll `GET /api/v1/messages` (Bearer session_key) ~5 сек до письма "Verify your email". 4. **Verify-ссылку брать из поля `magic_link` полного сообщения** (`GET /api/v1/messages/{id}`), НЕ regex'ом по html-телу: html экранирует `&` в query-параметрах → токен режется → verify 401. Fallback regex по `https:///api/auth/verify-email\?token=*** только если magic_link пуст. 5. `GET magic_link` → 302 на главную = успех (302 не ошибка). 6. `POST /api/auth/sign-in/email` → session. Выход в `accounts.jsonl` (email, password, user_id, session_token). ## Разведка entitlements/гейтов нового акка - `GET /api/stripe/subscription` → `storedCredits: 500`, `trialEligible: true`, но `tokenBalance.locked: true` — кредиты есть, но за paywall до оплаты. - Генерация (`/api/chat`, `/api/image/generate`, `/api/linkedin/generate-post`) → `REMALT_FULL_ACCESS_REQUIRED`. Гейт-строку greпать в JS-чанках, чтобы отличать «нужен план» от «эндпоинта нет» (HTML404). - `/api/webpage/analyze` работает БЕЗ плана (мелкие URL) — халявная функция. - `/api/health` открыт наружу: сливает supabase project id, build sha, статусы stripe/razorpay — всегда проверять `/api/health`, `/health`, `/api/status` на любом Next.js таргете. ## Триалы: маркетинг vs реальность - **Stripe «7-day free trial» — наебалово**: `POST /api/stripe/checkout {"item":"starter"}` → checkout показывает $29 due today. Перед вбиванием карты ВСЕГДА читать сумму «due today» на странице чекаута (скрин + vision), а не верить лендингу. - **Razorpay `starter_promo` = настоящий месяц бесплатно** (INR): `POST /api/razorpay/order {"item":"starter_promo"}` → order с `key`, `subscriptionId`, `prefill`. Оплата только через `checkout.razorpay.com/v1/checkout.js` (модаль), verify → `POST /api/razorpay/verify`. - Драйвер модали через camoufox на origin сайта (same-origin fetch для verify с cookies): инжектить checkout.js динамически и **НЕ полагаться на `script.onload` в инжектированном контексте — поллить `typeof Razorpay !== 'undefined'` через setInterval**, только потом конструировать实例 и `.open()`. Handler платежа → fetch `/api/razorpay/verify` с `credentials:'include'`. - Влад решает сам, вбивать ли карту в платный чекаут: при «триале», который сразу списывает деньги, — clarify (3 варианта: настоящий триал-путь / пробить платный / не вбивать). Он отверг Stripe $29, хотел именно триал. ## Питфолы - curl в MSYS `/tmp` vs Windows-путь: файлы, скачанные curl'ом в `/tmp`, не видны Python-коду с Windows-путями и наоборот — все артефакты держать в `C:/Users/User/AppData/Local/Temp` или в project-дире, пути сверять. - `page.reload()` сразу после evaluate-fetch sign-in может оборвать session-cookie flow — ждать `wait_for_load_state` в try/except, не reload вслепую. - В репо НЕ пушить card.json/accounts.jsonl (gitignore), скрипты читать секреты из локальных файлов рядом (`pathlib.Path(__file__).parent`).