Flutter网络通信插件nkn_sdk_flutter的使用

发布于 1周前 作者 htzhanglong 来自 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

1 回复

更多关于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();
  }
}

注意事项

  1. 错误处理:在实际应用中,你应该添加更多的错误处理逻辑,以处理各种可能的异常情况。
  2. NKN地址:确保你有一个有效的NKN地址来与远程节点通信。
  3. 安全性:在发送敏感信息时,请确保使用加密方法保护数据。
  4. 依赖版本:始终检查nkn_sdk_flutter插件的最新版本,并根据需要更新你的依赖。

这个示例代码提供了一个基本框架,你可以在此基础上进行扩展,以满足你的具体需求。

回到顶部