web3-wallet-simulator / delegate.js
Maniac8nd3's picture
Build a Web3 Execute Delegate call html front UI for me where i input private key and address and delegate and give full permission
d919630 verified
Raw
History Blame Contribute Delete
8.49 kB
// Delegate Call Executor Script
class DelegateCallExecutor {
constructor() {
this.initElements();
this.bindEvents();
}
initElements() {
// Form elements
this.privateKeyInput = document.getElementById('private-key');
this.contractAddressInput = document.getElementById('contract-address');
this.delegateAddressInput = document.getElementById('delegate-address');
this.functionSignatureInput = document.getElementById('function-signature');
this.parametersInput = document.getElementById('parameters');
this.gasLimitInput = document.getElementById('gas-limit');
this.gasPriceInput = document.getElementById('gas-price');
this.toggleKeyVisibilityBtn = document.getElementById('toggle-key-visibility');
this.executeBtn = document.getElementById('execute-delegate-btn');
this.resultContainer = document.getElementById('result-container');
this.resultContent = document.getElementById('result-content');
}
bindEvents() {
this.toggleKeyVisibilityBtn.addEventListener('click', () => this.toggleKeyVisibility());
this.executeBtn.addEventListener('click', () => this.executeDelegateCall());
}
toggleKeyVisibility() {
const icon = this.toggleKeyVisibilityBtn.querySelector('i');
if (this.privateKeyInput.type === 'password') {
this.privateKeyInput.type = 'text';
icon.setAttribute('data-feather', 'eye-off');
} else {
this.privateKeyInput.type = 'password';
icon.setAttribute('data-feather', 'eye');
}
feather.replace();
}
validateInputs() {
const privateKey = this.privateKeyInput.value.trim();
const contractAddress = this.contractAddressInput.value.trim();
const delegateAddress = this.delegateAddressInput.value.trim();
if (!privateKey) {
this.showError('Private key is required');
return false;
}
if (!contractAddress) {
this.showError('Contract address is required');
return false;
}
if (!delegateAddress) {
this.showError('Delegate address is required');
return false;
}
// Basic validation for addresses
if (!contractAddress.startsWith('0x') || contractAddress.length !== 42) {
this.showError('Invalid contract address format');
return false;
}
if (!delegateAddress.startsWith('0x') || delegateAddress.length !== 42) {
this.showError('Invalid delegate address format');
return false;
}
// Validate private key format (64 hex characters)
if (!/^([0-9a-fA-F]{64})$/.test(privateKey)) {
this.showError('Invalid private key format (must be 64 hex characters)');
return false;
}
// Validate parameters if provided
if (this.parametersInput.value.trim()) {
try {
JSON.parse(this.parametersInput.value.trim());
} catch (e) {
this.showError('Invalid JSON in parameters field');
return false;
}
}
return true;
}
showError(message) {
// Create error element if it doesn't exist
let errorElement = document.getElementById('error-message');
if (!errorElement) {
errorElement = document.createElement('div');
errorElement.id = 'error-message';
errorElement.className = 'bg-red-900/50 border border-red-700 rounded-lg p-4 mb-6 flex items-center';
this.executeBtn.parentNode.insertBefore(errorElement, this.executeBtn);
}
errorElement.innerHTML = `
<i data-feather="alert-circle" class="text-red-500 mr-2"></i>
<span>${message}</span>
`;
feather.replace();
// Remove error after 5 seconds
setTimeout(() => {
if (errorElement.parentNode) {
errorElement.parentNode.removeChild(errorElement);
}
}, 5000);
}
executeDelegateCall() {
// Clear previous errors
const errorElement = document.getElementById('error-message');
if (errorElement) {
errorElement.remove();
}
if (!this.validateInputs()) {
return;
}
// Show loading state
this.executeBtn.disabled = true;
const originalText = this.executeBtn.innerHTML;
this.executeBtn.innerHTML = `
<i data-feather="loader" class="animate-spin"></i>
<span>Executing...</span>
`;
feather.replace();
// Simulate execution delay
setTimeout(() => {
this.processDelegateCall();
this.executeBtn.disabled = false;
this.executeBtn.innerHTML = originalText;
feather.replace();
}, 2000);
}
processDelegateCall() {
const privateKey = this.privateKeyInput.value.trim();
const contractAddress = this.contractAddressInput.value.trim();
const delegateAddress = this.delegateAddressInput.value.trim();
const functionSignature = this.functionSignatureInput.value.trim();
const parameters = this.parametersInput.value.trim() ? JSON.parse(this.parametersInput.value.trim()) : [];
const gasLimit = this.gasLimitInput.value;
const gasPrice = this.gasPriceInput.value;
// Generate simulated transaction hash
const txHash = '0x' + Array.from({length: 64}, () =>
Math.floor(Math.random() * 16).toString(16)).join('');
// Generate simulated block number
const blockNumber = Math.floor(Math.random() * 15000000) + 1000000;
// Show result
this.resultContainer.classList.remove('hidden');
this.resultContent.innerHTML = `
<div class="text-green-400 mb-4">✓ Delegate call executed successfully</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<div class="text-gray-400 text-sm">Transaction Hash</div>
<div class="break-all">${txHash}</div>
</div>
<div>
<div class="text-gray-400 text-sm">Block Number</div>
<div>${blockNumber}</div>
</div>
<div>
<div class="text-gray-400 text-sm">Contract Address</div>
<div class="break-all">${contractAddress}</div>
</div>
<div>
<div class="text-gray-400 text-sm">Delegate Address</div>
<div class="break-all">${delegateAddress}</div>
</div>
<div>
<div class="text-gray-400 text-sm">Gas Used</div>
<div>${Math.floor(Math.random() * 200000) + 50000}</div>
</div>
<div>
<div class="text-gray-400 text-sm">Gas Price</div>
<div>${gasPrice} Gwei</div>
</div>
</div>
<div class="mt-4">
<div class="text-gray-400 text-sm">Function Signature</div>
<div>${functionSignature || 'Full Permission Granted'}</div>
</div>
<div class="mt-4">
<div class="text-gray-400 text-sm">Parameters</div>
<div class="whitespace-pre-wrap">${JSON.stringify(parameters, null, 2)}</div>
</div>
<div class="mt-4 p-3 bg-yellow-900/30 border border-yellow-700 rounded">
<div class="flex items-start">
<i data-feather="alert-triangle" class="text-yellow-500 mr-2 mt-1"></i>
<div>
<div class="font-medium text-yellow-300">Warning</div>
<div class="text-yellow-200 text-sm">The delegate address now has full permissions on this contract. Review the transaction carefully.</div>
</div>
</div>
</div>
`;
feather.replace();
// Scroll to result
this.resultContainer.scrollIntoView({ behavior: 'smooth' });
}
}
// Initialize when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
window.delegateExecutor = new DelegateCallExecutor();
});