diff options
Diffstat (limited to 'rpc/api/shh_args.go')
-rw-r--r-- | rpc/api/shh_args.go | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/rpc/api/shh_args.go b/rpc/api/shh_args.go new file mode 100644 index 000000000..00abac232 --- /dev/null +++ b/rpc/api/shh_args.go @@ -0,0 +1,158 @@ +package api + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/rpc/shared" +) + +type WhisperMessageArgs struct { + Payload string + To string + From string + Topics []string + Priority uint32 + Ttl uint32 +} + +func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) { + var obj []struct { + Payload string + To string + From string + Topics []string + Priority interface{} + Ttl interface{} + } + + if err = json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + args.Payload = obj[0].Payload + args.To = obj[0].To + args.From = obj[0].From + args.Topics = obj[0].Topics + + var num *big.Int + if num, err = numString(obj[0].Priority); err != nil { + return err + } + args.Priority = uint32(num.Int64()) + + if num, err = numString(obj[0].Ttl); err != nil { + return err + } + args.Ttl = uint32(num.Int64()) + + return nil +} + +type WhisperIdentityArgs struct { + Identity string +} + +func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) { + var obj []interface{} + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + + argstr, ok := obj[0].(string) + if !ok { + return shared.NewInvalidTypeError("arg0", "not a string") + } + + args.Identity = argstr + + return nil +} + +type WhisperFilterArgs struct { + To string + From string + Topics [][]string +} + +// UnmarshalJSON implements the json.Unmarshaler interface, invoked to convert a +// JSON message blob into a WhisperFilterArgs structure. +func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) { + // Unmarshal the JSON message and sanity check + var obj []struct { + To interface{} `json:"to"` + From interface{} `json:"from"` + Topics interface{} `json:"topics"` + } + if err := json.Unmarshal(b, &obj); err != nil { + return shared.NewDecodeParamError(err.Error()) + } + if len(obj) < 1 { + return shared.NewInsufficientParamsError(len(obj), 1) + } + // Retrieve the simple data contents of the filter arguments + if obj[0].To == nil { + args.To = "" + } else { + argstr, ok := obj[0].To.(string) + if !ok { + return shared.NewInvalidTypeError("to", "is not a string") + } + args.To = argstr + } + if obj[0].From == nil { + args.From = "" + } else { + argstr, ok := obj[0].From.(string) + if !ok { + return shared.NewInvalidTypeError("from", "is not a string") + } + args.From = argstr + } + // Construct the nested topic array + if obj[0].Topics != nil { + // Make sure we have an actual topic array + list, ok := obj[0].Topics.([]interface{}) + if !ok { + return shared.NewInvalidTypeError("topics", "is not an array") + } + // Iterate over each topic and handle nil, string or array + topics := make([][]string, len(list)) + for idx, field := range list { + switch value := field.(type) { + case nil: + topics[idx] = []string{} + + case string: + topics[idx] = []string{value} + + case []interface{}: + topics[idx] = make([]string, len(value)) + for i, nested := range value { + switch value := nested.(type) { + case nil: + topics[idx][i] = "" + + case string: + topics[idx][i] = value + + default: + return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", idx, i), "is not a string") + } + } + default: + return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d]", idx), "not a string or array") + } + } + args.Topics = topics + } + return nil +} |