Skip to main content

AA Validation Package

The @layerg-ua-sdk/aa-validation package provides validation utilities for ensuring the integrity and correctness of operations in the LayerG Universal Account system. This package helps developers validate user inputs, transaction data, and user operations before submitting them to the blockchain.

Transaction Validation

validateTransactionRequest

validateTransactionRequest(request: TransactionRequest): ValidationResult

Validates a transaction request for completeness and correctness.

Parameters:

  • request: TransactionRequest - Transaction request object

Returns:

  • ValidationResult - Validation result:
    • valid: boolean - Whether the transaction is valid
    • errors: ValidationError[] - Array of validation errors (if any)

Example:

import { validateTransactionRequest } from '@layerg-ua-sdk/aa-validation';

const txRequest = {
to: '0xContractAddress',
data: '0x1234...',
value: '1000'
};

const validation = validateTransactionRequest(txRequest);

if (validation.valid) {
console.log('Transaction is valid!');
} else {
console.error('Transaction validation failed:');
validation.errors.forEach(err => {
console.error(`- ${err.message}`);
});
}

validateUserOperation

validateUserOperation(userOp: UserOperation): ValidationResult

Validates a user operation for completeness and correctness.

Parameters:

  • userOp: UserOperation - User operation object

Returns:

  • ValidationResult - Validation result:
    • valid: boolean - Whether the user operation is valid
    • errors: ValidationError[] - Array of validation errors (if any)

Example:

import { validateUserOperation } from '@layerg-ua-sdk/aa-validation';

const userOp = {
sender: '0xSenderAddress',
nonce: '5',
initCode: '0x',
callData: '0x1234...',
callGasLimit: '100000',
verificationGasLimit: '150000',
preVerificationGas: '50000',
maxFeePerGas: '1000000000',
maxPriorityFeePerGas: '1000000000',
paymasterAndData: '0x',
signature: '0xSignature...'
};

const validation = validateUserOperation(userOp);

if (validation.valid) {
console.log('User operation is valid!');
} else {
console.error('User operation validation failed:');
validation.errors.forEach(err => {
console.error(`- ${err.message}`);
});
}

Input Validation

validateAddress

validateAddress(address: string): boolean

Validates if a string is a valid Ethereum address.

Parameters:

  • address: string - Ethereum address to validate

Returns:

  • boolean - Whether the address is valid

Example:

import { validateAddress } from '@layerg-ua-sdk/aa-validation';

const isValid = validateAddress('0x1234567890123456789012345678901234567890');
console.log(`Address is valid: ${isValid}`); // true

const isInvalid = validateAddress('0x123'); // Too short
console.log(`Address is valid: ${isInvalid}`); // false

validateChainId

validateChainId(chainId: number): boolean

Validates if a chain ID is supported by the LayerG Universal Account system.

Parameters:

  • chainId: number - Chain ID to validate

Returns:

  • boolean - Whether the chain ID is supported

Example:

import { validateChainId } from '@layerg-ua-sdk/aa-validation';

// U2U Mainnet
const isSupported = validateChainId(2484);
console.log(`Chain ID 2484 is supported: ${isSupported}`); // true

// Unknown chain
const isUnsupported = validateChainId(99999);
console.log(`Chain ID 99999 is supported: ${isUnsupported}`); // false

validateSignatureFormat

validateSignatureFormat(signature: string): boolean

Validates if a string has the correct format for an Ethereum signature.

Parameters:

  • signature: string - Signature string to validate

Returns:

  • boolean - Whether the signature format is valid

Example:

import { validateSignatureFormat } from '@layerg-ua-sdk/aa-validation';

const isValid = validateSignatureFormat('0x1234...'); // Check with a real signature
console.log(`Signature format is valid: ${isValid}`);

Smart Contract Validation

validateContractABI

validateContractABI(abi: any): ValidationResult

Validates a contract ABI for correctness.

Parameters:

  • abi: any - Contract ABI to validate

Returns:

  • ValidationResult - Validation result:
    • valid: boolean - Whether the ABI is valid
    • errors: ValidationError[] - Array of validation errors (if any)

Example:

import { validateContractABI } from '@layerg-ua-sdk/aa-validation';

const validation = validateContractABI(CONTRACT_ABI);

if (validation.valid) {
console.log('Contract ABI is valid!');
} else {
console.error('Contract ABI validation failed:');
validation.errors.forEach(err => {
console.error(`- ${err.message}`);
});
}

validateMethodParameters

validateMethodParameters(
abi: any,
methodName: string,
params: any[]
): ValidationResult

Validates parameters against a specific contract method.

Parameters:

  • abi: any - Contract ABI
  • methodName: string - Method name
  • params: any[] - Parameters to validate

Returns:

  • ValidationResult - Validation result:
    • valid: boolean - Whether the parameters are valid
    • errors: ValidationError[] - Array of validation errors (if any)

Example:

import { validateMethodParameters } from '@layerg-ua-sdk/aa-validation';

const params = [
'0xRecipientAddress',
'1000000000000000000' // 1 token
];

const validation = validateMethodParameters(
ERC20_ABI,
'transfer',
params
);

if (validation.valid) {
console.log('Method parameters are valid!');
} else {
console.error('Method parameter validation failed:');
validation.errors.forEach(err => {
console.error(`- ${err.message} (parameter: ${err.field})`);
});
}

Security Validation

validatePermissions

validatePermissions(
requiredPermissions: PermissionType[],
grantedPermissions: Permission[]
): boolean

Validates if all required permissions are granted.

Parameters:

  • requiredPermissions: PermissionType[] - Permissions required for an operation
  • grantedPermissions: Permission[] - Permissions granted to the caller

Returns:

  • boolean - Whether all required permissions are granted

Example:

import { validatePermissions } from '@layerg-ua-sdk/aa-validation';

const requiredPermissions = ['CALL_CONTRACT', 'TRANSFER_ASSET'];
const grantedPermissions = [
{ type: 'CALL_CONTRACT', validUntil: 1727934753 },
{ type: 'TRANSFER_ASSET', validUntil: 1727934753 }
];

const hasPermissions = validatePermissions(requiredPermissions, grantedPermissions);
console.log(`Has required permissions: ${hasPermissions}`); // true

validateTransactionSecurity

validateTransactionSecurity(
txRequest: TransactionRequest,
securityOptions: SecurityOptions
): SecurityValidationResult

Performs security validation on a transaction request.

Parameters:

  • txRequest: TransactionRequest - Transaction request to validate
  • securityOptions: SecurityOptions - Security options:
    • maxValue?: string - Maximum value allowed
    • allowedContractAddresses?: string[] - Whitelist of contract addresses
    • disallowedMethods?: string[] - Blacklist of contract methods
    • maxGasLimit?: string - Maximum gas limit allowed

Returns:

  • SecurityValidationResult - Security validation result:
    • secure: boolean - Whether the transaction is secure
    • warnings: SecurityWarning[] - Array of security warnings
    • critical: boolean - Whether any critical security issues were found

Example:

import { validateTransactionSecurity } from '@layerg-ua-sdk/aa-validation';

const txRequest = {
to: '0xContractAddress',
data: encodedFunctionData,
value: '1000000000000000' // 0.001 ETH
};

const securityOptions = {
maxValue: '10000000000000000', // Max 0.01 ETH
allowedContractAddresses: ['0xContractAddress', '0xAnotherAllowedContract'],
disallowedMethods: ['transferOwnership', 'setApprovalForAll'],
maxGasLimit: '500000'
};

const securityResult = validateTransactionSecurity(txRequest, securityOptions);

if (securityResult.secure) {
console.log('Transaction is secure!');
} else {
console.warn('Transaction security warnings:');
securityResult.warnings.forEach(warning => {
console.warn(`- ${warning.message} (${warning.severity})`);
});

if (securityResult.critical) {
console.error('Transaction has critical security issues!');
}
}

Data Validation

validateTraceResults

validateTraceResults(
trace: TransactionTrace,
validationRules: TraceValidationRules
): ValidationResult

Validates transaction trace results against security rules.

Parameters:

  • trace: TransactionTrace - Transaction execution trace
  • validationRules: TraceValidationRules - Validation rules:
    • maxStorageWrites?: number - Maximum storage writes allowed
    • maxEventEmits?: number - Maximum events allowed
    • allowedStorageSlots?: string[] - Whitelist of storage slots
    • disallowedOpcodes?: string[] - Blacklist of EVM opcodes

Returns:

  • ValidationResult - Validation result

Example:

import { validateTraceResults } from '@layerg-ua-sdk/aa-validation';

// Transaction trace from RPC call
const trace = await provider.send('debug_traceTransaction', [txHash]);

const validationRules = {
maxStorageWrites: 10,
maxEventEmits: 5,
disallowedOpcodes: ['SELFDESTRUCT', 'DELEGATECALL']
};

const validation = validateTraceResults(trace, validationRules);

if (validation.valid) {
console.log('Transaction trace is valid!');
} else {
console.error('Transaction trace validation failed:');
validation.errors.forEach(err => {
console.error(`- ${err.message}`);
});
}

validatePayload

validatePayload(
payload: any,
schema: ValidationSchema
): ValidationResult

Validates any data payload against a validation schema.

Parameters:

  • payload: any - Data payload to validate
  • schema: ValidationSchema - Schema defining validation rules

Returns:

  • ValidationResult - Validation result

Example:

import { validatePayload } from '@layerg-ua-sdk/aa-validation';

const userInfo = {
name: 'Alice',
email: '[email protected]',
age: 28
};

const userSchema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'number', minimum: 18 }
},
required: ['name', 'email']
};

const validation = validatePayload(userInfo, userSchema);

if (validation.valid) {
console.log('User info is valid!');
} else {
console.error('User info validation failed:');
validation.errors.forEach(err => {
console.error(`- ${err.message}`);
});
}

Bundle Validation

validateBundleRequest

validateBundleRequest(
bundleRequest: BundleRequest
): ValidationResult

Validates a bundle request before submitting it to the bundler.

Parameters:

  • bundleRequest: BundleRequest - Bundle request to validate

Returns:

  • ValidationResult - Validation result

Example:

import { validateBundleRequest } from '@layerg-ua-sdk/aa-validation';

const bundleRequest = {
chainId: 2484,
userOperations: [
userOp1,
userOp2
],
maxFeePerGas: '1500000000',
maxPriorityFeePerGas: '1000000000'
};

const validation = validateBundleRequest(bundleRequest);

if (validation.valid) {
console.log('Bundle request is valid!');
} else {
console.error('Bundle request validation failed:');
validation.errors.forEach(err => {
console.error(`- ${err.message}`);
});
}

Validation Types and Interfaces

The validation package exports various types and interfaces that can be used in your application:

import {
ValidationResult,
ValidationError,
SecurityValidationResult,
SecurityWarning,
ValidationSeverity,
ValidationSchema,
TraceValidationRules
} from '@layerg-ua-sdk/aa-validation';

ValidationResult

Interface describing a validation result:

interface ValidationResult {
valid: boolean;
errors: ValidationError[];
}

ValidationError

Interface describing a validation error:

interface ValidationError {
code: string;
message: string;
field?: string;
severity: ValidationSeverity;
}

ValidationSeverity

Enum defining validation severity levels:

enum ValidationSeverity {
INFO = 'info',
WARNING = 'warning',
ERROR = 'error',
CRITICAL = 'critical'
}

Validation Manager

ValidationManager

The ValidationManager class provides a centralized way to manage validators and perform validations.

import { ValidationManager } from '@layerg-ua-sdk/aa-validation';

// Create a new validation manager
const validationManager = new ValidationManager();

// Register custom validators
validationManager.registerValidator('customRule', (value) => {
// Return true if valid, false if invalid
return value !== null && value !== undefined;
});

// Validate using the manager
const result = validationManager.validate(
{ key: 'value' },
{
key: ['required', 'string', 'customRule']
}
);

if (result.valid) {
console.log('Validation passed!');
} else {
console.error('Validation failed:', result.errors);
}

Custom Validators

You can also create custom validators using the provided utilities:

import { createValidator, combineValidators } from '@layerg-ua-sdk/aa-validation';

// Create a custom validator
const isPositiveNumber = createValidator(
'isPositiveNumber',
(value) => typeof value === 'number' && value > 0,
'Value must be a positive number'
);

// Combine validators
const isValidAmount = combineValidators([
(value) => typeof value === 'string' || typeof value === 'number',
(value) => !isNaN(Number(value)),
(value) => Number(value) > 0
], 'Amount must be a valid positive number');

// Use the validators
const amountValidation = isValidAmount('100');
console.log(`Amount validation: ${amountValidation.valid}`);

const numberValidation = isPositiveNumber(42);
console.log(`Number validation: ${numberValidation.valid}`);

Next Steps

  • See the AA SDK for how to use these validation utilities in contract calls
  • Check AA Utils for general utility functions
  • Learn about Error Handling patterns for working with validation errors