Skip to content

Commit

Permalink
v0.3 (#26)
Browse files Browse the repository at this point in the history
* feat: Update login controller to create a user if one does not already exist

* feat: Remove 404 error from login route

* fix: Load env variables into auth middleware file

* url(feat): send eip receipt

* tag(feat): send eip receipt

* likes(feat): sync with contract

* types(fix): delete unused types to avoid confusion

* likes(feat): send eip receipt

* contract(feat): move eip domain fetcher to function

* env(fix): use latest contract address

* likes(feat): dont use user address

* routes(feat): split routes to different files

* routes(feat): delete verifyMessage functions

* like(feat): receive like data in req.body

* likes(fix): better naming

* likes(fix): fix naming spelling

* tag(feat): receive params in req.body

* url(feat): receive params in req.body

* auth(fix): delete unused code

* auth(feat): get userId from jwt in middleware

* routes(feat): use ExtendedRequest in authenticate write functions

* schemas(feat): split into different files

* Feat/nico/routes splits in different files (#36)

* contract(feat): retrieve in format that contract understands

* env(feat): add new contract address

* sync(feat): set syncToBlockchain=false in every interaction

* Update deploy.yaml

* url(feat): send eip receipt

* tag(feat): send eip receipt

* likes(feat): sync with contract

* types(fix): delete unused types to avoid confusion

* likes(feat): send eip receipt

* contract(feat): move eip domain fetcher to function

* env(fix): use latest contract address

* likes(feat): dont use user address

* routes(feat): split routes to different files

* likes(fix): use the req, res function

* feat: Tags now passed in from mix as string. Object ids must be fetched that match the tag names

* feat: Save minor changes

* fix: Handle case where no tags are passed to backend

---------

Co-authored-by: Nico Serrano <[email protected]>
Co-authored-by: Nico Serrano <[email protected]>
  • Loading branch information
3 people authored Jan 16, 2024
1 parent a830317 commit f9735a2
Show file tree
Hide file tree
Showing 30 changed files with 5,142 additions and 779 deletions.
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ LOGIN_SECRET="login to backend"
DB_NAME="channel4"
PRIVATE_KEY=0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
RPC_URL=https://goerli.infura.io/v3/<YOUR_PROJECT_ID>
CONTRACT_ADDRESS=0x6189a62161FEDfFeBc5A56ffA419978937618843
CONTRACT_ADDRESS=0xC5Ae702852c6C262366dA86DB1CF0BDB9B376c86
2 changes: 1 addition & 1 deletion .env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ LOGIN_SECRET="login to backend"
DB_NAME="channel4"
PRIVATE_KEY=0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6
RPC_URL=http://localhost:8545
CONTRACT_ADDRESS=0x6189a62161FEDfFeBc5A56ffA419978937618843
CONTRACT_ADDRESS=0xC5Ae702852c6C262366dA86DB1CF0BDB9B376c86
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# channel-4-backend-poc2
# channel-4-backend
Backend code to synchronize users actions in the app to the state of the smart contract.

## To start
Expand Down
64 changes: 32 additions & 32 deletions src/abi/channel4.json
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,8 @@
"type": "uint256"
}
],
"internalType": "struct Data.PendingToLitigate",
"name": "pending",
"internalType": "struct Data.LikeToLitigate",
"name": "likeToLitigate",
"type": "tuple"
},
{
Expand Down Expand Up @@ -882,9 +882,31 @@
"internalType": "uint256",
"name": "numberOfLikesInPeriod",
"type": "uint256"
},
{
"components": [
{
"internalType": "uint256",
"name": "url",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "nonce",
"type": "uint256"
},
{
"internalType": "bool",
"name": "liked",
"type": "bool"
}
],
"internalType": "struct Data.UrlNonce[]",
"name": "urlNonces",
"type": "tuple[]"
}
],
"internalType": "struct Data.User[]",
"internalType": "struct Data.UserToSync[]",
"name": "usersToSync",
"type": "tuple[]"
},
Expand Down Expand Up @@ -922,6 +944,11 @@
"name": "submittedBy",
"type": "address"
},
{
"internalType": "uint256",
"name": "likes",
"type": "uint256"
},
{
"internalType": "string[]",
"name": "tagIds",
Expand All @@ -931,33 +958,6 @@
"internalType": "struct Data.ContentToSync[]",
"name": "contentsToAdd",
"type": "tuple[]"
},
{
"components": [
{
"internalType": "address",
"name": "submittedBy",
"type": "address"
},
{
"internalType": "string",
"name": "url",
"type": "string"
},
{
"internalType": "bool",
"name": "liked",
"type": "bool"
},
{
"internalType": "uint256",
"name": "nonce",
"type": "uint256"
}
],
"internalType": "struct Data.Pending[]",
"name": "pendingActions",
"type": "tuple[]"
}
],
"name": "syncState",
Expand Down Expand Up @@ -1079,8 +1079,8 @@
"type": "uint256"
}
],
"internalType": "struct Data.PendingToLitigate",
"name": "pending",
"internalType": "struct Data.LikeToLitigate",
"name": "like",
"type": "tuple"
},
{
Expand Down
28 changes: 15 additions & 13 deletions src/controllers/auth.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
const { ethers } = require("ethers");
const { User } = require("../models/schema");
const { generateToken } = require("../middleware/auth");
import { Request, Response } from 'express';
import { User } from '../models/users';
import { ethers } from 'ethers';
import { generateToken } from '../middleware/auth';


export const login = async (req: Request, res: Response) => {
try {
const { signedMessage } = req.body;

const message: string = process.env.LOGIN_SECRET ?? "";
const signer: string = ethers.verifyMessage(message, signedMessage);
const user = await User.findOne({ walletAddress: signer });
if (!user) {
return res.status(404).json({ message: "User not found" });
}
const message = process.env.LOGIN_SECRET;
const signer = ethers.verifyMessage(message as string, signedMessage);
// Find user or insert if they do not already exist
const user = await User.findOneAndUpdate(
{ walletAddress: signer },
{ $setOnInsert: { walletAddress: signer } },
{ returnOriginal: false, upsert: true }
);
const token = generateToken(user);
return res.status(200).json({ user: user, token: token });
} catch (error) {
if (error instanceof Error) {
console.log(error.message);
return res.status(500).json({ error: error.message });
} else {
return res.status(500).json({error: 'Unknown error occurred while logging in'});
return res.status(500).json({ error: 'Unknown error occurred while logging in' });
}

}
};

Expand All @@ -43,8 +45,8 @@ export const recoverAccount = async (req: Request, res: Response) => {
console.log(error.message);
res.status(400).json({ error: error.message });
} else {
return res.status(400).json({error: 'Unknown error occurred while recovering account'});
return res.status(400).json({ error: 'Unknown error occurred while recovering account' });
}

}
};
22 changes: 17 additions & 5 deletions src/controllers/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as LikeControl from './likes';
import ABI from '../abi/channel4.json';
import { Channel4 } from '../types/typechain/Channel4';

const __createContract = () => {
const getContractObject = () => {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL as string);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY as string, provider);
const contract = new ethers.Contract(
Expand All @@ -25,7 +25,7 @@ const syncDataToSmartContract = async (_req: Request, res: Response) => {
// Connect to smart contract
let contract: Channel4;
try {
contract = __createContract();
contract = getContractObject();
} catch (error: any) {
return res.status(500).json({ error: `Failed contract connection: ${error.message}` });
}
Expand All @@ -34,11 +34,10 @@ const syncDataToSmartContract = async (_req: Request, res: Response) => {
const users = await UserControl.getUsersToSync();
const tags = await TagControl.getTagsToSync();
const urls = await URLControl.getContentToSync();
const likes = await LikeControl.getLikesToSync();

// Submit a batch of data to the smart contract to sync
try {
let tx = await contract.syncState(users, tags, urls, likes);
let tx = await contract.syncState(users, tags, urls);
await tx.wait();
} catch (error: any) {
console.error("error: ", error);
Expand All @@ -49,12 +48,25 @@ const syncDataToSmartContract = async (_req: Request, res: Response) => {
await UserControl.markSynced(users.map(user => user.userAddress as string));
await TagControl.markSynced(tags.map(tag => tag.name));
await URLControl.markSynced(urls.map(url => url.url));
await LikeControl.markSynced();
await LikeControl.markSynced(users.map(user => user.userAddress as string));

// Return success on syncing smart contract with backend state
return res.status(200).json({});
};

const getEIPDomain = async () => {
const contract = getContractObject();
const EIP712Domain = await contract.eip712Domain();
return {
name: EIP712Domain.name,
version: EIP712Domain.version,
chainId: EIP712Domain.chainId,
verifyingContract: EIP712Domain.verifyingContract,
};
};

export {
getContractObject,
syncDataToSmartContract,
getEIPDomain,
};
Loading

0 comments on commit f9735a2

Please sign in to comment.