Flutter Solana钱包管理插件solana_wallets_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
包含用于显示用户选择首选钱包对话框的函数。您可以不使用它并创建自己的对话框。
使用方法
以下是使用此插件的通常步骤:
- 在项目的主要方法中调用(但不要等待)
initSolanaWallets
来自solana_wallets_flutter
库。 - 调用
getWalletAdaptersWhenInitalized
来自solana_wallets_flutter
库获取适配器列表,并可选地过滤返回的列表以排除您不想在您的DApp中支持的适配器。 - 通过
solana_wallets_flutter_ui
中的showWalletSelectDialog
函数与(过滤后的)适配器列表一起让用户从对话框中选择一个钱包,或者构建自己的系统让用户决定要使用的钱包。 - 您现在有了用户想要使用的
BaseWalletAdapter
,调用其上的addListener
方法以监视walletState
。重要的是:如果您完成了适配器的操作,请调用removeListener
,否则可能会遇到性能问题! - 调用
connect
方法,用户的浏览器将打开钱包扩展程序或弹出窗口,用户需要接受您的DApp。 connect
的未来要么完成要么抛出错误。一旦完成,您可能需要再次检查walletState
以查看是否已连接。如果注册了监听器,它应该会在walletState
更改时触发。- 您现在可以在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.signTransaction
和BaseSignerWalletAdapter.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
更多关于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)'),
),
],
),
),
);
}
}
说明:
-
生成新钱包:点击“Generate New Wallet”按钮将生成一个新的 Solana 钱包,并显示其地址和私钥(仅供演示用途,实际应用中不应显示私钥)。
-
从助记词导入钱包:用户可以在输入框中输入助记词,并在完成编辑后自动导入钱包。注意,出于安全考虑,导入时不会返回私钥。
-
显示私钥:这仅用于演示目的,实际应用中不应显示或处理私钥。
注意事项:
- 安全性:在实际应用中,私钥管理应非常谨慎,避免私钥泄露。
- 错误处理:示例代码中的错误处理较为简单,实际应用中应更详细地处理各种可能的错误情况。
- UI/UX:示例代码中的 UI 较为简单,实际应用中应根据需求进行优化。
希望这个示例能帮你更好地理解如何使用 solana_wallets_flutter
插件来管理 Solana 钱包。