Chrome Extension (Manifest V3) que sincroniza automaticamente posições e movimentações de FIIs (Fundos de Investimento Imobiliário) entre Genial Investimentos e Investidor10.
Quando comecei a investir em FIIs pela Genial Investimentos, percebi que a Investidor10 oferece uma visão de carteira muito mais completa: métricas consolidadas, histórico estruturado e acompanhamento detalhado dos ativos.
O desafio era operacional: cada compra e venda precisava ser lançada manualmente para manter as duas plataformas alinhadas.
Desenvolvi uma Chrome Extension (Manifest V3) em React + Vite que:
- Extrai tokens e cookies via Content Scripts
- Consome APIs autenticadas das plataformas
- Implementa sincronização idempotente (zero duplicidade)
- Processa jobs em background com controle de progresso
- Persiste estado mesmo com a extensão fechada
Ela replica automaticamente as operações executadas na corretora, mantendo a carteira da Investidor10 sempre atualizada.
- React + Vite
- Chrome Extension API (Manifest V3)
- Service Workers
- Chrome Storage
- CryptoJS
A Genial utiliza tokens criptografados com AES. Foi necessário reproduzir a lógica de descriptografia do front-end para extrair o token válido.
Cada operação é identificada por uma chave composta:
ticker | quantidade | preço | data | tipo
Garantindo sincronização determinística e sem duplicatas.
Controle de chamadas para evitar bloqueios por excesso de requisições.
O Content Script precisa aguardar o carregamento do CryptoJS no contexto da página para que a descriptografia funcione corretamente.
- Carteira sempre sincronizada
- Visão mais completa dos FIIs
- Eliminação de retrabalho manual
- Processo automatizado e confiável
- Extração Automática - Captura tokens e cookies das plataformas via Content Scripts
- Sincronização Idempotente - Evita duplicações usando chave composta
- Visualização de Progresso - Barra de progresso em tempo real durante sincronização
- Histórico de Sincronização - Persistência de estado e histórico de operações
- Exportação - Exportação de dados para JSON/CSV
- Sistema de Logs - Níveis configuráveis (DEBUG, INFO, WARN, ERROR)
- Tratamento de Erros - Classificação de erros (Network, Validation, API, Duplicate)
- Jobs em Background - Processamento assíncrono com controle de progresso
- Node.js 18+
- npm ou yarn
- Google Chrome
# Clonar ou navegar até o projeto
cd extensao
# Instalar dependências
npm install
# Build da extensão
npm run build- Build da extensão:
npm run build - Abra
chrome://extensions/ - Habilite "Modo de desenvolvedor"
- Clique em "Carregar sem compactação"
- Selecione a pasta
dist/
- Faça login na Genial e no Investidor10 em abas do Chrome
- Abra o popup da extensão
- Clique em "Atualizar" para carregar estado/config
- Defina o Wallet ID e salve a configuração
- Execute:
- "Posições Genial" - busca movimentações
- "FIIs mapeados" - busca FIIs suportados
- "Carteira FIIs" - busca entradas existentes
- "Sincronizar ausentes" - sincroniza movimentações
src/
├── manifest.js # Configuração Manifest V3
├── App.jsx # Componente principal React
├── main.jsx # Ponto de entrada
├── styles.css # Estilos da extensão
├── extension/
│ ├── background.js # Service worker (mensagens, estado, jobs)
│ └── content.js # Content scripts (extrair tokens/cookies)
├── components/ # Componentes UI React
│ ├── ActionButtons.jsx # Botões de ação de sincronização
│ ├── Button.jsx # Componente de botão reutilizável
│ ├── ConfigSection.jsx # Painel de configurações
│ ├── ConfirmModal.jsx # Diálogo de confirmação
│ ├── ErrorModal.jsx # Modal de erro
│ ├── Modal.jsx # Wrapper base de modal
│ ├── ProgressBar.jsx # Visualização de progresso
│ ├── ResultSection.jsx # Exibição de resultados
│ ├── StatsCards.jsx # Cards de estatísticas
│ ├── StatusBadge.jsx # Indicador de status de auth
│ ├── SuccessModal.jsx # Modal de sucesso
│ ├── Toast.jsx # Notificações toast
│ └── WalletSelect.jsx # Seleção de carteira
└── services/
├── constants.js # Endpoints, configs, tipos de mensagem
├── storage.js # Wrappers Chrome Storage
├── http.js # Utilitários fetch com retry
├── time.js # Utilitários de data
├── runtime.js # Helpers de message passing
├── logger.js # Serviço de logging com níveis
├── errors.js # Classes de erro e parsing
├── genialApi.js # API Genial (posições)
├── genialMovements.js # Movimentações Genial com cache
├── investidor10Api.js # API Investidor10 (carteira, FIIs, entradas)
├── sync.js # Lógica de sincronização idempotente
└── export.js # Exportação JSON/CSV
O token é armazenado no localStorage criptografado com AES usando a chave @genial-web-app-v1.
Fluxo de extração:
- Ler
persist:sessionStoragedo localStorage - Fazer parse do JSON
loginData - Descriptografar com
CryptoJS.AES.decrypt(data, "@genial-web-app-v1") - Extrair
tokenDeAcesso
Autenticação via cookies (user_id, laravel_session, XSRF-TOKEN). Os cookies são atualizados automaticamente a cada 60s pelo content script.
O service worker gerencia jobs assíncronos com persistência de estado:
- movements job: Busca movimentações da Genial com tracking de progresso
- sync job: Sincroniza movimentações para entradas na carteira do Investidor10
Estado do job inclui: id, tipo, running, status, progress, error, timestamps.
/api//v4/posicao/renda-variavel- Posições/api//v1/rentabilidade/movimentacoes?identificador={TICKER}- Movimentações
/wallet-api-proxy/wallet-app/search-ticker/Fii- FIIs mapeados/wallet-api-proxy/wallet-app/entries/{WALLET_ID}/{PAGE}- Entradas da carteira/wallet-api-proxy/wallet-app/entry/store- Registrar entrada (POST)
| Campo | Descrição | Padrão |
|---|---|---|
genialAutoExtract |
Extração automática do token Genial | true |
investidor10AutoExtract |
Extração automática dos cookies I10 | true |
requestDelay |
Delay entre requests (ms) | 500 |
maxRetries |
Tentativas em caso de falha | 2 |
timeout |
Timeout de requisições (ms) | 8000 |
logLevel |
Nível de logging | INFO |
npm install # Instalar dependências
npm run build # Build da extensão (dist/)
npm run dev # Desenvolvimento com HMR
npm run preview # Visualizar build- Usar
chrome.storage.localpara dados persistentes (não localStorage) - Mínimo de 500ms de delay entre requests para evitar rate limiting
- Content scripts executam em
document_end - CryptoJS deve carregar antes do content script nas páginas da Genial
- Tokens/cookies expiram após 24 horas
- Estado do job persiste entre reinicializações da extensão
import logger from "./services/logger";
logger.debug("Mensagem de debug", { contexto });
logger.info("Mensagem info", { dados });
logger.warn("Aviso", { advertencia });
logger.error("Erro", { erro });import { parseError, getErrorMessage } from "./services/errors";
try {
// operação
} catch (error) {
const parsed = parseError(error);
const message = getErrorMessage(parsed.type);
}- React 18
- Vite 5
- Chrome Extension Manifest V3
- CryptoJS (criptografia)
- @crxjs/vite-plugin
MIT