Aptos
Aptos is a Layer 1 blockchain utilizing the Move language and its resource-based model.
Core Concepts
Processors
Aptos integration offers several processor types, listed in order of common usage:
User-Defined Processors
Generate type-safe processors from your smart contract ABIs using Sentio's code generation tools. These provide the best developer experience with full type safety and auto-completion.
// Example: Generated from PancakeSwap contract
import { pancakeswap } from './types/aptos/0xc7efb4076dbe143cbcd98cfaaa929ecfc8f299203dfff63b95ccb6bfe19850fa.js'
pancakeswap.bind({
network: AptosNetwork.MAINNET,
startVersion: 1000000n
}).onEventSwapEvent(async (evt, ctx) => {
// Fully typed event data
const { amount_x_in, amount_x_out } = evt.data_decoded
// Process swap...
})Built-in System Processors
Sentio SDK pre-generates type-safe processors from Aptos core system modules, providing ready-to-use bindings for system-level monitoring:
// Aptos coin module
import { aptos_coin } from '@sentio/sdk/aptos/builtin/0x1'
// Staking module
import { staking_contract } from '@sentio/sdk/aptos/builtin/0x1'
// Account module
import { account } from '@sentio/sdk/aptos/builtin/0x1'These processors are generated by Sentio SDK from Aptos's system packages and provide fully-typed interfaces for monitoring token transfers, staking operations, and account activities.
AptosResourcesProcessor
Periodically fetches and processes Aptos resources associated with one or more accounts. Ideal for tracking account state changes over time or by block version.
- Use Case: Monitoring account balances, tracking NFT ownership changes stored in resources
- Binding:
AptosResourcesProcessor.bind({ address: '0x...', network: AptosNetwork.MAINNET, startVersion: 123456n })
AptosModulesProcessor
Binds to a specific Aptos module (smart contract) address for manual event and function call processing.
- Note: Consider using code generation for type-safe processors instead
- Binding:
AptosModulesProcessor.bind({ address: '0x...', network: AptosNetwork.MAINNET, startVersion: 123456n }) - Advanced Use: Rarely needed as user-defined processors handle most use cases better
AptosGlobalProcessor
Processes transactions across the entire Aptos network with optional filtering.
- Warning: Can be resource-intensive; use specific processors when possible
- Binding:
AptosGlobalProcessor.bind({ network: AptosNetwork.MAINNET, startVersion: 123456n }) - Advanced Use: Only for chain-wide analytics like tracking gas usage patterns or monitoring whale wallets
Handlers
Processors define handlers to react to specific blockchain activities:
-
Transaction-Based (for
AptosModulesProcessor,AptosGlobalProcessor):onMoveEvent(handler(event, ctx), filter): Triggered when a specific Move event matching thefilteris emitted within a transaction. Theeventobject is automatically decoded based on the module's ABI if available.onEntryFunctionCall(handler(call, ctx), filter): Triggered when an entry function matching thefilteris called within a transaction. Thecallpayload is automatically decoded.onTransaction(handler(tx, ctx), filter?): Triggered for every transaction processed by the processor (optionally filtered bysenderorincludeFailed). Provides the rawUserTransactionResponse.onTimeInterval(handler(txns, ctx), intervalMinutes?, backfillIntervalMinutes?): Processes transactions in time-based batches.onVersionInterval(handler(txns, ctx), interval?, backfillInterval?): Processes transactions in version-based batches.
-
Resource-Based (for
AptosResourcesProcessor):onTimeInterval(handler(resources, ctx), intervalMinutes?, backfillIntervalMinutes?, type?, fetchConfig?): Periodically fetches resources based on time.onVersionInterval(handler(resources, ctx), interval?, backfillInterval?, type?, fetchConfig?): Periodically fetches resources based on block versions.onResourceChange(handler(changes, ctx), typeDescriptor): Processes detailed changes (write, delete, create) to specific resource types within transactions included by the bound module (Note: RequiresAptosModulesProcessorand appropriate fetch config).
Context (ctx)
ctx)Each handler receives a Context object (AptosContext for transaction-based handlers, AptosResourcesContext for resource-based handlers) providing:
- Chain-specific information:
network,version. - Transaction details:
transaction(forAptosContext). - Timestamp:
timestampInMicrosorgetTimestamp(). - Helper methods:
client.getAccountResource(...),coder.decodeEvent(...), etc. - Standard SDK outputs:
ctx.meter.Counter('...'),ctx.eventLogger.emit('...'),ctx.exporter.aptos_Account(...).
Fetch Configuration
Handlers can optionally include a fetchConfig parameter to specify what additional data should be fetched for the transaction being processed. This optimizes data fetching. The configuration is defined by the MoveFetchConfig interface:
interface MoveFetchConfig {
allEvents: boolean; // Fetch all events for the transaction
includeFailedTransaction?: boolean; // Include failed transactions
inputs: boolean; // Fetch transaction input arguments
resourceChanges: boolean; // Fetch resource changes
resourceConfig?: ResourceConfig; // Specific configuration for resource fetching
supportMultisigFunc?: boolean; // Support for multisig functions
}For example, to fetch resource changes for transactions that emit a specific event:
processor.onEvent(..., { fetchConfig: { resourceChanges: true } }); // Fetch resource changes for transactions with this eventGetting Started Example
First, create an Aptos processor project: yarn sentio create -c aptos <project-name>. You can refer to the CLI Reference to learn details.
import { AptosModulesProcessor, AptosContext, AptosNetwork } from "@sentio/sdk/aptos";
import { pancakeswap } from './types/aptos/0xc7efb4076dbe143cbcd98cfaaa929ecfc8f299203dfff63b95ccb6bfe19850fa.js'; // Generated types
AptosModulesProcessor.bind({
address: pancakeswap.DEFAULT_OPTIONS.address,
network: AptosNetwork.MAINNET,
startVersion: 1000000n // Start processing from version 1,000,000
})
.onEvent(async (event: pancakeswap.SwapEvent, ctx: AptosContext) => {
ctx.meter.Counter("swap_volume").add(event.data_decoded.amount_x_in + event.data_decoded.amount_y_in);
ctx.eventLogger.emit("Swap", {
distinctId: ctx.transaction.sender,
pair: event.type_arguments[0], // Assuming type argument represents the pair
amountXIn: event.data_decoded.amount_x_in,
amountYIn: event.data_decoded.amount_y_in,
amountXOut: event.data_decoded.amount_x_out,
amountYOut: event.data_decoded.amount_y_out,
});
}, { type: `${pancakeswap.DEFAULT_OPTIONS.address}::swap::SwapEvent` }) // Filter for SwapEvent
.onEntryFunctionCall(async (call: pancakeswap.Add_liquidityPayload, ctx: AptosContext) => {
if (!ctx.transaction.success) return; // Skip failed transactions
ctx.meter.Counter("liquidity_adds").add(1);
ctx.eventLogger.emit("AddLiquidity", {
distinctId: ctx.transaction.sender,
amountX: call.arguments_decoded[0],
amountY: call.arguments_decoded[1],
});
}, { function: `${pancakeswap.DEFAULT_OPTIONS.address}::swap::add_liquidity` }); // Filter for add_liquidity functionUpdated 16 days ago