Flutter网络通信插件nkn_sdk_flutter的使用
Flutter网络通信插件nkn_sdk_flutter的使用
使用
安装
首先,在main()
函数中初始化插件:
void main() {
WidgetsFlutterBinding.ensureInitialized();
Wallet.install();
Client.install();
runApp(MyApp());
}
钱包 (Wallet)
创建钱包
创建一个新钱包,并打印地址、种子和公钥:
Wallet wallet = await Wallet.create(null, config: WalletConfig(password: '123'));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);
导出钱包到JSON字符串
导出钱包信息到JSON字符串:
print(wallet.keystore);
自定义RPC服务器
使用自定义的RPC服务器创建钱包:
Wallet wallet = await Wallet.create(null, config: WalletConfig(password: '123', seedRPCServerAddr: ['http://seed.nkn.org:30003']));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);
从JSON字符串恢复钱包
从JSON字符串恢复钱包,并确保密码一致:
Wallet wallet = await Wallet.restore(w.keystore,
config: WalletConfig(password: '123'));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);
查询资产余额
查询当前钱包的余额:
double balance = await wallet.getBalance();
转账
向指定地址转账:
String txHash = await wallet.transfer(NKN_ADDRESS, '1.23');
客户端 (Client)
创建客户端
使用生成的密钥对创建客户端:
var client = await Client.create(WALLET_SEED);
监听连接建立
监听连接建立事件:
client.onConnect.listen((event) {
print(event.node);
});
接收数据
接收其他客户端发送的数据:
client.onMessage.listen((event) {
print(event.type);
print(event.encrypted);
print(event.messageId);
print(event.data);
print(event.src);
});
发送文本消息
向其他客户端发送文本消息:
await client.sendText([CLIENT_ADDRESS], jsonEncode({'contentType': 'text', 'content': 'Hello'}));
发布消息到指定主题
发布一条消息到指定主题:
await client.publishText(TOPIC, jsonEncode({'contentType': 'text', 'content': 'Hello'}));
发布/订阅 (Pub/Sub)
订阅和取消订阅主题:
var res = await client.subscribe(topic: TOPIC);
var res = await client.unsubscribe(topic: TOPIC);
// 获取订阅者数量
var res = await client.getSubscribersCount(topic: TOPIC);
// 获取特定订阅关系
var res = await client.getSubscription(topic: TOPIC, subscriber: CLIENT_ADDRESS);
示例代码
以下是一个完整的示例代码,展示了如何使用nkn_sdk_flutter
插件进行网络通信。
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:nkn_sdk_flutter/client.dart';
import 'package:nkn_sdk_flutter/crypto.dart';
import 'package:nkn_sdk_flutter/utils/hash.dart';
import 'package:nkn_sdk_flutter/utils/hex.dart';
import 'package:nkn_sdk_flutter/wallet.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Wallet.install();
Client.install();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Client? _client1;
Client? _client2;
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Container(
padding: const EdgeInsets.only(top: 10),
child: Column(
children: [
Text(
'Wallet',
style: TextStyle(fontSize: 16),
),
Wrap(
children: [
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.create(null, config: WalletConfig(password: '123'));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);
print(wallet.keystore);
print(wallet.programHash);
},
child: Text('create'),
),
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.restore(
'{"Version":2,"IV":"d103adf904b4b2e8cca9659e88201e5d","MasterKey":"20042c80ccb809c72eb5cf4390b29b2ef0efb014b38f7229d48fb415ccf80668","SeedEncrypted":"3bcdca17d84dc7088c4b3f929cf1e96cf66c988f2b306f076fd181e04c5be187","Address":"NKNVgahGfYYxYaJdGZHZSxBg2QJpUhRH24M7","Scrypt":{"Salt":"a455be75074c2230","N":32768,"R":8,"P":1}}',
config: WalletConfig(password: '123'));
print(wallet.address);
print(wallet.seed);
print(wallet.publicKey);
print(wallet.keystore);
print(wallet.programHash);
},
child: Text('restore'),
),
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.restore(
'{"Version":2,"IV":"d103adf904b4b2e8cca9659e88201e5d","MasterKey":"20042c80ccb809c72eb5cf4390b29b2ef0efb014b38f7229d48fb415ccf80668","SeedEncrypted":"3bcdca17d84dc7088c4b3f929cf1e96cf66c988f2b306f076fd181e04c5be187","Address":"NKNVgahGfYYxYaJdGZHZSxBg2QJpUhRH24M7","Scrypt":{"Salt":"a455be75074c2230","N":32768,"R":8,"P":1}}',
config: WalletConfig(password: '123'));
print(await wallet.getBalance());
},
child: Text('getBalance'),
),
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.restore(
'{"Version":2,"IV":"d103adf904b4b2e8cca9659e88201e5d","MasterKey":"20042c80ccb809c72eb5cf4390b29b2ef0efb014b38f7229d48fb415ccf80668","SeedEncrypted":"3bcdca17d84dc7088c4b3f929cf1e96cf66c988f2b306f076fd181e04c5be187","Address":"NKNVgahGfYYxYaJdGZHZSxBg2QJpUhRH24M7","Scrypt":{"Salt":"a455be75074c2230","N":32768,"R":8,"P":1}}',
config: WalletConfig(password: '123'));
print(await wallet.getBalance());
String? hash = await wallet.transfer(wallet.address, '0');
print(hash);
},
child: Text('transfer'),
),
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.restore(
'{"Version":2,"IV":"d103adf904b4b2e8cca9659e88201e5d","MasterKey":"20042c80ccb809c72eb5cf4390b29b2ef0efb014b38f7229d48fb415ccf80668","SeedEncrypted":"3bcdca17d84dc7088c4b3f929cf1e96cf66c988f2b306f076fd181e04c5be187","Address":"NKNVgahGfYYxYaJdGZHZSxBg2QJpUhRH24M7","Scrypt":{"Salt":"a455be75074c2230","N":32768,"R":8,"P":1}}',
config: WalletConfig(password: '123'));
int? nonce = await wallet.getNonce();
print(nonce);
},
child: Text('getNonce'),
),
TextButton(
onPressed: () async {
int? height = await Wallet.getHeight();
print(height);
},
child: Text('getHeight'),
),
TextButton(
onPressed: () async {
int? nonce = await Wallet.getNonceByAddress('NKNVgahGfYYxYaJdGZHZSxBg2QJpUhRH24M7');
print(nonce);
},
child: Text('getNonceByAddress'),
),
],
),
Text(
'Client1',
style: TextStyle(fontSize: 16),
),
Wrap(
children: [
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.restore(
'{"Version":2,"IV":"d103adf904b4b2e8cca9659e88201e5d","MasterKey":"20042c80ccb809c72eb5cf4390b29b2ef0efb014b38f7229d48fb415ccf80668","SeedEncrypted":"3bcdca17d84dc7088c4b3f929cf1e96cf66c988f2b306f076fd181e04c5be187","Address":"NKNVgahGfYYxYaJdGZHZSxBg2QJpUhRH24M7","Scrypt":{"Salt":"a455be75074c2230","N":32768,"R":8,"P":1}}',
config: WalletConfig(password: '123'));
await _client1?.close();
_client1 = await Client.create(
wallet.seed,
config: ClientConfig(
dnsResolverConfig: [
DnsResolverConfig(
dnsServer: '8.8.8.8:53',
),
],
),
);
print('-------------_client1----------');
print(_client1?.address);
_client1?.onConnect.listen((event) {
print('------onConnect1-----');
print(event.node);
});
Map dic = Map();
_client1?.onMessage.listen((event) {
print('------onMessage1-----');
if (dic[event.src] == null) {
dic[event.src] = 1;
} else {
dic[event.src] += 1;
}
print(dic[event.src]);
// print(event.type);
// print(event.encrypted);
// print(event.messageId);
print(event.data);
// print(event.src);
print(event.noReply);
if (event.noReply != true) {
event.reply(jsonEncode({'id': DateTime.now().millisecondsSinceEpoch.toString(), 'contentType': 'text', 'content': 'reply'}));
}
});
},
child: Text('create'),
),
TextButton(
onPressed: () async {
_client1?.close();
},
child: Text('close'),
),
TextButton(
onPressed: () async {
await _client1?.reconnect();
},
child: Text('reconnect')),
TextButton(
onPressed: () async {
print(jsonEncode({'id': DateTime.now().millisecondsSinceEpoch.toString(), 'contentType': 'text', 'content': 'hi'}));
var res = await _client1
?.sendText([_client2!.address], jsonEncode({'id': DateTime.now().millisecondsSinceEpoch.toString(), 'contentType': 'text', 'content': 'hi'}));
print(res);
},
child: Text('sendText'),
),
TextButton(
onPressed: () async {
var res = await _client1?.subscribe(topic: genChannelId('ttest'));
print(res);
},
child: Text('subscribe'),
),
TextButton(
onPressed: () async {
var res = await _client1?.unsubscribe(topic: genChannelId('ttest'));
print(res);
},
child: Text('unsubscribe'),
),
TextButton(
onPressed: () async {
var res = await _client1?.getSubscribersCount(topic: genChannelId('ttest'));
print(res);
},
child: Text('getSubscribersCount'),
),
TextButton(
onPressed: () async {
var res = await _client1?.getSubscription(topic: genChannelId('ttest'), subscriber: _client1!.address);
print(res);
},
child: Text('getSubscription'),
),
TextButton(
onPressed: () async {
var res = await _client1?.getSubscribers(topic: genChannelId('ttest'));
print(res);
},
child: Text('getSubscribers'),
),
TextButton(
onPressed: () async {
var res = await _client1?.getHeight();
print(res);
},
child: Text('getHeight'),
),
TextButton(
onPressed: () async {
var res = await _client1?.getNonce();
print(res);
},
child: Text('getNonce'),
),
TextButton(
onPressed: () async {
var res = await _client1?.getNonceByAddress('NKNVgahGfYYxYaJdGZHZSxBg2QJpUhRH24M7');
print(res);
},
child: Text('getNonceByAddress'),
),
],
),
Text(
'Client2',
style: TextStyle(fontSize: 16),
),
Wrap(
children: [
TextButton(
onPressed: () async {
await _client2?.close();
_client2 = await Client.create(hexDecode('bd8bd3de4dd0f798fac5a0a56e536a8bacd5b7f46d0951d8665fd68d0a910996'));
_client2?.onConnect.listen((event) {
print('------onConnect2-----');
print(event.node);
});
_client2?.onMessage.listen((event) {
print('------onMessage2-----');
print(event.type);
print(event.encrypted);
print(event.messageId);
print(event.data);
print(event.src);
});
},
child: Text('create'),
),
TextButton(
onPressed: () async {
_client2?.close();
},
child: Text('close'),
),
TextButton(
onPressed: () async {
var res = await _client2?.sendText([_client1!.address], jsonEncode({'contentType': 'text', 'content': 'hi2'}), noReply: false);
print(res?.data);
},
child: Text('sendText'),
),
],
),
Text(
'Crypto',
style: TextStyle(fontSize: 16),
),
Wrap(
children: [
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.create(hexDecode('a2df9fafa747b4da6afa58cdee8e170f0a71815584c3ed3bfa52040c89d0bd61'), config: WalletConfig(password: '123'));
Uint8List privateKey = await Crypto.getPrivateKeyFromSeed(wallet.seed);
var res = await Crypto.sign(privateKey, Uint8List.fromList(utf8.encode('Hello, world!')));
print(hexEncode(res));
},
child: Text('sign'),
),
TextButton(
onPressed: () async {
Wallet wallet = await Wallet.create(hexDecode('a2df9fafa747b4da6afa58cdee8e170f0a71815584c3ed3bfa52040c89d0bd61'), config: WalletConfig(password: '123'));
bool verified = await Crypto.verify(wallet.publicKey, Uint8List.fromList(utf8.encode('Hello, world!')),
hexDecode('fc81c36aa9002bb973fb7db3b8d334ae52194edf5e051d4c5105d20fbbad7287cd5172aea0acac43d843bf3b692aa486d96e4dcfbed9b7dcfb6e7c385c070d0d'));
print(verified);
},
child: Text('verify'),
),
],
),
],
),
),
),
);
}
}
更多关于Flutter网络通信插件nkn_sdk_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络通信插件nkn_sdk_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用nkn_sdk_flutter
插件进行网络通信的示例代码。这个插件允许你与NKN(一个开源、社区驱动的、公共的区块链网络)进行交互。
1. 添加依赖
首先,你需要在你的pubspec.yaml
文件中添加nkn_sdk_flutter
依赖:
dependencies:
flutter:
sdk: flutter
nkn_sdk_flutter: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来获取依赖。
2. 初始化NKN客户端
在你的Flutter应用中,你需要初始化NKN客户端。这通常在你的应用的主文件(例如main.dart
)中进行。
import 'package:flutter/material.dart';
import 'package:nkn_sdk_flutter/nkn_sdk_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化NKN客户端
NKNClient client = NKNClient();
await client.init();
runApp(MyApp(client: client));
}
class MyApp extends StatelessWidget {
final NKNClient client;
MyApp({required this.client});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(client: client),
);
}
}
3. 使用NKN客户端进行通信
接下来,你可以使用NKN客户端来发送和接收消息。以下是一个简单的示例,展示如何创建一个会话并发送消息。
import 'package:flutter/material.dart';
import 'package:nkn_sdk_flutter/nkn_sdk_flutter.dart';
class HomeScreen extends StatefulWidget {
final NKNClient client;
HomeScreen({required this.client});
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
late String remoteAddress; // 远程NKN地址
late TextEditingController messageController;
@override
void initState() {
super.initState();
remoteAddress = 'your.remote.nkn.address'; // 替换为你的远程NKN地址
messageController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('NKN Communication Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
controller: messageController,
decoration: InputDecoration(
labelText: 'Message',
),
),
SizedBox(height: 16),
ElevatedButton(
onPressed: () async {
try {
// 创建会话
NKNSession session = await widget.client.newSession(remoteAddress);
// 发送消息
String message = messageController.text;
await session.send(message);
// 显示发送成功的Snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Message sent: $message')),
);
} catch (e) {
// 显示错误Snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Error: ${e.message}')),
);
}
},
child: Text('Send Message'),
),
],
),
),
);
}
@override
void dispose() {
messageController.dispose();
super.dispose();
}
}
注意事项
- 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,以处理各种可能的异常情况。
- NKN地址:确保你有一个有效的NKN地址来与远程节点通信。
- 安全性:在发送敏感信息时,请确保使用加密方法保护数据。
- 依赖版本:始终检查
nkn_sdk_flutter
插件的最新版本,并根据需要更新你的依赖。
这个示例代码提供了一个基本框架,你可以在此基础上进行扩展,以满足你的具体需求。