Auto faucet claim and bonus with smart click.
// ==UserScript==
// @name EarnBitMoon Auto Claim
// @namespace http://tampermonkey.net/
// @version 2.1
// @description Auto faucet claim and bonus with smart click.
// @author Rubystance
// @license MIT
// @match https://earnbitmoon.club/*
// @grant none
// ==/UserScript==
(function () {
'use strict';
const MIN_DELAY = 1000;
const MAX_DELAY = 3000;
const CAPTCHA_TIMEOUT = 60000;
const RESULT_TIMEOUT = 20000;
const HARD_RELOAD_INTERVAL = 5 * 60 * 1000;
let alreadyClicked = false;
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const randomDelay = () => sleep(Math.floor(Math.random() * (MAX_DELAY - MIN_DELAY + 1)) + MIN_DELAY);
const smartClick = async (el, label = 'button') => {
if (!el) return;
try {
const eventResult = el.dispatchEvent(new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
}));
if (!eventResult) throw new Error('dispatchEvent blocked');
console.log(`[EarnBitMoon] Smart click (dispatch) on ${label}`);
} catch (err) {
console.warn(`[EarnBitMoon] dispatchEvent failed on ${label}, falling back to .click()`);
try {
el.click();
console.log(`[EarnBitMoon] Fallback click() successful on ${label}`);
} catch (e2) {
console.error(`[EarnBitMoon] Both click methods failed on ${label}`, e2);
}
}
};
const isCaptchaSolved = () => {
const turnstile = document.querySelector('input[name="cf-turnstile-response"]');
const recaptcha = document.querySelector('#g-recaptcha-response');
const hcaptcha = document.querySelector('textarea[name="h-captcha-response"]');
const icon = document.querySelector('.iconcaptcha-wrap.solved, .iconcaptcha-done');
return (
(turnstile && turnstile.value.length > 10) ||
(recaptcha && recaptcha.value.length > 10) ||
(hcaptcha && hcaptcha.value.length > 10) ||
icon
);
};
const isButtonClickable = btn => {
if (!btn) return false;
const style = window.getComputedStyle(btn);
return (
style.display !== 'none' &&
style.visibility !== 'hidden' &&
style.opacity !== '0' &&
!btn.disabled &&
btn.offsetParent !== null
);
};
async function waitForCaptchaAndPress() {
console.log('[EarnBitMoon] Waiting for CAPTCHA and "Press & Win"...');
const startTime = Date.now();
while (Date.now() - startTime < CAPTCHA_TIMEOUT) {
const pressBtn = document.querySelector('button.zxz');
if (isCaptchaSolved() && isButtonClickable(pressBtn) && !alreadyClicked) {
console.log('[EarnBitMoon] CAPTCHA solved. Claiming reward...');
alreadyClicked = true;
await randomDelay();
await smartClick(pressBtn, '"Press & Win"');
waitForResultOrReload();
return;
}
await sleep(5000);
}
console.warn('[EarnBitMoon] CAPTCHA timeout. Reloading...');
location.reload();
}
async function waitForResultOrReload() {
console.log('[EarnBitMoon] Waiting for claim result...');
const start = Date.now();
while (Date.now() - start < RESULT_TIMEOUT) {
const restartBtn = document.querySelector('.fa-rotate-right');
const closeBtn = document.querySelector('.fa-xmark');
if (restartBtn) {
console.log('[EarnBitMoon] Claim successful.');
return;
}
if (closeBtn && !restartBtn) {
console.warn('[EarnBitMoon] Only close button visible. Reloading...');
location.reload();
return;
}
await sleep(2000);
}
console.warn('[EarnBitMoon] No result after timeout. Reloading...');
location.reload();
}
async function clickRollNow() {
await randomDelay();
const rollBtn = [...document.querySelectorAll('button')].find(btn =>
btn.innerText.includes('ROLL NOW') && btn.dataset.toggle === "modal"
);
if (rollBtn) {
console.log('[EarnBitMoon] Clicking "ROLL NOW"...');
await smartClick(rollBtn, '"ROLL NOW"');
} else {
console.warn('[EarnBitMoon] "ROLL NOW" button not found.');
}
}
async function checkAndGoToBonus() {
const bonusLink = [...document.querySelectorAll('a.btn')].find(a =>
a.innerText.includes('Daily Bonus') && a.innerText.includes('1')
);
if (bonusLink) {
console.log('[EarnBitMoon] Daily Bonus available. Going to bonus page...');
bonusLink.click();
return true;
}
return false;
}
async function handleBonusPage() {
console.log('[EarnBitMoon] On bonus page...');
const start = Date.now();
while (Date.now() - start < 15000) {
const claimBtn = [...document.querySelectorAll('button')].find(btn =>
btn.innerText.includes('CLAIM DAILY BONUS')
);
if (claimBtn) {
console.log('[EarnBitMoon] Clicking "CLAIM DAILY BONUS"...');
await randomDelay();
await smartClick(claimBtn, '"CLAIM DAILY BONUS"');
const modalStart = Date.now();
while (Date.now() - modalStart < 10000) {
const innerClaim = document.querySelector('#dailyBonus');
if (innerClaim) {
console.log('[EarnBitMoon] Clicking "Claim Coins"...');
await randomDelay();
await smartClick(innerClaim, '"Claim Coins"');
await sleep(4000);
location.href = '/faucet.html';
return;
}
await sleep(1000);
}
console.warn('[EarnBitMoon] "Claim Coins" button not found. Reloading...');
location.reload();
return;
}
await sleep(1000);
}
console.warn('[EarnBitMoon] Bonus claim button not detected. Returning to faucet...');
location.href = '/faucet.html';
}
function hardReloadTimer() {
setTimeout(() => {
console.log('[EarnBitMoon] Hard reload triggered after 5 minutes.');
location.reload();
}, HARD_RELOAD_INTERVAL);
}
async function main() {
console.log(`[EarnBitMoon] Current page: ${location.pathname}`);
if (location.pathname === '/bonus.html') {
await handleBonusPage();
return;
}
const wentToBonus = await checkAndGoToBonus();
if (wentToBonus) return;
await sleep(2000);
await clickRollNow();
await waitForCaptchaAndPress();
hardReloadTimer();
}
window.addEventListener('load', main);
})();