shhclient.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // Copyright 2017 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. // Contains a wrapper for the Whisper client.
  17. package geth
  18. import (
  19. "github.com/ethereum/go-ethereum/whisper/shhclient"
  20. whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
  21. )
  22. // WhisperClient provides access to the Ethereum APIs.
  23. type WhisperClient struct {
  24. client *shhclient.Client
  25. }
  26. // NewWhisperClient connects a client to the given URL.
  27. func NewWhisperClient(rawurl string) (client *WhisperClient, _ error) {
  28. rawClient, err := shhclient.Dial(rawurl)
  29. return &WhisperClient{rawClient}, err
  30. }
  31. // GetVersion returns the Whisper sub-protocol version.
  32. func (wc *WhisperClient) GetVersion(ctx *Context) (version string, _ error) {
  33. return wc.client.Version(ctx.context)
  34. }
  35. // Info returns diagnostic information about the whisper node.
  36. func (wc *WhisperClient) GetInfo(ctx *Context) (info *Info, _ error) {
  37. rawInfo, err := wc.client.Info(ctx.context)
  38. return &Info{&rawInfo}, err
  39. }
  40. // SetMaxMessageSize sets the maximal message size allowed by this node. Incoming
  41. // and outgoing messages with a larger size will be rejected. Whisper message size
  42. // can never exceed the limit imposed by the underlying P2P protocol (10 Mb).
  43. func (wc *WhisperClient) SetMaxMessageSize(ctx *Context, size int32) error {
  44. return wc.client.SetMaxMessageSize(ctx.context, uint32(size))
  45. }
  46. // SetMinimumPoW (experimental) sets the minimal PoW required by this node.
  47. // This experimental function was introduced for the future dynamic adjustment of
  48. // PoW requirement. If the node is overwhelmed with messages, it should raise the
  49. // PoW requirement and notify the peers. The new value should be set relative to
  50. // the old value (e.g. double). The old value could be obtained via shh_info call.
  51. func (wc *WhisperClient) SetMinimumPoW(ctx *Context, pow float64) error {
  52. return wc.client.SetMinimumPoW(ctx.context, pow)
  53. }
  54. // Marks specific peer trusted, which will allow it to send historic (expired) messages.
  55. // Note This function is not adding new nodes, the node needs to exists as a peer.
  56. func (wc *WhisperClient) MarkTrustedPeer(ctx *Context, enode string) error {
  57. return wc.client.MarkTrustedPeer(ctx.context, enode)
  58. }
  59. // NewKeyPair generates a new public and private key pair for message decryption and encryption.
  60. // It returns an identifier that can be used to refer to the key.
  61. func (wc *WhisperClient) NewKeyPair(ctx *Context) (string, error) {
  62. return wc.client.NewKeyPair(ctx.context)
  63. }
  64. // AddPrivateKey stored the key pair, and returns its ID.
  65. func (wc *WhisperClient) AddPrivateKey(ctx *Context, key []byte) (string, error) {
  66. return wc.client.AddPrivateKey(ctx.context, key)
  67. }
  68. // DeleteKeyPair delete the specifies key.
  69. func (wc *WhisperClient) DeleteKeyPair(ctx *Context, id string) (string, error) {
  70. return wc.client.DeleteKeyPair(ctx.context, id)
  71. }
  72. // HasKeyPair returns an indication if the node has a private key or
  73. // key pair matching the given ID.
  74. func (wc *WhisperClient) HasKeyPair(ctx *Context, id string) (bool, error) {
  75. return wc.client.HasKeyPair(ctx.context, id)
  76. }
  77. // GetPublicKey return the public key for a key ID.
  78. func (wc *WhisperClient) GetPublicKey(ctx *Context, id string) ([]byte, error) {
  79. return wc.client.PublicKey(ctx.context, id)
  80. }
  81. // GetPrivateKey return the private key for a key ID.
  82. func (wc *WhisperClient) GetPrivateKey(ctx *Context, id string) ([]byte, error) {
  83. return wc.client.PrivateKey(ctx.context, id)
  84. }
  85. // NewSymmetricKey generates a random symmetric key and returns its identifier.
  86. // Can be used encrypting and decrypting messages where the key is known to both parties.
  87. func (wc *WhisperClient) NewSymmetricKey(ctx *Context) (string, error) {
  88. return wc.client.NewSymmetricKey(ctx.context)
  89. }
  90. // AddSymmetricKey stores the key, and returns its identifier.
  91. func (wc *WhisperClient) AddSymmetricKey(ctx *Context, key []byte) (string, error) {
  92. return wc.client.AddSymmetricKey(ctx.context, key)
  93. }
  94. // GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier.
  95. func (wc *WhisperClient) GenerateSymmetricKeyFromPassword(ctx *Context, passwd string) (string, error) {
  96. return wc.client.GenerateSymmetricKeyFromPassword(ctx.context, passwd)
  97. }
  98. // HasSymmetricKey returns an indication if the key associated with the given id is stored in the node.
  99. func (wc *WhisperClient) HasSymmetricKey(ctx *Context, id string) (bool, error) {
  100. return wc.client.HasSymmetricKey(ctx.context, id)
  101. }
  102. // GetSymmetricKey returns the symmetric key associated with the given identifier.
  103. func (wc *WhisperClient) GetSymmetricKey(ctx *Context, id string) ([]byte, error) {
  104. return wc.client.GetSymmetricKey(ctx.context, id)
  105. }
  106. // DeleteSymmetricKey deletes the symmetric key associated with the given identifier.
  107. func (wc *WhisperClient) DeleteSymmetricKey(ctx *Context, id string) error {
  108. return wc.client.DeleteSymmetricKey(ctx.context, id)
  109. }
  110. // Post a message onto the network.
  111. func (wc *WhisperClient) Post(ctx *Context, message *NewMessage) (string, error) {
  112. return wc.client.Post(ctx.context, *message.newMessage)
  113. }
  114. // NewHeadHandler is a client-side subscription callback to invoke on events and
  115. // subscription failure.
  116. type NewMessageHandler interface {
  117. OnNewMessage(message *Message)
  118. OnError(failure string)
  119. }
  120. // SubscribeMessages subscribes to messages that match the given criteria. This method
  121. // is only supported on bi-directional connections such as websockets and IPC.
  122. // NewMessageFilter uses polling and is supported over HTTP.
  123. func (wc *WhisperClient) SubscribeMessages(ctx *Context, criteria *Criteria, handler NewMessageHandler, buffer int) (*Subscription, error) {
  124. // Subscribe to the event internally
  125. ch := make(chan *whisper.Message, buffer)
  126. rawSub, err := wc.client.SubscribeMessages(ctx.context, *criteria.criteria, ch)
  127. if err != nil {
  128. return nil, err
  129. }
  130. // Start up a dispatcher to feed into the callback
  131. go func() {
  132. for {
  133. select {
  134. case message := <-ch:
  135. handler.OnNewMessage(&Message{message})
  136. case err := <-rawSub.Err():
  137. if err != nil {
  138. handler.OnError(err.Error())
  139. }
  140. return
  141. }
  142. }
  143. }()
  144. return &Subscription{rawSub}, nil
  145. }
  146. // NewMessageFilter creates a filter within the node. This filter can be used to poll
  147. // for new messages (see FilterMessages) that satisfy the given criteria. A filter can
  148. // timeout when it was polled for in whisper.filterTimeout.
  149. func (wc *WhisperClient) NewMessageFilter(ctx *Context, criteria *Criteria) (string, error) {
  150. return wc.client.NewMessageFilter(ctx.context, *criteria.criteria)
  151. }
  152. // DeleteMessageFilter removes the filter associated with the given id.
  153. func (wc *WhisperClient) DeleteMessageFilter(ctx *Context, id string) error {
  154. return wc.client.DeleteMessageFilter(ctx.context, id)
  155. }
  156. // GetFilterMessages retrieves all messages that are received between the last call to
  157. // this function and match the criteria that where given when the filter was created.
  158. func (wc *WhisperClient) GetFilterMessages(ctx *Context, id string) (*Messages, error) {
  159. rawFilterMessages, err := wc.client.FilterMessages(ctx.context, id)
  160. if err != nil {
  161. return nil, err
  162. }
  163. res := make([]*whisper.Message, len(rawFilterMessages))
  164. copy(res, rawFilterMessages)
  165. return &Messages{res}, nil
  166. }