Introduce a new type Api in the rpc package:
// Api describes the set of methods offered over the RPC interface
type Api struct {
Namespace string // namespace under which the rpc methods of Service are exposed
Version string // api version for DApp's
Service interface{} // receiver instance which holds the methods
Public bool // indication if the methods must be considered safe for public use
}
Extend the node.Service interface with a new method:
// Api retrieves the list of RPC methods the service provides
Api() []*rpc.Api
When the node stack is started a new rpc.Server instance is created and available API's are registered.
ipcServer := rpc.NewServer()
httpServer := rpc.NewServer()
for _, api := range apis {
if mustOffer(api, rpc.IPC) {
ipcServer.register(api)
}
if mustOffer(api, rpc.HTTP) {
httpServer.register(api)
}
}
// mustOffer indicates if the API must be offered for the given rpc type (IPC, HTTP, WS?...)
func mustOffer(api *Api, type rpc.Type) bool {
// use defaults, all over IPC and only public over HTTP
// or use user overriden settings
}
An example implementation for the Api() call:
// BlockServer offers a public block API
type BlockService struct {}
func (*s BlockService) Get(...) ... {}
// BlockManagementService offers a private block API
type BlockManagementService struct {}
func (s *BlockService) Delete(...) ... {}
func (s *MyService) Apis() []*Api {
return []*Api{
&Api{
Namespace: "eth",
Version: "1.0",
Public: true,
Service: new(BlockService),
},
&Api{
Namespace: "eth",
Version: "1.0",
Public: false,
Service: new(BlockManagementService),
},
}
}