forked from codeSTACKr/nft-landing-page
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1e3e4e9
commit f5836eb
Showing
10 changed files
with
307 additions
and
73 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
node_modules | ||
.env | ||
package-lock.json | ||
# Local Netlify folder | ||
.netlify |
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
const fetch = require('node-fetch') | ||
|
||
const CONTRACT = process.env.CONTRACT_ADDRESS; | ||
const AUTH = process.env.NFTPORT_AUTH; | ||
const chain = "polygon"; | ||
const include = "metadata"; | ||
|
||
exports.handler = async (event, context) => { | ||
const wallet = event.queryStringParameters && event.queryStringParameters.wallet | ||
const page = event.queryStringParameters && event.queryStringParameters.page | ||
|
||
const isOwner = (wallet) => { | ||
if(!wallet) { | ||
return { | ||
isOwner: false | ||
} | ||
} else { | ||
return getOwnedNfts(wallet, page) | ||
} | ||
} | ||
|
||
const response = await isOwner(wallet) | ||
|
||
return { | ||
'statusCode': 200, | ||
'headers': { | ||
'Cache-Control': 'no-cache', | ||
'Content-Type': 'application/json', | ||
}, | ||
'body': JSON.stringify(response) | ||
} | ||
} | ||
|
||
const getOwnedNfts = async (wallet, page) => { | ||
const url = `https://api.nftport.xyz/v0/accounts/${wallet}/?`; | ||
|
||
const options = { | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: AUTH | ||
} | ||
}; | ||
const query = new URLSearchParams({ | ||
chain, | ||
include, | ||
page_number: page | ||
}); | ||
|
||
let editions = [] | ||
try { | ||
const data = await fetchData(url + query, options) | ||
console.log(`Recieved page ${page}`) | ||
const total = data.total; | ||
const pages = Math.ceil(total / 50); | ||
data.nfts.forEach(nft => { | ||
if(nft.contract_address === CONTRACT) { | ||
editions.push(nft.token_id) | ||
} | ||
}) | ||
|
||
return { | ||
isOwner: editions.length > 0 ? true : false, | ||
editions, | ||
next_page: +page === pages ? null : +page + 1, | ||
} | ||
} catch(err) { | ||
console.log(`Catch: ${JSON.stringify(err)}`) | ||
return { | ||
error: err | ||
} | ||
} | ||
} | ||
|
||
async function fetchData(url, options) { | ||
return new Promise((resolve, reject) => { | ||
return fetch(url, options).then(res => { | ||
const status = res.status; | ||
|
||
if(status === 200) { | ||
return resolve(res.json()); | ||
} else { | ||
console.log(`Fetch failed with status ${status}`); | ||
return reject(res.json()); | ||
} | ||
}).catch(function (error) { | ||
reject(error) | ||
}); | ||
}); | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ | |
<link rel="icon" type="image/png" sizes="32x32" href="images/x-icon/favicon-32x32.png"> | ||
<link rel="icon" type="image/png" sizes="16x16" href="images/x-icon/favicon-16x16.png"> | ||
<link rel="manifest" href="images/x-icon/site.webmanifest"> | ||
<link rel="stylesheet" href="style.css" /> | ||
<link rel="stylesheet" href="css/style.css" /> | ||
</head> | ||
<body> | ||
<header> | ||
|
@@ -51,6 +51,7 @@ | |
</header> | ||
|
||
<section class="container"> | ||
<div class="owner-status"></div> | ||
<div class="countdown"> | ||
<ul | ||
id="countdown" | ||
|
@@ -87,6 +88,7 @@ <h1>NFT Drop Coming Soon!!</h1> | |
</section> | ||
|
||
<script src="https://cdn.jsdelivr.net/npm/@metamask/[email protected]/dist/metamask-onboarding.bundle.js"></script> | ||
<script src="app.js"></script> | ||
<script src="js/countdown.js"></script> | ||
<script src="js/app.js"></script> | ||
</body> | ||
</html> |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
// METAMASK CONNECTION | ||
const TIMEOUT = 1000; | ||
const COLLECTION_NAME = 'CodeCats'; | ||
let editions = []; | ||
let dots = 1; | ||
|
||
window.addEventListener('DOMContentLoaded', () => { | ||
const onboarding = new MetaMaskOnboarding(); | ||
const onboardButton = document.getElementById('connectWallet'); | ||
let accounts; | ||
|
||
const updateButton = async () => { | ||
if (!MetaMaskOnboarding.isMetaMaskInstalled()) { | ||
onboardButton.innerText = 'Install MetaMask!'; | ||
onboardButton.onclick = () => { | ||
onboardButton.innerText = 'Connecting...'; | ||
onboardButton.disabled = true; | ||
onboarding.startOnboarding(); | ||
}; | ||
} else if (accounts && accounts.length > 0) { | ||
onboardButton.innerText = `✔ ...${accounts[0].slice(-4)}`; | ||
onboardButton.disabled = true; | ||
onboarding.stopOnboarding(); | ||
checkOwner(accounts[0]); | ||
} else { | ||
onboardButton.innerText = 'Connect MetaMask!'; | ||
onboardButton.onclick = async () => { | ||
await window.ethereum.request({ | ||
method: 'eth_requestAccounts', | ||
}) | ||
.then(function(accounts) { | ||
onboardButton.innerText = `✔ ...${accounts[0].slice(-4)}`; | ||
onboardButton.disabled = true; | ||
checkOwner(accounts[0]); | ||
}); | ||
}; | ||
} | ||
}; | ||
|
||
updateButton(); | ||
if (MetaMaskOnboarding.isMetaMaskInstalled()) { | ||
window.ethereum.on('accountsChanged', (newAccounts) => { | ||
accounts = newAccounts; | ||
updateButton(); | ||
}); | ||
} | ||
}); | ||
|
||
const checkOwner = async (account) => { | ||
if(account) { | ||
let isOwner = false; | ||
let page = 1 | ||
|
||
const data = await fetchWithRetry(`/.netlify/functions/isowner/?wallet=${account}&page=${page}`); | ||
|
||
isOwner = !isOwner ? data.isOwner : isOwner; | ||
updateStatusText(isOwner, true) | ||
|
||
editions = [...data.editions] | ||
let nextPage = data.next_page | ||
|
||
while(nextPage) { | ||
page = nextPage | ||
const data = await fetchWithRetry(`/.netlify/functions/isowner/?wallet=${account}&page=${page}`); | ||
|
||
isOwner = !isOwner ? data.isOwner : isOwner; | ||
updateStatusText(isOwner, true) | ||
|
||
editions = [...editions, ...data.editions] | ||
nextPage = data.next_page | ||
} | ||
|
||
updateStatusText(isOwner, false) | ||
} | ||
} | ||
|
||
function updateStatusText(isOwner, checking) { | ||
const statusText = document.querySelector('.owner-status'); | ||
if(checking) { | ||
if(isOwner) { | ||
statusText.innerText = `You do own ${COLLECTION_NAME}!! 😻 Let's see how many${renderDots(dots)}`; | ||
} else { | ||
statusText.innerText = `Checking to see if you own any ${COLLECTION_NAME} 😻${renderDots(dots)}`; | ||
} | ||
} else { | ||
if(isOwner) { | ||
statusText.innerText = `You own ${editions.length} ${COLLECTION_NAME}!! 😻`; | ||
} else { | ||
statusText.innerText = `You don't own any ${COLLECTION_NAME} 😿`; | ||
} | ||
} | ||
dots = dots === 3 ? 1 : dots + 1; | ||
} | ||
|
||
function renderDots(dots) { | ||
let dotsString = ''; | ||
for (let i = 0; i < dots; i++) { | ||
dotsString += '.'; | ||
} | ||
return dotsString; | ||
} | ||
|
||
function timer(ms) { | ||
return new Promise(res => setTimeout(res, ms)); | ||
} | ||
|
||
async function fetchWithRetry(url) { | ||
await timer(TIMEOUT); | ||
return new Promise((resolve, reject) => { | ||
const fetch_retry = (_url) => { | ||
return fetch(_url).then(async (res) => { | ||
const status = res.status; | ||
|
||
if(status === 200) { | ||
return resolve(res.json()); | ||
} | ||
else { | ||
console.error(`ERROR STATUS: ${status}`) | ||
console.log('Retrying') | ||
await timer(TIMEOUT) | ||
fetch_retry(_url) | ||
} | ||
}) | ||
.catch(async (error) => { | ||
console.error(`CATCH ERROR: ${error}`) | ||
console.log('Retrying') | ||
await timer(TIMEOUT) | ||
fetch_retry(_url) | ||
}); | ||
} | ||
return fetch_retry(url); | ||
}); | ||
} |
Oops, something went wrong.