polkawallet SDK for integrating substrate-based blockchain as a plugin.

Building a polkawallet_plugin dart package.

1. Create your plugin repo

create a dart package

flutter create --template=package polkwalllet_plugin_acala
cd polkwalllet_plugin_acala/

add dependencies in pubspec.yaml

  polkawallet_sdk: ^0.1.2

and install the dependencies.

flutter pub get

2. Build your polkadot-js wrapper

The App use a polkadot-js/api instance running in a hidden webView to connect to remote node.


3. Implement your plugin class

Modify the plugin entry file(eg. polkwalllet_plugin_acala.dart), create a PluginFoo class extending PolkawalletPlugin:

class PluginAcala extends PolkawalletPlugin {
  /// define your own plugin

3.1. override PolkawalletPlugin.basic

  final basic = PluginBasicData(
    name: 'acala',
    ss58: 42,
    primaryColor: Colors.deepPurple,
    // The `bg.png` will be displayed as texture on a block with theme color,
    // so it should have a transparent or dark background color.
    backgroundImage: AssetImage('packages/polkawallet_plugin_acala/assets/images/bg.png'),
    // The `logo_gray.png` should have a gray color `#9e9e9e`.
    iconDisabled: Image.asset(
    isTestNet: false,

3.2. override PolkawalletPlugin.tokenIcons

Define the icon widgets so the Polkawallet App can display tokens of your para-chain with token icons.

  final Map<String, Widget> tokenIcons = {
    'KSM': Image.asset(
    'DOT': Image.asset(

3.3. override PolkawalletPlugin.nodeList

const node_list = [
    'name': 'Mandala TC5 Node 1 (Hosted by OnFinality)',
    'ss58': 42,
    'endpoint': 'wss://',
  List<NetworkParams> get nodeList {
    return => NetworkParams.fromJson(e)).toList();

3.4. override PolkawalletPlugin.getNavItems(BuildContext, Keyring)

Define your custom navigation-item in BottomNavigationBar of Polkawallet App. The HomeNavItem.content is the page content widget displayed while your navItem was selected.

  List<HomeNavItem> getNavItems(BuildContext context, Keyring keyring) {
    return [
        text: 'Acala',
        icon: SvgPicture.asset(
          color: Theme.of(context).disabledColor,
        iconActive: SvgPicture.asset(
        content: AcalaEntry(this, keyring),

3.5. override PolkawalletPlugin.getRoutes(Keyring)

Define navigation route for your plugin pages.

  Map<String, WidgetBuilder> getRoutes(Keyring keyring) {
    return {
      TxConfirmPage.route: (_) =>
          TxConfirmPage(this, keyring, _service.getPassword),
      CurrencySelectPage.route: (_) => CurrencySelectPage(this),
      AccountQrCodePage.route: (_) => AccountQrCodePage(this, keyring),

      TokenDetailPage.route: (_) => TokenDetailPage(this, keyring),
      TransferPage.route: (_) => TransferPage(this, keyring),

      // other pages
      // ...

3.6. override PolkawalletPlugin.loadJSCode() method

Load the polkadot-js/api wrapper you built in step 2.

  Future<String> loadJSCode() => rootBundle.loadString(

3.7. override plugin life-circle methods

  • onWillStart(), you may want to prepare your plugin state data here.
  • onStarted(), remote node connected, you may fetch data from network.
  • onAccountChanged(), user just changed account, you may clear cache of the prev account and query data for new account.


4. Fetch data and build pages

We use as the App state management tool. So the directories in a plugin looks like this:

__ lib
    |__ pages (the UI)
    |__ store (the MobX store)
    |__ service (the Actions fired by UI to mutate the store)
    |__ ...

To query data through PolkawalletPlugin.sdk.api:


  Future<List> queryReferendums() async {
    final data = await;;
    return data;

To query data by calling JS directly:


  Future<void> updateBestNumber() async {
    final int bestNumber = await api.service.webView

While we set data to MobX store, the MobX Observer Flutter Widget will rebuild with new data.

5. Run your pages in example/ app

You may want to run an example app in dev while building your plugin pages.

See the kusama/polkadot or acala or laminar examples: