diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/filter.go | 1 | ||||
-rw-r--r-- | ui/frontend.go | 18 | ||||
-rw-r--r-- | ui/qt/filter.go | 1 | ||||
-rw-r--r-- | ui/qt/qwhisper/message.go | 23 | ||||
-rw-r--r-- | ui/qt/qwhisper/watch.go | 13 | ||||
-rw-r--r-- | ui/qt/qwhisper/whisper.go | 121 | ||||
-rw-r--r-- | ui/qt/qwhisper/whisper_test.go | 15 | ||||
-rw-r--r-- | ui/qt/webengine/all.cpp | 1 | ||||
-rw-r--r-- | ui/qt/webengine/cpp/webengine.cpp | 6 | ||||
-rw-r--r-- | ui/qt/webengine/cpp/webengine.h | 14 | ||||
-rw-r--r-- | ui/qt/webengine/webengine.go | 18 |
11 files changed, 231 insertions, 0 deletions
diff --git a/ui/filter.go b/ui/filter.go new file mode 100644 index 000000000..5b1faa293 --- /dev/null +++ b/ui/filter.go @@ -0,0 +1 @@ +package ui diff --git a/ui/frontend.go b/ui/frontend.go new file mode 100644 index 000000000..22dc64fdf --- /dev/null +++ b/ui/frontend.go @@ -0,0 +1,18 @@ +package ui + +// ReturnInterface is returned by the Intercom interface when a method is called +type ReturnInterface interface { + Get(i int) (interface{}, error) + Size() int +} + +// Frontend is the basic interface for calling arbitrary methods on something that +// implements a front end (GUI, CLI, etc) +type Frontend interface { + // Checks whether a specific method is implemented + Supports(method string) bool + // Call calls the given method on interface it implements. This will return + // an error with errNotImplemented if the method hasn't been implemented + // and will return a ReturnInterface if it does. + Call(method string) (ReturnInterface, error) +} diff --git a/ui/qt/filter.go b/ui/qt/filter.go new file mode 100644 index 000000000..090260e4e --- /dev/null +++ b/ui/qt/filter.go @@ -0,0 +1 @@ +package qt diff --git a/ui/qt/qwhisper/message.go b/ui/qt/qwhisper/message.go new file mode 100644 index 000000000..26e72ac93 --- /dev/null +++ b/ui/qt/qwhisper/message.go @@ -0,0 +1,23 @@ +package qwhisper + +import ( + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/whisper" +) + +type Message struct { + ref *whisper.Message + Flags int32 `json:"flags"` + Payload string `json:"payload"` + From string `json:"from"` +} + +func ToQMessage(msg *whisper.Message) *Message { + return &Message{ + ref: msg, + Flags: int32(msg.Flags), + Payload: "0x" + ethutil.Bytes2Hex(msg.Payload), + From: "0x" + ethutil.Bytes2Hex(crypto.FromECDSAPub(msg.Recover())), + } +} diff --git a/ui/qt/qwhisper/watch.go b/ui/qt/qwhisper/watch.go new file mode 100644 index 000000000..0ccedc719 --- /dev/null +++ b/ui/qt/qwhisper/watch.go @@ -0,0 +1,13 @@ +package qwhisper + +import ( + "fmt" + "unsafe" +) + +type Watch struct { +} + +func (self *Watch) Arrived(v unsafe.Pointer) { + fmt.Println(v) +} diff --git a/ui/qt/qwhisper/whisper.go b/ui/qt/qwhisper/whisper.go new file mode 100644 index 000000000..2bc455b0b --- /dev/null +++ b/ui/qt/qwhisper/whisper.go @@ -0,0 +1,121 @@ +// QWhisper package. This package is temporarily on hold until QML DApp dev will reemerge. +package qwhisper + +import ( + "time" + + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/whisper" + "github.com/obscuren/qml" +) + +var qlogger = logger.NewLogger("QSHH") + +func fromHex(s string) []byte { + if len(s) > 1 { + return ethutil.Hex2Bytes(s[2:]) + } + return nil +} +func toHex(b []byte) string { return "0x" + ethutil.Bytes2Hex(b) } + +type Whisper struct { + *whisper.Whisper + view qml.Object + + watches map[int]*Watch +} + +func New(w *whisper.Whisper) *Whisper { + return &Whisper{w, nil, make(map[int]*Watch)} +} + +func (self *Whisper) SetView(view qml.Object) { + self.view = view +} + +func (self *Whisper) Post(payload []string, to, from string, topics []string, priority, ttl uint32) { + var data []byte + for _, d := range payload { + data = append(data, fromHex(d)...) + } + + pk := crypto.ToECDSAPub(fromHex(from)) + if key := self.Whisper.GetIdentity(pk); key != nil { + msg := whisper.NewMessage(data) + envelope, err := msg.Seal(time.Duration(priority*100000), whisper.Opts{ + Ttl: time.Duration(ttl) * time.Second, + To: crypto.ToECDSAPub(fromHex(to)), + From: key, + Topics: whisper.TopicsFromString(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 (self *Whisper) NewIdentity() string { + key := self.Whisper.NewIdentity() + + return toHex(crypto.FromECDSAPub(&key.PublicKey)) +} + +func (self *Whisper) HasIdentity(key string) bool { + return self.Whisper.HasIdentity(crypto.ToECDSAPub(fromHex(key))) +} + +func (self *Whisper) Watch(opts map[string]interface{}, view *qml.Common) int { + filter := filterFromMap(opts) + var i int + filter.Fn = func(msg *whisper.Message) { + if view != nil { + view.Call("onShhMessage", ToQMessage(msg), i) + } + } + + i = self.Whisper.Watch(filter) + self.watches[i] = &Watch{} + + return i +} + +func (self *Whisper) Messages(id int) (messages *ethutil.List) { + msgs := self.Whisper.Messages(id) + messages = ethutil.EmptyList() + for _, message := range msgs { + messages.Append(ToQMessage(message)) + } + + return +} + +func filterFromMap(opts map[string]interface{}) (f whisper.Filter) { + if to, ok := opts["to"].(string); ok { + f.To = crypto.ToECDSAPub(fromHex(to)) + } + if from, ok := opts["from"].(string); ok { + f.From = crypto.ToECDSAPub(fromHex(from)) + } + if topicList, ok := opts["topics"].(*qml.List); ok { + var topics []string + topicList.Convert(&topics) + f.Topics = whisper.TopicsFromString(topics...) + } + + return +} diff --git a/ui/qt/qwhisper/whisper_test.go b/ui/qt/qwhisper/whisper_test.go new file mode 100644 index 000000000..efa4e6238 --- /dev/null +++ b/ui/qt/qwhisper/whisper_test.go @@ -0,0 +1,15 @@ +package qwhisper + +import ( + "testing" + + "github.com/ethereum/go-ethereum/whisper" +) + +func TestHasIdentity(t *testing.T) { + qw := New(whisper.New()) + id := qw.NewIdentity() + if !qw.HasIdentity(id) { + t.Error("expected to have identity") + } +} diff --git a/ui/qt/webengine/all.cpp b/ui/qt/webengine/all.cpp new file mode 100644 index 000000000..3b7c2f7b8 --- /dev/null +++ b/ui/qt/webengine/all.cpp @@ -0,0 +1 @@ +#include "cpp/webengine.cpp" diff --git a/ui/qt/webengine/cpp/webengine.cpp b/ui/qt/webengine/cpp/webengine.cpp new file mode 100644 index 000000000..118b451ef --- /dev/null +++ b/ui/qt/webengine/cpp/webengine.cpp @@ -0,0 +1,6 @@ +#include <QtWebEngine> +#include "webengine.h" + +void webengineInitialize() { + QtWebEngine::initialize(); +} diff --git a/ui/qt/webengine/cpp/webengine.h b/ui/qt/webengine/cpp/webengine.h new file mode 100644 index 000000000..9c3b13bfa --- /dev/null +++ b/ui/qt/webengine/cpp/webengine.h @@ -0,0 +1,14 @@ +#ifndef WEBENGINE_H +#define WEBENGINE_H + +#ifdef __cplusplus +extern "C" { +#endif + +void webengineInitialize(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // WEBENGINE_H diff --git a/ui/qt/webengine/webengine.go b/ui/qt/webengine/webengine.go new file mode 100644 index 000000000..600dbb6cb --- /dev/null +++ b/ui/qt/webengine/webengine.go @@ -0,0 +1,18 @@ +package webengine + +// #cgo CPPFLAGS: -I./ +// #cgo CXXFLAGS: -std=c++0x -pedantic-errors -Wall -fno-strict-aliasing +// #cgo LDFLAGS: -lstdc++ +// #cgo pkg-config: Qt5WebEngine +// +// #include "cpp/webengine.h" +import "C" + +import "github.com/obscuren/qml" + +// Initializes the WebEngine extension. +func Initialize() { + qml.RunMain(func() { + C.webengineInitialize() + }) +} |