Skip to content

Commit

Permalink
Merge pull request #11370 from hassnian/issue-expired-status-delay
Browse files Browse the repository at this point in the history
feat: expire trades based on `blockNumber`
  • Loading branch information
vikiival authored Jan 23, 2025
2 parents 47d8d28 + e38fb8a commit 09f5a05
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 19 deletions.
9 changes: 4 additions & 5 deletions components/trade/TradeActivityTableRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@
<div class="flex-1">
<div class="h-[50px] flex items-center">
<template v-if="trade.expirationDate">
<div v-if="isExpired">
<div v-if="trade.isExpired">
<span>{{ $t('expired') }}</span>
</div>
<div v-else>
<span>{{ format(trade.expirationDate, EXPIRATION_FORMAT) }}</span>
<span class="text-k-grey ml-3">({{ formatToNow(trade.expirationDate, isExpired) }})</span>
<span class="text-k-grey ml-3">({{ formatToNow(trade.expirationDate, trade.isExpired) }})</span>
</div>
</template>
<span v-else>
Expand Down Expand Up @@ -147,12 +147,12 @@
{{ blank }}
</div>
<template v-if="trade.expirationDate">
<div v-if="isExpired">
<div v-if="trade.isExpired">
<span>{{ $t('expired') }}</span>
</div>
<div v-else>
<span>{{ format(trade.expirationDate, EXPIRATION_FORMAT) }}</span>
<span class="text-k-grey ml-3">({{ formatToNow(trade.expirationDate, isExpired) }})</span>
<span class="text-k-grey ml-3">({{ formatToNow(trade.expirationDate, trade.isExpired) }})</span>
</div>
</template>
<span v-else>
Expand Down Expand Up @@ -241,7 +241,6 @@ const image = ref()
const animationUrl = ref()
const isDesktop = computed(() => props.variant === 'Desktop')
const isExpired = computed(() => props.trade.status === TradeStatus.EXPIRED)
const isTradeCollection = computed(() => desiredType === TradeDesiredType.COLLECTION)
const itemPath = computed(() => isTradeCollection.value ? `/${urlPrefix.value}/collection/${item.id}` : `/${urlPrefix.value}/gallery/${item.id}`)
Expand Down
2 changes: 1 addition & 1 deletion components/trade/TradeOwnerButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const details = {
}
const buttonConfig = computed<ButtonConfig | null>(() => {
if (props.trade.status === TradeStatus.EXPIRED) {
if (props.trade.isExpired) {
return isCreatorOfTrade.value
? {
label: $i18n.t(details[props.trade.type].withdraw),
Expand Down
3 changes: 1 addition & 2 deletions components/trade/overviewModal/Details.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
{{ $t('expiration') }}
</span>

<span v-if="trade.status === TradeStatus.EXPIRED">
<span v-if="trade.isExpired">
{{ $t('expired') }}
</span>
<span v-else>
Expand All @@ -45,7 +45,6 @@
<script setup lang="ts">
import { useIsTradeOverview } from './utils'
import { formatToNow } from '@/utils/format/time'
import { TradeStatus } from '@/composables/useTrades'
import type { NFT } from '@/types'
const props = defineProps<{
Expand Down
29 changes: 29 additions & 0 deletions composables/useCurrentBlock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const currentBlock = ref(0)
const subscription = ref()
const syncCount = ref(0)

export default function useCurrentBlock() {
const { apiInstance } = useApi()

syncCount.value++

if (!subscription.value) {
onBeforeMount(async () => {
const api = await apiInstance.value
subscription.value = await api.rpc.chain.subscribeNewHeads((lastHeader) => {
currentBlock.value = lastHeader.number.toNumber()
})
})
}

onBeforeUnmount(() => {
syncCount.value--

if (syncCount.value === 0 && subscription.value) {
subscription.value()
subscription.value = undefined
}
})

return currentBlock
}
17 changes: 6 additions & 11 deletions composables/useTrades.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export type TradeNftItem<T = Trade> = T & {
type: TradeType
desiredType: TradeDesiredType
isEntireCollectionDesired: boolean
isExpired: boolean
}

export const TRADES_QUERY_MAP: Record<TradeType, { queryDocument: DocumentNode, dataKey: string }> = {
Expand All @@ -78,7 +79,6 @@ export const TRADES_QUERY_MAP: Record<TradeType, { queryDocument: DocumentNode,
}

const BLOCKS_PER_HOUR = 300
const currentBlock = ref(0)

export default function ({ where = {}, limit = 100, disabled = computed(() => false), type = TradeType.SWAP }: {
where?: MaybeRef<Record<string, unknown>>
Expand All @@ -89,6 +89,8 @@ export default function ({ where = {}, limit = 100, disabled = computed(() => fa
const { queryDocument, dataKey } = TRADES_QUERY_MAP[type]

const { client } = usePrefix()
const currentBlock = useCurrentBlock()

const variables = computed(() => ({
where: unref(where),
limit: limit,
Expand Down Expand Up @@ -116,23 +118,16 @@ export default function ({ where = {}, limit = 100, disabled = computed(() => fa
offered: trade.nft,
desiredType: desiredType,
isEntireCollectionDesired: desiredType === TradeDesiredType.COLLECTION,
// Check block number to handle trades that are expired but not yet updated in indexer
// @see https://github.com/kodadot/stick/blob/9eac12938c47bf0e66e93760231208e4249d8637/src/mappings/utils/cache.ts#L127
isExpired: trade.status === TradeStatus.EXPIRED || currentBlock.value > Number(trade.expiration),
type,
} as TradeNftItem
}) || []
})

async function getCurrentBlock() {
const api = await useApi().apiInstance.value
const { number } = await api.rpc.chain.getHeader()
return number.toNumber()
}

const loading = computed(() => !currentBlock.value || fetching.value)

if (!currentBlock.value) {
getCurrentBlock().then(b => currentBlock.value = b)
}

return {
items,
loading,
Expand Down

0 comments on commit 09f5a05

Please sign in to comment.