diff --git a/rpc/api.go b/rpc/api.go
index d5e18eec86dc0cebae322ceca39e4051de8705be..1102b7cb208924b2cf60c9827502d863e4b18502 100644
--- a/rpc/api.go
+++ b/rpc/api.go
@@ -348,13 +348,14 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
 		opts := toFilterOptions(args)
 		*reply = NewLogsRes(p.xeth().AllLogs(opts))
 	case "eth_getWork":
-		*reply = p.getWork()
+		p.xeth().SetMining(true)
+		*reply = p.agent.GetWork().Hex()
 	case "eth_submitWork":
-		// TODO what is the reply here?
-		// TODO what are the arguments?
-		p.agent.SetResult(0, common.Hash{}, common.Hash{})
-
-		return NewNotImplementedError(req.Method)
+		args := new(SubmitWorkArgs)
+		if err := json.Unmarshal(req.Params, &args); err != nil {
+			return err
+		}
+		*reply = p.agent.SetResult(args.Nonce, args.Digest, args.Header)
 	case "db_putString":
 		args := new(DbArgs)
 		if err := json.Unmarshal(req.Params, &args); err != nil {
@@ -466,11 +467,6 @@ func (p *EthereumApi) GetRequestReply(req *RpcRequest, reply *interface{}) error
 	return nil
 }
 
-func (p *EthereumApi) getWork() string {
-	p.xeth().SetMining(true)
-	return p.agent.GetWork().Hex()
-}
-
 func toFilterOptions(options *BlockFilterArgs) *core.FilterOptions {
 	var opts core.FilterOptions
 
diff --git a/rpc/args.go b/rpc/args.go
index e50c9b1f5bcd4fff77a4d7cb18bfede0c1a6ac4f..504e67c07e58553efb2ede4f4c5ea5a77b1b10e8 100644
--- a/rpc/args.go
+++ b/rpc/args.go
@@ -686,3 +686,42 @@ func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
 
 	return nil
 }
+
+type SubmitWorkArgs struct {
+	Nonce  uint64
+	Header common.Hash
+	Digest common.Hash
+}
+
+func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
+	var obj []interface{}
+	if err = json.Unmarshal(b, &obj); err != nil {
+		return NewDecodeParamError(err.Error())
+	}
+
+	if len(obj) < 3 {
+		return NewInsufficientParamsError(len(obj), 3)
+	}
+
+	var objstr string
+	var ok bool
+	if objstr, ok = obj[0].(string); !ok {
+		return NewDecodeParamError("Nonce is not a string")
+	}
+
+	args.Nonce = common.BytesToNumber(common.Hex2Bytes(objstr))
+
+	if objstr, ok = obj[1].(string); !ok {
+		return NewDecodeParamError("Header is not a string")
+	}
+
+	args.Header = common.HexToHash(objstr)
+
+	if objstr, ok = obj[2].(string); !ok {
+		return NewDecodeParamError("Digest is not a string")
+	}
+
+	args.Digest = common.HexToHash(objstr)
+
+	return nil
+}
diff --git a/rpc/miner_agest.go b/rpc/miner_agest.go
index 64dba82a642ed0c1d5a9b77cb616ef70d85236fb..46fb872071f1cd60fe3a1ac4834a77ea693d8b8e 100644
--- a/rpc/miner_agest.go
+++ b/rpc/miner_agest.go
@@ -55,6 +55,8 @@ out:
 }
 
 func (a *Agent) GetWork() common.Hash {
+	// TODO return HashNoNonce, DAGSeedHash, Difficulty
+
 	// XXX Wait here untill work != nil ?.
 	if a.work != nil {
 		return a.work.HashNoNonce()
@@ -62,9 +64,14 @@ func (a *Agent) GetWork() common.Hash {
 	return common.Hash{}
 }
 
-func (a *Agent) SetResult(nonce uint64, mixDigest, seedHash common.Hash) {
+func (a *Agent) SetResult(nonce uint64, mixDigest, seedHash common.Hash) bool {
+	// Return true or false, but does not indicate if the PoW was correct
+
 	// Make sure the external miner was working on the right hash
 	if a.currentWork != nil && a.work != nil && a.currentWork.Hash() == a.work.Hash() {
 		a.returnCh <- miner.Work{a.currentWork.Number().Uint64(), nonce, mixDigest.Bytes(), seedHash.Bytes()}
+		return true
 	}
+
+	return false
 }