Skip to content

Extend instance init to allow core and chain abstraction params for b… #142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

ludowkm
Copy link

@ludowkm ludowkm commented Apr 3, 2025

…oth wallet and app kit usage

Description

There are some projects using both WalletKit and AppKit but the current implementation of constructor just allow to use only one of that kit.
So now i extend it to support optional params, static method to create required instance, then we are able to init both WalletKit and AppKit to use in single project.

@ludowkm
Copy link
Author

ludowkm commented Apr 3, 2025

@quetool Please help to review this PR, thank you!

@quetool
Copy link
Member

quetool commented Apr 4, 2025

Hello! Thanks, I'll take a look ASAP

@quetool
Copy link
Member

quetool commented May 7, 2025

Hello @ludowkm, sorry for the late response on this! Is still in my bucket list but sadly I just couldn't run the proper tests yet

@quetool
Copy link
Member

quetool commented May 7, 2025

Also, can you elaborate a bit more or share some code? Cause I am able to instantiate and initialize both AppKit and WalletKit

@ludowkm
Copy link
Author

ludowkm commented May 8, 2025

Hello @quetool , thank you for the response. There is a case that an app use both walletkit and appkit. Both require init() separately so when we call both init(), there is some issue which make both walletkit and appkit not work.
In this case, we just need to call init once from walletkit only then it's fine.
But to make both walletkit and appkit use same instance of reownSign and chainAbstraction, we will need to make walletkit and appkit's constructors allow reownSign and chainAbstraction. Then we can initialize both that params and use the same.
Like the below code snippet, both walletkit and appkit is init by single walletkit init.

final _core = ReownCore(
  projectId: BuildConfig.instance.walletConnectProjectID,
);

final reOwnSignInstance =
  ReownWalletKit.createReOwnSignInstance(core: _core, metadata: metadata);

_walletKit = ReownWalletKit(
  core: _core, metadata: metadata, overrideReOwnSign: reOwnSignInstance);
_appKit = ReownAppKit(
  core: _core, metadata: metadata, overrideReOwnSign: reOwnSignInstance);

await _walletKit.init();

@quetool
Copy link
Member

quetool commented May 8, 2025

Hello @ludowkm, here I set up a little example where I initialize both appkit and walletkit. Can you modify this file in order to repro your issue?

import 'package:flutter/material.dart';
import 'package:reown_appkit/reown_appkit.dart';
import 'package:reown_walletkit/reown_walletkit.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ReownAppKitModalTheme(
      child: MaterialApp(
        title: 'appkit_test_dapp',
        theme: ThemeData(
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
          useMaterial3: true,
        ),
        home: const HomePage(),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  late ReownAppKitModal _appKitModal;
  late ReownWalletKit _walletKit;

  @override
  void initState() {
    super.initState();
    _initializeAppKit();
    _initializeWalletKit();
  }

  Future<void> _initializeAppKit() async {
    try {
      _appKitModal = ReownAppKitModal(
        context: context,
        logLevel: LogLevel.all,
        projectId: '50f81661a58229027394e0a19e9db752',
        metadata: const PairingMetadata(
          name: 'appkit_test_dapp',
          description: 'appkit_test_dapp description',
          url: 'https://appkit_test_dapp.com',
          icons: ['https://appkit_test_dapp.com/logo.png'],
          redirect: Redirect(
            native: 'appkit_test_dapp://',
          ),
        ),
      );

      _appKitModal.appKit!.core.addLogListener(_appKitCoreListener);

      // More events at https://docs.reown.com/appkit/flutter/core/events
      _appKitModal.onModalConnect.subscribe(_onModalConnect);
      _appKitModal.onModalDisconnect.subscribe(_onModalDisconnect);

      await _appKitModal.init();
      setState(() {});
    } catch (e) {
      debugPrint('❌ $e');
    }
  }

  Future<void> _initializeWalletKit() async {
    try {
      // Create the ReownWalletKit instance
      _walletKit = ReownWalletKit(
        core: ReownCore(
          projectId: '50f81661a58229027394e0a19e9db752',
          logLevel: LogLevel.all,
        ),
        metadata: const PairingMetadata(
          name: 'appkit_test_wallet',
          description: 'appkit_test_wallet description',
          url: 'https://appkit_test_wallet.com',
          icons: ['https://appkit_test_wallet.com/logo.png'],
          redirect: Redirect(
            native: 'appkit_test_wallet://',
          ),
        ),
      );

      _walletKit.core.addLogListener(_walletKitCoreListener);

      // Setup our accounts
      _walletKit.registerAccount(
        chainId: 'eip155:1',
        accountAddress: '0xsa87dfs6gd45sa6d85f74s68a769d5f7g456',
      );

      await _walletKit.init();
      setState(() {});
    } catch (e) {
      debugPrint('❌ $e');
    }
  }

  void _walletKitCoreListener(String message) {
    print(message);
  }

  void _appKitCoreListener(String message) {
    print(message);
  }

  void _onModalConnect(ModalConnect? event) {
    setState(() {});
  }

  void _onModalDisconnect(ModalDisconnect? event) {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('appkit_test_dapp'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: Center(
        child: Column(
          children: [
            AppKitModalNetworkSelectButton(
              appKit: _appKitModal,
              context: context,
            ),
            AppKitModalConnectButton(
              appKit: _appKitModal,
              context: context,
            ),
            Visibility(
              visible: _appKitModal.isConnected,
              child: Column(
                children: [
                  AppKitModalAccountButton(
                    appKitModal: _appKitModal,
                    context: context,
                  ),
                  AppKitModalAddressButton(
                    appKitModal: _appKitModal,
                    onTap: () {},
                  ),
                  AppKitModalBalanceButton(
                    appKitModal: _appKitModal,
                    onTap: () {},
                  ),
                  ValueListenableBuilder<String>(
                    valueListenable: _appKitModal.balanceNotifier,
                    builder: (_, balance, __) {
                      return Text('My balance: $balance');
                    },
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

Versions used are:

reown_appkit: ^1.4.2+2
reown_walletkit: ^1.1.5

@ludowkm
Copy link
Author

ludowkm commented May 14, 2025

Hello @quetool, with this implementation, we create 2 instances of ReownCore with 2 Relay connections to be established. I think it's not best practice, is it?
Also with this 2 instances, we have to handle connection, sessions separately, what do you think about it ?

@ludowkm
Copy link
Author

ludowkm commented May 14, 2025

Also when we re-launch app and get active sessions from appkit or walletkit, it returns all sessions from both appkit and walletkit causes duplicated, while in runtime each kit returns each sessions only.

@quetool
Copy link
Member

quetool commented May 14, 2025

Can you share your implementation? I'd like to check it.

@ludowkm
Copy link
Author

ludowkm commented May 14, 2025

You can run the above your code snippet, my implementation is almost same.
You can run as a wallet app, connect to any dapp. Then close and re-launch app and try to get active session from appkit or walletkit. Both will return that session. In fact, it should return from walletkit only.

@ludowkm
Copy link
Author

ludowkm commented May 14, 2025

Beside that issue, i'm wondering why do we need to create 2 ReownCore instances as well as inside AppKit and WalletKit also has each own ReownSign instance. I thought we can use one ReownCore and ReownSign for both WalletKit and AppKit, don't it?

@quetool
Copy link
Member

quetool commented May 14, 2025

You may have a valid point, @ludowkm, allow me some time to re-evaluate the implications of this and I'll reach back! Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants