Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Populate offers table #350

Merged
merged 33 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
561bd8d
populate offers table on home and user page
torztomasz Mar 16, 2023
f33351e
fix offers status labels
torztomasz Mar 16, 2023
791f3b5
handle more statuses
torztomasz Mar 16, 2023
edbd3c9
add function for building offer history
torztomasz Mar 16, 2023
dcfcf74
add repo tests
torztomasz Mar 16, 2023
ab295e1
fix linter issues
torztomasz Mar 16, 2023
53954a2
remove todos
torztomasz Mar 17, 2023
9629d6c
use PaginationOptions interface
torztomasz Mar 17, 2023
c3e798a
add wrappers for repo functions
torztomasz Mar 17, 2023
15c1135
improve test coverage for ForcedTradeOfferRepository
torztomasz Mar 20, 2023
c4e9b54
Merge remote-tracking branch 'origin/master' into populate-offers-table
torztomasz Mar 20, 2023
cf4cec1
fix after merge issues
torztomasz Mar 20, 2023
c74dc15
add methods for getting available offers
torztomasz Mar 21, 2023
dacec31
show offers on user page with role
torztomasz Mar 23, 2023
c194ab6
add unit tests for getUserOffersByStarkKey
torztomasz Mar 23, 2023
9cd3499
fix available offers requirements
torztomasz Mar 23, 2023
7469229
remove redundant ?? operator
torztomasz Mar 23, 2023
c531f1c
add todo
torztomasz Mar 23, 2023
3bd4c34
Merge remote-tracking branch 'origin/master' into populate-offers-table
torztomasz Mar 24, 2023
a3dd1f1
fix failing test
torztomasz Mar 24, 2023
9e76843
change getUsersOffersByStarkKey to getByMakerOrTakerStarkKey
torztomasz Mar 24, 2023
8caca6f
refactor countByStarkKey
torztomasz Mar 24, 2023
ad179a8
Merge remote-tracking branch 'origin/master' into populate-offers-table
torztomasz Mar 27, 2023
90df922
fix merge issues
torztomasz Mar 27, 2023
2e138c9
use buildTransactionHistory instead inlining logic
torztomasz Mar 28, 2023
685e7b6
aggregate user and sent transaction history to offers showed on user …
torztomasz Mar 28, 2023
16bcf48
refactor forcedTradeOffersToEntry to class
torztomasz Mar 28, 2023
d871e8a
use Promise.all
torztomasz Mar 28, 2023
3e88306
Merge remote-tracking branch 'origin/master' into populate-offers-table
torztomasz Mar 28, 2023
4d3ed37
implement user offers page (#365)
torztomasz Mar 28, 2023
e59b86c
Merge remote-tracking branch 'origin/master' into populate-offers-table
torztomasz Mar 28, 2023
8788bf2
use TransactionHistory class
torztomasz Mar 29, 2023
b90acc0
Merge remote-tracking branch 'origin/master' into populate-offers-table
torztomasz Mar 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/backend/src/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,7 @@ export class Application {
userService,
assetRepository,
userTransactionRepository,
forcedTradeOfferRepository,
preprocessedStateDetailsRepository,
config.starkex.tradingMode,
collateralAsset
Expand All @@ -456,6 +457,7 @@ export class Application {
preprocessedAssetHistoryRepository,
sentTransactionRepository,
userTransactionRepository,
forcedTradeOfferRepository,
userRegistrationEventRepository,
assetRepository,
config.starkex.tradingMode,
Expand Down
22 changes: 12 additions & 10 deletions packages/backend/src/api/controllers/HomeController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import { CollateralAsset } from '../../config/starkex/StarkexConfig'
import { UserService } from '../../core/UserService'
import { PaginationOptions } from '../../model/PaginationOptions'
import { AssetRepository } from '../../peripherals/database/AssetRepository'
import { ForcedTradeOfferRepository } from '../../peripherals/database/ForcedTradeOfferRepository'
import { PreprocessedStateDetailsRepository } from '../../peripherals/database/PreprocessedStateDetailsRepository'
import { UserTransactionData } from '../../peripherals/database/transactions/UserTransaction'
import { UserTransactionRepository } from '../../peripherals/database/transactions/UserTransactionRepository'
import { ControllerResult } from './ControllerResult'
import { forcedTradeOfferToEntry } from './forcedTradeOfferToEntry'
import { getAssetHashToAssetDetailsMap } from './getAssetDetailsMap'
import { userTransactionToEntry } from './userTransactionToEntry'

Expand All @@ -27,6 +29,7 @@ export class HomeController {
private readonly userService: UserService,
private readonly assetRepository: AssetRepository,
private readonly userTransactionRepository: UserTransactionRepository,
private readonly forcedTradeOfferRepository: ForcedTradeOfferRepository,
private readonly preprocessedStateDetailsRepository: PreprocessedStateDetailsRepository,
private readonly tradingMode: TradingMode,
private readonly collateralAsset?: CollateralAsset
Expand All @@ -36,25 +39,24 @@ export class HomeController {
givenUser: Partial<UserDetails>
): Promise<ControllerResult> {
const user = await this.userService.getUserDetails(givenUser)

const paginationOpts = { offset: 0, limit: 6 }
const [
stateUpdates,
totalStateUpdates,
forcedUserTransactions,
forcedUserTransactionsCount,
availableOffers,
availableOffersCount,
] = await Promise.all([
this.preprocessedStateDetailsRepository.getPaginated({
offset: 0,
limit: 6,
}),
this.preprocessedStateDetailsRepository.getPaginated(paginationOpts),
this.preprocessedStateDetailsRepository.countAll(),

this.userTransactionRepository.getPaginated({
offset: 0,
limit: 6,
...paginationOpts,
types: FORCED_TRANSACTION_TYPES,
}),
this.userTransactionRepository.countAll(FORCED_TRANSACTION_TYPES),
this.forcedTradeOfferRepository.getAvailablePaginated(paginationOpts),
this.forcedTradeOfferRepository.countAvailable(),
])

const assetDetailsMap = await getAssetHashToAssetDetailsMap(
Expand Down Expand Up @@ -82,8 +84,8 @@ export class HomeController {
totalStateUpdates,
transactions,
totalForcedTransactions: forcedUserTransactionsCount,
offers: [],
totalOffers: 0,
offers: availableOffers.map((offer) => forcedTradeOfferToEntry(offer)),
totalOffers: availableOffersCount,
tradingMode: this.tradingMode,
})
return { type: 'success', content }
Expand Down
47 changes: 34 additions & 13 deletions packages/backend/src/api/controllers/UserController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import {
} from '@explorer/frontend'
import { UserBalanceChangeEntry } from '@explorer/frontend/src/view/pages/user/components/UserBalanceChangesTable'
import { AssetDetails, TradingMode, UserDetails } from '@explorer/shared'
import { AssetHash, AssetId, EthereumAddress, StarkKey } from '@explorer/types'
import { AssetHash, AssetId, StarkKey } from '@explorer/types'

import { CollateralAsset } from '../../config/starkex/StarkexConfig'
import { UserService } from '../../core/UserService'
import { PaginationOptions } from '../../model/PaginationOptions'
import { AssetRepository } from '../../peripherals/database/AssetRepository'
import { ForcedTradeOfferRepository } from '../../peripherals/database/ForcedTradeOfferRepository'
import {
PreprocessedAssetHistoryRecord,
PreprocessedAssetHistoryRepository,
Expand All @@ -28,6 +29,7 @@ import {
} from '../../peripherals/database/transactions/UserTransactionRepository'
import { UserRegistrationEventRepository } from '../../peripherals/database/UserRegistrationEventRepository'
import { ControllerResult } from './ControllerResult'
import { forcedTradeOfferToEntry } from './forcedTradeOfferToEntry'
import { getAssetHashToAssetDetailsMap } from './getAssetDetailsMap'
import { sentTransactionToEntry } from './sentTransactionToEntry'
import { userTransactionToEntry } from './userTransactionToEntry'
Expand All @@ -41,6 +43,7 @@ export class UserController {
>,
private readonly sentTransactionRepository: SentTransactionRepository,
private readonly userTransactionRepository: UserTransactionRepository,
private readonly forcedTradeOfferRepository: ForcedTradeOfferRepository,
private readonly userRegistrationEventRepository: UserRegistrationEventRepository,
private readonly assetRepository: AssetRepository,
private readonly tradingMode: TradingMode,
Expand All @@ -51,6 +54,10 @@ export class UserController {
givenUser: Partial<UserDetails>,
starkKey: StarkKey
): Promise<ControllerResult> {
const paginationOpts = {
offset: 0,
limit: 10,
}
const [
user,
registeredUser,
Expand All @@ -61,30 +68,42 @@ export class UserController {
sentTransactions,
userTransactions,
userTransactionsCount,
forcedTradeOffers,
forcedTradeOffersCount,
] = await Promise.all([
this.userService.getUserDetails(givenUser),
this.userRegistrationEventRepository.findByStarkKey(starkKey),
this.preprocessedAssetHistoryRepository.getCurrentByStarkKeyPaginated(
starkKey,
{ offset: 0, limit: 10 },
paginationOpts,
this.collateralAsset?.assetId
),
this.preprocessedAssetHistoryRepository.getCountOfCurrentByStarkKey(
starkKey
),
this.preprocessedAssetHistoryRepository.getByStarkKeyPaginated(starkKey, {
offset: 0,
limit: 10,
}),
this.preprocessedAssetHistoryRepository.getByStarkKeyPaginated(
starkKey,
paginationOpts
),
this.preprocessedAssetHistoryRepository.getCountByStarkKey(starkKey),
this.sentTransactionRepository.getByStarkKey(starkKey),
this.userTransactionRepository.getByStarkKey(starkKey, undefined, {
offset: 0,
limit: 10,
}),
this.userTransactionRepository.getByStarkKey(
starkKey,
undefined,
paginationOpts
),
this.userTransactionRepository.getCountByStarkKey(starkKey),
this.forcedTradeOfferRepository.getUserOffersByStarkKey(
torztomasz marked this conversation as resolved.
Show resolved Hide resolved
starkKey,
paginationOpts
),
this.forcedTradeOfferRepository.countByStarkKey(starkKey),
])

if (!registeredUser) {
return { type: 'not found', content: 'User not found' }
}

const assetDetailsMap = await getAssetHashToAssetDetailsMap(
this.tradingMode,
this.assetRepository,
Expand Down Expand Up @@ -122,7 +141,7 @@ export class UserController {
user,
tradingMode: this.tradingMode,
starkKey,
ethereumAddress: registeredUser?.ethAddress ?? EthereumAddress.ZERO,
ethereumAddress: registeredUser.ethAddress,
withdrawableAssets: [],
offersToAccept: [],
assets: assetEntries,
Expand All @@ -131,8 +150,10 @@ export class UserController {
totalBalanceChanges: historyCount,
transactions,
totalTransactions,
offers: [],
totalOffers: 0,
offers: forcedTradeOffers.map((offer) =>
forcedTradeOfferToEntry(offer, registeredUser.starkKey)
),
totalOffers: forcedTradeOffersCount,
})

return { type: 'success', content }
Expand Down
59 changes: 59 additions & 0 deletions packages/backend/src/api/controllers/forcedTradeOfferToEntry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { OfferEntry } from '@explorer/frontend'
import { StarkKey, Timestamp } from '@explorer/types'

import { ForcedTradeOfferRecord } from '../../peripherals/database/ForcedTradeOfferRepository'

function buildTradeOfferHistory(
forcedTradeOffer: ForcedTradeOfferRecord
): OfferEntry['status'][] {
const history: OfferEntry['status'][] = []
if (forcedTradeOffer.accepted) {
if (forcedTradeOffer.accepted.transactionHash) {
history.push('SENT')
} else if (
Timestamp.fromHours(forcedTradeOffer.accepted.submissionExpirationTime) <
Timestamp.now()
) {
history.push('EXPIRED')
}
}

if (forcedTradeOffer.cancelledAt) {
history.push('CANCELLED')
}

if (forcedTradeOffer.accepted) {
history.push('ACCEPTED')
}

history.push('CREATED')

return history
}

export function forcedTradeOfferToEntry(
forcedTradeOffer: ForcedTradeOfferRecord,
userStarkKey?: StarkKey
): OfferEntry {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const status = buildTradeOfferHistory(forcedTradeOffer)[0]!
const role =
forcedTradeOffer.starkKeyA === userStarkKey
? 'MAKER'
: forcedTradeOffer.accepted?.starkKeyB === userStarkKey
? 'TAKER'
: undefined
return {
id: forcedTradeOffer.id.toString(),
timestamp: forcedTradeOffer.createdAt,
asset: {
hashOrId: forcedTradeOffer.syntheticAssetId,
},
amount: forcedTradeOffer.syntheticAmount,
price: 0n, //TODO: calculate price
totalPrice: 0n * forcedTradeOffer.syntheticAmount,
status,
type: forcedTradeOffer.isABuyingSynthetic ? 'BUY' : 'SELL',
role,
}
}