// 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 (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) }
// 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 (s *PublicWhisperAPI) HasIdentity(identity string) (bool, error) { if s.w == nil { return false, whisperOffLineErr } return s.w.HasIdentity(crypto.ToECDSAPub(common.FromHex(identity))), nil }