shh.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package api
  2. import (
  3. "math/big"
  4. "github.com/ethereum/go-ethereum/eth"
  5. "github.com/ethereum/go-ethereum/rpc/codec"
  6. "github.com/ethereum/go-ethereum/rpc/shared"
  7. "github.com/ethereum/go-ethereum/xeth"
  8. )
  9. const (
  10. ShhApiVersion = "1.0"
  11. )
  12. var (
  13. // mapping between methods and handlers
  14. shhMapping = map[string]shhhandler{
  15. "shh_version": (*shhApi).Version,
  16. "shh_post": (*shhApi).Post,
  17. "shh_hasIdentity": (*shhApi).HasIdentity,
  18. "shh_newIdentity": (*shhApi).NewIdentity,
  19. "shh_newFilter": (*shhApi).NewFilter,
  20. "shh_uninstallFilter": (*shhApi).UninstallFilter,
  21. "shh_getFilterChanges": (*shhApi).GetFilterChanges,
  22. }
  23. )
  24. func newWhisperOfflineError(method string) error {
  25. return shared.NewNotAvailableError(method, "whisper offline")
  26. }
  27. // net callback handler
  28. type shhhandler func(*shhApi, *shared.Request) (interface{}, error)
  29. // shh api provider
  30. type shhApi struct {
  31. xeth *xeth.XEth
  32. ethereum *eth.Ethereum
  33. methods map[string]shhhandler
  34. codec codec.ApiCoder
  35. }
  36. // create a new whisper api instance
  37. func NewShhApi(xeth *xeth.XEth, eth *eth.Ethereum, coder codec.Codec) *shhApi {
  38. return &shhApi{
  39. xeth: xeth,
  40. ethereum: eth,
  41. methods: shhMapping,
  42. codec: coder.New(nil),
  43. }
  44. }
  45. // collection with supported methods
  46. func (self *shhApi) Methods() []string {
  47. methods := make([]string, len(self.methods))
  48. i := 0
  49. for k := range self.methods {
  50. methods[i] = k
  51. i++
  52. }
  53. return methods
  54. }
  55. // Execute given request
  56. func (self *shhApi) Execute(req *shared.Request) (interface{}, error) {
  57. if callback, ok := self.methods[req.Method]; ok {
  58. return callback(self, req)
  59. }
  60. return nil, shared.NewNotImplementedError(req.Method)
  61. }
  62. func (self *shhApi) Name() string {
  63. return shared.ShhApiName
  64. }
  65. func (self *shhApi) ApiVersion() string {
  66. return ShhApiVersion
  67. }
  68. func (self *shhApi) Version(req *shared.Request) (interface{}, error) {
  69. w := self.xeth.Whisper()
  70. if w == nil {
  71. return nil, newWhisperOfflineError(req.Method)
  72. }
  73. return w.Version(), nil
  74. }
  75. func (self *shhApi) Post(req *shared.Request) (interface{}, error) {
  76. w := self.xeth.Whisper()
  77. if w == nil {
  78. return nil, newWhisperOfflineError(req.Method)
  79. }
  80. args := new(WhisperMessageArgs)
  81. if err := self.codec.Decode(req.Params, &args); err != nil {
  82. return nil, err
  83. }
  84. err := w.Post(args.Payload, args.To, args.From, args.Topics, args.Priority, args.Ttl)
  85. if err != nil {
  86. return false, err
  87. }
  88. return true, nil
  89. }
  90. func (self *shhApi) HasIdentity(req *shared.Request) (interface{}, error) {
  91. w := self.xeth.Whisper()
  92. if w == nil {
  93. return nil, newWhisperOfflineError(req.Method)
  94. }
  95. args := new(WhisperIdentityArgs)
  96. if err := self.codec.Decode(req.Params, &args); err != nil {
  97. return nil, err
  98. }
  99. return w.HasIdentity(args.Identity), nil
  100. }
  101. func (self *shhApi) NewIdentity(req *shared.Request) (interface{}, error) {
  102. w := self.xeth.Whisper()
  103. if w == nil {
  104. return nil, newWhisperOfflineError(req.Method)
  105. }
  106. return w.NewIdentity(), nil
  107. }
  108. func (self *shhApi) NewFilter(req *shared.Request) (interface{}, error) {
  109. args := new(WhisperFilterArgs)
  110. if err := self.codec.Decode(req.Params, &args); err != nil {
  111. return nil, err
  112. }
  113. id := self.xeth.NewWhisperFilter(args.To, args.From, args.Topics)
  114. return newHexNum(big.NewInt(int64(id)).Bytes()), nil
  115. }
  116. func (self *shhApi) UninstallFilter(req *shared.Request) (interface{}, error) {
  117. args := new(FilterIdArgs)
  118. if err := self.codec.Decode(req.Params, &args); err != nil {
  119. return nil, err
  120. }
  121. return self.xeth.UninstallWhisperFilter(args.Id), nil
  122. }
  123. func (self *shhApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
  124. w := self.xeth.Whisper()
  125. if w == nil {
  126. return nil, newWhisperOfflineError(req.Method)
  127. }
  128. // Retrieve all the new messages arrived since the last request
  129. args := new(FilterIdArgs)
  130. if err := self.codec.Decode(req.Params, &args); err != nil {
  131. return nil, err
  132. }
  133. return self.xeth.WhisperMessagesChanged(args.Id), nil
  134. }
  135. func (self *shhApi) GetMessages(req *shared.Request) (interface{}, error) {
  136. w := self.xeth.Whisper()
  137. if w == nil {
  138. return nil, newWhisperOfflineError(req.Method)
  139. }
  140. // Retrieve all the cached messages matching a specific, existing filter
  141. args := new(FilterIdArgs)
  142. if err := self.codec.Decode(req.Params, &args); err != nil {
  143. return nil, err
  144. }
  145. return self.xeth.WhisperMessages(args.Id), nil
  146. }