Last active
March 7, 2022 21:56
-
-
Save polluterofminds/68cfb3340b79e54a3af221c421eb5dbd to your computer and use it in GitHub Desktop.
Verify Signed Transactions and Access Gated Content
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 axios from "axios"; | |
import * as util from "ethereumjs-util"; | |
import {ethers} from "ethers"; | |
import { v4 as uuidv4 } from 'uuid'; | |
import { withIronSession } from 'next-iron-session' | |
const abi = require("../../PFPinatas.json").abi; | |
const contractAddress = "Your PFPinata Contract Address" | |
const ALCHEMY_API_KEY = process.env.ALCHEMY_API_KEY; | |
const urlV2API = `https://managed.mypinata.cloud/api/v1`; | |
const API_KEY = process.env.PINATA_V2_API_KEY | |
const CID = "CID for your content that should be for members only" | |
const GATEWAY_URL = "Your dedicated gateway URL"; | |
function withSession(handler) { | |
return withIronSession(handler, { | |
password: process.env.SECRET_COOKIE_PASSWORD, | |
cookieName: 'web3-auth-session', | |
cookieOptions: { | |
secure: process.env.NODE_ENV === 'production' ? true : false, | |
}, | |
}) | |
} | |
export default withSession(async (req, res) => { | |
if(req.method === "POST") { | |
try { | |
const message = req.session.get('message-session'); | |
const provider = await new ethers.providers.JsonRpcProvider(`https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_API_KEY}`); | |
const contract = await new ethers.Contract( contractAddress , abi , provider ); | |
let nonce = "\x19Ethereum Signed Message:\n" + JSON.stringify(message).length + JSON.stringify(message) | |
nonce = util.keccak(Buffer.from(nonce, "utf-8")) | |
const { v, r, s } = util.fromRpcSig(req.body.signature) | |
const pubKey = util.ecrecover(util.toBuffer(nonce), v, r, s) | |
const addrBuf = util.pubToAddress(pubKey) | |
const addr = util.bufferToHex(addrBuf) | |
if(req.body.address === addr) { | |
const balance = await contract.balanceOf(addr); | |
if(balance.toString() !== "0") { | |
const config = { | |
headers: { | |
"x-api-key": `${API_KEY}`, | |
'Content-Type': 'application/json' | |
} | |
} | |
// Generate Access Token | |
const content = await axios.get(`${urlV2API}/content`, config) | |
const { data } = content; | |
const { items } = data; | |
const item = items.find(i => i.cid === CID); | |
const body = { | |
timeoutSeconds: 3600, | |
contentIds: [item.id] | |
} | |
const token = await axios.post(`${urlV2API}/auth/content/jwt`, body, config); | |
return res.send(`${GATEWAY_URL}/ipfs/${CID}?accessToken=${token.data}`); | |
} else { | |
return res.status(401).send("You aren't a PFPinata"); | |
} | |
} else { | |
return res.status(401).send("Invalid signature"); | |
} | |
} catch (error) { | |
console.log(error); | |
res.status(500).json(error); | |
} | |
} else if(req.method === "GET") { | |
try { | |
const message = { contractAddress, id: uuidv4()} | |
req.session.set('message-session', message) | |
await req.session.save() | |
res.json(message) | |
} catch (error) { | |
console.log(error); | |
const { response: fetchResponse } = error | |
res.status(fetchResponse?.status || 500).json(error.data) | |
} | |
} else { | |
res.status(200).json({ message: 'This is the way...wait, no it is not. What are you doing here?' }) | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment