From f03fbe1abf82869ac96bcf95e1ce3f84a7a12c85 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Thu, 28 Sep 2023 20:23:52 -0400 Subject: [PATCH 1/9] fix(persistence-interface): Switch saveoffchainproof to return void --- server/helpers/adapters/postgres.ts | 1 - server/repositories/offchain-proofs-repository.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index 5a06e526..11c76e51 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -244,7 +244,6 @@ const saveOffchainProof = async ( JSON.stringify(steps) ]); console.log(result.rows.length); - return result.rows; }; const getOffchainProof = async (space: string, merkleRoot: string) => { diff --git a/server/repositories/offchain-proofs-repository.ts b/server/repositories/offchain-proofs-repository.ts index 6645fb19..99c09e10 100644 --- a/server/repositories/offchain-proofs-repository.ts +++ b/server/repositories/offchain-proofs-repository.ts @@ -6,6 +6,6 @@ export type OffchainProofsRepository = { space: string, merkleRoot: string, steps: Record[] - ) => Promise; + ) => Promise; }; export const offchainProofsRepository: OffchainProofsRepository = postgresOffchainProofsRepository; From 8b4f9e04120a6f749df2e4295223e359f3e60431 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Thu, 28 Sep 2023 20:41:28 -0400 Subject: [PATCH 2/9] fix(persistence-interface): Introduce offchain proof type to simplify offchain proof repository interface --- server/helpers/adapters/postgres.ts | 21 ++++++++++++------- server/index.ts | 6 +++++- .../offchain-proofs-repository.ts | 14 ++++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index 11c76e51..5334d5e9 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -233,20 +233,27 @@ const getAllDraftsExceptSponsored = async (space: string) => { }; const saveOffchainProof = async ( - space: string, - merkleRoot: string, - steps: Record[] +offchainProof: OffchainProof ) => { const insert = `INSERT INTO offchain_proofs (merkle_root, space, steps) VALUES ($1, $2, $3);`; const result = await db.query(insert, [ - merkleRoot, - space, - JSON.stringify(steps) + offchainProof.merkleRoot, + offchainProof.space, + JSON.stringify(offchainProof.steps) ]); console.log(result.rows.length); }; -const getOffchainProof = async (space: string, merkleRoot: string) => { +export type OffchainProof = { + space: string, + merkleRoot: string, + steps: Record[] +}; + +const getOffchainProof = async ( + space: string, + merkleRoot: string +): Promise => { const select = `SELECT * FROM offchain_proofs WHERE space = $1 AND merkle_root = $2 LIMIT 1;`; const result = await db.query(select, [space, merkleRoot]); console.log(result.rows.length); diff --git a/server/index.ts b/server/index.ts index 1bf7092d..ffb6e9d1 100644 --- a/server/index.ts +++ b/server/index.ts @@ -242,7 +242,11 @@ router.post('/:space/offchain_proofs', async (req, res) => { if (merkleTree.getHexRoot() === merkleRoot) { try { - await offchainProofsRepository.saveOffchainProof(space, merkleRoot, steps); + await offchainProofsRepository.saveOffchainProof({ + space, + merkleRoot, + steps + }); return res.sendStatus(201); } catch (error) { return res.status(500).send({ diff --git a/server/repositories/offchain-proofs-repository.ts b/server/repositories/offchain-proofs-repository.ts index 99c09e10..689fda46 100644 --- a/server/repositories/offchain-proofs-repository.ts +++ b/server/repositories/offchain-proofs-repository.ts @@ -1,11 +1,15 @@ -import { postgresOffchainProofsRepository } from '../helpers/adapters/postgres'; +import { + OffchainProof, + postgresOffchainProofsRepository +} from '../helpers/adapters/postgres'; export type OffchainProofsRepository = { - getOffchainProof: (space: string, merkleRoot: string) => Promise; - saveOffchainProof: ( + getOffchainProof: ( space: string, - merkleRoot: string, - steps: Record[] + merkleRoot: string + ) => Promise; + saveOffchainProof: ( + offchainProof: OffchainProof ) => Promise; }; export const offchainProofsRepository: OffchainProofsRepository = postgresOffchainProofsRepository; From cd806a71f7775008932f044438d082aeaa1ae465 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Thu, 28 Sep 2023 20:47:00 -0400 Subject: [PATCH 3/9] fix(persistence-interface): Specify void returns for events repository where applicable --- server/helpers/adapters/postgres.ts | 89 ++++++++++++------------ server/repositories/events-repository.ts | 8 +-- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index 5334d5e9..fa75f689 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -1,6 +1,9 @@ import db from '../postgres'; import { toVotesMessageJson } from '../utils'; -import { EventsDB, EventsRepository } from '../../repositories/events-repository.js'; +import { + EventsDB, + EventsRepository +} from '../../repositories/events-repository.js'; import { MessagesRepository } from '../../repositories/messages-repository.js'; import { OffchainProofsRepository } from '../../repositories/offchain-proofs-repository.js'; @@ -59,7 +62,7 @@ const sponsorDraftIfAny = async (space, erc712DraftHash) => { return result; }; - const storeDraft = async ( +const storeDraft = async ( space, erc712Hash, token, @@ -132,7 +135,9 @@ const storeVote = async ( ); }; -const getExpiredEvents: (timestamp: number) => Promise = (timestamp) => { +const getExpiredEvents: ( + timestamp: number +) => Promise = timestamp => { return db .query('SELECT * FROM events WHERE expire <= $1', [ timestamp @@ -157,11 +162,7 @@ const getMessagesByAction = async ( return result.rows; }; -const getMessagesById = async ( - space: string, - id: string, - msgType: string -) => { +const getMessagesById = async (space: string, id: string, msgType: string) => { const query = `SELECT * FROM messages WHERE space = $1 AND id = $2 AND type = $3`; const result = await db.query(query, [space, id, msgType]); console.log(result.rows.length); @@ -232,9 +233,7 @@ const getAllDraftsExceptSponsored = async (space: string) => { return result.rows; }; -const saveOffchainProof = async ( -offchainProof: OffchainProof -) => { +const saveOffchainProof = async (offchainProof: OffchainProof) => { const insert = `INSERT INTO offchain_proofs (merkle_root, space, steps) VALUES ($1, $2, $3);`; const result = await db.query(insert, [ offchainProof.merkleRoot, @@ -245,9 +244,9 @@ offchainProof: OffchainProof }; export type OffchainProof = { - space: string, - merkleRoot: string, - steps: Record[] + space: string; + merkleRoot: string; + steps: Record[]; }; const getOffchainProof = async ( @@ -261,47 +260,51 @@ const getOffchainProof = async ( }; const deleteProcessedEvent = (event: EventsDB) => { - return db.query( - 'DELETE FROM events WHERE id = $1 AND event = $2', - [event.id, event.event] - ); -} + return db + .query( + 'DELETE FROM events WHERE id = $1 AND event = $2', + [event.id, event.event] + ) + .then(() => undefined); +}; function insertCreatedProposal( EVENT_ID: string, space: string, timestamp: number ) { - return db.query(EVENTS_INSERT_STATEMENT, [ - EVENT_ID, - 'proposal/created', - space, - timestamp - ]); + return db + .query(EVENTS_INSERT_STATEMENT, [ + EVENT_ID, + 'proposal/created', + space, + timestamp + ]) + .then(() => undefined); } function insertStartedProposal( EVENT_ID: string, space: string, timestamp: number ) { - return db.query(EVENTS_INSERT_STATEMENT, [ - EVENT_ID, - 'proposal/start', - space, - timestamp - ]); + return db + .query(EVENTS_INSERT_STATEMENT, [ + EVENT_ID, + 'proposal/start', + space, + timestamp + ]) + .then(() => undefined); } -function insertProposalEnd( - EVENT_ID: string, - space: string, - timestamp: number -) { - return db.query(EVENTS_INSERT_STATEMENT, [ - EVENT_ID, - 'proposal/end', - space, - timestamp - ]); +function insertProposalEnd(EVENT_ID: string, space: string, timestamp: number) { + return db + .query(EVENTS_INSERT_STATEMENT, [ + EVENT_ID, + 'proposal/end', + space, + timestamp + ]) + .then(() => undefined); } export const postgresEventsRepository: EventsRepository = { deleteProcessedEvent, @@ -329,4 +332,4 @@ export const postgresMessagesRepository: MessagesRepository = { export const postgresOffchainProofsRepository: OffchainProofsRepository = { getOffchainProof, saveOffchainProof -} +}; diff --git a/server/repositories/events-repository.ts b/server/repositories/events-repository.ts index 7582764c..73b53496 100644 --- a/server/repositories/events-repository.ts +++ b/server/repositories/events-repository.ts @@ -8,22 +8,22 @@ export type EventsDB = { }; export type EventsRepository = { getExpiredEvents: (timestamp: number) => Promise; - deleteProcessedEvent: (event: EventsDB) => Promise; + deleteProcessedEvent: (event: EventsDB) => Promise; insertCreatedProposal: ( EVENT_ID: string, space: string, timestamp: number - ) => Promise, + ) => Promise, insertStartedProposal: ( EVENT_ID: string, space: string, timestamp: number - ) => Promise + ) => Promise insertProposalEnd: ( EVENT_ID: string, space: string, timestamp: number - ) => Promise + ) => Promise }; export const eventsRepository: EventsRepository = postgresEventsRepository; From bb5bf34b48d4964e5eda23bcffe564dbdeded9e6 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Thu, 5 Oct 2023 23:54:07 -0400 Subject: [PATCH 4/9] fix(persistence-interface): Move event to own file --- server/helpers/adapters/postgres.ts | 2 +- server/models/event.ts | 6 ++++++ server/repositories/events-repository.ts | 7 +------ 3 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 server/models/event.ts diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index fa75f689..a18d380b 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -1,11 +1,11 @@ import db from '../postgres'; import { toVotesMessageJson } from '../utils'; import { - EventsDB, EventsRepository } from '../../repositories/events-repository.js'; import { MessagesRepository } from '../../repositories/messages-repository.js'; import { OffchainProofsRepository } from '../../repositories/offchain-proofs-repository.js'; +import { EventsDB } from '../../models/event.js'; /** * Values to insert into the `events` database. diff --git a/server/models/event.ts b/server/models/event.ts new file mode 100644 index 00000000..69e3d782 --- /dev/null +++ b/server/models/event.ts @@ -0,0 +1,6 @@ +export type EventsDB = { + event: string; + expire: number; + id: string; + space: string; +}; diff --git a/server/repositories/events-repository.ts b/server/repositories/events-repository.ts index 73b53496..dbff23b3 100644 --- a/server/repositories/events-repository.ts +++ b/server/repositories/events-repository.ts @@ -1,11 +1,6 @@ import { postgresEventsRepository } from '../helpers/adapters/postgres'; +import { EventsDB } from '../models/event.js'; -export type EventsDB = { - event: string; - expire: number; - id: string; - space: string; -}; export type EventsRepository = { getExpiredEvents: (timestamp: number) => Promise; deleteProcessedEvent: (event: EventsDB) => Promise; From 6abd7b4ed1162f1450f5b5b16af0515a9b905d23 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Thu, 5 Oct 2023 23:55:06 -0400 Subject: [PATCH 5/9] fix(persistence-interface): Rename EventDb to event --- server/helpers/adapters/postgres.ts | 8 ++++---- server/models/event.ts | 2 +- server/repositories/events-repository.ts | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index a18d380b..f69e2b47 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -5,7 +5,7 @@ import { } from '../../repositories/events-repository.js'; import { MessagesRepository } from '../../repositories/messages-repository.js'; import { OffchainProofsRepository } from '../../repositories/offchain-proofs-repository.js'; -import { EventsDB } from '../../models/event.js'; +import { Event } from '../../models/event.js'; /** * Values to insert into the `events` database. @@ -137,9 +137,9 @@ const storeVote = async ( const getExpiredEvents: ( timestamp: number -) => Promise = timestamp => { +) => Promise = timestamp => { return db - .query('SELECT * FROM events WHERE expire <= $1', [ + .query('SELECT * FROM events WHERE expire <= $1', [ timestamp ]) .then(result => result.rows); @@ -259,7 +259,7 @@ const getOffchainProof = async ( return result.rows; }; -const deleteProcessedEvent = (event: EventsDB) => { +const deleteProcessedEvent = (event: Event) => { return db .query( 'DELETE FROM events WHERE id = $1 AND event = $2', diff --git a/server/models/event.ts b/server/models/event.ts index 69e3d782..28cf7ecd 100644 --- a/server/models/event.ts +++ b/server/models/event.ts @@ -1,4 +1,4 @@ -export type EventsDB = { +export type Event = { event: string; expire: number; id: string; diff --git a/server/repositories/events-repository.ts b/server/repositories/events-repository.ts index dbff23b3..94596bc8 100644 --- a/server/repositories/events-repository.ts +++ b/server/repositories/events-repository.ts @@ -1,9 +1,9 @@ import { postgresEventsRepository } from '../helpers/adapters/postgres'; -import { EventsDB } from '../models/event.js'; +import { Event } from '../models/event.js'; export type EventsRepository = { - getExpiredEvents: (timestamp: number) => Promise; - deleteProcessedEvent: (event: EventsDB) => Promise; + getExpiredEvents: (timestamp: number) => Promise; + deleteProcessedEvent: (event: Event) => Promise; insertCreatedProposal: ( EVENT_ID: string, space: string, From 157864cee5bf9901a342ede18500a008c5bfdb17 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Wed, 4 Oct 2023 21:18:50 -0400 Subject: [PATCH 6/9] feat(persistence-interface): Create message model --- server/models/message.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 server/models/message.ts diff --git a/server/models/message.ts b/server/models/message.ts new file mode 100644 index 00000000..67c7dd95 --- /dev/null +++ b/server/models/message.ts @@ -0,0 +1,14 @@ +export type Message = { + id: string; + address: string; + version: string; + timestamp: number; + space?: string; + token?: string; + type: string; + payload?: string; + sig: string; + metadata?: string; + actionId: string; + data?: string; +}; From 6062f815c7a4869edfd9f61ec2874ee6caf8a977 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Fri, 6 Oct 2023 00:32:29 -0400 Subject: [PATCH 7/9] fix(persistence-interface): Return draft proposals as number --- server/helpers/adapters/postgres.ts | 5 ++--- server/index.ts | 4 ++-- server/repositories/messages-repository.ts | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index f69e2b47..69df0ce8 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -56,10 +56,9 @@ const insert = async (params: Array) => { return await db.query(cmd, params); }; -const sponsorDraftIfAny = async (space, erc712DraftHash) => { +const sponsorDraftIfAny = async (space, erc712DraftHash): Promise => { const update = `UPDATE messages SET data=data||'{"sponsored": true}' WHERE type = 'draft' AND id = $1 AND space = $2`; - const result = await db.query(update, [erc712DraftHash, space]); - return result; + return await db.query(update, [erc712DraftHash, space]).then((result) => result.rowCount); }; const storeDraft = async ( diff --git a/server/index.ts b/server/index.ts index ffb6e9d1..491dbaa6 100644 --- a/server/index.ts +++ b/server/index.ts @@ -509,13 +509,13 @@ router.post('/message', async (req, res) => { erc712Data.chainId ); - const sponsorDraftResult = await messagesRepository.sponsorDraftIfAny( + const numberOfDrafts = await messagesRepository.sponsorDraftIfAny( space, erc712DraftHash ); const erc712DraftHashToSet = - sponsorDraftResult.rowCount > 0 ? erc712DraftHash : ''; + numberOfDrafts> 0 ? erc712DraftHash : ''; await messagesRepository.storeProposal( space, diff --git a/server/repositories/messages-repository.ts b/server/repositories/messages-repository.ts index e6a2d485..930ada24 100644 --- a/server/repositories/messages-repository.ts +++ b/server/repositories/messages-repository.ts @@ -53,7 +53,7 @@ export type MessagesRepository = { relayerIpfsHash, actionId ) => Promise - sponsorDraftIfAny: (space, erc712DraftHash) => Promise, + sponsorDraftIfAny: (space, erc712DraftHash) => Promise, findVotesForProposals: (space, proposals) => Promise }; export const messagesRepository: MessagesRepository = postgresMessagesRepository; From d45a66a5d050bbf1a7abc52e92bce0ef549652c0 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Fri, 6 Oct 2023 00:33:54 -0400 Subject: [PATCH 8/9] fix(persistence-interface): Use Message type for persistence where trivially possible --- server/helpers/adapters/postgres.ts | 15 ++++++++------- server/repositories/messages-repository.ts | 21 +++++++++++---------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index 69df0ce8..d099c919 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -6,6 +6,7 @@ import { import { MessagesRepository } from '../../repositories/messages-repository.js'; import { OffchainProofsRepository } from '../../repositories/offchain-proofs-repository.js'; import { Event } from '../../models/event.js'; +import { Message } from '../../models/message.js'; /** * Values to insert into the `events` database. @@ -69,8 +70,8 @@ const storeDraft = async ( authorIpfsHash, relayerIpfsHash, actionId -) => { - return await insert( +): Promise => { + await insert( format( erc712Hash, body, @@ -94,8 +95,8 @@ const storeProposal = async ( authorIpfsHash, relayerIpfsHash, actionId -) => { - return await insert( +): Promise => { + await insert( format( erc712Hash, body, @@ -118,8 +119,8 @@ const storeVote = async ( authorIpfsHash, relayerIpfsHash, actionId -) => { - return await insert( +): Promise => { + await insert( format( erc712Hash, body, @@ -225,7 +226,7 @@ const getAllProposalsAndVotesByAction = async ( return await findVotesForProposals(space, proposalsResult.rows); }; -const getAllDraftsExceptSponsored = async (space: string) => { +const getAllDraftsExceptSponsored = async (space: string): Promise => { const query = `SELECT * FROM messages WHERE type = 'draft' AND space = $1 AND data ->> 'sponsored' = 'false' ORDER BY timestamp ASC`; const result = await db.query(query, [space]); console.log(result.rows.length); diff --git a/server/repositories/messages-repository.ts b/server/repositories/messages-repository.ts index 930ada24..89fc1620 100644 --- a/server/repositories/messages-repository.ts +++ b/server/repositories/messages-repository.ts @@ -1,30 +1,31 @@ import { postgresMessagesRepository } from '../helpers/adapters/postgres'; +import { Message } from '../models/message.js'; export type MessagesRepository = { - getMessages: (spaces: string, msgType: string) => Promise; + getMessages: (spaces: string, msgType: string) => Promise; getMessagesByAction: ( space: string, actionId: string, msgType: string - ) => Promise; + ) => Promise; getMessagesById: ( space: string, id: string, msgType: string - ) => Promise; + ) => Promise; getVoteBySender: ( space: string, address: string, proposalId: string - ) => Promise; - getProposalByDraft: (space: string, id: string) => Promise; - getProposalVotes: (space: string, id: string) => Promise; + ) => Promise; + getProposalByDraft: (space: string, id: string) => Promise; + getProposalVotes: (space: string, id: string) => Promise; getAllProposalsAndVotes: (space: string) => Promise; getAllProposalsAndVotesByAction: ( space: string, actionId: string ) => Promise; - getAllDraftsExceptSponsored: (space: string) => Promise; + getAllDraftsExceptSponsored: (space: string) => Promise; storeDraft: ( space, erc712Hash, @@ -33,7 +34,7 @@ export type MessagesRepository = { authorIpfsHash, relayerIpfsHash, actionId - ) => Promise, + ) => Promise, storeProposal: ( space, erc712Hash, @@ -43,7 +44,7 @@ export type MessagesRepository = { authorIpfsHash, relayerIpfsHash, actionId - ) => Promise, + ) => Promise, storeVote:( space, erc712Hash, @@ -52,7 +53,7 @@ export type MessagesRepository = { authorIpfsHash, relayerIpfsHash, actionId - ) => Promise + ) => Promise sponsorDraftIfAny: (space, erc712DraftHash) => Promise, findVotesForProposals: (space, proposals) => Promise }; From 7c0a1b076d4d439752be93651596560eb3ba7f22 Mon Sep 17 00:00:00 2001 From: Yousuf Haque Date: Fri, 6 Oct 2023 01:15:26 -0400 Subject: [PATCH 9/9] fix(persistence-interface): Introduce message with votes and proposal with votes types --- server/helpers/adapters/postgres.ts | 21 ++-- server/helpers/utils.ts | 108 +++++++++++---------- server/models/message.ts | 26 ++++- server/repositories/messages-repository.ts | 11 ++- 4 files changed, 103 insertions(+), 63 deletions(-) diff --git a/server/helpers/adapters/postgres.ts b/server/helpers/adapters/postgres.ts index d099c919..33e1346b 100644 --- a/server/helpers/adapters/postgres.ts +++ b/server/helpers/adapters/postgres.ts @@ -6,7 +6,7 @@ import { import { MessagesRepository } from '../../repositories/messages-repository.js'; import { OffchainProofsRepository } from '../../repositories/offchain-proofs-repository.js'; import { Event } from '../../models/event.js'; -import { Message } from '../../models/message.js'; +import { Message, MessageWithVotes, VoteMessage } from '../../models/message.js'; /** * Values to insert into the `events` database. @@ -188,28 +188,28 @@ const getProposalByDraft = async (space: string, id: string) => { return result.rows; }; -const getProposalVotes = async (space: string, id: string) => { +const getProposalVotes = async (space: string, id: string): Promise => { const query = `SELECT * FROM messages WHERE type = 'vote' AND space = $1 AND payload ->> 'proposalId' = $2 ORDER BY timestamp ASC`; const result = await db.query(query, [space, id]); console.log(result.rows.length); return result.rows; }; -const findVotesForProposals = (space, proposals) => +const findVotesForProposals: (space: string, proposals: Message[]) => Promise = (space, proposals) => Promise.all( proposals.map(p => getProposalVotes(space, p.id) .then(votes => votes && votes.length > 0 ? toVotesMessageJson(votes) : [] ) - .then(votes => { - p['votes'] = votes; - return p; - }) + .then(votes => ({ + ...p, + votes + })) ) ); -const getAllProposalsAndVotes = async (space: string) => { +const getAllProposalsAndVotes = async (space: string): Promise => { const queryProposals = `SELECT * FROM messages WHERE type = 'proposal' AND space = $1`; const proposalsResult = await db.query(queryProposals, [space]); console.log(proposalsResult.rows.length); @@ -219,7 +219,7 @@ const getAllProposalsAndVotes = async (space: string) => { const getAllProposalsAndVotesByAction = async ( space: string, actionId: string -) => { +) : Promise=> { const queryProposals = `SELECT * FROM messages WHERE type = 'proposal' AND space = $1 AND "actionId" = $2 ORDER BY timestamp DESC`; const proposalsResult = await db.query(queryProposals, [space, actionId]); console.log(proposalsResult.rows.length); @@ -282,6 +282,7 @@ function insertCreatedProposal( ]) .then(() => undefined); } + function insertStartedProposal( EVENT_ID: string, space: string, @@ -296,6 +297,7 @@ function insertStartedProposal( ]) .then(() => undefined); } + function insertProposalEnd(EVENT_ID: string, space: string, timestamp: number) { return db .query(EVENTS_INSERT_STATEMENT, [ @@ -306,6 +308,7 @@ function insertProposalEnd(EVENT_ID: string, space: string, timestamp: number) { ]) .then(() => undefined); } + export const postgresEventsRepository: EventsRepository = { deleteProcessedEvent, getExpiredEvents, diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index b8f1064a..aee146ac 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts @@ -3,6 +3,12 @@ import { providers } from 'ethers'; import { convertUtf8ToHex } from '@walletconnect/utils'; import * as ethUtil from 'ethereumjs-util'; import { isValidSignature } from './eip1271'; +import { + Message, + MessageWithVotes, + ProposalWithVotesMessage, + VoteMessage +} from '../models/message.js'; export const jsonParse = (input, fallback?) => { try { @@ -88,31 +94,31 @@ export const hashPersonalMessage = (msg: string): string => { return ethUtil.bufferToHex(hash); }; -export const toMessageJson = (messages: any): any => - Object.fromEntries( - messages.map(message => { - return [ - message.type === 'vote' ? message.address : message.id, - { - address: message.address, - data: message.data, - msg: { - version: message.version, - timestamp: message.timestamp.toString(), - token: message.token, - type: message.type, - payload: message.payload - }, - sig: message.sig, - authorIpfsHash: message.id, - relayerIpfsHash: message.metadata.relayerIpfsHash, - actionId: message.actionId +export const toMessageJson = (messages: Message[]): ProposalWithVotesMessage => + messages.reduce((proposal, message) => { + return { + ...proposal, + [message.type === 'vote' ? message.address : message.id]: { + address: message.address, + data: message.data, + msg: { + version: message.version, + timestamp: message.timestamp.toString(), + token: message.token, + type: message.type, + payload: message.payload }, - ]; - }) - ); + sig: message.sig, + authorIpfsHash: message.id, + relayerIpfsHash: message.metadata + ? message.metadata.relayerIpfsHash + : undefined, + actionId: message.actionId + } + }; + }, {}); -export const toVoteMessageJson = (message: any): any => { +export const toVoteMessageJson = (message: Message): VoteMessage => { return { [message.address]: { id: message.id, @@ -127,36 +133,40 @@ export const toVoteMessageJson = (message: any): any => { }, sig: message.sig, authorIpfsHash: message.id, - relayerIpfsHash: message.metadata.relayerIpfsHash, + relayerIpfsHash: message.metadata + ? message.metadata.relayerIpfsHash + : undefined, actionId: message.actionId } }; }; -export const toVotesMessageJson = (messages: any): any => +export const toVotesMessageJson = (messages: Message[]): VoteMessage[] => messages.map(m => toVoteMessageJson(m)); -export const toProposalWithVotesMessageJson = (messages: any): any => - Object.fromEntries( - messages.map(message => { - return [ - message.id, - { - address: message.address, - data: message.data, - msg: { - version: message.version, - timestamp: message.timestamp.toString(), - token: message.token, - type: message.type, - payload: message.payload - }, - votes: message.votes, - sig: message.sig, - authorIpfsHash: message.id, - relayerIpfsHash: message.metadata.relayerIpfsHash, - actionId: message.actionId - } - ]; - }) - ); +export const toProposalWithVotesMessageJson = ( + messages: MessageWithVotes[] +): ProposalWithVotesMessage => + messages.reduce((proposal, message) => { + return { + ...proposal, + [message.id]: { + address: message.address, + data: message.data, + msg: { + version: message.version, + timestamp: message.timestamp.toString(), + token: message.token, + type: message.type, + payload: message.payload + }, + votes: message.votes, + sig: message.sig, + authorIpfsHash: message.id, + relayerIpfsHash: message.metadata + ? message.metadata.relayerIpfsHash + : undefined, + actionId: message.actionId + } + }; + }, {}); diff --git a/server/models/message.ts b/server/models/message.ts index 67c7dd95..b00fce63 100644 --- a/server/models/message.ts +++ b/server/models/message.ts @@ -8,7 +8,31 @@ export type Message = { type: string; payload?: string; sig: string; - metadata?: string; + metadata?: { + relayerIpfsHash: string; + }; actionId: string; data?: string; }; +export type VoteMessage = { + [address: string]: { + id: string; + address: string; + data?: string; + msg: { + version: string; + timestamp: string; + token?: string; + type: string; + payload?: string; + }; + sig: string; + authorIpfsHash: string; + relayerIpfsHash?: string; + actionId: string; + }; +}; +export type MessageWithVotes = Message & { votes: VoteMessage[] }; +export type ProposalWithVotesMessage = { + [id: string]: MessageWithVotes; +}; diff --git a/server/repositories/messages-repository.ts b/server/repositories/messages-repository.ts index 89fc1620..4e9db953 100644 --- a/server/repositories/messages-repository.ts +++ b/server/repositories/messages-repository.ts @@ -1,5 +1,5 @@ import { postgresMessagesRepository } from '../helpers/adapters/postgres'; -import { Message } from '../models/message.js'; +import { Message, MessageWithVotes } from '../models/message.js'; export type MessagesRepository = { getMessages: (spaces: string, msgType: string) => Promise; @@ -20,11 +20,11 @@ export type MessagesRepository = { ) => Promise; getProposalByDraft: (space: string, id: string) => Promise; getProposalVotes: (space: string, id: string) => Promise; - getAllProposalsAndVotes: (space: string) => Promise; + getAllProposalsAndVotes: (space: string) => Promise; getAllProposalsAndVotesByAction: ( space: string, actionId: string - ) => Promise; + ) => Promise; getAllDraftsExceptSponsored: (space: string) => Promise; storeDraft: ( space, @@ -55,6 +55,9 @@ export type MessagesRepository = { actionId ) => Promise sponsorDraftIfAny: (space, erc712DraftHash) => Promise, - findVotesForProposals: (space, proposals) => Promise + findVotesForProposals: (space, proposals) => Promise }; + + + export const messagesRepository: MessagesRepository = postgresMessagesRepository;