sendUserOperation method

  1. @override
Future<ISendUserOperationResponse> sendUserOperation(
  1. IUserOperationBuilder builder, {
  2. ISendUserOperationOpts? opts,
})
override

Sends a user operation.

Accepts an IUserOperationBuilder and optional send operation options. Returns a response containing the hash of the user operation and a wait function.

Implementation

@override
Future<ISendUserOperationResponse> sendUserOperation(
  IUserOperationBuilder builder, {
  ISendUserOperationOpts? opts,
}) async {
  final dryRun = opts?.dryRun ?? false;
  final op = await buildUserOperation(builder);
  opts?.onBuild?.call(op);

  final String userOpHash = dryRun
      ? bytesToHex(
          UserOperationMiddlewareCtx(op, entryPoint.self.address, chainId)
              .getUserOpHash(),
          include0x: true,
        )
      : (await web3client.makeRPCCall<String>("eth_sendUserOperation", [
          op.opToJson(),
          entryPoint.self.address.toString(),
        ]));

  builder.resetOp();

  return ISendUserOperationResponse(
    userOpHash,
    () async {
      if (dryRun) {
        return null;
      }

      final end = DateTime.now().millisecondsSinceEpoch + waitTimeoutMs;
      final block = await web3client.getBlockNumber();
      while (DateTime.now().millisecondsSinceEpoch < end) {
        final userOperationEvent =
            entryPoint.self.event('UserOperationEvent');
        final filterEvent = await web3client
            .events(
              UserOperationEventEventFilter.events(
                contract: entryPoint.self,
                event: userOperationEvent,
                userOpHash: userOpHash,
                fromBlock: BlockNum.exact(block - 100),
              ),
            )
            .take(1)
            .first;
        if (filterEvent.transactionHash != null) {
          return filterEvent;
        }

        await Future.delayed(Duration(milliseconds: waitIntervalMs));
      }

      return null;
    },
  );
}