Skip to content

CyberAccount SDK

CyberAccount SDK is the official NPM package that implements CyberConnect V3 account abstraction.

Examples

Supported Chains

  • Optimism / Optimism Goerli
  • Polygon / Polygon Mumbai
  • Base / Base Goerli
  • Linea / Linea Goerli
  • Arbitrum / Arbitrum Goerli
  • opBNB

Installation

npm install @cyberlab/cyber-account

Getting Started

const cyberBundler = new CyberBundler({
  rpcUrl: "https://api.stg.cyberconnect.dev/cyberaccount/bundler/v1/rpc",
  appId: "ab23459a-32d7-4235-8129-77bd5de27fb1",
});
 
const walletClient = createWalletClient({
  chain: optimismGoerli,
  transport: custom(window.ethereum),
});
 
const accounts = await walletClient.requestAddresses();
const ownerAddress = accounts[0];
 
const sign = async (message) => {
  return await walletClient.signMessage({
    account: ownerAddress,
    message: { raw: message },
  });
};
 
// Optional: Paymaster
const cyberPaymaster = new CyberPaymaster({
  rpcUrl: "<rpcUrl>",
  appId: "<appId>",
  generateJwt: (cyberAccountAddress) => jwt,
});
 
const cyberAccount = new CyberAccount({
  chain: {
    id: 420,
    testnet: true,
  },
  owner: {
    address: ownerAddress,
    signMessage: sign,
  },
  bundler: cyberBundler,
  paymaster: cyberPaymaster,
});

Sending Native Token

cyberAccount.sendTransaction({
  to: "0x1e6754b227c6ae4b0ca61d82f79d60660737554a",
  value: parseUnits("0.0001", 18),
  data: "0x",
});
  • to - Address of the token receiver
  • value - The amount of the native token to send
  • data - The encoded data of the transaction

Sending ERC20 Tokens

Sending ERC20 tokens is different from sending the native token, it requires two steps:

  1. Encode the transaction data with the ERC20 contract ABI

    const encoded = encodeFunctionData({
      abi: erc20ABI,
      functionName: "transfer",
      args: [
        "0x85AAc6211aC91E92594C01F8c9557026797493AE",
        parseUnits("0.5", 18),
      ],
    });

    Argument list:

    • Address - The address of the token receiver
    • Amount - The amount of the token to send
  2. Send the transaction with the encoded data

    cyberAccount.sendTransaction({
      to: "0x32307adfFE088e383AFAa721b06436aDaBA47DBE",
      value: BigInt(0),
      data: encoded,
    });
  • to - Address of the ERC20 token contract
  • value - The amount of native token to send, it should be 0
  • data - The encoded ERC20 token transaction detail

Sending Batch Transaction (Beta)

npm install @cyberlab/cyber-account@beta
cyberAccount.sendTransaction([
  {
    to: "0x1e6754b227c6ae4b0ca61d82f79d60660737554a",
    value: parseUnits("0.0001", 18),
    data: "0x",
  },
  {
    to: "0x1e6754b227c6ae4b0ca61d82f79d60660737554a",
    value: parseUnits("0.0002", 18),
    data: "0x",
  },
  {
    to: "0x1e6754b227c6ae4b0ca61d82f79d60660737554a",
    value: parseUnits("0.0003", 18),
    data: "0x",
  },
]);

CyberAccount

class CyberAccount({chain, owner, bundler, paymaster})

Parameters

  • chain: The target chain of the CyberAccount is deployed on.

    type Chain = {
      id: number;
      testnet?: boolean;
      rpcUrl?: string;
    };
  • owner: The owner of a CyberAccount (Check Signing the user operation hash section for the details).

    type Owner = {
      address: Address;
      signMessage: async (message: string) => Promise<Hash>;
    }
  • bundler (CyberBundler): An instance of CyberBundler for handling the CyberAccount user operations.

  • paymaster (CyberPaymaster - Optional): An instance of CyberPaymaster for sponsoring the CyberAccount transactions.

Signing the user operation hash

By default, both Ethers and Viem will convert a message string to UTF-8 bytes when signing a message, for siging userOperationHash we need to avoid this conversion.

  • Signing userOperationHash using Viem
const walletClient = createWalletClient({
  chain: optimismGoerli,
  transport: custom(window.ethereum),
});
 
const accounts = await walletClient.requestAddresses();
const ownerAddress = accounts[0];
 
const sign = async (userOperationHash) => {
  return await walletClient.signMessage({
    account: ownerAddress,
    message: { raw: userOperationHash }, // pass the UO hash as a raw message
  });
};
  • Signing userOperationHash using Ethers
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
 
const sign = async (userOperationHash) => {
  return await signer.signMessage(hexToBytes(userOperationHash)); // convert the UO hash into bytes before passing into the signer
};

Properties

  • chain Chain - The target chain that the CyberAccount is deployed on.
  • owner Owner - The owner of the CyberAccount
  • address Address - The contract address of the CyberAccount
  • bundler CyberBundler - The Bundler for handling the CyberAccount user operations.
  • paymaster CyberPaymaster - The Paymaster for sponsoring the CyberAccount transactions.

Methods

  • isAccountDeployed: async () => boolean; - Checks if the CyberAccount is deployed.
  • getAccountInitCode: async () => Hex; - Returns the init code of the CyberAccount.
  • getCallData: (userOperationCallData: UserOperationCallData); - Get the encoded executable call data.
  • getSignature: (rawSig: Hash) => Hash; - Get the wrapped signature for validation.
  • sendTransaction: async (transcationData: TransactionData, {disablePaymaster?: boolean}) => Promise<Hash | null> - Send a transaction using the CyberAccount.
  • estimateTransaction: async (transcationData: TransactionData, {disablePaymaster?: boolean}) => Promise<EstimateUserOperationReturn> - Estimate the credit cost of a transaction using the CyberAccount if the CyberPaymaster is provided, otherwise return the estimated gas from the bundler.

CyberBundler

CyberBundler is a standard ERC-4337 bundler class.

const cyberBundler = new CyberBundler({
  rpcUrl: "https://api.stg.cyberconnect.dev/cyberaccount/bundler/v1/rpc",
  appId: "ab23459a-32d7-4235-8129-77bd5de27fb1",
});

RPC Urls

  • For development
    https://api.stg.cyberconnect.dev/cyberaccount/bundler/v1/rpc
  • For production
    https://api.cyberconnect.dev/cyberaccount/bundler/v1/rpc

Methods

  • sendUserOperation - Sends a user operation transaction to a bundler.
  • getUserOperationReceipt - Gets a user operation receipt based on the userOperationHash.
  • getUserOperationByHash - Returns a user operation based on the userOperationHash.
  • estimateUserOperationGas - Estimate the gas cost of a user operation.
  • supportedEntryPoints - Returns an array of the entryPoint addresses supported by the client.

CyberPaymaster

CyberPaymaster is a Paymaster class for sponsoring CyberAccount transactions.

const cyberPaymaster = new CyberPaymaster({
  rpcUrl: "<rpcUrl>",
  appId: "<appId>",
  generateJwt: (cyberAccountAddress) => jwt,
});

RPC Urls

  • For development
    https://api.stg.cyberconnect.dev/cyberaccount/paymaster/v1/rpc
  • For production
    https://api.cyberconnect.dev/cyberaccount/paymaster/v1/rpc

Methods

  • getUserCredit - Returns the user credit.
  • estimateUserOperation - Estimate the credit cost of a user operation.
  • sponsorUserOperation - Returns the complete ready-for-sign user operation with paymasterAndData.
  • rejectUserOperation - Rejects a user operation.
  • listPendingUserOperations - Returns a list of pending user operations.
  • topUp: ({amount, chainId, sender, to, writeContract}) => Promise<Hash> - Tops up the user credit, it returns the top up transaction hash.
    • amount - The amount of credit to top up.
    • chainId - The target chain id.
    • sender - (Optional) The address of the top up payer, it's CyberAccount owner address by default.,
    • to - (Optional) The address of the gas credit consumer, it's CyberAccount address by default.
    • writeContract: (request: TopUpContractRequest) => Promise<Hash> - (Optional) Overrides the default contract writing function.

RPC Errors

The RPC errors from the SDK are error instances from Viem. Two types of RPC errors can be thrown from the SDK:

  1. Provider RPC errors
  2. RPC Request errors
Properties
  • name - The RPC error name
  • code - The RPC error code
  • details - The RPC error details
  • shortMessage - The RPC error short message

We recommend using the code property to create a custom error handler.

Provider RPC Errors

codedescription
4001User denied message signature

Check all possible provider RPC errors here.

RPC Request Errors

Bundler RPC errors

For the bundler RPC errors, you can find the details in ERC-4337.

Paymaster RPC errors (CyberPaymaster)

CodeDescription
-32500Rejected by EP or Account
-32501Rejected by Paymaster
-32502Banned Opcode
-32503Short Deadline
-32504Banned or Throttled Paymaster
-32505Invalid Paymaster Stake
-32506Invalid Aggregator
-32507Invalid Signature
-32601Method Not Found
-32602Invalid Params
-32603Internal Error
-42000Invalid Chain ID
-42001Gas Price Beyond Limit
-42002Invalid Sponsor Sig Type
-42003Invalid Sponsor Sig
-42004Insufficient Credits
-42005Failed Get Price
-42006Account Balance Locked
-42007Pimlico Call Failed
-42008Stackup Call Failed
-42009Invalid Owner
-42010Invalid Calldata
-42012User Op Not Found
-42014Biconomy Call Failed
-42015Invalid Value
-42016User Op Not Estimated
-42017Alchemy Call Failed
-42018Exist Pending User Op
-42019Send User Op Wrong State
-42020PM and Data Timeout
-42021Invalid Sender
-42022Rate Limit
-42024Invalid App ID
-42025User Op Already Sent
-42026Invalid Auth Token
-42027Auth Not Allowed
-32521Execution Reverted