github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/whisper/shhclient/client.go (about)

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