Skip to content

Commit

Permalink
draft impl estimatesmartfee endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
GambolingPangolin committed Mar 6, 2019
1 parent de8f14a commit 6a03ead
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
.project
Setup.hs
dist/
dist-newstyle/
cabal-dev/
network-bitcoin-tests
cabal.sandbox.config
Expand Down
2 changes: 2 additions & 0 deletions .hgignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
syntax: regexp
\#.*\#$
\.\#
\.sw[op]
\.DS_Store$
\.cabal-sandbox/
\.vagrant/
Expand All @@ -10,6 +11,7 @@ cabal\.sandbox\.config$
\.shake\.database$
\.shake/
dist/
dist-newstyle/
\.tfstate\.backup$
\.tfstate\.blank$
\.terraform/
Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
See the [Hackage documentation](http://hackage.haskell.org/package/network-bitcoin)
network-bitcoin
====

See the [Hackage documentation](http://hackage.haskell.org/package/network-bitcoin).

Testing
----

The tests expect to run against a `bitcoind` node synced to testnet. Invoke `bitcoind` with:

```shell
$ bitcoind -rpcuser -rpcpassword -testnet
```
1 change: 1 addition & 0 deletions src/Network/Bitcoin/BlockChain.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Network.Bitcoin.BlockChain ( Client
, setTransactionFee
, getRawMemoryPool
, BlockHash
, BlockHeight
, getBlockHash
, Block(..)
, getBlock
Expand Down
35 changes: 34 additions & 1 deletion src/Network/Bitcoin/Wallet.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ module Network.Bitcoin.Wallet ( Client
, moveBitcoins
, sendFromAccount
, sendMany
, EstimationMode (..)
, estimateSmartFee
-- , createMultiSig
, ReceivedByAddress(..)
, listReceivedByAddress
Expand Down Expand Up @@ -63,14 +65,20 @@ module Network.Bitcoin.Wallet ( Client
, isAddressValid
) where

import Control.Applicative (liftA2)
import Control.Monad
import Data.Aeson as A
import Data.Aeson.Types (parseEither)
import Data.Bifunctor (first)
import Data.Bool (bool)
import qualified Data.HashMap.Lazy as HM
import qualified Data.List as List
import Data.Maybe
import Data.Text
import Data.Time.Clock.POSIX
import Data.Vector as V hiding ((++))
import Network.Bitcoin.BlockChain (BlockHash)
import Data.Word
import Network.Bitcoin.BlockChain (BlockHash, BlockHeight)
import Network.Bitcoin.Internal
import Network.Bitcoin.RawTransaction (RawTransaction)

Expand Down Expand Up @@ -745,3 +753,28 @@ instance FromJSON IsValid where
-- | Checks if a given address is a valid one.
isAddressValid :: Client -> Address -> IO Bool
isAddressValid client addr = getValid <$> callApi client "validateaddress" [ tj addr ]


-- | Possible fee estimation modes
data EstimationMode
= Economical
| Conservative
deriving Eq


instance ToJSON EstimationMode where
toJSON Economical = toJSON ("ECONOMICAL" :: String)
toJSON Conservative = toJSON ("CONSERVATIVE" :: String)


-- | Estimate the fee per kb to send a transaction
estimateSmartFee :: Client -> Word32 -> Maybe EstimationMode -> IO (Either [String] (Double, BlockHeight))
estimateSmartFee client target mode =
parse <$> callApi client "estimatesmartfee" (catMaybes [ Just $ tj target, tj <$> mode ])
where
parse = join . first pure . parseEither parseResp
parseResp = withObject "estimatesmartfee response" $ \obj -> do
merrs <- obj .:? "errors"
flip (maybe (parseVals obj)) merrs $ \errs ->
bool (pure $ Left errs) (parseVals obj) . List.null $ errs
parseVals = fmap Right . (liftA2 (,) <$> (.: "feerate") <*> (.: "blocks"))

0 comments on commit 6a03ead

Please sign in to comment.