CyberAccount SDK
CyberAccount SDK is the official NPM package that implements CyberConnect V3 account abstraction.
Examples
Supported Chains
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 receivervalue
- The amount of the native token to senddata
- The encoded data of the transaction
Sending ERC20 Tokens
Sending ERC20 tokens is different from sending the native token, it requires two steps:
-
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
-
Send the transaction with the encoded data
cyberAccount.sendTransaction({ to: "0x32307adfFE088e383AFAa721b06436aDaBA47DBE", value: BigInt(0), data: encoded, });
to
- Address of the ERC20 token contractvalue
- The amount of native token to send, it should be 0data
- 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 CyberAccountaddress
Address - The contract address of the CyberAccountbundler
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 theuserOperationHash
.getUserOperationByHash
- Returns a user operation based on theuserOperationHash
.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 withpaymasterAndData
.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:
- Provider RPC errors
- RPC Request errors
name
- The RPC error namecode
- The RPC error codedetails
- The RPC error detailsshortMessage
- The RPC error short message
We recommend using the code
property to create a custom error handler.
Provider RPC Errors
code | description |
---|---|
4001 | User 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)
Code | Description |
---|---|
-32500 | Rejected by EP or Account |
-32501 | Rejected by Paymaster |
-32502 | Banned Opcode |
-32503 | Short Deadline |
-32504 | Banned or Throttled Paymaster |
-32505 | Invalid Paymaster Stake |
-32506 | Invalid Aggregator |
-32507 | Invalid Signature |
-32601 | Method Not Found |
-32602 | Invalid Params |
-32603 | Internal Error |
-42000 | Invalid Chain ID |
-42001 | Gas Price Beyond Limit |
-42002 | Invalid Sponsor Sig Type |
-42003 | Invalid Sponsor Sig |
-42004 | Insufficient Credits |
-42005 | Failed Get Price |
-42006 | Account Balance Locked |
-42007 | Pimlico Call Failed |
-42008 | Stackup Call Failed |
-42009 | Invalid Owner |
-42010 | Invalid Calldata |
-42012 | User Op Not Found |
-42014 | Biconomy Call Failed |
-42015 | Invalid Value |
-42016 | User Op Not Estimated |
-42017 | Alchemy Call Failed |
-42018 | Exist Pending User Op |
-42019 | Send User Op Wrong State |
-42020 | PM and Data Timeout |
-42021 | Invalid Sender |
-42022 | Rate Limit |
-42024 | Invalid App ID |
-42025 | User Op Already Sent |
-42026 | Invalid Auth Token |
-42027 | Auth Not Allowed |
-32521 | Execution Reverted |