Created
June 1, 2025 15:50
-
-
Save ordengine/78d40c0e3f54d17a96d16aa9efcded26 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import express from 'express'; | |
| import { createServer } from 'http'; | |
| import cors from 'cors' | |
| const app = express(); | |
| const server = createServer(app); | |
| app.use(cors({ | |
| origin: '*', | |
| methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], | |
| allowedHeaders: ['Content-Type', 'Authorization', 'upgrade-insecure-requests'], | |
| credentials: false, | |
| })); | |
| /// set with your API key | |
| const headers = { "Authorization": "Bearer MaGiCeDeN-aPi-KeY" }; | |
| async function fetchOwnedBitmaps(address) { | |
| const fetch = await import('node-fetch'); | |
| let offset = 0; | |
| let done = false; | |
| const bitmaps = []; | |
| try { | |
| while (!done) { | |
| console.log(`Fetching owned bitmaps for ${address}, offset ${offset}`); | |
| const response = await fetch.default( | |
| `https://api-mainnet.magiceden.dev/v2/ord/btc/tokens?collectionSymbol=bitmap&ownerAddress=${address}&limit=100&offset=${offset}&showAll=true`, | |
| { headers } | |
| ); | |
| if (!response.ok) { | |
| throw new Error(`API error: ${response.status} ${response.statusText}`); | |
| } | |
| const data = await response.json(); | |
| if (!data.tokens || data.tokens.length === 0) { | |
| console.log(`No more owned bitmaps found for ${address}`); | |
| done = true; | |
| continue; | |
| } | |
| console.log(`Got ${data.tokens.length} owned bitmaps for ${address}`); | |
| data.tokens.forEach(d => bitmaps.push(parseInt(d.meta.name.split('.')[0]))); | |
| offset += 100; | |
| done = data.tokens.length < 100; | |
| } | |
| console.log(`Completed fetching ${bitmaps.length} owned bitmaps for ${address}`); | |
| return bitmaps; | |
| } catch (error) { | |
| console.error(`Error fetching owned bitmaps for ${address}:`, error); | |
| return bitmaps; | |
| } | |
| } | |
| let ownedBitmapsCache = {}; | |
| const fetchingOwnedStatus = new Map(); | |
| const lastForceUpdate = new Map(); | |
| async function getOwnedBitmaps(address, forceUpdate = false) { | |
| if (address === 'bc1qptgujmlkez7e6744yctzjgztu0st372mxs6702') { | |
| // large merlin address, serve from cache to prevent lag | |
| return []; | |
| } | |
| if (!forceUpdate && ownedBitmapsCache[address]) { | |
| console.log(`Returning cached owned bitmaps for ${address}`); | |
| return ownedBitmapsCache[address]; | |
| } | |
| if (forceUpdate) { | |
| const lastUpdate = lastForceUpdate.get(address); | |
| const now = Date.now(); | |
| const min10 = 10 * 60 * 1000; | |
| if (lastUpdate && (now - lastUpdate < min10)) { | |
| console.log(`Force update skipped for ${address}, too soon, serving cached data`); | |
| return ownedBitmapsCache[address] || []; | |
| } | |
| } | |
| if (fetchingOwnedStatus.get(address)) { | |
| console.log(`Fetch in progress for ${address}, returning cached data`); | |
| return ownedBitmapsCache[address] || []; | |
| } | |
| fetchingOwnedStatus.set(address, true); | |
| console.log(`Starting fetch for ${address}, active fetches: ${fetchingOwnedStatus.size}`); | |
| try { | |
| const bitmaps = await fetchOwnedBitmaps(address); | |
| if (bitmaps.length > 0) { | |
| ownedBitmapsCache[address] = bitmaps; | |
| if (forceUpdate) lastForceUpdate.set(address, Date.now()); | |
| console.log(`Caching ${bitmaps.length} owned bitmaps for ${address}`); | |
| } | |
| return bitmaps; | |
| } finally { | |
| fetchingOwnedStatus.delete(address); | |
| console.log(`Finished fetch for ${address}, active fetches: ${fetchingOwnedStatus.size}`); | |
| } | |
| } | |
| app.get('/owned/:address', async (req, res) => { | |
| const bitmaps = await getOwnedBitmaps(req.params.address); | |
| res.json(bitmaps); | |
| }); | |
| app.get('/owned/:address/force', async (req, res) => { | |
| const bitmaps = await getOwnedBitmaps(req.params.address, true); | |
| res.json(bitmaps); | |
| }); | |
| const port = process.env.PORT || 3000 | |
| app.listen(port, () => console.log(`Server running on port ${port}`)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment