| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // Contains the external API to the whisper sub-protocol. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | package xeth | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-03-16 14:46:46 -04:00
										 |  |  | 	"github.com/ethereum/go-ethereum/crypto" | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/whisper" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var qlogger = logger.NewLogger("XSHH") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // Whisper represents the API wrapper around the internal whisper implementation. | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | type Whisper struct { | 
					
						
							|  |  |  | 	*whisper.Whisper | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // NewWhisper wraps an internal whisper client into an external API version. | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | func NewWhisper(w *whisper.Whisper) *Whisper { | 
					
						
							|  |  |  | 	return &Whisper{w} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // NewIdentity generates a new cryptographic identity for the client, and injects | 
					
						
							|  |  |  | // it into the known identities for message decryption. | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | func (self *Whisper) NewIdentity() string { | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	identity := self.Whisper.NewIdentity() | 
					
						
							|  |  |  | 	return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)) | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // HasIdentity checks if the the whisper node is configured with the private key | 
					
						
							|  |  |  | // of the specified public pair. | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | func (self *Whisper) HasIdentity(key string) bool { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	return self.Whisper.HasIdentity(crypto.ToECDSAPub(common.FromHex(key))) | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // 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 { | 
					
						
							| 
									
										
										
										
											2015-04-22 17:25:54 +03:00
										 |  |  | 	// Decode the topic strings | 
					
						
							|  |  |  | 	topicsDecoded := make([][]byte, len(topics)) | 
					
						
							|  |  |  | 	for i, topic := range topics { | 
					
						
							|  |  |  | 		topicsDecoded[i] = common.FromHex(topic) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	// 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, | 
					
						
							| 
									
										
										
										
											2015-04-22 17:25:54 +03:00
										 |  |  | 		Topics: whisper.NewTopics(topicsDecoded...), | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	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) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	// Wrap and send the message | 
					
						
							|  |  |  | 	pow := time.Duration(priority) * time.Millisecond | 
					
						
							|  |  |  | 	envelope, err := message.Wrap(pow, options) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	if err := self.Whisper.Send(envelope); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // Watch installs a new message handler to run in case a matching packet arrives | 
					
						
							|  |  |  | // from the whisper network. | 
					
						
							| 
									
										
										
										
											2015-04-21 18:31:08 +03:00
										 |  |  | func (self *Whisper) Watch(to, from string, topics [][]string, fn func(WhisperMessage)) int { | 
					
						
							| 
									
										
										
										
											2015-04-22 17:25:54 +03:00
										 |  |  | 	// 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 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	filter := whisper.Filter{ | 
					
						
							|  |  |  | 		To:     crypto.ToECDSAPub(common.FromHex(to)), | 
					
						
							|  |  |  | 		From:   crypto.ToECDSAPub(common.FromHex(from)), | 
					
						
							| 
									
										
										
										
											2015-04-22 17:25:54 +03:00
										 |  |  | 		Topics: whisper.NewFilterTopics(topicsDecoded...), | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	filter.Fn = func(message *whisper.Message) { | 
					
						
							|  |  |  | 		fn(NewWhisperMessage(message)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return self.Whisper.Watch(filter) | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | // Messages retrieves all the currently pooled messages matching a filter id. | 
					
						
							|  |  |  | func (self *Whisper) Messages(id int) []WhisperMessage { | 
					
						
							|  |  |  | 	pool := self.Whisper.Messages(id) | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	messages := make([]WhisperMessage, len(pool)) | 
					
						
							|  |  |  | 	for i, message := range pool { | 
					
						
							|  |  |  | 		messages[i] = NewWhisperMessage(message) | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-04-17 16:45:44 +03:00
										 |  |  | 	return messages | 
					
						
							| 
									
										
										
										
											2015-01-30 13:25:12 +01:00
										 |  |  | } |