Flutter Solana钱包管理插件solana_wallets_flutter的使用

发布于 1周前 作者 phonegap100 来自 Flutter

Flutter Solana钱包管理插件solana_wallets_flutter的使用

插件介绍

此插件允许在浏览器中连接用户的Solana钱包,支持如phantom、solflare、sollet等。它封装了solanas官方的@solana/wallet-adapter-wallets库,并提供了访问所有版本0.19.15中的钱包适配器的功能。如果需要其他版本,请参阅tool/README.md以自行构建。

理论知识

在Flutter Web中,可以使用js包来操作JavaScript对象,这正是此插件所依赖的。我们还可以通过js包调用JavaScript函数。此外,存在一些名为Object类型的对象,在这些对象“链接到”或“代理”一个JavaScript对象。我们可以使用js包调用函数并使用“代理”的的对象作为参数。这样JavaScript函数就可以访问到“真实的”对象。上述内容中提到的“将钱包适配器对象传递给JavaScript”意味着就是这个意思。

UI

插件solana_wallets_flutter_ui包含用于显示用户选择首选钱包对话框的函数。您可以不使用它并创建自己的对话框。 example.webp

使用方法

以下是使用此插件的通常步骤:

  1. 在项目的主要方法中调用(但不要等待)initSolanaWallets来自solana_wallets_flutter库。
  2. 调用getWalletAdaptersWhenInitalized来自solana_wallets_flutter库获取适配器列表,并可选地过滤返回的列表以排除您不想在您的DApp中支持的适配器。
  3. 通过solana_wallets_flutter_ui中的showWalletSelectDialog函数与(过滤后的)适配器列表一起让用户从对话框中选择一个钱包,或者构建自己的系统让用户决定要使用的钱包。
  4. 您现在有了用户想要使用的BaseWalletAdapter,调用其上的addListener方法以监视walletState。重要的是:如果您完成了适配器的操作,请调用removeListener,否则可能会遇到性能问题!
  5. 调用connect方法,用户的浏览器将打开钱包扩展程序或弹出窗口,用户需要接受您的DApp。
  6. connect的未来要么完成要么抛出错误。一旦完成,您可能需要再次检查walletState以查看是否已连接。如果注册了监听器,它应该会在walletState更改时触发。
  7. 您现在可以在Flutter中使用BaseWalletAdapter,也可以将其js属性传递给JavaScript并在那里进行操作。

JavaScript使用

确保先阅读“理论”部分。所有Adapter类的子类(包括BaseWalletAdapter)都包含一个js属性,这是一个代理的JavaScript对象,指向钱包适配器。您可以将此js属性传递给JavaScript并在其中使用它,例如与anchor库配合使用。在这种情况下,您会使用js属性作为wallet参数来创建AnchorProvider

以下代码总结了这一点。假设您已经加载了以下JavaScript到浏览器中:

import { AnchorProvider } from '@coral-xyz/anchor';
import { Connection } from '@solana/web3.js';

function doSomething(wallet) {
    const url = 'https://solana-mainnet.rpc.extrnode.com';
    const provider = new AnchorProvider(new Connection(url), wallet, {});
    //do something related to your project with the provider
}

const my_project = {
    'doSomething': doSomething
};

if (window.dartInteropt == undefined) {
    window.dartInteropt = new Object();
}

window.dartInteropt.my_project = my_project;

然后,您可以使用js属性来与Adapter交互:

@JS('window.dartInteropt.my_project')
library my_project;

import 'package:js/js.dart';
import 'package:solana_wallets_flutter/solana_wallets_flutter.dart';

@JS('doSomething')
external void _doSomething(Object wallet);

void main() async {
  BaseWalletAdapter phantom = await getPhantom();
  _doSomething(phantom.js);
}

Future<BaseWalletAdapter> getPhantom() async {
    // ...
    // get the phantom wallet and connect it,
    // see example/lib/main.dart how to do this!
}

为了更好地理解这里发生的事情,请阅读js包的文档。

Flutter使用

此插件仅提供对用户钱包的访问,不负责创建或发送交易。BaseWalletAdapter有一个sendTransaction方法,但这只是一个代理的JavaScript函数,详细解释在其API文档中(确保阅读“理论”部分以了解详情),因此可能很难用“纯”Flutter使用此功能(因为它需要提供一个JavaScript@solana/web3.js/Connection对象)。但是,您可以使用solana包来创建和发送交易,并使用solana_wallets_flutter来使用用户的钱包签名。为此,您需要一个BaseSignerWalletAdapter。大多数由getWalletAdaptersWhenInitalized返回的适配器实际上是这种类型(所以您可以将其转换)。然后,查看BaseSignerWalletAdapter.signTransactionBaseSignerWalletAdapter.signAllTransactions。示例也演示了这一点(请参见example/lib/transaction_example.dart)。

示例

示例文件夹包含一个项目,该项目展示了如何连接钱包。它还展示了如何使用solana Dart包创建交易、使用solana_wallets_flutter签名并使用solana包发送交易。如果您想查看使用此插件编写的Solana DApp,请查看NFT-Pixels.io


示例代码


更多关于Flutter Solana钱包管理插件solana_wallets_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Solana钱包管理插件solana_wallets_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用 solana_wallets_flutter 插件来管理 Solana 钱包的示例代码。这个插件允许你在 Flutter 应用中生成、导入和导出 Solana 钱包。

首先,确保你已经在你的 pubspec.yaml 文件中添加了 solana_wallets_flutter 依赖:

dependencies:
  flutter:
    sdk: flutter
  solana_wallets_flutter: ^最新版本号  # 请替换为实际的最新版本号

然后运行 flutter pub get 来安装依赖。

接下来是一个简单的 Flutter 应用示例,展示了如何使用 solana_wallets_flutter 插件:

import 'package:flutter/material.dart';
import 'package:solana_wallets_flutter/solana_wallets_flutter.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Solana Wallet Management',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SolanaWalletScreen(),
    );
  }
}

class SolanaWalletScreen extends StatefulWidget {
  @override
  _SolanaWalletScreenState createState() => _SolanaWalletScreenState();
}

class _SolanaWalletScreenState extends State<SolanaWalletScreen> {
  late SolanaWallets _solanaWallets;
  String? _walletAddress;
  String? _privateKey;

  @override
  void initState() {
    super.initState();
    _solanaWallets = SolanaWallets();
  }

  Future<void> generateWallet() async {
    try {
      var wallet = await _solanaWallets.generateNewWallet();
      setState(() {
        _walletAddress = wallet.address;
        _privateKey = wallet.privateKey;
      });
    } catch (e) {
      print('Error generating wallet: $e');
    }
  }

  Future<void> importWalletFromSeed(String seedPhrase) async {
    try {
      var wallet = await _solanaWallets.importWalletFromSeed(seedPhrase);
      setState(() {
        _walletAddress = wallet.address;
        // Note: Private key is not returned when importing from seed phrase for security reasons
      });
    } catch (e) {
      print('Error importing wallet: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Solana Wallet Management'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Wallet Address: $_walletAddress'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: generateWallet,
              child: Text('Generate New Wallet'),
            ),
            SizedBox(height: 20),
            TextField(
              decoration: InputDecoration(labelText: 'Seed Phrase'),
              onChanged: (value) {}, // Handle input if needed
              onEditingComplete: () async {
                // Assume user has entered seed phrase and pressed done
                importWalletFromSeed(value);
              },
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () async {
                // Note: This is just an example. Never expose private key in real apps.
                if (_privateKey != null) {
                  // Perform actions with private key
                  print('Private Key: $_privateKey');
                } else {
                  print('No private key available.');
                }
              },
              child: Text('Show Private Key (For Demo Purposes Only)'),
            ),
          ],
        ),
      ),
    );
  }
}

说明:

  1. 生成新钱包:点击“Generate New Wallet”按钮将生成一个新的 Solana 钱包,并显示其地址和私钥(仅供演示用途,实际应用中不应显示私钥)。

  2. 从助记词导入钱包:用户可以在输入框中输入助记词,并在完成编辑后自动导入钱包。注意,出于安全考虑,导入时不会返回私钥。

  3. 显示私钥:这仅用于演示目的,实际应用中不应显示或处理私钥。

注意事项:

  • 安全性:在实际应用中,私钥管理应非常谨慎,避免私钥泄露。
  • 错误处理:示例代码中的错误处理较为简单,实际应用中应更详细地处理各种可能的错误情况。
  • UI/UX:示例代码中的 UI 较为简单,实际应用中应根据需求进行优化。

希望这个示例能帮你更好地理解如何使用 solana_wallets_flutter 插件来管理 Solana 钱包。

回到顶部