client.go 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. package shhclient
  17. import (
  18. "context"
  19. "github.com/ethereum/go-ethereum"
  20. "github.com/ethereum/go-ethereum/common/hexutil"
  21. "github.com/ethereum/go-ethereum/rpc"
  22. whisper "github.com/ethereum/go-ethereum/whisper/whisperv6"
  23. )
  24. // Client defines typed wrappers for the Whisper v6 RPC API.
  25. type Client struct {
  26. c *rpc.Client
  27. }
  28. // Dial connects a client to the given URL.
  29. func Dial(rawurl string) (*Client, error) {
  30. c, err := rpc.Dial(rawurl)
  31. if err != nil {
  32. return nil, err
  33. }
  34. return NewClient(c), nil
  35. }
  36. // NewClient creates a client that uses the given RPC client.
  37. func NewClient(c *rpc.Client) *Client {
  38. return &Client{c}
  39. }
  40. // Version returns the Whisper sub-protocol version.
  41. func (sc *Client) Version(ctx context.Context) (string, error) {
  42. var result string
  43. err := sc.c.CallContext(ctx, &result, "shh_version")
  44. return result, err
  45. }
  46. // Info returns diagnostic information about the whisper node.
  47. func (sc *Client) Info(ctx context.Context) (whisper.Info, error) {
  48. var info whisper.Info
  49. err := sc.c.CallContext(ctx, &info, "shh_info")
  50. return info, err
  51. }
  52. // SetMaxMessageSize sets the maximal message size allowed by this node. Incoming
  53. // and outgoing messages with a larger size will be rejected. Whisper message size
  54. // can never exceed the limit imposed by the underlying P2P protocol (10 Mb).
  55. func (sc *Client) SetMaxMessageSize(ctx context.Context, size uint32) error {
  56. var ignored bool
  57. return sc.c.CallContext(ctx, &ignored, "shh_setMaxMessageSize", size)
  58. }
  59. // SetMinimumPoW (experimental) sets the minimal PoW required by this node.
  60. // This experimental function was introduced for the future dynamic adjustment of
  61. // PoW requirement. If the node is overwhelmed with messages, it should raise the
  62. // PoW requirement and notify the peers. The new value should be set relative to
  63. // the old value (e.g. double). The old value could be obtained via shh_info call.
  64. func (sc *Client) SetMinimumPoW(ctx context.Context, pow float64) error {
  65. var ignored bool
  66. return sc.c.CallContext(ctx, &ignored, "shh_setMinPoW", pow)
  67. }
  68. // MarkTrustedPeer marks specific peer trusted, which will allow it to send historic (expired) messages.
  69. // Note This function is not adding new nodes, the node needs to exists as a peer.
  70. func (sc *Client) MarkTrustedPeer(ctx context.Context, enode string) error {
  71. var ignored bool
  72. return sc.c.CallContext(ctx, &ignored, "shh_markTrustedPeer", enode)
  73. }
  74. // NewKeyPair generates a new public and private key pair for message decryption and encryption.
  75. // It returns an identifier that can be used to refer to the key.
  76. func (sc *Client) NewKeyPair(ctx context.Context) (string, error) {
  77. var id string
  78. return id, sc.c.CallContext(ctx, &id, "shh_newKeyPair")
  79. }
  80. // AddPrivateKey stored the key pair, and returns its ID.
  81. func (sc *Client) AddPrivateKey(ctx context.Context, key []byte) (string, error) {
  82. var id string
  83. return id, sc.c.CallContext(ctx, &id, "shh_addPrivateKey", hexutil.Bytes(key))
  84. }
  85. // DeleteKeyPair delete the specifies key.
  86. func (sc *Client) DeleteKeyPair(ctx context.Context, id string) (string, error) {
  87. var ignored bool
  88. return id, sc.c.CallContext(ctx, &ignored, "shh_deleteKeyPair", id)
  89. }
  90. // HasKeyPair returns an indication if the node has a private key or
  91. // key pair matching the given ID.
  92. func (sc *Client) HasKeyPair(ctx context.Context, id string) (bool, error) {
  93. var has bool
  94. return has, sc.c.CallContext(ctx, &has, "shh_hasKeyPair", id)
  95. }
  96. // PublicKey return the public key for a key ID.
  97. func (sc *Client) PublicKey(ctx context.Context, id string) ([]byte, error) {
  98. var key hexutil.Bytes
  99. return []byte(key), sc.c.CallContext(ctx, &key, "shh_getPublicKey", id)
  100. }
  101. // PrivateKey return the private key for a key ID.
  102. func (sc *Client) PrivateKey(ctx context.Context, id string) ([]byte, error) {
  103. var key hexutil.Bytes
  104. return []byte(key), sc.c.CallContext(ctx, &key, "shh_getPrivateKey", id)
  105. }
  106. // NewSymmetricKey generates a random symmetric key and returns its identifier.
  107. // Can be used encrypting and decrypting messages where the key is known to both parties.
  108. func (sc *Client) NewSymmetricKey(ctx context.Context) (string, error) {
  109. var id string
  110. return id, sc.c.CallContext(ctx, &id, "shh_newSymKey")
  111. }
  112. // AddSymmetricKey stores the key, and returns its identifier.
  113. func (sc *Client) AddSymmetricKey(ctx context.Context, key []byte) (string, error) {
  114. var id string
  115. return id, sc.c.CallContext(ctx, &id, "shh_addSymKey", hexutil.Bytes(key))
  116. }
  117. // GenerateSymmetricKeyFromPassword generates the key from password, stores it, and returns its identifier.
  118. func (sc *Client) GenerateSymmetricKeyFromPassword(ctx context.Context, passwd string) (string, error) {
  119. var id string
  120. return id, sc.c.CallContext(ctx, &id, "shh_generateSymKeyFromPassword", passwd)
  121. }
  122. // HasSymmetricKey returns an indication if the key associated with the given id is stored in the node.
  123. func (sc *Client) HasSymmetricKey(ctx context.Context, id string) (bool, error) {
  124. var found bool
  125. return found, sc.c.CallContext(ctx, &found, "shh_hasSymKey", id)
  126. }
  127. // GetSymmetricKey returns the symmetric key associated with the given identifier.
  128. func (sc *Client) GetSymmetricKey(ctx context.Context, id string) ([]byte, error) {
  129. var key hexutil.Bytes
  130. return []byte(key), sc.c.CallContext(ctx, &key, "shh_getSymKey", id)
  131. }
  132. // DeleteSymmetricKey deletes the symmetric key associated with the given identifier.
  133. func (sc *Client) DeleteSymmetricKey(ctx context.Context, id string) error {
  134. var ignored bool
  135. return sc.c.CallContext(ctx, &ignored, "shh_deleteSymKey", id)
  136. }
  137. // Post a message onto the network.
  138. func (sc *Client) Post(ctx context.Context, message whisper.NewMessage) (string, error) {
  139. var hash string
  140. return hash, sc.c.CallContext(ctx, &hash, "shh_post", message)
  141. }
  142. // SubscribeMessages subscribes to messages that match the given criteria. This method
  143. // is only supported on bi-directional connections such as websockets and IPC.
  144. // NewMessageFilter uses polling and is supported over HTTP.
  145. func (sc *Client) SubscribeMessages(ctx context.Context, criteria whisper.Criteria, ch chan<- *whisper.Message) (ethereum.Subscription, error) {
  146. return sc.c.ShhSubscribe(ctx, ch, "messages", criteria)
  147. }
  148. // NewMessageFilter creates a filter within the node. This filter can be used to poll
  149. // for new messages (see FilterMessages) that satisfy the given criteria. A filter can
  150. // timeout when it was polled for in whisper.filterTimeout.
  151. func (sc *Client) NewMessageFilter(ctx context.Context, criteria whisper.Criteria) (string, error) {
  152. var id string
  153. return id, sc.c.CallContext(ctx, &id, "shh_newMessageFilter", criteria)
  154. }
  155. // DeleteMessageFilter removes the filter associated with the given id.
  156. func (sc *Client) DeleteMessageFilter(ctx context.Context, id string) error {
  157. var ignored bool
  158. return sc.c.CallContext(ctx, &ignored, "shh_deleteMessageFilter", id)
  159. }
  160. // FilterMessages retrieves all messages that are received between the last call to
  161. // this function and match the criteria that where given when the filter was created.
  162. func (sc *Client) FilterMessages(ctx context.Context, id string) ([]*whisper.Message, error) {
  163. var messages []*whisper.Message
  164. return messages, sc.c.CallContext(ctx, &messages, "shh_getFilterMessages", id)
  165. }