H2ABVZI2NFTERQMJ2Z7WGMRNORV3OQQWCCFEN6YO5GAUT2ONM2MAC KKJSBWO6RNORAPTJPCCUJJNVI2OYTGLQKB3XJGOASH43GNTJBMKAC HMDM3B557TO5RYP2IGFFC2C2VN6HYZTDQ47CJY2O37BW55DSMFZAC 64C6AWH66FDKU6UE6Z6JPX2J2GBM2JOPTH2GL6LHKAIUBGNGDZ5AC DFOBMSAODB3NKW37B272ZXA2ML5HMIH3N3C4GT2DPEQS7ZFK4SNAC IPG33FAWXGEQ2PO6OXRT2PWWXHRNMPVUKKADL6UKKN5GD2CNZ25AC 4B66XH43UYRVNTX57ORJ7U6IJTRFKSUS6IJ3CXVODMEF7NA7UHVQC QO4NFWIYHF45PF7BA4IYGVZZ7CVZDHIV2427MQ6NXWHLIGBHBQCAC MJDIMD5BQEBC265AQAGYE2K6EHHS7ZMZY3I6WE5MCDSTA2E2VY7AC M4PWY5RUV72AEDCNC4O7UKBPHBIACR4354YTSC3SUZGWFV5UBJBQC X3ES7NUA42D2BF7CQDDKXM5CLMVCYA3H5YU5KXLPTGDBFPE2LNVAC B6HWAPDPXIWH7CHK5VLMWLL6EQN6NOFZEFYO47BPUY2ZO4SL7VDAC EFSXYZPOGA5M4DN65IEIDO7JK6U34DMQELAPHOIL2UAT6HRC66BAC ENNZIQJG4XJ62QCNRMLNAXN7ICTPCHQFZTURX6QSUYYWNADFJHXQC W35DDBFYF6Z4ZPCFEO5RPAONZLYCSNTXUSTS6FIUUVZHCI6Q7GHAC MU6WOCCJQWG4A5NLD3GBFATCE3SRE3QQCYXYH6WIKSGLHQOOBVRAC 2WOOGXDHVQ6L2MQYUTLJ6H6FVSQNJN6SMJL5DG7HAHFYPJLRT2SAC PBD7LZYQHXAA3KLH2ZUX5GW4UFML6BQ32KXZF4KZ6OYFASUYFJ5QC 4U7F3CPIDTK6JSEDMNMHVKSR7HOQDLZQD2PPVMDLHO5SFSIMUXZAC V2VDN77HCSRYYWXDJJ2XOVHV4P6PVWNJZLXZ7JUYPQEZQIH5BZ3QC GMYPBCWEB6NKURRILAHR3TJUKDOGR2ZMK5I6MS6P5G2LAGH36P3QC 6L5BK5EHPAOQX3JCKUJ273UDNAC23LPQL4HIJGM4AV3P3QK5OKIQC MJ6R42RCK2ASXAJ6QXDPMAW56RBOJ4F4HI2LFIV3KXFIKWYMQK3QC 4R7XIYK3BP664CO3YJ2VM64ES2JYN27UTQG5KS34OTEPAIODSZLQC NEDDHXUK3GNFMOFO3KLU7NRIHCTYNWBT3D6HTKZAOXFDE6HMDZ6AC 2XQD6KKKD6QVHFHAEMVE3XXY7X2T7BLTLL7XIILZAXNJJH2YONUQC IR75ZMX32SFFMDNV2I2L22X5JTWCOC4UUBCSPU7S6VHR6HFV6ADQC BSIUHCGFDFDFGWYMHZB7OVU3Z3IHPEUXRISIOPGZI2RUXZFDS2EQC ADMKQQGCGVSHHIMVQ4XFRDCG544SBJCYALSKZV45CQQBZ4ACUH2AC IZEVQF627FA7VV25KJAWYWGGC35LZUUBBQRPN5ZAINTQLPEDRTEAC 5IDB3IWSB6LFW4U772Y7BH5Y3FQOQ7IFWLVXDZE5XS6SKJITFV4QC PT4276XCOP5NJ3GRFJLIBZKVNVAOATAY5PLWV7FWK6RZW5FTEP5AC 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}
bip70URL <- bip70PaymentURL (nreq ^. Bitcoin.paymentRequestKey)mail <- buildBip70PaymentRequestEmail preqCfg req''' bip70URL
let bip70URIGen = Bitcoin.uriGen (pcfg' ^. P.bitcoinBillingOps)bip70URL <- bip70URIGen (nreq ^. Bitcoin.paymentRequestKey)mail <- traverse (buildBip70PaymentRequestEmail preqCfg req''') bip70URL
_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
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
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")
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
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
import Aftok.Currency.Bitcoinimport Aftok.Currency.Zcash (_Zatoshi)
import Aftok.Currency.Bitcoin (Address, NetworkMode, Satoshi, _Satoshi, getNetwork)import Aftok.Currency.Zcash (Zatoshi, _Zatoshi)
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;
#!/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"
readQConfig :: CT.Config -> Maybe PGSConfig -> IO QConfigreadQConfig cfg pc =QConfig
readServerConfig :: CT.Config -> Maybe PGSConfig -> IO ServerConfigreadServerConfig cfg pc =ServerConfig
---- 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)]]