Skip to content

Commit b5f778f

Browse files
committed
feat(#3672): add /account service for the usage of Proposal Discussion Forum pillar
1 parent 0903942 commit b5f778f

File tree

12 files changed

+133
-4
lines changed

12 files changed

+133
-4
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
SELECT
2+
sa.id,
3+
sa.view,
4+
CASE
5+
WHEN sa.script_hash IS NOT NULL THEN true
6+
ELSE false
7+
END AS is_script_based,
8+
CASE
9+
WHEN (
10+
SELECT COALESCE(MAX(epoch_no), 0)
11+
FROM stake_registration sr
12+
WHERE sr.addr_id = sa.id
13+
) > (
14+
SELECT COALESCE(MAX(epoch_no), 0)
15+
FROM stake_deregistration sd
16+
WHERE sd.addr_id = sa.id
17+
) THEN true
18+
ELSE false
19+
END AS is_registered
20+
FROM
21+
stake_address sa
22+
WHERE
23+
sa.hash_raw = decode(?, 'hex');

govtool/backend/src/VVA/API.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import VVA.Config
4040
import qualified VVA.DRep as DRep
4141
import qualified VVA.Epoch as Epoch
4242
import VVA.Network as Network
43+
import VVA.Account as Account
4344
import qualified VVA.Proposal as Proposal
4445
import qualified VVA.Transaction as Transaction
4546
import qualified VVA.Types as Types
@@ -85,6 +86,7 @@ type VVAApi =
8586
:<|> "network" :> "metrics" :> Get '[JSON] GetNetworkMetricsResponse
8687
:<|> "network" :> "info" :> Get '[JSON] GetNetworkInfoResponse
8788
:<|> "network" :> "total-stake" :> Get '[JSON] GetNetworkTotalStakeResponse
89+
:<|> "account" :> Capture "stakeKey" HexText :> Get '[JSON] GetAccountInfoResponse
8890

8991
server :: App m => ServerT VVAApi m
9092
server = drepList
@@ -103,6 +105,7 @@ server = drepList
103105
:<|> getNetworkMetrics
104106
:<|> getNetworkInfo
105107
:<|> getNetworkTotalStake
108+
:<|> getAccountInfo
106109

107110
mapDRepType :: Types.DRepType -> DRepType
108111
mapDRepType Types.DRep = NormalDRep
@@ -527,3 +530,14 @@ getNetworkMetrics = do
527530
, getNetworkMetricsResponseQuorumNumerator = networkMetricsQuorumNumerator
528531
, getNetworkMetricsResponseQuorumDenominator = networkMetricsQuorumDenominator
529532
}
533+
534+
getAccountInfo :: App m => HexText -> m GetAccountInfoResponse
535+
getAccountInfo (unHexText -> stakeKey) = do
536+
-- CacheEnv {accountInfoCache} <- asks vvaCache
537+
Types.AccountInfo {..} <- Account.accountInfo stakeKey
538+
return $ GetAccountInfoResponse
539+
{ getAccountInfoResponseId = accountInfoId
540+
, getAccountInfoResponseView = accountInfoView
541+
, getAccountInfoResponseIsRegistered = accountInfoIsRegistered
542+
, getAccountInfoResponseIsScriptBased = accountInfoIsScriptBased
543+
}

govtool/backend/src/VVA/API/Types.hs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,3 +1032,26 @@ instance ToSchema GetNetworkMetricsResponse where
10321032
& description ?~ "GetNetworkMetricsResponse"
10331033
& example
10341034
?~ toJSON exampleGetNetworkMetricsResponse
1035+
1036+
data GetAccountInfoResponse
1037+
= GetAccountInfoResponse
1038+
{ getAccountInfoResponseId :: Integer
1039+
, getAccountInfoResponseView :: Text
1040+
, getAccountInfoResponseIsRegistered :: Bool
1041+
, getAccountInfoResponseIsScriptBased :: Bool
1042+
}
1043+
deriving (Generic, Show)
1044+
deriveJSON (jsonOptions "getAccountInfoResponse") ''GetAccountInfoResponse
1045+
exampleGetAccountInfoResponse :: Text
1046+
exampleGetAccountInfoResponse =
1047+
"{\"stakeKey\": \"stake1u9\","
1048+
<> " \"id\": \"1\","
1049+
<> "\"view\": \"stake_test1uzapf83wydusjln97rqr7fen6vgrz5087yqdxm0akqdqkgstjz8g4\","
1050+
<> "\"isRegistered\": false,"
1051+
<> "\"isScriptBased\": false}"
1052+
instance ToSchema GetAccountInfoResponse where
1053+
declareNamedSchema _ = pure $ NamedSchema (Just "GetAccountInfoResponse") $ mempty
1054+
& type_ ?~ OpenApiObject
1055+
& description ?~ "GetAccountInfoResponse"
1056+
& example
1057+
?~ toJSON exampleGetAccountInfoResponse

govtool/backend/src/VVA/Account.hs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{-# LANGUAGE FlexibleContexts #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE TemplateHaskell #-}
4+
5+
module VVA.Account where
6+
7+
import Control.Monad.Except (MonadError, throwError)
8+
import Control.Monad.Reader (MonadIO, MonadReader, liftIO)
9+
import Data.ByteString (ByteString)
10+
import Data.FileEmbed (embedFile)
11+
import Data.String (fromString)
12+
import qualified Database.PostgreSQL.Simple as SQL
13+
import VVA.Types (AppError(..), AccountInfo(..))
14+
import Data.Text (Text, unpack)
15+
import qualified Data.Text.Encoding as Text
16+
import qualified Data.Text.IO as Text
17+
import Data.Has (Has)
18+
import VVA.Pool (ConnectionPool, withPool)
19+
20+
sqlFrom :: ByteString -> SQL.Query
21+
sqlFrom = fromString . unpack . Text.decodeUtf8
22+
23+
accountInfoSql :: SQL.Query
24+
accountInfoSql = sqlFrom $(embedFile "sql/get-account-info.sql")
25+
26+
accountInfo ::
27+
(Has ConnectionPool r, MonadReader r m, MonadIO m, MonadError AppError m) =>
28+
Text ->
29+
m AccountInfo
30+
accountInfo stakeKey = withPool $ \conn -> do
31+
result <- liftIO $ SQL.query conn accountInfoSql (SQL.Only stakeKey)
32+
case result of
33+
[(id, view, is_registered, is_script_based)] ->
34+
return $ AccountInfo id view is_registered is_script_based
35+
_ -> throwError $ CriticalError "Could not query the account info."

govtool/backend/src/VVA/Types.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,3 +302,11 @@ data Delegation
302302
, delegationIsDRepScriptBased :: Bool
303303
, delegationTxHash :: Text
304304
}
305+
306+
data AccountInfo
307+
= AccountInfo
308+
{ accountInfoId :: Integer
309+
, accountInfoView :: Text
310+
, accountInfoIsRegistered :: Bool
311+
, accountInfoIsScriptBased :: Bool
312+
}

govtool/backend/vva-be.cabal

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ extra-source-files:
3737
sql/get-dreps-voting-power-list.sql
3838
sql/get-filtered-dreps-voting-power.sql
3939
sql/get-previous-enacted-governance-action-proposal-details.sql
40+
sql/get-account-info.sql
4041
executable vva-be
4142
main-is: Main.hs
4243

@@ -124,4 +125,5 @@ library
124125
, VVA.Pool
125126
, VVA.Types
126127
, VVA.Network
128+
, VVA.Account
127129
ghc-options: -threaded

govtool/frontend/src/models/api.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,3 +261,10 @@ type DRepVotingPower = {
261261
};
262262

263263
export type DRepVotingPowerListResponse = DRepVotingPower[];
264+
265+
export type Account = {
266+
id: number,
267+
view: string,
268+
isRegistered: boolean,
269+
isScriptBased: boolean
270+
}

govtool/frontend/src/pages/ProposalDiscussion.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useValidateMutation } from "@/hooks/mutations";
1212
import { useScreenDimension } from "@/hooks/useScreenDimension";
1313
import { Footer, TopNav } from "@/components/organisms";
1414
import { useGetDRepVotingPowerList, useGetVoterInfo } from "@/hooks";
15-
import { getAdaHolderVotingPower } from "@/services";
15+
import { getAdaHolderVotingPower, getAccount } from "@/services";
1616

1717
const ProposalDiscussion = React.lazy(
1818
() => import("@intersect.mbo/pdf-ui/cjs"),
@@ -81,6 +81,7 @@ export const ProposalDiscussionPillar = () => {
8181
setUsername={setUsername}
8282
epochParams={epochParams}
8383
getAdaHolderVotingPower={getAdaHolderVotingPower}
84+
getAccount={getAccount}
8485
{...snackbarContext}
8586
/>
8687
</Suspense>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Account } from "@/models";
2+
import { API } from "../API";
3+
4+
export const getAccount = async ({ stakeKey }: { stakeKey?: string }) => {
5+
const response = await API.get<Account>(`/account/${stakeKey || ""}`);
6+
7+
return response.data;
8+
};

govtool/frontend/src/services/requests/getAdaHolderVotingPower.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ export const getAdaHolderVotingPower = async ({
44
stakeKey,
55
}: {
66
stakeKey?: string;
7-
}): Promise<number> => {
8-
const response = await API.get(`/ada-holder/get-voting-power/${stakeKey}`);
7+
}) => {
8+
const response = await API.get<number>(
9+
`/ada-holder/get-voting-power/${stakeKey}`,
10+
);
911

1012
return response.data;
1113
};

0 commit comments

Comments
 (0)