Skip to content

Instantly share code, notes, and snippets.

@gr1zix
Created July 13, 2025 11:13
Show Gist options
  • Save gr1zix/631104c5cf4c589dff523a09e8c763ba to your computer and use it in GitHub Desktop.
Save gr1zix/631104c5cf4c589dff523a09e8c763ba to your computer and use it in GitHub Desktop.
FS swap from usdc
const usdcInput = '/html/body/div[1]/div[2]/main/div[1]/div[1]/div/div/div[2]/div/div[1]/div[2]/input';
const reviewSwapButton = '/html/body/div/div[2]/main/div[1]/div[1]/div/div/div[2]/button'
const confirmSwapButton = '/html/body/div/div[2]/main/div[1]/div[1]/div/div/div[3]/div[2]/button'
async function sendForm(isRetry = false) {
try {
if (isRetry) {
await sleep(200)
}
if (!isRetry) {
const usdcAmountInputElement = getElementByXpath(usdcInput);
if (!usdcAmountInputElement) {
throw new Error('Amount input not found');
}
setReactInputValue(usdcAmountInputElement, getRandomAmount());
await sleep(300);
}
const reviewSwapButtonElement = await waitForReviewSwapButton(reviewSwapButton);
if (!reviewSwapButtonElement) {
throw new Error('Add form button not found');
}
reviewSwapButtonElement.click()
await sleep(150)
const confirmSwapButtonEl = getElementByXpath(confirmSwapButton);
if (!confirmSwapButtonEl) {
await sendForm(true)
}
confirmSwapButtonEl.click();
await sleep(200)
const closeSwapButtonEl = document.querySelector('body > div > div.flex-1.flex.flex-col.overflow-hidden > main > div.flex.flex-col.gap-5.overflow-x-hidden.md\\:gap-7.items-center.pb-5.md\\:pb-10.md\\:pt-7 > div:nth-child(1) > div > div > div.MuiBox-root.css-1is9dp0 > div.MuiBox-root.css-n6dxc2 > svg');
const clickEvent = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window,
});
closeSwapButtonEl.dispatchEvent(clickEvent);
await sleep(100)
return true;
} catch (error) {
console.error('Error during form submission:', error);
return false;
}
}
function waitForReviewSwapButton(reviewSwapButton, timeout = 12000) {
return new Promise((resolve, reject) => {
const element = getElementByXpath(reviewSwapButton);
if (element && element.textContent.includes('Review Swap')) {
return resolve(element);
}
const observer = new MutationObserver(() => {
const currentElement = getElementByXpath(reviewSwapButton);
if (currentElement && currentElement.textContent.includes('Review Swap')) {
observer.disconnect();
resolve(currentElement);
}
});
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true,
});
setTimeout(() => {
observer.disconnect();
reject(new Error('Review Swap button not found within timeout'));
}, timeout);
});
}
async function runIterations(iterations, delayBetweenIterationsFrom = 500, delayBetweenIterationsTo = 2000) {
let isCancelled = false;
let completedIterations = 0;
// Function to cancel execution
const cancel = () => {
isCancelled = true;
};
// To be able to cancel from console, we can expose `cancel` function globally
window.cancelScript = cancel;
console.log("To stop execution, type 'window.cancelScript()' in the console.");
for (let i = 0; i < iterations && !isCancelled; i++) {
console.log(`Starting iteration ${i + 1}/${iterations}`);
const success = await sendForm();
if (!success) {
console.log(`Iteration ${i + 1} failed. Stopping.`);
break;
}
completedIterations++;
console.log(`Iteration ${i + 1} completed successfully.`);
if (i < iterations - 1 && !isCancelled) {
const delay = getRandom(delayBetweenIterationsFrom, delayBetweenIterationsTo)
console.log(`Waiting for ${delay}ms before next iteration...`);
await sleep(delay);
}
}
console.log(`Completed ${completedIterations} of ${iterations} iterations.`);
window.cancelScript = undefined; // Clean up
return { completed: completedIterations, cancelled: isCancelled };
}
function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
function getRandomAmount(min = 0.5, max = 5) {
return (Math.random() * (max - min) + min).toFixed(3);
}
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min) ) + min;
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function setReactInputValue(element, value) {
try {
if (!element || typeof element.value === 'undefined') {
throw new Error('Element is not a valid input');
}
const descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
if (!descriptor || !descriptor.set) {
element.value = value;
element.dispatchEvent(new Event('input', { bubbles: true }));
return;
}
descriptor.set.call(element, value);
const events = ['input', 'change', 'blur'];
events.forEach(type => {
element.dispatchEvent(new Event(type, { bubbles: true }));
});
} catch (error) {
console.error('Error in setReactInputValue:', error);
if (element) {
element.value = value;
element.dispatchEvent(new Event('input', { bubbles: true }));
}
}
}
/**
* 30 - iterations
* 500 - start of range delay in ms between iterations
* 1500 - end of range delay in ms between iterations
*/
runIterations(10, 500, 1500);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment