Skip to content

Commit

Permalink
feat(cip-1694): init
Browse files Browse the repository at this point in the history
  • Loading branch information
1000101 committed Dec 17, 2023
1 parent c732023 commit 3ba9b33
Show file tree
Hide file tree
Showing 11 changed files with 340 additions and 8 deletions.
7 changes: 5 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,12 @@ const start = (options = {}): FastifyInstance => {
if (isCIP1694Active) {
// governance
registerRoute(app, import('./routes/governance/dreps/index.js'));
registerRoute(app, import('./routes/governance/dreps/hash/index.js'));
registerRoute(app, import('./routes/governance/dreps/hash/distribution.js'));
registerRoute(app, import('./routes/governance/dreps/drep-id/index.js'));
registerRoute(app, import('./routes/governance/dreps/drep-id/delegators.js'));
registerRoute(app, import('./routes/governance/dreps/drep-id/metadata.js'));
registerRoute(app, import('./routes/governance/dreps/drep-id/updates.js'));
}

// health
registerRoute(app, import('./routes/health/index.js'));
registerRoute(app, import('./routes/health/clock.js'));
Expand Down
35 changes: 35 additions & 0 deletions src/routes/governance/dreps/drep-id/delegators.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { FastifyInstance, FastifyRequest } from 'fastify';
import * as QueryTypes from '../../../../types/queries/governance.js';
import * as ResponseTypes from '../../../../types/responses/governance.js';
import { getDbSync } from '../../../../utils/database.js';
import { SQLQuery } from '../../../../sql/index.js';
//import { getSchemaForEndpoint } from '@blockfrost/openapi';

async function route(fastify: FastifyInstance) {
fastify.route({
url: '/governance/dreps/:drep_id/delegators',
method: 'GET',
// TODO: SCHEMA
// schema: getSchemaForEndpoint('/governance/dreps/{drep_id}/delegators'),

handler: async (request: FastifyRequest<QueryTypes.RequestParametersDRepID>, reply) => {
const clientDbSync = await getDbSync(fastify);

const { rows }: { rows: ResponseTypes.DRepsDrepIDDelegators } =
await clientDbSync.query<QueryTypes.DRepsDrepIDDelegators>(
SQLQuery.get('governance_dreps_drep_id_delegators'),
[request.query.order, request.query.count, request.query.page, request.params.drep_id],
);

clientDbSync.release();

if (rows.length === 0) {
return reply.send([]);
}

return reply.send(rows);
},
});
}

export default route;
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import * as ResponseTypes from '../../../../types/responses/governance.js';
import { getDbSync } from '../../../../utils/database.js';
import { handle404 } from '../../../../utils/error-handler.js';
import { SQLQuery } from '../../../../sql/index.js';
//import { getSchemaForEndpoint } from '@blockfrost/openapi';

async function route(fastify: FastifyInstance) {
fastify.route({
url: '/governance/dreps/:hash',
url: '/governance/dreps/:drep_id',
method: 'GET',
// TODO: add schema when available
// schema: getSchemaForEndpoint('/governance/dreps/{hash}'),
handler: async (request: FastifyRequest<QueryTypes.RequestParametersDRepID>, reply) => {
// TODO: SCHEMA
//schema: getSchemaForEndpoint('/governance/dreps/{drep_id}'),
handler: async (request: FastifyRequest<QueryTypes.RequestDRepID>, reply) => {
const clientDbSync = await getDbSync(fastify);

const { rows }: { rows: ResponseTypes.DRepsDrepID } =
Expand All @@ -20,7 +21,6 @@ async function route(fastify: FastifyInstance) {
]);

clientDbSync.release();

const row = rows[0];

if (!row) {
Expand Down
36 changes: 36 additions & 0 deletions src/routes/governance/dreps/drep-id/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { FastifyInstance, FastifyRequest } from 'fastify';
import * as QueryTypes from '../../../../types/queries/governance.js';
import * as ResponseTypes from '../../../../types/responses/governance.js';
import { getDbSync } from '../../../../utils/database.js';
import { handle404 } from '../../../../utils/error-handler.js';
import { SQLQuery } from '../../../../sql/index.js';
//import { getSchemaForEndpoint } from '@blockfrost/openapi';

async function route(fastify: FastifyInstance) {
fastify.route({
url: '/governance/dreps/:drep_id/metadata',
method: 'GET',
// TODO: SCHEMA
// schema: getSchemaForEndpoint('/governance/dreps/{drep_id}/metadata'),
handler: async (request: FastifyRequest<QueryTypes.RequestDRepID>, reply) => {
const clientDbSync = await getDbSync(fastify);

const { rows }: { rows: ResponseTypes.DRepsDrepIDMetadata } =
await clientDbSync.query<QueryTypes.DRepsDrepIDMetadata>(
SQLQuery.get('governance_dreps_drep_id_metadata'),
[request.params.drep_id],
);

clientDbSync.release();

const row = rows[0];

if (!row) {
return handle404(reply);
}
return reply.send(row);
},
});
}

export default route;
35 changes: 35 additions & 0 deletions src/routes/governance/dreps/drep-id/updates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { FastifyInstance, FastifyRequest } from 'fastify';
import * as QueryTypes from '../../../../types/queries/governance.js';
import * as ResponseTypes from '../../../../types/responses/governance.js';
import { getDbSync } from '../../../../utils/database.js';
import { SQLQuery } from '../../../../sql/index.js';
//import { getSchemaForEndpoint } from '@blockfrost/openapi';

async function route(fastify: FastifyInstance) {
fastify.route({
url: '/governance/dreps/:drep_id/updates',
method: 'GET',
// TODO: SCHEMA
// schema: getSchemaForEndpoint('/governance/dreps/{drep_id}/updates'),

handler: async (request: FastifyRequest<QueryTypes.RequestParametersDRepID>, reply) => {
const clientDbSync = await getDbSync(fastify);

const { rows }: { rows: ResponseTypes.DRepsDrepIDUpdates } =
await clientDbSync.query<QueryTypes.DRepsDrepIDUpdates>(
SQLQuery.get('governance_dreps_drep_id_updates'),
[request.query.order, request.query.count, request.query.page, request.params.drep_id],
);

clientDbSync.release();

if (rows.length === 0) {
return reply.send([]);
}

return reply.send(rows);
},
});
}

export default route;
26 changes: 25 additions & 1 deletion src/sql/governance/dreps.sql
Original file line number Diff line number Diff line change
@@ -1 +1,25 @@
governance_dreps
SELECT dh.view AS "drep_id",
encode(dh.raw, 'hex') AS "hex"
FROM drep_hash dh
ORDER BY CASE
WHEN LOWER($1) = 'desc' THEN dh.id
END DESC,
CASE
WHEN LOWER($1) <> 'desc'
OR $1 IS NULL THEN dh.id
END ASC
LIMIT CASE
WHEN $2 >= 1
AND $2 <= 100 THEN $2
ELSE 100
END OFFSET CASE
WHEN $3 > 1
AND $3 < 2147483647 THEN ($3 - 1) * (
CASE
WHEN $2 >= 1
AND $2 <= 100 THEN $2
ELSE 100
END
)
ELSE 0
END
42 changes: 42 additions & 0 deletions src/sql/governance/dreps_drep_id.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
WITH queried_epoch AS (
SELECT no AS "epoch_no"
FROM epoch e
ORDER BY e.no DESC
LIMIT 1
)
SELECT dh.view AS "drep_id",
encode(dh.raw, 'hex') AS "hex",
COALESCE(dd.amount, 0)::TEXT AS "amount",
(
CASE
WHEN dr.deposit >= 0 THEN true
ELSE false
END
) AS "is_registered",
(
CASE
WHEN dr.deposit >= 0 THEN (
SELECT b.epoch_no
FROM block b
WHERE b.id = (
SELECT tx.block_id
FROM tx
WHERE tx.id = (dr.tx_id)
)
)
ELSE NULL
END
) AS "active_epoch",
dh.has_script AS "has_script"
FROM drep_hash dh
JOIN drep_registration dr ON (dh.id = dr.drep_hash_id)
LEFT JOIN drep_distr dd ON (
dh.id = dd.hash_id
AND dd.epoch_no = (
SELECT *
FROM queried_epoch
)
)
WHERE dh.view = $1
ORDER BY (tx_id, cert_index) DESC
LIMIT 1
79 changes: 79 additions & 0 deletions src/sql/governance/dreps_drep_id_delegators.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
WITH current_epoch AS (
SELECT b.epoch_no
FROM block b
ORDER BY b.id DESC
LIMIT 1
)
SELECT "address" AS "address",
(
(
SELECT COALESCE(SUM(txo.value), 0)
FROM tx_out txo
LEFT JOIN tx_in txi ON (txo.tx_id = txi.tx_out_id)
AND (txo.index = txi.tx_out_index)
WHERE txi IS NULL
AND txo.stake_address_id = address_id
) + (
SELECT COALESCE(SUM(amount), 0)
FROM reward r
WHERE (r.addr_id = address_id)
AND r.spendable_epoch <= (
SELECT *
FROM current_epoch
)
) - (
SELECT COALESCE(SUM(amount), 0)
FROM withdrawal w
WHERE (w.addr_id = address_id)
)
)::TEXT AS "amount" -- cast to TEXT to avoid number overflow
FROM (
SELECT sa.view AS "address",
dv.addr_id AS "address_id",
dv.id AS "did"
FROM delegation_vote dv
JOIN drep_hash dh ON (dh.id = dv.drep_hash_id)
JOIN stake_address sa ON (sa.id = dv.addr_id)
WHERE dh.view = $4
AND dv.id = (
SELECT MAX(id)
FROM delegation_vote
WHERE addr_id = dv.addr_id
)
GROUP BY sa.view,
dv.drep_hash_id,
dv.addr_id,
dv.id
ORDER BY CASE
WHEN LOWER($1) = 'desc' THEN dv.id
END DESC,
CASE
WHEN LOWER($1) <> 'desc'
OR $1 IS NULL THEN dv.id
END ASC
LIMIT CASE
WHEN $2 >= 1
AND $2 <= 100 THEN $2
ELSE 100
END OFFSET CASE
WHEN $3 > 1
AND $3 < 2147483647 THEN ($3 - 1) * (
CASE
WHEN $2 >= 1
AND $2 <= 100 THEN $2
ELSE 100
END
)
ELSE 0
END
) "sorted_limited"
GROUP BY address,
address_id,
did
ORDER BY CASE
WHEN LOWER($1) = 'desc' THEN did
END DESC,
CASE
WHEN LOWER($1) <> 'desc'
OR $1 IS NULL THEN did
END ASC
16 changes: 16 additions & 0 deletions src/sql/governance/dreps_drep_id_metadata.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
SELECT dh.view AS "drep_id",
encode(dh.raw, 'hex') AS "hex",
CASE
WHEN dr.deposit >= 0 THEN va.url
ELSE NULL
END AS "url",
CASE
WHEN dr.deposit >= 0 THEN encode(va.data_hash, 'hex')
ELSE NULL
END AS "hash"
FROM drep_hash dh
JOIN drep_registration dr ON (dh.id = dr.drep_hash_id)
LEFT JOIN voting_anchor va ON (dr.voting_anchor_id = va.id)
WHERE dh.view = $1
ORDER BY (dr.tx_id, dr.cert_index) DESC
LIMIT 1
34 changes: 34 additions & 0 deletions src/sql/governance/dreps_drep_id_updates.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
SELECT encode(tx.hash, 'hex') AS "tx_hash",
dr.cert_index AS "cert_index",
(
CASE
WHEN dr.deposit >= 0 THEN 'registered'
ELSE 'deregistered'
END
) AS "action"
FROM drep_hash dh
JOIN drep_registration dr ON (dh.id = dr.drep_hash_id)
JOIN tx ON (dr.tx_id = tx.id)
WHERE dh.view = $4
ORDER BY CASE
WHEN LOWER($1) = 'desc' THEN dr.id
END DESC,
CASE
WHEN LOWER($1) <> 'desc'
OR $1 IS NULL THEN dr.id
END ASC
LIMIT CASE
WHEN $2 >= 1
AND $2 <= 100 THEN $2
ELSE 100
END OFFSET CASE
WHEN $3 > 1
AND $3 < 2147483647 THEN ($3 - 1) * (
CASE
WHEN $2 >= 1
AND $2 <= 100 THEN $2
ELSE 100
END
)
ELSE 0
END
28 changes: 28 additions & 0 deletions src/types/queries/governance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export interface RequestParametersDRepID {
};
}

export interface RequestDRepID {
Params: {
drep_id: string;
};
}

export interface DReps {
drep_id: string;
hex: string;
Expand All @@ -31,3 +37,25 @@ export interface DRepsDrepID {
active_epoch: number | null;
has_script: boolean;
}

export interface DRepsDrepIDDelegators {
address: string;
amount: string;
}

export interface DRepsDrepIDMetadata {
drep_id: string;
hex: string;
url: string | null;
hash: string | null;
}
export interface DRepsDrepIDUpdates {
tx_hash: string;
/** @description Certificate within the transaction */
cert_index: number;
/**
* @description Action in the certificate
* @enum {string}
*/
action: 'registered' | 'deregistered';
}

0 comments on commit 3ba9b33

Please sign in to comment.