4
4
5
5
import { IMCPToolResult } from '../../types/mcp' ;
6
6
import { BaseToolHandler } from '../registry/RemixToolRegistry' ;
7
- import {
8
- ToolCategory ,
7
+ import {
8
+ ToolCategory ,
9
9
RemixToolDefinition ,
10
10
DeployContractArgs ,
11
11
CallContractArgs ,
12
12
SendTransactionArgs ,
13
13
DeploymentResult ,
14
+ AccountInfo ,
14
15
ContractInteractionResult
15
16
} from '../types/mcpTools' ;
16
17
import { Plugin } from '@remixproject/engine' ;
@@ -549,6 +550,208 @@ export class GetAccountBalanceHandler extends BaseToolHandler {
549
550
}
550
551
}
551
552
553
+ /**
554
+ * Get User Accounts Tool Handler
555
+ */
556
+ export class GetUserAccountsHandler extends BaseToolHandler {
557
+ name = 'get_user_accounts' ;
558
+ description = 'Get user accounts from the current execution environment' ;
559
+ inputSchema = {
560
+ type : 'object' ,
561
+ properties : {
562
+ includeBalances : {
563
+ type : 'boolean' ,
564
+ description : 'Whether to include account balances' ,
565
+ default : true
566
+ }
567
+ }
568
+ } ;
569
+
570
+ getPermissions ( ) : string [ ] {
571
+ return [ 'accounts:read' ] ;
572
+ }
573
+
574
+ validate ( args : { includeBalances ?: boolean } ) : boolean | string {
575
+ const types = this . validateTypes ( args , { includeBalances : 'boolean' } ) ;
576
+ if ( types !== true ) return types ;
577
+ return true ;
578
+ }
579
+
580
+ async execute ( args : { includeBalances ?: boolean } , plugin : Plugin ) : Promise < IMCPToolResult > {
581
+ try {
582
+ // Get accounts from the run-tab plugin (udapp)
583
+ const runTabApi = await plugin . call ( 'udapp' as any , 'getRunTabAPI' ) ;
584
+ console . log ( 'geetting accounts returned' , runTabApi )
585
+
586
+ if ( ! runTabApi || ! runTabApi . accounts ) {
587
+ return this . createErrorResult ( 'Could not retrieve accounts from execution environment' ) ;
588
+ }
589
+
590
+ const accounts : AccountInfo [ ] = [ ] ;
591
+ const loadedAccounts = runTabApi . accounts . loadedAccounts || { } ;
592
+ const selectedAccount = runTabApi . accounts . selectedAccount ;
593
+ console . log ( 'loadedAccounts' , loadedAccounts )
594
+ console . log ( 'selected account' , selectedAccount )
595
+
596
+ for ( const [ address , displayName ] of Object . entries ( loadedAccounts ) ) {
597
+ const account : AccountInfo = {
598
+ address : address ,
599
+ displayName : displayName as string ,
600
+ isSmartAccount : ( displayName as string ) ?. includes ( '[SMART]' ) || false
601
+ } ;
602
+
603
+ // Get balance if requested
604
+ if ( args . includeBalances !== false ) {
605
+ try {
606
+ const balance = await plugin . call ( 'blockchain' as any , 'getBalanceInEther' , address ) ;
607
+ account . balance = balance || '0' ;
608
+ } catch ( error ) {
609
+ console . warn ( `Could not get balance for account ${ address } :` , error ) ;
610
+ account . balance = 'unknown' ;
611
+ }
612
+ }
613
+
614
+ accounts . push ( account ) ;
615
+ }
616
+
617
+ const result = {
618
+ success : true ,
619
+ accounts : accounts ,
620
+ selectedAccount : selectedAccount ,
621
+ totalAccounts : accounts . length ,
622
+ environment : await this . getCurrentEnvironment ( plugin )
623
+ } ;
624
+
625
+ return this . createSuccessResult ( result ) ;
626
+ } catch ( error ) {
627
+ return this . createErrorResult ( `Failed to get user accounts: ${ error . message } ` ) ;
628
+ }
629
+ }
630
+
631
+ private async getCurrentEnvironment ( plugin : Plugin ) : Promise < string > {
632
+ try {
633
+ const provider = await plugin . call ( 'blockchain' as any , 'getCurrentProvider' ) ;
634
+ return provider ?. displayName || provider ?. name || 'unknown' ;
635
+ } catch ( error ) {
636
+ return 'unknown' ;
637
+ }
638
+ }
639
+ }
640
+
641
+ /**
642
+ * Set Selected Account Tool Handler
643
+ */
644
+ export class SetSelectedAccountHandler extends BaseToolHandler {
645
+ name = 'set_selected_account' ;
646
+ description = 'Set the currently selected account in the execution environment' ;
647
+ inputSchema = {
648
+ type : 'object' ,
649
+ properties : {
650
+ address : {
651
+ type : 'string' ,
652
+ description : 'The account address to select'
653
+ }
654
+ } ,
655
+ required : [ 'address' ]
656
+ } ;
657
+
658
+ getPermissions ( ) : string [ ] {
659
+ return [ 'accounts:write' ] ;
660
+ }
661
+
662
+ validate ( args : { address : string } ) : boolean | string {
663
+ const required = this . validateRequired ( args , [ 'address' ] ) ;
664
+ if ( required !== true ) return required ;
665
+
666
+ const types = this . validateTypes ( args , { address : 'string' } ) ;
667
+ if ( types !== true ) return types ;
668
+
669
+ // Basic address validation
670
+ if ( ! / ^ 0 x [ a - f A - F 0 - 9 ] { 40 } $ / . test ( args . address ) ) {
671
+ return 'Invalid Ethereum address format' ;
672
+ }
673
+
674
+ return true ;
675
+ }
676
+
677
+ async execute ( args : { address : string } , plugin : Plugin ) : Promise < IMCPToolResult > {
678
+ try {
679
+ // Set the selected account through the udapp plugin
680
+ await plugin . call ( 'udapp' as any , 'setAccount' , args . address ) ;
681
+
682
+ // Verify the account was set
683
+ const runTabApi = await plugin . call ( 'udapp' as any , 'getAccounts' ) ;
684
+ const currentSelected = runTabApi ?. accounts ?. selectedAccount ;
685
+
686
+ if ( currentSelected !== args . address ) {
687
+ return this . createErrorResult ( `Failed to set account. Current selected: ${ currentSelected } ` ) ;
688
+ }
689
+
690
+ return this . createSuccessResult ( {
691
+ success : true ,
692
+ selectedAccount : args . address ,
693
+ message : `Successfully set account ${ args . address } as selected`
694
+ } ) ;
695
+ } catch ( error ) {
696
+ return this . createErrorResult ( `Failed to set selected account: ${ error . message } ` ) ;
697
+ }
698
+ }
699
+ }
700
+
701
+ /**
702
+ * Get Current Environment Tool Handler
703
+ */
704
+ export class GetCurrentEnvironmentHandler extends BaseToolHandler {
705
+ name = 'get_current_environment' ;
706
+ description = 'Get information about the current execution environment' ;
707
+ inputSchema = {
708
+ type : 'object' ,
709
+ properties : { }
710
+ } ;
711
+
712
+ getPermissions ( ) : string [ ] {
713
+ return [ 'environment:read' ] ;
714
+ }
715
+
716
+ async execute ( _args : any , plugin : Plugin ) : Promise < IMCPToolResult > {
717
+ try {
718
+ // Get environment information
719
+ const provider = await plugin . call ( 'blockchain' as any , 'getCurrentProvider' ) ;
720
+ const networkName = await plugin . call ( 'blockchain' as any , 'getNetworkName' ) . catch ( ( ) => 'unknown' ) ;
721
+ const chainId = await plugin . call ( 'blockchain' as any , 'getChainId' ) . catch ( ( ) => 'unknown' ) ;
722
+
723
+ // Get accounts info
724
+ const runTabApi = await plugin . call ( 'udapp' as any , 'getAccounts' ) ;
725
+ const accountsCount = runTabApi ?. accounts ?. loadedAccounts
726
+ ? Object . keys ( runTabApi . accounts . loadedAccounts ) . length
727
+ : 0 ;
728
+
729
+ const result = {
730
+ success : true ,
731
+ environment : {
732
+ provider : {
733
+ name : provider ?. name || 'unknown' ,
734
+ displayName : provider ?. displayName || provider ?. name || 'unknown' ,
735
+ kind : provider ?. kind || 'unknown'
736
+ } ,
737
+ network : {
738
+ name : networkName ,
739
+ chainId : chainId
740
+ } ,
741
+ accounts : {
742
+ total : accountsCount ,
743
+ selected : runTabApi ?. accounts ?. selectedAccount || null
744
+ }
745
+ }
746
+ } ;
747
+
748
+ return this . createSuccessResult ( result ) ;
749
+ } catch ( error ) {
750
+ return this . createErrorResult ( `Failed to get environment information: ${ error . message } ` ) ;
751
+ }
752
+ }
753
+ }
754
+
552
755
/**
553
756
* Create deployment and interaction tool definitions
554
757
*/
@@ -601,6 +804,30 @@ export function createDeploymentTools(): RemixToolDefinition[] {
601
804
category : ToolCategory . DEPLOYMENT ,
602
805
permissions : [ 'account:read' ] ,
603
806
handler : new GetAccountBalanceHandler ( )
807
+ } ,
808
+ {
809
+ name : 'get_user_accounts' ,
810
+ description : 'Get user accounts from the current execution environment' ,
811
+ inputSchema : new GetUserAccountsHandler ( ) . inputSchema ,
812
+ category : ToolCategory . DEPLOYMENT ,
813
+ permissions : [ 'accounts:read' ] ,
814
+ handler : new GetUserAccountsHandler ( )
815
+ } ,
816
+ {
817
+ name : 'set_selected_account' ,
818
+ description : 'Set the currently selected account in the execution environment' ,
819
+ inputSchema : new SetSelectedAccountHandler ( ) . inputSchema ,
820
+ category : ToolCategory . DEPLOYMENT ,
821
+ permissions : [ 'accounts:write' ] ,
822
+ handler : new SetSelectedAccountHandler ( )
823
+ } ,
824
+ {
825
+ name : 'get_current_environment' ,
826
+ description : 'Get information about the current execution environment' ,
827
+ inputSchema : new GetCurrentEnvironmentHandler ( ) . inputSchema ,
828
+ category : ToolCategory . DEPLOYMENT ,
829
+ permissions : [ 'environment:read' ] ,
830
+ handler : new GetCurrentEnvironmentHandler ( )
604
831
}
605
832
] ;
606
833
}
0 commit comments