diff --git a/packages/engine/paima-funnel/src/cde/cardanoProjectedNFT.ts b/packages/engine/paima-funnel/src/cde/cardanoProjectedNFT.ts index a605ba10b..1bb57177a 100644 --- a/packages/engine/paima-funnel/src/cde/cardanoProjectedNFT.ts +++ b/packages/engine/paima-funnel/src/cde/cardanoProjectedNFT.ts @@ -1,58 +1,69 @@ import type { - CdeCardanoProjectedNFTDatum, - ChainDataExtensionCardanoProjectedNFT, - ChainDataExtensionDatum, + CdeCardanoProjectedNFTDatum, + ChainDataExtensionCardanoProjectedNFT, + ChainDataExtensionDatum, } from '@paima/sm'; import { ChainDataExtensionDatumType, DEFAULT_FUNNEL_TIMEOUT, timeout } from '@paima/utils'; import { Routes, query } from '@dcspark/carp-client/client/src'; -import type { ProjectedNftRangeResponse } from "@dcspark/carp-client/shared/models/ProjectedNftRange"; +import type { ProjectedNftRangeResponse } from '@dcspark/carp-client/shared/models/ProjectedNftRange'; export default async function getCdeProjectedNFTData( - url: string, - extension: ChainDataExtensionCardanoProjectedNFT, - fromAbsoluteSlot: number, - toAbsoluteSlot: number, - getBlockNumber: (slot: number) => number + url: string, + extension: ChainDataExtensionCardanoProjectedNFT, + fromAbsoluteSlot: number, + toAbsoluteSlot: number, + getBlockNumber: (slot: number) => number ): Promise { - const events = await timeout( - query(url, Routes.projectedNftEventsRange, { - range: { minSlot: fromAbsoluteSlot, maxSlot: toAbsoluteSlot }, - }), - DEFAULT_FUNNEL_TIMEOUT - ); - - return events.map(e => eventToCdeDatum(e, extension, getBlockNumber(e.actionSlot))).filter(e => e != null).map(e => e!!); + const events = await timeout( + query(url, Routes.projectedNftEventsRange, { + range: { minSlot: fromAbsoluteSlot, maxSlot: toAbsoluteSlot }, + }), + DEFAULT_FUNNEL_TIMEOUT + ); + + return events + .map(e => eventToCdeDatum(e, extension, getBlockNumber(e.actionSlot))) + .filter(e => e != null) + .map(e => e!!); } function eventToCdeDatum( - event: ProjectedNftRangeResponse[0], - extension: ChainDataExtensionCardanoProjectedNFT, - blockNumber: number + event: ProjectedNftRangeResponse[0], + extension: ChainDataExtensionCardanoProjectedNFT, + blockNumber: number ): CdeCardanoProjectedNFTDatum | null { - if (event.ownerAddress == null || event.actionTxId == null || event.status == null) { - return null; - } - - return { - cdeId: extension.cdeId, - cdeDatumType: ChainDataExtensionDatumType.CardanoProjectedNFT, - blockNumber, - payload: { - ownerAddress: event.ownerAddress!!, - - actionTxId: event.actionTxId, - actionOutputIndex: event.actionOutputIndex || undefined, - - previousTxHash: event.previousTxHash || undefined, - previousTxOutputIndex: event.previousTxOutputIndex || undefined, - - asset: event.asset, - amount: event.amount, - status: event.status, - plutusDatum: event.plutusDatum || "", - - forHowLong: event.forHowLong || undefined, - }, - scheduledPrefix: extension.scheduledPrefix, - }; + if ( + event.ownerAddress === null || + event.ownerAddress == '' || + event.actionTxId === null || + event.actionTxId == '' || + event.status === null || + event.actionTxId == '' + ) { + return null; + } + + return { + cdeId: extension.cdeId, + cdeDatumType: ChainDataExtensionDatumType.CardanoProjectedNFT, + blockNumber, + payload: { + ownerAddress: event.ownerAddress != null ? event.ownerAddress : '', + + actionTxId: event.actionTxId, + actionOutputIndex: event.actionOutputIndex != null ? event.actionOutputIndex : undefined, + + previousTxHash: event.previousTxHash != null ? event.previousTxHash : undefined, + previousTxOutputIndex: + event.previousTxOutputIndex != null ? event.previousTxOutputIndex : undefined, + + asset: event.asset, + amount: event.amount, + status: event.status, + plutusDatum: event.plutusDatum != null ? event.plutusDatum : '', + + forHowLong: event.forHowLong != null ? event.forHowLong : undefined, + }, + scheduledPrefix: extension.scheduledPrefix, + }; } diff --git a/packages/engine/paima-funnel/src/funnels/BaseFunnel.ts b/packages/engine/paima-funnel/src/funnels/BaseFunnel.ts index c032fbbba..51938b957 100644 --- a/packages/engine/paima-funnel/src/funnels/BaseFunnel.ts +++ b/packages/engine/paima-funnel/src/funnels/BaseFunnel.ts @@ -1,5 +1,5 @@ import type { ChainFunnel, ReadPresyncDataFrom } from '@paima/runtime'; -import type {ChainData, ChainDataExtension, PresyncChainData } from '@paima/sm'; +import type { ChainData, ChainDataExtension, PresyncChainData } from '@paima/sm'; import type { PaimaL2Contract, Web3 } from '@paima/utils'; import type { FunnelCacheManager } from './FunnelCache.js'; import type { PoolClient } from 'pg'; diff --git a/packages/engine/paima-funnel/src/funnels/carp/funnel.ts b/packages/engine/paima-funnel/src/funnels/carp/funnel.ts index c65186ff3..8c8be28f3 100644 --- a/packages/engine/paima-funnel/src/funnels/carp/funnel.ts +++ b/packages/engine/paima-funnel/src/funnels/carp/funnel.ts @@ -11,21 +11,22 @@ import { import { type ChainData, type ChainDataExtension, - type ChainDataExtensionCardanoDelegation, ChainDataExtensionCardanoProjectedNFT, + type ChainDataExtensionCardanoDelegation, + ChainDataExtensionCardanoProjectedNFT, type ChainDataExtensionDatum, type PresyncChainData, } from '@paima/sm'; -import {composeChainData, groupCdeData} from '../../utils.js'; -import type {FunnelSharedData} from '../BaseFunnel.js'; -import {BaseFunnel} from '../BaseFunnel.js'; -import type {PoolClient} from 'pg'; -import type {ChainFunnel, ReadPresyncDataFrom} from '@paima/runtime'; +import { composeChainData, groupCdeData } from '../../utils.js'; +import type { FunnelSharedData } from '../BaseFunnel.js'; +import { BaseFunnel } from '../BaseFunnel.js'; +import type { PoolClient } from 'pg'; +import type { ChainFunnel, ReadPresyncDataFrom } from '@paima/runtime'; import getCdePoolData from '../../cde/cardanoPool.js'; import getCdeProjectedNFTData from '../../cde/cardanoProjectedNFT.js'; -import {query} from '@dcspark/carp-client/client/src/index'; -import {Routes} from '@dcspark/carp-client/shared/routes'; -import {FUNNEL_PRESYNC_FINISHED} from '@paima/utils/src/constants'; -import {CarpFunnelCacheEntry} from '../FunnelCache.js'; +import { query } from '@dcspark/carp-client/client/src/index'; +import { Routes } from '@dcspark/carp-client/shared/routes'; +import { FUNNEL_PRESYNC_FINISHED } from '@paima/utils/src/constants'; +import { CarpFunnelCacheEntry } from '../FunnelCache.js'; const delayForWaitingForFinalityLoop = 1000; @@ -144,28 +145,33 @@ export class CarpFunnel extends BaseFunnel implements ChainFunnel { const [carpEvents, data] = await Promise.all([ Promise.all( this.sharedData.extensions - .filter(extension => extension.cdeType === ChainDataExtensionType.CardanoPool || extension.cdeType === ChainDataExtensionType.CardanoProjectedNFT) + .filter( + extension => + extension.cdeType === ChainDataExtensionType.CardanoPool || + extension.cdeType === ChainDataExtensionType.CardanoProjectedNFT + ) .map(extension => { if (extension.cdeType === ChainDataExtensionType.CardanoPool) { const data = getCdePoolData( - this.carpUrl, - extension as ChainDataExtensionCardanoDelegation, - arg.from, - Math.min(arg.to, this.cache.getState().startingSlot - 1), - slot => { - return slot; - } + this.carpUrl, + extension as ChainDataExtensionCardanoDelegation, + arg.from, + Math.min(arg.to, this.cache.getState().startingSlot - 1), + slot => { + return slot; + } ); return data; - } else { // ProjectedNFT + } else { + // ProjectedNFT const data = getCdeProjectedNFTData( - this.carpUrl, - extension as ChainDataExtensionCardanoProjectedNFT, - arg.from, - Math.min(arg.to, this.cache.getState().startingSlot - 1), - slot => { - return slot; - } + this.carpUrl, + extension as ChainDataExtensionCardanoProjectedNFT, + arg.from, + Math.min(arg.to, this.cache.getState().startingSlot - 1), + slot => { + return slot; + } ); return data; } @@ -326,8 +332,7 @@ async function readDataInternal( Network.EVM, data[0].blockNumber, data[data.length - 1].blockNumber, - poolEvents - .filter(data => data.length > 0) + poolEvents.filter(data => data.length > 0) ); return grouped; diff --git a/packages/engine/paima-runtime/src/cde-config/utils.ts b/packages/engine/paima-runtime/src/cde-config/utils.ts index 802d12194..b3cedc416 100644 --- a/packages/engine/paima-runtime/src/cde-config/utils.ts +++ b/packages/engine/paima-runtime/src/cde-config/utils.ts @@ -1,12 +1,15 @@ import * as fs from 'fs/promises'; -import {ChainDataExtensionType, doLog} from '@paima/utils'; +import { ChainDataExtensionType, doLog } from '@paima/utils'; -import type {ChainDataExtension} from '@paima/sm'; +import type { ChainDataExtension } from '@paima/sm'; export function getEarliestStartBlockheight(config: ChainDataExtension[]): number { const minStartBlockheight = config.reduce((min, cde) => { - if (cde.cdeType !== ChainDataExtensionType.CardanoPool && cde.cdeType != ChainDataExtensionType.CardanoProjectedNFT) { + if ( + cde.cdeType !== ChainDataExtensionType.CardanoPool && + cde.cdeType != ChainDataExtensionType.CardanoProjectedNFT + ) { return Math.min(min, cde.startBlockHeight); } return min; @@ -16,7 +19,10 @@ export function getEarliestStartBlockheight(config: ChainDataExtension[]): numbe export function getEarliestStartSlot(config: ChainDataExtension[]): number { const minStartSlot = config.reduce((min, cde) => { - if (cde.cdeType === ChainDataExtensionType.CardanoPool || cde.cdeType == ChainDataExtensionType.CardanoProjectedNFT) { + if ( + cde.cdeType === ChainDataExtensionType.CardanoPool || + cde.cdeType == ChainDataExtensionType.CardanoProjectedNFT + ) { return Math.min(min, cde.startSlot); } return min; diff --git a/packages/engine/paima-runtime/src/runtime-loops.ts b/packages/engine/paima-runtime/src/runtime-loops.ts index 223fe0834..39c297779 100644 --- a/packages/engine/paima-runtime/src/runtime-loops.ts +++ b/packages/engine/paima-runtime/src/runtime-loops.ts @@ -2,10 +2,8 @@ import process from 'process'; import { doLog, logError, delay, Network, ENV } from '@paima/utils'; import { tx, DataMigrations } from '@paima/db'; import { getEarliestStartBlockheight, getEarliestStartSlot } from './cde-config/utils.js'; -import type { ChainFunnel, - IFunnelFactory, - ReadPresyncDataFrom -} from './types.js';import type { ChainData, ChainDataExtension, GameStateMachine } from '@paima/sm'; +import type { ChainFunnel, IFunnelFactory, ReadPresyncDataFrom } from './types.js'; +import type { ChainData, ChainDataExtension, GameStateMachine } from '@paima/sm'; import { run } from './run-flag.js'; import { snapshotIfTime } from './snapshots.js'; import { diff --git a/packages/engine/paima-sm/src/cde-cardano-projected-nft.ts b/packages/engine/paima-sm/src/cde-cardano-projected-nft.ts index 3663d9eee..ff5b55036 100644 --- a/packages/engine/paima-sm/src/cde-cardano-projected-nft.ts +++ b/packages/engine/paima-sm/src/cde-cardano-projected-nft.ts @@ -1,64 +1,69 @@ import { ENV } from '@paima/utils'; import type { CdeCardanoProjectedNFTDatum } from './types'; -import {createScheduledData, cdeCardanoProjectedNftInsertData, cdeCardanoProjectedNftUpdateData} from '@paima/db'; +import { + createScheduledData, + cdeCardanoProjectedNftInsertData, + cdeCardanoProjectedNftUpdateData, +} from '@paima/db'; import type { SQLUpdate } from '@paima/db'; -export default async function processDatum(cdeDatum: CdeCardanoProjectedNFTDatum): Promise { - const cdeId = cdeDatum.cdeId; - const prefix = cdeDatum.scheduledPrefix; - const ownerAddress = cdeDatum.payload.ownerAddress; - const previousTxHash = cdeDatum.payload.previousTxHash; - const previousOutputIndex = cdeDatum.payload.previousTxOutputIndex; - const currentTxHash = cdeDatum.payload.actionTxId; - const currentOutputIndex = cdeDatum.payload.actionOutputIndex; - const amount = cdeDatum.payload.amount; - const asset = cdeDatum.payload.asset; - const status = cdeDatum.payload.status; - const datum = cdeDatum.payload.plutusDatum; - const forHowLong = cdeDatum.payload.forHowLong; +export default async function processDatum( + cdeDatum: CdeCardanoProjectedNFTDatum +): Promise { + const cdeId = cdeDatum.cdeId; + const prefix = cdeDatum.scheduledPrefix; + const ownerAddress = cdeDatum.payload.ownerAddress; + const previousTxHash = cdeDatum.payload.previousTxHash; + const previousOutputIndex = cdeDatum.payload.previousTxOutputIndex; + const currentTxHash = cdeDatum.payload.actionTxId; + const currentOutputIndex = cdeDatum.payload.actionOutputIndex; + const amount = cdeDatum.payload.amount; + const asset = cdeDatum.payload.asset; + const status = cdeDatum.payload.status; + const datum = cdeDatum.payload.plutusDatum; + const forHowLong = cdeDatum.payload.forHowLong; - const scheduledBlockHeight = Math.max(cdeDatum.blockNumber, ENV.SM_START_BLOCKHEIGHT + 1); - const scheduledInputData = `${prefix}|${ownerAddress}|${previousTxHash}|${previousOutputIndex}|${currentTxHash}|${currentOutputIndex}|${status}`; + const scheduledBlockHeight = Math.max(cdeDatum.blockNumber, ENV.SM_START_BLOCKHEIGHT + 1); + const scheduledInputData = `${prefix}|${ownerAddress}|${previousTxHash}|${previousOutputIndex}|${currentTxHash}|${currentOutputIndex}|${asset}|${status}`; - if (previousTxHash === undefined || previousOutputIndex === undefined) { - const updateList: SQLUpdate[] = [ - createScheduledData(scheduledInputData, scheduledBlockHeight), - [ - cdeCardanoProjectedNftInsertData, - { - cde_id: cdeId, - owner_address: ownerAddress, - current_tx_hash: currentTxHash, - current_tx_output_index: currentOutputIndex, - asset: asset, - amount: amount, - status: status, - plutus_datum: datum, - for_how_long: forHowLong - }, - ], - ]; - return updateList; - } + if (previousTxHash === undefined || previousOutputIndex === undefined) { const updateList: SQLUpdate[] = [ - createScheduledData(scheduledInputData, scheduledBlockHeight), - [ - cdeCardanoProjectedNftUpdateData, - { - cde_id: cdeId, - owner_address: ownerAddress, - new_tx_hash: currentTxHash, - new_tx_output_index: currentOutputIndex, - previous_tx_hash: previousTxHash, - previous_tx_output_index: previousOutputIndex, - asset: asset, - amount: amount, - status: status, - plutus_datum: datum, - for_how_long: forHowLong - }, - ], + createScheduledData(scheduledInputData, scheduledBlockHeight), + [ + cdeCardanoProjectedNftInsertData, + { + cde_id: cdeId, + owner_address: ownerAddress, + current_tx_hash: currentTxHash, + current_tx_output_index: currentOutputIndex, + asset: asset, + amount: amount, + status: status, + plutus_datum: datum, + for_how_long: forHowLong, + }, + ], ]; return updateList; - + } + const updateList: SQLUpdate[] = [ + createScheduledData(scheduledInputData, scheduledBlockHeight), + [ + cdeCardanoProjectedNftUpdateData, + { + cde_id: cdeId, + owner_address: ownerAddress, + new_tx_hash: currentTxHash, + new_tx_output_index: currentOutputIndex, + previous_tx_hash: previousTxHash, + previous_tx_output_index: previousOutputIndex, + asset: asset, + amount: amount, + status: status, + plutus_datum: datum, + for_how_long: forHowLong, + }, + ], + ]; + return updateList; } diff --git a/packages/engine/paima-sm/src/types.ts b/packages/engine/paima-sm/src/types.ts index cc0940360..01ca42c1b 100644 --- a/packages/engine/paima-sm/src/types.ts +++ b/packages/engine/paima-sm/src/types.ts @@ -298,9 +298,9 @@ export const ChainDataExtensionCardanoProjectedNFTConfig = Type.Object({ }); export type ChainDataExtensionCardanoProjectedNFT = ChainDataExtensionBase & - Static & { - cdeType: ChainDataExtensionType.CardanoProjectedNFT; -}; + Static & { + cdeType: ChainDataExtensionType.CardanoProjectedNFT; + }; export const CdeConfig = Type.Object({ extensions: Type.Array( diff --git a/packages/node-sdk/paima-utils-backend/src/cde-access-internals.ts b/packages/node-sdk/paima-utils-backend/src/cde-access-internals.ts index 330b5ffd3..aab373f4b 100644 --- a/packages/node-sdk/paima-utils-backend/src/cde-access-internals.ts +++ b/packages/node-sdk/paima-utils-backend/src/cde-access-internals.ts @@ -13,7 +13,8 @@ import { cdeErc6551GetOwnedAccounts, cdeErc6551GetOwner, cdeCardanoPoolGetAddressDelegation, - cdeCardanoGetProjectedNft, ICdeCardanoGetProjectedNftResult, + cdeCardanoGetProjectedNft, + ICdeCardanoGetProjectedNftResult, } from '@paima/db'; import type { OwnedNftsResponse, GenericCdeDataUnit, TokenIdPair } from './types.js'; diff --git a/packages/node-sdk/paima-utils-backend/src/cde-access.ts b/packages/node-sdk/paima-utils-backend/src/cde-access.ts index fd5b1610e..647427f69 100644 --- a/packages/node-sdk/paima-utils-backend/src/cde-access.ts +++ b/packages/node-sdk/paima-utils-backend/src/cde-access.ts @@ -16,7 +16,7 @@ import { internalGetCardanoProjectedNft, } from './cde-access-internals.js'; import type { OwnedNftsResponse, GenericCdeDataUnit, TokenIdPair } from './types.js'; -import {ICdeCardanoGetProjectedNftResult} from "@paima/db/src"; +import { ICdeCardanoGetProjectedNftResult } from '@paima/db/src'; /** * Fetch the owner of the NFT from the database