module Network.Bitcoin.Wallet ( Auth(..)
, BitcoindInfo(..)
, getBitcoindInfo
, getNewAddress
, getAccountAddress
, getAccount
, setAccount
, getAddressByAccount
, sendToAddress
, AddressInfo(..)
, listAddressGroupings
, Signature
, signMessage
, verifyMessage
, getReceivedByAddress
, getReceivedByAddress'
, getReceivedByAccount
, getReceivedByAccount'
, getBalance
, getBalance'
, getBalance''
, moveBitcoins
, sendFromAccount
, sendMany
, ReceivedByAddress(..)
, listReceivedByAddress
, listReceivedByAddress'
, ReceivedByAccount(..)
, listReceivedByAccount
, listReceivedByAccount'
, backupWallet
, keyPoolRefill
, unlockWallet
, lockWallet
, changePassword
, encryptWallet
, isAddressValid
) where
import Control.Applicative
import Control.Monad
import Data.Aeson as A
import Data.Maybe
import Data.Vector as V
import Network.Bitcoin.Internal
data BitcoindInfo =
BitcoindInfo {
bitcoinVersion :: Integer
, protocolVersion :: Integer
, walletVersion :: Integer
, balance :: BTC
, numBlocks :: Integer
, numConnections :: Integer
, proxy :: Text
, generationDifficulty :: Double
, onTestNetwork :: Bool
, keyPoolOldest :: Integer
, keyPoolSize :: Integer
, transactionFeePaid :: BTC
, unlockedUntil :: Maybe Integer
, bitcoindErrors :: Text
}
deriving ( Show, Read, Ord, Eq )
instance FromJSON BitcoindInfo where
parseJSON (Object o) = BitcoindInfo <$> o .: "version"
<*> o .: "protocolversion"
<*> o .: "walletversion"
<*> (unwrapBTC <$> o .: "balance")
<*> o .: "blocks"
<*> o .: "connections"
<*> o .: "proxy"
<*> o .: "difficulty"
<*> o .: "testnet"
<*> o .: "keypoololddest"
<*> o .: "keypoolsize"
<*> (unwrapBTC <$> o .: "paytxfee")
<*> o .:? "unlocked_until"
<*> o .: "errors"
parseJSON _ = mzero
getBitcoindInfo :: Auth -> IO BitcoindInfo
getBitcoindInfo auth = callApi auth "getinfo" []
getNewAddress :: Auth -> Maybe Account -> IO Address
getNewAddress auth ma = let acc = fromMaybe "" ma
in callApi auth "getnewaddress" [ tj acc ]
getAccountAddress :: Auth -> Account -> IO Address
getAccountAddress auth acc = callApi auth "getaccountaddress" [ tj acc ]
setAccount :: Auth -> Address -> Account -> IO ()
setAccount auth addr acc = callApi auth "setaccount" [ tj addr, tj acc ]
getAccount :: Auth -> Address -> IO Account
getAccount auth addr = callApi auth "getaccount" [ tj addr ]
getAddressByAccount :: Auth -> Account -> IO (Vector Address)
getAddressByAccount auth acc = callApi auth "getaddressbyaccount" [ tj acc ]
sendToAddress :: Auth
-> Address
-> BTC
-> Maybe Text
-> Maybe Text
-> IO TransactionID
sendToAddress auth addr amount comm comm2 =
callApi auth "sendtoaddress" [ tj addr, tj $ WBTC amount, tj comm, tj comm2 ]
data AddressInfo = AddressInfo {
aiAddress :: Address
, aiAmount :: BTC
, aiAccount :: Maybe Account
}
deriving ( Show, Read, Eq, Ord )
instance FromJSON AddressInfo where
parseJSON (A.Array a) | V.length a == 2 = AddressInfo <$> parseJSON (a ! 0)
<*> (unwrapBTC <$> parseJSON (a ! 1))
<*> pure Nothing
| V.length a == 3 = AddressInfo <$> parseJSON (a ! 0)
<*> (unwrapBTC <$> parseJSON (a ! 1))
<*> (Just <$> parseJSON (a ! 2))
| otherwise = mzero
parseJSON _ = mzero
listAddressGroupings :: Auth
-> IO (Vector (Vector AddressInfo))
listAddressGroupings auth =
callApi auth "listaddressgroupings" []
type Signature = HexString
signMessage :: Auth
-> Address
-> Text
-> IO Signature
signMessage auth addr msg = callApi auth "signmessage" [ tj addr, tj msg ]
verifyMessage :: Auth
-> Address
-> Signature
-> Text
-> IO Bool
verifyMessage auth addr sig msg =
callApi auth "verifymessage" [ tj addr, tj sig, tj msg ]
getReceivedByAddress :: Auth -> Address -> IO BTC
getReceivedByAddress auth addr =
unwrapBTC <$> callApi auth "getreceivedbyaddress" [ tj addr ]
getReceivedByAddress' :: Auth
-> Address
-> Int
-> IO BTC
getReceivedByAddress' auth addr minconf =
unwrapBTC <$> callApi auth "getreceivedbyaddress" [ tj addr, tj minconf ]
getReceivedByAccount :: Auth -> Account -> IO BTC
getReceivedByAccount auth acc =
unwrapBTC <$> callApi auth "getreceivedbyaccount" [ tj acc ]
getReceivedByAccount' :: Auth
-> Account
-> Int
-> IO BTC
getReceivedByAccount' auth acc minconf =
unwrapBTC <$> callApi auth "getreceivedbyaccount" [ tj acc, tj minconf ]
getBalance :: Auth
-> IO BTC
getBalance auth =
unwrapBTC <$> callApi auth "getbalance" []
getBalance' :: Auth
-> Account
-> IO BTC
getBalance' auth acc =
unwrapBTC <$> callApi auth "getbalance" [ tj acc ]
getBalance'' :: Auth
-> Account
-> Int
-> IO BTC
getBalance'' auth acc minconf =
unwrapBTC <$> callApi auth "getbalance" [ tj acc, tj minconf ]
moveBitcoins :: Auth
-> Account
-> Account
-> BTC
-> Text
-> IO ()
moveBitcoins auth from to amt comm =
stupidAPI <$> callApi auth "move" [ tj from, tj to, tj $ WBTC amt, tj one, tj comm ]
where one = 1 :: Int
stupidAPI :: Bool -> ()
stupidAPI = const ()
sendFromAccount :: Auth
-> Account
-> Address
-> BTC
-> Maybe Text
-> Maybe Text
-> IO TransactionID
sendFromAccount auth from to amount comm comm2 =
callApi auth "sendfrom" [ tj from, tj to, tj $ WBTC amount, tj one, tj comm, tj comm2 ]
where one = 1 :: Int
sendMany :: Auth
-> Account
-> Vector (Address, BTC)
-> Maybe Text
-> IO TransactionID
sendMany auth acc amounts comm =
callApi auth "sendmany" [ tj acc, tj $ AA amounts, tj comm ]
data ReceivedByAddress =
ReceivedByAddress {
recvAddress :: Address
, recvAccount :: Account
, recvAmount :: BTC
, recvNumConfirmations :: Integer
}
deriving ( Show, Read, Ord, Eq )
instance FromJSON ReceivedByAddress where
parseJSON (Object o) = ReceivedByAddress <$> o .: "address"
<*> o .: "account"
<*> (unwrapBTC <$> o .: "amount")
<*> o .: "confirmations"
parseJSON _ = mzero
listReceivedByAddress :: Auth -> IO (Vector ReceivedByAddress)
listReceivedByAddress auth = listReceivedByAddress' auth 1 False
listReceivedByAddress' :: Auth
-> Int
-> Bool
-> IO (Vector ReceivedByAddress)
listReceivedByAddress' auth minconf includeEmpty =
callApi auth "listreceivedbyaddress" [ tj minconf, tj includeEmpty ]
data ReceivedByAccount =
ReceivedByAccount { raccAccount :: Account
, raccAmount :: BTC
, raccNumConfirmations :: Integer
}
deriving ( Show, Read, Ord, Eq )
instance FromJSON ReceivedByAccount where
parseJSON (Object o) = ReceivedByAccount <$> o .: "account"
<*> (unwrapBTC <$> o .: "amount")
<*> o .: "confirmations"
parseJSON _ = mzero
listReceivedByAccount :: Auth -> IO (Vector ReceivedByAccount)
listReceivedByAccount auth = listReceivedByAccount' auth 1 False
listReceivedByAccount' :: Auth
-> Int
-> Bool
-> IO (Vector ReceivedByAccount)
listReceivedByAccount' auth minconf includeEmpty =
callApi auth "listreceivedbyaccount" [ tj minconf, tj includeEmpty ]
backupWallet :: Auth
-> FilePath
-> IO ()
backupWallet auth fp =
callApi auth "backupwallet" [ tj fp ]
keyPoolRefill :: Auth -> IO ()
keyPoolRefill auth = callApi auth "keypoolrefill" []
unlockWallet :: Auth
-> Text
-> Integer
-> IO ()
unlockWallet auth pass timeout =
callApi auth "walletpassphrase" [ tj pass, tj timeout ]
changePassword :: Auth
-> Text
-> Text
-> IO ()
changePassword auth old new =
callApi auth "walletpassphrase" [ tj old, tj new ]
lockWallet :: Auth -> IO ()
lockWallet auth = callApi auth "walletlock" []
encryptWallet :: Auth -> Text -> IO ()
encryptWallet auth pass = stupidAPI <$> callApi auth "encryptwallet" [ tj pass ]
where
stupidAPI :: Text -> ()
stupidAPI = const ()
data IsValid = IsValid { getValid :: Bool }
instance FromJSON IsValid where
parseJSON (Object o) = IsValid <$> o .: "isvalid"
parseJSON _ = mzero
isAddressValid :: Auth -> Address -> IO Bool
isAddressValid auth addr = getValid <$> callApi auth "validateaddress" [ tj addr ]