Skip to content

Commit

Permalink
[feat] Wire up create font project submit button to the backend and s…
Browse files Browse the repository at this point in the history
…mart contract apis (#11)
  • Loading branch information
jsanchez034 authored Jan 6, 2023
1 parent 8c599a4 commit 8f582d4
Show file tree
Hide file tree
Showing 13 changed files with 581 additions and 65 deletions.
3 changes: 2 additions & 1 deletion frontend/clientApi/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,5 @@ export * from './lens/getPublications';
export * from './lens/mirror';
export * from './lens/refresh';

export * from './ipfonts/createIPFontsUser';
export * from './ipfonts/createIPFontsUser';
export * from './ipfonts/createIPFontProject';
91 changes: 91 additions & 0 deletions frontend/clientApi/ipfonts/createIPFontProject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
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
});

if (!fontUploadOk) {
console.log(fontUploadError);
return;
}

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 (!metadataUploadOk) {
console.log(metadataUploadError);
return;
}

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);
} catch(err) {
console.log(err);
}
}
12 changes: 3 additions & 9 deletions frontend/clientApi/ipfonts/createIPFontsUser.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;

Expand Down
23 changes: 23 additions & 0 deletions frontend/clientApi/ipfonts/getIPFontsUser.js
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]
});
}
28 changes: 23 additions & 5 deletions frontend/components/Forms/Submit/Submit.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
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 { isConnected } = useAccount();
const { activeStepIndex, setActiveStepIndex, formData } = useContext(FormContext);

const submit = async () => {
// Check to see if user is logged in
if (isConnected) {
// 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
});
}

const submit = () => {
const data = { ...formData };
setFormData(data);
setActiveStepIndex(activeStepIndex + 1);
console.table(formData);
};
Expand Down
2 changes: 0 additions & 2 deletions frontend/components/UI/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { useRouter } from 'next/router';
import logo from '../../public/logoHeader.svg';
import classes from '../../styles/NavBar.module.css';
import ConnectButton from '../UI/ConnectButton';
import { client as lensClient, challenge, authenticate, getProfileByAddress, createIPFontsUser } from '../../clientApi';
import { ethers } from 'ethers';

export default function NavBar(props) {
const router = useRouter();
Expand Down
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"clsx": "^1.2.1",
"ethers": "^5.7.2",
"graphql": "^15.8.0",
"ipfs-http-client": "^59.0.0",
"iron-session": "^6.3.1",
"multer": "1.4.5-lts.1",
"next": "12.2.5",
Expand Down
45 changes: 0 additions & 45 deletions frontend/pages/api/store-font-data.js

This file was deleted.

2 changes: 1 addition & 1 deletion frontend/pages/api/upload-font.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const handler = async (req, res) => {
cid
});
} catch (_error) {
res.json({ ok: false });
res.status(500).json({ error: "Error uploading font files", ok: false });
}
break;
default:
Expand Down
41 changes: 41 additions & 0 deletions frontend/pages/api/upload-metadata.js
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);
} 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)
4 changes: 2 additions & 2 deletions frontend/utils/storeFilesIPFS.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Web3Storage, File } from "web3.storage";

function makeStorageClient() {
function makeWeb3StorageClient() {
return new Web3Storage({ token: process.env.WEB3STORAGE_TOKEN });
}

Expand All @@ -9,7 +9,7 @@ export async function storeFilesIPFS(files) {
return new File([buffer],name);
});

const client = makeStorageClient();
const client = makeWeb3StorageClient();
const cid = await client.put(web3StorageFiles);

return cid;
Expand Down
26 changes: 26 additions & 0 deletions frontend/utils/storeMetadataFileIPFS.js
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();
}
Loading

1 comment on commit 8f582d4

@vercel
Copy link

@vercel vercel bot commented on 8f582d4 Jan 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.