contract DeployAndCall {
  /// @dev The AccountFactory to use for account deployments
  AccountFactory constant ACCOUNT_FACTORY = AccountFactory(0xe925f84cA9Dd5b3844fC424861D7bDf9485761B6);

  /// @dev Deploys an account for the given owner and executes callData on the account
  /// @param owner Address of the account owner
  /// @param callData The call to execute on the account after deployment
  function deployAndCall(address owner, bytes memory callData) external payable {
    address account = ACCOUNT_FACTORY.deployAccount(owner);

    if (callData.length > 0) {
      assembly {
        let result := call(gas(), account, callvalue(), add(callData, 0x20), mload(callData), 0, 0)
        returndatacopy(0, 0, returndatasize())
        switch result
        case 0 {
          revert(0, returndatasize())
        }
        default {
          return(0, returndatasize())
        }
      }
    }
  }
}
/// @title DeployAndCall
/// @notice This contract contains a function to batch account deploy and call into one transaction
function deployAndCall(address owner, bytes memory callData) external payable {
  address account = ACCOUNT_FACTORY.deployAccount(owner);

  if (callData.length > 0) {
    assembly {
      let result := call(gas(), account, callvalue(), add(callData, 0x20), mload(callData), 0, 0)
      returndatacopy(0, 0, returndatasize())
      switch result
      case 0 {
        revert(0, returndatasize())
      }
      default {
        return(0, returndatasize())
      }
    }
  }
}

/// @dev Deploys an account for the given owner and executes callData on the account
/// @param owner Address of the account owner
/// @param callData The call to execute on the account after deployment