Skip to content

Commit 4ff9398

Browse files
authored
Merge pull request #60 from geniusyield/57-taptools
feat: add taptools provider, add nft token in place order response...
2 parents ff73c7e + 8c5442c commit 4ff9398

File tree

21 files changed

+623
-113
lines changed

21 files changed

+623
-113
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ For details please see the following section:
131131
maestroToken: YOUR_MAESTRO_TOKEN
132132
# API key to protect server endpoints with. It's value must be provided under `api-key` header of request.
133133
serverApiKey: YOUR_SECRET_KEY
134+
# TapTools API key, to access historical prices using TapTools.
135+
tapToolsApiKey: YOUR_TAP_TOOLS_KEY
134136
# Optionally, wallet key details if one wants server to be able to sign transactions using this key.
135137
wallet:
136138
tag: mnemonicWallet

geniusyield-dex-api/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Revision history for geniusyield-dex-api
22

3+
## 0.2.1.0 -- 2024-05-07
4+
5+
* Adds `placePartialOrder''`, `placePartialOrderWithVersion''` to also return for order's NFT token.
6+
* Exports `placePartialOrder''`, `placePartialOrderWithVersion`, `placePartialOrderWithVersion'` and `placePartialOrderWithVersion''`.
7+
38
## 0.2.0.0 -- 2024-04-17
49

510
* Adds support for v1.1 family of scripts.

geniusyield-dex-api/geniusyield-dex-api.cabal

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ name: geniusyield-dex-api
44
-- PVP summary: +-+------- breaking API changes
55
-- | | +----- non-breaking API additions
66
-- | | | +--- code changes with no API change
7-
version: 0.2.0.0
7+
version: 0.2.1.0
88
synopsis: API code to interact with GeniusYield DEX.
99
description:
1010
API code to interact with GeniusYield DEX. Learn more about GeniusYield by visiting https://www.geniusyield.co/.
@@ -72,10 +72,8 @@ library
7272
build-depends:
7373
, aeson
7474
, base ^>=4.16.4.0
75-
, bytestring
7675
, containers
7776
, data-default
78-
, file-embed
7977
, http-types
8078
, lens
8179
, mtl

geniusyield-dex-api/src/GeniusYield/Api/Dex/PartialOrder.hs

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ module GeniusYield.Api.Dex.PartialOrder (
4040
-- * Tx constructors
4141
placePartialOrder,
4242
placePartialOrder',
43+
placePartialOrder'',
44+
placePartialOrderWithVersion,
45+
placePartialOrderWithVersion',
46+
placePartialOrderWithVersion'',
4347
completelyFillPartialOrder,
4448
partiallyFillPartialOrder,
4549
fillPartialOrder,
@@ -603,7 +607,33 @@ placePartialOrder'
603607
GYTxOutRef
604608
PartialOrderConfigInfoF GYAddress
605609
m (GYTxSkeleton 'PlutusV2)
606-
placePartialOrder' pors = placePartialOrderWithVersion' pors defaultPOCVersion
610+
placePartialOrder' pors addr (offerAmt, offerAC) priceAC price start end addLov addOff stakeCred cfgRef pocd = snd <$> placePartialOrder'' pors addr (offerAmt, offerAC) priceAC price start end addLov addOff stakeCred cfgRef pocd
611+
612+
placePartialOrder''
613+
(GYDexApiMonad m a, HasCallStack)
614+
PORefs
615+
GYAddress
616+
-- ^ Order owner
617+
(Natural, GYAssetClass)
618+
-- ^ Amount and asset to offer.
619+
GYAssetClass
620+
-- ^ The asset being asked for as payment.
621+
GYRational
622+
-- ^ The price for one unit of the offered asset.
623+
Maybe GYTime
624+
-- ^ The earliest time when the order can be filled (optional).
625+
Maybe GYTime
626+
-- ^ The latest time when the order can be filled (optional).
627+
Natural
628+
-- ^ Additional lovelace fee.
629+
Natural
630+
-- ^ Additional fee in offered tokens.
631+
Maybe GYStakeCredential
632+
-- ^ Stake credential of user. We do not support pointer reference.
633+
GYTxOutRef
634+
PartialOrderConfigInfoF GYAddress
635+
m (GYAssetClass, GYTxSkeleton 'PlutusV2)
636+
placePartialOrder'' pors = placePartialOrderWithVersion'' pors defaultPOCVersion
607637

608638
placePartialOrderWithVersion'
609639
(GYDexApiMonad m a, HasCallStack)
@@ -630,7 +660,34 @@ placePartialOrderWithVersion'
630660
GYTxOutRef
631661
PartialOrderConfigInfoF GYAddress
632662
m (GYTxSkeleton 'PlutusV2)
633-
placePartialOrderWithVersion' pors pocVersion addr (offerAmt, offerAC) priceAC price start end addLov addOff stakeCred cfgRef pocd = do
663+
placePartialOrderWithVersion' pors pocVersion addr (offerAmt, offerAC) priceAC price start end addLov addOff stakeCred cfgRef pocd = snd <$> placePartialOrderWithVersion'' pors pocVersion addr (offerAmt, offerAC) priceAC price start end addLov addOff stakeCred cfgRef pocd
664+
665+
placePartialOrderWithVersion''
666+
(GYDexApiMonad m a, HasCallStack)
667+
PORefs
668+
POCVersion
669+
GYAddress
670+
-- ^ Order owner
671+
(Natural, GYAssetClass)
672+
-- ^ Amount and asset to offer.
673+
GYAssetClass
674+
-- ^ The asset being asked for as payment.
675+
GYRational
676+
-- ^ The price for one unit of the offered asset.
677+
Maybe GYTime
678+
-- ^ The earliest time when the order can be filled (optional).
679+
Maybe GYTime
680+
-- ^ The latest time when the order can be filled (optional).
681+
Natural
682+
-- ^ Additional lovelace fee.
683+
Natural
684+
-- ^ Additional fee in offered tokens.
685+
Maybe GYStakeCredential
686+
-- ^ Stake credential of user. We do not support pointer reference.
687+
GYTxOutRef
688+
PartialOrderConfigInfoF GYAddress
689+
m (GYAssetClass, GYTxSkeleton 'PlutusV2)
690+
placePartialOrderWithVersion'' pors pocVersion addr (offerAmt, offerAC) priceAC price start end addLov addOff stakeCred cfgRef pocd = do
634691
when (offerAmt == 0) $ throwAppError $ PodNonPositiveAmount $ toInteger offerAmt
635692
when (price <= 0) $ throwAppError $ PodNonPositivePrice price
636693
when (offerAC == priceAC) $ throwAppError $ PodNonDifferentAssets offerAC
@@ -696,11 +753,12 @@ placePartialOrderWithVersion' pors pocVersion addr (offerAmt, offerAC) priceAC p
696753
o = mkGYTxOut outAddr' offerV (datumFromPlutusData od)
697754

698755
return $
699-
mustHaveInput nftInput
700-
<> mustHaveOutput o
701-
<> mustMint (GYMintReference porMintRef $ mintingPolicyToScript policy) nftRedeemer nftName 1
702-
<> mustHaveRefInput cfgRef
703-
<> mustHaveTxMetadata stampPlaced
756+
(nft,) $
757+
mustHaveInput nftInput
758+
<> mustHaveOutput o
759+
<> mustMint (GYMintReference porMintRef $ mintingPolicyToScript policy) nftRedeemer nftName 1
760+
<> mustHaveRefInput cfgRef
761+
<> mustHaveTxMetadata stampPlaced
704762

705763
-- | Fills an order. If the provided amount of offered tokens to buy is equal to the offered amount, then we completely fill the order. Otherwise, it gets partially filled.
706764
fillPartialOrder

geniusyield-server-lib/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Revision history for geniusyield-server-lib
22

3+
## 0.3.0 -- 2024-05-07
4+
5+
* Adds TapTools OHLCV endpoint.
6+
* Adds NFT token in response of place order family of endpoints.
7+
* Adds GET variant for getting details of an order from it's NFT token identifier.
8+
* Clarifies which endpoints require `maestroToken` field to be set.
9+
* Clarifies which endpoints require signing key to be configured in the server to derive for wallet's address, likewise it is clarified that which endpoints use fields such as `collateral`, etc. from server's configuration.
10+
311
## 0.2.0 -- 2024-04-22
412

513
* Uses latest version of `geniusyield-dex-api` which adds support of v1.1 script.

geniusyield-server-lib/geniusyield-server-lib.cabal

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 3.6
22
name: geniusyield-server-lib
3-
version: 0.2.0
3+
version: 0.3.0
44
synopsis: GeniusYield server library
55
description: Library for GeniusYield server.
66
license: Apache-2.0
@@ -58,10 +58,13 @@ library
5858
GeniusYield.Server.Constants
5959
GeniusYield.Server.Ctx
6060
GeniusYield.Server.Dex.HistoricalPrices.Maestro
61+
GeniusYield.Server.Dex.HistoricalPrices.TapTools
62+
GeniusYield.Server.Dex.HistoricalPrices.TapTools.Client
6163
GeniusYield.Server.Dex.Markets
6264
GeniusYield.Server.Dex.PartialOrder
6365
GeniusYield.Server.ErrorMiddleware
6466
GeniusYield.Server.Options
67+
GeniusYield.Server.Orphans
6568
GeniusYield.Server.RequestLoggerMiddleware
6669
GeniusYield.Server.Run
6770
GeniusYield.Server.Tx
@@ -78,7 +81,7 @@ library
7881
build-depends:
7982
, aeson
8083
, atlas-cardano
81-
, base ^>=4.16.4.0
84+
, base ^>=4.16.4.0
8285
, binary
8386
, bytestring
8487
, cardano-api
@@ -89,13 +92,19 @@ library
8992
, geniusyield-dex-api
9093
, geniusyield-orderbot-lib
9194
, githash
95+
, http-client
96+
, http-client-tls
9297
, http-types
9398
, insert-ordered-containers
9499
, lens
95100
, optparse-applicative
96101
, plutus-ledger-api
97102
, ply-core
98103
, rio
104+
, servant
105+
, servant-checked-exceptions
106+
, servant-client
107+
, servant-client-core
99108
, servant-foreign
100109
, servant-server
101110
, servant-swagger

geniusyield-server-lib/src/GeniusYield/Server/Api.hs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ import GeniusYield.Server.Auth (APIKeyAuthProtect, V0)
3434
import GeniusYield.Server.Constants (gitHash)
3535
import GeniusYield.Server.Ctx
3636
import GeniusYield.Server.Dex.HistoricalPrices.Maestro
37+
import GeniusYield.Server.Dex.HistoricalPrices.TapTools (TapToolsPriceHistoryAPI, handleTapToolsPriceHistoryApi)
3738
import GeniusYield.Server.Dex.Markets (MarketsAPI, handleMarketsApi)
3839
import GeniusYield.Server.Dex.PartialOrder (OrderInfo (..), OrdersAPI, handleOrdersApi, poiToOrderInfo)
40+
import GeniusYield.Server.Orphans ()
3941
import GeniusYield.Server.Tx (TxAPI, handleTxApi)
4042
import GeniusYield.Server.Utils
4143
import GeniusYield.TxBuilder (GYTxQueryMonad (utxosAtAddress))
@@ -186,6 +188,10 @@ type OrderBookAPI = Summary "Order book" :> Description "Get order book for a sp
186188

187189
type BalancesAPI = Summary "Balances" :> Description "Get token balances of an address." :> Capture "address" GYAddressBech32 :> Get '[JSON] GYBalance
188190

191+
type HistoricalPricesAPI =
192+
"maestro" :> MaestroPriceHistoryAPI
193+
:<|> "tap-tools" :> TapToolsPriceHistoryAPI
194+
189195
type V0API =
190196
"settings" :> SettingsAPI
191197
:<|> "orders" :> OrdersAPI
@@ -194,7 +200,7 @@ type V0API =
194200
:<|> "trading-fees" :> TradingFeesAPI
195201
:<|> "assets" :> AssetsAPI
196202
:<|> "order-books" :> OrderBookAPI
197-
:<|> "historical-prices" :> "maestro" :> MaestroPriceHistoryAPI
203+
:<|> "historical-prices" :> HistoricalPricesAPI
198204
:<|> "balances" :> BalancesAPI
199205

200206
type GeniusYieldAPI = APIKeyAuthProtect :> V0 :> V0API
@@ -239,7 +245,7 @@ geniusYieldAPISwagger =
239245
& applyTagsFor (subOperations (Proxy Proxy ("trading-fees" +> TradingFeesAPI)) (Proxy Proxy GeniusYieldAPI)) ["Trading Fees" & description ?~ "Endpoint to get trading fees of DEX."]
240246
& applyTagsFor (subOperations (Proxy Proxy ("assets" +> AssetsAPI)) (Proxy Proxy GeniusYieldAPI)) ["Assets" & description ?~ "Endpoint to fetch asset details."]
241247
& applyTagsFor (subOperations (Proxy Proxy ("order-books" +> OrderBookAPI)) (Proxy Proxy GeniusYieldAPI)) ["Order Book" & description ?~ "Endpoint to fetch order book."]
242-
& applyTagsFor (subOperations (Proxy Proxy ("historical-prices" +> "maestro" :> MaestroPriceHistoryAPI)) (Proxy Proxy GeniusYieldAPI)) ["Historical Prices" & description ?~ "Endpoints to fetch historical prices."]
248+
& applyTagsFor (subOperations (Proxy Proxy ("historical-prices" +> HistoricalPricesAPI)) (Proxy Proxy GeniusYieldAPI)) ["Historical Prices" & description ?~ "Endpoints to fetch historical prices."]
243249
& applyTagsFor (subOperations (Proxy Proxy ("balances" +> BalancesAPI)) (Proxy Proxy GeniusYieldAPI)) ["Balances" & description ?~ "Endpoint to fetch token balances."]
244250

245251
geniusYieldServer Ctx ServerT GeniusYieldAPI IO
@@ -252,11 +258,16 @@ geniusYieldServer ctx =
252258
:<|> handleTradingFeesApi ctx
253259
:<|> handleAssetsApi ctx
254260
:<|> handleOrderBookApi ctx
255-
:<|> handleMaestroPriceHistoryApi ctx
261+
:<|> handleHistoricalPricesApi ctx
256262
:<|> handleBalancesApi ctx
257263
where
258264
ignoredAuthResult f _authResult = f
259265

266+
handleHistoricalPricesApi Ctx ServerT HistoricalPricesAPI IO
267+
handleHistoricalPricesApi ctx =
268+
handleMaestroPriceHistoryApi ctx
269+
:<|> handleTapToolsPriceHistoryApi ctx
270+
260271
type MainAPI =
261272
GeniusYieldAPI
262273

geniusyield-server-lib/src/GeniusYield/Server/Assets.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ module GeniusYield.Server.Assets (
44
) where
55

66
import Fmt
7+
import GHC.TypeLits (AppendSymbol)
78
import GeniusYield.OrderBot.Domain.Assets
89
import GeniusYield.Server.Ctx
910
import GeniusYield.Server.Utils
1011
import GeniusYield.Types
1112
import RIO hiding (logDebug, logInfo)
1213
import Servant
1314

14-
type AssetsAPI = Summary "Get assets information" :> Description "Get information for a specific asset." :> Capture "asset" GYAssetClass :> Get '[JSON] AssetDetails
15+
type AssetsAPI = Summary "Get assets information" :> Description ("Get information for a specific asset. " `AppendSymbol` CommonMaestroKeyRequirementText) :> Capture "asset" GYAssetClass :> Get '[JSON] AssetDetails
1516

1617
handleAssetsApi Ctx GYAssetClass IO AssetDetails
1718
handleAssetsApi ctx@Ctx {..} ac = do
Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
{-# OPTIONS_GHC -Wno-orphans #-}
2-
31
module GeniusYield.Server.Auth (
42
V0,
53
ApiKey,
@@ -10,17 +8,12 @@ module GeniusYield.Server.Auth (
108
APIKeyAuthProtect,
119
) where
1210

13-
import Control.Lens (at, (?~))
14-
import Data.HashMap.Strict.InsOrd qualified as IOHM
15-
import Data.Swagger
1611
import GHC.TypeLits (Symbol, symbolVal)
1712
import Network.Wai (Request (requestHeaders))
1813
import RIO
1914
import RIO.Text qualified as T
2015
import Servant
21-
import Servant.Foreign
2216
import Servant.Server.Experimental.Auth (AuthHandler, AuthServerData, mkAuthHandler)
23-
import Servant.Swagger
2417

2518
type V0 Symbol
2619
type V0 = "v0"
@@ -50,68 +43,3 @@ apiKeyAuthHandler (ApiKey key) = mkAuthHandler handler
5043
type APIKeyAuthProtect = AuthProtect ApiKeyHeader
5144

5245
type instance AuthServerData APIKeyAuthProtect = ()
53-
54-
instance HasSwagger api HasSwagger (APIKeyAuthProtect :> api) where
55-
toSwagger _ =
56-
toSwagger (Proxy Proxy api)
57-
& securityDefinitions
58-
.~ SecurityDefinitions (IOHM.fromList [(apiKeyHeaderText, apiKeySecurityScheme)])
59-
-- & paths
60-
-- . at signingKeyReqEndpoint
61-
-- . _Just
62-
-- . post
63-
-- . _Just
64-
-- . responses
65-
-- %~ add500SigningKeyFailureResponse
66-
-- & paths
67-
-- . at signingKeyReqEndpoint
68-
-- . _Just
69-
-- . delete
70-
-- . _Just
71-
-- . responses
72-
-- %~ add500SigningKeyFailureResponse
73-
& allOperations
74-
. security
75-
.~ [SecurityRequirement (IOHM.singleton apiKeyHeaderText [])]
76-
& allOperations
77-
. responses
78-
%~ addCommonResponses
79-
where
80-
apiKeySecurityScheme SecurityScheme
81-
apiKeySecurityScheme =
82-
SecurityScheme
83-
{ _securitySchemeType = SecuritySchemeApiKey (ApiKeyParams apiKeyHeaderText ApiKeyHeader),
84-
_securitySchemeDescription = Just "API key for accessing the server's API."
85-
}
86-
addCommonResponses Responses Responses
87-
addCommonResponses resps = resps & at 401 ?~ Inline response401 & at 403 ?~ Inline response403 & at 500 ?~ Inline response500
88-
89-
-- add500SigningKeyFailureResponse ∷ Responses → Responses
90-
-- add500SigningKeyFailureResponse resps = resps & at 500 ?~ Inline response500SigningKeyFailure
91-
92-
response401 Response
93-
response401 = mempty & description .~ "Unauthorized access - API key missing"
94-
95-
response403 Response
96-
response403 = mempty & description .~ "Forbidden - The API key does not have permission to perform the request"
97-
98-
response500 Response
99-
response500 = mempty & description .~ "Internal server error"
100-
101-
-- response500SigningKeyFailure ∷ Response
102-
-- response500SigningKeyFailure = mempty & description .~ "Internal server error - Corresponding signing key is not configured"
103-
104-
-- signingKeyReqEndpoint = "/" <> symbolVal (Proxy ∷ Proxy V0) <> "/orders"
105-
106-
-- `HasForeign` instance for `APIKeyAuthProtect :> api` is required to generate client code using libraries such as `servant-py`.
107-
-- This is written with help from https://github.com/haskell-servant/servant-auth/issues/8#issue-185541839.
108-
instance lang ftype api. (HasForeign lang ftype api, HasForeignType lang ftype Text) HasForeign lang ftype (APIKeyAuthProtect :> api) where
109-
type Foreign ftype (APIKeyAuthProtect :> api) = Foreign ftype api
110-
foreignFor lang Proxy Proxy subR = foreignFor lang Proxy (Proxy Proxy api) subR'
111-
where
112-
subR' = subR {_reqHeaders = HeaderArg arg : _reqHeaders subR}
113-
arg =
114-
Arg
115-
{ _argName = "api-key",
116-
_argType = typeFor lang (Proxy Proxy ftype) (Proxy Proxy Text)
117-
}

geniusyield-server-lib/src/GeniusYield/Server/Config.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ data ServerConfig = ServerConfig
5656
scPort !Port,
5757
scWallet !(Maybe UserWallet),
5858
scServerApiKey !(Confidential Text),
59+
scTapToolsApiKey !(Maybe (Confidential Text)),
5960
scCollateral !(Maybe GYTxOutRef),
6061
scStakeAddress !(Maybe GYStakeAddressBech32)
6162
}

0 commit comments

Comments
 (0)