@@ -16,6 +16,34 @@ import { StateHistorySocket } from "../indexer/connections/state-history.js";
1616import { mongodb } from "@fastify/mongodb" ;
1717import { MongoClient } from "mongodb" ;
1818
19+ interface IndexConfig {
20+ [ key : string ] : number ;
21+ }
22+
23+ interface TableConfig {
24+ auto_index : boolean ;
25+ indices : IndexConfig ;
26+ }
27+
28+ interface ContractsState {
29+ account : string ;
30+ tables : {
31+ [ tableName : string ] : TableConfig ;
32+ } ;
33+ }
34+
35+ interface ChainConfig {
36+ features : {
37+ contracts_state : ContractsState [ ] ;
38+ } ;
39+ }
40+
41+ interface TableInput {
42+ name : string ;
43+ autoIndex : boolean ;
44+ indices : IndexConfig ;
45+ }
46+
1947const program = new Command ( ) ;
2048const rootDir = path . join ( import . meta. dirname , '../../' ) ;
2149const referencesDir = path . join ( rootDir , 'references' ) ;
@@ -794,6 +822,97 @@ async function resetConnections() {
794822 }
795823}
796824
825+ function customStringify ( obj : any , indent = 0 ) : string {
826+ const indentStr = ' ' . repeat ( indent ) ;
827+ let result = '' ;
828+
829+ for ( const [ key , value ] of Object . entries ( obj ) ) {
830+ if ( typeof value === 'object' && value !== null ) {
831+ result += `${ indentStr } ${ key } :\n${ customStringify ( value , indent + 2 ) } ` ;
832+ } else {
833+ result += `${ indentStr } ${ key } : ${ value } \n` ;
834+ }
835+ }
836+
837+ return result ;
838+ }
839+
840+ async function listConfigContract ( shortName : string ) {
841+ console . log ( `Listing Contracts config for ${ shortName } ...` ) ;
842+ const targetPath = path . join ( chainsDir , `${ shortName } .config.json` ) ;
843+
844+ if ( ! existsSync ( targetPath ) ) {
845+ console . error ( `Chain config for ${ shortName } not found!` ) ;
846+ process . exit ( 0 ) ;
847+ }
848+
849+ const chainJsonFile = await readFile ( targetPath ) ;
850+ const chainConfig : ChainConfig = JSON . parse ( chainJsonFile . toString ( ) ) ;
851+ const contracts_state = chainConfig . features . contracts_state ;
852+
853+ if ( ! contracts_state || contracts_state . length === 0 ) {
854+ console . log ( 'No contracts state configuration found.' ) ;
855+ return ;
856+ }
857+
858+ console . log ( 'Contracts State Configuration:' ) ;
859+ console . log ( '------------------------------' ) ;
860+
861+ contracts_state . forEach ( ( contractState , index ) => {
862+ console . log ( `Contract State ${ index + 1 } :` ) ;
863+ console . log ( `Account: ${ contractState . account } ` ) ;
864+ console . log ( 'Tables:' ) ;
865+
866+ for ( const [ tableName , tableConfig ] of Object . entries ( contractState . tables ) ) {
867+ console . log ( ` ${ tableName } :` ) ;
868+ console . log ( ` auto_index: ${ tableConfig . auto_index } ` ) ;
869+ console . log ( ' indices:' ) ;
870+ console . log ( customStringify ( tableConfig . indices , 6 ) ) ;
871+ }
872+
873+ if ( index < contracts_state . length - 1 ) {
874+ console . log ( '------------------------------' ) ;
875+ }
876+ } ) ;
877+ }
878+
879+ async function addOrUpdateContractConfig ( shortName : string , account : string , tables : TableInput [ ] ) {
880+ console . log ( `Adding/updating contract config for ${ shortName } ...` ) ;
881+ const targetPath = path . join ( chainsDir , `${ shortName } .config.json` ) ;
882+
883+ if ( ! existsSync ( targetPath ) ) {
884+ console . error ( `Chain config for ${ shortName } not found!` ) ;
885+ process . exit ( 0 ) ;
886+ }
887+
888+ const chainJsonFile = await readFile ( targetPath ) ;
889+ const chainConfig : ChainConfig = JSON . parse ( chainJsonFile . toString ( ) ) ;
890+
891+ if ( ! chainConfig . features . contracts_state ) {
892+ chainConfig . features . contracts_state = [ ] ;
893+ }
894+
895+ let accountConfig = chainConfig . features . contracts_state . find ( cs => cs . account === account ) ;
896+
897+ if ( ! accountConfig ) {
898+ accountConfig = {
899+ account : account ,
900+ tables : { }
901+ } ;
902+ chainConfig . features . contracts_state . push ( accountConfig ) ;
903+ }
904+
905+ tables . forEach ( table => {
906+ accountConfig . tables [ table . name ] = {
907+ auto_index : table . autoIndex ,
908+ indices : table . indices
909+ } ;
910+ } ) ;
911+
912+ await writeFile ( targetPath , JSON . stringify ( chainConfig , null , 2 ) ) ;
913+ console . log ( `Contract config added/updated successfully for account ${ account } ` ) ;
914+ }
915+
797916
798917// main program
799918( ( ) => {
@@ -873,6 +992,37 @@ async function resetConnections() {
873992 . description ( 'backup and delete chain configuration' )
874993 . action ( rmChain ) ;
875994
995+
996+ const contracts = program . command ( 'contracts' ) ;
997+
998+ //List Config
999+ contracts . command ( 'list <chainName>' )
1000+ . description ( 'list contracts config' )
1001+ . action ( listConfigContract )
1002+
1003+ // Add to config
1004+ contracts . command ( 'add-single <chainName> <account> <table> <autoIndex> <indices>' )
1005+ . description ( 'add or update a single table in contract config' )
1006+ . action ( async ( chainName , account , table , autoIndex , indices ) => {
1007+ const tableInput : TableInput = {
1008+ name : table ,
1009+ autoIndex : autoIndex === 'true' ,
1010+ indices : JSON . parse ( indices )
1011+ } ;
1012+ await addOrUpdateContractConfig ( chainName , account , [ tableInput ] ) ;
1013+ } ) ;
1014+
1015+ contracts . command ( 'add-multiple <chainName> <account> <tablesJson>' )
1016+ . description ( 'add or update multiple tables in contract config' )
1017+ . action ( async ( chainName , account , tablesJson ) => {
1018+ try {
1019+ const tables : TableInput [ ] = JSON . parse ( tablesJson ) ;
1020+ await addOrUpdateContractConfig ( chainName , account , tables ) ;
1021+ } catch ( error ) {
1022+ console . error ( 'Error parsing tables JSON:' , error ) ;
1023+ }
1024+ } ) ;
1025+
8761026
8771027 program . parse ( process . argv ) ;
8781028
0 commit comments