File tree Expand file tree Collapse file tree 5 files changed +108
-12
lines changed
Expand file tree Collapse file tree 5 files changed +108
-12
lines changed Original file line number Diff line number Diff line change 44 "type" : " module" ,
55 "scripts" : {
66 "build" : " tsc" ,
7- "start" : " bun run src/index.ts"
7+ "start" : " bun run src/index.ts" ,
8+ "dev" : " bun run --watch src/index.ts"
89 },
910 "dependencies" : {
1011 "discord.js" : " ^14.14.1" ,
Original file line number Diff line number Diff line change 1+ import {
2+ SlashCommandBuilder ,
3+ ChatInputCommandInteraction ,
4+ MessageFlags ,
5+ PermissionFlagsBits ,
6+ } from "discord.js" ;
7+ import { ChainInfoService } from "../services/chaininfo-service.js" ;
8+ import { paginate } from "../utils/pagination.js" ;
9+
10+ export default {
11+ data : new SlashCommandBuilder ( )
12+ . setName ( "admin-info" )
13+ . setDescription ( "Get admin info about the chain " )
14+ . setDefaultMemberPermissions ( PermissionFlagsBits . Administrator )
15+ . addSubcommand ( ( subcommand ) =>
16+ subcommand
17+ . setName ( "validators" )
18+ . setDescription ( "Get the current list of validators" )
19+ )
20+ . addSubcommand ( ( subcommand ) =>
21+ subcommand
22+ . setName ( "committee" )
23+ . setDescription ( "Get the current committee" )
24+ ) ,
25+
26+ execute : async ( interaction : ChatInputCommandInteraction ) => {
27+ await interaction . deferReply ( {
28+ flags : MessageFlags . Ephemeral ,
29+ } ) ;
30+
31+ try {
32+ const addressesPerPage = 40 ;
33+
34+ const { validators, committee } = await ChainInfoService . getInfo ( ) ;
35+ if ( interaction . options . getSubcommand ( ) === "committee" ) {
36+ await paginate (
37+ committee as string [ ] ,
38+ addressesPerPage ,
39+ interaction ,
40+ "Committee"
41+ ) ;
42+ } else if ( interaction . options . getSubcommand ( ) === "validators" ) {
43+ await paginate (
44+ validators as string [ ] ,
45+ addressesPerPage ,
46+ interaction ,
47+ "Validators"
48+ ) ;
49+
50+ return ;
51+ }
52+ } catch ( error ) {
53+ console . error ( "Error in get-info command:" , error ) ;
54+ await interaction . editReply ( {
55+ content : `Failed to get chain info` ,
56+ } ) ;
57+ }
58+ } ,
59+ } ;
Original file line number Diff line number Diff line change 11import addValidator from "./addValidator.js" ;
22import getChainInfo from "./getChainInfo.js" ;
3+ import getAdminInfo from "./getAdminInfo.js" ;
34
4- export default {
5- addValidator,
6- getChainInfo,
7- } ;
5+ export default { addValidator, getChainInfo, getAdminInfo } ;
Original file line number Diff line number Diff line change @@ -6,12 +6,12 @@ import {
66 ETHEREUM_CHAIN_ID ,
77} from "../env.js" ;
88
9- type ChainInfo = {
9+ type ChainInfo < > = {
1010 pendingBlockNum : string ;
1111 provenBlockNum : string ;
12- validators : string [ ] ;
13- committee : string [ ] ;
14- archive : string [ ] ;
12+ validators : string | string [ ] ;
13+ committee : string | string [ ] ;
14+ archive : string | string [ ] ;
1515 currentEpoch : string ;
1616 currentSlot : string ;
1717 proposerNow : string ;
@@ -37,13 +37,18 @@ export class ChainInfoService {
3737 . map ( ( line ) => line . trim ( ) )
3838 . filter ( Boolean )
3939 . reduce ( ( acc , s ) => {
40- const [ key , value ] = s . split ( ": " ) ;
40+ let [ key , value ] = s . split ( ": " ) ;
4141 const sanitizedKey = key
4242 . toLowerCase ( )
4343 . replace ( / \s + ( .) / g, ( _ , c ) => c . toUpperCase ( ) ) ;
4444 return { ...acc , [ sanitizedKey ] : value } ;
45- } , { } ) ;
46-
45+ } , { } ) as ChainInfo ;
46+ if ( typeof info . validators === "string" ) {
47+ info . validators = info . validators . split ( ", " ) . map ( String ) ;
48+ }
49+ if ( typeof info . committee === "string" ) {
50+ info . committee = info . committee . split ( ", " ) . map ( String ) ;
51+ }
4752 return info as ChainInfo ;
4853 } catch ( error ) {
4954 console . error ( "Error getting chain info:" , error ) ;
Original file line number Diff line number Diff line change 1+ import { MessageFlags } from "discord.js" ;
2+
3+ import { ChatInputCommandInteraction } from "discord.js" ;
4+
5+ export const paginate = async (
6+ array : string [ ] ,
7+ perMessage : number ,
8+ interaction : ChatInputCommandInteraction ,
9+ message : string
10+ ) => {
11+ const numMessages = Math . ceil ( array . length / perMessage ) ;
12+
13+ for ( let i = 0 ; i < numMessages ; i ++ ) {
14+ const start = i * perMessage ;
15+ const end = Math . min ( start + perMessage , array . length ) ;
16+ const validatorSlice = array . slice ( start , end ) as string [ ] ;
17+
18+ if ( i === 0 ) {
19+ await interaction . editReply ( {
20+ content : `${ message } (${ start + 1 } -${ end } of ${
21+ array . length
22+ } ):\n${ validatorSlice . join ( "\n" ) } `,
23+ } ) ;
24+ } else {
25+ await interaction . followUp ( {
26+ content : `${ message } (${ start + 1 } -${ end } of ${
27+ array . length
28+ } ):\n${ validatorSlice . join ( "\n" ) } `,
29+ flags : MessageFlags . Ephemeral ,
30+ } ) ;
31+ }
32+ }
33+ } ;
You can’t perform that action at this time.
0 commit comments