Skip to content

Instantly share code, notes, and snippets.

@StephenBrown2
Last active June 17, 2025 15:00
Show Gist options
  • Save StephenBrown2/0a01846c355ef5c56f94a1f129cc00a2 to your computer and use it in GitHub Desktop.
Save StephenBrown2/0a01846c355ef5c56f94a1f129cc00a2 to your computer and use it in GitHub Desktop.
Real Estate in BTC UserScript
// ==UserScript==
// @name Real Estate Priced in BTC
// @namespace http://tampermonkey.net/
// @version 0.2
// @updateURL https://gist.github.com/StephenBrown2/0a01846c355ef5c56f94a1f129cc00a2
// @downloadURL https://gist.github.com/StephenBrown2/0a01846c355ef5c56f94a1f129cc00a2
// @description Display all home prices in BTC.
// @author Phteven
// @match http*://www.zillow.com/*
// @match http*://www.redfin.com/*
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant none
// ==/UserScript==
async function getBTC() {
const url = "https://mempool.space/api/v1/prices";
const btc = await fetch(url).then(function (response) {
return response.json();
}).then(function (data) {
return data.USD;
}).catch(function (err) {
console.log('Fetch Error :-S', err);
})
return btc;
}
async function getHistoricalBTC(date = new Date()) {
const url = `https://mempool.space/api/v1/historical-price?currency=USD&timestamp=${Math.floor(date.getTime() / 1000)}`;
const btc = await fetch(url).then(function (response) {
return response.json();
}).then(function (data) {
return data.prices[0].USD;
}).catch(function (err) {
console.log('Fetch Error :-S', err);
});
return btc;
}
async function setRedfinLastSoldPrice() {
let lastSold = document.querySelector('div.ListingStatusBannerSection.remodel');
if (!lastSold) {
console.log("Last sold element not found");
return;
}
// Extract the date and price from the text "LAST SOLD ON MAR 1, 2024 FOR $384,900"
let dateMatch = lastSold.textContent.match(/ON (.+?) FOR/);
let priceMatch = lastSold.textContent.match(/FOR (\$[,\d]+)/);
let date = dateMatch ? dateMatch[1] : null;
let usdPrice = priceMatch ? priceMatch[1].replace(/[\$,]/g, '') : null;
usdPrice = usdPrice ? parseFloat(usdPrice) : null;
date = date ? new Date(date + " 12:00 PM") : null;
var btcPrice = await getHistoricalBTC(date);
if (btcPrice === 0) {
console.error("BTC price is zero, cannot calculate BTC value.");
return;
}
let BTC = (usdPrice / btcPrice).toFixed(8) + ' ₿';
if (lastSold.hasChildNodes()) {
for (const node of lastSold.childNodes) {
if (node.nodeType === Node.TEXT_NODE) {
if (node.textContent.match(/FOR \$([,\d]+)/)) {
let span = document.createElement('span');
span.title = priceMatch[1] + ' @ $' + btcPrice + '/BTC';
span.textContent = ' FOR ' + BTC;
node.replaceWith(span);
}
}
}
}
}
function getAllPrices() {
// Combined query selector for all possible price elements
return document.querySelectorAll(
'div.stat-block .statsValue,' + // Redfin
'.bp-Homecard__Price--value,' + // Redfin Homepage Cards
'.price-text,' + // Zillow
'[data-testid="primary-zestimate"],' + // Zestimate
'.hs-fact-value,' + // Home Zestimate
'[data-test="property-card-price"],' + // Zillow Cards
'[data-testid="data-price-row"]', + // Zillow Favorite homes
'[data-testid="price"]' // Zillow photos view
);
}
// setBTC takes an element with a USD price, and btcPrice,
// and updates the element's innerHTML to show the BTC equivalent
// of the USD price
function setBTC(elem, btcPrice) {
if (!elem.textContent.includes('$')) {
return;
}
let usdPrice = Number(elem.textContent.replace(/[^0-9.-]+/g, ""));
let BTC = (usdPrice / btcPrice).toFixed(8) + ' ₿';
const inner = '<span title="' + elem.textContent + ' @ $' + btcPrice + '/BTC">' + BTC + '</span>';
elem.innerHTML = inner;
}
(async function() {
'use strict';
var btcPrice = await getBTC();
var runIt = async function() {
var prices = getAllPrices();
for (const priceObj of prices) {
setBTC(priceObj, btcPrice);
}
await setRedfinLastSoldPrice();
};
window.onload = await runIt;
setInterval(runIt, 1000);
setInterval(async function() { btcPrice = await getBTC(); }, 60000);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment