Algorand Mapping
Mapping functions define how chain data is transformed into the optimised GraphQL entities that we have previously defined in the schema.graphql
file.
- Mappings are defined in the
src/mappings
directory and are exported as a function. - These mappings are also exported in
src/index.ts
. - The mappings files are reference in
project.yaml
under the mapping handlers.
There are different classes of mappings functions for Algorand: Block handlers, and Transaction Handlers.
Block Handler
You can use block handlers to capture information each time a new block is attached to the chain, e.g. block number. To achieve this, a defined BlockHandler will be called once for every block.
Using block handlers slows your project down as they can be executed with each and every block - only use if you need to.
import { AlgorandBlock } from "@subql/types-algorand";
export async function handleBlock(block: AlgorandBlock): Promise<void> {
const record = BlockEntity.create({
id: block.round.toString(),
field1: block.round,
field2: "block",
});
await record.save();
}
Transaction Handler
You can use transaction handlers to capture information about each of the transactions in a block. To achieve this, a defined TransactionHandler will be called once for every transaction. You should use Mapping Filters in your manifest to filter transactions to reduce the time it takes to index data and improve mapping performance.
import { AlgorandTransaction } from "@subql/types-algorand";
export async function handleTransaction(
tx: AlgorandTransaction
): Promise<void> {
const record = TransactionEntity.create({
id: tx.id,
field1: tx.roundTime,
field2: "tx",
});
await record.save();
}
The Sandbox
SubQuery is deterministic by design, that means that each SubQuery project is guranteed to index the same data set. This is a critical factor that is required to decentralise SubQuery in the SubQuery Network. This limitation means that the indexer is by default run in a strict virtual machine, with access to a strict number of third party libraries.
You can bypass this limitation, allowing you to index and retrieve information from third party data sources like HTTP endpoints, non historical RPC calls, and more. In order to do to, you must run your project in unsafe-mode
, you can read more about this in the references. An easy way to do this while developing (and running in Docker) is to add the following line to your docker-compose.yml
:
subquery-node:
image: onfinality/subql-node-algorand:latest
...
command:
- -f=/app
- --db-schema=app
- --unsafe
...
By default, the VM2 sandbox only allows the folling:
- only some certain built-in modules, e.g.
assert
,buffer
,crypto
,util
andpath
- third-party libraries written by CommonJS.
- Note
HTTP
andWebSocket
connections are forbidden
Modules and Libraries
To improve SubQuery's data processing capabilities, we have allowed some of the NodeJS's built-in modules for running mapping functions in the sandbox, and have allowed users to call third-party libraries.
Please note this is an experimental feature and you may encounter bugs or issues that may negatively impact your mapping functions. Please report any bugs you find by creating an issue in GitHub.
Built-in modules
Currently, we allow the following NodeJS modules: assert
, buffer
, crypto
, util
, and path
.
Rather than importing the whole module, we recommend only importing the required method(s) that you need. Some methods in these modules may have dependencies that are unsupported and will fail on import.
import { hashMessage } from "ethers/lib/utils"; // Good way
import { utils } from "ethers"; // Bad way