-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[feat] Wire up create font project submit button to the backend and smart contract apis #11
Changes from 3 commits
76b778f
193867c
84eced6
b26bdca
2f480b8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import connectContract from '../../utils/connectContract'; | ||
|
||
|
||
export async function createIPFontProject({ | ||
files, | ||
name, | ||
description, | ||
perCharacterMintPrice, | ||
mintLimit | ||
}) { | ||
const ipfontsContract = connectContract(); | ||
|
||
if (!ipfontsContract) { | ||
console.log('Cound not connect to contract'); | ||
return; | ||
} | ||
|
||
const formData = new FormData(); | ||
|
||
for (let i = 0; i < files.length; i++) { | ||
formData.append('fonts', files[i]); | ||
}; | ||
|
||
try { | ||
const uploadFontResponse = await fetch('/api/upload-font', { | ||
method: 'POST', | ||
body: formData | ||
}); | ||
|
||
const { | ||
ok: fontUploadOk, | ||
cid: fontFilesCID, | ||
error: fontUploadError | ||
} = await uploadFontResponse.json(); | ||
|
||
console.log({ | ||
fontUploadOk, | ||
fontFilesCID, | ||
fontUploadError | ||
}); | ||
|
||
const uploadMetadataResponse = await fetch('/api/upload-metadata', { | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
name, | ||
description | ||
}) | ||
}); | ||
|
||
const { | ||
ok: metadataUploadOk, | ||
cid: fontMetadataCID, | ||
error: metadataUploadError | ||
} = await uploadMetadataResponse.json(); | ||
|
||
console.log({ | ||
metadataUploadOk, | ||
fontMetadataCID, | ||
metadataUploadError | ||
}); | ||
|
||
if (fontUploadOk && metadataUploadOk) { | ||
const createdAt = Date.now(); | ||
|
||
const txn = await ipfontsContract.createFontProject( | ||
createdAt, | ||
createdAt, | ||
perCharacterMintPrice, | ||
mintLimit, | ||
process.env.NEXT_PUBLIC_SUPERFLUID_MATICX_TOKEN_ADDRESS, | ||
fontMetadataCID, | ||
fontFilesCID, | ||
{ gasLimit: 900000 } | ||
); | ||
console.log("IPFonts : Creating font project entity", txn.hash); | ||
|
||
await txn.wait(); | ||
console.log("IPFonts : Font project entity created", txn.hash); | ||
} else { | ||
console.log(fontUploadError); | ||
console.log(metadataUploadError); | ||
} | ||
} catch(err) { | ||
console.log(err); | ||
} | ||
} | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,11 +2,10 @@ import { readContract } from '@wagmi/core' | |
import connectContract from '../../utils/connectContract'; | ||
import abiJSON from "../../utils/FontProject.json"; | ||
import { ethers } from 'ethers'; | ||
|
||
const contractAddress = process.env.NEXT_PUBLIC_CONTRACT_ADDRESS; | ||
import getIPFontsUser from './getIPFontsUser'; | ||
|
||
export async function createIPFontsUser({ | ||
lensAddress, | ||
address, | ||
lensHandle, | ||
email, | ||
name, | ||
|
@@ -27,12 +26,7 @@ export async function createIPFontsUser({ | |
return; | ||
} | ||
|
||
const { createdAt} = await readContract({ | ||
address: contractAddress, | ||
abi: abiJSON.abi, | ||
functionName: 'addressToUser', | ||
args: [lensAddress] | ||
}); | ||
const { createdAt } = await getIPFontsUser(address); | ||
|
||
const isRegistered = !ethers.BigNumber.from(createdAt).isZero; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file is related to the part I'm testing, didn't modify it (but I used parts of it) to avoid merging stashing, but my plan is to refactor some of the logic I'm using in the form here, does that make sense? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cool yeah makes sense to me 👍 |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { readContract } from '@wagmi/core' | ||
import connectContract from '../../utils/connectContract'; | ||
import abiJSON from "../../utils/FontProject.json"; | ||
|
||
const contractAddress = process.env.NEXT_PUBLIC_CONTRACT_ADDRESS; | ||
|
||
export async function getIPFontsUser({ | ||
address | ||
}) { | ||
const ipfontsContract = connectContract(); | ||
|
||
if (!ipfontsContract) { | ||
console.log('Cound not connect to contract'); | ||
return; | ||
} | ||
|
||
return await readContract({ | ||
address: contractAddress, | ||
abi: abiJSON.abi, | ||
functionName: 'addressToUser', | ||
args: [lensAddress] | ||
}); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,39 @@ | ||
import React, { useContext } from "react"; | ||
import { useAccount } from 'wagmi'; | ||
import { FormContext } from "../../Overlay/CreateProject.js"; | ||
import classes from "../../../styles/Forms.module.css"; | ||
import { | ||
client as lensClient, | ||
createIPFontsUser, | ||
createIPFontProject, | ||
getProfileByAddress | ||
} from '../../../clientApi'; | ||
|
||
export default function Submit() { | ||
const { activeStepIndex, setActiveStepIndex, formData, setFormData } = | ||
useContext(FormContext); | ||
const { address, isConnected } = useAccount(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Haven't seen this before, looks smart! |
||
const { activeStepIndex, setActiveStepIndex, formData } = useContext(FormContext); | ||
|
||
const submit = async () => { | ||
// Check to see if user is logged in | ||
if (isConnected) { | ||
const lensProfile = await lensClient.query({ | ||
query: getProfileByAddress, | ||
variables: { | ||
owner: address, | ||
}, | ||
}); | ||
|
||
// TODO - create user in smart contract if it does not exist already | ||
|
||
await createIPFontProject({ | ||
files: formData.files, | ||
name : formData.projectName, | ||
description : formData.description, | ||
perCharacterMintPrice: formData.setPrice, | ||
mintLimit: formData.minLimit | ||
}); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file really got cleaned 💯 sweet! |
||
|
||
const submit = () => { | ||
const data = { ...formData }; | ||
setFormData(data); | ||
setActiveStepIndex(activeStepIndex + 1); | ||
console.table(formData); | ||
}; | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { withIronSessionApiRoute } from 'iron-session/next'; | ||
import ironOptions from '../../config/ironOptions'; | ||
import { storeMetadataFileIPFS } from '../../utils/storeMetadataFileIPFS'; | ||
|
||
async function handler(req, res) { | ||
if (req.method === "POST") { | ||
// Check that user has signed in and is authorized to uplaod files | ||
if (!req.session.siwe) { | ||
return res.status(401).json({ message: 'You have to sign-in first' }); | ||
} | ||
|
||
return await storeFontMetadata(req, res); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you think about making a generic There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah yeah good call 👍 Let me update in a follow up PR. The type variable could be a param passed in the request body |
||
} else { | ||
return res | ||
.setHeader('Allow', ['POST']) | ||
.status(405) | ||
.json({ message: "Method not allowed", success: false }); | ||
} | ||
} | ||
|
||
async function storeFontMetadata(req, res) { | ||
const body = req.body; | ||
|
||
try { | ||
const file = { | ||
path : '/tmp/data.json', | ||
content: Buffer.from(body) | ||
}; | ||
|
||
const cid = await storeMetadataFileIPFS(file); | ||
|
||
return res.status(200).json({ ok: true, cid: cid }); | ||
} catch (err) { | ||
console.log(err); | ||
return res | ||
.status(500) | ||
.json({ error: "Error uploading font metadata", ok: false }); | ||
} | ||
} | ||
|
||
export default withIronSessionApiRoute(handler, ironOptions) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { create } from 'ipfs-http-client' | ||
|
||
function makeInfuraStorageClient() { | ||
const idKeySecretPair = `${process.env.INFURA_IPFS_PROJECT_ID}:${process.env.INFURA_IPFS_KEY_SECRET}`; | ||
const auth = 'Basic ' + Buffer.from(idKeySecretPair).toString('base64'); | ||
|
||
return create({ | ||
host: process.env.INFURA_IPFS_HOST, | ||
port: process.env.INFURA_IPFS_PORT, | ||
protocol: 'https', | ||
headers: { | ||
authorization: auth, | ||
}, | ||
}); | ||
} | ||
|
||
export async function storeMetadataFileIPFS(file) { | ||
const client = makeInfuraStorageClient(); | ||
|
||
const result = await client.add({ | ||
path : file.path, | ||
content : file.content | ||
}); | ||
|
||
return result.cid.toString(); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already used this file for the user :) thanks a lot JP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll take this as example for the user :) Does make sense to have these files:
createIPFontsUser.js
editIPFontsUser.js
createLensUser.js
(just in testnet)editLensUser.js
And condition them according to how the user has been authenticated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice yeah makes sense 😃