waas_sdk 2.2.0
waas_sdk: ^2.2.0 copied to clipboard
Flutter WebView com bridge WaaS para integrar a experiência WaaS (Wealth as a Service) em aplicativos nativos iOS e Android.
waas_sdk #
SDK Flutter para integrar a experiência WaaS (Wealth as a Service) da Warren em aplicativos iOS e Android via WebView com bridge nativo.
Instalação #
dependencies:
waas_sdk: ^1.0.0
Quick Start #
import 'package:waas_sdk/waas_sdk.dart';
// Abra a experiência WaaS passando o token de acesso e o tenant
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SafeArea(
bottom: false,
child: WaasView(
token: accessToken, // JWT obtido via /authenticate
tenant: 'seu-tenant', // Identificador do tenant
environment: WaasEnvironment.certification, // Ambiente do BFF
),
),
),
);
Autenticação #
O SDK espera um access token JWT obtido via client_credentials no endpoint de autenticação WaaS. O token é injetado automaticamente na WebView — o app host é responsável apenas por obtê-lo e passá-lo ao WaasView.
// Exemplo simplificado de obtenção do token
final response = await http.post(
Uri.parse('https://api.waas.warren.com.br/authenticate'),
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'grant_type=client_credentials&client_id=$clientId&client_secret=$clientSecret',
);
final accessToken = jsonDecode(response.body)['access_token'];
API #
WaasView #
Widget principal do SDK. Renderiza a experiência WaaS dentro de uma WebView gerenciada.
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
token |
String |
Sim | JWT de acesso obtido via autenticação WaaS. |
tenant |
String |
Sim | Slug do tenant (ex: sample). |
environment |
WaasEnvironment |
Sim | Ambiente do BFF: certification (staging) ou production. Em debug usa esta URL; BFF local só com --dart-define=WAAS_LOCAL_BFF=true. |
customerId |
String? |
Não | Customer ID na abertura. Injetado em window.__WAAS_CUSTOMER_ID__. |
controller |
WaasViewController? |
Não | Push de customerId / token em runtime via updateCustomerId / updateToken. |
loadingPageBackgroundColor |
Color? |
Não | Cor de fundo do overlay de carregamento. |
loaderWidget |
Widget? |
Não | Widget customizado exibido durante o loading. |
onActionRequired |
WaasActionRequiredCallback? |
Não | Callback quando a WebView pede integração nativa. Para requestCustomerBalance, retorne { balance: <num> } em BRL. |
WaasEnvironment #
Enum que seleciona a URL do BFF que a WebView carrega:
| Valor | URL padrão |
|---|---|
WaasEnvironment.certification |
Staging (waas-experience-staging.up.railway.app). |
WaasEnvironment.production |
Produção (default ainda igual à certificação até go-live). |
Ambiente ≠ Sandbox. O modo sandbox (dados mockados determinísticos) é ativado pelo token — basta passar um marcador
waas_sandbox_<tenant>_<profile>emtoken— e funciona em qualquerenvironment. Não existe valor de enum para sandbox. Ver ADR 0001.Debug e URL do BFF:
- Parceiro / staging em debug (padrão):
environmentdefine a URL (Railway).- Warren, BFF local (
pnpm dev): rode com--dart-define=WAAS_LOCAL_BFF=true(localhost:3000/10.0.2.2:3000no Android).
As URLs têm defaults embutidos, mas são sobrescrevíveis em build time
via --dart-define:
flutter run --dart-define=WAAS_LOCAL_BFF=true # BFF local (monorepo)
flutter build apk \
--dart-define=WAAS_CERTIFICATION_URL=https://cert.exemplo.com \
--dart-define=WAAS_PRODUCTION_URL=https://app.exemplo.com
WaasViewController #
Controla o WaasView a partir do app host. Use quando o customer ID ou o access token só ficam disponíveis depois que a WebView abriu — sem esperar o web chamar requestNewToken.
| Método | Descrição |
|---|---|
updateCustomerId(String) |
Injeta/atualiza window.__WAAS_CUSTOMER_ID__ e dispara customerIdReady. |
updateToken(String) |
Injeta/atualiza window.__WAAS_ACCESS_TOKEN__ e dispara tokenReady. |
isAttached |
true quando ligado a um WaasView montado. |
final waasController = WaasViewController();
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => WaasView(
token: token,
tenant: 'plenapay',
environment: WaasEnvironment.certification,
controller: waasController,
),
),
);
// Após resolver o customer ID no app nativo (login, seleção de conta, etc.):
waasController.updateCustomerId(customerId);
WaaSChannel #
Bridge de comunicação entre a WebView e o app nativo.
injectToken(String token)— Injeta o token na WebView e dispara o eventotokenReady.injectCustomerId(String customerId)— Uso interno do SDK. Apps host devem preferirWaasView.customerIdouWaasViewController.updateCustomerId.injectBridgeScript()— Inicializa os listeners de mensagens na WebView.
WaaSMessageHandler #
Handler de mensagens recebidas da WebView via bridge. Processa comandos como closeWebView (fecha a tela e retorna ao app host).
extractFormattedClientId(String? token) #
Utilitário que extrai e formata o client_id do payload JWT (ex: banco-rendimento.zion → bancorendimento).
Bridge — Protocolo de Mensagens #
A comunicação entre a WebView e o app nativo segue o protocolo request/response:
// Request (WebView → App)
{
"id": "uuid",
"type": "request",
"method": "closeWebView",
"meta": { "tenantId": "sample", "bridgeVersion": "1.0.0" }
}
// Response (App → WebView)
{
"id": "uuid",
"origin": "sdk",
"type": "response",
"result": { "success": true },
"meta": { "bridgeVersion": "1.0.0", "tenantId": "sample" }
}
Métodos suportados #
| Método | Descrição |
|---|---|
closeWebView |
Fecha a WebView e retorna ao app host via Navigator.pop(). |
addMoney |
Fecha a WebView e chama onActionRequired('addMoney') (cash-in nativo). |
createAccount |
Fecha a WebView e chama onActionRequired('createAccount') (criação de conta Warren). |
investmentDone |
Chama onActionRequired('investmentDone') sem fechar a WebView. |
redemptionDone |
Chama onActionRequired('redemptionDone') sem fechar a WebView. |
requestCustomerBalance |
Aguarda onActionRequired retornar { balance }, injeta na WebView e responde sem fechar. |
requestNewToken |
Aguarda onActionRequired retornar { token }, injeta na WebView e dispara tokenReady sem fechar. |
WaasView(
token: token,
tenant: 'plenapay',
environment: WaasEnvironment.certification,
onActionRequired: (payload) async {
switch (payload.action) {
case WaasBridgeActions.addMoney:
// abrir fluxo de cash-in
break;
case WaasBridgeActions.investmentDone:
final amount = payload.params['investedAmount']; // num (BRL)
final portfolioId = payload.params['portfolioId']; // String
// atualizar estado em background
break;
case WaasBridgeActions.redemptionDone:
final amount = payload.params['redeemedAmount']; // num (BRL)
final portfolioId = payload.params['portfolioId']; // String
// atualizar estado em background
break;
case WaasBridgeActions.requestCustomerBalance:
final balance = await bankingService.fetchAvailableBalance();
return {WaasActionRequiredKeys.balance: balance};
case WaasBridgeActions.requestNewToken:
final newToken = await authService.refreshAccessToken();
return {WaasActionRequiredKeys.token: newToken};
}
return null;
},
)
Exemplo completo #
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:waas_sdk/waas_sdk.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(home: const HomePage());
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
Future<String> _fetchToken() async {
final uri = Uri.parse('https://api.waas.warren.com.br/authenticate');
final client = HttpClient();
final request = await client.postUrl(uri);
request.headers.set('Content-Type', 'application/x-www-form-urlencoded');
request.write('grant_type=client_credentials'
'&client_id=SEU_CLIENT_ID'
'&client_secret=SEU_CLIENT_SECRET');
final response = await request.close();
final body = await response.transform(utf8.decoder).join();
client.close(force: true);
return jsonDecode(body)['access_token'];
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Meu App')),
floatingActionButton: FloatingActionButton(
onPressed: () async {
final token = await _fetchToken();
if (!context.mounted) return;
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => SafeArea(
bottom: false,
child: WaasView(
token: token,
tenant: 'seu-tenant',
environment: WaasEnvironment.certification,
loadingPageBackgroundColor: const Color(0xFF00463C),
),
),
),
);
},
child: const Icon(Icons.attach_money),
),
);
}
}
Para um exemplo com cache de token e
.env, veja o waas_playground no repositório.
Plataformas #
| Plataforma | Suporte |
|---|---|
| Android | ✅ |
| iOS | ✅ |
| Web | ❌ (usa dart:io) |
Requisitos #
- Flutter SDK
>=3.0.0 <4.0.0 webview_flutter: ^4.13.0
Licença #
MIT — Copyright (c) 2025 Warren Brasil