Skip to content

Instantly share code, notes, and snippets.

@justincavery
Last active July 6, 2021 12:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save justincavery/2c29c054b864726719839ca194979974 to your computer and use it in GitHub Desktop.
Save justincavery/2c29c054b864726719839ca194979974 to your computer and use it in GitHub Desktop.
CloudFlare Reverse Proxy Worker Opensea
addEventListener('fetch', event => {
event.respondWith(handleRequest(event))
})
async function handleRequest(event) {
let request = event.request
if (request.method === "OPTIONS") {
return new Response("OK", {
headers: corsHeaders
})
}
if (request.method === "GET") {
return getNFTAsset(event) // changed from request
}
}
//
// Set the URL for the OpenSea request
const openSeaApiUrl = 'https://api.opensea.io/api/v1'
const allowedOrigins = [ // need to update this based on https://egghead.io/lessons/cloudflare-secure-an-api-with-access-control-allow-headers
"app.nftx.org",
"v1.nftx.org",
"v2.nftx.org",
]
// Set the generic cors headers to be included for all responses.
const corsHeaders = {
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Methods': 'GET',
'Access-Control-Allow-Origin': '*' // we will want the origin to be from our sites/
}
const getNFTAsset = async event => {
let request = event.request
// Get the URL that is being reqeusted and set it to requesturl
const requesturl = new URL(request.url)
// Get the newurl and grab the path name from the URL. So https://example.com/asset/contractid/assetid path is /asset/blah/blah
const nftid = requesturl.pathname
const thirdPartyRequest = new Request(`https://api.opensea.io/api/v1${nftid}`,{ headers: {'X-API-KEY': `${OPENSEA_API_KEY}` }})
const cache = caches.default
const match = await cache.match(thirdPartyRequest)
if (match) {
return match
}
// Use the nftid to append to the end of the OpenSea API request
const resp = await fetch(thirdPartyRequest, {
headers: {
// Send over the API key to opensea. The API key is set using Wranger Secrets with cloudflare so it can't be snooped.
'X-API-KEY': `${OPENSEA_API_KEY}`
},
})
// This section will remap the response to reduce the fields coming back, it's a TBD.
const data = await resp.json()
// I want to remap the request so that only the required data is passed on and thus
// saving the user from some usless data.
// const nftdata = data.map(nft => ({
// id: nft.id,
// token_id: nft.token_id,
// background_color: nft.background_color,
// img_url: nft.img_url,
// img_preview_url: nft.img_preview_url,
// animation_url: nft.animation_url,
// }))
// If the response from Cloudflare is a 429 status
if (resp.status === 429) {
// include a new response to say the rate is limited and try again
return new Response("Rate limited, try again sooooon Mr Quag!",{
// Set the status of the response to 429 so the front end can try again
status: 429,
// Set cloudflare specific settings
// cf: {
// // Set the cache TTL to -1 so nothing is cached.
// cacheTtl: -1,
// // turn off caching for everything because we don't want this cached.
// cacheEverything : false,
// },
headers: {
// Set the header for the response to be application/json so it is in the proper format
'Content-type': 'application/json',
// Checking that the worker is working, this helped for debugging
'Worker-working': '429 from Opensea',
// Include the response status as a custom header, again just for tsting
'Response-Status-Check': resp.status,
// Pass through the corsHeaders set at the top.
...corsHeaders
},
})
} else { // if it's not a 429 we're assuming it's a 200.
const response = new Response(JSON.stringify(data), {
headers: {
// Set the headers as above, but with alternative checks and debugging comments
'Content-Type': 'application/json',
'cache-control': 'max-age=600',
'Worker-working': 'yeah it is',
'Response-Status-Check': resp.status,
...corsHeaders
}
})
event.waitUntil(cache.put(thirdPartyRequest, response.clone()))
return response
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment