packages feed

solana-staking-csvs 0.1.1.0 → 0.1.2.0

raw patch · 5 files changed

+80/−23 lines, 5 filesdep ~textPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: text

API changes (from Hackage documentation)

+ Console.SolanaStaking.Api: getYearsStakeRewards :: (MonadIO m, MonadReader Config m) => StakingPubKey -> Integer -> m ([APIError], [StakeReward])
+ Console.SolanaStaking.Api: runApi :: Monad m => APIResponse a -> m (Either APIError a)
+ Console.SolanaStaking.Main: [argYear] :: Args -> Maybe Integer
- Console.SolanaStaking.Api: getAllStakeRewards :: forall m. (MonadIO m, MonadReader Config m) => StakingPubKey -> m ([APIError], [StakeReward])
+ Console.SolanaStaking.Api: getAllStakeRewards :: (MonadIO m, MonadReader Config m) => StakingPubKey -> m ([APIError], [StakeReward])
- Console.SolanaStaking.Main: Args :: String -> String -> Maybe String -> Bool -> Args
+ Console.SolanaStaking.Main: Args :: String -> String -> Maybe String -> Bool -> Maybe Integer -> Args

Files

CHANGELOG.md view
@@ -3,6 +3,12 @@ ## master  +## v0.1.2.0++* Add `--year` flag to allow filtering the output by date.+* Bump dependency versions(aeson).++ ## v0.1.1.0  * Add `--cointracking` flag to format data for use with CoinTracking's Bulk
README.md view
@@ -15,7 +15,6 @@  TODO: -* Add `-Y <year>` flag to limit years exported(or start/end flags?). * Allow sourcing pubkey & apikey from env variables? * Move SolanaBeach API to separate, published package. 
solana-staking-csvs.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           solana-staking-csvs-version:        0.1.1.0+version:        0.1.2.0 synopsis:       Generate CSV Exports of your Solana Staking Rewards. description:    @solana-staking-csvs@ is a CLI program that queries the Solana blockchain                 for an account's staking accounts and exports all their staking rewards to@@ -25,7 +25,7 @@                 .                 See @solana-staking-csvs --help@ for additional options. category:       Web, Finance, Console-homepage:       https://github.com/prikhi/solana-staking-csv#readme+homepage:       https://github.com/prikhi/solana-staking-csvs#readme bug-reports:    https://github.com/prikhi/solana-staking-csvs/issues author:         Pavan Rikhi maintainer:     pavan.rikhi@gmail.com@@ -61,7 +61,7 @@       ViewPatterns   ghc-options: -Wall -Wcompat -Wincomplete-record-updates -Wincomplete-uni-patterns -Wredundant-constraints -O2   build-depends:-      aeson ==1.*+      aeson >=1 && <3     , base >=4.7 && <5     , bytestring <1     , cassava <1
src/Console/SolanaStaking/Api.hs view
@@ -13,6 +13,7 @@       -- * Requests / Responses     , APIResponse(..)     , APIError(..)+    , runApi     , raiseAPIError       -- ** Get Stake Accounts     , getAccountStakes@@ -20,6 +21,7 @@     , StakingAccount(..)       -- ** Get Staking Rewards     , getAllStakeRewards+    , getYearsStakeRewards     , getStakeRewards     , StakeReward(..)       -- ** Get Block@@ -47,12 +49,18 @@                                                 , Value(Object)                                                 , withObject                                                 )+import           Data.Bifunctor                 ( second ) import           Data.Scientific                ( FPFormat(Fixed)                                                 , Scientific                                                 , formatScientific                                                 ) import           Data.Text.Encoding             ( encodeUtf8 )-import           Data.Time.Clock.POSIX          ( POSIXTime )+import           Data.Time                      ( toGregorian+                                                , utctDay+                                                )+import           Data.Time.Clock.POSIX          ( POSIXTime+                                                , posixSecondsToUTCTime+                                                ) import           GHC.Generics                   ( Generic ) import           Network.HTTP.Req               ( (/:)                                                 , (/~)@@ -177,31 +185,59 @@ -- we have to use the earliest epoch as the @cursor@ in an additional -- request to see if there are any more rewards. getAllStakeRewards-    :: forall m-     . (MonadIO m, MonadReader Config m)+    :: (MonadIO m, MonadReader Config m)     => StakingPubKey     -> m ([APIError], [StakeReward]) getAllStakeRewards pubkey =-    getStakeRewards pubkey Nothing >>= runExceptT . raiseAPIError >>= go+    getStakeRewards pubkey Nothing >>= runApi >>= getStakeRewardsUntil+        pubkey+        (const True)         ([], [])++-- | Get the year's worth of staking rewards for the given account.+getYearsStakeRewards+    :: (MonadIO m, MonadReader Config m)+    => StakingPubKey+    -> Integer+    -> m ([APIError], [StakeReward])+getYearsStakeRewards pubkey year =+    fmap (second $ filter ((== year) . rewardYear))+        $   getStakeRewards pubkey Nothing+        >>= runApi+        >>= getStakeRewardsUntil pubkey stopAfterYear ([], [])   where-    go-        :: ([APIError], [StakeReward])-        -> Either APIError [StakeReward]-        -> m ([APIError], [StakeReward])-    go (errs, rws) = \case-        Left  err     -> return (err : errs, rws)-        Right rewards -> if length rewards < 5-            then return (errs, rewards <> rws)-            else-                let minEpoch = minimum $ map srEpoch rewards-                in  getStakeRewards pubkey (Just minEpoch)-                    >>= runExceptT-                    .   raiseAPIError-                    >>= go (errs, rewards <> rws)+    rewardYear :: StakeReward -> Integer+    rewardYear =+        (\(y, _, _) -> y)+            . toGregorian+            . utctDay+            . posixSecondsToUTCTime+            . srTimestamp +    stopAfterYear :: [StakeReward] -> Bool+    stopAfterYear rewards =+        let years = map rewardYear rewards in any (< year) years +-- | Fetch staking rewards until we get less than 5 rewards or the general+-- predicate returns true.+getStakeRewardsUntil+    :: (MonadIO m, MonadReader Config m)+    => StakingPubKey+    -> ([StakeReward] -> Bool)+    -> ([APIError], [StakeReward])+    -> Either APIError [StakeReward]+    -> m ([APIError], [StakeReward])+getStakeRewardsUntil pubkey cond (errs, rws) = \case+    Left  err     -> return (err : errs, rws)+    Right rewards -> if length rewards < 5 || cond rewards+        then return (errs, rewards <> rws)+        else+            let minEpoch = minimum $ map srEpoch rewards+            in  getStakeRewards pubkey (Just minEpoch)+                >>= runApi+                >>= getStakeRewardsUntil pubkey cond (errs, rewards <> rws) + -- | A Staking Reward Payment. data StakeReward = StakeReward     { srEpoch     :: Integer@@ -302,6 +338,10 @@                     Just (_ :: Bool) -> return ProcessingResponse                 Nothing -> fmap SuccessfulReponse . parseJSON $ Object o         _ -> SuccessfulReponse <$> parseJSON v++-- | Evaluate an API response.+runApi :: Monad m => APIResponse a -> m (Either APIError a)+runApi = runExceptT . raiseAPIError  -- | Pull the inner value out of an 'APIResponse' or throw the respective -- 'APIError'.
src/Console/SolanaStaking/Main.hs view
@@ -63,7 +63,11 @@     -- Grab rewards for each stake account     (stakeErrors, stakeRewards) <-         fmap (bimap concat concat . unzip) . forM stakes $ \sa -> do-            second (map (sa, )) <$> getAllStakeRewards (saPubKey sa)++            second (map (sa, ))+                <$> maybe (getAllStakeRewards (saPubKey sa))+                          (getYearsStakeRewards $ saPubKey sa)+                          argYear     unless (null stakeErrors) . liftIO $ do         hPutStrLn stderr "Got errors while fetching stake rewards:"         mapM_ (hPutStrLn stderr . ("\t" <>) . show) stakeErrors@@ -94,6 +98,8 @@     , argCoinTracking :: Bool     -- ^ Flag to enable writing/printing files formatted for CoinTracking     -- Imports.+    , argYear         :: Maybe Integer+    -- ^ Year to limit output to.     }     deriving (Show, Read, Eq, Data, Typeable) @@ -117,6 +123,12 @@                                 &= help "Generate a CoinTracking Import file."                                 &= explicit                                 &= name "cointracking"+            , argYear         = Nothing+                                &= help "Limit to given year"+                                &= explicit+                                &= name "y"+                                &= name "year"+                                &= typ "YYYY"             }         &= summary                (  "solana-staking-csvs v"