Add endpoint for payment request creation.
[?]
Feb 7, 2021, 2:10 AM
H2ABVZI2NFTERQMJ2Z7WGMRNORV3OQQWCCFEN6YO5GAUT2ONM2MACDependencies
- [2]
KKJSBWO6Add createPaymentRequestHandler - [3]
GMYPBCWEMake docker-compose work. - [4]
I2KHGVD4Require project permissions for access to most data. - [5]
IR75ZMX3Return actual events for interval ends, not just timestamps. - [6]
X3ES7NUAFine. I'll use ormolu. At least it doesn't break the code. - [7]
MJDIMD5BImprove documentation of local docker-compose setup. - [8]
O227CEAVAdds storage of original event JSON for some DBOp constructors. - [9]
AL37SVTCImplement payments service endpoints. - [10]
M3KUPGZKAdd invitation email template. - [11]
EFSXYZPOAutoformat everything with brittany. - [12]
4R7XIYK3Switch from ClassyPrelude to Relude - [13]
U256ZALIAdd captcha check to register route. - [14]
U7YAT2ZKAdd error reporting to signup form. - [15]
LTSVBVA2Update to a recent haskoin-core. Fix Stack build. - [16]
64C6AWH6Rename Ananke -> Quixotic, project reboot. - [17]
ENNZIQJGUse live signup API for client. - [18]
HMDM3B55Implement core of payments/billing infrastructure. - [19]
NEDDHXUKReformat via stylish-haskell - [20]
6L5BK5EHUse generic SMTP rather than Sendmail-specific mail client. - [21]
NLZ3JXLOFix formatting with stylish-haskell. - [22]
MU6WOCCJUpdate auctions to permit zcash as a funding currency. - [23]
PT4276XCAdd logout functionality. - [24]
IZEVQF62Work in progress replacing sqlite with postgres. - [25]
O5FVTOM6Undo JSON silliness, enable a couple more routes. - [26]
BROSTG5KBeginning of modularization of server. - [27]
W35DDBFYFactor common JSON conversions up into client lib module. - [28]
V2VDN77HEnable postgres configuration via environment variable for Heroku. - [29]
BSIUHCGFAdd payment response handler. - [30]
WZFQDWW4Add retrieval/storage of current exchange rate data to payment recording. - [31]
2XQD6KKKAdd invitation logic and clean up DBProg error handling. - [32]
4B66XH43Add sample billing config - [33]
VJPT6HDRFix remaining type errors after addition of login handler. - [34]
B6HWAPDPModularize & update to recent haskoin. - [35]
MJ6R42RCUtility methods for reading key & cert data. - [36]
UWMGUJOWAutoformat sources. - [37]
QMRKFEPGRefactor QDB to use a free monad algebra instead. - [38]
O2BZOX7MAdd signup form, captcha check. - [39]
DFOBMSAOInitial work on payments API - [40]
5IDB3IWSIntegrate zcashd-based zaddr validation. - [41]
XXJFUZOVAdd first revenue date to project payout computation. - [42]
4354Y4PEAdd endpoint to list project contributors. - [43]
4U7F3CPITHE GREAT RENAMING OF THINGS! - [44]
M4PWY5RUPreliminary work to add support for Zcash payments. - [45]
JFOEOFGAstylish-haskell formatting. - [46]
A6HKMINBAttempting to improve JSON handling. - [47]
IPG33FAWAdd billing daemon - [*]
QO4NFWIYAdded sample config file. - [*]
2WOOGXDHUse dbmigrations to manage database state. - [*]
PBD7LZYQPostgres & auth are beginning to function. - [*]
ADMKQQGCInitial empty Snap project.
Change contents
- edit in aftok.cabal at line 85
, HStringTemplate - replacement in aftok.cabal at line 159
other-modules: Aftok.QConfigother-modules: Aftok.ServerConfig - edit in aftok.cabal at line 212
, vector-space - replacement in conf/server/aftok.cfg at line 31
network = "test"# Signing key for BIP-70 payment requestssigningKeyFile = "/etc/aftok/aftok.bip70.key.pem"certsFile = "/etc/aftok/aftok.bip70-chain.cert.pem"exchangeRateServiceURI = "https://blockchain.info/ticker"bitcoin {networkMode = "test"# Signing key for BIP-70 payment requestssigningKeyFile = "/etc/aftok/aftok.bip70.key.pem"certsFile = "/etc/aftok/aftok.bip70-chain.cert.pem"exchangeRateServiceURI = "https://blockchain.info/ticker"bip70Host = "localhost:8443"}zcash {minPayment = 100} - edit in daemon/AftokD/AftokM.hs at line 6
{-# LANGUAGE TypeApplications #-} - replacement in daemon/AftokD/AftokM.hs at line 12
( Billable,Billable',( Billable', - edit in daemon/AftokD/AftokM.hs at line 18
paymentRequestMemoTemplate, - edit in daemon/AftokD/AftokM.hs at line 23
import Aftok.Currency.Zcash (Zatoshi (..)) - edit in daemon/AftokD/AftokM.hs at line 26
import Aftok.Payments.Bitcoin (BillingOps (..), PaymentsConfig) - replacement in daemon/AftokD/AftokM.hs at line 27
import qualified Aftok.Payments.Zcash as Zcashimport qualified Aftok.Payments.Bitcoin as Bitcoin - edit in daemon/AftokD/AftokM.hs at line 62
import Data.Thyme.Time as C - replacement in daemon/AftokD/AftokM.hs at line 69
import Network.URI( URI,parseURI,)import Network.URI (URI) - edit in daemon/AftokD/AftokM.hs at line 82
| MailGenError - replacement in daemon/AftokD/AftokM.hs at line 95
_pcfg :: !PaymentsConfig_pcfg :: !(P.PaymentsConfig AftokM) - edit in daemon/AftokD/AftokM.hs at line 98
makeLenses ''AftokMEnv - edit in daemon/AftokD/AftokM.hs at line 106
makeLenses ''AftokMEnv - replacement in daemon/AftokD/AftokM.hs at line 117
let f a = (a ^. dcfg . D.billingConfig . AC.networkMode, a ^. conn)let f a = (a ^. dcfg . D.billingConfig . AC.bitcoinConfig . AC.networkMode, a ^. conn) - replacement in daemon/AftokD/AftokM.hs at line 138
btcCfg <- asks _pcfglet btcOps = BillingOps _memoGen (fmap Just . bip70PaymentURL) _payloadGenzecCfg = Zcash.PaymentsConfig (Zatoshi 100)pcfg' = P.PaymentsConfig btcOps btcCfg zecCfgpcfg' <- asks _pcfg - edit in daemon/AftokD/AftokM.hs at line 154
pcfg' <- liftIO $ AC.toPaymentsConfig @AftokM (cfg ^. dcfg . D.billingConfig) - replacement in daemon/AftokD/AftokM.hs at line 162
bip70URL <- bip70PaymentURL (nreq ^. Bitcoin.paymentRequestKey)mail <- buildBip70PaymentRequestEmail preqCfg req''' bip70URLlet bip70URIGen = Bitcoin.uriGen (pcfg' ^. P.bitcoinBillingOps)bip70URL <- bip70URIGen (nreq ^. Bitcoin.paymentRequestKey)mail <- traverse (buildBip70PaymentRequestEmail preqCfg req''') bip70URL - replacement in daemon/AftokD/AftokM.hs at line 170
liftIO $ mailer _smtpUser _smtpPass mailcase mail ofJust email -> liftIO $ mailer _smtpUser _smtpPass emailNothing -> throwError MailGenError - edit in daemon/AftokD/AftokM.hs at line 230[3.3552]→[3.7417:7418](∅→∅),[3.7417]→[3.7417:7418](∅→∅),[3.7418]→[3.4765:4960](∅→∅),[3.4960]→[3.6448:6494](∅→∅),[3.7639]→[3.6448:6494](∅→∅),[3.6494]→[3.4961:5012](∅→∅),[3.5012]→[3.3875:3914](∅→∅),[3.6557]→[3.3875:3914](∅→∅),[3.3914]→[3.5013:5120](∅→∅),[3.5120]→[3.4043:4148](∅→∅),[3.4043]→[3.4043:4148](∅→∅),[3.4148]→[3.7983:8127](∅→∅),[3.7983]→[3.7983:8127](∅→∅),[3.8127]→[3.5121:5217](∅→∅),[3.5217]→[3.8197:8210](∅→∅),[3.8197]→[3.8197:8210](∅→∅),[3.8210]→[3.4149:4219](∅→∅),[3.4219]→[3.8280:8354](∅→∅),[3.6684]→[3.8280:8354](∅→∅),[3.8280]→[3.8280:8354](∅→∅),[3.8354]→[3.4220:4356](∅→∅),[3.4356]→[3.6804:6810](∅→∅),[3.6804]→[3.6804:6810](∅→∅),[3.6810]→[3.8454:8505](∅→∅),[3.8454]→[3.8454:8505](∅→∅),[3.8505]→[3.5218:5233](∅→∅),[3.5233]→[3.4371:4384](∅→∅),[3.4371]→[3.4371:4384](∅→∅),[3.4384]→[3.5234:5256](∅→∅),[3.5256]→[3.4419:4468](∅→∅),[3.4419]→[3.4419:4468](∅→∅),[3.4468]→[3.5257:5290](∅→∅)
_memoGen ::DB.MonadDB m =>Billable Satoshi ->C.Day ->C.UTCTime ->m (Maybe Text)_memoGen bill billingDate requestTime = doreq <- traverseOf B.project DB.findProjectOrError billlet template =(newSTMP . T.unpack)<$> (bill ^. paymentRequestMemoTemplate)setAttrs =setManyAttrib[ ("project_name", req ^. B.project . projectName),("subscription", req ^. B.name),("billing_date", show billingDate),("issue_time", show requestTime)]pure $ fmap (render . setAttrs) template-- The same URL is used for retrieving a BIP-70 payment request and for submitting-- the response.bip70PaymentURL :: Bitcoin.PaymentKey -> AftokM URIbip70PaymentURL (Bitcoin.PaymentKey k) = doenv <- asklet hostname = env ^. (dcfg . D.paymentRequestConfig . D.aftokHost)paymentRequestPath = "https://" <> hostname <> "/pay/" <> kmaybe( throwError. ConfigError$ "Could not parse path "<> paymentRequestPath<> " to a valid URI")pure(parseURI $ show paymentRequestPath)_payloadGen ::Monad m =>Billable Satoshi ->C.Day ->C.UTCTime ->m (Maybe ByteString)_payloadGen _ _ _ = pure Nothing - edit in lib/Aftok/Config.hs at line 5
import qualified Aftok.Billing as Bimport Aftok.Project (projectName) - edit in lib/Aftok/Config.hs at line 8
import qualified Aftok.Currency.Bitcoin.Payments as Bitcoinimport Aftok.Currency.Zcash (Zatoshi(..))import Aftok.Database (MonadDB, findProjectOrError)import Aftok.Payments (PaymentsConfig(..)) - edit in lib/Aftok/Config.hs at line 13
import qualified Aftok.Payments.Zcash as Zcash - replacement in lib/Aftok/Config.hs at line 17
makeClassy,makeLenses,traverseOf, - edit in lib/Aftok/Config.hs at line 22
import Data.Thyme.Clock (UTCTime)import Data.Thyme.Time (Day) - edit in lib/Aftok/Config.hs at line 37
import Network.URI (URI, parseURI) - edit in lib/Aftok/Config.hs at line 39
import Text.StringTemplate( newSTMP,render,setManyAttrib,) - edit in lib/Aftok/Config.hs at line 45
readConnectInfo :: C.Config -> IO ConnectInforeadConnectInfo cfg =ConnectInfo<$> C.require cfg "host"<*> C.require cfg "port"<*> C.require cfg "user"<*> C.require cfg "password"<*> C.require cfg "database" - edit in lib/Aftok/Config.hs at line 61
makeLenses ''SmtpConfig - replacement in lib/Aftok/Config.hs at line 64
makeClassy ''SmtpConfigreadSmtpConfig :: C.Config -> IO SmtpConfigreadSmtpConfig cfg =SmtpConfig<$> C.require cfg "smtpHost"<*> ((fmap . fmap) fromInteger $ C.lookup cfg "smtpPort")<*> C.require cfg "smtpUser"<*> C.require cfg "smtpKey" - replacement in lib/Aftok/Config.hs at line 72
data BillingConfig= BillingConfigdata BitcoinConfig= BitcoinConfig - replacement in lib/Aftok/Config.hs at line 78
_minPayment :: Satoshi_minPayment :: Satoshi,_bip70Host :: NS.HostName - edit in lib/Aftok/Config.hs at line 81
makeLenses ''BitcoinConfig - replacement in lib/Aftok/Config.hs at line 84
makeClassy ''BillingConfigdata BillingConfig= BillingConfig{ _bitcoinConfig :: BitcoinConfig, _zcashConfig :: Zcash.PaymentsConfig} - replacement in lib/Aftok/Config.hs at line 90[3.11879]→[3.3798:3842](∅→∅),[3.3842]→[3.11924:11945](∅→∅),[3.11924]→[3.11924:11945](∅→∅),[3.11945]→[3.11613:11786](∅→∅)
readSmtpConfig :: C.Config -> IO SmtpConfigreadSmtpConfig cfg =SmtpConfig<$> C.require cfg "smtpHost"<*> ((fmap . fmap) fromInteger $ C.lookup cfg "smtpPort")<*> C.require cfg "smtpUser"<*> C.require cfg "smtpKey"makeLenses ''BillingConfig - edit in lib/Aftok/Config.hs at line 95
<$> (readBitcoinConfig $ C.subconfig "bitcoin" cfg)<*> (readZcashPaymentsConfig $ C.subconfig "zcash" cfg)readBitcoinConfig :: C.Config -> IO BitcoinConfigreadBitcoinConfig cfg =BitcoinConfig - edit in lib/Aftok/Config.hs at line 106
<*> C.require cfg "bip70Host" - replacement in lib/Aftok/Config.hs at line 108[3.12594]→[3.3943:3989](∅→∅),[3.3989]→[3.12641:12663](∅→∅),[3.12641]→[3.12641:12663](∅→∅),[3.12663]→[3.11990:12157](∅→∅)
readConnectInfo :: C.Config -> IO ConnectInforeadConnectInfo cfg =ConnectInfo<$> C.require cfg "host"<*> C.require cfg "port"<*> C.require cfg "user"<*> C.require cfg "password"<*> C.require cfg "database"readZcashPaymentsConfig :: C.Config -> IO Zcash.PaymentsConfigreadZcashPaymentsConfig cfg =Zcash.PaymentsConfig<$> (Zatoshi <$> C.require cfg "minPayment") - replacement in lib/Aftok/Config.hs at line 113
toPaymentsConfig :: BillingConfig -> IO Bitcoin.PaymentsConfigtoPaymentsConfig c = dotoBitcoinPaymentsConfig :: BitcoinConfig -> IO Bitcoin.PaymentsConfigtoBitcoinPaymentsConfig c = do - edit in lib/Aftok/Config.hs at line 129[3.6657]
toPaymentsConfig :: MonadDB m => BillingConfig -> IO (PaymentsConfig m)toPaymentsConfig cfg = dobtcCfg <- toBitcoinPaymentsConfig (cfg ^. bitcoinConfig)let btcOps = Bitcoin.BillingOps _memoGen (_uriGen $ cfg ^. bitcoinConfig . bip70Host) _payloadGenpure $ PaymentsConfig {_bitcoinBillingOps = btcOps,_bitcoinPaymentsConfig = btcCfg,_zcashPaymentsConfig = cfg ^. zcashConfig}_memoGen ::MonadDB m =>B.Billable Satoshi ->Day ->UTCTime ->m (Maybe Text)_memoGen bill billingDate requestTime = doreq <- traverseOf B.project findProjectOrError billlet template =(newSTMP . toString)<$> (bill ^. B.paymentRequestMemoTemplate)setAttrs =setManyAttrib[ ("project_name", req ^. B.project . projectName),("subscription", req ^. B.name),("billing_date", show billingDate),("issue_time", show requestTime)]pure $ fmap (render . setAttrs) template_payloadGen ::Monad m =>B.Billable Satoshi ->Day ->UTCTime ->m (Maybe ByteString)_payloadGen _ _ _ = pure Nothing-- The same URL is used for retrieving a BIP-70 payment request and for submitting-- the response._uriGen ::Monad m =>NS.HostName ->Bitcoin.PaymentKey-> m (Maybe URI)_uriGen hostname (Bitcoin.PaymentKey k) =let paymentRequestPath = "https://" <> fromString hostname <> "/pay/" <> kin pure . parseURI $ show paymentRequestPath - edit in lib/Aftok/Currency/Bitcoin/Bip70.hs at line 5
protoBase64,fromBase64Proto, - edit in lib/Aftok/Currency/Bitcoin/Bip70.hs at line 11[3.6805]
import qualified Data.ByteString.Base64 as B64import Data.ProtocolBuffers (Decode, Encode, decodeMessage, encodeMessage)import Data.Serialize.Get (runGet)import Data.Serialize.Put (runPut)protoBase64 :: Encode a => a -> TextprotoBase64 = B64.encodeBase64 . runPut . encodeMessagefromBase64Proto :: Decode a => Text -> Either Text afromBase64Proto t = (first toText . runGet decodeMessage) <=< B64.decodeBase64 $ encodeUtf8 t - edit in lib/Aftok/Database/PostgreSQL/Json.hs at line 6
import qualified Aftok.Currency.Bitcoin.Bip70 as Bip70 - edit in lib/Aftok/Database/PostgreSQL/Json.hs at line 25
import qualified Data.ByteString.Base64 as B64import Data.ProtocolBuffers (Decode, Encode, decodeMessage, encodeMessage)import Data.Serialize.Get (runGet)import Data.Serialize.Put (runPut) - edit in lib/Aftok/Database/PostgreSQL/Json.hs at line 29
protoBase64 :: Encode a => a -> TextprotoBase64 = B64.encodeBase64 . runPut . encodeMessagefromBase64Proto :: Decode a => Text -> Either Text afromBase64Proto t = (first toText . runGet decodeMessage) <=< B64.decodeBase64 $ encodeUtf8 t - replacement in lib/Aftok/Database/PostgreSQL/Json.hs at line 35
"payment_request_protobuf_64" .= (r ^. Bitcoin.bip70Request . to protoBase64)"payment_request_protobuf_64" .= (r ^. Bitcoin.bip70Request . to Bip70.protoBase64) - replacement in lib/Aftok/Database/PostgreSQL/Json.hs at line 45
<*> ( either (fail . toString) pure . fromBase64Proto =<< (o .: "payment_request_protobuf_64")<*> ( either (fail . toString) pure . Bip70.fromBase64Proto =<< (o .: "payment_request_protobuf_64") - replacement in lib/Aftok/Database/PostgreSQL/Json.hs at line 74
"payment_protobuf_64" .= (bp ^. Bitcoin.bip70Payment . to protoBase64)"payment_protobuf_64" .= (bp ^. Bitcoin.bip70Payment . to Bip70.protoBase64) - replacement in lib/Aftok/Database/PostgreSQL/Json.hs at line 87
<*> ( either (fail . unpack) pure . fromBase64Proto =<< (o .: "payment_protobuf_64")<*> ( either (fail . unpack) pure . Bip70.fromBase64Proto =<< (o .: "payment_protobuf_64") - replacement in lib/Aftok/Database/PostgreSQL/Users.hs at line 96
AND currency = 'BTC'AND is_primary = true |]AND is_primary = trueAND btc_addr IS NOT NULL |] - replacement in lib/Aftok/Database/PostgreSQL/Users.hs at line 105
AND currency = 'ZEC'AND is_primary = true |]AND is_primary = trueAND zcash_addr IS NOT NULL |] - replacement in lib/Aftok/Json.hs at line 13
import Aftok.Currency.Bitcoinimport Aftok.Currency.Zcash (_Zatoshi)import Aftok.Currency.Bitcoin (Address, NetworkMode, Satoshi, _Satoshi, getNetwork)import Aftok.Currency.Zcash (Zatoshi, _Zatoshi) - replacement in lib/Aftok/Json.hs at line 165
BTC -> object ["satoshi" .= (value ^. _Satoshi)]ZEC -> object ["zatoshi" .= (value ^. _Zatoshi)]BTC -> satsJSON valueZEC -> zatsJSON valuezatsJSON :: Zatoshi -> ValuezatsJSON value = object ["zatoshi" .= (value ^. _Zatoshi)] - edit in lib/Aftok/Json.hs at line 171
satsJSON :: Satoshi -> ValuesatsJSON value = object ["satoshi" .= (value ^. _Satoshi)] - file addition: 2021-02-07_02-43-08_account_detail.txt[50.1]
Description: (Describe migration here.)Created: 2021-02-07 02:43:18.803817984 UTCDepends: 2020-11-25_04-22-24_zcash-supportApply: |ALTER TABLE cryptocurrency_accounts ADD COLUMN name text;ALTER TABLE cryptocurrency_accounts ADD COLUMN description text;ALTER TABLE cryptocurrency_accounts DROP COLUMN currency; - file addition: create_payment_request.sh[51.1220]
#!/bin/bashif [ -f ".env" ]; thensource .envfiif [ -z "${AFTOK_HOST}" ]; thenAFTOK_HOST="aftok.com"fiif [ -z "${PID}" ]; thenread -p "Project UUID: " PIDechofiif [ -z "${USER}" ]; thenread -p "Username: " USERechofiread -p "Billable ID: " BIDcurl --verbose \${ALLOW_INSECURE} \--user $USER \--header "Content-Type: application/json" \--data "{}" \"https://$AFTOK_HOST/api/projects/$PID/billables/$BID/paymentRequests" - file move: QConfig.hs → ServerConfig.hs
- replacement in server/Aftok/ServerConfig.hs at line 4
module Aftok.QConfig wheremodule Aftok.ServerConfig where - edit in server/Aftok/ServerConfig.hs at line 26
- replacement in server/Aftok/ServerConfig.hs at line 28
data QConfig= QConfigdata ServerConfig= ServerConfig - replacement in server/Aftok/ServerConfig.hs at line 43
makeLenses ''QConfigmakeLenses ''ServerConfig - replacement in server/Aftok/ServerConfig.hs at line 45[3.5085]→[3.4378:4418](∅→∅),[3.4418]→[3.7326:7351](∅→∅),[3.32776]→[3.7326:7351](∅→∅),[3.5133]→[3.7326:7351](∅→∅)
loadQConfig :: P.FilePath -> IO QConfigloadQConfig cfgFile = doloadServerConfig :: P.FilePath -> IO ServerConfigloadServerConfig cfgFile = do - replacement in server/Aftok/ServerConfig.hs at line 50
readQConfig cfg dbEnvCfgreadServerConfig cfg dbEnvCfg - replacement in server/Aftok/ServerConfig.hs at line 52
readQConfig :: CT.Config -> Maybe PGSConfig -> IO QConfigreadQConfig cfg pc =QConfigreadServerConfig :: CT.Config -> Maybe PGSConfig -> IO ServerConfigreadServerConfig cfg pc =ServerConfig - replacement in server/Aftok/ServerConfig.hs at line 84
baseSnapConfig :: QConfig -> SC.Config m a -> SC.Config m abaseSnapConfig :: ServerConfig -> SC.Config m a -> SC.Config m a - replacement in server/Aftok/ServerConfig.hs at line 89
snapConfig :: QConfig -> IO (SC.Config Snap a)snapConfig :: ServerConfig -> IO (SC.Config Snap a) - edit in server/Aftok/Snaplet/Billing.hs at line 8
paymentRequestDetailJSON, - edit in server/Aftok/Snaplet/Billing.hs at line 22
import Aftok.Currency.Bitcoin.Bip70 (protoBase64)import qualified Aftok.Currency.Bitcoin.Payments as Bitcoin - edit in server/Aftok/Snaplet/Billing.hs at line 25
import qualified Aftok.Currency.Zcash.Zip321 as Zip321 - edit in server/Aftok/Snaplet/Billing.hs at line 28
MonadDB, - replacement in server/Aftok/Snaplet/Billing.hs at line 33
import Aftok.Json (Version (..), badVersion, unversion)import Aftok.Json( Version (..),badVersion,obj,satsJSON,unversion,v1,zatsJSON,) - replacement in server/Aftok/Snaplet/Billing.hs at line 43
( PaymentRequestId,( PaymentRequest' (..),PaymentRequestId, - replacement in server/Aftok/Snaplet/Billing.hs at line 52
( PaymentRequestError (..),( NativeRequest (..),PaymentRequestError (..),_PaymentRequestId,billable,nativeRequest,createdAt, - replacement in server/Aftok/Snaplet/Billing.hs at line 70
import Control.Lens ((.~), (^.))-- import Data.Aeson ()import Control.Lens ((.~), (^.), to)import Data.Aeson - replacement in server/Aftok/Snaplet/Billing.hs at line 73
( (.:),(.:?),Object,( Pair, - edit in server/Aftok/Snaplet/Billing.hs at line 75
Value (..), - edit in server/Aftok/Snaplet/Billing.hs at line 76
parseJSON, - edit in server/Aftok/Snaplet/Billing.hs at line 77
import Data.AffineSpace ((.+^)) - edit in server/Aftok/Snaplet/Billing.hs at line 81
import Snap.Core (MonadSnap) - replacement in server/Aftok/Snaplet/Billing.hs at line 129
MonadSnap m =>MonadDB m => - replacement in server/Aftok/Snaplet/Billing.hs at line 136
billable <- snapEval $ withProjectAuth pid uid (FindBillable bid)billableMay <- snapEval $ withProjectAuth pid uid (FindBillable bid) - replacement in server/Aftok/Snaplet/Billing.hs at line 139
case billable ofcase billableMay of - replacement in server/Aftok/Snaplet/Billing.hs at line 170
---- paymentRequestDetailJSON :: PaymentRequestDetail Amount -> Object-- paymentRequestDetailJSON r = obj $ concat-- [ ["payment_request_id" .= view () r]-- , paymentRequestKV $ view _2 r-- , subscriptionKV $ view _3 r-- , billableKV $ view _4 r-- ]paymentRequestDetailJSON :: (PaymentRequestId, SomePaymentRequestDetail) -> ObjectpaymentRequestDetailJSON (rid, (SomePaymentRequest req)) =obj $ ["payment_request_id" .= (rid ^. _PaymentRequestId)] <> fields reqwherefields :: PaymentRequest' (Billable' ProjectId UserId) c -> [Pair]fields r = case r ^. nativeRequest of(Zip321Request req') ->[ "total" .= (r ^. billable . B.amount . to zatsJSON),"expires_at" .= ((r ^. createdAt) .+^ (r ^. billable . B.requestExpiryPeriod)),"native_request" .= zip321PaymentRequestJSON req'](Bip70Request req') ->[ "total" .= (r ^. billable . B.amount . to satsJSON),"expires_at" .= ((r ^. createdAt) .+^ (r ^. billable . B.requestExpiryPeriod)),"native_request" .= bip70PaymentRequestJSON req']bip70PaymentRequestJSON :: Bitcoin.PaymentRequest -> Valuebip70PaymentRequestJSON r =v1 . obj $[ "bip70_request".= object[ "payment_key" .= (r ^. Bitcoin.paymentRequestKey . Bitcoin._PaymentKey),"payment_request_protobuf_64" .= (r ^. Bitcoin.bip70Request . to protoBase64)]] - edit in server/Aftok/Snaplet/Billing.hs at line 198
zip321PaymentRequestJSON :: Zip321.PaymentRequest -> Valuezip321PaymentRequestJSON r =v1 . obj $["zip321_request" .= (toJSON . Zip321.toURI $ r)] - replacement in server/Aftok/Snaplet/Payments.hs at line 54
bip70PaymentResponseHandler :: AC.BillingConfig -> S.Handler App App PaymentIdbip70PaymentResponseHandler :: AC.BitcoinConfig -> S.Handler App App PaymentId - replacement in server/Aftok/Snaplet/Projects.hs at line 25
import Aftok.QConfig as QCimport Aftok.ServerConfig as QC - replacement in server/Aftok/Snaplet/Projects.hs at line 151
projectInviteHandler :: QConfig -> S.Handler App App ()projectInviteHandler :: ServerConfig -> S.Handler App App () - replacement in server/Aftok/Snaplet/Projects.hs at line 171
QConfig ->ServerConfig -> - edit in server/Main.hs at line 10
import Aftok.Database.PostgreSQL (QDBM) - replacement in server/Main.hs at line 13
import Aftok.QConfig as Qimport Aftok.ServerConfig - replacement in server/Main.hs at line 51
cfg <- loadQConfig . decodeString $ fromRight "conf/aftok.cfg" cfgPathcfg <- loadServerConfig . decodeString $ fromRight "conf/aftok.cfg" cfgPath - replacement in server/Main.hs at line 55
registerOps :: Manager -> QConfig -> RegisterOps IOregisterOps :: Manager -> ServerConfig -> RegisterOps IO - replacement in server/Main.hs at line 62
appInit :: QConfig -> SnapletInit App AppappInit :: ServerConfig -> SnapletInit App App - edit in server/Main.hs at line 65
paymentsConfig <- liftIO $ C.toPaymentsConfig @QDBM (cfg ^. billingConfig) - replacement in server/Main.hs at line 77
let nmode = cfg ^. billingConfig . C.networkModelet nmode = cfg ^. billingConfig . C.bitcoinConfig . C.networkMode - edit in server/Main.hs at line 111
-- Routes for billables - edit in server/Main.hs at line 118
paymentRequestCreateRoute =serveJSON paymentRequestDetailJSON $ method POST (createPaymentRequestHandler paymentsConfig) - replacement in server/Main.hs at line 131
method POST (bip70PaymentResponseHandler $ cfg ^. billingConfig)method POST (bip70PaymentResponseHandler $ cfg ^. billingConfig . C.bitcoinConfig) - edit in server/Main.hs at line 149
("projects/:projectId/billables/:billableId/paymentRequests", paymentRequestCreateRoute), -- create_billable.sh / list_project_billables.sh