@ixily/activ
Version:
Alpha Capture Trade Idea Verification. Blockchain ownership proven trade ideas and strategies.
576 lines (565 loc) • 18.6 kB
text/typescript
import { CONTRACT_CONSTANTS, CONTRACT_INTERFACES } from '../../'
const validatePricingInfo = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
): string | undefined => {
const idea = ideaComplete.idea as CONTRACT_INTERFACES.ITradeIdeaIdea
if (idea.priceInfo === undefined) {
return 'The idea must have priceInfo.'
}
const priceInfo = idea.priceInfo!
if (!Array.isArray(priceInfo.response)) {
return 'The idea must have priceInfo response as array.'
}
for (const resp of priceInfo.response) {
if (typeof resp !== 'string') {
return 'The idea must have priceInfo response as array of strings.'
}
}
if (priceInfo.keys === undefined) {
return 'The idea must have priceInfo keys.'
}
if (!Array.isArray(priceInfo.keys)) {
return 'The idea must have priceInfo keys as array.'
}
for (const key of priceInfo.keys) {
if (!Array.isArray(key)) {
return 'The idea must have priceInfo keys as array of arrays.'
}
if (key.length !== 2) {
return 'The idea must have priceInfo keys as array of arrays of length 2.'
}
for (const k of key) {
if (typeof k !== 'string') {
return 'The idea must have priceInfo keys as array of arrays of strings.'
}
}
}
if (priceInfo.price === undefined) {
return 'The idea must have priceInfo price.'
}
if (priceInfo.price.provider === undefined) {
return 'The idea must have priceInfo price provider.'
}
if (
CONTRACT_CONSTANTS.PRICING_PROVIDER.find(
(one) => one === priceInfo.price!.provider,
) === undefined
) {
return 'The idea must have valid priceInfo price provider.'
}
if (priceInfo.price.symbol === undefined) {
return 'The idea must have priceInfo price symbol.'
}
if (typeof priceInfo.price.symbol !== 'string') {
return 'The idea must have priceInfo price symbol as string.'
}
if (priceInfo.price.timestamp === undefined) {
return 'The idea must have priceInfo price timestamp.'
}
if (typeof priceInfo.price.timestamp !== 'number') {
return 'The idea must have priceInfo price timestamp as number.'
}
if (
priceInfo.price.ask === undefined &&
priceInfo.price.bid !== undefined
) {
return 'The idea must have priceInfo price ask if it has bid.'
}
if (
priceInfo.price.ask !== undefined &&
priceInfo.price.bid === undefined
) {
return 'The idea must have priceInfo price bid if it has ask.'
}
if (priceInfo.price.globalPrice === undefined) {
return 'The idea must have priceInfo price globalPrice.'
}
if (typeof priceInfo.price.globalPrice !== 'number') {
return 'The idea must have priceInfo price globalPrice as number.'
}
if (priceInfo.price.globalPrice <= 0) {
return 'The idea must have priceInfo price globalPrice greater than 0.'
}
return undefined
}
const validateBasicIdeaTrade = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
): string | undefined => {
const idea = ideaComplete.idea as CONTRACT_INTERFACES.ITradeIdeaIdea
const strategyType = ideaComplete.strategy.ordersType!
if (idea.kind === undefined) {
return 'The idea must have kind.'
}
if (idea.kind === 'open') {
if (idea.adjustment !== undefined) {
return 'The idea must not have adjustment.'
}
if (idea.trade === undefined) {
return 'The idea must have trade.'
}
if (strategyType === 'ALLOCATION') {
if (idea.trade.allocation === undefined) {
return 'The idea must have trade allocation.'
}
if (typeof idea.trade.allocation !== 'number') {
return 'The idea must have trade allocation as number.'
}
if (idea.trade.allocation <= 0) {
return 'The idea must have trade allocation greater than 0.'
}
if (idea.trade.allocation > 100) {
return 'The idea must have trade allocation less or equal to 100.'
}
} else {
if (idea.trade.conviction === undefined) {
return 'The idea must have trade conviction.'
}
if (typeof idea.trade.conviction !== 'number') {
return 'The idea must have trade conviction as number.'
}
if (idea.trade.conviction <= 0) {
return 'The idea must have trade conviction greater than 0.'
}
if (idea.trade.conviction > 100) {
return 'The idea must have trade conviction less or equal to 100.'
}
}
} else if (idea.kind === 'adjust') {
if (idea.adjustment === undefined) {
return 'The idea must have adjustment object'
}
if (idea.adjustment!.kind === 'decrease') {
if (idea.adjustment.percentage <= 0) {
return 'The middle stages of the chained idea must have positive decrease.'
} else if (idea.adjustment.percentage >= 100) {
return 'The middle stages of the chained idea must have decrease less than 100.'
}
} else if (idea.adjustment!.kind === 'increase') {
if (strategyType === 'ALLOCATION') {
if (idea.adjustment.percentage < 0) {
return 'The adjustment idea must have positive increase or zero for allocation.'
}
} else {
if (idea.adjustment.percentage <= 0) {
return 'The adjustment idea must have positive increase.'
}
}
} else {
return 'The idea must have adjustment kind as increase or decrease.'
}
} else if (idea.kind === 'close') {
if (idea.adjustment !== undefined) {
return 'The idea must not have adjustment.'
}
if (idea.trade !== undefined) {
if (strategyType === 'ALLOCATION') {
if (idea.trade.allocation === undefined) {
return 'The idea must have trade allocation.'
}
if (typeof idea.trade.allocation !== 'number') {
return 'The idea must have trade allocation as number.'
}
if (idea.trade.allocation !== 0) {
return 'The idea must have trade allocation 0 when closing.'
}
} else {
if (idea.trade.conviction === undefined) {
return 'The idea must have trade conviction.'
}
if (typeof idea.trade.conviction !== 'number') {
return 'The idea must have trade conviction as number.'
}
if (idea.trade.conviction <= 0) {
return 'The idea must have trade conviction greater than 0.'
}
if (idea.trade.conviction > 100) {
return 'The idea must have trade conviction less or equal to 100.'
}
}
}
} else {
return 'The idea must have kind as open, close or adjust.'
}
if (idea.asset === undefined) {
return 'The idea must have asset.'
}
if (idea.asset.ticker === undefined) {
return 'The idea must have asset ticker.'
}
if (typeof idea.asset.ticker !== 'string') {
return 'The idea must have asset ticker as string.'
}
if (idea.asset.ticker.trim().length === 0) {
return 'The idea must have asset ticker as non empty string.'
}
if (idea.asset.description === undefined) {
return 'The idea must have asset description.'
}
if (typeof idea.asset.description !== 'string') {
return 'The idea must have asset description as string.'
}
if (idea.asset.description.trim().length === 0) {
return 'The idea must have asset description as non empty string.'
}
if (idea.notes === undefined) {
return 'The idea must have notes.'
}
if (idea.notes.commentary === undefined) {
return 'The idea must have notes commentary.'
}
if (typeof idea.notes.commentary !== 'string') {
return 'The idea must have notes commentary as string.'
}
if (idea.notes.commentary.trim().length === 0) {
return 'The idea must have notes commentary as non empty string.'
}
}
const validateBasicIdeaRoot = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
preMint: boolean = false,
): string | undefined => {
if (!preMint) {
if (ideaComplete.nftId === undefined) {
return 'The idea must have nftId.'
}
if (typeof ideaComplete.nftId !== 'number') {
return 'The idea must have nftId as number.'
}
if (ideaComplete.nftId <= 0) {
return 'The idea must have nftId greater than 0.'
}
}
if (ideaComplete.ideaSha512Hash === undefined) {
return 'The idea must have ideaSha512Hash'
}
if (typeof ideaComplete.ideaSha512Hash !== 'string') {
return 'The idea must have ideaSha512Hash as string'
}
if (ideaComplete.ideaSha512Hash.trim().length === 0) {
return 'The idea must have ideaSha512Hash as non empty string'
}
if (ideaComplete.pricing === undefined) {
return 'The idea must have pricing'
}
if (typeof ideaComplete.pricing.provider !== 'string') {
return 'The idea must have pricing provider as string'
}
if (
CONTRACT_CONSTANTS.PRICING_PROVIDER.find(
(one) => one === ideaComplete.pricing.provider,
) === undefined
) {
return 'The idea must have valid pricing provider'
}
}
const validateBasicIdeaContent = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
preMint: boolean = false,
): string | undefined => {
const idea = ideaComplete.idea as CONTRACT_INTERFACES.ITradeIdeaIdea
if (ideaComplete.content === undefined) {
return 'The idea must have content'
}
if (ideaComplete.content.reference === undefined) {
return 'The idea must have content reference'
}
if (typeof ideaComplete.content.reference !== 'string') {
return 'The idea must have content reference as string'
}
if (ideaComplete.content.reference.trim().length === 0) {
return 'The idea must have content reference as non empty string'
}
if (!preMint) {
if (ideaComplete.content.ideaNftId === undefined) {
return 'The idea must have content ideaNftId'
}
if (ideaComplete.content.ideaNftId !== ideaComplete.nftId) {
return 'The idea must have content ideaNftId equal to nftId'
}
if (ideaComplete.content.ideaStageKey === undefined) {
return 'The idea must have content ideaStageKey'
}
if (typeof ideaComplete.content.ideaStageKey !== 'number') {
return 'The idea must have content ideaStageKey as number'
}
if (ideaComplete.content.ideaStageKey < 0) {
return 'The idea must have content ideaStageKey greater or equal 0'
}
}
if (!preMint || idea.kind !== 'open') {
if (ideaComplete.content.ideaKey === undefined) {
return 'The idea must have content ideaKey'
}
if (typeof ideaComplete.content.ideaKey !== 'number') {
return 'The idea must have content ideaKey as number'
}
}
}
const validateBasicEncryptedIdeaContent = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
preMint: boolean = false,
): string | undefined => {
if (ideaComplete.content === undefined) {
return 'The idea must have content'
}
if (ideaComplete.content.reference === undefined) {
return 'The idea must have content reference'
}
if (typeof ideaComplete.content.reference !== 'string') {
return 'The idea must have content reference as string'
}
if (ideaComplete.content.reference.trim().length === 0) {
return 'The idea must have content reference as non empty string'
}
if (!preMint) {
if (ideaComplete.content.ideaNftId === undefined) {
return 'The idea must have content ideaNftId'
}
if (ideaComplete.content.ideaNftId !== ideaComplete.nftId) {
return 'The idea must have content ideaNftId equal to nftId'
}
if (ideaComplete.content.ideaStageKey === undefined) {
return 'The idea must have content ideaStageKey'
}
if (typeof ideaComplete.content.ideaStageKey !== 'number') {
return 'The idea must have content ideaStageKey as number'
}
if (ideaComplete.content.ideaStageKey < 0) {
return 'The idea must have content ideaStageKey greater or equal 0'
}
}
if (!preMint) {
if (ideaComplete.content.ideaKey === undefined) {
return 'The idea must have content ideaKey'
}
if (typeof ideaComplete.content.ideaKey !== 'number') {
return 'The idea must have content ideaKey as number'
}
}
}
const validateBasicIdeaCreator = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
): string | undefined => {
if (ideaComplete.creator === undefined) {
return 'The idea must have creator'
}
if (ideaComplete.creator.name === undefined) {
return 'The idea must have creator name'
}
if (typeof ideaComplete.creator.name !== 'string') {
return 'The idea must have creator name as string'
}
if (ideaComplete.creator.name.trim().length === 0) {
return 'The idea must have creator name as non empty string'
}
if (ideaComplete.creator.company !== undefined) {
if (typeof ideaComplete.creator.company !== 'string') {
return 'The idea must have creator company as string'
}
if (ideaComplete.creator.company.trim().length === 0) {
return 'The idea must have creator company as non empty string'
}
}
if (ideaComplete.creator.url !== undefined) {
if (typeof ideaComplete.creator.url !== 'string') {
return 'The idea must have creator url as string'
}
if (ideaComplete.creator.url.trim().length === 0) {
return 'The idea must have creator url as non empty string'
}
}
if (ideaComplete.creator.companyLogo?.cid !== undefined) {
if (typeof ideaComplete.creator.companyLogo.cid !== 'string') {
return 'The idea must have creator companyLogo as string'
}
}
// if (ideaComplete.creator.backgroundImage !== undefined) {
// if (typeof ideaComplete.creator.backgroundImage !== 'string') {
// return 'The idea must have creator backgroundImage as string'
// }
// }
if (ideaComplete.creator.walletAddress === undefined) {
return 'The idea must have creator walletAddress'
}
if (typeof ideaComplete.creator.walletAddress !== 'string') {
return 'The idea must have creator walletAddress as string'
}
if (ideaComplete.creator.walletAddress.trim().length === 0) {
return 'The idea must have creator walletAddress as non empty string'
}
return undefined
}
const validateBasicIdeaStrategy = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
cachedStrategyState: CONTRACT_INTERFACES.IStrategyState,
preMint: boolean = false,
): string | undefined => {
if (ideaComplete.strategy === undefined) {
return 'The idea must have strategy'
}
if (ideaComplete.strategy.reference === undefined) {
return 'The idea must have strategy reference'
}
if (ideaComplete.strategy.uniqueKey === undefined) {
return 'The idea must have strategy uniqueKey'
}
if (typeof ideaComplete.strategy.reference !== 'string') {
return 'The idea must have strategy reference as string'
}
if (typeof ideaComplete.strategy.uniqueKey !== 'string') {
return 'The idea must have strategy uniqueKey as string'
}
if (ideaComplete.strategy.reference.trim().length === 0) {
return 'The idea must have strategy reference as non empty string'
}
if (ideaComplete.strategy.name === undefined) {
return 'The idea must have strategy name'
}
if (typeof ideaComplete.strategy.name !== 'string') {
return 'The idea must have strategy name as string'
}
if (ideaComplete.strategy.name.trim().length === 0) {
return 'The idea must have strategy name as non empty string'
}
if (ideaComplete.strategy.description === undefined) {
return 'The idea must have strategy description'
}
if (typeof ideaComplete.strategy.description !== 'string') {
return 'The idea must have strategy description as string'
}
if (ideaComplete.strategy.description.trim().length === 0) {
return 'The idea must have strategy description as non empty string'
}
if (preMint) {
if (ideaComplete.strategy.createdAt === undefined) {
ideaComplete.strategy.createdAt =
cachedStrategyState.strategy.createdAt!
}
if (ideaComplete.strategy.changedAt === undefined) {
ideaComplete.strategy.changedAt =
cachedStrategyState.strategy.changedAt!
}
} else {
if (ideaComplete.strategy.createdAt === undefined) {
return 'The idea must have strategy createdAt'
}
if (typeof ideaComplete.strategy.createdAt !== 'number') {
return 'The idea must have strategy createdAt as number'
}
if (ideaComplete.strategy.changedAt === undefined) {
return 'The idea must have strategy changedAt'
}
if (typeof ideaComplete.strategy.changedAt !== 'number') {
return 'The idea must have strategy changedAt as number'
}
if (ideaComplete.strategy.image?.cid !== undefined) {
if (typeof ideaComplete.strategy.image.cid !== 'string') {
return 'The idea must have strategy image as string'
}
}
}
if (ideaComplete.strategy.externalLink !== undefined) {
if (typeof ideaComplete.strategy.externalLink !== 'string') {
return 'The idea must have strategy externalLink as string'
}
}
if (ideaComplete.strategy.ordersType === undefined) {
if (preMint) {
ideaComplete.strategy.ordersType =
cachedStrategyState.strategy.ordersType!
} else {
return 'The idea must have strategy ordersType'
}
}
if (typeof ideaComplete.strategy.ordersType !== 'string') {
return 'The idea must have strategy ordersType as string'
}
if (
ideaComplete.strategy.ordersType !== 'ALLOCATION' &&
ideaComplete.strategy.ordersType !== 'STANDARD'
) {
return 'The idea must have strategy ordersType as ALLOCATION or STANDARD'
}
if (cachedStrategyState.strategy.ordersType !== undefined) {
if (
ideaComplete.strategy.ordersType !==
cachedStrategyState.strategy.ordersType
) {
return (
'The idea must have strategy ordersType equal to cached strategy ordersType ' +
cachedStrategyState.strategy.ordersType +
'.'
)
}
}
}
export const validateBasicIdea = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
cachedStrategyState: CONTRACT_INTERFACES.IStrategyState,
preMint: boolean = false,
): string | undefined => {
let violation: string | undefined = undefined
// nftId
// ideaShar512Hash
// pricing
violation = validateBasicIdeaRoot(ideaComplete, preMint)
if (violation !== undefined) {
return violation
}
violation = validateBasicIdeaContent(ideaComplete, preMint)
if (violation !== undefined) {
return violation
}
violation = validateBasicIdeaStrategy(
ideaComplete,
cachedStrategyState,
preMint,
)
if (violation !== undefined) {
return violation
}
violation = validateBasicIdeaCreator(ideaComplete)
if (violation !== undefined) {
return violation
}
violation = validateBasicIdeaTrade(ideaComplete)
if (violation !== undefined) {
return violation
}
violation = validatePricingInfo(ideaComplete)
if (violation !== undefined) {
return violation
}
return undefined
}
export const validateBasicEncryptedIdea = (
ideaComplete: CONTRACT_INTERFACES.ITradeIdea,
cachedStrategyState: CONTRACT_INTERFACES.IStrategyState,
preMint: boolean = false,
): string | undefined => {
let violation: string | undefined = undefined
// nftId
// ideaShar512Hash
// pricing
violation = validateBasicIdeaRoot(ideaComplete, preMint)
if (violation !== undefined) {
return violation
}
violation = validateBasicEncryptedIdeaContent(ideaComplete, preMint)
if (violation !== undefined) {
return violation
}
violation = validateBasicIdeaStrategy(
ideaComplete,
cachedStrategyState,
preMint,
)
if (violation !== undefined) {
return violation
}
violation = validateBasicIdeaCreator(ideaComplete)
if (violation !== undefined) {
return violation
}
return undefined
}