MU6WOCCJQWG4A5NLD3GBFATCE3SRE3QQCYXYH6WIKSGLHQOOBVRAC JUFBTX45TKSZMB2D4CGNB73UYM5FXAV2QMKIHBSMHEQDAECYP7HQC LAROLAYUGJ4Q5AEFV5EJMIA2ZKBNCBWHHHPCJ3CKCNIUIYUKRFVQC X3ES7NUA42D2BF7CQDDKXM5CLMVCYA3H5YU5KXLPTGDBFPE2LNVAC M4PWY5RUV72AEDCNC4O7UKBPHBIACR4354YTSC3SUZGWFV5UBJBQC GCVQD44VRPQVKPZEPIC4AOIXLJIG2ZMV3QI2Y7KALUT6NVUBSGSAC 75N3UJ4JK56KXF56GASGPAWLFYGJDETVJNYTF4KXFCQM767JUU5AC EKI57EJR65DA5FPILAHGHHAIU5ITVGHA6V3775OX7GV5XD67OWRQC LHJ2HFXVUQ4VG25I7DADWU73G5K5WNZBDQ3SVNKFYLZ5BEYM4XCQC B6HWAPDPXIWH7CHK5VLMWLL6EQN6NOFZEFYO47BPUY2ZO4SL7VDAC EFSXYZPOGA5M4DN65IEIDO7JK6U34DMQELAPHOIL2UAT6HRC66BAC F2XLL7XWGUV4TJD4X2MJADYAQHCSB4HD2TPPEYVHEKHOQIOOFISAC WO2MINIF4TXOHWSE7JWXRZYN64XRVLYIRFMF4SMPSOXKA2V77KMQC GLFF5ZDKWI7WKPZSAEE3IUM27LL6DFOPIL4VPODXYXV3BCSCJ6GQC NAS4BFL43SIUAAC663R6VFBHQ2DKI45K6Y6ZKVQI7S5547HBAN7QC 5IDB3IWSB6LFW4U772Y7BH5Y3FQOQ7IFWLVXDZE5XS6SKJITFV4QC 64C6AWH66FDKU6UE6Z6JPX2J2GBM2JOPTH2GL6LHKAIUBGNGDZ5AC O5FVTOM6YFBLEPF3S576K6IMT6ZZ5VQCSB3YVXNS4CKBITKCRZ7AC 5OI44E4EEVYOMHDWNK2WA7K4L4JWRWCUJUNN2UAUGE5VY4W7GTNAC FXJQACESPGTLPG5ELXBU3M3OQXUZQQIR7HPIEHQ3FNUTMWVH4WBAC ASF3UPJLCX7KIUCNJD5KAXSPDXCUEJHLL4HBRTRUBPCW73IXOCWQC W35DDBFYF6Z4ZPCFEO5RPAONZLYCSNTXUSTS6FIUUVZHCI6Q7GHAC IPG33FAWXGEQ2PO6OXRT2PWWXHRNMPVUKKADL6UKKN5GD2CNZ25AC NVOCQVASZWTKQJG7GPH7KHKZZR7NUG4WLV5YY4KAIRPCJRWCZPIAC HALRDT2F22DAQ54M334YSKD2XJCAXDXEZPDKGMOWKH7XELBAS6MAC 4R7XIYK3BP664CO3YJ2VM64ES2JYN27UTQG5KS34OTEPAIODSZLQC 5ZSKPQ3KY6T6O5S6T6HW4OHJMQXA72WKJSJJMGKGX2WMFTNZ7EGAC Z3MK2PJ5U222DXRS22WCDHVPZ7HVAR3HOCUNXIGX6VMEPBQDF6PQC HMDM3B557TO5RYP2IGFFC2C2VN6HYZTDQ47CJY2O37BW55DSMFZAC RPAJLHMTUJU4AYNBOHVGHGGB4NY2NLY3BVPYN5FMWB3ZIMAUQHCQC BROSTG5KP3NUNLSYPVQID254TE47E5RKQAKLPIY7PGWETE6JNMTAC QMRKFEPGFBCEWAIXPEIG5ILKAJ2JH5L3TOITHR4HNJXK5FN3KXBQC 2J37EVJMX255K3XEJHTZGRPEIRMAQ62JQWOA7JU3YTZUB6PUPWVQC UWMGUJOW5X5HQTS76T2FD7MNAJF7SESPQVU5FDIZO52V75TT2X6AC ADMKQQGCGVSHHIMVQ4XFRDCG544SBJCYALSKZV45CQQBZ4ACUH2AC UUR6SMCAJMA7O3ZFUCQMPZFDDIPUVQ5IHUAC5F252YVD6H3JIKPQC LTSVBVA235BQAIU3SQURKSRHIAL33K47G4J6TSEP2K353OCHNJEAC bidOrder :: Bid -> Bid -> OrderingbidOrder = comparing costRatio `mappend` comparing (^. bidTime)
bidOrder ::forall c.IsCurrency c =>Bid c ->Bid c ->OrderingbidOrder = comparing costRatio <> comparing (^. bidTime)
secs bid = toRational $ bid ^. bidSecondsbtc bid = toRational $ bid ^. bidAmount . _SatoshicostRatio bid = secs bid / btc bid
costRatio :: Bid c -> RationalcostRatio bid = (toRational $ bid ^. bidSeconds) / (toRational $ bid ^. bidAmount . _Units)
| -- if the last bid will exceed the raise amount, reduce it to fittotal < raiseAmount' =let winFraction r = r % (bid ^. bidAmount . _Satoshi)remainderSeconds (Satoshi r) =
| total < raiseAmount' =-- if the last bid will exceed the raise amount, reduce it to fitlet winFraction r =(r ^. _Units) % (bid ^. bidAmount . _Units)remainderSeconds r =
adjustBid r = bid & bidSeconds .~ remainderSeconds r & bidAmount .~ rin toList $ adjustBid <$> raiseAmount' `ssub` total
adjustBid r =bid & bidSeconds .~ remainderSeconds r & bidAmount .~ rin toList $ adjustBid <$> raiseAmount' `csub` total
(raiseAmount' `ssub` submittedTotal)bidCommitment :: Satoshi -> Bid -> State Satoshi (Maybe Commitment)bidCommitment raiseAmount' bid = doraised <- getcase raised of-- if the total is fully within the raise amountx| x <> (bid ^. bidAmount) < raiseAmount' ->put (x <> bid ^. bidAmount)>> (pure . Just $ Commitment bid (bid ^. bidSeconds) (bid ^. bidAmount))-- if the last bid will exceed the raise amount, reduce it to fitx| x < raiseAmount' ->let winFraction r = r % (bid ^. bidAmount . _Satoshi)remainderSeconds (Satoshi r) =Seconds . round $ winFraction r * fromIntegral (bid ^. bidSeconds)in for (raiseAmount' `ssub` x) $ \remainder ->put (x <> remainder)*> (pure $ Commitment bid (remainderSeconds remainder) remainder)-- otherwise,_ -> pure Nothing
(raiseAmount' `csub` submittedTotal)
import qualified Aftok.Currency.Zcash as Zcashimport qualified Bippy.Types as Bitcoinimport Control.Lens (view)import qualified Haskoin.Address as Bitcoin
import qualified Aftok.Currency.Bitcoin as Bimport qualified Aftok.Currency.Zcash as Zimport Control.Lens (Iso')import qualified Text.Show
BTC :: Currency Bitcoin.Address Bitcoin.SatoshiZEC :: Currency Zcash.Address Zcash.Zatoshi
BTC :: Currency B.Address B.SatoshiZEC :: Currency Z.Address Z.Zatoshiinstance Eq (Currency a c) whereBTC == BTC = TrueZEC == ZEC = Trueinstance Show (Currency a c) whereshow = \caseBTC -> "BTC"ZEC -> "ZEC"
scaleCurrency :: Currency a c -> c -> Rational -> Maybe cscaleCurrency c amount factor = case c ofBTC -> (\(Bitcoin.Satoshi amt) -> Just $ Bitcoin.Satoshi ((round $ toRational amt * factor) :: Word64)) amountZEC -> (\amt -> Zcash.toZatoshi ((round $ toRational (view Zcash._Zatoshi amt) * factor) :: Word64)) amount
instance IsCurrency B.Satoshi wherecsub = B.ssubcscale (B.Satoshi amt) factor =let r = toRational amt * factorin if (r >= 0) then Just (B.Satoshi . round $ r) else Nothing_Units = B._Satoshicurrency' = Currency' BTCinstance IsCurrency Z.Zatoshi wherecsub = Z.zsubcscale (Z.Zatoshi amt) factor =let r = toRational amt * factorin if (r >= 0) then Just (Z.Zatoshi . round $ r) else Nothing_Units = Z._Zatoshicurrency' = Currency' ZEC
-- import Aftok.Currency ( Amount(..) )-- import qualified Aftok.Currency.Bitcoin as Bitcoinimport Aftok.Currency.Bitcoin (_Satoshi)-- import qualified Aftok.Currency.Zcash as Zcashimport Aftok.Database (Limit(..))
import Aftok.Currency (Amount (..))import Aftok.Database (Limit (..))
[sql| INSERT INTO auctions (project_id, initiator_id, name, description, raise_amount, end_time)VALUES (?, ?, ?, ?) RETURNING id |]( auc ^. (projectId . _ProjectId),auc ^. (initiator . _UserId),
[sql| INSERT INTO auctions (project_id, initiator_id, name, description, currency, raise_amount, start_time, end_time)VALUES (?, ?, ?, ?, ?, ?, ?, ?) RETURNING id |]( auc ^. projectId . _ProjectId,auc ^. initiator . _UserId,
ListAuctions :: ProjectId -> RangeQuery -> Limit -> DBOp [A.Auction]CreateAuction :: A.Auction -> DBOp A.AuctionIdFindAuction :: A.AuctionId -> DBOp (Maybe A.Auction)CreateBid :: A.AuctionId -> A.Bid -> DBOp A.BidIdFindBids :: A.AuctionId -> DBOp [(A.BidId, A.Bid)]
ListAuctions :: ProjectId -> RangeQuery -> Limit -> DBOp [A.Auction Amount]CreateAuction :: A.Auction Amount -> DBOp A.AuctionIdFindAuction :: A.AuctionId -> DBOp (Maybe (A.Auction Amount))CreateBid :: A.AuctionId -> A.Bid Amount -> DBOp A.BidIdFindBids :: A.AuctionId -> DBOp [(A.BidId, A.Bid Amount)]
parseAmountJSON :: Value -> Parser AmountparseAmountJSON = \caseObject o ->maybeT (fail $ "Expected to find one of [\"satoshi\", \"zatoshi\"] as a key.") pure $MaybeT (fmap (Amount BTC . review _Satoshi) <$> o .:? "satoshi")<|> MaybeT (fmap (Amount ZEC . review _Zatoshi) <$> o .:? "zatoshi")val -> fail $ "Value " <> show val <> " is not a JSON object."
parseRecurrence' (Object o) = parseRecurrence oparseRecurrence' val = fail $ "Value " <> show val <> " is not a JSON object."
parseRecurrence' = \case(Object o) -> parseRecurrence oval -> fail $ "Value " <> show val <> " is not a JSON object."
ALTER TABLE auctions ADD COLUMN currency currency_t NOT NULL;
data AuctionCreateRequest = CA {raiseAmount :: Word64, auctionStart :: C.UTCTime, auctionEnd :: C.UTCTime}
data AuctionCreateRequest= CA{ name :: Text,description :: Maybe Text,raiseAmount :: Amount,auctionStart :: C.UTCTime,auctionEnd :: C.UTCTime}
endpoints <- (,) <$> timeParam "after" <*> timeParam "before"let ival = case endpoints of(Just s, Just e) -> During s e(Nothing, Just e) -> Before e(Just s, Nothing) -> After s(Nothing, Nothing) -> Alwayslimit <- fromMaybe 1 <$> decimalParam "limit"
ival <- rangeQueryParamlimit <- Limit . fromMaybe 1 <$> decimalParam "limit"