Skip to content

Commit

Permalink
feat: query-keys-factory
Browse files Browse the repository at this point in the history
  • Loading branch information
gomesalexandre committed Jan 29, 2025
1 parent 15d0437 commit 3c68f41
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 68 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@chakra-ui/react": "^2.10.3",
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@lukemorales/query-key-factory": "^1.3.4",
"@shapeshiftoss/caip": "^8.15.0",
"@shapeshiftoss/types": "^8.6.0",
"@tanstack/react-query": "^5.65.1",
Expand Down
10 changes: 2 additions & 8 deletions src/queries/chainflip/assets.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
import {
arbitrumAssetId,
btcAssetId,
Expand All @@ -12,10 +11,9 @@ import {
usdtAssetId,
} from 'constants/caip'

import { reactQueries } from '../react-queries'
import type { ChainflipAssetsResponse } from './types'

const CHAINFLIP_API_URL = import.meta.env.VITE_CHAINFLIP_API_URL

// Map Chainflip internal asset IDs to CAIPs
const chainflipToAssetId: Record<string, string> = {
'btc.btc': btcAssetId,
Expand All @@ -35,11 +33,7 @@ export const transformChainflipAssets = (data: ChainflipAssetsResponse) => {

export const useChainflipAssetsQuery = () => {
return useQuery({
queryKey: ['chainflip', 'assets'],
queryFn: async () => {
const { data } = await axios.get<ChainflipAssetsResponse>(`${CHAINFLIP_API_URL}/assets`)
return data
},
...reactQueries.chainflip.assets,
select: transformChainflipAssets,
})
}
25 changes: 3 additions & 22 deletions src/queries/chainflip/quote.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'

import type { ChainflipQuote, ChainflipQuoteParams } from './types'

const CHAINFLIP_API_URL = import.meta.env.VITE_CHAINFLIP_API_URL
const CHAINFLIP_API_KEY = import.meta.env.VITE_CHAINFLIP_API_KEY
import { reactQueries } from '../react-queries'
import type { ChainflipQuoteParams } from './types'

export const useChainflipQuoteQuery = (params: ChainflipQuoteParams) => {
const { sourceAsset, destinationAsset, amount, commissionBps } = params

return useQuery({
queryKey: ['chainflip', 'quote', params],
queryFn: async () => {
const { data } = await axios.get<ChainflipQuote[]>(`${CHAINFLIP_API_URL}/quotes-native`, {
params: {
apiKey: CHAINFLIP_API_KEY,
sourceAsset,
destinationAsset,
amount,
...(commissionBps && { commissionBps }),
},
})

// TODO(gomes): select best quote based on output amount, since o.g doesn't support multiple quotes
return data[0]
},
...reactQueries.chainflip.quote(params),
})
}
20 changes: 2 additions & 18 deletions src/queries/chainflip/status.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'

import type { ChainflipStatusResponse } from './types'

const CHAINFLIP_API_URL = import.meta.env.VITE_CHAINFLIP_API_URL
const CHAINFLIP_API_KEY = import.meta.env.VITE_CHAINFLIP_API_KEY
import { reactQueries } from '../react-queries'

type ChainflipStatusQueryParams = {
swapId: number
Expand All @@ -13,19 +9,7 @@ type ChainflipStatusQueryParams = {

export const useChainflipStatusQuery = ({ swapId, enabled = true }: ChainflipStatusQueryParams) => {
return useQuery({
queryKey: ['chainflip', 'status', swapId],
queryFn: async () => {
const { data } = await axios.get<ChainflipStatusResponse>(
`${CHAINFLIP_API_URL}/status-by-id`,
{
params: {
apiKey: CHAINFLIP_API_KEY,
swapId,
},
},
)
return data
},
...reactQueries.chainflip.status(swapId),
refetchInterval: 15000,
enabled,
})
Expand Down
20 changes: 3 additions & 17 deletions src/queries/chainflip/swap.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'

import type { ChainflipSwapParams, ChainflipSwapResponse } from './types'

const CHAINFLIP_API_URL = import.meta.env.VITE_CHAINFLIP_API_URL
const CHAINFLIP_API_KEY = import.meta.env.VITE_CHAINFLIP_API_KEY
import { reactQueries } from '../react-queries'
import type { ChainflipSwapParams } from './types'

export const useChainflipSwapQuery = (params: ChainflipSwapParams) => {
return useQuery({
queryKey: ['chainflip', 'swap', params],
queryFn: async () => {
const { data } = await axios.get<ChainflipSwapResponse>(`${CHAINFLIP_API_URL}/swap`, {
params: {
apiKey: CHAINFLIP_API_KEY,
...params,
boostFee: params.maxBoostFee ?? 0,
retryDurationInBlocks: params.retryDurationInBlocks ?? 150,
},
})
return data
},
...reactQueries.chainflip.swap(params),
})
}
6 changes: 3 additions & 3 deletions src/queries/marketData/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
usdtAssetId,
} from 'constants/caip'

import { reactQueries } from '../react-queries'
import type { CoinGeckoAssetData, MarketData } from './types'

const COINGECKO_BASE_URL = 'https://api.proxy.shapeshift.com/api/v1/markets'
Expand Down Expand Up @@ -56,8 +57,7 @@ export const findByAssetId = async (assetId: string): Promise<MarketData | null>
}

export const useMarketDataByAssetIdQuery = (assetId: string) => {
return useQuery<MarketData | null>({
queryKey: ['marketData', assetId],
queryFn: () => findByAssetId(assetId),
return useQuery({
...reactQueries.marketData.byAssetId(assetId),
})
}
Empty file added src/queries/queryKeys.ts
Empty file.
80 changes: 80 additions & 0 deletions src/queries/react-queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { inferQueryKeyStore } from '@lukemorales/query-key-factory'
import { createQueryKeyStore } from '@lukemorales/query-key-factory'
import axios from 'axios'

import type {
ChainflipAssetsResponse,
ChainflipQuote,
ChainflipQuoteParams,
ChainflipStatusResponse,
ChainflipSwapParams,
ChainflipSwapResponse,
} from './chainflip/types'
import { findByAssetId } from './marketData'

const CHAINFLIP_API_URL = import.meta.env.VITE_CHAINFLIP_API_URL
const CHAINFLIP_API_KEY = import.meta.env.VITE_CHAINFLIP_API_KEY

export const reactQueries = createQueryKeyStore({
chainflip: {
assets: {
queryKey: null,
queryFn: async () => {
const { data } = await axios.get<ChainflipAssetsResponse>(`${CHAINFLIP_API_URL}/assets`)
return data
},
},
quote: (params: ChainflipQuoteParams) => ({
queryKey: [params],
queryFn: async () => {
const { data } = await axios.get<ChainflipQuote[]>(`${CHAINFLIP_API_URL}/quotes-native`, {
params: {
apiKey: CHAINFLIP_API_KEY,
sourceAsset: params.sourceAsset,
destinationAsset: params.destinationAsset,
amount: params.amount,
...(params.commissionBps && { commissionBps: params.commissionBps }),
},
})
return data[0]
},
}),
swap: (params: ChainflipSwapParams) => ({
queryKey: [params],
queryFn: async () => {
const { data } = await axios.get<ChainflipSwapResponse>(`${CHAINFLIP_API_URL}/swap`, {
params: {
apiKey: CHAINFLIP_API_KEY,
...params,
boostFee: params.maxBoostFee ?? 0,
retryDurationInBlocks: params.retryDurationInBlocks ?? 150,
},
})
return data
},
}),
status: (swapId: number) => ({
queryKey: [swapId],
queryFn: async () => {
const { data } = await axios.get<ChainflipStatusResponse>(
`${CHAINFLIP_API_URL}/status-by-id`,
{
params: {
apiKey: CHAINFLIP_API_KEY,
swapId,
},
},
)
return data
},
}),
},
marketData: {
byAssetId: (assetId: string) => ({
queryKey: [assetId],
queryFn: () => findByAssetId(assetId),
}),
},
})

export type QueryKeys = inferQueryKeyStore<typeof reactQueries>
11 changes: 11 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2365,6 +2365,16 @@ __metadata:
languageName: node
linkType: hard

"@lukemorales/query-key-factory@npm:^1.3.4":
version: 1.3.4
resolution: "@lukemorales/query-key-factory@npm:1.3.4"
peerDependencies:
"@tanstack/query-core": ">= 4.0.0"
"@tanstack/react-query": ">= 4.0.0"
checksum: 10c0/d4e829aad970c159e3e3d6545f4f1e47d1a02621cd692bc0e13b7cc36861541e205f801d7ab8081ed8b1c8c3fd365483e1656537ef1ab165cb14743b4b1f1d6c
languageName: node
linkType: hard

"@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1":
version: 5.1.1-v1
resolution: "@nicolo-ribaudo/eslint-scope-5-internals@npm:5.1.1-v1"
Expand Down Expand Up @@ -7329,6 +7339,7 @@ __metadata:
"@chakra-ui/react": "npm:^2.10.3"
"@emotion/react": "npm:^11.11.3"
"@emotion/styled": "npm:^11.11.0"
"@lukemorales/query-key-factory": "npm:^1.3.4"
"@shapeshiftoss/caip": "npm:^8.15.0"
"@shapeshiftoss/types": "npm:^8.6.0"
"@tanstack/react-query": "npm:^5.65.1"
Expand Down

0 comments on commit 3c68f41

Please sign in to comment.