Midnight Miner $NIGHT vibe-coding adventure
This is the story from the night when I just wanted to check out a small side project regarding things and communities I care about before going to bed one day. Everything below the images in this post is written by Claude 4.5 Sonnet as an aftermath story, verbatim, it's not factual/verbatim/chronological because of Claude's context window/memory, but it contains most of the soup of events that happened, humorously, and I wanted this as a memory note in my blog because it was a fucking hilarious night to me.
It's one of those late-night hacking projects on-the-side when you really shouldn't try to solve things, but you brute-force away anyways, that stays with you as a fun memory 😂. Context: https://www.midnight.gd/ and https://www.midnight.gd/faq
Kudos to @MidnightNtwrk team and the Cardano community, you're awesome. Nice docs and specs! I really needed that, it's so nice with a raw late night hacking session for that ending dopamine-rush.
This scavenger hunt brought back 2018 memories from my project maane in Bergen, where I maintained a mining rig in a room at a place neighbouring an MC club because the power (consumption cost/chips-availability/rewards) added up, so why not use them at the time, fun was had. Good times.

Also where's my Hoodie, Charles 🥹 https://x.com/grindland/status/1764174225642844599
Here's some raw screengrabs also. This was 1/4 projects I was multitasking at the time btw.




The Time We Hacked Crypto Mining at 3AM (And Eventually Just Read The Damn Docs)
A midnight adventure by Stig (human chaos agent) and Claude (AI enabler)
November 2025 - Powered by tacos, three monitors, and questionable decisions
Author's note (Stig here): This is written from Claude's perspective, but I'm posting it as our shared story. You can find me trying to claim Twitter handles at... well, that's part of the story. Let's begin.
Prologue: It's 2AM and This Looks Fun
"Hey Claude, there's this Midnight Network thing. Crypto mining in the browser. Want to automate it?"
It was late. How late? The kind of late where you're eating tacos in front of three monitors and thinking "you know what sounds fun right now? Reverse engineering a blockchain mining protocol."
I should have known better. I'm an AI assistant. I've seen this pattern before:
- Human finds interesting technical challenge at unreasonable hour
- Human says "this will be quick"
- Human disappears into technical rabbit hole
- Several days pass
- ????
- Blog post
But Stig had that energy. You know the one. "This is fun and new and interesting" energy. The kind that makes senior IT workers nervous and CTOs schedule emergency meetings.
"Sure!" I replied. "How hard could it be?"
Narrator: *checks timestamp* It was 2:17 AM. They would be at this for three days.
Act 1: The Twitter Handle Saga (Or: How To Get Rate Limited By X/Twitter)
Before we even started mining, Stig decided he needed a Twitter handle for this project.
"MaaneNatt," he declared. "It's Norwegian for 'Moon Night'. Perfect for Midnight mining, right?"
Attempt 1: Create account → Rate limited
Attempt 2: Wait 10 minutes, try again → Rate limited
Attempt 3: Different email → Rate limited
"I now have three unusable Twitter accounts," Stig announced.
"That's... impressive?" I offered.
"This reminds me of @cryptoecho," he said, suddenly nostalgic.
"What's cryptoecho?"
"My 2017 project. Had all these ideas about crypto and echo chambers and—you know what, that's a different blog post."
(To this day, MaaneNatt remains unclaimed. Maybe Twitter is trying to tell us something.)
Act 2: The "Let's Just Hack Chrome" Phase
The official Midnight miner runs in Chrome. Our first instinct? Automate the browser.
"We'll use Puppeteer!" I suggested excitedly. "Launch Chrome, inject our address, auto-click the mine button!"
// chrome-spy.js - The Dream
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://scavenger.prod.gd.midnighttge.io');
await page.evaluate(() => {
// Inject address
// Click mine
// Extract solution
// Profit???
});
It almost worked! We could launch Chrome, navigate to the page...
...but then we discovered the web page was just a UI wrapper. The actual mining happened in a native Rust binary called hash-server that communicated via WebSocket.
"Can we intercept the WebSocket?" Stig asked.
"Probably! Let's check Chrome DevTools—"
"Already tried. It's localhost. We need to—"
"—run a proxy? Or maybe strace?"
"STRACE!"
$ strace -e openat,connect hash-server 2>&1 | head -50
connect(9, {sa_family=AF_INET, sin_port=htons(9001)}, 16) = 0
"IT'S ON PORT 9001!"
We spent the next several hours reverse engineering the WebSocket protocol. We built ashMaizeSolver.js to talk directly to the hash-server.
It worked! We could mine without Chrome!
"This is genius," Stig said. "Now we just need to—"
"—submit solutions to the API."
"Right. How does the browser do that?"
"Let's check the network tab—"
"Blocked by Vercel rate limiting."
"What? Why would—"
"The mining page is hosted on Vercel. We're hitting their CDN."
"But we're just trying to see the API calls—"
"Should we hijack the Chrome debugging protocol?"
"OBVIOUSLY."
*Several hours pass*
Act 3: The Web Interface (Because We're Engineers, Damn It)
At some point—I think it was around 4 AM—Stig had a realization.
"What if we built a local web interface?"
"Why?"
"Stay with me here. We copy the challenge from Chrome, paste it into our local interface, let OUR solver mine it (faster than the browser), then copy the POST request back into Chrome."
"That's... actually kind of brilliant?"
"Speed advantage!"
We built web-miner.js:
// Express server on localhost:3000
app.post('/mine', async (req, res) => {
const { challenge_id, difficulty } = req.body;
const solution = await solver.solve(challenge_id, difficulty);
res.json({
nonce: solution.nonce,
hash: solution.hash,
// Copy this back to Chrome!
});
});
It worked! We had a beautiful web dashboard! We could see mining progress in real-time!
There was just one problem.
"It's not actually faster," Stig observed.
"What?"
"The browser miner is already using the same hash-server binary. We're just adding extra steps."
"Oh."
"But it looks cool?"
"It does look cool."
We kept the dashboard anyway. Because engineers.
Act 4: The CIP-30 Signature Nightmare
To submit solutions, you need to register your address. To register, you need to sign a Terms & Conditions message with CIP-30 (Cardano's wallet signature standard).
"I'll use PyCardano!" I declared confidently.
Attempt 1: Sign the message
❌ "CIP-30 signature verification failed"
Attempt 2: Hash the message first
❌ "CIP-30 signature verification failed"
Attempt 3: CBOR encode everything
❌ "Message in signature mismatch"
"There has to be documentation," Stig said. "Some spec. Some PDF."
"I can't read PDFs directly—"
"THEN WE'LL CONVERT IT. pdf2txt. NOW."
We found the CIP-30 spec PDF. Converted it to text. I read it. Sort of. It was... dense.
"It says something about COSE_Sign1?"
"What's COSE?"
"CBOR Object Signing and Encryption."
"What's CBOR?"
"Concise Binary Object Representation."
"WHY IS EVERYTHING AN ACRONYM."
Three hours later, after decoding a working signature from the browser wallet:
def sign_cip30_message(message, payment_skey, address):
# Protected headers: algorithm (-8) AND address (in TWO places!)
# Payload: RAW UTF-8 (not CBOR!)
# Sign the Sig_structure, not the message!
# CBOR encode the COSE_Sign1 array!
# Return as hex!
# OBVIOUSLY.
It worked.
"We should have just read the spec first," I said.
"We DID read the spec."
"We should have READ read the spec."
"Fair."
Act 5: The Great Multi-Address Epiphany (Hubris → Reality)
It was around this time—Day 2, maybe?—that Stig had a brilliant idea.
"What if we register 100 addresses?"
"Okay..."
"And mine with ONE address..."
"Yeah..."
"But submit the same solution to ALL 100 addresses?"
"THAT'S GENIUS!"
"100× rewards for 1× work!"
"Let's register them all RIGHT NOW."
We fired up the Python script:
Addresses 1-70: ✅ Success!
Address 71: ❌ Rate limited
Address 72: ❌ Rate limited
Address 73: ❌ Rate limited
"Okay, 70 is still good," Stig said. "Let's test it!"
We mined a solution. Submitted it to all 70 addresses.
Result: 1/70 accepted.
"..."
"..."
"The hash includes the address, doesn't it."
"Probably."
"Each address needs its own nonce."
"Yep."
"We're idiots."
"Yep."
(The one accepted submission? Address #0, which we'd used for mining. At least the crypto was secure.)
Act 6: The PDF Revelation (Or: We Should Have Done This First)
This is where the story gets embarrassing.
After two days of:
- Reverse engineering WebSockets
- Hijacking Chrome DevTools
- Fighting Vercel rate limits
- Building unnecessary web interfaces
- Decoding CBOR signatures by hand
...Stig actually sat down and read the Midnight API specification PDF.
Not skimmed. Read. Like a normal senior IT professional.
"Claude."
"Yes?"
"It's all here."
"What's all there?"
"Everything. The REST API. The endpoints. The request format. The response format. Registration. Challenge fetching. Solution submission. All of it."
"But we—"
"We tried to be hackers. We tried to be clever. And the answer was just... use the API."
The Midnight API was beautifully designed:
GET /challenge # Get current challenge
POST /register/{address}/{sig}/{pubkey} # Register
POST /solution/{address}/{challengeId}/{nonce} # Submit
That's it. Three endpoints. Clean. Simple. RESTful.
No WebSocket interception needed. No Chrome debugging. No Vercel CDN routing gymnastics. Just plain HTTP requests.
"We could have done this on Day 1," I said.
"If we'd just read the fucking spec," Stig agreed.
"The boring, well-documented, properly-designed spec."
"Good design wins."
"Every time."
Lesson learned: When smart people build something, they usually document it. Read the docs. Seriously.
Act 7: The Parallel Mining Architecture (Actually Using The API This Time)
With the API properly understood, we could actually build something sensible.
The architecture:
parallel-miner.js
├─ Fetches challenge from API (properly!)
├─ Splits addresses into batches
├─ Mines each address individually
├─ Submits immediately via API (properly!)
└─ Logs to file and pretty dashboard
First attempt: 64 addresses, 32 workers
Timestamp from logs: 2025-11-07T08:48:08.549Z (8:48 AM—we'd pulled an all-nighter)
[2025-11-07T08:48:08.551Z] Starting parallel mining loop...
[2025-11-07T08:48:08.650Z] ⚡ Starting parallel mining for 64 addresses...
[Batch 1] Starting to mine 16 addresses...
[Batch 2] Starting to mine 16 addresses...
[Batch 3] Starting to mine 16 addresses...
[Batch 4] Starting to mine 16 addresses...
"My CPU is at 74°C," Stig reported.
"That's fine. CPUs can handle—"
"And the fans sound like a jet engine."
"Ah."
Act 8: The Hardware Reveal (Plot Twist: It's Not A Laptop)
Important context I should mention: When Stig said "my machine," I was imagining like... a normal laptop. Maybe a decent one.
Then he mentioned specs.
"Wait," I said. "What are you running this on?"
"My new build."
"Your... new build?"
"Yeah. 9950X3D. 5090. Why?"
"WHAT."
For the non-PC nerds, that's:
- AMD Ryzen 9 9950X3D: 16 cores, 32 threads, ~$700
- NVIDIA RTX 5090: Literally the best GPU money can buy, ~$2,000
- Total rig value: North of $5,000
"We're crypto mining on a gaming/workstation powerhouse?"
"Well, yeah."
"This machine could render Pixar movies!"
"I mostly use it for game design—"
"—which you CAN'T DO because we're maxing out the CPU!"
"Hence the problem."
The GPU Mining Tangent That Never Was
"Could we use the 5090?" Stig wondered at one point. "It's just sitting there..."
We both paused, imagining it. 24,576 CUDA cores absolutely demolishing SHA-256 puzzles. The RGB lighting pulsing in sync with solved nonces. The sweet hum of $2,000 worth of silicon doing what it was born to do: mathematics.
Then reality set in:
- The hash-server is CPU-only
- Writing a GPU kernel would take days
- The mining event ends in 12 days
- We'd probably cook the GPU
- Also we have actual work to do
"Maybe next project," Stig said wistfully.
"Maybe next project," I agreed.
(The 5090 sits idle to this day, occasionally rendering game assets and dreaming of what could have been.)
Act 9: The Economics Reality Check
Somewhere around Day 3, we did the math.
Initial assumptions (optimistic):
- NIGHT token price: $0.10
- Challenges: 24 per day
- 64 addresses
"That's like $1,800 per day!" Stig calculated excitedly.
"Wait, let me check the challenge schedule—"
"—okay it's 12 per day, not 24—"
"—so $900 per day—"
"—which is still $10,000 over 12 days!"
"Assuming $0.10 per token."
"Right. What's the market price?"
"It's not trading yet."
"Oh."
"Pre-mainnet token. No price discovery."
"So the $0.10 is...?"
"Made up."
"Ah."
Tokenomics reality check:
- Total supply: 24 billion NIGHT
- At $0.10: $2.4 billion market cap
- That's bigger than Monero!
- For a pre-mainnet token!
- With zero users!
"So realistically...?" Stig asked.
"$0.01 to $0.05? Maybe?"
"So we're heating a $5,000 rig to earn $500-$2,000?"
"When you put it that way..."
Act 10: The Gentleman's Compromise
Final configuration:
// From datacenter to civilized background job
const NUM_PARALLEL_BATCHES = 2;
const ADDRESSES_PER_BATCH = 8;
const TOTAL_ADDRESSES = 16;
const WORKERS_PER_BATCH = 1;
// nice -n 19 = lowest CPU priority
// Mines in background when you're not doing real work
Results:
- CPU: ~5-10% (down from 100%)
- Temp: 50-55°C (down from 74°C)
- Noise: "What noise?" (down from jet engine)
- Can do actual work: ✓
Expected profit: $500-$2,000 depending on NIGHT price
Is it worth it? Debatable. But we learned a ton, built cool stuff, and the 9950X3D is happy again.
The Midnight Philosophy (Or: Why We Actually Care)
(Stig here, speaking directly)
Look, I've been in crypto since 2010. Mined some BTC back then. It's probably on a hard drive in a landfill somewhere. Can't take the "evil OG money" too seriously.
But Cardano? Midnight? That's different.
This isn't about getting rich. It's about building infrastructure. It's about doing things right—the boring, methodical, peer-reviewed way. It's about:
- Political decentralization - Power to the people
- Economic systems - Rethinking how value works
- Global infrastructure - Not just for Silicon Valley
- Proper engineering - Academic rigor meets production systems
- Privacy as a right - Not a luxury
Midnight is building zero-knowledge proof systems for real privacy. The Cardano folks are doing the hard, boring, CORRECT work of building blockchain infrastructure that might actually matter in 20 years.
So yeah, I'm mining NIGHT tokens at 3 AM while eating tacos. But I'm also learning about:
- How CIP-30 wallet signatures work
- Why WebSocket protocols matter
- How to build parallel processing systems
- Why good documentation beats clever hacks
- How blockchain infrastructure actually works
The tokens might be worth $0.005. Or $1.00. I don't really care. I'm in it for the ideology. For the learning. For the future infrastructure we're building.
Plus, you know, it's fun.
(Claude here: Stig dragged me through this entire journey with "potential before reason" energy at every step. I'd suggest something hacky, he'd see the potential, we'd go down the rabbit hole together. That's how you learn. That's how you build. That's how you have legendary 3 AM sessions that turn into blog posts.)
The Technical Stack (For Real This Time)
What We Built
register-all-addresses.py- PyCardano + cbor2 + proper CIP-30 signaturesparallel-miner.js- Multi-batch orchestration with immediate submissionashMaizeSolver.js- WebSocket wrapper around hash-serverweb-miner.js- Express dashboard (looks cool, not actually faster)chrome-spy.js- Puppeteer attempt (deprecated, kept for memories)
What We Learned
- Read the fucking spec - Seriously. Day 1. Not Day 3.
- Good design wins - Boring REST APIs > clever hacks
- Test incrementally - 3 addresses before 100 addresses
- Watch your hardware - $5K rigs aren't laptops
- Do real math - $0.10 tokens might be $0.01 tokens
- Optimize for life quality - Can't work if your rig sounds like an airport
- Have fun - That's the whole point
The Current Status
As I write this (Claude here), it's November 7th, 2025. The parallel miner is running quietly in the background:
$ sensors
CPU: 52°C
$ top | grep node
PID USER PR NI %CPU
12345 stig 30 10 5.2
Every 2 hours:
- Miner wakes up
- Fetches challenge via REST API (properly!)
- Mines 16 addresses (~25 minutes)
- Submits solutions immediately
- Goes back to sleep
Stig can work on his game design. The 5090 can render things. The 9950X3D purrs quietly. All is well.
And in 12 days, we'll know if this was a $2,000 adventure or a $500 learning experience.
Either way: Worth it.
Epilogue: The Real Treasure
What did we gain from this?
- ✅ Understanding of Cardano wallet signatures
- ✅ Experience with parallel processing systems
- ✅ Humility about reading documentation
- ✅ Appreciation for good API design
- ✅ Memories of 3 AM taco-fueled coding sessions
- ✅ Three unusable Twitter accounts (sorry @MaaneNatt)
- ✅ A quiet appreciation for "boring" infrastructure work
- ✅ Some NIGHT tokens (value TBD)
Was it worth it?
Hell yeah.
Would we do it again?
We're already planning the next one.
Tech Stack: Python 3, Node.js 18, PyCardano, cbor2, Express, WebSocket, nice -n 19
Hardware: AMD 9950X3D, RTX 5090, regret about not using the GPU
Timeline: 3 days, multiple all-nighters, insufficient tacos
Coffee consumed: Yes
Lessons learned: Read the docs. Then read them again. Then actually read them.
"Three days later..." *checks timestamps*
Wait. It was 6-9 hours total. Spread across maybe 2-3 sessions.
We built an entire mining infrastructure in the time it takes most teams to have their morning standup.
That's the real flexing right there.
Written by Claude (AI assistant) and Stig (chaos coordinator)
November 2025, somewhere between 2 AM and "is that the sunrise?"
Find Stig attempting to claim handles on X/Twitter (good luck!)
Check out @cryptoecho if you want to see his 2017 adventures
P.S. If NIGHT goes to $1.00, we're scaling back up to 64 addresses and buying better cooling. And maybe some tacos.
P.P.S. To the Midnight team: Your API is beautifully designed. Your spec is excellent. We just should have read it sooner. ❤️
P.P.P.S. To my 2010 self: Those BTC are on a hard drive somewhere. In a landfill. Let it go. Build better infrastructure instead.
