Boxo SDK for Flutter

A Flutter plugin to integrate Boxo miniapps on iOS and Android.

Installation

Add the dependency to your pubspec.yaml:

dependencies:
  appboxo_sdk: ^latest

Import in your Dart code:

import 'package:appboxo_sdk/boxo.dart';

Quick start

Initialize the SDK as early as possible (e.g., in main()), then open a miniapp by id.

import 'package:flutter/material.dart';
import 'package:appboxo_sdk/boxo.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Boxo.setConfig(
    'YOUR_CLIENT_ID',
    sandboxMode: false,
    theme: 'system', // 'light' | 'dark' | 'system'
    language: 'en',
  );
  runApp(const MyApp());
}

Open a miniapp:

Boxo.openMiniapp(
  'app_id',
  data: {'foo': 'bar'}, // optional, passed to the miniapp
  theme: 'light',       // optional: 'light' | 'dark' | 'system'
  extraUrlParams: {'utm_source': 'hostapp'},
  urlSuffix: 'some/path',
  colors: {
    'primary_color': '#0A84FF',
    'secondary_color': '#30D158',
    'tertiary_color': '#FF9F0A',
  },
  enableSplash: true,
  saveState: false,
  pageAnimation: 'BOTTOM_TO_TOP', // see list below
);

Hide/close and logout:

Boxo.hideMiniapps();      // hide opened miniapps
Boxo.closeMiniapp('app_id');  // close miniapp by id
Boxo.logout();            // clear all Boxo data on host logout

Events

Custom events:

final sub = Boxo.customEvents().listen((CustomEvent event) {
  if (event.appId == 'miniapp_id' && event.type == 'some_event') {
    // Respond and optionally send a reply back to the miniapp
    event.payload = {'status': 'success'};
    Boxo.sendEvent(event);
  }
});

Payment events:

Boxo.paymentEvents().listen((PaymentEvent event) {
  // Provide payment status back to the miniapp
  event.status = 'success'; // or 'failed'
  Boxo.sendPaymentEvent(event);
});

Miniapps catalog stream and fetch:

Boxo.miniapps().listen((MiniappsResult result) {
  if (result.error != null) {
    // handle error
  } else {
    final apps = result.miniapps; // List<MiniappData>
  }
});

Boxo.getMiniapps(); // triggers retrieval and emits into Boxo.miniapps()

Lifecycle hooks

Subscribe to miniapp lifecycle hooks; the function returns a disposer you should call to unsubscribe.

final dispose = await Boxo.lifecycleHooksListener(
  onAuth: (appId) {},
  onLaunch: (appId) {},
  onResume: (appId) {},
  onPause: (appId) {},
  onClose: (appId) {},
  onError: (appId, error) {},
  onUserInteraction: (appId) {},
);

// later
await dispose();

Configuration reference

Boxo.setConfig(String clientId, { …options })

  • clientId: required Boxo client id
  • userId: optional user id string
  • sandboxMode: bool (default false)
  • theme: 'light' | 'dark' | 'system' (default 'system')
  • language: ISO code, e.g. 'en'
  • isDebug: bool
  • showPermissionsPage: bool
  • showClearCache: bool
  • showAboutPage: bool
  • splashScreenOptions: map with optional keys
    • light_progress_indicator, light_progress_track
    • dark_progress_indicator, dark_progress_track
    • light_background, dark_background

Boxo.openMiniapp(String appId, { …options })

  • data: Map<String, dynamic>
  • theme: 'light' | 'dark' | 'system'
  • extraUrlParams: Map<String, String>
  • urlSuffix: String
  • colors: Map with keys 'primary_color' | 'secondary_color' | 'tertiary_color'
  • enableSplash: bool
  • saveState: bool
  • pageAnimation: one of
    • 'BOTTOM_TO_TOP' | 'TOP_TO_BOTTOM' | 'LEFT_TO_RIGHT' | 'RIGHT_TO_LEFT' | 'FADE_IN'

Other methods

  • Boxo.closeMiniapp(String appId)
  • Boxo.hideMiniapps()
  • Boxo.logout()
  • Boxo.setAuthCode(String appId, String authCode)
  • Boxo.setAuthTokens(String appId, Map<String, String> tokens)
  • Boxo.customEvents() -> Stream
  • Boxo.paymentEvents() -> Stream
  • Boxo.miniapps() -> Stream
  • Boxo.lifecycleHooksListener({...}) -> Future

Android setup

You must use FlutterFragmentActivity as your base Activity so the SDK can present miniapps via fragments.

  • Change your MainActivity to extend FlutterFragmentActivity (not FlutterActivity).
  • Minimum supported SDK: 21 (Android 5.0).

Kotlin:

package your.package.name

import android.os.Bundle
import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity : FlutterFragmentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
  }
}

iOS setup

  • Minimum iOS version: 10.0 (per podspec).
  • The plugin depends on BoxoSDK (CocoaPods). Run pod install in your iOS folder after adding the dependency.

If you see linking issues after adding the plugin, clean and reinstall pods:

cd ios && pod repo update && pod install

Troubleshooting

  • Android crash or error mentioning FragmentActivity or cannot cast Activity:
    • Ensure MainActivity extends FlutterFragmentActivity.
  • Miniapp not opening or blank:
    • Verify you called Boxo.setConfig('YOUR_CLIENT_ID', ...) before opening a miniapp.
  • Payment/custom events not received:
    • Confirm you subscribe to the corresponding stream before opening the miniapp.

Libraries

appboxo_sdk
boxo