Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
d1a6084bf7 | |||
a9b857769d | |||
e100aa3c6c | |||
5053ec2190 | |||
6db40ecb22 | |||
41ae6f298e | |||
bd95fd770b | |||
2b8eae9810 | |||
b2dc19155f | |||
7a5b279459 | |||
cf999c4622 | |||
dc944f7518 | |||
d5d1e50365 | |||
29f5dd38e3 |
@ -7,7 +7,7 @@ Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ether
|
|||||||
|
|
||||||
Ethereum Go Client © 2014 Jeffrey Wilcke.
|
Ethereum Go Client © 2014 Jeffrey Wilcke.
|
||||||
|
|
||||||
Current state: Proof of Concept 0.6.6.
|
Current state: Proof of Concept 0.6.7.
|
||||||
|
|
||||||
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).
|
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).
|
||||||
|
|
||||||
|
@ -10,36 +10,41 @@ import (
|
|||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Identifier string
|
var (
|
||||||
var KeyRing string
|
Identifier string
|
||||||
var DiffTool bool
|
KeyRing string
|
||||||
var DiffType string
|
DiffTool bool
|
||||||
var KeyStore string
|
DiffType string
|
||||||
var StartRpc bool
|
KeyStore string
|
||||||
var RpcPort int
|
StartRpc bool
|
||||||
var UseUPnP bool
|
StartWebSockets bool
|
||||||
var OutboundPort string
|
RpcPort int
|
||||||
var ShowGenesis bool
|
UseUPnP bool
|
||||||
var AddPeer string
|
OutboundPort string
|
||||||
var MaxPeer int
|
ShowGenesis bool
|
||||||
var GenAddr bool
|
AddPeer string
|
||||||
var UseSeed bool
|
MaxPeer int
|
||||||
var SecretFile string
|
GenAddr bool
|
||||||
var ExportDir string
|
UseSeed bool
|
||||||
var NonInteractive bool
|
SecretFile string
|
||||||
var Datadir string
|
ExportDir string
|
||||||
var LogFile string
|
NonInteractive bool
|
||||||
var ConfigFile string
|
Datadir string
|
||||||
var DebugFile string
|
LogFile string
|
||||||
var LogLevel int
|
ConfigFile string
|
||||||
var Dump bool
|
DebugFile string
|
||||||
var DumpHash string
|
LogLevel int
|
||||||
var DumpNumber int
|
Dump bool
|
||||||
|
DumpHash string
|
||||||
|
DumpNumber int
|
||||||
|
)
|
||||||
|
|
||||||
// flags specific to cli client
|
// flags specific to cli client
|
||||||
var StartMining bool
|
var (
|
||||||
var StartJsConsole bool
|
StartMining bool
|
||||||
var InputFile string
|
StartJsConsole bool
|
||||||
|
InputFile string
|
||||||
|
)
|
||||||
|
|
||||||
func defaultDataDir() string {
|
func defaultDataDir() string {
|
||||||
usr, _ := user.Current()
|
usr, _ := user.Current()
|
||||||
@ -62,6 +67,7 @@ func Init() {
|
|||||||
flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
|
flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers")
|
||||||
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
|
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
|
||||||
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
|
flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
|
||||||
|
flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server")
|
||||||
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
|
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
|
||||||
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
|
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
|
||||||
flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
|
flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ClientIdentifier = "Ethereum(G)"
|
ClientIdentifier = "Ethereum(G)"
|
||||||
Version = "0.6.6"
|
Version = "0.6.7"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger = ethlog.NewLogger("CLI")
|
var logger = ethlog.NewLogger("CLI")
|
||||||
@ -103,6 +103,10 @@ func main() {
|
|||||||
utils.StartRpc(ethereum, RpcPort)
|
utils.StartRpc(ethereum, RpcPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if StartWebSockets {
|
||||||
|
utils.StartWebSockets(ethereum)
|
||||||
|
}
|
||||||
|
|
||||||
utils.StartEthereum(ethereum, UseSeed)
|
utils.StartEthereum(ethereum, UseSeed)
|
||||||
|
|
||||||
// this blocks the thread
|
// this blocks the thread
|
||||||
|
@ -357,7 +357,7 @@ ApplicationWindow {
|
|||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement { text: "Snippets" ; value: "" }
|
ListElement { text: "Snippets" ; value: "" }
|
||||||
ListElement { text: "Call Contract" ; value: "var[2] in;\nvar ret;\n\nin[0] = \"arg1\"\nin[1] = 0xdeadbeef\n\nvar success = call(0x0c542ddea93dae0c2fcb2cf175f03ad80d6be9a0, 0, 7000, in, ret)\n\nreturn ret" }
|
ListElement { text: "Call Contract" ; value: "var[2] in = { \"arg1\", 0xdeadbeef };\nvar ret;\n\nvar success = call(0x0c542ddea93dae0c2fcb2cf175f03ad80d6be9a0, 0, 7000, in, ret)\n\nreturn ret" }
|
||||||
}
|
}
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
if(currentIndex != 0) {
|
if(currentIndex != 0) {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
// The magic return variable. The magic return variable will be set during the execution of the QML call.
|
// The magic return variable. The magic return variable will be set during the execution of the QML call.
|
||||||
(function(window) {
|
(function(window) {
|
||||||
function message(type, data) {
|
var Promise = window.Promise;
|
||||||
document.title = JSON.stringify({type: type, data: data});
|
if(typeof(Promise) === "undefined") {
|
||||||
|
var Promise = Q.Promise;
|
||||||
return window.____returnData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPromise(o) {
|
function isPromise(o) {
|
||||||
@ -92,19 +91,19 @@
|
|||||||
promises.push(params.from.then(function(_from) { params.from = _from; }));
|
promises.push(params.from.then(function(_from) { params.from = _from; }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isPromise(params.data)) {
|
if(typeof params.data !== "object" || isPromise(params.data)) {
|
||||||
promises.push(params.data.then(function(_code) { params.data = _code; }));
|
params.data = [params.data]
|
||||||
} else {
|
}
|
||||||
if(typeof params.data === "object") {
|
|
||||||
data = "";
|
|
||||||
for(var i = 0; i < params.data.length; i++) {
|
|
||||||
data += params.data[i]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data = params.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var data = params.data;
|
||||||
|
for(var i = 0; i < params.data.length; i++) {
|
||||||
|
if(isPromise(params.data[i])) {
|
||||||
|
var promise = params.data[i];
|
||||||
|
var _i = i;
|
||||||
|
promises.push(promise.then(function(_arg) { params.data[_i] = _arg; }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure everything is string
|
// Make sure everything is string
|
||||||
var fields = ["value", "gas", "gasPrice"];
|
var fields = ["value", "gas", "gasPrice"];
|
||||||
for(var i = 0; i < fields.length; i++) {
|
for(var i = 0; i < fields.length; i++) {
|
||||||
@ -117,6 +116,7 @@
|
|||||||
// Load promises then call the last "transact".
|
// Load promises then call the last "transact".
|
||||||
return Q.all(promises).then(function() {
|
return Q.all(promises).then(function() {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
params.data = params.data.join("");
|
||||||
postData({call: "transact", args: params}, function(data) {
|
postData({call: "transact", args: params}, function(data) {
|
||||||
if(data[1])
|
if(data[1])
|
||||||
reject(data[0]);
|
reject(data[0]);
|
||||||
@ -445,6 +445,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
var g_seed = 1;
|
var g_seed = 1;
|
||||||
function postData(data, cb) {
|
function postData(data, cb) {
|
||||||
data._seed = g_seed;
|
data._seed = g_seed;
|
||||||
@ -458,24 +459,6 @@
|
|||||||
|
|
||||||
g_seed++;
|
g_seed++;
|
||||||
|
|
||||||
navigator.qt.postMessage(JSON.stringify(data));
|
window._messagingAdapter.call(this, JSON.stringify(data))
|
||||||
}
|
|
||||||
|
|
||||||
navigator.qt.onmessage = function(ev) {
|
|
||||||
var data = JSON.parse(ev.data)
|
|
||||||
|
|
||||||
if(data._event !== undefined) {
|
|
||||||
eth.trigger(data._event, data.data);
|
|
||||||
} else {
|
|
||||||
if(data._seed) {
|
|
||||||
var cb = eth._callbacks[data._seed];
|
|
||||||
if(cb) {
|
|
||||||
cb.call(this, data.data)
|
|
||||||
|
|
||||||
// Remove the "trigger" callback
|
|
||||||
delete eth._callbacks[ev._seed];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})(this);
|
})(this);
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
if(typeof(Promise) === "undefined") {
|
|
||||||
window.Promise = Q.Promise;
|
|
||||||
}
|
|
21
mist/assets/ext/qt_messaging_adapter.js
Normal file
21
mist/assets/ext/qt_messaging_adapter.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
window._messagingAdapter = function(data) {
|
||||||
|
navigator.qt.postMessage(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
navigator.qt.onmessage = function(ev) {
|
||||||
|
var data = JSON.parse(ev.data)
|
||||||
|
|
||||||
|
if(data._event !== undefined) {
|
||||||
|
eth.trigger(data._event, data.data);
|
||||||
|
} else {
|
||||||
|
if(data._seed) {
|
||||||
|
var cb = eth._callbacks[data._seed];
|
||||||
|
if(cb) {
|
||||||
|
cb.call(this, data.data)
|
||||||
|
|
||||||
|
// Remove the "trigger" callback
|
||||||
|
delete eth._callbacks[ev._seed];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
911
mist/assets/qml/main.qml
Normal file
911
mist/assets/qml/main.qml
Normal file
@ -0,0 +1,911 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 1.0;
|
||||||
|
import QtQuick.Layouts 1.0;
|
||||||
|
import QtQuick.Dialogs 1.0;
|
||||||
|
import QtQuick.Window 2.1;
|
||||||
|
import QtQuick.Controls.Styles 1.1
|
||||||
|
import Ethereum 1.0
|
||||||
|
|
||||||
|
import "../ext/filter.js" as Eth
|
||||||
|
import "../ext/http.js" as Http
|
||||||
|
|
||||||
|
ApplicationWindow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias miningButtonText: miningButton.text
|
||||||
|
property var ethx : Eth.ethx
|
||||||
|
property var browser
|
||||||
|
|
||||||
|
width: 1200
|
||||||
|
height: 820
|
||||||
|
minimumHeight: 300
|
||||||
|
|
||||||
|
title: "Mist"
|
||||||
|
|
||||||
|
// This signal is used by the filter API. The filter API connects using this signal handler from
|
||||||
|
// the different QML files and plugins.
|
||||||
|
signal messages(var messages, int id);
|
||||||
|
function invokeFilterCallback(data, receiverSeed) {
|
||||||
|
//var messages = JSON.parse(data)
|
||||||
|
// Signal handler
|
||||||
|
messages(data, receiverSeed);
|
||||||
|
root.browser.view.messages(data, receiverSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: copyElementHax
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToClipboard(text) {
|
||||||
|
copyElementHax.text = text
|
||||||
|
copyElementHax.selectAll()
|
||||||
|
copyElementHax.copy()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Takes care of loading all default plugins
|
||||||
|
Component.onCompleted: {
|
||||||
|
var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true});
|
||||||
|
var browser = addPlugin("./webapp.qml", {noAdd: true, close: false, section: "ethereum", active: true});
|
||||||
|
root.browser = browser;
|
||||||
|
|
||||||
|
addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"});
|
||||||
|
addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"});
|
||||||
|
addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"});
|
||||||
|
addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"});
|
||||||
|
addPlugin("./views/javascript.qml", {noAdd: true, close: false, section: "legacy"});
|
||||||
|
|
||||||
|
addPlugin("./views/jeffcoin/jeffcoin.qml", {noAdd: true, close: false, section: "apps"})
|
||||||
|
|
||||||
|
mainSplit.setView(wallet.view, wallet.menuItem);
|
||||||
|
|
||||||
|
// Call the ready handler
|
||||||
|
gui.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addViews(view, path, options) {
|
||||||
|
var views = mainSplit.addComponent(view, options)
|
||||||
|
views.menuItem.path = path
|
||||||
|
|
||||||
|
mainSplit.views.push(views);
|
||||||
|
|
||||||
|
if(!options.noAdd) {
|
||||||
|
gui.addPlugin(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
return views
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPlugin(path, options) {
|
||||||
|
try {
|
||||||
|
if(typeof(path) === "string" && /^https?/.test(path)) {
|
||||||
|
console.log('load http')
|
||||||
|
Http.request(path, function(o) {
|
||||||
|
if(o.status === 200) {
|
||||||
|
var view = Qt.createQmlObject(o.responseText, mainView, path)
|
||||||
|
addViews(view, path, options)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var component = Qt.createComponent(path);
|
||||||
|
if(component.status != Component.Ready) {
|
||||||
|
if(component.status == Component.Error) {
|
||||||
|
ethx.note("error: ", component.errorString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var view = mainView.createView(component, options)
|
||||||
|
var views = addViews(view, path, options)
|
||||||
|
|
||||||
|
return views
|
||||||
|
} catch(e) {
|
||||||
|
ethx.note(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
menuBar: MenuBar {
|
||||||
|
Menu {
|
||||||
|
title: "File"
|
||||||
|
MenuItem {
|
||||||
|
text: "Import App"
|
||||||
|
shortcut: "Ctrl+o"
|
||||||
|
onTriggered: {
|
||||||
|
generalFileDialog.show(true, importApp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
MenuItem {
|
||||||
|
text: "Browser"
|
||||||
|
onTriggered: eth.openBrowser()
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Add plugin"
|
||||||
|
onTriggered: {
|
||||||
|
generalFileDialog.show(true, function(path) {
|
||||||
|
addPlugin(path, {close: true, section: "apps"})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuSeparator {}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Import key"
|
||||||
|
shortcut: "Ctrl+i"
|
||||||
|
onTriggered: {
|
||||||
|
generalFileDialog.show(true, function(path) {
|
||||||
|
gui.importKey(path)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Export keys"
|
||||||
|
shortcut: "Ctrl+e"
|
||||||
|
onTriggered: {
|
||||||
|
generalFileDialog.show(false, function(path) {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
title: "Developer"
|
||||||
|
MenuItem {
|
||||||
|
iconSource: "../icecream.png"
|
||||||
|
text: "Debugger"
|
||||||
|
shortcut: "Ctrl+d"
|
||||||
|
onTriggered: eth.startDebugger()
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Import Tx"
|
||||||
|
onTriggered: {
|
||||||
|
txImportDialog.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Run JS file"
|
||||||
|
onTriggered: {
|
||||||
|
generalFileDialog.show(true, function(path) {
|
||||||
|
eth.evalJavascriptFile(path)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Dump state"
|
||||||
|
onTriggered: {
|
||||||
|
generalFileDialog.show(false, function(path) {
|
||||||
|
// Empty hash for latest
|
||||||
|
gui.dumpState("", path)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuSeparator {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
MenuItem {
|
||||||
|
id: miningSpeed
|
||||||
|
text: "Mining: Turbo"
|
||||||
|
onTriggered: {
|
||||||
|
gui.toggleTurboMining()
|
||||||
|
if(text == "Mining: Turbo") {
|
||||||
|
text = "Mining: Normal";
|
||||||
|
} else {
|
||||||
|
text = "Mining: Turbo";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
title: "Network"
|
||||||
|
MenuItem {
|
||||||
|
text: "Add Peer"
|
||||||
|
shortcut: "Ctrl+p"
|
||||||
|
onTriggered: {
|
||||||
|
addPeerWin.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: "Show Peers"
|
||||||
|
shortcut: "Ctrl+e"
|
||||||
|
onTriggered: {
|
||||||
|
peerWindow.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
title: "Help"
|
||||||
|
MenuItem {
|
||||||
|
text: "About"
|
||||||
|
onTriggered: {
|
||||||
|
aboutWin.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
title: "GLOBAL SHORTCUTS"
|
||||||
|
visible: false
|
||||||
|
MenuItem {
|
||||||
|
visible: false
|
||||||
|
shortcut: "Ctrl+l"
|
||||||
|
onTriggered: {
|
||||||
|
url.focus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
statusBar: StatusBar {
|
||||||
|
height: 32
|
||||||
|
id: statusBar
|
||||||
|
RowLayout {
|
||||||
|
Button {
|
||||||
|
id: miningButton
|
||||||
|
text: "Start Mining"
|
||||||
|
onClicked: {
|
||||||
|
gui.toggleMining()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Label {
|
||||||
|
id: walletValueLabel
|
||||||
|
|
||||||
|
font.pixelSize: 10
|
||||||
|
styleColor: "#797979"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
y: 6
|
||||||
|
objectName: "miningLabel"
|
||||||
|
visible: true
|
||||||
|
font.pixelSize: 10
|
||||||
|
anchors.right: lastBlockLabel.left
|
||||||
|
anchors.rightMargin: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
y: 6
|
||||||
|
id: lastBlockLabel
|
||||||
|
objectName: "lastBlockLabel"
|
||||||
|
visible: true
|
||||||
|
text: ""
|
||||||
|
font.pixelSize: 10
|
||||||
|
anchors.right: peerGroup.left
|
||||||
|
anchors.rightMargin: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressBar {
|
||||||
|
id: downloadIndicator
|
||||||
|
value: 0
|
||||||
|
objectName: "downloadIndicator"
|
||||||
|
y: 3
|
||||||
|
x: statusBar.width / 2 - this.width / 2
|
||||||
|
width: 160
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
objectName: "downloadLabel"
|
||||||
|
y: 7
|
||||||
|
anchors.left: downloadIndicator.right
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
font.pixelSize: 10
|
||||||
|
text: "0 / 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: peerGroup
|
||||||
|
y: 7
|
||||||
|
anchors.right: parent.right
|
||||||
|
MouseArea {
|
||||||
|
onDoubleClicked: peerWindow.visible = true
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: peerLabel
|
||||||
|
font.pixelSize: 8
|
||||||
|
text: "0 / 0"
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
id: peerImage
|
||||||
|
width: 10; height: 10
|
||||||
|
source: "../network.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
property var blockModel: ListModel {
|
||||||
|
id: blockModel
|
||||||
|
}
|
||||||
|
|
||||||
|
SplitView {
|
||||||
|
property var views: [];
|
||||||
|
|
||||||
|
id: mainSplit
|
||||||
|
anchors.fill: parent
|
||||||
|
resizing: false
|
||||||
|
|
||||||
|
function setView(view, menu) {
|
||||||
|
for(var i = 0; i < views.length; i++) {
|
||||||
|
views[i].view.visible = false
|
||||||
|
views[i].menuItem.setSelection(false)
|
||||||
|
}
|
||||||
|
view.visible = true
|
||||||
|
|
||||||
|
//menu.border.color = "#CCCCCC"
|
||||||
|
//menu.color = "#FFFFFFFF"
|
||||||
|
menu.setSelection(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function addComponent(view, options) {
|
||||||
|
view.visible = false
|
||||||
|
view.anchors.fill = mainView
|
||||||
|
|
||||||
|
if( !view.hasOwnProperty("iconSource") ) {
|
||||||
|
console.log("Could not load plugin. Property 'iconSourc' not found on view.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var menuItem = menu.createMenuItem(view.iconSource, view, options);
|
||||||
|
if( view.hasOwnProperty("menuItem") ) {
|
||||||
|
view.menuItem = menuItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( view.hasOwnProperty("onReady") ) {
|
||||||
|
view.onReady.call(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
if( options.active ) {
|
||||||
|
setView(view, menuItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {view: view, menuItem: menuItem}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* Main menu.
|
||||||
|
********************/
|
||||||
|
Rectangle {
|
||||||
|
id: menu
|
||||||
|
Layout.minimumWidth: 210
|
||||||
|
Layout.maximumWidth: 210
|
||||||
|
anchors.top: parent.top
|
||||||
|
color: "#ececec"
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: menuItemTemplate
|
||||||
|
Rectangle {
|
||||||
|
id: menuItem
|
||||||
|
property var view;
|
||||||
|
property var path;
|
||||||
|
property var closable;
|
||||||
|
|
||||||
|
property alias title: label.text
|
||||||
|
property alias icon: icon.source
|
||||||
|
property alias secondaryTitle: secondary.text
|
||||||
|
function setSelection(on) {
|
||||||
|
sel.visible = on
|
||||||
|
}
|
||||||
|
|
||||||
|
width: 206
|
||||||
|
height: 28
|
||||||
|
color: "#00000000"
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 4
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: sel
|
||||||
|
visible: false
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#00000000"
|
||||||
|
Rectangle {
|
||||||
|
id: r
|
||||||
|
anchors.fill: parent
|
||||||
|
border.color: "#CCCCCC"
|
||||||
|
border.width: 1
|
||||||
|
radius: 5
|
||||||
|
color: "#FFFFFFFF"
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
top: r.top
|
||||||
|
bottom: r.bottom
|
||||||
|
right: r.right
|
||||||
|
}
|
||||||
|
width: 10
|
||||||
|
color: "#FFFFFFFF"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
height: 1
|
||||||
|
color: "#CCCCCC"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
}
|
||||||
|
height: 1
|
||||||
|
color: "#CCCCCC"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
mainSplit.setView(view, menuItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: icon
|
||||||
|
height: 20
|
||||||
|
width: 20
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
leftMargin: 3
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
menuItem.closeApp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: label
|
||||||
|
anchors {
|
||||||
|
left: icon.right
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
leftMargin: 3
|
||||||
|
}
|
||||||
|
|
||||||
|
color: "#0D0A01"
|
||||||
|
font.pixelSize: 12
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: secondary
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
rightMargin: 8
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
color: "#AEADBE"
|
||||||
|
font.pixelSize: 12
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function closeApp() {
|
||||||
|
if(!this.closable) { return; }
|
||||||
|
|
||||||
|
if(this.view.hasOwnProperty("onDestroy")) {
|
||||||
|
this.view.onDestroy.call(this.view)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.view.destroy()
|
||||||
|
this.destroy()
|
||||||
|
gui.removePlugin(this.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMenuItem(icon, view, options) {
|
||||||
|
if(options === undefined) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
var section;
|
||||||
|
switch(options.section) {
|
||||||
|
case "ethereum":
|
||||||
|
section = menuDefault;
|
||||||
|
break;
|
||||||
|
case "legacy":
|
||||||
|
section = menuLegacy;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
section = menuApps;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var comp = menuItemTemplate.createObject(section)
|
||||||
|
|
||||||
|
comp.view = view
|
||||||
|
comp.title = view.title
|
||||||
|
comp.icon = view.iconSource
|
||||||
|
comp.closable = options.close;
|
||||||
|
|
||||||
|
return comp
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: menuColumn
|
||||||
|
y: 10
|
||||||
|
width: parent.width
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: 3
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "ETHEREUM"
|
||||||
|
font.bold: true
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 5
|
||||||
|
}
|
||||||
|
color: "#888888"
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: menuDefault
|
||||||
|
spacing: 3
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "APPS"
|
||||||
|
font.bold: true
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 5
|
||||||
|
}
|
||||||
|
color: "#888888"
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: menuApps
|
||||||
|
spacing: 3
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "DEBUG"
|
||||||
|
font.bold: true
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
leftMargin: 5
|
||||||
|
}
|
||||||
|
color: "#888888"
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: menuLegacy
|
||||||
|
spacing: 3
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************
|
||||||
|
* Main view
|
||||||
|
********************/
|
||||||
|
Rectangle {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.left: menu.right
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.top: parent.top
|
||||||
|
color: "#00000000"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: urlPane
|
||||||
|
height: 40
|
||||||
|
color: "#00000000"
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
leftMargin: 5
|
||||||
|
rightMargin: 5
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 5
|
||||||
|
}
|
||||||
|
TextField {
|
||||||
|
id: url
|
||||||
|
objectName: "url"
|
||||||
|
placeholderText: "DApp URL"
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
topMargin: 5
|
||||||
|
rightMargin: 5
|
||||||
|
leftMargin: 5
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if(/^https?/.test(this.text)) {
|
||||||
|
root.browser.view.open(this.text);
|
||||||
|
mainSplit.setView(root.browser.view, root.browser.menuItem);
|
||||||
|
} else {
|
||||||
|
addPlugin(this.text, {close: true, section: "apps"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Border
|
||||||
|
Rectangle {
|
||||||
|
id: divider
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
top: urlPane.bottom
|
||||||
|
}
|
||||||
|
z: -1
|
||||||
|
height: 1
|
||||||
|
color: "#CCCCCC"
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: mainView
|
||||||
|
color: "#00000000"
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.top: divider.bottom
|
||||||
|
|
||||||
|
function createView(component) {
|
||||||
|
var view = component.createObject(mainView)
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* Dialogs
|
||||||
|
*****************/
|
||||||
|
FileDialog {
|
||||||
|
id: generalFileDialog
|
||||||
|
property var callback;
|
||||||
|
onAccepted: {
|
||||||
|
var path = this.fileUrl.toString();
|
||||||
|
callback.call(this, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(selectExisting, callback) {
|
||||||
|
generalFileDialog.callback = callback;
|
||||||
|
generalFileDialog.selectExisting = selectExisting;
|
||||||
|
|
||||||
|
this.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************
|
||||||
|
* Wallet functions
|
||||||
|
*****************/
|
||||||
|
function importApp(path) {
|
||||||
|
var ext = path.split('.').pop()
|
||||||
|
if(ext == "html" || ext == "htm") {
|
||||||
|
eth.openHtml(path)
|
||||||
|
}else if(ext == "qml"){
|
||||||
|
addPlugin(path, {close: true, section: "apps"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function setWalletValue(value) {
|
||||||
|
walletValueLabel.text = value
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadPlugin(name) {
|
||||||
|
console.log("Loading plugin" + name)
|
||||||
|
var view = mainView.addPlugin(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPeers(text) {
|
||||||
|
peerLabel.text = text
|
||||||
|
}
|
||||||
|
|
||||||
|
function addPeer(peer) {
|
||||||
|
// We could just append the whole peer object but it cries if you try to alter them
|
||||||
|
peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version, caps: peer.caps})
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetPeers(){
|
||||||
|
peerModel.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
function timeAgo(unixTs){
|
||||||
|
var lapsed = (Date.now() - new Date(unixTs*1000)) / 1000
|
||||||
|
return (lapsed + " seconds ago")
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertToPretty(unixTs){
|
||||||
|
var a = new Date(unixTs*1000);
|
||||||
|
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
||||||
|
var year = a.getFullYear();
|
||||||
|
var month = months[a.getMonth()];
|
||||||
|
var date = a.getDate();
|
||||||
|
var hour = a.getHours();
|
||||||
|
var min = a.getMinutes();
|
||||||
|
var sec = a.getSeconds();
|
||||||
|
var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ;
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************
|
||||||
|
* Windows
|
||||||
|
*********************/
|
||||||
|
Window {
|
||||||
|
id: peerWindow
|
||||||
|
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
|
||||||
|
height: 200
|
||||||
|
width: 700
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
property var peerModel: ListModel {
|
||||||
|
id: peerModel
|
||||||
|
}
|
||||||
|
TableView {
|
||||||
|
anchors.fill: parent
|
||||||
|
id: peerTable
|
||||||
|
model: peerModel
|
||||||
|
TableViewColumn{width: 100; role: "ip" ; title: "IP" }
|
||||||
|
TableViewColumn{width: 60; role: "port" ; title: "Port" }
|
||||||
|
TableViewColumn{width: 140; role: "lastResponse"; title: "Last event" }
|
||||||
|
TableViewColumn{width: 100; role: "latency"; title: "Latency" }
|
||||||
|
TableViewColumn{width: 260; role: "version" ; title: "Version" }
|
||||||
|
TableViewColumn{width: 80; role: "caps" ; title: "Capabilities" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: aboutWin
|
||||||
|
visible: false
|
||||||
|
title: "About"
|
||||||
|
minimumWidth: 350
|
||||||
|
maximumWidth: 350
|
||||||
|
maximumHeight: 200
|
||||||
|
minimumHeight: 200
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: aboutIcon
|
||||||
|
height: 150
|
||||||
|
width: 150
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
smooth: true
|
||||||
|
source: "../facet.png"
|
||||||
|
x: 10
|
||||||
|
y: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
anchors.left: aboutIcon.right
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.topMargin: 30
|
||||||
|
font.pointSize: 12
|
||||||
|
text: "<h2>Mist (0.6.5)</h2><h4>Amalthea</h4><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br><h3>Building</h3>Maran Hidskes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: txImportDialog
|
||||||
|
minimumWidth: 270
|
||||||
|
maximumWidth: 270
|
||||||
|
maximumHeight: 50
|
||||||
|
minimumHeight: 50
|
||||||
|
TextField {
|
||||||
|
id: txImportField
|
||||||
|
width: 170
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
onAccepted: {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
anchors.left: txImportField.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.leftMargin: 5
|
||||||
|
text: "Import"
|
||||||
|
onClicked: {
|
||||||
|
eth.importTx(txImportField.text)
|
||||||
|
txImportField.visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
addrField.focus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window {
|
||||||
|
id: addPeerWin
|
||||||
|
visible: false
|
||||||
|
minimumWidth: 300
|
||||||
|
maximumWidth: 300
|
||||||
|
maximumHeight: 50
|
||||||
|
minimumHeight: 50
|
||||||
|
title: "Connect to peer"
|
||||||
|
|
||||||
|
ComboBox {
|
||||||
|
id: addrField
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: addPeerButton.left
|
||||||
|
anchors.leftMargin: 10
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
onAccepted: {
|
||||||
|
eth.connectToPeer(addrField.currentText)
|
||||||
|
addPeerWin.visible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
editable: true
|
||||||
|
model: ListModel { id: pastPeers }
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
var ips = eth.pastPeers()
|
||||||
|
for(var i = 0; i < ips.length; i++) {
|
||||||
|
pastPeers.append({text: ips.get(i)})
|
||||||
|
}
|
||||||
|
|
||||||
|
pastPeers.insert(0, {text: "poc-6.ethdev.com:30303"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: addPeerButton
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.rightMargin: 10
|
||||||
|
text: "Add"
|
||||||
|
onClicked: {
|
||||||
|
eth.connectToPeer(addrField.currentText)
|
||||||
|
addPeerWin.visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component.onCompleted: {
|
||||||
|
addrField.focus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -121,6 +121,23 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TableView {
|
||||||
|
id: logView
|
||||||
|
headerVisible: false
|
||||||
|
anchors {
|
||||||
|
right: logLevelSlider.left
|
||||||
|
left: parent.left
|
||||||
|
bottom: parent.bottom
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
|
||||||
|
TableViewColumn{ role: "description" ; title: "log" }
|
||||||
|
|
||||||
|
model: logModel
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
Slider {
|
Slider {
|
||||||
id: logLevelSlider
|
id: logLevelSlider
|
||||||
value: gui.getLogLevelInt()
|
value: gui.getLogLevelInt()
|
||||||
@ -149,52 +166,6 @@ Rectangle {
|
|||||||
id: logModel
|
id: logModel
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
RowLayout {
|
|
||||||
id: logLayout
|
|
||||||
width: parent.width
|
|
||||||
height: 200
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
TableView {
|
|
||||||
id: logView
|
|
||||||
headerVisible: false
|
|
||||||
anchors {
|
|
||||||
right: logLevelSlider.left
|
|
||||||
left: parent.left
|
|
||||||
bottom: parent.bottom
|
|
||||||
top: parent.top
|
|
||||||
}
|
|
||||||
|
|
||||||
TableViewColumn{ role: "description" ; title: "log" }
|
|
||||||
|
|
||||||
model: logModel
|
|
||||||
}
|
|
||||||
|
|
||||||
Slider {
|
|
||||||
id: logLevelSlider
|
|
||||||
value: gui.getLogLevelInt()
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
bottom: parent.bottom
|
|
||||||
|
|
||||||
rightMargin: 5
|
|
||||||
leftMargin: 5
|
|
||||||
topMargin: 5
|
|
||||||
bottomMargin: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
orientation: Qt.Vertical
|
|
||||||
maximumValue: 5
|
|
||||||
stepSize: 1
|
|
||||||
|
|
||||||
onValueChanged: {
|
|
||||||
gui.setLogLevel(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
function addDebugMessage(message){
|
function addDebugMessage(message){
|
||||||
debuggerLog.append({value: message})
|
debuggerLog.append({value: message})
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,8 @@ Rectangle {
|
|||||||
|
|
||||||
var me = eth.key().address;
|
var me = eth.key().address;
|
||||||
if((to == me|| from == me) && message.input.length == 128) {
|
if((to == me|| from == me) && message.input.length == 128) {
|
||||||
|
var to = eth.lookupName(to)
|
||||||
|
var from = eth.lookupName(from)
|
||||||
txModel.insert(0, {confirmations: blockNumber - message.number, from: from, to: to, value: value})
|
txModel.insert(0, {confirmations: blockNumber - message.number, from: from, to: to, value: value})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,7 +153,11 @@ Rectangle {
|
|||||||
Button {
|
Button {
|
||||||
text: "Send"
|
text: "Send"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
eth.transact({from: eth.key().privateKey, to:address, gas: "9000", gasPrice: "10000000000000", data: ["0x"+txTo.text, txValue.text]})
|
var lookup = eth.lookupAddress(address)
|
||||||
|
if(lookup.length == 0)
|
||||||
|
lookup = address
|
||||||
|
|
||||||
|
eth.transact({from: eth.key().privateKey, to:lookup, gas: "9000", gasPrice: "10000000000000", data: ["0x"+txTo.text, txValue.text]})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,9 @@ Rectangle {
|
|||||||
function addTxs(messages) {
|
function addTxs(messages) {
|
||||||
for(var i = 0; i < messages.length; i++) {
|
for(var i = 0; i < messages.length; i++) {
|
||||||
var message = messages.get(i);
|
var message = messages.get(i);
|
||||||
txModel.insert(0, {num: txModel.count, from: message.from, to: message.to, value: eth.numberToHuman(message.value)})
|
var to = eth.lookupName(message.to);
|
||||||
|
var from = eth.lookupName(message.from);
|
||||||
|
txModel.insert(0, {num: txModel.count, from: from, to: to, value: eth.numberToHuman(message.value)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,902 +0,0 @@
|
|||||||
import QtQuick 2.0
|
|
||||||
import QtQuick.Controls 1.0;
|
|
||||||
import QtQuick.Layouts 1.0;
|
|
||||||
import QtQuick.Dialogs 1.0;
|
|
||||||
import QtQuick.Window 2.1;
|
|
||||||
import QtQuick.Controls.Styles 1.1
|
|
||||||
import Ethereum 1.0
|
|
||||||
|
|
||||||
import "../ext/filter.js" as Eth
|
|
||||||
import "../ext/http.js" as Http
|
|
||||||
|
|
||||||
ApplicationWindow {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property alias miningButtonText: miningButton.text
|
|
||||||
property var ethx : Eth.ethx
|
|
||||||
property var browser
|
|
||||||
|
|
||||||
width: 1200
|
|
||||||
height: 820
|
|
||||||
minimumHeight: 300
|
|
||||||
|
|
||||||
title: "Mist"
|
|
||||||
|
|
||||||
// This signal is used by the filter API. The filter API connects using this signal handler from
|
|
||||||
// the different QML files and plugins.
|
|
||||||
signal messages(var messages, int id);
|
|
||||||
function invokeFilterCallback(data, receiverSeed) {
|
|
||||||
//var messages = JSON.parse(data)
|
|
||||||
// Signal handler
|
|
||||||
messages(data, receiverSeed);
|
|
||||||
root.browser.view.messages(data, receiverSeed);
|
|
||||||
}
|
|
||||||
|
|
||||||
TextField {
|
|
||||||
id: copyElementHax
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
|
|
||||||
function copyToClipboard(text) {
|
|
||||||
copyElementHax.text = text
|
|
||||||
copyElementHax.selectAll()
|
|
||||||
copyElementHax.copy()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Takes care of loading all default plugins
|
|
||||||
Component.onCompleted: {
|
|
||||||
var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true});
|
|
||||||
var browser = addPlugin("./webapp.qml", {noAdd: true, close: false, section: "ethereum", active: true});
|
|
||||||
root.browser = browser;
|
|
||||||
|
|
||||||
addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"});
|
|
||||||
addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"});
|
|
||||||
addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"});
|
|
||||||
addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"});
|
|
||||||
addPlugin("./views/javascript.qml", {noAdd: true, close: false, section: "legacy"});
|
|
||||||
|
|
||||||
addPlugin("./views/jeffcoin/jeffcoin.qml", {noAdd: true, close: false, section: "apps"})
|
|
||||||
|
|
||||||
mainSplit.setView(wallet.view, wallet.menuItem);
|
|
||||||
|
|
||||||
// Call the ready handler
|
|
||||||
gui.done();
|
|
||||||
}
|
|
||||||
|
|
||||||
function addViews(view, path, options) {
|
|
||||||
var views = mainSplit.addComponent(view, options)
|
|
||||||
views.menuItem.path = path
|
|
||||||
|
|
||||||
mainSplit.views.push(views);
|
|
||||||
|
|
||||||
if(!options.noAdd) {
|
|
||||||
gui.addPlugin(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
return views
|
|
||||||
}
|
|
||||||
|
|
||||||
function addPlugin(path, options) {
|
|
||||||
try {
|
|
||||||
if(typeof(path) === "string" && /^https?/.test(path)) {
|
|
||||||
console.log('load http')
|
|
||||||
Http.request(path, function(o) {
|
|
||||||
if(o.status === 200) {
|
|
||||||
var view = Qt.createQmlObject(o.responseText, mainView, path)
|
|
||||||
addViews(view, path, options)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var component = Qt.createComponent(path);
|
|
||||||
if(component.status != Component.Ready) {
|
|
||||||
if(component.status == Component.Error) {
|
|
||||||
ethx.note("error: ", component.errorString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var view = mainView.createView(component, options)
|
|
||||||
var views = addViews(view, path, options)
|
|
||||||
|
|
||||||
return views
|
|
||||||
} catch(e) {
|
|
||||||
ethx.note(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuBar: MenuBar {
|
|
||||||
Menu {
|
|
||||||
title: "File"
|
|
||||||
MenuItem {
|
|
||||||
text: "Import App"
|
|
||||||
shortcut: "Ctrl+o"
|
|
||||||
onTriggered: {
|
|
||||||
generalFileDialog.show(true, importApp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
MenuItem {
|
|
||||||
text: "Browser"
|
|
||||||
onTriggered: eth.openBrowser()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Add plugin"
|
|
||||||
onTriggered: {
|
|
||||||
generalFileDialog.show(true, function(path) {
|
|
||||||
addPlugin(path, {close: true, section: "apps"})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuSeparator {}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Import key"
|
|
||||||
shortcut: "Ctrl+i"
|
|
||||||
onTriggered: {
|
|
||||||
generalFileDialog.show(true, function(path) {
|
|
||||||
gui.importKey(path)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Export keys"
|
|
||||||
shortcut: "Ctrl+e"
|
|
||||||
onTriggered: {
|
|
||||||
generalFileDialog.show(false, function(path) {
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu {
|
|
||||||
title: "Developer"
|
|
||||||
MenuItem {
|
|
||||||
iconSource: "../icecream.png"
|
|
||||||
text: "Debugger"
|
|
||||||
shortcut: "Ctrl+d"
|
|
||||||
onTriggered: eth.startDebugger()
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Import Tx"
|
|
||||||
onTriggered: {
|
|
||||||
txImportDialog.visible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Run JS file"
|
|
||||||
onTriggered: {
|
|
||||||
generalFileDialog.show(true, function(path) {
|
|
||||||
eth.evalJavascriptFile(path)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Dump state"
|
|
||||||
onTriggered: {
|
|
||||||
generalFileDialog.show(false, function(path) {
|
|
||||||
// Empty hash for latest
|
|
||||||
gui.dumpState("", path)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuSeparator {}
|
|
||||||
|
|
||||||
/*
|
|
||||||
MenuItem {
|
|
||||||
id: miningSpeed
|
|
||||||
text: "Mining: Turbo"
|
|
||||||
onTriggered: {
|
|
||||||
gui.toggleTurboMining()
|
|
||||||
if(text == "Mining: Turbo") {
|
|
||||||
text = "Mining: Normal";
|
|
||||||
} else {
|
|
||||||
text = "Mining: Turbo";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu {
|
|
||||||
title: "Network"
|
|
||||||
MenuItem {
|
|
||||||
text: "Add Peer"
|
|
||||||
shortcut: "Ctrl+p"
|
|
||||||
onTriggered: {
|
|
||||||
addPeerWin.visible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MenuItem {
|
|
||||||
text: "Show Peers"
|
|
||||||
shortcut: "Ctrl+e"
|
|
||||||
onTriggered: {
|
|
||||||
peerWindow.visible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu {
|
|
||||||
title: "Help"
|
|
||||||
MenuItem {
|
|
||||||
text: "About"
|
|
||||||
onTriggered: {
|
|
||||||
aboutWin.visible = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu {
|
|
||||||
title: "GLOBAL SHORTCUTS"
|
|
||||||
visible: false
|
|
||||||
MenuItem {
|
|
||||||
visible: false
|
|
||||||
shortcut: "Ctrl+l"
|
|
||||||
onTriggered: {
|
|
||||||
url.focus = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
statusBar: StatusBar {
|
|
||||||
height: 32
|
|
||||||
id: statusBar
|
|
||||||
RowLayout {
|
|
||||||
Button {
|
|
||||||
id: miningButton
|
|
||||||
text: "Start Mining"
|
|
||||||
onClicked: {
|
|
||||||
gui.toggleMining()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Label {
|
|
||||||
id: walletValueLabel
|
|
||||||
|
|
||||||
font.pixelSize: 10
|
|
||||||
styleColor: "#797979"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
y: 6
|
|
||||||
objectName: "miningLabel"
|
|
||||||
visible: true
|
|
||||||
font.pixelSize: 10
|
|
||||||
anchors.right: lastBlockLabel.left
|
|
||||||
anchors.rightMargin: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
y: 6
|
|
||||||
id: lastBlockLabel
|
|
||||||
objectName: "lastBlockLabel"
|
|
||||||
visible: true
|
|
||||||
text: ""
|
|
||||||
font.pixelSize: 10
|
|
||||||
anchors.right: peerGroup.left
|
|
||||||
anchors.rightMargin: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgressBar {
|
|
||||||
id: downloadIndicator
|
|
||||||
value: 0
|
|
||||||
visible: true
|
|
||||||
objectName: "downloadIndicator"
|
|
||||||
y: 3
|
|
||||||
x: statusBar.width / 2 - this.width / 2
|
|
||||||
width: 160
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
id: peerGroup
|
|
||||||
y: 7
|
|
||||||
anchors.right: parent.right
|
|
||||||
MouseArea {
|
|
||||||
onDoubleClicked: peerWindow.visible = true
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: peerLabel
|
|
||||||
font.pixelSize: 8
|
|
||||||
text: "0 / 0"
|
|
||||||
}
|
|
||||||
Image {
|
|
||||||
id: peerImage
|
|
||||||
width: 10; height: 10
|
|
||||||
source: "../network.png"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
property var blockModel: ListModel {
|
|
||||||
id: blockModel
|
|
||||||
}
|
|
||||||
|
|
||||||
SplitView {
|
|
||||||
property var views: [];
|
|
||||||
|
|
||||||
id: mainSplit
|
|
||||||
anchors.fill: parent
|
|
||||||
resizing: false
|
|
||||||
|
|
||||||
function setView(view, menu) {
|
|
||||||
for(var i = 0; i < views.length; i++) {
|
|
||||||
views[i].view.visible = false
|
|
||||||
views[i].menuItem.setSelection(false)
|
|
||||||
}
|
|
||||||
view.visible = true
|
|
||||||
|
|
||||||
//menu.border.color = "#CCCCCC"
|
|
||||||
//menu.color = "#FFFFFFFF"
|
|
||||||
menu.setSelection(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
function addComponent(view, options) {
|
|
||||||
view.visible = false
|
|
||||||
view.anchors.fill = mainView
|
|
||||||
|
|
||||||
if( !view.hasOwnProperty("iconSource") ) {
|
|
||||||
console.log("Could not load plugin. Property 'iconSourc' not found on view.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var menuItem = menu.createMenuItem(view.iconSource, view, options);
|
|
||||||
if( view.hasOwnProperty("menuItem") ) {
|
|
||||||
view.menuItem = menuItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( view.hasOwnProperty("onReady") ) {
|
|
||||||
view.onReady.call(view)
|
|
||||||
}
|
|
||||||
|
|
||||||
if( options.active ) {
|
|
||||||
setView(view, menuItem)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return {view: view, menuItem: menuItem}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* Main menu.
|
|
||||||
********************/
|
|
||||||
Rectangle {
|
|
||||||
id: menu
|
|
||||||
Layout.minimumWidth: 210
|
|
||||||
Layout.maximumWidth: 210
|
|
||||||
anchors.top: parent.top
|
|
||||||
color: "#ececec"
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: menuItemTemplate
|
|
||||||
Rectangle {
|
|
||||||
id: menuItem
|
|
||||||
property var view;
|
|
||||||
property var path;
|
|
||||||
property var closable;
|
|
||||||
|
|
||||||
property alias title: label.text
|
|
||||||
property alias icon: icon.source
|
|
||||||
property alias secondaryTitle: secondary.text
|
|
||||||
function setSelection(on) {
|
|
||||||
sel.visible = on
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 206
|
|
||||||
height: 28
|
|
||||||
color: "#00000000"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: 4
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: sel
|
|
||||||
visible: false
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "#00000000"
|
|
||||||
Rectangle {
|
|
||||||
id: r
|
|
||||||
anchors.fill: parent
|
|
||||||
border.color: "#CCCCCC"
|
|
||||||
border.width: 1
|
|
||||||
radius: 5
|
|
||||||
color: "#FFFFFFFF"
|
|
||||||
}
|
|
||||||
Rectangle {
|
|
||||||
anchors {
|
|
||||||
top: r.top
|
|
||||||
bottom: r.bottom
|
|
||||||
right: r.right
|
|
||||||
}
|
|
||||||
width: 10
|
|
||||||
color: "#FFFFFFFF"
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
}
|
|
||||||
height: 1
|
|
||||||
color: "#CCCCCC"
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
bottom: parent.bottom
|
|
||||||
}
|
|
||||||
height: 1
|
|
||||||
color: "#CCCCCC"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
mainSplit.setView(view, menuItem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: icon
|
|
||||||
height: 20
|
|
||||||
width: 20
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
leftMargin: 3
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
onClicked: {
|
|
||||||
menuItem.closeApp()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: label
|
|
||||||
anchors {
|
|
||||||
left: icon.right
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
leftMargin: 3
|
|
||||||
}
|
|
||||||
|
|
||||||
color: "#0D0A01"
|
|
||||||
font.pixelSize: 12
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
id: secondary
|
|
||||||
anchors {
|
|
||||||
right: parent.right
|
|
||||||
rightMargin: 8
|
|
||||||
verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
color: "#AEADBE"
|
|
||||||
font.pixelSize: 12
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function closeApp() {
|
|
||||||
if(!this.closable) { return; }
|
|
||||||
|
|
||||||
if(this.view.hasOwnProperty("onDestroy")) {
|
|
||||||
this.view.onDestroy.call(this.view)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.view.destroy()
|
|
||||||
this.destroy()
|
|
||||||
gui.removePlugin(this.path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function createMenuItem(icon, view, options) {
|
|
||||||
if(options === undefined) {
|
|
||||||
options = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var section;
|
|
||||||
switch(options.section) {
|
|
||||||
case "ethereum":
|
|
||||||
section = menuDefault;
|
|
||||||
break;
|
|
||||||
case "legacy":
|
|
||||||
section = menuLegacy;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
section = menuApps;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var comp = menuItemTemplate.createObject(section)
|
|
||||||
|
|
||||||
comp.view = view
|
|
||||||
comp.title = view.title
|
|
||||||
comp.icon = view.iconSource
|
|
||||||
comp.closable = options.close;
|
|
||||||
|
|
||||||
return comp
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: menuColumn
|
|
||||||
y: 10
|
|
||||||
width: parent.width
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
spacing: 3
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "ETHEREUM"
|
|
||||||
font.bold: true
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: 5
|
|
||||||
}
|
|
||||||
color: "#888888"
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: menuDefault
|
|
||||||
spacing: 3
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "APPS"
|
|
||||||
font.bold: true
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: 5
|
|
||||||
}
|
|
||||||
color: "#888888"
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: menuApps
|
|
||||||
spacing: 3
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "DEBUG"
|
|
||||||
font.bold: true
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
leftMargin: 5
|
|
||||||
}
|
|
||||||
color: "#888888"
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: menuLegacy
|
|
||||||
spacing: 3
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********************
|
|
||||||
* Main view
|
|
||||||
********************/
|
|
||||||
Rectangle {
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.left: menu.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.top: parent.top
|
|
||||||
color: "#00000000"
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: urlPane
|
|
||||||
height: 40
|
|
||||||
color: "#00000000"
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
leftMargin: 5
|
|
||||||
rightMargin: 5
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 5
|
|
||||||
}
|
|
||||||
TextField {
|
|
||||||
id: url
|
|
||||||
objectName: "url"
|
|
||||||
placeholderText: "DApp URL"
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
top: parent.top
|
|
||||||
topMargin: 5
|
|
||||||
rightMargin: 5
|
|
||||||
leftMargin: 5
|
|
||||||
}
|
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
|
||||||
if(/^https?/.test(this.text)) {
|
|
||||||
root.browser.view.open(this.text);
|
|
||||||
mainSplit.setView(root.browser.view, root.browser.menuItem);
|
|
||||||
} else {
|
|
||||||
addPlugin(this.text, {close: true, section: "apps"})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Border
|
|
||||||
Rectangle {
|
|
||||||
id: divider
|
|
||||||
anchors {
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
top: urlPane.bottom
|
|
||||||
}
|
|
||||||
z: -1
|
|
||||||
height: 1
|
|
||||||
color: "#CCCCCC"
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: mainView
|
|
||||||
color: "#00000000"
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.top: divider.bottom
|
|
||||||
|
|
||||||
function createView(component) {
|
|
||||||
var view = component.createObject(mainView)
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************
|
|
||||||
* Dialogs
|
|
||||||
*****************/
|
|
||||||
FileDialog {
|
|
||||||
id: generalFileDialog
|
|
||||||
property var callback;
|
|
||||||
onAccepted: {
|
|
||||||
var path = this.fileUrl.toString();
|
|
||||||
callback.call(this, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function show(selectExisting, callback) {
|
|
||||||
generalFileDialog.callback = callback;
|
|
||||||
generalFileDialog.selectExisting = selectExisting;
|
|
||||||
|
|
||||||
this.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************
|
|
||||||
* Wallet functions
|
|
||||||
*****************/
|
|
||||||
function importApp(path) {
|
|
||||||
var ext = path.split('.').pop()
|
|
||||||
if(ext == "html" || ext == "htm") {
|
|
||||||
eth.openHtml(path)
|
|
||||||
}else if(ext == "qml"){
|
|
||||||
addPlugin(path, {close: true, section: "apps"})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function setWalletValue(value) {
|
|
||||||
walletValueLabel.text = value
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadPlugin(name) {
|
|
||||||
console.log("Loading plugin" + name)
|
|
||||||
var view = mainView.addPlugin(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPeers(text) {
|
|
||||||
peerLabel.text = text
|
|
||||||
}
|
|
||||||
|
|
||||||
function addPeer(peer) {
|
|
||||||
// We could just append the whole peer object but it cries if you try to alter them
|
|
||||||
peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version})
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetPeers(){
|
|
||||||
peerModel.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
function timeAgo(unixTs){
|
|
||||||
var lapsed = (Date.now() - new Date(unixTs*1000)) / 1000
|
|
||||||
return (lapsed + " seconds ago")
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertToPretty(unixTs){
|
|
||||||
var a = new Date(unixTs*1000);
|
|
||||||
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
|
||||||
var year = a.getFullYear();
|
|
||||||
var month = months[a.getMonth()];
|
|
||||||
var date = a.getDate();
|
|
||||||
var hour = a.getHours();
|
|
||||||
var min = a.getMinutes();
|
|
||||||
var sec = a.getSeconds();
|
|
||||||
var time = date+' '+month+' '+year+' '+hour+':'+min+':'+sec ;
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************
|
|
||||||
* Windows
|
|
||||||
*********************/
|
|
||||||
Window {
|
|
||||||
id: peerWindow
|
|
||||||
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
|
|
||||||
height: 200
|
|
||||||
width: 700
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
property var peerModel: ListModel {
|
|
||||||
id: peerModel
|
|
||||||
}
|
|
||||||
TableView {
|
|
||||||
anchors.fill: parent
|
|
||||||
id: peerTable
|
|
||||||
model: peerModel
|
|
||||||
TableViewColumn{width: 100; role: "ip" ; title: "IP" }
|
|
||||||
TableViewColumn{width: 60; role: "port" ; title: "Port" }
|
|
||||||
TableViewColumn{width: 140; role: "lastResponse"; title: "Last event" }
|
|
||||||
TableViewColumn{width: 100; role: "latency"; title: "Latency" }
|
|
||||||
TableViewColumn{width: 260; role: "version" ; title: "Version" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Window {
|
|
||||||
id: aboutWin
|
|
||||||
visible: false
|
|
||||||
title: "About"
|
|
||||||
minimumWidth: 350
|
|
||||||
maximumWidth: 350
|
|
||||||
maximumHeight: 200
|
|
||||||
minimumHeight: 200
|
|
||||||
|
|
||||||
Image {
|
|
||||||
id: aboutIcon
|
|
||||||
height: 150
|
|
||||||
width: 150
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
smooth: true
|
|
||||||
source: "../facet.png"
|
|
||||||
x: 10
|
|
||||||
y: 10
|
|
||||||
}
|
|
||||||
|
|
||||||
Text {
|
|
||||||
anchors.left: aboutIcon.right
|
|
||||||
anchors.leftMargin: 10
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: 30
|
|
||||||
font.pointSize: 12
|
|
||||||
text: "<h2>Mist (0.6.5)</h2><h4>Amalthea</h4><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br><h3>Building</h3>Maran Hidskes"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Window {
|
|
||||||
id: txImportDialog
|
|
||||||
minimumWidth: 270
|
|
||||||
maximumWidth: 270
|
|
||||||
maximumHeight: 50
|
|
||||||
minimumHeight: 50
|
|
||||||
TextField {
|
|
||||||
id: txImportField
|
|
||||||
width: 170
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 10
|
|
||||||
onAccepted: {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
anchors.left: txImportField.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.leftMargin: 5
|
|
||||||
text: "Import"
|
|
||||||
onClicked: {
|
|
||||||
eth.importTx(txImportField.text)
|
|
||||||
txImportField.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
addrField.focus = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Window {
|
|
||||||
id: addPeerWin
|
|
||||||
visible: false
|
|
||||||
minimumWidth: 300
|
|
||||||
maximumWidth: 300
|
|
||||||
maximumHeight: 50
|
|
||||||
minimumHeight: 50
|
|
||||||
title: "Connect to peer"
|
|
||||||
|
|
||||||
ComboBox {
|
|
||||||
id: addrField
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: addPeerButton.left
|
|
||||||
anchors.leftMargin: 10
|
|
||||||
anchors.rightMargin: 10
|
|
||||||
onAccepted: {
|
|
||||||
eth.connectToPeer(addrField.currentText)
|
|
||||||
addPeerWin.visible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
editable: true
|
|
||||||
model: ListModel { id: pastPeers }
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
var ips = eth.pastPeers()
|
|
||||||
for(var i = 0; i < ips.length; i++) {
|
|
||||||
pastPeers.append({text: ips.get(i)})
|
|
||||||
}
|
|
||||||
|
|
||||||
pastPeers.insert(0, {text: "poc-6.ethdev.com:30303"})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Button {
|
|
||||||
id: addPeerButton
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.rightMargin: 10
|
|
||||||
text: "Add"
|
|
||||||
onClicked: {
|
|
||||||
eth.connectToPeer(addrField.currentText)
|
|
||||||
addPeerWin.visible = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onCompleted: {
|
|
||||||
addrField.focus = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -164,7 +164,7 @@ import "../ext/qml_messaging.js" as Messaging
|
|||||||
experimental.preferences.javascriptEnabled: true
|
experimental.preferences.javascriptEnabled: true
|
||||||
experimental.preferences.navigatorQtObjectEnabled: true
|
experimental.preferences.navigatorQtObjectEnabled: true
|
||||||
experimental.preferences.developerExtrasEnabled: true
|
experimental.preferences.developerExtrasEnabled: true
|
||||||
experimental.userScripts: ["../ext/q.js", "../ext/pre.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
|
experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"]
|
||||||
experimental.onMessageReceived: {
|
experimental.onMessageReceived: {
|
||||||
console.log("[onMessageReceived]: ", message.data)
|
console.log("[onMessageReceived]: ", message.data)
|
||||||
// TODO move to messaging.js
|
// TODO move to messaging.js
|
||||||
|
23
mist/gui.go
23
mist/gui.go
@ -172,7 +172,7 @@ func (gui *Gui) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
|
func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
|
||||||
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/wallet.qml"))
|
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/main.qml"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -271,7 +271,8 @@ func (gui *Gui) loadAddressBook() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) insertTransaction(window string, tx *ethchain.Transaction) {
|
func (gui *Gui) insertTransaction(window string, tx *ethchain.Transaction) {
|
||||||
nameReg := ethpipe.New(gui.eth).World().Config().Get("NameReg")
|
pipe := ethpipe.New(gui.eth)
|
||||||
|
nameReg := pipe.World().Config().Get("NameReg")
|
||||||
addr := gui.address()
|
addr := gui.address()
|
||||||
|
|
||||||
var inout string
|
var inout string
|
||||||
@ -282,14 +283,14 @@ func (gui *Gui) insertTransaction(window string, tx *ethchain.Transaction) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ptx = ethpipe.NewJSTx(tx)
|
ptx = ethpipe.NewJSTx(tx, pipe.World().State())
|
||||||
send = nameReg.Storage(tx.Sender())
|
send = nameReg.Storage(tx.Sender())
|
||||||
rec = nameReg.Storage(tx.Recipient)
|
rec = nameReg.Storage(tx.Recipient)
|
||||||
s, r string
|
s, r string
|
||||||
)
|
)
|
||||||
|
|
||||||
if tx.CreatesContract() {
|
if tx.CreatesContract() {
|
||||||
rec = nameReg.Storage(tx.CreationAddress())
|
rec = nameReg.Storage(tx.CreationAddress(pipe.World().State()))
|
||||||
}
|
}
|
||||||
|
|
||||||
if send.Len() != 0 {
|
if send.Len() != 0 {
|
||||||
@ -301,7 +302,7 @@ func (gui *Gui) insertTransaction(window string, tx *ethchain.Transaction) {
|
|||||||
r = strings.Trim(rec.Str(), "\x00")
|
r = strings.Trim(rec.Str(), "\x00")
|
||||||
} else {
|
} else {
|
||||||
if tx.CreatesContract() {
|
if tx.CreatesContract() {
|
||||||
r = ethutil.Bytes2Hex(tx.CreationAddress())
|
r = ethutil.Bytes2Hex(tx.CreationAddress(pipe.World().State()))
|
||||||
} else {
|
} else {
|
||||||
r = ethutil.Bytes2Hex(tx.Recipient)
|
r = ethutil.Bytes2Hex(tx.Recipient)
|
||||||
}
|
}
|
||||||
@ -466,13 +467,11 @@ func (gui *Gui) update() {
|
|||||||
var (
|
var (
|
||||||
pct float64 = 1.0 / float64(chainLength) * float64(blockLength)
|
pct float64 = 1.0 / float64(chainLength) * float64(blockLength)
|
||||||
dlWidget = gui.win.Root().ObjectByName("downloadIndicator")
|
dlWidget = gui.win.Root().ObjectByName("downloadIndicator")
|
||||||
|
dlLabel = gui.win.Root().ObjectByName("downloadLabel")
|
||||||
)
|
)
|
||||||
if pct < 1.0 {
|
|
||||||
dlWidget.Set("visible", true)
|
dlWidget.Set("value", pct)
|
||||||
dlWidget.Set("value", pct)
|
dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength))
|
||||||
} else {
|
|
||||||
dlWidget.Set("visible", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
case <-statsUpdateTicker.C:
|
case <-statsUpdateTicker.C:
|
||||||
gui.setStatsPane()
|
gui.setStatsPane()
|
||||||
@ -500,7 +499,7 @@ func (gui *Gui) setStatsPane() {
|
|||||||
runtime.ReadMemStats(&memStats)
|
runtime.ReadMemStats(&memStats)
|
||||||
|
|
||||||
statsPane := gui.getObjectByName("statsPane")
|
statsPane := gui.getObjectByName("statsPane")
|
||||||
statsPane.Set("text", fmt.Sprintf(`###### Mist 0.6.5 (%s) #######
|
statsPane.Set("text", fmt.Sprintf(`###### Mist 0.6.8 (%s) #######
|
||||||
|
|
||||||
eth %d (p2p = %d)
|
eth %d (p2p = %d)
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ClientIdentifier = "Mist"
|
ClientIdentifier = "Mist"
|
||||||
Version = "0.6.6"
|
Version = "0.6.7"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ethereum *eth.Ethereum
|
var ethereum *eth.Ethereum
|
||||||
|
@ -71,6 +71,32 @@ func (self *UiLib) LookupDomain(domain string) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *UiLib) LookupName(addr string) string {
|
||||||
|
var (
|
||||||
|
nameReg = self.World().Config().Get("NameReg")
|
||||||
|
lookup = nameReg.Storage(ethutil.Hex2Bytes(addr))
|
||||||
|
)
|
||||||
|
|
||||||
|
if lookup.Len() != 0 {
|
||||||
|
return strings.Trim(lookup.Str(), "\x00")
|
||||||
|
}
|
||||||
|
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *UiLib) LookupAddress(name string) string {
|
||||||
|
var (
|
||||||
|
nameReg = self.World().Config().Get("NameReg")
|
||||||
|
lookup = nameReg.Storage(ethutil.RightPadBytes([]byte(name), 32))
|
||||||
|
)
|
||||||
|
|
||||||
|
if lookup.Len() != 0 {
|
||||||
|
return ethutil.Bytes2Hex(lookup.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func (self *UiLib) PastPeers() *ethutil.List {
|
func (self *UiLib) PastPeers() *ethutil.List {
|
||||||
return ethutil.NewList(eth.PastPeers())
|
return ethutil.NewList(eth.PastPeers())
|
||||||
}
|
}
|
||||||
|
161
utils/websockets.go
Normal file
161
utils/websockets.go
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/eth-go"
|
||||||
|
"github.com/ethereum/eth-go/ethpipe"
|
||||||
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
|
"github.com/ethereum/eth-go/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func args(v ...interface{}) []interface{} {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
type WebSocketServer struct {
|
||||||
|
ethereum *eth.Ethereum
|
||||||
|
filterCallbacks map[int][]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWebSocketServer(eth *eth.Ethereum) *WebSocketServer {
|
||||||
|
return &WebSocketServer{eth, make(map[int][]int)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *WebSocketServer) Serv() {
|
||||||
|
pipe := ethpipe.NewJSPipe(self.ethereum)
|
||||||
|
|
||||||
|
wsServ := websocket.NewServer("/eth", ":40404")
|
||||||
|
wsServ.MessageFunc(func(c *websocket.Client, msg *websocket.Message) {
|
||||||
|
switch msg.Call {
|
||||||
|
case "compile":
|
||||||
|
data := ethutil.NewValue(msg.Args)
|
||||||
|
bcode, err := ethutil.Compile(data.Get(0).Str(), false)
|
||||||
|
if err != nil {
|
||||||
|
c.Write(args(nil, err.Error()), msg.Seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
code := ethutil.Bytes2Hex(bcode)
|
||||||
|
c.Write(args(code, nil), msg.Seed)
|
||||||
|
case "getBlockByNumber":
|
||||||
|
args := msg.Arguments()
|
||||||
|
|
||||||
|
block := pipe.BlockByNumber(int32(args.Get(0).Uint()))
|
||||||
|
c.Write(block, msg.Seed)
|
||||||
|
|
||||||
|
case "getKey":
|
||||||
|
c.Write(pipe.Key().PrivateKey, msg.Seed)
|
||||||
|
case "transact":
|
||||||
|
if mp, ok := msg.Args[0].(map[string]interface{}); ok {
|
||||||
|
object := mapToTxParams(mp)
|
||||||
|
c.Write(
|
||||||
|
args(pipe.Transact(object["from"], object["to"], object["value"], object["gas"], object["gasPrice"], object["data"])),
|
||||||
|
msg.Seed,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
case "getCoinBase":
|
||||||
|
c.Write(pipe.CoinBase(), msg.Seed)
|
||||||
|
|
||||||
|
case "getIsListening":
|
||||||
|
c.Write(pipe.IsListening(), msg.Seed)
|
||||||
|
|
||||||
|
case "getIsMining":
|
||||||
|
c.Write(pipe.IsMining(), msg.Seed)
|
||||||
|
|
||||||
|
case "getPeerCoint":
|
||||||
|
c.Write(pipe.PeerCount(), msg.Seed)
|
||||||
|
|
||||||
|
case "getCountAt":
|
||||||
|
args := msg.Arguments()
|
||||||
|
|
||||||
|
c.Write(pipe.TxCountAt(args.Get(0).Str()), msg.Seed)
|
||||||
|
|
||||||
|
case "getCodeAt":
|
||||||
|
args := msg.Arguments()
|
||||||
|
|
||||||
|
c.Write(len(pipe.CodeAt(args.Get(0).Str())), msg.Seed)
|
||||||
|
|
||||||
|
case "getBlockByHash":
|
||||||
|
args := msg.Arguments()
|
||||||
|
|
||||||
|
c.Write(pipe.BlockByHash(args.Get(0).Str()), msg.Seed)
|
||||||
|
|
||||||
|
case "getStorageAt":
|
||||||
|
args := msg.Arguments()
|
||||||
|
|
||||||
|
c.Write(pipe.StorageAt(args.Get(0).Str(), args.Get(1).Str()), msg.Seed)
|
||||||
|
|
||||||
|
case "getBalanceAt":
|
||||||
|
args := msg.Arguments()
|
||||||
|
|
||||||
|
c.Write(pipe.BalanceAt(args.Get(0).Str()), msg.Seed)
|
||||||
|
|
||||||
|
case "getSecretToAddress":
|
||||||
|
args := msg.Arguments()
|
||||||
|
|
||||||
|
c.Write(pipe.SecretToAddress(args.Get(0).Str()), msg.Seed)
|
||||||
|
|
||||||
|
case "newFilter":
|
||||||
|
case "newFilterString":
|
||||||
|
case "messages":
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
wsServ.Listen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartWebSockets(eth *eth.Ethereum) {
|
||||||
|
sock := NewWebSocketServer(eth)
|
||||||
|
go sock.Serv()
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO This is starting to become a generic method. Move to utils
|
||||||
|
func mapToTxParams(object map[string]interface{}) map[string]string {
|
||||||
|
// Default values
|
||||||
|
if object["from"] == nil {
|
||||||
|
object["from"] = ""
|
||||||
|
}
|
||||||
|
if object["to"] == nil {
|
||||||
|
object["to"] = ""
|
||||||
|
}
|
||||||
|
if object["value"] == nil {
|
||||||
|
object["value"] = ""
|
||||||
|
}
|
||||||
|
if object["gas"] == nil {
|
||||||
|
object["gas"] = ""
|
||||||
|
}
|
||||||
|
if object["gasPrice"] == nil {
|
||||||
|
object["gasPrice"] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var dataStr string
|
||||||
|
var data []string
|
||||||
|
if str, ok := object["data"].(string); ok {
|
||||||
|
data = []string{str}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, str := range data {
|
||||||
|
if ethutil.IsHex(str) {
|
||||||
|
str = str[2:]
|
||||||
|
|
||||||
|
if len(str) != 64 {
|
||||||
|
str = ethutil.LeftPadString(str, 64)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str = ethutil.Bytes2Hex(ethutil.LeftPadBytes(ethutil.Big(str).Bytes(), 32))
|
||||||
|
}
|
||||||
|
|
||||||
|
dataStr += str
|
||||||
|
}
|
||||||
|
object["data"] = dataStr
|
||||||
|
|
||||||
|
conv := make(map[string]string)
|
||||||
|
for key, value := range object {
|
||||||
|
if v, ok := value.(string); ok {
|
||||||
|
conv[key] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return conv
|
||||||
|
}
|
Reference in New Issue
Block a user