From 91e4fe7d79bccf666e0c1ca5d6255dc275a0de92 Mon Sep 17 00:00:00 2001 From: pory-gone Date: Tue, 16 Sep 2025 10:17:05 +0200 Subject: [PATCH] new feature, Sats per Big Mac --- api/resolvers/price.js | 32 ++++++++++++++++++++++++++++++++ api/typeDefs/price.js | 1 + components/nav/price-carousel.js | 3 ++- components/price.js | 19 +++++++++++++++---- fragments/price.js | 1 + 5 files changed, 51 insertions(+), 5 deletions(-) diff --git a/api/resolvers/price.js b/api/resolvers/price.js index 0df412a1ed..ba2e3547fe 100644 --- a/api/resolvers/price.js +++ b/api/resolvers/price.js @@ -18,10 +18,42 @@ const getPrice = cachedFetcher(async function fetchPrice (fiat = 'USD') { keyGenerator: (fiat = 'USD') => fiat }) +const getBigMacPrice = cachedFetcher(async function fetchBigMacPrice () { + const csvUrl = 'https://raw.githubusercontent.com/TheEconomist/big-mac-data/master/output-data/big-mac-raw-index.csv' + try { + const res = await fetch(csvUrl) + const csvText = await res.text() + const lines = csvText.split('\n') + const usaEntries = lines + .filter(line => line.includes(',USA,USD,')) + .map(line => { + const cols = line.split(',') + return { + date: cols[0], + price: parseFloat(cols[4]) + } + }) + .filter(entry => !isNaN(entry.price)) + .sort((a, b) => new Date(b.date) - new Date(a.date)) + return usaEntries[0]?.price || 5.79 + } catch (err) { + console.error('Big Mac price fetch error:', err) + return 5.79 + } +}, { + maxSize: 1, + cacheExpiry: 24 * 60 * 60 * 1000, + forceRefreshThreshold: 0, + keyGenerator: () => 'bigmac-usd' +}) + export default { Query: { price: async (parent, { fiatCurrency }, ctx) => { return await getPrice(fiatCurrency) || -1 + }, + bigMacPrice: async () => { + return await getBigMacPrice() || 5.79 } } } diff --git a/api/typeDefs/price.js b/api/typeDefs/price.js index 5ffb8e3679..0f5c0dbf71 100644 --- a/api/typeDefs/price.js +++ b/api/typeDefs/price.js @@ -3,5 +3,6 @@ import { gql } from 'graphql-tag' export default gql` extend type Query { price(fiatCurrency: String): Float + bigMacPrice: Float } ` diff --git a/components/nav/price-carousel.js b/components/nav/price-carousel.js index 0b09c6721f..8687aafd5d 100644 --- a/components/nav/price-carousel.js +++ b/components/nav/price-carousel.js @@ -9,7 +9,8 @@ const carousel = [ '1btc', 'blockHeight', 'chainFee', - 'halving' + 'halving', + 'bigmac' ] export const PriceCarouselContext = createContext({ diff --git a/components/price.js b/components/price.js index 01dd9f7a30..f5a0958be4 100644 --- a/components/price.js +++ b/components/price.js @@ -12,7 +12,8 @@ import { usePriceCarousel } from './nav/price-carousel' export const PriceContext = React.createContext({ price: null, - fiatSymbol: null + fiatSymbol: null, + bigMacPrice: null }) export function usePrice () { @@ -34,8 +35,9 @@ export function PriceProvider ({ price, children }) { const contextValue = useMemo(() => ({ price: data?.price || price, - fiatSymbol: CURRENCY_SYMBOLS[fiatCurrency] || '$' - }), [data?.price, price, me?.privates?.fiatCurrency]) + fiatSymbol: CURRENCY_SYMBOLS[fiatCurrency] || '$', + bigMacPrice: data?.bigMacPrice || 5.79 + }), [data?.price, data?.bigMacPrice, price, me?.privates?.fiatCurrency]) return ( @@ -56,7 +58,7 @@ function AccessibleButton ({ id, description, children, ...props }) { export default function Price ({ className }) { const [selection, handleClick] = usePriceCarousel() - const { price, fiatSymbol } = usePrice() + const { price, fiatSymbol, bigMacPrice } = usePrice() const { height: blockHeight, halving } = useBlockHeight() const { fee: chainFee } = useChainFee() @@ -106,6 +108,15 @@ export default function Price ({ className }) { ) } + if (selection === 'bigmac') { + if (!price || price < 0 || !bigMacPrice) return null + return ( + + {fixedDecimal(Math.round((bigMacPrice / price) * 100000000), 0)} sats/Big Mac + + ) + } + if (selection === 'fiat') { if (!price || price < 0) return null return ( diff --git a/fragments/price.js b/fragments/price.js index 39a18a83ee..52c0a5a2e3 100644 --- a/fragments/price.js +++ b/fragments/price.js @@ -3,4 +3,5 @@ import { gql } from '@apollo/client' export const PRICE = gql` query price($fiatCurrency: String) { price(fiatCurrency: $fiatCurrency) + bigMacPrice }`