📜 Scripting
Open sourced scripts for anyone to use.
Introduction To level the playing field, we have made browser scripts available to everyone. This scripting type does not need you to provide your private key to a cloud service. These scripting tools works as a browser add-on that automatically calls functions on the website without you having to manually do it. The script triggers the function, and accepts the wallet confirmation popup. It's simply put an automated mouse clicker. You can configure the scripts to operate based on your preference in crime types. These scripting tools relies on you using Rabby wallet. Scripting vs. Helper bots
Operational cost
Network gas
Helper Credits
Supports vault
No
Yes
Rank XP
Slower
Faster
Cash rewards
Lower
Higher
Risk
Higher
Lower
External requirements
PC turned on at all times
No requirements
Overall expense
Lower
Higher
Creates on-chain activity
Yes
No
Supports bullet buy
No
Yes
Supports Bust out
Yes
No
Required to Double rank
No
Yes
Wallet compatibility
Rabby
All wallets
Game updates
Needs modification
Always works
Frontend dependency
Yes
No
Click limit
Yes
No
Works with perks
4 perks
28 perks
Works on mobile
No
Yes
Note: We will not be maintaining the scripts on a frequent basis or per update. We will update scripts in batches, meaning that you might have period of time where certain functions does not work if you are not able to modify them yourself. The absolute fastest way to build your character up in MAFIA is by running both at the same time. But this is expensive, and is only for the very competitive & dedicated players. Installing scripts. So you made the decision to use scripts! Here's how you get started. Step 1: Install Tamper monkey browser add on. It supports Chrome, Firefox, Edge, Opera and Safari. Find all store links here: https://www.tampermonkey.net/ Remember to allow developer mode Step 2: Download and install AutoIT 3 with Rabby wallet auto accepter. Download files here. After you have installed it, you open the software and then open the .au3 file. This will now automatically accept prompts to your Rabby wallet.
Step 3: Now navigate to your Tampermonkey extension. Click "Create a new script"
Step 4: Paste this code into the new user script you created. Then save it. File -> Save
// MasterScript - Mafia
// ==UserScript==
// @name Mafia – Master Helper (rank-aware capacity, 2025-09-21)
// @namespace https://tampermonkey.net/
// @version 3.6
// @description Automates bust-out, market buy/sell, travel, crimes-first loop, car theft & kill-skill — now with rank-aware capacity detection (“Max X units/kg”) on both Booze and Narcotics pages.
// @author Godfather
// @match https://bnbmafia.io/*
// @grant none
// ==/UserScript==
/*──────────────────────── GLOBAL CONFIG & MENUS ───────────────────────*/
(function () {
'use strict';
const LS_KEY = 'bnbmafia_script_cfg';
/* item groups */
const BOOZE = ['Whiskey', 'Tequila', 'Cognac'];
const NARCO = ['Cocaine', 'Morphine', 'Opium', 'Heroin'];
/* preset function → returns {buyLimit,sellFloor} */
function preset(mode) {
const buyLimit = {};
const sellFloor = {};
if (mode === 'xp') { // “Get XP” preset
BOOZE.forEach(i => { buyLimit[i] = 4_000; sellFloor[i] = 4_000; });
NARCO.forEach(i => { buyLimit[i] = 10_000; sellFloor[i] = 10_000; });
} else { // “Make Money” preset
buyLimit['Cognac'] = 3_000; sellFloor['Cognac'] = 4_500;
buyLimit['Tequila'] = 3_500; sellFloor['Tequila'] = 5_000;
buyLimit['Whiskey'] = 2_800; sellFloor['Whiskey'] = 3_500;
buyLimit['Cocaine'] = 8_000; sellFloor['Cocaine'] = 10_000;
buyLimit['Opium'] = 7_000; sellFloor['Opium'] = 11_000;
buyLimit['Heroin'] = 8_000; sellFloor['Heroin'] = 11_000;
buyLimit['Morphine'] = 9_000; sellFloor['Morphine'] = 12_000;
}
return { buyLimit, sellFloor };
}
/* default cfg */
const defaultCfg = {
/* slot selections */
carIndex : 1,
crimeIndex : 1,
killIndex : 1,
/* timings */
redirectMinutes : 4,
clickDelaySec : 45,
/* misc */
travelVehicle : 'Airplane',
mode : 'money', // "money" | "xp"
enabledActivities: {
jail : true,
killskill : true,
travel : true,
market : true,
crimes : true,
nickcar : true
},
...preset('money')
};
/* restore stored cfg */
const stored = JSON.parse(localStorage.getItem(LS_KEY) || '{}');
const cfg = Object.assign({}, defaultCfg, stored);
cfg.enabledActivities = Object.assign({}, defaultCfg.enabledActivities, stored.enabledActivities);
/* ensure buy/sell reflect current mode */
const modeLimits = preset(cfg.mode);
cfg.buyLimit = modeLimits.buyLimit;
cfg.sellFloor = modeLimits.sellFloor;
/* expose */
window.BNBMAFIA_AUTOSCRIPT_CFG = cfg;
const saveCfg = () => localStorage.setItem(LS_KEY, JSON.stringify(cfg));
let reloadTimer = null;
const triggerReload = () => { if (!reloadTimer) reloadTimer = setTimeout(() => location.reload(), 300); };
/*────────── MAIN floating menu ──────────*/
function createMainMenu() {
const m = document.createElement('div');
Object.assign(m.style, {
position:'fixed', top:'5cm', right:'10px', zIndex:9999,
background:'rgba(0,0,0,0.88)', color:'#fff', padding:'10px',
borderRadius:'8px', fontFamily:'sans-serif', fontSize:'13px', lineHeight:'1.3em'
});
m.innerHTML = `
<label style="display:block;margin-bottom:4px;">
Redirect every:
<select id="redirSel">
<option value="1">1 min</option><option value="2">2 min</option><option value="3">3 min</option><option value="4">4 min</option><option value="5">5 min</option>
</select>
</label>
<label style="display:block;margin-bottom:4px;">
Click delay:
<select id="clickSel">
<option value="15">15 s</option><option value="30">30 s</option><option value="45">45 s</option><option value="60">60 s</option>
</select>
</label>
<label style="display:block;margin-bottom:4px;">
Travel vehicle:
<select id="travelSel">
<option>Airplane</option><option>Train</option><option>Car/Motorcycle</option>
</select>
</label>
<label style="display:block;margin-bottom:4px;">
Car-theft slot
<select id="carSel"><option>1</option><option>2</option><option>3</option><option>4</option></select>
</label>
<label style="display:block;margin-bottom:4px;">
Crime slot
<select id="crimeSel"><option>1</option><option>2</option><option>3</option><option>4</option></select>
</label>
<label style="display:block;margin-bottom:4px;">
Kill-skill slot
<select id="killSel"><option>1</option><option>2</option><option>3</option></select>
</label>
<hr style="margin:6px 0;border:0;border-top:1px solid #555;">
<label><input type="checkbox" id="actJail"> Bust-out</label><br>
<label><input type="checkbox" id="actKill"> Kill-skill</label><br>
<label><input type="checkbox" id="actTravel"> Travel</label><br>
<label><input type="checkbox" id="actMarket"> Market</label><br>
<label><input type="checkbox" id="actCrimes"> Crimes</label><br>
<label><input type="checkbox" id="actNick"> Car theft</label>
<hr style="margin:6px 0;border:0;border-top:1px solid #555;">
<label style="display:block;margin-bottom:4px;">
Price preset:
<select id="modeSel">
<option value="money">Make Money</option>
<option value="xp">Get XP</option>
</select>
</label>
<button id="btnFromCrime"
style="display:block;width:100%;margin-top:4px;padding:5px;border:1px solid #888;background:#222;color:#fff;border-radius:4px;">
Force Crimes
</button>
`;
document.body.appendChild(m);
/* Init values */
m.querySelector('#redirSel').value = cfg.redirectMinutes;
m.querySelector('#clickSel').value = cfg.clickDelaySec;
m.querySelector('#travelSel').value = cfg.travelVehicle;
m.querySelector('#carSel').value = cfg.carIndex;
m.querySelector('#crimeSel').value = cfg.crimeIndex;
m.querySelector('#killSel').value = cfg.killIndex;
m.querySelector('#modeSel').value = cfg.mode;
m.querySelector('#actJail').checked = cfg.enabledActivities.jail;
m.querySelector('#actKill').checked = cfg.enabledActivities.killskill;
m.querySelector('#actTravel').checked = cfg.enabledActivities.travel;
m.querySelector('#actMarket').checked = cfg.enabledActivities.market;
m.querySelector('#actCrimes').checked = cfg.enabledActivities.crimes;
m.querySelector('#actNick').checked = cfg.enabledActivities.nickcar;
/* Handlers */
m.querySelector('#redirSel').onchange = e => { cfg.redirectMinutes = +e.target.value; saveCfg(); triggerReload(); };
m.querySelector('#clickSel').onchange = e => { cfg.clickDelaySec = +e.target.value; saveCfg(); triggerReload(); };
m.querySelector('#travelSel').onchange = e => { cfg.travelVehicle = e.target.value; saveCfg(); triggerReload(); };
m.querySelector('#carSel').onchange = e => { cfg.carIndex = +e.target.value; saveCfg(); triggerReload(); };
m.querySelector('#crimeSel').onchange = e => { cfg.crimeIndex = +e.target.value; saveCfg(); triggerReload(); };
m.querySelector('#killSel').onchange = e => { cfg.killIndex = +e.target.value; saveCfg(); triggerReload(); };
m.querySelector('#modeSel').onchange = e => {
cfg.mode = e.target.value;
Object.assign(cfg, preset(cfg.mode));
saveCfg(); triggerReload();
};
const map = {actJail:'jail', actKill:'killskill', actTravel:'travel', actMarket:'market', actCrimes:'crimes', actNick:'nickcar'};
Object.keys(map).forEach(id =>
m.querySelector('#'+id).onchange = e => { cfg.enabledActivities[map[id]] = e.target.checked; saveCfg(); triggerReload(); });
m.querySelector('#btnFromCrime').onclick = () => {
sessionStorage.setItem('BNBMAFIA_FORCE_CRIME', '1');
location.replace('/crimes');
};
}
(document.readyState === 'loading')
? window.addEventListener('DOMContentLoaded', createMainMenu)
: createMainMenu();
})();
/*──────────────────── SHARED HELPERS ───────────────────*/
(function () {
'use strict';
window.BNBMAFIA_COOLDOWN_ACTIVE = root => {
const m = /Next\s+[^:]+?:\s*([^\n]+)/i.exec(root?.textContent ?? '');
if (!m) return false;
return !/^(Now|0s?|0m?:?0s?)$/i.test(m[1].trim());
};
window.BNBMAFIA_OVERLAY_HIDDEN = () => {
const d = document.querySelector('div[aria-hidden="true"]');
return d ? getComputedStyle(d).opacity === '0' : false;
};
window.BNBMAFIA_ORDERED_ATTEMPTS = sel =>
[...document.querySelectorAll(`${sel} button`)]
.filter(b => /attempt\s+now/i.test(b.textContent) && !b.disabled)
.sort((a, b) => a.getBoundingClientRect().left - b.getBoundingClientRect().left);
})();
/* helper shortcuts */
const _cfgDelaySec = () => (window.BNBMAFIA_AUTOSCRIPT_CFG?.clickDelaySec || 45); // seconds
const _cfgRedirectMs = () => (window.BNBMAFIA_AUTOSCRIPT_CFG?.redirectMinutes || 4) * 60_000; // ms
/*──────────────────────────── MODULES ─────────────────────────────*/
/*================ AUTO BUST-OUT ================*/
(function () {
'use strict';
console.log('[Bust-out] module loaded');
const priority = ['Elite OGs','The Syndicate','Original Gangsters','Disturbed','GoodFellas'];
const num = t => parseInt(t.replace(/,/g,''),10)||0;
function go(){
if(!window.BNBMAFIA_OVERLAY_HIDDEN()) return;
if(window.BNBMAFIA_COOLDOWN_ACTIVE(document)) return;
let best=-1,btn=null;
document.querySelectorAll('div[class*="prisonerListItem"]').forEach(row=>{
const fam=row.querySelectorAll('a.MuiTypography-body1,p.MuiTypography-body1')[1]?.textContent.trim();
const buy=row.querySelector('button[class*="moneyCopyButton"]');
const bust=row.querySelector('button[class*="bustOutButton"]');
if(!priority.includes(fam)||!buy||!bust) return;
const price=num([...buy.childNodes].find(n=>n.nodeType===3).textContent);
if(price>best){best=price;btn=bust;}
});
if(btn){console.log(`[Bust-out] Busting for $${best.toLocaleString()}`);btn.click();}
}
setTimeout(go,_cfgDelaySec()*1_000);
})();
/*================ AUTO MARKET BUY/SELL (Booze + Narcotics) ================*/
(function () {
'use strict';
console.log('[Market] module loaded');
/* Force React input to accept programmatic values */
const reactSet=(input,val)=>{
const last=input.value;input.value=val;
input._valueTracker?.setValue(last);
input.dispatchEvent(new Event('input',{bubbles:true}));
};
/* Capacity detection */
const warehouseCap=rows=>{
/* 1) explicit “Max # units / kg” badge – any capitalisation, any whitespace */
const badge=[...document.querySelectorAll('*')].find(e=>/Max\s+\d+/i.test(e.textContent));
let max=parseInt((/Max\s+(\d+)/i.exec(badge?.textContent||'')||[])[1],10);
if(!max||isNaN(max)) max=40; // safe fallback
/* 2) subtract current holdings to get free capacity */
const totalHeld=rows.reduce((sum,r)=>{
const cell=[...r.children].find(td=>/holding/i.test(td.textContent)||td.getAttribute('data-title')?.match(/hold/i));
const h=parseInt((cell?.textContent||'').replace(/\D/g,''),10)||0;
return sum+h;
},0);
return Math.max(max-totalHeld,0);
};
function go(){
if(!window.BNBMAFIA_OVERLAY_HIDDEN()) return;
const table=document.querySelector('table.css-ov0lr2-table'); if(!table) return;
/* ----- column indexes are detected dynamically ----- */
let idxName=0, idxPrice=1, idxHold=2, idxAmt=3;
const header=[...table.querySelectorAll('thead th')].map(th=>th.textContent.trim().toLowerCase());
if(header.length){
idxName = header.findIndex(t=>t.startsWith('product'));
idxPrice = header.findIndex(t=>t.startsWith('price'));
idxHold = header.findIndex(t=>t.startsWith('hold'));
idxAmt = header.findIndex(t=>t.startsWith('amount'));
}
const {buyLimit, sellFloor}=window.BNBMAFIA_AUTOSCRIPT_CFG;
const rows=[...table.querySelectorAll('tbody tr:not(.css-cv5lsn-tableFooter)')];
/* ---- SELL first ---- */
for(const row of rows){
const cells=row.querySelectorAll('td');
const name =cells[idxName ]?.textContent.trim();
const price=parseInt(cells[idxPrice]?.textContent.replace(/\D/g,''),10)||0;
const qty =parseInt(cells[idxHold ]?.textContent.replace(/\D/g,''),10)||0;
const input=cells[idxAmt ]?.querySelector('input')||row.querySelector('input');
if(!sellFloor[name]||qty===0||price<sellFloor[name]) continue;
rows.forEach(r=>reactSet(r.querySelector('input'),'0'));
reactSet(input,qty.toString());
setTimeout(()=>document.querySelectorAll('button')
.forEach(b=>/^\s*sell\s*$/i.test(b.textContent)&&b.click()),200);
console.log(`[Market] Sold ${qty} ${name} @ $${price}`);
return;
}
/* ---- BUY ---- */
const freeCap=warehouseCap(rows); if(freeCap===0) return;
const options=rows.map(r=>{
const cells=r.querySelectorAll('td');
const name =cells[idxName ]?.textContent.trim();
const price=parseInt(cells[idxPrice]?.textContent.replace(/\D/g,''),10)||0;
return {name,price,input:cells[idxAmt]?.querySelector('input'),
ok:buyLimit[name]&&price<buyLimit[name]};
}).filter(o=>o.ok);
if(!options.length) return;
/* choose the item with the best profit margin */
const best=options.reduce((a,b)=>(sellFloor[b.name]-b.price)>(sellFloor[a.name]-a.price)?b:a);
rows.forEach(r=>reactSet(r.querySelector('input'),'0'));
reactSet(best.input,freeCap.toString());
setTimeout(()=>document.querySelectorAll('button')
.forEach(b=>/^\s*buy\s*$/i.test(b.textContent)&&b.click()),300);
console.log(`[Market] Bought ${freeCap} ${best.name} @ $${best.price}`);
}
setTimeout(go,_cfgDelaySec()*1_000);
})();
/*================ AUTO TRAVEL (random) ================*/
(function () {
'use strict';
console.log('[Travel] module loaded');
const POLL=500,MAX=30_000;
function randomTravel(){
if(window.BNBMAFIA_COOLDOWN_ACTIVE(document)) return false;
const vehicle=window.BNBMAFIA_AUTOSCRIPT_CFG.travelVehicle;
const btns=[...document.querySelectorAll('button.MuiButtonBase-root')]
.filter(b=>b.querySelector('p')?.textContent.trim()===vehicle&&!b.disabled);
if(!btns.length){console.log('[Travel] No enabled',vehicle);return false;}
btns[Math.random()*btns.length|0].click();
console.log('[Travel] Clicked',vehicle);
return true;
}
function confirm(){
const start=Date.now();
const id=setInterval(()=>{
const ok=[...document.querySelectorAll('button')].find(b=>/^\s*confirm\s*$/i.test(b.textContent)&&!b.disabled);
if(ok){ok.click();clearInterval(id);} else if(Date.now()-start>MAX) clearInterval(id);
},POLL);
}
setTimeout(()=>{if(randomTravel()) confirm();},_cfgDelaySec()*1_000);
})();
/*================ REDIRECT LOOP ================*/
(function () {
'use strict';
console.log('[Redirect] module loaded');
const route = [
{key:'crimes' ,url:'/crimes'},
{key:'jail' ,url:'/jail'},
{key:'nickcar' ,url:'/nickcar'},
{key:'travel' ,url:'/travel'},
{key:'crimes' ,url:'/crimes'},
{key:'killskill',url:'/killskill'},
{key:'market' ,url:'/booze/*'},
{key:'market' ,url:'/narcotics/*'}
];
const FIXUPS = [
[/^\/injail$/,'/jail']
];
let loopPos=parseInt(sessionStorage.getItem('BNB_LOOPPOS')||'0',10);
function go(){
FIXUPS.forEach(([re,replacement])=>{
if(re.test(location.pathname)) location.replace(replacement);
});
const cfg=window.BNBMAFIA_AUTOSCRIPT_CFG;
if(!cfg?.enabledActivities) return;
for(let step=0;step<route.length;step++){
loopPos=(loopPos+1)%route.length;
const next=route[loopPos];
if(cfg.enabledActivities[next.key]){
sessionStorage.setItem('BNB_LOOPPOS',loopPos);
if(!location.pathname.startsWith(next.url))
location.replace(next.url);
break;
}
}
}
setInterval(go,_cfgRedirectMs());
})();
/*================ AUTO CAR THEFT (Nick Car) ================*/
(function () {
'use strict';
console.log('[Car theft] module loaded');
function go(){
if(!window.BNBMAFIA_OVERLAY_HIDDEN()) return;
const btns=window.BNBMAFIA_ORDERED_ATTEMPTS('div.MuiBox-root[class*="nickcarListItem"]');
const idx=(window.BNBMAFIA_AUTOSCRIPT_CFG.carIndex||1)-1;
const btn=btns[idx]; if(!btn) return;
if(window.BNBMAFIA_COOLDOWN_ACTIVE(btn.closest('[class*="nickcarListItem"]'))) return;
const title=btn.closest('[class*="nickcarListItem"]')?.querySelector('p')?.textContent.trim()||`slot ${idx+1}`;
console.log(`[Car theft] Clicking “${title}” (slot ${idx+1})`);
btn.click();
}
setTimeout(go,_cfgDelaySec()*1_000);
})();
/*================ AUTO KILL-SKILL TRAINING ================*/
(function () {
'use strict';
console.log('[Kill-skill] module loaded');
function go(){
if(!window.BNBMAFIA_OVERLAY_HIDDEN()) return;
const items=document.querySelectorAll('div.MuiBox-root[class*="killSkillListItem"]');
const idx=(window.BNBMAFIA_AUTOSCRIPT_CFG.killIndex||1)-1;
const itm=items[idx]; if(!itm) return;
if(window.BNBMAFIA_COOLDOWN_ACTIVE(itm)) return;
const btn=itm.querySelector('button[class*="attemptButton"]:not([disabled])') || [...itm.querySelectorAll('button')].find(b=>/attempt\s*now/i.test(b.textContent)&&!b.disabled);
if(btn){
const title=itm.querySelector('p')?.textContent.trim()||'skill';
console.log('[Kill-skill] Training',title);
btn.click();
}
}
setTimeout(go,_cfgDelaySec()*1_000);
})();
/*================ AUTO CRIMES ================*/
(function () {
'use strict';
console.log('[Crimes] module loaded');
function go(){
if(!window.BNBMAFIA_OVERLAY_HIDDEN()) return;
const btns=window.BNBMAFIA_ORDERED_ATTEMPTS('div.MuiBox-root[class*="crimeListItem"]');
const idx=(window.BNBMAFIA_AUTOSCRIPT_CFG.crimeIndex||1)-1;
const btn=btns[idx]; if(!btn) return;
const card=btn.closest('div.MuiBox-root[class*="crimeListItem"]');
if(window.BNBMAFIA_COOLDOWN_ACTIVE(card)) return;
const title=card.querySelector('p')?.textContent.trim()||`slot ${idx+1}`;
console.log(`[Crimes] Clicking “${title}” (slot ${idx+1})`);
btn.click();
}
if(sessionStorage.getItem('BNBMAFIA_FORCE_CRIME')==='1'){
sessionStorage.removeItem('BNBMAFIA_FORCE_CRIME');
}
setTimeout(go,_cfgDelaySec()*1_000);
})();
/*================ GLOBAL CLICK THROTTLE ================*/
(function(){
'use strict';
const MIN=_cfgDelaySec()*1_000;let last=0;
const orig=HTMLElement.prototype.click;
HTMLElement.prototype.click=function(...a){
const now=Date.now(),delta=now-last;
if(this.matches('button')&&/^\s*confirm\s*$/i.test(this.textContent)) return orig.apply(this,a);
if(delta>=MIN){last=now;return orig.apply(this,a);}
};
})();
🎉 Congratulations! You now have a MAFIA Script. You will see this menu overlay on the website.

Script menu options: You can configure the script to operate based on your preferences. Redirect every: This function is to reduce the amount of times you hit the 10 click limit Click delay: This function is to reduce the amount of times you hit the 10 click limit Travel vehicle: Based on what item you own. you can configure the script to use that as travel vehicle Car-theft slot: Select which car slot to use. Slot 1 has highest success chance Crime slot: Select which crime slot to use. Slot 1 has highest success chance Kill skill slot: Select which slot you want the script to use. Remeber that only slot 1 is free Activate different types: You can select which types of crime you want your script to run. If you are not Cloak rank or above, you should remove "Market" as you don't have the allowance to buy any units. Price preset: This preset allows you to define if your priority is simply getting XP as fast as possible or if you want to get as much cash reward as well. This preset impacts Booze and Narcs buying/selling Force crimes: Starts the script over if its stuck. Bustout script tip: If you edit the script code, you can find line 219: Here you can define a single family you want the script to only bust out. Right now we set 5 families in the code as a default setup.

Booze and Narcs buy / sell prices. If you are a bit more firm with code, you can modify these values we put in the script to optimize your market deals. You might want to sell at higher prices, or you might want to just sell no matter what to get the XP and move on. You can modify these values here:

Good luck with scripting your way to the top!
Last updated