Skip to content

Send user operations

Once your users have been authenticated, you can start sending user operations! Account Kit makes it really easy to send user operations using React hooks.

To send user operations, you need to first create a SmartAccountClient using the createLightAccountClient function. Once you have a SmartAccountClient, you can use the sendUserOperation function to send user operations.

If you want to sponsor the gas for a user, see our guide.

Single user operation

send-user-operation.tsx
import React, { useState, useEffect } from "react";
import { Alert, View, Button } from "react-native";
import { User } from "@account-kit/signer";
import {
  createLightAccountClient,
  LightAccount,
} from "@account-kit/smart-contracts";
import { sepolia, alchemy } from "@account-kit/infra";
import { SmartAccountClient } from "@aa-sdk/core";
 
// import the signer
import { signer } from "./signer";
 
export default function MyOpSenderComponent() {
  const [user, setUser] = useState<User | null>(null);
  const [client, setClient] = useState<SmartAccountClient | null>(null);
  const [isSendingUserOperation, setIsSendingUserOperation] = useState(false);
 
  useEffect(() => {
    // get the user if they are already authenticated
    signer.getAuthDetails().then(setUser);
  }, []);
 
  useEffect(() => {
    if (user) {
      // Create a light account client for the authenticated user
      createLightAccountClient({
        signer,
        chain: sepolia,
        transport: alchemy({ apiKey: "YOUR_API_KEY" }),
      }).then((client) => {
        setClient(client);
      });
    }
  }, [user]);
 
  const handleSendUserOperation = async () => {
    if (!client) return;
 
    try {
      setIsSendingUserOperation(true);
      const { hash } = await client.sendUserOperation({
        uo: {
          target: "0xTARGET_ADDRESS",
          data: "0x",
          value: 0n,
        },
        account: client.account,
      });
 
      Alert.alert("User Operation Sent", hash);
    } catch (error) {
      Alert.alert("Error", "Error sending user operation");
    } finally {
      setIsSendingUserOperation(false);
    }
  };
 
  return (
    <View>
      <Button
        onPress={handleSendUserOperation}
        disabled={isSendingUserOperation}
        title={isSendingUserOperation ? "Sending..." : "Send UO"}
      />
    </View>
  );
}

Batch user operation

To send multiple user operations in a single call, simply pass an array of user operations to the sendUserOperation method.

batch-user-operation-component.tsx
import React, { useState, useEffect } from "react";
import { Alert, View, Button } from "react-native";
import { User } from "@account-kit/signer";
import {
  createLightAccountClient,
  LightAccount,
} from "@account-kit/smart-contracts";
import { sepolia, alchemy } from "@account-kit/infra";
import { SmartAccountClient } from "@aa-sdk/core";
 
// import the signer
import { signer } from "./signer";
 
export default function MyOpSenderComponent() {
  const [user, setUser] = useState<User | null>(null);
  const [client, setClient] = useState<SmartAccountClient | null>(null);
  const [isSendingUserOperation, setIsSendingUserOperation] = useState(false);
 
  useEffect(() => {
    // get the user if they are already authenticated
    signer.getAuthDetails().then(setUser);
  }, []);
 
  useEffect(() => {
    if (user) {
      // Create a light account client for the authenticated user
      createLightAccountClient({
        signer,
        chain: sepolia,
        transport: alchemy({ apiKey: "YOUR_API_KEY" }),
      }).then((client) => {
        setClient(client);
        setAccount(client.account);
      });
    }
  }, [user]);
 
  const handleSendUserOperation = async () => {
    if (!client) return;
 
    try {
      setIsSendingUserOperation(true);
 
      const { hash } = await client.sendUserOperation({
        uo: [
          {
            target: "0xTARGET_ADDRESS_1",
            data: "0x",
            value: 0n,
          },
          {
            target: "0xTARGET_ADDRESS_2",
            data: "0x",
            value: 0n,
          },
        ],
        account: client.account,
      });
 
      Alert.alert("User Operation Sent", hash);
    } catch (error) {
      Alert.alert("Error", "Error sending user operation");
    } finally {
      setIsSendingUserOperation(false);
    }
  };
 
  return (
    <View>
      <Button
        onClick={handleSendUserOperation}
        disabled={isSendingUserOperation}
        title={isSendingUserOperation ? "Sending..." : "Send UO"}
      />
    </View>
  );
}