Skip to main content

AA Smart Contract Package

The @layerg-ua-sdk/aa-smc package provides tools and utilities for working with the LayerG Universal Account smart contracts. This package is essential for developers who need to deploy, interact with, or extend the Account Abstraction smart contracts.

Overview

This package includes contract ABIs, deployment utilities, and helper functions for interacting with the core Universal Account contracts in the LayerG ecosystem.

Contract Interfaces

Core Interfaces

The package exports TypeScript interfaces for all core UA contracts.

import { 
IAuthorizationModule,
IUniversalAccount,
IAccountFactory,
IBundler,
IEntryPoint
} from '@layerg-ua-sdk/aa-smc';

These interfaces provide strongly-typed access to contract methods and events, making it easier to interact with the contracts in a type-safe manner.

Contract ABIs

Available ABIs

The package includes ABIs for all core contracts in the LayerG Universal Account system:

import {
UNIVERSAL_ACCOUNT_ABI,
ACCOUNT_FACTORY_ABI,
ENTRY_POINT_ABI,
EIP7092_AUTHORIZATION_ABI,
DETERMINISTIC_DEPLOYER_ABI,
PAYMASTER_ABI
} from '@layerg-ua-sdk/aa-smc';

Example Usage:

import { ethers } from 'ethers';
import { UNIVERSAL_ACCOUNT_ABI } from '@layerg-ua-sdk/aa-smc';

// Create a contract instance using ethers.js
const accountContract = new ethers.Contract(
accountAddress,
UNIVERSAL_ACCOUNT_ABI,
provider
);

// Call contract methods
const owner = await accountContract.owner();
console.log(`Account owner: ${owner}`);

Deploy Helper Functions

deployAccountFactory

deployAccountFactory(
signer: ethers.Signer,
entryPointAddress: string
): Promise<string>

Deploys an Account Factory contract.

Parameters:

  • signer: ethers.Signer - Signer with funds to deploy the contract
  • entryPointAddress: string - Address of the ERC-4337 EntryPoint contract

Returns:

  • Promise<string> - Address of the deployed Account Factory

Example:

import { deployAccountFactory } from '@layerg-ua-sdk/aa-smc';
import { ethers } from 'ethers';

const provider = new ethers.providers.JsonRpcProvider('https://rpc.endpoint.url');
const signer = new ethers.Wallet(privateKey, provider);

const factoryAddress = await deployAccountFactory(
signer,
'0xEntryPointAddress'
);
console.log(`Account Factory deployed at: ${factoryAddress}`);

deployUniversalAccount

deployUniversalAccount(
signer: ethers.Signer,
factoryAddress: string,
owner: string,
salt?: string
): Promise<string>

Deploys a new Universal Account instance.

Parameters:

  • signer: ethers.Signer - Signer with funds to deploy the contract
  • factoryAddress: string - Address of the Account Factory
  • owner: string - Address that will own the Universal Account
  • salt?: string - Optional salt for deterministic address generation

Returns:

  • Promise<string> - Address of the deployed Universal Account

Example:

import { deployUniversalAccount } from '@layerg-ua-sdk/aa-smc';

const accountAddress = await deployUniversalAccount(
signer,
factoryAddress,
ownerAddress,
'0x123' // Optional salt
);
console.log(`Universal Account deployed at: ${accountAddress}`);

deployAuthorizationModule

deployAuthorizationModule(
signer: ethers.Signer,
entryPointAddress: string
): Promise<string>

Deploys an EIP-7092 Authorization Module.

Parameters:

  • signer: ethers.Signer - Signer with funds to deploy the contract
  • entryPointAddress: string - Address of the ERC-4337 EntryPoint contract

Returns:

  • Promise<string> - Address of the deployed Authorization Module

Example:

import { deployAuthorizationModule } from '@layerg-ua-sdk/aa-smc';

const moduleAddress = await deployAuthorizationModule(
signer,
entryPointAddress
);
console.log(`Authorization Module deployed at: ${moduleAddress}`);

Contract Helpers

getAccountImplementation

getAccountImplementation(
provider: ethers.providers.Provider,
factoryAddress: string
): Promise<string>

Gets the implementation address for Universal Accounts from a factory.

Parameters:

  • provider: ethers.providers.Provider - Blockchain provider
  • factoryAddress: string - Address of the Account Factory

Returns:

  • Promise<string> - Implementation address

Example:

import { getAccountImplementation } from '@layerg-ua-sdk/aa-smc';

const implementationAddress = await getAccountImplementation(
provider,
factoryAddress
);
console.log(`Implementation address: ${implementationAddress}`);

calculateAccountAddress

calculateAccountAddress(
factoryAddress: string,
owner: string,
salt?: string
): string

Calculates the counterfactual address for a Universal Account before deployment.

Parameters:

  • factoryAddress: string - Address of the Account Factory
  • owner: string - Owner address of the Universal Account
  • salt?: string - Optional salt for address generation

Returns:

  • string - Calculated counterfactual address

Example:

import { calculateAccountAddress } from '@layerg-ua-sdk/aa-smc';

const predictedAddress = calculateAccountAddress(
factoryAddress,
ownerAddress,
'0x123' // Optional salt
);
console.log(`Account will be deployed at: ${predictedAddress}`);

Contract Constants

The package provides various constants related to the Universal Account system:

import {
DEFAULT_ENTRY_POINT_ADDRESS,
CHAIN_IDS,
UNIVERSAL_ACCOUNT_INTERFACE_ID,
EIP7092_AUTHORIZATION_INTERFACE_ID
} from '@layerg-ua-sdk/aa-smc';

EntryPoint Addresses

Predefined EntryPoint addresses for supported networks:

// Get EntryPoint address for a specific chain
const entryPointAddress = DEFAULT_ENTRY_POINT_ADDRESS[CHAIN_IDS.U2U_MAINNET];

Interface IDs

Standard EIP interface IDs for feature detection:

// Check if contract implements Universal Account interface
const supportsUA = await contract.supportsInterface(UNIVERSAL_ACCOUNT_INTERFACE_ID);

Verification Functions

isUniversalAccount

isUniversalAccount(
provider: ethers.providers.Provider,
address: string
): Promise<boolean>

Verifies if an address is a deployed Universal Account.

Parameters:

  • provider: ethers.providers.Provider - Blockchain provider
  • address: string - Address to check

Returns:

  • Promise<boolean> - True if address is a Universal Account

Example:

import { isUniversalAccount } from '@layerg-ua-sdk/aa-smc';

const isUA = await isUniversalAccount(provider, accountAddress);
if (isUA) {
console.log(`${accountAddress} is a Universal Account`);
} else {
console.log(`${accountAddress} is NOT a Universal Account`);
}

getAccountType

getAccountType(
provider: ethers.providers.Provider,
address: string
): Promise<AccountType>

Determines the type of Universal Account at the given address.

Parameters:

  • provider: ethers.providers.Provider - Blockchain provider
  • address: string - Account address to check

Returns:

  • Promise<AccountType> - Account type ('G_ACCOUNT', 'ERC4337_ACCOUNT', 'UNKNOWN')

Example:

import { getAccountType } from '@layerg-ua-sdk/aa-smc';

const accountType = await getAccountType(provider, accountAddress);
console.log(`Account type: ${accountType}`);

Event Utilities

getAccountCreationEvents

getAccountCreationEvents(
provider: ethers.providers.Provider,
factoryAddress: string,
fromBlock?: number,
toBlock?: number
): Promise<AccountCreationEvent[]>

Retrieves account creation events from the specified factory.

Parameters:

  • provider: ethers.providers.Provider - Blockchain provider
  • factoryAddress: string - Account Factory address
  • fromBlock?: number - Optional starting block number
  • toBlock?: number - Optional ending block number

Returns:

  • Promise<AccountCreationEvent[]> - Array of account creation events

Example:

import { getAccountCreationEvents } from '@layerg-ua-sdk/aa-smc';

const events = await getAccountCreationEvents(
provider,
factoryAddress,
10000000 // Start from block 10,000,000
);

console.log(`Found ${events.length} account creation events`);
events.forEach(event => {
console.log(`Account: ${event.accountAddress}, Owner: ${event.owner}`);
});

Next Steps