github.com/jeffallen/go-ethereum@v1.1.4-0.20150910155051-571d3236c49c/rpc/api/shh_args.go (about)

     1  // Copyright 2015 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  
    17  package api
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"math/big"
    23  
    24  	"github.com/ethereum/go-ethereum/rpc/shared"
    25  )
    26  
    27  type WhisperMessageArgs struct {
    28  	Payload  string
    29  	To       string
    30  	From     string
    31  	Topics   []string
    32  	Priority uint32
    33  	Ttl      uint32
    34  }
    35  
    36  func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) {
    37  	var obj []struct {
    38  		Payload  string
    39  		To       string
    40  		From     string
    41  		Topics   []string
    42  		Priority interface{}
    43  		Ttl      interface{}
    44  	}
    45  
    46  	if err = json.Unmarshal(b, &obj); err != nil {
    47  		return shared.NewDecodeParamError(err.Error())
    48  	}
    49  
    50  	if len(obj) < 1 {
    51  		return shared.NewInsufficientParamsError(len(obj), 1)
    52  	}
    53  	args.Payload = obj[0].Payload
    54  	args.To = obj[0].To
    55  	args.From = obj[0].From
    56  	args.Topics = obj[0].Topics
    57  
    58  	var num *big.Int
    59  	if num, err = numString(obj[0].Priority); err != nil {
    60  		return err
    61  	}
    62  	args.Priority = uint32(num.Int64())
    63  
    64  	if num, err = numString(obj[0].Ttl); err != nil {
    65  		return err
    66  	}
    67  	args.Ttl = uint32(num.Int64())
    68  
    69  	return nil
    70  }
    71  
    72  type WhisperIdentityArgs struct {
    73  	Identity string
    74  }
    75  
    76  func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
    77  	var obj []interface{}
    78  	if err := json.Unmarshal(b, &obj); err != nil {
    79  		return shared.NewDecodeParamError(err.Error())
    80  	}
    81  
    82  	if len(obj) < 1 {
    83  		return shared.NewInsufficientParamsError(len(obj), 1)
    84  	}
    85  
    86  	argstr, ok := obj[0].(string)
    87  	if !ok {
    88  		return shared.NewInvalidTypeError("arg0", "not a string")
    89  	}
    90  
    91  	args.Identity = argstr
    92  
    93  	return nil
    94  }
    95  
    96  type WhisperFilterArgs struct {
    97  	To     string
    98  	From   string
    99  	Topics [][]string
   100  }
   101  
   102  // UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a
   103  // JSON message blob into a WhisperFilterArgs structure.
   104  func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
   105  	// Unmarshal the JSON message and sanity check
   106  	var obj []struct {
   107  		To     interface{} `json:"to"`
   108  		From   interface{} `json:"from"`
   109  		Topics interface{} `json:"topics"`
   110  	}
   111  	if err := json.Unmarshal(b, &obj); err != nil {
   112  		return shared.NewDecodeParamError(err.Error())
   113  	}
   114  	if len(obj) < 1 {
   115  		return shared.NewInsufficientParamsError(len(obj), 1)
   116  	}
   117  	// Retrieve the simple data contents of the filter arguments
   118  	if obj[0].To == nil {
   119  		args.To = ""
   120  	} else {
   121  		argstr, ok := obj[0].To.(string)
   122  		if !ok {
   123  			return shared.NewInvalidTypeError("to", "is not a string")
   124  		}
   125  		args.To = argstr
   126  	}
   127  	if obj[0].From == nil {
   128  		args.From = ""
   129  	} else {
   130  		argstr, ok := obj[0].From.(string)
   131  		if !ok {
   132  			return shared.NewInvalidTypeError("from", "is not a string")
   133  		}
   134  		args.From = argstr
   135  	}
   136  	// Construct the nested topic array
   137  	if obj[0].Topics != nil {
   138  		// Make sure we have an actual topic array
   139  		list, ok := obj[0].Topics.([]interface{})
   140  		if !ok {
   141  			return shared.NewInvalidTypeError("topics", "is not an array")
   142  		}
   143  		// Iterate over each topic and handle nil, string or array
   144  		topics := make([][]string, len(list))
   145  		for idx, field := range list {
   146  			switch value := field.(type) {
   147  			case nil:
   148  				topics[idx] = []string{}
   149  
   150  			case string:
   151  				topics[idx] = []string{value}
   152  
   153  			case []interface{}:
   154  				topics[idx] = make([]string, len(value))
   155  				for i, nested := range value {
   156  					switch value := nested.(type) {
   157  					case nil:
   158  						topics[idx][i] = ""
   159  
   160  					case string:
   161  						topics[idx][i] = value
   162  
   163  					default:
   164  						return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", idx, i), "is not a string")
   165  					}
   166  				}
   167  			default:
   168  				return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d]", idx), "not a string or array")
   169  			}
   170  		}
   171  		args.Topics = topics
   172  	}
   173  	return nil
   174  }