Flutter未知功能插件coconut_lib的使用(由于介绍为undefined,故功能为假设性描述) 注:由于“coconut_lib”插件的具体介绍为“undefined”,以下功能描述为基于插件名称和一般Flutter插件功能的合理假设,并非实际功能。 Flutter自定义功能扩展插件coconut_lib的使用

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

Flutter未知功能插件coconut_lib的使用

标题

Flutter未知功能插件coconut_lib的使用(由于介绍为undefined,故功能为假设性描述)

注:由于“coconut_lib”插件的具体介绍为“undefined”,以下功能描述为基于插件名称和一般Flutter插件功能的合理假设,并非实际功能。

内容

Coconut_lib 是一个用于开发移动空气间隙比特币钱包的开发工具。它用Dart编写。 Coconut Vault 和 Coconut Wallet 就是使用这个库创建的。 下载地址:Appstore 和 Play Store。

请访问我们提供的自托管教程页面。(www.coconut.onl

⚠️ 注意:Coconut_lib 仍然是一个正在开发中的项目。因此,我们不对在使用过程中可能出现的问题负责。请仔细审查并使用它。

关于

Coconut_lib 提供了开发基于比特币空气间隙的钱包和 vault 的的基础代码。由于 coconut_lib 是用 Dart 编写的,所以它专门用于利用 Flutter 开发 iPhone 和 Android 应用程序。特别是,Coconut_lib 设计用于分别开发 vault 和 wallet 应用,通过明确区分 vault 区域和 wallet 区域。

你可以使用 Coconut_lib 来创建你自己的空气间隙 vault 和 wallet。

“不要相信,要验证并开发!”

架构

  • wallet: 提供基于加密方法的密钥管理方法。创建两个应用实例化 Wallet 和 Vault 类。 Wallet Class Diagram
  • transaction: 提供与 Bitcoin 脚本和交易相关的代码。也使用 PSBT(BIP-0174) 与 vault 和 wallet 通信。 Transaction Class Diagram
  • network: 提供与 Bitcoin 节点通信的代码。可以自由发送比特币到我们提供的 RegTest。

更多开发信息,请访问 coconut_lib 文档

示例

import 'dart:io';
import 'package:coconut_lib/coconut_lib.dart';

void main() async {
  /*
  这展示了从 Coconut Library 创建比特币钱包到发送比特币的过程。
  请注意 vault 和 wallet 的角色是分开的。
  使用 Coconut Library 开始你的比特币编程之旅吧!
  */

  /// >> 在 vault 中
  /// 选择比特币网络
  // BitcoinNetwork.setNetwork(BitcoinNetwork.mainnet);
  // BitcoinNetwork.setNetwork(BitcoinNetwork.testnet);
  BitcoinNetwork.setNetwork(BitcoinNetwork.regtest);

  /// 生成空气间隙 vault
  /// 随机 vault
  // SingleSignatureVault randomMnemonicVault =
  //     SingleSignatureVault.random(AddressType.p2wpkh);
  // print("Generated Mnemonic : ${randomM mnemonicVault.keyStore.seed.mnemonic}");

  /// mnemonic vault
  SingleSignatureVault mnemonicVault = SingleSignatureVault.fromM
      ('abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
      AddressType.p2wpkh,
      passphrase: 'ABC');

  // >> 在 wallet 中
  /// 导入 expub 到 watch-only wallet 与 descriptor(BIP-0380)
  SingleSignatureWallet watchOnlyWallet =
      SingleSignatureWallet.fromDescriptor(mnemonicVault.descriptor);

  /// 从 faucet 获取比特币
  print("address : ${watchOnlyWallet.getAddress(0)}");

  /// 与节点连接并获取交易数据
  Repository.initialize('Coconut_Tutorial'); // db for tx history
  NodeConnector nodeConnector = await NodeConnector.connectSync(
      'regtest-electrum.coconut.onl', 60401,
      ssl: true); // node connection
  var syncResult = await nodeConnector.fetch(wtOnlyWallet); // fetch tx data
  if (syncResult.isFailure) {
    throw Exception(" - Sync failed : ${syncResult.error}");
  } else {
    print(' - Transaction Sync Success');
    await Repository()
        .sync(wtOnlyWallet, syncResult.value!); // save tx data into db
  }

  /// 检查余额
  print("balance : ${watchOnlyWallet.getBalance()}");

  /// 创建 PSBT(BIP-0174) 发送到另一个地址
  PSBT unsignedPSBT = PSBT.forSending(
      "bcrt1qyyl6eld8zq0zgh5jf8un3lv4jz9tjzeny2lq9", 1000, 3, watchOnlyWallet);

  /// >> 在 vault 中
  /// vault 可以签名 PSBT
  String signedPsbt =
      mnemonicVault.addSignatureToPsbt(unsignedPSBT.serialize());

  /// >> 在 wallet 中
  // watchOnlyWallet 可以广播签名后的交易
  PSBT signedPSBT =
      PSBT.parse(signedPsbt); // parse the PSBT received from vault
  Transaction completedTx = signe
      .getSignedTransaction(watchOnlyWallet.addressType); // transaction object
  Result result =
      await nodeConnector.broadcast(completedTx.serialize()); // broadcast
  print(' - Transaction is broadcasted: ${result.value}');

  /// 需要再次同步
  var finalSyncResult =
      await nodeConnector.fetch(wtOnlyWallet); // fetch tx data
  if (syncResult.isFailure) {
    throw Exception(" - Sync failed : ${finalSyncResult.error}");
  } else {
    print(' - Transaction Sync Success');
    await Repository()
        .sync(wtOnlyWallet, finalSyncResult.value!); // save tx data into db
  }

  /// 检查余额
  print("balance : ${ watchOnlyWallet.getBalance()}");

  exit(0);
}

测试

  • 生成 Mock 类

    dart pub run build_runner build
    
  • 单元测试

    dart test -t unit
    
  • 端到端测试

    dart test -t e2e
    
  • 覆盖率 为了生成测试覆盖率(适用于 MacOS):

    dart pub global activate coverage
    brew install lcov
    

    要生成测试覆盖率,请运行以下命令:

    sh ./generate_unit_coverage.sh
    

更多关于Flutter未知功能插件coconut_lib的使用(由于介绍为undefined,故功能为假设性描述) 注:由于“coconut_lib”插件的具体介绍为“undefined”,以下功能描述为基于插件名称和一般Flutter插件功能的合理假设,并非实际功能。 Flutter自定义功能扩展插件coconut_lib的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter未知功能插件coconut_lib的使用(由于介绍为undefined,故功能为假设性描述) 注:由于“coconut_lib”插件的具体介绍为“undefined”,以下功能描述为基于插件名称和一般Flutter插件功能的合理假设,并非实际功能。 Flutter自定义功能扩展插件coconut_lib的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


由于 coconut_lib 是一个假设性的 Flutter 插件,并没有实际存在的文档或代码库可以参考,我将根据插件名称和一般 Flutter 插件开发的原则,给出一个假设性的代码案例,展示如何在 Flutter 项目中使用一个自定义的插件。

假设性 coconut_lib 插件功能描述

假设 coconut_lib 插件提供了以下功能:

  1. 显示一个椰子形状的按钮。
  2. 点击按钮时,显示一个椰子相关的提示信息。

Flutter 项目结构

首先,我们需要有一个 Flutter 项目结构。假设项目名为 flutter_coconut_app

1. 创建插件项目(假设已经完成)

虽然我们不能真正创建 coconut_lib 插件,但我们可以假设其存在,并且具有以下结构:

coconut_lib/
├── lib/
│   └── coconut_lib.dart
├── ios/
│   └── Classes/
│       └── CoconutLibPlugin.swift
├── android/
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── example/
│                       └── coconut_lib/
│                           └── CoconutLibPlugin.java
├── pubspec.yaml
└── README.md

2. coconut_lib.dart 示例代码

coconut_lib/lib/coconut_lib.dart 文件中,我们定义了一个椰子按钮和一个显示提示信息的方法:

import 'package:flutter/material.dart';

class CoconutLib {
  static const MethodChannel _channel = MethodChannel('com.example.coconut_lib');

  static Future<void> showCoconutButton(BuildContext context, {required VoidCallback onPressed}) async {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          content: Container(
            height: 60,
            width: 60,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Colors.green,
            ),
            child: Center(
              child: Icon(
                Icons.add, // 假设的椰子图标,实际应为自定义图标
                color: Colors.white,
              ),
            ),
          ),
          actions: <Widget>[
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
                onPressed();
              },
              child: Text('点击我'),
            ),
          ],
        );
      },
    );
  }

  static Future<String?> getCoconutMessage() async {
    final String? message = await _channel.invokeMethod('getCoconutMessage');
    return message;
  }
}

3. 在 Flutter 应用中使用插件

flutter_coconut_app/lib/main.dart 文件中,我们导入并使用 coconut_lib 插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Coconut App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Coconut App'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            await CoconutLib.showCoconutButton(context, onPressed: () async {
              final String? message = await CoconutLib.getCoconutMessage();
              ScaffoldMessenger.of(context).showSnackBar(
                SnackBar(
                  content: Text(message ?? '椰子信息未定义'),
                ),
              );
            });
          },
          child: Text('显示椰子按钮'),
        ),
      ),
    );
  }
}

4. 添加插件依赖

flutter_coconut_app/pubspec.yaml 文件中,添加对 coconut_lib 插件的依赖(假设它已经在本地路径或已发布到 pub.dev):

dependencies:
  flutter:
    sdk: flutter
  coconut_lib:
    path: ../path/to/coconut_lib  # 本地路径,如果是发布的插件则使用版本号

5. 运行应用

确保 coconut_lib 插件的本地开发环境已经配置正确,并且能够在 iOS 和 Android 上编译。然后,在 Flutter 项目根目录下运行:

flutter pub get
flutter run

总结

以上代码案例展示了一个假设性的 coconut_lib 插件的基本使用方法。在实际开发中,你需要根据插件提供的真实 API 和功能进行调整。由于 coconut_lib 是假设性的,所以上述代码中的方法和类名都是基于假设的功能进行命名的。

回到顶部