Flutter用户操作管理插件userop的使用

Flutter用户操作管理插件userop的使用

简介

userop.dart 是什么?

userop.dart 是一个专门用于构建ERC-4337用户操作(User Operations)的库。虽然 web3dart 使开发者能够轻松生成标准的EVM交易,但 userop.dart 可以简化用户操作的创建和发送到ERC-4337捆绑器(Bundler)的过程。

为什么使用 userop.dart?

  • 💪 多功能实现:适用于任何ERC-4337智能账户、捆绑器平台或支付处理器。
  • 🏗️ 用户友好的架构:采用建造者设计模式,反映实际的用户操作构建过程。

安装

pubspec.yaml 文件中添加以下依赖:

dependencies:
  userop: [latest-version]

示例

创建一个简单的账户

import 'package:userop/userop.dart';

void main() async {
  final signingKey = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  final bundlerRPC = 'YOUR_BUNDLER_RPC_URL';

  final opts = IPresetBuilderOpts()
    ..overrideBundlerRpc = bundlerRPC;
  final simpleAccount = await SimpleAccount.init(
    signingKey,
    bundlerRPC,
    opts: opts,
  );

  print('SimpleAccount address: ${simpleAccount.getSender()}');
}

转账资金

import 'package:userop/userop.dart';

void main() async {
  final signingKey = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  final bundlerRPC = 'YOUR_BUNDLER_RPC_URL';

  final opts = IPresetBuilderOpts()
    ..overrideBundlerRpc = bundlerRPC;
  final simpleAccount = await SimpleAccount.init(
    signingKey,
    bundlerRPC,
    opts: opts,
  );

  final targetAddress = EthereumAddress.fromHex('TARGET_ADDRESS');
  final amount = BigInt.parse('AMOUNT_IN_WEI');

  final client = await Client.init(bundlerRPC);

  final res = await client.sendUserOperation(
    await simpleAccount.execute(
      Call(
        to: targetAddress,
        value: amount,
        data: Uint8List(0),
      ),
    ),
  );
  print('UserOpHash: ${res.userOpHash}');

  print('Waiting for transaction...');
  final ev = await res.wait();
  print('Transaction hash: ${ev?.transactionHash}');
}

转移ERC20代币

import 'package:userop/userop.dart';

void main() async {
  final signingKey = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  final bundlerRPC = 'YOUR_BUNDLER_RPC_URL';

  final opts = IPresetBuilderOpts()
    ..overrideBundlerRpc = bundlerRPC;
  final simpleAccount = await SimpleAccount.init(
    signingKey,
    bundlerRPC,
    opts: opts,
  );

  final targetAddress = EthereumAddress.fromHex('TARGET_ADDRESS');
  final amount = BigInt.parse('AMOUNT_IN_WEI');

  final client = await Client.init(bundlerRPC);

  final res = await client.sendUserOperation(
    await simpleAccount.execute(
      Call(
        to: targetAddress,
        value: amount,
        data: Uint8List(0),
      ),
    ),
  );
  print('UserOpHash: ${res.userOpHash}');

  print('Waiting for transaction...');
  final ev = await res.wait();
  print('Transaction hash: ${ev?.transactionHash}');
}

批量转账

import 'package:userop/userop.dart';

void main() async {
  final signingKey = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  final bundlerRPC = 'YOUR_BUNDLER_RPC_URL';

  final opts = IPresetBuilderOpts()
    ..overrideBundlerRpc = bundlerRPC;
  final simpleAccount = await SimpleAccount.init(
    signingKey,
    bundlerRPC,
    opts: opts,
  );

  final targetAddress1 = EthereumAddress.fromHex('TARGET_ADDRESS_1');
  final targetAddress2 = EthereumAddress.fromHex('TARGET_ADDRESS_2');
  final amount = BigInt.parse('AMOUNT_IN_WEI');

  final client = await Client.init(bundlerRPC);

  final res1 = await client.sendUserOperation(
    await simpleAccount.execute(
      Call(
        to: targetAddress1,
        value: amount,
        data: Uint8List(0),
      ),
    ),
  );
  print('UserOpHash for Target Address 1: ${res1.userOpHash}');

  final res2 = await client.sendUserOperation(
    await simpleAccount.execute(
      Call(
        to: targetAddress2,
        value: amount,
        data: Uint8List(0),
      ),
    ),
  );
  print('UserOpHash for Target Address 2: ${res2.userOpHash}');

  print('Waiting for transaction...');
  final ev1 = await res1.wait();
  final ev2 = await res2.wait();
  print('Transaction hash for Target Address 1: ${ev1?.transactionHash}');
  print('Transaction hash for Target Address 2: ${ev2?.transactionHash}');
}

客户端

通过 userop.dart 连接到ERC-4337捆绑器非常简单。userop.dart 允许你通过客户端接口连接到捆绑器RPC。

使用

import 'package:userop/userop.dart';

void main() async {
  final String bundlerRPC = 'YOUR_BUNDLER_RPC_URL';
  final IClientOpts iClientOpts = IClientOpts()
    ..overrideBundlerRpc = bundlerRPC
    ..entryPoint = EthereumAddress.fromHex('YOUR_ENTRY_POINT' ?? ERC4337.ENTRY_POINT);

  final client = await Client.init(
    bundlerRPC,
    opts: iClientOpts,
  );
}

发送用户操作

使用 sendUserOperation 方法将用户操作发送到捆绑器。

import 'package:userop/userop.dart';

void main() async {
  final String bundlerRPC = 'YOUR_BUNDLER_RPC_URL';
  final IClientOpts iClientOpts = IClientOpts()
    ..overrideBundlerRpc = bundlerRPC
    ..entryPoint = EthereumAddress.fromHex('YOUR_ENTRY_POINT' ?? ERC4337.ENTRY_POINT);

  final client = await Client.init(
    bundlerRPC,
    opts: iClientOpts,
  );

  final targetAddress = EthereumAddress.fromHex('TARGET_ADDRESS');
  final amount = BigInt.parse('AMOUNT_IN_WEI');

  final response = await client.sendUserOperation(
    await simpleAccount.execute(
      Call(
        to: targetAddress,
        value: amount,
        data: Uint8List(0),
      ),
    ),
    opts: sendOpts,
  );
  final filterEvent = await response.wait();

  print('UserOpHash: ${filterEvent?.userOpHash}');
  print('Transaction hash: ${filterEvent?.transactionHash}');
}

构建用户操作

使用 buildUserOperation 方法来构建用户操作而不发送它。

import 'package:userop/userop.dart';

void main() async {
  final String bundlerRPC = 'YOUR_BUNDLER_RPC_URL';
  final IClientOpts iClientOpts = IClientOpts()
    ..overrideBundlerRpc = bundlerRPC
    ..entryPoint = EthereumAddress.fromHex('YOUR_ENTRY_POINT' ?? ERC4337.ENTRY_POINT);

  final client = await Client.init(
    bundlerRPC,
    opts: iClientOpts,
  );

  final userOp = await client.buildUserOperation(builder);
}

常数

可以设置一些常量来控制等待时间和其他参数。

import 'package:userop/userop.dart';

void main() async {
  final String bundlerRPC = 'YOUR_BUNDLER_RPC_URL';
  final IClientOpts iClientOpts = IClientOpts()
    ..overrideBundlerRpc = bundlerRPC
    ..entryPoint = EthereumAddress.fromHex('YOUR_ENTRY_POINT' ?? ERC4337.ENTRY_POINT);

  final client = await Client.init(
    bundlerRPC,
    opts: iClientOpts,
  );

  // 设置等待超时时间为30秒
  client.waitTimeoutMs = 30000;

  // 设置轮询间隔为5秒
  client.waitIntervalMs = 5000;
}

提供者

userop.dart 提供了一个简单的 web3dart JsonRPC包装器,允许重定向捆绑器方法。默认情况下,假设捆绑器和节点方法共享相同的RPC URL。但在不一致的情况下,该模块提供了覆盖捆绑器RPC的功能,允许所有捆绑器RPC方法被重定向到不同的端点。

BundlerJsonRpcProvider

import 'package:userop/userop.dart';
import 'package:http/http.dart' as http;

void main() async {
  final String bundlerRPC = 'YOUR_BUNDLER_RPC_URL';
  final provider = BundlerJsonRpcProvider(bundlerRPC, http.Client());
}

预设

userop.dart 提供了一些预设,以便更快地设置特定用例。

构建器

构建器预设提供了已配置的构建器,用于已知的合约账户实现。这些预设可以直接使用,也可以通过 getset 函数进行自定义。

Kernel

import 'package:userop/userop.dart';

void main() async {
  final targetAddress = EthereumAddress.fromHex('YOUR_TARGET_ADDRESS');
  final amount = BigInt.parse('AMOUNT_IN_WEI');
  final signingKey = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  final bundlerRPC = 'YOUR_BUNDLER_RPC_URL';
  final opts = IPresetBuilderOpts()
    ..factoryAddress = EthereumAddress.fromHex(
      'YOUR_FACTORY_ADDRESS',
    );
  final kernel = await Kernel.init(
    signingKey,
    bundlerRPC,
    opts: opts,
  );

  final client = await Client.init(bundlerRPC);

  final res = await client.sendUserOperation(
    await kernel.execute(
      Call(
        to: targetAddress,
        value: amount,
        data: Uint8List(0),
      ),
    ),
  );
  print('UserOpHash: ${res.userOpHash}');

  print('Waiting for transaction...');
  final ev = await res.wait();
  print('Transaction hash: ${ev?.transactionHash}');
}

Etherspot Wallet

import 'package:userop/userop.dart';

void main() async {
  final targetAddress = EthereumAddress.fromHex('YOUR_TARGET_ADDRESS');
  final amount = BigInt.parse('AMOUNT_IN_WEI');
  final signingKey = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  final bundlerRPC = 'YOUR_BUNDLER_RPC_URL';

  final etherspotWallet = await EtherspotWallet.init(
    signingKey,
    bundlerRPC,
  );

  final client = await Client.init(bundlerRPC);

  final res = await client.sendUserOperation(
    await etherspotWallet.execute(
      Call(
        to: targetAddress,
        value: amount,
        data: Uint8List(0),
      ),
    ),
  );
  print('UserOpHash: ${res.userOpHash}');

  print('Waiting for transaction...');
  final ev = await res.wait();
  print('Transaction hash: ${ev?.transactionHash}');
}

SimpleAccount

import 'package:userop/userop.dart';

void main() async {
  final targetAddress = EthereumAddress.fromHex('YOUR_TARGET_ADDRESS');
  final amount = BigInt.parse('AMOUNT_IN_WEI');
  final signingKey = EthPrivateKey.fromHex('YOUR_PRIVATE_KEY');
  final bundlerRPC = 'YOUR_BUNDLER_RPC_URL';

  final simpleAccount = await SimpleAccount.init(
    signingKey,
    bundlerRPC,
  );

  final client = await Client.init(bundlerRPC);

  final res = await client.sendUserOperation(
    await simpleAccount.execute(
      Call(
        to: targetAddress,
        value: amount,
        data: Uint8List(0),
      ),
    ),
  );
  print('UserOpHash: ${res.userOpHash}');

  print('Waiting for transaction...');
  final ev = await res.wait();
  print('Transaction hash: ${ev?.transactionHash}');
}

中间件

中间件预设提供了可重用的中间件函数,针对不同的构建器实例。

estimateUserOperationGas

import 'package:userop/userop.dart';

void main() async {
  final builder = UserOperationBuilder();

  builder = builder.useMiddleware(estimateUserOperationGas(
    Web3Client('RPC_URL', http.Client()),
    BundlerJsonRpcProvider('RPC_URL', http.Client()),
  ));
}

getGasPrice

import 'package:userop/userop.dart';

void main() async {
  final builder = UserOperationBuilder();

  builder = builder.useMiddleware(getGasPrice(
    Web3Client('RPC_URL', http.Client()),
    BundlerJsonRpcProvider('RPC_URL', http.Client()),
  ));
}

verifyingPaymaster

import 'package:userop/userop.dart';

void main() async {
  final paymasterMiddleware = verifyingPaymaster(
    'YOUR_PAYMASTER_SERVICE_URL',
    {},
  );

  final IPresetBuilderOpts opts = IPresetBuilderOpts()
    ..paymasterMiddleware = paymasterMiddleware;

  final simpleAccount = await SimpleAccount.init(
    signingKey,
    bundlerRPC,
    opts: opts,
  );
}

eOASignature

import 'package:userop/userop.dart';

void main() async {
  final builder = UserOperationBuilder();

  builder = builder.useMiddleware(eOASignature(signer));
}

更多关于Flutter用户操作管理插件userop的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

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


在Flutter中,userop(假设这是一个用于用户操作管理的插件,尽管这不是一个广为人知的官方或广泛使用的插件名称)通常旨在帮助开发者简化用户交互的管理。虽然无法提供一个确切的userop插件代码,因为这不是一个标准的Flutter包,但我可以提供一个假设性的示例,展示如何创建一个类似功能的插件来管理用户操作。

以下是一个简化的示例,展示如何使用Flutter和Dart创建一个基本的用户操作管理器。这个示例不会包含实际的第三方插件代码,而是演示如何从头开始实现类似功能。

1. 创建Flutter项目

首先,创建一个新的Flutter项目(如果还没有的话):

flutter create user_operation_manager
cd user_operation_manager

2. 创建用户操作管理器类

lib目录下创建一个新的Dart文件,比如user_operation_manager.dart,并在其中定义用户操作管理器类:

import 'package:flutter/material.dart';

class UserOperationManager with ChangeNotifier {
  // 假设有一个用户操作的历史记录列表
  List<String> operationHistory = [];

  // 添加一个新的用户操作
  void addOperation(String operation) {
    operationHistory.add(operation);
    notifyListeners(); // 通知监听器数据已更改
  }

  // 获取操作历史记录
  List<String> getHistory() {
    return operationHistory;
  }
}

3. 创建UI来展示和操作用户数据

lib/main.dart中,创建一个简单的UI来展示用户操作历史,并提供添加新操作的按钮:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<UserOperationManager>(
      create: (_) => UserOperationManager(),
      child: MaterialApp(
        title: 'User Operation Manager',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final TextEditingController _controller = TextEditingController();

  void _addOperation(BuildContext context) {
    final UserOperationManager manager = Provider.of<UserOperationManager>(context);
    String newOperation = _controller.text;
    if (newOperation.isNotEmpty) {
      manager.addOperation(newOperation);
      _controller.clear();
      ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Operation added!')));
    }
  }

  @override
  Widget build(BuildContext context) {
    final UserOperationManager manager = Provider.of<UserOperationManager>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('User Operation Manager'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextField(
              controller: _controller,
              decoration: InputDecoration(
                labelText: 'Enter new operation',
              ),
            ),
            SizedBox(height: 16),
            ElevatedButton(
              onPressed: () => _addOperation(context),
              child: Text('Add Operation'),
            ),
            SizedBox(height: 16),
            Expanded(
              child: ListView.builder(
                itemCount: manager.getHistory().length,
                itemBuilder: (context, index) {
                  return ListTile(
                    title: Text(manager.getHistory()[index]),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

4. 使用Provider进行状态管理

在上面的代码中,我们使用了Provider包来进行状态管理。确保在pubspec.yaml文件中添加provider依赖:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.0 # 确保使用最新版本

然后运行flutter pub get来获取依赖。

5. 运行应用

现在,你可以运行应用并测试用户操作管理功能:

flutter run

这个示例展示了如何从头开始创建一个简单的用户操作管理器,它允许用户输入操作并将其添加到历史记录中。虽然这不是一个真正的userop插件的示例,但它提供了一个基础框架,你可以根据实际需求进行扩展和修改。如果userop是一个实际存在的插件,请参考其官方文档以获取具体的实现细节和用法。

回到顶部