|
1 | 1 | import { Prisma } from '@prisma/client'
|
2 | 2 | import { prisma } from '../config/db'
|
| 3 | +import { formatResult } from '../helpers/formatter' |
| 4 | +import { GovActionStateTypes, ProposalTypes, SortTypes } from '../types/proposal' |
3 | 5 | import { ProposalTypes, SortTypes } from '../types/proposal'
|
4 | 6 |
|
| 7 | + |
5 | 8 | export const fetchProposals = async (
|
6 | 9 | page: number,
|
7 | 10 | size: number,
|
8 | 11 | proposal?: string,
|
9 | 12 | proposalType?: ProposalTypes[],
|
10 | 13 | sort?: SortTypes,
|
| 14 | + state?: GovActionStateTypes, |
11 | 15 | includeVoteCount?: boolean
|
12 | 16 | ) => {
|
13 | 17 | const result = (await prisma.$queryRaw`
|
@@ -180,12 +184,28 @@ SELECT
|
180 | 184 | ELSE
|
181 | 185 | null
|
182 | 186 | END,
|
183 |
| - 'status', CASE |
184 |
| - when gov_action_proposal.enacted_epoch is not NULL then json_build_object('enactedEpoch', gov_action_proposal.enacted_epoch) |
185 |
| - when gov_action_proposal.ratified_epoch is not NULL then json_build_object('ratifiedEpoch', gov_action_proposal.ratified_epoch) |
186 |
| - when gov_action_proposal.expired_epoch is not NULL then json_build_object('expiredEpoch', gov_action_proposal.expired_epoch) |
187 |
| - else NULL |
188 |
| - END, |
| 187 | + 'status', json_build_object( |
| 188 | + 'ratified', |
| 189 | + json_build_object( |
| 190 | + 'epoch', gov_action_proposal.ratified_epoch, |
| 191 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.ratified_epoch) |
| 192 | + ), |
| 193 | + 'enacted', |
| 194 | + json_build_object( |
| 195 | + 'epoch', gov_action_proposal.enacted_epoch, |
| 196 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.enacted_epoch) |
| 197 | + ), |
| 198 | + 'dropped', |
| 199 | + json_build_object( |
| 200 | + 'epoch', gov_action_proposal.dropped_epoch, |
| 201 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.dropped_epoch) |
| 202 | + ), |
| 203 | + 'expired', |
| 204 | + json_build_object( |
| 205 | + 'epoch', gov_action_proposal.expired_epoch, |
| 206 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.expired_epoch) |
| 207 | + ) |
| 208 | + ), |
189 | 209 | 'expiryDate', epoch_utils.last_epoch_end_time + epoch_utils.epoch_duration * (gov_action_proposal.expiration - epoch_utils.last_epoch_no),
|
190 | 210 | 'expiryEpochNon', gov_action_proposal.expiration,
|
191 | 211 | 'createdDate', creator_block.time,
|
@@ -243,6 +263,10 @@ FROM
|
243 | 263 | CROSS JOIN always_abstain_voting_power
|
244 | 264 | JOIN tx AS creator_tx ON creator_tx.id = gov_action_proposal.tx_id
|
245 | 265 | JOIN block AS creator_block ON creator_block.id = creator_tx.block_id
|
| 266 | + LEFT JOIN epoch AS ratified_epoch ON ratified_epoch.no = gov_action_proposal.ratified_epoch |
| 267 | + LEFT JOIN epoch AS enacted_epoch ON enacted_epoch.no = gov_action_proposal.enacted_epoch |
| 268 | + LEFT JOIN epoch AS dropped_epoch ON dropped_epoch.no = gov_action_proposal.dropped_epoch |
| 269 | + LEFT JOIN epoch AS expired_epoch ON expired_epoch.no = gov_action_proposal.expired_epoch |
246 | 270 | LEFT JOIN voting_anchor ON voting_anchor.id = gov_action_proposal.voting_anchor_id
|
247 | 271 | LEFT JOIN param_proposal as proposal_params ON gov_action_proposal.param_proposal = proposal_params.id
|
248 | 272 | LEFT JOIN cost_model AS cost_model ON proposal_params.cost_model_id = cost_model.id
|
@@ -290,14 +314,33 @@ FROM
|
290 | 314 | AND gov_action_proposal.enacted_epoch IS NULL
|
291 | 315 | AND gov_action_proposal.expired_epoch IS NULL
|
292 | 316 | AND gov_action_proposal.dropped_epoch IS NULL
|
293 |
| -${ |
294 |
| - proposalType |
295 |
| - ? Prisma.sql`WHERE gov_action_proposal.type = ANY(${Prisma.raw( |
296 |
| - `ARRAY[${proposalType.map((type) => `'${type}'`).join(', ')}]::govactiontype[]` |
297 |
| - )})` |
298 |
| - : Prisma.sql`` |
299 |
| -} |
300 |
| -
|
| 317 | + ${ |
| 318 | + state === 'Live' |
| 319 | + ? Prisma.sql`WHERE gov_action_proposal.ratified_epoch is NULL |
| 320 | + AND gov_action_proposal.enacted_epoch is NULL |
| 321 | + AND gov_action_proposal.dropped_epoch is NULL |
| 322 | + AND gov_action_proposal.expired_epoch is NULL` |
| 323 | + : state === 'Expired' |
| 324 | + ? Prisma.sql`WHERE gov_action_proposal.expired_epoch is not NULL` |
| 325 | + : state === 'Enacted' |
| 326 | + ? Prisma.sql`WHERE gov_action_proposal.enacted_epoch is not NULL` |
| 327 | + : state === 'Ratified' |
| 328 | + ? Prisma.sql`WHERE gov_action_proposal.ratified_epoch is not NULL` |
| 329 | + : state === 'Dropped' |
| 330 | + ? Prisma.sql`WHERE gov_action_proposal.dropped_epoch is not NULL` |
| 331 | + : Prisma.sql`` |
| 332 | + } |
| 333 | + ${ |
| 334 | + proposalType |
| 335 | + ? state |
| 336 | + ? Prisma.sql`AND gov_action_proposal.type = ANY(${Prisma.raw( |
| 337 | + `ARRAY[${proposalType.map((type) => `'${type}'`).join(', ')}]::govactiontype[]` |
| 338 | + )})` |
| 339 | + : Prisma.sql`WHERE gov_action_proposal.type = ANY(${Prisma.raw( |
| 340 | + `ARRAY[${proposalType.map((type) => `'${type}'`).join(', ')}]::govactiontype[]` |
| 341 | + )})` |
| 342 | + : Prisma.sql`` |
| 343 | + } |
301 | 344 | GROUP BY
|
302 | 345 | (gov_action_proposal.id,
|
303 | 346 | stake_address.view,
|
|
329 | 372 | always_no_confidence_voting_power.amount,
|
330 | 373 | always_abstain_voting_power.amount,
|
331 | 374 | prev_gov_action.index,
|
332 |
| - prev_gov_action_tx.hash) |
| 375 | + prev_gov_action_tx.hash, |
| 376 | + ratified_epoch.no, |
| 377 | + ratified_epoch.end_time, |
| 378 | + enacted_epoch.no, |
| 379 | + enacted_epoch.end_time, |
| 380 | + dropped_epoch.no, |
| 381 | + dropped_epoch.end_time, |
| 382 | + expired_epoch.no, |
| 383 | + expired_epoch.end_time |
| 384 | + ) |
333 | 385 | ${proposal ? Prisma.sql`HAVING creator_tx.hash = decode(${proposal},'hex')` : Prisma.sql``}
|
334 | 386 | ${
|
335 |
| - sort === 'ExpiryDate' |
336 |
| - ? Prisma.sql`ORDER BY epoch_utils.last_epoch_end_time + epoch_utils.epoch_duration * (gov_action_proposal.expiration - epoch_utils.last_epoch_no) DESC` |
| 387 | + sort === 'Soon to Expire' |
| 388 | + ? proposal |
| 389 | + ? Prisma.sql`` |
| 390 | + : Prisma.sql`HAVING epoch_utils.last_epoch_end_time + epoch_utils.epoch_duration * (gov_action_proposal.expiration - epoch_utils.last_epoch_no) >= CURRENT_DATE |
| 391 | + ORDER BY epoch_utils.last_epoch_end_time + epoch_utils.epoch_duration * (gov_action_proposal.expiration - epoch_utils.last_epoch_no) ASC` |
337 | 392 | : Prisma.sql`ORDER BY creator_block.time DESC`
|
338 | 393 | }
|
339 | 394 | OFFSET ${(page ? page - 1 : 0) * (size ? size : 10)}
|
|
380 | 435 | parsedResults.push(parsedResult)
|
381 | 436 | }
|
382 | 437 |
|
| 438 | + if (includeVoteCount && sort == 'Highest Yes Count') { |
| 439 | + parsedResults.sort((a, b) => { |
| 440 | + const aDrepYes = a.vote.drep.yes.count ?? 0 |
| 441 | + const aSpoYes = a.vote.spo.yes.count ?? 0 |
| 442 | + const bDrepYes = b.vote.drep.yes.count ?? 0 |
| 443 | + const bSpoYes = b.vote.spo.yes.count ?? 0 |
| 444 | + const aCCYes = a.vote.cc.yes |
| 445 | + const bCCYes = b.vote.cc.yes |
| 446 | + return bDrepYes + bSpoYes + bCCYes - (aDrepYes + aSpoYes + aCCYes) |
| 447 | + }) |
| 448 | + } |
383 | 449 | return { items: parsedResults, totalCount }
|
384 | 450 | }
|
385 | 451 |
|
@@ -1181,12 +1247,28 @@ export const fetchProposalById = async (proposalId: string, proposaIndex: number
|
1181 | 1247 | ELSE
|
1182 | 1248 | null
|
1183 | 1249 | END,
|
1184 |
| - 'status', CASE |
1185 |
| - when gov_action_proposal.enacted_epoch is not NULL then json_build_object('enactedEpoch', gov_action_proposal.enacted_epoch) |
1186 |
| - when gov_action_proposal.ratified_epoch is not NULL then json_build_object('ratifiedEpoch', gov_action_proposal.ratified_epoch) |
1187 |
| - when gov_action_proposal.expired_epoch is not NULL then json_build_object('expiredEpoch', gov_action_proposal.expired_epoch) |
1188 |
| - else NULL |
1189 |
| - END, |
| 1250 | + 'status', json_build_object( |
| 1251 | + 'ratified', |
| 1252 | + json_build_object( |
| 1253 | + 'epoch', gov_action_proposal.ratified_epoch, |
| 1254 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.ratified_epoch) |
| 1255 | + ), |
| 1256 | + 'enacted', |
| 1257 | + json_build_object( |
| 1258 | + 'epoch', gov_action_proposal.enacted_epoch, |
| 1259 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.enacted_epoch) |
| 1260 | + ), |
| 1261 | + 'dropped', |
| 1262 | + json_build_object( |
| 1263 | + 'epoch', gov_action_proposal.dropped_epoch, |
| 1264 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.dropped_epoch) |
| 1265 | + ), |
| 1266 | + 'expired', |
| 1267 | + json_build_object( |
| 1268 | + 'epoch', gov_action_proposal.expired_epoch, |
| 1269 | + 'time', (SELECT end_time FROM epoch WHERE epoch.no = gov_action_proposal.expired_epoch) |
| 1270 | + ) |
| 1271 | + ), |
1190 | 1272 | 'expiryDate', epoch_utils.last_epoch_end_time + epoch_utils.epoch_duration * (gov_action_proposal.expiration - epoch_utils.last_epoch_no),
|
1191 | 1273 | 'expiryEpochNon', gov_action_proposal.expiration,
|
1192 | 1274 | 'createdDate', creator_block.time,
|
@@ -1331,6 +1413,9 @@ export const fetchProposalById = async (proposalId: string, proposaIndex: number
|
1331 | 1413 | const proposalVoteCount = includeVoteCount
|
1332 | 1414 | ? { vote: await fetchProposalVoteCount(proposalId, proposaIndex) }
|
1333 | 1415 | : undefined
|
| 1416 | + if (result.length == 0) { |
| 1417 | + return null |
| 1418 | + } |
1334 | 1419 | const resultData = result[0].result
|
1335 | 1420 | const parsedResult = {
|
1336 | 1421 | proposal: {
|
|
0 commit comments