@getrail/react-native
v0.1.0
Published
Widget de conexión bancaria de Rail para React Native / Expo — modal nativo con el widget de Rail embebido (WebView). Sin navegador, credenciales aisladas.
Maintainers
Readme
@getrail/react-native
Widget de conexión bancaria de Rail para React Native / Expo. Abre el widget de Rail como una pantalla nativa (modal full-screen) — sin abrir un navegador y con las credenciales del usuario aisladas en el origen de Rail.
Diseño y trade-offs:
rail-api/docs/decisions/0048-sdk-nativo-expo-widget-webview-embebido.md· Plan:rail-api/docs/plans/0003-sdk-expo-rail-react-native.md.
Cómo funciona (modelo de seguridad)
El componente monta un react-native-webview que carga el widget web de Rail
(widget.rail.cl). El RUT y la clave se tipean dentro del WebView, en el
origen de Rail — el bundle JS de tu app nunca los ve. Tu app solo recibe al
final un exchange_token (et_*), inútil sin tu sk_. Es el mismo borde de
confianza que el iframe del widget web (modelo Plaid / Stripe).
Modelo de amenaza: cliente semi-confiable. La API pública no expone inyección de JS en el WebView.
Requisitos
- Depende de
react-native-webview(módulo nativo) → necesitás un dev build de Expo / bare RN. No corre en Expo Go.
Instalación
npm install @getrail/react-native react-native-webview
# Expo:
npx expo install react-native-webviewUso
import { RailConnect } from "@getrail/react-native";
<RailConnect
widgetToken={wt} // wt_* emitido por tu backend con la sk_
publicKey={pk} // pk_* de tu cliente
environment="live" // "live" | "sandbox"
onSuccess={(et) => {
// et_* → mandalo a tu backend para canjearlo por el link_id
exchangeOnBackend(et);
}}
onExit={() => setOpen(false)}
onEvent={(e) => track(e)} // opcional: eventos intermedios
onError={(err) => toast(err)}
/>Ver example/App.tsx para el flujo completo.
Backend (tu servidor, con la sk_)
El SDK no toca la sk_. Tu backend hace las dos llamadas server-to-server:
POST /v1/widget_tokens (Bearer rail_sk_*) → { id: "wt_..." }
POST /v1/exchange_tokens/:et (Bearer rail_sk_*) → { link_id, institution, status }Props
| Prop | Tipo | Default | |
|---|---|---|---|
| widgetToken | string | — | wt_* (requerido) |
| publicKey | string | — | pk_* (requerido) |
| onSuccess | (et: string) => void | — | recibe el et_* (requerido) |
| onExit | () => void | — | cierre / back Android (requerido) |
| visible | boolean | true | controla el modal |
| environment | "live" \| "sandbox" | "live" | ambiente del widget |
| baseUrl | string | — | override de la URL del widget (dev/LAN) |
| onEvent | (e) => void | — | eventos intermedios |
| onError | (e) => void | — | error fatal |
| style | ViewStyle | — | estilo del contenedor |
Desarrollo
npm install
npm run typecheck # tsc --noEmit
npm run build # tsup → dist/ (ESM + CJS + .d.ts)
npm run dev # tsup --watchStack: TypeScript strict + tsup (esbuild). react,
react-native y react-native-webview son peer deps (los pone la app
anfitriona). Única dependencia propia: zod (validación del contrato de eventos).
Estado
0.1.0 — flujo single-banco cableado end-to-end (SDK ↔ widget ↔ API).
- ✅
<RailConnect>: modal nativo + WebView + bridge de eventos (rail:*) + back Android + deep-links. - ✅ Transporte con el widget web (
rail-widget-webdetectaReactNativeWebView). - ⏳ Pendiente: app de ejemplo Expo corrible, recuperación de held-request + timeouts,
y eventos multi-banco (
rail.*, PRD 0007) en el schema.
Diseño y roadmap: ver ADR 0048 + plan 0003 en el repo rail-api.
