OBFPJS2GHO2PEHBHGEHKIUOUAFIQHPIZXEVD2YIE3ZIE2PVMH5VAC
WO2MINIF4TXOHWSE7JWXRZYN64XRVLYIRFMF4SMPSOXKA2V77KMQC
QO4NFWIYHF45PF7BA4IYGVZZ7CVZDHIV2427MQ6NXWHLIGBHBQCAC
ADMKQQGCGVSHHIMVQ4XFRDCG544SBJCYALSKZV45CQQBZ4ACUH2AC
NTPC7KJEAPA34SBIA74FVQSJXYNW32RIUQTHUSUTKMEUCPLUIBJAC
AXKKXBWN4EMUOLV43WN52JSKJPBV7TLSGLNJW5EZXHSJNKCYUWOQC
64C6AWH66FDKU6UE6Z6JPX2J2GBM2JOPTH2GL6LHKAIUBGNGDZ5AC
WZUHEZSBRKHQMNWDKVG4X6DDIQEAXTGI6IGAJ5ERPRQ3W2KUMX4QC
NVOCQVASZWTKQJG7GPH7KHKZZR7NUG4WLV5YY4KAIRPCJRWCZPIAC
NMWWP4ZNOKHZKSJ6F5KYEREWXXR5F4UD35WOKI3EH42AZWVCTCJAC
RSEB2NFGUBTFESE5BJKDUVQL5Y5ZVGY5O4CJX2LNP63MS3NRHHZQC
Y35QCWYW2OTZ27ZVTH2BA3XJTUCJ2WMLKU32ZCOCDY3AW7TIZXRAC
GKGVYBZGPJXO7N7GLHLRNYQPXFHBQSNQN53OKRFCXLQEYDTC5I4QC
EQXRXRZDYCM7BDAVBOXQYPG6C7IJT3OFGNIXCDAHJJBRKAXNGL7AC
2KZPOGRBY6KBMO76F55ZKIVOLSG3O63VP3RHRZVANXYT3OLZ3OWQC
N4NDAZYTLSI2W22KT3SYXL257DBMSH3UT2BXOYM7LH7FSZAY4RLAC
Setup
# This file was auto-generated by cabal2nix. Please do NOT edit manually!
{ haskellPackages ? (import <nixpkgs> {}).haskellPackages }:
#{ cabal, aeson, bifunctors, classyPrelude
#, configurator, either, errors, groups, hourglass, hspec, lens
#, MonadCatchIOTransformers, mtl, networkBitcoin
#, optparseApplicative, safe, snapCore, snapServer, sqliteSimple
#, text, time, transformers
#}:
with haskellPackages; cabal.mkDerivation (self: {
pname = "quixotic";
version = "0.1";
src = "./.";
isLibrary = true;
isExecutable = true;
#buildTools = [ cabalInstall ];
buildDepends = [
aeson bifunctors classyPrelude configurator either
errors groups hourglass lens MonadCatchIOTransformers mtl
networkBitcoin optparseApplicative safe snapCore snapServer
sqliteSimple text time transformers
];
testDepends = [ aeson hspec text time ];
meta = {
description = "The Quixotic Collaboration Platform";
license = self.stdenv.lib.licenses.unfree;
platforms = self.ghc.meta.platforms;
};
})
{-# LANGUAGE ScopedTypeVariables, OverloadedStrings, NoImplicitPrelude #-}
module Main where
import ClassyPrelude
import Network.Bitcoin
import Control.Concurrent
import qualified Data.Configurator as C
import qualified Data.Vector as V
main :: IO ()
main = do
cfg <- parseConfig "quixotic-payouts.cfg"
loop cfg
loop :: QPConfig -> IO ()
loop cfg = do
threadDelay (pollingInterval cfg)
distributePayouts cfg
loop cfg
data QPConfig = QPConfig
{ pollingInterval :: Int
, bitcoindUrl :: Text
, bitcoindUser :: Text
, bitcoindPassword :: Text
, payoutMinConfirmations :: Int
}
parseConfig :: FilePath -> IO QPConfig
parseConfig cfgFile = do
cfg <- C.load [C.Required (fpToString cfgFile)]
QPConfig <$> C.require cfg "pollingInterval"
<*> C.require cfg "bitcoindUrl"
<*> C.require cfg "bitcoindUser"
<*> C.require cfg "bitcoindPassword"
<*> C.require cfg "payoutMinConfirmations"
auth :: QPConfig -> Auth
auth = Auth <$> bitcoindUrl <*> bitcoindUser <*> bitcoindPassword
distributePayouts :: QPConfig -> IO ()
distributePayouts cfg = do
-- find unspent transactions
unspent <- listUnspent (auth cfg) (Just . payoutMinConfirmations $ cfg) Nothing V.empty
putStrLn $ tshow unspent
-- get payouts amounts
-- create a new txn spending all UTXOs to payouts
pollingInterval = 10000000
bitcoindUrl = "http://localhost:18444/"
bitcoindUser = ""
bitcoindPassword = ""
Executable quixotic-payouts
default-language: Haskell2010
ghc-options: -Wall -Werror
hs-source-dirs: payouts
main-is: Main.hs
build-depends:
quixotic
, base
, classy-prelude >= 0.10.2
, containers
, either
, mtl >= 2 && < 3
, lens
, text
, time
, vector
, transformers
, configurator
, optparse-applicative
, bytestring
, network-bitcoin