UNPKG

@ixily/activ

Version:

Alpha Capture Trade Idea Verification. Blockchain ownership proven trade ideas and strategies.

829 lines (791 loc) 19.8 kB
import { CONTRACT_INTERFACES, CONTRACT_TOOLS, IPaging, IPortfolioRebalanceAssetOpaque, IPortfolioRebalanceOpaque, IPortfolioView, IStrategyWithCreator, IWeb3AuthorizationOptions, Mess, MyMessDbServer, getDataWithPaging, postQueryIdeasFilterAndPagination, voidPaging, } from '../..' import { MyIdeaKeys } from '../../interfaces/chunks/my-idea-keys.i' import { ConfigModule } from './config.module' const state = { servers: undefined as MyMessDbServer[] | undefined, } const startLocalServer = async (details: IWeb3AuthorizationOptions) => { if (state.servers === undefined) { state.servers = [] state.servers = await Mess.serveContractsDb([ { blockchainNetwork: 'amoy', contractName: 'v4', details, }, { blockchainNetwork: 'polygon', contractName: 'v4', details, }, ]) state.servers.forEach((server) => { server.error$.subscribe((error) => { if (error !== undefined) { console.error(error) throw error } }) }) } else { state.servers.forEach((server) => { server.resume() }) } } ConfigModule.getConfigUpdatedStream().subscribe((config) => { if (config !== undefined) { if (config.dataSource !== undefined) { if (config.dataSource.publicCache.source === 'local') { if (config.dataSource.publicCache.autoServe !== false) { startLocalServer(config.web3AuthorizationOptions) } } } } }) const pauseLocalServer = () => { if (state.servers !== undefined) { state.servers.forEach((server) => { server.pause() }) } } const listContracts = async (): Promise<string[]> => { return Mess.contractsInMemoryDbView.listAllContracts() } const getCreator = async ( contract: string, creatorWallet: string, ): Promise<CONTRACT_INTERFACES.ITradeIdeaCreator> => { return Mess.contractsInMemoryDbView.getCreator(contract, creatorWallet) } const getIdeaByUniqueId = async ( uniqueIdeaId: string, ): Promise<CONTRACT_INTERFACES.ITradeIdea> => { return Mess.contractsInMemoryDbView.getIdeaData(uniqueIdeaId) } const listCreatorStrategies = async ( contract: string, creatorWallet: string, page: number = 1, limit: number = 5, ): Promise<IPaging<IStrategyWithCreator>> => { try { const preCut = await Mess.contractsInMemoryDbView.listContractCreatorStrategies( contract, creatorWallet, ) preCut.reverse() const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<IStrategyWithCreator> = { ...preInflate, data: await Promise.all( preInflate.data.map((strategyKey) => Mess.contractsInMemoryDbView.getStrategyWithCreator( strategyKey, ), ), ), } return result } catch (err: any) { if (typeof err.message === 'string') { if ( err.message.indexOf('No creator found for creatorWallet') !== -1 ) { return voidPaging<IStrategyWithCreator>(page, limit) } else { throw err } } else { throw err } } } const listStrategiesWithAccessibleIdeasBy = async ( contract: string, accessorWallet: string, page: number = 1, limit: number = 5, ): Promise<IPaging<IStrategyWithCreator>> => { try { const preCut = await Mess.contractsInMemoryDbView.listContractUserWithAccessibleIdeasStrategies( contract, accessorWallet, ) const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<IStrategyWithCreator> = { ...preInflate, data: await Promise.all( (preCut as string[]).map((strategyKey) => Mess.contractsInMemoryDbView.getStrategyWithCreator( strategyKey, ), ), ), } return result } catch (err: any) { if (typeof err.message === 'string') { if ( err.message.indexOf( 'No contractDb found for uniqueContractKey:', ) !== -1 ) { return voidPaging<IStrategyWithCreator>(page, limit) } else { throw err } } else { throw err } } } const listStrategiesSubscribedToBy = async ( contract: string, accessorWallet: string, page: number = 1, limit: number = 5, ): Promise<IPaging<IStrategyWithCreator>> => { try { const preCut = await Mess.contractsInMemoryDbView.listContractUserSubscribedToIdeasStrategies( contract, accessorWallet, ) const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<IStrategyWithCreator> = { ...preInflate, data: await Promise.all( (preCut as string[]).map((strategyKey) => Mess.contractsInMemoryDbView.getStrategyWithCreator( strategyKey, ), ), ), } return result } catch (err: any) { if (typeof err.message === 'string') { if ( err.message.indexOf( 'No contractDb found for uniqueContractKey:', ) !== -1 ) { return voidPaging<IStrategyWithCreator>(page, limit) } else { throw err } } else { throw err } } } const listStrategiesPublic = async ( contract?: string, page: number = 1, limit: number = 5, ): Promise<IPaging<IStrategyWithCreator>> => { let contracts: string[] = [] if (contract !== undefined) { if (typeof contract === 'string') { if (contract.length > 1) { const keyContracts = await Mess.contractsInMemoryDbView.listAllContracts() if ( keyContracts.find((one) => one === contract) !== undefined ) { contracts.push(contract) } else { // not fount contract key error return voidPaging<IStrategyWithCreator>(page, limit) } } else { // not fount contract key error return voidPaging<IStrategyWithCreator>(page, limit) } } else { // not fount contract key error return voidPaging<IStrategyWithCreator>(page, limit) } } // console.log('&&&&&&&&') // console.log('contracts') // console.log(contracts) // console.log('&&&&&&&&') if (contracts.length === 0) { contracts = [...(await Mess.contractsInMemoryDbView.listAllContracts())] } const allData = await Promise.all( contracts.map((contract) => (async () => { // console.log('contract') // console.log(contract) const data = ( await Mess.contractsInMemoryDbView.listContractWithPublicIdeasStrategies( contract, ) ).reverse() // console.log('data') // console.log(data) return data })(), ), ) // console.log('allData') // console.log(allData) const preCut = CONTRACT_TOOLS.deterministicEvenlyMixedArray(allData) const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) // contract here is unique contract key. we need to translate it into right strategy chain const result: IPaging<IStrategyWithCreator> = { ...preInflate, data: await Promise.all( preInflate.data.map((strategyKey) => Mess.contractsInMemoryDbView.getStrategyWithCreator( strategyKey, ), ), ), } return result } const getPublicStrategyWithCreator = async ( strategyUniqueKey: string, ): Promise<IStrategyWithCreator> => { return Mess.contractsInMemoryDbView.getStrategyWithCreator( strategyUniqueKey, ) } const listIdeasUniqueIndexesByLatest = async ( contract: string, page: number = 1, limit: number = 5, ): Promise<IPaging<string>> => { const preCut = await Mess.contractsInMemoryDbView.listAllIdeasIndexesByContract( contract, ) const posReverse = preCut.reverse() const preInflate = await getDataWithPaging<string>({ data: posReverse as string[], paging: { page: page || 1, limit: limit || 5, }, }) return preInflate } const listPublicIdeasUniqueIndexesByLatest = async ( contract: string, page: number = 1, limit: number = 5, ): Promise<IPaging<string>> => { const preReverse = await Mess.contractsInMemoryDbView.listAllPublicIdeasIndexesByContract( contract, ) const preCut = preReverse.reverse() const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) return preInflate } /* const listIdeasIndexes = async ( contract: string, page: number = 1, limit: number = 5, ): Promise<IPaging<MyIdeaKeys>> => { const indexes = await listIdeasUniqueIndexesByLatest(contract, page, limit) const dataKeys = await Promise.all( indexes.data.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaKeys(ideaKey), ), ) const result: IPaging<MyIdeaKeys> = { ...indexes, data: dataKeys, } return result } */ const listLatestIdeas = async ( contract: string, page: number = 1, limit: number = 5, ): Promise<IPaging<CONTRACT_INTERFACES.ITradeIdea>> => { const keys = await listIdeasUniqueIndexesByLatest(contract, page, limit) const result: IPaging<CONTRACT_INTERFACES.ITradeIdea> = { ...keys, data: await Promise.all( keys.data.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaData(ideaKey), ), ), } return result } const listLatestPublicIdeas = async ( contract?: string, page: number = 1, limit: number = 5, ): Promise<IPaging<CONTRACT_INTERFACES.ITradeIdea>> => { let contracts: string[] = [] if (contract !== undefined) { if (typeof contract === 'string') { if (contract.length > 1) { const keyContracts = await Mess.contractsInMemoryDbView.listAllContracts() if ( keyContracts.find((one) => one === contract) !== undefined ) { contracts.push(contract) } else { // not fount contract key error return voidPaging<CONTRACT_INTERFACES.ITradeIdea>( page, limit, ) } } else { // not fount contract key error return voidPaging<CONTRACT_INTERFACES.ITradeIdea>(page, limit) } } else { // not fount contract key error return voidPaging<CONTRACT_INTERFACES.ITradeIdea>(page, limit) } } if (contracts.length === 0) { contracts = [...(await Mess.contractsInMemoryDbView.listAllContracts())] } const allData = await Promise.all( contracts.map((contract) => (async () => { // console.log('contract') // console.log(contract) const data = ( await Mess.contractsInMemoryDbView.listAllPublicIdeasIndexesByContract( contract, ) ).reverse() // console.log('data') // console.log(data) return data })(), ), ) const preCut = CONTRACT_TOOLS.deterministicEvenlyMixedArray(allData) const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<CONTRACT_INTERFACES.ITradeIdea> = { ...preInflate, data: await Promise.all( preInflate.data.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaData(ideaKey), ), ), } return result } const listCreatorIdeas = async ( contract: string, creatorWallet: string, page: number = 1, limit: number = 5, filterType: CONTRACT_INTERFACES.ITradeIdeaIdeaKind[] | 'bypass' = 'bypass', filterIncludeEncrypted: boolean = false, bypassPaginationAndGetAll: boolean = false, ): Promise<IPaging<CONTRACT_INTERFACES.ITradeIdea>> => { const preReverse = await Mess.contractsInMemoryDbView.listCreatedByIdeasIndexesByContract( contract, creatorWallet, ) const preCut = preReverse.reverse() const postInflate = await Promise.all( preCut.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaData(ideaKey), ), ) const postPageFiltered = postQueryIdeasFilterAndPagination( postInflate, page, limit, filterType, filterIncludeEncrypted, bypassPaginationAndGetAll, ) /* const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<CONTRACT_INTERFACES.ITradeIdea> = { ...preInflate, data: await Promise.all( preInflate.data.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaData(ideaKey), ), ), } */ return postPageFiltered } const listOwnedIdeas = async ( contract: string, creatorWallet: string, page: number = 1, limit: number = 5, filterType: CONTRACT_INTERFACES.ITradeIdeaIdeaKind[] | 'bypass' = 'bypass', filterIncludeEncrypted: boolean = false, bypassPaginationAndGetAll: boolean = false, ): Promise<IPaging<CONTRACT_INTERFACES.ITradeIdea>> => { const preCut = await Mess.contractsInMemoryDbView.listOwnedByIdeasKeysByContract( contract, creatorWallet, ) const onlyLastStagesOfEachIdeaIndexes = getOnlyLastStagesOfEachIdeaIndexes(preCut) onlyLastStagesOfEachIdeaIndexes.reverse() const postInflate = await Promise.all( onlyLastStagesOfEachIdeaIndexes.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaData(ideaKey), ), ) const postPageFiltered = postQueryIdeasFilterAndPagination( postInflate, page, limit, filterType, filterIncludeEncrypted, bypassPaginationAndGetAll, ) /* const preInflate = await getDataWithPaging<string>({ data: preCut as string[], paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<CONTRACT_INTERFACES.ITradeIdea> = { ...preInflate, data: await Promise.all( preInflate.data.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaData(ideaKey), ), ), } */ return postPageFiltered } const getOnlyLastStagesOfEachIdeaIndexes = (ideas: MyIdeaKeys[]): string[] => { const alreadyKey = new Map<number, string>() const ideaKeysOrdered: number[] = [] for (const idKey of ideas) { if (!alreadyKey.has(idKey.ideaKey)) { ideaKeysOrdered.push(idKey.ideaKey) } alreadyKey.set(idKey.ideaKey, idKey.ideaIndex) } // console.log('ideaKeysOrdered') // console.log(ideaKeysOrdered) const onlyLatestStagesOrderedIndexes = ideaKeysOrdered.map( (each) => alreadyKey.get(each)!, ) return onlyLatestStagesOrderedIndexes } const listStrategyIdeas = async ( strategyUniqueKey: string, page: number = 1, limit: number = 5, filterType: CONTRACT_INTERFACES.ITradeIdeaIdeaKind[] | 'bypass' = 'bypass', filterIncludeEncrypted: boolean = true, bypassPaginationAndGetAll: boolean = false, ) => { const preCut = await Mess.contractsInMemoryDbView.listAllIdeasKeysByStrategy( strategyUniqueKey, ) // console.log('preCut') // console.log(preCut) const onlyLatestStagesOrderedIndexes = getOnlyLastStagesOfEachIdeaIndexes(preCut) // console.log('onlyLatestStagesOrderedIndexes') // console.log(onlyLatestStagesOrderedIndexes) onlyLatestStagesOrderedIndexes.reverse() const postInflate = await Promise.all( onlyLatestStagesOrderedIndexes.map((ideaKey) => Mess.contractsInMemoryDbView.getIdeaData(ideaKey), ), ) // console.log('postInflate') // console.log(postInflate) const postPageFiltered = postQueryIdeasFilterAndPagination( postInflate, page, limit, filterType, filterIncludeEncrypted, bypassPaginationAndGetAll, ) return postPageFiltered } const getStrategyPortfolio = async ( strategyUniqueKey: string, ): Promise<IPortfolioView | 'ENCRYPTED'> => { const portfolio = await Mess.contractsInMemoryDbView.getStrategyPortfolio( strategyUniqueKey, ) return portfolio } const listStrategyRebalances = async ( strategyUniqueKey: string, page: number = 1, limit: number = 5, ): Promise<IPaging<IPortfolioRebalanceOpaque>> => { const preCut = await Mess.contractsInMemoryDbView.getStrategyRebalances( strategyUniqueKey, ) // console.log('preCut') // console.log(preCut) preCut.reverse() const preInflate = await getDataWithPaging<{ index: number reference: string ideaIndexes: string[] }>({ data: preCut, paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<IPortfolioRebalanceOpaque> = { ...preInflate, data: await Promise.all( preInflate.data.map(async (rebalance) => { let assets = await Promise.all( rebalance.ideaIndexes.map(async (ideaIndex) => { const lastIdea = await Mess.contractsInMemoryDbView.getIdeaData( ideaIndex, ) const result: IPortfolioRebalanceAssetOpaque = { lastIdea, } return result }), ) assets = assets.filter((asset) => { let kindClose: boolean = false if (typeof asset.lastIdea.idea !== 'string') { if ( ( asset.lastIdea .idea as CONTRACT_INTERFACES.ITradeIdeaIdea ).kind === 'close' ) { kindClose = true } } return !kindClose }) const result: IPortfolioRebalanceOpaque = { strategyKey: strategyUniqueKey, reference: rebalance.reference, totalAssets: assets.length, assets, } return result }), ), } return result } const getStrategyRebalance = async ( strategyUniqueKey: string, rebalanceReference: string, ): Promise<IPortfolioRebalanceOpaque> => { const rebalance = await Mess.contractsInMemoryDbView.getStrategyRebalance( strategyUniqueKey, rebalanceReference, ) let assets = await Promise.all( rebalance.ideaIndexes.map(async (ideaIndex) => { const lastIdea = await Mess.contractsInMemoryDbView.getIdeaData( ideaIndex, ) const result: IPortfolioRebalanceAssetOpaque = { lastIdea, } return result }), ) assets = assets.filter((asset) => { let kindClose: boolean = false if (typeof asset.lastIdea.idea !== 'string') { if ( (asset.lastIdea.idea as CONTRACT_INTERFACES.ITradeIdeaIdea) .kind === 'close' ) { kindClose = true } } return !kindClose }) const result: IPortfolioRebalanceOpaque = { strategyKey: strategyUniqueKey, reference: rebalance.reference, totalAssets: assets.length, assets, } return result } const listStrategyRebalancesInPeriod = async ( strategyUniqueKey: string, start: number, end: number, page: number = 1, limit: number = 5, ): Promise<IPaging<IPortfolioRebalanceOpaque>> => { const preCut = await Mess.contractsInMemoryDbView.getStrategyRebalancesInPeriod( strategyUniqueKey, start, end, ) const preInflate = await getDataWithPaging<{ index: number reference: string ideaIndexes: string[] }>({ data: preCut, paging: { page: page || 1, limit: limit || 5, }, }) const result: IPaging<IPortfolioRebalanceOpaque> = { ...preInflate, data: await Promise.all( preInflate.data.map(async (rebalance) => { let assets = await Promise.all( rebalance.ideaIndexes.map(async (ideaIndex) => { const lastIdea = await Mess.contractsInMemoryDbView.getIdeaData( ideaIndex, ) const result: IPortfolioRebalanceAssetOpaque = { lastIdea, } return result }), ) assets = assets.filter((asset) => { let kindClose: boolean = false if (typeof asset.lastIdea.idea !== 'string') { if ( ( asset.lastIdea .idea as CONTRACT_INTERFACES.ITradeIdeaIdea ).kind === 'close' ) { kindClose = true } } return !kindClose }) const result: IPortfolioRebalanceOpaque = { strategyKey: strategyUniqueKey, reference: rebalance.reference, totalAssets: assets.length, assets, } return result }), ), } return result } export const ViewsSourceMessModule = { startLocalServer, pauseLocalServer, // listContracts, getCreator, listCreatorStrategies, listStrategiesWithAccessibleIdeasBy, listStrategiesSubscribedToBy, listStrategiesPublic, listIdeasUniqueIndexesByLatest, listLatestIdeas, listLatestPublicIdeas, listCreatorIdeas, listOwnedIdeas, listStrategyIdeas, getIdeaByUniqueId, getPublicStrategyWithCreator, getStrategyPortfolio, listStrategyRebalances, getStrategyRebalance, listStrategyRebalancesInPeriod, // listIdeaStagesIndexes, // getIdeaByNftId, // listIdeaNftsByStrategy, }