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 validerrors: 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 validerrors: 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 validerrors: 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 ABImethodName: string
- Method nameparams: any[]
- Parameters to validate
Returns:
ValidationResult
- Validation result:valid: boolean
- Whether the parameters are validerrors: 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 operationgrantedPermissions: 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 validatesecurityOptions: SecurityOptions
- Security options:maxValue?: string
- Maximum value allowedallowedContractAddresses?: string[]
- Whitelist of contract addressesdisallowedMethods?: string[]
- Blacklist of contract methodsmaxGasLimit?: string
- Maximum gas limit allowed
Returns:
SecurityValidationResult
- Security validation result:secure: boolean
- Whether the transaction is securewarnings: SecurityWarning[]
- Array of security warningscritical: 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 tracevalidationRules: TraceValidationRules
- Validation rules:maxStorageWrites?: number
- Maximum storage writes allowedmaxEventEmits?: number
- Maximum events allowedallowedStorageSlots?: string[]
- Whitelist of storage slotsdisallowedOpcodes?: 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 validateschema: 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