Skip to content

felipeosmar/OpenClaw_MobileApp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 

Repository files navigation

OpenClaw MobileApp (Quasar Node)

App React Native que transforma qualquer celular Android num node completo do OpenClaw, com acesso a todos os recursos de hardware do dispositivo.

🎯 Objetivo

Ter controle total sobre o código do node mobile, sem depender de apps de terceiros. O app implementa o protocolo WebSocket do OpenClaw Gateway e expõe todos os recursos do celular para o agente.

✨ Recursos

Recurso Comandos Biblioteca
📸 Câmera camera.snap, camera.clip react-native-camera-kit
📍 GPS location.get react-native-geolocation
🎤 Microfone audio.record react-native-audio-api
🔊 Alto-falante audio.play, audio.tts react-native-tts + expo-av
🔵 Bluetooth bluetooth.scan, bluetooth.connect, bluetooth.send react-native-ble-plx
📡 NFC nfc.read, nfc.write react-native-nfc-manager
🧭 Sensores sensors.read, sensors.subscribe react-native-sensors
📱 SMS sms.send Native bridge
📂 Filesystem fs.read, fs.write, fs.list react-native-fs
💻 Sistema system.run, system.info Native bridge

🏗️ Arquitetura

┌─────────────────────────────────────┐
│         OpenClaw Gateway            │
│      (DeskFelipeDell :18789)        │
└──────────────┬──────────────────────┘
               │ WebSocket (JSON frames)
               │
┌──────────────▼──────────────────────┐
│      App React Native (Android)     │
│                                     │
│  ┌───────────────────────────────┐  │
│  │    Protocol Layer (TS)        │  │
│  │  - WebSocket client           │  │
│  │  - Handshake + auth + pairing │  │
│  │  - Request/Response/Event     │  │
│  │  - Reconnect automático       │  │
│  └──────────────┬────────────────┘  │
│                 │                    │
│  ┌──────────────▼────────────────┐  │
│  │    Command Router (TS)        │  │
│  │  - Recebe node.invoke         │  │
│  │  - Despacha pro handler certo │  │
│  └──────────────┬────────────────┘  │
│                 │                    │
│  ┌──────────────▼────────────────┐  │
│  │    Hardware Handlers          │  │
│  │  camera.*    → CameraKit      │  │
│  │  location.*  → Geolocation    │  │
│  │  bluetooth.* → BLE-PLX        │  │
│  │  audio.*     → Audio API      │  │
│  │  sensors.*   → RN Sensors     │  │
│  │  nfc.*       → NFC Manager    │  │
│  │  sms.*       → Native bridge  │  │
│  │  fs.*        → RN-FS          │  │
│  │  system.*    → Shell/Info     │  │
│  └───────────────────────────────┘  │
│                                     │
│  ┌───────────────────────────────┐  │
│  │  Foreground Service (Kotlin)  │  │
│  │  - Mantém app vivo            │  │
│  │  - Notificação persistente    │  │
│  │  - Wake lock parcial          │  │
│  └───────────────────────────────┘  │
└─────────────────────────────────────┘

Três camadas

  1. Protocol Layer — Implementa o protocolo OpenClaw (connect challenge, handshake com role: "node", framing req/res/event, auth com device token, reconnect com backoff exponencial)

  2. Command Router — Quando o Gateway envia node.invoke, o router despacha pro handler correspondente

  3. Hardware Handlers — Cada módulo encapsula uma lib RN e traduz entre o formato OpenClaw e a API nativa

📡 Protocolo OpenClaw

Handshake

  1. App conecta no WebSocket ws://<gateway>:18789
  2. Recebe connect.challenge com nonce + ts
  3. Responde com connect:
{
  "type": "req",
  "id": "...",
  "method": "connect",
  "params": {
    "minProtocol": 3,
    "maxProtocol": 3,
    "client": {
      "id": "quasar-node-android",
      "version": "0.1.0",
      "platform": "android",
      "mode": "node"
    },
    "role": "node",
    "caps": [
      "camera", "location", "audio", "bluetooth",
      "nfc", "sensors", "sms", "filesystem", "system"
    ],
    "commands": [
      "camera.snap", "camera.clip",
      "location.get",
      "audio.record", "audio.play", "audio.tts",
      "bluetooth.scan", "bluetooth.connect", "bluetooth.send",
      "nfc.read", "nfc.write",
      "sensors.read", "sensors.subscribe",
      "sms.send",
      "fs.read", "fs.write", "fs.list",
      "system.run", "system.info"
    ],
    "device": {
      "id": "<fingerprint>",
      "publicKey": "...",
      "signature": "<nonce assinado>",
      "signedAt": 1737264000000,
      "nonce": "..."
    }
  }
}
  1. Recebe hello-ok com deviceToken (persiste em AsyncStorage)
  2. Nas reconexões seguintes, usa o deviceToken salvo

Reconexão automática

  • Backoff exponencial: 1s → 2s → 4s → 8s → max 30s
  • Detecta rede via NetInfo, reconecta ao voltar online
  • Heartbeat/ping a cada 15s (conforme tickIntervalMs do Gateway)

Framing

Gateway → App:  { type: "req", id: "abc", method: "node.invoke",
                   params: { command: "camera.snap", ... } }

App → Gateway:  { type: "res", id: "abc", ok: true,
                   payload: { format: "jpg", base64: "..." } }

Em caso de erro:

{ "type": "res", "id": "abc", "ok": false,
  "error": { "code": "CAMERA_UNAVAILABLE", "message": "..." } }

🎯 Comandos Detalhados

camera.snap

Tira foto (front/back/both), retorna { format: "jpg", base64 }

camera.clip

Grava vídeo curto (até 60s), retorna { format: "mp4", base64 }

location.get

Retorna { lat, lon, accuracy, timestamp }, aceita accuracy: "coarse"|"balanced"|"precise"

audio.record

Grava áudio do microfone por X segundos, retorna { format: "mp3", base64 }

audio.play

Recebe base64 de áudio e toca no alto-falante

audio.tts

Recebe texto, sintetiza com TTS do Android e toca

bluetooth.scan

Escaneia dispositivos BLE, retorna [{ name, mac, rssi }]

bluetooth.connect

Conecta num device por MAC

bluetooth.send

Envia dados pra um device conectado

nfc.read / nfc.write

Lê/escreve tags NFC

sensors.read

Leitura instantânea de { accelerometer, gyroscope, magnetometer, barometer, light, proximity }

sensors.subscribe

Stream de dados por X segundos com intervalo configurável

sms.send

Envia SMS para { to, message }

fs.read / fs.write / fs.list

Acesso ao sistema de arquivos (scoped ao storage do app)

system.run

Executa comando shell (limitado no Android)

system.info

Retorna { model, brand, os, battery, network, storage }

🔋 Background & Foreground Service

  • Foreground Service com notificação persistente ("Quasar Node • Conectado ao Gateway")
  • Tipo: FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE
  • Wake Lock parcial para manter CPU ativa
  • Boot Receiver para auto-start após reiniciar o celular
  • Network Callback para reconectar automaticamente ao mudar de rede
  • Solicita desativação de otimização de bateria na primeira execução
Boot → BroadcastReceiver → Foreground Service → WebSocket → Gateway

📁 Estrutura do Projeto

quasar-node/
├── android/                          # Código nativo Android
│   └── app/src/main/java/.../
│       ├── NodeForegroundService.kt  # Foreground service
│       ├── BootReceiver.kt           # Auto-start no boot
│       └── NativeBridgeModule.kt     # Bridges extras
│
├── src/
│   ├── protocol/
│   │   ├── client.ts                 # WebSocket client + reconnect
│   │   ├── handshake.ts              # Challenge, connect, auth
│   │   ├── framing.ts                # Req/Res/Event types
│   │   ├── crypto.ts                 # Keypair, assinatura de nonce
│   │   └── storage.ts                # Persistência do deviceToken
│   │
│   ├── router/
│   │   └── commandRouter.ts          # Despacha node.invoke → handler
│   │
│   ├── handlers/
│   │   ├── camera.ts                 # camera.snap, camera.clip
│   │   ├── location.ts               # location.get
│   │   ├── audio.ts                  # audio.record, audio.play, audio.tts
│   │   ├── bluetooth.ts              # bluetooth.scan, connect, send
│   │   ├── nfc.ts                    # nfc.read, nfc.write
│   │   ├── sensors.ts                # sensors.read, sensors.subscribe
│   │   ├── sms.ts                    # sms.send
│   │   ├── filesystem.ts             # fs.read, fs.write, fs.list
│   │   └── system.ts                 # system.run, system.info
│   │
│   ├── services/
│   │   ├── foreground.ts             # Interface JS pro foreground service
│   │   └── network.ts                # Monitoramento de conectividade
│   │
│   ├── ui/
│   │   ├── App.tsx                   # Tela principal
│   │   ├── StatusScreen.tsx          # Status da conexão + logs
│   │   └── SetupScreen.tsx           # Config inicial (host:port)
│   │
│   └── config/
│       └── constants.ts              # Versão, defaults, timeouts
│
├── package.json
├── tsconfig.json
├── babel.config.js
└── README.md

🗓️ Plano de Implementação

Sprint 0 — Fundação (1-2 dias)

  • Criar projeto React Native + TypeScript
  • Foreground Service nativo (Kotlin)
  • Boot receiver
  • UI mínima: setup + status

Sprint 1 — Protocolo OpenClaw (2-3 dias)

  • WebSocket client com reconnect + backoff
  • Handshake completo: challenge → connect → hello-ok
  • Keypair + assinatura de nonce
  • Persistência do deviceToken
  • Command router

Sprint 2 — Câmera + Localização (1-2 dias)

  • camera.snap e camera.clip
  • location.get

Sprint 3 — Áudio (2 dias)

  • audio.record, audio.play, audio.tts

Sprint 4 — Bluetooth (2-3 dias)

  • bluetooth.scan, bluetooth.connect, bluetooth.send

Sprint 5 — Sensores + Sistema (1 dia)

  • sensors.read, sensors.subscribe
  • system.info, system.run

Sprint 6 — NFC + SMS + Filesystem (1-2 dias)

  • nfc.read, nfc.write
  • sms.send
  • fs.read, fs.write, fs.list

Sprint 7 — Polish + Estabilidade (2 dias)

  • Testes de longa duração (24h+)
  • Edge cases e tratamento de erros
  • Otimização de bateria por OEM
  • Documentação completa

Total estimado: 12-17 dias

📝 Decision Log

# Decisão Alternativas Motivo
1 React Native (não Flutter, não nativo) Flutter, Kotlin puro, C/C++ Preferência do dev, ecossistema JS/TS, velocidade
2 Compatível com protocolo OpenClaw API própria independente Integração nativa com Gateway, node real
3 RN + libs existentes Expo, tudo nativo, C++ Equilíbrio esforço/controle, 90% coberto
4 Permissões tudo-ou-nada Granular, granular com atalho Simplicidade, público confiável
5 Background obrigatório (foreground service) Foreground only, fase 2 Node always-on é requisito core
6 Foco Android Android + iOS Reduz escopo, dispositivos disponíveis
7 UI mínima (2 telas) UI elaborada, zero UI Setup + status, nada mais

🚫 Não-objetivos (por enquanto)

  • iOS (pode vir depois)
  • UI elaborada
  • Compatibilidade com o app oficial do OpenClaw

⚠️ Questões em Aberto

  • Alguns recursos em background (câmera, microfone) têm restrições no Android 12+ — pode ter limitações
  • Bluetooth e NFC em background dependem do tipo de foreground service declarado

📄 Licença

MIT

About

React Native app that turns any Android phone into a full OpenClaw node with access to camera, microphone, Bluetooth, GPS, NFC, sensors and more

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors