// NewWhisperFilter creates and registers a new message filter to watch for inbound whisper messages. func (s *PublicWhisperAPI) NewFilter(args NewFilterArgs) (*rpc.HexNumber, error) { if s.w == nil { return nil, whisperOffLineErr } var id int filter := Filter{ To: crypto.ToECDSAPub(common.FromHex(args.To)), From: crypto.ToECDSAPub(common.FromHex(args.From)), Topics: NewFilterTopics(args.Topics...), Fn: func(message *Message) { wmsg := NewWhisperMessage(message) s.messagesMu.RLock() // Only read lock to the filter pool defer s.messagesMu.RUnlock() if s.messages[id] != nil { s.messages[id].insert(wmsg) } }, } id = s.w.Watch(filter) s.messagesMu.Lock() s.messages[id] = newWhisperFilter(id, s.w) s.messagesMu.Unlock() return rpc.NewHexNumber(id), nil }
// Post injects a message into the whisper network for distribution. func (self *Whisper) Post(payload string, to, from string, topics []string, priority, ttl uint32) error { // Decode the topic strings topicsDecoded := make([][]byte, len(topics)) for i, topic := range topics { topicsDecoded[i] = common.FromHex(topic) } // Construct the whisper message and transmission options message := whisper.NewMessage(common.FromHex(payload)) options := whisper.Options{ To: crypto.ToECDSAPub(common.FromHex(to)), TTL: time.Duration(ttl) * time.Second, Topics: whisper.NewTopics(topicsDecoded...), } if len(from) != 0 { if key := self.Whisper.GetIdentity(crypto.ToECDSAPub(common.FromHex(from))); key != nil { options.From = key } else { return fmt.Errorf("unknown identity to send from: %s", from) } } // Wrap and send the message pow := time.Duration(priority) * time.Millisecond envelope, err := message.Wrap(pow, options) if err != nil { return err } if err := self.Whisper.Send(envelope); err != nil { return err } return nil }
// Post injects a message into the whisper network for distribution. func (s *PublicWhisperAPI) Post(args PostArgs) (bool, error) { if s.w == nil { return false, whisperOffLineErr } // construct whisper message with transmission options message := NewMessage(common.FromHex(args.Payload)) options := Options{ To: crypto.ToECDSAPub(common.FromHex(args.To)), TTL: time.Duration(args.TTL) * time.Second, Topics: NewTopics(args.Topics...), } // set sender identity if len(args.From) > 0 { if key := s.w.GetIdentity(crypto.ToECDSAPub(common.FromHex(args.From))); key != nil { options.From = key } else { return false, fmt.Errorf("unknown identity to send from: %s", args.From) } } // Wrap and send the message pow := time.Duration(args.Priority) * time.Millisecond envelope, err := message.Wrap(pow, options) if err != nil { return false, err } return true, s.w.Send(envelope) }
func (self *Whisper) Post(payload []string, to, from string, topics []string, priority, ttl uint32) { var data []byte for _, d := range payload { data = append(data, common.FromHex(d)...) } pk := crypto.ToECDSAPub(common.FromHex(from)) if key := self.Whisper.GetIdentity(pk); key != nil { msg := whisper.NewMessage(data) envelope, err := msg.Wrap(time.Duration(priority*100000), whisper.Options{ TTL: time.Duration(ttl) * time.Second, To: crypto.ToECDSAPub(common.FromHex(to)), From: key, Topics: whisper.NewTopicsFromStrings(topics...), }) if err != nil { qlogger.Infoln(err) // handle error return } if err := self.Whisper.Send(envelope); err != nil { qlogger.Infoln(err) // handle error return } } else { qlogger.Infoln("unmatched pub / priv for seal") } }
func filterFromMap(opts map[string]interface{}) (f whisper.Filter) { if to, ok := opts["to"].(string); ok { f.To = crypto.ToECDSAPub(common.FromHex(to)) } if from, ok := opts["from"].(string); ok { f.From = crypto.ToECDSAPub(common.FromHex(from)) } if topicList, ok := opts["topics"].(*qml.List); ok { var topics []string topicList.Convert(&topics) f.Topics = whisper.NewFilterTopicsFromStringsFlat(topics...) } return }
// Watch installs a new message handler to run in case a matching packet arrives // from the whisper network. func (self *Whisper) Watch(to, from string, topics [][]string, fn func(WhisperMessage)) int { // Decode the topic strings topicsDecoded := make([][][]byte, len(topics)) for i, condition := range topics { topicsDecoded[i] = make([][]byte, len(condition)) for j, topic := range condition { topicsDecoded[i][j] = common.FromHex(topic) } } // Assemble and inject the filter into the whisper client filter := whisper.Filter{ To: crypto.ToECDSAPub(common.FromHex(to)), From: crypto.ToECDSAPub(common.FromHex(from)), Topics: whisper.NewFilterTopics(topicsDecoded...), } filter.Fn = func(message *whisper.Message) { fn(NewWhisperMessage(message)) } return self.Whisper.Watch(filter) }
// importPublicKey unmarshals 512 bit public keys. func importPublicKey(pubKey []byte) (*ecies.PublicKey, error) { var pubKey65 []byte switch len(pubKey) { case 64: // add 'uncompressed key' flag pubKey65 = append([]byte{0x04}, pubKey...) case 65: pubKey65 = pubKey default: return nil, fmt.Errorf("invalid public key length %v (expect 64/65)", len(pubKey)) } // TODO: fewer pointless conversions return ecies.ImportECDSAPublic(crypto.ToECDSAPub(pubKey65)), nil }
// HasIdentity checks if the the whisper node is configured with the private key // of the specified public pair. func (self *Whisper) HasIdentity(key string) bool { return self.Whisper.HasIdentity(crypto.ToECDSAPub(common.FromHex(key))) }
// HasIdentity checks if the the whisper node is configured with the private key // of the specified public pair. func (s *PublicWhisperAPI) HasIdentity(identity string) (bool, error) { if s.w == nil { return false, whisperOffLineErr } return s.w.HasIdentity(crypto.ToECDSAPub(common.FromHex(identity))), nil }