Guia completo para desenvolvedores que querem criar, validar e publicar addons HTTP compatíveis com o sistema V5.
manifestVersion: 1
contractVersion: addon-contract@1.x
hostAppVersion: 1.1.19
Quando o app inicia, o host de addons faz o bootstrap na seguinte ordem:
legacy_bridge (somente se fallback legado ativo)| Feature | Ordem de resolução | Fallback |
|---|---|---|
search |
Nativo → HTTP | Retorna vazio |
meta |
Nativo → HTTP | Retorna null |
stream |
Nativo → HTTP → Backend (se ativo) | Fallback desativado |
lyrics |
Nativo → HTTP | Sem fallback |
Para o addon ser aceito pelo runtime, o manifesto deve conter:
id, name, version, descriptionauthors — array não vazioappVersionRange — ex: >=1.0.0 <2.0.0platforms, features, typesdefaultTTL >= 0 e networkAllowlist não vaziacontractVersion com prefixo addon-contract@1.manifestVersion — não maior que 1entrypoints.type = http e baseUrl com HTTPS{
"manifestVersion": 1,
"id": "community_radio",
"name": "Community Radio",
"version": "1.0.0",
"description": "Addon de comunidade para busca/meta/stream.",
"authors": ["Alice"],
"contractVersion": "addon-contract@1.0.0",
"appVersionRange": ">=1.0.0 <2.0.0",
"platforms": ["android", "windows"],
"types": ["music"],
"features": ["search", "meta", "stream"],
"entrypoints": {
"type": "http",
"baseUrl": "https://addons.example.com"
},
"endpoints": {
"search": "/search",
"meta": "/meta",
"stream": "/stream"
},
"networkAllowlist": ["addons.example.com"],
"defaultTTL": 60
}
GET com query param q. Resposta aceita: array direto ou objeto com campo
items.
GET https://addons.example.com/search?q=despacito
GET com videoId e id (mesmo valor).
GET https://addons.example.com/meta?videoId=abc123&id=abc123
POST com Content-Type: application/json. Pode incluir
Authorization.
POST https://addons.example.com/stream
Content-Type: application/json
{
"id": "yt:abc123",
"quality": "low"
}
Resposta deve conter streams com ao menos uma fonte válida (url ou
manifestUrl).
GET com videoId. Retorna objeto com text ou lines
(sincronizado).
GET https://addons.example.com/lyrics?videoId=abc123
| Regra | Status |
|---|---|
| HTTPS obrigatório para manifesto e endpoints | Ativo |
| Network allowlist validada por request | Ativo |
| Bloqueio de rede privada/loopback | Ativo |
| Blocklist remota (impede install/exec) | Ativo |
| Timeout de 10s em todas as chamadas HTTP | Ativo |
| Sandbox por addon | Não impl. |
| Assinatura criptográfica | Não impl. |
| Eixo | Regra |
|---|---|
manifestVersion |
Aceita 1; rejeita >1 |
contractVersion |
Prefixo addon-contract@1. |
appVersionRange |
Parser por tokens e operadores básicos |
hostAppVersion |
1.1.19 |
Monte um JSON com todos os campos obrigatórios. Use o exemplo da seção 2 como template.
Crie um servidor HTTPS que responda nos caminhos declarados em endpoints.
# Na pasta "apis fluxo":
npm run schema:validate -- --type manifest --file seu-manifest.json
npm run schema:validate -- --type stream --key stream --file sua-resposta.json
flutter test test/addons/addon_manifest_validator_test.dart
flutter test test/addons/addon_manager_test.dart
Vá em Configurações → Gerenciar addons, cole a URL do manifesto e valide o fluxo completo.
Acesse a Addon Store e cadastre seu addon com a URL do manifesto.
| Sintoma | Causa | Solução |
|---|---|---|
Manifest URL deve usar HTTPS |
URL HTTP insegura | Publicar em https:// |
Entrypoint baseUrl deve usar https |
baseUrl sem HTTPS | Trocar para HTTPS |
Host ... não permitido |
Fora da allowlist | Adicionar em networkAllowlist |
Contract version incompatível |
Major ≠ 1 | Usar addon-contract@1.x |
Addon incompatível com versão do app |
Range incompatível | Ajustar appVersionRange |
| Timeout nas chamadas | Servidor lento (>10s) | Responder em <10s |