From eab9bd39f08894c4b8c6b88c943bc6aef34792d4 Mon Sep 17 00:00:00 2001 From: Fuyao Zhao Date: Tue, 3 Dec 2024 21:01:53 +0800 Subject: [PATCH 1/2] chore(sui): move object change into object type processor --- packages/sdk/src/aptos/aptos-processor.ts | 6 +- packages/sdk/src/core/constants.ts | 1 + packages/sdk/src/core/index.ts | 1 + packages/sdk/src/eth/base-processor.ts | 7 +- packages/sdk/src/eth/eth.ts | 3 +- packages/sdk/src/eth/tests/erc20-star.test.ts | 3 +- packages/sdk/src/fuel/global-processor.ts | 5 +- packages/sdk/src/sui/sui-object-processor.ts | 86 +++++++++++++++++-- packages/sdk/src/sui/sui-plugin.ts | 11 +++ packages/sdk/src/sui/sui-processor.ts | 9 +- packages/sdk/src/testing/eth-facet.ts | 3 +- 11 files changed, 113 insertions(+), 22 deletions(-) create mode 100644 packages/sdk/src/core/constants.ts diff --git a/packages/sdk/src/aptos/aptos-processor.ts b/packages/sdk/src/aptos/aptos-processor.ts index c874d1220a..1afa02318c 100644 --- a/packages/sdk/src/aptos/aptos-processor.ts +++ b/packages/sdk/src/aptos/aptos-processor.ts @@ -30,7 +30,7 @@ import { parseMoveType, ResourceChangeHandler } from '../move/index.js' -import { Labels, PromiseOrVoid } from '../core/index.js' +import { ALL_ADDRESS, Labels, PromiseOrVoid } from '../core/index.js' import { TypeDescriptor } from '@typemove/move' import { decodeResourceChange, ResourceChange } from '@typemove/aptos' @@ -267,7 +267,7 @@ export class AptosBaseProcessor { export class AptosModulesProcessor extends AptosBaseProcessor { private constructor(options: AptosBindOptions) { - super('*', options) + super(ALL_ADDRESS, options) } static bind(options: AptosBindOptions): AptosModulesProcessor { @@ -432,7 +432,7 @@ function configure(options: AptosBindOptions): IndexConfigure { return { startVersion: startVersion, - address: options.address === '*' ? '*' : accountTypeString(options.address), // aptos don't use address string in api, so only use type string + address: options.address === ALL_ADDRESS ? ALL_ADDRESS : accountTypeString(options.address), // aptos don't use address string in api, so only use type string network: options.network || AptosNetwork.MAIN_NET, baseLabels: options.baseLabels } diff --git a/packages/sdk/src/core/constants.ts b/packages/sdk/src/core/constants.ts new file mode 100644 index 0000000000..c0b082c7a2 --- /dev/null +++ b/packages/sdk/src/core/constants.ts @@ -0,0 +1 @@ +export const ALL_ADDRESS = '*' diff --git a/packages/sdk/src/core/index.ts b/packages/sdk/src/core/index.ts index ed0a8a1323..58216c7194 100644 --- a/packages/sdk/src/core/index.ts +++ b/packages/sdk/src/core/index.ts @@ -11,3 +11,4 @@ export { type Numberish, toBigInteger, toMetricValue } from './numberish.js' export { CorePlugin } from './core-plugin.js' export { DatabaseSchema } from './database-schema.js' +export * from './constants.js' diff --git a/packages/sdk/src/eth/base-processor.ts b/packages/sdk/src/eth/base-processor.ts index 33874677ca..f13cf1e7a8 100644 --- a/packages/sdk/src/eth/base-processor.ts +++ b/packages/sdk/src/eth/base-processor.ts @@ -22,6 +22,7 @@ import sha3 from 'js-sha3' import { ListStateStorage, metricsStorage } from '@sentio/runtime' import { EthChainId } from '@sentio/chain' import { handlersProxy } from '../utils/metrics.js' +import { ALL_ADDRESS } from '../core/index.js' export interface AddressOrTypeEventFilter extends DeferredTopicFilter { addressType?: AddressType @@ -85,7 +86,7 @@ export class GlobalProcessor { constructor(config: Omit) { this.config = { - address: '*', + address: ALL_ADDRESS, name: config.name || 'Global', network: config.network || EthChainId.ETHEREUM, startBlock: 0n @@ -180,7 +181,7 @@ export class GlobalProcessor { const ctx = new GlobalContext( chainId, - '*', + ALL_ADDRESS, new Date(block.timestamp * 1000), block, undefined, @@ -201,7 +202,7 @@ export class GlobalProcessor { const ctx = new GlobalContext( chainId, - '*', + ALL_ADDRESS, new Date(block.timestamp * 1000), block, undefined, diff --git a/packages/sdk/src/eth/eth.ts b/packages/sdk/src/eth/eth.ts index 2b69940f65..f475d9324d 100644 --- a/packages/sdk/src/eth/eth.ts +++ b/packages/sdk/src/eth/eth.ts @@ -27,6 +27,7 @@ import { ContractContext } from './context.js' import { getAddress } from 'ethers/address' import { getBigInt, getNumber, hexlify } from 'ethers/utils' import { EthCallContext, EthCallParam } from '@sentio/protos' +import { ALL_ADDRESS } from '../core/index.js' export interface IResult { /** @@ -271,7 +272,7 @@ export function isNullAddress(address: string) { } export function validateAndNormalizeAddress(address: string): string { - if (address === '*') { + if (address === ALL_ADDRESS) { return address } const normalizedAddress = getAddress(address) diff --git a/packages/sdk/src/eth/tests/erc20-star.test.ts b/packages/sdk/src/eth/tests/erc20-star.test.ts index facc4c93d3..f50e8bf29d 100644 --- a/packages/sdk/src/eth/tests/erc20-star.test.ts +++ b/packages/sdk/src/eth/tests/erc20-star.test.ts @@ -5,11 +5,12 @@ import { expect } from 'chai' import { firstCounterValue, TestProcessorServer } from '../../testing/index.js' import { ERC20Processor, mockTransferLog } from '../builtin/erc20.js' +import { ALL_ADDRESS } from '@sentio/sdk' describe('Test star Examples', () => { const service = new TestProcessorServer(async () => { ERC20Processor.bind({ - address: '*', + address: ALL_ADDRESS, startBlock: 14201940 }).onEventTransfer(async (evt, ctx) => { ctx.meter.Counter('c1').add(1) diff --git a/packages/sdk/src/fuel/global-processor.ts b/packages/sdk/src/fuel/global-processor.ts index 92020bc6fe..2bfc609b80 100644 --- a/packages/sdk/src/fuel/global-processor.ts +++ b/packages/sdk/src/fuel/global-processor.ts @@ -6,6 +6,7 @@ import { decodeFuelTransaction, DEFAULT_FUEL_FETCH_CONFIG, FuelFetchConfig } fro import { FuelContext } from './context.js' import { FuelProcessorConfig, getOptionsSignature } from './fuel-processor.js' import { mergeProcessResults } from '@sentio/runtime' +import { ALL_ADDRESS } from '../core/index.js' type GlobalFuelProcessorConfig = Omit @@ -21,7 +22,7 @@ export class FuelGlobalProcessor implements FuelBaseProcessor { templateId: number | undefined objectHandlers: ObjectHandler[] = [] + objectChangeHandlers: ObjectChangeHandler[] = [] // static bind(options: SuiObjectsBindOptions): SuiBaseObjectsProcessor { // return new SuiBaseObjectsProcessor(options) @@ -113,7 +115,11 @@ export abstract class SuiBaseObjectOrAddressProcessor { }) return this } +} +abstract class SuiBaseObjectOrAddressProcessorInternal< + HandlerType +> extends SuiBaseObjectOrAddressProcessor { public onTimeInterval( handler: HandlerType, timeIntervalInMinutes = 60, @@ -150,7 +156,7 @@ export abstract class SuiBaseObjectOrAddressProcessor { } } -export class SuiAddressProcessor extends SuiBaseObjectOrAddressProcessor< +export class SuiAddressProcessor extends SuiBaseObjectOrAddressProcessorInternal< (objects: SuiMoveObject[], ctx: SuiAddressContext) => PromiseOrVoid > { callHandlers: CallHandler[] = [] @@ -212,7 +218,7 @@ export class SuiAddressProcessor extends SuiBaseObjectOrAddressProcessor< } } -export class SuiObjectProcessor extends SuiBaseObjectOrAddressProcessor< +export class SuiObjectProcessor extends SuiBaseObjectOrAddressProcessorInternal< (self: SuiMoveObject, dynamicFieldObjects: SuiMoveObject[], ctx: SuiObjectContext) => PromiseOrVoid > { static bind(options: SuiObjectBindOptions): SuiObjectProcessor { @@ -242,9 +248,10 @@ export class SuiObjectTypeProcessor extends SuiBaseObjectOrAddressProcessor< (self: TypedSuiMoveObject, dynamicFieldObjects: SuiMoveObject[], ctx: SuiObjectContext) => PromiseOrVoid > { objectType: TypeDescriptor + static bind(options: SuiObjectTypeBindOptions): SuiObjectTypeProcessor { const processor = new SuiObjectTypeProcessor({ - address: options.objectType.qname, + address: ALL_ADDRESS, // current only support on all address network: options.network, startCheckpoint: options.startCheckpoint, ownerType: MoveOwnerType.TYPE, @@ -270,6 +277,71 @@ export class SuiObjectTypeProcessor extends SuiBaseObjectOrAddressProcessor< const object = await ctx.coder.filterAndDecodeObjects(this.objectType, [data.self as SuiMoveObject]) return handler(object[0], data.objects as SuiMoveObject[], ctx) } + + public onObjectChange(handler: (changes: SuiObjectChange[], ctx: SuiObjectChangeContext) => void): this { + if (this.config.network === SuiNetwork.TEST_NET) { + throw new ServerError(Status.INVALID_ARGUMENT, 'object change not supported in testnet') + } + const processor = this + this.objectChangeHandlers.push({ + handler: async function (data: Data_SuiObjectChange) { + const ctx = new SuiObjectChangeContext( + processor.config.network, + processor.config.address, + data.timestamp || new Date(0), + data.slot, + data.txDigest, + processor.config.baseLabels + ) + await handler(data.changes as SuiObjectChange[], ctx) + return ctx.stopAndGetResult() + }, + type: this.objectType.qname + }) + + return this + } + + public onTimeInterval( + handler: ( + self: TypedSuiMoveObject, + dynamicFieldObjects: SuiMoveObject[], + ctx: SuiObjectContext + ) => PromiseOrVoid, + timeIntervalInMinutes = 60, + backfillTimeIntervalInMinutes = 240, + fetchConfig?: Partial + ): this { + return this.onInterval( + handler, + { + recentInterval: timeIntervalInMinutes, + backfillInterval: backfillTimeIntervalInMinutes + }, + undefined, + this.objectType.qname, + fetchConfig + ) + } + + public onCheckpointInterval( + handler: ( + self: TypedSuiMoveObject, + dynamicFieldObjects: SuiMoveObject[], + ctx: SuiObjectContext + ) => PromiseOrVoid, + checkpointInterval = 100000, + backfillCheckpointInterval = 400000, + fetchConfig?: Partial + ): this { + return this.onInterval( + handler, + undefined, + { recentInterval: checkpointInterval, backfillInterval: backfillCheckpointInterval }, + this.objectType.qname, + fetchConfig + ) + } } export class SuiWrappedObjectProcessor extends SuiBaseObjectOrAddressProcessor< diff --git a/packages/sdk/src/sui/sui-plugin.ts b/packages/sdk/src/sui/sui-plugin.ts index b165ae657d..969a9da41d 100644 --- a/packages/sdk/src/sui/sui-plugin.ts +++ b/packages/sdk/src/sui/sui-plugin.ts @@ -122,6 +122,7 @@ export class SuiPlugin extends Plugin { } contractConfig.moveCallConfigs.push(functionHandlerConfig) } + // deprecated, use objectType processor instead for (const handler of suiProcessor.objectChangeHandlers) { const handlerId = handlers.suiObjectChangeHandlers.push(handler.handler) - 1 const objectChangeHandler: MoveResourceChangeConfig = { @@ -141,6 +142,16 @@ export class SuiPlugin extends Plugin { }) for (const handler of processor.objectHandlers) { const handlerId = handlers.suiObjectHandlers.push(handler.handler) - 1 + + for (const handler of processor.objectChangeHandlers) { + const handlerId = handlers.suiObjectChangeHandlers.push(handler.handler) - 1 + const objectChangeHandler: MoveResourceChangeConfig = { + type: handler.type, + handlerId + } + accountConfig.moveResourceChangeConfigs.push(objectChangeHandler) + } + accountConfig.moveIntervalConfigs.push({ intervalConfig: { handlerId: handlerId, diff --git a/packages/sdk/src/sui/sui-processor.ts b/packages/sdk/src/sui/sui-processor.ts index 9b8165eaaf..ce14bbd0b7 100644 --- a/packages/sdk/src/sui/sui-processor.ts +++ b/packages/sdk/src/sui/sui-processor.ts @@ -17,7 +17,7 @@ import { } from '../move/index.js' import { getMoveCalls } from './utils.js' import { defaultMoveCoder, MoveCoder } from './index.js' -import { Labels } from '../core/index.js' +import { ALL_ADDRESS, Labels } from '../core/index.js' import { Required } from 'utility-types' export const DEFAULT_FETCH_CONFIG: MoveFetchConfig = { @@ -31,7 +31,7 @@ export type IndexConfigure = Required): SuiGlobalProcessor { - return new SuiGlobalProcessor('*', { ...options, address: '*' }) + return new SuiGlobalProcessor(ALL_ADDRESS, { ...options, address: ALL_ADDRESS }) } onTransactionBlock( handler: (transaction: SuiTransactionBlockResponse, ctx: SuiContext) => void, @@ -291,6 +291,7 @@ export class SuiGlobalProcessor extends SuiBaseProcessor { return super.onTransactionBlock(handler, filter, fetchConfig) } + // deprecated,, use object type processor public onObjectChange( handler: (changes: SuiObjectChange[], ctx: SuiObjectChangeContext) => void, type: string diff --git a/packages/sdk/src/testing/eth-facet.ts b/packages/sdk/src/testing/eth-facet.ts index 6b277fe6a8..9b0aef4a9d 100644 --- a/packages/sdk/src/testing/eth-facet.ts +++ b/packages/sdk/src/testing/eth-facet.ts @@ -3,6 +3,7 @@ import { DataBinding, HandlerType, ProcessBindingResponse } from '@sentio/protos import { Trace } from '../eth/eth.js' import { BlockParams, LogParams } from 'ethers/providers' import { ChainId, EthChainId } from '@sentio/chain' +import { ALL_ADDRESS } from '@sentio/sdk' export class EthFacet { server: TestProcessorServer @@ -41,7 +42,7 @@ export class EthFacet { } if ( trace.action.to?.toLowerCase() !== contract.contract?.address.toLowerCase() && - contract.contract?.address !== '*' + contract.contract?.address !== ALL_ADDRESS ) { continue } From 754882c1add87d5abb1c10f4263efb45caecb6fa Mon Sep 17 00:00:00 2001 From: Fuyao Zhao Date: Wed, 4 Dec 2024 22:09:29 +0800 Subject: [PATCH 2/2] chore(aptos): make movement network alias --- examples/sui/src/processor.ts | 1 - packages/sdk/src/aptos/codegen/codegen.ts | 14 +++++++------- packages/sdk/src/aptos/index.ts | 2 +- packages/sdk/src/aptos/network.ts | 8 ++++++-- packages/sdk/src/sui/tests/sui.test.ts | 1 - packages/sdk/src/testing/eth-facet.ts | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/sui/src/processor.ts b/examples/sui/src/processor.ts index 1130b5f5ff..7f9e3da586 100644 --- a/examples/sui/src/processor.ts +++ b/examples/sui/src/processor.ts @@ -47,6 +47,5 @@ SuiObjectTypeProcessor.bind({ }, 60, 60 * 24 * 30, - undefined, { owned: false } ) diff --git a/packages/sdk/src/aptos/codegen/codegen.ts b/packages/sdk/src/aptos/codegen/codegen.ts index 526034412a..0578d2d7e1 100644 --- a/packages/sdk/src/aptos/codegen/codegen.ts +++ b/packages/sdk/src/aptos/codegen/codegen.ts @@ -63,7 +63,7 @@ class AptosNetworkCodegen extends BaseAptosCodegen { const MAINNET_CODEGEN = new AptosNetworkCodegen(AptosNetwork.MAIN_NET) const TESTNET_CODEGEN = new AptosNetworkCodegen(AptosNetwork.TEST_NET) const MOVEMENT_MAINNET_CODEGEN = new AptosNetworkCodegen(AptosNetwork.MOVEMENT_MAIN_NET) -const M2_TESTNET_CODEGEN = new AptosNetworkCodegen(AptosNetwork.MOVEMENT_TEST_NET) +// const M2_TESTNET_CODEGEN = new AptosNetworkCodegen(AptosNetwork.MOVEMENT_TEST_NET) const MOVEMENT_PROTO_CODEGEN = new AptosNetworkCodegen(AptosNetwork.MOVEMENT_PORTO) class AptosCodegen { @@ -75,16 +75,16 @@ class AptosCodegen { path.join(outputDir, 'movement-mainnet'), builtin ) - const num4 = await M2_TESTNET_CODEGEN.generate( - path.join(srcDir, 'm2-testnet'), - path.join(outputDir, 'm2-testnet'), - builtin - ) + // const num4 = await M2_TESTNET_CODEGEN.generate( + // path.join(srcDir, 'm2-testnet'), + // path.join(outputDir, 'm2-testnet'), + // builtin + // ) const num5 = await MOVEMENT_PROTO_CODEGEN.generate( path.join(srcDir, 'movement-porto'), path.join(outputDir, 'movement-porto'), builtin ) - return num1 + num2 + num3 + num4 + num5 + return num1 + num2 + num3 + num5 } } diff --git a/packages/sdk/src/aptos/index.ts b/packages/sdk/src/aptos/index.ts index 0469836bb5..730b085b38 100644 --- a/packages/sdk/src/aptos/index.ts +++ b/packages/sdk/src/aptos/index.ts @@ -7,7 +7,7 @@ export { } from './aptos-processor.js' export { AptosResourceProcessorTemplate } from './aptos-resource-processor-template.js' export { AptosContext, AptosResourcesContext } from './context.js' -export { AptosBindOptions, AptosNetwork } from './network.js' +export { AptosBindOptions, AptosNetwork, MovementNetwork } from './network.js' export { type ResourceChange } from '@typemove/aptos' export * from './api.js' diff --git a/packages/sdk/src/aptos/network.ts b/packages/sdk/src/aptos/network.ts index 0ff1576ac0..3195bb7585 100644 --- a/packages/sdk/src/aptos/network.ts +++ b/packages/sdk/src/aptos/network.ts @@ -9,10 +9,14 @@ export const AptosNetwork = { TEST_NET: AptosChainId.APTOS_TESTNET, // DEV_NET: AptosChainId.APTOS_DEVNET, MOVEMENT_MAIN_NET: AptosChainId.APTOS_MOVEMENT_MAINNET, - MOVEMENT_TEST_NET: AptosChainId.APTOS_MOVEMENT_TESTNET, MOVEMENT_PORTO: AptosChainId.APTOS_MOVEMENT_PORTO } +export const MovementNetwork = { + MAIN_NET: AptosChainId.APTOS_MOVEMENT_MAINNET, + PORTO: AptosChainId.APTOS_MOVEMENT_PORTO +} + export class AptosBindOptions { address: string network?: AptosNetwork = AptosNetwork.MAIN_NET @@ -27,7 +31,7 @@ export function getRpcEndpoint(network: AptosNetwork): string { return 'https://mainnet.aptoslabs.com/v1' case AptosNetwork.TEST_NET: return 'https://testnet.aptoslabs.com/v1' - case AptosNetwork.MOVEMENT_TEST_NET: + case AptosChainId.APTOS_MOVEMENT_TESTNET: return 'https://aptos.testnet.suzuka.movementlabs.xyz/v1' case AptosNetwork.MOVEMENT_MAIN_NET: return 'https://mainnet.movementnetwork.xyz/v1' diff --git a/packages/sdk/src/sui/tests/sui.test.ts b/packages/sdk/src/sui/tests/sui.test.ts index 93bbec0362..bc68d369e8 100644 --- a/packages/sdk/src/sui/tests/sui.test.ts +++ b/packages/sdk/src/sui/tests/sui.test.ts @@ -31,7 +31,6 @@ describe('Test Sui Example', () => { }, 60, 60, - undefined, { owned: false } ) }) diff --git a/packages/sdk/src/testing/eth-facet.ts b/packages/sdk/src/testing/eth-facet.ts index 9b0aef4a9d..4aff1ca456 100644 --- a/packages/sdk/src/testing/eth-facet.ts +++ b/packages/sdk/src/testing/eth-facet.ts @@ -3,7 +3,7 @@ import { DataBinding, HandlerType, ProcessBindingResponse } from '@sentio/protos import { Trace } from '../eth/eth.js' import { BlockParams, LogParams } from 'ethers/providers' import { ChainId, EthChainId } from '@sentio/chain' -import { ALL_ADDRESS } from '@sentio/sdk' +import { ALL_ADDRESS } from '../index.js' export class EthFacet { server: TestProcessorServer