// 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) }
// 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 }
// 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 pub := crypto.ToECDSAPub(pubKey65) if pub.X == nil { return nil, fmt.Errorf("invalid public key") } return ecies.ImportECDSAPublic(pub), nil }
// 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 }
// 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))) }