aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/utils/websockets.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/utils/websockets.go')
-rw-r--r--cmd/utils/websockets.go161
1 files changed, 161 insertions, 0 deletions
diff --git a/cmd/utils/websockets.go b/cmd/utils/websockets.go
new file mode 100644
index 000000000..7bda805ac
--- /dev/null
+++ b/cmd/utils/websockets.go
@@ -0,0 +1,161 @@
+package utils
+
+import (
+ "github.com/ethereum/go-ethereum"
+ "github.com/ethereum/go-ethereum/ethpipe"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/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
+}