Skip to content
This repository has been archived by the owner on May 19, 2023. It is now read-only.

Commit

Permalink
feat: adds expiration table and removes status from offers
Browse files Browse the repository at this point in the history
feat: adds expiration table and removes status from offers

refactor: fixes es/ts issues
  • Loading branch information
jurajpiar committed Jun 5, 2020
1 parent 2c3f7f1 commit 1642ab4
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 176 deletions.
40 changes: 24 additions & 16 deletions src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,31 @@ import { RatesService } from './services/rates'
import { RnsService } from './services/rns'
import ConfirmationService from './blockchain/confirmation.service'

export enum ServiceAddresses {
RNS_DOMAINS = '/rns/v0/:ownerAddress/domains',
RNS_SOLD = '/rns/v0/:ownerAddress/sold',
RNS_OFFERS = '/rns/v0/offers',
STORAGE_OFFERS = '/storage/v0/offers',
XR = '/rates/v0/',
CONFIRMATIONS = '/confirmations'
}
// A mapping of service names to types. Will be extended in service files.
interface ServiceTypes {
'/storage/v0/offers': OfferService & ServiceAddons<any>
'/rates/v0/': RatesService & ServiceAddons<any>
'/rns/v0/:ownerAddress/domains': RnsService & ServiceAddons<any>
'/rns/v0/:ownerAddress/sold': RnsService & ServiceAddons<any>
'/rns/v0/offers': RnsService & ServiceAddons<any>
'/confirmations': ConfirmationService & ServiceAddons<any>
[ServiceAddresses.STORAGE_OFFERS]: OfferService & ServiceAddons<any>
[ServiceAddresses.XR]: RatesService & ServiceAddons<any>
[ServiceAddresses.RNS_DOMAINS]: RnsService & ServiceAddons<any>
[ServiceAddresses.RNS_SOLD]: RnsService & ServiceAddons<any>
[ServiceAddresses.RNS_OFFERS]: RnsService & ServiceAddons<any>
[ServiceAddresses.CONFIRMATIONS]: ConfirmationService & ServiceAddons<any>
}

// The application instance type that will be used everywhere else
export type Application = ExpressFeathers<ServiceTypes>;

export interface CachedService {
precache (eth?: Eth): Promise<void>
purge (): Promise<void>
initialize (app: Application): Promise<void>
precache(eth?: Eth): Promise<void>
purge(): Promise<void>
initialize(app: Application): Promise<void>
}

export enum RatesProvider {
Expand Down Expand Up @@ -157,7 +165,7 @@ export interface Config {
}
}

interface Args {[name: string]: any}
interface Args { [name: string]: any }

type Options<T> = T extends Parser.Input<infer R>
? Parser.Output<R, Args>
Expand All @@ -170,22 +178,22 @@ export type Flags<T> = Options<T>['flags']
*/
export interface Logger {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
critical (message: string | Error | object, ...meta: any[]): never
critical(message: string | Error | object, ...meta: any[]): never

// eslint-disable-next-line @typescript-eslint/no-explicit-any
error (message: string | Error | object, ...meta: any[]): void
error(message: string | Error | object, ...meta: any[]): void

// eslint-disable-next-line @typescript-eslint/no-explicit-any
warn (message: string | object, ...meta: any[]): void
warn(message: string | object, ...meta: any[]): void

// eslint-disable-next-line @typescript-eslint/no-explicit-any
info (message: string | object, ...meta: any[]): void
info(message: string | object, ...meta: any[]): void

// eslint-disable-next-line @typescript-eslint/no-explicit-any
verbose (message: string | object, ...meta: any[]): void
verbose(message: string | object, ...meta: any[]): void

// eslint-disable-next-line @typescript-eslint/no-explicit-any
debug (message: string | object, ...meta: any[]): void
debug(message: string | object, ...meta: any[]): void
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/services/rates/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Service } from 'feathers-sequelize'
import config from 'config'

import { Application, CachedService } from '../../definitions'
import { Application, CachedService, ServiceAddresses } from '../../definitions'
import { loggingFactory } from '../../logger'
import hooks from './rates.hooks'
import Rate from './rates.model'
Expand All @@ -24,8 +24,8 @@ const storage: CachedService = {
logger.info('Rates service: enabled')

// Initialize feather's service
app.use('/rates/v0/', new RatesService({ Model: Rate }))
const service = app.service('/rates/v0/')
app.use(ServiceAddresses.XR, new RatesService({ Model: Rate }))
const service = app.service(ServiceAddresses.XR)
service.hooks(hooks)

// Start periodical refresh
Expand Down
17 changes: 13 additions & 4 deletions src/services/rns/hooks/domain-offer.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { disallow } from 'feathers-hooks-common'
import Domain from '../models/domain.model'
import { Op } from 'sequelize'
import { sha3, numberToHex } from 'web3-utils'
import DomainExpiration from '../models/expiration.model'

export default {
before: {
Expand All @@ -12,14 +13,18 @@ export default {
context.params.sequelize = {
raw: false,
nest: true,
include: [Domain]
include: {
model: Domain,
include: {
model: DomainExpiration,
attributes: ['expirationDate']
}
}
}

if (!context.params.query) {
context.params.query = {}
}

context.params.query.status = 'ACTIVE'
}
],
find: [
Expand All @@ -28,7 +33,11 @@ export default {
raw: false,
nest: true,
include: {
model: Domain
model: Domain,
include: {
model: DomainExpiration,
attributes: ['expirationDate']
}
}
}
const { params: { sequelize: { include } } } = context
Expand Down
106 changes: 41 additions & 65 deletions src/services/rns/hooks/domain.hooks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { HookContext } from '@feathersjs/feathers'
import { disallow } from 'feathers-hooks-common'
import { sha3, numberToHex } from 'web3-utils'
import Domain from '../models/domain.model'
import { Op } from 'sequelize'
import { numberToHex, sha3 } from 'web3-utils'
import DomainOffer from '../models/domain-offer.model'
import DomainExpiration from '../models/expiration.model'

export default {
before: {
Expand Down Expand Up @@ -33,74 +34,49 @@ export default {
}
return context
},
async (context: HookContext) => {
if (context.params.query?.status) {
const { status, ownerAddress, name: nameFilter } = context.params.query

const isOwned = status === 'owned'
const sql =
`SELECT
"Domain"."tokenId",
"Domain"."ownerAddress",
"Domain"."name",
"Domain"."expirationDate",
"offers"."offerId",
"offers"."paymentToken",
"offers"."price",
"offers"."creationDate"
FROM
"rns_domain" AS "Domain"
LEFT JOIN "rns_domain-offer" AS "offers" ON "Domain"."tokenId" = "offers"."tokenId"
${isOwned ? `LEFT JOIN "rns_domain-offer" AS "active_offers" ON "Domain"."tokenId" = "active_offers"."tokenId"
AND "active_offers"."status" = 'ACTIVE'` : ''}
LEFT JOIN (
SELECT
"tokenId",
"creationDate",
ROW_NUMBER() OVER(
PARTITION BY "tokenId"
ORDER BY
"creationDate" DESC
) AS "ROW_PRIORITY"
FROM
"rns_domain-offer"
WHERE
${isOwned ? '"status" IN (\'CANCELED\', \'SOLD\')' : '"status" = \'ACTIVE\''}
) "INACTIVE_OFFERS" ON "INACTIVE_OFFERS"."tokenId" = "Domain"."tokenId"
AND "INACTIVE_OFFERS"."creationDate" = "offers"."creationDate"
AND "INACTIVE_OFFERS"."ROW_PRIORITY" = 1
WHERE
"Domain"."ownerAddress" = '${ownerAddress}'
${isOwned
? `
AND ("offers"."status" IN ('CANCELED', 'SOLD') OR "offers"."tokenId" IS NULL)
AND "active_offers"."tokenId" IS NULL
AND ("INACTIVE_OFFERS"."tokenId" IS NOT NULL OR "offers"."tokenId" IS NULL)
`
: `
AND "offers"."status" = 'ACTIVE'
`}
${nameFilter?.$like ? `AND ("Domain"."name" LIKE '%${nameFilter.$like}%' OR "Domain"."tokenId" = '${numberToHex((sha3(nameFilter.$like)) as string)}')` : ''}
`

const sequelize = context.app.get('sequelize')
const results = (await sequelize.query(sql))[0]
(context: HookContext) => {
if (context.params.query) {
const { ownerAddress, placed, name } = context.params.query

context.result = results.map((item: Domain & DomainOffer) => {
const { offerId, paymentToken, price, creationDate, ...rest } = item
context.params.sequelize = {
raw: false,
nest: true,
include: [
{
model: DomainExpiration,
attributes: ['expirationDate']
},
{
model: DomainOffer,
as: 'offers',
required: false
}
],
where: {
'$offers.tokenId$': placed
? { [Op.not]: null }
: { [Op.is]: null },
ownerAddress
}
}

return {
...rest,
offer: offerId && {
offerId,
paymentToken,
price,
creationDate
if (name) {
const { $like: nameFilter } = name
context.params.sequelize.where = {
...context.params.sequelize.where,
[Op.or]: {
name: {
[Op.like]: `%${nameFilter}%`
},
tokenId: {
[Op.eq]: numberToHex(((sha3(nameFilter)) as string))
}
}
}
})
}
delete (context.params.query as any).status
delete (context.params.query as any).name
}
return context
}
],
get: [],
Expand Down
3 changes: 2 additions & 1 deletion src/services/rns/hooks/sold-domain.hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Domain from '../models/domain.model'
import { Op } from 'sequelize'
import { numberToHex, sha3 } from 'web3-utils'
import Transfer from '../models/transfer.model'
import DomainExpiration from '../models/expiration.model'

export default {
before: {
Expand All @@ -27,7 +28,7 @@ export default {
raw: false,
nest: true,
include: [
{ model: Domain, attributes: ['tokenId', 'name', 'expirationDate'] },
{ model: Domain, attributes: ['tokenId', 'name'] },
{
model: Transfer,
attributes: ['sellerAddress', 'newOwnerAddress'],
Expand Down
14 changes: 7 additions & 7 deletions src/services/rns/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import config from 'config'
import { EventData } from 'web3-eth-contract'
import { getObject } from 'sequelize-store'

import { Application, CachedService } from '../../definitions'
import { Application, CachedService, ServiceAddresses } from '../../definitions'
import { loggingFactory } from '../../logger'
import { ethFactory } from '../../blockchain'
import { getEventsEmitterForService, isServiceInitialized } from '../../blockchain/utils'
Expand Down Expand Up @@ -88,13 +88,13 @@ const rns: CachedService = {
await waitForReadyApp(app)

// Initialize feather's service
app.use('/rns/v0/:ownerAddress/domains', new RnsService({ Model: Domain }))
app.use('/rns/v0/:ownerAddress/sold', new RnsService({ Model: SoldDomain }))
app.use('/rns/v0/offers', new RnsService({ Model: DomainOffer }))
app.use(ServiceAddresses.RNS_DOMAINS, new RnsService({ Model: Domain }))
app.use(ServiceAddresses.RNS_SOLD, new RnsService({ Model: SoldDomain }))
app.use(ServiceAddresses.RNS_OFFERS, new RnsService({ Model: DomainOffer }))

app.service('/rns/v0/:ownerAddress/domains').hooks(domainHooks)
app.service('/rns/v0/:ownerAddress/sold').hooks(soldDomainHooks)
app.service('/rns/v0/offers').hooks(domainOfferHooks)
app.service(ServiceAddresses.RNS_DOMAINS).hooks(domainHooks)
app.service(ServiceAddresses.RNS_SOLD).hooks(soldDomainHooks)
app.service(ServiceAddresses.RNS_OFFERS).hooks(domainOfferHooks)

// Initialize blockchain watcher
const eth = app.get('eth') as Eth
Expand Down
3 changes: 0 additions & 3 deletions src/services/rns/models/domain-offer.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,4 @@ export default class DomainOffer extends Model {

@Column(DataType.DATE)
creationDate!: number

@Column(DataType.ENUM('ACTIVE', 'CANCELED', 'SOLD'))
status!: string
}
20 changes: 14 additions & 6 deletions src/services/rns/models/domain.model.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { Table, DataType, Column, Model, Scopes, HasMany } from 'sequelize-typescript'
import { Table, DataType, Column, Model, Scopes, HasMany, HasOne, BelongsTo } from 'sequelize-typescript'
import { Op } from 'sequelize'

import DomainOffer from './domain-offer.model'
import SoldDomain from './sold-domain.model'
import DomainExpiration from './expiration.model'

@Scopes(() => ({
active: {
where: {
expirationDate: { [Op.gt]: Date.now() }
}
include: [
{
model: DomainExpiration,
where: {
expirationDate: { [Op.gt]: Date.now() }
}
}
]
}
}))
@Table({ freezeTableName: true, tableName: 'rns_domain', timestamps: false })
Expand All @@ -22,8 +28,10 @@ export default class Domain extends Model {
@Column(DataType.STRING)
name!: string

@Column({ type: DataType.DATE })
expirationDate!: number
@BelongsTo(() => DomainExpiration, {
foreignKey: 'tokenId'
})
expiration!: DomainExpiration

@HasMany(() => SoldDomain)
sales!: SoldDomain[]
Expand Down
11 changes: 11 additions & 0 deletions src/services/rns/models/expiration.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Column, DataType, Model, Table, HasMany, BelongsTo, ForeignKey } from 'sequelize-typescript'
import Domain from './domain.model'

@Table({ freezeTableName: true, tableName: 'rns_domain_expiration', timestamps: false })
export default class DomainExpiration extends Model {
@Column({ primaryKey: true, type: DataType.STRING })
tokenId!: string

@Column({ type: DataType.DATE })
expirationDate!: number
}
Loading

0 comments on commit 1642ab4

Please sign in to comment.